-
Notifications
You must be signed in to change notification settings - Fork 12.6k
feat: Added invitation badge to room members list #37643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
|
Looks like this PR is not ready to merge, because of the following issues:
Please fix the issues and try again If you have any trouble, please check the PR guidelines |
|
WalkthroughIntroduces an InvitationBadge component that displays a mail icon with invitation date formatting. Updates room member-related components and types to support propagating and displaying the invited status, includes Storybook stories and tests for the new component, and adds a translation key for the feature. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
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 (2)
apps/meteor/client/views/room/contextualBar/RoomMembers/types.ts (1)
1-6: SharedRoomMemberUsertype looks correct; consider reusingIUser['roles']to avoid duplicationThe alias cleanly centralizes the member shape and the
status?: UserStatus | SubscriptionStatusunion fits the invited-member use case.You can make the
rolestyping more robust (and drop theIRoleimport) by reusing the existingIUser.rolesdefinition instead of duplicatingIRole['_id'][]:-import type { IUser, IRole, SubscriptionStatus, UserStatus } from '@rocket.chat/core-typings'; - -export type RoomMemberUser = Pick<IUser, 'username' | '_id' | 'name' | 'freeSwitchExtension' | 'federated'> & { - roles?: IRole['_id'][]; - status?: UserStatus | SubscriptionStatus; -}; +import type { IUser, SubscriptionStatus, UserStatus } from '@rocket.chat/core-typings'; + +export type RoomMemberUser = Pick<IUser, 'username' | '_id' | 'name' | 'freeSwitchExtension' | 'federated'> & + Partial<Pick<IUser, 'roles'>> & { + status?: UserStatus | SubscriptionStatus; + };apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.stories.tsx (1)
96-96: ClarifyisABACRoomconfiguration.Setting
isABACRoom: truein the invited member story appears unrelated to the invitation feature. This should likely befalseto isolate the invitation badge functionality, unless ABAC rooms have specific invitation behavior.Consider applying this diff if ABAC is not relevant to the invitation scenario:
reload: action('reload'), - isABACRoom: true, + isABACRoom: false, };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
apps/meteor/client/views/room/contextualBar/RoomMembers/__snapshots__/RoomMembers.spec.tsx.snapis excluded by!**/*.snap
📒 Files selected for processing (7)
apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.stories.tsx(1 hunks)apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsx(2 hunks)apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsx(3 hunks)apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersRow.tsx(2 hunks)apps/meteor/client/views/room/contextualBar/RoomMembers/badges/InvitationBadge.tsx(1 hunks)apps/meteor/client/views/room/contextualBar/RoomMembers/types.ts(1 hunks)packages/i18n/src/locales/en.i18n.json(1 hunks)
🧰 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/RoomMembers/types.tsapps/meteor/client/views/room/contextualBar/RoomMembers/badges/InvitationBadge.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.stories.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersRow.tsx
🧠 Learnings (7)
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.
Applied to files:
apps/meteor/client/views/room/contextualBar/RoomMembers/types.tsapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersRow.tsx
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.
Applied to files:
apps/meteor/client/views/room/contextualBar/RoomMembers/types.tsapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersRow.tsx
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.
Applied to files:
apps/meteor/client/views/room/contextualBar/RoomMembers/types.tsapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersRow.tsx
📚 Learning: 2025-11-17T15:07:13.273Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37398
File: packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx:357-363
Timestamp: 2025-11-17T15:07:13.273Z
Learning: In packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx, IconElement is a presentational, non-actionable element that does not require wrapping in AppIdProvider, similar to plain_text and mrkdwn renderers. Only actionable elements (those with actions, actionId, or interactive behavior) should be wrapped in AppIdProvider.
Applied to files:
apps/meteor/client/views/room/contextualBar/RoomMembers/badges/InvitationBadge.tsx
📚 Learning: 2025-11-19T12:32:29.696Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37547
File: packages/i18n/src/locales/en.i18n.json:634-634
Timestamp: 2025-11-19T12:32:29.696Z
Learning: Repo: RocketChat/Rocket.Chat
Context: i18n workflow
Learning: In this repository, new translation keys should be added to packages/i18n/src/locales/en.i18n.json only; other locale files are populated via the external translation pipeline and/or fall back to English. Do not request adding the same key to all locale files in future reviews.
Applied to files:
packages/i18n/src/locales/en.i18n.json
📚 Learning: 2025-11-27T17:56:26.050Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37557
File: apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx:115-116
Timestamp: 2025-11-27T17:56:26.050Z
Learning: In Rocket.Chat, the GET /v1/abac/rooms endpoint (implemented in ee/packages/abac/src/index.ts) only returns rooms where abacAttributes exists and is not an empty array (query: { abacAttributes: { $exists: true, $ne: [] } }). Therefore, in components consuming this endpoint (like AdminABACRooms.tsx), room.abacAttributes is guaranteed to be defined for all returned rooms, and optional chaining before calling array methods like .join() is sufficient without additional null coalescing.
Applied to files:
apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsxapps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsx
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: UserBridge.doGetUserRoomIds in packages/apps-engine/src/server/bridges/UserBridge.ts has a bug where it implicitly returns undefined when the app lacks read permission (missing return statement in the else case of the permission check).
Applied to files:
apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsx
🧬 Code graph analysis (2)
apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsx (2)
apps/meteor/client/views/room/contextualBar/RoomMembers/types.ts (1)
RoomMemberUser(3-6)packages/core-typings/src/IRoom.ts (1)
IRoom(21-95)
apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersRow.tsx (1)
apps/meteor/client/views/room/contextualBar/RoomMembers/types.ts (1)
RoomMemberUser(3-6)
🔇 Additional comments (4)
apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersRow.tsx (1)
1-41: LGTM! Type refactoring is clean.The migration from local type definition to centralized
RoomMemberUsertype improves maintainability, and the newstatusprop is correctly wired toRoomMembersItem.apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsx (1)
1-12: LGTM! Type centralization is consistent.Moving the
RoomMemberUsertype to a dedicated types module improves code organization and reusability.apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsx (1)
19-20: LGTM! Invitation badge integration is well-structured.The component correctly:
- Uses the centralized
RoomMemberUsertype- Conditionally renders
InvitationBadgefor invited members- Wraps the badge in
OptionColumnfor proper layoutThe string literal comparison
status === 'INVITED'should be verified to match the enum definition (see verification comment in the stories file).Also applies to: 25-30, 37-37, 63-67
apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.stories.tsx (1)
82-82: Remove this comment—'INVITED' is a valid SubscriptionStatus value.SubscriptionStatus is defined as
type SubscriptionStatus = 'INVITED'in packages/core-typings/src/ISubscription.ts. The status value in the story correctly uses this type.
apps/meteor/client/views/room/contextualBar/RoomMembers/badges/InvitationBadge.tsx
Outdated
Show resolved
Hide resolved
02ef424 to
432d3b1
Compare
432d3b1 to
2b81d46
Compare
b2cc5c0 to
0d14b19
Compare
cd472aa to
8316778
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #37643 +/- ##
===========================================
- Coverage 67.70% 67.70% -0.01%
===========================================
Files 3452 3453 +1
Lines 113975 113979 +4
Branches 20940 20943 +3
===========================================
- Hits 77168 77165 -3
- Misses 34678 34686 +8
+ Partials 2129 2128 -1
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
dba8733 to
85183c9
Compare
85183c9 to
aa7354e
Compare
bc5722b to
9c7345e
Compare
c420eb2 to
36e006f
Compare
9c7345e to
b243f28
Compare
36e006f to
65ca437
Compare
b243f28 to
2fe6480
Compare
fddb5b3 to
cb7d33a
Compare
3591e8f to
78f37b5
Compare
2fe6480 to
ffa1368
Compare
ffa1368 to
fd8054d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
apps/meteor/client/components/InvitationBadge/InvitationBadge.tsx (2)
11-14: Consider handling undefined invitationDate.When
invitationDateis undefined,formattedDatebecomes an empty string, resulting in a translated label like "Invited " with no actual date. Consider whether the component should render at all wheninvitationDateis not provided, or if the translation should handle this case differently.If the component shouldn't render without a date, apply this diff:
const InvitationBadge = ({ invitationDate, ...props }: InvitationBadgeProps) => { const { t } = useTranslation(); const timeAgo = useTimeAgo(); + + if (!invitationDate) { + return null; + } + - const formattedDate = invitationDate ? timeAgo(invitationDate) : ''; + const formattedDate = timeAgo(invitationDate);
16-27: Remove redundant aria-hidden and optimize translation call.Two minor optimizations:
aria-hidden='false'is redundant as it's the default value for Icon components.- The translation
t('Invited__date__', { date: formattedDate })is called twice for bothtitleandaria-label.Apply this diff:
const InvitationBadge = ({ invitationDate, ...props }: InvitationBadgeProps) => { const { t } = useTranslation(); const timeAgo = useTimeAgo(); const formattedDate = invitationDate ? timeAgo(invitationDate) : ''; + const label = t('Invited__date__', { date: formattedDate }); return ( <Icon size='x20' {...props} role='status' color='info' name='mail' - aria-hidden='false' - title={t('Invited__date__', { date: formattedDate })} - aria-label={t('Invited__date__', { date: formattedDate })} + title={label} + aria-label={label} /> ); };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
apps/meteor/client/components/InvitationBadge/__snapshots__/InvitationBadge.spec.tsx.snapis excluded by!**/*.snap
📒 Files selected for processing (5)
apps/meteor/client/components/InvitationBadge/InvitationBadge.spec.tsx(1 hunks)apps/meteor/client/components/InvitationBadge/InvitationBadge.stories.tsx(1 hunks)apps/meteor/client/components/InvitationBadge/InvitationBadge.tsx(1 hunks)apps/meteor/client/components/InvitationBadge/index.ts(1 hunks)apps/meteor/client/views/hooks/useMembersList.ts(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/meteor/client/components/InvitationBadge/index.ts
🧰 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/InvitationBadge/InvitationBadge.tsxapps/meteor/client/components/InvitationBadge/InvitationBadge.spec.tsxapps/meteor/client/components/InvitationBadge/InvitationBadge.stories.tsxapps/meteor/client/views/hooks/useMembersList.ts
🧠 Learnings (15)
📚 Learning: 2025-11-17T15:07:13.273Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37398
File: packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx:357-363
Timestamp: 2025-11-17T15:07:13.273Z
Learning: In packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx, IconElement is a presentational, non-actionable element that does not require wrapping in AppIdProvider, similar to plain_text and mrkdwn renderers. Only actionable elements (those with actions, actionId, or interactive behavior) should be wrapped in AppIdProvider.
Applied to files:
apps/meteor/client/components/InvitationBadge/InvitationBadge.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/components/InvitationBadge/InvitationBadge.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/components/InvitationBadge/InvitationBadge.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 : All test files must be created in `apps/meteor/tests/e2e/` directory
Applied to files:
apps/meteor/client/components/InvitationBadge/InvitationBadge.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/components/InvitationBadge/InvitationBadge.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/components/InvitationBadge/InvitationBadge.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/components/InvitationBadge/InvitationBadge.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 : Prefer web-first assertions (`toBeVisible`, `toHaveText`, etc.) in Playwright tests
Applied to files:
apps/meteor/client/components/InvitationBadge/InvitationBadge.spec.tsx
📚 Learning: 2025-12-10T21:00:43.645Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37091
File: ee/packages/abac/jest.config.ts:4-7
Timestamp: 2025-12-10T21:00:43.645Z
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/components/InvitationBadge/InvitationBadge.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/components/InvitationBadge/InvitationBadge.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/page-objects/**/*.ts : Utilize existing page objects pattern from `apps/meteor/tests/e2e/page-objects/`
Applied to files:
apps/meteor/client/components/InvitationBadge/InvitationBadge.spec.tsx
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.
Applied to files:
apps/meteor/client/views/hooks/useMembersList.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.
Applied to files:
apps/meteor/client/views/hooks/useMembersList.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.
Applied to files:
apps/meteor/client/views/hooks/useMembersList.ts
📚 Learning: 2025-11-27T17:56:26.050Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37557
File: apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx:115-116
Timestamp: 2025-11-27T17:56:26.050Z
Learning: In Rocket.Chat, the GET /v1/abac/rooms endpoint (implemented in ee/packages/abac/src/index.ts) only returns rooms where abacAttributes exists and is not an empty array (query: { abacAttributes: { $exists: true, $ne: [] } }). Therefore, in components consuming this endpoint (like AdminABACRooms.tsx), room.abacAttributes is guaranteed to be defined for all returned rooms, and optional chaining before calling array methods like .join() is sufficient without additional null coalescing.
Applied to files:
apps/meteor/client/views/hooks/useMembersList.ts
🧬 Code graph analysis (1)
apps/meteor/client/components/InvitationBadge/InvitationBadge.stories.tsx (1)
packages/mock-providers/src/index.ts (1)
mockAppRoot(3-3)
🔇 Additional comments (4)
apps/meteor/client/views/hooks/useMembersList.ts (2)
1-1: LGTM!The additional imports
ISubscriptionandSerializedare correctly added to support the expandedRoomMembertype definition.
23-28: Fix RoomMember type to match actual API response shapes.The
RoomMembertype is incompatible with the/v1/im.membersendpoint response. The DM members endpoint returns only_id | status | name | username | utcOffset, butRoomMemberrequiresfederatedandfreeSwitchExtension. SinceuseMembersListuses the sameRoomMembertype for both endpoints (DM and room), either:
- Define separate types for each endpoint response, or
- Make
federatedandfreeSwitchExtensionoptional inRoomMemberto match the actual DM response shape, or- Ensure the backend returns these fields for all endpoints
Current state creates a type mismatch at runtime when fetching DM members.
⛔ Skipped due to learnings
Learnt from: d-gubert Repo: RocketChat/Rocket.Chat PR: 37152 File: packages/apps-engine/tests/test-data/utilities.ts:557-573 Timestamp: 2025-10-06T20:32:23.658Z Learning: In packages/apps-engine/tests/test-data/utilities.ts, the field name `isSubscripbedViaBundle` in the `IMarketplaceSubscriptionInfo` type should not be flagged as a typo, as it may match the upstream API's field name.Learnt from: ricardogarim Repo: RocketChat/Rocket.Chat PR: 37205 File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301 Timestamp: 2025-10-28T16:53:42.761Z Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.Learnt from: ricardogarim Repo: RocketChat/Rocket.Chat PR: 37205 File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301 Timestamp: 2025-10-28T16:53:42.761Z Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.Learnt from: Dnouv Repo: RocketChat/Rocket.Chat PR: 37057 File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27 Timestamp: 2025-09-25T09:59:26.461Z Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.Learnt from: Dnouv Repo: RocketChat/Rocket.Chat PR: 37057 File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27 Timestamp: 2025-09-25T09:59:26.461Z Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.apps/meteor/client/components/InvitationBadge/InvitationBadge.stories.tsx (1)
1-26: LGTM!The Storybook story is well-structured with appropriate mocking of translations and a centered layout. The
mockAppRootdecorator correctly provides theInvited__date__translation key needed by the component.apps/meteor/client/components/InvitationBadge/InvitationBadge.spec.tsx (1)
1-18: LGTM!The test file follows best practices by:
- Using
composeStoriesto test all story variants- Including both snapshot tests and accessibility tests with jest-axe
- Leveraging
test.eachfor concise, maintainable test structure
Proposed changes (including videos or screenshots)
This pull request adds a visual badge for invited users in the room members contextual. The changes also add a new story and snapshot test for rooms with invited members.
Issue(s)
FB-63
Steps to test or reproduce
ℹ️ Currently invitation requests are only available for federated rooms.
ℹ️ You'll need two workspaces with federation enabled (I'll refer to them as
ws-aandws-b)ws-a)ws-bto the room (ws-a)Further comments
Summary by CodeRabbit
Release Notes
New Features
Localization
Tests
✏️ Tip: You can customize this high-level summary in your review settings.