diff options
Diffstat (limited to 'web/react/components/user_settings')
8 files changed, 220 insertions, 57 deletions
diff --git a/web/react/components/user_settings/import_theme_modal.jsx b/web/react/components/user_settings/import_theme_modal.jsx index de0663874..1a9ac0ad3 100644 --- a/web/react/components/user_settings/import_theme_modal.jsx +++ b/web/react/components/user_settings/import_theme_modal.jsx @@ -35,7 +35,7 @@ export default class ImportThemeModal extends React.Component { handleSubmit(e) { e.preventDefault(); - const text = React.findDOMNode(this.refs.input).value; + const text = ReactDOM.findDOMNode(this.refs.input).value; if (!this.isInputValid(text)) { this.setState({inputError: 'Invalid format, please try copying and pasting in again.'}); diff --git a/web/react/components/user_settings/user_settings.jsx b/web/react/components/user_settings/user_settings.jsx index 5ce9b6330..15bf961d6 100644 --- a/web/react/components/user_settings/user_settings.jsx +++ b/web/react/components/user_settings/user_settings.jsx @@ -9,6 +9,7 @@ var GeneralTab = require('./user_settings_general.jsx'); var AppearanceTab = require('./user_settings_appearance.jsx'); var DeveloperTab = require('./user_settings_developer.jsx'); var IntegrationsTab = require('./user_settings_integrations.jsx'); +var DisplayTab = require('./user_settings_display.jsx'); export default class UserSettings extends React.Component { constructor(props) { @@ -98,6 +99,17 @@ export default class UserSettings extends React.Component { /> </div> ); + } else if (this.props.activeTab === 'display') { + return ( + <div> + <DisplayTab + user={this.state.user} + activeSection={this.props.activeSection} + updateSection={this.props.updateSection} + updateTab={this.props.updateTab} + /> + </div> + ); } return <div/>; diff --git a/web/react/components/user_settings/user_settings_appearance.jsx b/web/react/components/user_settings/user_settings_appearance.jsx index a16440d55..8c62a189d 100644 --- a/web/react/components/user_settings/user_settings_appearance.jsx +++ b/web/react/components/user_settings/user_settings_appearance.jsx @@ -29,14 +29,14 @@ export default class UserSettingsAppearance extends React.Component { UserStore.addChangeListener(this.onChange); if (this.props.activeSection === 'theme') { - $(React.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); + $(ReactDOM.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); } $('#user_settings').on('hidden.bs.modal', this.handleClose); } componentDidUpdate() { if (this.props.activeSection === 'theme') { $('.color-btn').removeClass('active-border'); - $(React.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); + $(ReactDOM.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); } } componentWillUnmount() { @@ -152,9 +152,8 @@ export default class UserSettingsAppearance extends React.Component { <input type='radio' checked={!displayCustom} onChange={this.updateType.bind(this, 'premade')} - > - {'Theme Colors'} - </input> + /> + {'Theme Colors'} </label> <br/> </div> @@ -164,9 +163,8 @@ export default class UserSettingsAppearance extends React.Component { <input type='radio' checked={displayCustom} onChange={this.updateType.bind(this, 'custom')} - > - {'Custom Theme'} - </input> + /> + {'Custom Theme'} </label> <br/> </div> diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx new file mode 100644 index 000000000..22a62273c --- /dev/null +++ b/web/react/components/user_settings/user_settings_display.jsx @@ -0,0 +1,165 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +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'; +import PreferenceStore from '../../stores/preference_store.jsx'; + +function getDisplayStateFromStores() { + const militaryTime = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', {value: 'false'}); + + return {militaryTime: militaryTime.value}; +} + +export default class UserSettingsDisplay extends React.Component { + constructor(props) { + super(props); + + this.handleSubmit = this.handleSubmit.bind(this); + this.handleClockRadio = this.handleClockRadio.bind(this); + this.updateSection = this.updateSection.bind(this); + this.handleClose = this.handleClose.bind(this); + + this.state = getDisplayStateFromStores(); + } + handleSubmit() { + const preference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime); + + savePreferences([preference], + () => { + PreferenceStore.emitChange(); + this.updateSection(''); + }, + (err) => { + this.setState({serverError: err.message}); + } + ); + } + handleClockRadio(militaryTime) { + this.setState({militaryTime}); + } + updateSection(section) { + this.setState(getDisplayStateFromStores()); + this.props.updateSection(section); + } + handleClose() { + this.updateSection(''); + } + componentDidMount() { + $('#user_settings').on('hidden.bs.modal', this.handleClose); + } + componentWillUnmount() { + $('#user_settings').off('hidden.bs.modal', this.handleClose); + } + render() { + const serverError = this.state.serverError || null; + let clockSection; + if (this.props.activeSection === 'clock') { + const clockFormat = [false, false]; + if (this.state.militaryTime === 'true') { + clockFormat[1] = true; + } else { + clockFormat[0] = true; + } + + const handleUpdateClockSection = (e) => { + this.updateSection(''); + e.preventDefault(); + }; + + const inputs = [ + <div key='userDisplayClockOptions'> + <div className='radio'> + <label> + <input + type='radio' + checked={clockFormat[0]} + onChange={this.handleClockRadio.bind(this, 'false')} + /> + {'12-hour clock (example: 4:00 PM)'} + </label> + <br/> + </div> + <div className='radio'> + <label> + <input + type='radio' + checked={clockFormat[1]} + onChange={this.handleClockRadio.bind(this, 'true')} + /> + {'24-hour clock (example: 16:00)'} + </label> + <br/> + </div> + <div><br/>{'Select how you prefer time displayed.'}</div> + </div> + ]; + + clockSection = ( + <SettingItemMax + title='Clock Display' + inputs={inputs} + submit={this.handleSubmit} + server_error={serverError} + updateSection={handleUpdateClockSection} + /> + ); + } else { + let describe = ''; + if (this.state.militaryTime === 'true') { + describe = '24-hour clock (example: 16:00)'; + } else { + describe = '12-hour clock (example: 4:00 PM)'; + } + + const handleUpdateClockSection = () => { + this.props.updateSection('clock'); + }; + + clockSection = ( + <SettingItemMin + title='Clock Display' + describe={describe} + updateSection={handleUpdateClockSection} + /> + ); + } + + return ( + <div> + <div className='modal-header'> + <button + type='button' + className='close' + data-dismiss='modal' + aria-label='Close' + > + <span aria-hidden='true'>{'×'}</span> + </button> + <h4 + className='modal-title' + ref='title' + > + <i className='modal-back'></i> + {'Display Settings'} + </h4> + </div> + <div className='user-settings'> + <h3 className='tab-header'>{'Display Settings'}</h3> + <div className='divider-dark first'/> + {clockSection} + <div className='divider-dark'/> + </div> + </div> + ); + } +} + +UserSettingsDisplay.propTypes = { + user: React.PropTypes.object, + updateSection: React.PropTypes.func, + updateTab: React.PropTypes.func, + activeSection: React.PropTypes.string +}; diff --git a/web/react/components/user_settings/user_settings_general.jsx b/web/react/components/user_settings/user_settings_general.jsx index 0e872315d..9c03f77a6 100644 --- a/web/react/components/user_settings/user_settings_general.jsx +++ b/web/react/components/user_settings/user_settings_general.jsx @@ -211,7 +211,7 @@ export default class UserSettingsGeneralTab extends React.Component { this.props.updateSection(section); } handleClose() { - $(React.findDOMNode(this)).find('.form-control').each(function clearForms() { + $(ReactDOM.findDOMNode(this)).find('.form-control').each(function clearForms() { this.value = ''; }); diff --git a/web/react/components/user_settings/user_settings_modal.jsx b/web/react/components/user_settings/user_settings_modal.jsx index 19b97fc85..692fb26ee 100644 --- a/web/react/components/user_settings/user_settings_modal.jsx +++ b/web/react/components/user_settings/user_settings_modal.jsx @@ -41,6 +41,7 @@ export default class UserSettingsModal extends React.Component { if (global.window.config.EnableIncomingWebhooks === 'true') { tabs.push({name: 'integrations', uiName: 'Integrations', icon: 'glyphicon glyphicon-transfer'}); } + tabs.push({name: 'display', uiName: 'Display', icon: 'glyphicon glyphicon-eye-open'}); return ( <div diff --git a/web/react/components/user_settings/user_settings_notifications.jsx b/web/react/components/user_settings/user_settings_notifications.jsx index 4728a33ee..8693af494 100644 --- a/web/react/components/user_settings/user_settings_notifications.jsx +++ b/web/react/components/user_settings/user_settings_notifications.jsx @@ -129,7 +129,7 @@ export default class NotificationsTab extends React.Component { ); } handleClose() { - $(React.findDOMNode(this)).find('.form-control').each(function clearField() { + $(ReactDOM.findDOMNode(this)).find('.form-control').each(function clearField() { this.value = ''; }); @@ -158,15 +158,15 @@ export default class NotificationsTab extends React.Component { } handleNotifyRadio(notifyLevel) { this.setState({notifyLevel: notifyLevel}); - React.findDOMNode(this.refs.wrapper).focus(); + ReactDOM.findDOMNode(this.refs.wrapper).focus(); } handleEmailRadio(enableEmail) { this.setState({enableEmail: enableEmail}); - React.findDOMNode(this.refs.wrapper).focus(); + ReactDOM.findDOMNode(this.refs.wrapper).focus(); } handleSoundRadio(enableSound) { this.setState({enableSound: enableSound}); - React.findDOMNode(this.refs.wrapper).focus(); + ReactDOM.findDOMNode(this.refs.wrapper).focus(); } updateUsernameKey(val) { this.setState({usernameKey: val}); @@ -184,10 +184,10 @@ export default class NotificationsTab extends React.Component { this.setState({channelKey: val}); } updateCustomMentionKeys() { - var checked = React.findDOMNode(this.refs.customcheck).checked; + var checked = ReactDOM.findDOMNode(this.refs.customcheck).checked; if (checked) { - var text = React.findDOMNode(this.refs.custommentions).value; + var text = ReactDOM.findDOMNode(this.refs.custommentions).value; // remove all spaces and split string into individual keys this.setState({customKeys: text.replace(/ /g, ''), customKeysChecked: true}); @@ -196,7 +196,7 @@ export default class NotificationsTab extends React.Component { } } onCustomChange() { - React.findDOMNode(this.refs.customcheck).checked = true; + ReactDOM.findDOMNode(this.refs.customcheck).checked = true; this.updateCustomMentionKeys(); } render() { @@ -228,9 +228,8 @@ export default class NotificationsTab extends React.Component { <input type='radio' checked={notifyActive[0]} onChange={this.handleNotifyRadio.bind(this, 'all')} - > - For all activity - </input> + /> + {'For all activity'} </label> <br/> </div> @@ -240,9 +239,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={notifyActive[1]} onChange={this.handleNotifyRadio.bind(this, 'mention')} - > - Only for mentions and direct messages - </input> + /> + {'Only for mentions and direct messages'} </label> <br/> </div> @@ -252,9 +250,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={notifyActive[2]} onChange={this.handleNotifyRadio.bind(this, 'none')} - > - Never - </input> + /> + {'Never'} </label> </div> </div> @@ -320,9 +317,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={soundActive[0]} onChange={this.handleSoundRadio.bind(this, 'true')} - > - On - </input> + /> + {'On'} </label> <br/> </div> @@ -332,9 +328,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={soundActive[1]} onChange={this.handleSoundRadio.bind(this, 'false')} - > - Off - </input> + /> + {'Off'} </label> <br/> </div> @@ -402,9 +397,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={emailActive[0]} onChange={this.handleEmailRadio.bind(this, 'true')} - > - On - </input> + /> + {'On'} </label> <br/> </div> @@ -414,9 +408,8 @@ export default class NotificationsTab extends React.Component { type='radio' checked={emailActive[1]} onChange={this.handleEmailRadio.bind(this, 'false')} - > - Off - </input> + /> + {'Off'} </label> <br/> </div> @@ -482,9 +475,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.firstNameKey} onChange={handleUpdateFirstNameKey} - > - {'Your case sensitive first name "' + user.first_name + '"'} - </input> + /> + {'Your case sensitive first name "' + user.first_name + '"'} </label> </div> </div> @@ -502,9 +494,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.usernameKey} onChange={handleUpdateUsernameKey} - > - {'Your non-case sensitive username "' + user.username + '"'} - </input> + /> + {'Your non-case sensitive username "' + user.username + '"'} </label> </div> </div> @@ -521,9 +512,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.mentionKey} onChange={handleUpdateMentionKey} - > - {'Your username mentioned "@' + user.username + '"'} - </input> + /> + {'Your username mentioned "@' + user.username + '"'} </label> </div> </div> @@ -540,9 +530,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.allKey} onChange={handleUpdateAllKey} - > - {'Team-wide mentions "@all"'} - </input> + /> + {'Team-wide mentions "@all"'} </label> </div> </div> @@ -559,9 +548,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.channelKey} onChange={handleUpdateChannelKey} - > - {'Channel-wide mentions "@channel"'} - </input> + /> + {'Channel-wide mentions "@channel"'} </label> </div> </div> @@ -576,9 +564,8 @@ export default class NotificationsTab extends React.Component { type='checkbox' checked={this.state.customKeysChecked} onChange={this.updateCustomMentionKeys} - > - {'Other non-case sensitive words, separated by commas:'} - </input> + /> + {'Other non-case sensitive words, separated by commas:'} </label> </div> <input diff --git a/web/react/components/user_settings/user_settings_security.jsx b/web/react/components/user_settings/user_settings_security.jsx index 74190781c..983a10df0 100644 --- a/web/react/components/user_settings/user_settings_security.jsx +++ b/web/react/components/user_settings/user_settings_security.jsx @@ -82,7 +82,7 @@ export default class SecurityTab extends React.Component { $('#user_settings').modal('hide'); } handleClose() { - $(React.findDOMNode(this)).find('.form-control').each(function resetValue() { + $(ReactDOM.findDOMNode(this)).find('.form-control').each(function resetValue() { this.value = ''; }); this.setState({currentPassword: '', newPassword: '', confirmPassword: '', serverError: null, passwordError: null}); |