summaryrefslogtreecommitdiffstats
path: root/webapp/components/user_settings
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/components/user_settings')
-rw-r--r--webapp/components/user_settings/custom_theme_chooser.jsx10
-rw-r--r--webapp/components/user_settings/import_theme_modal.jsx2
-rw-r--r--webapp/components/user_settings/manage_languages.jsx2
-rw-r--r--webapp/components/user_settings/premade_theme_chooser.jsx1
-rw-r--r--webapp/components/user_settings/user_settings_advanced.jsx2
-rw-r--r--webapp/components/user_settings/user_settings_developer.jsx4
-rw-r--r--webapp/components/user_settings/user_settings_display.jsx127
-rw-r--r--webapp/components/user_settings/user_settings_general.jsx16
-rw-r--r--webapp/components/user_settings/user_settings_notifications.jsx189
-rw-r--r--webapp/components/user_settings/user_settings_security.jsx29
-rw-r--r--webapp/components/user_settings/user_settings_theme.jsx8
11 files changed, 346 insertions, 44 deletions
diff --git a/webapp/components/user_settings/custom_theme_chooser.jsx b/webapp/components/user_settings/custom_theme_chooser.jsx
index 9fbdd1251..e77ea1d30 100644
--- a/webapp/components/user_settings/custom_theme_chooser.jsx
+++ b/webapp/components/user_settings/custom_theme_chooser.jsx
@@ -230,11 +230,11 @@ class CustomThemeChooser extends React.Component {
overlay={popoverContent}
ref='headerOverlay'
>
- <span className='input-group-addon'>
- <img
- src={codeThemeURL}
- />
- </span>
+ <span className='input-group-addon'>
+ <img
+ src={codeThemeURL}
+ />
+ </span>
</OverlayTrigger>
</div>
</div>
diff --git a/webapp/components/user_settings/import_theme_modal.jsx b/webapp/components/user_settings/import_theme_modal.jsx
index 32da296bf..f743feee6 100644
--- a/webapp/components/user_settings/import_theme_modal.jsx
+++ b/webapp/components/user_settings/import_theme_modal.jsx
@@ -81,7 +81,7 @@ class ImportThemeModal extends React.Component {
theme.mentionHighlightLink = '#2f81b7';
theme.codeTheme = 'github';
- let user = UserStore.getCurrentUser();
+ const user = UserStore.getCurrentUser();
user.theme_props = theme;
Client.updateUser(user,
diff --git a/webapp/components/user_settings/manage_languages.jsx b/webapp/components/user_settings/manage_languages.jsx
index bbf3a2e40..269181922 100644
--- a/webapp/components/user_settings/manage_languages.jsx
+++ b/webapp/components/user_settings/manage_languages.jsx
@@ -5,7 +5,7 @@ import SettingItemMax from '../setting_item_max.jsx';
import Client from 'utils/web_client.jsx';
import * as I18n from 'i18n/i18n.jsx';
-import * as GlobalActions from 'action_creators/global_actions.jsx';
+import * as GlobalActions from 'actions/global_actions.jsx';
import {FormattedMessage} from 'react-intl';
diff --git a/webapp/components/user_settings/premade_theme_chooser.jsx b/webapp/components/user_settings/premade_theme_chooser.jsx
index 4b0faf865..9552c686d 100644
--- a/webapp/components/user_settings/premade_theme_chooser.jsx
+++ b/webapp/components/user_settings/premade_theme_chooser.jsx
@@ -59,6 +59,7 @@ export default class PremadeThemeChooser extends React.Component {
<a
href='http://docs.mattermost.com/help/settings/theme-colors.html#custom-theme-examples'
target='_blank'
+ rel='noopener noreferrer'
>
<FormattedMessage
id='user.settings.display.theme.otherThemes'
diff --git a/webapp/components/user_settings/user_settings_advanced.jsx b/webapp/components/user_settings/user_settings_advanced.jsx
index 61e0e1dad..dc5bd1c0e 100644
--- a/webapp/components/user_settings/user_settings_advanced.jsx
+++ b/webapp/components/user_settings/user_settings_advanced.jsx
@@ -173,6 +173,7 @@ class AdvancedSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='sendOnCtrlEnter'
checked={ctrlSendActive[0]}
onChange={this.updateSetting.bind(this, 'send_on_ctrl_enter', 'true')}
/>
@@ -187,6 +188,7 @@ class AdvancedSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='sendOnCtrlEnter'
checked={ctrlSendActive[1]}
onChange={this.updateSetting.bind(this, 'send_on_ctrl_enter', 'false')}
/>
diff --git a/webapp/components/user_settings/user_settings_developer.jsx b/webapp/components/user_settings/user_settings_developer.jsx
index cabb021cb..ae6d60362 100644
--- a/webapp/components/user_settings/user_settings_developer.jsx
+++ b/webapp/components/user_settings/user_settings_developer.jsx
@@ -3,7 +3,7 @@
import SettingItemMin from '../setting_item_min.jsx';
import SettingItemMax from '../setting_item_max.jsx';
-import * as GlobalActions from 'action_creators/global_actions.jsx';
+import * as GlobalActions from 'actions/global_actions.jsx';
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl';
@@ -135,4 +135,4 @@ DeveloperTab.propTypes = {
collapseModal: React.PropTypes.func.isRequired
};
-export default injectIntl(DeveloperTab); \ No newline at end of file
+export default injectIntl(DeveloperTab);
diff --git a/webapp/components/user_settings/user_settings_display.jsx b/webapp/components/user_settings/user_settings_display.jsx
index c4af57d4c..16175d4de 100644
--- a/webapp/components/user_settings/user_settings_display.jsx
+++ b/webapp/components/user_settings/user_settings_display.jsx
@@ -23,7 +23,8 @@ function getDisplayStateFromStores() {
militaryTime: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', 'false'),
nameFormat: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'username'),
selectedFont: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', Constants.DEFAULT_FONT),
- channelDisplayMode: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT)
+ channelDisplayMode: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT),
+ messageDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT)
};
}
@@ -70,8 +71,14 @@ export default class UserSettingsDisplay extends React.Component {
name: Preferences.CHANNEL_DISPLAY_MODE,
value: this.state.channelDisplayMode
};
+ const messageDisplayPreference = {
+ user_id: userId,
+ category: Preferences.CATEGORY_DISPLAY_SETTINGS,
+ name: Preferences.MESSAGE_DISPLAY,
+ value: this.state.messageDisplay
+ };
- AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference],
+ AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference, messageDisplayPreference],
() => {
this.updateSection('');
},
@@ -89,6 +96,9 @@ export default class UserSettingsDisplay extends React.Component {
handleChannelDisplayModeRadio(channelDisplayMode) {
this.setState({channelDisplayMode});
}
+ handlemessageDisplayRadio(messageDisplay) {
+ this.setState({messageDisplay});
+ }
handleFont(selectedFont) {
Utils.applyFont(selectedFont);
this.setState({selectedFont});
@@ -115,6 +125,7 @@ export default class UserSettingsDisplay extends React.Component {
let channelDisplayModeSection;
let fontSection;
let languagesSection;
+ let messageDisplaySection;
if (this.props.activeSection === 'clock') {
const clockFormat = [false, false];
@@ -135,6 +146,7 @@ export default class UserSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='clockFormat'
checked={clockFormat[0]}
onChange={this.handleClockRadio.bind(this, 'false')}
/>
@@ -149,6 +161,7 @@ export default class UserSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='clockFormat'
checked={clockFormat[1]}
onChange={this.handleClockRadio.bind(this, 'true')}
/>
@@ -253,6 +266,7 @@ export default class UserSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='nameFormat'
checked={nameFormat[1]}
onChange={this.handleNameRadio.bind(this, 'username')}
/>
@@ -264,6 +278,7 @@ export default class UserSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='nameFormat'
checked={nameFormat[0]}
onChange={this.handleNameRadio.bind(this, 'nickname_full_name')}
/>
@@ -275,6 +290,7 @@ export default class UserSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='nameFormat'
checked={nameFormat[2]}
onChange={this.handleNameRadio.bind(this, 'full_name')}
/>
@@ -350,6 +366,107 @@ export default class UserSettingsDisplay extends React.Component {
);
}
+ if (this.props.activeSection === Preferences.MESSAGE_DISPLAY) {
+ const messageDisplay = [false, false];
+ if (this.state.messageDisplay === Preferences.MESSAGE_DISPLAY_CLEAN) {
+ messageDisplay[0] = true;
+ } else {
+ messageDisplay[1] = true;
+ }
+
+ const inputs = [
+ <div key='userDisplayNameOptions'>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ name='messageDisplay'
+ checked={messageDisplay[0]}
+ onChange={this.handlemessageDisplayRadio.bind(this, Preferences.MESSAGE_DISPLAY_CLEAN)}
+ />
+ <FormattedMessage
+ id='user.settings.display.messageDisplayClean'
+ defaultMessage='Clean'
+ />
+ </label>
+ <br/>
+ </div>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ name='messageDisplay'
+ checked={messageDisplay[1]}
+ onChange={this.handlemessageDisplayRadio.bind(this, Preferences.MESSAGE_DISPLAY_COMPACT)}
+ />
+ <FormattedMessage
+ id='user.settings.display.messageDisplayCompact'
+ defaultMessage='Compact'
+ />
+ </label>
+ <br/>
+ </div>
+ <div>
+ <br/>
+ <FormattedMessage
+ id='user.settings.display.messageDisplayDescription'
+ defaultMessage='Select how messages in a channel should be displayed.'
+ />
+ </div>
+ </div>
+ ];
+
+ messageDisplaySection = (
+ <SettingItemMax
+ title={
+ <FormattedMessage
+ id='user.settings.display.messageDisplayTitle'
+ defaultMessage='Message Display'
+ />
+ }
+ inputs={inputs}
+ submit={this.handleSubmit}
+ server_error={serverError}
+ updateSection={(e) => {
+ this.updateSection('');
+ e.preventDefault();
+ }}
+ />
+ );
+ } else {
+ let describe;
+ if (this.state.messageDisplay === Preferences.MESSAGE_DISPLAY_CLEAN) {
+ describe = (
+ <FormattedMessage
+ id='user.settings.display.messageDisplayClean'
+ defaultMessage='Clean'
+ />
+ );
+ } else {
+ describe = (
+ <FormattedMessage
+ id='user.settings.display.messageDisplayCompact'
+ defaultMessage='Compact'
+ />
+ );
+ }
+
+ messageDisplaySection = (
+ <SettingItemMin
+ title={
+ <FormattedMessage
+ id='user.settings.display.messageDisplayTitle'
+ defaultMessage='Message Display'
+ />
+ }
+ describe={describe}
+ updateSection={() => {
+ this.props.updateSection(Preferences.MESSAGE_DISPLAY);
+ }}
+ />
+ );
+ }
+
if (this.props.activeSection === Preferences.CHANNEL_DISPLAY_MODE) {
const channelDisplayMode = [false, false];
if (this.state.channelDisplayMode === Preferences.CHANNEL_DISPLAY_MODE_CENTERED) {
@@ -364,6 +481,7 @@ export default class UserSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='channelDisplayMode'
checked={channelDisplayMode[0]}
onChange={this.handleChannelDisplayModeRadio.bind(this, Preferences.CHANNEL_DISPLAY_MODE_CENTERED)}
/>
@@ -378,6 +496,7 @@ export default class UserSettingsDisplay extends React.Component {
<label>
<input
type='radio'
+ name='channelDisplayMode'
checked={channelDisplayMode[1]}
onChange={this.handleChannelDisplayModeRadio.bind(this, Preferences.CHANNEL_DISPLAY_MODE_FULL_SCREEN)}
/>
@@ -392,7 +511,7 @@ export default class UserSettingsDisplay extends React.Component {
<br/>
<FormattedMessage
id='user.settings.display.channeldisplaymode'
- defaultMessage='Select how text in a channel is displayed.'
+ defaultMessage='Select the width of the center channel.'
/>
</div>
</div>
@@ -601,6 +720,8 @@ export default class UserSettingsDisplay extends React.Component {
<div className='divider-dark'/>
{nameFormatSection}
<div className='divider-dark'/>
+ {messageDisplaySection}
+ <div className='divider-dark'/>
{channelDisplayModeSection}
<div className='divider-dark'/>
{languagesSection}
diff --git a/webapp/components/user_settings/user_settings_general.jsx b/webapp/components/user_settings/user_settings_general.jsx
index be1d1e6c5..6149b1630 100644
--- a/webapp/components/user_settings/user_settings_general.jsx
+++ b/webapp/components/user_settings/user_settings_general.jsx
@@ -160,6 +160,11 @@ class UserSettingsGeneralTab extends React.Component {
const email = this.state.email.trim().toLowerCase();
const confirmEmail = this.state.confirmEmail.trim().toLowerCase();
+ if (user.email === email) {
+ this.updateSection('');
+ return;
+ }
+
const {formatMessage} = this.props.intl;
if (email === '' || !Utils.isEmail(email)) {
this.setState({emailError: formatMessage(holders.validEmail), clientError: '', serverError: ''});
@@ -171,11 +176,6 @@ class UserSettingsGeneralTab extends React.Component {
return;
}
- if (user.email === email) {
- this.updateSection('');
- return;
- }
-
user.email = email;
this.submitUser(user, true);
}
@@ -342,7 +342,7 @@ class UserSettingsGeneralTab extends React.Component {
<div className='col-sm-7'>
<input
className='form-control'
- type='text'
+ type='email'
onChange={this.updateEmail}
value={this.state.email}
/>
@@ -363,7 +363,7 @@ class UserSettingsGeneralTab extends React.Component {
<div className='col-sm-7'>
<input
className='form-control'
- type='text'
+ type='email'
onChange={this.updateConfirmEmail}
value={this.state.confirmEmail}
/>
@@ -681,6 +681,7 @@ class UserSettingsGeneralTab extends React.Component {
type='text'
onChange={this.updateNickname}
value={this.state.nickname}
+ autoCapitalize='off'
/>
</div>
</div>
@@ -764,6 +765,7 @@ class UserSettingsGeneralTab extends React.Component {
type='text'
onChange={this.updateUsername}
value={this.state.username}
+ autoCapitalize='off'
/>
</div>
</div>
diff --git a/webapp/components/user_settings/user_settings_notifications.jsx b/webapp/components/user_settings/user_settings_notifications.jsx
index fa84ce2d6..410ce1a4e 100644
--- a/webapp/components/user_settings/user_settings_notifications.jsx
+++ b/webapp/components/user_settings/user_settings_notifications.jsx
@@ -30,6 +30,10 @@ function getNotificationsStateFromStores() {
if (user.notify_props && user.notify_props.email) {
email = user.notify_props.email;
}
+ var push = 'mention';
+ if (user.notify_props && user.notify_props.push) {
+ push = user.notify_props.push;
+ }
var usernameKey = false;
var mentionKey = false;
@@ -72,9 +76,20 @@ function getNotificationsStateFromStores() {
}
}
- return {notifyLevel: desktop, enableEmail: email, soundNeeded: soundNeeded, enableSound: sound,
- usernameKey: usernameKey, mentionKey: mentionKey, customKeys: customKeys, customKeysChecked: customKeys.length > 0,
- firstNameKey: firstNameKey, allKey: allKey, channelKey: channelKey};
+ return {
+ notifyLevel: desktop,
+ notifyPushLevel: push,
+ enableEmail: email,
+ soundNeeded,
+ enableSound: sound,
+ usernameKey,
+ mentionKey,
+ customKeys,
+ customKeysChecked: customKeys.length > 0,
+ firstNameKey,
+ allKey,
+ channelKey
+ };
}
const holders = defineMessages({
@@ -121,6 +136,7 @@ class NotificationsTab extends React.Component {
this.updateChannelKey = this.updateChannelKey.bind(this);
this.updateCustomMentionKeys = this.updateCustomMentionKeys.bind(this);
this.onCustomChange = this.onCustomChange.bind(this);
+ this.createPushNotificationSection = this.createPushNotificationSection.bind(this);
this.state = getNotificationsStateFromStores();
}
@@ -130,6 +146,7 @@ class NotificationsTab extends React.Component {
data.email = this.state.enableEmail;
data.desktop_sound = this.state.enableSound;
data.desktop = this.state.notifyLevel;
+ data.push = this.state.notifyPushLevel;
var mentionKeys = [];
if (this.state.usernameKey) {
@@ -150,13 +167,13 @@ class NotificationsTab extends React.Component {
data.channel = this.state.channelKey.toString();
Client.updateUserNotifyProps(data,
- function success() {
+ () => {
this.props.updateSection('');
AsyncClient.getMe();
- }.bind(this),
- function failure(err) {
+ },
+ (err) => {
this.setState({serverError: err.message});
- }.bind(this)
+ }
);
}
handleCancel(e) {
@@ -185,15 +202,21 @@ class NotificationsTab extends React.Component {
this.updateState();
}
handleNotifyRadio(notifyLevel) {
- this.setState({notifyLevel: notifyLevel});
+ this.setState({notifyLevel});
+ ReactDOM.findDOMNode(this.refs.wrapper).focus();
+ }
+
+ handlePushRadio(notifyPushLevel) {
+ this.setState({notifyPushLevel});
ReactDOM.findDOMNode(this.refs.wrapper).focus();
}
+
handleEmailRadio(enableEmail) {
- this.setState({enableEmail: enableEmail});
+ this.setState({enableEmail});
ReactDOM.findDOMNode(this.refs.wrapper).focus();
}
handleSoundRadio(enableSound) {
- this.setState({enableSound: enableSound});
+ this.setState({enableSound});
ReactDOM.findDOMNode(this.refs.wrapper).focus();
}
updateUsernameKey(val) {
@@ -227,12 +250,129 @@ class NotificationsTab extends React.Component {
ReactDOM.findDOMNode(this.refs.customcheck).checked = true;
this.updateCustomMentionKeys();
}
+ createPushNotificationSection() {
+ var handleUpdateDesktopSection;
+ if (this.props.activeSection === 'push') {
+ var notifyActive = [false, false, false];
+ if (this.state.notifyPushLevel === 'all') {
+ notifyActive[0] = true;
+ } else if (this.state.notifyPushLevel === 'none') {
+ notifyActive[2] = true;
+ } else {
+ notifyActive[1] = true;
+ }
+
+ let inputs = [];
+
+ inputs.push(
+ <div key='userNotificationLevelOption'>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ name='pushNotificationLevel'
+ checked={notifyActive[0]}
+ onChange={this.handlePushRadio.bind(this, 'all')}
+ />
+ <FormattedMessage
+ id='user.settings.push_notification.allActivity'
+ defaultMessage='For all activity'
+ />
+ </label>
+ <br/>
+ </div>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ name='pushNotificationLevel'
+ checked={notifyActive[1]}
+ onChange={this.handlePushRadio.bind(this, 'mention')}
+ />
+ <FormattedMessage
+ id='user.settings.push_notifications.onlyMentions'
+ defaultMessage='For mentions and direct messages'
+ />
+ </label>
+ <br/>
+ </div>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ name='pushNotificationLevel'
+ checked={notifyActive[2]}
+ onChange={this.handlePushRadio.bind(this, 'none')}
+ />
+ <FormattedMessage
+ id='user.settings.push_notifications.off'
+ defaultMessage='Off'
+ />
+ </label>
+ </div>
+ </div>
+ );
+
+ const extraInfo = (
+ <span>
+ <FormattedMessage
+ id='user.settings.push_notifications.info'
+ defaultMessage='Notification alerts are pushed to your mobile device when there is activity in Mattermost.'
+ />
+ </span>
+ );
+
+ return (
+ <SettingItemMax
+ title={Utils.localizeMessage('user.settings.notifications.push', 'Mobile push notifications')}
+ extraInfo={extraInfo}
+ inputs={inputs}
+ submit={this.handleSubmit}
+ server_error={this.state.serverError}
+ updateSection={this.handleCancel}
+ />
+ );
+ }
+
+ let describe = '';
+ if (this.state.notifyPushLevel === 'all') {
+ describe = (
+ <FormattedMessage
+ id='user.settings.push_notification.allActivity'
+ defaultMessage='For all activity'
+ />
+ );
+ } else if (this.state.notifyPushLevel === 'none') {
+ describe = (
+ <FormattedMessage
+ id='user.settings.push_notifications.off'
+ defaultMessage='Off'
+ />
+ );
+ } else {
+ describe = (
+ <FormattedMessage
+ id='user.settings.push_notifications.onlyMentions'
+ defaultMessage='For mentions and direct messages'
+ />
+ );
+ }
+
+ handleUpdateDesktopSection = function updateDesktopSection() {
+ this.props.updateSection('push');
+ }.bind(this);
+
+ return (
+ <SettingItemMin
+ title={Utils.localizeMessage('user.settings.notifications.push', 'Mobile push notifications')}
+ describe={describe}
+ updateSection={handleUpdateDesktopSection}
+ />
+ );
+ }
render() {
const {formatMessage} = this.props.intl;
- var serverError = null;
- if (this.state.serverError) {
- serverError = this.state.serverError;
- }
+ const serverError = this.state.serverError;
var user = this.props.user;
@@ -254,7 +394,9 @@ class NotificationsTab extends React.Component {
<div key='userNotificationLevelOption'>
<div className='radio'>
<label>
- <input type='radio'
+ <input
+ type='radio'
+ name='desktopNotificationLevel'
checked={notifyActive[0]}
onChange={this.handleNotifyRadio.bind(this, 'all')}
/>
@@ -269,6 +411,7 @@ class NotificationsTab extends React.Component {
<label>
<input
type='radio'
+ name='desktopNotificationLevel'
checked={notifyActive[1]}
onChange={this.handleNotifyRadio.bind(this, 'mention')}
/>
@@ -283,6 +426,7 @@ class NotificationsTab extends React.Component {
<label>
<input
type='radio'
+ name='desktopNotificationLevel'
checked={notifyActive[2]}
onChange={this.handleNotifyRadio.bind(this, 'none')}
/>
@@ -370,6 +514,7 @@ class NotificationsTab extends React.Component {
<label>
<input
type='radio'
+ name='notificationSounds'
checked={soundActive[0]}
onChange={this.handleSoundRadio.bind(this, 'true')}
/>
@@ -384,6 +529,7 @@ class NotificationsTab extends React.Component {
<label>
<input
type='radio'
+ name='notificationSounds'
checked={soundActive[1]}
onChange={this.handleSoundRadio.bind(this, 'false')}
/>
@@ -393,8 +539,8 @@ class NotificationsTab extends React.Component {
/>
</label>
<br/>
- </div>
- </div>
+ </div>
+ </div>
);
const extraInfo = (
@@ -473,6 +619,7 @@ class NotificationsTab extends React.Component {
<label>
<input
type='radio'
+ name='emailNotifications'
checked={emailActive[0]}
onChange={this.handleEmailRadio.bind(this, 'true')}
/>
@@ -487,6 +634,7 @@ class NotificationsTab extends React.Component {
<label>
<input
type='radio'
+ name='emailNotifications'
checked={emailActive[1]}
onChange={this.handleEmailRadio.bind(this, 'false')}
/>
@@ -763,6 +911,11 @@ class NotificationsTab extends React.Component {
);
}
+ let pushNotificationSection;
+ if (global.window.mm_config.SendPushNotifications === 'true') {
+ pushNotificationSection = this.createPushNotificationSection();
+ }
+
return (
<div>
<div className='modal-header'>
@@ -808,6 +961,8 @@ class NotificationsTab extends React.Component {
<div className='divider-light'/>
{emailSection}
<div className='divider-light'/>
+ {pushNotificationSection}
+ <div className='divider-light'/>
{keysSection}
<div className='divider-dark'/>
</div>
diff --git a/webapp/components/user_settings/user_settings_security.jsx b/webapp/components/user_settings/user_settings_security.jsx
index 700aa295a..47a762442 100644
--- a/webapp/components/user_settings/user_settings_security.jsx
+++ b/webapp/components/user_settings/user_settings_security.jsx
@@ -61,6 +61,7 @@ class SecurityTab extends React.Component {
this.state = this.getDefaultState();
}
+
getDefaultState() {
return {
currentPassword: '',
@@ -71,6 +72,7 @@ class SecurityTab extends React.Component {
mfaToken: ''
};
}
+
submitPassword(e) {
e.preventDefault();
@@ -117,6 +119,7 @@ class SecurityTab extends React.Component {
}
);
}
+
activateMfa() {
Client.updateMfa(
this.state.mfaToken,
@@ -138,6 +141,7 @@ class SecurityTab extends React.Component {
}
);
}
+
deactivateMfa() {
Client.updateMfa(
'',
@@ -159,22 +163,28 @@ class SecurityTab extends React.Component {
}
);
}
+
updateCurrentPassword(e) {
this.setState({currentPassword: e.target.value});
}
+
updateNewPassword(e) {
this.setState({newPassword: e.target.value});
}
+
updateConfirmPassword(e) {
this.setState({confirmPassword: e.target.value});
}
+
updateMfaToken(e) {
this.setState({mfaToken: e.target.value});
}
+
showQrCode(e) {
e.preventDefault();
this.setState({mfaShowQr: true});
}
+
createMfaSection() {
let updateSectionStatus;
let submit;
@@ -329,6 +339,7 @@ class SecurityTab extends React.Component {
/>
);
}
+
createPasswordSection() {
let updateSectionStatus;
@@ -519,6 +530,7 @@ class SecurityTab extends React.Component {
/>
);
}
+
createSignInSection() {
let updateSectionStatus;
const user = this.props.user;
@@ -608,11 +620,11 @@ class SecurityTab extends React.Component {
const inputs = [];
inputs.push(
<div key='userSignInOption'>
- {emailOption}
- {gitlabOption}
- <br/>
- {ldapOption}
- {googleOption}
+ {emailOption}
+ {gitlabOption}
+ <br/>
+ {ldapOption}
+ {googleOption}
</div>
);
@@ -676,7 +688,10 @@ class SecurityTab extends React.Component {
/>
);
}
+
render() {
+ const user = this.props.user;
+
const passwordSection = this.createPasswordSection();
let numMethods = 0;
@@ -690,7 +705,9 @@ class SecurityTab extends React.Component {
}
let mfaSection;
- if (global.window.mm_config.EnableMultifactorAuthentication === 'true' && global.window.mm_license.IsLicensed === 'true') {
+ if (global.window.mm_config.EnableMultifactorAuthentication === 'true' &&
+ global.window.mm_license.IsLicensed === 'true' &&
+ (user.auth_service === '' || user.auth_service === Constants.LDAP_SERVICE)) {
mfaSection = this.createMfaSection();
}
diff --git a/webapp/components/user_settings/user_settings_theme.jsx b/webapp/components/user_settings/user_settings_theme.jsx
index f19538f71..811f4d8e4 100644
--- a/webapp/components/user_settings/user_settings_theme.jsx
+++ b/webapp/components/user_settings/user_settings_theme.jsx
@@ -212,7 +212,9 @@ export default class ThemeSetting extends React.Component {
key='premadeThemeColorLabel'
>
<label>
- <input type='radio'
+ <input
+ type='radio'
+ name='theme'
checked={!displayCustom}
onChange={this.updateType.bind(this, 'premade')}
/>
@@ -233,7 +235,9 @@ export default class ThemeSetting extends React.Component {
key='customThemeColorLabel'
>
<label>
- <input type='radio'
+ <input
+ type='radio'
+ name='theme'
checked={displayCustom}
onChange={this.updateType.bind(this, 'custom')}
/>