The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/client/admin/apps/AppLogsPage.js

146 lines
4.5 KiB

import { Box, Button, ButtonGroup, Icon, Accordion, Skeleton, Margins, Pagination } from '@rocket.chat/fuselage';
import { useSafely } from '@rocket.chat/fuselage-hooks';
import React, { useCallback, useState, useEffect } from 'react';
import Page from '../../components/basic/Page';
import { useCurrentRoute, useRoute } from '../../contexts/RouterContext';
import { useEndpoint } from '../../contexts/ServerContext';
import { useTranslation } from '../../contexts/TranslationContext';
import { useHighlightedCode } from '../../hooks/useHighlightedCode';
import { useFormatDateAndTime } from '../../hooks/useFormatDateAndTime';
const LogEntry = ({ severity, timestamp, caller, args }) => {
const t = useTranslation();
return <Box>
<Box>{severity}: {timestamp} {t('Caller')}: {caller}</Box>
<Box withRichContent width='full'>
<pre>
<code
dangerouslySetInnerHTML={{
__html: useHighlightedCode('json', JSON.stringify(args, null, 2)),
}}
/>
</pre>
</Box>
</Box>;
};
const LogItem = ({ entries, instanceId, title, t, ...props }) => <Accordion.Item title={title} {...props}>
{instanceId && <Box>{t('Instance')}: {instanceId}</Box>}
{entries.map(({ severity, timestamp, caller, args }, i) => <LogEntry
key={i}
severity={severity}
timestamp={timestamp}
caller={caller}
args={args}
/>)}
</Accordion.Item>;
const LogsLoading = () => <Box maxWidth='x600' w='full' alignSelf='center'>
<Margins block='x2'>
<Skeleton variant='rect' width='100%' height='x80' />
<Skeleton variant='rect' width='100%' height='x80' />
<Skeleton variant='rect' width='100%' height='x80' />
</Margins>
</Box>;
const useAppWithLogs = ({ id, current, itemsPerPage }) => {
const [data, setData] = useSafely(useState({}));
const getAppData = useEndpoint('GET', `/apps/${ id }`);
const getAppLogs = useEndpoint('GET', `/apps/${ id }/logs`);
const fetchData = useCallback(async () => {
try {
const [
{ app },
{ logs },
] = await Promise.all([
getAppData(),
getAppLogs(),
]);
setData({ ...app, logs });
} catch (error) {
setData({ error });
}
}, [getAppData, getAppLogs, setData]);
useEffect(() => {
fetchData();
}, [fetchData]);
const sliceStart = data.logs && current > data.logs.length ? 0 : current;
const total = data.logs ? data.logs.length : 0;
const filteredData = data.logs
? { ...data, logs: data.logs.slice(sliceStart, itemsPerPage + current) }
: data;
return [filteredData, total, fetchData];
};
function AppLogsPage({ id, ...props }) {
const t = useTranslation();
const formatDateAndTime = useFormatDateAndTime();
const [itemsPerPage, setItemsPerPage] = useState(25);
const [current, setCurrent] = useState(0);
const [app, logEntriesCount, fetchData] = useAppWithLogs({ id, itemsPerPage, current });
const [currentRouteName] = useCurrentRoute();
const appLogsRoute = useRoute(currentRouteName);
const handleResetButtonClick = () => {
fetchData();
};
const handleBackButtonClick = () => {
appLogsRoute.push();
};
const loading = !Object.values(app).length;
const showData = !loading && !app.error;
const showingResultsLabel = useCallback(({ count, current, itemsPerPage }) => t('Showing results %s - %s of %s', current + 1, Math.min(current + itemsPerPage, count), count), [t]);
const itemsPerPageLabel = useCallback(() => t('Items_per_page:'), [t]);
return <Page flexDirection='column' {...props}>
<Page.Header title={t('View_the_Logs_for', { name: app.name || '' })}>
<ButtonGroup>
<Button primary onClick={handleResetButtonClick}>
<Icon name='undo'/> {t('Refresh')}
</Button>
<Button onClick={handleBackButtonClick}>
<Icon name='back'/> {t('Back')}
</Button>
</ButtonGroup>
</Page.Header>
<Page.ScrollableContent>
{loading && <LogsLoading />}
{app.error && <Box maxWidth='x600' alignSelf='center' fontScale='h1'>{app.error.message}</Box>}
{showData && <>
<Accordion maxWidth='x600' alignSelf='center'>
{app.logs && app.logs.map((log) => <LogItem
key={log._createdAt}
title={`${ formatDateAndTime(log._createdAt) }: "${ log.method }" (${ log.totalTime }ms)`}
instanceId={log.instanceId}
entries={log.entries}
t={t}
/>)}
</Accordion>
</>}
</Page.ScrollableContent>
<Pagination
mi='x24'
divider
current={current}
itemsPerPage={itemsPerPage}
itemsPerPageLabel={itemsPerPageLabel}
showingResultsLabel={showingResultsLabel}
count={logEntriesCount}
onSetItemsPerPage={setItemsPerPage}
onSetCurrent={setCurrent}
/>
</Page>;
}
export default AppLogsPage;