mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
PLT-2553 Additional backstage UI Improvements (#2673)
* Renamed Commands to Slash Commands in backstage UI * Updated displayed info for listed commands and outgoing webhooks * Disallowed empty outgoing webhook trigger words and improved client-side validation for them
This commit is contained in:
committed by
Christopher Speller
parent
81e7e85369
commit
29e1a85360
@@ -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"
|
||||
|
||||
@@ -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, "")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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 (
|
||||
<div className='backstage-list__item'>
|
||||
<div className='item-details'>
|
||||
@@ -86,7 +91,7 @@ export default class InstalledCommand extends React.Component {
|
||||
{name}
|
||||
</span>
|
||||
<span className='item-details__trigger'>
|
||||
{'- /' + command.trigger}
|
||||
{trigger}
|
||||
</span>
|
||||
</div>
|
||||
{description}
|
||||
|
||||
@@ -74,14 +74,14 @@ export default class InstalledCommands extends React.Component {
|
||||
<InstalledIntegrations
|
||||
header={
|
||||
<FormattedMessage
|
||||
id='installed_integrations.commands'
|
||||
defaultMessage='Installed Commands'
|
||||
id='installed_commands.header'
|
||||
defaultMessage='Installed Slash Commands'
|
||||
/>
|
||||
}
|
||||
addText={
|
||||
<FormattedMessage
|
||||
id='installed_integrations.add_command'
|
||||
defaultMessage='Add Command'
|
||||
id='installed_commands.add'
|
||||
defaultMessage='Add Slash Command'
|
||||
/>
|
||||
}
|
||||
addLink='/settings/integrations/commands/add'
|
||||
|
||||
@@ -95,6 +95,23 @@ export default class InstalledOutgoingWebhook extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
let triggerWords = null;
|
||||
if (outgoingWebhook.trigger_words && outgoingWebhook.trigger_words.length > 0) {
|
||||
triggerWords = (
|
||||
<div className='item-details__row'>
|
||||
<span className='item-details__trigger-words'>
|
||||
<FormattedMessage
|
||||
id='installed_integrations.triggerWords'
|
||||
defaultMessage='Trigger Words: {triggerWords}'
|
||||
values={{
|
||||
triggerWords: outgoingWebhook.trigger_words.join(', ')
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='backstage-list__item'>
|
||||
<div className='item-details'>
|
||||
@@ -104,6 +121,7 @@ export default class InstalledOutgoingWebhook extends React.Component {
|
||||
</span>
|
||||
</div>
|
||||
{description}
|
||||
{triggerWords}
|
||||
<div className='item-details__row'>
|
||||
<span className='item-details__token'>
|
||||
<FormattedMessage
|
||||
@@ -128,7 +146,7 @@ export default class InstalledOutgoingWebhook extends React.Component {
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='actions'>
|
||||
<div className='item-actions'>
|
||||
<a
|
||||
href='#'
|
||||
onClick={this.handleRegenToken}
|
||||
@@ -152,21 +170,4 @@ export default class InstalledOutgoingWebhook extends React.Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user