[MM-54879] Goodbye, GraphQL -- Regards Webapp (#24850)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
cd4d220a21
Коммит
760dfe41f9
@@ -694,7 +694,6 @@ const defaultServerConfig: AdminConfig = {
|
||||
PermalinkPreviews: false,
|
||||
CallsEnabled: true,
|
||||
NormalizeLdapDNs: false,
|
||||
GraphQL: false,
|
||||
PostPriority: false,
|
||||
WysiwygEditor: false,
|
||||
OnboardingTourTips: true,
|
||||
|
||||
@@ -1,27 +1,15 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import nock from 'nock';
|
||||
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {Role} from '@mattermost/types/roles';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
|
||||
import {
|
||||
searchMoreChannels,
|
||||
addUsersToChannel,
|
||||
openDirectChannelToUserId,
|
||||
openGroupChannelToUserIds,
|
||||
loadChannelsForCurrentUser, fetchChannelsAndMembers,
|
||||
loadChannelsForCurrentUser,
|
||||
} from 'actions/channel_actions';
|
||||
import {CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE} from 'actions/channel_queries';
|
||||
import {loadProfilesForSidebar} from 'actions/user_actions';
|
||||
import configureStore from 'store';
|
||||
|
||||
import TestHelper from 'packages/mattermost-redux/test/test_helper';
|
||||
import mockStore from 'tests/test_store';
|
||||
|
||||
const initialState = {
|
||||
@@ -116,7 +104,7 @@ const initialState = {
|
||||
const realDateNow = Date.now;
|
||||
|
||||
jest.mock('mattermost-redux/actions/channels', () => ({
|
||||
fetchMyChannelsAndMembersREST: (...args: any) => ({type: 'MOCK_FETCH_CHANNELS_AND_MEMBERS', args}),
|
||||
fetchChannelsAndMembers: (...args: any) => ({type: 'MOCK_FETCH_CHANNELS_AND_MEMBERS', args}),
|
||||
searchChannels: () => {
|
||||
return {
|
||||
type: 'MOCK_SEARCH_CHANNELS',
|
||||
@@ -281,217 +269,5 @@ describe('Actions.Channel', () => {
|
||||
await testStore.dispatch(openGroupChannelToUserIds(fakeData.userIds));
|
||||
expect(testStore.getActions()).toEqual(expectedActions);
|
||||
});
|
||||
|
||||
describe('fetchChannelsAndMembers', () => {
|
||||
let role1: Role;
|
||||
let role2: Role;
|
||||
|
||||
beforeAll(() => {
|
||||
TestHelper.initBasic(Client4);
|
||||
|
||||
role1 = TestHelper.basicRoles?.system_admin as Role;
|
||||
role2 = TestHelper.basicRoles?.system_user as Role;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
nock.cleanAll();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
TestHelper.tearDown();
|
||||
});
|
||||
|
||||
test('should throws error when response errors out', async () => {
|
||||
const store = configureStore();
|
||||
|
||||
nock(Client4.getGraphQLUrl()).
|
||||
post('').reply(200, {
|
||||
errors: [{message: 'some error'}],
|
||||
});
|
||||
|
||||
const result = await store.dispatch(fetchChannelsAndMembers());
|
||||
|
||||
expect(Object.keys(result)).toEqual(['error']);
|
||||
});
|
||||
|
||||
test('should throws error when response is not correct', async () => {
|
||||
[null, undefined, {}].
|
||||
forEach(async (dataResponse) => {
|
||||
const store = configureStore();
|
||||
|
||||
nock(Client4.getGraphQLUrl()).
|
||||
post('').reply(200, {
|
||||
data: dataResponse,
|
||||
});
|
||||
|
||||
const result = await store.dispatch(fetchChannelsAndMembers());
|
||||
|
||||
expect(Object.keys(result)).toEqual(['error']);
|
||||
});
|
||||
});
|
||||
|
||||
test('should throws not throw error when responses are empty', async () => {
|
||||
[[[], []], [[fakeGQLChannelWithId('team1')], []], [[], [fakeGQLChannelMember('user1', 'channel2', [role1])]]].
|
||||
forEach(async ([channelResponse, channelMemberResponse]) => {
|
||||
const store = configureStore();
|
||||
|
||||
nock(Client4.getGraphQLUrl()).
|
||||
post('').
|
||||
reply(200, {
|
||||
data: {
|
||||
channels: [...channelResponse],
|
||||
channelMembers: [...channelMemberResponse],
|
||||
},
|
||||
});
|
||||
|
||||
const result = await store.dispatch(fetchChannelsAndMembers());
|
||||
|
||||
expect(Object.keys(result)).not.toEqual(['error']);
|
||||
});
|
||||
});
|
||||
|
||||
test('should return correct channels, channel members and roles when under max limit', async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const perPage = Math.floor(CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE / 2);
|
||||
|
||||
const channels = [];
|
||||
for (let i = 1; i <= perPage; i++) {
|
||||
channels.push(fakeGQLChannelWithId(`team${i}`));
|
||||
}
|
||||
|
||||
const channelMembers = [];
|
||||
for (let i = 1; i <= perPage; i++) {
|
||||
channelMembers.push(fakeGQLChannelMember('user1', `channel${i}`, [role1]));
|
||||
}
|
||||
|
||||
nock(Client4.getGraphQLUrl()).
|
||||
post('').
|
||||
reply(200, {
|
||||
data: {
|
||||
channels: [...channels],
|
||||
channelMembers: [...channelMembers],
|
||||
},
|
||||
});
|
||||
|
||||
const result = await store.dispatch(fetchChannelsAndMembers());
|
||||
|
||||
expect(result.data.channels.length).toEqual(perPage);
|
||||
expect(result.data.channelMembers.length).toEqual(perPage);
|
||||
|
||||
// Since we added a single role to each channel member, we should have as many roles as channel members
|
||||
expect(result.data.roles.length).toEqual(perPage);
|
||||
});
|
||||
|
||||
test('should return correct channels, channel members, roles when responses span across multiple pages', async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const p1Page = CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE;
|
||||
const p2Page = CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE;
|
||||
const p3Page = Math.floor(CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE / 2);
|
||||
const responsesPerPage = [p1Page, p2Page, p3Page];
|
||||
const totalNumOfResponses = p1Page + p2Page + p3Page;
|
||||
|
||||
const channelsResponsePages: any[][] = [];
|
||||
const channelMembersResponsePages: any[][] = [];
|
||||
|
||||
responsesPerPage.forEach((responsePerPage, i) => {
|
||||
const channelResponsePerPage = [];
|
||||
const channelMemberResponsePerPage = [];
|
||||
for (let j = 1; j <= responsePerPage; j++) {
|
||||
const channel = fakeGQLChannelWithId(`team${i}_${j}`);
|
||||
channelResponsePerPage.push(channel);
|
||||
|
||||
const random0or1 = Math.round(Math.random());
|
||||
channelMemberResponsePerPage.push(fakeGQLChannelMember('user1', `channel${i}_${j}`, random0or1 === 0 ? [role1, role2] : [role2]));
|
||||
}
|
||||
|
||||
channelsResponsePages.push(channelResponsePerPage);
|
||||
channelMembersResponsePages.push(channelMemberResponsePerPage);
|
||||
});
|
||||
|
||||
responsesPerPage.forEach((_, i) => {
|
||||
nock(Client4.getGraphQLUrl()).
|
||||
post('').
|
||||
reply(200, {
|
||||
data: {
|
||||
channels: [...channelsResponsePages[i]],
|
||||
channelMembers: [...channelMembersResponsePages[i]],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
const result = await store.dispatch(fetchChannelsAndMembers());
|
||||
expect(result.data.channels.length).toEqual(totalNumOfResponses);
|
||||
expect(result.data.channelMembers.length).toEqual(totalNumOfResponses);
|
||||
});
|
||||
|
||||
test('should error out when pagination throws errors', async () => {
|
||||
const store = configureStore();
|
||||
|
||||
const p1Page = CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE;
|
||||
const p2Page = CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE; // so that page 3 will throw an error
|
||||
|
||||
const responsesPerPage = [p1Page, p2Page];
|
||||
|
||||
const channelsResponsePages: any[][] = [];
|
||||
const channelMembersResponsePages: any[][] = [];
|
||||
|
||||
responsesPerPage.forEach((responsePerPage, i) => {
|
||||
const channelResponsePerPage = [];
|
||||
const channelMemberResponsePerPage = [];
|
||||
for (let j = 1; j <= responsePerPage; j++) {
|
||||
const channel = fakeGQLChannelWithId(`team${i}_${j}`);
|
||||
channelResponsePerPage.push(channel);
|
||||
|
||||
const random0or1 = Math.round(Math.random());
|
||||
channelMemberResponsePerPage.push(fakeGQLChannelMember('user1', `channel${i}_${j}`, random0or1 === 0 ? [role1, role2] : [role2]));
|
||||
}
|
||||
|
||||
channelsResponsePages.push(channelResponsePerPage);
|
||||
channelMembersResponsePages.push(channelMemberResponsePerPage);
|
||||
});
|
||||
|
||||
responsesPerPage.forEach((_, i) => {
|
||||
nock(Client4.getGraphQLUrl()).
|
||||
post('').
|
||||
reply(200, {
|
||||
data: {
|
||||
channels: [...channelsResponsePages[i]],
|
||||
channelMembers: [...channelMembersResponsePages[i]],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Last page will throw an error
|
||||
nock(Client4.getGraphQLUrl()).
|
||||
post('').
|
||||
reply(200, {
|
||||
data: {},
|
||||
errors: [{message: 'some error'}],
|
||||
});
|
||||
|
||||
const result = await store.dispatch(fetchChannelsAndMembers());
|
||||
expect(Object.keys(result)).toEqual(['error']);
|
||||
});
|
||||
|
||||
function fakeGQLChannelWithId(teamId: Team['id']) {
|
||||
return Object.assign(TestHelper.fakeChannelWithId(teamId), {
|
||||
team: {id: teamId},
|
||||
});
|
||||
}
|
||||
|
||||
function fakeGQLChannelMember(userId: UserProfile['id'], channelId: Channel['id'], roles: Role[] = []) {
|
||||
return Object.assign(TestHelper.fakeChannelMember(userId, channelId), {
|
||||
channel: {
|
||||
id: channelId,
|
||||
},
|
||||
user: {
|
||||
id: userId,
|
||||
},
|
||||
roles: [...roles],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,33 +3,19 @@
|
||||
|
||||
import {batchActions} from 'redux-batched-actions';
|
||||
|
||||
import type {Channel, ChannelMembership, ServerChannel} from '@mattermost/types/channels';
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {ServerError} from '@mattermost/types/errors';
|
||||
import type {Role} from '@mattermost/types/roles';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {ChannelTypes, PreferenceTypes, RoleTypes} from 'mattermost-redux/action_types';
|
||||
import {PreferenceTypes} from 'mattermost-redux/action_types';
|
||||
import * as ChannelActions from 'mattermost-redux/actions/channels';
|
||||
import {logError} from 'mattermost-redux/actions/errors';
|
||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {getChannelByName, getUnreadChannelIds, getChannel} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getMyChannelMemberships} from 'mattermost-redux/selectors/entities/common';
|
||||
import {getCurrentTeamUrl, getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {ActionFunc} from 'mattermost-redux/types/actions';
|
||||
|
||||
import {
|
||||
getChannelsAndChannelMembersQueryString,
|
||||
transformToReceivedChannelsReducerPayload,
|
||||
transformToReceivedChannelMembersReducerPayload,
|
||||
CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE,
|
||||
} from 'actions/channel_queries';
|
||||
import type {
|
||||
ChannelsAndChannelMembersQueryResponseType,
|
||||
GraphQLChannel,
|
||||
GraphQLChannelMember} from 'actions/channel_queries';
|
||||
import {trackEvent} from 'actions/telemetry_actions.jsx';
|
||||
import {loadNewDMIfNeeded, loadNewGMIfNeeded, loadProfilesForSidebar} from 'actions/user_actions';
|
||||
|
||||
@@ -95,7 +81,7 @@ export function loadChannelsForCurrentUser(): ActionFunc {
|
||||
const state = getState();
|
||||
const unreads = getUnreadChannelIds(state);
|
||||
|
||||
await dispatch(ChannelActions.fetchMyChannelsAndMembersREST(getCurrentTeamId(state)));
|
||||
await dispatch(ChannelActions.fetchChannelsAndMembers(getCurrentTeamId(state)));
|
||||
for (const id of unreads) {
|
||||
const channel = getChannel(state, id);
|
||||
if (channel && channel.type === Constants.DM_CHANNEL) {
|
||||
@@ -191,89 +177,3 @@ export function muteChannel(userId: UserProfile['id'], channelId: Channel['id'])
|
||||
mark_unread: NotificationLevels.MENTION,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches channels and channel members with graphql and then dispatches the result to redux store.
|
||||
* @param teamId If team id is provided, only channels and channel members in that team will be fetched. Otherwise, all channels and all channel members will be fetched.
|
||||
*/
|
||||
export function fetchChannelsAndMembers(teamId: Team['id'] = ''): ActionFunc<{channels: ServerChannel[]; channelMembers: ChannelMembership[]}> {
|
||||
return async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
|
||||
let channelsResponse: GraphQLChannel[] = [];
|
||||
let channelMembersResponse: GraphQLChannelMember[] = [];
|
||||
|
||||
try {
|
||||
let channelsCursor = '';
|
||||
let channelMembersCursor = '';
|
||||
let page = 1;
|
||||
let responsesPerPage: number;
|
||||
|
||||
do {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const {data, errors} = await Client4.fetchWithGraphQL<ChannelsAndChannelMembersQueryResponseType>(getChannelsAndChannelMembersQueryString(teamId, channelsCursor, channelMembersCursor));
|
||||
|
||||
if (errors || !data) {
|
||||
throw new Error(`Failed to fetch channels and channel members at page ${page}`);
|
||||
} else if (data.channels.length === 0 || data.channelMembers.length === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Based on the fact that the number of channels and channel members returned by the server is the same
|
||||
responsesPerPage = data.channels.length;
|
||||
channelsCursor = data.channels[responsesPerPage - 1].cursor;
|
||||
channelMembersCursor = data.channelMembers[responsesPerPage - 1].cursor;
|
||||
page += 1;
|
||||
|
||||
channelsResponse = [...channelsResponse, ...data.channels];
|
||||
channelMembersResponse = [...channelMembersResponse, ...data.channelMembers];
|
||||
} while (responsesPerPage === CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE);
|
||||
} catch (error) {
|
||||
dispatch(logError(error as ServerError));
|
||||
return {error: error as ServerError};
|
||||
}
|
||||
|
||||
let roles: Role[] = [];
|
||||
channelMembersResponse.forEach((channelMembers) => {
|
||||
if (channelMembers?.roles?.length) {
|
||||
channelMembers.roles.forEach((role) => {
|
||||
roles = [...roles, role];
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const channels = transformToReceivedChannelsReducerPayload(channelsResponse);
|
||||
const channelMembers = transformToReceivedChannelMembersReducerPayload(channelMembersResponse, currentUserId);
|
||||
|
||||
const actions = [];
|
||||
if (teamId) {
|
||||
actions.push({
|
||||
type: ChannelTypes.RECEIVED_CHANNELS,
|
||||
teamId,
|
||||
data: channels,
|
||||
});
|
||||
actions.push({
|
||||
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBERS,
|
||||
data: channelMembers,
|
||||
});
|
||||
actions.push({
|
||||
type: RoleTypes.RECEIVED_ROLES,
|
||||
data: roles,
|
||||
});
|
||||
} else {
|
||||
actions.push({
|
||||
type: ChannelTypes.RECEIVED_ALL_CHANNELS,
|
||||
data: channels,
|
||||
});
|
||||
actions.push({
|
||||
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBERS,
|
||||
data: channelMembers,
|
||||
});
|
||||
}
|
||||
|
||||
await dispatch(batchActions(actions));
|
||||
|
||||
return {data: {channels, channelMembers, roles}};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {ChannelMembership, ServerChannel, ChannelType} from '@mattermost/types/channels';
|
||||
import type {Role} from '@mattermost/types/roles';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {convertRolesNamesArrayToString} from 'mattermost-redux/actions/roles';
|
||||
|
||||
export const CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE = 200;
|
||||
|
||||
type Cursor = {
|
||||
cursor: string;
|
||||
}
|
||||
|
||||
export type GraphQLChannel = Omit<ServerChannel, 'team_id'> & Cursor & {
|
||||
team: Team;
|
||||
};
|
||||
|
||||
export type GraphQLChannelMember = Omit<ChannelMembership, 'channel_id | user_id | roles | post_root_id'> & Cursor & {
|
||||
channel: ServerChannel;
|
||||
roles: Role[];
|
||||
};
|
||||
|
||||
export type ChannelsAndChannelMembersQueryResponseType = {
|
||||
data?: {
|
||||
channels: GraphQLChannel[];
|
||||
channelMembers: GraphQLChannelMember[];
|
||||
};
|
||||
errors?: unknown;
|
||||
}
|
||||
|
||||
const channelsFragment = `
|
||||
fragment channelsFragment on Channel {
|
||||
cursor
|
||||
id
|
||||
create_at: createAt
|
||||
update_at: updateAt
|
||||
delete_at: deleteAt
|
||||
team {
|
||||
id
|
||||
}
|
||||
type
|
||||
display_name: displayName
|
||||
name
|
||||
header
|
||||
purpose
|
||||
last_post_at: lastPostAt
|
||||
last_root_post_at: lastRootPostAt
|
||||
total_msg_count: totalMsgCount
|
||||
total_msg_count_root: totalMsgCountRoot
|
||||
creator_id: creatorId
|
||||
scheme_id: schemeId
|
||||
group_constrained: groupConstrained
|
||||
shared
|
||||
props
|
||||
policy_id: policyId
|
||||
}
|
||||
`;
|
||||
|
||||
const channelMembersFragment = `
|
||||
fragment channelMembersFragment on ChannelMember {
|
||||
cursor
|
||||
channel {
|
||||
id
|
||||
}
|
||||
roles {
|
||||
id
|
||||
name
|
||||
permissions
|
||||
}
|
||||
last_viewed_at: lastViewedAt
|
||||
msg_count: msgCount
|
||||
msg_count_root: msgCountRoot
|
||||
mention_count: mentionCount
|
||||
mention_count_root: mentionCountRoot
|
||||
urgent_mention_count: urgentMentionCount
|
||||
notify_props: notifyProps
|
||||
last_update_at: lastUpdateAt
|
||||
scheme_admin: schemeAdmin
|
||||
scheme_user: schemeUser
|
||||
}
|
||||
`;
|
||||
|
||||
const channelsAndChannelMembersQueryString = `
|
||||
query gqlWebChannelsAndChannelMembers($teamId: String, $perPage: Int!, $channelsCursor: String, $channelMembersCursor: String) {
|
||||
channels(userId: "me", teamId: $teamId, first: $perPage, after: $channelsCursor) {
|
||||
...channelsFragment
|
||||
}
|
||||
channelMembers(userId: "me", teamId: $teamId, first: $perPage, after: $channelMembersCursor) {
|
||||
...channelMembersFragment
|
||||
}
|
||||
}
|
||||
|
||||
${channelsFragment}
|
||||
${channelMembersFragment}
|
||||
`;
|
||||
|
||||
export function getChannelsAndChannelMembersQueryString(teamId: Team['id'] = '', channelsCursor: Cursor['cursor'] = '', channelMembersCursor: Cursor['cursor'] = '') {
|
||||
return JSON.stringify({
|
||||
query: channelsAndChannelMembersQueryString,
|
||||
operationName: 'gqlWebChannelsAndChannelMembers',
|
||||
variables: {
|
||||
teamId,
|
||||
perPage: CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE,
|
||||
channelsCursor,
|
||||
channelMembersCursor,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function transformToReceivedChannelsReducerPayload(
|
||||
channels: Partial<GraphQLChannel[]>,
|
||||
): ServerChannel[] {
|
||||
return channels.map((channel) => ({
|
||||
id: channel?.id ?? '',
|
||||
create_at: channel?.create_at ?? 0,
|
||||
update_at: channel?.update_at ?? 0,
|
||||
delete_at: channel?.delete_at ?? 0,
|
||||
team_id: channel?.team?.id ?? '',
|
||||
type: channel?.type ?? '' as ChannelType,
|
||||
display_name: channel?.display_name ?? '',
|
||||
name: channel?.name ?? '',
|
||||
header: channel?.header ?? '',
|
||||
purpose: channel?.purpose ?? '',
|
||||
last_post_at: channel?.last_post_at ?? 0,
|
||||
last_root_post_at: channel?.last_root_post_at ?? 0,
|
||||
total_msg_count: channel?.total_msg_count ?? 0,
|
||||
total_msg_count_root: channel?.total_msg_count_root ?? 0,
|
||||
creator_id: channel?.creator_id ?? '',
|
||||
scheme_id: channel?.scheme_id ?? '',
|
||||
group_constrained: channel?.group_constrained ?? false,
|
||||
shared: channel?.shared ?? undefined,
|
||||
props: channel && channel.props ? {...channel.props} : undefined,
|
||||
policy_id: channel?.policy_id ?? null,
|
||||
}));
|
||||
}
|
||||
|
||||
export function transformToReceivedChannelMembersReducerPayload(
|
||||
channelMembers: Partial<GraphQLChannelMember[]>,
|
||||
userId: UserProfile['id'],
|
||||
): ChannelMembership[] {
|
||||
return channelMembers.map((channelMember) => ({
|
||||
channel_id: channelMember?.channel?.id ?? '',
|
||||
user_id: userId,
|
||||
roles: convertRolesNamesArrayToString(channelMember?.roles ?? []),
|
||||
last_viewed_at: channelMember?.last_viewed_at ?? 0,
|
||||
msg_count: channelMember?.msg_count ?? 0,
|
||||
msg_count_root: channelMember?.msg_count_root ?? 0,
|
||||
mention_count: channelMember?.mention_count ?? 0,
|
||||
mention_count_root: channelMember?.mention_count_root ?? 0,
|
||||
urgent_mention_count: channelMember?.urgent_mention_count ?? 0,
|
||||
notify_props: channelMember && channelMember.notify_props ? {...channelMember.notify_props} : {},
|
||||
last_update_at: channelMember?.last_update_at ?? 0,
|
||||
scheme_admin: channelMember?.scheme_admin ?? false,
|
||||
scheme_user: channelMember?.scheme_user ?? false,
|
||||
}));
|
||||
}
|
||||
@@ -23,7 +23,7 @@ jest.mock('actions/views/lhs', () => ({
|
||||
}));
|
||||
|
||||
jest.mock('mattermost-redux/actions/users', () => ({
|
||||
loadMeREST: () => ({type: 'MOCK_RECEIVED_ME'}),
|
||||
loadMe: () => ({type: 'MOCK_RECEIVED_ME'}),
|
||||
}));
|
||||
|
||||
jest.mock('stores/redux_store', () => {
|
||||
|
||||
@@ -11,17 +11,17 @@ import type {UserProfile} from '@mattermost/types/users';
|
||||
import {ChannelTypes} from 'mattermost-redux/action_types';
|
||||
import {fetchAppBindings} from 'mattermost-redux/actions/apps';
|
||||
import {
|
||||
fetchMyChannelsAndMembersREST,
|
||||
fetchChannelsAndMembers,
|
||||
getChannelByNameAndTeamName,
|
||||
getChannelStats,
|
||||
selectChannel,
|
||||
} from 'mattermost-redux/actions/channels';
|
||||
import {logout, loadMe, loadMeREST} from 'mattermost-redux/actions/users';
|
||||
import {logout, loadMe} from 'mattermost-redux/actions/users';
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
import {appsEnabled} from 'mattermost-redux/selectors/entities/apps';
|
||||
import {getCurrentChannelStats, getCurrentChannelId, getMyChannelMember, getRedirectChannelNameForTeam, getChannelsNameMapInTeam, getAllDirectChannels, getChannelMessageCount} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getConfig, isPerformanceDebuggingEnabled} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getBool, getIsOnboardingFlowEnabled, isCollapsedThreadsEnabled, isGraphQLEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getBool, getIsOnboardingFlowEnabled, isCollapsedThreadsEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentTeamId, getMyTeams, getTeam, getMyTeamMember, getTeamMemberships, getActiveTeamsList} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentUser, getCurrentUserId, isFirstAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {ActionFunc, DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions';
|
||||
@@ -309,7 +309,7 @@ export async function getTeamRedirectChannelIfIsAccesible(user: UserProfile, tea
|
||||
let teamChannels = getChannelsNameMapInTeam(state, team.id);
|
||||
if (!teamChannels || Object.keys(teamChannels).length === 0) {
|
||||
// This should be executed in pretty limited scenarios (empty teams)
|
||||
await dispatch(fetchMyChannelsAndMembersREST(team.id)); // eslint-disable-line no-await-in-loop
|
||||
await dispatch(fetchChannelsAndMembers(team.id)); // eslint-disable-line no-await-in-loop
|
||||
state = getState();
|
||||
teamChannels = getChannelsNameMapInTeam(state, team.id);
|
||||
}
|
||||
@@ -356,11 +356,7 @@ export async function redirectUserToDefaultTeam() {
|
||||
const shouldLoadUser = Utils.isEmptyObject(getTeamMemberships(state)) || !user;
|
||||
const onboardingFlowEnabled = getIsOnboardingFlowEnabled(state);
|
||||
if (shouldLoadUser) {
|
||||
if (isGraphQLEnabled(state)) {
|
||||
await dispatch(loadMe());
|
||||
} else {
|
||||
await dispatch(loadMeREST());
|
||||
}
|
||||
await dispatch(loadMe());
|
||||
state = getState();
|
||||
user = getCurrentUser(state);
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ function initRequestCountingIfNecessary() {
|
||||
for (const entry of entries.getEntries()) {
|
||||
const url = entry.name;
|
||||
|
||||
if (!url.includes('/api/v4/') && !url.includes('/api/v5/')) {
|
||||
if (!url.includes('/api/v4/')) {
|
||||
// Don't count requests made outside of the MM server's API
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ jest.mock('mattermost-redux/actions/users', () => {
|
||||
const original = jest.requireActual('mattermost-redux/actions/users');
|
||||
return {
|
||||
...original,
|
||||
loadMeREST: () => ({type: 'MOCK_LOAD_ME'}),
|
||||
loadMe: () => ({type: 'MOCK_LOAD_ME'}),
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
|
||||
import {loadMe, loadMeREST} from 'mattermost-redux/actions/users';
|
||||
import {loadMe} from 'mattermost-redux/actions/users';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import type {DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions';
|
||||
|
||||
@@ -20,22 +20,15 @@ export type TranslationPluginFunction = (locale: string) => Translations
|
||||
|
||||
export function loadConfigAndMe() {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
const [{data: clientConfig}] = await Promise.all([
|
||||
await Promise.all([
|
||||
dispatch(getClientConfig()),
|
||||
dispatch(getLicenseConfig()),
|
||||
]);
|
||||
|
||||
const isGraphQLEnabled = clientConfig && clientConfig.FeatureFlagGraphQL === 'true';
|
||||
|
||||
let isMeLoaded = false;
|
||||
if (document.cookie.includes('MMUSERID=')) {
|
||||
if (isGraphQLEnabled) {
|
||||
const dataFromLoadMe = await dispatch(loadMe());
|
||||
isMeLoaded = dataFromLoadMe?.data ?? false;
|
||||
} else {
|
||||
const dataFromLoadMeREST = await dispatch(loadMeREST());
|
||||
isMeLoaded = dataFromLoadMeREST?.data ?? false;
|
||||
}
|
||||
const dataFromLoadMe = await dispatch(loadMe());
|
||||
isMeLoaded = dataFromLoadMe?.data ?? false;
|
||||
}
|
||||
|
||||
return {data: isMeLoaded};
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {History} from 'history';
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {GlobalState} from '@mattermost/types/store';
|
||||
|
||||
import {joinChannel, getChannelByNameAndTeamName, getChannelMember, markGroupChannelOpen, fetchMyChannelsAndMembersREST} from 'mattermost-redux/actions/channels';
|
||||
import {joinChannel, getChannelByNameAndTeamName, getChannelMember, markGroupChannelOpen, fetchChannelsAndMembers} from 'mattermost-redux/actions/channels';
|
||||
import {getUser, getUserByUsername, getUserByEmail} from 'mattermost-redux/actions/users';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {getChannelByName, getOtherChannels, getChannel, getChannelsNameMapInTeam, getRedirectChannelNameForTeam} from 'mattermost-redux/selectors/entities/channels';
|
||||
@@ -68,7 +68,7 @@ export function onChannelByIdentifierEnter({match, history}: MatchAndHistory): A
|
||||
dispatch(goToDirectChannelByUserId(match, history, identifier));
|
||||
break;
|
||||
case 'error':
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
break;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ export function goToChannelByChannelId(match: Match, history: History): ActionFu
|
||||
if (!channel || !member) {
|
||||
const dispatchResult = await dispatch(joinChannel(getCurrentUserId(state), teamObj!.id, channelId, ''));
|
||||
if ('error' in dispatchResult) {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleChannelJoinError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
return {data: undefined};
|
||||
}
|
||||
@@ -202,7 +202,7 @@ export function goToChannelByChannelName(match: Match, history: History): Action
|
||||
if (!channel) {
|
||||
const getChannelDispatchResult = await dispatch(getChannelByNameAndTeamName(team, channelName, true));
|
||||
if ('error' in getChannelDispatchResult || getChannelDispatchResult.data.delete_at === 0) {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleChannelJoinError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
return {data: undefined};
|
||||
}
|
||||
@@ -235,7 +235,7 @@ function goToDirectChannelByUsername(match: Match, history: History): ActionFunc
|
||||
if (!user) {
|
||||
const dispatchResult = await dispatch(getUserByUsername(username));
|
||||
if ('error' in dispatchResult) {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
return {data: undefined};
|
||||
}
|
||||
@@ -244,7 +244,7 @@ function goToDirectChannelByUsername(match: Match, history: History): ActionFunc
|
||||
|
||||
const directChannelDispatchRes = await dispatch(openDirectChannelToUserId(user.id));
|
||||
if ('error' in directChannelDispatchRes) {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
return {data: undefined};
|
||||
}
|
||||
@@ -264,7 +264,7 @@ export function goToDirectChannelByUserId(match: Match, history: History, userId
|
||||
if (!user) {
|
||||
const dispatchResult = await dispatch(getUser(userId));
|
||||
if ('error' in dispatchResult) {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
return {data: undefined};
|
||||
}
|
||||
@@ -287,7 +287,7 @@ export function goToDirectChannelByUserIds(match: Match, history: History): Acti
|
||||
if (!user) {
|
||||
const dispatchResult = await dispatch(getUser(userId));
|
||||
if ('error' in dispatchResult) {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
return {data: undefined};
|
||||
}
|
||||
@@ -310,7 +310,7 @@ export function goToDirectChannelByEmail(match: Match, history: History): Action
|
||||
if (!user) {
|
||||
const dispatchResult = await dispatch(getUserByEmail(email));
|
||||
if ('error' in dispatchResult) {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
return {data: undefined};
|
||||
}
|
||||
@@ -335,7 +335,7 @@ function goToGroupChannelByGroupId(match: Match, history: History): ActionFunc {
|
||||
if (!channel) {
|
||||
const dispatchResult = await dispatch(joinChannel(getCurrentUserId(state), teamObj!.id, '', groupId));
|
||||
if ('error' in dispatchResult) {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
||||
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||
return {data: undefined};
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ import {Link, useLocation, useHistory, Route} from 'react-router-dom';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {loadMe, loadMeREST} from 'mattermost-redux/actions/users';
|
||||
import {loadMe} from 'mattermost-redux/actions/users';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {RequestStatus} from 'mattermost-redux/constants';
|
||||
import {isCurrentLicenseCloud} from 'mattermost-redux/selectors/entities/cloud';
|
||||
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getIsOnboardingFlowEnabled, isGraphQLEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getIsOnboardingFlowEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getTeamByName, getMyTeamMember} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {DispatchFunc} from 'mattermost-redux/types/actions';
|
||||
@@ -112,7 +112,6 @@ const Login = ({onCustomizeHeader}: LoginProps) => {
|
||||
const experimentalPrimaryTeamMember = useSelector((state: GlobalState) => getMyTeamMember(state, experimentalPrimaryTeam?.id ?? ''));
|
||||
const onboardingFlowEnabled = useSelector(getIsOnboardingFlowEnabled);
|
||||
const isCloud = useSelector(isCurrentLicenseCloud);
|
||||
const graphQLEnabled = useSelector(isGraphQLEnabled);
|
||||
|
||||
const loginIdInput = useRef<HTMLInputElement>(null);
|
||||
const passwordInput = useRef<HTMLInputElement>(null);
|
||||
@@ -629,11 +628,7 @@ const Login = ({onCustomizeHeader}: LoginProps) => {
|
||||
};
|
||||
|
||||
const postSubmit = async (userProfile: UserProfile) => {
|
||||
if (graphQLEnabled) {
|
||||
await dispatch(loadMe());
|
||||
} else {
|
||||
await dispatch(loadMeREST());
|
||||
}
|
||||
await dispatch(loadMe());
|
||||
|
||||
// check for query params brought over from signup_user_complete
|
||||
const params = new URLSearchParams(search);
|
||||
|
||||
@@ -13,10 +13,10 @@ import type {ServerError} from '@mattermost/types/errors';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {getTeamInviteInfo} from 'mattermost-redux/actions/teams';
|
||||
import {createUser, loadMe, loadMeREST} from 'mattermost-redux/actions/users';
|
||||
import {createUser, loadMe} from 'mattermost-redux/actions/users';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getIsOnboardingFlowEnabled, isGraphQLEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getIsOnboardingFlowEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {DispatchFunc} from 'mattermost-redux/types/actions';
|
||||
import {isEmail} from 'mattermost-redux/utils/helpers';
|
||||
@@ -110,7 +110,6 @@ const Signup = ({onCustomizeHeader}: SignupProps) => {
|
||||
const loggedIn = Boolean(useSelector(getCurrentUserId));
|
||||
const onboardingFlowEnabled = useSelector(getIsOnboardingFlowEnabled);
|
||||
const usedBefore = useSelector((state: GlobalState) => (!inviteId && !loggedIn && token ? getGlobalItem(state, token, null) : undefined));
|
||||
const graphQLEnabled = useSelector(isGraphQLEnabled);
|
||||
|
||||
const emailInput = useRef<HTMLInputElement>(null);
|
||||
const nameInput = useRef<HTMLInputElement>(null);
|
||||
@@ -482,11 +481,7 @@ const Signup = ({onCustomizeHeader}: SignupProps) => {
|
||||
const postSignupSuccess = async () => {
|
||||
const redirectTo = (new URLSearchParams(search)).get('redirect_to');
|
||||
|
||||
if (graphQLEnabled) {
|
||||
await dispatch(loadMe());
|
||||
} else {
|
||||
await dispatch(loadMeREST());
|
||||
}
|
||||
await dispatch(loadMe());
|
||||
|
||||
if (token) {
|
||||
setGlobalItem(token, JSON.stringify({usedBefore: true}));
|
||||
|
||||
@@ -5,17 +5,16 @@ import type {ServerError} from '@mattermost/types/errors';
|
||||
import type {GetGroupsForUserParams, GetGroupsParams} from '@mattermost/types/groups';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
|
||||
import {fetchMyChannelsAndMembersREST} from 'mattermost-redux/actions/channels';
|
||||
import {fetchChannelsAndMembers} from 'mattermost-redux/actions/channels';
|
||||
import {logError} from 'mattermost-redux/actions/errors';
|
||||
import {getGroups, getAllGroupsAssociatedToChannelsInTeam, getAllGroupsAssociatedToTeam, getGroupsByUserIdPaginated} from 'mattermost-redux/actions/groups';
|
||||
import {forceLogoutIfNecessary} from 'mattermost-redux/actions/helpers';
|
||||
import {getTeamByName, selectTeam} from 'mattermost-redux/actions/teams';
|
||||
import {getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||
import {isCustomGroupsEnabled, isGraphQLEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {isCustomGroupsEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {ActionFunc} from 'mattermost-redux/types/actions';
|
||||
|
||||
import {fetchChannelsAndMembers} from 'actions/channel_actions';
|
||||
import {loadStatusesForChannelAndSidebar} from 'actions/status_actions';
|
||||
import {addUserToTeam} from 'actions/team_actions';
|
||||
import LocalStorageStore from 'stores/local_storage_store';
|
||||
@@ -30,13 +29,8 @@ export function initializeTeam(team: Team): ActionFunc<Team, ServerError> {
|
||||
const currentUser = getCurrentUser(state);
|
||||
LocalStorageStore.setPreviousTeamId(currentUser.id, team.id);
|
||||
|
||||
const graphQLEnabled = isGraphQLEnabled(state);
|
||||
try {
|
||||
if (graphQLEnabled) {
|
||||
await dispatch(fetchChannelsAndMembers(team.id));
|
||||
} else {
|
||||
await dispatch(fetchMyChannelsAndMembersREST(team.id));
|
||||
}
|
||||
await dispatch(fetchChannelsAndMembers(team.id));
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error as ServerError, dispatch, getState);
|
||||
dispatch(logError(error as ServerError));
|
||||
|
||||
@@ -5,14 +5,12 @@ import {connect} from 'react-redux';
|
||||
import type {ConnectedProps} from 'react-redux';
|
||||
import type {RouteComponentProps} from 'react-router-dom';
|
||||
|
||||
import {fetchAllMyTeamsChannelsAndChannelMembersREST, fetchMyChannelsAndMembersREST} from 'mattermost-redux/actions/channels';
|
||||
import {fetchAllMyTeamsChannelsAndChannelMembersREST, fetchChannelsAndMembers} from 'mattermost-redux/actions/channels';
|
||||
import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getLicense, getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {isGraphQLEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentTeamId, getMyTeams} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {fetchChannelsAndMembers} from 'actions/channel_actions';
|
||||
import {markChannelAsReadOnFocus} from 'actions/views/channel';
|
||||
import {getSelectedThreadIdInCurrentTeam} from 'selectors/views/threads';
|
||||
|
||||
@@ -36,7 +34,6 @@ function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
|
||||
const config = getConfig(state);
|
||||
const currentUser = getCurrentUser(state);
|
||||
const plugins = state.plugins.components.NeedsTeamComponent;
|
||||
const graphQLEnabled = isGraphQLEnabled(state);
|
||||
const disableRefetchingOnBrowserFocus = config.DisableRefetchingOnBrowserFocus === 'true';
|
||||
|
||||
return {
|
||||
@@ -46,14 +43,12 @@ function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
|
||||
plugins,
|
||||
selectedThreadId: getSelectedThreadIdInCurrentTeam(state),
|
||||
mfaRequired: checkIfMFARequired(currentUser, license, config, ownProps.match.url),
|
||||
graphQLEnabled,
|
||||
disableRefetchingOnBrowserFocus,
|
||||
};
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchChannelsAndMembers,
|
||||
fetchMyChannelsAndMembersREST,
|
||||
fetchAllMyTeamsChannelsAndChannelMembersREST,
|
||||
markChannelAsReadOnFocus,
|
||||
initializeTeam,
|
||||
|
||||
@@ -53,17 +53,13 @@ function TeamController(props: Props) {
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchInitialChannels() {
|
||||
if (props.graphQLEnabled) {
|
||||
await props.fetchChannelsAndMembers();
|
||||
} else {
|
||||
await props.fetchAllMyTeamsChannelsAndChannelMembersREST();
|
||||
}
|
||||
await props.fetchAllMyTeamsChannelsAndChannelMembersREST();
|
||||
|
||||
setInitialChannelsLoaded(true);
|
||||
}
|
||||
|
||||
fetchInitialChannels();
|
||||
}, [props.graphQLEnabled]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const wakeUpIntervalId = setInterval(() => {
|
||||
@@ -95,11 +91,7 @@ function TeamController(props: Props) {
|
||||
if (!props.disableRefetchingOnBrowserFocus) {
|
||||
const currentTime = Date.now();
|
||||
if ((currentTime - blurTime.current) > UNREAD_CHECK_TIME_MILLISECONDS && props.currentTeamId) {
|
||||
if (props.graphQLEnabled) {
|
||||
props.fetchChannelsAndMembers(props.currentTeamId);
|
||||
} else {
|
||||
props.fetchMyChannelsAndMembersREST(props.currentTeamId);
|
||||
}
|
||||
props.fetchChannelsAndMembers(props.currentTeamId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,7 +124,7 @@ function TeamController(props: Props) {
|
||||
window.removeEventListener('blur', handleBlur);
|
||||
window.removeEventListener('keydown', handleKeydown);
|
||||
};
|
||||
}, [props.selectedThreadId, props.graphQLEnabled, props.currentChannelId, props.currentTeamId]);
|
||||
}, [props.selectedThreadId, props.currentChannelId, props.currentTeamId]);
|
||||
|
||||
// Effect runs on mount, adds active state to window
|
||||
useEffect(() => {
|
||||
|
||||
@@ -9,7 +9,7 @@ import {UserTypes} from 'mattermost-redux/action_types';
|
||||
import * as Actions from 'mattermost-redux/actions/channels';
|
||||
import {createIncomingHook, createOutgoingHook} from 'mattermost-redux/actions/integrations';
|
||||
import {addUserToTeam} from 'mattermost-redux/actions/teams';
|
||||
import {getProfilesByIds, loadMeREST} from 'mattermost-redux/actions/users';
|
||||
import {getProfilesByIds, loadMe} from 'mattermost-redux/actions/users';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||
import {getPreferenceKey} from 'mattermost-redux/utils/preference_utils';
|
||||
@@ -185,7 +185,7 @@ describe('Actions.Channels', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users/ids').
|
||||
@@ -358,7 +358,7 @@ describe('Actions.Channels', () => {
|
||||
expect(myMembers[TestHelper.basicChannel!.id]).toBeTruthy();
|
||||
});
|
||||
|
||||
it('fetchMyChannelsAndMembersREST', async () => {
|
||||
it('fetchChannelsAndMembers', async () => {
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
query(true).
|
||||
@@ -386,7 +386,7 @@ describe('Actions.Channels', () => {
|
||||
get(`/users/me/teams/${TestHelper.basicTeam!.id}/channels/members`).
|
||||
reply(200, [{user_id: TestHelper.basicUser!.id, roles: 'channel_user', channel_id: directChannel.id}, TestHelper.basicChannelMember]);
|
||||
|
||||
await store.dispatch(Actions.fetchMyChannelsAndMembersREST(TestHelper.basicTeam!.id));
|
||||
await store.dispatch(Actions.fetchChannelsAndMembers(TestHelper.basicTeam!.id));
|
||||
|
||||
const {channels, channelsInTeam, myMembers} = store.getState().entities.channels;
|
||||
expect(channels).toBeTruthy();
|
||||
@@ -412,7 +412,7 @@ describe('Actions.Channels', () => {
|
||||
get(`/users/me/teams/${TestHelper.basicTeam!.id}/channels/members`).
|
||||
reply(200, [TestHelper.basicChannelMember]);
|
||||
|
||||
await store.dispatch(Actions.fetchMyChannelsAndMembersREST(TestHelper.basicTeam!.id));
|
||||
await store.dispatch(Actions.fetchChannelsAndMembers(TestHelper.basicTeam!.id));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
put(`/channels/${TestHelper.basicChannel!.id}/members/${TestHelper.basicUser!.id}/notify_props`).
|
||||
@@ -475,7 +475,7 @@ describe('Actions.Channels', () => {
|
||||
get(`/users/me/teams/${TestHelper.basicTeam!.id}/channels/members`).
|
||||
reply(200, [{user_id: TestHelper.basicUser!.id, roles: 'channel_user', channel_id: secondChannel.id}, TestHelper.basicChannelMember]);
|
||||
|
||||
await store.dispatch(Actions.fetchMyChannelsAndMembersREST(TestHelper.basicTeam!.id));
|
||||
await store.dispatch(Actions.fetchChannelsAndMembers(TestHelper.basicTeam!.id));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
@@ -579,7 +579,7 @@ describe('Actions.Channels', () => {
|
||||
get(`/users/me/teams/${TestHelper.basicTeam!.id}/channels/members`).
|
||||
reply(200, [{user_id: TestHelper.basicUser!.id, roles: 'channel_user', channel_id: secondChannel.id}, TestHelper.basicChannelMember]);
|
||||
|
||||
await store.dispatch(Actions.fetchMyChannelsAndMembersREST(TestHelper.basicTeam!.id));
|
||||
await store.dispatch(Actions.fetchChannelsAndMembers(TestHelper.basicTeam!.id));
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/hooks/incoming').
|
||||
@@ -1900,7 +1900,7 @@ describe('Actions.Channels', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/channels').
|
||||
@@ -1933,7 +1933,7 @@ describe('Actions.Channels', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/channels').
|
||||
|
||||
@@ -497,7 +497,7 @@ export function getChannelTimezones(channelId: string): ActionFunc {
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchMyChannelsAndMembersREST(teamId: string): ActionFunc<{channels: ServerChannel[]; channelMembers: ChannelMembership[]}> {
|
||||
export function fetchChannelsAndMembers(teamId: string): ActionFunc<{channels: ServerChannel[]; channelMembers: ChannelMembership[]}> {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let channels;
|
||||
let channelMembers;
|
||||
@@ -1503,7 +1503,7 @@ export default {
|
||||
patchChannel,
|
||||
updateChannelNotifyProps,
|
||||
getChannel,
|
||||
fetchMyChannelsAndMembersREST,
|
||||
fetchChannelsAndMembers,
|
||||
getChannelTimezones,
|
||||
getChannelMembersByIds,
|
||||
leaveChannel,
|
||||
|
||||
@@ -12,7 +12,7 @@ import {PostTypes, UserTypes} from 'mattermost-redux/action_types';
|
||||
import {getChannelStats} from 'mattermost-redux/actions/channels';
|
||||
import {createCustomEmoji} from 'mattermost-redux/actions/emojis';
|
||||
import * as Actions from 'mattermost-redux/actions/posts';
|
||||
import {loadMeREST} from 'mattermost-redux/actions/users';
|
||||
import {loadMe} from 'mattermost-redux/actions/users';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import type {ActionResult, GetStateFunc} from 'mattermost-redux/types/actions';
|
||||
import {getPreferenceKey} from 'mattermost-redux/utils/preference_utils';
|
||||
@@ -274,7 +274,7 @@ describe('Actions.Posts', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/posts').
|
||||
@@ -368,7 +368,7 @@ describe('Actions.Posts', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/posts').
|
||||
@@ -1015,7 +1015,7 @@ describe('Actions.Posts', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/posts').
|
||||
@@ -1048,7 +1048,7 @@ describe('Actions.Posts', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/posts').
|
||||
@@ -1221,7 +1221,7 @@ describe('Actions.Posts', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/posts').
|
||||
@@ -1250,7 +1250,7 @@ describe('Actions.Posts', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/posts').
|
||||
@@ -1284,7 +1284,7 @@ describe('Actions.Posts', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await store.dispatch(loadMeREST());
|
||||
await store.dispatch(loadMe());
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/posts').
|
||||
|
||||
@@ -5,7 +5,7 @@ import nock from 'nock';
|
||||
|
||||
import {UserTypes} from 'mattermost-redux/action_types';
|
||||
import * as Actions from 'mattermost-redux/actions/preferences';
|
||||
import {loadMeREST} from 'mattermost-redux/actions/users';
|
||||
import {loadMe} from 'mattermost-redux/actions/users';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
@@ -203,7 +203,7 @@ describe('Actions.Preferences', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await loadMeREST()(store.dispatch, store.getState);
|
||||
await loadMe()(store.dispatch, store.getState);
|
||||
|
||||
// Test that a new preference is created if none exists
|
||||
nock(Client4.getUsersRoute()).
|
||||
@@ -303,7 +303,7 @@ describe('Actions.Preferences', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await loadMeREST()(store.dispatch, store.getState);
|
||||
await loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const theme = {
|
||||
type: 'Mattermost Dark',
|
||||
|
||||
@@ -104,7 +104,3 @@ export function loadRolesIfNeeded(roles: Iterable<string>): ActionFunc {
|
||||
return {data: state.entities.roles.roles};
|
||||
};
|
||||
}
|
||||
|
||||
export function convertRolesNamesArrayToString(roles: Role[]): string {
|
||||
return roles.map((role) => role.name!).join(' ') ?? '';
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {Team} from '@mattermost/types/teams';
|
||||
|
||||
import {GeneralTypes, UserTypes} from 'mattermost-redux/action_types';
|
||||
import * as Actions from 'mattermost-redux/actions/teams';
|
||||
import {loadMeREST} from 'mattermost-redux/actions/users';
|
||||
import {loadMe} from 'mattermost-redux/actions/users';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {General, RequestStatus} from 'mattermost-redux/constants';
|
||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||
@@ -55,7 +55,7 @@ describe('Actions.Teams', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await loadMeREST()(store.dispatch, store.getState);
|
||||
await loadMe()(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get('/users/me/teams').
|
||||
@@ -741,7 +741,7 @@ describe('Actions.Teams', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await loadMeREST()(store.dispatch, store.getState);
|
||||
await loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const team = TestHelper.basicTeam;
|
||||
const imageData = fs.createReadStream('src/packages/mattermost-redux/test/assets/images/test.png');
|
||||
@@ -759,7 +759,7 @@ describe('Actions.Teams', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await loadMeREST()(store.dispatch, store.getState);
|
||||
await loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const team = TestHelper.basicTeam;
|
||||
|
||||
@@ -776,7 +776,7 @@ describe('Actions.Teams', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await loadMeREST()(store.dispatch, store.getState);
|
||||
await loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const schemeId = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
|
||||
const {id} = TestHelper.basicTeam!;
|
||||
|
||||
@@ -89,7 +89,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users/me/terms_of_service').
|
||||
@@ -115,7 +115,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users/me/terms_of_service').
|
||||
@@ -661,7 +661,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users/login').
|
||||
@@ -717,7 +717,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users/login').
|
||||
@@ -854,7 +854,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const currentUser = state.entities.users.profiles[state.entities.users.currentUserId];
|
||||
@@ -905,7 +905,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
const currentUserId = state.entities.users.currentUserId;
|
||||
@@ -953,7 +953,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -974,7 +974,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -995,7 +995,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const beforeTime = new Date().getTime();
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
@@ -1090,7 +1090,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const testImageData = fs.createReadStream('src/packages/mattermost-redux/test/assets/images/test.png');
|
||||
|
||||
@@ -1115,7 +1115,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -1182,7 +1182,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -1213,7 +1213,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -1249,7 +1249,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -1286,7 +1286,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -1323,7 +1323,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -1371,7 +1371,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -1426,7 +1426,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
@@ -1481,7 +1481,7 @@ describe('Actions.Users', () => {
|
||||
store.dispatch({
|
||||
type: UserTypes.LOGIN_SUCCESS,
|
||||
});
|
||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
||||
await Actions.loadMe()(store.dispatch, store.getState);
|
||||
|
||||
const currentUserId = store.getState().entities.users.currentUserId;
|
||||
|
||||
|
||||
@@ -4,29 +4,16 @@
|
||||
import type {AnyAction} from 'redux';
|
||||
import {batchActions} from 'redux-batched-actions';
|
||||
|
||||
import type {ClientConfig, ClientLicense} from '@mattermost/types/config';
|
||||
import type {ServerError} from '@mattermost/types/errors';
|
||||
import type {PreferenceType} from '@mattermost/types/preferences';
|
||||
import type {Role} from '@mattermost/types/roles';
|
||||
import type {Team, TeamMembership} from '@mattermost/types/teams';
|
||||
import type {UserProfile, UserStatus, GetFilteredUsersStatsOpts, UsersStats, UserCustomStatus} from '@mattermost/types/users';
|
||||
|
||||
import {UserTypes, AdminTypes, GeneralTypes, PreferenceTypes, TeamTypes, RoleTypes} from 'mattermost-redux/action_types';
|
||||
import {UserTypes, AdminTypes} from 'mattermost-redux/action_types';
|
||||
import {logError} from 'mattermost-redux/actions/errors';
|
||||
import {setServerVersion, getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
|
||||
import {bindClientFunc, forceLogoutIfNecessary, debounce} from 'mattermost-redux/actions/helpers';
|
||||
import {getMyPreferences} from 'mattermost-redux/actions/preferences';
|
||||
import {loadRolesIfNeeded} from 'mattermost-redux/actions/roles';
|
||||
import {getMyTeams, getMyTeamMembers, getMyTeamUnreads} from 'mattermost-redux/actions/teams';
|
||||
import {
|
||||
currentUserInfoQuery,
|
||||
transformToRecievedMeReducerPayload,
|
||||
transformToRecievedTeamsListReducerPayload,
|
||||
transformToReceivedUserAndTeamRolesReducerPayload,
|
||||
transformToRecievedMyTeamMembersReducerPayload,
|
||||
} from 'mattermost-redux/actions/users_queries';
|
||||
import type {
|
||||
CurrentUserInfoQueryResponseType} from 'mattermost-redux/actions/users_queries';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
import {getServerVersion} from 'mattermost-redux/selectors/entities/general';
|
||||
@@ -67,7 +54,7 @@ export function createUser(user: UserProfile, token: string, inviteId: string, r
|
||||
};
|
||||
}
|
||||
|
||||
export function loadMeREST(): ActionFunc {
|
||||
export function loadMe(): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
// Sometimes the server version is set in one or the other
|
||||
const serverVersion = getState().entities.general.serverVersion || Client4.getServerVersion();
|
||||
@@ -94,76 +81,6 @@ export function loadMeREST(): ActionFunc {
|
||||
};
|
||||
}
|
||||
|
||||
export function loadMe(): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
// Sometimes the server version is set in one or the other
|
||||
const serverVersion = getState().entities.general.serverVersion || Client4.getServerVersion();
|
||||
dispatch(setServerVersion(serverVersion));
|
||||
|
||||
let clientLicense: ClientLicense;
|
||||
let clientConfig: ClientConfig;
|
||||
let userProfile: UserProfile;
|
||||
let roles: Role[];
|
||||
let preferences: PreferenceType[];
|
||||
let teams: Team[];
|
||||
let teamMemberships: TeamMembership[];
|
||||
|
||||
try {
|
||||
const {data, errors} = await Client4.fetchWithGraphQL<CurrentUserInfoQueryResponseType>(currentUserInfoQuery);
|
||||
|
||||
if (errors || !data) {
|
||||
throw new Error('Error returned in fetching current user info with graphQL');
|
||||
}
|
||||
|
||||
clientLicense = Object.assign({}, data.license);
|
||||
clientConfig = Object.assign({}, data.config);
|
||||
userProfile = transformToRecievedMeReducerPayload(data.user);
|
||||
roles = transformToReceivedUserAndTeamRolesReducerPayload(data.user.roles, data.teamMembers);
|
||||
preferences = [...data.user.preferences];
|
||||
teams = transformToRecievedTeamsListReducerPayload(data.teamMembers);
|
||||
teamMemberships = transformToRecievedMyTeamMembersReducerPayload(data.teamMembers, data.user.id);
|
||||
} catch (error) {
|
||||
dispatch(logError(error as ServerError));
|
||||
return {error: error as ServerError};
|
||||
}
|
||||
|
||||
dispatch(
|
||||
batchActions([
|
||||
{
|
||||
type: GeneralTypes.CLIENT_LICENSE_RECEIVED,
|
||||
data: clientLicense,
|
||||
},
|
||||
{
|
||||
type: GeneralTypes.CLIENT_CONFIG_RECEIVED,
|
||||
data: clientConfig,
|
||||
},
|
||||
{
|
||||
type: UserTypes.RECEIVED_ME,
|
||||
data: userProfile,
|
||||
},
|
||||
{
|
||||
type: RoleTypes.RECEIVED_ROLES,
|
||||
data: roles,
|
||||
},
|
||||
{
|
||||
type: PreferenceTypes.RECEIVED_ALL_PREFERENCES,
|
||||
data: preferences,
|
||||
},
|
||||
{
|
||||
type: TeamTypes.RECEIVED_TEAMS_LIST,
|
||||
data: teams,
|
||||
},
|
||||
{
|
||||
type: TeamTypes.RECEIVED_MY_TEAM_MEMBERS,
|
||||
data: teamMemberships,
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
}
|
||||
|
||||
export function logout(): ActionFunc {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
dispatch({type: UserTypes.LOGOUT_REQUEST, data: null});
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {ClientConfig, ClientLicense} from '@mattermost/types/config';
|
||||
import type {PreferenceType} from '@mattermost/types/preferences';
|
||||
import type {Role} from '@mattermost/types/roles';
|
||||
import type {Team, TeamMembership} from '@mattermost/types/teams';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {convertRolesNamesArrayToString} from 'mattermost-redux/actions/roles';
|
||||
|
||||
const currentUserInfoQueryString = `
|
||||
query gqlWebCurrentUserInfo {
|
||||
config
|
||||
license
|
||||
user(id: "me") {
|
||||
id
|
||||
create_at: createAt
|
||||
delete_at: deleteAt
|
||||
update_at: updateAt
|
||||
username
|
||||
auth_service: authService
|
||||
email
|
||||
nickname
|
||||
first_name: firstName
|
||||
last_name: lastName
|
||||
position
|
||||
roles {
|
||||
id
|
||||
name
|
||||
permissions
|
||||
}
|
||||
props
|
||||
notify_props: notifyProps
|
||||
last_picture_update: lastPictureUpdate
|
||||
last_password_update: lastPasswordUpdate
|
||||
terms_of_service_id: termsOfServiceId
|
||||
terms_of_service_create_at: termsOfServiceCreateAt
|
||||
locale
|
||||
timezone
|
||||
remote_id: remoteId
|
||||
preferences {
|
||||
name
|
||||
user_id: userId
|
||||
category
|
||||
value
|
||||
}
|
||||
is_bot: isBot
|
||||
bot_description: botDescription
|
||||
mfa_active: mfaActive
|
||||
}
|
||||
teamMembers(userId: "me") {
|
||||
team {
|
||||
id
|
||||
display_name: displayName
|
||||
name
|
||||
create_at: createAt
|
||||
update_at: updateAt
|
||||
delete_at: deleteAt
|
||||
description
|
||||
email
|
||||
type
|
||||
company_name: companyName
|
||||
allowed_domains: allowedDomains
|
||||
invite_id: inviteId
|
||||
last_team_icon_update: lastTeamIconUpdate
|
||||
group_constrained: groupConstrained
|
||||
allow_open_invite: allowOpenInvite
|
||||
scheme_id: schemeId
|
||||
policy_id: policyId
|
||||
}
|
||||
roles {
|
||||
id
|
||||
name
|
||||
permissions
|
||||
}
|
||||
delete_at: deleteAt
|
||||
scheme_guest: schemeGuest
|
||||
scheme_user: schemeUser
|
||||
scheme_admin: schemeAdmin
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const currentUserInfoQuery = JSON.stringify({query: currentUserInfoQueryString, operationName: 'gqlWebCurrentUserInfo'});
|
||||
|
||||
type GraphQLUser = UserProfile & {
|
||||
roles: Role[];
|
||||
preferences: PreferenceType[];
|
||||
};
|
||||
|
||||
type GraphQLTeamMember = {
|
||||
team: Team;
|
||||
user: UserProfile;
|
||||
roles: Role[];
|
||||
delete_at: number;
|
||||
scheme_guest: boolean;
|
||||
scheme_user: boolean;
|
||||
scheme_admin: boolean;
|
||||
}
|
||||
|
||||
export type CurrentUserInfoQueryResponseType = {
|
||||
data?: {
|
||||
user: GraphQLUser;
|
||||
config: ClientConfig;
|
||||
license: ClientLicense;
|
||||
teamMembers: GraphQLTeamMember[];
|
||||
};
|
||||
errors?: unknown;
|
||||
};
|
||||
|
||||
export function transformToReceivedUserAndTeamRolesReducerPayload(
|
||||
userRoles: GraphQLUser['roles'],
|
||||
teamMembers: GraphQLTeamMember[]): Role[] {
|
||||
let roles: Role[] = [...userRoles];
|
||||
|
||||
teamMembers.forEach((teamMember) => {
|
||||
if (teamMember.roles) {
|
||||
roles = [...roles, ...teamMember.roles];
|
||||
}
|
||||
});
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
export function transformToRecievedMeReducerPayload(user: GraphQLUser): UserProfile {
|
||||
return {
|
||||
...user,
|
||||
position: user?.position ?? '',
|
||||
roles: convertRolesNamesArrayToString(user?.roles ?? []),
|
||||
};
|
||||
}
|
||||
|
||||
export function transformToRecievedTeamsListReducerPayload(teamsMembers: GraphQLTeamMember[]): Team[] {
|
||||
return teamsMembers.map((teamMember) => ({...teamMember.team}));
|
||||
}
|
||||
|
||||
export function transformToRecievedMyTeamMembersReducerPayload(
|
||||
teamsMembers: Partial<GraphQLTeamMember[]>,
|
||||
userId: UserProfile['id'],
|
||||
): TeamMembership[] {
|
||||
return teamsMembers.map((teamMember) => ({
|
||||
team_id: teamMember?.team?.id ?? '',
|
||||
user_id: userId || '',
|
||||
delete_at: teamMember?.delete_at ?? 0,
|
||||
roles: convertRolesNamesArrayToString(teamMember?.roles ?? []),
|
||||
scheme_admin: teamMember?.scheme_admin ?? false,
|
||||
scheme_guest: teamMember?.scheme_guest ?? false,
|
||||
scheme_user: teamMember?.scheme_user ?? false,
|
||||
|
||||
// Remove these fields once webapp deprecates getting unread counts from teams
|
||||
// below fields arent included in the response but were inside of TeamMembership api types
|
||||
mention_count: 0,
|
||||
mention_count_root: 0,
|
||||
msg_count: 0,
|
||||
msg_count_root: 0,
|
||||
thread_count: 0,
|
||||
thread_mention_count: 0,
|
||||
}));
|
||||
}
|
||||
@@ -244,10 +244,6 @@ export function getIsOnboardingFlowEnabled(state: GlobalState): boolean {
|
||||
return getConfig(state).EnableOnboardingFlow === 'true';
|
||||
}
|
||||
|
||||
export function isGraphQLEnabled(state: GlobalState): boolean {
|
||||
return getFeatureFlagValue(state, 'GraphQL') === 'true';
|
||||
}
|
||||
|
||||
export function getHasDismissedSystemConsoleLimitReached(state: GlobalState): boolean {
|
||||
return getBool(state, Preferences.CATEGORY_UPGRADE_CLOUD, Preferences.SYSTEM_CONSOLE_LIMIT_REACHED, false);
|
||||
}
|
||||
|
||||
@@ -41,15 +41,6 @@ describe('Client4', () => {
|
||||
expect(client.serverVersion).toEqual('5.3.0.5.3.0.abc123');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchWithGraphQL', () => {
|
||||
test('Should have correct graphql url', async () => {
|
||||
const client = new Client4();
|
||||
client.setUrl('http://mattermost.example.com');
|
||||
|
||||
expect(client.getGraphQLUrl()).toEqual('http://mattermost.example.com/api/v5/graphql');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ClientError', () => {
|
||||
|
||||
@@ -159,8 +159,6 @@ const PER_PAGE_DEFAULT = 60;
|
||||
export const DEFAULT_LIMIT_BEFORE = 30;
|
||||
export const DEFAULT_LIMIT_AFTER = 30;
|
||||
|
||||
const GRAPHQL_ENDPOINT = '/api/v5/graphql';
|
||||
|
||||
export default class Client4 {
|
||||
logToConsole = false;
|
||||
serverVersion = '';
|
||||
@@ -194,10 +192,6 @@ export default class Client4 {
|
||||
return this.getUrl() + baseUrl;
|
||||
}
|
||||
|
||||
getGraphQLUrl() {
|
||||
return `${this.url}${GRAPHQL_ENDPOINT}`;
|
||||
}
|
||||
|
||||
setUrl(url: string) {
|
||||
this.url = url;
|
||||
}
|
||||
@@ -4049,15 +4043,6 @@ export default class Client4 {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param query string query of graphQL, pass the json stringified version of the query
|
||||
* eg. const query = JSON.stringify({query: `{license, config}`, operationName: 'queryForLicenseAndConfig'});
|
||||
* client4.fetchWithGraphQL(query);
|
||||
*/
|
||||
fetchWithGraphQL = async <DataResponse>(query: string) => {
|
||||
return this.doFetch<DataResponse>(this.getGraphQLUrl(), {method: 'post', body: query});
|
||||
}
|
||||
|
||||
getCallsChannelState = (channelId: string) => {
|
||||
return this.doFetch<{enabled: boolean; id: string}>(
|
||||
`${this.url}/plugins/${'com.mattermost.calls'}/${channelId}`,
|
||||
|
||||
@@ -120,7 +120,6 @@ export type ClientConfig = {
|
||||
FileLevel: string;
|
||||
FeatureFlagAppsEnabled: string;
|
||||
FeatureFlagCallsEnabled: string;
|
||||
FeatureFlagGraphQL: string;
|
||||
ForgotPasswordLink: string;
|
||||
GiphySdkKey: string;
|
||||
GoogleDeveloperKey: string;
|
||||
|
||||
Ссылка в новой задаче
Block a user