Merge pull request #1600 from hmhealey/plt1152
PLT-1152 Fix cross-contamination between invite member modals
Этот коммит содержится в:
@@ -40,7 +40,6 @@ export default class ChannelHeader extends React.Component {
|
||||
|
||||
const state = this.getStateFromStores();
|
||||
state.showEditChannelPurposeModal = false;
|
||||
state.showInviteModal = false;
|
||||
state.showMembersModal = false;
|
||||
this.state = state;
|
||||
}
|
||||
@@ -201,13 +200,13 @@ export default class ChannelHeader extends React.Component {
|
||||
key='add_members'
|
||||
role='presentation'
|
||||
>
|
||||
<a
|
||||
<ToggleModalButton
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={() => this.setState({showInviteModal: true})}
|
||||
dialogType={ChannelInviteModal}
|
||||
dialogProps={{channel}}
|
||||
>
|
||||
{'Add Members'}
|
||||
</a>
|
||||
</ToggleModalButton>
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -402,13 +401,10 @@ export default class ChannelHeader extends React.Component {
|
||||
onModalDismissed={() => this.setState({showEditChannelPurposeModal: false})}
|
||||
channel={channel}
|
||||
/>
|
||||
<ChannelInviteModal
|
||||
show={this.state.showInviteModal}
|
||||
onModalDismissed={() => this.setState({showInviteModal: false})}
|
||||
/>
|
||||
<ChannelMembersModal
|
||||
show={this.state.showMembersModal}
|
||||
onModalDismissed={() => this.setState({showMembersModal: false})}
|
||||
channel={channel}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -53,15 +53,8 @@ export default class ChannelInviteModal extends React.Component {
|
||||
return a.username.localeCompare(b.username);
|
||||
});
|
||||
|
||||
var channelName = '';
|
||||
if (ChannelStore.getCurrent()) {
|
||||
channelName = ChannelStore.getCurrent().display_name;
|
||||
}
|
||||
|
||||
return {
|
||||
nonmembers,
|
||||
memberIds,
|
||||
channelName,
|
||||
loading
|
||||
};
|
||||
}
|
||||
@@ -94,28 +87,14 @@ export default class ChannelInviteModal extends React.Component {
|
||||
}
|
||||
}
|
||||
handleInvite(userId) {
|
||||
// Make sure the user isn't already a member of the channel
|
||||
if (this.state.memberIds.indexOf(userId) > -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = {};
|
||||
data.user_id = userId;
|
||||
|
||||
Client.addChannelMember(ChannelStore.getCurrentId(), data,
|
||||
Client.addChannelMember(
|
||||
this.props.channel.id,
|
||||
data,
|
||||
() => {
|
||||
var nonmembers = this.state.nonmembers;
|
||||
var memberIds = this.state.memberIds;
|
||||
|
||||
for (var i = 0; i < nonmembers.length; i++) {
|
||||
if (userId === nonmembers[i].id) {
|
||||
nonmembers[i].invited = true;
|
||||
memberIds.push(userId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({inviteError: null, memberIds, nonmembers});
|
||||
this.setState({inviteError: null});
|
||||
AsyncClient.getChannelExtraInfo();
|
||||
},
|
||||
(err) => {
|
||||
@@ -157,10 +136,10 @@ export default class ChannelInviteModal extends React.Component {
|
||||
<Modal
|
||||
dialogClassName='more-modal'
|
||||
show={this.props.show}
|
||||
onHide={this.props.onModalDismissed}
|
||||
onHide={this.props.onHide}
|
||||
>
|
||||
<Modal.Header closeButton={true}>
|
||||
<Modal.Title>{'Add New Members to '}<span className='name'>{this.state.channelName}</span></Modal.Title>
|
||||
<Modal.Title>{'Add New Members to '}<span className='name'>{this.props.channel.display_nam}</span></Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body
|
||||
ref='modalBody'
|
||||
@@ -173,7 +152,7 @@ export default class ChannelInviteModal extends React.Component {
|
||||
<button
|
||||
type='button'
|
||||
className='btn btn-default'
|
||||
onClick={this.props.onModalDismissed}
|
||||
onClick={this.props.onHide}
|
||||
>
|
||||
{'Close'}
|
||||
</button>
|
||||
@@ -185,5 +164,6 @@ export default class ChannelInviteModal extends React.Component {
|
||||
|
||||
ChannelInviteModal.propTypes = {
|
||||
show: React.PropTypes.bool.isRequired,
|
||||
onModalDismissed: React.PropTypes.func.isRequired
|
||||
onHide: React.PropTypes.func.isRequired,
|
||||
channel: React.PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
@@ -69,16 +69,9 @@ export default class ChannelMembersModal extends React.Component {
|
||||
memberList.sort(compareByUsername);
|
||||
nonmemberList.sort(compareByUsername);
|
||||
|
||||
const channel = ChannelStore.getCurrent();
|
||||
let channelName = '';
|
||||
if (channel) {
|
||||
channelName = channel.display_name;
|
||||
}
|
||||
|
||||
return {
|
||||
nonmemberList,
|
||||
memberList,
|
||||
channelName
|
||||
memberList
|
||||
};
|
||||
}
|
||||
onShow() {
|
||||
@@ -169,7 +162,7 @@ export default class ChannelMembersModal extends React.Component {
|
||||
onHide={this.props.onModalDismissed}
|
||||
>
|
||||
<Modal.Header closeButton={true}>
|
||||
<Modal.Title><span className='name'>{this.state.channelName}</span>{' Members'}</Modal.Title>
|
||||
<Modal.Title><span className='name'>{this.props.channel.display_name}</span>{' Members'}</Modal.Title>
|
||||
<a
|
||||
className='btn btn-md btn-primary'
|
||||
href='#'
|
||||
@@ -205,7 +198,8 @@ export default class ChannelMembersModal extends React.Component {
|
||||
</Modal>
|
||||
<ChannelInviteModal
|
||||
show={this.state.showInviteModal}
|
||||
onModalDismissed={() => this.setState({showInviteModal: false})}
|
||||
onHide={() => this.setState({showInviteModal: false})}
|
||||
channel={this.props.channel}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -218,5 +212,6 @@ ChannelMembersModal.defaultProps = {
|
||||
|
||||
ChannelMembersModal.propTypes = {
|
||||
show: React.PropTypes.bool.isRequired,
|
||||
onModalDismissed: React.PropTypes.func.isRequired
|
||||
onModalDismissed: React.PropTypes.func.isRequired,
|
||||
channel: React.PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
@@ -31,9 +31,7 @@ export default class MemberListItem extends React.Component {
|
||||
var timestamp = UserStore.getCurrentUser().update_at;
|
||||
|
||||
var invite;
|
||||
if (member.invited && this.props.handleInvite) {
|
||||
invite = <span className='member-role'>Added</span>;
|
||||
} else if (this.props.handleInvite) {
|
||||
if (this.props.handleInvite) {
|
||||
invite = (
|
||||
<a
|
||||
onClick={this.handleInvite}
|
||||
|
||||
@@ -44,7 +44,6 @@ export default class Navbar extends React.Component {
|
||||
state.showEditChannelPurposeModal = false;
|
||||
state.showEditChannelHeaderModal = false;
|
||||
state.showMembersModal = false;
|
||||
state.showInviteModal = false;
|
||||
this.state = state;
|
||||
}
|
||||
getStateFromStores() {
|
||||
@@ -171,13 +170,13 @@ export default class Navbar extends React.Component {
|
||||
if (!isDirect && !ChannelStore.isDefault(channel)) {
|
||||
addMembersOption = (
|
||||
<li role='presentation'>
|
||||
<a
|
||||
<ToggleModalButton
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={() => this.setState({showInviteModal: true})}
|
||||
dialogType={ChannelInviteModal}
|
||||
dialogProps={{channel}}
|
||||
>
|
||||
{'Add Members'}
|
||||
</a>
|
||||
</ToggleModalButton>
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -475,10 +474,7 @@ export default class Navbar extends React.Component {
|
||||
<ChannelMembersModal
|
||||
show={this.state.showMembersModal}
|
||||
onModalDismissed={() => this.setState({showMembersModal: false})}
|
||||
/>
|
||||
<ChannelInviteModal
|
||||
show={this.state.showInviteModal}
|
||||
onModalDismissed={() => this.setState({showInviteModal: false})}
|
||||
channel={{channel}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
import PostsView from './posts_view.jsx';
|
||||
import LoadingScreen from './loading_screen.jsx';
|
||||
import ChannelInviteModal from './channel_invite_modal.jsx';
|
||||
|
||||
import ChannelStore from '../stores/channel_store.jsx';
|
||||
import PostStore from '../stores/post_store.jsx';
|
||||
@@ -13,7 +12,7 @@ import * as EventHelpers from '../dispatcher/event_helpers.jsx';
|
||||
|
||||
import Constants from '../utils/constants.jsx';
|
||||
|
||||
import {createChannelIntroMessage} from '../utils/channel_intro_mssages.jsx';
|
||||
import {createChannelIntroMessage} from '../utils/channel_intro_messages.jsx';
|
||||
|
||||
export default class PostsViewContainer extends React.Component {
|
||||
constructor() {
|
||||
@@ -177,7 +176,7 @@ export default class PostsViewContainer extends React.Component {
|
||||
loadMorePostsBottomClicked={() => {}}
|
||||
showMoreMessagesTop={!this.state.atTop[this.state.currentChannelIndex]}
|
||||
showMoreMessagesBottom={false}
|
||||
introText={channel ? createChannelIntroMessage(channel, () => this.setState({showInviteModal: true})) : null}
|
||||
introText={channel ? createChannelIntroMessage(channel) : null}
|
||||
messageSeparatorTime={this.state.currentLastViewed}
|
||||
/>
|
||||
);
|
||||
@@ -194,10 +193,6 @@ export default class PostsViewContainer extends React.Component {
|
||||
return (
|
||||
<div id='post-list'>
|
||||
{postListCtls}
|
||||
<ChannelInviteModal
|
||||
show={this.state.showInviteModal}
|
||||
onModalDismissed={() => this.setState({showInviteModal: false})}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -167,18 +167,7 @@ class ChannelStoreClass extends EventEmitter {
|
||||
this.emitChange();
|
||||
}
|
||||
getCurrentExtraInfo() {
|
||||
var currentId = this.getCurrentId();
|
||||
var extra = null;
|
||||
|
||||
if (currentId) {
|
||||
extra = this.pGetExtraInfos()[currentId];
|
||||
}
|
||||
|
||||
if (extra == null) {
|
||||
extra = {members: []};
|
||||
}
|
||||
|
||||
return extra;
|
||||
return this.getExtraInfo(this.getCurrentId());
|
||||
}
|
||||
getExtraInfo(channelId) {
|
||||
var extra = null;
|
||||
@@ -187,7 +176,10 @@ class ChannelStoreClass extends EventEmitter {
|
||||
extra = this.pGetExtraInfos()[channelId];
|
||||
}
|
||||
|
||||
if (extra == null) {
|
||||
if (extra) {
|
||||
// create a defensive copy
|
||||
extra = JSON.parse(JSON.stringify(extra));
|
||||
} else {
|
||||
extra = {members: []};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// See License.txt for license information.
|
||||
|
||||
import * as Utils from './utils.jsx';
|
||||
import ChannelInviteModal from '../components/channel_invite_modal.jsx';
|
||||
import EditChannelHeaderModal from '../components/edit_channel_header_modal.jsx';
|
||||
import ToggleModalButton from '../components/toggle_modal_button.jsx';
|
||||
import UserProfile from '../components/user_profile.jsx';
|
||||
@@ -10,15 +11,15 @@ import Constants from '../utils/constants.jsx';
|
||||
import TeamStore from '../stores/team_store.jsx';
|
||||
import * as EventHelpers from '../dispatcher/event_helpers.jsx';
|
||||
|
||||
export function createChannelIntroMessage(channel, showInviteModal) {
|
||||
export function createChannelIntroMessage(channel) {
|
||||
if (channel.type === 'D') {
|
||||
return createDMIntroMessage(channel);
|
||||
} else if (ChannelStore.isDefault(channel)) {
|
||||
return createDefaultIntroMessage(channel);
|
||||
} else if (channel.name === Constants.OFFTOPIC_CHANNEL) {
|
||||
return createOffTopicIntroMessage(channel, showInviteModal);
|
||||
return createOffTopicIntroMessage(channel);
|
||||
} else if (channel.type === 'O' || channel.type === 'P') {
|
||||
return createStandardIntroMessage(channel, showInviteModal);
|
||||
return createStandardIntroMessage(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ export function createDMIntroMessage(channel) {
|
||||
);
|
||||
}
|
||||
|
||||
export function createOffTopicIntroMessage(channel, showInviteModal) {
|
||||
export function createOffTopicIntroMessage(channel) {
|
||||
return (
|
||||
<div className='channel-intro'>
|
||||
<h4 className='channel-intro__title'>{'Beginning of ' + channel.display_name}</h4>
|
||||
@@ -71,13 +72,7 @@ export function createOffTopicIntroMessage(channel, showInviteModal) {
|
||||
<br/>
|
||||
</p>
|
||||
{createSetHeaderButton(channel)}
|
||||
<a
|
||||
href='#'
|
||||
className='intro-links'
|
||||
onClick={showInviteModal}
|
||||
>
|
||||
<i className='fa fa-user-plus'></i>{'Invite others to this channel'}
|
||||
</a>
|
||||
{createInviteChannelMemberButton(channel, 'channel')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -122,7 +117,7 @@ export function createDefaultIntroMessage(channel) {
|
||||
);
|
||||
}
|
||||
|
||||
export function createStandardIntroMessage(channel, showInviteModal) {
|
||||
export function createStandardIntroMessage(channel) {
|
||||
var uiName = channel.display_name;
|
||||
var creatorName = '';
|
||||
|
||||
@@ -162,17 +157,23 @@ export function createStandardIntroMessage(channel, showInviteModal) {
|
||||
<br/>
|
||||
</p>
|
||||
{createSetHeaderButton(channel)}
|
||||
<a
|
||||
className='intro-links'
|
||||
href='#'
|
||||
onClick={showInviteModal}
|
||||
>
|
||||
<i className='fa fa-user-plus'></i>{'Invite others to this ' + uiType}
|
||||
</a>
|
||||
{createInviteChannelMemberButton(channel, uiType)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function createInviteChannelMemberButton(channel, uiType) {
|
||||
return (
|
||||
<ToggleModalButton
|
||||
className='intro-links'
|
||||
dialogType={ChannelInviteModal}
|
||||
dialogProps={{channel}}
|
||||
>
|
||||
<i className='fa fa-user-plus'></i>{'Invite others to this ' + uiType}
|
||||
</ToggleModalButton>
|
||||
);
|
||||
}
|
||||
|
||||
function createSetHeaderButton(channel) {
|
||||
return (
|
||||
<ToggleModalButton
|
||||
Ссылка в новой задаче
Block a user