mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Fix types of various fields in GlobalState (#26125)
* Fix types of entities.admin.analytics and entities.admin.teamAnalytics * Fix type of entities.channels.channelsInTeam * Fix types of entities.users.stats and entities.users.filteredStats * Fix types of various profilesInX fields in entities.users * Fix incorrect field name last_password_update_at used when updating password We never noticed this bug before because the settings modal reloads the current user after updating their password. * MM-56760 Fix users not being removed from state.entities.users properly
This commit is contained in:
parent
64b140900e
commit
54507bb115
@ -44,7 +44,7 @@ const initialState = {
|
||||
}),
|
||||
},
|
||||
channelsInTeam: {
|
||||
'team-id': ['current_channel_id'],
|
||||
'team-id': new Set(['asdf']),
|
||||
},
|
||||
messageCounts: {
|
||||
current_channel_id: {total: 10},
|
||||
|
@ -112,8 +112,8 @@ describe('actions/global_actions', () => {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['channel-in-team-1'],
|
||||
team2: ['channel-in-team-2'],
|
||||
team1: new Set(['channel-in-team-1']),
|
||||
team2: new Set(['channel-in-team-2']),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -185,8 +185,8 @@ describe('actions/global_actions', () => {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['channel-in-team-1'],
|
||||
team2: ['channel-in-team-2'],
|
||||
team1: new Set(['channel-in-team-1']),
|
||||
team2: new Set(['channel-in-team-2']),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -257,8 +257,8 @@ describe('actions/global_actions', () => {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['channel-in-team-1'],
|
||||
team2: ['channel-in-team-2'],
|
||||
team1: new Set(['channel-in-team-1']),
|
||||
team2: new Set(['channel-in-team-2']),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -382,8 +382,8 @@ describe('actions/global_actions', () => {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['channel-in-team-1', directChannelId],
|
||||
team2: ['channel-in-team-2'],
|
||||
team1: new Set(['channel-in-team-1', directChannelId]),
|
||||
team2: new Set(['channel-in-team-2']),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -479,8 +479,8 @@ describe('actions/global_actions', () => {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['channel-in-team-1', directChannelId, groupChannelId],
|
||||
team2: ['channel-in-team-2'],
|
||||
team1: new Set(['channel-in-team-1', directChannelId, groupChannelId]),
|
||||
team2: new Set(['channel-in-team-2']),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -554,8 +554,8 @@ describe('actions/global_actions', () => {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['channel-in-team-1'],
|
||||
team2: ['channel-in-team-2'],
|
||||
team1: new Set(['channel-in-team-1']),
|
||||
team2: new Set(['channel-in-team-2']),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
|
@ -12,8 +12,6 @@ import * as Actions from 'actions/status_actions';
|
||||
|
||||
import mockStore from 'tests/test_store';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
jest.mock('mattermost-redux/actions/users', () => ({
|
||||
getStatusesByIds: jest.fn(() => {
|
||||
return {type: ''};
|
||||
@ -38,7 +36,7 @@ describe('actions/status_actions', () => {
|
||||
currentChannelId: 'channel_id1',
|
||||
channels: {channel_id1: {id: 'channel_id1', name: 'channel1', team_id: 'team_id1'}, channel_id2: {id: 'channel_id2', name: 'channel2', team_id: 'team_id1'}},
|
||||
myMembers: {channel_id1: {channel_id: 'channel_id1', user_id: 'current_user_id'}},
|
||||
channelsInTeam: {team_id1: ['channel_id1']},
|
||||
channelsInTeam: {team_id1: new Set(['channel_id1'])},
|
||||
},
|
||||
general: {
|
||||
config: {
|
||||
@ -76,7 +74,7 @@ describe('actions/status_actions', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown as GlobalState;
|
||||
};
|
||||
|
||||
describe('loadStatusesForChannelAndSidebar', () => {
|
||||
test('load statuses with posts in channel and user in sidebar', () => {
|
||||
|
@ -90,7 +90,7 @@ describe('Actions.User', () => {
|
||||
} as Channel,
|
||||
},
|
||||
channelsInTeam: {
|
||||
team_1: ['current_channel_id'],
|
||||
team_1: new Set(['current_channel_id']),
|
||||
},
|
||||
messageCounts: {
|
||||
current_channel_id: {total: 10} as ChannelMessageCount,
|
||||
@ -539,7 +539,7 @@ describe('Actions.User', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
'': [gmChannel.id],
|
||||
'': new Set([gmChannel.id]),
|
||||
};
|
||||
|
||||
const myMembers = {
|
||||
|
@ -212,7 +212,7 @@ describe('multiSelectChannelTo', () => {
|
||||
}, {}),
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: channelIds.map((id) => `category1_${id}`).concat(channelIds.map((id) => `category2_${id}`)),
|
||||
team1: new Set(channelIds.map((id) => `category1_${id}`).concat(channelIds.map((id) => `category2_${id}`))),
|
||||
},
|
||||
},
|
||||
teams: {
|
||||
|
@ -132,7 +132,7 @@ let mockState = {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
team: ['channel1', 'channel2'],
|
||||
team: new Set(['channel1', 'channel2']),
|
||||
},
|
||||
membersInChannel: {
|
||||
otherChannel: {},
|
||||
|
@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
|
||||
import type {AnalyticsRow} from '@mattermost/types/admin';
|
||||
import type {AnalyticsState} from '@mattermost/types/admin';
|
||||
import type {CloudCustomer} from '@mattermost/types/cloud';
|
||||
import type {ClientLicense} from '@mattermost/types/config';
|
||||
|
||||
@ -46,7 +46,7 @@ type Props = {
|
||||
|
||||
prevTrialLicense: ClientLicense;
|
||||
|
||||
stats?: Record<string, number | AnalyticsRow[]>;
|
||||
stats?: AnalyticsState;
|
||||
actions: {
|
||||
getPrevTrialLicense: () => void;
|
||||
getCloudSubscription: () => void;
|
||||
|
@ -6,7 +6,7 @@ import {bindActionCreators} from 'redux';
|
||||
import type {Dispatch} from 'redux';
|
||||
|
||||
import type {ChannelStats} from '@mattermost/types/channels';
|
||||
import type {UserProfile, UsersStats} from '@mattermost/types/users';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {getChannelStats} from 'mattermost-redux/actions/channels';
|
||||
import {getFilteredUsersStats} from 'mattermost-redux/actions/users';
|
||||
@ -69,10 +69,10 @@ function makeMapStateToProps() {
|
||||
};
|
||||
totalCount = stats.member_count;
|
||||
} else {
|
||||
const filteredUserStats: UsersStats = selectFilteredUsersStats(state) || {
|
||||
const filteredUserStats = selectFilteredUsersStats(state) || {
|
||||
total_users_count: 0,
|
||||
};
|
||||
totalCount = filteredUserStats.total_users_count;
|
||||
totalCount = filteredUserStats.total_users_count ?? 0;
|
||||
}
|
||||
|
||||
let users = [];
|
||||
|
@ -5,7 +5,7 @@ import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import type {Dispatch} from 'redux';
|
||||
|
||||
import type {UserProfile, UsersStats} from '@mattermost/types/users';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {getTeamStats as loadTeamStats} from 'mattermost-redux/actions/teams';
|
||||
import {getFilteredUsersStats} from 'mattermost-redux/actions/users';
|
||||
@ -49,10 +49,10 @@ function mapStateToProps(state: GlobalState, props: Props) {
|
||||
const stats = getTeamStats(state)[teamId] || {active_member_count: 0};
|
||||
totalCount = stats.active_member_count;
|
||||
} else {
|
||||
const filteredUserStats: UsersStats = selectFilteredUsersStats(state) || {
|
||||
const filteredUserStats = selectFilteredUsersStats(state) || {
|
||||
total_users_count: 0,
|
||||
};
|
||||
totalCount = filteredUserStats.total_users_count;
|
||||
totalCount = filteredUserStats.total_users_count ?? 0;
|
||||
}
|
||||
|
||||
let users = [];
|
||||
|
@ -72,7 +72,7 @@ const usesLDAP = async (
|
||||
// // @see discussion here: https://github.com/mattermost/mattermost-webapp/pull/9822#discussion_r806879385
|
||||
// const fetchGuestAccounts = async (
|
||||
// config: Partial<AdminConfig>,
|
||||
// analytics: Record<string, number | AnalyticsRow[]> | undefined,
|
||||
// analytics: AnalyticsState | undefined,
|
||||
// ) => {
|
||||
// if (config.TeamSettings?.EnableOpenServer && config.GuestAccountsSettings?.Enable) {
|
||||
// let usersArray = await fetch(`${Client4.getBaseRoute()}/users/invalid_emails`).then((result) => result.json());
|
||||
|
@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage, defineMessages} from 'react-intl';
|
||||
|
||||
import type {AnalyticsRow, PluginAnalyticsRow, IndexedPluginAnalyticsRow} from '@mattermost/types/admin';
|
||||
import type {AnalyticsRow, PluginAnalyticsRow, IndexedPluginAnalyticsRow, AnalyticsState} from '@mattermost/types/admin';
|
||||
import type {ClientLicense} from '@mattermost/types/config';
|
||||
|
||||
import * as AdminActions from 'actions/admin_actions.jsx';
|
||||
@ -33,7 +33,7 @@ const StatTypes = Constants.StatTypes;
|
||||
|
||||
type Props = {
|
||||
isLicensed: boolean;
|
||||
stats?: Record<string, number | AnalyticsRow[]>;
|
||||
stats?: AnalyticsState;
|
||||
license: ClientLicense;
|
||||
pluginStatHandlers: GlobalState['plugins']['siteStatsHandlers'];
|
||||
}
|
||||
@ -119,7 +119,7 @@ export default class SystemAnalytics extends React.PureComponent<Props, State> {
|
||||
this.setState({pluginSiteStats: allStatsIndexed});
|
||||
}
|
||||
|
||||
private getStatValue(stat: number | AnalyticsRow[]): number | undefined {
|
||||
private getStatValue(stat: number | AnalyticsRow[] | undefined): number | undefined {
|
||||
if (typeof stat === 'number') {
|
||||
return stat;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import React from 'react';
|
||||
import type {MessageDescriptor} from 'react-intl';
|
||||
import {FormattedDate, FormattedMessage, defineMessages} from 'react-intl';
|
||||
|
||||
import type {AnalyticsRow} from '@mattermost/types/admin';
|
||||
import type {AnalyticsRow, AnalyticsState} from '@mattermost/types/admin';
|
||||
import type {ClientLicense} from '@mattermost/types/config';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
@ -52,7 +52,7 @@ type Props = {
|
||||
|
||||
license: ClientLicense;
|
||||
|
||||
stats: RelationOneToOne<Team, Record<string, number | AnalyticsRow[]>>;
|
||||
stats: RelationOneToOne<Team, AnalyticsState>;
|
||||
|
||||
actions: {
|
||||
|
||||
@ -129,7 +129,7 @@ export default class TeamAnalytics extends React.PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
private getStatValue(stat: number | AnalyticsRow[]): number | undefined {
|
||||
private getStatValue(stat: number | AnalyticsRow[] | undefined): number | undefined {
|
||||
if (typeof stat === 'number') {
|
||||
return stat;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ const initialState: DeepPartial<GlobalState> = {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
'team-id': ['current_channel_id'],
|
||||
'team-id': new Set(['current_channel_id']),
|
||||
},
|
||||
messageCounts: {
|
||||
current_channel_id: {total: 10},
|
||||
|
@ -46,7 +46,7 @@ const initialState: DeepPartial<GlobalState> = {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
'team-id': ['current_channel_id'],
|
||||
'team-id': new Set(['current_channel_id']),
|
||||
},
|
||||
messageCounts: {
|
||||
current_channel_id: {total: 10},
|
||||
|
@ -45,7 +45,7 @@ const initialState: DeepPartial<GlobalState> = {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
'team-id': ['current_channel_id'],
|
||||
'team-id': new Set(['current_channel_id']),
|
||||
},
|
||||
messageCounts: {
|
||||
current_channel_id: {total: 10},
|
||||
|
@ -59,7 +59,7 @@ describe('Actions', () => {
|
||||
currentChannelId: 'channel_id1',
|
||||
channels: {channel_id1: channel1, channel_id2: channel2, channel_id3: channel3, channel_id4: channel4, channel_id5: channel5, channel_id6: channel6},
|
||||
myMembers: {channel_id1: {channel_id: 'channel_id1', user_id: 'current_user_id'}, channel_id2: {channel_id: 'channel_id2', user_id: 'current_user_id'}},
|
||||
channelsInTeam: {team_id1: ['channel_id1'], team_id2: ['channel_id2']},
|
||||
channelsInTeam: {team_id1: new Set(['channel_id1']), team_id2: new Set(['channel_id2'])},
|
||||
},
|
||||
teams: {
|
||||
currentTeamId: 'team_id1',
|
||||
|
@ -78,7 +78,7 @@ const makeMapStateToProps = () => {
|
||||
currentChannelMembers,
|
||||
currentUserId,
|
||||
restrictDirectMessage,
|
||||
totalCount: stats.total_users_count,
|
||||
totalCount: stats.total_users_count ?? 0,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -216,7 +216,7 @@ describe('makeGetOptions', () => {
|
||||
[gmChannel3.id]: gmChannel3,
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': [gmChannel1.id, gmChannel2.id, gmChannel3.id],
|
||||
'': new Set([gmChannel1.id, gmChannel2.id, gmChannel3.id]),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -291,7 +291,7 @@ describe('makeGetOptions', () => {
|
||||
[gmChannel2.id]: gmChannel2,
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': [gmChannel1.id, gmChannel2.id],
|
||||
'': new Set([gmChannel1.id, gmChannel2.id]),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -378,7 +378,7 @@ describe('makeGetOptions', () => {
|
||||
[gmChannel3.id]: gmChannel3,
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': [gmChannel1.id, gmChannel2.id, gmChannel3.id],
|
||||
'': new Set([gmChannel1.id, gmChannel2.id, gmChannel3.id]),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -480,7 +480,7 @@ describe('makeGetOptions', () => {
|
||||
[gmChannel2.id]: gmChannel2,
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': [gmChannel1.id, gmChannel2.id],
|
||||
'': new Set([gmChannel1.id, gmChannel2.id]),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
@ -591,7 +591,7 @@ describe('makeGetOptions', () => {
|
||||
[dm1.id]: dm1,
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': [dm1.id],
|
||||
'': new Set([dm1.id]),
|
||||
},
|
||||
},
|
||||
users: {
|
||||
|
@ -35,7 +35,7 @@ describe('components/sidebar/invite_members_button', () => {
|
||||
},
|
||||
stats: {
|
||||
total_users_count: 10,
|
||||
} as any, // HARRISONTODO The defined type of entities.users.stats is incorrect
|
||||
},
|
||||
},
|
||||
roles: {
|
||||
roles: {
|
||||
|
@ -141,7 +141,7 @@ describe('components/sidebar', () => {
|
||||
channel2,
|
||||
},
|
||||
channelsInTeam: {
|
||||
[currentTeamId]: [channel1.id, channel2.id],
|
||||
[currentTeamId]: new Set([channel1.id, channel2.id]),
|
||||
},
|
||||
messageCounts: {
|
||||
channel1: {total: 10},
|
||||
|
@ -40,7 +40,7 @@ export const reduxTestState = {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
'team-id': ['current_channel_id'],
|
||||
'team-id': new Set(['current_channel_id']),
|
||||
},
|
||||
messageCounts: {
|
||||
current_channel_id: {total: 10},
|
||||
|
@ -91,14 +91,14 @@ describe('components/SearchChannelWithPermissionsProvider', () => {
|
||||
}),
|
||||
},
|
||||
channelsInTeam: {
|
||||
someTeamId: [
|
||||
someTeamId: new Set([
|
||||
'somePublicMemberChannelId',
|
||||
'somePrivateMemberChannelId',
|
||||
'somePublicNonMemberChannelId',
|
||||
'somePrivateNonMemberChannelId',
|
||||
'someDirectConversation',
|
||||
'someGroupConversation',
|
||||
],
|
||||
]),
|
||||
},
|
||||
},
|
||||
roles: {
|
||||
|
@ -726,7 +726,7 @@ describe('components/SwitchChannelProvider', () => {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': ['other_gm_channel'],
|
||||
'': new Set(['other_gm_channel']),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -793,7 +793,7 @@ describe('components/SwitchChannelProvider', () => {
|
||||
}),
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': ['other_gm_channel'],
|
||||
'': new Set(['other_gm_channel']),
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
@ -960,7 +960,7 @@ describe('components/SwitchChannelProvider', () => {
|
||||
},
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': ['thread_gm_channel'],
|
||||
'': new Set(['thread_gm_channel']),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -132,7 +132,7 @@ const notices: Notice[] = [
|
||||
return false;
|
||||
}
|
||||
|
||||
if (analytics.TOTAL_USERS < USERS_THRESHOLD) {
|
||||
if (analytics.TOTAL_USERS && analytics.TOTAL_USERS < USERS_THRESHOLD) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage, injectIntl, type WrappedComponentProps} from 'react-intl';
|
||||
|
||||
import type {AnalyticsRow} from '@mattermost/types/admin';
|
||||
import type {AnalyticsState} from '@mattermost/types/admin';
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {ClientConfig, ClientLicense} from '@mattermost/types/config';
|
||||
import type {PreferenceType} from '@mattermost/types/preferences';
|
||||
@ -23,7 +23,7 @@ export interface Props extends WrappedComponentProps {
|
||||
serverVersion: string;
|
||||
config: Partial<ClientConfig>;
|
||||
license: ClientLicense;
|
||||
analytics?: Record<string, number | AnalyticsRow[]>;
|
||||
analytics?: AnalyticsState;
|
||||
currentChannel?: Channel;
|
||||
actions: {
|
||||
savePreferences(userId: string, preferences: PreferenceType[]): void;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
import type React from 'react';
|
||||
|
||||
import type {AnalyticsRow} from '@mattermost/types/admin';
|
||||
import type {AnalyticsState} from '@mattermost/types/admin';
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
|
||||
export type Notice = {
|
||||
@ -17,7 +17,7 @@ export type Notice = {
|
||||
serverVersion: string,
|
||||
config: any,
|
||||
license: any,
|
||||
analytics?: Record<string, number | AnalyticsRow[]>,
|
||||
analytics?: AnalyticsState,
|
||||
currentChannel?: Channel,
|
||||
): boolean;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ describe('component/user_group_popover', () => {
|
||||
},
|
||||
users: {
|
||||
profiles,
|
||||
profilesInGroup: profilesInGroup as any, // HARRISONTODO The type entities.users.profilesInGroup is incorrectly an array when it should be a Set
|
||||
profilesInGroup,
|
||||
},
|
||||
preferences: {
|
||||
myPreferences: {},
|
||||
|
@ -619,12 +619,12 @@ describe('Actions.Admin', () => {
|
||||
|
||||
const analytics = state.entities.admin.analytics;
|
||||
expect(analytics).toBeTruthy();
|
||||
expect(analytics[Stats.TOTAL_PUBLIC_CHANNELS] > 0).toBeTruthy();
|
||||
expect(analytics[Stats.TOTAL_PUBLIC_CHANNELS]).toBeGreaterThan(0);
|
||||
|
||||
const teamAnalytics = state.entities.admin.teamAnalytics;
|
||||
expect(teamAnalytics).toBeTruthy();
|
||||
expect(teamAnalytics[TestHelper.basicTeam!.id]).toBeTruthy();
|
||||
expect(teamAnalytics[TestHelper.basicTeam!.id][Stats.TOTAL_PUBLIC_CHANNELS] > 0).toBeTruthy();
|
||||
expect(teamAnalytics[TestHelper.basicTeam!.id][Stats.TOTAL_PUBLIC_CHANNELS]).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('getAdvancedAnalytics', async () => {
|
||||
@ -641,12 +641,12 @@ describe('Actions.Admin', () => {
|
||||
|
||||
const analytics = state.entities.admin.analytics;
|
||||
expect(analytics).toBeTruthy();
|
||||
expect(analytics[Stats.TOTAL_SESSIONS] > 0).toBeTruthy();
|
||||
expect(analytics[Stats.TOTAL_SESSIONS]).toBeGreaterThan(0);
|
||||
|
||||
const teamAnalytics = state.entities.admin.teamAnalytics;
|
||||
expect(teamAnalytics).toBeTruthy();
|
||||
expect(teamAnalytics[TestHelper.basicTeam!.id]).toBeTruthy();
|
||||
expect(teamAnalytics[TestHelper.basicTeam!.id][Stats.TOTAL_SESSIONS] > 0).toBeTruthy();
|
||||
expect(teamAnalytics[TestHelper.basicTeam!.id][Stats.TOTAL_SESSIONS]).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('getPostsPerDayAnalytics', async () => {
|
||||
|
@ -91,7 +91,7 @@ describe('Actions.Threads', () => {
|
||||
},
|
||||
channels: {
|
||||
channelsInTeam: {
|
||||
[currentTeamId]: [channel.id],
|
||||
[currentTeamId]: new Set([channel.id]),
|
||||
},
|
||||
channels: {
|
||||
[channel.id]: channel,
|
||||
|
@ -1007,7 +1007,7 @@ describe('Actions.Users', () => {
|
||||
const currentUser = profiles[currentUserId];
|
||||
|
||||
expect(currentUser).toBeTruthy();
|
||||
expect(currentUser.last_password_update_at > beforeTime).toBeTruthy();
|
||||
expect(currentUser.last_password_update > beforeTime).toBeTruthy();
|
||||
});
|
||||
|
||||
it('generateMfaSecret', async () => {
|
||||
|
@ -962,7 +962,7 @@ export function updateUserPassword(userId: string, currentPassword: string, newP
|
||||
|
||||
const profile = getState().entities.users.profiles[userId];
|
||||
if (profile) {
|
||||
dispatch({type: UserTypes.RECEIVED_PROFILE, data: {...profile, last_password_update_at: new Date().getTime()}});
|
||||
dispatch({type: UserTypes.RECEIVED_PROFILE, data: {...profile, last_password_update: new Date().getTime()}});
|
||||
}
|
||||
|
||||
return {data: true};
|
||||
|
@ -4,7 +4,7 @@
|
||||
import type {AnyAction} from 'redux';
|
||||
import {combineReducers} from 'redux';
|
||||
|
||||
import type {ClusterInfo, AnalyticsRow} from '@mattermost/types/admin';
|
||||
import type {ClusterInfo, AnalyticsRow, AnalyticsState, AdminState} from '@mattermost/types/admin';
|
||||
import type {Audit} from '@mattermost/types/audits';
|
||||
import type {Compliance} from '@mattermost/types/compliance';
|
||||
import type {AdminConfig, EnvironmentConfig} from '@mattermost/types/config';
|
||||
@ -12,7 +12,6 @@ import type {DataRetentionCustomPolicy} from '@mattermost/types/data_retention';
|
||||
import type {MixedUnlinkedGroupRedux} from '@mattermost/types/groups';
|
||||
import type {PluginRedux, PluginStatusRedux} from '@mattermost/types/plugins';
|
||||
import type {SamlCertificateStatus, SamlMetadataResponse} from '@mattermost/types/saml';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserAccessToken, UserProfile} from '@mattermost/types/users';
|
||||
import type {RelationOneToOne, IDMappedObjects} from '@mattermost/types/utilities';
|
||||
|
||||
@ -161,8 +160,8 @@ function samlCertStatus(state: Partial<SamlCertificateStatus> = {}, action: AnyA
|
||||
}
|
||||
}
|
||||
|
||||
export function convertAnalyticsRowsToStats(data: AnalyticsRow[], name: string): Record<string, number | AnalyticsRow[]> {
|
||||
const stats: any = {};
|
||||
export function convertAnalyticsRowsToStats(data: AnalyticsRow[], name: string): AnalyticsState {
|
||||
const stats: AnalyticsState = {};
|
||||
const clonedData = [...data];
|
||||
|
||||
if (name === 'post_counts_day') {
|
||||
@ -250,7 +249,7 @@ export function convertAnalyticsRowsToStats(data: AnalyticsRow[], name: string):
|
||||
return stats;
|
||||
}
|
||||
|
||||
function analytics(state: Record<string, number | AnalyticsRow[]> = {}, action: AnyAction) {
|
||||
function analytics(state: AdminState['analytics'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case AdminTypes.RECEIVED_SYSTEM_ANALYTICS: {
|
||||
const stats = convertAnalyticsRowsToStats(action.data, action.name);
|
||||
@ -264,7 +263,7 @@ function analytics(state: Record<string, number | AnalyticsRow[]> = {}, action:
|
||||
}
|
||||
}
|
||||
|
||||
function teamAnalytics(state: RelationOneToOne<Team, Record<string, number | AnalyticsRow[]>> = {}, action: AnyAction) {
|
||||
function teamAnalytics(state: AdminState['teamAnalytics'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case AdminTypes.RECEIVED_TEAM_ANALYTICS: {
|
||||
const nextState = {...state};
|
||||
|
@ -12,11 +12,12 @@ import type {
|
||||
ChannelMemberCountByGroup,
|
||||
ChannelMemberCountsByGroup,
|
||||
ServerChannel,
|
||||
ChannelsState,
|
||||
} from '@mattermost/types/channels';
|
||||
import type {Group} from '@mattermost/types/groups';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {
|
||||
RelationOneToMany,
|
||||
RelationOneToManyUnique,
|
||||
RelationOneToOne,
|
||||
IDMappedObjects,
|
||||
} from '@mattermost/types/utilities';
|
||||
@ -37,7 +38,7 @@ function removeMemberFromChannels(state: RelationOneToOne<Channel, Record<string
|
||||
return nextState;
|
||||
}
|
||||
|
||||
function channelListToSet(state: any, action: AnyAction) {
|
||||
function channelListToSet(state: RelationOneToManyUnique<Team, Channel>, action: AnyAction) {
|
||||
const nextState = {...state};
|
||||
|
||||
action.data.forEach((channel: Channel) => {
|
||||
@ -49,7 +50,7 @@ function channelListToSet(state: any, action: AnyAction) {
|
||||
return nextState;
|
||||
}
|
||||
|
||||
function removeChannelFromSet(state: any, action: AnyAction) {
|
||||
function removeChannelFromSet(state: RelationOneToManyUnique<Team, Channel>, action: AnyAction): RelationOneToManyUnique<Team, Channel> {
|
||||
const id = action.data.team_id;
|
||||
const nextSet = new Set(state[id]);
|
||||
nextSet.delete(action.data.id);
|
||||
@ -220,7 +221,7 @@ function toClientChannel(serverChannel: ServerChannel): Channel {
|
||||
return channel;
|
||||
}
|
||||
|
||||
function channelsInTeam(state: RelationOneToMany<Team, Channel> = {}, action: AnyAction) {
|
||||
function channelsInTeam(state: ChannelsState['channelsInTeam'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case ChannelTypes.RECEIVED_CHANNEL: {
|
||||
const nextSet = new Set(state[action.data.team_id]);
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
import type {UserProfile, UsersState} from '@mattermost/types/users';
|
||||
import type {IDMappedObjects} from '@mattermost/types/utilities';
|
||||
|
||||
import {UserTypes, ChannelTypes} from 'mattermost-redux/action_types';
|
||||
@ -1006,4 +1006,90 @@ describe('Reducers.users', () => {
|
||||
expect(newProfiles.third_user_id).toEqual(thirdUser);
|
||||
});
|
||||
});
|
||||
|
||||
test('PROFILE_NO_LONGER_VISIBLE should remove references to users from state', () => {
|
||||
const user = TestHelper.getUserMock({id: 'user'});
|
||||
|
||||
let state: UsersState = {
|
||||
currentUserId: '',
|
||||
mySessions: [],
|
||||
myAudits: [],
|
||||
myUserAccessTokens: {},
|
||||
profiles: {
|
||||
user,
|
||||
},
|
||||
profilesInTeam: {
|
||||
team1: new Set([user.id]),
|
||||
},
|
||||
profilesNotInTeam: {
|
||||
team2: new Set([user.id]),
|
||||
},
|
||||
profilesWithoutTeam: new Set([user.id]),
|
||||
profilesInChannel: {
|
||||
channel1: new Set([user.id]),
|
||||
},
|
||||
profilesNotInChannel: {
|
||||
channel2: new Set([user.id]),
|
||||
},
|
||||
profilesInGroup: {
|
||||
group1: new Set([user.id]),
|
||||
},
|
||||
profilesNotInGroup: {
|
||||
group2: new Set([user.id]),
|
||||
},
|
||||
statuses: {
|
||||
[user.id]: 'online',
|
||||
},
|
||||
isManualStatus: {
|
||||
[user.id]: true,
|
||||
},
|
||||
stats: {},
|
||||
filteredStats: {
|
||||
total_users_count: 0,
|
||||
},
|
||||
lastActivity: {},
|
||||
};
|
||||
state = deepFreezeAndThrowOnMutation(state);
|
||||
|
||||
const nextState = reducer(state, {
|
||||
type: UserTypes.PROFILE_NO_LONGER_VISIBLE,
|
||||
data: {
|
||||
user_id: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(nextState).toEqual({
|
||||
currentUserId: '',
|
||||
mySessions: [],
|
||||
myAudits: [],
|
||||
myUserAccessTokens: {},
|
||||
profiles: {},
|
||||
profilesInTeam: {
|
||||
team1: new Set(),
|
||||
},
|
||||
profilesNotInTeam: {
|
||||
team2: new Set(),
|
||||
},
|
||||
profilesWithoutTeam: new Set(),
|
||||
profilesInChannel: {
|
||||
channel1: new Set(),
|
||||
},
|
||||
profilesNotInChannel: {
|
||||
channel2: new Set(),
|
||||
},
|
||||
profilesInGroup: {
|
||||
group1: new Set(),
|
||||
},
|
||||
profilesNotInGroup: {
|
||||
group2: new Set(),
|
||||
},
|
||||
statuses: {},
|
||||
isManualStatus: {},
|
||||
stats: {},
|
||||
filteredStats: {
|
||||
total_users_count: 0,
|
||||
},
|
||||
lastActivity: {},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -5,22 +5,20 @@ import isEqual from 'lodash/isEqual';
|
||||
import type {AnyAction} from 'redux';
|
||||
import {combineReducers} from 'redux';
|
||||
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {Group} from '@mattermost/types/groups';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserAccessToken, UserProfile, UserStatus} from '@mattermost/types/users';
|
||||
import type {RelationOneToMany, IDMappedObjects, RelationOneToOne} from '@mattermost/types/utilities';
|
||||
import type {UserAccessToken, UserProfile, UserStatus, UsersState} from '@mattermost/types/users';
|
||||
import type {IDMappedObjects, RelationOneToManyUnique, RelationOneToOne} from '@mattermost/types/utilities';
|
||||
|
||||
import {UserTypes, ChannelTypes} from 'mattermost-redux/action_types';
|
||||
|
||||
function profilesToSet(state: RelationOneToMany<Team, UserProfile>, action: AnyAction) {
|
||||
function profilesToSet(state: RelationOneToManyUnique<Team, UserProfile>, action: AnyAction) {
|
||||
const id = action.id;
|
||||
const users: UserProfile[] = Object.values(action.data);
|
||||
|
||||
return users.reduce((nextState, user) => addProfileToSet(nextState, id, user.id), state);
|
||||
}
|
||||
|
||||
function profileListToSet(state: RelationOneToMany<Team, UserProfile>, action: AnyAction, replace = false) {
|
||||
function profileListToSet(state: RelationOneToManyUnique<Team, UserProfile>, action: AnyAction, replace = false) {
|
||||
const id = action.id;
|
||||
const users: UserProfile[] = action.data || [];
|
||||
|
||||
@ -34,7 +32,7 @@ function profileListToSet(state: RelationOneToMany<Team, UserProfile>, action: A
|
||||
return users.reduce((nextState, user) => addProfileToSet(nextState, id, user.id), state);
|
||||
}
|
||||
|
||||
function removeProfileListFromSet(state: RelationOneToMany<Team, UserProfile>, action: AnyAction) {
|
||||
function removeProfileListFromSet(state: RelationOneToManyUnique<Team, UserProfile>, action: AnyAction) {
|
||||
const id = action.id;
|
||||
const nextSet = new Set(state[id]);
|
||||
if (action.data) {
|
||||
@ -51,50 +49,31 @@ function removeProfileListFromSet(state: RelationOneToMany<Team, UserProfile>, a
|
||||
return state;
|
||||
}
|
||||
|
||||
function addProfileToSet(state: RelationOneToMany<Team, UserProfile>, id: string, userId: string) {
|
||||
if (state[id]) {
|
||||
// The type definitions for this function expect state[id] to be an array, but we seem to use Sets, so handle
|
||||
// both of those just in case
|
||||
if (Array.isArray(state[id]) && state[id].includes(userId)) {
|
||||
return state;
|
||||
} else if (!Array.isArray(state[id]) && (state[id] as unknown as Set<string>).has(userId)) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function addProfileToSet(state: RelationOneToManyUnique<Team, UserProfile>, id: string, userId: string) {
|
||||
const nextSet = new Set(state[id]);
|
||||
nextSet.add(userId);
|
||||
return {
|
||||
...state,
|
||||
[id]: nextSet,
|
||||
} as RelationOneToMany<Team, UserProfile>;
|
||||
};
|
||||
}
|
||||
|
||||
function removeProfileFromTeams(state: RelationOneToMany<Team, UserProfile>, action: AnyAction) {
|
||||
function removeProfileFromSets(state: RelationOneToManyUnique<Team, UserProfile>, action: AnyAction) {
|
||||
const newState = {...state};
|
||||
let removed = false;
|
||||
Object.keys(state).forEach((key) => {
|
||||
if (newState[key][action.data.user_id]) {
|
||||
delete newState[key][action.data.user_id];
|
||||
if (newState[key].has(action.data.user_id)) {
|
||||
newState[key] = new Set(newState[key]);
|
||||
newState[key].delete(action.data.user_id);
|
||||
removed = true;
|
||||
}
|
||||
});
|
||||
return removed ? newState : state;
|
||||
}
|
||||
|
||||
function removeProfileFromSet(state: RelationOneToMany<Team, UserProfile>, action: AnyAction) {
|
||||
function removeProfileFromSet(state: RelationOneToManyUnique<Team, UserProfile>, action: AnyAction) {
|
||||
const {id, user_id: userId} = action.data;
|
||||
|
||||
if (state[id]) {
|
||||
// The type definitions for this function expect state[id] to be an array, but we seem to use Sets, so handle
|
||||
// both of those just in case
|
||||
if (Array.isArray(state[id]) && !state[id].includes(userId)) {
|
||||
return state;
|
||||
} else if (!Array.isArray(state[id]) && !(state[id] as unknown as Set<string>).has(userId)) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
const nextSet = new Set(state[id]);
|
||||
nextSet.delete(userId);
|
||||
return {
|
||||
@ -161,7 +140,7 @@ function mySessions(state: Array<{id: string}> = [], action: AnyAction) {
|
||||
}
|
||||
}
|
||||
|
||||
function myAudits(state = [], action: AnyAction) {
|
||||
function myAudits(state: UsersState['myAudits'] = [], action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_AUDITS:
|
||||
return [...action.data];
|
||||
@ -274,7 +253,7 @@ function profiles(state: IDMappedObjects<UserProfile> = {}, action: AnyAction) {
|
||||
}
|
||||
}
|
||||
|
||||
function profilesInTeam(state: RelationOneToMany<Team, UserProfile> = {}, action: AnyAction) {
|
||||
function profilesInTeam(state: UsersState['profilesInTeam'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_PROFILE_IN_TEAM:
|
||||
return addProfileToSet(state, action.data.id, action.data.user_id);
|
||||
@ -295,14 +274,14 @@ function profilesInTeam(state: RelationOneToMany<Team, UserProfile> = {}, action
|
||||
return {};
|
||||
|
||||
case UserTypes.PROFILE_NO_LONGER_VISIBLE:
|
||||
return removeProfileFromTeams(state, action);
|
||||
return removeProfileFromSets(state, action);
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function profilesNotInTeam(state: RelationOneToMany<Team, UserProfile> = {}, action: AnyAction) {
|
||||
function profilesNotInTeam(state: UsersState['profilesNotInTeam'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_PROFILE_NOT_IN_TEAM:
|
||||
return addProfileToSet(state, action.data.id, action.data.user_id);
|
||||
@ -323,14 +302,14 @@ function profilesNotInTeam(state: RelationOneToMany<Team, UserProfile> = {}, act
|
||||
return {};
|
||||
|
||||
case UserTypes.PROFILE_NO_LONGER_VISIBLE:
|
||||
return removeProfileFromTeams(state, action);
|
||||
return removeProfileFromSets(state, action);
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function profilesWithoutTeam(state: Set<string> = new Set(), action: AnyAction) {
|
||||
function profilesWithoutTeam(state: UsersState['profilesWithoutTeam'] = new Set<string>(), action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_PROFILE_WITHOUT_TEAM: {
|
||||
const nextSet = new Set(state);
|
||||
@ -342,21 +321,26 @@ function profilesWithoutTeam(state: Set<string> = new Set(), action: AnyAction)
|
||||
action.data.forEach((user: UserProfile) => nextSet.add(user.id));
|
||||
return nextSet;
|
||||
}
|
||||
case UserTypes.PROFILE_NO_LONGER_VISIBLE:
|
||||
case UserTypes.RECEIVED_PROFILE_IN_TEAM: {
|
||||
const nextSet = new Set(state);
|
||||
nextSet.delete(action.data.id);
|
||||
return nextSet;
|
||||
}
|
||||
case UserTypes.PROFILE_NO_LONGER_VISIBLE: {
|
||||
const nextSet = new Set(state);
|
||||
nextSet.delete(action.data.user_id);
|
||||
return nextSet;
|
||||
}
|
||||
|
||||
case UserTypes.LOGOUT_SUCCESS:
|
||||
return new Set();
|
||||
return new Set<string>();
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function profilesInChannel(state: RelationOneToMany<Channel, UserProfile> = {}, action: AnyAction) {
|
||||
function profilesInChannel(state: UsersState['profilesInChannel'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_PROFILE_IN_CHANNEL:
|
||||
return addProfileToSet(state, action.data.id, action.data.user_id);
|
||||
@ -379,7 +363,7 @@ function profilesInChannel(state: RelationOneToMany<Channel, UserProfile> = {},
|
||||
}});
|
||||
|
||||
case UserTypes.PROFILE_NO_LONGER_VISIBLE:
|
||||
return removeProfileFromTeams(state, action);
|
||||
return removeProfileFromSets(state, action);
|
||||
|
||||
case UserTypes.LOGOUT_SUCCESS:
|
||||
return {};
|
||||
@ -388,7 +372,7 @@ function profilesInChannel(state: RelationOneToMany<Channel, UserProfile> = {},
|
||||
}
|
||||
}
|
||||
|
||||
function profilesNotInChannel(state: RelationOneToMany<Channel, UserProfile> = {}, action: AnyAction) {
|
||||
function profilesNotInChannel(state: UsersState['profilesNotInChannel'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_PROFILE_NOT_IN_CHANNEL:
|
||||
return addProfileToSet(state, action.data.id, action.data.user_id);
|
||||
@ -417,14 +401,14 @@ function profilesNotInChannel(state: RelationOneToMany<Channel, UserProfile> = {
|
||||
return {};
|
||||
|
||||
case UserTypes.PROFILE_NO_LONGER_VISIBLE:
|
||||
return removeProfileFromTeams(state, action);
|
||||
return removeProfileFromSets(state, action);
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function profilesInGroup(state: RelationOneToMany<Group, UserProfile> = {}, action: AnyAction) {
|
||||
function profilesInGroup(state: UsersState['profilesInGroup'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_PROFILES_LIST_IN_GROUP: {
|
||||
return profileListToSet(state, action);
|
||||
@ -459,12 +443,18 @@ function profilesInGroup(state: RelationOneToMany<Group, UserProfile> = {}, acti
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
case UserTypes.PROFILE_NO_LONGER_VISIBLE:
|
||||
return removeProfileFromSets(state, action);
|
||||
|
||||
case UserTypes.LOGOUT_SUCCESS:
|
||||
return {};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function profilesNotInGroup(state: RelationOneToMany<Group, UserProfile> = {}, action: AnyAction) {
|
||||
function profilesNotInGroup(state: UsersState['profilesNotInGroup'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_PROFILES_FOR_GROUP: {
|
||||
const id = action.id;
|
||||
@ -484,6 +474,12 @@ function profilesNotInGroup(state: RelationOneToMany<Group, UserProfile> = {}, a
|
||||
case UserTypes.RECEIVED_PROFILES_LIST_NOT_IN_GROUP: {
|
||||
return profileListToSet(state, action);
|
||||
}
|
||||
|
||||
case UserTypes.PROFILE_NO_LONGER_VISIBLE:
|
||||
return removeProfileFromSets(state, action);
|
||||
|
||||
case UserTypes.LOGOUT_SUCCESS:
|
||||
return {};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
@ -611,7 +607,7 @@ function myUserAccessTokens(state: Record<string, UserAccessToken> = {}, action:
|
||||
}
|
||||
}
|
||||
|
||||
function stats(state = {}, action: AnyAction) {
|
||||
function stats(state: UsersState['stats'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_USER_STATS: {
|
||||
const stat = action.data;
|
||||
@ -625,7 +621,7 @@ function stats(state = {}, action: AnyAction) {
|
||||
}
|
||||
}
|
||||
|
||||
function filteredStats(state = {}, action: AnyAction) {
|
||||
function filteredStats(state: UsersState['filteredStats'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_FILTERED_USER_STATS: {
|
||||
const stat = action.data;
|
||||
@ -639,7 +635,7 @@ function filteredStats(state = {}, action: AnyAction) {
|
||||
}
|
||||
}
|
||||
|
||||
function lastActivity(state: RelationOneToOne<UserProfile, string> = {}, action: AnyAction) {
|
||||
function lastActivity(state: UsersState['lastActivity'] = {}, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case UserTypes.RECEIVED_STATUS: {
|
||||
const nextState = Object.assign({}, state);
|
||||
|
@ -40,9 +40,9 @@ describe('Selectors.Channels.getChannelsInCurrentTeam', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel3.id],
|
||||
[team2.id]: [channel2.id],
|
||||
'': [channel4.id],
|
||||
[team1.id]: new Set([channel1.id, channel3.id]),
|
||||
[team2.id]: new Set([channel2.id]),
|
||||
'': new Set([channel4.id]),
|
||||
};
|
||||
|
||||
const testState = deepFreezeAndThrowOnMutation({
|
||||
@ -97,7 +97,7 @@ describe('Selectors.Channels.getChannelsInCurrentTeam', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel2.id],
|
||||
[team1.id]: new Set([channel1.id, channel2.id]),
|
||||
};
|
||||
|
||||
const testStateDe = deepFreezeAndThrowOnMutation({
|
||||
@ -188,9 +188,9 @@ describe('Selectors.Channels.getMyChannels', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel3.id],
|
||||
[team2.id]: [channel2.id],
|
||||
'': [channel4.id, channel5.id],
|
||||
[team1.id]: new Set([channel1.id, channel3.id]),
|
||||
[team2.id]: new Set([channel2.id]),
|
||||
'': new Set([channel4.id, channel5.id]),
|
||||
};
|
||||
|
||||
const myMembers = {
|
||||
@ -319,9 +319,9 @@ describe('Selectors.Channels.getOtherChannels', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel3.id, channel5.id, channel6.id],
|
||||
[team2.id]: [channel2.id],
|
||||
'': [channel4.id],
|
||||
[team1.id]: new Set([channel1.id, channel3.id, channel5.id, channel6.id]),
|
||||
[team2.id]: new Set([channel2.id]),
|
||||
'': new Set([channel4.id]),
|
||||
};
|
||||
|
||||
const myMembers = {
|
||||
@ -625,8 +625,8 @@ describe('Selectors.Channels.getChannelsNameMapInCurrentTeam', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel4.id],
|
||||
[team2.id]: [channel2.id, channel3.id],
|
||||
[team1.id]: new Set([channel1.id, channel4.id]),
|
||||
[team2.id]: new Set([channel2.id, channel3.id]),
|
||||
};
|
||||
|
||||
const testState = deepFreezeAndThrowOnMutation({
|
||||
@ -741,8 +741,8 @@ describe('Selectors.Channels.getChannelsNameMapInTeam', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel4.id],
|
||||
[team2.id]: [channel2.id, channel3.id],
|
||||
[team1.id]: new Set([channel1.id, channel4.id]),
|
||||
[team2.id]: new Set([channel2.id, channel3.id]),
|
||||
};
|
||||
|
||||
const testState = deepFreezeAndThrowOnMutation({
|
||||
@ -796,8 +796,8 @@ describe('Selectors.Channels.getChannelNameToDisplayNameMap', () => {
|
||||
channel4,
|
||||
},
|
||||
channelsInTeam: {
|
||||
[team1.id]: [channel1.id, channel2.id, channel3.id],
|
||||
[team2.id]: [channel4.id],
|
||||
[team1.id]: new Set([channel1.id, channel2.id, channel3.id]),
|
||||
[team2.id]: new Set([channel4.id]),
|
||||
},
|
||||
},
|
||||
teams: {
|
||||
@ -913,7 +913,7 @@ describe('Selectors.Channels.getChannelNameToDisplayNameMap', () => {
|
||||
newChannel,
|
||||
},
|
||||
channelsInTeam: {
|
||||
[team1.id]: [channel1.id, channel2.id, channel3.id, newChannel.id],
|
||||
[team1.id]: new Set([channel1.id, channel2.id, channel3.id, newChannel.id]),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -980,8 +980,8 @@ describe('Selectors.Channels.getGroupChannels', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel2.id],
|
||||
'': [channel3.id, channel4.id, channel5.id],
|
||||
[team1.id]: new Set([channel1.id, channel2.id]),
|
||||
'': new Set([channel3.id, channel4.id, channel5.id]),
|
||||
};
|
||||
|
||||
const testState = deepFreezeAndThrowOnMutation({
|
||||
@ -1028,10 +1028,9 @@ describe('Selectors.Channels.getChannelIdsInCurrentTeam', () => {
|
||||
const channel5 = TestHelper.fakeChannelWithId('');
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel2.id],
|
||||
[team2.id]: [channel3.id, channel4.id],
|
||||
// eslint-disable-next-line no-useless-computed-key
|
||||
['']: [channel5.id],
|
||||
[team1.id]: new Set([channel1.id, channel2.id]),
|
||||
[team2.id]: new Set([channel3.id, channel4.id]),
|
||||
'': new Set([channel5.id]),
|
||||
};
|
||||
|
||||
const testState = deepFreezeAndThrowOnMutation({
|
||||
@ -1055,10 +1054,10 @@ describe('Selectors.Channels.getChannelIdsInCurrentTeam', () => {
|
||||
...testState.entities.channels,
|
||||
channelsInTeam: {
|
||||
...testState.entities.channels.channelsInTeam,
|
||||
[team2.id]: [
|
||||
[team2.id]: new Set([
|
||||
...testState.entities.channels.channelsInTeam[team2.id],
|
||||
newChannel.id,
|
||||
],
|
||||
]),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1085,10 +1084,9 @@ describe('Selectors.Channels.getChannelIdsForCurrentTeam', () => {
|
||||
const channel5 = TestHelper.fakeChannelWithId('');
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel2.id],
|
||||
[team2.id]: [channel3.id, channel4.id],
|
||||
// eslint-disable-next-line no-useless-computed-key
|
||||
['']: [channel5.id],
|
||||
[team1.id]: new Set([channel1.id, channel2.id]),
|
||||
[team2.id]: new Set([channel3.id, channel4.id]),
|
||||
'': new Set([channel5.id]),
|
||||
};
|
||||
|
||||
const testState = deepFreezeAndThrowOnMutation({
|
||||
@ -1112,10 +1110,10 @@ describe('Selectors.Channels.getChannelIdsForCurrentTeam', () => {
|
||||
...testState.entities.channels,
|
||||
channelsInTeam: {
|
||||
...testState.entities.channels.channelsInTeam,
|
||||
[team2.id]: [
|
||||
[team2.id]: new Set([
|
||||
...testState.entities.channels.channelsInTeam[team2.id],
|
||||
anotherChannel.id,
|
||||
],
|
||||
]),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1273,8 +1271,8 @@ describe('Selectors.Channels.getChannelsWithUserProfiles', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id],
|
||||
'': [channel2.id],
|
||||
[team1.id]: new Set([channel1.id]),
|
||||
'': new Set([channel2.id]),
|
||||
};
|
||||
|
||||
const user1 = TestHelper.fakeUserWithId();
|
||||
@ -1333,7 +1331,7 @@ describe('Selectors.Channels.getChannelsWithUserProfiles', () => {
|
||||
[unloadedChannel.id]: unloadedChannel,
|
||||
},
|
||||
channelsInTeam: {
|
||||
'': [channel2.id, unloadedChannel.id],
|
||||
'': new Set([channel2.id, unloadedChannel.id]),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2006,7 +2004,7 @@ describe('Selectors.Channels.getUnreadStatusInCurrentTeam', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel2.id],
|
||||
[team1.id]: new Set([channel1.id, channel2.id]),
|
||||
};
|
||||
|
||||
const testState = deepFreezeAndThrowOnMutation({
|
||||
@ -3078,9 +3076,9 @@ describe('Selectors.Channels.getUnreadChannelIds', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel3.id],
|
||||
[team2.id]: [channel2.id],
|
||||
'': [channel4.id],
|
||||
[team1.id]: new Set([channel1.id, channel3.id]),
|
||||
[team2.id]: new Set([channel2.id]),
|
||||
'': new Set([channel4.id]),
|
||||
};
|
||||
|
||||
const messageCounts = {
|
||||
@ -3152,9 +3150,9 @@ describe('Selectors.Channels.getUnreadChannelIds', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
[team1.id]: [channel1.id, channel3.id],
|
||||
[team2.id]: [channel2.id],
|
||||
'': [channel4.id],
|
||||
[team1.id]: new Set([channel1.id, channel3.id]),
|
||||
[team2.id]: new Set([channel2.id]),
|
||||
'': new Set([channel4.id]),
|
||||
};
|
||||
|
||||
const messageCounts = {
|
||||
|
@ -17,7 +17,6 @@ import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserProfile, UsersState} from '@mattermost/types/users';
|
||||
import type {
|
||||
IDMappedObjects,
|
||||
RelationOneToMany,
|
||||
RelationOneToManyUnique,
|
||||
RelationOneToOne,
|
||||
} from '@mattermost/types/utilities';
|
||||
@ -99,7 +98,7 @@ export function getChannelsMemberCount(state: GlobalState): Record<string, numbe
|
||||
return state.entities.channels.channelsMemberCount;
|
||||
}
|
||||
|
||||
export function getChannelsInTeam(state: GlobalState): RelationOneToMany<Team, Channel> {
|
||||
export function getChannelsInTeam(state: GlobalState): RelationOneToManyUnique<Team, Channel> {
|
||||
return state.entities.channels.channelsInTeam;
|
||||
}
|
||||
|
||||
@ -131,7 +130,7 @@ export function getChannelsInPolicy() {
|
||||
export const getDirectChannelsSet: (state: GlobalState) => Set<string> = createSelector(
|
||||
'getDirectChannelsSet',
|
||||
getChannelsInTeam,
|
||||
(channelsInTeam: RelationOneToMany<Team, Channel>): Set<string> => {
|
||||
(channelsInTeam: RelationOneToManyUnique<Team, Channel>): Set<string> => {
|
||||
if (!channelsInTeam) {
|
||||
return new Set();
|
||||
}
|
||||
@ -364,12 +363,12 @@ export function getChannelByTeamIdAndChannelName(state: GlobalState, teamId: str
|
||||
);
|
||||
}
|
||||
|
||||
export const getChannelSetInCurrentTeam: (state: GlobalState) => string[] = createSelector(
|
||||
export const getChannelSetInCurrentTeam: (state: GlobalState) => Set<string> = createSelector(
|
||||
'getChannelSetInCurrentTeam',
|
||||
getCurrentTeamId,
|
||||
getChannelsInTeam,
|
||||
(currentTeamId: string, channelsInTeam: RelationOneToMany<Team, Channel>): string[] => {
|
||||
return (channelsInTeam && channelsInTeam[currentTeamId]) || [];
|
||||
(currentTeamId: string, channelsInTeam: RelationOneToManyUnique<Team, Channel>) => {
|
||||
return (channelsInTeam && channelsInTeam[currentTeamId]) || new Set();
|
||||
},
|
||||
);
|
||||
|
||||
@ -387,7 +386,7 @@ export const getChannelSetForAllTeams: (state: GlobalState) => string[] = create
|
||||
},
|
||||
);
|
||||
|
||||
function sortAndInjectChannels(channels: IDMappedObjects<Channel>, channelSet: string[], locale: string): Channel[] {
|
||||
function sortAndInjectChannels(channels: IDMappedObjects<Channel>, channelSet: string[] | Set<string>, locale: string): Channel[] {
|
||||
const currentChannels: Channel[] = [];
|
||||
|
||||
if (typeof channelSet === 'undefined') {
|
||||
@ -406,7 +405,7 @@ export const getChannelsInCurrentTeam: (state: GlobalState) => Channel[] = creat
|
||||
getAllChannels,
|
||||
getChannelSetInCurrentTeam,
|
||||
getCurrentUser,
|
||||
(channels: IDMappedObjects<Channel>, currentTeamChannelSet: string[], currentUser: UserProfile): Channel[] => {
|
||||
(channels: IDMappedObjects<Channel>, currentTeamChannelSet: Set<string>, currentUser: UserProfile): Channel[] => {
|
||||
let locale = General.DEFAULT_LOCALE;
|
||||
|
||||
if (currentUser && currentUser.locale) {
|
||||
@ -433,8 +432,8 @@ export const getChannelsNameMapInTeam: (state: GlobalState, teamId: string) => R
|
||||
getAllChannels,
|
||||
getChannelsInTeam,
|
||||
(state: GlobalState, teamId: string): string => teamId,
|
||||
(channels: IDMappedObjects<Channel>, channelsInTeams: RelationOneToMany<Team, Channel>, teamId: string): Record<string, Channel> => {
|
||||
const channelsInTeam = channelsInTeams[teamId] || [];
|
||||
(channels: IDMappedObjects<Channel>, channelsInTeams: RelationOneToManyUnique<Team, Channel>, teamId: string): Record<string, Channel> => {
|
||||
const channelsInTeam = channelsInTeams[teamId] || new Set();
|
||||
const channelMap: Record<string, Channel> = {};
|
||||
channelsInTeam.forEach((id) => {
|
||||
const channel = channels[id];
|
||||
@ -448,7 +447,7 @@ export const getChannelsNameMapInCurrentTeam: (state: GlobalState) => Record<str
|
||||
'getChannelsNameMapInCurrentTeam',
|
||||
getAllChannels,
|
||||
getChannelSetInCurrentTeam,
|
||||
(channels: IDMappedObjects<Channel>, currentTeamChannelSet: string[]): Record<string, Channel> => {
|
||||
(channels: IDMappedObjects<Channel>, currentTeamChannelSet: Set<string>): Record<string, Channel> => {
|
||||
const channelMap: Record<string, Channel> = {};
|
||||
currentTeamChannelSet.forEach((id) => {
|
||||
const channel = channels[id];
|
||||
@ -462,7 +461,7 @@ export const getChannelNameToDisplayNameMap: (state: GlobalState) => Record<stri
|
||||
'getChannelNameToDisplayNameMap',
|
||||
getAllChannels,
|
||||
getChannelSetInCurrentTeam,
|
||||
(channels: IDMappedObjects<Channel>, currentTeamChannelSet: string[]) => {
|
||||
(channels: IDMappedObjects<Channel>, currentTeamChannelSet: Set<string>) => {
|
||||
const channelMap: Record<string, string> = {};
|
||||
for (const id of currentTeamChannelSet) {
|
||||
const channel = channels[id];
|
||||
@ -948,7 +947,7 @@ export const getChannelIdsInCurrentTeam: (state: GlobalState) => string[] = crea
|
||||
'getChannelIdsInCurrentTeam',
|
||||
getCurrentTeamId,
|
||||
getChannelsInTeam,
|
||||
(currentTeamId: string, channelsInTeam: RelationOneToMany<Team, Channel>): string[] => {
|
||||
(currentTeamId: string, channelsInTeam: RelationOneToManyUnique<Team, Channel>): string[] => {
|
||||
return Array.from(channelsInTeam[currentTeamId] || []);
|
||||
},
|
||||
);
|
||||
|
@ -65,11 +65,6 @@ describe('Selectors.Roles', () => {
|
||||
channels[channel11.id] = channel11;
|
||||
channels[channel12.id] = channel12;
|
||||
|
||||
const channelsInTeam: Record<string, Array<Channel['id']>> = {};
|
||||
channelsInTeam[team1.id] = [channel1.id, channel2.id, channel5.id, channel6.id, channel8.id, channel10.id, channel11.id];
|
||||
channelsInTeam[team2.id] = [channel3.id];
|
||||
channelsInTeam[''] = [channel4.id, channel7.id, channel9.id];
|
||||
|
||||
const user = TestHelper.fakeUserWithId();
|
||||
const profiles: Record<string, UserProfile> = {};
|
||||
profiles[user.id] = user;
|
||||
|
@ -49,7 +49,7 @@ describe('Selectors.Threads.getThreadOrderInCurrentTeam', () => {
|
||||
},
|
||||
channels: {
|
||||
channelsInTeam: {
|
||||
[team1.id]: [post1.channel_id, post2.channel_id],
|
||||
[team1.id]: new Set([post1.channel_id, post2.channel_id]),
|
||||
},
|
||||
channels: {
|
||||
[post1.channel_id]: {
|
||||
@ -116,7 +116,7 @@ describe('Selectors.Threads.getUnreadThreadOrderInCurrentTeam', () => {
|
||||
},
|
||||
channels: {
|
||||
channelsInTeam: {
|
||||
[team1.id]: [post1.channel_id, post2.channel_id],
|
||||
[team1.id]: new Set([post1.channel_id, post2.channel_id]),
|
||||
},
|
||||
channels: {
|
||||
[post1.channel_id]: {
|
||||
|
@ -9,7 +9,6 @@ import type {Team, TeamMembership} from '@mattermost/types/teams';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
import type {
|
||||
IDMappedObjects,
|
||||
RelationOneToMany,
|
||||
RelationOneToManyUnique,
|
||||
RelationOneToOne,
|
||||
} from '@mattermost/types/utilities';
|
||||
@ -60,11 +59,11 @@ export function getUserIdsNotInChannels(state: GlobalState): RelationOneToManyUn
|
||||
return state.entities.users.profilesNotInChannel;
|
||||
}
|
||||
|
||||
export function getUserIdsInTeams(state: GlobalState): RelationOneToMany<Team, UserProfile> {
|
||||
export function getUserIdsInTeams(state: GlobalState): RelationOneToManyUnique<Team, UserProfile> {
|
||||
return state.entities.users.profilesInTeam;
|
||||
}
|
||||
|
||||
export function getUserIdsNotInTeams(state: GlobalState): RelationOneToMany<Team, UserProfile> {
|
||||
export function getUserIdsNotInTeams(state: GlobalState): RelationOneToManyUnique<Team, UserProfile> {
|
||||
return state.entities.users.profilesNotInTeam;
|
||||
}
|
||||
|
||||
@ -72,11 +71,11 @@ export function getUserIdsWithoutTeam(state: GlobalState): Set<UserProfile['id']
|
||||
return state.entities.users.profilesWithoutTeam;
|
||||
}
|
||||
|
||||
export function getUserIdsInGroups(state: GlobalState): RelationOneToMany<Group, UserProfile> {
|
||||
export function getUserIdsInGroups(state: GlobalState): RelationOneToManyUnique<Group, UserProfile> {
|
||||
return state.entities.users.profilesInGroup;
|
||||
}
|
||||
|
||||
export function getUserIdsNotInGroups(state: GlobalState): RelationOneToMany<Group, UserProfile> {
|
||||
export function getUserIdsNotInGroups(state: GlobalState): RelationOneToManyUnique<Group, UserProfile> {
|
||||
return state.entities.users.profilesNotInGroup;
|
||||
}
|
||||
|
||||
@ -262,7 +261,7 @@ export const getProfileSetNotInCurrentChannel: (state: GlobalState) => Set<UserP
|
||||
},
|
||||
);
|
||||
|
||||
export const getProfileSetInCurrentTeam: (state: GlobalState) => Array<UserProfile['id']> = createSelector(
|
||||
export const getProfileSetInCurrentTeam: (state: GlobalState) => Set<UserProfile['id']> = createSelector(
|
||||
'getProfileSetInCurrentTeam',
|
||||
(state) => state.entities.teams.currentTeamId,
|
||||
getUserIdsInTeams,
|
||||
@ -271,7 +270,7 @@ export const getProfileSetInCurrentTeam: (state: GlobalState) => Array<UserProfi
|
||||
},
|
||||
);
|
||||
|
||||
export const getProfileSetNotInCurrentTeam: (state: GlobalState) => Array<UserProfile['id']> = createSelector(
|
||||
export const getProfileSetNotInCurrentTeam: (state: GlobalState) => Set<UserProfile['id']> = createSelector(
|
||||
'getProfileSetNotInCurrentTeam',
|
||||
(state) => state.entities.teams.currentTeamId,
|
||||
getUserIdsNotInTeams,
|
||||
@ -281,12 +280,12 @@ export const getProfileSetNotInCurrentTeam: (state: GlobalState) => Array<UserPr
|
||||
);
|
||||
|
||||
const PROFILE_SET_ALL = 'all';
|
||||
function sortAndInjectProfiles(profiles: IDMappedObjects<UserProfile>, profileSet?: 'all' | Array<UserProfile['id']> | Set<UserProfile['id']>): UserProfile[] {
|
||||
function sortAndInjectProfiles(profiles: IDMappedObjects<UserProfile>, profileSet?: 'all' | Set<UserProfile['id']>): UserProfile[] {
|
||||
const currentProfiles = injectProfiles(profiles, profileSet);
|
||||
return currentProfiles.sort(sortByUsername);
|
||||
}
|
||||
|
||||
function injectProfiles(profiles: IDMappedObjects<UserProfile>, profileSet?: 'all' | Array<UserProfile['id']> | Set<UserProfile['id']>): UserProfile[] {
|
||||
function injectProfiles(profiles: IDMappedObjects<UserProfile>, profileSet?: 'all' | Set<UserProfile['id']>): UserProfile[] {
|
||||
let currentProfiles: UserProfile[] = [];
|
||||
|
||||
if (typeof profileSet === 'undefined') {
|
||||
@ -436,11 +435,11 @@ export function getStatusForUserId(state: GlobalState, userId: UserProfile['id']
|
||||
return getUserStatuses(state)[userId];
|
||||
}
|
||||
|
||||
export function getTotalUsersStats(state: GlobalState): any {
|
||||
export function getTotalUsersStats(state: GlobalState) {
|
||||
return state.entities.users.stats;
|
||||
}
|
||||
|
||||
export function getFilteredUsersStats(state: GlobalState): any {
|
||||
export function getFilteredUsersStats(state: GlobalState) {
|
||||
return state.entities.users.filteredStats;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ describe('utils.makeAddLastViewAtToProfiles', () => {
|
||||
};
|
||||
|
||||
const channelsInTeam = {
|
||||
'': [channel1.id, channel2.id, channel3.id],
|
||||
'': new Set([channel1.id, channel2.id, channel3.id]),
|
||||
};
|
||||
|
||||
const testState = deepFreezeAndThrowOnMutation({
|
||||
|
@ -31,6 +31,7 @@ const state: GlobalState = {
|
||||
profilesNotInGroup: {},
|
||||
statuses: {},
|
||||
stats: {},
|
||||
filteredStats: {},
|
||||
myUserAccessTokens: {},
|
||||
lastActivity: {},
|
||||
},
|
||||
@ -110,6 +111,7 @@ const state: GlobalState = {
|
||||
userAccessTokens: {},
|
||||
clusterInfo: [],
|
||||
analytics: {},
|
||||
teamAnalytics: {},
|
||||
dataRetentionCustomPolicies: {},
|
||||
dataRetentionCustomPoliciesCount: 0,
|
||||
prevTrialLicense: {},
|
||||
|
@ -29,7 +29,7 @@ const initialState = {
|
||||
currentChannelId: {id: currentChannelId, team_id: currentTeamId},
|
||||
},
|
||||
channelsInTeam: {
|
||||
currentTeamId: [currentChannelId],
|
||||
currentTeamId: new Set([currentChannelId]),
|
||||
},
|
||||
myMembers: {
|
||||
currentChannelId: {
|
||||
|
@ -84,7 +84,7 @@ describe('getUnreadChannels', () => {
|
||||
unreadChannel2,
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['unreadChannel1', 'unreadChannel2', 'readChannel'],
|
||||
team1: new Set(['unreadChannel1', 'unreadChannel2', 'readChannel']),
|
||||
},
|
||||
currentChannelId: 'currentChannel',
|
||||
messageCounts: {
|
||||
@ -375,10 +375,10 @@ describe('getUnreadChannels', () => {
|
||||
},
|
||||
channelsInTeam: {
|
||||
...baseState.entities.channels.channelsInTeam,
|
||||
team1: [
|
||||
team1: new Set([
|
||||
...baseState.entities.channels.channelsInTeam.team1,
|
||||
'archivedChannel',
|
||||
],
|
||||
]),
|
||||
},
|
||||
messageCounts: {
|
||||
...baseState.entities.channels.messageCounts,
|
||||
@ -435,7 +435,7 @@ describe('getDisplayedChannels', () => {
|
||||
unreadChannel2,
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['unreadChannel1', 'unreadChannel2', 'readChannel'],
|
||||
team1: new Set(['unreadChannel1', 'unreadChannel2', 'readChannel']),
|
||||
},
|
||||
currentChannelId: 'currentChannel',
|
||||
messageCounts: {
|
||||
@ -608,7 +608,7 @@ describe('makeGetFilteredChannelIdsForCategory', () => {
|
||||
unreadChannel2,
|
||||
},
|
||||
channelsInTeam: {
|
||||
team1: ['unreadChannel1', 'unreadChannel2', 'readChannel'],
|
||||
team1: new Set(['unreadChannel1', 'unreadChannel2', 'readChannel']),
|
||||
},
|
||||
currentChannelId: 'currentChannel',
|
||||
messageCounts: {
|
||||
|
@ -20,6 +20,7 @@ const emptyOtherUsersState: Omit<GlobalState['entities']['users'], 'profiles' |
|
||||
profilesNotInGroup: {},
|
||||
statuses: {},
|
||||
stats: {},
|
||||
filteredStats: {},
|
||||
myUserAccessTokens: {},
|
||||
lastActivity: {},
|
||||
};
|
||||
|
@ -60,8 +60,8 @@ export type AdminState = {
|
||||
userAccessTokens: Record<string, UserAccessToken>;
|
||||
clusterInfo: ClusterInfo[];
|
||||
samlCertStatus?: SamlCertificateStatus;
|
||||
analytics?: Record<string, number | AnalyticsRow[]>;
|
||||
teamAnalytics?: RelationOneToOne<Team, Record<string, number | AnalyticsRow[]>>;
|
||||
analytics: AnalyticsState;
|
||||
teamAnalytics: RelationOneToOne<Team, AnalyticsState>;
|
||||
userAccessTokensByUser?: RelationOneToOne<UserProfile, Record<string, UserAccessToken>>;
|
||||
plugins?: Record<string, PluginRedux>;
|
||||
pluginStatuses?: Record<string, PluginStatusRedux>;
|
||||
@ -71,6 +71,31 @@ export type AdminState = {
|
||||
prevTrialLicense: ClientLicense;
|
||||
};
|
||||
|
||||
export type AnalyticsState = {
|
||||
POST_PER_DAY?: AnalyticsRow[];
|
||||
BOT_POST_PER_DAY?: AnalyticsRow[];
|
||||
USERS_WITH_POSTS_PER_DAY?: AnalyticsRow[];
|
||||
|
||||
TOTAL_PUBLIC_CHANNELS?: number;
|
||||
TOTAL_PRIVATE_GROUPS?: number;
|
||||
TOTAL_POSTS?: number;
|
||||
TOTAL_USERS?: number;
|
||||
TOTAL_INACTIVE_USERS?: number;
|
||||
TOTAL_TEAMS?: number;
|
||||
TOTAL_WEBSOCKET_CONNECTIONS?: number;
|
||||
TOTAL_MASTER_DB_CONNECTIONS?: number;
|
||||
TOTAL_READ_DB_CONNECTIONS?: number;
|
||||
DAILY_ACTIVE_USERS?: number;
|
||||
MONTHLY_ACTIVE_USERS?: number;
|
||||
TOTAL_FILE_POSTS?: number;
|
||||
TOTAL_HASHTAG_POSTS?: number;
|
||||
TOTAL_IHOOKS?: number;
|
||||
TOTAL_OHOOKS?: number;
|
||||
TOTAL_COMMANDS?: number;
|
||||
TOTAL_SESSIONS?: number;
|
||||
REGISTERED_USERS?: number;
|
||||
}
|
||||
|
||||
export type ClusterInfo = {
|
||||
id: string;
|
||||
version: string;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {IDMappedObjects, RelationOneToMany, RelationOneToOne} from './utilities';
|
||||
import {IDMappedObjects, RelationOneToManyUnique, RelationOneToOne} from './utilities';
|
||||
import {Team} from './teams';
|
||||
|
||||
// e.g.
|
||||
@ -147,7 +147,7 @@ export type ChannelUnread = {
|
||||
export type ChannelsState = {
|
||||
currentChannelId: string;
|
||||
channels: IDMappedObjects<Channel>;
|
||||
channelsInTeam: RelationOneToMany<Team, Channel>;
|
||||
channelsInTeam: RelationOneToManyUnique<Team, Channel>;
|
||||
myMembers: RelationOneToOne<Channel, ChannelMembership>;
|
||||
roles: RelationOneToOne<Channel, Set<string>>;
|
||||
membersInChannel: RelationOneToOne<Channel, Record<string, ChannelMembership>>;
|
||||
|
@ -70,16 +70,16 @@ export type UsersState = {
|
||||
mySessions: Session[];
|
||||
myAudits: Audit[];
|
||||
profiles: IDMappedObjects<UserProfile>;
|
||||
profilesInTeam: RelationOneToMany<Team, UserProfile>;
|
||||
profilesNotInTeam: RelationOneToMany<Team, UserProfile>;
|
||||
profilesInTeam: RelationOneToManyUnique<Team, UserProfile>;
|
||||
profilesNotInTeam: RelationOneToManyUnique<Team, UserProfile>;
|
||||
profilesWithoutTeam: Set<string>;
|
||||
profilesInChannel: RelationOneToManyUnique<Channel, UserProfile>;
|
||||
profilesNotInChannel: RelationOneToManyUnique<Channel, UserProfile>;
|
||||
profilesInGroup: RelationOneToMany<Group, UserProfile>;
|
||||
profilesNotInGroup: RelationOneToMany<Group, UserProfile>;
|
||||
profilesInGroup: RelationOneToManyUnique<Group, UserProfile>;
|
||||
profilesNotInGroup: RelationOneToManyUnique<Group, UserProfile>;
|
||||
statuses: RelationOneToOne<UserProfile, string>;
|
||||
stats: RelationOneToOne<UserProfile, UsersStats>;
|
||||
filteredStats?: UsersStats;
|
||||
stats: Partial<UsersStats>;
|
||||
filteredStats: Partial<UsersStats>;
|
||||
myUserAccessTokens: Record<string, UserAccessToken>;
|
||||
lastActivity: RelationOneToOne<UserProfile, number>;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user