mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
PLT-1750 Moved slash commands to backstage
* Added slash commands to InstalledIntegrations page * Reset installed integration type filter if there is no longer any integrations of the selected type * Added pages to backstage to add slash commands * Cleaned up internationalization for slash commands * Added ability to regen slash command tokens from backstage * Removed Integrations tab from UserSettings
This commit is contained in:
committed by
Christopher Speller
parent
c12d997f24
commit
b3edd32aee
@@ -99,7 +99,7 @@ func (o *Command) IsValid() *AppError {
|
||||
return NewLocAppError("Command.IsValid", "model.command.is_valid.team_id.app_error", nil, "")
|
||||
}
|
||||
|
||||
if len(o.Trigger) > 1024 {
|
||||
if len(o.Trigger) > 128 {
|
||||
return NewLocAppError("Command.IsValid", "model.command.is_valid.trigger.app_error", nil, "")
|
||||
}
|
||||
|
||||
|
||||
509
webapp/components/backstage/add_command.jsx
Normal file
509
webapp/components/backstage/add_command.jsx
Normal file
@@ -0,0 +1,509 @@
|
||||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import * as AsyncClient from 'utils/async_client.jsx';
|
||||
import {browserHistory} from 'react-router';
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import FormError from 'components/form_error.jsx';
|
||||
import {Link} from 'react-router';
|
||||
import SpinnerButton from 'components/spinner_button.jsx';
|
||||
|
||||
const REQUEST_POST = 'P';
|
||||
const REQUEST_GET = 'G';
|
||||
|
||||
export default class AddCommand extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
|
||||
this.updateDisplayName = this.updateDisplayName.bind(this);
|
||||
this.updateDescription = this.updateDescription.bind(this);
|
||||
this.updateTrigger = this.updateTrigger.bind(this);
|
||||
this.updateUrl = this.updateUrl.bind(this);
|
||||
this.updateMethod = this.updateMethod.bind(this);
|
||||
this.updateUsername = this.updateUsername.bind(this);
|
||||
this.updateIconUrl = this.updateIconUrl.bind(this);
|
||||
this.updateAutocomplete = this.updateAutocomplete.bind(this);
|
||||
this.updateAutocompleteHint = this.updateAutocompleteHint.bind(this);
|
||||
this.updateAutocompleteDescription = this.updateAutocompleteDescription.bind(this);
|
||||
|
||||
this.state = {
|
||||
displayName: '',
|
||||
description: '',
|
||||
trigger: '',
|
||||
url: '',
|
||||
method: REQUEST_POST,
|
||||
username: '',
|
||||
iconUrl: '',
|
||||
autocomplete: false,
|
||||
autocompleteHint: '',
|
||||
autocompleteDescription: '',
|
||||
saving: false,
|
||||
serverError: '',
|
||||
clientError: null
|
||||
};
|
||||
}
|
||||
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.state.saving) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
saving: true,
|
||||
serverError: '',
|
||||
clientError: ''
|
||||
});
|
||||
|
||||
const command = {
|
||||
display_name: this.state.displayName,
|
||||
description: this.state.description,
|
||||
trigger: this.state.trigger.trim(),
|
||||
url: this.state.url.trim(),
|
||||
method: this.state.method,
|
||||
username: this.state.username,
|
||||
icon_url: this.state.iconUrl,
|
||||
auto_complete: this.state.autocomplete
|
||||
};
|
||||
|
||||
if (command.auto_complete) {
|
||||
command.auto_complete_desc = this.state.autocompleteDescription;
|
||||
command.auto_complete_hint = this.state.autocompleteHint;
|
||||
}
|
||||
|
||||
if (!command.trigger) {
|
||||
this.setState({
|
||||
saving: false,
|
||||
clientError: (
|
||||
<FormattedMessage
|
||||
id='add_command.triggerRequired'
|
||||
defaultMessage='A trigger word is required'
|
||||
/>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
if (!command.url) {
|
||||
this.setState({
|
||||
saving: false,
|
||||
clientError: (
|
||||
<FormattedMessage
|
||||
id='add_command.urlRequired'
|
||||
defaultMessage='A request URL is required'
|
||||
/>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
AsyncClient.addCommand(
|
||||
command,
|
||||
() => {
|
||||
browserHistory.push('/settings/integrations/installed');
|
||||
},
|
||||
(err) => {
|
||||
this.setState({
|
||||
saving: false,
|
||||
serverError: err.message
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateDisplayName(e) {
|
||||
this.setState({
|
||||
displayName: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
updateDescription(e) {
|
||||
this.setState({
|
||||
description: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
updateTrigger(e) {
|
||||
this.setState({
|
||||
trigger: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
updateUrl(e) {
|
||||
this.setState({
|
||||
url: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
updateMethod(e) {
|
||||
this.setState({
|
||||
method: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
updateUsername(e) {
|
||||
this.setState({
|
||||
username: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
updateIconUrl(e) {
|
||||
this.setState({
|
||||
iconUrl: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
updateAutocomplete(e) {
|
||||
this.setState({
|
||||
autocomplete: e.target.checked
|
||||
});
|
||||
}
|
||||
|
||||
updateAutocompleteHint(e) {
|
||||
this.setState({
|
||||
autocompleteHint: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
updateAutocompleteDescription(e) {
|
||||
this.setState({
|
||||
autocompleteDescription: e.target.value
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let autocompleteFields = null;
|
||||
if (this.state.autocomplete) {
|
||||
autocompleteFields = [(
|
||||
<div
|
||||
key='autocompleteHint'
|
||||
className='form-group'
|
||||
>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='autocompleteHint'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.autocompleteHint'
|
||||
defaultMessage='Autocomplete Hint'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
id='autocompleteHint'
|
||||
type='text'
|
||||
maxLength='1024'
|
||||
className='form-control'
|
||||
value={this.state.autocompleteHint}
|
||||
onChange={this.updateAutocompleteHint}
|
||||
placeholder={Utils.localizeMessage('add_command.autocompleteHint.placeholder', 'Example: [Patient Name]')}
|
||||
/>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.autocompleteDescription.help'
|
||||
defaultMessage='Optional hint in the autocomplete list about command parameters'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
(
|
||||
<div
|
||||
key='autocompleteDescription'
|
||||
className='form-group'
|
||||
>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='autocompleteDescription'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.autocompleteDescription'
|
||||
defaultMessage='Autocomplete Description'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
id='description'
|
||||
type='text'
|
||||
maxLength='128'
|
||||
className='form-control'
|
||||
value={this.state.autocompleteDescription}
|
||||
onChange={this.updateAutocompleteDescription}
|
||||
placeholder={Utils.localizeMessage('add_command.autocompleteDescription.placeholder', 'Example: "Returns search results for patient records"')}
|
||||
/>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.autocompleteDescription.help'
|
||||
defaultMessage='Optional short description of slash command for the autocomplete list.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)];
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='backstage-content row'>
|
||||
<div className='add-command'>
|
||||
<div className='backstage-header'>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id='add_command.header'
|
||||
defaultMessage='Add Slash Command'
|
||||
/>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className='backstage-form'>
|
||||
<form className='form-horizontal'>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='displayName'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.displayName'
|
||||
defaultMessage='Display Name'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
id='displayName'
|
||||
type='text'
|
||||
maxLength='64'
|
||||
className='form-control'
|
||||
value={this.state.displayName}
|
||||
onChange={this.updateDisplayName}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='description'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.description'
|
||||
defaultMessage='Description'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
id='description'
|
||||
type='text'
|
||||
maxLength='128'
|
||||
className='form-control'
|
||||
value={this.state.description}
|
||||
onChange={this.updateDescription}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='trigger'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.trigger'
|
||||
defaultMessage='Command Trigger Word'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
id='trigger'
|
||||
type='text'
|
||||
maxLength='128'
|
||||
className='form-control'
|
||||
value={this.state.trigger}
|
||||
onChange={this.updateTrigger}
|
||||
placeholder={Utils.localizeMessage('add_command.trigger.placeholder', 'Command trigger e.g. "hello" not including the slash')}
|
||||
/>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.trigger.help1'
|
||||
defaultMessage='Examples: /patient, /client /employee'
|
||||
/>
|
||||
</div>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.trigger.help2'
|
||||
defaultMessage='Reserved: /echo, /join, /logout, /me, /shrug'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='url'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.url'
|
||||
defaultMessage='Request URL'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
id='url'
|
||||
type='text'
|
||||
maxLength='1024'
|
||||
className='form-control'
|
||||
value={this.state.url}
|
||||
onChange={this.updateUrl}
|
||||
placeholder={Utils.localizeMessage('add_command.url.placeholder', 'Must start with http:// or https://')}
|
||||
/>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.url.help'
|
||||
defaultMessage='The callback URL to receive the HTTP POST or GET event request when the slash command is run.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='method'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.method'
|
||||
defaultMessage='Request Method'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<select
|
||||
id='method'
|
||||
className='form-control'
|
||||
value={this.state.method}
|
||||
onChange={this.updateMethod}
|
||||
>
|
||||
<option value={REQUEST_POST}>
|
||||
{Utils.localizeMessage('add_command.method.post', 'POST')}
|
||||
</option>
|
||||
<option value={REQUEST_GET}>
|
||||
{Utils.localizeMessage('add_command.method.get', 'GET')}
|
||||
</option>
|
||||
</select>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.method.help'
|
||||
defaultMessage='The type of command request issued to the Request URL.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-lavel col-sm-3'
|
||||
htmlFor='username'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.username'
|
||||
defaultMessage='Response Username'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
id='username'
|
||||
type='text'
|
||||
maxLength='64'
|
||||
className='form-control'
|
||||
value={this.state.username}
|
||||
onChange={this.updateUsername}
|
||||
placholder={Utils.localizeMessage('add_command.username.placeholder', 'Username')}
|
||||
/>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.username.help'
|
||||
defaultMessage='Choose a username override for responses for this slash command. Usernames can consist of up to 22 characters consisting of lowercase letters, numbers and the symbols "-", "_", and ".".'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='iconUrl'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.iconUrl'
|
||||
defaultMessage='Response Icon'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
id='iconUrl'
|
||||
type='text'
|
||||
maxLength='1024'
|
||||
className='form-control'
|
||||
value={this.state.iconUrl}
|
||||
onChange={this.updateIconUrl}
|
||||
placeholder={Utils.localizeMessage('add_command.iconUrl.placeholder', 'https://www.example.com/myicon.png')}
|
||||
/>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.iconUrl.help'
|
||||
defaultMessage='Choose a profile picture override for the post responses to this slash command. Enter the URL of a .png or .jpg file at least 128 pixels by 128 pixels.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-3'
|
||||
htmlFor='autocomplete'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.autocomplete'
|
||||
defaultMessage='Autocomplete'
|
||||
/>
|
||||
</label>
|
||||
<div className='col-md-5 col-sm-9'>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={this.state.autocomplete}
|
||||
onChange={this.updateAutocomplete}
|
||||
/>
|
||||
<div className='add-integration__help'>
|
||||
<FormattedMessage
|
||||
id='add_command.autocomplete.help'
|
||||
defaultMessage='Show this command in the autocomplete list'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{autocompleteFields}
|
||||
<div className='backstage-form__footer'>
|
||||
<FormError errors={[this.state.serverError, this.state.clientError]}/>
|
||||
<Link
|
||||
className='btn btn-sm'
|
||||
to={'/settings/integrations/add'}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.cancel'
|
||||
defaultMessage='Cancel'
|
||||
/>
|
||||
</Link>
|
||||
<SpinnerButton
|
||||
className='btn btn-primary'
|
||||
type='submit'
|
||||
spinning={this.state.saving}
|
||||
onClick={this.handleSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='add_command.save'
|
||||
defaultMessage='Save'
|
||||
/>
|
||||
</SpinnerButton>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,28 @@ export default class AddIntegration extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (window.mm_config.EnableCommands === 'true') {
|
||||
options.push(
|
||||
<AddIntegrationOption
|
||||
key='command'
|
||||
image={WebhookIcon}
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='add_integration.command.title'
|
||||
defaultMessage='Slash Command'
|
||||
/>
|
||||
}
|
||||
description={
|
||||
<FormattedMessage
|
||||
id='add_integration.command.description'
|
||||
defaultMessage='Create slash commands to send events to external integrations and receive a response.'
|
||||
/>
|
||||
}
|
||||
link={'/settings/integrations/add/command'}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='backstage-content row'>
|
||||
<div className='backstage-header'>
|
||||
|
||||
@@ -59,6 +59,15 @@ export default class BackstageSidebar extends React.Component {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<BackstageSection
|
||||
name='command'
|
||||
title={(
|
||||
<FormattedMessage
|
||||
id='backstage_sidebar.integrations.add.command'
|
||||
defaultMessage='Slash Command'
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</BackstageSection>
|
||||
</BackstageCategory>
|
||||
</ul>
|
||||
|
||||
97
webapp/components/backstage/installed_command.jsx
Normal file
97
webapp/components/backstage/installed_command.jsx
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
export default class InstalledCommand extends React.Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
command: React.PropTypes.object.isRequired,
|
||||
onRegenToken: React.PropTypes.func.isRequired,
|
||||
onDelete: React.PropTypes.func.isRequired
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleRegenToken = this.handleRegenToken.bind(this);
|
||||
this.handleDelete = this.handleDelete.bind(this);
|
||||
}
|
||||
|
||||
handleRegenToken(e) {
|
||||
e.preventDefault();
|
||||
|
||||
this.props.onRegenToken(this.props.command);
|
||||
}
|
||||
|
||||
handleDelete(e) {
|
||||
e.preventDefault();
|
||||
|
||||
this.props.onDelete(this.props.command);
|
||||
}
|
||||
|
||||
render() {
|
||||
const command = this.props.command;
|
||||
|
||||
return (
|
||||
<div className='backstage-list__item'>
|
||||
<div className='item-details'>
|
||||
<div className='item-details__row'>
|
||||
<span className='item-details__name'>
|
||||
{command.display_name}
|
||||
</span>
|
||||
<span className='item-details__type'>
|
||||
<FormattedMessage
|
||||
id='installed_integrations.commandType'
|
||||
defaultMessage='(Slash Command)'
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div className='item-details__row'>
|
||||
<span className='item-details__description'>
|
||||
{command.description}
|
||||
</span>
|
||||
</div>
|
||||
<div className='item-details__row'>
|
||||
<span className='item-details__creation'>
|
||||
<FormattedMessage
|
||||
id='installed_integrations.creation'
|
||||
defaultMessage='Created by {creator} on {createAt, date, full}'
|
||||
values={{
|
||||
creator: Utils.displayUsername(command.creator_Id),
|
||||
createAt: command.create_at
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='item-actions'>
|
||||
<a
|
||||
href='#'
|
||||
onClick={this.handleRegenToken}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='installed_integrations.regenToken'
|
||||
defaultMessage='Regen Token'
|
||||
/>
|
||||
</a>
|
||||
{' - '}
|
||||
<a
|
||||
href='#'
|
||||
onClick={this.handleDelete}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='installed_integrations.delete'
|
||||
defaultMessage='Delete'
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,20 +12,20 @@ export default class InstalledIncomingWebhook extends React.Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
incomingWebhook: React.PropTypes.object.isRequired,
|
||||
onDeleteClick: React.PropTypes.func.isRequired
|
||||
onDelete: React.PropTypes.func.isRequired
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleDeleteClick = this.handleDeleteClick.bind(this);
|
||||
this.handleDelete = this.handleDelete.bind(this);
|
||||
}
|
||||
|
||||
handleDeleteClick(e) {
|
||||
handleDelete(e) {
|
||||
e.preventDefault();
|
||||
|
||||
this.props.onDeleteClick(this.props.incomingWebhook);
|
||||
this.props.onDelete(this.props.incomingWebhook);
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -69,7 +69,7 @@ export default class InstalledIncomingWebhook extends React.Component {
|
||||
<div className='item-actions'>
|
||||
<a
|
||||
href='#'
|
||||
onClick={this.handleDeleteClick}
|
||||
onClick={this.handleDelete}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='installed_integrations.delete'
|
||||
|
||||
@@ -11,6 +11,7 @@ import * as Utils from 'utils/utils.jsx';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import InstalledIncomingWebhook from './installed_incoming_webhook.jsx';
|
||||
import InstalledOutgoingWebhook from './installed_outgoing_webhook.jsx';
|
||||
import InstalledCommand from './installed_command.jsx';
|
||||
import {Link} from 'react-router';
|
||||
|
||||
export default class InstalledIntegrations extends React.Component {
|
||||
@@ -24,10 +25,13 @@ export default class InstalledIntegrations extends React.Component {
|
||||
this.deleteIncomingWebhook = this.deleteIncomingWebhook.bind(this);
|
||||
this.regenOutgoingWebhookToken = this.regenOutgoingWebhookToken.bind(this);
|
||||
this.deleteOutgoingWebhook = this.deleteOutgoingWebhook.bind(this);
|
||||
this.regenCommandToken = this.regenCommandToken.bind(this);
|
||||
this.deleteCommand = this.deleteCommand.bind(this);
|
||||
|
||||
this.state = {
|
||||
incomingWebhooks: [],
|
||||
outgoingWebhooks: [],
|
||||
commands: [],
|
||||
typeFilter: '',
|
||||
filter: ''
|
||||
};
|
||||
@@ -55,6 +59,16 @@ export default class InstalledIntegrations extends React.Component {
|
||||
AsyncClient.listOutgoingHooks();
|
||||
}
|
||||
}
|
||||
|
||||
if (window.mm_config.EnableCommands === 'true') {
|
||||
if (IntegrationStore.hasReceivedCommands()) {
|
||||
this.setState({
|
||||
commands: IntegrationStore.getCommands()
|
||||
});
|
||||
} else {
|
||||
AsyncClient.listTeamCommands();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -62,10 +76,24 @@ export default class InstalledIntegrations extends React.Component {
|
||||
}
|
||||
|
||||
handleIntegrationChange() {
|
||||
const incomingWebhooks = IntegrationStore.getIncomingWebhooks();
|
||||
const outgoingWebhooks = IntegrationStore.getOutgoingWebhooks();
|
||||
const commands = IntegrationStore.getCommands();
|
||||
|
||||
this.setState({
|
||||
incomingWebhooks: IntegrationStore.getIncomingWebhooks(),
|
||||
outgoingWebhooks: IntegrationStore.getOutgoingWebhooks()
|
||||
incomingWebhooks,
|
||||
outgoingWebhooks,
|
||||
commands
|
||||
});
|
||||
|
||||
// reset the type filter if we were viewing a category that is now empty
|
||||
if ((this.state.typeFilter === 'incomingWebhooks' && incomingWebhooks.length === 0) ||
|
||||
(this.state.typeFilter === 'outgoingWebhooks' && outgoingWebhooks.length === 0) ||
|
||||
(this.state.typeFilter === 'commands' && commands.length === 0)) {
|
||||
this.setState({
|
||||
typeFilter: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
updateTypeFilter(e, typeFilter) {
|
||||
@@ -94,10 +122,18 @@ export default class InstalledIntegrations extends React.Component {
|
||||
AsyncClient.deleteOutgoingHook(outgoingWebhook.id);
|
||||
}
|
||||
|
||||
renderTypeFilters(incomingWebhooks, outgoingWebhooks) {
|
||||
regenCommandToken(command) {
|
||||
AsyncClient.regenCommandToken(command.id);
|
||||
}
|
||||
|
||||
deleteCommand(command) {
|
||||
AsyncClient.deleteCommand(command.id);
|
||||
}
|
||||
|
||||
renderTypeFilters(incomingWebhooks, outgoingWebhooks, commands) {
|
||||
const fields = [];
|
||||
|
||||
if (incomingWebhooks.length > 0 || outgoingWebhooks.length > 0) {
|
||||
if (incomingWebhooks.length > 0 || outgoingWebhooks.length > 0 || commands.length > 0) {
|
||||
let filterClassName = 'filter-sort';
|
||||
if (this.state.typeFilter === '') {
|
||||
filterClassName += ' filter-sort--active';
|
||||
@@ -187,6 +223,39 @@ export default class InstalledIntegrations extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (commands.length > 0) {
|
||||
fields.push(
|
||||
<span
|
||||
key='commandsDivider'
|
||||
className='divider'
|
||||
>
|
||||
{'|'}
|
||||
</span>
|
||||
);
|
||||
|
||||
let filterClassName = 'filter-sort';
|
||||
if (this.state.typeFilter === 'commands') {
|
||||
filterClassName += ' filter-sort--active';
|
||||
}
|
||||
|
||||
fields.push(
|
||||
<a
|
||||
key='commandsFilter'
|
||||
className={filterClassName}
|
||||
href='#'
|
||||
onClick={(e) => this.updateTypeFilter(e, 'commands')}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='installed_integrations.commandsFilter'
|
||||
defaultMessage='Slash Commands ({count})'
|
||||
values={{
|
||||
count: commands.length
|
||||
}}
|
||||
/>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='backstage-filters__sort'>
|
||||
{fields}
|
||||
@@ -197,7 +266,9 @@ export default class InstalledIntegrations extends React.Component {
|
||||
render() {
|
||||
const incomingWebhooks = this.state.incomingWebhooks;
|
||||
const outgoingWebhooks = this.state.outgoingWebhooks;
|
||||
const commands = this.state.commands;
|
||||
|
||||
// TODO description, name, creator filtering
|
||||
const filter = this.state.filter.toLowerCase();
|
||||
|
||||
const integrations = [];
|
||||
@@ -215,7 +286,7 @@ export default class InstalledIntegrations extends React.Component {
|
||||
<InstalledIncomingWebhook
|
||||
key={incomingWebhook.id}
|
||||
incomingWebhook={incomingWebhook}
|
||||
onDeleteClick={this.deleteIncomingWebhook}
|
||||
onDelete={this.deleteIncomingWebhook}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -242,6 +313,27 @@ export default class InstalledIntegrations extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.state.typeFilter || this.state.typeFilter === 'commands') {
|
||||
for (const command of commands) {
|
||||
if (filter) {
|
||||
const channel = ChannelStore.get(command.channel_id);
|
||||
|
||||
if (!channel || channel.name.toLowerCase().indexOf(filter) === -1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
integrations.push(
|
||||
<InstalledCommand
|
||||
key={command.id}
|
||||
command={command}
|
||||
onRegenToken={this.regenCommandToken}
|
||||
onDelete={this.deleteCommand}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='backstage-content row'>
|
||||
<div className='installed-integrations'>
|
||||
@@ -270,7 +362,7 @@ export default class InstalledIntegrations extends React.Component {
|
||||
</Link>
|
||||
</div>
|
||||
<div className='backstage-filters'>
|
||||
{this.renderTypeFilters(this.state.incomingWebhooks, this.state.outgoingWebhooks)}
|
||||
{this.renderTypeFilters(incomingWebhooks, outgoingWebhooks, commands)}
|
||||
<div className='backstage-filter__search'>
|
||||
<i className='fa fa-search'></i>
|
||||
<input
|
||||
|
||||
@@ -1,681 +0,0 @@
|
||||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import LoadingScreen from '../loading_screen.jsx';
|
||||
|
||||
import * as Client from 'utils/client.jsx';
|
||||
|
||||
import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl';
|
||||
|
||||
const holders = defineMessages({
|
||||
requestTypePost: {
|
||||
id: 'user.settings.cmds.request_type_post',
|
||||
defaultMessage: 'POST'
|
||||
},
|
||||
requestTypeGet: {
|
||||
id: 'user.settings.cmds.request_type_get',
|
||||
defaultMessage: 'GET'
|
||||
},
|
||||
addDisplayNamePlaceholder: {
|
||||
id: 'user.settings.cmds.add_display_name.placeholder',
|
||||
defaultMessage: 'Example: "Search patient records"'
|
||||
},
|
||||
addUsernamePlaceholder: {
|
||||
id: 'user.settings.cmds.add_username.placeholder',
|
||||
defaultMessage: 'Username'
|
||||
},
|
||||
addTriggerPlaceholder: {
|
||||
id: 'user.settings.cmds.add_trigger.placeholder',
|
||||
defaultMessage: 'Command trigger e.g. "hello" not including the slash'
|
||||
},
|
||||
addAutoCompleteDescPlaceholder: {
|
||||
id: 'user.settings.cmds.auto_complete_desc.placeholder',
|
||||
defaultMessage: 'Example: "Returns search results for patient records"'
|
||||
},
|
||||
addAutoCompleteHintPlaceholder: {
|
||||
id: 'user.settings.cmds.auto_complete_hint.placeholder',
|
||||
defaultMessage: 'Example: [Patient Name]'
|
||||
},
|
||||
adUrlPlaceholder: {
|
||||
id: 'user.settings.cmds.url.placeholder',
|
||||
defaultMessage: 'Must start with http:// or https://'
|
||||
},
|
||||
autocompleteYes: {
|
||||
id: 'user.settings.cmds.auto_complete.yes',
|
||||
defaultMessage: 'yes'
|
||||
},
|
||||
autocompleteNo: {
|
||||
id: 'user.settings.cmds.auto_complete.no',
|
||||
defaultMessage: 'no'
|
||||
}
|
||||
});
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default class ManageCommandCmds extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.getCmds = this.getCmds.bind(this);
|
||||
this.addNewCmd = this.addNewCmd.bind(this);
|
||||
this.emptyCmd = this.emptyCmd.bind(this);
|
||||
this.updateTrigger = this.updateTrigger.bind(this);
|
||||
this.updateURL = this.updateURL.bind(this);
|
||||
this.updateMethod = this.updateMethod.bind(this);
|
||||
this.updateUsername = this.updateUsername.bind(this);
|
||||
this.updateIconURL = this.updateIconURL.bind(this);
|
||||
this.updateDisplayName = this.updateDisplayName.bind(this);
|
||||
this.updateAutoComplete = this.updateAutoComplete.bind(this);
|
||||
this.updateAutoCompleteDesc = this.updateAutoCompleteDesc.bind(this);
|
||||
this.updateAutoCompleteHint = this.updateAutoCompleteHint.bind(this);
|
||||
|
||||
this.state = {cmds: [], cmd: this.emptyCmd(), getCmdsComplete: false};
|
||||
}
|
||||
|
||||
static propTypes() {
|
||||
return {
|
||||
intl: intlShape.isRequired
|
||||
};
|
||||
}
|
||||
|
||||
emptyCmd() {
|
||||
var cmd = {};
|
||||
cmd.url = '';
|
||||
cmd.trigger = '';
|
||||
cmd.method = 'P';
|
||||
cmd.username = '';
|
||||
cmd.icon_url = '';
|
||||
cmd.auto_complete = false;
|
||||
cmd.auto_complete_desc = '';
|
||||
cmd.auto_complete_hint = '';
|
||||
cmd.display_name = '';
|
||||
return cmd;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getCmds();
|
||||
}
|
||||
|
||||
addNewCmd(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.state.cmd.trigger === '' || this.state.cmd.url === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
var cmd = this.state.cmd;
|
||||
if (cmd.trigger.length !== 0) {
|
||||
cmd.trigger = cmd.trigger.trim();
|
||||
}
|
||||
cmd.url = cmd.url.trim();
|
||||
|
||||
Client.addCommand(
|
||||
cmd,
|
||||
(data) => {
|
||||
let cmds = Object.assign([], this.state.cmds);
|
||||
if (!cmds) {
|
||||
cmds = [];
|
||||
}
|
||||
cmds.push(data);
|
||||
this.setState({cmds, addError: null, cmd: this.emptyCmd()});
|
||||
},
|
||||
(err) => {
|
||||
this.setState({addError: err.message});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
removeCmd(id) {
|
||||
const data = {};
|
||||
data.id = id;
|
||||
|
||||
Client.deleteCommand(
|
||||
data,
|
||||
() => {
|
||||
const cmds = this.state.cmds;
|
||||
let index = -1;
|
||||
for (let i = 0; i < cmds.length; i++) {
|
||||
if (cmds[i].id === id) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index !== -1) {
|
||||
cmds.splice(index, 1);
|
||||
}
|
||||
|
||||
this.setState({cmds});
|
||||
},
|
||||
(err) => {
|
||||
this.setState({editError: err.message});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
regenToken(id) {
|
||||
const regenData = {};
|
||||
regenData.id = id;
|
||||
|
||||
Client.regenCommandToken(
|
||||
regenData,
|
||||
(data) => {
|
||||
const cmds = Object.assign([], this.state.cmds);
|
||||
for (let i = 0; i < cmds.length; i++) {
|
||||
if (cmds[i].id === id) {
|
||||
cmds[i] = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({cmds, editError: null});
|
||||
},
|
||||
(err) => {
|
||||
this.setState({editError: err.message});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
getCmds() {
|
||||
Client.listTeamCommands(
|
||||
(data) => {
|
||||
if (data) {
|
||||
this.setState({cmds: data, getCmdsComplete: true, editError: null});
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
this.setState({editError: err.message});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateTrigger(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.trigger = e.target.value;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateURL(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.url = e.target.value;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateMethod(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.method = e.target.value;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateUsername(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.username = e.target.value;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateIconURL(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.icon_url = e.target.value;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateDisplayName(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.display_name = e.target.value;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateAutoComplete(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.auto_complete = e.target.checked;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateAutoCompleteDesc(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.auto_complete_desc = e.target.value;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateAutoCompleteHint(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.auto_complete_hint = e.target.value;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
render() {
|
||||
let addError;
|
||||
if (this.state.addError) {
|
||||
addError = <label className='has-error'>{this.state.addError}</label>;
|
||||
}
|
||||
|
||||
let editError;
|
||||
if (this.state.editError) {
|
||||
addError = <label className='has-error'>{this.state.editError}</label>;
|
||||
}
|
||||
|
||||
const cmds = [];
|
||||
this.state.cmds.forEach((cmd) => {
|
||||
let triggerDiv;
|
||||
if (cmd.trigger && cmd.trigger.length !== 0) {
|
||||
triggerDiv = (
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.trigger'
|
||||
defaultMessage='Command Trigger Word: '
|
||||
/>
|
||||
</strong>{cmd.trigger}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
cmds.push(
|
||||
<div
|
||||
key={cmd.id}
|
||||
className='webhook__item webcmd__item'
|
||||
>
|
||||
{triggerDiv}
|
||||
<div className='padding-top x2 webcmd__url'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.url'
|
||||
defaultMessage='Request URL: '
|
||||
/>
|
||||
</strong><span className='word-break--all'>{cmd.url}</span>
|
||||
</div>
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.request_type'
|
||||
defaultMessage='Request Method: '
|
||||
/>
|
||||
</strong>
|
||||
<span className='word-break--all'>
|
||||
{
|
||||
cmd.method === 'P' ?
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.request_type_post'
|
||||
defaultMessage='POST'
|
||||
/> :
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.request_type_get'
|
||||
defaultMessage='GET'
|
||||
/>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.username'
|
||||
defaultMessage='Response Username: '
|
||||
/>
|
||||
</strong><span className='word-break--all'>{cmd.username}</span>
|
||||
</div>
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.icon_url'
|
||||
defaultMessage='Response Icon: '
|
||||
/>
|
||||
</strong><span className='word-break--all'>{cmd.icon_url}</span>
|
||||
</div>
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete'
|
||||
defaultMessage='Autocomplete: '
|
||||
/>
|
||||
</strong><span className='word-break--all'>{cmd.auto_complete ? this.props.intl.formatMessage(holders.autocompleteYes) : this.props.intl.formatMessage(holders.autocompleteNo)}</span>
|
||||
</div>
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_hint'
|
||||
defaultMessage='Autocomplete Hint: '
|
||||
/>
|
||||
</strong><span className='word-break--all'>{cmd.auto_complete_hint}</span>
|
||||
</div>
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_desc'
|
||||
defaultMessage='Autocomplete Description: '
|
||||
/>
|
||||
</strong><span className='word-break--all'>{cmd.auto_complete_desc}</span>
|
||||
</div>
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.display_name'
|
||||
defaultMessage='Descriptive Label: '
|
||||
/>
|
||||
</strong><span className='word-break--all'>{cmd.display_name}</span>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.token'
|
||||
defaultMessage='Token: '
|
||||
/>
|
||||
</strong>{cmd.token}
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<a
|
||||
className='text-danger'
|
||||
href='#'
|
||||
onClick={this.regenToken.bind(this, cmd.id)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.regen'
|
||||
defaultMessage='Regen Token'
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
className='webhook__remove webcmd__remove'
|
||||
href='#'
|
||||
onClick={this.removeCmd.bind(this, cmd.id)}
|
||||
>
|
||||
<span aria-hidden='true'>{'×'}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className='padding-top x2 divider-light'></div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
let displayCmds;
|
||||
if (!this.state.getCmdsComplete) {
|
||||
displayCmds = <LoadingScreen/>;
|
||||
} else if (cmds.length > 0) {
|
||||
displayCmds = cmds;
|
||||
} else {
|
||||
displayCmds = (
|
||||
<div className='padding-top x2'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.none'
|
||||
defaultMessage='None'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const existingCmds = (
|
||||
<div className='webhooks__container webcmds__container'>
|
||||
<label className='control-label padding-top x2'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.existing'
|
||||
defaultMessage='Existing commands'
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top divider-light'></div>
|
||||
<div className='webhooks__list webcmds__list'>
|
||||
{displayCmds}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const disableButton = this.state.cmd.trigger === '' || this.state.cmd.url === '';
|
||||
|
||||
return (
|
||||
<div key='addCommandCmd'>
|
||||
<FormattedHTMLMessage
|
||||
id='user.settings.cmds.add_desc'
|
||||
defaultMessage='Create slash commands to send events to external integrations and receive a response. For example typing `/patient Joe Smith` could bring back search results from your internal health records management system for the name “Joe Smith”. Please see <a href="http://docs.mattermost.com/developer/slash-commands.html">Slash commands documentation</a> for detailed instructions. View all slash commands configured on this team below.'
|
||||
/>
|
||||
<div><label className='control-label padding-top x2'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.add_new'
|
||||
defaultMessage='Add a new command'
|
||||
/>
|
||||
</label></div>
|
||||
<div className='padding-top divider-light'></div>
|
||||
<div className='padding-top'>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.trigger'
|
||||
defaultMessage='Command Trigger Word: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='trigger'
|
||||
className='form-control'
|
||||
value={this.state.cmd.trigger}
|
||||
onChange={this.updateTrigger}
|
||||
placeholder={this.props.intl.formatMessage(holders.addTriggerPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.trigger_desc'
|
||||
defaultMessage='Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.url'
|
||||
defaultMessage='Request URL: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='URL'
|
||||
className='form-control'
|
||||
value={this.state.cmd.url}
|
||||
rows={1}
|
||||
onChange={this.updateURL}
|
||||
placeholder={this.props.intl.formatMessage(holders.adUrlPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.url_desc'
|
||||
defaultMessage='The callback URL to receive the HTTP POST or GET event request when the slash command is run.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.request_type'
|
||||
defaultMessage='Request Method: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<select
|
||||
ref='method'
|
||||
className='form-control'
|
||||
value={this.state.cmd.method}
|
||||
onChange={this.updateMethod}
|
||||
>
|
||||
<option value='P'>
|
||||
{this.props.intl.formatMessage(holders.requestTypePost)}
|
||||
</option>
|
||||
<option value='G'>
|
||||
{this.props.intl.formatMessage(holders.requestTypeGet)}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.request_type_desc'
|
||||
defaultMessage='The type of command request issued to the Request URL.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.username'
|
||||
defaultMessage='Response Username: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='username'
|
||||
className='form-control'
|
||||
value={this.state.cmd.username}
|
||||
onChange={this.updateUsername}
|
||||
placeholder={this.props.intl.formatMessage(holders.addUsernamePlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.username_desc'
|
||||
defaultMessage='Choose a username override for responses for this slash command. Usernames can consist of up to 22 characters consisting of lowercase letters, numbers and they symbols "-", "_", and "." .'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.icon_url'
|
||||
defaultMessage='Response Icon: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='iconURL'
|
||||
className='form-control'
|
||||
value={this.state.cmd.icon_url}
|
||||
onChange={this.updateIconURL}
|
||||
placeholder='https://www.example.com/myicon.png'
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.icon_url_desc'
|
||||
defaultMessage='Choose a profile picture override for the post responses to this slash command. Enter the URL of a .png or .jpg file at least 128 pixels by 128 pixels.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete'
|
||||
defaultMessage='Autocomplete: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<div className='checkbox'>
|
||||
<label>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={this.state.cmd.auto_complete}
|
||||
onChange={this.updateAutoComplete}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_help'
|
||||
defaultMessage=' Show this command in the autocomplete list.'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_hint'
|
||||
defaultMessage='Autocomplete Hint: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='autoCompleteHint'
|
||||
className='form-control'
|
||||
value={this.state.cmd.auto_complete_hint}
|
||||
onChange={this.updateAutoCompleteHint}
|
||||
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteHintPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_hint_desc'
|
||||
defaultMessage='Optional hint in the autocomplete list about parameters needed for command.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_desc'
|
||||
defaultMessage='Autocomplete Description: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='autoCompleteDesc'
|
||||
className='form-control'
|
||||
value={this.state.cmd.auto_complete_desc}
|
||||
onChange={this.updateAutoCompleteDesc}
|
||||
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteDescPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_desc_desc'
|
||||
defaultMessage='Optional short description of slash command for the autocomplete list.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.display_name'
|
||||
defaultMessage='Descriptive Label: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='displayName'
|
||||
className='form-control'
|
||||
value={this.state.cmd.display_name}
|
||||
onChange={this.updateDisplayName}
|
||||
placeholder={this.props.intl.formatMessage(holders.addDisplayNamePlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.cmd_display_name'
|
||||
defaultMessage='Brief description of slash command to show in listings.'
|
||||
/>
|
||||
</div>
|
||||
{addError}
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2 padding-bottom'>
|
||||
<a
|
||||
className={'btn btn-sm btn-primary'}
|
||||
href='#'
|
||||
disabled={disableButton}
|
||||
onClick={this.addNewCmd}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.add'
|
||||
defaultMessage='Add'
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{existingCmds}
|
||||
{editError}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(ManageCommandCmds);
|
||||
@@ -7,7 +7,6 @@ import NotificationsTab from './user_settings_notifications.jsx';
|
||||
import SecurityTab from './user_settings_security.jsx';
|
||||
import GeneralTab from './user_settings_general.jsx';
|
||||
import DeveloperTab from './user_settings_developer.jsx';
|
||||
import IntegrationsTab from './user_settings_integrations.jsx';
|
||||
import DisplayTab from './user_settings_display.jsx';
|
||||
import AdvancedTab from './user_settings_advanced.jsx';
|
||||
|
||||
@@ -98,20 +97,6 @@ export default class UserSettings extends React.Component {
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.activeTab === 'integrations') {
|
||||
return (
|
||||
<div>
|
||||
<IntegrationsTab
|
||||
ref='activeTab'
|
||||
user={this.state.user}
|
||||
activeSection={this.props.activeSection}
|
||||
updateSection={this.props.updateSection}
|
||||
updateTab={this.props.updateTab}
|
||||
closeModal={this.props.closeModal}
|
||||
collapseModal={this.props.collapseModal}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.activeTab === 'display') {
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import $ from 'jquery';
|
||||
import SettingItemMin from '../setting_item_min.jsx';
|
||||
import SettingItemMax from '../setting_item_max.jsx';
|
||||
import ManageCommandHooks from './manage_command_hooks.jsx';
|
||||
|
||||
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl';
|
||||
|
||||
const holders = defineMessages({
|
||||
cmdName: {
|
||||
id: 'user.settings.integrations.commands',
|
||||
defaultMessage: 'Slash Commands'
|
||||
},
|
||||
cmdDesc: {
|
||||
id: 'user.settings.integrations.commandsDescription',
|
||||
defaultMessage: 'Manage your slash commands'
|
||||
}
|
||||
});
|
||||
|
||||
import React from 'react';
|
||||
|
||||
class UserSettingsIntegrationsTab extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.updateSection = this.updateSection.bind(this);
|
||||
|
||||
this.state = {};
|
||||
}
|
||||
updateSection(section) {
|
||||
$('.settings-modal .modal-body').scrollTop(0).perfectScrollbar('update');
|
||||
this.props.updateSection(section);
|
||||
}
|
||||
render() {
|
||||
let commandHooksSection;
|
||||
var inputs = [];
|
||||
const {formatMessage} = this.props.intl;
|
||||
|
||||
if (global.window.mm_config.EnableCommands === 'true') {
|
||||
if (this.props.activeSection === 'command-hooks') {
|
||||
inputs.push(
|
||||
<ManageCommandHooks key='command-hook-ui'/>
|
||||
);
|
||||
|
||||
commandHooksSection = (
|
||||
<SettingItemMax
|
||||
title={formatMessage(holders.cmdName)}
|
||||
width='medium'
|
||||
inputs={inputs}
|
||||
updateSection={(e) => {
|
||||
this.updateSection('');
|
||||
e.preventDefault();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
commandHooksSection = (
|
||||
<SettingItemMin
|
||||
title={formatMessage(holders.cmdName)}
|
||||
width='medium'
|
||||
describe={formatMessage(holders.cmdDesc)}
|
||||
updateSection={() => {
|
||||
this.updateSection('command-hooks');
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='modal-header'>
|
||||
<button
|
||||
type='button'
|
||||
className='close'
|
||||
data-dismiss='modal'
|
||||
aria-label='Close'
|
||||
onClick={this.props.closeModal}
|
||||
>
|
||||
<span aria-hidden='true'>{'×'}</span>
|
||||
</button>
|
||||
<h4
|
||||
className='modal-title'
|
||||
ref='title'
|
||||
>
|
||||
<div className='modal-back'>
|
||||
<i
|
||||
className='fa fa-angle-left'
|
||||
onClick={this.props.collapseModal}
|
||||
/>
|
||||
</div>
|
||||
<FormattedMessage
|
||||
id='user.settings.integrations.title'
|
||||
defaultMessage='Integration Settings'
|
||||
/>
|
||||
</h4>
|
||||
</div>
|
||||
<div className='user-settings'>
|
||||
<h3 className='tab-header'>
|
||||
<FormattedMessage
|
||||
id='user.settings.integrations.title'
|
||||
defaultMessage='Integration Settings'
|
||||
/>
|
||||
</h3>
|
||||
<div className='divider-dark first'/>
|
||||
{commandHooksSection}
|
||||
<div className='divider-dark'/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UserSettingsIntegrationsTab.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
user: React.PropTypes.object,
|
||||
updateSection: React.PropTypes.func,
|
||||
updateTab: React.PropTypes.func,
|
||||
activeSection: React.PropTypes.string,
|
||||
closeModal: React.PropTypes.func.isRequired,
|
||||
collapseModal: React.PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default injectIntl(UserSettingsIntegrationsTab);
|
||||
@@ -31,10 +31,6 @@ const holders = defineMessages({
|
||||
id: 'user.settings.modal.developer',
|
||||
defaultMessage: 'Developer'
|
||||
},
|
||||
integrations: {
|
||||
id: 'user.settings.modal.integrations',
|
||||
defaultMessage: 'Integrations'
|
||||
},
|
||||
display: {
|
||||
id: 'user.settings.modal.display',
|
||||
defaultMessage: 'Display'
|
||||
@@ -227,7 +223,6 @@ class UserSettingsModal extends React.Component {
|
||||
if (this.state.currentUser == null) {
|
||||
return (<div/>);
|
||||
}
|
||||
var isAdmin = Utils.isAdmin(this.state.currentUser.roles);
|
||||
var tabs = [];
|
||||
|
||||
tabs.push({name: 'general', uiName: formatMessage(holders.general), icon: 'glyphicon glyphicon-cog'});
|
||||
@@ -237,18 +232,6 @@ class UserSettingsModal extends React.Component {
|
||||
tabs.push({name: 'developer', uiName: formatMessage(holders.developer), icon: 'glyphicon glyphicon-th'});
|
||||
}
|
||||
|
||||
if (global.window.mm_config.EnableIncomingWebhooks === 'true' || global.window.mm_config.EnableOutgoingWebhooks === 'true' || global.window.mm_config.EnableCommands === 'true') {
|
||||
var show = global.window.mm_config.EnableOnlyAdminIntegrations !== 'true';
|
||||
|
||||
if (global.window.mm_config.EnableOnlyAdminIntegrations === 'true' && isAdmin) {
|
||||
show = true;
|
||||
}
|
||||
|
||||
if (show) {
|
||||
tabs.push({name: 'integrations', uiName: formatMessage(holders.integrations), icon: 'glyphicon glyphicon-transfer'});
|
||||
}
|
||||
}
|
||||
|
||||
tabs.push({name: 'display', uiName: formatMessage(holders.display), icon: 'glyphicon glyphicon-eye-open'});
|
||||
tabs.push({name: 'advanced', uiName: formatMessage(holders.advanced), icon: 'glyphicon glyphicon-list-alt'});
|
||||
|
||||
|
||||
@@ -27,6 +27,36 @@
|
||||
"activity_log_modal.android": "Android",
|
||||
"activity_log_modal.androidNativeApp": "Android Native App",
|
||||
"activity_log_modal.iphoneNativeApp": "iPhone Native App",
|
||||
"add_command.autocomplete": "Autocomplete",
|
||||
"add_command.autocomplete.help": " Show this command in the autocomplete list.",
|
||||
"add_command.autocompleteDescription": "Autocomplete Description",
|
||||
"add_command.autocompleteDescription.help": "Optional short description of slash command for the autocomplete list.",
|
||||
"add_command.autocompleteDescription.placeholder": "Example: \"Returns search results for patient records\"",
|
||||
"add_command.autocompleteHint": "Autocomplete Hint",
|
||||
"add_command.autocompleteHint.help": "Optional hint in the autocomplete list about parameters needed for command.",
|
||||
"add_command.autocompleteHint.placeholder": "Example: [Patient Name]",
|
||||
"add_command.description": "Description",
|
||||
"add_command.displayName": "Display Name",
|
||||
"add_command.header": "Add Slash Command",
|
||||
"add_command.iconUrl": "Response Icon",
|
||||
"add_command.iconUrl.placeholder": "https://www.example.com/myicon.png",
|
||||
"add_command.iconUrl.help": "Choose a profile picture override for the post responses to this slash command. Enter the URL of a .png or .jpg file at least 128 pixels by 128 pixels.",
|
||||
"add_command.method": "Request Method",
|
||||
"add_command.method.get": "GET",
|
||||
"add_command.method.help": "The type of command request issued to the Request URL.",
|
||||
"add_command.method.post": "POST",
|
||||
"add_command.trigger": "Command Trigger Word",
|
||||
"add_command.trigger.help1": "Examples: /patient, /client, /employee",
|
||||
"add_command.trigger.help2": "Reserved: /echo, /join, /logout, /me, /shrug",
|
||||
"add_command.trigger.placeholder": "Command trigger e.g. \"hello\" not including the slash",
|
||||
"add_command.triggerRequired": "A trigger word is required",
|
||||
"add_command.username": "Response Username",
|
||||
"add_command.username.help": "Choose a username override for responses for this slash command. Usernames can consist of up to 22 characters consisting of lowercase letters, numbers and they symbols \"-\", \"_\", and \".\" .",
|
||||
"add_command.username.placeholder": "Username",
|
||||
"add_command.url": "Request URL",
|
||||
"add_command.url.help": "The callback URL to receive the HTTP POST or GET event request when the slash command is run.",
|
||||
"add_command.url.placeholder": "Must start with http:// or https://",
|
||||
"add_command.urlRequired": "A request URL is required",
|
||||
"add_incoming_webhook.cancel": "Cancel",
|
||||
"add_incoming_webhook.channel": "Channel",
|
||||
"add_incoming_webhook.channelRequired": "A valid channel is required",
|
||||
@@ -35,6 +65,8 @@
|
||||
"add_incoming_webhook.name": "Name",
|
||||
"add_incoming_webhook.save": "Save",
|
||||
"add_integration.header": "Add Integration",
|
||||
"add_integration.command.description": "Create slash commands to send events to external integrations and receive a response.",
|
||||
"add_integration.command.title": "Slash Command",
|
||||
"add_integration.incomingWebhook.description": "Create webhook URLs for use in external integrations.",
|
||||
"add_integration.incomingWebhook.title": "Incoming Webhook",
|
||||
"add_integration.outgoingWebhook.description": "Create webhooks to send new message events to an external integration.",
|
||||
@@ -588,6 +620,7 @@
|
||||
"backstage_navbar.backToMattermost": "Back to {siteName}",
|
||||
"backstage_sidebar.integrations": "Integrations",
|
||||
"backstage_sidebar.integrations.add": "Add Integration",
|
||||
"backstage_sidebar.integrations.add.command": "Outgoing Webhook",
|
||||
"backstage_sidebar.integrations.add.incomingWebhook": "Incoming Webhook",
|
||||
"backstage_sidebar.integrations.add.outgoingWebhook": "Outgoing Webhook",
|
||||
"backstage_sidebar.integrations.installed": "Installed Integrations",
|
||||
@@ -817,6 +850,8 @@
|
||||
"installed_integrations.creation": "Created by {creator} on {createAt, date, full}",
|
||||
"installed_integrations.delete": "Delete",
|
||||
"installed_integrations.header": "Installed Integrations",
|
||||
"installed_integrations.commandType": "(Slash Command)",
|
||||
"installed_integrations.commandsFilter": "Slash Commands ({count})",
|
||||
"installed_integrations.incomingWebhookType": "(Incoming Webhook)",
|
||||
"installed_integrations.incomingWebhooksFilter": "Incoming Webhooks ({count})",
|
||||
"installed_integrations.outgoingWebhookType": "(Outgoing Webhook)",
|
||||
@@ -1222,42 +1257,6 @@
|
||||
"user.settings.advance.sendTitle": "Send messages on Ctrl + Enter",
|
||||
"user.settings.advance.slashCmd_autocmp": "Enable external application to offer slash command autocomplete",
|
||||
"user.settings.advance.title": "Advanced Settings",
|
||||
"user.settings.cmds.add": "Add",
|
||||
"user.settings.cmds.add_desc": "Create slash commands to send events to external integrations and receive a response. For example typing `/patient Joe Smith` could bring back search results from your internal health records management system for the name “Joe Smith”. Please see <a href=\"http://docs.mattermost.com/developer/slash-commands.html\">Slash commands documentation</a> for detailed instructions. View all slash commands configured on this team below.",
|
||||
"user.settings.cmds.add_display_name.placeholder": "Example: \"Search patient records\"",
|
||||
"user.settings.cmds.add_new": "Add a new command",
|
||||
"user.settings.cmds.add_trigger.placeholder": "Command trigger e.g. \"hello\" not including the slash",
|
||||
"user.settings.cmds.add_username.placeholder": "Username",
|
||||
"user.settings.cmds.auto_complete": "Autocomplete: ",
|
||||
"user.settings.cmds.auto_complete.no": "no",
|
||||
"user.settings.cmds.auto_complete.yes": "yes",
|
||||
"user.settings.cmds.auto_complete_desc": "Autocomplete Description: ",
|
||||
"user.settings.cmds.auto_complete_desc.placeholder": "Example: \"Returns search results for patient records\"",
|
||||
"user.settings.cmds.auto_complete_desc_desc": "Optional short description of slash command for the autocomplete list.",
|
||||
"user.settings.cmds.auto_complete_help": " Show this command in the autocomplete list.",
|
||||
"user.settings.cmds.auto_complete_hint": "Autocomplete Hint: ",
|
||||
"user.settings.cmds.auto_complete_hint.placeholder": "Example: [Patient Name]",
|
||||
"user.settings.cmds.auto_complete_hint_desc": "Optional hint in the autocomplete list about parameters needed for command.",
|
||||
"user.settings.cmds.cmd_display_name": "Brief description of slash command to show in listings.",
|
||||
"user.settings.cmds.display_name": "Descriptive Label: ",
|
||||
"user.settings.cmds.existing": "Existing commands",
|
||||
"user.settings.cmds.icon_url": "Response Icon: ",
|
||||
"user.settings.cmds.icon_url_desc": "Choose a profile picture override for the post responses to this slash command. Enter the URL of a .png or .jpg file at least 128 pixels by 128 pixels.",
|
||||
"user.settings.cmds.none": "None",
|
||||
"user.settings.cmds.regen": "Regen Token",
|
||||
"user.settings.cmds.request_type": "Request Method: ",
|
||||
"user.settings.cmds.request_type_desc": "The type of command request issued to the Request URL.",
|
||||
"user.settings.cmds.request_type_get": "GET",
|
||||
"user.settings.cmds.request_type_post": "POST",
|
||||
"user.settings.cmds.slashCmd_autocmp": "Enable external application to offer autocomplete",
|
||||
"user.settings.cmds.token": "Token: ",
|
||||
"user.settings.cmds.trigger": "Command Trigger Word: ",
|
||||
"user.settings.cmds.trigger_desc": "Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug",
|
||||
"user.settings.cmds.url": "Request URL: ",
|
||||
"user.settings.cmds.url.placeholder": "Must start with http:// or https://",
|
||||
"user.settings.cmds.url_desc": "The callback URL to receive the HTTP POST or GET event request when the slash command is run.",
|
||||
"user.settings.cmds.username": "Response Username: ",
|
||||
"user.settings.cmds.username_desc": "Choose a username override for responses for this slash command. Usernames can consist of up to 22 characters consisting of lowercase letters, numbers and they symbols \"-\", \"_\", and \".\" .",
|
||||
"user.settings.custom_theme.awayIndicator": "Away Indicator",
|
||||
"user.settings.custom_theme.buttonBg": "Button BG",
|
||||
"user.settings.custom_theme.buttonColor": "Button Text",
|
||||
@@ -1344,9 +1343,6 @@
|
||||
"user.settings.import_theme.importHeader": "Import Slack Theme",
|
||||
"user.settings.import_theme.submit": "Submit",
|
||||
"user.settings.import_theme.submitError": "Invalid format, please try copying and pasting in again.",
|
||||
"user.settings.integrations.commands": "Slash Commands",
|
||||
"user.settings.integrations.commandsDescription": "Manage your slash commands",
|
||||
"user.settings.integrations.title": "Integration Settings",
|
||||
"user.settings.languages.change": "Change interface language",
|
||||
"user.settings.mfa.add": "Add MFA to your account",
|
||||
"user.settings.mfa.addHelp": "To add multi-factor authentication to your account you must have a smartphone with Google Authenticator installed.",
|
||||
@@ -1362,7 +1358,6 @@
|
||||
"user.settings.modal.developer": "Developer",
|
||||
"user.settings.modal.display": "Display",
|
||||
"user.settings.modal.general": "General",
|
||||
"user.settings.modal.integrations": "Integrations",
|
||||
"user.settings.modal.notifications": "Notifications",
|
||||
"user.settings.modal.security": "Security",
|
||||
"user.settings.modal.title": "Account Settings",
|
||||
|
||||
@@ -27,6 +27,29 @@
|
||||
"activity_log_modal.android": "Android",
|
||||
"activity_log_modal.androidNativeApp": "Android App Nativa",
|
||||
"activity_log_modal.iphoneNativeApp": "iPhone App Nativa",
|
||||
"add_command.autocomplete.help": "Mostrar este comando en la lista de auto completado.",
|
||||
"add_command.autocompleteDescription": "Descripción del Autocompletado",
|
||||
"add_command.autocompleteDescription.help": "Descripción corta opcional para la lista de autocompletado del comando de barra.",
|
||||
"add_command.autocompleteDescription.placeholder": "Ejemplo: \"Retorna resultados de una búsqueda con los registros de un paciente\"",
|
||||
"add_command.autocompleteHint": "Pista del Autocompletado",
|
||||
"add_command.autocompleteHint.help": "Pista opcional que aparece como paramentros necesarios en la lista de autocompletado para el comando.",
|
||||
"add_command.autocompleteHint.placeholder": "Ejemplo: [Nombre del Paciente]",
|
||||
"add_command.iconUrl": "Icono de Respuesta",
|
||||
"add_command.iconUrl.help": "Escoge una imagen de perfil que reemplazara los mensajes publicados por este comando de barra. Ingresa el URL de un archivo .png o .jpg de al menos 128 x 128 pixels.",
|
||||
"add_command.method": "Método de Solicitud",
|
||||
"add_command.method.get": "GET",
|
||||
"add_command.method.help": "El tipo de comando que se utiliza al hacer una solicitud al URL.",
|
||||
"add_command.method.post": "POST",
|
||||
"add_command.trigger": "Palabra Gatilladora del Comando",
|
||||
"add_command.trigger.help1": "Ejemplos: /paciente, /cliente, /empleado",
|
||||
"add_command.trigger.help2": "Reservadas: /echo, /join, /logout, /me, /shrug",
|
||||
"add_command.trigger.placeholder": "Gatillador del Comando ej. \"hola\" no se debe incluir la barra",
|
||||
"add_command.url": "URL de Solicitud",
|
||||
"add_command.url.help": "El URL para recibir el evento de la solicitud HTTP POST o GET cuando se ejecuta el comando de barra.",
|
||||
"add_command.url.placeholder": "Debe comenzar con http:// o https://",
|
||||
"add_command.username": "Nombre de usuario de Respuesta",
|
||||
"add_command.username.help": "Escoge un nombre de usuario que reemplazara los mensajes publicados por este comando de barra. Los nombres de usuario pueden tener hasta 22 caracteres y contener letras en minúsculas, números y los siguientes símbolos \"-\", \"_\", y \".\" .",
|
||||
"add_command.username.placeholder": "Nombre de usuario",
|
||||
"add_incoming_webhook.cancel": "Cancelar",
|
||||
"add_incoming_webhook.channel": "Canal",
|
||||
"add_incoming_webhook.channelRequired": "Es obligatorio asignar un canal válido",
|
||||
@@ -1222,42 +1245,6 @@
|
||||
"user.settings.advance.sendTitle": "Enviar mensajes con Ctrl + Retorno",
|
||||
"user.settings.advance.slashCmd_autocmp": "Habilitar que una aplicación externa ofrezca el autocompletado de los comandos de barra",
|
||||
"user.settings.advance.title": "Configuración Avanzada",
|
||||
"user.settings.cmds.add": "Agregar",
|
||||
"user.settings.cmds.add_desc": "Crea comandos de barra para enviar eventos a integraciones externas recibiendo una respuesta. Por ejemplo al escribir `/paciente Joe Smith` podría retornar los resultados de una búsqueda de los regístros de salud en tu sistema de administración para el nombre “Joe Smith”. Revisa la <a href=\"http://docs.mattermost.com/developer/slash-commands.html\">documentación de Comandos de Barra</a> para instrucciones detalladas. Ver todos los comandos de barra configurados para este equipo en la parte de abajo.",
|
||||
"user.settings.cmds.add_display_name.placeholder": "Ejemplo: \"Buscar registros del paciente\"",
|
||||
"user.settings.cmds.add_new": "Agregar un nuevo comando",
|
||||
"user.settings.cmds.add_trigger.placeholder": "Gatillador del Comando ej. \"hola\" no se debe incluir la barra",
|
||||
"user.settings.cmds.add_username.placeholder": "Nombre de usuario",
|
||||
"user.settings.cmds.auto_complete": "Autocompletado: ",
|
||||
"user.settings.cmds.auto_complete.no": "no",
|
||||
"user.settings.cmds.auto_complete.yes": "sí",
|
||||
"user.settings.cmds.auto_complete_desc": "Descripción del Autocompletado: ",
|
||||
"user.settings.cmds.auto_complete_desc.placeholder": "Ejemplo: \"Retorna resultados de una búsqueda con los registros de un paciente\"",
|
||||
"user.settings.cmds.auto_complete_desc_desc": "Descripción corta opcional para la lista de autocompletado del comando de barra.",
|
||||
"user.settings.cmds.auto_complete_help": "Mostrar este comando en la lista de auto completado.",
|
||||
"user.settings.cmds.auto_complete_hint": "Pista del Autocompletado: ",
|
||||
"user.settings.cmds.auto_complete_hint.placeholder": "Ejemplo: [Nombre del Paciente]",
|
||||
"user.settings.cmds.auto_complete_hint_desc": "Pista opcional que aparece como paramentros necesarios en la lista de autocompletado para el comando.",
|
||||
"user.settings.cmds.cmd_display_name": "Breve descripción del comando de barra para mostrar en el listado.",
|
||||
"user.settings.cmds.display_name": "Etiqueta Descriptiva: ",
|
||||
"user.settings.cmds.existing": "Comandos existentes",
|
||||
"user.settings.cmds.icon_url": "Icono de Respuesta: ",
|
||||
"user.settings.cmds.icon_url_desc": "Escoge una imagen de perfil que reemplazara los mensajes publicados por este comando de barra. Ingresa el URL de un archivo .png o .jpg de al menos 128 x 128 pixels.",
|
||||
"user.settings.cmds.none": "Ninguno",
|
||||
"user.settings.cmds.regen": "Regenerar Token",
|
||||
"user.settings.cmds.request_type": "Método de Solicitud: ",
|
||||
"user.settings.cmds.request_type_desc": "El tipo de comando que se utiliza al hacer una solicitud al URL.",
|
||||
"user.settings.cmds.request_type_get": "GET",
|
||||
"user.settings.cmds.request_type_post": "POST",
|
||||
"user.settings.cmds.slashCmd_autocmp": "Habilitar que una aplicación externa ofrezca autocompletado",
|
||||
"user.settings.cmds.token": "Token: ",
|
||||
"user.settings.cmds.trigger": "Palabra Gatilladora del Comando: ",
|
||||
"user.settings.cmds.trigger_desc": "Ejemplos: /paciente, /cliente, /empleado Reservadas: /echo, /join, /logout, /me, /shrug",
|
||||
"user.settings.cmds.url": "URL de Solicitud: ",
|
||||
"user.settings.cmds.url.placeholder": "Debe comenzar con http:// o https://",
|
||||
"user.settings.cmds.url_desc": "El URL para recibir el evento de la solicitud HTTP POST o GET cuando se ejecuta el comando de barra.",
|
||||
"user.settings.cmds.username": "Nombre de usuario de Respuesta: ",
|
||||
"user.settings.cmds.username_desc": "Escoge un nombre de usuario que reemplazara los mensajes publicados por este comando de barra. Los nombres de usuario pueden tener hasta 22 caracteres y contener letras en minúsculas, números y los siguientes símbolos \"-\", \"_\", y \".\" .",
|
||||
"user.settings.custom_theme.awayIndicator": "Indicador Ausente",
|
||||
"user.settings.custom_theme.buttonBg": "Fondo Botón",
|
||||
"user.settings.custom_theme.buttonColor": "Texto Botón",
|
||||
@@ -1344,9 +1331,6 @@
|
||||
"user.settings.import_theme.importHeader": "Importar Tema de Slack",
|
||||
"user.settings.import_theme.submit": "Enviar",
|
||||
"user.settings.import_theme.submitError": "Formato inválido, por favor intenta copiando y pegando nuevamente.",
|
||||
"user.settings.integrations.commands": "Comandos de Barra",
|
||||
"user.settings.integrations.commandsDescription": "Administra tus comandos de barra",
|
||||
"user.settings.integrations.title": "Configuraciones de Integración",
|
||||
"user.settings.languages.change": "Cambia el idioma con el que se muestra la intefaz de usuario",
|
||||
"user.settings.mfa.add": "Agrega AMF a tu cuenta",
|
||||
"user.settings.mfa.addHelp": "Para agregar autenticación de múltiples factores a tu cuenta debes tener un teléfono inteligente con Google Authenticator instalado.",
|
||||
@@ -1362,7 +1346,6 @@
|
||||
"user.settings.modal.developer": "Desarrollo",
|
||||
"user.settings.modal.display": "Visualización",
|
||||
"user.settings.modal.general": "General",
|
||||
"user.settings.modal.integrations": "Integraciones",
|
||||
"user.settings.modal.notifications": "Notificaciones",
|
||||
"user.settings.modal.security": "Seguridad",
|
||||
"user.settings.modal.title": "Configuración de la Cuenta",
|
||||
|
||||
@@ -22,6 +22,28 @@
|
||||
"activity_log_modal.android": "Android",
|
||||
"activity_log_modal.androidNativeApp": "Application Android",
|
||||
"activity_log_modal.iphoneNativeApp": "Application pour iPhone",
|
||||
"add_command.autocomplete.help": "Afficher cette commande dans la liste d'auto-complétion",
|
||||
"add_command.autocompleteDescription": "Description de l'auto-complétion",
|
||||
"add_command.autocompleteDescription.help": "Description facultative de la commande slash dans la la liste d'auto-complétion.",
|
||||
"add_command.autocompleteDescription.placeholder": "Exemple : \"Retourne les résultats de recherche de dossiers médicaux\"",
|
||||
"add_command.autocompleteHint": "Explication pour l'auto-complétion",
|
||||
"add_command.autocompleteHint.help": "Explication facultative pour la liste d'auto-complétion au sujet des paramètres requis par cette commande slash.",
|
||||
"add_command.autocompleteHint.placeholder": "Exemple : [Nom du patient]",
|
||||
"add_command.iconUrl": "Icône de la réponse",
|
||||
"add_command.iconUrl.help": "Choisissez une photo de profil pour les réponses à cette commande slash. Entrez l'URL d'un fichier .png ou .jpg d'au moins 128x128 pixels.",
|
||||
"add_command.method": "Méthode de requête",
|
||||
"add_command.method.get": "GET",
|
||||
"add_command.method.help": "Le type de méthode de requête HTTP envoyé à cette URL.",
|
||||
"add_command.method.post": "POST",
|
||||
"add_command.token": "Jeton",
|
||||
"add_command.trigger": "Mot-clé de déclenchement",
|
||||
"add_command.trigger.help1": "Exemples: /patient, /client, /employé",
|
||||
"add_command.trigger.help2": "Mots réservés : /echo, /join, /logout, /me, /shrug",
|
||||
"add_command.url": "URL de requête",
|
||||
"add_command.url.help": "L'URL de callback qui recevra la requête POST ou GET quand cette commande slash est exécutée.",
|
||||
"add_command.url.placeholder": "Doit commencer par http:// ou https://",
|
||||
"add_command.username": "Utilisateur affiché dans la réponse",
|
||||
"add_command.username.help": "Choisissez un nom d'utilisateur qui sera affiché dans la réponse de la commande slash. Les noms d'utilisateurs peuvent contenir jusqu'à 22 caractères, chiffres, lettres minuscules et symboles \"-\", \"_\" et \".\".",
|
||||
"admin.audits.reload": "Rafraîchir",
|
||||
"admin.audits.title": "Activité de l'utilisateur",
|
||||
"admin.compliance.directoryDescription": "Répertoire des rapports de conformité. Si non spécifié : ./data/ .",
|
||||
@@ -1161,42 +1183,6 @@
|
||||
"user.settings.advance.sendTitle": "Envoyer vos messages avec Ctrl+Entrée",
|
||||
"user.settings.advance.slashCmd_autocmp": "Autoriser les applications externes à propose l'auto-complétion",
|
||||
"user.settings.advance.title": "Paramètres avancés",
|
||||
"user.settings.cmds.add": "Ajouter",
|
||||
"user.settings.cmds.add_desc": "Créez des commandes slash pour envoyer des événements à des intégrations externes et recevoir des réponses. Par exemple, saisir \"/patient Christelle Durand\" peut retourner les résultats de recherche depuis votre système de santé pour le nom \"Christelle Durand\". Veuillez consulter <a href=\"http://docs.mattermost.com/developer/slash-commands.html\">la documentation des commandes slash</a> pour des instructions plus complètes. Vous pouvez consulter toutes les commandes slash déjà configurées ci-dessous.",
|
||||
"user.settings.cmds.add_display_name.placeholder": "Exemple : \"Recherche dossiers médicaux\"",
|
||||
"user.settings.cmds.add_new": "Ajouter une nouvelle commande",
|
||||
"user.settings.cmds.add_trigger.placeholder": "Déclencheur (par exemple \"hello\"), sans le slash",
|
||||
"user.settings.cmds.add_username.placeholder": "Nom d'utilisateur",
|
||||
"user.settings.cmds.auto_complete": "Auto-complétion",
|
||||
"user.settings.cmds.auto_complete.no": "Non",
|
||||
"user.settings.cmds.auto_complete.yes": "Oui",
|
||||
"user.settings.cmds.auto_complete_desc": "Description de l'auto-complétion :",
|
||||
"user.settings.cmds.auto_complete_desc.placeholder": "Exemple : \"Retourne les résultats de recherche de dossiers médicaux\"",
|
||||
"user.settings.cmds.auto_complete_desc_desc": "Description facultative de la commande slash dans la la liste d'auto-complétion.",
|
||||
"user.settings.cmds.auto_complete_help": "Afficher cette commande dans la liste d'auto-complétion",
|
||||
"user.settings.cmds.auto_complete_hint": "Explication pour l'auto-complétion :",
|
||||
"user.settings.cmds.auto_complete_hint.placeholder": "Exemple : [Nom du patient]",
|
||||
"user.settings.cmds.auto_complete_hint_desc": "Explication facultative pour la liste d'auto-complétion au sujet des paramètres requis par cette commande slash.",
|
||||
"user.settings.cmds.cmd_display_name": "Brève description de la commande slash à afficher dans les listings.",
|
||||
"user.settings.cmds.display_name": "Description :",
|
||||
"user.settings.cmds.existing": "Commandes existantes",
|
||||
"user.settings.cmds.icon_url": "Icône de la réponse :",
|
||||
"user.settings.cmds.icon_url_desc": "Choisissez une photo de profil pour les réponses à cette commande slash. Entrez l'URL d'un fichier .png ou .jpg d'au moins 128x128 pixels.",
|
||||
"user.settings.cmds.none": "Aucun",
|
||||
"user.settings.cmds.regen": "Réinitialiser le jeton",
|
||||
"user.settings.cmds.request_type": "Méthode de requête :",
|
||||
"user.settings.cmds.request_type_desc": "Le type de méthode de requête HTTP envoyé à cette URL.",
|
||||
"user.settings.cmds.request_type_get": "GET",
|
||||
"user.settings.cmds.request_type_post": "POST",
|
||||
"user.settings.cmds.slashCmd_autocmp": "Autoriser les applications externes à propose l'auto-complétion",
|
||||
"user.settings.cmds.token": "Jeton :",
|
||||
"user.settings.cmds.trigger": "Mot-clé de déclenchement :",
|
||||
"user.settings.cmds.trigger_desc": "Exemples: /patient, /client, /employé Mots réservés : /echo, /join, /logout, /me, /shrug",
|
||||
"user.settings.cmds.url": "URL de requête :",
|
||||
"user.settings.cmds.url.placeholder": "Doit commencer par http:// ou https://",
|
||||
"user.settings.cmds.url_desc": "L'URL de callback qui recevra la requête POST ou GET quand cette commande slash est exécutée.",
|
||||
"user.settings.cmds.username": "Utilisateur affiché dans la réponse :",
|
||||
"user.settings.cmds.username_desc": "Choisissez un nom d'utilisateur qui sera affiché dans la réponse de la commande slash. Les noms d'utilisateurs peuvent contenir jusqu'à 22 caractères, chiffres, lettres minuscules et symboles \"-\", \"_\" et \".\".",
|
||||
"user.settings.custom_theme.awayIndicator": "Indicateur \"absent\"",
|
||||
"user.settings.custom_theme.buttonBg": "Fond de bouton",
|
||||
"user.settings.custom_theme.buttonColor": "Texte de bouton",
|
||||
@@ -1277,9 +1263,6 @@
|
||||
"user.settings.import_theme.importHeader": "Importer un thème Slack",
|
||||
"user.settings.import_theme.submit": "Envoyer",
|
||||
"user.settings.import_theme.submitError": "Format invalide, veuillez réessayer de copier-coller.",
|
||||
"user.settings.integrations.commands": "Commandes slash",
|
||||
"user.settings.integrations.commandsDescription": "Gérez vos commandes slash",
|
||||
"user.settings.integrations.title": "Paramètres d'intégration",
|
||||
"user.settings.languages.change": "Changer la langue de l'interface",
|
||||
"user.settings.modal.advanced": "Options avancées",
|
||||
"user.settings.modal.confirmBtns": "Oui, abandonner",
|
||||
@@ -1288,7 +1271,6 @@
|
||||
"user.settings.modal.developer": "Développeur",
|
||||
"user.settings.modal.display": "Affichage",
|
||||
"user.settings.modal.general": "Général",
|
||||
"user.settings.modal.integrations": "Intégrations",
|
||||
"user.settings.modal.notifications": "Notifications",
|
||||
"user.settings.modal.security": "Sécurité",
|
||||
"user.settings.modal.title": "Paramètres du compte",
|
||||
|
||||
@@ -22,6 +22,31 @@
|
||||
"activity_log_modal.android": "Android",
|
||||
"activity_log_modal.androidNativeApp": "App Nativo Android",
|
||||
"activity_log_modal.iphoneNativeApp": "App Nativo para iPhone",
|
||||
"add_command.autocomplete": "Autocompletar",
|
||||
"add_command.autocomplete.help": " Mostrar este comando na lista de preenchimento automático.",
|
||||
"add_command.autocompleteDescription": "Autocompletar Descrição",
|
||||
"add_command.autocompleteDescription.help": "Breve descrição opcional do comando slash para a lista de preenchimento automático.",
|
||||
"add_command.autocompleteDescription.placeholder": "Exemplo: \"Retorna os resultados da pesquisa, prontuário\"",
|
||||
"add_command.autocompleteHint": "Autocompletar Sugestão",
|
||||
"add_command.autocompleteHint.help": "Sugestão opcional na lista autocompletada sobre os parâmetros necessários para o comando.",
|
||||
"add_command.autocompleteHint.placeholder": "Exemplo: [Nome Do Paciente]",
|
||||
"add_command.displayName": "Etiqueta Descritiva",
|
||||
"add_command.iconUrl": "Ícone de Resposta",
|
||||
"add_command.iconUrl.help": "Escolha uma imagem do perfil para substituir as respostas dos posts deste comando slash. Digite a URL de um arquivo .png ou .jpg com pelo menos 128 pixels por 128 pixels.",
|
||||
"add_command.method": "Método de Requisição",
|
||||
"add_command.method.get": "GET",
|
||||
"add_command.method.help": "O tipo de solicitação do comando emitido para a URL requisitada.",
|
||||
"add_command.method.post": "POST",
|
||||
"add_command.trigger": "Comando Palavra Gatilho",
|
||||
"add_command.trigger.help1": "Exemplos: /patient, /client, /employee",
|
||||
"add_command.trigger.help2": "Reserved: /echo, /join, /logout, /me, /shrug",
|
||||
"add_command.trigger.placeholder": "Comando de gatilho ex. \"hello\", não incluí a barra",
|
||||
"add_command.url": "URL de solicitação",
|
||||
"add_command.url.help": "A URL callback para receber o evento HTTP POST ou GET quando o comando slash for executado.",
|
||||
"add_command.url.placeholder": "Deve começar com http:// ou https://",
|
||||
"add_command.username": "Usuário de Resposta",
|
||||
"add_command.username.help": "Escolha um nome de usuário para substituir as respostas deste comando slash. O nome de usuário deve ter até 22 caracteres contendo letras minúsculas, números e os símbolos \"-\", \"_\", e \".\" .",
|
||||
"add_command.username.placeholder": "Usuário",
|
||||
"add_incoming_webhook.cancel": "Cancelar",
|
||||
"add_incoming_webhook.channel": "Canal",
|
||||
"add_incoming_webhook.channelRequired": "Um canal válido é necessário",
|
||||
@@ -1207,42 +1232,6 @@
|
||||
"user.settings.advance.sendTitle": "Enviar mensagens Ctrl + Enter",
|
||||
"user.settings.advance.slashCmd_autocmp": "Ativar aplicação externa para autocompletar comandos slash",
|
||||
"user.settings.advance.title": "Configurações Avançadas",
|
||||
"user.settings.cmds.add": "Adicionar",
|
||||
"user.settings.cmds.add_desc": "Criar comandos slash para enviar eventos para integrações externas e receber uma resposta. Por exemplo digitando `/patient Joe Smith` poderia trazer de volta os resultados de pesquisa a partir do seu sistema de gestão de registos internos de saúde para o nome “Joe Smith”. Por favor veja <a href=\"http://docs.mattermost.com/developer/slash-commands.html\">Documentação comandos Slash</a> para detalhes e instruções. Ver todos os comandos slash configurados nesta equipe abaixo.",
|
||||
"user.settings.cmds.add_display_name.placeholder": "Exemplo: \"Procurar registros de pacientes\"",
|
||||
"user.settings.cmds.add_new": "Adicionar um novo comando",
|
||||
"user.settings.cmds.add_trigger.placeholder": "Comando de gatilho ex. \"hello\", não incluí a barra",
|
||||
"user.settings.cmds.add_username.placeholder": "Usuário",
|
||||
"user.settings.cmds.auto_complete": "Autocompletar: ",
|
||||
"user.settings.cmds.auto_complete.no": "não",
|
||||
"user.settings.cmds.auto_complete.yes": "sim",
|
||||
"user.settings.cmds.auto_complete_desc": "Autocompletar Descrição: ",
|
||||
"user.settings.cmds.auto_complete_desc.placeholder": "Exemplo: \"Retorna os resultados da pesquisa, prontuário\"",
|
||||
"user.settings.cmds.auto_complete_desc_desc": "Breve descrição opcional do comando slash para a lista de preenchimento automático.",
|
||||
"user.settings.cmds.auto_complete_help": " Mostrar este comando na lista de preenchimento automático.",
|
||||
"user.settings.cmds.auto_complete_hint": "Autocompletar Sugestão: ",
|
||||
"user.settings.cmds.auto_complete_hint.placeholder": "Exemplo: [Nome Do Paciente]",
|
||||
"user.settings.cmds.auto_complete_hint_desc": "Sugestão opcional na lista autocompletada sobre os parâmetros necessários para o comando.",
|
||||
"user.settings.cmds.cmd_display_name": "Breve descrição do comando slash para mostrar em listas.",
|
||||
"user.settings.cmds.display_name": "Etiqueta Descritiva: ",
|
||||
"user.settings.cmds.existing": "Comando existente",
|
||||
"user.settings.cmds.icon_url": "Ícone de Resposta: ",
|
||||
"user.settings.cmds.icon_url_desc": "Escolha uma imagem do perfil para substituir as respostas dos posts deste comando slash. Digite a URL de um arquivo .png ou .jpg com pelo menos 128 pixels por 128 pixels.",
|
||||
"user.settings.cmds.none": "Nenhum",
|
||||
"user.settings.cmds.regen": "Regen Token",
|
||||
"user.settings.cmds.request_type": "Método de Requisição: ",
|
||||
"user.settings.cmds.request_type_desc": "O tipo de solicitação do comando emitido para a URL requisitada.",
|
||||
"user.settings.cmds.request_type_get": "GET",
|
||||
"user.settings.cmds.request_type_post": "POST",
|
||||
"user.settings.cmds.slashCmd_autocmp": "Ativar aplicação externa para autocompletar",
|
||||
"user.settings.cmds.token": "Token: ",
|
||||
"user.settings.cmds.trigger": "Comando Palavra Gatilho: ",
|
||||
"user.settings.cmds.trigger_desc": "Exemplos: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug",
|
||||
"user.settings.cmds.url": "URL de solicitação: ",
|
||||
"user.settings.cmds.url.placeholder": "Deve começar com http:// ou https://",
|
||||
"user.settings.cmds.url_desc": "A URL callback para receber o evento HTTP POST ou GET quando o comando slash for executado.",
|
||||
"user.settings.cmds.username": "Usuário de Resposta: ",
|
||||
"user.settings.cmds.username_desc": "Escolha um nome de usuário para substituir as respostas deste comando slash. O nome de usuário deve ter até 22 caracteres contendo letras minúsculas, números e os símbolos \"-\", \"_\", e \".\" .",
|
||||
"user.settings.custom_theme.awayIndicator": "Indicador de Afastamento",
|
||||
"user.settings.custom_theme.buttonBg": "Fundo Botão",
|
||||
"user.settings.custom_theme.buttonColor": "Texto do Botão",
|
||||
@@ -1329,9 +1318,6 @@
|
||||
"user.settings.import_theme.importHeader": "Importar Tema Slack",
|
||||
"user.settings.import_theme.submit": "Enviar",
|
||||
"user.settings.import_theme.submitError": "Formato inválido, por favor tente copiar e colar novamente.",
|
||||
"user.settings.integrations.commands": "Comandos Slash",
|
||||
"user.settings.integrations.commandsDescription": "Gerenciar seus comandos slash",
|
||||
"user.settings.integrations.title": "Configuração de Integração",
|
||||
"user.settings.languages.change": "Alterar o idioma da interface",
|
||||
"user.settings.modal.advanced": "Avançado",
|
||||
"user.settings.modal.confirmBtns": "Sim, Descartar",
|
||||
@@ -1340,7 +1326,6 @@
|
||||
"user.settings.modal.developer": "Desenvolvedor",
|
||||
"user.settings.modal.display": "Exibir",
|
||||
"user.settings.modal.general": "Geral",
|
||||
"user.settings.modal.integrations": "Integrações",
|
||||
"user.settings.modal.notifications": "Notificações",
|
||||
"user.settings.modal.security": "Segurança",
|
||||
"user.settings.modal.title": "Definições de Conta",
|
||||
|
||||
@@ -42,6 +42,7 @@ import InstalledIntegrations from 'components/backstage/installed_integrations.j
|
||||
import AddIntegration from 'components/backstage/add_integration.jsx';
|
||||
import AddIncomingWebhook from 'components/backstage/add_incoming_webhook.jsx';
|
||||
import AddOutgoingWebhook from 'components/backstage/add_outgoing_webhook.jsx';
|
||||
import AddCommand from 'components/backstage/add_command.jsx';
|
||||
import ErrorPage from 'components/error_page.jsx';
|
||||
|
||||
import SignupTeamComplete from 'components/signup_team_complete/components/signup_team_complete.jsx';
|
||||
@@ -285,6 +286,14 @@ function renderRootComponent() {
|
||||
center: AddOutgoingWebhook
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path='command'
|
||||
components={{
|
||||
navbar: BackstageNavbar,
|
||||
sidebar: BackstageSidebar,
|
||||
center: AddCommand
|
||||
}}
|
||||
/>
|
||||
</Route>
|
||||
<Redirect
|
||||
from='*'
|
||||
|
||||
@@ -20,6 +20,9 @@ class IntegrationStore extends EventEmitter {
|
||||
|
||||
this.outgoingWebhooks = [];
|
||||
this.receivedOutgoingWebhooks = false;
|
||||
|
||||
this.commands = [];
|
||||
this.receivedCommands = false;
|
||||
}
|
||||
|
||||
addChangeListener(callback) {
|
||||
@@ -61,7 +64,7 @@ class IntegrationStore extends EventEmitter {
|
||||
}
|
||||
|
||||
hasReceivedOutgoingWebhooks() {
|
||||
return this.receivedIncomingWebhooks;
|
||||
return this.receivedOutgoingWebhooks;
|
||||
}
|
||||
|
||||
getOutgoingWebhooks() {
|
||||
@@ -95,6 +98,41 @@ class IntegrationStore extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
hasReceivedCommands() {
|
||||
return this.receivedCommands;
|
||||
}
|
||||
|
||||
getCommands() {
|
||||
return this.commands;
|
||||
}
|
||||
|
||||
setCommands(commands) {
|
||||
this.commands = commands;
|
||||
this.receivedCommands = true;
|
||||
}
|
||||
|
||||
addCommand(command) {
|
||||
this.commands.push(command);
|
||||
}
|
||||
|
||||
updateCommand(command) {
|
||||
for (let i = 0; i < this.commands.length; i++) {
|
||||
if (this.commands[i].id === command.id) {
|
||||
this.commands[i] = command;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeCommand(id) {
|
||||
for (let i = 0; i < this.commands.length; i++) {
|
||||
if (this.commands[i].id === id) {
|
||||
this.commands.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleEventPayload(payload) {
|
||||
const action = payload.action;
|
||||
|
||||
@@ -127,8 +165,27 @@ class IntegrationStore extends EventEmitter {
|
||||
this.removeOutgoingWebhook(action.id);
|
||||
this.emitChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_COMMANDS:
|
||||
this.setCommands(action.commands);
|
||||
this.emitChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_COMMAND:
|
||||
this.addCommand(action.command);
|
||||
this.emitChange();
|
||||
break;
|
||||
case ActionTypes.UPDATED_COMMAND:
|
||||
this.updateCommand(action.command);
|
||||
this.emitChange();
|
||||
break;
|
||||
case ActionTypes.REMOVED_COMMAND:
|
||||
this.removeCommand(action.id);
|
||||
this.emitChange();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new IntegrationStore();
|
||||
const instance = new IntegrationStore();
|
||||
export default instance;
|
||||
window.IntegrationStore = instance;
|
||||
|
||||
|
||||
@@ -1258,3 +1258,80 @@ export function regenOutgoingHookToken(id) {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function listTeamCommands() {
|
||||
if (isCallInProgress('listTeamCommands')) {
|
||||
return;
|
||||
}
|
||||
|
||||
callTracker.listTeamCommands = utils.getTimestamp();
|
||||
|
||||
client.listTeamCommands(
|
||||
(data) => {
|
||||
callTracker.listTeamCommands = 0;
|
||||
|
||||
AppDispatcher.handleServerAction({
|
||||
type: ActionTypes.RECEIVED_COMMANDS,
|
||||
commands: data
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
callTracker.listTeamCommands = 0;
|
||||
dispatchError(err, 'listTeamCommands');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function addCommand(command, success, error) {
|
||||
client.addCommand(
|
||||
command,
|
||||
(data) => {
|
||||
AppDispatcher.handleServerAction({
|
||||
type: ActionTypes.RECEIVED_COMMAND,
|
||||
command: data
|
||||
});
|
||||
|
||||
if (success) {
|
||||
success();
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
if (error) {
|
||||
error(err);
|
||||
} else {
|
||||
dispatchError(err, 'addCommand');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function deleteCommand(id) {
|
||||
client.deleteCommand(
|
||||
{id},
|
||||
() => {
|
||||
AppDispatcher.handleServerAction({
|
||||
type: ActionTypes.REMOVED_COMMAND,
|
||||
id
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
dispatchError(err, 'deleteCommand');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function regenCommandToken(id) {
|
||||
client.regenCommandToken(
|
||||
{id},
|
||||
(data) => {
|
||||
AppDispatcher.handleServerAction({
|
||||
type: ActionTypes.UPDATED_COMMAND,
|
||||
command: data
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
dispatchError(err, 'regenCommandToken');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,10 @@ export default {
|
||||
RECEIVED_OUTGOING_WEBHOOK: null,
|
||||
UPDATED_OUTGOING_WEBHOOK: null,
|
||||
REMOVED_OUTGOING_WEBHOOK: null,
|
||||
RECEIVED_COMMANDS: null,
|
||||
RECEIVED_COMMAND: null,
|
||||
UPDATED_COMMAND: null,
|
||||
REMOVED_COMMAND: null,
|
||||
|
||||
RECEIVED_MSG: null,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user