Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/meteor/client/sidebar/RoomMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import React, { memo, ReactElement, useMemo } from 'react';
import { RoomManager } from '../../app/ui-utils/client';
import { UiTextContext } from '../../definition/IRoomTypeConfig';
import { GenericModalDoNotAskAgain } from '../components/GenericModal';
import WarningModal from '../components/WarningModal';
import { useDontAskAgain } from '../hooks/useDontAskAgain';
import { roomCoordinator } from '../lib/rooms/roomCoordinator';
import WarningModal from '../views/admin/apps/WarningModal';

const fields: Fields = {
f: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { ISetting } from '@rocket.chat/apps-engine/definition/settings';
import { App } from '@rocket.chat/core-typings';
import { Button, ButtonGroup, Box, Throbber, Tabs } from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useTranslation, useCurrentRoute, useRoute, useRouteParameter } from '@rocket.chat/ui-contexts';
import React, { useState, useCallback, useRef, FC } from 'react';

import { ISettings } from '../../../../app/apps/client/@types/IOrchestrator';
import { Apps } from '../../../../app/apps/client/orchestrator';
import Page from '../../../components/Page';
import AppDetails from './AppDetails';
import AppDetailsHeader from './AppDetailsHeader';
import AppLogs from './AppLogs';
import AppReleases from './AppReleases';
import AppSecurity from './AppSecurity';
import LoadingDetails from './LoadingDetails';
import SettingsDisplay from './SettingsDisplay';
import { handleAPIError } from './helpers';
import { useAppInfo } from './hooks/useAppInfo';

const AppDetailsPage: FC<{ id: string }> = function AppDetailsPage({ id }) {
import React, { useState, useCallback, useRef, ReactElement } from 'react';

import { ISettings } from '../../../../../app/apps/client/@types/IOrchestrator';
import { Apps } from '../../../../../app/apps/client/orchestrator';
import Page from '../../../../components/Page';
import { handleAPIError } from '../helpers';
import { useAppInfo } from '../hooks/useAppInfo';
import AppDetailsPageHeader from './AppDetailsPageHeader';
import AppDetailsPageLoading from './AppDetailsPageLoading';
import AppDetails from './tabs/AppDetails';
import AppLogs from './tabs/AppLogs';
import AppReleases from './tabs/AppReleases';
import AppSecurity from './tabs/AppSecurity';
import AppSettings from './tabs/AppSettings';

const AppDetailsPage = ({ id }: { id: App['id'] }): ReactElement => {
const t = useTranslation();

const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
Expand Down Expand Up @@ -81,11 +82,10 @@ const AppDetailsPage: FC<{ id: string }> = function AppDetailsPage({ id }) {
</Page.Header>
<Page.ScrollableContentWithShadow padding='x24'>
<Box w='full' alignSelf='center'>
{!appData && <LoadingDetails />}
{!appData && <AppDetailsPageLoading />}
{appData && (
<>
<AppDetailsHeader app={appData} />

<AppDetailsPageHeader app={appData} />
<Tabs>
<Tabs.Item onClick={(): void => handleTabClick('details')} selected={!tab || tab === 'details'}>
{t('Details')}
Expand All @@ -111,9 +111,7 @@ const AppDetailsPage: FC<{ id: string }> = function AppDetailsPage({ id }) {
</Tabs.Item>
)}
</Tabs>

{Boolean(!tab || tab === 'details') && <AppDetails app={appData} />}

{tab === 'security' && isSecurityVisible && (
<AppSecurity
privacyPolicySummary={privacyPolicySummary}
Expand All @@ -122,17 +120,14 @@ const AppDetailsPage: FC<{ id: string }> = function AppDetailsPage({ id }) {
privacyLink={privacyLink}
/>
)}

{tab === 'releases' && <AppReleases id={id} />}

{Boolean(tab === 'settings' && settings && Object.values(settings).length) && (
<SettingsDisplay
<AppSettings
settings={settings || ({} as ISettings)}
setHasUnsavedChanges={setHasUnsavedChanges}
settingsRef={settingsRef}
/>
)}

{tab === 'logs' && <AppLogs id={id} />}
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { App } from '@rocket.chat/core-typings';
import { Box } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import moment from 'moment';
import React, { ReactElement } from 'react';

import AppAvatar from '../../../components/avatar/AppAvatar';
import AppMenu from './AppMenu';
import AppStatus from './AppStatus';
import BundleChips from './BundleChips';
import { App } from './types';
import AppAvatar from '../../../../components/avatar/AppAvatar';
import AppMenu from '../AppMenu';
import BundleChips from '../BundleChips';
import AppStatus from './tabs/AppStatus';

const AppDetailsHeader = ({ app }: { app: App }): ReactElement => {
const AppDetailsPageHeader = ({ app }: { app: App }): ReactElement => {
const t = useTranslation();
const { iconFileData, name, author, version, iconFileContent, installed, isSubscribed, modifiedAt, bundledIn } = app;
const lastUpdated = modifiedAt && moment(modifiedAt).fromNow();
Expand All @@ -26,9 +26,7 @@ const AppDetailsHeader = ({ app }: { app: App }): ReactElement => {
</Box>
{app?.shortDescription && <Box mbe='x16'>{app.shortDescription}</Box>}
<Box display='flex' flexDirection='row' alignItems='center' mbe='x16'>
<Box display='flex' flexDirection='row' alignItems='center'>
<AppStatus app={app} installed={installed} isAppDetailsPage={true} isSubscribed={isSubscribed} />
</Box>
<AppStatus app={app} installed={installed} isAppDetailsPage={true} isSubscribed={isSubscribed} />
{(installed || isSubscribed) && <AppMenu app={app} mis='x8' />}
</Box>
<Box display='flex' flexDirection='row' color='hint' alignItems='center'>
Expand All @@ -53,4 +51,4 @@ const AppDetailsHeader = ({ app }: { app: App }): ReactElement => {
);
};

export default AppDetailsHeader;
export default AppDetailsPageHeader;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Box, Skeleton } from '@rocket.chat/fuselage';
import React, { FC } from 'react';

const LoadingDetails: FC = () => (
const AppDetailsPageLoading: FC = () => (
<Box display='flex' flexDirection='row' mbe='x20' w='full'>
<Skeleton variant='rect' w='x120' h='x120' mie='x20' />
<Box display='flex' flexDirection='column' justifyContent='space-between' flexGrow={1}>
Expand All @@ -12,4 +12,4 @@ const LoadingDetails: FC = () => (
</Box>
);

export default LoadingDetails;
export default AppDetailsPageLoading;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AppDetailsPage';
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { Box, ButtonGroup, Callout, Chip, Margins } from '@rocket.chat/fuselage';
import { ExternalLink } from '@rocket.chat/ui-client';
import { TranslationKey, useTranslation } from '@rocket.chat/ui-contexts';
import React, { FC } from 'react';
import React, { ReactElement } from 'react';

import APIsDisplay from './APIsDisplay';
import ScreenshotCarouselAnchor from './components/ScreenshotCarouselAnchor';
import { AppInfo } from './definitions/AppInfo';
import ScreenshotCarouselAnchor from '../../../components/ScreenshotCarouselAnchor';
import { AppInfo } from '../../../definitions/AppInfo';
import AppDetailsAPIs from './AppDetailsAPIs';

type AppDetailsProps = {
app: AppInfo;
};

const AppDetails: FC<AppDetailsProps> = ({ app }) => {
const AppDetails = ({ app }: { app: AppInfo }): ReactElement => {
const t = useTranslation();
const {
author: { homepage, support },
detailedDescription,
Expand All @@ -21,8 +18,6 @@ const AppDetails: FC<AppDetailsProps> = ({ app }) => {
apis,
} = app;

const t = useTranslation();

const isMarkdown = detailedDescription && Object.keys(detailedDescription).length !== 0 && detailedDescription.rendered;
const isCarouselVisible = screenshots && Boolean(screenshots.length);

Expand Down Expand Up @@ -90,7 +85,7 @@ const AppDetails: FC<AppDetailsProps> = ({ app }) => {

{apis?.length ? (
<Box is='section'>
<APIsDisplay apis={apis || []} />
<AppDetailsAPIs apis={apis || []} />
</Box>
) : null}
</Margins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { Box } from '@rocket.chat/fuselage';
import { useAbsoluteUrl, useTranslation } from '@rocket.chat/ui-contexts';
import React, { FC, Fragment } from 'react';

import { apiCurlGetter } from './helpers';
import { apiCurlGetter } from '../../../helpers';

type APIsDisplayProps = {
type AppDetailsAPIsProps = {
apis: IApiEndpointMetadata[];
};

const APIsDisplay: FC<APIsDisplayProps> = ({ apis }) => {
const AppDetailsAPIs: FC<AppDetailsAPIsProps> = ({ apis }) => {
const t = useTranslation();
const absoluteUrl = useAbsoluteUrl();
const getApiCurl = apiCurlGetter(absoluteUrl);
Expand Down Expand Up @@ -48,4 +48,4 @@ const APIsDisplay: FC<APIsDisplayProps> = ({ apis }) => {
);
};

export default APIsDisplay;
export default AppDetailsAPIs;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AppDetails';
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Accordion, Box } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { ReactElement } from 'react';

import { useFormatDateAndTime } from '../../../hooks/useFormatDateAndTime';
import AccordionLoading from './AccordionLoading';
import LogItem from './LogItem';
import { useLogs } from './hooks/useLogs';
import { useFormatDateAndTime } from '../../../../../../hooks/useFormatDateAndTime';
import AccordionLoading from '../../../AccordionLoading';
import { useLogs } from '../../../hooks/useLogs';
import AppLogsItem from './AppLogsItem';

const AppLogs = ({ id }: { id: string }): ReactElement => {
const t = useTranslation();
Expand All @@ -23,7 +23,7 @@ const AppLogs = ({ id }: { id: string }): ReactElement => {
{isSuccess && (
<Accordion width='100%' alignSelf='center'>
{data?.logs?.map((log) => (
<LogItem
<AppLogsItem
key={log._createdAt}
title={`${formatDateAndTime(log._createdAt)}: "${log.method}" (${log.totalTime}ms)`}
instanceId={log.instanceId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { Box, Accordion } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { FC } from 'react';

import LogEntry from './LogEntry';
import AppLogsItemEntry from './AppLogsItemEntry';

type LogItemProps = {
type AppLogsItemProps = {
entries: ILogEntry[];
instanceId: string;
title: string;
};

const LogItem: FC<LogItemProps> = ({ entries, instanceId, title, ...props }) => {
const AppLogsItem: FC<AppLogsItemProps> = ({ entries, instanceId, title, ...props }) => {
const t = useTranslation();

return (
Expand All @@ -22,10 +22,10 @@ const LogItem: FC<LogItemProps> = ({ entries, instanceId, title, ...props }) =>
</Box>
)}
{entries.map(({ severity, timestamp, caller, args }, i) => (
<LogEntry key={i} severity={severity} timestamp={timestamp} caller={caller} args={args} />
<AppLogsItemEntry key={i} severity={severity} timestamp={timestamp} caller={caller} args={args} />
))}
</Accordion.Item>
);
};

export default LogItem;
export default AppLogsItem;
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import { Box } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { FC } from 'react';

import { useHighlightedCode } from '../../../hooks/useHighlightedCode';
import { useHighlightedCode } from '../../../../../../hooks/useHighlightedCode';

type LogEntryProps = {
type AppLogsItemEntryProps = {
severity: string;
timestamp: string;
caller: string;
args: unknown;
};

const LogEntry: FC<LogEntryProps> = ({ severity, timestamp, caller, args }) => {
const AppLogsItemEntry: FC<AppLogsItemEntryProps> = ({ severity, timestamp, caller, args }) => {
const t = useTranslation();

return (
Expand All @@ -32,4 +32,4 @@ const LogEntry: FC<LogEntryProps> = ({ severity, timestamp, caller, args }) => {
);
};

export default LogEntry;
export default AppLogsItemEntry;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AppLogs';
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { App } from '@rocket.chat/core-typings';
import { Accordion } from '@rocket.chat/fuselage';
import React, { ReactElement } from 'react';

import { useEndpointData } from '../../../../../../hooks/useEndpointData';
import { AsyncStatePhase } from '../../../../../../lib/asyncState/AsyncStatePhase';
import AccordionLoading from '../../../AccordionLoading';
import AppReleasesItem from './AppReleasesItem';

// TODO: replace useEndpointData
const AppReleases = ({ id }: { id: App['id'] }): ReactElement => {
const result = useEndpointData(`/apps/${id}/versions`);

return (
<>
<Accordion width='100%' alignSelf='center'>
{result.phase === AsyncStatePhase.LOADING && <AccordionLoading />}
{result.phase === AsyncStatePhase.RESOLVED && (
<>
{result.value.apps.map((release) => (
<AppReleasesItem release={release} key={release.version} />
))}
</>
)}
</Accordion>
</>
);
};

export default AppReleases;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Accordion, Box } from '@rocket.chat/fuselage';
import React from 'react';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { ReactElement } from 'react';

import { useTimeAgo } from '../../../hooks/useTimeAgo';
import { useTimeAgo } from '../../../../../../hooks/useTimeAgo';

type release = {
type IRelease = {
version: string;
createdDate: string;
detailedChangelog: {
Expand All @@ -13,10 +14,11 @@ type release = {
};

type ReleaseItemProps = {
release: release;
release: IRelease;
};

const ReleaseItem = ({ release, ...props }: ReleaseItemProps): JSX.Element => {
const AppReleasesItem = ({ release, ...props }: ReleaseItemProps): ReactElement => {
const t = useTranslation();
const formatDate = useTimeAgo();

const title = (
Expand All @@ -35,10 +37,10 @@ const ReleaseItem = ({ release, ...props }: ReleaseItemProps): JSX.Element => {
{release.detailedChangelog?.rendered ? (
<Box dangerouslySetInnerHTML={{ __html: release.detailedChangelog?.rendered }} />
) : (
'No release information provided'
t('No_release_information_provided')
)}
</Accordion.Item>
);
};

export default ReleaseItem;
export default AppReleasesItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AppReleases';
Loading