diff --git a/api/cli_test.go b/api/cli_test.go index 6597819b36..12f38b54a1 100644 --- a/api/cli_test.go +++ b/api/cli_test.go @@ -68,7 +68,7 @@ func TestCliCreateUserWithTeam(t *testing.T) { t.Fatal(err) } - profiles := th.SystemAdminClient.Must(th.SystemAdminClient.GetProfilesForTeam(th.SystemAdminTeam.Id, "")).Data.(map[string]*model.User) + profiles := th.SystemAdminClient.Must(th.SystemAdminClient.GetProfiles(th.SystemAdminTeam.Id, "")).Data.(map[string]*model.User) found := false @@ -149,7 +149,7 @@ func TestCliJoinTeam(t *testing.T) { t.Fatal(err) } - profiles := th.SystemAdminClient.Must(th.SystemAdminClient.GetProfilesForTeam(th.SystemAdminTeam.Id, "")).Data.(map[string]*model.User) + profiles := th.SystemAdminClient.Must(th.SystemAdminClient.GetProfiles(th.SystemAdminTeam.Id, "")).Data.(map[string]*model.User) found := false diff --git a/api/user.go b/api/user.go index aee4dab612..f7d3eb1d3e 100644 --- a/api/user.go +++ b/api/user.go @@ -55,6 +55,7 @@ func InitUser() { BaseRoutes.Users.Handle("/status", ApiUserRequiredActivity(getStatuses, false)).Methods("POST") BaseRoutes.Users.Handle("/direct_profiles", ApiUserRequired(getDirectProfiles)).Methods("GET") BaseRoutes.Users.Handle("/profiles/{id:[A-Za-z0-9]+}", ApiUserRequired(getProfiles)).Methods("GET") + BaseRoutes.Users.Handle("/profiles_for_dm_list/{id:[A-Za-z0-9]+}", ApiUserRequired(getProfilesForDirectMessageList)).Methods("GET") BaseRoutes.Users.Handle("/mfa", ApiAppHandler(checkMfa)).Methods("POST") BaseRoutes.Users.Handle("/generate_mfa_qr", ApiUserRequiredTrustRequester(generateMfaQrCode)).Methods("GET") @@ -902,6 +903,49 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) { } } +func getProfilesForDirectMessageList(c *Context, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + id := params["id"] + + var pchan store.StoreChannel + + if *utils.Cfg.TeamSettings.RestrictDirectMessage == model.DIRECT_MESSAGE_TEAM { + if c.Session.GetTeamByTeamId(id) == nil { + if !c.HasSystemAdminPermissions("getProfiles") { + return + } + } + + pchan = Srv.Store.User().GetProfiles(id) + } else { + pchan = Srv.Store.User().GetAllProfiles() + } + + if result := <-pchan; result.Err != nil { + c.Err = result.Err + return + } else { + profiles := result.Data.(map[string]*model.User) + + for k, p := range profiles { + options := utils.Cfg.GetSanitizeOptions() + options["passwordupdate"] = false + + if c.IsSystemAdmin() { + options["fullname"] = true + options["email"] = true + } else { + p.ClearNonProfileFields() + } + + p.Sanitize(options) + profiles[k] = p + } + + w.Write([]byte(model.UserMapToJson(profiles))) + } +} + func getProfiles(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) id := params["id"] @@ -940,7 +984,6 @@ func getProfiles(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set(model.HEADER_ETAG_SERVER, etag) w.Write([]byte(model.UserMapToJson(profiles))) - return } } @@ -973,7 +1016,6 @@ func getDirectProfiles(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set(model.HEADER_ETAG_SERVER, etag) w.Write([]byte(model.UserMapToJson(profiles))) - return } } diff --git a/api/user_test.go b/api/user_test.go index ee13f43f22..629f7d2572 100644 --- a/api/user_test.go +++ b/api/user_test.go @@ -395,6 +395,22 @@ func TestGetDirectProfiles(t *testing.T) { } } +func TestGetProfilesForDirectMessageList(t *testing.T) { + th := Setup().InitBasic() + + th.BasicClient.Must(th.BasicClient.CreateDirectChannel(th.BasicUser2.Id)) + + if result, err := th.BasicClient.GetProfilesForDirectMessageList(th.BasicTeam.Id); err != nil { + t.Fatal(err) + } else { + users := result.Data.(map[string]*model.User) + + if len(users) < 1 { + t.Fatal("map was wrong length") + } + } +} + func TestGetAudits(t *testing.T) { th := Setup() Client := th.CreateClient() diff --git a/config/config.json b/config/config.json index 3fe938fe2d..b4fc84e0cb 100644 --- a/config/config.json +++ b/config/config.json @@ -34,7 +34,8 @@ "RestrictCreationToDomains": "", "RestrictTeamNames": true, "EnableCustomBrand": false, - "CustomBrandText": "" + "CustomBrandText": "", + "RestrictDirectMessage": "any" }, "SqlSettings": { "DriverName": "mysql", @@ -155,4 +156,4 @@ "Directory": "./data/", "EnableDaily": false } -} \ No newline at end of file +} diff --git a/i18n/en.json b/i18n/en.json index 9a44ca31aa..487f386a5a 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2303,6 +2303,10 @@ "id": "model.config.is_valid.ldap_security.app_error", "translation": "Invalid connection security for LDAP settings. Must be '', 'TLS', or 'STARTTLS'" }, + { + "id": "model.config.is_valid.restrict_direct_message.app_error", + "translation": "Invalid direct message restriction. Must be 'any', or 'team'" + }, { "id": "model.config.is_valid.listen_address.app_error", "translation": "Invalid listen address for service settings Must be set." diff --git a/model/client.go b/model/client.go index 9285368c4a..804b0d2186 100644 --- a/model/client.go +++ b/model/client.go @@ -321,8 +321,8 @@ func (c *Client) GetMe(etag string) (*Result, *AppError) { } } -func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/users/profiles/"+teamId, "", etag); err != nil { +func (c *Client) GetProfilesForDirectMessageList(teamId string) (*Result, *AppError) { + if r, err := c.DoApiGet("/users/profiles_for_dm_list/"+teamId, "", ""); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -330,8 +330,8 @@ func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) { } } -func (c *Client) GetProfilesForTeam(teamId string, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/users/profiles/"+teamId+"?skip_direct=true", "", etag); err != nil { +func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) { + if r, err := c.DoApiGet("/users/profiles/"+teamId, "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), diff --git a/model/config.go b/model/config.go index b7c9392025..872a5a68f3 100644 --- a/model/config.go +++ b/model/config.go @@ -29,6 +29,9 @@ const ( GENERIC_NOTIFICATION = "generic" FULL_NOTIFICATION = "full" + DIRECT_MESSAGE_ANY = "any" + DIRECT_MESSAGE_TEAM = "team" + FAKE_SETTING = "********************************" ) @@ -162,6 +165,7 @@ type TeamSettings struct { RestrictTeamNames *bool EnableCustomBrand *bool CustomBrandText *string + RestrictDirectMessage *string } type LdapSettings struct { @@ -315,6 +319,11 @@ func (o *Config) SetDefaults() { *o.TeamSettings.EnableOpenServer = false } + if o.TeamSettings.RestrictDirectMessage == nil { + o.TeamSettings.RestrictDirectMessage = new(string) + *o.TeamSettings.RestrictDirectMessage = DIRECT_MESSAGE_ANY + } + if o.EmailSettings.EnableSignInWithEmail == nil { o.EmailSettings.EnableSignInWithEmail = new(bool) @@ -520,6 +529,10 @@ func (o *Config) IsValid() *AppError { return NewLocAppError("Config.IsValid", "model.config.is_valid.max_users.app_error", nil, "") } + if !(*o.TeamSettings.RestrictDirectMessage == DIRECT_MESSAGE_ANY || *o.TeamSettings.RestrictDirectMessage == DIRECT_MESSAGE_TEAM) { + return NewLocAppError("Config.IsValid", "model.config.is_valid.restrict_direct_message.app_error", nil, "") + } + if len(o.SqlSettings.AtRestEncryptKey) < 32 { return NewLocAppError("Config.IsValid", "model.config.is_valid.encrypt_sql.app_error", nil, "") } diff --git a/store/sql_user_store.go b/store/sql_user_store.go index 07e9745593..8d4f1a31bf 100644 --- a/store/sql_user_store.go +++ b/store/sql_user_store.go @@ -454,7 +454,14 @@ func (s SqlUserStore) GetEtagForDirectProfiles(userId string) StoreChannel { Channels.Type = 'D' AND Channels.Id = ChannelMembers.ChannelId AND ChannelMembers.UserId = :UserId)) - `, map[string]interface{}{"UserId": userId}) + OR Id IN (SELECT + Name + FROM + Preferences + WHERE + UserId = :UserId + AND Category = 'direct_channel_show') + `, map[string]interface{}{"UserId": userId}) if err != nil { result.Data = fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis()) } else { @@ -468,6 +475,57 @@ func (s SqlUserStore) GetEtagForDirectProfiles(userId string) StoreChannel { return storeChannel } +func (s SqlUserStore) GetEtagForAllProfiles() StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + updateAt, err := s.GetReplica().SelectInt("SELECT UpdateAt FROM Users ORDER BY UpdateAt DESC LIMIT 1") + if err != nil { + result.Data = fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis()) + } else { + result.Data = fmt.Sprintf("%v.%v", model.CurrentVersion, updateAt) + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (us SqlUserStore) GetAllProfiles() StoreChannel { + + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + var users []*model.User + + if _, err := us.GetReplica().Select(&users, "SELECT * FROM Users"); err != nil { + result.Err = model.NewLocAppError("SqlUserStore.GetProfiles", "store.sql_user.get_profiles.app_error", nil, err.Error()) + } else { + + userMap := make(map[string]*model.User) + + for _, u := range users { + u.Password = "" + u.AuthData = "" + userMap[u.Id] = u + } + + result.Data = userMap + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + func (s SqlUserStore) GetEtagForProfiles(teamId string) StoreChannel { storeChannel := make(StoreChannel) @@ -548,7 +606,15 @@ func (us SqlUserStore) GetDirectProfiles(userId string) StoreChannel { WHERE Channels.Type = 'D' AND Channels.Id = ChannelMembers.ChannelId - AND ChannelMembers.UserId = :UserId))`, map[string]interface{}{"UserId": userId}); err != nil { + AND ChannelMembers.UserId = :UserId)) + OR Id IN (SELECT + Name + FROM + Preferences + WHERE + UserId = :UserId + AND Category = 'direct_channel_show') + `, map[string]interface{}{"UserId": userId}); err != nil { result.Err = model.NewLocAppError("SqlUserStore.GetDirectProfiles", "store.sql_user.get_profiles.app_error", nil, err.Error()) } else { diff --git a/store/sql_user_store_test.go b/store/sql_user_store_test.go index fbe2285a96..b48da55f5d 100644 --- a/store/sql_user_store_test.go +++ b/store/sql_user_store_test.go @@ -263,6 +263,31 @@ func TestActiveUserCount(t *testing.T) { } } +func TestUserStoreGetAllProfiles(t *testing.T) { + Setup() + + teamId := model.NewId() + + u1 := &model.User{} + u1.Email = model.NewId() + Must(store.User().Save(u1)) + Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id})) + + u2 := &model.User{} + u2.Email = model.NewId() + Must(store.User().Save(u2)) + Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id})) + + if r1 := <-store.User().GetAllProfiles(); r1.Err != nil { + t.Fatal(r1.Err) + } else { + users := r1.Data.(map[string]*model.User) + if len(users) < 2 { + t.Fatal("invalid returned users") + } + } +} + func TestUserStoreGetProfiles(t *testing.T) { Setup() diff --git a/store/store.go b/store/store.go index 8097fd8e85..7801f78f99 100644 --- a/store/store.go +++ b/store/store.go @@ -131,6 +131,7 @@ type UserStore interface { UpdateMfaActive(userId string, active bool) StoreChannel Get(id string) StoreChannel GetAll() StoreChannel + GetAllProfiles() StoreChannel GetProfiles(teamId string) StoreChannel GetDirectProfiles(userId string) StoreChannel GetProfileByIds(userId []string) StoreChannel @@ -139,6 +140,7 @@ type UserStore interface { GetByUsername(username string) StoreChannel GetForLogin(loginId string, allowSignInWithUsername, allowSignInWithEmail, ldapEnabled bool) StoreChannel VerifyEmail(userId string) StoreChannel + GetEtagForAllProfiles() StoreChannel GetEtagForProfiles(teamId string) StoreChannel GetEtagForDirectProfiles(userId string) StoreChannel UpdateFailedPasswordAttempts(userId string, attempts int) StoreChannel diff --git a/utils/config.go b/utils/config.go index 14d6589a28..b0983892a1 100644 --- a/utils/config.go +++ b/utils/config.go @@ -209,6 +209,7 @@ func getClientConfig(c *model.Config) map[string]string { props["EnableUserCreation"] = strconv.FormatBool(c.TeamSettings.EnableUserCreation) props["EnableOpenServer"] = strconv.FormatBool(*c.TeamSettings.EnableOpenServer) props["RestrictTeamNames"] = strconv.FormatBool(*c.TeamSettings.RestrictTeamNames) + props["RestrictDirectMessage"] = *c.TeamSettings.RestrictDirectMessage props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider) props["SegmentDeveloperKey"] = c.ServiceSettings.SegmentDeveloperKey diff --git a/webapp/action_creators/global_actions.jsx b/webapp/action_creators/global_actions.jsx index 335c202192..ae7352e5d6 100644 --- a/webapp/action_creators/global_actions.jsx +++ b/webapp/action_creators/global_actions.jsx @@ -157,6 +157,11 @@ export function emitPostFocusEvent(postId) { ); } +export function emitProfilesForDmList() { + AsyncClient.getProfilesForDirectMessageList(); + AsyncClient.getTeamMembers(TeamStore.getCurrentId()); +} + export function emitCloseRightHandSide() { AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_SEARCH, @@ -335,6 +340,10 @@ export function emitClearSuggestions(suggestionId) { } export function emitPreferenceChangedEvent(preference) { + if (preference.category === Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW) { + AsyncClient.getDirectProfiles(); + } + AppDispatcher.handleServerAction({ type: Constants.ActionTypes.RECEIVED_PREFERENCE, preference diff --git a/webapp/client/client.jsx b/webapp/client/client.jsx index 69f573eff2..73cc6120fc 100644 --- a/webapp/client/client.jsx +++ b/webapp/client/client.jsx @@ -862,13 +862,22 @@ export default class Client { getProfilesForTeam = (teamId, success, error) => { request. - get(`${this.getUsersRoute()}/profiles/${teamId}?skip_direct=true`). + get(`${this.getUsersRoute()}/profiles/${teamId}`). set(this.defaultHeaders). type('application/json'). accept('application/json'). end(this.handleResponse.bind(this, 'getProfilesForTeam', success, error)); } + getProfilesForDirectMessageList = (success, error) => { + request. + get(`${this.getUsersRoute()}/profiles_for_dm_list/${this.getTeamId()}`). + set(this.defaultHeaders). + type('application/json'). + accept('application/json'). + end(this.handleResponse.bind(this, 'getProfilesForDirectMessageList', success, error)); + } + getStatuses = (ids, success, error) => { request. post(`${this.getUsersRoute()}/status`). diff --git a/webapp/components/admin_console/team_settings.jsx b/webapp/components/admin_console/team_settings.jsx index bbb7ec3c45..e7bfcd74a6 100644 --- a/webapp/components/admin_console/team_settings.jsx +++ b/webapp/components/admin_console/team_settings.jsx @@ -24,6 +24,14 @@ const holders = defineMessages({ saving: { id: 'admin.team.saving', defaultMessage: 'Saving Config...' + }, + restrictDirectMessageAny: { + id: 'admin.team.restrict_direct_message_any', + defaultMessage: 'Any user on the Mattermost server' + }, + restrictDirectMessageTeam: { + id: 'admin.team.restrict_direct_message_team', + defaultMessage: 'Any member of the team' } }); @@ -48,6 +56,7 @@ class TeamSettings extends React.Component { saveNeeded: false, brandImageExists: false, enableCustomBrand: this.props.config.TeamSettings.EnableCustomBrand, + restrictDirectMessage: this.props.config.TeamSettings.RestrictDirectMessage, serverError: null }; } @@ -104,6 +113,7 @@ class TeamSettings extends React.Component { config.TeamSettings.EnableUserCreation = this.refs.EnableUserCreation.checked; config.TeamSettings.EnableOpenServer = this.refs.EnableOpenServer.checked; config.TeamSettings.RestrictTeamNames = this.refs.RestrictTeamNames.checked; + config.TeamSettings.RestrictDirectMessage = this.refs.RestrictDirectMessage.value.trim(); if (this.refs.EnableCustomBrand) { config.TeamSettings.EnableCustomBrand = this.refs.EnableCustomBrand.checked; @@ -660,6 +670,36 @@ class TeamSettings extends React.Component { +
+ +
+ +

+ +

+
+
+ {brand}
diff --git a/webapp/components/create_team/components/team_url.jsx b/webapp/components/create_team/components/team_url.jsx index 1a20066b56..34e6969387 100644 --- a/webapp/components/create_team/components/team_url.jsx +++ b/webapp/components/create_team/components/team_url.jsx @@ -5,6 +5,7 @@ import $ from 'jquery'; import ReactDOM from 'react-dom'; import * as Utils from 'utils/utils.jsx'; import Client from 'utils/web_client.jsx'; +import * as AsyncClient from 'utils/async_client.jsx'; import TeamStore from 'stores/team_store.jsx'; import UserStore from 'stores/user_store.jsx'; import Constants from 'utils/constants.jsx'; @@ -99,6 +100,7 @@ class TeamUrl extends React.Component { (team) => { Client.track('signup', 'signup_team_08_complete'); $('#sign-up-button').button('reset'); + AsyncClient.getDirectProfiles(); TeamStore.saveTeam(team); TeamStore.appendTeamMember({team_id: team.id, user_id: UserStore.getCurrentId(), roles: 'admin'}); TeamStore.emitChange(); diff --git a/webapp/components/filtered_user_list.jsx b/webapp/components/filtered_user_list.jsx index e12faa2987..83747c03d5 100644 --- a/webapp/components/filtered_user_list.jsx +++ b/webapp/components/filtered_user_list.jsx @@ -15,6 +15,14 @@ const holders = defineMessages({ search: { id: 'filtered_user_list.search', defaultMessage: 'Search members' + }, + anyTeam: { + id: 'filtered_user_list.any_team', + defaultMessage: 'All Users' + }, + teamOnly: { + id: 'filtered_user_list.team_only', + defaultMessage: 'Members of this Team' } }); @@ -25,9 +33,13 @@ class FilteredUserList extends React.Component { super(props); this.handleFilterChange = this.handleFilterChange.bind(this); + this.handleListChange = this.handleListChange.bind(this); + this.filterUsers = this.filterUsers.bind(this); this.state = { - filter: '' + filter: '', + users: this.filterUsers(props.teamMembers, props.users), + selected: 'team' }; } @@ -37,18 +49,49 @@ class FilteredUserList extends React.Component { } } + filterUsers(teamMembers, users) { + if (!teamMembers || teamMembers.length === 0) { + return users; + } + + var filteredUsers = users.filter((user) => { + for (const index in teamMembers) { + if (teamMembers.hasOwnProperty(index) && teamMembers[index].user_id === user.id) { + return true; + } + } + + return false; + }); + + return filteredUsers; + } + handleFilterChange(e) { this.setState({ filter: e.target.value }); } + handleListChange(e) { + var users = this.props.users; + + if (e.target.value === 'team') { + users = this.filterUsers(this.props.teamMembers, this.props.users); + } + + this.setState({ + selected: e.target.value, + users + }); + } + render() { const {formatMessage} = this.props.intl; - let users = this.props.users; + let users = this.state.users; - if (this.state.filter) { + if (this.state.filter && this.state.filter.length > 0) { const filter = this.state.filter.toLowerCase(); users = users.filter((user) => { @@ -60,7 +103,7 @@ class FilteredUserList extends React.Component { } let count; - if (users.length === this.props.users.length) { + if (users.length === this.state.users.length) { count = ( ); } + let teamToggle; + + let teamMembers = this.props.teamMembers; + if (this.props.showTeamToggle) { + teamMembers = []; + + teamToggle = ( +
+ + + + +
+ ); + } + return (
{count}
+ {teamToggle}
@@ -121,7 +195,8 @@ FilteredUserList.defaultProps = { users: [], teamMembers: [], actions: [], - actionProps: {} + actionProps: {}, + showTeamToggle: false }; FilteredUserList.propTypes = { @@ -130,6 +205,7 @@ FilteredUserList.propTypes = { teamMembers: React.PropTypes.arrayOf(React.PropTypes.object), actions: React.PropTypes.arrayOf(React.PropTypes.func), actionProps: React.PropTypes.object, + showTeamToggle: React.PropTypes.bool, style: React.PropTypes.object }; diff --git a/webapp/components/more_direct_channels.jsx b/webapp/components/more_direct_channels.jsx index a7fb2b6cd5..761ce0c37d 100644 --- a/webapp/components/more_direct_channels.jsx +++ b/webapp/components/more_direct_channels.jsx @@ -4,11 +4,14 @@ import {Modal} from 'react-bootstrap'; import FilteredUserList from './filtered_user_list.jsx'; import UserStore from 'stores/user_store.jsx'; +import TeamStore from 'stores/team_store.jsx'; import * as Utils from 'utils/utils.jsx'; +import * as GlobalActions from 'action_creators/global_actions.jsx'; import {FormattedMessage} from 'react-intl'; import {browserHistory} from 'react-router'; import SpinnerButton from 'components/spinner_button.jsx'; +import LoadingScreen from 'components/loading_screen.jsx'; import React from 'react'; @@ -17,38 +20,27 @@ export default class MoreDirectChannels extends React.Component { super(props); this.handleHide = this.handleHide.bind(this); + this.handleOnEnter = this.handleOnEnter.bind(this); this.handleShowDirectChannel = this.handleShowDirectChannel.bind(this); this.handleUserChange = this.handleUserChange.bind(this); + this.onTeamChange = this.onTeamChange.bind(this); this.createJoinDirectChannelButton = this.createJoinDirectChannelButton.bind(this); this.state = { - users: this.getUsersFromStore(), + users: null, + teamMembers: null, loadingDMChannel: -1 }; } - getUsersFromStore() { - const currentId = UserStore.getCurrentId(); - const profiles = UserStore.getActiveOnlyProfiles(); - const users = []; - - for (const id in profiles) { - if (id !== currentId) { - users.push(profiles[id]); - } - } - - users.sort((a, b) => a.username.localeCompare(b.username)); - - return users; - } - componentDidMount() { - UserStore.addChangeListener(this.handleUserChange); + UserStore.addDmListChangeListener(this.handleUserChange); + TeamStore.addChangeListener(this.onTeamChange); } componentWillUnmount() { - UserStore.removeChangeListener(this.handleUserChange); + UserStore.removeDmListChangeListener(this.handleUserChange); + TeamStore.removeChangeListener(this.onTeamChange); } shouldComponentUpdate(nextProps, nextState) { @@ -77,6 +69,17 @@ export default class MoreDirectChannels extends React.Component { } } + handleOnEnter() { + this.setState({ + users: null, + teamMembers: null + }); + } + + handleOnEntered() { + GlobalActions.emitProfilesForDmList(); + } + handleShowDirectChannel(teammate, e) { e.preventDefault(); @@ -99,7 +102,15 @@ export default class MoreDirectChannels extends React.Component { } handleUserChange() { - this.setState({users: this.getUsersFromStore()}); + this.setState({ + users: UserStore.getProfilesForDmList() + }); + } + + onTeamChange() { + this.setState({ + teamMembers: TeamStore.getMembersForTeam() + }); } createJoinDirectChannelButton({user}) { @@ -123,11 +134,33 @@ export default class MoreDirectChannels extends React.Component { maxHeight = Utils.windowHeight() - 300; } + var body = null; + if (this.state.users == null || this.state.teamMembers == null) { + body = (); + } else { + var showTeamToggle = false; + if (global.window.mm_config.RestrictDirectMessage === 'any') { + showTeamToggle = true; + } + + body = ( + + ); + } + return ( @@ -138,11 +171,7 @@ export default class MoreDirectChannels extends React.Component { - + {body}