diff options
Diffstat (limited to 'web/react/components/user_settings')
4 files changed, 153 insertions, 6 deletions
diff --git a/web/react/components/user_settings/manage_languages.jsx b/web/react/components/user_settings/manage_languages.jsx new file mode 100644 index 000000000..123165b76 --- /dev/null +++ b/web/react/components/user_settings/manage_languages.jsx @@ -0,0 +1,101 @@ +// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +// See License.txt for license information. + +import * as Client from '../../utils/client.jsx'; +import * as Utils from '../../utils/utils.jsx'; + +export default class ManageLanguage extends React.Component { + constructor(props) { + super(props); + + this.setupInitialState = this.setupInitialState.bind(this); + this.setLanguage = this.setLanguage.bind(this); + this.changeLanguage = this.changeLanguage.bind(this); + this.submitUser = this.submitUser.bind(this); + this.state = this.setupInitialState(props); + } + setupInitialState(props) { + var user = props.user; + return { + languages: Utils.languages(), + locale: user.locale + }; + } + setLanguage(e) { + this.setState({locale: e.target.value}); + } + changeLanguage(e) { + e.preventDefault(); + + var user = this.props.user; + var locale = this.state.locale; + + user.locale = locale; + + this.submitUser(user); + } + submitUser(user) { + Client.updateUser(user, + () => { + window.location.reload(true); + }, + (err) => { + let serverError; + if (err.message) { + serverError = err.message; + } else { + serverError = err; + } + this.setState({serverError}); + } + ); + } + render() { + let serverError; + if (this.state.serverError) { + serverError = <label className='has-error'>{this.state.serverError}</label>; + } + + const options = []; + this.state.languages.forEach((lang) => { + options.push( + <option + key={lang.value} + value={lang.value} + > + {lang.name} + </option>); + }); + + return ( + <div key='changeLanguage'> + <br/> + <label className='control-label'>{'Change interface language'}</label> + <div className='padding-top'> + <select + ref='language' + className='form-control' + value={this.state.locale} + onChange={this.setLanguage} + > + {options} + </select> + {serverError} + <div className='padding-top'> + <a + className={'btn btn-sm btn-primary'} + href='#' + onClick={this.changeLanguage} + > + {'Set language'} + </a> + </div> + </div> + </div> + ); + } +} + +ManageLanguage.propTypes = { + user: React.PropTypes.object +};
\ No newline at end of file diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx index 1ff0a2913..f2c2502fb 100644 --- a/web/react/components/user_settings/user_settings_display.jsx +++ b/web/react/components/user_settings/user_settings_display.jsx @@ -5,7 +5,9 @@ import {savePreferences} from '../../utils/client.jsx'; import SettingItemMin from '../setting_item_min.jsx'; import SettingItemMax from '../setting_item_max.jsx'; import Constants from '../../utils/constants.jsx'; +const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES; import PreferenceStore from '../../stores/preference_store.jsx'; +import ManageLanguages from './manage_languages.jsx'; import * as Utils from '../../utils/utils.jsx'; function getDisplayStateFromStores() { @@ -78,6 +80,7 @@ export default class UserSettingsDisplay extends React.Component { let clockSection; let nameFormatSection; let fontSection; + let languagesSection; if (this.props.activeSection === 'clock') { const clockFormat = [false, false]; @@ -292,6 +295,48 @@ export default class UserSettingsDisplay extends React.Component { ); } + if (Utils.isFeatureEnabled(PreReleaseFeatures.LOC_PREVIEW)) { + if (this.props.activeSection === 'languages') { + var inputs = []; + inputs.push( + <ManageLanguages + user={this.props.user} + key='languages-ui' + /> + ); + + languagesSection = ( + <SettingItemMax + title={'Language'} + width='medium' + inputs={inputs} + updateSection={(e) => { + this.updateSection(''); + e.preventDefault(); + }} + /> + ); + } else { + var locale = 'English'; + Utils.languages().forEach((l) => { + if (l.value === this.props.user.locale) { + locale = l.name; + } + }); + + languagesSection = ( + <SettingItemMin + title={'Language'} + width='medium' + describe={locale} + updateSection={() => { + this.updateSection('languages'); + }} + /> + ); + } + } + return ( <div> <div className='modal-header'> @@ -324,6 +369,7 @@ export default class UserSettingsDisplay extends React.Component { <div className='divider-dark'/> {nameFormatSection} <div className='divider-dark'/> + {languagesSection} </div> </div> ); diff --git a/web/react/components/user_settings/user_settings_general.jsx b/web/react/components/user_settings/user_settings_general.jsx index 014038dd4..df7ae4a25 100644 --- a/web/react/components/user_settings/user_settings_general.jsx +++ b/web/react/components/user_settings/user_settings_general.jsx @@ -47,7 +47,7 @@ export default class UserSettingsGeneralTab extends React.Component { this.setState({clientError: 'This username is reserved, please choose a new one.'}); return; } else if (usernameError) { - this.setState({clientError: "Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'."}); + this.setState({clientError: 'Username must begin with a letter, and contain between ' + Constants.MIN_USERNAME_LENGTH + ' to ' + Constants.MAX_USERNAME_LENGTH + " lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'."}); return; } @@ -493,7 +493,7 @@ export default class UserSettingsGeneralTab extends React.Component { ); submit = this.submitEmail; - } else { + } else if (this.props.user.auth_service === Constants.GITLAB_SERVICE) { inputs.push( <div key='oauthEmailInfo' @@ -531,7 +531,7 @@ export default class UserSettingsGeneralTab extends React.Component { } else { describe = UserStore.getCurrentUser().email; } - } else { + } else if (this.props.user.auth_service === Constants.GITLAB_SERVICE) { describe = 'Log in done through GitLab'; } diff --git a/web/react/components/user_settings/user_settings_security.jsx b/web/react/components/user_settings/user_settings_security.jsx index d1266dd3f..5a21abd19 100644 --- a/web/react/components/user_settings/user_settings_security.jsx +++ b/web/react/components/user_settings/user_settings_security.jsx @@ -48,8 +48,8 @@ export default class SecurityTab extends React.Component { return; } - if (newPassword.length < 5) { - this.setState({passwordError: 'New passwords must be at least 5 characters', serverError: ''}); + if (newPassword.length < Constants.MIN_PASSWORD_LENGTH) { + this.setState({passwordError: 'New passwords must be at least ' + Constants.MIN_PASSWORD_LENGTH + ' characters', serverError: ''}); return; } @@ -337,7 +337,7 @@ export default class SecurityTab extends React.Component { className='security-links theme' dialogType={AccessHistoryModal} > - <i className='fa fa-clock-o'></i>View Access History + <i className='fa fa-clock-o'></i>{'View Access History'} </ToggleModalButton> <b> </b> <ToggleModalButton |