Ported ConfirmModal and InviteMemberModal to React-Bootstrap
Этот коммит содержится в:
@@ -1,70 +1,66 @@
|
|||||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
const Modal = ReactBootstrap.Modal;
|
||||||
|
|
||||||
export default class ConfirmModal extends React.Component {
|
export default class ConfirmModal extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.handleConfirm = this.handleConfirm.bind(this);
|
this.handleConfirm = this.handleConfirm.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
this.state = {};
|
|
||||||
}
|
|
||||||
handleConfirm() {
|
handleConfirm() {
|
||||||
$('#' + this.props.parent_id).attr('data-confirm', 'true');
|
if (this.props.onConfirm) {
|
||||||
$('#' + this.props.parent_id).modal('hide');
|
this.props.onConfirm();
|
||||||
$('#' + this.props.id).modal('hide');
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div
|
<Modal
|
||||||
className='modal fade'
|
className='modal-confirm'
|
||||||
id={this.props.id}
|
show={this.props.show}
|
||||||
tabIndex='-1'
|
onHide={this.props.onCancel}
|
||||||
role='dialog'
|
enforceFocus={false}
|
||||||
aria-hidden='true'
|
|
||||||
>
|
>
|
||||||
<div className='modal-dialog'>
|
<Modal.Header closeButton={false}>
|
||||||
<div className='modal-content'>
|
<Modal.Title>{this.props.title}</Modal.Title>
|
||||||
<div className='modal-header'>
|
</Modal.Header>
|
||||||
<h4 className='modal-title'>{this.props.title}</h4>
|
<Modal.Body>
|
||||||
</div>
|
{this.props.message}
|
||||||
<div className='modal-body'>
|
</Modal.Body>
|
||||||
{this.props.message}
|
<Modal.Footer>
|
||||||
</div>
|
<button
|
||||||
<div className='modal-footer'>
|
type='button'
|
||||||
<button
|
className='btn btn-default'
|
||||||
type='button'
|
onClick={this.props.onCancel}
|
||||||
className='btn btn-default'
|
>
|
||||||
data-dismiss='modal'
|
{'Cancel'}
|
||||||
>
|
</button>
|
||||||
Cancel
|
<button
|
||||||
</button>
|
type='button'
|
||||||
<button
|
className='btn btn-primary'
|
||||||
onClick={this.handleConfirm}
|
onClick={this.props.onConfirm}
|
||||||
type='button'
|
>
|
||||||
className='btn btn-primary'
|
{this.props.confirm_button}
|
||||||
>
|
</button>
|
||||||
{this.props.confirm_button}
|
</Modal.Footer>
|
||||||
</button>
|
</Modal>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmModal.defaultProps = {
|
ConfirmModal.defaultProps = {
|
||||||
parent_id: '',
|
|
||||||
id: '',
|
|
||||||
title: '',
|
title: '',
|
||||||
message: '',
|
message: '',
|
||||||
confirm_button: ''
|
confirm_button: ''
|
||||||
};
|
};
|
||||||
ConfirmModal.propTypes = {
|
ConfirmModal.propTypes = {
|
||||||
parent_id: React.PropTypes.string,
|
show: React.PropTypes.bool.isRequired,
|
||||||
id: React.PropTypes.string,
|
|
||||||
title: React.PropTypes.string,
|
title: React.PropTypes.string,
|
||||||
message: 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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,11 +7,14 @@ var UserStore = require('../stores/user_store.jsx');
|
|||||||
var TeamStore = require('../stores/team_store.jsx');
|
var TeamStore = require('../stores/team_store.jsx');
|
||||||
var ConfirmModal = require('./confirm_modal.jsx');
|
var ConfirmModal = require('./confirm_modal.jsx');
|
||||||
|
|
||||||
|
const Modal = ReactBootstrap.Modal;
|
||||||
|
|
||||||
export default class InviteMemberModal extends React.Component {
|
export default class InviteMemberModal extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
|
this.handleHide = this.handleHide.bind(this);
|
||||||
this.addInviteFields = this.addInviteFields.bind(this);
|
this.addInviteFields = this.addInviteFields.bind(this);
|
||||||
this.clearFields = this.clearFields.bind(this);
|
this.clearFields = this.clearFields.bind(this);
|
||||||
this.removeInviteFields = this.removeInviteFields.bind(this);
|
this.removeInviteFields = this.removeInviteFields.bind(this);
|
||||||
@@ -22,38 +25,11 @@ export default class InviteMemberModal extends React.Component {
|
|||||||
emailErrors: {},
|
emailErrors: {},
|
||||||
firstNameErrors: {},
|
firstNameErrors: {},
|
||||||
lastNameErrors: {},
|
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() {
|
handleSubmit() {
|
||||||
if (!this.state.emailEnabled) {
|
if (!this.state.emailEnabled) {
|
||||||
return;
|
return;
|
||||||
@@ -94,25 +70,55 @@ export default class InviteMemberModal extends React.Component {
|
|||||||
var data = {};
|
var data = {};
|
||||||
data.invites = invites;
|
data.invites = invites;
|
||||||
|
|
||||||
Client.inviteMembers(data,
|
Client.inviteMembers(
|
||||||
function success() {
|
data,
|
||||||
$(ReactDOM.findDOMNode(this.refs.modal)).attr('data-confirm', 'true');
|
() => {
|
||||||
$(ReactDOM.findDOMNode(this.refs.modal)).modal('hide');
|
this.handleHide(false);
|
||||||
}.bind(this),
|
},
|
||||||
function fail(err) {
|
(err) => {
|
||||||
if (err.message === 'This person is already on your team') {
|
if (err.message === 'This person is already on your team') {
|
||||||
emailErrors[err.detailed_error] = err.message;
|
emailErrors[err.detailed_error] = err.message;
|
||||||
this.setState({emailErrors: emailErrors});
|
this.setState({emailErrors: emailErrors});
|
||||||
} else {
|
} else {
|
||||||
this.setState({serverError: err.message});
|
this.setState({serverError: err.message});
|
||||||
}
|
}
|
||||||
}.bind(this)
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
handleHide(requireConfirm) {
|
||||||
$(ReactDOM.findDOMNode(this.refs.modalBody)).css('max-height', $(window).height() - 200);
|
if (requireConfirm) {
|
||||||
$(ReactDOM.findDOMNode(this.refs.modalBody)).css('overflow-y', 'scroll');
|
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() {
|
addInviteFields() {
|
||||||
@@ -292,7 +298,7 @@ export default class InviteMemberModal extends React.Component {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
var teamInviteLink = null;
|
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 linkUrl = utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + TeamStore.getCurrent().invite_id;
|
||||||
var link =
|
var link =
|
||||||
(
|
(
|
||||||
@@ -302,11 +308,7 @@ export default class InviteMemberModal extends React.Component {
|
|||||||
data-target='#get_link'
|
data-target='#get_link'
|
||||||
data-title='Team Invite'
|
data-title='Team Invite'
|
||||||
data-value={linkUrl}
|
data-value={linkUrl}
|
||||||
onClick={
|
onClick={() => this.handleHide(this, false)}
|
||||||
function click() {
|
|
||||||
$('#invite_member').modal('hide');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>Team Invite Link</a>
|
>Team Invite Link</a>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -327,64 +329,49 @@ export default class InviteMemberModal extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<Modal
|
||||||
className='modal fade'
|
className='modal-invite-member'
|
||||||
ref='modal'
|
show={this.props.show}
|
||||||
id='invite_member'
|
onHide={this.handleHide.bind(this, true)}
|
||||||
tabIndex='-1'
|
enforceFocus={!this.state.showConfirmModal}
|
||||||
role='dialog'
|
|
||||||
aria-hidden='true'
|
|
||||||
>
|
>
|
||||||
<div className='modal-dialog'>
|
<Modal.Header closeButton={true}>
|
||||||
<div className='modal-content'>
|
<Modal.Title>{'Invite New Member'}</Modal.Title>
|
||||||
<div className='modal-header'>
|
</Modal.Header>
|
||||||
|
<Modal.Body ref='modalBody'>
|
||||||
|
<form role='form'>
|
||||||
|
{inviteSections}
|
||||||
|
</form>
|
||||||
|
{content}
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
className='close'
|
className='btn btn-default'
|
||||||
data-dismiss='modal'
|
onClick={this.handleHide.bind(this, true)}
|
||||||
aria-label='Close'
|
|
||||||
>
|
>
|
||||||
<span aria-hidden='true'>×</span>
|
{'Cancel'}
|
||||||
</button>
|
</button>
|
||||||
<h4
|
{sendButton}
|
||||||
className='modal-title'
|
</Modal.Footer>
|
||||||
id='myModalLabel'
|
</Modal>
|
||||||
>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>
|
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
id='confirm_invite_modal'
|
|
||||||
parent_id='invite_member'
|
|
||||||
title='Discard Invitations?'
|
title='Discard Invitations?'
|
||||||
message='You have unsent invitations, are you sure you want to discard them?'
|
message='You have unsent invitations, are you sure you want to discard them?'
|
||||||
confirm_button='Yes, Discard'
|
confirm_button='Yes, Discard'
|
||||||
|
show={this.state.showConfirmModal}
|
||||||
|
onConfirm={this.handleHide.bind(this, false)}
|
||||||
|
onCancel={() => this.setState({showConfirmModal: false})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return <div/>;
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InviteMemberModal.propTypes = {
|
InviteMemberModal.propTypes = {
|
||||||
teamType: React.PropTypes.string
|
show: React.PropTypes.bool.isRequired,
|
||||||
|
onModalDismissed: React.PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ var UserStore = require('../stores/user_store.jsx');
|
|||||||
var TeamStore = require('../stores/team_store.jsx');
|
var TeamStore = require('../stores/team_store.jsx');
|
||||||
|
|
||||||
var AboutBuildModal = require('./about_build_modal.jsx');
|
var AboutBuildModal = require('./about_build_modal.jsx');
|
||||||
|
var InviteMemberModal = require('./invite_member_modal.jsx');
|
||||||
|
|
||||||
var Constants = require('../utils/constants.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.onListenerChange = this.onListenerChange.bind(this);
|
||||||
this.aboutModalDismissed = this.aboutModalDismissed.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) {
|
handleLogoutClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -96,8 +100,7 @@ export default class NavbarDropdown extends React.Component {
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href='#'
|
href='#'
|
||||||
data-toggle='modal'
|
onClick={() => this.setState({showInviteMemberModal: true})}
|
||||||
data-target='#invite_member'
|
|
||||||
>
|
>
|
||||||
{'Invite New Member'}
|
{'Invite New Member'}
|
||||||
</a>
|
</a>
|
||||||
@@ -268,6 +271,10 @@ export default class NavbarDropdown extends React.Component {
|
|||||||
show={this.state.showAboutModal}
|
show={this.state.showAboutModal}
|
||||||
onModalDismissed={this.aboutModalDismissed}
|
onModalDismissed={this.aboutModalDismissed}
|
||||||
/>
|
/>
|
||||||
|
<InviteMemberModal
|
||||||
|
show={this.state.showInviteMemberModal}
|
||||||
|
onModalDismissed={() => this.setState({showInviteMemberModal: false})}
|
||||||
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
var InviteMemberModal = require('./invite_member_modal.jsx');
|
||||||
var UserStore = require('../stores/user_store.jsx');
|
var UserStore = require('../stores/user_store.jsx');
|
||||||
var TeamStore = require('../stores/team_store.jsx');
|
var TeamStore = require('../stores/team_store.jsx');
|
||||||
var client = require('../utils/client.jsx');
|
var client = require('../utils/client.jsx');
|
||||||
@@ -15,6 +16,10 @@ export default class SidebarRightMenu extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.handleLogoutClick = this.handleLogoutClick.bind(this);
|
this.handleLogoutClick = this.handleLogoutClick.bind(this);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
showInviteMemberModal: false
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLogoutClick(e) {
|
handleLogoutClick(e) {
|
||||||
@@ -38,10 +43,12 @@ export default class SidebarRightMenu extends React.Component {
|
|||||||
|
|
||||||
inviteLink = (
|
inviteLink = (
|
||||||
<li>
|
<li>
|
||||||
<a href='#'
|
<a
|
||||||
data-toggle='modal'
|
href='#'
|
||||||
data-target='#invite_member'
|
onClick={() => this.setState({showInviteMemberModal: true})}
|
||||||
><i className='glyphicon glyphicon-user'></i>Invite New Member</a>
|
>
|
||||||
|
<i className='glyphicon glyphicon-user'></i>Invite New Member
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -141,6 +148,10 @@ export default class SidebarRightMenu extends React.Component {
|
|||||||
><i className='glyphicon glyphicon-earphone'></i>Report a Problem</a></li>
|
><i className='glyphicon glyphicon-earphone'></i>Report a Problem</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<InviteMemberModal
|
||||||
|
show={this.state.showInviteMemberModal}
|
||||||
|
onModalDismissed={() => this.setState({showInviteMemberModal: false})}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ var ErrorStore = require('../stores/error_store.jsx');
|
|||||||
|
|
||||||
var MentionList = require('../components/mention_list.jsx');
|
var MentionList = require('../components/mention_list.jsx');
|
||||||
var GetLinkModal = require('../components/get_link_modal.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 EditChannelModal = require('../components/edit_channel_modal.jsx');
|
||||||
var DeleteChannelModal = require('../components/delete_channel_modal.jsx');
|
var DeleteChannelModal = require('../components/delete_channel_modal.jsx');
|
||||||
var RenameChannelModal = require('../components/rename_channel_modal.jsx');
|
var RenameChannelModal = require('../components/rename_channel_modal.jsx');
|
||||||
@@ -102,11 +101,6 @@ function setupChannelPage(props) {
|
|||||||
document.getElementById('team_members_modal')
|
document.getElementById('team_members_modal')
|
||||||
);
|
);
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<MemberInviteModal teamType={props.TeamType} />,
|
|
||||||
document.getElementById('invite_member_modal')
|
|
||||||
);
|
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<EditChannelModal />,
|
<EditChannelModal />,
|
||||||
document.getElementById('edit_channel_modal')
|
document.getElementById('edit_channel_modal')
|
||||||
|
|||||||
@@ -186,6 +186,8 @@ export function createStandardIntroMessage(channel) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO show channel_invite modal now that it's a React-Bootstrap modal
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='channel-intro'>
|
<div className='channel-intro'>
|
||||||
<h4 className='channel-intro__title'>{'Beginning of ' + uiName}</h4>
|
<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}
|
<i className='fa fa-user-plus'></i>{'Invite others to this ' + uiType}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user