diff options
Diffstat (limited to 'web/react/components')
10 files changed, 173 insertions, 53 deletions
diff --git a/web/react/components/user_settings/user_settings.jsx b/web/react/components/user_settings/user_settings.jsx index cebbbebce..e089ce973 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,6 +30,10 @@ 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)) { @@ -41,10 +46,13 @@ export default class UserSettings extends React.Component { return ( <div> <GeneralTab + ref='activeTab' user={this.state.user} activeSection={this.props.activeSection} updateSection={this.props.updateSection} updateTab={this.props.updateTab} + closeModal={this.props.closeModal} + collapseModal={this.props.collapseModal} /> </div> ); @@ -52,10 +60,13 @@ export default class UserSettings extends React.Component { return ( <div> <SecurityTab + ref='activeTab' user={this.state.user} activeSection={this.props.activeSection} updateSection={this.props.updateSection} updateTab={this.props.updateTab} + closeModal={this.props.closeModal} + collapseModal={this.props.collapseModal} setEnforceFocus={this.props.setEnforceFocus} /> </div> @@ -64,10 +75,13 @@ export default class UserSettings extends React.Component { return ( <div> <NotificationsTab + ref='activeTab' user={this.state.user} activeSection={this.props.activeSection} updateSection={this.props.updateSection} updateTab={this.props.updateTab} + closeModal={this.props.closeModal} + collapseModal={this.props.collapseModal} /> </div> ); @@ -75,9 +89,12 @@ export default class UserSettings extends React.Component { return ( <div> <AppearanceTab + ref='activeTab' activeSection={this.props.activeSection} updateSection={this.props.updateSection} updateTab={this.props.updateTab} + closeModal={this.props.closeModal} + collapseModal={this.props.collapseModal} setEnforceFocus={this.props.setEnforceFocus} setRequireConfirm={this.props.setRequireConfirm} /> @@ -87,8 +104,11 @@ export default class UserSettings extends React.Component { return ( <div> <DeveloperTab + ref='activeTab' activeSection={this.props.activeSection} updateSection={this.props.updateSection} + closeModal={this.props.closeModal} + collapseModal={this.props.collapseModal} /> </div> ); @@ -96,10 +116,13 @@ export default class UserSettings extends React.Component { return ( <div> <IntegrationsTab + ref='activeTab' user={this.state.user} activeSection={this.props.activeSection} updateSection={this.props.updateSection} updateTab={this.props.updateTab} + closeModal={this.props.closeModal} + collapseModal={this.props.collapseModal} /> </div> ); @@ -107,10 +130,13 @@ export default class UserSettings extends React.Component { return ( <div> <DisplayTab + ref='activeTab' user={this.state.user} activeSection={this.props.activeSection} updateSection={this.props.updateSection} updateTab={this.props.updateTab} + closeModal={this.props.closeModal} + collapseModal={this.props.collapseModal} /> </div> ); @@ -118,10 +144,13 @@ export default class UserSettings extends React.Component { return ( <div> <AdvancedTab + ref='activeTab' user={this.state.user} activeSection={this.props.activeSection} updateSection={this.props.updateSection} updateTab={this.props.updateTab} + closeModal={this.props.closeModal} + collapseModal={this.props.collapseModal} /> </div> ); @@ -136,6 +165,8 @@ UserSettings.propTypes = { activeSection: React.PropTypes.string, updateSection: 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 8d91d264a..2616981ba 100644 --- a/web/react/components/user_settings/user_settings_advanced.jsx +++ b/web/react/components/user_settings/user_settings_advanced.jsx @@ -126,6 +126,7 @@ export default class AdvancedSettingsDisplay extends React.Component { className='close' data-dismiss='modal' aria-label='Close' + onClick={this.props.closeModal} > <span aria-hidden='true'>{'×'}</span> </button> @@ -133,7 +134,10 @@ export default class AdvancedSettingsDisplay extends React.Component { className='modal-title' ref='title' > - <i className='modal-back'></i> + <i + className='modal-back' + onClick={this.props.collapseModal} + /> {'Advanced Settings'} </h4> </div> @@ -152,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 28fc9018a..425645c1f 100644 --- a/web/react/components/user_settings/user_settings_appearance.jsx +++ b/web/react/components/user_settings/user_settings_appearance.jsx @@ -20,7 +20,8 @@ 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(); @@ -42,8 +43,6 @@ export default class UserSettingsAppearance extends React.Component { } componentWillUnmount() { UserStore.removeChangeListener(this.onChange); - - this.handleClose(); } getStateFromStores() { const user = UserStore.getCurrentUser(); @@ -130,10 +129,19 @@ export default class UserSettingsAppearance extends React.Component { updateType(type) { this.setState({type}); } - handleClose() { + deactivate() { + const state = this.getStateFromStores(); + + Utils.applyTheme(state.theme); + } + resetFields() { const state = this.getStateFromStores(); + state.serverError = null; + this.setState(state); Utils.applyTheme(state.theme); + + this.props.setRequireConfirm(false); } handleImportModal() { AppDispatcher.handleViewAction({ @@ -212,7 +220,7 @@ export default class UserSettingsAppearance extends React.Component { <a className='btn btn-sm theme' href='#' - onClick={this.handleClose} + onClick={this.resetFields} > {'Cancel'} </a> @@ -226,8 +234,8 @@ export default class UserSettingsAppearance extends React.Component { <button type='button' className='close' - data-dismiss='modal' aria-label='Close' + onClick={this.props.closeModal} > <span aria-hidden='true'>{'×'}</span> </button> @@ -235,7 +243,11 @@ export default class UserSettingsAppearance extends React.Component { className='modal-title' ref='title' > - <i className='modal-back'></i>{'Appearance Settings'} + <i + className='modal-back' + onClick={this.props.collapseModal} + /> + {'Appearance Settings'} </h4> </div> <div className='user-settings'> @@ -262,6 +274,8 @@ UserSettingsAppearance.defaultProps = { UserSettingsAppearance.propTypes = { activeSection: React.PropTypes.string, 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 c2d7a9710..e6adba1d4 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} > <span aria-hidden='true'>{'×'}</span> </button> @@ -70,7 +71,11 @@ export default class DeveloperTab extends React.Component { className='modal-title' ref='title' > - <i className='modal-back'></i>{'Developer Settings'} + <i + className='modal-back' + onClick={this.props.collapseModal} + /> + {'Developer Settings'} </h4> </div> <div className='user-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 8c31fdd93..3c12ead23 100644 --- a/web/react/components/user_settings/user_settings_display.jsx +++ b/web/react/components/user_settings/user_settings_display.jsx @@ -217,6 +217,7 @@ export default class UserSettingsDisplay extends React.Component { className='close' data-dismiss='modal' aria-label='Close' + onClick={this.props.closeModal} > <span aria-hidden='true'>{'×'}</span> </button> @@ -224,7 +225,10 @@ export default class UserSettingsDisplay extends React.Component { className='modal-title' ref='title' > - <i className='modal-back'></i> + <i + className='modal-back' + onClick={this.props.collapseModal} + /> {'Display Settings'} </h4> </div> @@ -245,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 8cd71f01c..9f0c16194 100644 --- a/web/react/components/user_settings/user_settings_general.jsx +++ b/web/react/components/user_settings/user_settings_general.jsx @@ -564,6 +564,7 @@ export default class UserSettingsGeneralTab extends React.Component { className='close' data-dismiss='modal' aria-label='Close' + onClick={this.props.closeModal} > <span aria-hidden='true'>{'×'}</span> </button> @@ -571,7 +572,10 @@ export default class UserSettingsGeneralTab extends React.Component { className='modal-title' ref='title' > - <i className='modal-back'></i> + <i + className='modal-back' + onClick={this.props.collapseModal} + /> {'General Settings'} </h4> </div> @@ -598,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 95f02d9f4..744a6beea 100644 --- a/web/react/components/user_settings/user_settings_integrations.jsx +++ b/web/react/components/user_settings/user_settings_integrations.jsx @@ -92,6 +92,7 @@ export default class UserSettingsIntegrationsTab extends React.Component { className='close' data-dismiss='modal' aria-label='Close' + onClick={this.props.closeModal} > <span aria-hidden='true'>{'×'}</span> </button> @@ -99,7 +100,10 @@ export default class UserSettingsIntegrationsTab extends React.Component { className='modal-title' ref='title' > - <i className='modal-back'></i> + <i + className='modal-back' + onClick={this.props.collapseModal} + /> {'Integration Settings'} </h4> </div> @@ -120,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 94b07f3a5..4dcf32cb9 100644 --- a/web/react/components/user_settings/user_settings_modal.jsx +++ b/web/react/components/user_settings/user_settings_modal.jsx @@ -12,9 +12,14 @@ export default class UserSettingsModal extends React.Component { 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); @@ -28,27 +33,6 @@ export default class UserSettingsModal extends React.Component { this.requireConfirm = false; } - componentDidMount() { - $('body').on('click', '.settings-content .modal-back', () => { - 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(); - - if (!this.requireConfirm) { - 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); @@ -58,15 +42,16 @@ export default class UserSettingsModal extends React.Component { } } - // called when the close button is pressed - handleHide(skipConfirm) { - if (!skipConfirm && this.requireConfirm) { - this.afterConfirm = () => this.handleHide(true); + // 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(); } @@ -78,6 +63,18 @@ export default class UserSettingsModal extends React.Component { }); } + // 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: '' + }); + } + handleConfirm() { this.setState({ showConfirmModal: false, @@ -97,20 +94,53 @@ export default class UserSettingsModal extends React.Component { showConfirmModal: false, enforceFocus: true }); + + this.afterConfirm = null; } - showConfirmModal() { + 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.afterConfirm = () => this.updateTab(tab, true); - this.showConfirmModal(); + this.showConfirmModal(() => this.updateTab(tab, true)); } else { + this.deactivateTab(); + this.setState({ active_tab: tab, active_section: '' @@ -120,8 +150,7 @@ export default class UserSettingsModal extends React.Component { updateSection(section, skipConfirm) { if (!skipConfirm && this.requireConfirm) { - this.afterConfirm = () => this.updateSection(section, true); - this.showConfirmModal(); + this.showConfirmModal(() => this.updateSection(section, true)); } else { this.setState({active_section: section}); } @@ -170,6 +199,8 @@ export default class UserSettingsModal extends React.Component { 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} /> diff --git a/web/react/components/user_settings/user_settings_notifications.jsx b/web/react/components/user_settings/user_settings_notifications.jsx index 49a94b74a..c6f47804f 100644 --- a/web/react/components/user_settings/user_settings_notifications.jsx +++ b/web/react/components/user_settings/user_settings_notifications.jsx @@ -630,15 +630,19 @@ export default class NotificationsTab extends React.Component { className='close' data-dismiss='modal' aria-label='Close' + onClick={this.props.closeModal} > - <span aria-hidden='true'>×</span> + <span aria-hidden='true'>{'×'}</span> </button> <h4 className='modal-title' ref='title' > - <i className='modal-back'></i> - Notifications + <i + className='modal-back' + onClick={this.props.collapseModal} + /> + {'Notification Settings'} </h4> </div> <div @@ -672,5 +676,7 @@ NotificationsTab.propTypes = { updateSection: React.PropTypes.func, updateTab: React.PropTypes.func, activeSection: React.PropTypes.string, - activeTab: React.PropTypes.string + activeTab: React.PropTypes.string, + closeModal: React.PropTypes.func.isRequired, + collapseModal: React.PropTypes.func.isRequired }; diff --git a/web/react/components/user_settings/user_settings_security.jsx b/web/react/components/user_settings/user_settings_security.jsx index c2b8a0093..61d13ed8b 100644 --- a/web/react/components/user_settings/user_settings_security.jsx +++ b/web/react/components/user_settings/user_settings_security.jsx @@ -237,14 +237,19 @@ export default class SecurityTab extends React.Component { className='close' data-dismiss='modal' aria-label='Close' + onClick={this.props.closeModal} > - <span aria-hidden='true'>×</span> + <span aria-hidden='true'>{'×'}</span> </button> <h4 className='modal-title' ref='title' > - <i className='modal-back'></i>Security Settings + <i + className='modal-back' + onClick={this.props.collapseModal} + /> + {'Security Settings'} </h4> </div> <div className='user-settings'> @@ -291,5 +296,7 @@ SecurityTab.propTypes = { activeSection: React.PropTypes.string, updateSection: React.PropTypes.func, updateTab: React.PropTypes.func, + closeModal: React.PropTypes.func.isRequired, + collapseModal: React.PropTypes.func.isRequired, setEnforceFocus: React.PropTypes.func.isRequired }; |