diff options
author | Joram Wilander <jwawilander@gmail.com> | 2017-04-25 11:46:02 -0400 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2017-04-25 11:46:02 -0400 |
commit | 6c4c706313eb765eb00c639f381646be74f27b69 (patch) | |
tree | 6068feaa9668dcd74601730ac1a5abfb366402b1 /webapp/components/popover_list_members/popover_list_members.jsx | |
parent | cc07c005074348de87854f1c953a549e8772fa03 (diff) | |
download | chat-6c4c706313eb765eb00c639f381646be74f27b69.tar.gz chat-6c4c706313eb765eb00c639f381646be74f27b69.tar.bz2 chat-6c4c706313eb765eb00c639f381646be74f27b69.zip |
Start moving webapp to Redux (#6140)
* Start moving webapp to Redux
* Fix localforage import
* Updates per feedback
* Feedback udpates and a few fixes
* Minor updates
* Fix statuses, config not loading properly, getMe sanitizing too much
* Fix preferences
* Fix user autocomplete
* Fix sessions and audits
* Fix error handling for all redux actions
* Use new directory structure for components and containers
* Refresh immediately on logout instead of after timeout
* Add fetch polyfill
Diffstat (limited to 'webapp/components/popover_list_members/popover_list_members.jsx')
-rw-r--r-- | webapp/components/popover_list_members/popover_list_members.jsx | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/webapp/components/popover_list_members/popover_list_members.jsx b/webapp/components/popover_list_members/popover_list_members.jsx new file mode 100644 index 000000000..e435126ff --- /dev/null +++ b/webapp/components/popover_list_members/popover_list_members.jsx @@ -0,0 +1,282 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import ProfilePicture from 'components/profile_picture.jsx'; + +import TeamStore from 'stores/team_store.jsx'; +import UserStore from 'stores/user_store.jsx'; +import ChannelStore from 'stores/channel_store.jsx'; + +import TeamMembersModal from 'components/team_members_modal.jsx'; +import ChannelMembersModal from 'components/channel_members_modal.jsx'; +import ChannelInviteModal from 'components/channel_invite_modal'; + +import {openDirectChannelToUser} from 'actions/channel_actions.jsx'; + +import Client from 'client/web_client.jsx'; +import * as Utils from 'utils/utils.jsx'; +import Constants from 'utils/constants.jsx'; +import {canManageMembers} from 'utils/channel_utils.jsx'; + +import $ from 'jquery'; +import React from 'react'; +import {Popover, Overlay} from 'react-bootstrap'; +import {FormattedMessage} from 'react-intl'; +import {browserHistory} from 'react-router/es6'; + +export default class PopoverListMembers extends React.Component { + static propTypes = { + channel: React.PropTypes.object.isRequired, + members: React.PropTypes.array.isRequired, + memberCount: React.PropTypes.number, + actions: React.PropTypes.shape({ + getProfilesInChannel: React.PropTypes.func.isRequired + }).isRequired + } + + constructor(props) { + super(props); + + this.showMembersModal = this.showMembersModal.bind(this); + + this.handleShowDirectChannel = this.handleShowDirectChannel.bind(this); + this.closePopover = this.closePopover.bind(this); + + this.state = { + showPopover: false, + showTeamMembersModal: false, + showChannelMembersModal: false, + showChannelInviteModal: false + }; + } + + componentDidUpdate() { + $('.member-list__popover .popover-content').perfectScrollbar(); + } + + handleShowDirectChannel(teammate, e) { + e.preventDefault(); + + openDirectChannelToUser( + teammate.id, + (channel, channelAlreadyExisted) => { + browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + channel.name); + if (channelAlreadyExisted) { + this.closePopover(); + } + }, + () => { + this.closePopover(); + } + ); + } + + closePopover() { + this.setState({showPopover: false}); + } + + showMembersModal(e) { + e.preventDefault(); + + this.setState({ + showPopover: false, + showChannelMembersModal: true + }); + } + + render() { + const popoverHtml = []; + const members = this.props.members; + const teamMembers = UserStore.getProfilesUsernameMap(); + const currentUserId = UserStore.getCurrentId(); + + const isSystemAdmin = UserStore.isSystemAdminForCurrentUser(); + const isTeamAdmin = TeamStore.isTeamAdminForCurrentTeam(); + const isChannelAdmin = ChannelStore.isChannelAdminForCurrentChannel(); + + if (members && teamMembers) { + members.sort((a, b) => { + const aName = Utils.displayUsername(a.id); + const bName = Utils.displayUsername(b.id); + + return aName.localeCompare(bName); + }); + + members.forEach((m, i) => { + let button = ''; + if (currentUserId !== m.id && this.props.channel.type !== Constants.DM_CHANNEl) { + button = ( + <a + href='#' + className='btn-message' + onClick={(e) => this.handleShowDirectChannel(m, e)} + > + <FormattedMessage + id='members_popover.msg' + defaultMessage='Message' + /> + </a> + ); + } + + let name = ''; + if (teamMembers[m.username]) { + name = Utils.displayUsername(teamMembers[m.username].id); + } + + if (name) { + popoverHtml.push( + <div + className='more-modal__row' + key={'popover-member-' + i} + > + <ProfilePicture + src={`${Client.getUsersRoute()}/${m.id}/image?time=${m.last_picture_update}`} + width='26' + height='26' + /> + <div className='more-modal__details'> + <div + className='more-modal__name' + > + {name} + </div> + </div> + <div + className='more-modal__actions' + > + {button} + </div> + </div> + ); + } + }); + + if (this.props.channel.type !== Constants.GM_CHANNEL) { + let membersName = ( + <FormattedMessage + id='members_popover.manageMembers' + defaultMessage='Manage Members' + /> + ); + + const manageMembers = canManageMembers(this.props.channel, isSystemAdmin, isTeamAdmin, isChannelAdmin); + const isDefaultChannel = ChannelStore.isDefault(this.props.channel); + + if ((manageMembers === false && isDefaultChannel === false) || isDefaultChannel) { + membersName = ( + <FormattedMessage + id='members_popover.viewMembers' + defaultMessage='View Members' + /> + ); + } + + popoverHtml.push( + <div + className='more-modal__row' + key={'popover-member-more'} + > + <div className='col-sm-3'/> + <div className='more-modal__details'> + <div + className='more-modal__name' + > + <a + href='#' + onClick={this.showMembersModal} + > + {membersName} + </a> + </div> + </div> + </div> + ); + } + } + + const count = this.props.memberCount; + let countText = '-'; + if (count > 0) { + countText = count.toString(); + } + + const title = ( + <FormattedMessage + id='members_popover.title' + defaultMessage='Members' + /> + ); + + let channelMembersModal; + if (this.state.showChannelMembersModal) { + channelMembersModal = ( + <ChannelMembersModal + onModalDismissed={() => this.setState({showChannelMembersModal: false})} + showInviteModal={() => this.setState({showChannelInviteModal: true})} + channel={this.props.channel} + /> + ); + } + + let teamMembersModal; + if (this.state.showTeamMembersModal) { + teamMembersModal = ( + <TeamMembersModal + onHide={() => this.setState({showTeamMembersModal: false})} + isAdmin={isTeamAdmin || isSystemAdmin} + /> + ); + } + + let channelInviteModal; + if (this.state.showChannelInviteModal) { + channelInviteModal = ( + <ChannelInviteModal + onHide={() => this.setState({showChannelInviteModal: false})} + channel={this.props.channel} + /> + ); + } + + return ( + <div className='member-popover__container'> + <div + id='member_popover' + className='member-popover__trigger' + ref='member_popover_target' + onClick={(e) => { + this.setState({popoverTarget: e.target, showPopover: !this.state.showPopover}); + this.props.actions.getProfilesInChannel(this.props.channel.id, 0); + }} + > + {countText} + <span + className='fa fa-user' + aria-hidden='true' + /> + </div> + <Overlay + rootClose={true} + onHide={this.closePopover} + show={this.state.showPopover} + target={() => this.state.popoverTarget} + placement='bottom' + > + <Popover + ref='memebersPopover' + title={title} + className='member-list__popover' + id='member-list-popover' + > + <div className='more-modal__list'>{popoverHtml}</div> + </Popover> + </Overlay> + {channelMembersModal} + {teamMembersModal} + {channelInviteModal} + </div> + ); + } +} + |