diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2017-03-30 12:46:47 -0400 |
---|---|---|
committer | Corey Hulen <corey@hulen.com> | 2017-03-30 09:46:47 -0700 |
commit | 689cac535e45c47a4f603b236dc129dd456efcc9 (patch) | |
tree | 767ef80b310d6d073840bd5216da38c439f6e193 /webapp/stores | |
parent | 9a9729f22fea7275637eafb4046900c9f372ec56 (diff) | |
download | chat-689cac535e45c47a4f603b236dc129dd456efcc9.tar.gz chat-689cac535e45c47a4f603b236dc129dd456efcc9.tar.bz2 chat-689cac535e45c47a4f603b236dc129dd456efcc9.zip |
PLT-2713/PLT-6028 Added System Users list to System Console (#5882)
* PLT-2713 Added ability for admins to list users not in any team
* Updated style of unit test
* Split SearchableUserList to give better control over its properties
* Added users without any teams to the user store
* Added ManageUsers page
* Renamed ManageUsers to SystemUsers
* Added ability to search by user id in SystemUsers page
* Added SystemUsersDropdown
* Removed unnecessary injectIntl
* Created TeamUtils
* Reduced scope of system console heading CSS
* Added team filter to TeamAnalytics page
* Updated admin console sidebar
* Removed unnecessary TODO
* Removed unused reference to deleted modal
* Fixed system console sidebar not scrolling on first load
* Fixed TeamAnalytics page not rendering on first load
* Fixed chart.js throwing an error when switching between teams
* Changed TeamAnalytics header to show the team's display name
* Fixed appearance of TeamAnalytics and SystemUsers on small screen widths
* Fixed placement of 'No users found' message
* Fixed teams not appearing in SystemUsers on first load
* Updated user count text for SystemUsers
* Changed search by id fallback to trigger less often
* Fixed SystemUsers list items not updating when searching
* Fixed localization strings for SystemUsers page
Diffstat (limited to 'webapp/stores')
-rw-r--r-- | webapp/stores/admin_store.jsx | 14 | ||||
-rw-r--r-- | webapp/stores/user_store.jsx | 130 |
2 files changed, 81 insertions, 63 deletions
diff --git a/webapp/stores/admin_store.jsx b/webapp/stores/admin_store.jsx index 4a68ec14c..59c763575 100644 --- a/webapp/stores/admin_store.jsx +++ b/webapp/stores/admin_store.jsx @@ -4,8 +4,6 @@ import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import EventEmitter from 'events'; -import BrowserStore from 'stores/browser_store.jsx'; - import Constants from 'utils/constants.jsx'; const ActionTypes = Constants.ActionTypes; @@ -138,18 +136,6 @@ class AdminStoreClass extends EventEmitter { getTeam(id) { return this.teams[id]; } - - getSelectedTeams() { - const result = BrowserStore.getItem('selected_teams'); - if (!result) { - return {}; - } - return result; - } - - saveSelectedTeams(teams) { - BrowserStore.setItem('selected_teams', teams); - } } var AdminStore = new AdminStoreClass(); diff --git a/webapp/stores/user_store.jsx b/webapp/stores/user_store.jsx index 007d8a5a7..6f4acae0a 100644 --- a/webapp/stores/user_store.jsx +++ b/webapp/stores/user_store.jsx @@ -16,6 +16,7 @@ const UserStatuses = Constants.UserStatuses; const CHANGE_EVENT_NOT_IN_CHANNEL = 'change_not_in_channel'; const CHANGE_EVENT_IN_CHANNEL = 'change_in_channel'; const CHANGE_EVENT_IN_TEAM = 'change_in_team'; +const CHANGE_EVENT_WITHOUT_TEAM = 'change_without_team'; const CHANGE_EVENT = 'change'; const CHANGE_EVENT_SESSIONS = 'change_sessions'; const CHANGE_EVENT_AUDITS = 'change_audits'; @@ -50,6 +51,9 @@ class UserStoreClass extends EventEmitter { this.not_in_channel_offset = {}; this.not_in_channel_count = {}; + // Lists of sorted IDs for users without a team + this.profiles_without_team = {}; + this.statuses = {}; this.sessions = {}; this.audits = []; @@ -105,6 +109,18 @@ class UserStoreClass extends EventEmitter { this.removeListener(CHANGE_EVENT_NOT_IN_CHANNEL, callback); } + emitWithoutTeamChange() { + this.emit(CHANGE_EVENT_WITHOUT_TEAM); + } + + addWithoutTeamChangeListener(callback) { + this.on(CHANGE_EVENT_WITHOUT_TEAM, callback); + } + + removeWithoutTeamChangeListener(callback) { + this.removeListener(CHANGE_EVENT_WITHOUT_TEAM, callback); + } + emitSessionsChange() { this.emit(CHANGE_EVENT_SESSIONS); } @@ -189,8 +205,33 @@ class UserStoreClass extends EventEmitter { return null; } + getProfileListForIds(userIds, skipCurrent = false, skipInactive = false) { + const profiles = []; + const currentId = this.getCurrentId(); + + for (let i = 0; i < userIds.length; i++) { + const profile = this.getProfile(userIds[i]); + + if (!profile) { + continue; + } + + if (skipCurrent && profile.id === currentId) { + continue; + } + + if (skipInactive && profile.delete_at > 0) { + continue; + } + + profiles.push(profile); + } + + return profiles; + } + hasProfile(userId) { - return this.getProfile(userId) != null; + return this.getProfiles().hasOwnProperty(userId); } getProfileByUsername(username) { @@ -248,7 +289,7 @@ class UserStoreClass extends EventEmitter { return profiles; } - getProfileList(skipCurrent) { + getProfileList(skipCurrent = false, allowInactive = false) { const profiles = []; const currentId = this.getCurrentId(); @@ -260,7 +301,7 @@ class UserStoreClass extends EventEmitter { continue; } - if (profile.delete_at === 0) { + if (allowInactive || profile.delete_at === 0) { profiles.push(profile); } } @@ -314,28 +355,8 @@ class UserStoreClass extends EventEmitter { getProfileListInTeam(teamId = TeamStore.getCurrentId(), skipCurrent = false, skipInactive = false) { const userIds = this.profiles_in_team[teamId] || []; - const profiles = []; - const currentId = this.getCurrentId(); - - for (let i = 0; i < userIds.length; i++) { - const profile = this.getProfile(userIds[i]); - - if (!profile) { - continue; - } - - if (skipCurrent && profile.id === currentId) { - continue; - } - - if (skipInactive && profile.delete_at > 0) { - continue; - } - - profiles.push(profile); - } - return profiles; + return this.getProfileListForIds(userIds, skipCurrent, skipInactive); } removeProfileFromTeam(teamId, userId) { @@ -416,21 +437,8 @@ class UserStoreClass extends EventEmitter { getProfileListInChannel(channelId = ChannelStore.getCurrentId(), skipCurrent = false) { const userIds = this.profiles_in_channel[channelId] || []; - const currentId = this.getCurrentId(); - const profiles = []; - - for (let i = 0; i < userIds.length; i++) { - const profile = this.getProfile(userIds[i]); - if (profile) { - if (skipCurrent && profile.id === currentId) { - continue; - } - - profiles.push(profile); - } - } - return profiles; + return this.getProfileListForIds(userIds, skipCurrent, false); } saveProfilesNotInChannel(channelId = ChannelStore.getCurrentId(), profiles) { @@ -482,23 +490,43 @@ class UserStoreClass extends EventEmitter { getProfileListNotInChannel(channelId = ChannelStore.getCurrentId(), skipInactive = false) { const userIds = this.profiles_not_in_channel[channelId] || []; - const profiles = []; - for (let i = 0; i < userIds.length; i++) { - const profile = this.getProfile(userIds[i]); + return this.getProfileListForIds(userIds, false, skipInactive); + } - if (!profile) { - continue; - } + // Profiles without any teams - if (skipInactive && profile.delete_at > 0) { - continue; + saveProfilesWithoutTeam(profiles) { + const oldProfileList = this.profiles_without_team; + const oldProfileMap = {}; + for (let i = 0; i < oldProfileList.length; i++) { + oldProfileMap[oldProfileList[i]] = this.getProfile(oldProfileList[i]); + } + + const newProfileMap = Object.assign({}, oldProfileMap, profiles); + const newProfileList = Object.keys(newProfileMap); + + newProfileList.sort((a, b) => { + const aProfile = newProfileMap[a]; + const bProfile = newProfileMap[b]; + + if (aProfile.username < bProfile.username) { + return -1; } + if (aProfile.username > bProfile.username) { + return 1; + } + return 0; + }); - profiles.push(profile); - } + this.profiles_without_team = newProfileList; + this.saveProfiles(profiles); + } - return profiles; + getProfileListWithoutTeam(skipCurrent = false, skipInactive = false) { + const userIds = this.profiles_without_team || []; + + return this.getProfileListForIds(userIds, skipCurrent, skipInactive); } // Other @@ -680,6 +708,10 @@ UserStore.dispatchToken = AppDispatcher.register((payload) => { } UserStore.emitNotInChannelChange(); break; + case ActionTypes.RECEIVED_PROFILES_WITHOUT_TEAM: + UserStore.saveProfilesWithoutTeam(action.profiles); + UserStore.emitWithoutTeamChange(); + break; case ActionTypes.RECEIVED_PROFILE: UserStore.saveProfile(action.profile); UserStore.emitChange(); |