From 77bf047c552c3b227f1a88e1ec3916262b8ab713 Mon Sep 17 00:00:00 2001 From: Julien Tant <785518+JulienTant@users.noreply.github.com> Date: Tue, 15 Apr 2025 08:06:27 -0700 Subject: [PATCH] [MM-63664] Fix mentions not paginating (#30671) --- .../mentions/multiple_mentions.spec.ts | 67 +++++++++++++++++++ .../channels/src/components/search/search.tsx | 14 +++- webapp/channels/src/selectors/rhs.ts | 8 ++- 3 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 e2e-tests/playwright/specs/functional/channels/mentions/multiple_mentions.spec.ts diff --git a/e2e-tests/playwright/specs/functional/channels/mentions/multiple_mentions.spec.ts b/e2e-tests/playwright/specs/functional/channels/mentions/multiple_mentions.spec.ts new file mode 100644 index 0000000000..9e4d58ae8b --- /dev/null +++ b/e2e-tests/playwright/specs/functional/channels/mentions/multiple_mentions.spec.ts @@ -0,0 +1,67 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {expect, test} from '@mattermost/playwright-lib'; + +test('Multiple user mentions test', async ({pw}) => { + const MENTION_COUNT = 20; + + const { + team, + user: mentioningUser, + userClient, + } = await pw.initSetup({ + userPrefix: 'mentioner', + }); + + // # Create a second user to be mentioned + const {adminClient} = await pw.getAdminClient(); + const mentionedUser = pw.random.user('mentioned'); + const {id: mentionedUserID} = await adminClient.createUser(mentionedUser, '', ''); + + await adminClient.addToTeam(team.id, mentionedUserID); + + // Get the town-square channel data + const channels = await userClient.getMyChannels(team.id); + const townSquare = channels.find((channel) => channel.name === 'town-square'); + + if (!townSquare) { + throw new Error('Town Square channel not found'); + } + + // Use API to create all the mention posts + for (let i = 0; i < MENTION_COUNT; i++) { + const message = `Hey @${mentionedUser.username}, this is mention #${i + 1}`; + await userClient.createPost({ + channel_id: townSquare.id, + message, + user_id: mentioningUser.id, + }); + } + + // Login as the mentioned user to check mentions in the UI + const {page: mentionedPage, channelsPage: mentionedChannelsPage} = await pw.testBrowser.login(mentionedUser); + await mentionedChannelsPage.goto(team.name, 'town-square'); + await mentionedChannelsPage.toBeVisible(); + + // Click on the Recent Mentions button in the channel header + await mentionedPage.getByRole('button', {name: 'Recent mentions'}).click(); + + // Wait for the RHS panel to be visible first + await mentionedChannelsPage.sidebarRight.toBeVisible(); + + // Get all the mention posts in the RHS + const mentionPosts = mentionedChannelsPage.sidebarRight.container.locator('.post'); + + // Verify we have the expected number of mention posts + // Note: RHS might not load all 100 at once due to pagination, so we'll check + // a sufficient number is loaded (at least the first page) + await expect(mentionPosts).toHaveCount(MENTION_COUNT); + + // Verify the content of the first few mentions (most recent first) + for (let i = 0; i < MENTION_COUNT; i++) { + const mentionNumber = MENTION_COUNT - i; + const expectedText = `Hey @${mentionedUser.username}, this is mention #${mentionNumber}`; + await expect(mentionPosts.nth(i)).toContainText(expectedText); + } +}); diff --git a/webapp/channels/src/components/search/search.tsx b/webapp/channels/src/components/search/search.tsx index 896ecd0241..b4afc7a313 100644 --- a/webapp/channels/src/components/search/search.tsx +++ b/webapp/channels/src/components/search/search.tsx @@ -174,11 +174,19 @@ const Search: React.FC = (props: Props): JSX.Element => { }, [isMobileView, searchTerms]); const getMorePostsForSearch = useCallback(() => { - props.actions.getMorePostsForSearch(searchTeam); - }, [searchTeam, props.actions]); + let team = searchTeam; + if (props.isMentionSearch) { + team = ''; + } + props.actions.getMorePostsForSearch(team); + }, [searchTeam, props.actions, props.isMentionSearch]); const getMoreFilesForSearch = useCallback(() => { - props.actions.getMoreFilesForSearch(searchTeam); + let team = searchTeam; + if (props.isMentionSearch) { + team = ''; + } + props.actions.getMoreFilesForSearch(team); }, [searchTeam, props.actions]); // handle cloding of rhs-flyout diff --git a/webapp/channels/src/selectors/rhs.ts b/webapp/channels/src/selectors/rhs.ts index 534553f78b..b72d44295b 100644 --- a/webapp/channels/src/selectors/rhs.ts +++ b/webapp/channels/src/selectors/rhs.ts @@ -13,7 +13,7 @@ import {makeGetGlobalItem, makeGetGlobalItemWithDefault} from 'selectors/storage import type {SidebarSize} from 'components/resizable_sidebar/constants'; -import {PostTypes, StoragePrefixes} from 'utils/constants'; +import {PostTypes, RHSStates, StoragePrefixes} from 'utils/constants'; import {localizeMessage} from 'utils/utils'; import type {GlobalState} from 'types/store'; @@ -113,8 +113,10 @@ export const getCurrentSearchForSearchTeam: (state: GlobalState) => Record state.entities.search.current, getSearchTeam, - (current, teamId) => { - return current[teamId || 'ALL_TEAMS']; + (state: GlobalState) => getRhsState(state) === RHSStates.MENTION, + (current, teamId, isMentionSearch) => { + const team = isMentionSearch ? 'ALL_TEAMS' : teamId || 'ALL_TEAMS'; + return current[team]; }, );