diff options
Diffstat (limited to 'web/react/components/user_settings/user_settings_modal.jsx')
-rw-r--r-- | web/react/components/user_settings/user_settings_modal.jsx | 215 |
1 files changed, 171 insertions, 44 deletions
diff --git a/web/react/components/user_settings/user_settings_modal.jsx b/web/react/components/user_settings/user_settings_modal.jsx index 18dd490e7..4dcf32cb9 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; + } + + 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(); } - componentDidMount() { - $('body').on('click', '.modal-back', function changeDisplay() { - $(this).closest('.modal-dialog').removeClass('display--content'); + + // called after the dialog is fully hidden and faded out + handleHidden() { + this.setState({ + active_tab: 'general', + active_section: '' }); - $('body').on('click', '.modal-header .close', () => { - setTimeout(() => { - $('.modal-dialog.display--content').removeClass('display--content'); - }, 500); + } + + // 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: '' }); } - updateTab(tab) { - this.setState({active_tab: tab}); + + handleConfirm() { + this.setState({ + showConfirmModal: false, + enforceFocus: true + }); + + this.requireConfirm = false; + + if (this.afterConfirm) { + this.afterConfirm(); + this.afterConfirm = null; + } } - updateSection(section) { - this.setState({active_section: section}); + + 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 ( - <div - className='modal fade' - ref='modal' - id='user_settings' - role='dialog' - tabIndex='-1' - aria-hidden='true' + <Modal + dialogClassName='settings-modal' + show={this.props.show} + onHide={this.handleHide} + onExited={this.handleHidden} + enforceFocus={this.state.enforceFocus} > - <div className='modal-dialog settings-modal'> - <div className='modal-content'> - <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' - > - {'Account Settings'} - </h4> - </div> - <div className='modal-body'> + <Modal.Header closeButton={true}> + <Modal.Title>{'Account Settings'}</Modal.Title> + </Modal.Header> + <Modal.Body ref='modalBody'> <div className='settings-table'> <div className='settings-links'> <SettingsSidebar @@ -83,17 +194,33 @@ export default class UserSettingsModal extends React.Component { </div> <div className='settings-content minimize-settings'> <UserSettings + ref='userSettings' activeTab={this.state.active_tab} activeSection={this.state.active_section} updateSection={this.updateSection} updateTab={this.updateTab} + closeModal={this.closeModal} + collapseModal={this.collapseModal} + setEnforceFocus={(enforceFocus) => this.setState({enforceFocus})} + setRequireConfirm={(requireConfirm) => this.requireConfirm = requireConfirm} /> </div> </div> - </div> - </div> - </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.handleCancelConfirmation} + /> + </Modal> ); } } + +UserSettingsModal.propTypes = { + show: React.PropTypes.bool.isRequired, + onModalDismissed: React.PropTypes.func.isRequired +}; |