summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/react/components/admin_console/image_settings.jsx5
-rw-r--r--web/react/components/admin_console/user_item.jsx4
-rw-r--r--web/react/components/delete_post_modal.jsx2
-rw-r--r--web/react/components/member_list_item.jsx4
-rw-r--r--web/react/components/member_list_team_item.jsx4
-rw-r--r--web/react/components/more_channels.jsx2
-rw-r--r--web/react/components/posts_view.jsx6
-rw-r--r--web/react/components/search_results.jsx30
-rw-r--r--web/react/components/search_results_item.jsx6
-rw-r--r--web/react/components/signup_user_complete.jsx11
-rw-r--r--web/react/components/user_settings/manage_command_hooks.jsx272
-rw-r--r--web/react/components/user_settings/user_settings_integrations.jsx4
-rw-r--r--web/react/components/user_settings/user_settings_modal.jsx15
-rw-r--r--web/react/stores/channel_store.jsx4
-rw-r--r--web/react/stores/socket_store.jsx4
-rw-r--r--web/react/utils/async_client.jsx8
-rw-r--r--web/react/utils/constants.jsx1
-rw-r--r--web/react/utils/markdown.jsx4
-rw-r--r--web/react/utils/utils.jsx23
-rw-r--r--web/sass-files/sass/partials/_markdown.scss8
-rw-r--r--web/sass-files/sass/partials/_mentions.scss16
-rw-r--r--web/sass-files/sass/partials/_modal.scss16
-rw-r--r--web/sass-files/sass/partials/_popover.scss3
-rw-r--r--web/sass-files/sass/partials/_post.scss19
-rw-r--r--web/sass-files/sass/partials/_settings.scss17
-rw-r--r--web/static/i18n/en.json51
-rw-r--r--web/static/i18n/es.json24
-rw-r--r--web/static/images/postArrows.pngbin5684 -> 0 bytes
28 files changed, 326 insertions, 237 deletions
diff --git a/web/react/components/admin_console/image_settings.jsx b/web/react/components/admin_console/image_settings.jsx
index 12bf554ea..86f78e093 100644
--- a/web/react/components/admin_console/image_settings.jsx
+++ b/web/react/components/admin_console/image_settings.jsx
@@ -8,10 +8,6 @@ import crypto from 'crypto';
import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl';
const holders = defineMessages({
- storeDisabled: {
- id: 'admin.image.storeDisabled',
- defaultMessage: 'Disable File Storage'
- },
storeLocal: {
id: 'admin.image.storeLocal',
defaultMessage: 'Local File System'
@@ -242,7 +238,6 @@ class FileSettings extends React.Component {
defaultValue={this.props.config.FileSettings.DriverName}
onChange={this.handleChange.bind(this, 'DriverName')}
>
- <option value=''>{formatMessage(holders.storeDisabled)}</option>
<option value='local'>{formatMessage(holders.storeLocal)}</option>
<option value='amazons3'>{formatMessage(holders.storeAmazonS3)}</option>
</select>
diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx
index 02b01b090..0c1a55cc1 100644
--- a/web/react/components/admin_console/user_item.jsx
+++ b/web/react/components/admin_console/user_item.jsx
@@ -360,8 +360,8 @@ export default class UserItem extends React.Component {
height='36'
width='36'
/>
- <span className='member-name'>{Utils.getDisplayName(user)}</span>
- <span className='member-email'>{email}</span>
+ <span className='more-name'>{Utils.getDisplayName(user)}</span>
+ <span className='more-description'>{email}</span>
<div className='dropdown member-drop'>
<a
href='#'
diff --git a/web/react/components/delete_post_modal.jsx b/web/react/components/delete_post_modal.jsx
index 65ffa96a1..95b2e58a8 100644
--- a/web/react/components/delete_post_modal.jsx
+++ b/web/react/components/delete_post_modal.jsx
@@ -173,7 +173,7 @@ export default class DeletePostModal extends React.Component {
<Modal.Body>
<FormattedMessage
id='delete_post.question'
- defaultMessage='Are you sure you want to delete this ${term}?'
+ defaultMessage='Are you sure you want to delete this {term}?'
values={{
term: (postTerm)
}}
diff --git a/web/react/components/member_list_item.jsx b/web/react/components/member_list_item.jsx
index c50ee5c96..41ea58eeb 100644
--- a/web/react/components/member_list_item.jsx
+++ b/web/react/components/member_list_item.jsx
@@ -124,8 +124,8 @@ export default class MemberListItem extends React.Component {
height='36'
width='36'
/>
- <div className='member-name'>{Utils.displayUsername(member.id)}</div>
- <div className='member-description'>{member.email}</div>
+ <div className='more-name'>{Utils.displayUsername(member.id)}</div>
+ <div className='more-description'>{member.email}</div>
</td>
<td className='td--action lg'>{invite}</td>
</tr>
diff --git a/web/react/components/member_list_team_item.jsx b/web/react/components/member_list_team_item.jsx
index 6e1006911..30086d1b2 100644
--- a/web/react/components/member_list_team_item.jsx
+++ b/web/react/components/member_list_team_item.jsx
@@ -208,8 +208,8 @@ export default class MemberListTeamItem extends React.Component {
height='36'
width='36'
/>
- <span className='member-name'>{Utils.displayUsername(user.id)}</span>
- <span className='member-email'>{email}</span>
+ <span className='more-name'>{Utils.displayUsername(user.id)}</span>
+ <span className='more-description'>{email}</span>
<div className='dropdown member-drop'>
<a
href='#'
diff --git a/web/react/components/more_channels.jsx b/web/react/components/more_channels.jsx
index d12ea4703..d800f93d8 100644
--- a/web/react/components/more_channels.jsx
+++ b/web/react/components/more_channels.jsx
@@ -114,7 +114,7 @@ export default class MoreChannels extends React.Component {
<tr key={channel.id}>
<td>
<p className='more-name'>{channel.display_name}</p>
- <p className='more-purpose'>{channel.purpose}</p>
+ <p className='more-description'>{channel.purpose}</p>
</td>
<td className='td--action'>
{joinButton}
diff --git a/web/react/components/posts_view.jsx b/web/react/components/posts_view.jsx
index f108ace2e..ebe19abad 100644
--- a/web/react/components/posts_view.jsx
+++ b/web/react/components/posts_view.jsx
@@ -94,7 +94,7 @@ export default class PostsView extends React.Component {
});
}
- this.scrollStopAction.fireAfter(1000);
+ this.scrollStopAction.fireAfter(2000);
}
handleScrollStop() {
this.setState({
@@ -564,6 +564,8 @@ function ScrollToBottomArrows({isScrolling, atBottom, onClick}) {
<div
className={className}
onClick={onClick}
- />
+ >
+ <span dangerouslySetInnerHTML={{__html: Constants.SCROLL_BOTTOM_ICON}} />
+ </div>
);
}
diff --git a/web/react/components/search_results.jsx b/web/react/components/search_results.jsx
index 9dcc99061..4adc3afe0 100644
--- a/web/react/components/search_results.jsx
+++ b/web/react/components/search_results.jsx
@@ -1,6 +1,7 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
+import ChannelStore from '../stores/channel_store.jsx';
import SearchStore from '../stores/search_store.jsx';
import UserStore from '../stores/user_store.jsx';
import SearchBox from './search_bar.jsx';
@@ -11,7 +12,22 @@ import SearchResultsItem from './search_results_item.jsx';
import {FormattedMessage, FormattedHTMLMessage} from 'mm-intl';
function getStateFromStores() {
- return {results: SearchStore.getSearchResults()};
+ const results = SearchStore.getSearchResults();
+
+ const channels = new Map();
+ const channelIds = results.order.map((postId) => results.posts[postId].channel_id);
+ for (const id of channelIds) {
+ if (channels.has(id)) {
+ continue;
+ }
+
+ channels.set(id, ChannelStore.get(id));
+ }
+
+ return {
+ results,
+ channels
+ };
}
export default class SearchResults extends React.Component {
@@ -33,16 +49,22 @@ export default class SearchResults extends React.Component {
componentDidMount() {
this.mounted = true;
SearchStore.addSearchChangeListener(this.onChange);
+ ChannelStore.addChangeListener(this.onChange);
this.resize();
window.addEventListener('resize', this.handleResize);
}
+ shouldComponentUpdate(nextProps, nextState) {
+ return !Utils.areObjectsEqual(this.props, nextProps) || !Utils.areObjectsEqual(this.state, nextState);
+ }
+
componentDidUpdate() {
this.resize();
}
componentWillUnmount() {
SearchStore.removeSearchChangeListener(this.onChange);
+ ChannelStore.removeChangeListener(this.onChange);
this.mounted = false;
window.removeEventListener('resize', this.handleResize);
}
@@ -56,10 +78,7 @@ export default class SearchResults extends React.Component {
onChange() {
if (this.mounted) {
- var newState = getStateFromStores();
- if (!Utils.areObjectsEqual(newState, this.state)) {
- this.setState(newState);
- }
+ this.setState(getStateFromStores());
}
}
@@ -116,6 +135,7 @@ export default class SearchResults extends React.Component {
return (
<SearchResultsItem
key={post.id}
+ channel={this.state.channels.get(post.channel_id)}
post={post}
term={searchTerm}
isMentionSearch={this.props.isMentionSearch}
diff --git a/web/react/components/search_results_item.jsx b/web/react/components/search_results_item.jsx
index 544ba920a..d3533037f 100644
--- a/web/react/components/search_results_item.jsx
+++ b/web/react/components/search_results_item.jsx
@@ -1,7 +1,6 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import ChannelStore from '../stores/channel_store.jsx';
import UserStore from '../stores/user_store.jsx';
import UserProfile from './user_profile.jsx';
import * as EventHelpers from '../dispatcher/event_helpers.jsx';
@@ -37,8 +36,8 @@ export default class SearchResultsItem extends React.Component {
}
render() {
- var channelName = '';
- var channel = ChannelStore.get(this.props.post.channel_id);
+ var channelName = null;
+ const channel = this.props.channel;
var timestamp = UserStore.getCurrentUser().update_at;
if (channel) {
@@ -136,6 +135,7 @@ export default class SearchResultsItem extends React.Component {
SearchResultsItem.propTypes = {
post: React.PropTypes.object,
+ channel: React.PropTypes.object,
isMentionSearch: React.PropTypes.bool,
term: React.PropTypes.string
};
diff --git a/web/react/components/signup_user_complete.jsx b/web/react/components/signup_user_complete.jsx
index 672213d1a..b770a2a2c 100644
--- a/web/react/components/signup_user_complete.jsx
+++ b/web/react/components/signup_user_complete.jsx
@@ -362,6 +362,17 @@ class SignupUserComplete extends React.Component {
);
}
+ if (signupMessage.length === 0 && !emailSignup) {
+ emailSignup = (
+ <div>
+ <FormattedMessage
+ id='signup_user_completed.none'
+ defaultMessage='No user creation method has been enabled. Please contact an administrator for access.'
+ />
+ </div>
+ );
+ }
+
return (
<div>
<form>
diff --git a/web/react/components/user_settings/manage_command_hooks.jsx b/web/react/components/user_settings/manage_command_hooks.jsx
index d23d2957e..f4009aeaa 100644
--- a/web/react/components/user_settings/manage_command_hooks.jsx
+++ b/web/react/components/user_settings/manage_command_hooks.jsx
@@ -18,7 +18,7 @@ const holders = defineMessages({
},
addDisplayNamePlaceholder: {
id: 'user.settings.cmds.add_display_name.placeholder',
- defaultMessage: 'Display Name'
+ defaultMessage: 'Example: "Search patient records"'
},
addUsernamePlaceholder: {
id: 'user.settings.cmds.add_username.placeholder',
@@ -30,11 +30,11 @@ const holders = defineMessages({
},
addAutoCompleteDescPlaceholder: {
id: 'user.settings.cmds.auto_complete_desc.placeholder',
- defaultMessage: 'A short description of what this commands does.'
+ defaultMessage: 'Example: "Returns search results for patient records"'
},
addAutoCompleteHintPlaceholder: {
id: 'user.settings.cmds.auto_complete_hint.placeholder',
- defaultMessage: '[zipcode]'
+ defaultMessage: 'Example: [Patient Name]'
},
adUrlPlaceholder: {
id: 'user.settings.cmds.url.placeholder',
@@ -261,7 +261,7 @@ export default class ManageCommandCmds extends React.Component {
<strong>
<FormattedMessage
id='user.settings.cmds.trigger'
- defaultMessage='Trigger: '
+ defaultMessage='Command Trigger Word: '
/>
</strong>{cmd.trigger}
</div>
@@ -271,21 +271,43 @@ export default class ManageCommandCmds extends React.Component {
cmds.push(
<div
key={cmd.id}
- className='webcmd__item'
+ 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.display_name'
- defaultMessage='Display Name: '
+ id='user.settings.cmds.request_type'
+ defaultMessage='Request Method: '
/>
- </strong><span className='word-break--all'>{cmd.display_name}</span>
+ </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='Username: '
+ defaultMessage='Response Username: '
/>
</strong><span className='word-break--all'>{cmd.username}</span>
</div>
@@ -293,7 +315,7 @@ export default class ManageCommandCmds extends React.Component {
<strong>
<FormattedMessage
id='user.settings.cmds.icon_url'
- defaultMessage='Icon URL: '
+ defaultMessage='Response Icon: '
/>
</strong><span className='word-break--all'>{cmd.icon_url}</span>
</div>
@@ -301,56 +323,34 @@ export default class ManageCommandCmds extends React.Component {
<strong>
<FormattedMessage
id='user.settings.cmds.auto_complete'
- defaultMessage='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_desc'
- defaultMessage='Auto Complete Description: '
- />
- </strong><span className='word-break--all'>{cmd.auto_complete_desc}</span>
- </div>
- <div className='padding-top x2'>
- <strong>
- <FormattedMessage
id='user.settings.cmds.auto_complete_hint'
- defaultMessage='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.request_type'
- defaultMessage='Request Type: '
+ id='user.settings.cmds.auto_complete_desc'
+ defaultMessage='Autocomplete Description: '
/>
- </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>
+ </strong><span className='word-break--all'>{cmd.auto_complete_desc}</span>
</div>
- <div className='padding-top x2 webcmd__url'>
+ <div className='padding-top x2'>
<strong>
<FormattedMessage
- id='user.settings.cmds.url'
- defaultMessage='URL: '
+ id='user.settings.cmds.display_name'
+ defaultMessage='Descriptive Label: '
/>
- </strong><span className='word-break--all'>{cmd.url}</span>
+ </strong><span className='word-break--all'>{cmd.display_name}</span>
</div>
- {triggerDiv}
<div className='padding-top'>
<strong>
<FormattedMessage
@@ -400,7 +400,7 @@ export default class ManageCommandCmds extends React.Component {
}
const existingCmds = (
- <div className='webcmds__container'>
+ <div className='webhooks__container webcmds__container'>
<label className='control-label padding-top x2'>
<FormattedMessage
id='user.settings.cmds.existing'
@@ -408,7 +408,7 @@ export default class ManageCommandCmds extends React.Component {
/>
</label>
<div className='padding-top divider-light'></div>
- <div className='webcmds__list'>
+ <div className='webhooks__list webcmds__list'>
{displayCmds}
</div>
</div>
@@ -420,7 +420,7 @@ export default class ManageCommandCmds extends React.Component {
<div key='addCommandCmd'>
<FormattedHTMLMessage
id='user.settings.cmds.add_desc'
- defaultMessage='Create commands to send message events to an external integration. Please see <a href="http://mattermost.org/commands">http://mattermost.org/commands</a> to learn more.'
+ 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.'
/>
<div><label className='control-label padding-top x2'>
<FormattedMessage
@@ -430,103 +430,139 @@ export default class ManageCommandCmds extends React.Component {
</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.display_name'
- defaultMessage='Display Name: '
+ id='user.settings.cmds.trigger'
+ defaultMessage='Command Trigger Word: '
/>
</label>
<div className='padding-top'>
<input
- ref='displayName'
+ ref='trigger'
className='form-control'
- value={this.state.cmd.display_name}
- onChange={this.updateDisplayName}
- placeholder={this.props.intl.formatMessage(holders.addDisplayNamePlaceholder)}
+ 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.cmd_display_name'
- defaultMessage='Command display name.'
+ 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.username'
- defaultMessage='Username: '
+ id='user.settings.cmds.url'
+ defaultMessage='Request URL: '
/>
</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)}
+ <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.username_desc'
- defaultMessage='The username to use when overriding the post.'
+ 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.icon_url'
- defaultMessage='Icon URL: '
+ id='user.settings.cmds.username'
+ defaultMessage='Response Username: '
/>
</label>
<div className='padding-top'>
<input
- ref='iconURL'
+ ref='username'
className='form-control'
- value={this.state.cmd.icon_url}
- onChange={this.updateIconURL}
- placeholder='https://www.example.com/myicon.png'
+ 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.icon_url_desc'
- defaultMessage='URL to an icon'
+ 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.trigger'
- defaultMessage='Trigger: '
+ id='user.settings.cmds.icon_url'
+ defaultMessage='Response Icon: '
/>
</label>
<div className='padding-top'>
<input
- ref='trigger'
+ ref='iconURL'
className='form-control'
- value={this.state.cmd.trigger}
- onChange={this.updateTrigger}
- placeholder={this.props.intl.formatMessage(holders.addTriggerPlaceholder)}
+ 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.trigger_desc'
- defaultMessage='Word to trigger on'
+ 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>
+
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.auto_complete'
- defaultMessage='Auto Complete: '
+ defaultMessage='Autocomplete: '
/>
</label>
<div className='padding-top'>
@@ -539,34 +575,18 @@ export default class ManageCommandCmds extends React.Component {
/>
<FormattedMessage
id='user.settings.cmds.auto_complete_help'
- defaultMessage=' Show this command in autocomplete list'
+ 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_desc'
- defaultMessage='Auto Complete 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>
+
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.auto_complete_hint'
- defaultMessage='Auto Complete Hint: '
+ defaultMessage='Autocomplete Hint: '
/>
</label>
<div className='padding-top'>
@@ -581,64 +601,60 @@ export default class ManageCommandCmds extends React.Component {
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.auto_complete_hint_desc'
- defaultMessage='List parameters to be passed to the command.'
+ 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.request_type'
- defaultMessage='Request Type: '
+ id='user.settings.cmds.auto_complete_desc'
+ defaultMessage='Autocomplete Description: '
/>
</label>
<div className='padding-top'>
- <select
- ref='method'
+ <input
+ ref='autoCompleteDesc'
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>
+ 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.request_type_desc'
- defaultMessage='Command request type issued to the callback URL.'
+ 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.url'
- defaultMessage='URL: '
+ id='user.settings.cmds.display_name'
+ defaultMessage='Descriptive Label: '
/>
</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)}
- />
+ <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.url_desc'
- defaultMessage='URL that will receive the HTTP POST or GET event'
+ 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'}
diff --git a/web/react/components/user_settings/user_settings_integrations.jsx b/web/react/components/user_settings/user_settings_integrations.jsx
index 1a9edab03..07d5230d1 100644
--- a/web/react/components/user_settings/user_settings_integrations.jsx
+++ b/web/react/components/user_settings/user_settings_integrations.jsx
@@ -28,11 +28,11 @@ const holders = defineMessages({
},
cmdName: {
id: 'user.settings.integrations.commands',
- defaultMessage: 'Commands'
+ defaultMessage: 'Slash Commands'
},
cmdDesc: {
id: 'user.settings.integrations.commandsDescription',
- defaultMessage: 'Manage your commands'
+ defaultMessage: 'Manage your slash commands'
}
});
diff --git a/web/react/components/user_settings/user_settings_modal.jsx b/web/react/components/user_settings/user_settings_modal.jsx
index e0b72157b..a7541073e 100644
--- a/web/react/components/user_settings/user_settings_modal.jsx
+++ b/web/react/components/user_settings/user_settings_modal.jsx
@@ -113,6 +113,7 @@ class UserSettingsModal extends React.Component {
return false;
}
+ this.resetTheme();
this.deactivateTab();
this.props.onModalDismissed();
}
@@ -215,15 +216,19 @@ class UserSettingsModal extends React.Component {
this.showConfirmModal(() => this.updateSection(section, true));
} else {
if (this.state.active_section === 'theme' && section !== 'theme') {
- const user = UserStore.getCurrentUser();
- if (user.theme_props != null) {
- Utils.applyTheme(user.theme_props);
- }
+ this.resetTheme();
}
this.setState({active_section: section});
}
}
+ resetTheme() {
+ const user = UserStore.getCurrentUser();
+ if (user.theme_props != null) {
+ Utils.applyTheme(user.theme_props);
+ }
+ }
+
render() {
const {formatMessage} = this.props.intl;
var tabs = [];
@@ -234,7 +239,7 @@ 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') {
+ if (global.window.mm_config.EnableIncomingWebhooks === 'true' || global.window.mm_config.EnableOutgoingWebhooks === 'true' || global.window.mm_config.EnableCommands === 'true') {
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'});
diff --git a/web/react/stores/channel_store.jsx b/web/react/stores/channel_store.jsx
index d650b23c2..ac800a988 100644
--- a/web/react/stores/channel_store.jsx
+++ b/web/react/stores/channel_store.jsx
@@ -308,7 +308,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
ChannelStore.storeChannels(action.channels);
ChannelStore.storeChannelMembers(action.members);
currentId = ChannelStore.getCurrentId();
- if (currentId) {
+ if (currentId && !document.hidden) {
ChannelStore.resetCounts(currentId);
}
ChannelStore.setUnreadCounts();
@@ -321,7 +321,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
ChannelStore.pStoreChannelMember(action.member);
}
currentId = ChannelStore.getCurrentId();
- if (currentId) {
+ if (currentId && !document.hidden) {
ChannelStore.resetCounts(currentId);
}
ChannelStore.setUnreadCount(action.channel.id);
diff --git a/web/react/stores/socket_store.jsx b/web/react/stores/socket_store.jsx
index bc2bdbe64..e1b65fe14 100644
--- a/web/react/stores/socket_store.jsx
+++ b/web/react/stores/socket_store.jsx
@@ -188,7 +188,9 @@ function handleNewPostEvent(msg, translations) {
// Update channel state
if (ChannelStore.getCurrentId() === msg.channel_id) {
- if (window.isActive) {
+ if (document.hidden) {
+ AsyncClient.getChannel(msg.channel_id);
+ } else {
AsyncClient.updateLastViewedAt();
}
} else if (UserStore.getCurrentId() !== msg.user_id || post.type !== Constants.POST_TYPE_JOIN_LEAVE) {
diff --git a/web/react/utils/async_client.jsx b/web/react/utils/async_client.jsx
index d5fc10b8f..c8676f45d 100644
--- a/web/react/utils/async_client.jsx
+++ b/web/react/utils/async_client.jsx
@@ -779,13 +779,19 @@ export function getSuggestedCommands(command, suggestionId, component) {
var matches = [];
data.forEach((cmd) => {
if (('/' + cmd.trigger).indexOf(command) === 0) {
+ let s = '/' + cmd.trigger;
+ if (cmd.auto_complete_hint && cmd.auto_complete_hint.length !== 0) {
+ s += ' ' + cmd.auto_complete_hint;
+ }
matches.push({
- suggestion: '/' + cmd.trigger + ' ' + cmd.auto_complete_hint,
+ suggestion: s,
description: cmd.auto_complete_desc
});
}
});
+ matches = matches.sort((a, b) => a.suggestion.localeCompare(b.suggestion));
+
// pull out the suggested commands from the returned data
const terms = matches.map((suggestion) => suggestion.suggestion);
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx
index 0a055d55c..428549d57 100644
--- a/web/react/utils/constants.jsx
+++ b/web/react/utils/constants.jsx
@@ -174,6 +174,7 @@ export default {
MENU_ICON: "<svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='4px' height='16px' viewBox='0 0 8 32' enable-background='new 0 0 8 32' xml:space='preserve'> <g> <circle cx='4' cy='4.062' r='4'/> <circle cx='4' cy='16' r='4'/> <circle cx='4' cy='28' r='4'/> </g> </svg>",
COMMENT_ICON: "<svg version='1.1' id='Layer_2' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='15px' height='15px' viewBox='1 1.5 15 15' enable-background='new 1 1.5 15 15' xml:space='preserve'> <g> <g> <path fill='#211B1B' d='M14,1.5H3c-1.104,0-2,0.896-2,2v8c0,1.104,0.896,2,2,2h1.628l1.884,3l1.866-3H14c1.104,0,2-0.896,2-2v-8 C16,2.396,15.104,1.5,14,1.5z M15,11.5c0,0.553-0.447,1-1,1H8l-1.493,2l-1.504-1.991L5,12.5H3c-0.552,0-1-0.447-1-1v-8 c0-0.552,0.448-1,1-1h11c0.553,0,1,0.448,1,1V11.5z'/> </g> </g> </svg>",
REPLY_ICON: "<svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'viewBox='-158 242 18 18' style='enable-background:new -158 242 18 18;' xml:space='preserve'> <path d='M-142.2,252.6c-2-3-4.8-4.7-8.3-4.8v-3.3c0-0.2-0.1-0.3-0.2-0.3s-0.3,0-0.4,0.1l-6.9,6.2c-0.1,0.1-0.1,0.2-0.1,0.3 c0,0.1,0,0.2,0.1,0.3l6.9,6.4c0.1,0.1,0.3,0.1,0.4,0.1c0.1-0.1,0.2-0.2,0.2-0.4v-3.8c4.2,0,7.4,0.4,9.6,4.4c0.1,0.1,0.2,0.2,0.3,0.2 c0,0,0.1,0,0.1,0c0.2-0.1,0.3-0.3,0.2-0.4C-140.2,257.3-140.6,255-142.2,252.6z M-150.8,252.5c-0.2,0-0.4,0.2-0.4,0.4v3.3l-6-5.5 l6-5.3v2.8c0,0.2,0.2,0.4,0.4,0.4c3.3,0,6,1.5,8,4.5c0.5,0.8,0.9,1.6,1.2,2.3C-144,252.8-147.1,252.5-150.8,252.5z'/> </svg>",
+ SCROLL_BOTTOM_ICON: "<svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'viewBox='-239 239 21 23' style='enable-background:new -239 239 21 23;' xml:space='preserve'> <path d='M-239,241.4l2.4-2.4l8.1,8.2l8.1-8.2l2.4,2.4l-10.5,10.6L-239,241.4z M-228.5,257.2l8.1-8.2l2.4,2.4l-10.5,10.6l-10.5-10.6 l2.4-2.4L-228.5,257.2z'/> </svg>",
UPDATE_TYPING_MS: 5000,
THEMES: {
default: {
diff --git a/web/react/utils/markdown.jsx b/web/react/utils/markdown.jsx
index 47b3a9a66..8b3602a89 100644
--- a/web/react/utils/markdown.jsx
+++ b/web/react/utils/markdown.jsx
@@ -151,6 +151,10 @@ class MattermostMarkdownRenderer extends marked.Renderer {
);
}
+ codespan(text) {
+ return '<pre class="text-nowrap">' + super.codespan(text) + '</pre>';
+ }
+
br() {
if (this.formattingOptions.singleline) {
return ' ';
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 896a94ac5..e2a5b9620 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -392,6 +392,10 @@ export function areObjectsEqual(x, y) {
return x.toString() === y.toString();
}
+ if (x instanceof Map && y instanceof Map) {
+ return areMapsEqual(x, y);
+ }
+
// At last checking prototypes as good a we can
if (!(x instanceof Object && y instanceof Object)) {
return false;
@@ -456,6 +460,24 @@ export function areObjectsEqual(x, y) {
return true;
}
+export function areMapsEqual(a, b) {
+ if (a.size !== b.size) {
+ return false;
+ }
+
+ for (const [key, value] of a) {
+ if (!b.has(key)) {
+ return false;
+ }
+
+ if (!areObjectsEqual(value, b.get(key))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
export function replaceHtmlEntities(text) {
var tagsToReplace = {
'&amp;': '&',
@@ -680,6 +702,7 @@ export function applyTheme(theme) {
}
if (theme.centerChannelColor) {
+ changeCss('.post-list__arrows', 'fill:' + changeOpacity(theme.centerChannelColor, 0.3), 1);
changeCss('.sidebar--left, .sidebar--right .sidebar--right__header', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.app__content, .post-create__container .post-create-body .btn-file, .post-create__container .post-create-footer .msg-typing, .command-name, .modal .modal-content, .dropdown-menu, .popover, .mentions-name, .tip-overlay', 'color:' + theme.centerChannelColor, 1);
changeCss('#archive-link-home', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1);
diff --git a/web/sass-files/sass/partials/_markdown.scss b/web/sass-files/sass/partials/_markdown.scss
index 14e12ecd2..a08379ae1 100644
--- a/web/sass-files/sass/partials/_markdown.scss
+++ b/web/sass-files/sass/partials/_markdown.scss
@@ -39,6 +39,7 @@
padding: 4px 10px 5px 10px;
font-size: 13px;
opacity: 0.7;
+ z-index: 5;
}
.post__body {
@@ -53,6 +54,13 @@
code {
white-space: pre;
}
+ pre {
+ &.text-nowrap {
+ code {
+ white-space: nowrap;
+ }
+ }
+ }
}
.markdown__table {
background: #fff;
diff --git a/web/sass-files/sass/partials/_mentions.scss b/web/sass-files/sass/partials/_mentions.scss
index df6dd40a2..aa654e9e8 100644
--- a/web/sass-files/sass/partials/_mentions.scss
+++ b/web/sass-files/sass/partials/_mentions.scss
@@ -18,6 +18,13 @@
line-height: 36px;
font-size: 13px;
cursor: pointer;
+ white-space: nowrap;
+
+ .mention-align {
+ @include clearfix;
+ text-overflow: ellipsis;
+ width: calc(100% - 50px);
+ }
}
.mentions-text {
@@ -33,6 +40,15 @@
font-size: 20px;
text-align: center;
@include border-radius(32px);
+
+ .mention-align {
+ max-width: 80%;
+ overflow: hidden;
+ display: inline-block;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+
}
.mention-fullname {
diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss
index b451adb75..db99e840b 100644
--- a/web/sass-files/sass/partials/_modal.scss
+++ b/web/sass-files/sass/partials/_modal.scss
@@ -103,7 +103,7 @@
background: rgba(0, 0, 0, 0.1);
}
span {
- font-family: 'Open Sans', sans-serif;
+ font-family: 'Open Sans', sans-serif;
line-height: 10px;
}
}
@@ -170,6 +170,12 @@
overflow: hidden;
text-overflow: ellipsis;
}
+ .more-description {
+ @include opacity(0.7);
+ display: block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
tbody {
> tr {
&:hover td {
@@ -425,9 +431,9 @@
}
.modal-body.edit-modal-body {
- overflow: visible;
+ overflow: visible;
- .suggestion-content {
- max-height: 150px;
- }
+ .suggestion-content {
+ max-height: 150px;
+ }
}
diff --git a/web/sass-files/sass/partials/_popover.scss b/web/sass-files/sass/partials/_popover.scss
index 8a61758f1..bf762d2c9 100644
--- a/web/sass-files/sass/partials/_popover.scss
+++ b/web/sass-files/sass/partials/_popover.scss
@@ -150,6 +150,9 @@
}
.more-name {
margin-left: 6px;
+ max-width: 140px;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
}
}
diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss
index cc22cc913..323691d89 100644
--- a/web/sass-files/sass/partials/_post.scss
+++ b/web/sass-files/sass/partials/_post.scss
@@ -264,32 +264,37 @@ body.ios {
line-height: 25px;
margin-left: -60px;
-webkit-font-smoothing: initial;
- @include single-transition(all, 0.3s, ease);
+ @include single-transition(all, 0.6s, ease);
@include translateY(-45px);
@include opacity(0);
display: none;
&.scrolling {
- @include single-transition(all, 0.3s, ease);
@include translateY(0);
@include opacity(0.8);
}
}
.post-list__arrows {
- background: url('../images/postArrows.png') center;
- @include background-size(28px 28px);
background-repeat: no-repeat;
width: 40px;
height: 40px;
+ text-align: center;
+ fill: #444;
position: absolute;
bottom: 0;
- left: 10px;
+ left: 9px;
z-index: 50;
@include opacity(0);
- @include single-transition(all, 0.3s);
+ @include single-transition(all, 0.6s);
display: none;
+ svg {
+ color: inherit;
+ width: 28px;
+ height: 28px;
+ }
+
&.scrolling {
display: block;
@include opacity(1);
@@ -487,7 +492,7 @@ body.ios {
position: absolute;
top: -2px;
left: -7px;
- font-size: 11px;
+ font-size: 11px;
line-height: 37px;
@include opacity(0);
}
diff --git a/web/sass-files/sass/partials/_settings.scss b/web/sass-files/sass/partials/_settings.scss
index bf296e913..1bbec566c 100644
--- a/web/sass-files/sass/partials/_settings.scss
+++ b/web/sass-files/sass/partials/_settings.scss
@@ -223,6 +223,8 @@
.section-describe {
@include opacity(0.7);
white-space:pre;
+ @include clearfix;
+ text-overflow: ellipsis;
}
.divider-dark {
@@ -341,21 +343,6 @@ h3 {
@include border-radius(50px);
margin-right: 8px;
}
- .member-name {
- font-weight:500;
- display: block;
- max-width: 80%;
- overflow: hidden;
- text-overflow: ellipsis;
- }
-
- .member-email {
- color:darkgrey;
- display: block;
- max-width: 80%;
- overflow: hidden;
- text-overflow: ellipsis;
- }
}
.member-role, .member-drop {
diff --git a/web/static/i18n/en.json b/web/static/i18n/en.json
index b4a68425e..ade6462e9 100644
--- a/web/static/i18n/en.json
+++ b/web/static/i18n/en.json
@@ -148,7 +148,6 @@
"admin.gitlab.userTitle": "User API Endpoint:",
"admin.gitlab.userDescription": "Enter https://<your-gitlab-url>/api/v3/user. Make sure you use HTTP or HTTPS in your URL depending on your server configuration.",
"admin.gitlab.save": "Save",
- "admin.image.storeDisabled": "Disable File Storage",
"admin.image.storeLocal": "Local File System",
"admin.image.storeAmazonS3": "Amazon S3",
"admin.image.localExample": "Ex \"./data/\"",
@@ -580,7 +579,7 @@
"delete_post.comment": "Comment",
"delete_post.post": "Post",
"delete_post.confirm": "Confirm {term} Delete",
- "delete_post.question": "Are you sure you want to delete this ${term}?",
+ "delete_post.question": "Are you sure you want to delete this {term}?",
"delete_post.cancel": "Cancel",
"delete_post.del": "Delete",
"edit_channel_header_modal.error": "This channel header is too long, please enter a shorter one",
@@ -902,6 +901,7 @@
"signup_user_completed.choosePwd": "Choose your password",
"signup_user_completed.create": "Create Account",
"signup_user_completed.or": "or",
+ "signup_user_completed.none": "No user creation method has been enabled. Please contact an administrator for access.",
"signup_user_completed.welcome": "Welcome to:",
"signup_user_completed.onSite": "on {siteName}",
"signup_user_completed.lets": "Let's create your account",
@@ -1063,37 +1063,38 @@
"user.settings.import_theme.submit": "Submit",
"user.settings.cmds.request_type_post": "POST",
"user.settings.cmds.request_type_get": "GET",
- "user.settings.cmds.add_display_name.placeholder": "Display Name",
+ "user.settings.cmds.add_display_name.placeholder": "Example: \"Search patient records\"",
"user.settings.cmds.add_username.placeholder": "Username",
"user.settings.cmds.add_trigger.placeholder": "Command trigger e.g. \"hello\" not including the slash",
- "user.settings.cmds.auto_complete_desc.placeholder": "A short description of what this commands does.",
- "user.settings.cmds.auto_complete_hint.placeholder": "[zipcode]",
+ "user.settings.cmds.auto_complete_desc.placeholder": "Example: \"Returns search results for patient records\"",
+ "user.settings.cmds.auto_complete_hint.placeholder": "Example: [Patient Name]",
+ "user.settings.cmds.auto_complete_desc_desc": "Optional short description of slash command for the autocomplete list.",
"user.settings.cmds.url.placeholder": "Must start with http:// or https://",
"user.settings.cmds.auto_complete.yes": "yes",
"user.settings.cmds.auto_complete.no": "no",
- "user.settings.cmds.trigger": "Trigger: ",
- "user.settings.cmds.display_name": "Display Name: ",
- "user.settings.cmds.username": "Username: ",
- "user.settings.cmds.icon_url": "Icon URL: ",
- "user.settings.cmds.auto_complete": "Auto Complete: ",
- "user.settings.cmds.auto_complete_desc": "Auto Complete Description: ",
- "user.settings.cmds.auto_complete_hint": "Auto Complete Hint: ",
- "user.settings.cmds.request_type": "Request Type: ",
- "user.settings.cmds.url": "URL: ",
+ "user.settings.cmds.trigger": "Command Trigger Word: ",
+ "user.settings.cmds.display_name": "Descriptive Label: ",
+ "user.settings.cmds.username": "Response Username: ",
+ "user.settings.cmds.icon_url": "Response Icon: ",
+ "user.settings.cmds.auto_complete": "Autocomplete: ",
+ "user.settings.cmds.auto_complete_desc": "Autocomplete Description: ",
+ "user.settings.cmds.auto_complete_hint": "Autocomplete Hint: ",
+ "user.settings.cmds.request_type": "Request Method: ",
+ "user.settings.cmds.url": "Request URL: ",
"user.settings.cmds.token": "Token: ",
"user.settings.cmds.regen": "Regen Token",
"user.settings.cmds.none": "None",
"user.settings.cmds.existing": "Existing commands",
- "user.settings.cmds.add_desc": "Create commands to send message events to an external integration. Please see <a href=\"http://mattermost.org/commands\">http://mattermost.org/commands</a> to learn more.",
+ "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.",
"user.settings.cmds.add_new": "Add a new command",
- "user.settings.cmds.cmd_display_name": "Command display name.",
- "user.settings.cmds.username_desc": "The username to use when overriding the post.",
- "user.settings.cmds.icon_url_desc": "URL to an icon",
- "user.settings.cmds.trigger_desc": "Word to trigger on",
- "user.settings.cmds.auto_complete_help": "Show this command in autocomplete list",
- "user.settings.cmds.auto_complete_hint_desc": "List parameters to be passed to the command.",
- "user.settings.cmds.request_type_desc": "Command request type issued to the callback URL.",
- "user.settings.cmds.url_desc": "URL that will receive the HTTP POST or GET event",
+ "user.settings.cmds.cmd_display_name": "Brief description of slash command to show in listings.",
+ "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.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.trigger_desc": "Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug",
+ "user.settings.cmds.auto_complete_help": " Show this command in the autocomplete list.",
+ "user.settings.cmds.auto_complete_hint_desc": "Optional hint in the autocomplete list about parameters needed for command.",
+ "user.settings.cmds.request_type_desc": "The type of command request issued to the Request URL.",
+ "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.add": "Add",
"user.settings.hooks_in.channel": "Channel: ",
"user.settings.hooks_in.none": "None",
@@ -1183,8 +1184,8 @@
"user.settings.integrations.incomingWebhooksDescription": "Manage your incoming webhooks",
"user.settings.integrations.outWebhooks": "Outgoing Webhooks",
"user.settings.integrations.outWebhooksDescription": "Manage your outgoing webhooks",
- "user.settings.integrations.commands": "Commands",
- "user.settings.integrations.commandsDescription": "Manage your commands",
+ "user.settings.integrations.commands": "Slash Commands",
+ "user.settings.integrations.commandsDescription": "Manage your slash commands",
"user.settings.integrations.title": "Integration Settings",
"user.settings.modal.general": "General",
"user.settings.modal.security": "Security",
diff --git a/web/static/i18n/es.json b/web/static/i18n/es.json
index a3c7e13a7..e4ddd76ce 100644
--- a/web/static/i18n/es.json
+++ b/web/static/i18n/es.json
@@ -157,7 +157,6 @@
"admin.image.shareDescription": "Permitir a los usuarios compartir enlaces públicos para archivos e imágenes.",
"admin.image.shareTitle": "Compartir publicamente enlaces de archivos: ",
"admin.image.storeAmazonS3": "Amazon S3",
- "admin.image.storeDisabled": "Deshabilitar almacenamiento de archivos",
"admin.image.storeLocal": "Sistema local de archivos",
"admin.image.storeTitle": "Almacenar archivos en:",
"admin.image.thumbHeightDescription": "Alto de imágen miniatura subida. Actualizando este valor la imagen miniatura cambia en el futuro, pero no cambia para imagenes creadas en el pasado.",
@@ -933,6 +932,7 @@
"signup_user_completed.gitlab": "con GitLab",
"signup_user_completed.google": "con Google",
"signup_user_completed.lets": "Vamos a crear tu cuenta",
+ "signup_user_completed.none": "No está habilitado ningún método para crear usuarios. Por favor contacta a un administrador para obtener acceso.",
"signup_user_completed.onSite": "en {siteName}",
"signup_user_completed.or": "o",
"signup_user_completed.passwordLength": "Por favor ingresa al menos {min} caracteres",
@@ -1058,39 +1058,19 @@
"user.settings.advance.sendTitle": "Enviar mensajes con Ctrl + Retorno",
"user.settings.advance.title": "Configuración Avanzada",
"user.settings.cmds.add": "Agregar",
- "user.settings.cmds.add_desc": "Crea comandos que permitan enviar eventos a integraciones externas. Por favor revisa <a href=\"http://mattermost.org/commands\">http://mattermost.org/commands</a> para aprender más.",
- "user.settings.cmds.add_display_name.placeholder": "Nombre a mostrar",
"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": "Auto completado: ",
"user.settings.cmds.auto_complete.no": "no",
"user.settings.cmds.auto_complete.yes": "sí",
- "user.settings.cmds.auto_complete_desc": "Descripción del Auto Completado: ",
- "user.settings.cmds.auto_complete_desc.placeholder": "Una pequeña descripción de que hace el comando.",
"user.settings.cmds.auto_complete_help": "Mostrar este comando en la lista de auto completado.",
- "user.settings.cmds.auto_complete_hint": "Pista de auto completado: ",
- "user.settings.cmds.auto_complete_hint.placeholder": "[código postal]",
- "user.settings.cmds.auto_complete_hint_desc": "Lista de parámetros que recibe el comando.",
- "user.settings.cmds.cmd_display_name": "Nombre a mostrar del Comando.",
- "user.settings.cmds.display_name": "Nombre a mostrar: ",
"user.settings.cmds.existing": "Comandos existentes",
- "user.settings.cmds.icon_url": "URL del icono: ",
- "user.settings.cmds.icon_url_desc": "URL para un icono",
"user.settings.cmds.none": "Ninguno",
"user.settings.cmds.regen": "Regenerar Token",
- "user.settings.cmds.request_type": "Tipo de Solicitud: ",
- "user.settings.cmds.request_type_desc": "Tipo de solicitud emitido al callback URL por el Comando.",
"user.settings.cmds.request_type_get": "GET",
"user.settings.cmds.request_type_post": "POST",
"user.settings.cmds.token": "Token: ",
- "user.settings.cmds.trigger": "Gatillador: ",
- "user.settings.cmds.trigger_desc": "Palabra que gatilla la acción",
- "user.settings.cmds.url": "URL: ",
"user.settings.cmds.url.placeholder": "Debe comenzar con http:// o https://",
- "user.settings.cmds.url_desc": "URL que va a recibir el evento HTTP POST o GET",
- "user.settings.cmds.username": "Nombre de usuario: ",
- "user.settings.cmds.username_desc": "El nombre de usuario a utilizar cuando se genere el mensaje.",
"user.settings.custom_theme.awayIndicator": "Indicador Ausente",
"user.settings.custom_theme.buttonBg": "Fondo Botón",
"user.settings.custom_theme.buttonColor": "Texto Botón",
@@ -1193,8 +1173,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",
- "user.settings.integrations.commandsDescription": "Administra tus comandos",
"user.settings.integrations.incomingWebhooks": "Webhooks de entrada",
"user.settings.integrations.incomingWebhooksDescription": "Administra tus webhooks de entrada",
"user.settings.integrations.outWebhooks": "Webhooks de salida",
diff --git a/web/static/images/postArrows.png b/web/static/images/postArrows.png
deleted file mode 100644
index 7b5919fc3..000000000
--- a/web/static/images/postArrows.png
+++ /dev/null
Binary files differ