Skip to content

Commit

Permalink
Merge pull request #14 from Brightscout/MI-806
Browse files Browse the repository at this point in the history
MI-806 move logic to open edit subscription modal from server to webapp
  • Loading branch information
chetanyakan authored Feb 7, 2020
2 parents 109343a + a70e6ac commit 4fa33cf
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 69 deletions.
13 changes: 0 additions & 13 deletions server/command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ var ConfluenceCommandHandler = Handler{
handlers: map[string]HandlerFunc{
"list": listChannelSubscription,
"unsubscribe": deleteSubscription,
"edit": editSubscription,
"help": confluenceHelp,
},
defaultHandler: executeConfluenceDefault,
Expand Down Expand Up @@ -109,18 +108,6 @@ func listChannelSubscription(context *model.CommandArgs, args ...string) *model.
return &model.CommandResponse{}
}

func editSubscription(context *model.CommandArgs, args ...string) *model.CommandResponse {
if len(args) == 0 {
postCommandResponse(context, specifyAlias)
return &model.CommandResponse{}
}
alias := args[0]
if err := service.OpenSubscriptionEditModal(context.ChannelId, context.UserId, alias); err != nil {
postCommandResponse(context, err.Error())
}
return &model.CommandResponse{}
}

func confluenceHelp(context *model.CommandArgs, args ...string) *model.CommandResponse {
postCommandResponse(context, helpText)
return &model.CommandResponse{}
Expand Down
6 changes: 3 additions & 3 deletions server/controller/edit_subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
"github.com/Brightscout/mattermost-plugin-confluence/server/service"
)

var EditChannelSubscription = &Endpoint{
var editChannelSubscription = &Endpoint{
RequiresAuth: true,
Path: "/subscription",
Method: http.MethodPut,
Execute: editChannelSubscription,
Execute: handleEditChannelSubscription,
}

func editChannelSubscription(w http.ResponseWriter, r *http.Request) {
func handleEditChannelSubscription(w http.ResponseWriter, r *http.Request) {
body := json.NewDecoder(r.Body)
subscription := serializer.Subscription{}
if err := body.Decode(&subscription); err != nil {
Expand Down
26 changes: 26 additions & 0 deletions server/controller/get_subscription.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package controller

import (
"net/http"

"github.com/Brightscout/mattermost-plugin-confluence/server/service"
)

var getChannelSubscription = &Endpoint{
RequiresAuth: true,
Path: "/subscription",
Method: http.MethodGet,
Execute: handleGetChannelSubscription,
}

func handleGetChannelSubscription(w http.ResponseWriter, r *http.Request) {
channelID := r.FormValue("channelID")
alias := r.FormValue("alias")
subscription, errCode, err := service.GetChannelSubscription(channelID, alias)
if err != nil {
http.Error(w, err.Error(), errCode)
return
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(subscription.ToJSON()))
}
5 changes: 3 additions & 2 deletions server/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ type Endpoint struct {
// Usage: getEndpointKey(GetMetadata): GetMetadata
var Endpoints = map[string]*Endpoint{
getEndpointKey(confluenceCloudWebhook): confluenceCloudWebhook,
getEndpointKey(SaveChannelSubscription): SaveChannelSubscription,
getEndpointKey(EditChannelSubscription): EditChannelSubscription,
getEndpointKey(saveChannelSubscription): saveChannelSubscription,
getEndpointKey(editChannelSubscription): editChannelSubscription,
getEndpointKey(confluenceServerWebhook): confluenceServerWebhook,
getEndpointKey(getChannelSubscription): getChannelSubscription,
}

// Uniquely identifies an endpoint using path and method
Expand Down
6 changes: 3 additions & 3 deletions server/controller/save_subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
"github.com/Brightscout/mattermost-plugin-confluence/server/service"
)

var SaveChannelSubscription = &Endpoint{
var saveChannelSubscription = &Endpoint{
RequiresAuth: true,
Path: "/subscription",
Method: http.MethodPost,
Execute: saveChannelSubscription,
Execute: handleSaveChannelSubscription,
}

func saveChannelSubscription(w http.ResponseWriter, r *http.Request) {
func handleSaveChannelSubscription(w http.ResponseWriter, r *http.Request) {
body := json.NewDecoder(r.Body)
subscription := serializer.Subscription{}
if err := body.Decode(&subscription); err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package serializer

import (
"encoding/json"
"fmt"
url2 "net/url"
"strings"
Expand Down Expand Up @@ -66,3 +67,11 @@ func FormattedSubscriptionList(channelSubscriptions map[string]Subscription) str
}
return list
}

func (s *Subscription) ToJSON() string {
b, err := json.Marshal(s)
if err != nil {
return ""
}
return string(b)
}
33 changes: 1 addition & 32 deletions server/service/edit_subscription.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package service

import (
"encoding/json"
"fmt"
"net/http"

"github.com/mattermost/mattermost-server/model"
Expand All @@ -13,11 +11,7 @@ import (
"github.com/Brightscout/mattermost-plugin-confluence/server/store"
)

const (
openEditSubscriptionModalWebsocketEvent = "open_edit_subscription_modal"
generalError = "Some error occurred. Please try again after sometime."
subscriptionEditSuccess = "Subscription updated successfully."
)
const subscriptionEditSuccess = "Subscription updated successfully."

func EditSubscription(subscription serializer.Subscription, userID string) (int, error) {
channelSubscriptions, cKey, gErr := GetChannelSubscriptions(subscription.ChannelID)
Expand Down Expand Up @@ -46,28 +40,3 @@ func EditSubscription(subscription serializer.Subscription, userID string) (int,

return http.StatusOK, nil
}

func OpenSubscriptionEditModal(channelID, userID, alias string) error {
channelSubscriptions, _, gErr := GetChannelSubscriptions(channelID)
if gErr != nil {
return errors.New(generalError)
}
if subscription, ok := channelSubscriptions[alias]; ok {
bytes, err := json.Marshal(subscription)
if err != nil {
return errors.New(generalError)
}
config.Mattermost.PublishWebSocketEvent(
openEditSubscriptionModalWebsocketEvent,
map[string]interface{}{
"subscription": string(bytes),
},
&model.WebsocketBroadcast{
UserId: userID,
},
)
return nil
}

return errors.New(fmt.Sprintf(subscriptionNotFound, alias))
}
24 changes: 24 additions & 0 deletions server/service/get_subscription.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package service

import (
"fmt"
"net/http"

"github.com/pkg/errors"

"github.com/Brightscout/mattermost-plugin-confluence/server/serializer"
)

const generalError = "Some error occurred. Please try again after sometime."

func GetChannelSubscription(channelID, alias string) (serializer.Subscription, int, error) {
channelSubscriptions, _, gErr := GetChannelSubscriptions(channelID)
if gErr != nil {
return serializer.Subscription{}, http.StatusInternalServerError, errors.New(generalError)
}
subscription, found := channelSubscriptions[alias]
if !found {
return serializer.Subscription{}, http.StatusBadRequest, errors.New(fmt.Sprintf(subscriptionNotFound, alias))
}
return subscription, http.StatusOK, nil
}
File renamed without changes.
4 changes: 2 additions & 2 deletions webapp/src/actions/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
closeSubscriptionModal, openSubscriptionModal, saveChannelSubscription, receivedSubscription, editChannelSubscription,
closeSubscriptionModal, openSubscriptionModal, saveChannelSubscription, editChannelSubscription, getChannelSubscription,
} from './subscription_modal';

export {
saveChannelSubscription,
openSubscriptionModal,
closeSubscriptionModal,
receivedSubscription,
editChannelSubscription,
getChannelSubscription,
};
38 changes: 33 additions & 5 deletions webapp/src/actions/subscription_modal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {PostTypes} from 'mattermost-redux/action_types';

import Client from '../client';
import Constants from '../constants';

Expand Down Expand Up @@ -51,10 +53,36 @@ export const closeSubscriptionModal = () => (dispatch) => {
});
};

export const receivedSubscription = (subscription) => (dispatch) => {
dispatch({
type: Constants.ACTION_TYPES.RECEIVED_SUBSCRIPTION,
data: JSON.parse(subscription),
});
export const getChannelSubscription = (channelID, alias, userID) => async (dispatch) => {
try {
const response = await Client.getChannelSubscription(channelID, alias);
dispatch({
type: Constants.ACTION_TYPES.RECEIVED_SUBSCRIPTION,
data: response,
});
} catch (e) {
dispatch(sendEphemeralPost(e.response.text, channelID, userID));
}
};

export function sendEphemeralPost(message, channelID, userID) {
const timestamp = Date.now();
const post = {
id: 'confluencePlugin' + timestamp,
user_id: userID,
channel_id: channelID,
message,
type: 'system_ephemeral',
create_at: timestamp,
update_at: timestamp,
root_id: '',
parent_id: '',
props: {},
};

return {
type: PostTypes.RECEIVED_NEW_POST,
data: post,
channelID,
};
}
5 changes: 5 additions & 0 deletions webapp/src/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export default class Client {
return this.doPut(url, channelSubscription);
};

getChannelSubscription = (channelID, alias) => {
const url = `${this.pluginApiUrl}/subscription?channelID=${channelID}&alias=${alias}`;
return this.doGet(url);
};

doGet = async (url, headers = {}) => {
headers['X-Requested-With'] = 'XMLHttpRequest';

Expand Down
2 changes: 2 additions & 0 deletions webapp/src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ const CONFLUENCE_EVENTS = [

const MATTERMOST_CSRF_COOKIE = 'MMCSRF';
const OPEN_EDIT_SUBSCRIPTION_MODAL_WEBSOCKET_EVENT = `custom_${PLUGIN_NAME}_open_edit_subscription_modal`;
const SPECIFY_ALIAS = 'Please specify alias.';

export default {
ACTION_TYPES,
CONFLUENCE_EVENTS,
MATTERMOST_CSRF_COOKIE,
OPEN_EDIT_SUBSCRIPTION_MODAL_WEBSOCKET_EVENT,
PLUGIN_NAME,
SPECIFY_ALIAS,
};
16 changes: 14 additions & 2 deletions webapp/src/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import {openSubscriptionModal} from '../actions';
import {openSubscriptionModal, getChannelSubscription} from '../actions';

import {splitArgs} from '../utils';
import {sendEphemeralPost} from '../actions/subscription_modal';
import Constants from '../constants';

export default class Hooks {
constructor(store) {
Expand All @@ -10,10 +14,18 @@ export default class Hooks {
if (message) {
commandTrimmed = message.trim();
}

const userID = this.store.getState().entities.users.currentUserId;
if (commandTrimmed && commandTrimmed === '/confluence subscribe') {
this.store.dispatch(openSubscriptionModal());
return Promise.resolve({});
} else if (commandTrimmed && commandTrimmed.startsWith('/confluence edit')) {
const args = splitArgs(commandTrimmed);
if (args.length < 3) { // eslint-disable-line
this.store.dispatch(sendEphemeralPost(Constants.SPECIFY_ALIAS, contextArgs.channel_id, userID));
} else {
this.store.dispatch(getChannelSubscription(contextArgs.channel_id, args[2], userID));
}
return Promise.resolve({});
}
return Promise.resolve({
message,
Expand Down
7 changes: 0 additions & 7 deletions webapp/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Constants from './constants';
import Hooks from './hooks';
import reducer from './reducers';

import {receivedSubscription} from './actions';
import SubscriptionModal from './components/subscription_modal';

//
Expand All @@ -13,12 +12,6 @@ class PluginClass {
initialize(registry, store) {
registry.registerReducer(reducer);
registry.registerRootComponent(SubscriptionModal);
registry.registerWebSocketEventHandler(
Constants.OPEN_EDIT_SUBSCRIPTION_MODAL_WEBSOCKET_EVENT,
(payload) => {
store.dispatch(receivedSubscription(payload.data.subscription));
},
);
const hooks = new Hooks(store);
registry.registerSlashCommandWillBePostedHook(hooks.slashCommandWillBePostedHook);
}
Expand Down
12 changes: 12 additions & 0 deletions webapp/src/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const splitArgs = (command) => {
const myRegexp = /[^\s"]+|"([^"]*)"/gi;
const myArray = [];
let match;
do {
match = myRegexp.exec(command);
if (match != null) {
myArray.push(match[1] ? match[1] : match[0]);
}
} while (match != null);
return myArray;
};

0 comments on commit 4fa33cf

Please sign in to comment.