From d693f880431741e3e1482503c4e80d6148b0f1bf Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Tue, 13 Jun 2023 16:32:08 -0400 Subject: [PATCH] Migrate actions/views/profile_popover to TS (#23663) * Migrate actions/views/profile_popover to TS * Fix typing --- .../src/actions/views/profile_popover.test.ts | 54 +++++++++++++++++++ ...{profile_popover.js => profile_popover.ts} | 6 ++- .../src/components/profile_popover/index.ts | 10 ++-- .../profile_popover/profile_popover.tsx | 2 +- .../src/selectors/entities/channels.ts | 4 ++ .../src/selectors/entities/teams.ts | 9 +--- 6 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 webapp/channels/src/actions/views/profile_popover.test.ts rename webapp/channels/src/actions/views/{profile_popover.js => profile_popover.ts} (67%) diff --git a/webapp/channels/src/actions/views/profile_popover.test.ts b/webapp/channels/src/actions/views/profile_popover.test.ts new file mode 100644 index 0000000000..8470cb6906 --- /dev/null +++ b/webapp/channels/src/actions/views/profile_popover.test.ts @@ -0,0 +1,54 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {getChannelMember} from 'mattermost-redux/actions/channels'; +import {getTeamMember} from 'mattermost-redux/actions/teams'; + +import testConfigureStore from 'tests/test_store'; + +import {getMembershipForEntities} from './profile_popover'; + +jest.mock('mattermost-redux/actions/channels', () => ({ + getChannelMember: jest.fn(() => ({type: 'GET_CHANNEL_MEMBER'})), +})); +jest.mock('mattermost-redux/actions/teams', () => ({ + getTeamMember: jest.fn(() => ({type: 'GET_TEAM_MEMBER'})), +})); + +describe('getMembershipForEntities', () => { + const baseState = { + entities: { + channels: { + membersInChannel: {}, + }, + teams: { + membersInTeam: {}, + }, + }, + }; + + const userId = 'userId'; + const teamId = 'teamId'; + const channelId = 'channelId'; + + const getChannelMemberMock = getChannelMember as jest.Mock; + const getTeamMemberMock = getTeamMember as jest.Mock; + + test('should only fetch team member in a DM/GM', () => { + const store = testConfigureStore(baseState); + + store.dispatch(getMembershipForEntities(teamId, userId, '')); + + expect(getChannelMemberMock).not.toHaveBeenCalled(); + expect(getTeamMemberMock).toHaveBeenCalledWith(teamId, userId); + }); + + test('should fetch both team and channel member for regular channels', () => { + const store = testConfigureStore(baseState); + + store.dispatch(getMembershipForEntities(teamId, userId, channelId)); + + expect(getChannelMemberMock).toHaveBeenCalledWith(channelId, userId); + expect(getTeamMemberMock).toHaveBeenCalledWith(teamId, userId); + }); +}); diff --git a/webapp/channels/src/actions/views/profile_popover.js b/webapp/channels/src/actions/views/profile_popover.ts similarity index 67% rename from webapp/channels/src/actions/views/profile_popover.js rename to webapp/channels/src/actions/views/profile_popover.ts index df6c56ce9a..0aed9fd27b 100644 --- a/webapp/channels/src/actions/views/profile_popover.js +++ b/webapp/channels/src/actions/views/profile_popover.ts @@ -4,8 +4,10 @@ import {getTeamMember} from 'mattermost-redux/actions/teams'; import {getChannelMember} from 'mattermost-redux/actions/channels'; -export function getMembershipForEntities(teamId, userId, channelId) { - return async (dispatch) => { +import {DispatchFunc} from 'mattermost-redux/types/actions'; + +export function getMembershipForEntities(teamId: string, userId: string, channelId?: string) { + return (dispatch: DispatchFunc) => { return Promise.all([ dispatch(getTeamMember(teamId, userId)), channelId && dispatch(getChannelMember(channelId, userId)), diff --git a/webapp/channels/src/components/profile_popover/index.ts b/webapp/channels/src/components/profile_popover/index.ts index 86c77f0203..da6c5cde5c 100644 --- a/webapp/channels/src/components/profile_popover/index.ts +++ b/webapp/channels/src/components/profile_popover/index.ts @@ -11,13 +11,13 @@ import { getTeamMember, } from 'mattermost-redux/selectors/entities/teams'; import { - getChannelMembersInChannels, canManageAnyChannelMembersInCurrentTeam, getCurrentChannelId, getChannelByName, + getChannelMember, } from 'mattermost-redux/selectors/entities/channels'; import {getCallsConfig, getCalls} from 'mattermost-redux/selectors/entities/common'; -import {Action} from 'mattermost-redux/types/actions'; +import {GenericAction} from 'mattermost-redux/types/actions'; import {getTeammateNameDisplaySetting} from 'mattermost-redux/selectors/entities/preferences'; import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone'; @@ -75,7 +75,7 @@ function makeMapStateToProps() { const teamMember = getTeamMember(state, team.id, userId); const isTeamAdmin = Boolean(teamMember && teamMember.scheme_admin); - const channelMember = getChannelMembersInChannels(state)?.[channelId]?.[userId]; + const channelMember = getChannelMember(state, channelId, userId); let isChannelAdmin = false; if (getRhsState(state) !== 'search' && channelMember != null && channelMember.scheme_admin) { @@ -135,9 +135,9 @@ type Actions = { getMembershipForEntities: (teamId: string, userId: string, channelId?: string) => Promise; } -function mapDispatchToProps(dispatch: Dispatch) { +function mapDispatchToProps(dispatch: Dispatch) { return { - actions: bindActionCreators, Actions>({ + actions: bindActionCreators({ closeModal, openDirectChannelToUserId, openModal, diff --git a/webapp/channels/src/components/profile_popover/profile_popover.tsx b/webapp/channels/src/components/profile_popover/profile_popover.tsx index 642f77e563..ea0af4753a 100644 --- a/webapp/channels/src/components/profile_popover/profile_popover.tsx +++ b/webapp/channels/src/components/profile_popover/profile_popover.tsx @@ -50,7 +50,7 @@ import BotTag from '../widgets/tag/bot_tag'; import GuestTag from '../widgets/tag/guest_tag'; import Tag from '../widgets/tag/tag'; -interface ProfilePopoverProps extends Omit, 'id'> { +export interface ProfilePopoverProps extends Omit, 'id'> { /** * Source URL from the image to display in the popover diff --git a/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/channels.ts b/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/channels.ts index 92d978c06b..97c715baa3 100644 --- a/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/channels.ts +++ b/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/channels.ts @@ -143,6 +143,10 @@ export function getChannelMembersInChannels(state: GlobalState): RelationOneToOn return state.entities.channels.membersInChannel; } +export function getChannelMember(state: GlobalState, channelId: string, userId: string): ChannelMembership | undefined { + return getChannelMembersInChannels(state)[channelId]?.[userId]; +} + // makeGetChannel returns a selector that returns a channel from the store with the following filled in for DM/GM channels: // - The display_name set to the other user(s) names, following the Teammate Name Display setting // - The teammate_id for DM channels diff --git a/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/teams.ts b/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/teams.ts index 0e0d608eb4..2647b6503b 100644 --- a/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/teams.ts +++ b/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/teams.ts @@ -190,13 +190,8 @@ export const getMembersInCurrentTeam: (state: GlobalState) => RelationOneToOne Array = createIdsSelector(