diff options
Diffstat (limited to 'web/react')
-rw-r--r-- | web/react/components/confirm_modal.jsx | 82 | ||||
-rw-r--r-- | web/react/components/invite_member_modal.jsx | 163 | ||||
-rw-r--r-- | web/react/components/navbar_dropdown.jsx | 13 | ||||
-rw-r--r-- | web/react/components/sidebar_right_menu.jsx | 19 | ||||
-rw-r--r-- | web/react/pages/channel.jsx | 6 | ||||
-rw-r--r-- | web/react/utils/channel_intro_mssages.jsx | 3 |
6 files changed, 142 insertions, 144 deletions
diff --git a/web/react/components/confirm_modal.jsx b/web/react/components/confirm_modal.jsx index 12002f33f..60069b2b1 100644 --- a/web/react/components/confirm_modal.jsx +++ b/web/react/components/confirm_modal.jsx @@ -1,70 +1,66 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +const Modal = ReactBootstrap.Modal; + export default class ConfirmModal extends React.Component { constructor(props) { super(props); this.handleConfirm = this.handleConfirm.bind(this); - - this.state = {}; } + handleConfirm() { - $('#' + this.props.parent_id).attr('data-confirm', 'true'); - $('#' + this.props.parent_id).modal('hide'); - $('#' + this.props.id).modal('hide'); + if (this.props.onConfirm) { + this.props.onConfirm(); + } } + render() { return ( - <div - className='modal fade' - id={this.props.id} - tabIndex='-1' - role='dialog' - aria-hidden='true' + <Modal + className='modal-confirm' + show={this.props.show} + onHide={this.props.onCancel} + enforceFocus={false} > - <div className='modal-dialog'> - <div className='modal-content'> - <div className='modal-header'> - <h4 className='modal-title'>{this.props.title}</h4> - </div> - <div className='modal-body'> - {this.props.message} - </div> - <div className='modal-footer'> - <button - type='button' - className='btn btn-default' - data-dismiss='modal' - > - Cancel - </button> - <button - onClick={this.handleConfirm} - type='button' - className='btn btn-primary' - > - {this.props.confirm_button} - </button> - </div> - </div> - </div> - </div> + <Modal.Header closeButton={false}> + <Modal.Title>{this.props.title}</Modal.Title> + </Modal.Header> + <Modal.Body> + {this.props.message} + </Modal.Body> + <Modal.Footer> + <button + type='button' + className='btn btn-default' + onClick={this.props.onCancel} + > + {'Cancel'} + </button> + <button + type='button' + className='btn btn-primary' + onClick={this.props.onConfirm} + > + {this.props.confirm_button} + </button> + </Modal.Footer> + </Modal> ); } } ConfirmModal.defaultProps = { - parent_id: '', - id: '', title: '', message: '', confirm_button: '' }; ConfirmModal.propTypes = { - parent_id: React.PropTypes.string, - id: React.PropTypes.string, + show: React.PropTypes.bool.isRequired, title: React.PropTypes.string, message: React.PropTypes.string, - confirm_button: React.PropTypes.string + confirm_button: React.PropTypes.string, + onConfirm: React.PropTypes.func.isRequired, + onCancel: React.PropTypes.func.isRequired }; diff --git a/web/react/components/invite_member_modal.jsx b/web/react/components/invite_member_modal.jsx index bea700725..71f72625d 100644 --- a/web/react/components/invite_member_modal.jsx +++ b/web/react/components/invite_member_modal.jsx @@ -7,11 +7,14 @@ var UserStore = require('../stores/user_store.jsx'); var TeamStore = require('../stores/team_store.jsx'); var ConfirmModal = require('./confirm_modal.jsx'); +const Modal = ReactBootstrap.Modal; + export default class InviteMemberModal extends React.Component { constructor(props) { super(props); this.handleSubmit = this.handleSubmit.bind(this); + this.handleHide = this.handleHide.bind(this); this.addInviteFields = this.addInviteFields.bind(this); this.clearFields = this.clearFields.bind(this); this.removeInviteFields = this.removeInviteFields.bind(this); @@ -22,38 +25,11 @@ export default class InviteMemberModal extends React.Component { emailErrors: {}, firstNameErrors: {}, lastNameErrors: {}, - emailEnabled: global.window.mm_config.SendEmailNotifications === 'true' + emailEnabled: global.window.mm_config.SendEmailNotifications === 'true', + showConfirmModal: false }; } - componentDidMount() { - var self = this; - $('#invite_member').on('hide.bs.modal', function hide(e) { - if ($('#invite_member').attr('data-confirm') === 'true') { - $('#invite_member').attr('data-confirm', 'false'); - return; - } - - var notEmpty = false; - for (var i = 0; i < self.state.inviteIds.length; i++) { - var index = self.state.inviteIds[i]; - if (ReactDOM.findDOMNode(self.refs['email' + index]).value.trim() !== '') { - notEmpty = true; - break; - } - } - - if (notEmpty) { - $('#confirm_invite_modal').modal('show'); - e.preventDefault(); - } - }); - - $('#invite_member').on('hidden.bs.modal', function show() { - self.clearFields(); - }); - } - handleSubmit() { if (!this.state.emailEnabled) { return; @@ -94,25 +70,55 @@ export default class InviteMemberModal extends React.Component { var data = {}; data.invites = invites; - Client.inviteMembers(data, - function success() { - $(ReactDOM.findDOMNode(this.refs.modal)).attr('data-confirm', 'true'); - $(ReactDOM.findDOMNode(this.refs.modal)).modal('hide'); - }.bind(this), - function fail(err) { + Client.inviteMembers( + data, + () => { + this.handleHide(false); + }, + (err) => { if (err.message === 'This person is already on your team') { emailErrors[err.detailed_error] = err.message; this.setState({emailErrors: emailErrors}); } else { this.setState({serverError: err.message}); } - }.bind(this) + } ); } - componentDidUpdate() { - $(ReactDOM.findDOMNode(this.refs.modalBody)).css('max-height', $(window).height() - 200); - $(ReactDOM.findDOMNode(this.refs.modalBody)).css('overflow-y', 'scroll'); + handleHide(requireConfirm) { + if (requireConfirm) { + var notEmpty = false; + for (var i = 0; i < this.state.inviteIds.length; i++) { + var index = this.state.inviteIds[i]; + if (ReactDOM.findDOMNode(this.refs['email' + index]).value.trim() !== '') { + notEmpty = true; + break; + } + } + + if (notEmpty) { + this.setState({ + showConfirmModal: true + }); + + return; + } + } + + this.clearFields(); + + this.setState({showConfirmModal: false}); + this.props.onModalDismissed(); + } + + 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(); + } + } } addInviteFields() { @@ -292,7 +298,7 @@ export default class InviteMemberModal extends React.Component { ); } else { var teamInviteLink = null; - if (currentUser && this.props.teamType === 'O') { + if (currentUser && TeamStore.getCurrent().type === 'O') { var linkUrl = utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + TeamStore.getCurrent().invite_id; var link = ( @@ -302,11 +308,7 @@ export default class InviteMemberModal extends React.Component { data-target='#get_link' data-title='Team Invite' data-value={linkUrl} - onClick={ - function click() { - $('#invite_member').modal('hide'); - } - } + onClick={() => this.handleHide(this, false)} >Team Invite Link</a> ); @@ -327,64 +329,49 @@ export default class InviteMemberModal extends React.Component { return ( <div> - <div - className='modal fade' - ref='modal' - id='invite_member' - tabIndex='-1' - role='dialog' - aria-hidden='true' + <Modal + className='modal-invite-member' + show={this.props.show} + onHide={this.handleHide.bind(this, true)} + enforceFocus={!this.state.showConfirmModal} > - <div className='modal-dialog'> - <div className='modal-content'> - <div className='modal-header'> + <Modal.Header closeButton={true}> + <Modal.Title>{'Invite New Member'}</Modal.Title> + </Modal.Header> + <Modal.Body ref='modalBody'> + <form role='form'> + {inviteSections} + </form> + {content} + </Modal.Body> + <Modal.Footer> <button type='button' - className='close' - data-dismiss='modal' - aria-label='Close' + className='btn btn-default' + onClick={this.handleHide.bind(this, true)} > - <span aria-hidden='true'>×</span> + {'Cancel'} </button> - <h4 - className='modal-title' - id='myModalLabel' - >Invite New Member</h4> - </div> - <div - ref='modalBody' - className='modal-body' - > - <form role='form'> - {inviteSections} - </form> - {content} - </div> - <div className='modal-footer'> - <button - type='button' - className='btn btn-default' - data-dismiss='modal' - >Cancel</button> - {sendButton} - </div> - </div> - </div> - </div> + {sendButton} + </Modal.Footer> + </Modal> <ConfirmModal - id='confirm_invite_modal' - parent_id='invite_member' title='Discard Invitations?' message='You have unsent invitations, are you sure you want to discard them?' confirm_button='Yes, Discard' + show={this.state.showConfirmModal} + onConfirm={this.handleHide.bind(this, false)} + onCancel={() => this.setState({showConfirmModal: false})} /> </div> ); } - return <div/>; + + return null; } } InviteMemberModal.propTypes = { - teamType: React.PropTypes.string + show: React.PropTypes.bool.isRequired, + onModalDismissed: React.PropTypes.func.isRequired }; diff --git a/web/react/components/navbar_dropdown.jsx b/web/react/components/navbar_dropdown.jsx index dc21fad21..7d7acf5b9 100644 --- a/web/react/components/navbar_dropdown.jsx +++ b/web/react/components/navbar_dropdown.jsx @@ -7,6 +7,7 @@ var UserStore = require('../stores/user_store.jsx'); var TeamStore = require('../stores/team_store.jsx'); var AboutBuildModal = require('./about_build_modal.jsx'); +var InviteMemberModal = require('./invite_member_modal.jsx'); var Constants = require('../utils/constants.jsx'); @@ -41,7 +42,10 @@ export default class NavbarDropdown extends React.Component { this.onListenerChange = this.onListenerChange.bind(this); this.aboutModalDismissed = this.aboutModalDismissed.bind(this); - this.state = getStateFromStores(); + const state = getStateFromStores(); + state.showAboutModal = false; + state.showInviteMemberModal = false; + this.state = state; } handleLogoutClick(e) { e.preventDefault(); @@ -96,8 +100,7 @@ export default class NavbarDropdown extends React.Component { <li> <a href='#' - data-toggle='modal' - data-target='#invite_member' + onClick={() => this.setState({showInviteMemberModal: true})} > {'Invite New Member'} </a> @@ -268,6 +271,10 @@ export default class NavbarDropdown extends React.Component { show={this.state.showAboutModal} onModalDismissed={this.aboutModalDismissed} /> + <InviteMemberModal + show={this.state.showInviteMemberModal} + onModalDismissed={() => this.setState({showInviteMemberModal: false})} + /> </ul> </li> </ul> diff --git a/web/react/components/sidebar_right_menu.jsx b/web/react/components/sidebar_right_menu.jsx index 9350bbd42..5da8829ad 100644 --- a/web/react/components/sidebar_right_menu.jsx +++ b/web/react/components/sidebar_right_menu.jsx @@ -1,6 +1,7 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +var InviteMemberModal = require('./invite_member_modal.jsx'); var UserStore = require('../stores/user_store.jsx'); var TeamStore = require('../stores/team_store.jsx'); var client = require('../utils/client.jsx'); @@ -15,6 +16,10 @@ export default class SidebarRightMenu extends React.Component { super(props); this.handleLogoutClick = this.handleLogoutClick.bind(this); + + this.state = { + showInviteMemberModal: false + }; } handleLogoutClick(e) { @@ -38,10 +43,12 @@ export default class SidebarRightMenu extends React.Component { inviteLink = ( <li> - <a href='#' - data-toggle='modal' - data-target='#invite_member' - ><i className='glyphicon glyphicon-user'></i>Invite New Member</a> + <a + href='#' + onClick={() => this.setState({showInviteMemberModal: true})} + > + <i className='glyphicon glyphicon-user'></i>Invite New Member + </a> </li> ); @@ -141,6 +148,10 @@ export default class SidebarRightMenu extends React.Component { ><i className='glyphicon glyphicon-earphone'></i>Report a Problem</a></li> </ul> </div> + <InviteMemberModal + show={this.state.showInviteMemberModal} + onModalDismissed={() => this.setState({showInviteMemberModal: false})} + /> </div> ); } diff --git a/web/react/pages/channel.jsx b/web/react/pages/channel.jsx index 067dcde50..e0272d276 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'); @@ -103,11 +102,6 @@ function setupChannelPage(props) { ); ReactDOM.render( - <MemberInviteModal teamType={props.TeamType} />, - document.getElementById('invite_member_modal') - ); - - ReactDOM.render( <EditChannelModal />, document.getElementById('edit_channel_modal') ); diff --git a/web/react/utils/channel_intro_mssages.jsx b/web/react/utils/channel_intro_mssages.jsx index b3f868456..fdeb17bc1 100644 --- a/web/react/utils/channel_intro_mssages.jsx +++ b/web/react/utils/channel_intro_mssages.jsx @@ -186,6 +186,8 @@ export function createStandardIntroMessage(channel) { ); } + // TODO show channel_invite modal now that it's a React-Bootstrap modal + return ( <div className='channel-intro'> <h4 className='channel-intro__title'>{'Beginning of ' + uiName}</h4> @@ -213,6 +215,7 @@ export function createStandardIntroMessage(channel) { > <i className='fa fa-user-plus'></i>{'Invite others to this ' + uiType} </a> + </div> ); } |