diff options
Diffstat (limited to 'webapp/components')
11 files changed, 55 insertions, 49 deletions
diff --git a/webapp/components/admin_console/ldap_test_button.jsx b/webapp/components/admin_console/ldap_test_button.jsx index 082c13b1b..16a433c23 100644 --- a/webapp/components/admin_console/ldap_test_button.jsx +++ b/webapp/components/admin_console/ldap_test_button.jsx @@ -71,7 +71,7 @@ export default class LdapTestButton extends React.Component { <i className='fa fa-warning'/> <FormattedMessage id='admin.ldap.testFailure' - defaultMessage='LDAP Test Failure: {error}' + defaultMessage='AD/LDAP Test Failure: {error}' values={{ error: this.state.fail }} @@ -86,7 +86,7 @@ export default class LdapTestButton extends React.Component { <i className='fa fa-success'/> <FormattedMessage id='admin.ldap.testSuccess' - defaultMessage='LDAP Test Successful' + defaultMessage='AD/LDAP Test Successful' values={{ error: this.state.fail }} @@ -99,7 +99,7 @@ export default class LdapTestButton extends React.Component { let helpText = ( <FormattedHTMLMessage id='admin.ldap.testHelpText' - defaultMessage='Tests if the Mattermost server can connect to the LDAP server specified. See log file for more detailed error messages.' + defaultMessage='Tests if the Mattermost server can connect to the AD/LDAP server specified. See log file for more detailed error messages.' /> ); @@ -115,7 +115,7 @@ export default class LdapTestButton extends React.Component { contents = ( <FormattedMessage id='admin.ldap.ldap_test_button' - defaultMessage='LDAP Test' + defaultMessage='AD/LDAP Test' /> ); } diff --git a/webapp/components/admin_console/password_settings.jsx b/webapp/components/admin_console/password_settings.jsx index 1ebcc7707..ad805b38c 100644 --- a/webapp/components/admin_console/password_settings.jsx +++ b/webapp/components/admin_console/password_settings.jsx @@ -22,6 +22,8 @@ export default class PasswordSettings extends AdminSettings { this.getSampleErrorMsg = this.getSampleErrorMsg.bind(this); + this.handlePasswordLengthChange = this.handlePasswordLengthChange.bind(this); + this.state = Object.assign(this.state, { passwordMinimumLength: props.config.PasswordSettings.MinimumLength, passwordLowercase: props.config.PasswordSettings.Lowercase, @@ -54,17 +56,13 @@ export default class PasswordSettings extends AdminSettings { id={sampleErrorMsgId} default='Your password must be at least {min} characters.' values={{ - min: props.config.PasswordSettings.MinimumLength + min: (this.state.passwordMinimumLength || Constants.MIN_PASSWORD_LENGTH) }} /> ); } } - componentWillUpdate() { - this.sampleErrorMsg = this.getSampleErrorMsg(); - } - getConfigFromState(config) { if (global.window.mm_license.IsLicensed === 'true' && global.window.mm_license.PasswordRequirements === 'true') { config.PasswordSettings.MinimumLength = this.parseIntNonZero(this.state.passwordMinimumLength, Constants.MIN_PASSWORD_LENGTH); @@ -96,7 +94,7 @@ export default class PasswordSettings extends AdminSettings { }; } - getSampleErrorMsg() { + getSampleErrorMsg(minLength) { if (global.window.mm_license.IsLicensed === 'true' && global.window.mm_license.PasswordRequirements === 'true') { if (this.props.config.PasswordSettings.MinimumLength > Constants.MAX_PASSWORD_LENGTH || this.props.config.PasswordSettings.MinimumLength < Constants.MIN_PASSWORD_LENGTH) { return ( @@ -106,7 +104,6 @@ export default class PasswordSettings extends AdminSettings { /> ); } - let sampleErrorMsgId = 'user.settings.security.passwordError'; if (this.refs.lowercase.checked) { sampleErrorMsgId = sampleErrorMsgId + 'Lowercase'; @@ -125,7 +122,7 @@ export default class PasswordSettings extends AdminSettings { id={sampleErrorMsgId} default='Your password must be at least {min} characters.' values={{ - min: this.props.config.PasswordSettings.MinimumLength + min: (minLength || Constants.MIN_PASSWORD_LENGTH) }} /> ); @@ -134,6 +131,11 @@ export default class PasswordSettings extends AdminSettings { return null; } + handlePasswordLengthChange(id, value) { + this.sampleErrorMsg = this.getSampleErrorMsg(value); + this.handleChange(id, value); + } + renderTitle() { return ( <h3> @@ -193,7 +195,7 @@ export default class PasswordSettings extends AdminSettings { /> } value={this.state.passwordMinimumLength} - onChange={this.handleChange} + onChange={this.handlePasswordLengthChange} /> <Setting label={ diff --git a/webapp/components/filtered_user_list.jsx b/webapp/components/filtered_user_list.jsx index 67d038fd9..2f9a50d24 100644 --- a/webapp/components/filtered_user_list.jsx +++ b/webapp/components/filtered_user_list.jsx @@ -3,6 +3,7 @@ import $ from 'jquery'; import ReactDOM from 'react-dom'; +import * as UserAgent from 'utils/user_agent.jsx'; import UserList from './user_list.jsx'; import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl'; @@ -60,7 +61,10 @@ class FilteredUserList extends React.Component { } componentDidMount() { - ReactDOM.findDOMNode(this.refs.filter).focus(); + // only focus the search box on desktop so that we don't cause the keyboard to open on mobile + if (!UserAgent.isMobileApp()) { + ReactDOM.findDOMNode(this.refs.filter).focus(); + } } componentDidUpdate(prevProps, prevState) { diff --git a/webapp/components/integrations/components/add_command.jsx b/webapp/components/integrations/components/add_command.jsx index d71fb7c3f..e01358aa7 100644 --- a/webapp/components/integrations/components/add_command.jsx +++ b/webapp/components/integrations/components/add_command.jsx @@ -166,7 +166,7 @@ export default class AddCommand extends React.Component { AsyncClient.addCommand( command, (data) => { - browserHistory.push('/' + this.props.team.name + '/integrations/confirm?type=commands&id=' + data.token); + browserHistory.push('/' + this.props.team.name + '/integrations/confirm?type=commands&id=' + data.id); }, (err) => { this.setState({ diff --git a/webapp/components/integrations/components/add_outgoing_webhook.jsx b/webapp/components/integrations/components/add_outgoing_webhook.jsx index bf0d327ef..c3d9b0933 100644 --- a/webapp/components/integrations/components/add_outgoing_webhook.jsx +++ b/webapp/components/integrations/components/add_outgoing_webhook.jsx @@ -120,7 +120,7 @@ export default class AddOutgoingWebhook extends React.Component { AsyncClient.addOutgoingHook( hook, (data) => { - browserHistory.push('/' + this.props.team.name + '/integrations/confirm?type=outgoing_webhooks&id=' + data.token); + browserHistory.push('/' + this.props.team.name + '/integrations/confirm?type=outgoing_webhooks&id=' + data.id); }, (err) => { this.setState({ diff --git a/webapp/components/integrations/components/confirm_integration.jsx b/webapp/components/integrations/components/confirm_integration.jsx index bb26a9a8a..b9274f2e4 100644 --- a/webapp/components/integrations/components/confirm_integration.jsx +++ b/webapp/components/integrations/components/confirm_integration.jsx @@ -5,8 +5,7 @@ import React from 'react'; import BackstageHeader from 'components/backstage/components/backstage_header.jsx'; import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; -import {browserHistory, Link} from 'react-router/es6'; -import SpinnerButton from 'components/spinner_button.jsx'; +import {Link} from 'react-router/es6'; import UserStore from 'stores/user_store.jsx'; import IntegrationStore from 'stores/integration_store.jsx'; @@ -24,8 +23,6 @@ export default class ConfirmIntegration extends React.Component { constructor(props) { super(props); - this.handleDone = this.handleDone.bind(this); - this.handleIntegrationChange = this.handleIntegrationChange.bind(this); const userId = UserStore.getCurrentId(); @@ -55,13 +52,6 @@ export default class ConfirmIntegration extends React.Component { }); } - handleDone() { - browserHistory.push('/' + this.props.team.name + '/integrations/' + this.state.type); - this.setState({ - id: '' - }); - } - render() { let headerText = null; let helpText = null; @@ -87,7 +77,7 @@ export default class ConfirmIntegration extends React.Component { id='add_command.token' defaultMessage='<b>Token</b>: {token}' values={{ - token: this.state.id + token: IntegrationStore.getCommand(this.props.team.id, this.state.id).token }} /> </p> @@ -139,7 +129,7 @@ export default class ConfirmIntegration extends React.Component { id='add_outgoing_webhook.token' defaultMessage='<b>Token</b>: {token}' values={{ - token: this.state.id + token: IntegrationStore.getOutgoingWebhook(this.props.team.id, this.state.id).token }} /> </p> @@ -233,16 +223,16 @@ export default class ConfirmIntegration extends React.Component { {helpText} {tokenText} <div className='backstage-form__footer'> - <SpinnerButton + <Link className='btn btn-primary' type='submit' - onClick={this.handleDone} + to={'/' + this.props.team.name + '/integrations/' + this.state.type} > <FormattedMessage id='integrations.done' defaultMessage='Done' /> - </SpinnerButton> + </Link> </div> </div> </div> diff --git a/webapp/components/login/login_controller.jsx b/webapp/components/login/login_controller.jsx index 8335dce6f..117747ab9 100644 --- a/webapp/components/login/login_controller.jsx +++ b/webapp/components/login/login_controller.jsx @@ -459,6 +459,17 @@ export default class LoginController extends React.Component { ); } + if (gitlabSigninEnabled || samlSigninEnabled || office365SigninEnabled || googleSigninEnabled || gitlabSigninEnabled) { + loginControls.push( + <h5 key='oauthHeader'> + <FormattedMessage + id='login.signInWith' + defaultMessage='Sign in with:' + /> + </h5> + ); + } + if (gitlabSigninEnabled) { loginControls.push( <a diff --git a/webapp/components/suggestion/at_mention_provider.jsx b/webapp/components/suggestion/at_mention_provider.jsx index 87cdc6894..248e459b5 100644 --- a/webapp/components/suggestion/at_mention_provider.jsx +++ b/webapp/components/suggestion/at_mention_provider.jsx @@ -99,7 +99,7 @@ class AtMentionSuggestion extends Suggestion { } } -function filterUsersByPrefix(users, prefix, limit) { +function filterUsersByPrefix(users, prefix, limit, type) { const filtered = []; for (const id of Object.keys(users)) { @@ -117,7 +117,8 @@ function filterUsersByPrefix(users, prefix, limit) { (user.first_name && user.first_name.toLowerCase().startsWith(prefix)) || (user.last_name && user.last_name.toLowerCase().startsWith(prefix)) || (user.nickname && user.nickname.toLowerCase().startsWith(prefix))) { - filtered.push(user); + // create a new object here since we're mutating it by adding the type field + filtered.push(Object.assign({}, user, {type})); } } @@ -145,15 +146,15 @@ export default class AtMentionProvider { // Filter users by prefix. const filteredMembers = filterUsersByPrefix( - channelMembers, prefix, MaxUserSuggestions); + channelMembers, prefix, MaxUserSuggestions, Constants.MENTION_MEMBERS); const filteredNonmembers = filterUsersByPrefix( - channelNonmembers, prefix, MaxUserSuggestions - filteredMembers.length); + channelNonmembers, prefix, MaxUserSuggestions - filteredMembers.length, Constants.MENTION_NONMEMBERS); let filteredSpecialMentions = []; if (!pretext.startsWith('/msg')) { filteredSpecialMentions = ['here', 'channel', 'all'].filter((item) => { return item.startsWith(prefix); }).map((name) => { - return {username: name}; + return {username: name, type: Constants.MENTION_SPECIAL}; }); } @@ -173,16 +174,6 @@ export default class AtMentionProvider { }); }); - filteredMembers.forEach((item) => { - item.type = Constants.MENTION_MEMBERS; - }); - filteredNonmembers.forEach((item) => { - item.type = Constants.MENTION_NONMEMBERS; - }); - filteredSpecialMentions.forEach((item) => { - item.type = Constants.MENTION_SPECIAL; - }); - const filtered = filteredMembers.concat(filteredSpecialMentions).concat(filteredNonmembers); const mentions = filtered.map((user) => '@' + user.username); diff --git a/webapp/components/suggestion/suggestion_box.jsx b/webapp/components/suggestion/suggestion_box.jsx index d4b150787..d74038ead 100644 --- a/webapp/components/suggestion/suggestion_box.jsx +++ b/webapp/components/suggestion/suggestion_box.jsx @@ -189,6 +189,7 @@ export default class SuggestionBox extends React.Component { <SuggestionListComponent suggestionId={this.suggestionId} location={this.props.listStyle} + renderDividers={this.props.renderDividers} /> </div> ); @@ -220,6 +221,7 @@ SuggestionBox.propTypes = { value: React.PropTypes.string.isRequired, providers: React.PropTypes.arrayOf(React.PropTypes.object), listStyle: React.PropTypes.string, + renderDividers: React.PropTypes.bool, // explicitly name any input event handlers we override and need to manually call onInput: React.PropTypes.func, diff --git a/webapp/components/suggestion/suggestion_list.jsx b/webapp/components/suggestion/suggestion_list.jsx index 7c746ac2a..7d8059e1e 100644 --- a/webapp/components/suggestion/suggestion_list.jsx +++ b/webapp/components/suggestion/suggestion_list.jsx @@ -121,7 +121,7 @@ export default class SuggestionList extends React.Component { // ReactComponent names need to be upper case when used in JSX const Component = this.state.components[i]; - if (item.type !== lastType) { + if (this.props.renderDividers && item.type !== lastType) { items.push(this.renderDivider(item.type)); lastType = item.type; } @@ -157,5 +157,10 @@ export default class SuggestionList extends React.Component { SuggestionList.propTypes = { suggestionId: React.PropTypes.string.isRequired, - location: React.PropTypes.string + location: React.PropTypes.string, + renderDividers: React.PropTypes.bool }; + +SuggestionList.defaultProps = { + renderDividers: false +};
\ No newline at end of file diff --git a/webapp/components/textbox.jsx b/webapp/components/textbox.jsx index fac1bd027..12f111833 100644 --- a/webapp/components/textbox.jsx +++ b/webapp/components/textbox.jsx @@ -198,6 +198,7 @@ export default class Textbox extends React.Component { providers={this.suggestionProviders} channelId={this.props.channelId} value={this.props.messageText} + renderDividers={true} /> <div ref='preview' |