diff options
Diffstat (limited to 'webapp/components/channel_invite_modal.jsx')
-rw-r--r-- | webapp/components/channel_invite_modal.jsx | 166 |
1 files changed, 77 insertions, 89 deletions
diff --git a/webapp/components/channel_invite_modal.jsx b/webapp/components/channel_invite_modal.jsx index c7c1906a5..99a4b9313 100644 --- a/webapp/components/channel_invite_modal.jsx +++ b/webapp/components/channel_invite_modal.jsx @@ -1,124 +1,85 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import $ from 'jquery'; import ChannelInviteButton from './channel_invite_button.jsx'; -import FilteredUserList from './filtered_user_list.jsx'; +import SearchableUserList from './searchable_user_list.jsx'; import LoadingScreen from './loading_screen.jsx'; import ChannelStore from 'stores/channel_store.jsx'; import UserStore from 'stores/user_store.jsx'; +import TeamStore from 'stores/team_store.jsx'; + +import {searchUsers} from 'actions/user_actions.jsx'; import * as Utils from 'utils/utils.jsx'; import * as AsyncClient from 'utils/async_client.jsx'; -import {FormattedMessage} from 'react-intl'; - +import React from 'react'; import {Modal} from 'react-bootstrap'; +import {FormattedMessage} from 'react-intl'; -import React from 'react'; +const USERS_PER_PAGE = 50; export default class ChannelInviteModal extends React.Component { constructor(props) { super(props); - this.onListenerChange = this.onListenerChange.bind(this); - this.getStateFromStores = this.getStateFromStores.bind(this); + this.onChange = this.onChange.bind(this); this.handleInviteError = this.handleInviteError.bind(this); + this.nextPage = this.nextPage.bind(this); + this.search = this.search.bind(this); - this.state = this.getStateFromStores(); - } - shouldComponentUpdate(nextProps, nextState) { - if (!this.props.show && !nextProps.show) { - return false; - } - - if (!Utils.areObjectsEqual(this.props, nextProps)) { - return true; - } - - if (!Utils.areObjectsEqual(this.state, nextState)) { - return true; - } - - return false; - } - getStateFromStores() { - const users = UserStore.getActiveOnlyProfiles(); - - if ($.isEmptyObject(users)) { - return { - loading: true - }; - } - - // make sure we have all members of this channel before rendering - const extraInfo = ChannelStore.getCurrentExtraInfo(); - if (extraInfo.member_count !== extraInfo.members.length) { - AsyncClient.getChannelExtraInfo(this.props.channel.id, -1); - - return { - loading: true - }; - } - - const currentUser = UserStore.getCurrentUser(); - if (!currentUser) { - return { - loading: true - }; - } - - const currentMember = ChannelStore.getCurrentMember(); - if (!currentMember) { - return { - loading: true - }; - } + this.term = ''; - const memberIds = extraInfo.members.map((user) => user.id); + const channelStats = ChannelStore.getStats(props.channel.id); + const teamStats = TeamStore.getCurrentStats(); - var nonmembers = []; - for (var id in users) { - if (memberIds.indexOf(id) === -1) { - nonmembers.push(users[id]); - } - } - - nonmembers.sort((a, b) => { - return a.username.localeCompare(b.username); - }); - - return { - nonmembers, - loading: false, - currentUser, - currentMember + this.state = { + users: [], + total: teamStats.member_count - channelStats.member_count, + search: false }; } + componentWillReceiveProps(nextProps) { if (!this.props.show && nextProps.show) { - ChannelStore.addExtraInfoChangeListener(this.onListenerChange); - ChannelStore.addChangeListener(this.onListenerChange); - UserStore.addChangeListener(this.onListenerChange); - this.onListenerChange(); + TeamStore.addStatsChangeListener(this.onChange); + ChannelStore.addStatsChangeListener(this.onChange); + UserStore.addNotInChannelChangeListener(this.onChange); + UserStore.addStatusesChangeListener(this.onChange); + + this.onChange(); + AsyncClient.getProfilesNotInChannel(this.props.channel.id, 0); + AsyncClient.getTeamStats(TeamStore.getCurrentId()); } else if (this.props.show && !nextProps.show) { - ChannelStore.removeExtraInfoChangeListener(this.onListenerChange); - ChannelStore.removeChangeListener(this.onListenerChange); - UserStore.removeChangeListener(this.onListenerChange); + TeamStore.removeStatsChangeListener(this.onChange); + ChannelStore.removeStatsChangeListener(this.onChange); + UserStore.removeNotInChannelChangeListener(this.onChange); + UserStore.removeStatusesChangeListener(this.onChange); } } + componentWillUnmount() { - ChannelStore.removeExtraInfoChangeListener(this.onListenerChange); - ChannelStore.removeChangeListener(this.onListenerChange); - UserStore.removeChangeListener(this.onListenerChange); + ChannelStore.removeStatsChangeListener(this.onChange); + ChannelStore.removeChangeListener(this.onChange); + UserStore.removeNotInChannelChangeListener(this.onChange); } - onListenerChange() { - var newState = this.getStateFromStores(); - if (!Utils.areObjectsEqual(this.state, newState)) { - this.setState(newState); + + onChange() { + if (this.state.search) { + this.search(this.term); + return; } + + const channelStats = ChannelStore.getStats(this.props.channel.id); + const teamStats = TeamStore.getCurrentStats(); + + this.setState({ + users: UserStore.getProfileListNotInChannel(this.props.channel.id), + total: teamStats.member_count - channelStats.member_count + }); } + handleInviteError(err) { if (err) { this.setState({ @@ -130,6 +91,29 @@ export default class ChannelInviteModal extends React.Component { }); } } + + nextPage(page) { + AsyncClient.getProfilesNotInChannel(this.props.channel.id, (page + 1) * USERS_PER_PAGE, USERS_PER_PAGE); + } + + search(term) { + this.term = term; + + if (term === '') { + this.setState({users: UserStore.getProfileListNotInChannel(), search: false}); + return; + } + + searchUsers( + term, + TeamStore.getCurrentId(), + {not_in_channel: this.props.channel.id}, + (users) => { + this.setState({search: true, users}); + } + ); + } + render() { var inviteError = null; if (this.state.inviteError) { @@ -145,9 +129,13 @@ export default class ChannelInviteModal extends React.Component { maxHeight = Utils.windowHeight() - 300; } content = ( - <FilteredUserList + <SearchableUserList style={{maxHeight}} - users={this.state.nonmembers} + users={this.state.users} + usersPerPage={USERS_PER_PAGE} + total={this.state.total} + nextPage={this.nextPage} + search={this.search} actions={[ChannelInviteButton]} actionProps={{ channel: this.props.channel, |