summaryrefslogtreecommitdiffstats
path: root/web/react/components/user_settings
diff options
context:
space:
mode:
Diffstat (limited to 'web/react/components/user_settings')
-rw-r--r--web/react/components/user_settings/import_theme_modal.jsx2
-rw-r--r--web/react/components/user_settings/user_settings.jsx12
-rw-r--r--web/react/components/user_settings/user_settings_appearance.jsx14
-rw-r--r--web/react/components/user_settings/user_settings_display.jsx165
-rw-r--r--web/react/components/user_settings/user_settings_general.jsx2
-rw-r--r--web/react/components/user_settings/user_settings_modal.jsx1
-rw-r--r--web/react/components/user_settings/user_settings_notifications.jsx79
-rw-r--r--web/react/components/user_settings/user_settings_security.jsx2
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});