snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import type { IRoom } from '@rocket.chat/core-typings';
|
||||
import { mockAppRoot } from '@rocket.chat/mock-providers';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { axe } from 'jest-axe';
|
||||
|
||||
import RoomInfoABACSection from './RoomInfoABACSection';
|
||||
import { createFakeRoom } from '../../../../../../../tests/mocks/data';
|
||||
|
||||
type RoomWithABAC = IRoom & {
|
||||
abacAttributes?: {
|
||||
key: string;
|
||||
values: string[];
|
||||
}[];
|
||||
};
|
||||
|
||||
describe('RoomInfoABACSection', () => {
|
||||
const createRoomWithABAC = (attributes: { key: string; values: string[] }[]): RoomWithABAC => {
|
||||
const room = createFakeRoom();
|
||||
return {
|
||||
...room,
|
||||
abacAttributes: attributes,
|
||||
} as RoomWithABAC;
|
||||
};
|
||||
|
||||
const appRootWithABACEnabled = mockAppRoot().withSetting('ABAC_Enabled', true).withSetting('ABAC_ShowAttributesInRooms', true).build();
|
||||
|
||||
describe('Conditional rendering', () => {
|
||||
it('should return null when ABAC_Enabled is false', () => {
|
||||
const room = createRoomWithABAC([{ key: 'Test', values: ['Value1'] }]);
|
||||
const appRoot = mockAppRoot().withSetting('ABAC_Enabled', false).withSetting('ABAC_ShowAttributesInRooms', true).build();
|
||||
|
||||
render(<RoomInfoABACSection room={room} />, { wrapper: appRoot });
|
||||
expect(screen.queryByText('ABAC_Managed')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should return null when ABAC_ShowAttributesInRooms is false', () => {
|
||||
const room = createRoomWithABAC([{ key: 'Test', values: ['Value1'] }]);
|
||||
const appRoot = mockAppRoot().withSetting('ABAC_Enabled', true).withSetting('ABAC_ShowAttributesInRooms', false).build();
|
||||
|
||||
render(<RoomInfoABACSection room={room} />, { wrapper: appRoot });
|
||||
expect(screen.queryByText('ABAC_Managed')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should return null when abacAttributes is empty', () => {
|
||||
const room = createRoomWithABAC([]);
|
||||
render(<RoomInfoABACSection room={room} />, { wrapper: appRootWithABACEnabled });
|
||||
expect(screen.queryByText('ABAC_Managed')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render when all conditions are met', () => {
|
||||
const room = createRoomWithABAC([{ key: 'Test', values: ['Value1'] }]);
|
||||
render(<RoomInfoABACSection room={room} />, { wrapper: appRootWithABACEnabled });
|
||||
expect(screen.getByText('ABAC_Managed')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Accessibility', () => {
|
||||
it('should have no accessibility violations', async () => {
|
||||
const room = createRoomWithABAC([
|
||||
{ key: 'Chat-sensitivity', values: ['Classified', 'Top-Secret'] },
|
||||
{ key: 'Country', values: ['US-only'] },
|
||||
]);
|
||||
const { container } = render(<RoomInfoABACSection room={room} />, { wrapper: appRootWithABACEnabled });
|
||||
|
||||
const results = await axe(container);
|
||||
expect(results).toHaveNoViolations();
|
||||
});
|
||||
});
|
||||
describe('Snapshot', () => {
|
||||
it('should match the snapshot', () => {
|
||||
const room = createRoomWithABAC([
|
||||
{ key: 'Chat-sensitivity', values: ['Classified', 'Top-Secret'] },
|
||||
{ key: 'Country', values: ['US-only'] },
|
||||
]);
|
||||
const { baseElement } = render(<RoomInfoABACSection room={room} />, { wrapper: appRootWithABACEnabled });
|
||||
expect(baseElement).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { IRoom } from '@rocket.chat/core-typings';
|
||||
import { Box, Divider, Tag } from '@rocket.chat/fuselage';
|
||||
import { InfoPanelField, InfoPanelLabel } from '@rocket.chat/ui-client';
|
||||
import { useSetting } from '@rocket.chat/ui-contexts';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { RoomIcon } from '../../../../../../components/RoomIcon';
|
||||
|
||||
// TODO: Remove type union when ABAC is implemented
|
||||
export type RoomInfoABACSectionProps = {
|
||||
room: IRoom & {
|
||||
abacAttributes?: {
|
||||
key: string;
|
||||
values: string[];
|
||||
}[];
|
||||
};
|
||||
};
|
||||
|
||||
const RoomInfoABACSection = ({ room }: RoomInfoABACSectionProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const abacEnabled = useSetting('ABAC_Enabled');
|
||||
const showAttributesInRoom = useSetting('ABAC_ShowAttributesInRooms');
|
||||
|
||||
if (!abacEnabled || !showAttributesInRoom || !room.abacAttributes?.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Divider marginBlock={32} width='full' />
|
||||
<InfoPanelField>
|
||||
<Box display='flex' marginBlockEnd={16}>
|
||||
<Tag medium>
|
||||
<Box display='flex' alignItems='center'>
|
||||
<RoomIcon room={room} />
|
||||
<Box marginInlineStart={2}>{t('ABAC_Managed')}</Box>
|
||||
</Box>
|
||||
</Tag>
|
||||
</Box>
|
||||
|
||||
{t('ABAC_Managed_description')}
|
||||
|
||||
<InfoPanelLabel id='room-attributes-list-label'>{t('ABAC_Room_Attributes')}</InfoPanelLabel>
|
||||
<Box is='ul' aria-labelledby='room-attributes-list-label'>
|
||||
{room.abacAttributes.map((attribute) => (
|
||||
<Box is='li' key={attribute.key} marginBlock={16}>
|
||||
<Box is='span' id={`room-attribute-${attribute.key}-label`}>
|
||||
{attribute.key}
|
||||
</Box>
|
||||
<Box
|
||||
is='ul'
|
||||
display='flex'
|
||||
marginBlockStart={8}
|
||||
alignItems='center'
|
||||
aria-labelledby={`room-attribute-${attribute.key}-label`}
|
||||
>
|
||||
{attribute.values.map((value) => (
|
||||
<Box is='li' marginInlineEnd={4} key={value}>
|
||||
<Tag medium>{value}</Tag>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</InfoPanelField>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default RoomInfoABACSection;
|
||||
@@ -0,0 +1,123 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`RoomInfoABACSection Snapshot should match the snapshot 1`] = `
|
||||
<body>
|
||||
<div>
|
||||
<hr
|
||||
class="rcx-box rcx-box--full rcx-divider rcx-css-1972bnv"
|
||||
/>
|
||||
<div
|
||||
class="rcx-box rcx-box--full rcx-css-1jagyun"
|
||||
>
|
||||
<div
|
||||
class="rcx-box rcx-box--full rcx-css-ukxwz6"
|
||||
>
|
||||
<span
|
||||
class="rcx-box rcx-box--full rcx-tag rcx-tag--medium"
|
||||
>
|
||||
<span
|
||||
class="rcx-tag__inner"
|
||||
>
|
||||
<div
|
||||
class="rcx-box rcx-box--full rcx-css-127j9mz"
|
||||
>
|
||||
<i
|
||||
aria-hidden="true"
|
||||
class="rcx-box rcx-box--full rcx-icon--name-hash-shield rcx-icon rcx-css-1g87xs3"
|
||||
>
|
||||
|
||||
</i>
|
||||
<div
|
||||
class="rcx-box rcx-box--full rcx-css-1hq8wl6"
|
||||
>
|
||||
ABAC_Managed
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
ABAC_Managed_description
|
||||
<div
|
||||
class="rcx-box rcx-box--full rcx-css-1po16l8"
|
||||
id="room-attributes-list-label"
|
||||
>
|
||||
ABAC_Room_Attributes
|
||||
</div>
|
||||
<ul
|
||||
aria-labelledby="room-attributes-list-label"
|
||||
class="rcx-box rcx-box--full"
|
||||
>
|
||||
<li
|
||||
class="rcx-box rcx-box--full rcx-css-1jagyun"
|
||||
>
|
||||
<span
|
||||
class="rcx-box rcx-box--full"
|
||||
id="room-attribute-Chat-sensitivity-label"
|
||||
>
|
||||
Chat-sensitivity
|
||||
</span>
|
||||
<ul
|
||||
aria-labelledby="room-attribute-Chat-sensitivity-label"
|
||||
class="rcx-box rcx-box--full rcx-css-q18nro"
|
||||
>
|
||||
<li
|
||||
class="rcx-box rcx-box--full rcx-css-sdt442"
|
||||
>
|
||||
<span
|
||||
class="rcx-box rcx-box--full rcx-tag rcx-tag--medium"
|
||||
>
|
||||
<span
|
||||
class="rcx-tag__inner"
|
||||
>
|
||||
Classified
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
class="rcx-box rcx-box--full rcx-css-sdt442"
|
||||
>
|
||||
<span
|
||||
class="rcx-box rcx-box--full rcx-tag rcx-tag--medium"
|
||||
>
|
||||
<span
|
||||
class="rcx-tag__inner"
|
||||
>
|
||||
Top-Secret
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="rcx-box rcx-box--full rcx-css-1jagyun"
|
||||
>
|
||||
<span
|
||||
class="rcx-box rcx-box--full"
|
||||
id="room-attribute-Country-label"
|
||||
>
|
||||
Country
|
||||
</span>
|
||||
<ul
|
||||
aria-labelledby="room-attribute-Country-label"
|
||||
class="rcx-box rcx-box--full rcx-css-q18nro"
|
||||
>
|
||||
<li
|
||||
class="rcx-box rcx-box--full rcx-css-sdt442"
|
||||
>
|
||||
<span
|
||||
class="rcx-box rcx-box--full rcx-tag rcx-tag--medium"
|
||||
>
|
||||
<span
|
||||
class="rcx-tag__inner"
|
||||
>
|
||||
US-only
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
@@ -0,0 +1,95 @@
|
||||
import type { RoomType } from '@rocket.chat/core-typings';
|
||||
import { mockAppRoot } from '@rocket.chat/mock-providers';
|
||||
import { Contextualbar } from '@rocket.chat/ui-client';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import RoomInfo from './RoomInfo';
|
||||
import FakeRoomProvider from '../../../../../../tests/mocks/client/FakeRoomProvider';
|
||||
|
||||
export default {
|
||||
component: RoomInfo,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||
},
|
||||
decorators: [
|
||||
(fn) => (
|
||||
<FakeRoomProvider roomOverrides={roomArgs}>
|
||||
<Contextualbar height='100vh'>{fn()}</Contextualbar>
|
||||
</FakeRoomProvider>
|
||||
),
|
||||
],
|
||||
args: {
|
||||
icon: 'lock',
|
||||
},
|
||||
} satisfies Meta<typeof RoomInfo>;
|
||||
|
||||
const roomArgs = {
|
||||
_id: 'myRoom',
|
||||
t: 'c' as RoomType,
|
||||
msgs: 5,
|
||||
usersCount: 1,
|
||||
u: {
|
||||
_id: 'rocketchat.internal.admin.test',
|
||||
username: 'rocketchat.internal.admin.test',
|
||||
},
|
||||
ts: new Date(),
|
||||
autoTranslateLanguage: 'en',
|
||||
_updatedAt: new Date(),
|
||||
fname: 'rocketchat-frontend-team',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam mollis nisi vel arcu bibendum vehicula. Integer vitae suscipit libero',
|
||||
announcement:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam mollis nisi vel arcu bibendum vehicula. Integer vitae suscipit libero',
|
||||
topic:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam mollis nisi vel arcu bibendum vehicula. Integer vitae suscipit libero',
|
||||
};
|
||||
|
||||
export const Default = {
|
||||
args: {
|
||||
room: roomArgs,
|
||||
},
|
||||
};
|
||||
|
||||
export const Archived = {
|
||||
args: {
|
||||
...Default.args,
|
||||
room: {
|
||||
...roomArgs,
|
||||
archived: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Broadcast = {
|
||||
args: {
|
||||
...Default.args,
|
||||
room: {
|
||||
...roomArgs,
|
||||
broadcast: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const ABAC: StoryObj<typeof RoomInfo> = {
|
||||
decorators: [
|
||||
mockAppRoot().withSetting('ABAC_Enabled', true).withSetting('ABAC_ShowAttributesInRooms', true).buildStoryDecorator(),
|
||||
(fn) => (
|
||||
<FakeRoomProvider roomOverrides={roomArgs}>
|
||||
<Contextualbar height='100vh'>{fn()}</Contextualbar>
|
||||
</FakeRoomProvider>
|
||||
),
|
||||
],
|
||||
|
||||
args: {
|
||||
...Default.args,
|
||||
room: {
|
||||
...roomArgs,
|
||||
abacAttributes: [
|
||||
{ key: 'Chat-sensitivity', values: ['Classified', 'Top-Secret'] },
|
||||
{ key: 'Country', values: ['US-only'] },
|
||||
{ key: 'Project', values: ['Ruminator-2000'] },
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,138 @@
|
||||
import type { IRoom } from '@rocket.chat/core-typings';
|
||||
import { Box, Callout, IconButton } from '@rocket.chat/fuselage';
|
||||
import { RoomAvatar } from '@rocket.chat/ui-avatar';
|
||||
import {
|
||||
GenericMenu,
|
||||
ContextualbarHeader,
|
||||
ContextualbarScrollableContent,
|
||||
ContextualbarBack,
|
||||
ContextualbarIcon,
|
||||
ContextualbarClose,
|
||||
ContextualbarTitle,
|
||||
ContextualbarDialog,
|
||||
InfoPanel,
|
||||
InfoPanelActionGroup,
|
||||
InfoPanelAvatar,
|
||||
InfoPanelField,
|
||||
InfoPanelLabel,
|
||||
InfoPanelSection,
|
||||
InfoPanelText,
|
||||
InfoPanelTitle,
|
||||
} from '@rocket.chat/ui-client';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import RoomInfoActions from './RoomInfoActions';
|
||||
import RetentionPolicyCallout from '../../../../../components/InfoPanel/RetentionPolicyCallout';
|
||||
import MarkdownText from '../../../../../components/MarkdownText';
|
||||
import { useRetentionPolicy } from '../../../hooks/useRetentionPolicy';
|
||||
import { useRoomActions } from '../hooks/useRoomActions';
|
||||
import { useSplitRoomActions } from '../hooks/useSplitRoomActions';
|
||||
import RoomInfoABACSection from './ABAC/RoomInfoABACSection';
|
||||
|
||||
export type RoomInfoProps = {
|
||||
room: IRoom;
|
||||
icon: string;
|
||||
onClickBack?: () => void;
|
||||
onClickClose?: () => void;
|
||||
onClickEnterRoom?: () => void;
|
||||
onClickEdit?: () => void;
|
||||
resetState?: () => void;
|
||||
};
|
||||
|
||||
const RoomInfo = ({ room, icon, onClickBack, onClickClose, onClickEnterRoom, onClickEdit, resetState }: RoomInfoProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { name, fname, description, topic, archived, broadcast, announcement } = room;
|
||||
const roomTitle = fname || name;
|
||||
const isDiscussion = 'prid' in room;
|
||||
|
||||
const retentionPolicy = useRetentionPolicy(room);
|
||||
const actions = useRoomActions(room, { onClickEnterRoom, onClickEdit, resetState });
|
||||
const { buttons, menu } = useSplitRoomActions(actions);
|
||||
|
||||
return (
|
||||
<ContextualbarDialog>
|
||||
<ContextualbarHeader>
|
||||
{onClickBack ? <ContextualbarBack onClick={onClickBack} /> : <ContextualbarIcon name='info-circled' />}
|
||||
<ContextualbarTitle>{isDiscussion ? t('Discussion_info') : t('Channel_info')}</ContextualbarTitle>
|
||||
{onClickClose && <ContextualbarClose onClick={onClickClose} />}
|
||||
</ContextualbarHeader>
|
||||
|
||||
<ContextualbarScrollableContent padding={24}>
|
||||
<InfoPanel>
|
||||
<InfoPanelSection maxWidth='x332' marginInline='auto'>
|
||||
<InfoPanelAvatar>
|
||||
<RoomAvatar size='x332' room={room} />
|
||||
</InfoPanelAvatar>
|
||||
<InfoPanelActionGroup>
|
||||
<RoomInfoActions actions={buttons} />
|
||||
{menu && (
|
||||
<GenericMenu
|
||||
title={t('More')}
|
||||
placement='bottom-end'
|
||||
button={<IconButton icon='kebab' secondary flexShrink={0} flexGrow={0} maxHeight='initial' />}
|
||||
sections={menu}
|
||||
/>
|
||||
)}
|
||||
</InfoPanelActionGroup>
|
||||
</InfoPanelSection>
|
||||
|
||||
{archived && (
|
||||
<InfoPanelSection>
|
||||
<Box marginBlock={16}>
|
||||
<Callout type='warning'>{t('Room_archived')}</Callout>
|
||||
</Box>
|
||||
</InfoPanelSection>
|
||||
)}
|
||||
|
||||
{roomTitle && (
|
||||
<InfoPanelSection>
|
||||
<InfoPanelTitle title={roomTitle} icon={icon} />
|
||||
</InfoPanelSection>
|
||||
)}
|
||||
|
||||
<InfoPanelSection>
|
||||
{broadcast && (
|
||||
<InfoPanelField>
|
||||
<InfoPanelLabel>
|
||||
<b>{t('Broadcast_channel')}</b> {t('Broadcast_channel_Description')}
|
||||
</InfoPanelLabel>
|
||||
</InfoPanelField>
|
||||
)}
|
||||
|
||||
{description && description !== '' && (
|
||||
<InfoPanelField>
|
||||
<InfoPanelLabel>{t('Description')}</InfoPanelLabel>
|
||||
<InfoPanelText withTruncatedText={false}>
|
||||
<MarkdownText variant='inline' content={description} />
|
||||
</InfoPanelText>
|
||||
</InfoPanelField>
|
||||
)}
|
||||
|
||||
{announcement && announcement !== '' && (
|
||||
<InfoPanelField>
|
||||
<InfoPanelLabel>{t('Announcement')}</InfoPanelLabel>
|
||||
<InfoPanelText withTruncatedText={false}>
|
||||
<MarkdownText variant='inline' content={announcement} />
|
||||
</InfoPanelText>
|
||||
</InfoPanelField>
|
||||
)}
|
||||
|
||||
{topic && topic !== '' && (
|
||||
<InfoPanelField>
|
||||
<InfoPanelLabel>{t('Topic')}</InfoPanelLabel>
|
||||
<InfoPanelText withTruncatedText={false}>
|
||||
<MarkdownText variant='inline' content={topic} />
|
||||
</InfoPanelText>
|
||||
</InfoPanelField>
|
||||
)}
|
||||
|
||||
{retentionPolicy?.isActive && <RetentionPolicyCallout room={room} />}
|
||||
<RoomInfoABACSection room={room} />
|
||||
</InfoPanelSection>
|
||||
</InfoPanel>
|
||||
</ContextualbarScrollableContent>
|
||||
</ContextualbarDialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default RoomInfo;
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { Keys as IconKeys } from '@rocket.chat/icons';
|
||||
import { InfoPanelAction } from '@rocket.chat/ui-client';
|
||||
|
||||
type Action = {
|
||||
id: string;
|
||||
content: string;
|
||||
icon: IconKeys;
|
||||
onClick: () => void;
|
||||
variant?: string;
|
||||
};
|
||||
|
||||
export type RoomInfoActionsProps = {
|
||||
actions: { items: Action[] };
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const RoomInfoActions = ({ actions, className }: RoomInfoActionsProps) => {
|
||||
return (
|
||||
<>
|
||||
{actions.items.map(({ id, content, icon, onClick }) => (
|
||||
<InfoPanelAction className={className} key={id} label={content} onClick={onClick} icon={icon} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default RoomInfoActions;
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './RoomInfo';
|
||||
Reference in New Issue
Block a user