Skip to content
7 changes: 4 additions & 3 deletions apps/meteor/client/components/Card/Body.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Box } from '@rocket.chat/fuselage';
import React, { FC, CSSProperties } from 'react';
import React, { FC, CSSProperties, ComponentProps } from 'react';

type BodyProps = {
flexDirection?: CSSProperties['flexDirection'];
height?: ComponentProps<typeof Box>['height'];
};

const Body: FC<BodyProps> = ({ children, flexDirection = 'row' }) => (
<Box mb='x8' display='flex' flexDirection={flexDirection} flexGrow={1}>
const Body: FC<BodyProps> = ({ children, flexDirection = 'row', height }) => (
<Box mb='x8' display='flex' flexDirection={flexDirection} flexGrow={1} height={height}>
{children}
</Box>
);
Expand Down
20 changes: 16 additions & 4 deletions apps/meteor/client/components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import { Box } from '@rocket.chat/fuselage';
import React, { FC } from 'react';

const Card: FC = ({ children, ...props }) => (
<Box display='flex' flexDirection='column' pi='x16' pb='x8' width='fit-content' bg='neutral-100' {...props}>
{children}
</Box>
type CardProps = {
variant?: 'light' | 'tint';
};

const Card: FC<CardProps> = ({ variant, ...props }: CardProps) => (
<Box
borderRadius='x2'
pbs='x20'
pbe='x28'
pi='x20'
height='full'
display='flex'
flexDirection='column'
backgroundColor={variant === 'light' ? 'white' : 'neutral-100'}
{...props}
/>
);

export default Card;
4 changes: 2 additions & 2 deletions apps/meteor/client/components/Card/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box } from '@rocket.chat/fuselage';
import { ButtonGroup } from '@rocket.chat/fuselage';
import React, { FC } from 'react';

const Footer: FC = ({ children }) => <Box mb='x8'>{children}</Box>;
const Footer: FC = ({ children }) => <ButtonGroup>{children}</ButtonGroup>;

export default Footer;
21 changes: 21 additions & 0 deletions apps/meteor/client/components/Page/PageBlockWithBorder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Box } from '@rocket.chat/fuselage';
import React, { ComponentProps, forwardRef, useContext } from 'react';

import PageContent from './PageContent';
import PageContext from './PageContext';

const PageBlockWithBorder = forwardRef<HTMLElement, ComponentProps<typeof Box>>(function PageBlockWithBorder(props, ref) {
const [border] = useContext(PageContext);
return (
<PageContent
{...props}
pb='x16'
ref={ref}
borderBlockEndColor={border ? 'neutral-200' : 'transparent'}
borderBlockEndWidth='x2'
height='auto'
/>
);
});

export default PageBlockWithBorder;
12 changes: 8 additions & 4 deletions apps/meteor/client/components/Page/PageHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Box } from '@rocket.chat/fuselage';
import { useLayout } from '@rocket.chat/ui-contexts';
import { Box, ActionButton } from '@rocket.chat/fuselage';
import { useLayout, useTranslation } from '@rocket.chat/ui-contexts';
import React, { useContext, FC, ReactNode } from 'react';

import BurgerMenu from '../BurgerMenu';
Expand All @@ -8,14 +8,17 @@ import PageContext from './PageContext';

type PageHeaderProps = {
title: ReactNode;
onClickBack?: () => void;
borderBlockEndColor?: string;
};

const PageHeader: FC<PageHeaderProps> = ({ children = undefined, title, ...props }) => {
const PageHeader: FC<PageHeaderProps> = ({ children = undefined, title, onClickBack, borderBlockEndColor, ...props }) => {
const t = useTranslation();
const [border] = useContext(PageContext);
const { isMobile } = useLayout();

return (
<Box borderBlockEndWidth='x2' borderBlockEndColor={border ? 'neutral-200' : 'transparent'}>
<Box borderBlockEndWidth='x2' borderBlockEndColor={borderBlockEndColor ?? border ? 'neutral-200' : 'transparent'}>
<Box
marginBlock='x16'
marginInline='x24'
Expand All @@ -32,6 +35,7 @@ const PageHeader: FC<PageHeaderProps> = ({ children = undefined, title, ...props
<BurgerMenu />
</TemplateHeader.ToolBox>
)}
{onClickBack && <ActionButton ghost small mie='x8' icon='arrow-back' onClick={onClickBack} title={t('Back')} />}
<Box is='h2' fontScale='h2' flexGrow={1}>
{title}
</Box>
Expand Down
16 changes: 16 additions & 0 deletions apps/meteor/client/components/Page/PageHeaderWithBorder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React, { useContext, FC, ReactNode } from 'react';

import PageContext from './PageContext';
import PageHeader from './PageHeader';

type PageHeaderWithBorderProps = {
title: ReactNode;
};

const PageHeaderWithBorder: FC<PageHeaderWithBorderProps> = (props) => {
const [border] = useContext(PageContext);

return <PageHeader {...props} borderBlockEndColor={border ? 'neutral-200' : 'transparent'} />;
};

export default PageHeaderWithBorder;
12 changes: 10 additions & 2 deletions apps/meteor/client/components/Page/PageScrollableContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@ type PageScrollableContentProps = {
} & ComponentProps<typeof Box>;

const PageScrollableContent = forwardRef<HTMLElement, PageScrollableContentProps>(function PageScrollableContent(
{ onScrollContent, ...props },
{ onScrollContent, borderBlockEndColor, ...props },
ref,
) {
return (
<Box height='50vh' display='flex' flexShrink={1} flexDirection='column' flexGrow={1} overflow='hidden'>
<Box
height='50vh'
display='flex'
flexShrink={1}
flexDirection='column'
flexGrow={1}
overflow='hidden'
borderBlockEndColor={borderBlockEndColor}
>
<ScrollableContentWrapper onScroll={onScrollContent as CustomScrollbarsProps['onScroll']} ref={ref as any}>
<Box p='x16' display='flex' flexDirection='column' flexGrow={1} {...props} />
</ScrollableContentWrapper>
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/sidebar/header/UserDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ type UserDropdownProps = {
const UserDropdown = ({ user, onClose }: UserDropdownProps): ReactElement => {
const t = useTranslation();
const accountRoute = useRoute('account');
const adminRoute = useRoute('admin');
const adminRoute = useRoute('admin-index');
const logout = useLogout();
const { sidebar, isMobile } = useLayout();

Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/views/admin/info/DeploymentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const DeploymentCard = ({ info, statistics, instances }: DeploymentCardProps): R
});

return (
<Card>
<Card data-qa-id='deployment-card'>
<Card.Title>{t('Deployment')}</Card.Title>
<Card.Body>
<Card.Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const FederationCard: FC = () => {
);

return (
<Card>
<Card data-qa-id='federation-card'>
<CardHeader>
<Card.Title>{t('Federation')}</Card.Title>
<Box display='flex'>
Expand Down
27 changes: 15 additions & 12 deletions apps/meteor/client/views/admin/info/InformationPage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import type { IInstanceStatus, IServerInfo, IStats } from '@rocket.chat/core-typings';
import { Box, Button, ButtonGroup, Callout, Icon, Margins } from '@rocket.chat/fuselage';
import { useResizeObserver } from '@rocket.chat/fuselage-hooks';
import { Box, Button, ButtonGroup, Callout, Grid, Icon } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { memo } from 'react';

import SeatsCard from '../../../../ee/client/views/admin/info/SeatsCard';
import { DOUBLE_COLUMN_CARD_WIDTH } from '../../../components/Card';
import Page from '../../../components/Page';
import DeploymentCard from './DeploymentCard';
import FederationCard from './FederationCard';
Expand All @@ -31,10 +29,6 @@ const InformationPage = memo(function InformationPage({
}: InformationPageProps) {
const t = useTranslation();

const { ref, contentBoxSize: { inlineSize = DOUBLE_COLUMN_CARD_WIDTH } = {} } = useResizeObserver();

const isSmall = inlineSize < DOUBLE_COLUMN_CARD_WIDTH;

if (!info) {
return null;
}
Expand Down Expand Up @@ -82,15 +76,24 @@ const InformationPage = memo(function InformationPage({
</Callout>
)}

<Box display='flex' flexDirection='row' w='full' flexWrap='wrap' justifyContent={isSmall ? 'center' : 'flex-start'} ref={ref}>
<Margins all='x8'>
<Grid>
<Grid.Item xl={3}>
<DeploymentCard info={info} statistics={statistics} instances={instances} />
</Grid.Item>
<Grid.Item xl={3}>
<LicenseCard />
<UsageCard vertical={isSmall} statistics={statistics} />
</Grid.Item>
<Grid.Item xl={4}>
<UsageCard vertical={false} statistics={statistics} />
</Grid.Item>
<Grid.Item xl={2}></Grid.Item>
<Grid.Item xl={6}>
<FederationCard />
</Grid.Item>
<Grid.Item xl={6}>
<SeatsCard />
</Margins>
</Box>
</Grid.Item>
</Grid>
</Box>
</Page.ScrollableContentWithShadow>
</Page>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ButtonGroup, Button, Skeleton, Margins } from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useSetModal, useSetting, useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';
import React, { ReactElement } from 'react';

import Card from '../../../components/Card';
import PlanTag from '../../../components/PlanTag';
Expand All @@ -10,9 +10,8 @@ import { useEndpointData } from '../../../hooks/useEndpointData';
import Feature from './Feature';
import OfflineLicenseModal from './OfflineLicenseModal';

const LicenseCard = () => {
const LicenseCard = (): ReactElement => {
const t = useTranslation();

const setModal = useSetModal();

const currentLicense = useSetting('Enterprise_License');
Expand All @@ -23,7 +22,7 @@ const LicenseCard = () => {
const { value, phase, error } = useEndpointData('licenses.get');
const endpointLoading = phase === AsyncStatePhase.LOADING;

const { modules = [] } = endpointLoading || error || !value.licenses.length ? {} : value.licenses[0];
const { modules = [] } = endpointLoading || error || !value?.licenses.length ? {} : value.licenses[0];

const hasEngagement = modules.includes('engagement-dashboard');
const hasOmnichannel = modules.includes('livechat-enterprise');
Expand All @@ -33,7 +32,7 @@ const LicenseCard = () => {
const handleApplyLicense = useMutableCallback(() =>
setModal(
<OfflineLicenseModal
onClose={() => {
onClose={(): void => {
setModal();
}}
license={currentLicense}
Expand All @@ -43,7 +42,7 @@ const LicenseCard = () => {
);

return (
<Card>
<Card data-qa-id='license-card'>
<Card.Title>{t('License')}</Card.Title>
<Card.Body>
<Card.Col>
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/views/admin/info/UsageCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const UsageCard = ({ statistics, vertical }: UsageCardProps): ReactElement => {
const canViewEngagement = useHasLicense('engagement-dashboard');

return (
<Card>
<Card data-qa-id='usage-card'>
<Card.Title>{t('Usage')}</Card.Title>
<Card.Body flexDirection={vertical ? 'column' : 'row'}>
<Card.Col>
Expand Down
10 changes: 3 additions & 7 deletions apps/meteor/client/views/admin/routes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Meteor } from 'meteor/meteor';

import { appLayout } from '../../lib/appLayout';
import { createRouteGroup } from '../../lib/createRouteGroup';

Expand Down Expand Up @@ -124,11 +122,9 @@ registerAdminRoute('/email-inboxes/:context?/:_id?', {
lazyRouteComponent: () => import('./emailInbox/EmailInboxRoute'),
});

Meteor.startup(() => {
registerAdminRoute('/:group+', {
name: 'admin',
lazyRouteComponent: () => import('./settings/SettingsRoute'),
});
registerAdminRoute('/settings/:group?', {
name: 'admin-settings',
lazyRouteComponent: () => import('./settings/SettingsRoute'),
});

registerAdminRoute('/chatpal', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { EditableSettingsContext, IEditableSetting, EditableSettingsContextValue
const defaultQuery: SettingsContextQuery = {};

type EditableSettingsProviderProps = {
readonly query: SettingsContextQuery;
readonly query?: SettingsContextQuery;
};

const EditableSettingsProvider: FunctionComponent<EditableSettingsProviderProps> = ({ children, query = defaultQuery }) => {
Expand Down
19 changes: 11 additions & 8 deletions apps/meteor/client/views/admin/settings/GroupPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
useTranslation,
useLoadLanguage,
TranslationKey,
useRoute,
} from '@rocket.chat/ui-contexts';
import React, { useMemo, memo, FC, ReactNode, FormEvent, MouseEvent } from 'react';

Expand All @@ -35,6 +36,13 @@ const GroupPage: FC<GroupPageProps> = ({
tabs = undefined,
isCustom = false,
}) => {
const t = useTranslation();
const user = useUser();
const router = useRoute('admin-settings');
const dispatch = useSettingsDispatch();
const dispatchToastMessage = useToastMessageDispatch();
const loadLanguage = useLoadLanguage();

const changedEditableSettings = useEditableSettings(
useMemo(
() => ({
Expand All @@ -54,13 +62,6 @@ const GroupPage: FC<GroupPageProps> = ({
),
);

const dispatch = useSettingsDispatch();

const dispatchToastMessage = useToastMessageDispatch();
const t = useTranslation();
const loadLanguage = useLoadLanguage();
const user = useUser();

const isColorSetting = (setting: ISetting): setting is ISettingColor => setting.type === 'color';

const save = useMutableCallback(async () => {
Expand Down Expand Up @@ -136,6 +137,8 @@ const GroupPage: FC<GroupPageProps> = ({
save();
};

const handleBack = useMutableCallback(() => router.push({}));

const handleCancelClick = (event: MouseEvent<HTMLOrSVGElement>): void => {
event.preventDefault();
cancel();
Expand All @@ -155,7 +158,7 @@ const GroupPage: FC<GroupPageProps> = ({

return (
<Page is='form' action='#' method='post' onSubmit={handleSubmit}>
<Page.Header title={i18nLabel && isTranslationKey(i18nLabel) && t(i18nLabel)}>
<Page.Header onClickBack={handleBack} title={i18nLabel && isTranslationKey(i18nLabel) && t(i18nLabel)}>
<ButtonGroup>
{changedEditableSettings.length > 0 && (
<Button danger primary type='reset' onClick={handleCancelClick}>
Expand Down
Loading