summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorhmhealey <harrisonmhealey@gmail.com>2015-10-30 16:33:51 -0400
committerhmhealey <harrisonmhealey@gmail.com>2015-11-02 15:10:50 -0500
commite56d21a9208209d515b645f95d293eae51f51f8d (patch)
treee272c8e18998ba0b89125f81d1bd45d0fdb55059 /web
parent738568e5a9726b3a1b2536a20ab6627c5e9fb01e (diff)
downloadchat-e56d21a9208209d515b645f95d293eae51f51f8d.tar.gz
chat-e56d21a9208209d515b645f95d293eae51f51f8d.tar.bz2
chat-e56d21a9208209d515b645f95d293eae51f51f8d.zip
Added a confirmation dialog for unsaved theme changes and removed unnecessary dialog close handling
Diffstat (limited to 'web')
-rw-r--r--web/react/components/confirm_modal.jsx4
-rw-r--r--web/react/components/user_settings/user_settings.jsx4
-rw-r--r--web/react/components/user_settings/user_settings_advanced.jsx13
-rw-r--r--web/react/components/user_settings/user_settings_appearance.jsx43
-rw-r--r--web/react/components/user_settings/user_settings_display.jsx10
-rw-r--r--web/react/components/user_settings/user_settings_general.jsx15
-rw-r--r--web/react/components/user_settings/user_settings_integrations.jsx12
-rw-r--r--web/react/components/user_settings/user_settings_modal.jsx93
-rw-r--r--web/react/components/user_settings/user_settings_notifications.jsx14
-rw-r--r--web/react/components/user_settings/user_settings_security.jsx16
10 files changed, 106 insertions, 118 deletions
diff --git a/web/react/components/confirm_modal.jsx b/web/react/components/confirm_modal.jsx
index 60069b2b1..bc3a0b814 100644
--- a/web/react/components/confirm_modal.jsx
+++ b/web/react/components/confirm_modal.jsx
@@ -11,9 +11,7 @@ export default class ConfirmModal extends React.Component {
}
handleConfirm() {
- if (this.props.onConfirm) {
- this.props.onConfirm();
- }
+ this.props.onConfirm();
}
render() {
diff --git a/web/react/components/user_settings/user_settings.jsx b/web/react/components/user_settings/user_settings.jsx
index ecba238f9..d569b9d6e 100644
--- a/web/react/components/user_settings/user_settings.jsx
+++ b/web/react/components/user_settings/user_settings.jsx
@@ -77,6 +77,7 @@ export default class UserSettings extends React.Component {
activeSection={this.props.activeSection}
updateSection={this.props.updateSection}
updateTab={this.props.updateTab}
+ setRequireConfirm={this.props.setRequireConfirm}
/>
</div>
);
@@ -132,5 +133,6 @@ UserSettings.propTypes = {
activeTab: React.PropTypes.string,
activeSection: React.PropTypes.string,
updateSection: React.PropTypes.func,
- updateTab: React.PropTypes.func
+ updateTab: React.PropTypes.func,
+ setRequireConfirm: React.PropTypes.func.isRequired
};
diff --git a/web/react/components/user_settings/user_settings_advanced.jsx b/web/react/components/user_settings/user_settings_advanced.jsx
index 910444735..8d91d264a 100644
--- a/web/react/components/user_settings/user_settings_advanced.jsx
+++ b/web/react/components/user_settings/user_settings_advanced.jsx
@@ -13,7 +13,6 @@ export default class AdvancedSettingsDisplay extends React.Component {
this.updateSection = this.updateSection.bind(this);
this.updateSetting = this.updateSetting.bind(this);
- this.handleClose = this.handleClose.bind(this);
this.setupInitialState = this.setupInitialState.bind(this);
this.state = this.setupInitialState();
@@ -59,18 +58,6 @@ export default class AdvancedSettingsDisplay extends React.Component {
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 ctrlSendSection;
diff --git a/web/react/components/user_settings/user_settings_appearance.jsx b/web/react/components/user_settings/user_settings_appearance.jsx
index 42c3fd65d..b3584e992 100644
--- a/web/react/components/user_settings/user_settings_appearance.jsx
+++ b/web/react/components/user_settings/user_settings_appearance.jsx
@@ -25,8 +25,7 @@ export default class UserSettingsAppearance extends React.Component {
this.state = this.getStateFromStores();
- this.originalTheme = this.state.theme;
- this.originalCodeTheme = this.state.theme.codeTheme;
+ this.originalTheme = Object.assign({}, this.state.theme);
}
componentDidMount() {
UserStore.addChangeListener(this.onChange);
@@ -34,7 +33,6 @@ export default class UserSettingsAppearance extends React.Component {
if (this.props.activeSection === 'theme') {
$(ReactDOM.findDOMNode(this.refs[this.state.theme])).addClass('active-border');
}
- $('#user_settings').on('hidden.bs.modal', this.handleClose);
}
componentDidUpdate() {
if (this.props.activeSection === 'theme') {
@@ -44,14 +42,15 @@ export default class UserSettingsAppearance extends React.Component {
}
componentWillUnmount() {
UserStore.removeChangeListener(this.onChange);
- $('#user_settings').off('hidden.bs.modal', this.handleClose);
+
+ this.handleClose();
}
getStateFromStores() {
const user = UserStore.getCurrentUser();
let theme = null;
if ($.isPlainObject(user.theme_props) && !$.isEmptyObject(user.theme_props)) {
- theme = user.theme_props;
+ theme = Object.assign({}, user.theme_props);
} else {
theme = $.extend(true, {}, Constants.THEMES.default);
}
@@ -86,11 +85,11 @@ export default class UserSettingsAppearance extends React.Component {
me: data
});
- $('#user_settings').off('hidden.bs.modal', this.handleClose);
- this.props.updateTab('general');
+ this.props.setRequireConfirm(false);
+ this.originalTheme = Object.assign({}, this.state.theme);
+
$('.ps-container.modal-body').scrollTop(0);
$('.ps-container.modal-body').perfectScrollbar('update');
- $('#user_settings').modal('hide');
},
(err) => {
var state = this.getStateFromStores();
@@ -103,29 +102,36 @@ export default class UserSettingsAppearance extends React.Component {
if (!theme.codeTheme) {
theme.codeTheme = this.state.theme.codeTheme;
}
+
+ let themeChanged = this.state.theme.length === theme.length;
+ if (!themeChanged) {
+ for (const field in theme) {
+ if (theme.hasOwnProperty(field)) {
+ if (this.state.theme[field] !== theme[field]) {
+ themeChanged = true;
+ break;
+ }
+ }
+ }
+ }
+
+ this.props.setRequireConfirm(themeChanged);
+
this.setState({theme});
Utils.applyTheme(theme);
}
updateCodeTheme(codeTheme) {
var theme = this.state.theme;
theme.codeTheme = codeTheme;
- this.setState({theme});
- Utils.applyTheme(theme);
+ this.updateTheme(theme);
}
updateType(type) {
this.setState({type});
}
handleClose() {
const state = this.getStateFromStores();
- state.serverError = null;
- state.theme.codeTheme = this.originalCodeTheme;
Utils.applyTheme(state.theme);
-
- this.setState(state);
-
- $('.ps-container.modal-body').scrollTop(0);
- $('.ps-container.modal-body').perfectScrollbar('update');
}
handleImportModal() {
AppDispatcher.handleViewAction({
@@ -251,5 +257,6 @@ UserSettingsAppearance.defaultProps = {
};
UserSettingsAppearance.propTypes = {
activeSection: React.PropTypes.string,
- updateTab: React.PropTypes.func
+ updateTab: React.PropTypes.func,
+ setRequireConfirm: React.PropTypes.func.isRequired
};
diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx
index d086c78a9..8c31fdd93 100644
--- a/web/react/components/user_settings/user_settings_display.jsx
+++ b/web/react/components/user_settings/user_settings_display.jsx
@@ -25,7 +25,6 @@ export default class UserSettingsDisplay extends React.Component {
this.handleClockRadio = this.handleClockRadio.bind(this);
this.handleNameRadio = this.handleNameRadio.bind(this);
this.updateSection = this.updateSection.bind(this);
- this.handleClose = this.handleClose.bind(this);
this.state = getDisplayStateFromStores();
}
@@ -53,15 +52,6 @@ export default class UserSettingsDisplay extends React.Component {
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;
diff --git a/web/react/components/user_settings/user_settings_general.jsx b/web/react/components/user_settings/user_settings_general.jsx
index 3adac197a..8cd71f01c 100644
--- a/web/react/components/user_settings/user_settings_general.jsx
+++ b/web/react/components/user_settings/user_settings_general.jsx
@@ -32,7 +32,6 @@ export default class UserSettingsGeneralTab extends React.Component {
this.updatePicture = this.updatePicture.bind(this);
this.updateSection = this.updateSection.bind(this);
- this.handleClose = this.handleClose.bind(this);
this.setupInitialState = this.setupInitialState.bind(this);
this.state = this.setupInitialState(props);
@@ -210,20 +209,6 @@ export default class UserSettingsGeneralTab extends React.Component {
this.submitActive = false;
this.props.updateSection(section);
}
- handleClose() {
- $(ReactDOM.findDOMNode(this)).find('.form-control').each(function clearForms() {
- this.value = '';
- });
-
- this.setState(assign({}, this.setupInitialState(this.props), {clientError: null, serverError: null, emailError: null}));
- this.props.updateSection('');
- }
- componentDidMount() {
- $('#user_settings').on('hidden.bs.modal', this.handleClose);
- }
- componentWillUnmount() {
- $('#user_settings').off('hidden.bs.modal', this.handleClose);
- }
setupInitialState(props) {
var user = props.user;
diff --git a/web/react/components/user_settings/user_settings_integrations.jsx b/web/react/components/user_settings/user_settings_integrations.jsx
index 4a9915a1f..95f02d9f4 100644
--- a/web/react/components/user_settings/user_settings_integrations.jsx
+++ b/web/react/components/user_settings/user_settings_integrations.jsx
@@ -11,24 +11,12 @@ export default class UserSettingsIntegrationsTab extends React.Component {
super(props);
this.updateSection = this.updateSection.bind(this);
- this.handleClose = this.handleClose.bind(this);
this.state = {};
}
updateSection(section) {
this.props.updateSection(section);
}
- handleClose() {
- this.updateSection('');
- $('.ps-container.modal-body').scrollTop(0);
- $('.ps-container.modal-body').perfectScrollbar('update');
- }
- componentDidMount() {
- $('#user_settings').on('hidden.bs.modal', this.handleClose);
- }
- componentWillUnmount() {
- $('#user_settings').off('hidden.bs.modal', this.handleClose);
- }
render() {
let incomingHooksSection;
let outgoingHooksSection;
diff --git a/web/react/components/user_settings/user_settings_modal.jsx b/web/react/components/user_settings/user_settings_modal.jsx
index 9f29b912b..4cfc2b3d4 100644
--- a/web/react/components/user_settings/user_settings_modal.jsx
+++ b/web/react/components/user_settings/user_settings_modal.jsx
@@ -1,9 +1,10 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
+const ConfirmModal = require('../confirm_modal.jsx');
const Modal = ReactBootstrap.Modal;
-var SettingsSidebar = require('../settings_sidebar.jsx');
-var UserSettings = require('./user_settings.jsx');
+const SettingsSidebar = require('../settings_sidebar.jsx');
+const UserSettings = require('./user_settings.jsx');
export default class UserSettingsModal extends React.Component {
constructor(props) {
@@ -11,26 +12,38 @@ export default class UserSettingsModal extends React.Component {
this.handleHide = this.handleHide.bind(this);
this.handleHidden = this.handleHidden.bind(this);
+ this.handleConfirm = this.handleConfirm.bind(this);
this.updateTab = this.updateTab.bind(this);
this.updateSection = this.updateSection.bind(this);
this.state = {
active_tab: 'general',
- active_section: ''
+ active_section: '',
+ showConfirmModal: false
};
+
+ this.requireConfirm = false;
}
componentDidMount() {
$('body').on('click', '.settings-content .modal-back', () => {
- $(this).closest('.modal-dialog').removeClass('display--content');
+ if (!this.requireConfirm) {
+ $(this).closest('.modal-dialog').removeClass('display--content');
+ }
});
$('body').on('click', '.settings-content .modal-header .close', () => {
+ if (!this.props.show) {
+ return;
+ }
+
this.handleHide();
- setTimeout(() => {
- $('.modal-dialog.display--content').removeClass('display--content');
- }, 500);
+ if (!this.requireConfirm) {
+ setTimeout(() => {
+ $('.modal-dialog.display--content').removeClass('display--content');
+ }, 500);
+ }
});
}
@@ -43,25 +56,64 @@ export default class UserSettingsModal extends React.Component {
}
}
- handleHide() {
- // called when the close button is pressed
+ // called when the close button is pressed
+ handleHide(skipConfirm) {
+ if (!skipConfirm && this.requireConfirm) {
+ this.afterConfirm = () => this.handleHide(true);
+ this.showConfirmModal();
+
+ return false;
+ }
+
this.props.onModalDismissed();
}
+ // called after the dialog is fully hidden and faded out
handleHidden() {
- // called after the dialog is fully hidden and faded out
this.setState({
- active_tag: 'general',
+ active_tab: 'general',
active_section: ''
});
}
- updateTab(tab) {
- this.setState({active_tab: tab});
+ handleConfirm() {
+ this.setState({
+ showConfirmModal: false
+ });
+
+ this.requireConfirm = false;
+
+ if (this.afterConfirm) {
+ this.afterConfirm();
+ this.afterConfirm = null;
+ }
}
- updateSection(section) {
- this.setState({active_section: section});
+ showConfirmModal() {
+ this.setState({
+ showConfirmModal: true
+ });
+ }
+
+ updateTab(tab, skipConfirm) {
+ if (!skipConfirm && this.requireConfirm) {
+ this.afterConfirm = () => this.updateTab(tab, true);
+ this.showConfirmModal();
+ } else {
+ this.setState({
+ active_tab: tab,
+ active_section: ''
+ });
+ }
+ }
+
+ updateSection(section, skipConfirm) {
+ if (!skipConfirm && this.requireConfirm) {
+ this.afterConfirm = () => this.updateSection(section, true);
+ this.showConfirmModal();
+ } else {
+ this.setState({active_section: section});
+ }
}
render() {
@@ -84,7 +136,7 @@ export default class UserSettingsModal extends React.Component {
<Modal
dialogClassName='settings-modal'
show={this.props.show}
- onHide={this.handleHide}
+ onHide={() => this.handleHide()}
onExited={this.handleHidden}
>
<Modal.Header closeButton={true}>
@@ -106,10 +158,19 @@ export default class UserSettingsModal extends React.Component {
activeSection={this.state.active_section}
updateSection={this.updateSection}
updateTab={this.updateTab}
+ setRequireConfirm={(requireConfirm) => this.requireConfirm = requireConfirm}
/>
</div>
</div>
</Modal.Body>
+ <ConfirmModal
+ title='Discard Changes?'
+ message='You have unsaved changes, are you sure you want to discard them?'
+ confirm_button='Yes, Discard'
+ show={this.state.showConfirmModal}
+ onConfirm={this.handleConfirm}
+ onCancel={() => this.setState({showConfirmModal: false})}
+ />
</Modal>
);
}
diff --git a/web/react/components/user_settings/user_settings_notifications.jsx b/web/react/components/user_settings/user_settings_notifications.jsx
index 2b904763c..49a94b74a 100644
--- a/web/react/components/user_settings/user_settings_notifications.jsx
+++ b/web/react/components/user_settings/user_settings_notifications.jsx
@@ -7,7 +7,6 @@ var SettingItemMax = require('../setting_item_max.jsx');
var client = require('../../utils/client.jsx');
var AsyncClient = require('../../utils/async_client.jsx');
var utils = require('../../utils/utils.jsx');
-var assign = require('object-assign');
function getNotificationsStateFromStores() {
var user = UserStore.getCurrentUser();
@@ -77,7 +76,6 @@ export default class NotificationsTab extends React.Component {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
- this.handleClose = this.handleClose.bind(this);
this.updateSection = this.updateSection.bind(this);
this.onListenerChange = this.onListenerChange.bind(this);
this.handleNotifyRadio = this.handleNotifyRadio.bind(this);
@@ -128,27 +126,15 @@ export default class NotificationsTab extends React.Component {
}.bind(this)
);
}
- handleClose() {
- $(ReactDOM.findDOMNode(this)).find('.form-control').each(function clearField() {
- this.value = '';
- });
-
- this.setState(assign({}, getNotificationsStateFromStores(), {serverError: null}));
-
- this.props.updateTab('general');
- }
updateSection(section) {
this.setState(getNotificationsStateFromStores());
this.props.updateSection(section);
}
componentDidMount() {
UserStore.addChangeListener(this.onListenerChange);
- $('#user_settings').on('hidden.bs.modal', this.handleClose);
}
componentWillUnmount() {
UserStore.removeChangeListener(this.onListenerChange);
- $('#user_settings').off('hidden.bs.modal', this.handleClose);
- this.props.updateSection('');
}
onListenerChange() {
var newState = getNotificationsStateFromStores();
diff --git a/web/react/components/user_settings/user_settings_security.jsx b/web/react/components/user_settings/user_settings_security.jsx
index 4d414008e..d4d6bf035 100644
--- a/web/react/components/user_settings/user_settings_security.jsx
+++ b/web/react/components/user_settings/user_settings_security.jsx
@@ -17,7 +17,6 @@ export default class SecurityTab extends React.Component {
this.updateCurrentPassword = this.updateCurrentPassword.bind(this);
this.updateNewPassword = this.updateNewPassword.bind(this);
this.updateConfirmPassword = this.updateConfirmPassword.bind(this);
- this.handleClose = this.handleClose.bind(this);
this.setupInitialState = this.setupInitialState.bind(this);
const state = this.setupInitialState();
@@ -80,24 +79,9 @@ export default class SecurityTab extends React.Component {
updateConfirmPassword(e) {
this.setState({confirmPassword: e.target.value});
}
- handleClose() {
- $(ReactDOM.findDOMNode(this)).find('.form-control').each(function resetValue() {
- this.value = '';
- });
- this.setState({currentPassword: '', newPassword: '', confirmPassword: '', serverError: null, passwordError: null});
-
- this.props.updateTab('general');
- }
setupInitialState() {
return {currentPassword: '', newPassword: '', confirmPassword: ''};
}
- componentDidMount() {
- $('#user_settings').on('hidden.bs.modal', this.handleClose);
- }
- componentWillUnmount() {
- $('#user_settings').off('hidden.bs.modal', this.handleClose);
- this.props.updateSection('');
- }
render() {
var serverError;
if (this.state.serverError) {