From 0b52e85ba73e5b3badeb1703462c5d05d3a7d224 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Tue, 10 Nov 2015 10:20:16 -0500 Subject: Added Modal base class that extends ReactBootstrap.Modal --- web/react/components/access_history_modal.jsx | 9 +--- web/react/components/activity_log_modal.jsx | 6 +-- web/react/components/confirm_modal.jsx | 2 +- web/react/components/modal.jsx | 48 ++++++++++++++++++++++ .../user_settings/user_settings_modal.jsx | 14 +++---- 5 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 web/react/components/modal.jsx (limited to 'web/react/components') diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index ab5686720..6a10f87b2 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -1,7 +1,7 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -var Modal = ReactBootstrap.Modal; +var Modal = require('./modal.jsx'); var UserStore = require('../stores/user_store.jsx'); var ChannelStore = require('../stores/channel_store.jsx'); var AsyncClient = require('../utils/async_client.jsx'); @@ -15,7 +15,6 @@ export default class AccessHistoryModal extends React.Component { this.onAuditChange = this.onAuditChange.bind(this); this.handleMoreInfo = this.handleMoreInfo.bind(this); this.onHide = this.onHide.bind(this); - this.onShow = this.onShow.bind(this); this.formatAuditInfo = this.formatAuditInfo.bind(this); this.handleRevokedSession = this.handleRevokedSession.bind(this); @@ -44,11 +43,6 @@ export default class AccessHistoryModal extends React.Component { componentDidMount() { UserStore.addAuditsChangeListener(this.onAuditChange); } - componentDidUpdate(prevProps) { - if (this.props.show && !prevProps.show) { - this.onShow(); - } - } componentWillUnmount() { UserStore.removeAuditsChangeListener(this.onAuditChange); } @@ -391,6 +385,7 @@ export default class AccessHistoryModal extends React.Component { diff --git a/web/react/components/activity_log_modal.jsx b/web/react/components/activity_log_modal.jsx index af423a601..6c329d416 100644 --- a/web/react/components/activity_log_modal.jsx +++ b/web/react/components/activity_log_modal.jsx @@ -63,11 +63,6 @@ export default class ActivityLogModal extends React.Component { componentDidMount() { UserStore.addSessionsChangeListener(this.onListenerChange); } - componentDidUpdate(prevProps) { - if (this.props.show && !prevProps.show) { - this.onShow(); - } - } componentWillUnmount() { UserStore.removeSessionsChangeListener(this.onListenerChange); } @@ -161,6 +156,7 @@ export default class ActivityLogModal extends React.Component { return ( diff --git a/web/react/components/confirm_modal.jsx b/web/react/components/confirm_modal.jsx index cdef1c1ea..a1138bf45 100644 --- a/web/react/components/confirm_modal.jsx +++ b/web/react/components/confirm_modal.jsx @@ -1,7 +1,7 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -const Modal = ReactBootstrap.Modal; +const Modal = require('./modal.jsx'); export default class ConfirmModal extends React.Component { constructor(props) { diff --git a/web/react/components/modal.jsx b/web/react/components/modal.jsx new file mode 100644 index 000000000..758a68847 --- /dev/null +++ b/web/react/components/modal.jsx @@ -0,0 +1,48 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +export default class Modal extends ReactBootstrap.Modal { + constructor(props) { + super(props); + } + + componentWillMount() { + if (this.props.show && this.props.onPreshow) { + this.props.onPreshow(); + } + } + + componentDidMount() { + super.componentDidMount(); + + if (this.props.show && this.props.onShow) { + this.props.onShow(); + } + } + + componentDidUpdate(prevProps) { + super.componentDidUpdate(prevProps); + + if (this.props.show && !prevProps.show && this.props.onShow) { + this.props.onShow(); + } + } + + componentWillReceiveProps(nextProps) { + super.componentWillReceiveProps(nextProps); + + if (nextProps.show && !this.props.show && this.props.onPreshow) { + this.props.onPreshow(); + } + } +} + +Modal.propTypes = { + ...ReactBootstrap.Modal.propTypes, + + // called before showing the dialog to allow for a state change before rendering + onPreshow: React.PropTypes.func, + + // called after the dialog has been shown and rendered + onShow: React.PropTypes.func +}; diff --git a/web/react/components/user_settings/user_settings_modal.jsx b/web/react/components/user_settings/user_settings_modal.jsx index 4dcf32cb9..85a8d0473 100644 --- a/web/react/components/user_settings/user_settings_modal.jsx +++ b/web/react/components/user_settings/user_settings_modal.jsx @@ -2,7 +2,7 @@ // See License.txt for license information. const ConfirmModal = require('../confirm_modal.jsx'); -const Modal = ReactBootstrap.Modal; +const Modal = require('../modal.jsx'); const SettingsSidebar = require('../settings_sidebar.jsx'); const UserSettings = require('./user_settings.jsx'); @@ -10,6 +10,7 @@ export default class UserSettingsModal extends React.Component { constructor(props) { super(props); + this.handleShow = this.handleShow.bind(this); this.handleHide = this.handleHide.bind(this); this.handleHidden = this.handleHidden.bind(this); this.handleCollapse = this.handleCollapse.bind(this); @@ -33,12 +34,10 @@ export default class UserSettingsModal extends React.Component { 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(); - } + handleShow() { + $(ReactDOM.findDOMNode(this.refs.modalBody)).css('max-height', $(window).height() - 300); + if ($(window).width() > 768) { + $(ReactDOM.findDOMNode(this.refs.modalBody)).perfectScrollbar(); } } @@ -176,6 +175,7 @@ export default class UserSettingsModal extends React.Component { Date: Tue, 10 Nov 2015 10:27:10 -0500 Subject: Added ToggleModalButton component --- web/react/components/toggle_modal_button.jsx | 62 ++++++++++++++++++++++ .../user_settings/user_settings_security.jsx | 48 ++++------------- 2 files changed, 71 insertions(+), 39 deletions(-) create mode 100644 web/react/components/toggle_modal_button.jsx (limited to 'web/react/components') diff --git a/web/react/components/toggle_modal_button.jsx b/web/react/components/toggle_modal_button.jsx new file mode 100644 index 000000000..86ee439a5 --- /dev/null +++ b/web/react/components/toggle_modal_button.jsx @@ -0,0 +1,62 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +export default class ModalToggleButton extends React.Component { + constructor(props) { + super(props); + + this.show = this.show.bind(this); + this.hide = this.hide.bind(this); + + this.state = { + show: false + }; + } + + show() { + this.setState({show: true}); + } + + hide() { + this.setState({show: false}); + } + + render() { + const {children, dialogType, dialogProps, ...props} = this.props; + + // this assumes that all modals will have a show property and an onModalDismissed event + const dialog = React.createElement(this.props.dialogType, Object.assign({}, dialogProps, { + show: this.state.show, + onModalDismissed: () => { + this.hide(); + + if (dialogProps.onModalDismissed) { + dialogProps.onModalDismissed(); + } + } + })); + + return ( +
+ + {children} + + {dialog} +
+ ); + } +} + +ModalToggleButton.propTypes = { + children: React.PropTypes.node.isRequired, + dialogType: React.PropTypes.func.isRequired, + dialogProps: React.PropTypes.object +}; + +ModalToggleButton.defaultProps = { + dialogProps: {} +}; diff --git a/web/react/components/user_settings/user_settings_security.jsx b/web/react/components/user_settings/user_settings_security.jsx index 61d13ed8b..16ace0abc 100644 --- a/web/react/components/user_settings/user_settings_security.jsx +++ b/web/react/components/user_settings/user_settings_security.jsx @@ -5,6 +5,7 @@ var SettingItemMin = require('../setting_item_min.jsx'); var SettingItemMax = require('../setting_item_max.jsx'); var AccessHistoryModal = require('../access_history_modal.jsx'); var ActivityLogModal = require('../activity_log_modal.jsx'); +var ToggleModalButton = require('../toggle_modal_button.jsx'); var Client = require('../../utils/client.jsx'); var AsyncClient = require('../../utils/async_client.jsx'); var Constants = require('../../utils/constants.jsx'); @@ -13,34 +14,13 @@ export default class SecurityTab extends React.Component { constructor(props) { super(props); - this.showAccessHistoryModal = this.showAccessHistoryModal.bind(this); - this.showActivityLogModal = this.showActivityLogModal.bind(this); - this.hideModals = this.hideModals.bind(this); this.submitPassword = this.submitPassword.bind(this); this.updateCurrentPassword = this.updateCurrentPassword.bind(this); this.updateNewPassword = this.updateNewPassword.bind(this); this.updateConfirmPassword = this.updateConfirmPassword.bind(this); this.setupInitialState = this.setupInitialState.bind(this); - const state = this.setupInitialState(); - state.showAccessHistoryModal = false; - state.showActivityLogModal = false; - this.state = state; - } - showAccessHistoryModal() { - this.props.setEnforceFocus(false); - this.setState({showAccessHistoryModal: true}); - } - showActivityLogModal() { - this.props.setEnforceFocus(false); - this.setState({showActivityLogModal: true}); - } - hideModals() { - this.props.setEnforceFocus(true); - this.setState({ - showAccessHistoryModal: false, - showActivityLogModal: false - }); + this.state = this.setupInitialState(); } submitPassword(e) { e.preventDefault(); @@ -258,30 +238,20 @@ export default class SecurityTab extends React.Component { {passwordSection}


- View Access History - + - - View and Logout of Active Sessions - + {'View and Logout of Active Sessions'} +
- - ); } -- cgit v1.2.3-1-g7c22 From 590e7f903f3b911566465b2fb51ff68c273ded96 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Tue, 10 Nov 2015 11:54:43 -0500 Subject: Renamed onModalDismissed to onHide to keep it consistent with React-Bootstrap --- web/react/components/access_history_modal.jsx | 5 +++-- web/react/components/activity_log_modal.jsx | 6 +++--- web/react/components/toggle_modal_button.jsx | 26 +++++++++++++------------- 3 files changed, 19 insertions(+), 18 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index 6a10f87b2..8306a4e8c 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -14,6 +14,7 @@ export default class AccessHistoryModal extends React.Component { this.onAuditChange = this.onAuditChange.bind(this); this.handleMoreInfo = this.handleMoreInfo.bind(this); + this.onShow = this.onShow.bind(this); this.onHide = this.onHide.bind(this); this.formatAuditInfo = this.formatAuditInfo.bind(this); this.handleRevokedSession = this.handleRevokedSession.bind(this); @@ -38,7 +39,7 @@ export default class AccessHistoryModal extends React.Component { } onHide() { this.setState({moreInfo: []}); - this.props.onModalDismissed(); + this.props.onHide(); } componentDidMount() { UserStore.addAuditsChangeListener(this.onAuditChange); @@ -401,5 +402,5 @@ export default class AccessHistoryModal extends React.Component { AccessHistoryModal.propTypes = { show: React.PropTypes.bool.isRequired, - onModalDismissed: React.PropTypes.func.isRequired + onHide: React.PropTypes.func.isRequired }; diff --git a/web/react/components/activity_log_modal.jsx b/web/react/components/activity_log_modal.jsx index 6c329d416..5c385c93d 100644 --- a/web/react/components/activity_log_modal.jsx +++ b/web/react/components/activity_log_modal.jsx @@ -4,7 +4,7 @@ const UserStore = require('../stores/user_store.jsx'); const Client = require('../utils/client.jsx'); const AsyncClient = require('../utils/async_client.jsx'); -const Modal = ReactBootstrap.Modal; +const Modal = require('./modal.jsx'); const LoadingScreen = require('./loading_screen.jsx'); const Utils = require('../utils/utils.jsx'); @@ -58,7 +58,7 @@ export default class ActivityLogModal extends React.Component { } onHide() { this.setState({moreInfo: []}); - this.props.onModalDismissed(); + this.props.onHide(); } componentDidMount() { UserStore.addSessionsChangeListener(this.onListenerChange); @@ -174,5 +174,5 @@ export default class ActivityLogModal extends React.Component { ActivityLogModal.propTypes = { show: React.PropTypes.bool.isRequired, - onModalDismissed: React.PropTypes.func.isRequired + onHide: React.PropTypes.func.isRequired }; diff --git a/web/react/components/toggle_modal_button.jsx b/web/react/components/toggle_modal_button.jsx index 86ee439a5..51c8d1f20 100644 --- a/web/react/components/toggle_modal_button.jsx +++ b/web/react/components/toggle_modal_button.jsx @@ -24,29 +24,29 @@ export default class ModalToggleButton extends React.Component { render() { const {children, dialogType, dialogProps, ...props} = this.props; - // this assumes that all modals will have a show property and an onModalDismissed event + // this assumes that all modals will have a show property and an onHide event const dialog = React.createElement(this.props.dialogType, Object.assign({}, dialogProps, { show: this.state.show, - onModalDismissed: () => { + onHide: () => { this.hide(); - if (dialogProps.onModalDismissed) { - dialogProps.onModalDismissed(); + if (dialogProps.onHide) { + dialogProps.onHide(); } } })); + // nesting the dialog in the anchor tag looks like it shouldn't work, but it does due to how react-bootstrap + // renders modals at the top level of the DOM instead of where you specify in the virtual DOM return ( - + ); } } -- cgit v1.2.3-1-g7c22 From 66638c4f70adb3fa2777af03c6175347b8dbee6b Mon Sep 17 00:00:00 2001 From: hmhealey Date: Tue, 10 Nov 2015 13:23:10 -0500 Subject: Converted ChannelInfoModal to React-Bootstrap --- web/react/components/channel_header.jsx | 12 +-- web/react/components/channel_info_modal.jsx | 112 ++++++++++------------------ web/react/components/navbar.jsx | 12 +-- 3 files changed, 53 insertions(+), 83 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index 79c7f90a9..33f20cd9e 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -5,8 +5,10 @@ const NavbarSearchBox = require('./search_bar.jsx'); const MessageWrapper = require('./message_wrapper.jsx'); const PopoverListMembers = require('./popover_list_members.jsx'); const EditChannelPurposeModal = require('./edit_channel_purpose_modal.jsx'); +const ChannelInfoModal = require('./channel_info_modal.jsx'); const ChannelInviteModal = require('./channel_invite_modal.jsx'); const ChannelMembersModal = require('./channel_members_modal.jsx'); +const ToggleModalButton = require('./toggle_modal_button.jsx'); const ChannelStore = require('../stores/channel_store.jsx'); const UserStore = require('../stores/user_store.jsx'); @@ -180,15 +182,13 @@ export default class ChannelHeader extends React.Component { key='view_info' role='presentation' > - {'View Info'} - + ); diff --git a/web/react/components/channel_info_modal.jsx b/web/react/components/channel_info_modal.jsx index bccd8d0b9..5eac6be0f 100644 --- a/web/react/components/channel_info_modal.jsx +++ b/web/react/components/channel_info_modal.jsx @@ -1,88 +1,58 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -var ChannelStore = require('../stores/channel_store.jsx'); - -export default class CommandList extends React.Component { - constructor(props) { - super(props); - - this.state = { - channel_id: ChannelStore.getCurrentId() - }; - } - - componentDidMount() { - var self = this; - if (this.refs.modal) { - $(ReactDOM.findDOMNode(this.refs.modal)).on('show.bs.modal', function show(e) { - var button = e.relatedTarget; - self.setState({channel_id: $(button).attr('data-channelid')}); - }); - } - } +const Modal = require('./modal.jsx'); +export default class ChannelInfoModal extends React.Component { render() { - var channel = ChannelStore.get(this.state.channel_id); - + let channel = this.props.channel; if (!channel) { - channel = {}; - channel.display_name = 'No Channel Found'; - channel.name = 'No Channel Found'; - channel.id = 'No Channel Found'; + channel = { + display_name: 'No Channel Found', + name: 'No Channel Found', + id: 'No Channel Found' + }; } return ( -