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
Этот коммит содержится в:
Harrison Healey
2017-03-30 12:46:47 -04:00
коммит произвёл Corey Hulen
родитель 9a9729f22f
Коммит 689cac535e
74 изменённых файлов: 1445 добавлений и 1298 удалений

Просмотреть файл

@@ -314,7 +314,7 @@ export function getChannelMember(channelId, userId) {
});
}
export function getUser(userId) {
export function getUser(userId, success, error) {
const callName = `getUser${userId}`;
if (isCallInProgress(callName)) {
@@ -331,10 +331,18 @@ export function getUser(userId) {
type: ActionTypes.RECEIVED_PROFILE,
profile: data
});
if (success) {
success(data);
}
},
(err) => {
callTracker[callName] = 0;
dispatchError(err, 'getUser');
if (error) {
error(err);
} else {
callTracker[callName] = 0;
dispatchError(err, 'getUser');
}
}
);
}

Просмотреть файл

@@ -98,6 +98,7 @@ export const ActionTypes = keyMirror({
RECEIVED_PROFILE: null,
RECEIVED_PROFILES_IN_CHANNEL: null,
RECEIVED_PROFILES_NOT_IN_CHANNEL: null,
RECEIVED_PROFILES_WITHOUT_TEAM: null,
RECEIVED_ME: null,
RECEIVED_SESSIONS: null,
RECEIVED_AUDITS: null,
@@ -205,7 +206,8 @@ export const UserStatuses = {
};
export const UserSearchOptions = {
ALLOW_INACTIVE: 'allow_inactive'
ALLOW_INACTIVE: 'allow_inactive',
WITHOUT_TEAM: 'without_team'
};
export const SocketEvents = {
@@ -253,6 +255,29 @@ export const PostTypes = {
EPHEMERAL: 'system_ephemeral'
};
export const StatTypes = keyMirror({
TOTAL_USERS: null,
TOTAL_PUBLIC_CHANNELS: null,
TOTAL_PRIVATE_GROUPS: null,
TOTAL_POSTS: null,
TOTAL_TEAMS: null,
TOTAL_FILE_POSTS: null,
TOTAL_HASHTAG_POSTS: null,
TOTAL_IHOOKS: null,
TOTAL_OHOOKS: null,
TOTAL_COMMANDS: null,
TOTAL_SESSIONS: null,
POST_PER_DAY: null,
USERS_WITH_POSTS_PER_DAY: null,
RECENTLY_ACTIVE_USERS: null,
NEWLY_CREATED_USERS: null,
TOTAL_WEBSOCKET_CONNECTIONS: null,
TOTAL_MASTER_DB_CONNECTIONS: null,
TOTAL_READ_DB_CONNECTIONS: null,
DAILY_ACTIVE_USERS: null,
MONTHLY_ACTIVE_USERS: null
});
export const Constants = {
Preferences,
SocketEvents,
@@ -269,28 +294,7 @@ export const Constants = {
VIEW_ACTION: null
}),
StatTypes: keyMirror({
TOTAL_USERS: null,
TOTAL_PUBLIC_CHANNELS: null,
TOTAL_PRIVATE_GROUPS: null,
TOTAL_POSTS: null,
TOTAL_TEAMS: null,
TOTAL_FILE_POSTS: null,
TOTAL_HASHTAG_POSTS: null,
TOTAL_IHOOKS: null,
TOTAL_OHOOKS: null,
TOTAL_COMMANDS: null,
TOTAL_SESSIONS: null,
POST_PER_DAY: null,
USERS_WITH_POSTS_PER_DAY: null,
RECENTLY_ACTIVE_USERS: null,
NEWLY_CREATED_USERS: null,
TOTAL_WEBSOCKET_CONNECTIONS: null,
TOTAL_MASTER_DB_CONNECTIONS: null,
TOTAL_READ_DB_CONNECTIONS: null,
DAILY_ACTIVE_USERS: null,
MONTHLY_ACTIVE_USERS: null
}),
StatTypes,
STAT_MAX_ACTIVE_USERS: 20,
STAT_MAX_NEW_USERS: 20,

27
webapp/utils/team_utils.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,27 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import LocalizationStore from 'stores/localization_store.jsx';
export function convertTeamMapToList(teamMap) {
const teams = [];
for (const id in teamMap) {
if (teamMap.hasOwnProperty(id)) {
teams.push(teamMap[id]);
}
}
return teams.sort(sortTeamsByDisplayName);
}
// Use when sorting multiple teams by their `display_name` field
export function sortTeamsByDisplayName(a, b) {
const locale = LocalizationStore.getLocale();
if (a.display_name !== b.display_name) {
return a.display_name.localeCompare(b.display_name, locale, {numeric: true});
}
return a.name.localeCompare(b.name, locale, {numeric: true});
}

Просмотреть файл

@@ -1117,17 +1117,6 @@ export function windowHeight() {
return $(window).height();
}
// Use when sorting multiple teams by their `display_name` field
export function sortTeamsByDisplayName(a, b) {
const locale = LocalizationStore.getLocale();
if (a.display_name !== b.display_name) {
return a.display_name.localeCompare(b.display_name, locale, {numeric: true});
}
return a.name.localeCompare(b.name, locale, {numeric: true});
}
export function getChannelTerm(channelType) {
let channelTerm = 'Channel';
if (channelType === Constants.PRIVATE_CHANNEL) {