Skip to content

feat: migrate MessageSearch to PaginatedVirtualList#40844

Open
srijnabhargav wants to merge 3 commits into
RocketChat:developfrom
srijnabhargav:feat/tanstack-message-search
Open

feat: migrate MessageSearch to PaginatedVirtualList#40844
srijnabhargav wants to merge 3 commits into
RocketChat:developfrom
srijnabhargav:feat/tanstack-message-search

Conversation

@srijnabhargav

@srijnabhargav srijnabhargav commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

This PR migrates MessageSearch from react-virtuoso to the shared PaginatedVirtualList component introduced by the Virtua foundation work.

Changes include:

  • Replacing the existing react-virtuoso implementation with PaginatedVirtualList
  • Updating useMessageSearchQuery to useInfiniteQuery with { items, itemCount } for pagination
  • Aligning MessageSearch with the same consumer pattern used in DiscussionsList and ThreadList
  • Removing Virtuoso-specific setup from MessageSearchTab
  • Adding focused Jest coverage for the MessageSearch migration

The goal is to keep MessageSearch consistent with the new virtualization approach while keeping the scope limited to MessageSearch-specific changes.

Issue(s)

Part of the Virtua migration work for the contextual bar lists.

Further comments

This PR should be merged after the Virtua foundation work (PaginatedVirtualList and DiscussionsList migration), #39394, as it reuses the shared virtualization infrastructure introduced there and only contains MessageSearch-specific changes.

Test plan

  • yarn .testunit:jest --testPathPatterns='contextualBar/MessageSearchTab'
  • ESLint on changed MessageSearchTab files
  • yarn typecheck in apps/meteor
  • Manual: search in room contextual bar, scroll/load more, empty state, date dividers

working video (no regressions):

Screen.Recording.2026-03-23.at.12.48.18.AM.mov

Summary by CodeRabbit

  • Refactor
    • Message search rebuilt to use infinite pagination and virtualized rendering for smoother, faster browsing of large result sets.
  • New Features
    • Search tab now shows a consolidated, paginated message results view with proper empty-state and correct handling of system vs. room messages and date dividers.
  • Tests
    • Updated tests to cover empty state, pending state, and message rendering variants.
  • Documentation
    • Added stories demonstrating empty, message, system-message, and multi-date scenarios.

@srijnabhargav srijnabhargav requested a review from a team as a code owner June 8, 2026 13:25
@dionisio-bot

dionisio-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot

changeset-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 2e1baa5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@srijnabhargav srijnabhargav marked this pull request as draft June 8, 2026 13:25
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 87496258-3300-48f9-a206-ee6055e68066

📥 Commits

Reviewing files that changed from the base of the PR and between d01e1da and 2e1baa5.

📒 Files selected for processing (4)
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.stories.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.stories.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
🧠 Learnings (2)
📚 Learning: 2026-03-27T14:52:56.865Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39892
File: apps/meteor/client/views/room/contextualBar/Threads/Thread.tsx:150-155
Timestamp: 2026-03-27T14:52:56.865Z
Learning: In Rocket.Chat, there are two different `ModalBackdrop` components with different prop APIs. During review, confirm the import source: (1) `rocket.chat/fuselage` `ModalBackdrop` uses `ModalBackdropProps` based on `BoxProps` (so it supports `onClick` and other Box/DOM props) and does not have an `onDismiss` prop; (2) `rocket.chat/ui-client` `ModalBackdrop` uses a narrower props interface like `{ children?: ReactNode; onDismiss?: () => void }` and handles Escape keypress and outside mouse-up, and it does not forward arbitrary DOM props such as `onClick`. Flag mismatched props (e.g., `onDismiss` passed to the fuselage component or `onClick` passed to the ui-client component) and ensure the usage matches the correct component being imported.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.stories.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.stories.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
🔇 Additional comments (2)
apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx (1)

1-111: LGTM!

apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.stories.tsx (1)

1-155: LGTM!


Walkthrough

This PR extracts message-search rendering into a new MessageSearch component, converts useMessageSearchQuery to useInfiniteQuery (infinite pagination), and simplifies MessageSearchTab to pass query results and UI context into MessageSearch.

Changes

Message Search Pagination and Component Extraction

Layer / File(s) Summary
Message search query hook to infinite pagination
apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
useMessageSearchQuery migrates from useQuery to useInfiniteQuery, removes the limit parameter in favor of deriving page size from PageSize, implements getNextPageParam, and exports new MessageSearchItem type.
MessageSearchTab delegates to MessageSearch
apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
MessageSearchTab now calls useMessageSearchQuery({ searchText, globalSearch }), derives items/itemCount from the query result, and delegates rendering to the new MessageSearch component.
MessageSearch component implementation
apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
New MessageSearch component renders empty-state when no items, otherwise wraps list in MessageListErrorBoundary/MessageListProvider, uses PaginatedVirtualList for results with day dividers, chooses SystemMessage vs RoomMessage, and computes unread/mention/all from subscription.
Tests and Storybook
apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx, .../MessageSearch.stories.tsx
Adds Jest tests with module mocks and helpers for empty/pending/populated states; adds Storybook stories (Empty, Messages, SystemMessages, MultipleDateGroups) with mocked room/subscription and message fixtures.

Sequence Diagram

sequenceDiagram
  participant MessageSearchTab
  participant MessageSearch
  participant useMessageSearchQuery
  participant PaginatedVirtualList
  MessageSearchTab->>MessageSearch: pass query props & UI context
  MessageSearch->>useMessageSearchQuery: receive paginated data/status
  useMessageSearchQuery-->>MessageSearch: items, itemCount, isPending, isSuccess, fetchNextPage
  MessageSearch->>PaginatedVirtualList: render items, onEndReached -> fetchNextPage
  PaginatedVirtualList->>MessageSearch: trigger fetchNextPage
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

type: feature

Suggested reviewers

  • MartinSchoeler
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: migrate MessageSearch to PaginatedVirtualList' clearly summarizes the main change: migrating from react-virtuoso to PaginatedVirtualList for message search virtualization.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the type: feature Pull requests that introduces new feature label Jun 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
apps/meteor/client/components/VirtualList/VirtuaListContainer.tsx (1)

10-13: ⚡ Quick win

Make style optional in the container props API.

style is currently required in VirtuaListContainerProps, but this component safely handles missing style and HTML style is normally optional. Requiring it makes reuse unnecessarily strict.

 export type VirtuaListContainerProps = {
 	children: ReactNode;
-	style: CSSProperties;
+	style?: CSSProperties;
 } & Omit<HTMLAttributes<HTMLUListElement>, 'children' | 'style'>;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/meteor/client/components/VirtualList/VirtuaListContainer.tsx` around
lines 10 - 13, The props type VirtuaListContainerProps currently marks style as
required; update it to make style optional by changing the declaration from
"style: CSSProperties" to "style?: CSSProperties" in the
VirtuaListContainerProps type (keeping children: ReactNode and the Omit of
HTMLAttributes<HTMLUListElement> intact) so the component API matches how the
component handles missing style and aligns with standard HTML optional style
props.
apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx (1)

30-31: 💤 Low value

Consider lifting query data from MessageSearch to avoid duplicate subscriptions.

Both MessageSearchTab and MessageSearch call useMessageSearchQuery with identical parameters. While React Query deduplicates network requests, both components maintain separate subscriptions. Passing data and query state as props to MessageSearch would reduce overhead, though the current approach is functionally correct.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx`
around lines 30 - 31, MessageSearchTab and MessageSearch both call
useMessageSearchQuery with the same args, causing duplicate React Query
subscriptions; refactor by lifting the query state out of MessageSearch so
MessageSearchTab calls useMessageSearchQuery once (keep const { isSuccess, data,
isPending } = useMessageSearchQuery({ searchText, globalSearch }) and const
itemCount = data?.itemCount ?? 0) and pass the resulting data and state props
(data, isSuccess, isPending, itemCount) into the MessageSearch component instead
of letting MessageSearch call useMessageSearchQuery itself; update
MessageSearch’s props/signature accordingly and remove its internal call to
useMessageSearchQuery.
apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx (1)

82-82: 💤 Low value

Consider memoizing renderItem callback to prevent unnecessary re-renders.

The inline renderItem function creates a new reference on every render. If PaginatedVirtualList uses reference equality checks for optimization, this could cause all visible items to re-render even when discussions, showRealNames, and onClick haven't changed.

♻️ Suggested refactor
+ const renderDiscussionRow = useCallback(
+   (discussion: IDiscussionMessage) => (
+     <DiscussionsListRow discussion={discussion} showRealNames={showRealNames} onClick={onClick} />
+   ),
+   [showRealNames, onClick],
+ );

Then use renderItem={renderDiscussionRow} in the JSX.

Also applies to: 98-108

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx`
at line 82, The inline renderItem passed to PaginatedVirtualList is recreated
each render causing unnecessary re-renders; extract it into a memoized callback
(e.g., create a function named renderDiscussionRow and wrap it with
React.useCallback) and replace the inline renderItem with renderDiscussionRow;
ensure the useCallback dependency array includes only discussions-relevant
values like showRealNames and onClick (and any props used inside) so the
function reference remains stable when those values don't change; apply the same
change for the other renderItem occurrences in this file that render discussion
rows.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/meteor/client/components/VirtualList/VirtuaListContainer.tsx`:
- Around line 10-13: The props type VirtuaListContainerProps currently marks
style as required; update it to make style optional by changing the declaration
from "style: CSSProperties" to "style?: CSSProperties" in the
VirtuaListContainerProps type (keeping children: ReactNode and the Omit of
HTMLAttributes<HTMLUListElement> intact) so the component API matches how the
component handles missing style and aligns with standard HTML optional style
props.

In `@apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx`:
- Line 82: The inline renderItem passed to PaginatedVirtualList is recreated
each render causing unnecessary re-renders; extract it into a memoized callback
(e.g., create a function named renderDiscussionRow and wrap it with
React.useCallback) and replace the inline renderItem with renderDiscussionRow;
ensure the useCallback dependency array includes only discussions-relevant
values like showRealNames and onClick (and any props used inside) so the
function reference remains stable when those values don't change; apply the same
change for the other renderItem occurrences in this file that render discussion
rows.

In
`@apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx`:
- Around line 30-31: MessageSearchTab and MessageSearch both call
useMessageSearchQuery with the same args, causing duplicate React Query
subscriptions; refactor by lifting the query state out of MessageSearch so
MessageSearchTab calls useMessageSearchQuery once (keep const { isSuccess, data,
isPending } = useMessageSearchQuery({ searchText, globalSearch }) and const
itemCount = data?.itemCount ?? 0) and pass the resulting data and state props
(data, isSuccess, isPending, itemCount) into the MessageSearch component instead
of letting MessageSearch call useMessageSearchQuery itself; update
MessageSearch’s props/signature accordingly and remove its internal call to
useMessageSearchQuery.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 83ab1447-f76b-4b87-b211-ca250bd28622

📥 Commits

Reviewing files that changed from the base of the PR and between cb386e9 and 310c396.

⛔ Files ignored due to path filters (1)
  • apps/meteor/client/views/room/contextualBar/Discussions/__snapshots__/DiscussionsList.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (15)
  • apps/meteor/client/components/VirtualList/VirtuaListContainer.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.tsx
  • apps/meteor/client/components/VirtualList/index.ts
  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.stories.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsListContextBar.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.stories.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/components/VirtualList/VirtuaListContainer.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.stories.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsListContextBar.tsx
  • apps/meteor/client/components/VirtualList/index.ts
  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.stories.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
🧠 Learnings (31)
📓 Common learnings
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 40755
File: apps/meteor/client/views/room/MessageList/MessageList.tsx:84-94
Timestamp: 2026-06-02T13:27:22.143Z
Learning: In `apps/meteor/client/views/room/MessageList/MessageList.tsx`, the keep-at-bottom `useEffect` intentionally calls `virtualizerRef.current.scrollToIndex(messagesLength, { align: 'end' })` where `messagesLength` is one past the last rendered item index. Using `messagesLength - 1` was tested and caused incorrect scroll positioning. The out-of-bounds index is clamped by Virtua to `itemCount - 1` (last item) — this is intentional and relies on documented stable behavior of the Virtua library. Do not flag this as a bug.
📚 Learning: 2026-06-02T13:27:22.143Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 40755
File: apps/meteor/client/views/room/MessageList/MessageList.tsx:84-94
Timestamp: 2026-06-02T13:27:22.143Z
Learning: In `apps/meteor/client/views/room/MessageList/MessageList.tsx`, the keep-at-bottom `useEffect` intentionally calls `virtualizerRef.current.scrollToIndex(messagesLength, { align: 'end' })` where `messagesLength` is one past the last rendered item index. Using `messagesLength - 1` was tested and caused incorrect scroll positioning. The out-of-bounds index is clamped by Virtua to `itemCount - 1` (last item) — this is intentional and relies on documented stable behavior of the Virtua library. Do not flag this as a bug.

Applied to files:

  • apps/meteor/client/components/VirtualList/VirtuaListContainer.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsListContextBar.tsx
  • apps/meteor/client/components/VirtualList/index.ts
  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-03-27T14:52:56.865Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39892
File: apps/meteor/client/views/room/contextualBar/Threads/Thread.tsx:150-155
Timestamp: 2026-03-27T14:52:56.865Z
Learning: In Rocket.Chat, there are two different `ModalBackdrop` components with different prop APIs. During review, confirm the import source: (1) `rocket.chat/fuselage` `ModalBackdrop` uses `ModalBackdropProps` based on `BoxProps` (so it supports `onClick` and other Box/DOM props) and does not have an `onDismiss` prop; (2) `rocket.chat/ui-client` `ModalBackdrop` uses a narrower props interface like `{ children?: ReactNode; onDismiss?: () => void }` and handles Escape keypress and outside mouse-up, and it does not forward arbitrary DOM props such as `onClick`. Flag mismatched props (e.g., `onDismiss` passed to the fuselage component or `onClick` passed to the ui-client component) and ensure the usage matches the correct component being imported.

Applied to files:

  • apps/meteor/client/components/VirtualList/VirtuaListContainer.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.stories.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsListContextBar.tsx
  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.stories.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.

Applied to files:

  • apps/meteor/client/components/VirtualList/VirtuaListContainer.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.stories.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsListContextBar.tsx
  • apps/meteor/client/components/VirtualList/index.ts
  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.stories.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-02-24T19:36:55.089Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').

Applied to files:

  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.stories.tsx
  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.stories.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.stories.tsx
📚 Learning: 2026-02-10T16:32:42.586Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38528
File: apps/meteor/client/startup/roles.ts:14-14
Timestamp: 2026-02-10T16:32:42.586Z
Learning: In Rocket.Chat's Meteor client code, DDP streams use EJSON and Date fields arrive as Date objects; do not manually construct new Date() in stream handlers (for example, in sdk.stream()). Only REST API responses return plain JSON where dates are strings, so implement explicit conversion there if needed. Apply this guidance to all TypeScript files under apps/meteor/client to ensure consistent date handling in DDP streams and REST responses.

Applied to files:

  • apps/meteor/client/components/VirtualList/index.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2026-05-11T20:30:35.265Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 40480
File: apps/meteor/client/meteor/startup/accounts.ts:59-61
Timestamp: 2026-05-11T20:30:35.265Z
Learning: In Rocket.Chat’s Meteor client code, when calling `dispatchToastMessage` with `{ type: 'error' }`, pass the raw caught error object as `message` without manual normalization. `dispatchToastMessage` is designed to accept `message: unknown` for error toasts, so avoid converting errors to strings (e.g., `String(error)`) or extracting `error.message` before passing them.

Applied to files:

  • apps/meteor/client/components/VirtualList/index.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/client/components/VirtualList/index.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/client/components/VirtualList/index.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2026-04-17T18:33:27.211Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 39858
File: apps/meteor/tests/e2e/apps/uikit-interactions.spec.ts:123-151
Timestamp: 2026-04-17T18:33:27.211Z
Learning: In RocketChat/Rocket.Chat (`apps/meteor/tests/e2e/apps/uikit-interactions.spec.ts`), `executeBlockActionHandler` invocations originating from a **modal** surface intentionally do NOT include a `block_action_room` (room property) in the interaction payload. Modals are not scoped to a room, so no room id is available in that context. Do not flag the absence of a room assertion in the modal block-action test as a missing coverage bug; instead, document it explicitly with a `test.step` asserting the room entry is `undefined`.

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.stories.tsx
📚 Learning: 2025-12-10T21:00:54.909Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37091
File: ee/packages/abac/jest.config.ts:4-7
Timestamp: 2025-12-10T21:00:54.909Z
Learning: Rocket.Chat monorepo: Jest testMatch pattern '<rootDir>/src/**/*.spec.(ts|js|mjs)' is valid in this repo and used across multiple packages (e.g., packages/tools, ee/packages/omnichannel-services). Do not flag it as invalid in future reviews.

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-12-16T17:29:45.163Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37834
File: apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-emoji.ts:12-22
Timestamp: 2025-12-16T17:29:45.163Z
Learning: In page object files under `apps/meteor/tests/e2e/page-objects/`, always import `expect` from `../../utils/test` (Playwright's async expect), not from Jest. Jest's `expect` has a synchronous signature and will cause TypeScript errors when used with web-first assertions like `toBeVisible()`.

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
📚 Learning: 2026-03-11T22:04:20.529Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 39545
File: apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts:59-61
Timestamp: 2026-03-11T22:04:20.529Z
Learning: In `apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts`, the `msg.u._id === uid` early-return in the `streamNewMessage` handler is intentional: the "New messages" indicator is designed to notify about messages from other users only. Self-sent messages — including those sent from a different session/device — are always skipped, by design. Do not flag this as a multi-session regression.

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Prefer web-first assertions (`toBeVisible`, `toHaveText`, etc.) in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
📚 Learning: 2026-03-06T18:10:15.268Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/code/CodeBlock.spec.tsx:47-68
Timestamp: 2026-03-06T18:10:15.268Z
Learning: In tests (especially those using testing-library/dom/jsdom) for Rocket.Chat components, the HTML <code> element has an implicit ARIA role of 'code'. Therefore, screen.getByRole('code') or screen.findByRole('code') will locate <code> elements even without a role attribute. Do not flag findByRole('code') as invalid in reviews; prefer using the implicit role instead of adding role="code" unless necessary for accessibility.

Applied to files:

  • apps/meteor/client/views/room/MessageList/MessageList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `test.step()` for complex test scenarios to improve organization in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx
  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.spec.ts : Use descriptive test names that clearly communicate expected behavior in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
📚 Learning: 2026-05-26T19:18:05.882Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 40644
File: apps/meteor/client/views/room/contextualBar/Threads/components/ThreadMessageList.tsx:145-147
Timestamp: 2026-05-26T19:18:05.882Z
Learning: In `apps/meteor/client/views/room/contextualBar/Threads/components/ThreadMessageList.tsx`, the `clearMsgJumpParam` cleanup in the timed effect (around line 145) intentionally clears the `msg` query parameter only when the target message IS found in `messages` (thread replies) and is not `mainMessage._id`. This is correct behavior: if `msgJumpParam` refers to a non-reply message (e.g., a main channel message), the main message list handles cleanup, so `ThreadMessageList` must not clear the param in that case.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-04-28T14:08:46.920Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 40105
File: apps/meteor/client/views/room/MessageList/hooks/useTryToJumpToMessage.ts:54-67
Timestamp: 2026-04-28T14:08:46.920Z
Learning: In `apps/meteor/client/views/room/MessageList/hooks/useTryToJumpToMessage.ts`, setting `isJumpingToMessage.current = true` before the guard clauses (RoomHistoryManager.isLoading check, message not found check) is intentional. The flag means "a jump is pending/in progress" and must stay `true` through all intermediate early-return paths (loading, unresolved message, etc.) so that downstream scroll and load behavior is suppressed while waiting for the jump conditions to be satisfied. Do not flag this as a "flag stuck true" bug.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-04-29T20:06:34.862Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 40268
File: apps/meteor/client/startup/incomingMessages.ts:21-25
Timestamp: 2026-04-29T20:06:34.862Z
Learning: In `apps/meteor/client/startup/incomingMessages.ts`, the `Messages.state.update` predicate that strips `ignored` from records when `'ignored' in sub` is false (i.e., the subscription update has no `ignored` field) is intentional. Absence of `ignored` in a `subscriptions-changed` event means the user's ignore list is empty/reset, so clearing all existing `ignored` flags on messages for that room is the correct behavior. Do not flag this as an unintentional ignored-state reset on unrelated subscription updates.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-05-05T16:51:36.461Z
Learnt from: nazabucciarelli
Repo: RocketChat/Rocket.Chat PR: 40306
File: apps/meteor/client/views/room/MessageList/hooks/useMessageBody.tsx:18-30
Timestamp: 2026-05-05T16:51:36.461Z
Learning: In Rocket.Chat, the `useMaxMarkdownParseLength` hook (in `apps/meteor/client/components/message/hooks/useMaxMarkdownParseLength.ts`) already normalizes values `<= 0` (or missing/non-numeric) to `Infinity`. Consumers like `useMessageBody` and `useNormalizedMessage` can safely use `message.msg.length > maxMarkdownParseLength` without an extra `maxMarkdownParseLength > 0` guard, because `length > Infinity` is always `false`.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • apps/meteor/client/components/VirtualList/VirtualList.spec.tsx
📚 Learning: 2025-11-19T18:20:07.720Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: packages/i18n/src/locales/en.i18n.json:918-921
Timestamp: 2025-11-19T18:20:07.720Z
Learning: Repo: RocketChat/Rocket.Chat — i18n/formatting
Learning: This repository uses a custom message formatting parser in UI blocks/messages; do not assume standard Markdown rules. For keys like Call_ended_bold, Call_not_answered_bold, Call_failed_bold, and Call_transferred_bold in packages/i18n/src/locales/en.i18n.json, retain the existing single-asterisk emphasis unless maintainers request otherwise.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-05-06T20:49:27.193Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 40186
File: packages/apps-engine/src/definition/externalComponent/IExternalComponentRoomInfo.ts:15-15
Timestamp: 2026-05-06T20:49:27.193Z
Learning: In the RocketChat/Rocket.Chat repository, the ExternalComponents feature (related to IExternalComponentRoomInfo, IExternalComponentUserInfo, and IExternalComponentState in packages/apps-engine/src/definition/externalComponent/) is deprecated and unreachable. Do not flag performance or API design concerns for code in this feature area.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
🔇 Additional comments (16)
apps/meteor/client/views/room/MessageList/MessageList.spec.tsx (1)

21-21: LGTM!

apps/meteor/client/components/VirtualList/index.ts (1)

1-1: LGTM!

apps/meteor/client/components/VirtualList/VirtualList.tsx (1)

1-110: LGTM!

apps/meteor/client/components/VirtualList/VirtualList.spec.tsx (1)

1-217: LGTM!

apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.stories.tsx (1)

4-4: LGTM!

Also applies to: 8-13, 23-23

apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.spec.tsx (1)

2-2: LGTM!

Also applies to: 4-7, 16-117

apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.stories.tsx (1)

8-9: LGTM!

apps/meteor/client/views/room/contextualBar/Discussions/components/DiscussionsListItem.tsx (1)

44-44: LGTM!

apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts (1)

1-42: LGTM!

apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx (1)

1-93: LGTM!

apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx (1)

1-110: LGTM!

apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx (1)

1-67: LGTM!

apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsList.tsx (3)

3-3: LGTM!

Also applies to: 15-15, 22-22


28-28: LGTM!


56-62: LGTM!

apps/meteor/client/views/room/contextualBar/Discussions/DiscussionsListContextBar.tsx (1)

47-47: LGTM!

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 16 files

Re-trigger cubic

@srijnabhargav srijnabhargav force-pushed the feat/tanstack-message-search branch from 310c396 to a73e172 Compare June 8, 2026 17:58
@srijnabhargav srijnabhargav marked this pull request as ready for review June 8, 2026 17:59

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Re-trigger cubic

@MartinSchoeler MartinSchoeler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scroll bar does not show up in the search message list for me, it seems the parents are stretching to the height of the list. Check if any of the parent's aren't missing a height attribute

@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.90164% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.03%. Comparing base (db0b1ad) to head (2e1baa5).
⚠️ Report is 105 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #40844      +/-   ##
===========================================
- Coverage    70.19%   70.03%   -0.17%     
===========================================
  Files         3340     3370      +30     
  Lines       123638   129375    +5737     
  Branches     22055    22552     +497     
===========================================
+ Hits         86789    90608    +3819     
- Misses       33507    35499    +1992     
+ Partials      3342     3268      -74     
Flag Coverage Δ
unit 69.99% <100.00%> (-1.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot removed the type: feature Pull requests that introduces new feature label Jun 11, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts (1)

29-35: Clarify paging semantics: client is using cumulative “top-N” (not offset pages), so select-last-page is consistent

  • getNextPageParam increases limit cumulatively (e.g., 10 → 20 → 30), so each query asks for the first N results again.
  • On the server, DefaultProvider.search() forwards only payload.limit to messageSearch (no offset), and parseMessageSearchQuery applies Mongo skip: offset with offset defaulting to 0 and limit to the provided value—so every call returns skip(0).limit(limit) results (top-N).
  • Given that each page already contains results from the beginning up to N, select: pages.at(-1) returning only the last page avoids duplicates (flattening would repeat items).
  • itemCount: items.length >= limit ? items.length + 1 : items.length matches the “full page means maybe more” behavior for this top-N approach.

Optional: if you want real incremental infinite-scroll (no re-fetching earlier results), add end-to-end offset/cursor paging support (client payload → provider forwarding → Mongo query) and update getNextPageParam to advance by offset instead of cumulatively increasing limit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts`
around lines 29 - 35, The paging is using a cumulative "top-N" approach rather
than offsets, so update the client logic to make this explicit: keep
getNextPageParam in useMessageSearchQuery to continue increasing the requested
limit cumulatively (e.g., 10→20→30) and ensure the consumer of the query (the
select that picks pages.at(-1)) continues to return only the last page to avoid
duplicates; also confirm itemCount logic (items.length >= limit ? items.length +
1 : items.length) matches the "full page means maybe more" behavior. If you
instead want true incremental paging, implement end-to-end offset/cursor passing
(client payload → DefaultProvider.search forwarding → parseMessageSearchQuery
applying skip) and change getNextPageParam to advance by offset rather than
increasing limit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts`:
- Around line 23-26: The return value from the hook useMessageSearchQuery
currently sets itemCount to items.length + 1 when items.length >= limit which
misrepresents total results; change the hook to return a clear pair such as {
items, itemCount: items.length, hasMore: items.length >= limit } (or rename
itemCount to loadedCount and add hasMore) and update consumers
(MessageSearchTab.tsx -> ResultsLiveRegion and PaginatedVirtualList) to use
itemCount/loadedCount for announced/virtualized counts and use hasMore to
indicate "more available" UI/ARIA cues instead of relying on a +1 heuristic.

In
`@apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx`:
- Around line 30-31: The screen reader announces data.itemCount (from
useMessageSearchQuery) which may be a "+1 if more" heuristic; change
MessageSearchTab to pass the actual number of loaded items to ResultsLiveRegion
instead of the heuristic value and also pass a boolean flag indicating "more
available" (e.g., compute loadedCount = data?.items?.length ?? 0 and hasMore =
(data?.itemCount ?? 0) > loadedCount), then update ResultsLiveRegion usage to
announce "X results, more available" or similar based on loadedCount and
hasMore; reference useMessageSearchQuery, data.itemCount, ResultsLiveRegion and
the local itemCount variable to locate where to adjust.

---

Nitpick comments:
In
`@apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts`:
- Around line 29-35: The paging is using a cumulative "top-N" approach rather
than offsets, so update the client logic to make this explicit: keep
getNextPageParam in useMessageSearchQuery to continue increasing the requested
limit cumulatively (e.g., 10→20→30) and ensure the consumer of the query (the
select that picks pages.at(-1)) continues to return only the last page to avoid
duplicates; also confirm itemCount logic (items.length >= limit ? items.length +
1 : items.length) matches the "full page means maybe more" behavior. If you
instead want true incremental paging, implement end-to-end offset/cursor passing
(client payload → DefaultProvider.search forwarding → parseMessageSearchQuery
applying skip) and change getNextPageParam to advance by offset rather than
increasing limit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e9966c89-fd2d-4575-bb7e-64d0a2e674e1

📥 Commits

Reviewing files that changed from the base of the PR and between 310c396 and d01e1da.

📒 Files selected for processing (4)
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
🧠 Learnings (7)
📚 Learning: 2026-03-06T18:10:15.268Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/code/CodeBlock.spec.tsx:47-68
Timestamp: 2026-03-06T18:10:15.268Z
Learning: In tests (especially those using testing-library/dom/jsdom) for Rocket.Chat components, the HTML <code> element has an implicit ARIA role of 'code'. Therefore, screen.getByRole('code') or screen.findByRole('code') will locate <code> elements even without a role attribute. Do not flag findByRole('code') as invalid in reviews; prefer using the implicit role instead of adding role="code" unless necessary for accessibility.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
📚 Learning: 2026-03-27T14:52:56.865Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39892
File: apps/meteor/client/views/room/contextualBar/Threads/Thread.tsx:150-155
Timestamp: 2026-03-27T14:52:56.865Z
Learning: In Rocket.Chat, there are two different `ModalBackdrop` components with different prop APIs. During review, confirm the import source: (1) `rocket.chat/fuselage` `ModalBackdrop` uses `ModalBackdropProps` based on `BoxProps` (so it supports `onClick` and other Box/DOM props) and does not have an `onDismiss` prop; (2) `rocket.chat/ui-client` `ModalBackdrop` uses a narrower props interface like `{ children?: ReactNode; onDismiss?: () => void }` and handles Escape keypress and outside mouse-up, and it does not forward arbitrary DOM props such as `onClick`. Flag mismatched props (e.g., `onDismiss` passed to the fuselage component or `onClick` passed to the ui-client component) and ensure the usage matches the correct component being imported.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx
📚 Learning: 2026-02-10T16:32:42.586Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38528
File: apps/meteor/client/startup/roles.ts:14-14
Timestamp: 2026-02-10T16:32:42.586Z
Learning: In Rocket.Chat's Meteor client code, DDP streams use EJSON and Date fields arrive as Date objects; do not manually construct new Date() in stream handlers (for example, in sdk.stream()). Only REST API responses return plain JSON where dates are strings, so implement explicit conversion there if needed. Apply this guidance to all TypeScript files under apps/meteor/client to ensure consistent date handling in DDP streams and REST responses.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2026-05-11T20:30:35.265Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 40480
File: apps/meteor/client/meteor/startup/accounts.ts:59-61
Timestamp: 2026-05-11T20:30:35.265Z
Learning: In Rocket.Chat’s Meteor client code, when calling `dispatchToastMessage` with `{ type: 'error' }`, pass the raw caught error object as `message` without manual normalization. `dispatchToastMessage` is designed to accept `message: unknown` for error toasts, so avoid converting errors to strings (e.g., `String(error)`) or extracting `error.message` before passing them.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts
🔇 Additional comments (3)
apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearch.spec.tsx (1)

1-124: LGTM!

apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx (1)

51-52: LGTM!

apps/meteor/client/views/room/contextualBar/MessageSearchTab/hooks/useMessageSearchQuery.ts (1)

36-36: Fix: select should keep pages.at(-1) because paging is cumulative (limit increases, offset stays 0).

useMessageSearchQuery only passes { limit, searchAll } (no offset). On the server, messageSearch uses parseMessageSearchQuery where skip defaults to offset (default 0) and limit is set from the passed limit, so each next page returns “first N results”. Taking pages.at(-1) returns the full accumulated list; flattening would duplicate earlier items.

			> Likely an incorrect or invalid review comment.

Comment thread apps/meteor/client/views/room/contextualBar/MessageSearchTab/MessageSearchTab.tsx Outdated
@coderabbitai coderabbitai Bot added the type: feature Pull requests that introduces new feature label Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community type: feature Pull requests that introduces new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants