this.setState({showUserSettingsModal: false})}
+ />
);
}
diff --git a/web/react/components/team_settings_modal.jsx b/web/react/components/team_settings_modal.jsx
index 17fe31c65e..4d47db2a89 100644
--- a/web/react/components/team_settings_modal.jsx
+++ b/web/react/components/team_settings_modal.jsx
@@ -17,11 +17,13 @@ export default class TeamSettingsModal extends React.Component {
};
}
componentDidMount() {
- $('body').on('click', '.modal-back', function handleBackClick() {
+ const modal = $(ReactDOM.findDOMNode(this.refs.modal));
+
+ modal.on('click', '.modal-back', function handleBackClick() {
$(this).closest('.modal-dialog').removeClass('display--content');
$(this).closest('.modal-dialog').find('.settings-table .nav li.active').removeClass('active');
});
- $('body').on('click', '.modal-header .close', () => {
+ modal.on('click', '.modal-header .close', () => {
setTimeout(() => {
$('.modal-dialog.display--content').removeClass('display--content');
}, 500);
diff --git a/web/react/components/user_settings/import_theme_modal.jsx b/web/react/components/user_settings/import_theme_modal.jsx
index 1a9ac0ad39..24da106d0b 100644
--- a/web/react/components/user_settings/import_theme_modal.jsx
+++ b/web/react/components/user_settings/import_theme_modal.jsx
@@ -1,6 +1,7 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
+const ModalStore = require('../../stores/modal_store.jsx');
const UserStore = require('../../stores/user_store.jsx');
const Utils = require('../../utils/utils.jsx');
const Client = require('../../utils/client.jsx');
@@ -24,10 +25,10 @@ export default class ImportThemeModal extends React.Component {
};
}
componentDidMount() {
- UserStore.addImportModalListener(this.updateShow);
+ ModalStore.addModalListener(ActionTypes.TOGGLE_IMPORT_THEME_MODAL, this.updateShow);
}
componentWillUnmount() {
- UserStore.removeImportModalListener(this.updateShow);
+ ModalStore.removeModalListener(ActionTypes.TOGGLE_IMPORT_THEME_MODAL, this.updateShow);
}
updateShow(show) {
this.setState({show});
@@ -74,7 +75,6 @@ export default class ImportThemeModal extends React.Component {
this.setState({show: false});
Utils.applyTheme(theme);
- $('#user_settings').modal('show');
},
(err) => {
var state = this.getStateFromStores();
diff --git a/web/react/components/user_settings/user_settings.jsx b/web/react/components/user_settings/user_settings.jsx
index 546e26ca30..e089ce973e 100644
--- a/web/react/components/user_settings/user_settings.jsx
+++ b/web/react/components/user_settings/user_settings.jsx
@@ -16,6 +16,7 @@ export default class UserSettings extends React.Component {
constructor(props) {
super(props);
+ this.getActiveTab = this.getActiveTab.bind(this);
this.onListenerChange = this.onListenerChange.bind(this);
this.state = {user: UserStore.getCurrentUser()};
@@ -29,10 +30,14 @@ export default class UserSettings extends React.Component {
UserStore.removeChangeListener(this.onListenerChange);
}
+ getActiveTab() {
+ return this.refs.activeTab;
+ }
+
onListenerChange() {
var user = UserStore.getCurrentUser();
if (!utils.areStatesEqual(this.state.user, user)) {
- this.setState({user: user});
+ this.setState({user});
}
}
@@ -41,10 +46,13 @@ export default class UserSettings extends React.Component {
return (
);
@@ -52,10 +60,14 @@ export default class UserSettings extends React.Component {
return (
);
@@ -63,10 +75,13 @@ export default class UserSettings extends React.Component {
return (
);
@@ -74,9 +89,14 @@ export default class UserSettings extends React.Component {
return (
);
@@ -84,8 +104,11 @@ export default class UserSettings extends React.Component {
return (
);
@@ -93,10 +116,13 @@ export default class UserSettings extends React.Component {
return (
);
@@ -104,10 +130,13 @@ export default class UserSettings extends React.Component {
return (
);
@@ -115,10 +144,13 @@ export default class UserSettings extends React.Component {
return (
);
@@ -132,5 +164,9 @@ UserSettings.propTypes = {
activeTab: React.PropTypes.string,
activeSection: React.PropTypes.string,
updateSection: React.PropTypes.func,
- updateTab: React.PropTypes.func
+ updateTab: React.PropTypes.func,
+ closeModal: React.PropTypes.func.isRequired,
+ collapseModal: React.PropTypes.func.isRequired,
+ setEnforceFocus: React.PropTypes.func.isRequired,
+ 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 910444735f..2616981bac 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;
@@ -139,6 +126,7 @@ export default class AdvancedSettingsDisplay extends React.Component {
className='close'
data-dismiss='modal'
aria-label='Close'
+ onClick={this.props.closeModal}
>
{'×'}
@@ -146,7 +134,10 @@ export default class AdvancedSettingsDisplay extends React.Component {
className='modal-title'
ref='title'
>
-
+
{'Advanced Settings'}
@@ -165,5 +156,7 @@ AdvancedSettingsDisplay.propTypes = {
user: React.PropTypes.object,
updateSection: React.PropTypes.func,
updateTab: React.PropTypes.func,
- activeSection: React.PropTypes.string
+ activeSection: React.PropTypes.string,
+ closeModal: React.PropTypes.func.isRequired,
+ collapseModal: React.PropTypes.func.isRequired
};
diff --git a/web/react/components/user_settings/user_settings_appearance.jsx b/web/react/components/user_settings/user_settings_appearance.jsx
index 7b4b54e272..425645c1f5 100644
--- a/web/react/components/user_settings/user_settings_appearance.jsx
+++ b/web/react/components/user_settings/user_settings_appearance.jsx
@@ -20,13 +20,13 @@ export default class UserSettingsAppearance extends React.Component {
this.submitTheme = this.submitTheme.bind(this);
this.updateTheme = this.updateTheme.bind(this);
this.updateCodeTheme = this.updateCodeTheme.bind(this);
- this.handleClose = this.handleClose.bind(this);
+ this.deactivate = this.deactivate.bind(this);
+ this.resetFields = this.resetFields.bind(this);
this.handleImportModal = this.handleImportModal.bind(this);
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 +34,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 +43,13 @@ export default class UserSettingsAppearance extends React.Component {
}
componentWillUnmount() {
UserStore.removeChangeListener(this.onChange);
- $('#user_settings').off('hidden.bs.modal', 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);
}
@@ -73,6 +71,8 @@ export default class UserSettingsAppearance extends React.Component {
if (!Utils.areStatesEqual(this.state, newState)) {
this.setState(newState);
}
+
+ this.props.setEnforceFocus(true);
}
submitTheme(e) {
e.preventDefault();
@@ -86,11 +86,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,37 +103,53 @@ 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() {
+ deactivate() {
+ const state = this.getStateFromStores();
+
+ Utils.applyTheme(state.theme);
+ }
+ resetFields() {
const state = this.getStateFromStores();
state.serverError = null;
- state.theme.codeTheme = this.originalCodeTheme;
+ this.setState(state);
Utils.applyTheme(state.theme);
- this.setState(state);
-
- $('.ps-container.modal-body').scrollTop(0);
- $('.ps-container.modal-body').perfectScrollbar('update');
- $('#user_settings').modal('hide');
+ this.props.setRequireConfirm(false);
}
handleImportModal() {
- $('#user_settings').modal('hide');
AppDispatcher.handleViewAction({
type: ActionTypes.TOGGLE_IMPORT_THEME_MODAL,
value: true
});
+
+ this.props.setEnforceFocus(false);
}
render() {
var serverError;
@@ -204,7 +220,7 @@ export default class UserSettingsAppearance extends React.Component {
{'Cancel'}
@@ -218,8 +234,8 @@ export default class UserSettingsAppearance extends React.Component {
{'×'}
@@ -227,7 +243,11 @@ export default class UserSettingsAppearance extends React.Component {
className='modal-title'
ref='title'
>
- {'Appearance Settings'}
+
+ {'Appearance Settings'}
@@ -253,5 +273,9 @@ UserSettingsAppearance.defaultProps = {
};
UserSettingsAppearance.propTypes = {
activeSection: React.PropTypes.string,
- updateTab: React.PropTypes.func
+ updateTab: React.PropTypes.func,
+ closeModal: React.PropTypes.func.isRequired,
+ collapseModal: React.PropTypes.func.isRequired,
+ setRequireConfirm: React.PropTypes.func.isRequired,
+ setEnforceFocus: React.PropTypes.func.isRequired
};
diff --git a/web/react/components/user_settings/user_settings_developer.jsx b/web/react/components/user_settings/user_settings_developer.jsx
index c2d7a9710d..e6adba1d4b 100644
--- a/web/react/components/user_settings/user_settings_developer.jsx
+++ b/web/react/components/user_settings/user_settings_developer.jsx
@@ -63,6 +63,7 @@ export default class DeveloperTab extends React.Component {
className='close'
data-dismiss='modal'
aria-label='Close'
+ onClick={this.props.closeModal}
>
{'×'}
@@ -70,7 +71,11 @@ export default class DeveloperTab extends React.Component {
className='modal-title'
ref='title'
>
- {'Developer Settings'}
+
+ {'Developer Settings'}
@@ -89,5 +94,7 @@ DeveloperTab.defaultProps = {
};
DeveloperTab.propTypes = {
activeSection: React.PropTypes.string,
- updateSection: React.PropTypes.func
+ updateSection: React.PropTypes.func,
+ closeModal: React.PropTypes.func.isRequired,
+ collapseModal: 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 d086c78a9b..3c12ead23c 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;
@@ -227,6 +217,7 @@ export default class UserSettingsDisplay extends React.Component {
className='close'
data-dismiss='modal'
aria-label='Close'
+ onClick={this.props.closeModal}
>
{'×'}
@@ -234,7 +225,10 @@ export default class UserSettingsDisplay extends React.Component {
className='modal-title'
ref='title'
>
-
+
{'Display Settings'}
@@ -255,5 +249,7 @@ UserSettingsDisplay.propTypes = {
user: React.PropTypes.object,
updateSection: React.PropTypes.func,
updateTab: React.PropTypes.func,
- activeSection: React.PropTypes.string
+ activeSection: React.PropTypes.string,
+ closeModal: React.PropTypes.func.isRequired,
+ collapseModal: React.PropTypes.func.isRequired
};
diff --git a/web/react/components/user_settings/user_settings_general.jsx b/web/react/components/user_settings/user_settings_general.jsx
index 3adac197ae..9f0c161940 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;
@@ -579,6 +564,7 @@ export default class UserSettingsGeneralTab extends React.Component {
className='close'
data-dismiss='modal'
aria-label='Close'
+ onClick={this.props.closeModal}
>
{'×'}
@@ -586,7 +572,10 @@ export default class UserSettingsGeneralTab extends React.Component {
className='modal-title'
ref='title'
>
-
+
{'General Settings'}
@@ -613,5 +602,7 @@ UserSettingsGeneralTab.propTypes = {
user: React.PropTypes.object,
updateSection: React.PropTypes.func,
updateTab: React.PropTypes.func,
- activeSection: React.PropTypes.string
+ activeSection: React.PropTypes.string,
+ closeModal: React.PropTypes.func.isRequired,
+ collapseModal: React.PropTypes.func.isRequired
};
diff --git a/web/react/components/user_settings/user_settings_integrations.jsx b/web/react/components/user_settings/user_settings_integrations.jsx
index 4a9915a1ff..744a6beeab 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;
@@ -104,6 +92,7 @@ export default class UserSettingsIntegrationsTab extends React.Component {
className='close'
data-dismiss='modal'
aria-label='Close'
+ onClick={this.props.closeModal}
>
{'×'}
@@ -111,7 +100,10 @@ export default class UserSettingsIntegrationsTab extends React.Component {
className='modal-title'
ref='title'
>
-
+
{'Integration Settings'}
@@ -132,5 +124,7 @@ UserSettingsIntegrationsTab.propTypes = {
user: React.PropTypes.object,
updateSection: React.PropTypes.func,
updateTab: React.PropTypes.func,
- activeSection: React.PropTypes.string
+ activeSection: React.PropTypes.string,
+ closeModal: React.PropTypes.func.isRequired,
+ collapseModal: React.PropTypes.func.isRequired
};
diff --git a/web/react/components/user_settings/user_settings_modal.jsx b/web/react/components/user_settings/user_settings_modal.jsx
index 18dd490e78..4dcf32cb9b 100644
--- a/web/react/components/user_settings/user_settings_modal.jsx
+++ b/web/react/components/user_settings/user_settings_modal.jsx
@@ -1,34 +1,161 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-var SettingsSidebar = require('../settings_sidebar.jsx');
-var UserSettings = require('./user_settings.jsx');
+const ConfirmModal = require('../confirm_modal.jsx');
+const Modal = ReactBootstrap.Modal;
+const SettingsSidebar = require('../settings_sidebar.jsx');
+const UserSettings = require('./user_settings.jsx');
export default class UserSettingsModal extends React.Component {
constructor(props) {
super(props);
+ this.handleHide = this.handleHide.bind(this);
+ this.handleHidden = this.handleHidden.bind(this);
+ this.handleCollapse = this.handleCollapse.bind(this);
+ this.handleConfirm = this.handleConfirm.bind(this);
+ this.handleCancelConfirmation = this.handleCancelConfirmation.bind(this);
+
+ this.deactivateTab = this.deactivateTab.bind(this);
+ this.closeModal = this.closeModal.bind(this);
+ this.collapseModal = this.collapseModal.bind(this);
+
this.updateTab = this.updateTab.bind(this);
this.updateSection = this.updateSection.bind(this);
- this.state = {active_tab: 'general', active_section: ''};
+ this.state = {
+ active_tab: 'general',
+ active_section: '',
+ showConfirmModal: false,
+ enforceFocus: true
+ };
+
+ this.requireConfirm = false;
}
- componentDidMount() {
- $('body').on('click', '.modal-back', function changeDisplay() {
- $(this).closest('.modal-dialog').removeClass('display--content');
- });
- $('body').on('click', '.modal-header .close', () => {
- setTimeout(() => {
- $('.modal-dialog.display--content').removeClass('display--content');
- }, 500);
+
+ componentDidUpdate(prevProps) {
+ if (!prevProps.show && this.props.show) {
+ $(ReactDOM.findDOMNode(this.refs.modalBody)).css('max-height', $(window).height() - 300);
+ if ($(window).width() > 768) {
+ $(ReactDOM.findDOMNode(this.refs.modalBody)).perfectScrollbar();
+ }
+ }
+ }
+
+ // Called when the close button is pressed on the main modal
+ handleHide() {
+ if (this.requireConfirm) {
+ this.afterConfirm = () => this.handleHide();
+ this.showConfirmModal();
+
+ return false;
+ }
+
+ this.deactivateTab();
+ this.props.onModalDismissed();
+ }
+
+ // called after the dialog is fully hidden and faded out
+ handleHidden() {
+ this.setState({
+ active_tab: 'general',
+ active_section: ''
});
}
- updateTab(tab) {
- this.setState({active_tab: tab});
+
+ // Called to hide the settings pane when on mobile
+ handleCollapse() {
+ $(ReactDOM.findDOMNode(this.refs.modalBody)).closest('.modal-dialog').removeClass('display--content');
+
+ this.deactivateTab();
+
+ this.setState({
+ active_tab: '',
+ active_section: ''
+ });
}
- updateSection(section) {
- this.setState({active_section: section});
+
+ handleConfirm() {
+ this.setState({
+ showConfirmModal: false,
+ enforceFocus: true
+ });
+
+ this.requireConfirm = false;
+
+ if (this.afterConfirm) {
+ this.afterConfirm();
+ this.afterConfirm = null;
+ }
}
+
+ handleCancelConfirmation() {
+ this.setState({
+ showConfirmModal: false,
+ enforceFocus: true
+ });
+
+ this.afterConfirm = null;
+ }
+
+ showConfirmModal(afterConfirm) {
+ this.setState({
+ showConfirmModal: true,
+ enforceFocus: false
+ });
+
+ if (afterConfirm) {
+ this.afterConfirm = afterConfirm;
+ }
+ }
+
+ // Called to let settings tab perform cleanup before being closed
+ deactivateTab() {
+ const activeTab = this.refs.userSettings.getActiveTab();
+ if (activeTab && activeTab.deactivate) {
+ activeTab.deactivate();
+ }
+ }
+
+ // Called by settings tabs when their close button is pressed
+ closeModal() {
+ if (this.requireConfirm) {
+ this.showConfirmModal(this.closeModal);
+ } else {
+ this.handleHide();
+ }
+ }
+
+ // Called by settings tabs when their back button is pressed
+ collapseModal() {
+ if (this.requireConfirm) {
+ this.showConfirmModal(this.collapseModal);
+ } else {
+ this.handleCollapse();
+ }
+ }
+
+ updateTab(tab, skipConfirm) {
+ if (!skipConfirm && this.requireConfirm) {
+ this.showConfirmModal(() => this.updateTab(tab, true));
+ } else {
+ this.deactivateTab();
+
+ this.setState({
+ active_tab: tab,
+ active_section: ''
+ });
+ }
+ }
+
+ updateSection(section, skipConfirm) {
+ if (!skipConfirm && this.requireConfirm) {
+ this.showConfirmModal(() => this.updateSection(section, true));
+ } else {
+ this.setState({active_section: section});
+ }
+ }
+
render() {
var tabs = [];
tabs.push({name: 'general', uiName: 'General', icon: 'glyphicon glyphicon-cog'});
@@ -46,33 +173,17 @@ export default class UserSettingsModal extends React.Component {
tabs.push({name: 'advanced', uiName: 'Advanced', icon: 'glyphicon glyphicon-list-alt'});
return (
-
-
-
-
-
- {'×'}
-
-
- {'Account Settings'}
-
-
-
+
+ {'Account Settings'}
+
+
this.setState({enforceFocus})}
+ setRequireConfirm={(requireConfirm) => this.requireConfirm = requireConfirm}
/>
-
-
-
-
+
+
+
);
}
}
+
+UserSettingsModal.propTypes = {
+ show: React.PropTypes.bool.isRequired,
+ onModalDismissed: React.PropTypes.func.isRequired
+};
diff --git a/web/react/components/user_settings/user_settings_notifications.jsx b/web/react/components/user_settings/user_settings_notifications.jsx
index 2b904763cb..c6f47804ff 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();
@@ -644,15 +630,19 @@ export default class NotificationsTab extends React.Component {
className='close'
data-dismiss='modal'
aria-label='Close'
+ onClick={this.props.closeModal}
>
-
×
+
{'×'}
-
- Notifications
+
+ {'Notification Settings'}
- ×
+ {'×'}
- Security Settings
+
+ {'Security Settings'}
+
+
);
}
@@ -285,5 +295,8 @@ SecurityTab.propTypes = {
user: React.PropTypes.object,
activeSection: React.PropTypes.string,
updateSection: React.PropTypes.func,
- updateTab: React.PropTypes.func
+ updateTab: React.PropTypes.func,
+ closeModal: React.PropTypes.func.isRequired,
+ collapseModal: React.PropTypes.func.isRequired,
+ setEnforceFocus: React.PropTypes.func.isRequired
};
diff --git a/web/react/pages/channel.jsx b/web/react/pages/channel.jsx
index 067dcde507..2f872effdb 100644
--- a/web/react/pages/channel.jsx
+++ b/web/react/pages/channel.jsx
@@ -9,7 +9,6 @@ var ErrorStore = require('../stores/error_store.jsx');
var MentionList = require('../components/mention_list.jsx');
var GetLinkModal = require('../components/get_link_modal.jsx');
-var MemberInviteModal = require('../components/invite_member_modal.jsx');
var EditChannelModal = require('../components/edit_channel_modal.jsx');
var DeleteChannelModal = require('../components/delete_channel_modal.jsx');
var RenameChannelModal = require('../components/rename_channel_modal.jsx');
@@ -18,17 +17,15 @@ var DeletePostModal = require('../components/delete_post_modal.jsx');
var MoreChannelsModal = require('../components/more_channels.jsx');
var PostDeletedModal = require('../components/post_deleted_modal.jsx');
var ChannelNotificationsModal = require('../components/channel_notifications.jsx');
-var UserSettingsModal = require('../components/user_settings/user_settings_modal.jsx');
var TeamSettingsModal = require('../components/team_settings_modal.jsx');
var ChannelMembersModal = require('../components/channel_members.jsx');
var ChannelInviteModal = require('../components/channel_invite_modal.jsx');
var TeamMembersModal = require('../components/team_members.jsx');
var ChannelInfoModal = require('../components/channel_info_modal.jsx');
-var AccessHistoryModal = require('../components/access_history_modal.jsx');
-var ActivityLogModal = require('../components/activity_log_modal.jsx');
var RemovedFromChannelModal = require('../components/removed_from_channel_modal.jsx');
var RegisterAppModal = require('../components/register_app_modal.jsx');
var ImportThemeModal = require('../components/user_settings/import_theme_modal.jsx');
+var InviteMemberModal = require('../components/invite_member_modal.jsx');
var AsyncClient = require('../utils/async_client.jsx');
var Constants = require('../utils/constants.jsx');
@@ -83,8 +80,8 @@ function setupChannelPage(props) {
);
ReactDOM.render(
- ,
- document.getElementById('user_settings_modal')
+ ,
+ document.getElementById('invite_member_modal')
);
ReactDOM.render(
@@ -102,11 +99,6 @@ function setupChannelPage(props) {
document.getElementById('team_members_modal')
);
- ReactDOM.render(
- ,
- document.getElementById('invite_member_modal')
- );
-
ReactDOM.render(
,
document.getElementById('edit_channel_modal')
@@ -162,16 +154,6 @@ function setupChannelPage(props) {
document.getElementById('post_deleted_modal')
);
- ReactDOM.render(
- ,
- document.getElementById('access_history_modal')
- );
-
- ReactDOM.render(
- ,
- document.getElementById('activity_log_modal')
- );
-
ReactDOM.render(
,
document.getElementById('removed_from_channel_modal')
diff --git a/web/react/stores/modal_store.jsx b/web/react/stores/modal_store.jsx
new file mode 100644
index 0000000000..dc65d48da3
--- /dev/null
+++ b/web/react/stores/modal_store.jsx
@@ -0,0 +1,42 @@
+// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+const AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
+const EventEmitter = require('events').EventEmitter;
+
+const Constants = require('../utils/constants.jsx');
+const ActionTypes = Constants.ActionTypes;
+
+class ModalStoreClass extends EventEmitter {
+ constructor() {
+ super();
+
+ this.addModalListener = this.addModalListener.bind(this);
+ this.removeModalListener = this.removeModalListener.bind(this);
+
+ this.handleEventPayload = this.handleEventPayload.bind(this);
+ this.dispatchToken = AppDispatcher.register(this.handleEventPayload);
+ }
+
+ addModalListener(action, callback) {
+ this.on(action, callback);
+ }
+
+ removeModalListener(action, callback) {
+ this.removeListener(action, callback);
+ }
+
+ handleEventPayload(payload) {
+ const action = payload.action;
+
+ switch (action.type) {
+ case ActionTypes.TOGGLE_IMPORT_THEME_MODAL:
+ case ActionTypes.TOGGLE_INVITE_MEMBER_MODAL:
+ this.emit(action.type, action.value);
+ break;
+ }
+ }
+}
+
+const ModalStore = new ModalStoreClass();
+export default ModalStore;
diff --git a/web/react/stores/user_store.jsx b/web/react/stores/user_store.jsx
index aedb3dc09d..4fa7224b70 100644
--- a/web/react/stores/user_store.jsx
+++ b/web/react/stores/user_store.jsx
@@ -13,7 +13,6 @@ var CHANGE_EVENT_SESSIONS = 'change_sessions';
var CHANGE_EVENT_AUDITS = 'change_audits';
var CHANGE_EVENT_TEAMS = 'change_teams';
var CHANGE_EVENT_STATUSES = 'change_statuses';
-var TOGGLE_IMPORT_MODAL_EVENT = 'toggle_import_modal';
class UserStoreClass extends EventEmitter {
constructor() {
@@ -34,9 +33,6 @@ class UserStoreClass extends EventEmitter {
this.emitStatusesChange = this.emitStatusesChange.bind(this);
this.addStatusesChangeListener = this.addStatusesChangeListener.bind(this);
this.removeStatusesChangeListener = this.removeStatusesChangeListener.bind(this);
- this.emitToggleImportModal = this.emitToggleImportModal.bind(this);
- this.addImportModalListener = this.addImportModalListener.bind(this);
- this.removeImportModalListener = this.removeImportModalListener.bind(this);
this.getCurrentId = this.getCurrentId.bind(this);
this.getCurrentUser = this.getCurrentUser.bind(this);
this.setCurrentUser = this.setCurrentUser.bind(this);
@@ -124,18 +120,6 @@ class UserStoreClass extends EventEmitter {
this.removeListener(CHANGE_EVENT_STATUSES, callback);
}
- emitToggleImportModal(value) {
- this.emit(TOGGLE_IMPORT_MODAL_EVENT, value);
- }
-
- addImportModalListener(callback) {
- this.on(TOGGLE_IMPORT_MODAL_EVENT, callback);
- }
-
- removeImportModalListener(callback) {
- this.removeListener(TOGGLE_IMPORT_MODAL_EVENT, callback);
- }
-
getCurrentUser() {
if (this.getProfiles()[global.window.mm_user.id] == null) {
this.saveProfile(global.window.mm_user);
@@ -353,10 +337,6 @@ UserStore.dispatchToken = AppDispatcher.register((payload) => {
UserStore.pSetStatuses(action.statuses);
UserStore.emitStatusesChange();
break;
- case ActionTypes.TOGGLE_IMPORT_THEME_MODAL:
- UserStore.emitToggleImportModal(action.value);
- break;
-
default:
}
});
diff --git a/web/react/utils/channel_intro_mssages.jsx b/web/react/utils/channel_intro_mssages.jsx
index b3f8684567..161c797618 100644
--- a/web/react/utils/channel_intro_mssages.jsx
+++ b/web/react/utils/channel_intro_mssages.jsx
@@ -3,6 +3,7 @@
// See License.txt for license information.
const Utils = require('./utils.jsx');
+const InviteMemberModal = require('../components/invite_member_modal.jsx');
const UserProfile = require('../components/user_profile.jsx');
const ChannelStore = require('../stores/channel_store.jsx');
const Constants = require('../utils/constants.jsx');
@@ -109,8 +110,7 @@ export function createDefaultIntroMessage(channel) {
{'Invite others to this team'}
@@ -213,6 +213,7 @@ export function createStandardIntroMessage(channel) {
>
{'Invite others to this ' + uiType}
+
);
}
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx
index 39be577df3..b8d346ba79 100644
--- a/web/react/utils/constants.jsx
+++ b/web/react/utils/constants.jsx
@@ -39,7 +39,8 @@ module.exports = {
RECIEVED_LOGS: null,
RECIEVED_ALL_TEAMS: null,
- TOGGLE_IMPORT_THEME_MODAL: null
+ TOGGLE_IMPORT_THEME_MODAL: null,
+ TOGGLE_INVITE_MEMBER_MODAL: null
}),
PayloadSources: keyMirror({
diff --git a/web/sass-files/sass/partials/_settings.scss b/web/sass-files/sass/partials/_settings.scss
index 96a6cf2ab1..3be83ed2fe 100644
--- a/web/sass-files/sass/partials/_settings.scss
+++ b/web/sass-files/sass/partials/_settings.scss
@@ -13,6 +13,10 @@
.settings-modal {
width:800px;
max-width: 100%;
+ .modal-content {
+ width:800px;
+ max-width: 100%;
+ }
.modal-back {
width: 40px;
height: 56px;