Skip to content

Conversation

@MartinSchoeler
Copy link
Member

@MartinSchoeler MartinSchoeler commented Nov 19, 2025

Proposed changes (including videos or screenshots)

Issue(s)

ABAC-50

Steps to test or reproduce

Further comments

Summary by CodeRabbit

Release Notes

  • New Features
    • Added ABAC room management interface with search and filtering capabilities
    • Implemented room creation, editing, and deletion workflows with confirmation modals
    • Added attribute assignment and management for controlled access
    • Introduced autocomplete for efficient room and attribute selection
    • Enhanced admin panel with new "Rooms" tab for ABAC configuration

✏️ Tip: You can customize this high-level summary in your review settings.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Nov 19, 2025

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
Copy link

changeset-bot bot commented Nov 19, 2025

⚠️ No Changeset found

Latest commit: 94b3eff

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

Walkthrough

This PR adds comprehensive ABAC (Attribute-Based Access Control) Rooms management to the admin panel, introducing new query keys, room autocomplete and selection components, contextual create/edit forms, deletion modalities, and associated hooks. Updates include refactored export patterns for existing hooks and adjusted i18n strings for ABAC room workflows.

Changes

Cohort / File(s) Summary
Query Keys and Localization
apps/meteor/client/lib/queryKeys.ts, packages/i18n/src/locales/en.i18n.json
Added ABACQueryKeys.rooms with nested query key accessors (all, list, autocomplete, room); refactored ABACQueryKeys.roomAttributes (roomAttributesList→list, shortened attribute path). Added 20+ ABAC-specific i18n keys for room deletion, creation, and updates; removed legacy ABAC_Managed keys.
Room Autocomplete Components
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete*
New room autocomplete with debounced search via GET /v1/rooms.adminRooms; dummy variant for display-only; accompanying Storybook story and snapshot tests.
Attribute Field Components
apps/meteor/client/views/admin/ABAC/ABACAttributeField*
New field component for selecting and managing ABAC attributes with repeated-attribute validation, debounced search, and multi-select value picking; includes stories and snapshot tests.
Room Form and Contextual Bars
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx, RoomsContextualBar*.tsx
Form component for creating/editing ABAC room attributes with dynamic field array (max 10 entries), confirmation modal on update, and form-level validation; contextual bars render form with data-fetching wrapper.
Room Deletion Modal
apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal*, hooks/useABACDeleteRoomModal*
Modal for confirming room deletion with translated content; hook wrapper for modal invocation; tests and Storybook story included.
Admin List and Menu Components
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx, AdminABACRoomMenu.tsx
New paginated room list view with search/filter (room name, attribute, value) and per-row action menu; menu component renders edit/delete actions with ABAC availability gating.
Hooks
apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.ts, useRoomItems*, useIsABACAvailable.ts
New infinite-pagination hook for attribute fetching; new hook for room menu items (edit/delete actions); refactored useIsABACAvailable from default to named export.
Updated Admin Pages and Navigation
apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx, AdminABACTabs.tsx, AdminABACRoomAttributes.tsx
Added "rooms" tab to AdminABACTabs; updated AdminABACPage to render AdminABACRooms and contextual bars for rooms; updated query keys and optional chaining in room attributes page.
Refactored Exports
apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions*
Changed hook exports from default to named; updated import statements; added test mocks for new export style.
Minor Updates
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm*, CurrentChatsPage.tsx
Updated translation key, refined Storybook decorators, added optional chaining for rooms length checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas requiring extra attention:
    • AdminABACRoomForm.tsx — complex form logic with dynamic field array, validation rules (repeated attributes, required fields), and confirmation modal flow
    • RoomsContextualBar.tsx — mutation handling, query invalidation, and onSuccess/onError toast dispatching patterns
    • Query key consistency across ABACQueryKeys.rooms and ABACQueryKeys.roomAttributes structures and their usage patterns
    • Export pattern consistency — verify all named export changes (useIsABACAvailable, useRoomAttributeItems) are correctly imported throughout the codebase
    • Form validation and error messaging for attributes — ensure validateRepeatedAttributes is robust and error states render correctly

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • KevLehman
  • aleksandernsilva

Poem

🐰 A rooms tab hops into view,
With autocomplete and forms anew,
Attributes dance, modals confirm,
And queries key all take their turn,
ABAC management—a feature so fine! ✨

Pre-merge checks and finishing touches

❌ Failed checks (2 inconclusive)
Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The linked issue ABAC-50 provides only a title 'Rooms Tab' with no detailed requirements. The PR implements a complete ABAC rooms management feature with room listing, filtering, searching, and CRUD operations. Verify that the implementation fully satisfies ABAC-50 requirements by reviewing the complete issue description and acceptance criteria on the project tracking system.
Out of Scope Changes check ❓ Inconclusive The PR includes core rooms tab functionality (AdminABACRooms, RoomsContextualBar, room form, autocomplete, deletion) plus modifications to existing ABAC features (query keys, attribute list handling, hook exports) and i18n updates. Clarify whether query key refactoring, export pattern changes (useIsABACAvailable, useRoomAttributeItems), and attribute list updates are intended scope or should be separated into distinct PRs.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: admin ABAC rooms tab' clearly and concisely describes the main change: adding a new rooms tab to the admin ABAC interface.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/abac-rooms

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.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 19, 2025

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 359MiB 347MiB +12MiB
omnichannel-transcript-service 132MiB 132MiB +13KiB
queue-worker-service 132MiB 132MiB +9.3KiB
ddp-streamer-service 126MiB 126MiB +8.7KiB
account-service 113MiB 113MiB +11KiB
authorization-service 111MiB 111MiB +64KiB
stream-hub-service 111MiB 111MiB +9.5KiB
presence-service 111MiB 111MiB +8.0KiB

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/15 22:28", "11/16 01:28", "11/17 23:50", "11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 06:12 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "queue-worker-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "rocketchat" [0.36, 0.36, 0.35, 0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.35]
  line "stream-hub-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
Loading

Statistics (last 12 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.2GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 1.2GiB
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-37557
  • Baseline: develop
  • Timestamp: 2025-12-04 06:12:51 UTC
  • Historical data points: 12

Updated: Thu, 04 Dec 2025 06:12:51 GMT

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (23)
apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx (1)

351-369: Safer guard on rooms length; consider aligning other checks

Updating this block to data?.rooms?.length > 0 is good—it avoids accessing .length on a possibly undefined rooms and keeps data.rooms.map(...) safe under this guard.

For consistency and to avoid similar edge cases elsewhere, consider updating the other rooms length checks in this component (e.g., Lines 315, 333, 334) from data?.rooms.length to data?.rooms?.length as well so all guards behave the same way if rooms is ever missing.

apps/meteor/client/lib/queryKeys.ts (1)

128-132: ABAC rooms query keys are consistent; consider tightening roomId typing

This new ABACQueryKeys.rooms block matches the existing roomAttributes pattern and looks correct in terms of query key composition.

One small optional improvement for type-safety and consistency with roomsQueryKeys.room above:

-   room: (roomId: string) => [...ABACQueryKeys.rooms.all(), 'room', roomId] as const,
+   room: (roomId: IRoom['_id']) => [...ABACQueryKeys.rooms.all(), 'room', roomId] as const,

Also, given ABAC attributes only exist on private rooms/teams (type 'p'), please ensure the APIs and components that use ABACQueryKeys.rooms.* are operating on private rooms only, not public channels. Based on learnings, this keeps the ABAC surface aligned with the server-side model.

packages/i18n/src/locales/en.i18n.json (5)

42-45: Deduplicate “Proceed with caution” strings; reuse existing key.

You added two new copies of the same annotation. Prefer referencing the existing generic "Proceed_with_caution" to avoid divergent translations.

Example:

-  "ABAC_Delete_room_annotation": "Proceed with caution",
+  "ABAC_Delete_room_annotation": "{{t 'Proceed_with_caution'}}",

-  "ABAC_Update_room_confirmation_modal_annotation": "Proceed with caution",
+  "ABAC_Update_room_confirmation_modal_annotation": "{{t 'Proceed_with_caution'}}",

Based on learnings, i18n keys should be maintained only in en.i18n.json; reusing a single key reduces translator churn.

Also applies to: 57-59


54-55: Key naming consistency: singular vs plural search labels.

You now have both “ABAC_Search_attributes” (line 40, existing) and “ABAC_Search_Attribute” (this change). Either make both plural or reuse the existing key to avoid UI inconsistency.

Suggested:

-  "ABAC_Search_Attribute": "Search attribute",
+  "ABAC_Search_Attribute": "{{t 'ABAC_Search_attributes'}}"

or rename to “ABAC_Search_attributes” if intent is identical.


46-49: Title case consistency for ABAC actions.

Existing ABAC strings use sentence case (“Edit attribute”); new ones are title case (“Add Attribute”, “Edit Room”). Align casing to one style across the ABAC section.

For example:

-  "ABAC_Add_Attribute": "Add Attribute",
+  "ABAC_Add_Attribute": "Add attribute",
-  "ABAC_Edit_Room": "Edit Room",
+  "ABAC_Edit_Room": "Edit room",

62-66: Empty-state capitalization consistency.

“No Attributes” vs “No rooms” mixes styles. Recommend sentence case for both.

-  "ABAC_No_attributes": "No Attributes",
+  "ABAC_No_attributes": "No attributes",

5742-5743: Namespace “View_rooms” or align with existing pattern.

If this label is ABAC‑navigation specific, consider “ABAC_View_rooms” to keep keys discoverable; otherwise confirm it’s intentionally global alongside “View_channels”.

Briefly confirm where “View_rooms” is used (sidebar, ABAC tab, or global), to avoid leaking ABAC copy into unrelated UIs.

apps/meteor/client/views/admin/ABAC/ABACRoomAutocompleteDummy.tsx (1)

3-5: Consider removing unused rid property.

The rid property in roomInfo is defined but never used in the component. If it's not needed for future functionality, consider simplifying the type.

 type ABACRoomAutocompleteDummyProps = {
-	roomInfo: { rid: string; name: string };
+	roomInfo: { name: string };
 };
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (1)

48-58: Consolidate redundant waitFor blocks.

The three separate waitFor blocks checking for Room 1, 2, and 3 can be consolidated into a single assertion block for better test clarity and performance.

-		await waitFor(() => {
-			expect(screen.getByText('Room 1')).toBeInTheDocument();
-		});
-
-		await waitFor(() => {
-			expect(screen.getByText('Room 2')).toBeInTheDocument();
-		});
-
-		await waitFor(() => {
-			expect(screen.getByText('Room 3')).toBeInTheDocument();
-		});
+		await waitFor(() => {
+			expect(screen.getByText('Room 1')).toBeInTheDocument();
+			expect(screen.getByText('Room 2')).toBeInTheDocument();
+			expect(screen.getByText('Room 3')).toBeInTheDocument();
+		});
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (2)

27-27: Address TODO: Use query keys object.

The TODO comment indicates that query keys should be moved to a centralized object for consistency with the rest of the codebase. Based on the context, ABACQueryKeys is available and should be used.

Would you like me to generate a script to verify the existence and structure of ABACQueryKeys.rooms in the codebase?


56-59: Type assertion safety concern.

The type assertion as unknown as IRoom on line 57 bypasses type checking. While this might work at runtime, it risks type safety if the API response structure doesn't match the IRoom interface exactly.

Consider adding runtime validation or using a type guard to ensure the selected room has the expected structure:

 			if (setSelectedRoom && typeof setSelectedRoom === 'function') {
-				const selectedRoom = result?.data?.rooms.find(({ _id }) => _id === val) as unknown as IRoom;
-				setSelectedRoom(selectedRoom);
+				const selectedRoom = result?.data?.rooms.find(({ _id }) => _id === val);
+				if (selectedRoom) {
+					setSelectedRoom(selectedRoom);
+				}
 			}
apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx (1)

10-10: Address the TODO comment about endpoint types.

Consider verifying the endpoint types to ensure type safety throughout the data flow.

Would you like me to help generate properly typed endpoint definitions or open an issue to track this?

apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx (1)

15-19: Consider adjusting staleTime for better performance.

Setting staleTime: 0 causes the data to be considered stale immediately, triggering refetches on every component mount or window focus. This may lead to unnecessary network requests and impact performance.

Unless real-time data is critical here, consider setting a reasonable staleTime:

 	const { data, isLoading, isFetching } = useQuery({
 		queryKey: ABACQueryKeys.rooms.room(id),
 		queryFn: () => getRoomAttributes({ rid: id }),
-		staleTime: 0,
+		staleTime: 5 * 60 * 1000, // 5 minutes
 	});
apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx (1)

34-37: Consider optimizing endpoint creation.

The useEndpoint call at line 37 includes watch('room') in the parameters, causing a new endpoint instance to be created whenever the room value changes in the form. This may be inefficient.

If the endpoint supports dynamic rid parameter, consider:

-	const attributeId = useRouteParameter('id');
-	const createOrUpdateABACRoom = useEndpoint('POST', '/v1/abac/rooms/:rid/attributes', { rid: watch('room') });
+	const attributeId = useRouteParameter('id');
+	const createOrUpdateABACRoomBase = useEndpoint('POST', '/v1/abac/rooms/:rid/attributes');

Then in the mutation:

-			await createOrUpdateABACRoom(payload);
+			await createOrUpdateABACRoomBase({ ...payload, rid: data.room });

Alternatively, if the current pattern is intentional for the endpoint's parameterization strategy, this can be kept as-is.

apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (4)

43-64: updateAction is declared async but performs no await.

The function is marked async but doesn't use any asynchronous operations. This is unnecessary and could be misleading.

-	const updateAction = useEffectEvent(async (action: () => void) => {
+	const updateAction = useEffectEvent((action: () => void) => {

77-77: Form submission bypasses native form behavior.

The form has an onSubmit handler, but the Save button (Line 123) uses onClick with type="button" (default). This means pressing Enter in the form won't trigger submission. Consider using type="submit" on the Save button or removing the onSubmit from the form if it's not needed.

-				<Box is='form' onSubmit={handleSubmit(onSave)} id={formId}>
+				<Box is='form' id={formId}>

Or alternatively, change the Save button to submit the form:

-				<Button onClick={handleSave}>{t('Save')}</Button>
+				<Button type='submit' form={formId} onClick={handleSave}>{t('Save')}</Button>

78-95: Use htmlFor instead of id on FieldLabel for proper accessibility.

At Line 79, FieldLabel uses id={nameField} which sets an ID on the label itself, but this doesn't create a proper label-input association. The aria-labelledby={nameField} on the input at Line 90 establishes a one-way association, but using htmlFor on the label would be more idiomatic.

-					<FieldLabel id={nameField} required>
+					<FieldLabel htmlFor={nameField} required>
						{t('ABAC_Room_to_be_managed')}
					</FieldLabel>

Note: This depends on whether the ABACRoomAutocomplete component accepts and uses an id prop.


120-125: Consider making the Save button primary for visual hierarchy.

The Cancel and Save buttons have the same styling. Typically, the primary action (Save) should be visually distinct using primary prop.

				<ButtonGroup stretch>
					<Button onClick={onClose}>{t('Cancel')}</Button>
-					<Button onClick={handleSave}>{t('Save')}</Button>
+					<Button primary onClick={handleSave}>{t('Save')}</Button>
				</ButtonGroup>
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (2)

34-42: Handler name handleNewAttribute is misleading.

This handler navigates to create a new room, not a new attribute. Consider renaming for clarity.

-const handleNewAttribute = useEffectEvent(() => {
+const handleNewRoom = useEffectEvent(() => {

And update usage at Line 86:

-<Button onClick={handleNewAttribute} primary mis={8} disabled={isABACAvailable !== true}>
+<Button onClick={handleNewRoom} primary mis={8} disabled={isABACAvailable !== true}>

91-94: Loading state not handled; table may flash empty state.

When isLoading is true and data is undefined (initial load), the condition (!data || data.rooms?.length === 0) && !isLoading is false, so neither the no-results state nor the table is shown. Consider showing a loading skeleton.

+import { TableSkeleton } from '../../../components/GenericTable';
...
-		{(!data || data.rooms?.length === 0) && !isLoading ? (
+		{isLoading ? (
+			<GenericTable>
+				<GenericTableHeader>
+					<GenericTableHeaderCell>{t('Room')}</GenericTableHeaderCell>
+					<GenericTableHeaderCell>{t('Members')}</GenericTableHeaderCell>
+					<GenericTableHeaderCell>{t('ABAC_Attributes')}</GenericTableHeaderCell>
+					<GenericTableHeaderCell>{t('ABAC_Attributes_Values')}</GenericTableHeaderCell>
+					<GenericTableHeaderCell key='spacer' w={40} />
+				</GenericTableHeader>
+				<GenericTableBody>
+					{/* Add skeleton rows */}
+				</GenericTableBody>
+			</GenericTable>
+		) : (!data || data.rooms?.length === 0) ? (
apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (3)

48-50: Loading skeleton may cause layout shift.

Returning InputBoxSkeleton while loading replaces the entire field structure (two rows + button), which could cause layout instability. Consider showing skeleton states for both fields and the button, or using a fixed-height container.

 if (isLoading) {
-	return <InputBoxSkeleton />;
+	return (
+		<Box display='flex' flexDirection='column' w='full'>
+			<FieldRow><InputBoxSkeleton /></FieldRow>
+			<FieldRow><InputBoxSkeleton /></FieldRow>
+			<Button disabled mbs={4}>{t('Remove')}</Button>
+		</Box>
+	);
 }

78-93: Values field should be disabled when no attribute is selected.

When currentAttribute is empty/undefined, valueOptions will be an empty array. The MultiSelect will be functional but show no options, which could confuse users. Consider disabling it until an attribute is selected.

 <MultiSelect
 	{...field}
 	options={valueOptions}
 	placeholder={t('ABAC_Select_Attribute_Values')}
 	error={errors.attributes?.[index]?.values?.message}
+	disabled={!currentAttribute}
 />

95-97: Consider adding danger variant to the Remove button for visual clarity.

The Remove button performs a destructive action. Adding visual distinction would improve UX.

-<Button onClick={onRemove} title={t('Remove')} mbs={4}>
+<Button danger onClick={onRemove} title={t('Remove')} mbs={4}>
 	{t('Remove')}
 </Button>
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between d852553 and c56b48d.

⛔ Files ignored due to path filters (3)
  • apps/meteor/client/views/admin/ABAC/__snapshots__/ABACAttributeField.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/admin/ABAC/__snapshots__/ABACRoomAutocomplete.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/admin/ABAC/__snapshots__/AdminABACRoomAttributesForm.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (22)
  • apps/meteor/client/lib/queryKeys.ts (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocompleteDummy.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx (2 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx (2 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACTabs.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1 hunks)
  • apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx (1 hunks)
  • packages/i18n/src/locales/en.i18n.json (5 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/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocompleteDummy.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACTabs.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx
  • apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx
🧠 Learnings (19)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 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/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
  • packages/i18n/src/locales/en.i18n.json
📚 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/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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 clean state for each test execution in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
📚 Learning: 2025-10-30T19:30:46.541Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37244
File: apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx:125-146
Timestamp: 2025-10-30T19:30:46.541Z
Learning: In the AdminABACRoomAttributesForm component (apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx), the first attribute value field is mandatory and does not have a Remove button. Only additional values beyond the first have Remove buttons. This means trashButtons[0] corresponds to the second value's Remove button, not the first value's.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocompleteDummy.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACTabs.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.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/**/*.{ts,spec.ts} : Store commonly used locators in variables/constants for reuse

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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 : Implement proper wait strategies for dynamic content in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.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-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/omnichannel/currentChats/CurrentChatsPage.tsx
🧬 Code graph analysis (9)
apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeLicenseInfo (213-261)
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (3)
packages/ui-contexts/src/index.ts (1)
  • useSetModal (68-68)
packages/livechat/src/components/Button/index.tsx (1)
  • Button (34-99)
packages/livechat/src/components/ButtonGroup/index.tsx (1)
  • ButtonGroup (8-14)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx (3)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeRoom (46-61)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx (1)
  • Default (75-75)
apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (2)
packages/ui-contexts/src/index.ts (3)
  • useRouter (60-60)
  • useSetModal (68-68)
  • useToastMessageDispatch (75-75)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-133)
apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx (2)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-133)
apps/meteor/app/ui-utils/client/lib/RoomHistoryManager.ts (1)
  • isLoading (279-282)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (4)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeRoom (46-61)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/lib/appLayout.tsx (1)
  • render (26-28)
packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx (1)
  • input (149-159)
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (4)
apps/meteor/client/components/GenericTable/hooks/usePagination.ts (1)
  • usePagination (11-40)
packages/ui-contexts/src/index.ts (1)
  • useRouter (60-60)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-133)
packages/livechat/src/components/Form/TextInput/index.tsx (1)
  • TextInput (38-38)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (2)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (22-98)
packages/ui-kit/src/index.ts (1)
  • Option (2-2)
apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx (3)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1)
  • AdminABACRoomFormData (20-23)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx (1)
  • Default (44-44)
⏰ 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: 📦 Build Packages
🔇 Additional comments (17)
packages/i18n/src/locales/en.i18n.json (1)

5694-5697: Based on my verification, I can now provide the rewritten review comment:


These generic keys follow the established i18n pattern and pose no collision risk.

The locale file already contains numerous single-word generic keys (Accept, Action, Activity, Add, Address, Administration, etc.), and "Value"/"Values" follow this established convention. No existing collision with these exact keys was found, and the related variant keys (Value_messages, Value_users) suggest appropriate context-specific organization. No evidence of ABAC-specific usage or conflicts detected.

apps/meteor/client/views/admin/ABAC/AdminABACTabs.tsx (1)

23-25: LGTM!

The new "Rooms" tab follows the established pattern and integrates cleanly with the existing tab structure.

apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx (1)

71-84: LGTM with optional chaining improvements.

The addition of optional chaining (data.attributes?.length, data?.attributes?.map) improves defensive coding and prevents potential null/undefined access errors. The translation key updates align with ABAC naming conventions.

apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx (1)

1-44: LGTM!

The Storybook story is well-structured with appropriate mocked endpoints and args. The use of private room types (t: 'p') aligns with ABAC requirements.

apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx (1)

37-37: TODO comment noted.

The TODO comment indicates a known limitation regarding a11y compliance and testability. This is appropriately documented for future work.

apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (2)

9-14: LGTM: Correct room type filtering.

The query correctly filters for private rooms (types: ['p']), which aligns with the ABAC requirement that ABAC attributes can only be set on private rooms and teams.

Based on learnings, ABAC attributes can only be set on private rooms (type 'p'), not public rooms.


36-38: LGTM: Filtering rooms with existing ABAC attributes.

The logic correctly excludes rooms that already have ABAC attributes, preventing duplicate management and ensuring only unmanaged rooms can be selected.

apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)

125-125: Translation key exists and is properly defined.

The translation key Add_Value is correctly defined in packages/i18n/src/locales/en.i18n.json at line 403, mapping to "Add Value". The change from the literal string to the i18n key reference is valid and follows proper internationalization practices.

apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx (1)

1-28: LGTM!

Clean component structure that properly integrates the room menu items hook with the GenericMenu UI.

apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx (1)

1-75: LGTM!

Well-structured Storybook story with appropriate mocks and decorators for testing the ABACAttributeField component.

apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (1)

54-225: LGTM!

Comprehensive test coverage for the useRoomItems hook, including menu structure, ABAC availability checks, navigation, modal interactions, and mutation side effects.

apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1)

1-83: LGTM!

Well-structured hook providing room menu actions with proper modal confirmations, mutation handling, and cache invalidation.

apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx (1)

7-13: LGTM!

The rooms tab integration follows the established pattern for room-attributes, with proper ABAC availability checks and contextual bar routing.

Also applies to: 71-91

apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (2)

96-108: LGTM!

The dynamic attribute field rendering with useFieldArray is well-implemented. The remove callback correctly uses the index to remove the specific field.


109-117: The review comment is based on a misunderstanding of the form structure and should be rejected.

The AdminABACRoomForm uses a MultiSelect component for the values field (ABACAttributeField.tsx, lines 84-89), not individual text input fields. The field has a required validation rule (line 82), which for a MultiSelect means at least one option must be selected—not that the array needs to be pre-populated with empty strings.

Initializing with values: [] is correct because:

  1. Users select values from a predefined list via the MultiSelect component
  2. The required validation triggers on form submission if no values are selected
  3. Initializing with values: [''] would not work with MultiSelect and would likely cause type errors

The learning referenced (about AdminABACRoomAttributesForm) describes a different form component that manages individual attribute values with separate text inputs—not the room form under review.

apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1)

96-118: LGTM!

The table rendering with room data, attribute keys, and action menu is well-structured. The fallback chain room.fname || room.name || room._id at Line 113 handles edge cases appropriately.

apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (1)

61-64: LGTM!

Resetting values when the attribute key changes is the correct behavior—it prevents stale values from a previously selected attribute from persisting.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (1)
apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (1)

158-225: Consider extracting shared delete flow setup.

These two tests share significant setup and execution logic (mock configuration, handler capture, delete trigger, modal wait, confirm execution). A helper function could reduce duplication and improve maintainability.

Example refactor:

const setupDeleteFlow = async (room: typeof mockRoom, deleteEndpoint: jest.Mock) => {
  let confirmHandler: (() => void) | undefined;
  
  mockSetModal.mockImplementation((modal) => {
    if (modal?.props?.onConfirm) {
      confirmHandler = modal.props.onConfirm;
    }
  });

  const { result } = renderHook(() => useRoomItems(room), {
    wrapper: baseAppRoot.withEndpoint('DELETE', '/v1/abac/rooms/:rid/attributes', deleteEndpoint).build(),
  });

  const deleteAction = result.current[1].onClick;
  if (deleteAction) {
    deleteAction();
  }

  await waitFor(() => {
    expect(mockSetModal).toHaveBeenCalled();
  });

  return confirmHandler;
};

Then use it in both tests:

it('should call delete endpoint when delete is confirmed', async () => {
  const deleteEndpointMock = jest.fn().mockResolvedValue(null);
  const confirmHandler = await setupDeleteFlow(mockRoom, deleteEndpointMock);

  if (confirmHandler) {
    confirmHandler();
  }

  await waitFor(() => {
    expect(deleteEndpointMock).toHaveBeenCalled();
  });
});

Additionally, consider adding a test for error handling when the delete endpoint fails.

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between c56b48d and 4fc4e1c.

📒 Files selected for processing (1)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (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/admin/ABAC/hooks/useRoomItems.spec.tsx
🧠 Learnings (8)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 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/admin/ABAC/hooks/useRoomItems.spec.tsx
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.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/views/admin/ABAC/hooks/useRoomItems.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/admin/ABAC/hooks/useRoomItems.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/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.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/admin/ABAC/hooks/useRoomItems.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/views/admin/ABAC/hooks/useRoomItems.spec.tsx
🧬 Code graph analysis (1)
apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeLicenseInfo (213-261)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (3)
apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (3)

1-52: LGTM! Comprehensive test setup.

The mock configuration and base app root setup are well-structured, providing all necessary context (router, modals, toast, translations, settings, endpoints) for testing the hook in isolation.


54-112: Excellent test coverage for core functionality.

These tests properly verify:

  • Menu item structure and properties
  • Edit button enabling based on ABAC availability
  • Navigation behavior with correct routing parameters

The use of waitFor and specific assertions with toMatchObject demonstrates solid testing practices.


114-156: Well-structured tests for edge cases and modal interaction.

The tests correctly verify:

  • Edit button disabled state when ABAC is unavailable
  • Delete confirmation modal display with proper variant and messaging
  • All modal properties are validated

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (6)
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (2)

54-57: Remove redundant inline comment above pagination reset effect.

The comment on Line 54 restates exactly what the useEffect does and conflicts with the guideline to avoid implementation comments in TS/JS files. The code is self-explanatory:

-	// Whenever the user changes the filter or the text, reset the pagination to the first page
 	useEffect(() => {
 		setCurrent(0);
 	}, [debouncedText, filterType, setCurrent]);

Dropping the comment keeps the implementation clean and aligned with the coding guidelines.


34-42: Align handler name with its behavior (room creation, not attribute).

handleNewAttribute actually navigates to the “new room” context (context: 'new' in the rooms tab). Renaming it improves readability and avoids confusion with attribute-level UIs:

-	const handleNewAttribute = useEffectEvent(() => {
+	const handleNewRoom = useEffectEvent(() => {
 		router.navigate({
 			name: 'admin-ABAC',
 			params: {
 				tab: 'rooms',
 				context: 'new',
 			},
 		});
 	});
...
-					<Button onClick={handleNewAttribute} primary mis={8} disabled={isABACAvailable !== true}>
+					<Button onClick={handleNewRoom} primary mis={8} disabled={isABACAvailable !== true}>

This is cosmetic but makes the intent of the handler clearer.

packages/i18n/src/locales/en.i18n.json (4)

49-50: De-duplicate “Add Room” to reuse existing key.

You added both ABAC_Add_room and the generic Add_room with the same value. Prefer reusing Add_room in the UI to avoid duplicate translations.

Also applies to: 403-405


47-47: Prefer generic keys where possible (“Attribute Values”, “Value/Values”).

You introduced ABAC_Attribute_Values while a generic Attribute_Values exists; likewise new generic Value/Values were added. Where feasible, reference the generic keys from ABAC screens to reduce translator workload and improve consistency.

Also applies to: 753-754, 5694-5694, 5697-5697


57-58: Reuse existing “Proceed with caution” key.

ABAC_Update_room_confirmation_modal_annotation duplicates existing Proceed_with_caution. Consider reusing the generic key to avoid duplicated strings.

-  "ABAC_Update_room_confirmation_modal_annotation": "Proceed with caution",
+  // Reuse "Proceed_with_caution"

52-53: Clarify private-room scope for ABAC management (if enforced).

If ABAC applies only to private rooms, consider reflecting that constraint near “ABAC_Room_to_be_managed” or via helper text to prevent confusion. Based on learnings, ABAC attributes can only be set on private rooms/teams.

Based on learnings, ...

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 4fc4e1c and b417d1f.

📒 Files selected for processing (4)
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx (1 hunks)
  • packages/i18n/src/locales/en.i18n.json (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
🧰 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/admin/ABAC/AdminABACRooms.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 Learning: 2025-10-30T19:30:46.541Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37244
File: apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx:125-146
Timestamp: 2025-10-30T19:30:46.541Z
Learning: In the AdminABACRoomAttributesForm component (apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx), the first attribute value field is mandatory and does not have a Remove button. Only additional values beyond the first have Remove buttons. This means trashButtons[0] corresponds to the second value's Remove button, not the first value's.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.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-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • packages/i18n/src/locales/en.i18n.json
🧬 Code graph analysis (1)
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (3)
apps/meteor/client/components/GenericTable/hooks/usePagination.ts (1)
  • usePagination (11-40)
packages/ui-contexts/src/index.ts (1)
  • useRouter (60-60)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-133)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (3)
packages/i18n/src/locales/en.i18n.json (3)

42-46: ABAC room removal strings look good.

Wording and placeholders are clear; no issues.


62-66: Empty-state ABAC texts read well.

Clear and consistent with the new tab’s purpose.


5742-5743: Parity with channels (“View rooms” / “View channels”).

Good consistency and capitalization.

@codecov
Copy link

codecov bot commented Nov 27, 2025

Codecov Report

❌ Patch coverage is 14.28571% with 6 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (feat/abac@638a197). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             feat/abac   #37557   +/-   ##
============================================
  Coverage             ?   54.48%           
============================================
  Files                ?     2637           
  Lines                ?    50056           
  Branches             ?    11202           
============================================
  Hits                 ?    27272           
  Misses               ?    20604           
  Partials             ?     2180           
Flag Coverage Δ
e2e 57.25% <14.28%> (?)
e2e-api 44.61% <ø> (?)

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1)

77-77: Form onSubmit bypasses confirmation modal for updates.

The form's onSubmit directly calls handleSubmit(onSave), but the Save button uses handleSave which shows a confirmation modal when roomInfo exists. If the form is submitted via Enter key, the confirmation modal will be bypassed for update operations.

-				<Box is='form' onSubmit={handleSubmit(onSave)} id={formId}>
+				<Box is='form' onSubmit={(e) => { e.preventDefault(); handleSave(); }} id={formId}>
apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (1)

31-39: Fix duplicate-attribute validation logic (still allows duplicates).

The current filter condition mixes value and currentAttribute and then checks > 1, which can still let a second duplicate slip through. You only need to count how many attributes share the same key and flag when more than one exists.

-	const validateRepeatedAttributes = useCallback(
-		(value: string) => {
-			const attributes = getValues('attributes');
-			// Only one instance of the same attribute is allowed to be in the form at a time
-			const repeatedAttributes = attributes.filter((attribute) => attribute.key === value && attribute.key !== currentAttribute).length > 1;
-			return repeatedAttributes ? t('ABAC_No_repeated_attributes') : undefined;
-		},
-		[currentAttribute, getValues, t],
-	);
+	const validateRepeatedAttributes = useCallback(
+		(value: string) => {
+			const attributes = getValues('attributes');
+			const repeatedAttributes = attributes.filter((attribute) => attribute.key === value).length > 1;
+			return repeatedAttributes ? t('ABAC_No_repeated_attributes') : undefined;
+		},
+		[getValues, t],
+	);
packages/i18n/src/locales/en.i18n.json (1)

42-60: Tighten ABAC microcopy; reuse shared annotation where possible.

  • ABAC_Room_updated reads awkward. Prefer clearer subject-first phrasing.
  • ABAC_Room_to_be_managed is clunky; suggest simpler wording.
  • Optional: both ABAC_*_annotation keys duplicate the existing generic "Proceed_with_caution". Consider reusing it to avoid translation churn.

Apply:

-  "ABAC_Room_to_be_managed": "Room to be ABAC-managed",
+  "ABAC_Room_to_be_managed": "Room to be managed by ABAC",
-  "ABAC_Room_updated": "{{roomName}} ABAC room updated",
+  "ABAC_Room_updated": "ABAC settings for {{roomName}} updated",

Optionally (ref): replace these with "Proceed_with_caution":

-  "ABAC_Delete_room_annotation": "Proceed with caution",
+  "ABAC_Delete_room_annotation": "{{Proceed_with_caution}}",
-  "ABAC_Update_room_confirmation_modal_annotation": "Proceed with caution",
+  "ABAC_Update_room_confirmation_modal_annotation": "{{Proceed_with_caution}}",
🧹 Nitpick comments (7)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (2)

11-18: Reduce reliance on as any in mocked rooms

The endpoint mock currently casts each room to any:

rooms: [mockRoom1 as any, mockRoom2 as any, mockRoom3 as any],

Since createFakeRoom is already typed to return an IRoom-compatible shape, it should be possible to keep these strongly typed by tightening the generic on createFakeRoom and/or the withEndpoint typings instead of using any. That keeps mocks aligned with the real API and helps catch shape drift in future refactors.


24-38: Story-based snapshot and a11y tests look good; consider shared wrapper if required

Using composeStories + test.each for snapshots and jest-axe checks is concise and scalable as stories evolve. If any of these stories rely on the same mocked app root / endpoints as the direct component test, consider rendering them with the appRoot wrapper as well, to avoid divergence between story behavior in tests vs. in isolation; if they’re already self-contained via decorators, current setup is fine.

apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (1)

158-225: Consider combining tests 6 and 7 to reduce duplication.

These two tests share identical setup and flow logic, differing only in their final assertions (endpoint call vs. toast message). Combining them would reduce duplication while maintaining coverage.

Example consolidated test:

it('should call delete endpoint and show success toast when delete is confirmed', async () => {
	const deleteEndpointMock = jest.fn().mockResolvedValue(null);
	let confirmHandler: (() => void) | undefined;

	mockSetModal.mockImplementation((modal) => {
		if (modal?.props?.onConfirm) {
			confirmHandler = modal.props.onConfirm;
		}
	});

	const { result } = renderHook(() => useRoomItems(mockRoom), {
		wrapper: baseAppRoot.withEndpoint('DELETE', '/v1/abac/rooms/:rid/attributes', deleteEndpointMock).build(),
	});

	const deleteAction = result.current[1].onClick;
	if (deleteAction) {
		deleteAction();
	}

	await waitFor(() => {
		expect(mockSetModal).toHaveBeenCalled();
	});

	if (confirmHandler) {
		confirmHandler();
	}

	await waitFor(() => {
		expect(deleteEndpointMock).toHaveBeenCalled();
		expect(mockDispatchToastMessage).toHaveBeenCalledWith({
			type: 'success',
			message: 'Room Test Room removed from ABAC management',
		});
	});
});
apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx (1)

9-13: Consider adding enabled option for license/permission gating.

The hook fetches ABAC attributes unconditionally. If ABAC has license or permission requirements, consider adding an enabled option to prevent unnecessary requests when those requirements aren't met.

Also, the TODO comment at line 12 should be tracked or addressed to avoid leaving it indefinitely.

apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx (1)

76-91: Simplify explicit boolean comparison and remove unnecessary fragments.

The isABACAvailable === true comparison is verbose and the empty fragments add no value.

 					{tab === 'room-attributes' && (
-						<>
-							{context === 'new' && isABACAvailable === true && <RoomAttributesContextualBar onClose={() => handleCloseContextualbar()} />}
-							{context === 'edit' && _id && isABACAvailable === true && (
+							{context === 'new' && isABACAvailable && <RoomAttributesContextualBar onClose={() => handleCloseContextualbar()} />}
+							{context === 'edit' && _id && isABACAvailable && (
 								<RoomAttributesContextualBarWithData id={_id} onClose={() => handleCloseContextualbar()} />
 							)}
-						</>
 					)}
 					{tab === 'rooms' && (
-						<>
-							{context === 'new' && isABACAvailable === true && <RoomsContextualBar onClose={() => handleCloseContextualbar()} />}
-							{context === 'edit' && _id && isABACAvailable === true && (
+							{context === 'new' && isABACAvailable && <RoomsContextualBar onClose={() => handleCloseContextualbar()} />}
+							{context === 'edit' && _id && isABACAvailable && (
 								<RoomsContextualBarWithData id={_id} onClose={() => handleCloseContextualbar()} />
 							)}
-						</>
 					)}
apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx (1)

11-17: Clean up unused attributeId prop and naming for clarity.

RoomsContextualBarProps exposes attributeId, but the component ignores it and instead derives attributeId from useRouteParameter('id'). Also, the success toasts still interpolate with attributeName even though this form manages rooms.

To reduce confusion and future bugs:

  • Drop attributeId from RoomsContextualBarProps (or actually use it instead of the route param).
  • Consider renaming the local attributeId variable to something like roomId (and aligning the toast interpolation key accordingly) to better reflect its purpose.

Also applies to: 36-37, 52-57

packages/i18n/src/locales/en.i18n.json (1)

753-755: Avoid overlapping labels if not needed.

You now have both "ABAC_Attribute_Values" and generic "Attribute_Values" with identical text. If components can use the generic key, drop the ABAC‑specific one to reduce duplicates and translation load. If contexts differ, keep both. As per i18n workflow, changes only in en file.

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between b417d1f and f90ced3.

⛔ Files ignored due to path filters (3)
  • apps/meteor/client/views/admin/ABAC/__snapshots__/ABACAttributeField.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/admin/ABAC/__snapshots__/ABACRoomAutocomplete.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/admin/ABAC/__snapshots__/AdminABACRoomAttributesForm.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (22)
  • apps/meteor/client/lib/queryKeys.ts (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocompleteDummy.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx (2 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx (2 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACTabs.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1 hunks)
  • apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx (1 hunks)
  • packages/i18n/src/locales/en.i18n.json (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocompleteDummy.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACTabs.tsx
  • apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx
🧰 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/admin/ABAC/ABACAttributeField.stories.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx
🧠 Learnings (20)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
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.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 Learning: 2025-10-30T19:30:46.541Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37244
File: apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx:125-146
Timestamp: 2025-10-30T19:30:46.541Z
Learning: In the AdminABACRoomAttributesForm component (apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx), the first attribute value field is mandatory and does not have a Remove button. Only additional values beyond the first have Remove buttons. This means trashButtons[0] corresponds to the second value's Remove button, not the first value's.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx
📚 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/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.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/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/hooks/useRoomItems.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/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/ABACRoomAutocomplete.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 clean state for each test execution in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/**/*.{ts,spec.ts} : Store commonly used locators in variables/constants for reuse

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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 : Implement proper wait strategies for dynamic content in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx
  • packages/i18n/src/locales/en.i18n.json
📚 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/admin/ABAC/AdminABACRooms.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
🧬 Code graph analysis (7)
apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1)
  • AdminABACRoomFormData (20-23)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (2)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeRoom (46-61)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx (1)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-133)
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (3)
apps/meteor/client/components/GenericTable/hooks/usePagination.ts (1)
  • usePagination (11-40)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-133)
apps/meteor/client/components/GenericTable/GenericTable.tsx (1)
  • GenericTable (11-24)
apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx (1)
apps/meteor/client/router/page.ts (1)
  • Page (92-241)
apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx (2)
packages/ui-contexts/src/index.ts (2)
  • useRouteParameter (64-64)
  • useToastMessageDispatch (77-77)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-133)
apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (1)
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1)
  • AdminABACRoomFormData (20-23)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (13)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (3)

1-10: Solid Storybook-driven and RTL test structure

The suite is well-structured: Storybook composition for snapshot + a11y coverage, plus a focused behavioral test using RTL is a good pattern here. Imports and utilities look appropriate for the current testing stack.


15-22: Confirm endpoint path matches ABACRoomAutocomplete implementation

The mock uses GET /v1/rooms.adminRooms. Other ABAC admin pieces (e.g., AdminABACRooms) are wired to /v1/abac/rooms where abacAttributes is guaranteed to exist and be non-empty. Based on that, it would be good to double-check that ABACRoomAutocomplete really calls /v1/rooms.adminRooms and not /v1/abac/rooms, otherwise the test may pass while the component is querying a different endpoint (or vice versa).


40-59: Behavioral test correctly exercises autocomplete flow

The functional test wiring (mocked endpoint + wrapper, clicking the textbox, waiting for each room label) exercises the core behavior of the autocomplete and should catch regressions in data loading or option rendering. Assertions on all three room labels are clear and robust enough given the current scope.

apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx (1)

31-34: Initial data pattern looks appropriate for infinite query bootstrapping.

Setting total: Infinity in initialData ensures getNextPageParam triggers the first fetch. This is a valid pattern for infinite queries that need to fetch immediately.

apps/meteor/client/views/admin/ABAC/ABACAttributeField.stories.tsx (2)

36-65: Decorator setup for form and API mocking looks well-structured.

The decorator properly mocks the ABAC attributes endpoint with pagination metadata and wraps the story with FormProvider. This enables testing the component's integration with both the API and form context.


10-29: Mock data is well-defined for testing attribute selection.

The three mock attributes cover different scenarios (Department, Security-Level, Location) with varied value sets, providing good coverage for the attribute field's behavior.

apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (2)

96-108: Dynamic attribute fields implementation looks correct.

The useFieldArray integration for managing multiple attributes with removal capability follows react-hook-form best practices. The key-based rendering ensures proper React reconciliation.


109-117: Attribute limit enforcement is clear.

Disabling the "Add Attribute" button when fields.length >= 10 provides clear user feedback. Consider adding a tooltip or helper text to explain the limit.

apps/meteor/client/lib/queryKeys.ts (1)

128-132: Query key structure follows established patterns.

The new ABACQueryKeys.rooms structure mirrors the existing roomAttributes pattern, maintaining consistency. The hierarchical key design (allroomsList/room) enables flexible cache invalidation granularity.

apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1)

54-57: Good call resetting pagination on filter changes.

Resetting current to 0 when debouncedText or filterType changes avoids landing on invalid pages after filter updates and aligns well with the usePagination behavior.

packages/i18n/src/locales/en.i18n.json (3)

403-405: LGTM — consistent button labels.

“Add Value” / “Add Room” match existing patterns.


5694-5697: LGTM — base labels.

“Value” / “Values” are fine and useful across contexts.


5742-5743: LGTM — aligns with “View channels”.

“View rooms” label is consistent.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (1)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (1)

16-19: Prefer an event-style callback over passing a state setter prop.

Exposing setSelectedRoomLabel: Dispatch<SetStateAction<string>> couples this component to React state details and was already questioned in a previous review. An API like onRoomSelected?(value: string, label: string) would be more generic and easier to reuse while still supporting the current use case.

🧹 Nitpick comments (2)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (1)

41-47: Remove debug logging and make onChange call tolerant of missing handler.

console.log in the change handler will spam the console in production, and props.onChange is invoked unconditionally even though it may be optional in the component’s public API.

You can clean this up and be defensive about onChange:

-			onChange={(val) => {
-				props.onChange(val);
-				console.log(val);
-				setSelectedRoomLabel(result.data?.find(({ value }) => value === val)?.label?.name || '');
-			}}
+			onChange={(val) => {
+				props.onChange?.(val);
+				setSelectedRoomLabel(result.data?.find(({ value }) => value === val)?.label?.name || '');
+			}}
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1)

45-47: Simplify save flow to avoid nested handleSubmit calls.

Right now the form calls handleSubmit(handleSave), and handleSave in turn calls handleSubmit(onSave) (and wraps that again in updateAction for existing rooms). This re-runs validation and makes the control flow harder to reason about.

You can let handleSave receive validated data directly and delegate to onSave or the confirmation modal:

-	const updateAction = useEffectEvent(async (action: () => void) => {
+	const updateAction = useEffectEvent((action: () => void) => {
 		setModal(
 			<GenericModal
@@
-	const handleSave = useEffectEvent(() => {
-		if (roomInfo) {
-			updateAction(handleSubmit(onSave));
-		} else {
-			handleSubmit(onSave)();
-		}
-	});
+	const handleSave = useEffectEvent((data: AdminABACRoomFormData) => {
+		if (roomInfo) {
+			updateAction(() => onSave(data));
+			return;
+		}
+
+		onSave(data);
+	});
@@
-				<Box is='form' onSubmit={handleSubmit(handleSave)} id={formId}>
+				<Box is='form' onSubmit={handleSubmit(handleSave)} id={formId}>

This keeps validation in a single handleSubmit call and makes the “new vs. existing room” logic explicit.

Also applies to: 68-74, 79-79

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between f90ced3 and 2133396.

📒 Files selected for processing (5)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx
🧰 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/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
🧠 Learnings (6)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
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.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 Learning: 2025-10-30T19:30:46.541Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37244
File: apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx:125-146
Timestamp: 2025-10-30T19:30:46.541Z
Learning: In the AdminABACRoomAttributesForm component (apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx), the first attribute value field is mandatory and does not have a Remove button. Only additional values beyond the first have Remove buttons. This means trashButtons[0] corresponds to the second value's Remove button, not the first value's.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
📚 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/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.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/admin/ABAC/AdminABACRooms.tsx
🧬 Code graph analysis (2)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (2)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (22-98)
packages/ui-kit/src/index.ts (1)
  • Option (2-2)
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (4)
apps/meteor/client/components/GenericTable/hooks/usePagination.ts (1)
  • usePagination (11-40)
packages/ui-contexts/src/index.ts (1)
  • useRouter (62-62)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-133)
apps/meteor/client/components/GenericTable/GenericTable.tsx (1)
  • GenericTable (11-24)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build

@MartinSchoeler MartinSchoeler removed request for a team December 2, 2025 14:19
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (6)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (1)

17-19: Consider renaming to event-style naming convention.

The onSelectedRoom prop name is acceptable, but passing it as a setter-style callback was previously flagged. The current implementation does follow an event pattern by providing both value and label, which is reasonable.

apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1)

67-78: Double handleSubmit wrapping causes redundant validation.

The form's onSubmit wraps handleSave in handleSubmit, but handleSave internally calls handleSubmit(onSave) again. This triggers form validation twice on every submission.

Apply this fix - remove the outer handleSubmit wrapper:

-				<Box is='form' onSubmit={handleSubmit(handleSave)} id={formId}>
+				<Box is='form' onSubmit={handleSave} id={formId}>
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1)

109-109: flatMap on a string splits it into individual characters.

When attribute.key is a string, flatMap treats it as an iterable and flattens it into individual characters, producing output like "d, e, p, t" instead of "dept".

Use map instead of flatMap for string keys:

-									<GenericTableCell>{room.abacAttributes?.flatMap((attribute) => attribute.key ?? []).join(', ')}</GenericTableCell>
+									<GenericTableCell>{room.abacAttributes?.map((attribute) => attribute.key).join(', ')}</GenericTableCell>

Based on learnings, abacAttributes is guaranteed to be defined for all returned rooms from /v1/abac/rooms, so additional null handling is not required.

packages/i18n/src/locales/en.i18n.json (3)

52-52: Grammar fix looks good.

“ABAC_Attribute_Values”: “Attribute Values” resolves the earlier “Attributes Values” issue.


58-58: Reword “ABAC_Room_updated”.

Reads awkwardly. Suggest clearer order.

-  "ABAC_Room_updated": "{{roomName}} ABAC room updated",
+  "ABAC_Room_updated": "ABAC settings for {{roomName}} updated",

67-67: Sentence case for empty‑state copy.

Match repository’s sentence‑case convention for similar labels.

-  "ABAC_No_attributes": "No Attributes",
+  "ABAC_No_attributes": "No attributes",

As per i18n style learnings. Based on learnings, …

🧹 Nitpick comments (13)
apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.spec.tsx (1)

16-24: Consider adding behavioral tests.

The current test only verifies rendering via snapshot. Consider adding tests for user interactions, such as:

  • Clicking the "Remove" button triggers onConfirm
  • Clicking the "Cancel" button triggers onClose
  • The roomName is properly interpolated in the content

Example:

+	it('should call onConfirm when Remove button is clicked', async () => {
+		const onConfirm = jest.fn();
+		const { getByText } = render(<ABACDeleteRoomModal onClose={jest.fn()} onConfirm={onConfirm} roomName='Test Room' />, {
+			wrapper: appRoot,
+		});
+		
+		getByText('Remove').click();
+		
+		expect(onConfirm).toHaveBeenCalled();
+	});
+
+	it('should call onClose when Cancel button is clicked', async () => {
+		const onClose = jest.fn();
+		const { getByText } = render(<ABACDeleteRoomModal onClose={onClose} onConfirm={jest.fn()} roomName='Test Room' />, {
+			wrapper: appRoot,
+		});
+		
+		getByText('Cancel').click();
+		
+		expect(onClose).toHaveBeenCalled();
+	});
apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx (1)

75-168: Consider extracting shared test setup to reduce duplication.

Tests 2, 3, and 4 share significant setup logic:

  • deleteEndpointMock initialization
  • confirmHandler capture pattern via mockSetModal.mockImplementation
  • Calling result.current() and waiting for modal
  • Executing confirmHandler

This pattern could be extracted into a helper function to improve maintainability.

Example:

const setupDeleteTest = async (wrapper: ReturnType<typeof baseAppRoot.build>) => {
  const deleteEndpointMock = jest.fn().mockResolvedValue(null);
  let confirmHandler: (() => void) | undefined;

  mockSetModal.mockImplementation((modal) => {
    if (modal?.props?.onConfirm) {
      confirmHandler = modal.props.onConfirm;
    }
  });

  const { result } = renderHook(() => useABACDeleteRoomModal(mockRoom), { wrapper });

  result.current();

  await waitFor(() => {
    expect(mockSetModal).toHaveBeenCalled();
  });

  return { deleteEndpointMock, confirmHandler: () => confirmHandler?.() };
};
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (1)

54-54: Provide a fallback for undefined options.

result.data can be undefined during initial load before placeholderData kicks in, which may cause AutoComplete to receive undefined for options.

-			options={result.data}
+			options={result.data ?? []}
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (2)

48-58: Consolidate waitFor assertions for cleaner test structure.

Multiple sequential waitFor calls checking for static content can be combined into a single waitFor block, reducing test verbosity and potential flakiness.

-		await waitFor(() => {
-			expect(screen.getByText('Room 1')).toBeInTheDocument();
-		});
-
-		await waitFor(() => {
-			expect(screen.getByText('Room 2')).toBeInTheDocument();
-		});
-
-		await waitFor(() => {
-			expect(screen.getByText('Room 3')).toBeInTheDocument();
-		});
+		await waitFor(() => {
+			expect(screen.getByText('Room 1')).toBeInTheDocument();
+			expect(screen.getByText('Room 2')).toBeInTheDocument();
+			expect(screen.getByText('Room 3')).toBeInTheDocument();
+		});

16-17: Type assertion bypasses type safety.

The as any cast on mock rooms loses type checking. Consider using a more specific type or extending the mock to satisfy the expected shape.

-		rooms: [mockRoom1 as any, mockRoom2 as any, mockRoom3 as any],
+		rooms: [mockRoom1, mockRoom2, mockRoom3],

If type errors arise, extend createFakeRoom overrides to include all required properties for the endpoint response type.

apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx (1)

21-23: Consider whether isFetching check is needed here.

Showing the skeleton on isFetching will display it during background refetches (e.g., window focus), causing visual flicker even when stale data is available. Typically, isLoading alone is sufficient for initial load states.

-	if (isLoading || isFetching) {
+	if (isLoading) {
 		return <ContextualbarSkeletonBody />;
 	}

If you intentionally want to block UI during refetches, consider using isPending instead, which handles the pending state more predictably.

apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1)

30-31: Simplify onClick handler.

The arrow function wrapper is unnecessary since editAction is already a stable callback from useEffectEvent.

-		{ id: 'edit', icon: 'edit' as const, content: t('Edit'), onClick: () => editAction(), disabled: isABACAvailable !== true },
+		{ id: 'edit', icon: 'edit' as const, content: t('Edit'), onClick: editAction, disabled: isABACAvailable !== true },
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1)

14-19: Consider event-style callback instead of setter prop.

Passing setSelectedRoomLabel as a setter dispatch function couples the parent's state management to this component. An event-style callback like onRoomLabelChange would be more idiomatic.

 type AdminABACRoomFormProps = {
 	onClose: () => void;
 	onSave: (data: AdminABACRoomFormData) => void;
 	roomInfo?: { rid: string; name: string };
-	setSelectedRoomLabel: Dispatch<SetStateAction<string>>;
+	onRoomLabelChange?: (label: string) => void;
 };
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (2)

33-41: Consider renaming handleNewAttribute to handleNewRoom for clarity.

The handler navigates to the rooms tab to create a new room, but the name suggests it handles attributes. This could confuse future maintainers.

-	const handleNewAttribute = useEffectEvent(() => {
+	const handleNewRoom = useEffectEvent(() => {
		router.navigate({
			name: 'admin-ABAC',
			params: {
				tab: 'rooms',
				context: 'new',
			},
		});
	});

Also update the reference on line 85:

-				<Button onClick={handleNewAttribute} primary mis={8} disabled={isABACAvailable !== true}>
+				<Button onClick={handleNewRoom} primary mis={8} disabled={isABACAvailable !== true}>

90-94: Consider adding a loading state indicator.

When isLoading is true and data is undefined, the table branch renders but displays an empty table body. Adding a loading skeleton or spinner would improve UX.

packages/i18n/src/locales/en.i18n.json (3)

57-57: Tighten phrasing: “to be ABAC-managed”.

Slightly awkward. Prefer clearer phrasing.

-  "ABAC_Room_to_be_managed": "Room to be ABAC-managed",
+  "ABAC_Room_to_be_managed": "Room to be added to ABAC management",

As per coding guidelines, keep labels concise.


63-64: Consistency with “ABAC‑managed”.

Use the same hyphenated adjective seen elsewhere (“ABAC‑managed rooms”).

-  "ABAC_Update_room_confirmation_modal_title": "Update ABAC room",
+  "ABAC_Update_room_confirmation_modal_title": "Update ABAC‑managed room",

77-80: ABAC section wording and hyphenation.

Improve clarity and align with “ABAC‑managed” terminology.

-  "ABAC_Managed": "ABAC Managed",
-  "ABAC_Managed_description": "Only compliant users have access to attribute-based access controlled rooms. Attributes determine room access.",
-  "ABAC_Room_Attributes": "Room Attributes",
-  "ABAC_Logs": "Logs",
+  "ABAC_Managed": "ABAC‑managed",
+  "ABAC_Managed_description": "Only compliant users can access ABAC‑managed rooms. Attributes determine room access.",
+  "ABAC_Room_Attributes": "Room attributes",
+  "ABAC_Logs": "ABAC logs",
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 43e910e and c9c3b4d.

⛔ Files ignored due to path filters (1)
  • apps/meteor/client/views/admin/ABAC/__snapshots__/ABACDeleteRoomModal.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (18)
  • apps/meteor/client/lib/queryKeys.ts (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx (3 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1 hunks)
  • packages/i18n/src/locales/en.i18n.json (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.stories.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBar.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.tsx
🧰 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/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.spec.tsx
🧠 Learnings (24)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
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.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 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/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.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/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.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/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.spec.tsx
📚 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/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
  • packages/i18n/src/locales/en.i18n.json
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.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/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.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/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.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/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.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/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.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 clean state for each test execution in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.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/admin/ABAC/ABACRoomAutocomplete.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/**/*.{ts,spec.ts} : Store commonly used locators in variables/constants for reuse

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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 : Implement proper wait strategies for dynamic content in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/ABACRoomAutocomplete.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
📚 Learning: 2025-10-30T19:30:46.541Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37244
File: apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx:125-146
Timestamp: 2025-10-30T19:30:46.541Z
Learning: In the AdminABACRoomAttributesForm component (apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx), the first attribute value field is mandatory and does not have a Remove button. Only additional values beyond the first have Remove buttons. This means trashButtons[0] corresponds to the second value's Remove button, not the first value's.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/lib/queryKeys.ts
  • packages/i18n/src/locales/en.i18n.json
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/lib/queryKeys.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: 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/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.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/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.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.beforeAll()` and `test.afterAll()` for setup/teardown in Playwright tests

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.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-17T22:38:48.631Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37505
File: packages/i18n/src/locales/en.i18n.json:3765-3765
Timestamp: 2025-11-17T22:38:48.631Z
Learning: Rocket.Chat i18n copy: Keep sentence case for the value of "Notification_Desktop_show_voice_calls" in packages/i18n/src/locales/en.i18n.json (“Show desktop notifications for voice calls”) per design directive; do not change to Title Case even if nearby labels differ.

Applied to files:

  • packages/i18n/src/locales/en.i18n.json
📚 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:

  • packages/i18n/src/locales/en.i18n.json
📚 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/admin/ABAC/ABACDeleteRoomModal.spec.tsx
🧬 Code graph analysis (7)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.spec.tsx (2)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeRoom (46-61)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (4)
apps/meteor/client/components/GenericTable/hooks/usePagination.ts (1)
  • usePagination (11-40)
packages/ui-contexts/src/index.ts (1)
  • useRouter (62-62)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-138)
apps/meteor/client/components/GenericTable/GenericTable.tsx (1)
  • GenericTable (11-24)
apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (3)
packages/ui-contexts/src/index.ts (1)
  • useSetModal (70-70)
packages/ui-client/src/components/Contextualbar/index.ts (2)
  • ContextualbarScrollableContent (35-35)
  • ContextualbarFooter (32-32)
apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx (1)
  • AdminABACRoomAttributesFormProps (30-133)
apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1)
packages/ui-contexts/src/index.ts (1)
  • useRouter (62-62)
apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeLicenseInfo (213-261)
apps/meteor/client/views/admin/ABAC/ABACRoomAutocomplete.tsx (2)
apps/meteor/client/lib/queryKeys.ts (1)
  • ABACQueryKeys (121-138)
packages/ui-kit/src/index.ts (1)
  • Option (2-2)
apps/meteor/client/views/admin/ABAC/ABACDeleteRoomModal.spec.tsx (1)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (9)
apps/meteor/client/views/admin/ABAC/RoomsContextualBarWithData.tsx (1)

13-31: LGTM on the data fetching pattern.

The component correctly uses ABACQueryKeys.rooms.room(id) for cache key consistency and handles the loading state before rendering.

apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1)

10-40: Hook follows single responsibility principle.

The hook is well-structured, delegating the delete modal logic to useABACDeleteRoomModal and focusing solely on returning menu item definitions. Good separation of concerns.

apps/meteor/client/views/admin/ABAC/AdminABACRoomForm.tsx (1)

107-119: Good use of dynamic field array for attributes.

The attribute fields implementation with useFieldArray and per-item removal is clean. The 10-attribute limit on line 122 provides sensible bounds.

apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1)

43-61: Query construction and data fetching look correct.

The memoized query object, pagination reset effect, and React Query integration are properly implemented. The dependency arrays are complete.

apps/meteor/client/lib/queryKeys.ts (1)

129-137: Query key structure is well-organized and follows the established pattern.

The new rooms object mirrors the roomAttributes structure with appropriate keys for listing, autocomplete, and individual room access. The composition via spreading base paths ensures proper cache invalidation hierarchy.

packages/i18n/src/locales/en.i18n.json (4)

416-418: New generic actions approved.

“Add Value” / “Add Room” are consistent with adjacent action labels.


766-768: Good normalization of generic attribute labels.

“Attribute Values” / “Attributes” additions look consistent.


5708-5712: Singular/plural value keys OK.

“Value” / “Values” added cleanly for reuse across UI.


5756-5756: “View rooms” addition looks consistent.

Matches existing “View channels” pattern.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (6)
apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx (1)

1-28: Simple, well-scoped menu component looks good

The props typing, hook usage, and GenericMenu configuration all look correct and consistent with the provided useRoomItems implementation; no functional or correctness issues stand out. If other ABAC admin views standardize on a specific useTranslation source (e.g., @rocket.chat/ui-contexts), you might optionally align this import for consistency, but that's not blocking.

apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx (2)

5-11: Add explicit return type annotation.

The hook lacks an explicit return type. Per the coding guidelines emphasizing "accurate typing", consider adding a return type annotation to improve type safety and code clarity.

Apply this diff to add the return type:

-export const useABACDeleteRoomModal = (room: { rid: string; name: string }) => {
+export const useABACDeleteRoomModal = (room: { rid: string; name: string }): (() => void) => {

8-10: Consider memoizing the returned function.

The returned function is recreated on every render. If passed as a prop (e.g., to a button's onClick), this could cause unnecessary re-renders of child components. Wrapping the returned function with useCallback would optimize this.

Apply this diff to memoize the function:

-	return () => {
-		setModal(<ABACDeleteRoomModal rid={room.rid} roomName={room.name} onClose={() => setModal(null)} />);
-	};
+	return useCallback(() => {
+		setModal(<ABACDeleteRoomModal rid={room.rid} roomName={room.name} onClose={() => setModal(null)} />);
+	}, [room.rid, room.name, setModal]);

Don't forget to import useCallback:

+import { useCallback } from 'react';
 import { useSetModal } from '@rocket.chat/ui-contexts';
apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.ts (1)

14-27: Address TODO: Endpoint type safety.

The TODO comment indicates that endpoint types need verification. Ensuring proper typing for the /v1/abac/attributes endpoint will improve type safety and catch potential runtime errors.

Do you want me to help verify the endpoint types or open an issue to track this task?

apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (2)

65-78: Avoid type casting for setFilter.

Line 72 uses type casting to force setFilter compatibility. This suggests a type mismatch that should be resolved at the source rather than worked around with casting.

Consider updating the setFilter state to match PaginatedSelectFiltered's expected signature:

-const [filter, setFilter] = useState<string>();
+const [filter, setFilter] = useState<string | number | undefined>();

Then remove the cast:

-setFilter={setFilter as (value: string | number | undefined) => void}
+setFilter={setFilter}

77-80: Remove redundant error displays.

Error messages are displayed twice for each field: once via the component's error prop (lines 77, 87) and once via FieldError (lines 80, 90). This creates duplicate error messages in the UI.

Remove the error prop from the components and rely solely on FieldError for consistency:

 <PaginatedSelectFiltered
   {...keyField}
   onChange={(val) => {
     resetField(`attributes.${index}.values`);
     keyField.onChange(val);
   }}
   filter={filter}
   setFilter={setFilter as (value: string | number | undefined) => void}
   options={options}
   endReached={() => fetchNextPage()}
   placeholder={t('ABAC_Search_Attribute')}
   mbe={4}
-  error={keyFieldState.error?.message}
 />
 <MultiSelect
   {...valuesField}
   options={valueOptions}
   placeholder={t('ABAC_Select_Attribute_Values')}
-  error={valuesFieldState.error?.message}
 />

Also applies to: 87-90

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 3b261ff and 94b3eff.

📒 Files selected for processing (15)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx (2 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributeMenu.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx (4 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.ts (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useIsABACAvailable.ts (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1 hunks)
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.spec.tsx (2 hunks)
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.spec.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributes.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.spec.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACPage.tsx
🧰 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/admin/ABAC/hooks/useIsABACAvailable.ts
  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.ts
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributeMenu.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.spec.tsx
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx
🧠 Learnings (10)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
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.
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.
📚 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/admin/ABAC/hooks/useABACAttributeList.ts
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributeMenu.tsx
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.spec.tsx
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx
📚 Learning: 2025-10-30T19:30:46.541Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37244
File: apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx:125-146
Timestamp: 2025-10-30T19:30:46.541Z
Learning: In the AdminABACRoomAttributesForm component (apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx), the first attribute value field is mandatory and does not have a Remove button. Only additional values beyond the first have Remove buttons. This means trashButtons[0] corresponds to the second value's Remove button, not the first value's.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.ts
  • apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributeMenu.tsx
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx
  • apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.ts
  • apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.spec.tsx
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.ts
  • apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.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/admin/ABAC/useRoomAttributeOptions.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/admin/ABAC/useRoomAttributeOptions.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/views/admin/ABAC/useRoomAttributeOptions.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/admin/ABAC/useRoomAttributeOptions.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/admin/ABAC/useRoomAttributeOptions.spec.tsx
🧬 Code graph analysis (2)
apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx (1)
packages/ui-contexts/src/index.ts (1)
  • useSetModal (70-70)
apps/meteor/client/views/admin/ABAC/AdminABACRoomMenu.tsx (1)
apps/meteor/client/views/admin/ABAC/hooks/useRoomItems.tsx (1)
  • useRoomItems (10-40)
⏰ 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). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (9)
apps/meteor/client/views/admin/ABAC/hooks/useABACDeleteRoomModal.tsx (1)

1-3: LGTM!

Imports are clean and correctly reference the required dependencies.

apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributeMenu.tsx (1)

4-4: LGTM: Export pattern updated correctly.

The import has been updated to use a named export, consistent with the refactoring in useRoomAttributeOptions.tsx.

apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.spec.tsx (2)

4-23: LGTM: Test mocks updated correctly.

The test file has been updated to:

  • Use named imports consistent with the refactored exports
  • Introduce a controllable mock for useIsABACAvailable
  • Simplify the ui-contexts mock while preserving necessary functionality

124-145: LGTM: ABAC availability test case implemented correctly.

The test properly uses the mock to simulate ABAC unavailability and verifies that the edit action is disabled accordingly.

apps/meteor/client/views/admin/ABAC/hooks/useIsABACAvailable.ts (1)

5-10: LGTM: Export pattern refactored correctly.

The hook has been converted to a named export, consistent with the broader refactoring across ABAC hooks.

apps/meteor/client/views/admin/ABAC/hooks/useABACAttributeList.ts (2)

11-13: LGTM: Query properly gated by ABAC availability.

The query is correctly disabled when ABAC is not available, preventing unnecessary API calls.


34-37: The use of Infinity for the initial total value is an intentional pattern used consistently across multiple pagination hooks in the codebase (useAgentsList, useAvailableAgentsList, useMonitorsList, useTagsList, useUnitsList, useDepartmentsList). This ensures hasNextPage returns true during the loading state, allowing the UI to properly display pagination controls before actual data arrives. Once the API responds with real data, the actual total value replaces Infinity, and pagination functions correctly. No changes needed.

apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx (1)

9-9: LGTM: Export patterns refactored consistently.

Both the import of useIsABACAvailable and the export of useRoomAttributeItems have been updated to use named exports, aligning with the broader refactoring effort.

Also applies to: 12-12

apps/meteor/client/views/admin/ABAC/ABACAttributeField.tsx (1)

24-32: LGTM: Validation logic correctly prevents duplicate attributes.

The validation now properly checks if more than one attribute has the same key, preventing duplicates in the form.

@tassoevan tassoevan merged commit 0621b1f into feat/abac Dec 4, 2025
88 of 91 checks passed
@tassoevan tassoevan deleted the feat/abac-rooms branch December 4, 2025 13:16
KevLehman pushed a commit that referenced this pull request Dec 8, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
KevLehman pushed a commit that referenced this pull request Dec 10, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
KevLehman pushed a commit that referenced this pull request Dec 15, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
MartinSchoeler added a commit that referenced this pull request Dec 17, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants