[MM-54879] Goodbye, GraphQL -- Regards Webapp (#24850)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
cd4d220a21
Коммит
760dfe41f9
@@ -694,7 +694,6 @@ const defaultServerConfig: AdminConfig = {
|
|||||||
PermalinkPreviews: false,
|
PermalinkPreviews: false,
|
||||||
CallsEnabled: true,
|
CallsEnabled: true,
|
||||||
NormalizeLdapDNs: false,
|
NormalizeLdapDNs: false,
|
||||||
GraphQL: false,
|
|
||||||
PostPriority: false,
|
PostPriority: false,
|
||||||
WysiwygEditor: false,
|
WysiwygEditor: false,
|
||||||
OnboardingTourTips: true,
|
OnboardingTourTips: true,
|
||||||
|
|||||||
@@ -1,27 +1,15 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// 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 {
|
import {
|
||||||
searchMoreChannels,
|
searchMoreChannels,
|
||||||
addUsersToChannel,
|
addUsersToChannel,
|
||||||
openDirectChannelToUserId,
|
openDirectChannelToUserId,
|
||||||
openGroupChannelToUserIds,
|
openGroupChannelToUserIds,
|
||||||
loadChannelsForCurrentUser, fetchChannelsAndMembers,
|
loadChannelsForCurrentUser,
|
||||||
} from 'actions/channel_actions';
|
} from 'actions/channel_actions';
|
||||||
import {CHANNELS_AND_CHANNEL_MEMBERS_PER_PAGE} from 'actions/channel_queries';
|
|
||||||
import {loadProfilesForSidebar} from 'actions/user_actions';
|
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';
|
import mockStore from 'tests/test_store';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
@@ -116,7 +104,7 @@ const initialState = {
|
|||||||
const realDateNow = Date.now;
|
const realDateNow = Date.now;
|
||||||
|
|
||||||
jest.mock('mattermost-redux/actions/channels', () => ({
|
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: () => {
|
searchChannels: () => {
|
||||||
return {
|
return {
|
||||||
type: 'MOCK_SEARCH_CHANNELS',
|
type: 'MOCK_SEARCH_CHANNELS',
|
||||||
@@ -281,217 +269,5 @@ describe('Actions.Channel', () => {
|
|||||||
await testStore.dispatch(openGroupChannelToUserIds(fakeData.userIds));
|
await testStore.dispatch(openGroupChannelToUserIds(fakeData.userIds));
|
||||||
expect(testStore.getActions()).toEqual(expectedActions);
|
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 {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 {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 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 * as ChannelActions from 'mattermost-redux/actions/channels';
|
||||||
import {logError} from 'mattermost-redux/actions/errors';
|
|
||||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||||
import {Client4} from 'mattermost-redux/client';
|
|
||||||
import {getChannelByName, getUnreadChannelIds, getChannel} from 'mattermost-redux/selectors/entities/channels';
|
import {getChannelByName, getUnreadChannelIds, getChannel} from 'mattermost-redux/selectors/entities/channels';
|
||||||
import {getMyChannelMemberships} from 'mattermost-redux/selectors/entities/common';
|
import {getMyChannelMemberships} from 'mattermost-redux/selectors/entities/common';
|
||||||
import {getCurrentTeamUrl, getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
import {getCurrentTeamUrl, getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
||||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||||
import type {ActionFunc} from 'mattermost-redux/types/actions';
|
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 {trackEvent} from 'actions/telemetry_actions.jsx';
|
||||||
import {loadNewDMIfNeeded, loadNewGMIfNeeded, loadProfilesForSidebar} from 'actions/user_actions';
|
import {loadNewDMIfNeeded, loadNewGMIfNeeded, loadProfilesForSidebar} from 'actions/user_actions';
|
||||||
|
|
||||||
@@ -95,7 +81,7 @@ export function loadChannelsForCurrentUser(): ActionFunc {
|
|||||||
const state = getState();
|
const state = getState();
|
||||||
const unreads = getUnreadChannelIds(state);
|
const unreads = getUnreadChannelIds(state);
|
||||||
|
|
||||||
await dispatch(ChannelActions.fetchMyChannelsAndMembersREST(getCurrentTeamId(state)));
|
await dispatch(ChannelActions.fetchChannelsAndMembers(getCurrentTeamId(state)));
|
||||||
for (const id of unreads) {
|
for (const id of unreads) {
|
||||||
const channel = getChannel(state, id);
|
const channel = getChannel(state, id);
|
||||||
if (channel && channel.type === Constants.DM_CHANNEL) {
|
if (channel && channel.type === Constants.DM_CHANNEL) {
|
||||||
@@ -191,89 +177,3 @@ export function muteChannel(userId: UserProfile['id'], channelId: Channel['id'])
|
|||||||
mark_unread: NotificationLevels.MENTION,
|
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', () => ({
|
jest.mock('mattermost-redux/actions/users', () => ({
|
||||||
loadMeREST: () => ({type: 'MOCK_RECEIVED_ME'}),
|
loadMe: () => ({type: 'MOCK_RECEIVED_ME'}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('stores/redux_store', () => {
|
jest.mock('stores/redux_store', () => {
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ import type {UserProfile} from '@mattermost/types/users';
|
|||||||
import {ChannelTypes} from 'mattermost-redux/action_types';
|
import {ChannelTypes} from 'mattermost-redux/action_types';
|
||||||
import {fetchAppBindings} from 'mattermost-redux/actions/apps';
|
import {fetchAppBindings} from 'mattermost-redux/actions/apps';
|
||||||
import {
|
import {
|
||||||
fetchMyChannelsAndMembersREST,
|
fetchChannelsAndMembers,
|
||||||
getChannelByNameAndTeamName,
|
getChannelByNameAndTeamName,
|
||||||
getChannelStats,
|
getChannelStats,
|
||||||
selectChannel,
|
selectChannel,
|
||||||
} from 'mattermost-redux/actions/channels';
|
} 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 {Preferences} from 'mattermost-redux/constants';
|
||||||
import {appsEnabled} from 'mattermost-redux/selectors/entities/apps';
|
import {appsEnabled} from 'mattermost-redux/selectors/entities/apps';
|
||||||
import {getCurrentChannelStats, getCurrentChannelId, getMyChannelMember, getRedirectChannelNameForTeam, getChannelsNameMapInTeam, getAllDirectChannels, getChannelMessageCount} from 'mattermost-redux/selectors/entities/channels';
|
import {getCurrentChannelStats, getCurrentChannelId, getMyChannelMember, getRedirectChannelNameForTeam, getChannelsNameMapInTeam, getAllDirectChannels, getChannelMessageCount} from 'mattermost-redux/selectors/entities/channels';
|
||||||
import {getConfig, isPerformanceDebuggingEnabled} from 'mattermost-redux/selectors/entities/general';
|
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 {getCurrentTeamId, getMyTeams, getTeam, getMyTeamMember, getTeamMemberships, getActiveTeamsList} from 'mattermost-redux/selectors/entities/teams';
|
||||||
import {getCurrentUser, getCurrentUserId, isFirstAdmin} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUser, getCurrentUserId, isFirstAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
import type {ActionFunc, DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions';
|
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);
|
let teamChannels = getChannelsNameMapInTeam(state, team.id);
|
||||||
if (!teamChannels || Object.keys(teamChannels).length === 0) {
|
if (!teamChannels || Object.keys(teamChannels).length === 0) {
|
||||||
// This should be executed in pretty limited scenarios (empty teams)
|
// 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();
|
state = getState();
|
||||||
teamChannels = getChannelsNameMapInTeam(state, team.id);
|
teamChannels = getChannelsNameMapInTeam(state, team.id);
|
||||||
}
|
}
|
||||||
@@ -356,11 +356,7 @@ export async function redirectUserToDefaultTeam() {
|
|||||||
const shouldLoadUser = Utils.isEmptyObject(getTeamMemberships(state)) || !user;
|
const shouldLoadUser = Utils.isEmptyObject(getTeamMemberships(state)) || !user;
|
||||||
const onboardingFlowEnabled = getIsOnboardingFlowEnabled(state);
|
const onboardingFlowEnabled = getIsOnboardingFlowEnabled(state);
|
||||||
if (shouldLoadUser) {
|
if (shouldLoadUser) {
|
||||||
if (isGraphQLEnabled(state)) {
|
await dispatch(loadMe());
|
||||||
await dispatch(loadMe());
|
|
||||||
} else {
|
|
||||||
await dispatch(loadMeREST());
|
|
||||||
}
|
|
||||||
state = getState();
|
state = getState();
|
||||||
user = getCurrentUser(state);
|
user = getCurrentUser(state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ function initRequestCountingIfNecessary() {
|
|||||||
for (const entry of entries.getEntries()) {
|
for (const entry of entries.getEntries()) {
|
||||||
const url = entry.name;
|
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
|
// Don't count requests made outside of the MM server's API
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jest.mock('mattermost-redux/actions/users', () => {
|
|||||||
const original = jest.requireActual('mattermost-redux/actions/users');
|
const original = jest.requireActual('mattermost-redux/actions/users');
|
||||||
return {
|
return {
|
||||||
...original,
|
...original,
|
||||||
loadMeREST: () => ({type: 'MOCK_LOAD_ME'}),
|
loadMe: () => ({type: 'MOCK_LOAD_ME'}),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
|
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 {Client4} from 'mattermost-redux/client';
|
||||||
import type {DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions';
|
import type {DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions';
|
||||||
|
|
||||||
@@ -20,22 +20,15 @@ export type TranslationPluginFunction = (locale: string) => Translations
|
|||||||
|
|
||||||
export function loadConfigAndMe() {
|
export function loadConfigAndMe() {
|
||||||
return async (dispatch: DispatchFunc) => {
|
return async (dispatch: DispatchFunc) => {
|
||||||
const [{data: clientConfig}] = await Promise.all([
|
await Promise.all([
|
||||||
dispatch(getClientConfig()),
|
dispatch(getClientConfig()),
|
||||||
dispatch(getLicenseConfig()),
|
dispatch(getLicenseConfig()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const isGraphQLEnabled = clientConfig && clientConfig.FeatureFlagGraphQL === 'true';
|
|
||||||
|
|
||||||
let isMeLoaded = false;
|
let isMeLoaded = false;
|
||||||
if (document.cookie.includes('MMUSERID=')) {
|
if (document.cookie.includes('MMUSERID=')) {
|
||||||
if (isGraphQLEnabled) {
|
const dataFromLoadMe = await dispatch(loadMe());
|
||||||
const dataFromLoadMe = await dispatch(loadMe());
|
isMeLoaded = dataFromLoadMe?.data ?? false;
|
||||||
isMeLoaded = dataFromLoadMe?.data ?? false;
|
|
||||||
} else {
|
|
||||||
const dataFromLoadMeREST = await dispatch(loadMeREST());
|
|
||||||
isMeLoaded = dataFromLoadMeREST?.data ?? false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {data: isMeLoaded};
|
return {data: isMeLoaded};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type {History} from 'history';
|
|||||||
import type {Channel} from '@mattermost/types/channels';
|
import type {Channel} from '@mattermost/types/channels';
|
||||||
import type {GlobalState} from '@mattermost/types/store';
|
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 {getUser, getUserByUsername, getUserByEmail} from 'mattermost-redux/actions/users';
|
||||||
import {Client4} from 'mattermost-redux/client';
|
import {Client4} from 'mattermost-redux/client';
|
||||||
import {getChannelByName, getOtherChannels, getChannel, getChannelsNameMapInTeam, getRedirectChannelNameForTeam} from 'mattermost-redux/selectors/entities/channels';
|
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));
|
dispatch(goToDirectChannelByUserId(match, history, identifier));
|
||||||
break;
|
break;
|
||||||
case 'error':
|
case 'error':
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ export function goToChannelByChannelId(match: Match, history: History): ActionFu
|
|||||||
if (!channel || !member) {
|
if (!channel || !member) {
|
||||||
const dispatchResult = await dispatch(joinChannel(getCurrentUserId(state), teamObj!.id, channelId, ''));
|
const dispatchResult = await dispatch(joinChannel(getCurrentUserId(state), teamObj!.id, channelId, ''));
|
||||||
if ('error' in dispatchResult) {
|
if ('error' in dispatchResult) {
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||||
handleChannelJoinError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
handleChannelJoinError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
return {data: undefined};
|
return {data: undefined};
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ export function goToChannelByChannelName(match: Match, history: History): Action
|
|||||||
if (!channel) {
|
if (!channel) {
|
||||||
const getChannelDispatchResult = await dispatch(getChannelByNameAndTeamName(team, channelName, true));
|
const getChannelDispatchResult = await dispatch(getChannelByNameAndTeamName(team, channelName, true));
|
||||||
if ('error' in getChannelDispatchResult || getChannelDispatchResult.data.delete_at === 0) {
|
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));
|
handleChannelJoinError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
return {data: undefined};
|
return {data: undefined};
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ function goToDirectChannelByUsername(match: Match, history: History): ActionFunc
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
const dispatchResult = await dispatch(getUserByUsername(username));
|
const dispatchResult = await dispatch(getUserByUsername(username));
|
||||||
if ('error' in dispatchResult) {
|
if ('error' in dispatchResult) {
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
return {data: undefined};
|
return {data: undefined};
|
||||||
}
|
}
|
||||||
@@ -244,7 +244,7 @@ function goToDirectChannelByUsername(match: Match, history: History): ActionFunc
|
|||||||
|
|
||||||
const directChannelDispatchRes = await dispatch(openDirectChannelToUserId(user.id));
|
const directChannelDispatchRes = await dispatch(openDirectChannelToUserId(user.id));
|
||||||
if ('error' in directChannelDispatchRes) {
|
if ('error' in directChannelDispatchRes) {
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
return {data: undefined};
|
return {data: undefined};
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ export function goToDirectChannelByUserId(match: Match, history: History, userId
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
const dispatchResult = await dispatch(getUser(userId));
|
const dispatchResult = await dispatch(getUser(userId));
|
||||||
if ('error' in dispatchResult) {
|
if ('error' in dispatchResult) {
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
return {data: undefined};
|
return {data: undefined};
|
||||||
}
|
}
|
||||||
@@ -287,7 +287,7 @@ export function goToDirectChannelByUserIds(match: Match, history: History): Acti
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
const dispatchResult = await dispatch(getUser(userId));
|
const dispatchResult = await dispatch(getUser(userId));
|
||||||
if ('error' in dispatchResult) {
|
if ('error' in dispatchResult) {
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
return {data: undefined};
|
return {data: undefined};
|
||||||
}
|
}
|
||||||
@@ -310,7 +310,7 @@ export function goToDirectChannelByEmail(match: Match, history: History): Action
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
const dispatchResult = await dispatch(getUserByEmail(email));
|
const dispatchResult = await dispatch(getUserByEmail(email));
|
||||||
if ('error' in dispatchResult) {
|
if ('error' in dispatchResult) {
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
return {data: undefined};
|
return {data: undefined};
|
||||||
}
|
}
|
||||||
@@ -335,7 +335,7 @@ function goToGroupChannelByGroupId(match: Match, history: History): ActionFunc {
|
|||||||
if (!channel) {
|
if (!channel) {
|
||||||
const dispatchResult = await dispatch(joinChannel(getCurrentUserId(state), teamObj!.id, '', groupId));
|
const dispatchResult = await dispatch(joinChannel(getCurrentUserId(state), teamObj!.id, '', groupId));
|
||||||
if ('error' in dispatchResult) {
|
if ('error' in dispatchResult) {
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(teamObj!.id));
|
await dispatch(fetchChannelsAndMembers(teamObj!.id));
|
||||||
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
handleError(match, history, getRedirectChannelNameForTeam(state, teamObj!.id));
|
||||||
return {data: undefined};
|
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 {Team} from '@mattermost/types/teams';
|
||||||
import type {UserProfile} from '@mattermost/types/users';
|
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 {Client4} from 'mattermost-redux/client';
|
||||||
import {RequestStatus} from 'mattermost-redux/constants';
|
import {RequestStatus} from 'mattermost-redux/constants';
|
||||||
import {isCurrentLicenseCloud} from 'mattermost-redux/selectors/entities/cloud';
|
import {isCurrentLicenseCloud} from 'mattermost-redux/selectors/entities/cloud';
|
||||||
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
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 {getTeamByName, getMyTeamMember} from 'mattermost-redux/selectors/entities/teams';
|
||||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||||
import type {DispatchFunc} from 'mattermost-redux/types/actions';
|
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 experimentalPrimaryTeamMember = useSelector((state: GlobalState) => getMyTeamMember(state, experimentalPrimaryTeam?.id ?? ''));
|
||||||
const onboardingFlowEnabled = useSelector(getIsOnboardingFlowEnabled);
|
const onboardingFlowEnabled = useSelector(getIsOnboardingFlowEnabled);
|
||||||
const isCloud = useSelector(isCurrentLicenseCloud);
|
const isCloud = useSelector(isCurrentLicenseCloud);
|
||||||
const graphQLEnabled = useSelector(isGraphQLEnabled);
|
|
||||||
|
|
||||||
const loginIdInput = useRef<HTMLInputElement>(null);
|
const loginIdInput = useRef<HTMLInputElement>(null);
|
||||||
const passwordInput = useRef<HTMLInputElement>(null);
|
const passwordInput = useRef<HTMLInputElement>(null);
|
||||||
@@ -629,11 +628,7 @@ const Login = ({onCustomizeHeader}: LoginProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const postSubmit = async (userProfile: UserProfile) => {
|
const postSubmit = async (userProfile: UserProfile) => {
|
||||||
if (graphQLEnabled) {
|
await dispatch(loadMe());
|
||||||
await dispatch(loadMe());
|
|
||||||
} else {
|
|
||||||
await dispatch(loadMeREST());
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for query params brought over from signup_user_complete
|
// check for query params brought over from signup_user_complete
|
||||||
const params = new URLSearchParams(search);
|
const params = new URLSearchParams(search);
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import type {ServerError} from '@mattermost/types/errors';
|
|||||||
import type {UserProfile} from '@mattermost/types/users';
|
import type {UserProfile} from '@mattermost/types/users';
|
||||||
|
|
||||||
import {getTeamInviteInfo} from 'mattermost-redux/actions/teams';
|
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 {Client4} from 'mattermost-redux/client';
|
||||||
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
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 {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||||
import type {DispatchFunc} from 'mattermost-redux/types/actions';
|
import type {DispatchFunc} from 'mattermost-redux/types/actions';
|
||||||
import {isEmail} from 'mattermost-redux/utils/helpers';
|
import {isEmail} from 'mattermost-redux/utils/helpers';
|
||||||
@@ -110,7 +110,6 @@ const Signup = ({onCustomizeHeader}: SignupProps) => {
|
|||||||
const loggedIn = Boolean(useSelector(getCurrentUserId));
|
const loggedIn = Boolean(useSelector(getCurrentUserId));
|
||||||
const onboardingFlowEnabled = useSelector(getIsOnboardingFlowEnabled);
|
const onboardingFlowEnabled = useSelector(getIsOnboardingFlowEnabled);
|
||||||
const usedBefore = useSelector((state: GlobalState) => (!inviteId && !loggedIn && token ? getGlobalItem(state, token, null) : undefined));
|
const usedBefore = useSelector((state: GlobalState) => (!inviteId && !loggedIn && token ? getGlobalItem(state, token, null) : undefined));
|
||||||
const graphQLEnabled = useSelector(isGraphQLEnabled);
|
|
||||||
|
|
||||||
const emailInput = useRef<HTMLInputElement>(null);
|
const emailInput = useRef<HTMLInputElement>(null);
|
||||||
const nameInput = useRef<HTMLInputElement>(null);
|
const nameInput = useRef<HTMLInputElement>(null);
|
||||||
@@ -482,11 +481,7 @@ const Signup = ({onCustomizeHeader}: SignupProps) => {
|
|||||||
const postSignupSuccess = async () => {
|
const postSignupSuccess = async () => {
|
||||||
const redirectTo = (new URLSearchParams(search)).get('redirect_to');
|
const redirectTo = (new URLSearchParams(search)).get('redirect_to');
|
||||||
|
|
||||||
if (graphQLEnabled) {
|
await dispatch(loadMe());
|
||||||
await dispatch(loadMe());
|
|
||||||
} else {
|
|
||||||
await dispatch(loadMeREST());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
setGlobalItem(token, JSON.stringify({usedBefore: true}));
|
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 {GetGroupsForUserParams, GetGroupsParams} from '@mattermost/types/groups';
|
||||||
import type {Team} from '@mattermost/types/teams';
|
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 {logError} from 'mattermost-redux/actions/errors';
|
||||||
import {getGroups, getAllGroupsAssociatedToChannelsInTeam, getAllGroupsAssociatedToTeam, getGroupsByUserIdPaginated} from 'mattermost-redux/actions/groups';
|
import {getGroups, getAllGroupsAssociatedToChannelsInTeam, getAllGroupsAssociatedToTeam, getGroupsByUserIdPaginated} from 'mattermost-redux/actions/groups';
|
||||||
import {forceLogoutIfNecessary} from 'mattermost-redux/actions/helpers';
|
import {forceLogoutIfNecessary} from 'mattermost-redux/actions/helpers';
|
||||||
import {getTeamByName, selectTeam} from 'mattermost-redux/actions/teams';
|
import {getTeamByName, selectTeam} from 'mattermost-redux/actions/teams';
|
||||||
import {getLicense} from 'mattermost-redux/selectors/entities/general';
|
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 {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||||
import type {ActionFunc} from 'mattermost-redux/types/actions';
|
import type {ActionFunc} from 'mattermost-redux/types/actions';
|
||||||
|
|
||||||
import {fetchChannelsAndMembers} from 'actions/channel_actions';
|
|
||||||
import {loadStatusesForChannelAndSidebar} from 'actions/status_actions';
|
import {loadStatusesForChannelAndSidebar} from 'actions/status_actions';
|
||||||
import {addUserToTeam} from 'actions/team_actions';
|
import {addUserToTeam} from 'actions/team_actions';
|
||||||
import LocalStorageStore from 'stores/local_storage_store';
|
import LocalStorageStore from 'stores/local_storage_store';
|
||||||
@@ -30,13 +29,8 @@ export function initializeTeam(team: Team): ActionFunc<Team, ServerError> {
|
|||||||
const currentUser = getCurrentUser(state);
|
const currentUser = getCurrentUser(state);
|
||||||
LocalStorageStore.setPreviousTeamId(currentUser.id, team.id);
|
LocalStorageStore.setPreviousTeamId(currentUser.id, team.id);
|
||||||
|
|
||||||
const graphQLEnabled = isGraphQLEnabled(state);
|
|
||||||
try {
|
try {
|
||||||
if (graphQLEnabled) {
|
await dispatch(fetchChannelsAndMembers(team.id));
|
||||||
await dispatch(fetchChannelsAndMembers(team.id));
|
|
||||||
} else {
|
|
||||||
await dispatch(fetchMyChannelsAndMembersREST(team.id));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
forceLogoutIfNecessary(error as ServerError, dispatch, getState);
|
forceLogoutIfNecessary(error as ServerError, dispatch, getState);
|
||||||
dispatch(logError(error as ServerError));
|
dispatch(logError(error as ServerError));
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ import {connect} from 'react-redux';
|
|||||||
import type {ConnectedProps} from 'react-redux';
|
import type {ConnectedProps} from 'react-redux';
|
||||||
import type {RouteComponentProps} from 'react-router-dom';
|
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 {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels';
|
||||||
import {getLicense, getConfig} from 'mattermost-redux/selectors/entities/general';
|
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 {getCurrentTeamId, getMyTeams} from 'mattermost-redux/selectors/entities/teams';
|
||||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
|
||||||
import {fetchChannelsAndMembers} from 'actions/channel_actions';
|
|
||||||
import {markChannelAsReadOnFocus} from 'actions/views/channel';
|
import {markChannelAsReadOnFocus} from 'actions/views/channel';
|
||||||
import {getSelectedThreadIdInCurrentTeam} from 'selectors/views/threads';
|
import {getSelectedThreadIdInCurrentTeam} from 'selectors/views/threads';
|
||||||
|
|
||||||
@@ -36,7 +34,6 @@ function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
|
|||||||
const config = getConfig(state);
|
const config = getConfig(state);
|
||||||
const currentUser = getCurrentUser(state);
|
const currentUser = getCurrentUser(state);
|
||||||
const plugins = state.plugins.components.NeedsTeamComponent;
|
const plugins = state.plugins.components.NeedsTeamComponent;
|
||||||
const graphQLEnabled = isGraphQLEnabled(state);
|
|
||||||
const disableRefetchingOnBrowserFocus = config.DisableRefetchingOnBrowserFocus === 'true';
|
const disableRefetchingOnBrowserFocus = config.DisableRefetchingOnBrowserFocus === 'true';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -46,14 +43,12 @@ function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
|
|||||||
plugins,
|
plugins,
|
||||||
selectedThreadId: getSelectedThreadIdInCurrentTeam(state),
|
selectedThreadId: getSelectedThreadIdInCurrentTeam(state),
|
||||||
mfaRequired: checkIfMFARequired(currentUser, license, config, ownProps.match.url),
|
mfaRequired: checkIfMFARequired(currentUser, license, config, ownProps.match.url),
|
||||||
graphQLEnabled,
|
|
||||||
disableRefetchingOnBrowserFocus,
|
disableRefetchingOnBrowserFocus,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
fetchChannelsAndMembers,
|
fetchChannelsAndMembers,
|
||||||
fetchMyChannelsAndMembersREST,
|
|
||||||
fetchAllMyTeamsChannelsAndChannelMembersREST,
|
fetchAllMyTeamsChannelsAndChannelMembersREST,
|
||||||
markChannelAsReadOnFocus,
|
markChannelAsReadOnFocus,
|
||||||
initializeTeam,
|
initializeTeam,
|
||||||
|
|||||||
@@ -53,17 +53,13 @@ function TeamController(props: Props) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function fetchInitialChannels() {
|
async function fetchInitialChannels() {
|
||||||
if (props.graphQLEnabled) {
|
await props.fetchAllMyTeamsChannelsAndChannelMembersREST();
|
||||||
await props.fetchChannelsAndMembers();
|
|
||||||
} else {
|
|
||||||
await props.fetchAllMyTeamsChannelsAndChannelMembersREST();
|
|
||||||
}
|
|
||||||
|
|
||||||
setInitialChannelsLoaded(true);
|
setInitialChannelsLoaded(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchInitialChannels();
|
fetchInitialChannels();
|
||||||
}, [props.graphQLEnabled]);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const wakeUpIntervalId = setInterval(() => {
|
const wakeUpIntervalId = setInterval(() => {
|
||||||
@@ -95,11 +91,7 @@ function TeamController(props: Props) {
|
|||||||
if (!props.disableRefetchingOnBrowserFocus) {
|
if (!props.disableRefetchingOnBrowserFocus) {
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
if ((currentTime - blurTime.current) > UNREAD_CHECK_TIME_MILLISECONDS && props.currentTeamId) {
|
if ((currentTime - blurTime.current) > UNREAD_CHECK_TIME_MILLISECONDS && props.currentTeamId) {
|
||||||
if (props.graphQLEnabled) {
|
props.fetchChannelsAndMembers(props.currentTeamId);
|
||||||
props.fetchChannelsAndMembers(props.currentTeamId);
|
|
||||||
} else {
|
|
||||||
props.fetchMyChannelsAndMembersREST(props.currentTeamId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +124,7 @@ function TeamController(props: Props) {
|
|||||||
window.removeEventListener('blur', handleBlur);
|
window.removeEventListener('blur', handleBlur);
|
||||||
window.removeEventListener('keydown', handleKeydown);
|
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
|
// Effect runs on mount, adds active state to window
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {UserTypes} from 'mattermost-redux/action_types';
|
|||||||
import * as Actions from 'mattermost-redux/actions/channels';
|
import * as Actions from 'mattermost-redux/actions/channels';
|
||||||
import {createIncomingHook, createOutgoingHook} from 'mattermost-redux/actions/integrations';
|
import {createIncomingHook, createOutgoingHook} from 'mattermost-redux/actions/integrations';
|
||||||
import {addUserToTeam} from 'mattermost-redux/actions/teams';
|
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 {Client4} from 'mattermost-redux/client';
|
||||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||||
import {getPreferenceKey} from 'mattermost-redux/utils/preference_utils';
|
import {getPreferenceKey} from 'mattermost-redux/utils/preference_utils';
|
||||||
@@ -185,7 +185,7 @@ describe('Actions.Channels', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/users/ids').
|
post('/users/ids').
|
||||||
@@ -358,7 +358,7 @@ describe('Actions.Channels', () => {
|
|||||||
expect(myMembers[TestHelper.basicChannel!.id]).toBeTruthy();
|
expect(myMembers[TestHelper.basicChannel!.id]).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fetchMyChannelsAndMembersREST', async () => {
|
it('fetchChannelsAndMembers', async () => {
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/users').
|
post('/users').
|
||||||
query(true).
|
query(true).
|
||||||
@@ -386,7 +386,7 @@ describe('Actions.Channels', () => {
|
|||||||
get(`/users/me/teams/${TestHelper.basicTeam!.id}/channels/members`).
|
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]);
|
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;
|
const {channels, channelsInTeam, myMembers} = store.getState().entities.channels;
|
||||||
expect(channels).toBeTruthy();
|
expect(channels).toBeTruthy();
|
||||||
@@ -412,7 +412,7 @@ describe('Actions.Channels', () => {
|
|||||||
get(`/users/me/teams/${TestHelper.basicTeam!.id}/channels/members`).
|
get(`/users/me/teams/${TestHelper.basicTeam!.id}/channels/members`).
|
||||||
reply(200, [TestHelper.basicChannelMember]);
|
reply(200, [TestHelper.basicChannelMember]);
|
||||||
|
|
||||||
await store.dispatch(Actions.fetchMyChannelsAndMembersREST(TestHelper.basicTeam!.id));
|
await store.dispatch(Actions.fetchChannelsAndMembers(TestHelper.basicTeam!.id));
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
put(`/channels/${TestHelper.basicChannel!.id}/members/${TestHelper.basicUser!.id}/notify_props`).
|
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`).
|
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]);
|
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()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/hooks/incoming').
|
post('/hooks/incoming').
|
||||||
@@ -579,7 +579,7 @@ describe('Actions.Channels', () => {
|
|||||||
get(`/users/me/teams/${TestHelper.basicTeam!.id}/channels/members`).
|
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]);
|
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()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/hooks/incoming').
|
post('/hooks/incoming').
|
||||||
@@ -1900,7 +1900,7 @@ describe('Actions.Channels', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/channels').
|
post('/channels').
|
||||||
@@ -1933,7 +1933,7 @@ describe('Actions.Channels', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/channels').
|
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) => {
|
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||||
let channels;
|
let channels;
|
||||||
let channelMembers;
|
let channelMembers;
|
||||||
@@ -1503,7 +1503,7 @@ export default {
|
|||||||
patchChannel,
|
patchChannel,
|
||||||
updateChannelNotifyProps,
|
updateChannelNotifyProps,
|
||||||
getChannel,
|
getChannel,
|
||||||
fetchMyChannelsAndMembersREST,
|
fetchChannelsAndMembers,
|
||||||
getChannelTimezones,
|
getChannelTimezones,
|
||||||
getChannelMembersByIds,
|
getChannelMembersByIds,
|
||||||
leaveChannel,
|
leaveChannel,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {PostTypes, UserTypes} from 'mattermost-redux/action_types';
|
|||||||
import {getChannelStats} from 'mattermost-redux/actions/channels';
|
import {getChannelStats} from 'mattermost-redux/actions/channels';
|
||||||
import {createCustomEmoji} from 'mattermost-redux/actions/emojis';
|
import {createCustomEmoji} from 'mattermost-redux/actions/emojis';
|
||||||
import * as Actions from 'mattermost-redux/actions/posts';
|
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 {Client4} from 'mattermost-redux/client';
|
||||||
import type {ActionResult, GetStateFunc} from 'mattermost-redux/types/actions';
|
import type {ActionResult, GetStateFunc} from 'mattermost-redux/types/actions';
|
||||||
import {getPreferenceKey} from 'mattermost-redux/utils/preference_utils';
|
import {getPreferenceKey} from 'mattermost-redux/utils/preference_utils';
|
||||||
@@ -274,7 +274,7 @@ describe('Actions.Posts', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/posts').
|
post('/posts').
|
||||||
@@ -368,7 +368,7 @@ describe('Actions.Posts', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/posts').
|
post('/posts').
|
||||||
@@ -1015,7 +1015,7 @@ describe('Actions.Posts', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/posts').
|
post('/posts').
|
||||||
@@ -1048,7 +1048,7 @@ describe('Actions.Posts', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/posts').
|
post('/posts').
|
||||||
@@ -1221,7 +1221,7 @@ describe('Actions.Posts', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/posts').
|
post('/posts').
|
||||||
@@ -1250,7 +1250,7 @@ describe('Actions.Posts', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/posts').
|
post('/posts').
|
||||||
@@ -1284,7 +1284,7 @@ describe('Actions.Posts', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await store.dispatch(loadMeREST());
|
await store.dispatch(loadMe());
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/posts').
|
post('/posts').
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import nock from 'nock';
|
|||||||
|
|
||||||
import {UserTypes} from 'mattermost-redux/action_types';
|
import {UserTypes} from 'mattermost-redux/action_types';
|
||||||
import * as Actions from 'mattermost-redux/actions/preferences';
|
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 {Client4} from 'mattermost-redux/client';
|
||||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ describe('Actions.Preferences', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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
|
// Test that a new preference is created if none exists
|
||||||
nock(Client4.getUsersRoute()).
|
nock(Client4.getUsersRoute()).
|
||||||
@@ -303,7 +303,7 @@ describe('Actions.Preferences', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await loadMeREST()(store.dispatch, store.getState);
|
await loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
const theme = {
|
const theme = {
|
||||||
type: 'Mattermost Dark',
|
type: 'Mattermost Dark',
|
||||||
|
|||||||
@@ -104,7 +104,3 @@ export function loadRolesIfNeeded(roles: Iterable<string>): ActionFunc {
|
|||||||
return {data: state.entities.roles.roles};
|
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 {GeneralTypes, UserTypes} from 'mattermost-redux/action_types';
|
||||||
import * as Actions from 'mattermost-redux/actions/teams';
|
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 {Client4} from 'mattermost-redux/client';
|
||||||
import {General, RequestStatus} from 'mattermost-redux/constants';
|
import {General, RequestStatus} from 'mattermost-redux/constants';
|
||||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||||
@@ -55,7 +55,7 @@ describe('Actions.Teams', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await loadMeREST()(store.dispatch, store.getState);
|
await loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
get('/users/me/teams').
|
get('/users/me/teams').
|
||||||
@@ -741,7 +741,7 @@ describe('Actions.Teams', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await loadMeREST()(store.dispatch, store.getState);
|
await loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
const team = TestHelper.basicTeam;
|
const team = TestHelper.basicTeam;
|
||||||
const imageData = fs.createReadStream('src/packages/mattermost-redux/test/assets/images/test.png');
|
const imageData = fs.createReadStream('src/packages/mattermost-redux/test/assets/images/test.png');
|
||||||
@@ -759,7 +759,7 @@ describe('Actions.Teams', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await loadMeREST()(store.dispatch, store.getState);
|
await loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
const team = TestHelper.basicTeam;
|
const team = TestHelper.basicTeam;
|
||||||
|
|
||||||
@@ -776,7 +776,7 @@ describe('Actions.Teams', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await loadMeREST()(store.dispatch, store.getState);
|
await loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
const schemeId = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
|
const schemeId = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
|
||||||
const {id} = TestHelper.basicTeam!;
|
const {id} = TestHelper.basicTeam!;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
await Actions.loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/users/me/terms_of_service').
|
post('/users/me/terms_of_service').
|
||||||
@@ -115,7 +115,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
await Actions.loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/users/me/terms_of_service').
|
post('/users/me/terms_of_service').
|
||||||
@@ -661,7 +661,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
await Actions.loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/users/login').
|
post('/users/login').
|
||||||
@@ -717,7 +717,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
await Actions.loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
nock(Client4.getBaseRoute()).
|
nock(Client4.getBaseRoute()).
|
||||||
post('/users/login').
|
post('/users/login').
|
||||||
@@ -854,7 +854,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
await Actions.loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
const state = store.getState();
|
const state = store.getState();
|
||||||
const currentUser = state.entities.users.profiles[state.entities.users.currentUserId];
|
const currentUser = state.entities.users.profiles[state.entities.users.currentUserId];
|
||||||
@@ -905,7 +905,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
await Actions.loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
const state = store.getState();
|
const state = store.getState();
|
||||||
const currentUserId = state.entities.users.currentUserId;
|
const currentUserId = state.entities.users.currentUserId;
|
||||||
@@ -953,7 +953,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -974,7 +974,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -995,7 +995,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
type: UserTypes.LOGIN_SUCCESS,
|
||||||
});
|
});
|
||||||
await Actions.loadMeREST()(store.dispatch, store.getState);
|
await Actions.loadMe()(store.dispatch, store.getState);
|
||||||
|
|
||||||
const beforeTime = new Date().getTime();
|
const beforeTime = new Date().getTime();
|
||||||
const currentUserId = store.getState().entities.users.currentUserId;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
@@ -1090,7 +1090,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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');
|
const testImageData = fs.createReadStream('src/packages/mattermost-redux/test/assets/images/test.png');
|
||||||
|
|
||||||
@@ -1115,7 +1115,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -1182,7 +1182,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -1213,7 +1213,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -1249,7 +1249,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -1286,7 +1286,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -1323,7 +1323,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -1371,7 +1371,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -1426,7 +1426,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
@@ -1481,7 +1481,7 @@ describe('Actions.Users', () => {
|
|||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UserTypes.LOGIN_SUCCESS,
|
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;
|
const currentUserId = store.getState().entities.users.currentUserId;
|
||||||
|
|
||||||
|
|||||||
@@ -4,29 +4,16 @@
|
|||||||
import type {AnyAction} from 'redux';
|
import type {AnyAction} from 'redux';
|
||||||
import {batchActions} from 'redux-batched-actions';
|
import {batchActions} from 'redux-batched-actions';
|
||||||
|
|
||||||
import type {ClientConfig, ClientLicense} from '@mattermost/types/config';
|
|
||||||
import type {ServerError} from '@mattermost/types/errors';
|
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 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 {logError} from 'mattermost-redux/actions/errors';
|
||||||
import {setServerVersion, getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
|
import {setServerVersion, getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
|
||||||
import {bindClientFunc, forceLogoutIfNecessary, debounce} from 'mattermost-redux/actions/helpers';
|
import {bindClientFunc, forceLogoutIfNecessary, debounce} from 'mattermost-redux/actions/helpers';
|
||||||
import {getMyPreferences} from 'mattermost-redux/actions/preferences';
|
import {getMyPreferences} from 'mattermost-redux/actions/preferences';
|
||||||
import {loadRolesIfNeeded} from 'mattermost-redux/actions/roles';
|
import {loadRolesIfNeeded} from 'mattermost-redux/actions/roles';
|
||||||
import {getMyTeams, getMyTeamMembers, getMyTeamUnreads} from 'mattermost-redux/actions/teams';
|
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 {Client4} from 'mattermost-redux/client';
|
||||||
import {General} from 'mattermost-redux/constants';
|
import {General} from 'mattermost-redux/constants';
|
||||||
import {getServerVersion} from 'mattermost-redux/selectors/entities/general';
|
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) => {
|
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||||
// Sometimes the server version is set in one or the other
|
// Sometimes the server version is set in one or the other
|
||||||
const serverVersion = getState().entities.general.serverVersion || Client4.getServerVersion();
|
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 {
|
export function logout(): ActionFunc {
|
||||||
return async (dispatch: DispatchFunc) => {
|
return async (dispatch: DispatchFunc) => {
|
||||||
dispatch({type: UserTypes.LOGOUT_REQUEST, data: null});
|
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';
|
return getConfig(state).EnableOnboardingFlow === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isGraphQLEnabled(state: GlobalState): boolean {
|
|
||||||
return getFeatureFlagValue(state, 'GraphQL') === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getHasDismissedSystemConsoleLimitReached(state: GlobalState): boolean {
|
export function getHasDismissedSystemConsoleLimitReached(state: GlobalState): boolean {
|
||||||
return getBool(state, Preferences.CATEGORY_UPGRADE_CLOUD, Preferences.SYSTEM_CONSOLE_LIMIT_REACHED, false);
|
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');
|
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', () => {
|
describe('ClientError', () => {
|
||||||
|
|||||||
@@ -159,8 +159,6 @@ const PER_PAGE_DEFAULT = 60;
|
|||||||
export const DEFAULT_LIMIT_BEFORE = 30;
|
export const DEFAULT_LIMIT_BEFORE = 30;
|
||||||
export const DEFAULT_LIMIT_AFTER = 30;
|
export const DEFAULT_LIMIT_AFTER = 30;
|
||||||
|
|
||||||
const GRAPHQL_ENDPOINT = '/api/v5/graphql';
|
|
||||||
|
|
||||||
export default class Client4 {
|
export default class Client4 {
|
||||||
logToConsole = false;
|
logToConsole = false;
|
||||||
serverVersion = '';
|
serverVersion = '';
|
||||||
@@ -194,10 +192,6 @@ export default class Client4 {
|
|||||||
return this.getUrl() + baseUrl;
|
return this.getUrl() + baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
getGraphQLUrl() {
|
|
||||||
return `${this.url}${GRAPHQL_ENDPOINT}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
setUrl(url: string) {
|
setUrl(url: string) {
|
||||||
this.url = url;
|
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) => {
|
getCallsChannelState = (channelId: string) => {
|
||||||
return this.doFetch<{enabled: boolean; id: string}>(
|
return this.doFetch<{enabled: boolean; id: string}>(
|
||||||
`${this.url}/plugins/${'com.mattermost.calls'}/${channelId}`,
|
`${this.url}/plugins/${'com.mattermost.calls'}/${channelId}`,
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ export type ClientConfig = {
|
|||||||
FileLevel: string;
|
FileLevel: string;
|
||||||
FeatureFlagAppsEnabled: string;
|
FeatureFlagAppsEnabled: string;
|
||||||
FeatureFlagCallsEnabled: string;
|
FeatureFlagCallsEnabled: string;
|
||||||
FeatureFlagGraphQL: string;
|
|
||||||
ForgotPasswordLink: string;
|
ForgotPasswordLink: string;
|
||||||
GiphySdkKey: string;
|
GiphySdkKey: string;
|
||||||
GoogleDeveloperKey: string;
|
GoogleDeveloperKey: string;
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user