diff --git a/i18n/en.json b/i18n/en.json index 17f1ba7c80..c730f57117 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2351,6 +2351,10 @@ "id": "model.outgoing_hook.is_valid.token.app_error", "translation": "Invalid token" }, + { + "id": "model.outgoing_hook.is_valid.trigger_words.app_error", + "translation": "Invalid trigger words" + }, { "id": "model.outgoing_hook.is_valid.update_at.app_error", "translation": "Update at must be a valid time" diff --git a/model/outgoing_webhook.go b/model/outgoing_webhook.go index e13de90800..ef1807e7aa 100644 --- a/model/outgoing_webhook.go +++ b/model/outgoing_webhook.go @@ -98,6 +98,14 @@ func (o *OutgoingWebhook) IsValid() *AppError { return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.words.app_error", nil, "") } + if len(o.TriggerWords) != 0 { + for _, triggerWord := range o.TriggerWords { + if len(triggerWord) == 0 { + return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "") + } + } + } + if len(o.CallbackURLs) == 0 || len(fmt.Sprintf("%s", o.CallbackURLs)) > 1024 { return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.callback.app_error", nil, "") } diff --git a/webapp/components/backstage/add_outgoing_webhook.jsx b/webapp/components/backstage/add_outgoing_webhook.jsx index acdd98ba8e..ff5e90e078 100644 --- a/webapp/components/backstage/add_outgoing_webhook.jsx +++ b/webapp/components/backstage/add_outgoing_webhook.jsx @@ -50,7 +50,18 @@ export default class AddOutgoingWebhook extends React.Component { clientError: '' }); - if (!this.state.channelId && !this.state.triggerWords) { + const triggerWords = []; + if (this.state.triggerWords) { + for (let triggerWord of this.state.triggerWords.split('\n')) { + triggerWord = triggerWord.trim(); + + if (triggerWord.length > 0) { + triggerWords.push(triggerWord); + } + } + } + + if (!this.state.channelId && triggerWords.length === 0) { this.setState({ saving: false, clientError: ( @@ -64,7 +75,16 @@ export default class AddOutgoingWebhook extends React.Component { return; } - if (!this.state.callbackUrls) { + const callbackUrls = []; + for (let callbackUrl of this.state.callbackUrls.split('\n')) { + callbackUrl = callbackUrl.trim(); + + if (callbackUrl.length > 0) { + callbackUrls.push(callbackUrl); + } + } + + if (callbackUrls.length === 0) { this.setState({ saving: false, clientError: ( @@ -80,8 +100,8 @@ export default class AddOutgoingWebhook extends React.Component { const hook = { channel_id: this.state.channelId, - trigger_words: this.state.triggerWords.split('\n').map((word) => word.trim()), - callback_urls: this.state.callbackUrls.split('\n').map((url) => url.trim()), + trigger_words: triggerWords, + callback_urls: callbackUrls, display_name: this.state.displayName, description: this.state.description }; diff --git a/webapp/components/backstage/installed_command.jsx b/webapp/components/backstage/installed_command.jsx index 8b56ed5950..c0c34bc78e 100644 --- a/webapp/components/backstage/installed_command.jsx +++ b/webapp/components/backstage/installed_command.jsx @@ -78,6 +78,11 @@ export default class InstalledCommand extends React.Component { ); } + let trigger = '- /' + command.trigger; + if (command.auto_complete && command.auto_complete_hint) { + trigger += ' ' + command.auto_complete_hint; + } + return (
@@ -86,7 +91,7 @@ export default class InstalledCommand extends React.Component { {name} - {'- /' + command.trigger} + {trigger}
{description} diff --git a/webapp/components/backstage/installed_commands.jsx b/webapp/components/backstage/installed_commands.jsx index ead2f98509..3527a574b2 100644 --- a/webapp/components/backstage/installed_commands.jsx +++ b/webapp/components/backstage/installed_commands.jsx @@ -74,14 +74,14 @@ export default class InstalledCommands extends React.Component { } addText={ } addLink='/settings/integrations/commands/add' diff --git a/webapp/components/backstage/installed_outgoing_webhook.jsx b/webapp/components/backstage/installed_outgoing_webhook.jsx index b8704ccef1..d27bd9029c 100644 --- a/webapp/components/backstage/installed_outgoing_webhook.jsx +++ b/webapp/components/backstage/installed_outgoing_webhook.jsx @@ -95,6 +95,23 @@ export default class InstalledOutgoingWebhook extends React.Component { ); } + let triggerWords = null; + if (outgoingWebhook.trigger_words && outgoingWebhook.trigger_words.length > 0) { + triggerWords = ( +
+ + + +
+ ); + } + return (
@@ -104,6 +121,7 @@ export default class InstalledOutgoingWebhook extends React.Component {
{description} + {triggerWords}
-
+
); } - - static matches(outgoingWebhook, filter) { - if (outgoingWebhook.display_name.toLowerCase().indexOf(filter) !== -1 || - outgoingWebhook.description.toLowerCase().indexOf(filter) !== -1) { - return true; - } - - if (outgoingWebhook.channel_id) { - const channel = ChannelStore.get(outgoingWebhook.channel_id); - - if (channel && channel.name.toLowerCase().indexOf(filter) !== -1) { - return true; - } - } - - return false; - } } diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json index 75280c5e6e..023584e1de 100644 --- a/webapp/i18n/en.json +++ b/webapp/i18n/en.json @@ -619,7 +619,7 @@ "backstage_sidebar.integrations": "Integrations", "backstage_sidebar.integrations.incoming_webhooks": "Incoming Webhooks", "backstage_sidebar.integrations.outgoing_webhooks": "Outgoing Webhooks", - "backstage_sidebar.integrations.commands": "Commands", + "backstage_sidebar.integrations.commands": "Slash Commands", "center_panel.recent": "Click here to jump to recent messages. ", "chanel_header.addMembers": "Add Members", "change_url.close": "Close", diff --git a/webapp/sass/routes/_backstage.scss b/webapp/sass/routes/_backstage.scss index f6e0a8ac02..3257f65828 100644 --- a/webapp/sass/routes/_backstage.scss +++ b/webapp/sass/routes/_backstage.scss @@ -192,6 +192,7 @@ body { } .item-details { + color: $dark-gray; flex-grow: 1; flex-shrink: 1; overflow: hidden; @@ -204,6 +205,7 @@ body { } .item-details__name { + color: black; font-weight: 600; } @@ -213,8 +215,8 @@ body { .item-details__description, .item-details__token, + .item-details__trigger-words, .item-details__creation { - color: $dark-gray; display: inline-block; margin-top: 10px; vertical-align: top; @@ -224,6 +226,10 @@ body { } } + .item-details__trigger-words { + white-space: nowrap; + } + .item-actions { flex-grow: 0; flex-shrink: 0;