From 2d2dddd92c84392b323196bc77a8044495df23b4 Mon Sep 17 00:00:00 2001 From: juliajforesti Date: Thu, 29 Oct 2026 12:36:20 -0300 Subject: [PATCH 1/4] fix: inset the workspace page content like the other admin pages The workspace page set its content 16px from the edges, while the subscription, settings, AI center and engagement pages use 24px, which also lines the cards up with the page title. Co-Authored-By: Claude Opus 5.5 --- apps/meteor/client/views/admin/workspace/WorkspacePage.tsx | 2 +- scripts/spacing-scale/baseline.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/views/admin/workspace/WorkspacePage.tsx b/apps/meteor/client/views/admin/workspace/WorkspacePage.tsx index 7c8c2d5c1820e..17f4691a7778b 100644 --- a/apps/meteor/client/views/admin/workspace/WorkspacePage.tsx +++ b/apps/meteor/client/views/admin/workspace/WorkspacePage.tsx @@ -48,7 +48,7 @@ const WorkspacePage = ({ )} - + {warningMultipleInstances && } diff --git a/scripts/spacing-scale/baseline.json b/scripts/spacing-scale/baseline.json index 8cb9cdcc31f76..a29d95be8285c 100644 --- a/scripts/spacing-scale/baseline.json +++ b/scripts/spacing-scale/baseline.json @@ -196,7 +196,7 @@ "apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.tsx": 1, "apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.tsx": 2, "apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.tsx": 2, - "apps/meteor/client/views/admin/workspace/WorkspacePage.tsx": 2, + "apps/meteor/client/views/admin/workspace/WorkspacePage.tsx": 1, "apps/meteor/client/views/apps/GameCenterContainer.tsx": 1, "apps/meteor/client/views/apps/GameCenterInvitePlayersModal.tsx": 2, "apps/meteor/client/views/audit/AuditPage.tsx": 2, From c5e051b493a8db47fcb65ba43c71a11ad0b9d3ba Mon Sep 17 00:00:00 2001 From: juliajforesti Date: Wed, 28 Oct 2026 16:01:00 -0300 Subject: [PATCH 2/4] test: stories for admin workspace states the app rarely shows The users and uploads card, the version card's skeleton and action items, and the workspace registration modals, so their layout can be compared before and after the migration off raw Box. Co-Authored-By: Claude Opus 5.5 --- .../UsersUploadsCard.stories.tsx | 29 ++++++++++++++++ .../VersionCardActionItem.stories.tsx | 33 +++++++++++++++++++ .../VersionCardSkeleton.stories.tsx | 20 +++++++++++ .../modals/RegisterWorkspaceModal.stories.tsx | 15 +++++++++ ...sterWorkspaceSetupStepOneModal.stories.tsx | 25 ++++++++++++++ ...sterWorkspaceSetupStepTwoModal.stories.tsx | 26 +++++++++++++++ .../RegisterWorkspaceTokenModal.stories.tsx | 15 +++++++++ .../RegisteredWorkspaceModal.stories.tsx | 15 +++++++++ 8 files changed, 178 insertions(+) create mode 100644 apps/meteor/client/views/admin/workspace/UsersUploadsCard/UsersUploadsCard.stories.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.stories.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.stories.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.stories.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.stories.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.stories.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.stories.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.stories.tsx diff --git a/apps/meteor/client/views/admin/workspace/UsersUploadsCard/UsersUploadsCard.stories.tsx b/apps/meteor/client/views/admin/workspace/UsersUploadsCard/UsersUploadsCard.stories.tsx new file mode 100644 index 0000000000000..3c64e67afd36e --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/UsersUploadsCard/UsersUploadsCard.stories.tsx @@ -0,0 +1,29 @@ +import type { IStats } from '@rocket.chat/core-typings'; +import type { Meta, StoryObj } from '@storybook/react'; + +import UsersUploadsCard from './UsersUploadsCard'; + +export default { + component: UsersUploadsCard, + parameters: { + layout: 'centered', + }, + args: { + statistics: { + onlineUsers: 12, + busyUsers: 3, + awayUsers: 5, + offlineUsers: 80, + totalUsers: 100, + totalConnectedUsers: 20, + activeUsers: 90, + activeGuests: 4, + nonActiveUsers: 6, + appUsers: 2, + uploadsTotal: 321, + uploadsTotalSize: 123456789, + } as IStats, + }, +} satisfies Meta; + +export const Default: StoryObj = {}; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.stories.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.stories.tsx new file mode 100644 index 0000000000000..8918f2bc60fbd --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.stories.tsx @@ -0,0 +1,33 @@ +import { ExternalLink } from '@rocket.chat/ui-client'; +import type { Meta, StoryObj } from '@storybook/react'; + +import VersionCardActionItem from './VersionCardActionItem'; + +export default { + component: VersionCardActionItem, + parameters: { + layout: 'padded', + }, + args: { + icon: 'check', + label: 'Operating within plan limits', + }, +} satisfies Meta; + +type Story = StoryObj; + +export const Default: Story = {}; + +export const Danger: Story = { + args: { danger: true, icon: 'warning', label: 'Plan limits reached' }, +}; + +export const WithLink: Story = { + args: { + label: ( + <> + Version supported until Dec 31, 2026 + + ), + }, +}; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.stories.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.stories.tsx new file mode 100644 index 0000000000000..78d62324bd54f --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.stories.tsx @@ -0,0 +1,20 @@ +import { Card } from '@rocket.chat/fuselage'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { VersionCardSkeleton } from './VersionCardSkeleton'; + +export default { + component: VersionCardSkeleton, + parameters: { + layout: 'padded', + }, + decorators: [ + (Story) => ( + + + + ), + ], +} satisfies Meta; + +export const Default: StoryObj = {}; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.stories.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.stories.tsx new file mode 100644 index 0000000000000..97cc4cbdadff1 --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.stories.tsx @@ -0,0 +1,15 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import RegisterWorkspaceModal from './RegisterWorkspaceModal'; + +export default { + component: RegisterWorkspaceModal, + parameters: { + layout: 'fullscreen', + }, + argTypes: { + onClose: { action: 'onClose' }, + }, +} satisfies Meta; + +export const Default: StoryObj = {}; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.stories.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.stories.tsx new file mode 100644 index 0000000000000..a48bb9edd4b5c --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.stories.tsx @@ -0,0 +1,25 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import RegisterWorkspaceSetupStepOneModal from './RegisterWorkspaceSetupStepOneModal'; + +export default { + component: RegisterWorkspaceSetupStepOneModal, + parameters: { + layout: 'fullscreen', + }, + args: { + email: '', + step: 1, + terms: false, + validInfo: false, + }, + argTypes: { + onClose: { action: 'onClose' }, + setEmail: { action: 'setEmail' }, + setStep: { action: 'setStep' }, + setTerms: { action: 'setTerms' }, + setIntentData: { action: 'setIntentData' }, + }, +} satisfies Meta; + +export const Default: StoryObj = {}; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.stories.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.stories.tsx new file mode 100644 index 0000000000000..3154605548843 --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.stories.tsx @@ -0,0 +1,26 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import RegisterWorkspaceSetupStepTwoModal from './RegisterWorkspaceSetupStepTwoModal'; + +export default { + component: RegisterWorkspaceSetupStepTwoModal, + parameters: { + layout: 'fullscreen', + }, + args: { + email: 'admin@example.com', + step: 2, + intentData: { + device_code: 'device-code', + interval: 3600, + user_code: 'ABCD-1234', + }, + }, + argTypes: { + onClose: { action: 'onClose' }, + setStep: { action: 'setStep' }, + onSuccess: { action: 'onSuccess' }, + }, +} satisfies Meta; + +export const Default: StoryObj = {}; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.stories.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.stories.tsx new file mode 100644 index 0000000000000..1333e8d3397b8 --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.stories.tsx @@ -0,0 +1,15 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import RegisterWorkspaceTokenModal from './RegisterWorkspaceTokenModal'; + +export default { + component: RegisterWorkspaceTokenModal, + parameters: { + layout: 'fullscreen', + }, + argTypes: { + onClose: { action: 'onClose' }, + }, +} satisfies Meta; + +export const Default: StoryObj = {}; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.stories.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.stories.tsx new file mode 100644 index 0000000000000..76207b6f1c3ad --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.stories.tsx @@ -0,0 +1,15 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import RegisteredWorkspaceModal from './RegisteredWorkspaceModal'; + +export default { + component: RegisteredWorkspaceModal, + parameters: { + layout: 'fullscreen', + }, + argTypes: { + onClose: { action: 'onClose' }, + }, +} satisfies Meta; + +export const Default: StoryObj = {}; From 0c48ded72c69a5ffbec086d2c933d986cbcbb898 Mon Sep 17 00:00:00 2001 From: juliajforesti Date: Wed, 28 Oct 2026 16:01:42 -0300 Subject: [PATCH 3/4] refactor: admin workspace screens compose layout containers instead of Box The workspace page, its cards and the registration modals stop laying themselves out with raw Box. Text carries typography, Stack gaps space siblings, and the spacing `Margins` gave the card sections now comes from a parent container. One-off containers live in `layout/` folders next to the screens. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci-code-check.yml | 2 +- .../DeploymentCard/DeploymentCard.tsx | 78 ++++++------------- .../InstancesModal/DescriptionList.tsx | 13 ++-- .../layout/DescriptionListFrame.tsx | 23 ++++++ .../MessagesRoomsCard/MessagesRoomsCard.tsx | 8 +- .../UsersUploadsCard/UsersUploadsCard.tsx | 20 ++--- .../components/VersionCardActionItem.tsx | 10 ++- .../components/VersionCardSkeleton.tsx | 16 ++-- .../layout/VersionCardSkeletonRow.tsx | 18 +++++ .../modals/RegisterWorkspaceModal.tsx | 41 +++++----- .../RegisterWorkspaceSetupStepOneModal.tsx | 30 +++---- .../RegisterWorkspaceSetupStepTwoModal.tsx | 50 ++++++------ .../modals/RegisterWorkspaceTokenModal.tsx | 16 ++-- .../modals/RegisteredWorkspaceModal.tsx | 18 ++--- .../modals/layout/FeatureBullet.tsx | 21 +++++ .../modals/layout/ModalFooterNote.tsx | 17 ++++ .../modals/layout/RegistrationAccountNote.tsx | 21 +++++ .../modals/layout/RegistrationProse.tsx | 13 ++++ .../views/admin/workspace/WorkspacePage.tsx | 10 +-- .../components/WorkspaceCardDetail.tsx | 21 +++++ .../components/WorkspaceCardSection.tsx | 15 +++- .../components/WorkspaceCardSectionTitle.tsx | 6 +- .../components/WorkspaceCardTextSeparator.tsx | 12 +-- .../workspace/layout/StatusBulletSlot.tsx | 17 ++++ .../layout/WorkspaceCardSections.tsx | 21 +++++ scripts/spacing-scale/baseline.json | 12 --- 26 files changed, 322 insertions(+), 207 deletions(-) create mode 100644 apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/layout/DescriptionListFrame.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/layout/VersionCardSkeletonRow.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/FeatureBullet.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/ModalFooterNote.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/RegistrationAccountNote.tsx create mode 100644 apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/RegistrationProse.tsx create mode 100644 apps/meteor/client/views/admin/workspace/components/WorkspaceCardDetail.tsx create mode 100644 apps/meteor/client/views/admin/workspace/layout/StatusBulletSlot.tsx create mode 100644 apps/meteor/client/views/admin/workspace/layout/WorkspaceCardSections.tsx diff --git a/.github/workflows/ci-code-check.yml b/.github/workflows/ci-code-check.yml index 48be56e1b1847..9d42a3066eb32 100644 --- a/.github/workflows/ci-code-check.yml +++ b/.github/workflows/ci-code-check.yml @@ -105,7 +105,7 @@ jobs: - name: Raw layout elements in screens if: matrix.check == 'lint' - run: node scripts/scan-raw-layout.mjs --max 1146 "$RUNNER_TEMP/raw-layout-findings.json" + run: node scripts/scan-raw-layout.mjs --max 1104 "$RUNNER_TEMP/raw-layout-findings.json" - name: Spacing scale if: matrix.check == 'lint' diff --git a/apps/meteor/client/views/admin/workspace/DeploymentCard/DeploymentCard.tsx b/apps/meteor/client/views/admin/workspace/DeploymentCard/DeploymentCard.tsx index ff3a2c70c64c6..e568305886da0 100644 --- a/apps/meteor/client/views/admin/workspace/DeploymentCard/DeploymentCard.tsx +++ b/apps/meteor/client/views/admin/workspace/DeploymentCard/DeploymentCard.tsx @@ -1,5 +1,5 @@ import type { IWorkspaceInfo, IStats } from '@rocket.chat/core-typings'; -import { Button, Card, CardBody, CardControls, Margins } from '@rocket.chat/fuselage'; +import { Button, Card, CardBody, CardControls, Text } from '@rocket.chat/fuselage'; import { useStableCallback } from '@rocket.chat/fuselage-hooks'; import type { IInstance } from '@rocket.chat/rest-typings'; import { useFormatDateAndTime } from '@rocket.chat/ui-client'; @@ -7,9 +7,10 @@ import { useSetModal } from '@rocket.chat/ui-contexts'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; -import WorkspaceCardSection from '../components/WorkspaceCardSection'; import InstancesModal from './components/InstancesModal'; +import WorkspaceCardDetail from '../components/WorkspaceCardDetail'; import WorkspaceCardSectionTitle from '../components/WorkspaceCardSectionTitle'; +import WorkspaceCardSections from '../layout/WorkspaceCardSections'; export type DeploymentCardProps = { serverInfo: IWorkspaceInfo; @@ -35,67 +36,34 @@ const DeploymentCard = ({ return ( - - - - - - - {statistics.version} - - {workspaceUrl && ( - - - {workspaceUrl} - - )} + + + {statistics.version} + {workspaceUrl && {workspaceUrl}} {hashedWorkspaceUrl && ( - - - {hashedWorkspaceUrl} - + + + {hashedWorkspaceUrl} + + )} - - - {statistics.uniqueId} - + {statistics.uniqueId} - {cloudWorkspaceId && ( - - - {cloudWorkspaceId} - - )} + {cloudWorkspaceId && {cloudWorkspaceId}} - {appsEngineVersion && ( - - - {appsEngineVersion} - - )} - - - {statistics.process.nodeVersion} - - - + {appsEngineVersion && {appsEngineVersion}} + {statistics.process.nodeVersion} + {`${statistics.migration.version} (${formatDateAndTime(statistics.migration.lockedAt)})`} - - - - {`${statistics.mongoVersion} / ${statistics.mongoStorageEngine}`} - - - + + {`${statistics.mongoVersion} / ${statistics.mongoStorageEngine}`} + {t('github_HEAD')}: ({commit.hash ? commit.hash.slice(0, 9) : ''})
{t('Branch')}: {commit.branch}
{commit.subject} -
- - - {statistics.process.pid} - -
+ + {statistics.process.pid} +
{!!instances.length && ( diff --git a/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/DescriptionList.tsx b/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/DescriptionList.tsx index 915e0368d4c89..77dc0c35c7183 100644 --- a/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/DescriptionList.tsx +++ b/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/DescriptionList.tsx @@ -1,23 +1,20 @@ -import { Box, Table, TableBody } from '@rocket.chat/fuselage'; +import { Table, TableBody } from '@rocket.chat/fuselage'; import type { ReactNode } from 'react'; import { memo } from 'react'; +import DescriptionListFrame from './layout/DescriptionListFrame'; + export type DescriptionListProps = { children: ReactNode; title?: string; }; const DescriptionList = ({ children, title }: DescriptionListProps) => ( - - {title && ( - - {title} - - )} + {children}
-
+ ); export default memo(DescriptionList); diff --git a/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/layout/DescriptionListFrame.tsx b/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/layout/DescriptionListFrame.tsx new file mode 100644 index 0000000000000..a7ae93458027b --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/layout/DescriptionListFrame.tsx @@ -0,0 +1,23 @@ +import { Box } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +type DescriptionListFrameProps = { + title?: string; + children: ReactNode; +}; + +/** + * Frames a description list: its optional title over the label column, and room below before the next list. + */ +const DescriptionListFrame = ({ title, children }: DescriptionListFrameProps) => ( + + {title && ( + + {title} + + )} + {children} + +); + +export default DescriptionListFrame; diff --git a/apps/meteor/client/views/admin/workspace/MessagesRoomsCard/MessagesRoomsCard.tsx b/apps/meteor/client/views/admin/workspace/MessagesRoomsCard/MessagesRoomsCard.tsx index a744307583317..060e485f841a4 100644 --- a/apps/meteor/client/views/admin/workspace/MessagesRoomsCard/MessagesRoomsCard.tsx +++ b/apps/meteor/client/views/admin/workspace/MessagesRoomsCard/MessagesRoomsCard.tsx @@ -4,7 +4,6 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import WorkspaceCardSection from '../components/WorkspaceCardSection'; -import WorkspaceCardSectionTitle from '../components/WorkspaceCardSectionTitle'; import WorkspaceCardTextSeparator from '../components/WorkspaceCardTextSeparator'; export type MessagesRoomsCardProps = { @@ -16,9 +15,7 @@ const MessagesRoomsCard = ({ statistics }: MessagesRoomsCardProps) => { return ( - - - + @@ -27,8 +24,7 @@ const MessagesRoomsCard = ({ statistics }: MessagesRoomsCardProps) => { - - + { return ( - - - - + + - - - + @@ -50,13 +46,11 @@ const UsersUploadsCard = ({ statistics }: UsersUploadsCardProps) => { - - - + - + diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.tsx index db5664eea2ea2..5cae688130222 100644 --- a/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.tsx +++ b/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.tsx @@ -1,4 +1,4 @@ -import { Box, FramedIcon } from '@rocket.chat/fuselage'; +import { FramedIcon, Stack, Text } from '@rocket.chat/fuselage'; import type { Keys } from '@rocket.chat/icons'; import type { ReactNode } from 'react'; @@ -12,10 +12,12 @@ export type VersionCardActionItemProps = VersionActionItem; const VersionCardActionItem = ({ icon, label, danger }: VersionCardActionItemProps) => { return ( - + - {label} - + + {label} + + ); }; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.tsx index 712fa8c4e5326..7c45bfbe4c05d 100644 --- a/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.tsx +++ b/apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.tsx @@ -1,22 +1,24 @@ -import { Box, Skeleton } from '@rocket.chat/fuselage'; +import { Skeleton } from '@rocket.chat/fuselage'; + +import VersionCardSkeletonRow from '../layout/VersionCardSkeletonRow'; export const VersionCardSkeleton = () => { return ( <> - + - - + + - - + + - + ); diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/layout/VersionCardSkeletonRow.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/layout/VersionCardSkeletonRow.tsx new file mode 100644 index 0000000000000..c74f3f647f790 --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/layout/VersionCardSkeletonRow.tsx @@ -0,0 +1,18 @@ +import { Box } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +type VersionCardSkeletonRowProps = { + width: number; + children: ReactNode; +}; + +/** + * The placeholder of one version card action item: its icon and label skeletons side by side. + */ +const VersionCardSkeletonRow = ({ width, children }: VersionCardSkeletonRowProps) => ( + + {children} + +); + +export default VersionCardSkeletonRow; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.tsx index 3768743b941d7..364e7b4a65eae 100644 --- a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.tsx +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.tsx @@ -1,5 +1,4 @@ import { - Box, Button, ButtonGroup, Modal, @@ -9,6 +8,7 @@ import { ModalHeader, ModalHeaderText, ModalTitle, + Text, } from '@rocket.chat/fuselage'; import { ExternalLink } from '@rocket.chat/ui-client'; import { useSetModal } from '@rocket.chat/ui-contexts'; @@ -16,6 +16,8 @@ import { useTranslation } from 'react-i18next'; import RegisterWorkspaceSetupModal from './RegisterWorkspaceSetupModal'; import RegisterWorkspaceTokenModal from './RegisterWorkspaceTokenModal'; +import FeatureBullet from './layout/FeatureBullet'; +import RegistrationProse from './layout/RegistrationProse'; import { links } from '../../../../../lib/links'; import useFeatureBullets from '../hooks/useFeatureBullets'; @@ -50,33 +52,26 @@ const RegisterWorkspaceModal = ({ onClose, onStatusChange, ...props }: RegisterW - - {`${t('RegisterWorkspace_NotRegistered_Subtitle')}:`} + + {`${t('RegisterWorkspace_NotRegistered_Subtitle')}:`}
    {bulletFeatures.map((features) => ( -
  • - {features.title} - - {features.description} - -
  • + + {features.description} + ))}
- - {t('RegisterWorkspace_Registered_Benefits')} - -
+ {t('RegisterWorkspace_Registered_Benefits')} +
- - - {t('Learn_more')} - - - - - + + {t('Learn_more')} + + + + ); diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.tsx index cb81b1b2ed347..c92c299dcba03 100644 --- a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.tsx +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.tsx @@ -1,5 +1,4 @@ import { - Box, Button, ButtonGroup, CheckBox, @@ -25,6 +24,7 @@ import { useTranslation, Trans } from 'react-i18next'; import { links } from '../../../../../../lib/links'; import WorkspaceRegistrationModal from '../RegisterWorkspaceModal'; +import RegistrationAccountNote from '../layout/RegistrationAccountNote'; type Props = { email: string; @@ -84,11 +84,9 @@ const RegisterWorkspaceSetupStepOneModal = ({ - + - - {t('RegisterWorkspace_Setup_Subtitle')} - + {t('RegisterWorkspace_Setup_Subtitle')} {t('RegisterWorkspace_Setup_Label')} @@ -101,19 +99,15 @@ const RegisterWorkspaceSetupStepOneModal = ({ - - - {t('RegisterWorkspace_Setup_Have_Account_Title')} - - {t('RegisterWorkspace_Setup_Have_Account_Subtitle')} - - {t('RegisterWorkspace_Setup_No_Account_Title')} - - {t('RegisterWorkspace_Setup_No_Account_Subtitle')} - + + {t('RegisterWorkspace_Setup_Have_Account_Subtitle')} + + + {t('RegisterWorkspace_Setup_No_Account_Subtitle')} + - + @@ -123,10 +117,10 @@ const RegisterWorkspaceSetupStepOneModal = ({ setTerms(!terms)} /> - + - + diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.tsx index 2d66e85377d2e..ef78748fcedb6 100644 --- a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.tsx +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.tsx @@ -19,6 +19,8 @@ import { useEndpoint, useToastMessageDispatch } from '@rocket.chat/ui-contexts'; import { useCallback, useEffect } from 'react'; import { useTranslation, Trans } from 'react-i18next'; +import ModalFooterNote from '../layout/ModalFooterNote'; + type Props = { email: string; step: number; @@ -83,42 +85,38 @@ const RegisterWorkspaceSetupStepTwoModal = ({ email, step, setStep, onClose, int - - - - - Email sent to{' '} - - {email}{' '} - - with a confirmation link. - - - - - {t('RegisterWorkspace_Setup_Email_Verification')} - - {t('Security_code')} - - - - - - + + + Email sent to{' '} + + {email}{' '} + + with a confirmation link. + + + + {t('RegisterWorkspace_Setup_Email_Verification')} + + {t('Security_code')} + + + + + - + Didn't receive email?{' '} - + Resend {' '} or{' '} - + change email - + ); diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.tsx index fbb86e429056d..eac7645e1423a 100644 --- a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.tsx +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.tsx @@ -1,5 +1,4 @@ import { - Box, Button, ButtonGroup, Field, @@ -15,6 +14,7 @@ import { ModalContent, ModalFooter, Stack, + Text, } from '@rocket.chat/fuselage'; import { useEndpoint, useSetModal, useToastMessageDispatch } from '@rocket.chat/ui-contexts'; import type { ChangeEvent } from 'react'; @@ -77,21 +77,21 @@ const RegisterWorkspaceTokenModal = ({ onClose, onStatusChange, ...props }: Regi - + 1. Go to:{' '} - + cloud.rocket.chat {'>'} Workspaces - {' '} + {' '} and click{' '} - + "Register self-managed" - + . - + - {`2. ${t('RegisterWorkspace_Token_Step_Two')}`} + {`2. ${t('RegisterWorkspace_Token_Step_Two')}`} {t('Registration_Token')} diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.tsx index aeed931bc0283..851e85566aabc 100644 --- a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.tsx +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.tsx @@ -1,5 +1,4 @@ import { - Box, Button, ButtonGroup, Modal, @@ -16,6 +15,8 @@ import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import useFeatureBullets from '../hooks/useFeatureBullets'; +import FeatureBullet from './layout/FeatureBullet'; +import RegistrationProse from './layout/RegistrationProse'; export type RegisteredWorkspaceModalProps = { onClose: () => void; @@ -61,19 +62,16 @@ const RegisteredWorkspaceModal = ({ onClose, onStatusChange, ...props }: Registe - - {`${t('RegisterWorkspace_Registered_Subtitle')}: `} + + {`${t('RegisterWorkspace_Registered_Subtitle')}: `}
    {bulletFeatures.map((item, index) => ( -
  • - {item.title} - - {item.description} - -
  • + + {item.description} + ))}
-
+
diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/FeatureBullet.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/FeatureBullet.tsx new file mode 100644 index 0000000000000..e25699815adfb --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/FeatureBullet.tsx @@ -0,0 +1,21 @@ +import { Box } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +type FeatureBulletProps = { + title: ReactNode; + children: ReactNode; +}; + +/** + * A list item naming a feature of registered workspaces, its description close below the name. + */ +const FeatureBullet = ({ title, children }: FeatureBulletProps) => ( +
  • + {title} + + {children} + +
  • +); + +export default FeatureBullet; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/ModalFooterNote.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/ModalFooterNote.tsx new file mode 100644 index 0000000000000..7d77a15f9e186 --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/ModalFooterNote.tsx @@ -0,0 +1,17 @@ +import { Box } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +type ModalFooterNoteProps = { + children: ReactNode; +}; + +/** + * A short note in small print at the start of a modal footer, its links set in line with the text. + */ +const ModalFooterNote = ({ children }: ModalFooterNoteProps) => ( + + {children} + +); + +export default ModalFooterNote; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/RegistrationAccountNote.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/RegistrationAccountNote.tsx new file mode 100644 index 0000000000000..c84022cc450ec --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/RegistrationAccountNote.tsx @@ -0,0 +1,21 @@ +import { Box, Text } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +type RegistrationAccountNoteProps = { + title: ReactNode; + children: ReactNode; +}; + +/** + * A note in small print on registering with or without a cloud account: a bold title, then the details. + */ +const RegistrationAccountNote = ({ title, children }: RegistrationAccountNoteProps) => ( + + + {title} + + {children} + +); + +export default RegistrationAccountNote; diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/RegistrationProse.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/RegistrationProse.tsx new file mode 100644 index 0000000000000..7a6594a8fea6e --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/layout/RegistrationProse.tsx @@ -0,0 +1,13 @@ +import { Box } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +type RegistrationProseProps = { + children: ReactNode; +}; + +/** + * The explanatory text of a registration modal, its paragraphs and lists spaced as rich text. + */ +const RegistrationProse = ({ children }: RegistrationProseProps) => {children}; + +export default RegistrationProse; diff --git a/apps/meteor/client/views/admin/workspace/WorkspacePage.tsx b/apps/meteor/client/views/admin/workspace/WorkspacePage.tsx index 17f4691a7778b..01dd5bb9cad47 100644 --- a/apps/meteor/client/views/admin/workspace/WorkspacePage.tsx +++ b/apps/meteor/client/views/admin/workspace/WorkspacePage.tsx @@ -1,5 +1,5 @@ import type { IWorkspaceInfo, IStats } from '@rocket.chat/core-typings'; -import { Box, Button, ButtonGroup, Callout, CardGrid } from '@rocket.chat/fuselage'; +import { Button, ButtonGroup, Callout, CardGrid, Stack } from '@rocket.chat/fuselage'; import type { IInstance } from '@rocket.chat/rest-typings'; import { Page, PageHeader, PageScrollableContentWithShadow, useIsEnterprise } from '@rocket.chat/ui-client'; import { memo } from 'react'; @@ -49,17 +49,15 @@ const WorkspacePage = ({ - + {warningMultipleInstances && } - - - + - +
    ); diff --git a/apps/meteor/client/views/admin/workspace/components/WorkspaceCardDetail.tsx b/apps/meteor/client/views/admin/workspace/components/WorkspaceCardDetail.tsx new file mode 100644 index 0000000000000..77edba5dc4af2 --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/components/WorkspaceCardDetail.tsx @@ -0,0 +1,21 @@ +import { Text } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +import WorkspaceCardSectionTitle from './WorkspaceCardSectionTitle'; + +export type WorkspaceCardDetailProps = { + label: string; + children: ReactNode; +}; + +/** + * One labelled value in a workspace card, its label on the line above it. + */ +const WorkspaceCardDetail = ({ label, children }: WorkspaceCardDetailProps) => ( + + + {children} + +); + +export default WorkspaceCardDetail; diff --git a/apps/meteor/client/views/admin/workspace/components/WorkspaceCardSection.tsx b/apps/meteor/client/views/admin/workspace/components/WorkspaceCardSection.tsx index e14319bf74ba5..848c5f0d78b4f 100644 --- a/apps/meteor/client/views/admin/workspace/components/WorkspaceCardSection.tsx +++ b/apps/meteor/client/views/admin/workspace/components/WorkspaceCardSection.tsx @@ -1,10 +1,21 @@ -import { Box } from '@rocket.chat/fuselage'; +import { Stack, Text } from '@rocket.chat/fuselage'; import type { ReactNode } from 'react'; +import WorkspaceCardSectionTitle from './WorkspaceCardSectionTitle'; + export type WorkspaceCardSectionProps = { + title: string; children: ReactNode; }; -const WorkspaceCardSection = ({ children }: WorkspaceCardSectionProps) => {children}; +/** + * A titled group of figures in a workspace card. + */ +const WorkspaceCardSection = ({ title, children }: WorkspaceCardSectionProps) => ( + + + {children} + +); export default WorkspaceCardSection; diff --git a/apps/meteor/client/views/admin/workspace/components/WorkspaceCardSectionTitle.tsx b/apps/meteor/client/views/admin/workspace/components/WorkspaceCardSectionTitle.tsx index 160cf5c8e1760..898886414f965 100644 --- a/apps/meteor/client/views/admin/workspace/components/WorkspaceCardSectionTitle.tsx +++ b/apps/meteor/client/views/admin/workspace/components/WorkspaceCardSectionTitle.tsx @@ -1,4 +1,4 @@ -import { Box } from '@rocket.chat/fuselage'; +import { Text } from '@rocket.chat/fuselage'; export type WorkspaceCardSectionTitleProps = { variant?: 'p2b' | 'h4'; @@ -6,9 +6,9 @@ export type WorkspaceCardSectionTitleProps = { }; const WorkspaceCardSectionTitle = ({ variant = 'p2b', title }: WorkspaceCardSectionTitleProps) => ( - + {title} - + ); export default WorkspaceCardSectionTitle; diff --git a/apps/meteor/client/views/admin/workspace/components/WorkspaceCardTextSeparator.tsx b/apps/meteor/client/views/admin/workspace/components/WorkspaceCardTextSeparator.tsx index 54cbba9ffe7e4..210edb27c449f 100644 --- a/apps/meteor/client/views/admin/workspace/components/WorkspaceCardTextSeparator.tsx +++ b/apps/meteor/client/views/admin/workspace/components/WorkspaceCardTextSeparator.tsx @@ -1,8 +1,10 @@ -import { Box, Icon, StatusBullet } from '@rocket.chat/fuselage'; +import { Icon, Stack, StatusBullet } from '@rocket.chat/fuselage'; import type { Keys } from '@rocket.chat/icons'; import { TextSeparator } from '@rocket.chat/ui-client'; import type { ComponentProps, ReactNode } from 'react'; +import StatusBulletSlot from '../layout/StatusBulletSlot'; + export type WorkspaceCardTextSeparatorProps = { label: ReactNode; icon?: Keys; @@ -12,15 +14,15 @@ export type WorkspaceCardTextSeparatorProps = { const WorkspaceCardTextSeparator = ({ icon, label, value, status }: WorkspaceCardTextSeparatorProps) => ( + {icon && } {status && ( - + - + )} {label && label} - + } value={value} /> diff --git a/apps/meteor/client/views/admin/workspace/layout/StatusBulletSlot.tsx b/apps/meteor/client/views/admin/workspace/layout/StatusBulletSlot.tsx new file mode 100644 index 0000000000000..05bb9303f334b --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/layout/StatusBulletSlot.tsx @@ -0,0 +1,17 @@ +import { Box } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +type StatusBulletSlotProps = { + children: ReactNode; +}; + +/** + * Centres a status bullet in an icon-wide slot, so a label with a bullet lines up with a label with an icon. + */ +const StatusBulletSlot = ({ children }: StatusBulletSlotProps) => ( + + {children} + +); + +export default StatusBulletSlot; diff --git a/apps/meteor/client/views/admin/workspace/layout/WorkspaceCardSections.tsx b/apps/meteor/client/views/admin/workspace/layout/WorkspaceCardSections.tsx new file mode 100644 index 0000000000000..ae107cda27e88 --- /dev/null +++ b/apps/meteor/client/views/admin/workspace/layout/WorkspaceCardSections.tsx @@ -0,0 +1,21 @@ +import type { BoxProps } from '@rocket.chat/fuselage'; +import { Box } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; + +type WorkspaceCardSectionsProps = { + gap: BoxProps['gap']; + spaceAbove?: BoxProps['paddingBlockStart']; + spaceBelow: BoxProps['paddingBlockEnd']; + children: ReactNode; +}; + +/** + * The sections of a workspace card's body, spaced apart and kept clear of the card's heading and controls. + */ +const WorkspaceCardSections = ({ gap, spaceAbove, spaceBelow, children }: WorkspaceCardSectionsProps) => ( + + {children} + +); + +export default WorkspaceCardSections; diff --git a/scripts/spacing-scale/baseline.json b/scripts/spacing-scale/baseline.json index a29d95be8285c..8b08537cf2b21 100644 --- a/scripts/spacing-scale/baseline.json +++ b/scripts/spacing-scale/baseline.json @@ -185,18 +185,6 @@ "apps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsx": 4, "apps/meteor/client/views/admin/users/UsersTable/UsersTableRow.tsx": 1, "apps/meteor/client/views/admin/viewLogs/AnalyticsReports.tsx": 7, - "apps/meteor/client/views/admin/workspace/components/WorkspaceCardSectionTitle.tsx": 1, - "apps/meteor/client/views/admin/workspace/components/WorkspaceCardTextSeparator.tsx": 1, - "apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/DescriptionList.tsx": 2, - "apps/meteor/client/views/admin/workspace/DeploymentCard/DeploymentCard.tsx": 1, - "apps/meteor/client/views/admin/workspace/UsersUploadsCard/UsersUploadsCard.tsx": 1, - "apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardActionItem.tsx": 1, - "apps/meteor/client/views/admin/workspace/VersionCard/components/VersionCardSkeleton.tsx": 3, - "apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisteredWorkspaceModal.tsx": 1, - "apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceModal.tsx": 1, - "apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepOneModal.tsx": 2, - "apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.tsx": 2, - "apps/meteor/client/views/admin/workspace/WorkspacePage.tsx": 1, "apps/meteor/client/views/apps/GameCenterContainer.tsx": 1, "apps/meteor/client/views/apps/GameCenterInvitePlayersModal.tsx": 2, "apps/meteor/client/views/audit/AuditPage.tsx": 2, From 15bb20f53bcdb7aeac0fcbb5600c3f68007d1c05 Mon Sep 17 00:00:00 2001 From: juliajforesti Date: Thu, 29 Oct 2026 12:43:05 -0300 Subject: [PATCH 4/4] refactor: the token modal's steps set their own font scale The two step paragraphs inherited p2 from the modal. They now set it, so a change to the modal's text size doesn't change them. Co-Authored-By: Claude Opus 5.5 --- .../VersionCard/modals/RegisterWorkspaceTokenModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.tsx b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.tsx index eac7645e1423a..c8f18ea97e260 100644 --- a/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.tsx +++ b/apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceTokenModal.tsx @@ -77,7 +77,7 @@ const RegisterWorkspaceTokenModal = ({ onClose, onStatusChange, ...props }: Regi - + 1. Go to:{' '} @@ -91,7 +91,7 @@ const RegisterWorkspaceTokenModal = ({ onClose, onStatusChange, ...props }: Regi - {`2. ${t('RegisterWorkspace_Token_Step_Two')}`} + {`2. ${t('RegisterWorkspace_Token_Step_Two')}`} {t('Registration_Token')}