diff --git a/apps/meteor/client/components/ABAC/ABACHeaderTag.spec.tsx b/apps/meteor/client/components/ABAC/ABACHeaderTag.spec.tsx new file mode 100644 index 0000000000000..212d8ce02341e --- /dev/null +++ b/apps/meteor/client/components/ABAC/ABACHeaderTag.spec.tsx @@ -0,0 +1,62 @@ +import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; +import { mockAppRoot } from '@rocket.chat/mock-providers'; +import { render, screen } from '@testing-library/react'; +import { axe } from 'jest-axe'; + +import ABACHeaderTag from './ABACHeaderTag'; + +const appRoot = mockAppRoot() + .withTranslations('en', 'core', { + ABAC_header_tag_title: 'Only compliant users have access to attribute-based access controlled rooms.', + ABAC_header_tag: 'ABAC', + }) + .build(); + +const createMockRoom = (overrides: Partial = {}) => ({ + _id: 'room-id', + t: 'c' as const, + name: 'test-room', + msgs: 0, + u: { _id: 'user-id', username: 'testuser' }, + usersCount: 1, + _updatedAt: new Date(), + ...overrides, +}); + +describe('ABACHeaderTag', () => { + it('should render the ABAC tag when room has ABAC attributes', () => { + const room = createMockRoom({ + // @ts-expect-error to be implemented + abacAttributes: { someAttribute: 'value' }, + }); + + const { baseElement } = render(, { wrapper: appRoot }); + expect(baseElement).toMatchSnapshot(); + }); + + it('should not render when room has no ABAC attributes', () => { + const room = createMockRoom(); + + render(, { wrapper: appRoot }); + expect(screen.queryByText('ABAC')).not.toBeInTheDocument(); + }); + + it('should have no accessibility violations when rendered', async () => { + const room = createMockRoom({ + // @ts-expect-error to be implemented + abacAttributes: { someAttribute: 'value' }, + }); + + const { container } = render(, { wrapper: appRoot }); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); + + it('should have no accessibility violations when not rendered', async () => { + const room = createMockRoom(); + + const { container } = render(, { wrapper: appRoot }); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); +}); diff --git a/apps/meteor/client/components/ABAC/ABACHeaderTag.tsx b/apps/meteor/client/components/ABAC/ABACHeaderTag.tsx new file mode 100644 index 0000000000000..b24538bf98736 --- /dev/null +++ b/apps/meteor/client/components/ABAC/ABACHeaderTag.tsx @@ -0,0 +1,28 @@ +import type { IRoom } from '@rocket.chat/core-typings'; +import { Box, Palette } from '@rocket.chat/fuselage'; +import { useTranslation } from 'react-i18next'; + +import { HeaderTag } from '../Header'; + +type ABACHeaderTagProps = { + room: IRoom; +}; + +const ABACHeaderTag = ({ room }: ABACHeaderTagProps) => { + const { t } = useTranslation(); + + // @ts-expect-error to be implemented + if (!room.abacAttributes) { + return null; + } + + return ( + + + {t('ABAC_header_tag')} + + + ); +}; + +export default ABACHeaderTag; diff --git a/apps/meteor/client/components/ABAC/__snapshots__/ABACHeaderTag.spec.tsx.snap b/apps/meteor/client/components/ABAC/__snapshots__/ABACHeaderTag.spec.tsx.snap new file mode 100644 index 0000000000000..20ce983ee9efd --- /dev/null +++ b/apps/meteor/client/components/ABAC/__snapshots__/ABACHeaderTag.spec.tsx.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`ABACHeaderTag should render the ABAC tag when room has ABAC attributes 1`] = ` + +
+
+ + +
+ ABAC +
+
+
+
+
+ +`; diff --git a/apps/meteor/client/views/room/Header/RoomHeader.tsx b/apps/meteor/client/views/room/Header/RoomHeader.tsx index 931aeaac92a41..2ea3dcd30b09a 100644 --- a/apps/meteor/client/views/room/Header/RoomHeader.tsx +++ b/apps/meteor/client/views/room/Header/RoomHeader.tsx @@ -13,6 +13,7 @@ import RoomToolbox from './RoomToolbox'; import Encrypted from './icons/Encrypted'; import Favorite from './icons/Favorite'; import Translate from './icons/Translate'; +import ABACHeaderTag from '../../../components/ABAC/ABACHeaderTag'; import { Header, HeaderAvatar, HeaderContent, HeaderContentRow, HeaderSubtitle, HeaderToolbar } from '../../../components/Header'; import MarkdownText from '../../../components/MarkdownText'; @@ -50,6 +51,7 @@ const RoomHeader = ({ room, topic = '', slots = {}, roomToolbox }: RoomHeaderPro {room.prid && } {room.teamId && !room.teamMain && } + {isRoomFederated(room) && } diff --git a/apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx b/apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx index 3fd1677675216..3bd6b828eb6c4 100644 --- a/apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx +++ b/apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx @@ -12,6 +12,7 @@ import RoomTopic from './RoomTopic'; import Encrypted from './icons/Encrypted'; import Favorite from './icons/Favorite'; import Translate from './icons/Translate'; +import ABACHeaderTag from '../../../components/ABAC/ABACHeaderTag'; import { Header, HeaderContent, HeaderContentRow, HeaderToolbar } from '../../../components/Header'; export type RoomHeaderProps = { @@ -43,6 +44,7 @@ const RoomHeader = ({ room, slots = {}, roomToolbox }: RoomHeaderProps) => { + {isRoomFederated(room) && } diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index 03afd7698f387..1ad8a3beeac6f 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -77,6 +77,8 @@ "A_new_owner_will_be_assigned_automatically_to_those__count__rooms__rooms__": "A new owner will be assigned automatically to those {{count}} rooms:
{{rooms}}.", "A_secure_and_highly_private_self-managed_solution_for_conference_calls": "A secure and highly private self-managed solution for conference calls.", "A_workspace_admin_needs_to_install_and_configure_a_conference_call_app": "A workspace admin needs to install and configure a conference call app.", + "ABAC_header_tag_title": "Only compliant users have access to attribute-based access controlled rooms.", + "ABAC_header_tag": "ABAC", "Accept": "Accept", "Accept_Call": "Accept Call", "Accept_incoming_livechat_requests_even_if_there_are_no_online_agents": "Accept incoming omnichannel requests even if there are no online agents", diff --git a/packages/ui-client/src/components/Header/HeaderTag/HeaderTag.tsx b/packages/ui-client/src/components/Header/HeaderTag/HeaderTag.tsx index 44661229707c4..afbad5d734340 100644 --- a/packages/ui-client/src/components/Header/HeaderTag/HeaderTag.tsx +++ b/packages/ui-client/src/components/Header/HeaderTag/HeaderTag.tsx @@ -2,7 +2,7 @@ import { Box, Tag } from '@rocket.chat/fuselage'; import type { ComponentProps, FC } from 'react'; const HeaderTag: FC> = ({ children, ...props }) => ( - + {children} diff --git a/packages/ui-client/src/components/HeaderV2/HeaderTag/HeaderTag.spec.tsx b/packages/ui-client/src/components/HeaderV2/HeaderTag/HeaderTag.spec.tsx new file mode 100644 index 0000000000000..4b4f0a3b3e7b6 --- /dev/null +++ b/packages/ui-client/src/components/HeaderV2/HeaderTag/HeaderTag.spec.tsx @@ -0,0 +1,8 @@ +import { render } from '@testing-library/react'; + +import HeaderTag from './HeaderTag'; + +it('should match snapshot', () => { + const { baseElement } = render(Test Tag); + expect(baseElement).toMatchSnapshot(); +}); diff --git a/packages/ui-client/src/components/HeaderV2/HeaderTag/HeaderTag.tsx b/packages/ui-client/src/components/HeaderV2/HeaderTag/HeaderTag.tsx index bef9407706e45..222a01dcf4daa 100644 --- a/packages/ui-client/src/components/HeaderV2/HeaderTag/HeaderTag.tsx +++ b/packages/ui-client/src/components/HeaderV2/HeaderTag/HeaderTag.tsx @@ -4,7 +4,7 @@ import type { ComponentProps } from 'react'; type HeaderTagProps = ComponentProps; const HeaderTag = ({ children, ...props }: HeaderTagProps) => ( - + {children} diff --git a/packages/ui-client/src/components/HeaderV2/HeaderTag/__snapshots__/HeaderTag.spec.tsx.snap b/packages/ui-client/src/components/HeaderV2/HeaderTag/__snapshots__/HeaderTag.spec.tsx.snap new file mode 100644 index 0000000000000..652dc9c51111a --- /dev/null +++ b/packages/ui-client/src/components/HeaderV2/HeaderTag/__snapshots__/HeaderTag.spec.tsx.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`should match snapshot 1`] = ` + +
+
+ + + Test Tag + + +
+
+ +`;