2025-02-20 22:19:36 +01:00
|
|
|
import Loading from 'components/loading/LoadingComponent';
|
|
|
|
import Page from 'components/Page';
|
|
|
|
import React, { useCallback } from 'react';
|
|
|
|
import { useParams } from 'react-router-dom';
|
|
|
|
import { useServerLog } from 'apps/dashboard/features/logs/api/useServerLog';
|
2025-02-24 19:33:01 +01:00
|
|
|
import Alert from '@mui/material/Alert';
|
|
|
|
import Box from '@mui/material/Box';
|
|
|
|
import Button from '@mui/material/Button';
|
|
|
|
import ButtonGroup from '@mui/material/ButtonGroup';
|
|
|
|
import Container from '@mui/material/Container';
|
2025-02-25 22:48:15 +01:00
|
|
|
import Paper from '@mui/material/Paper';
|
2025-02-24 19:33:01 +01:00
|
|
|
import Typography from '@mui/material/Typography';
|
2025-02-20 22:19:36 +01:00
|
|
|
import { ContentCopy, FileDownload } from '@mui/icons-material';
|
|
|
|
import globalize from 'lib/globalize';
|
2025-02-23 21:57:41 +01:00
|
|
|
import toast from 'components/toast/toast';
|
2025-02-25 22:48:15 +01:00
|
|
|
import { copy } from 'scripts/clipboard';
|
2025-02-20 22:19:36 +01:00
|
|
|
|
|
|
|
export const Component = () => {
|
|
|
|
const { file: fileName } = useParams();
|
|
|
|
const {
|
|
|
|
isError: error,
|
|
|
|
isPending: loading,
|
|
|
|
data: log,
|
|
|
|
refetch
|
|
|
|
} = useServerLog(fileName ?? '');
|
|
|
|
|
|
|
|
const retry = useCallback(() => refetch(), [refetch]);
|
|
|
|
|
|
|
|
const copyToClipboard = useCallback(async () => {
|
2025-02-25 22:48:15 +01:00
|
|
|
if (log) {
|
|
|
|
await copy(log);
|
2025-02-23 21:57:41 +01:00
|
|
|
toast({ text: globalize.translate('CopyLogSuccess') });
|
2025-02-20 22:19:36 +01:00
|
|
|
}
|
|
|
|
}, [log]);
|
|
|
|
|
|
|
|
const downloadFile = useCallback(() => {
|
|
|
|
if ('URL' in globalThis && log && fileName) {
|
|
|
|
const blob = new Blob([log], { type: 'text/plain' });
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
const a = document.createElement('a');
|
|
|
|
a.href = url;
|
|
|
|
a.download = fileName;
|
|
|
|
a.click();
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
}
|
|
|
|
}, [log, fileName]);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Page
|
|
|
|
id='logPage'
|
|
|
|
title={fileName}
|
|
|
|
className='mainAnimatedPage type-interior'
|
|
|
|
>
|
|
|
|
<Container className='content-primary'>
|
|
|
|
<Box>
|
|
|
|
<Typography variant='h1'>{fileName}</Typography>
|
|
|
|
|
|
|
|
{error && (
|
|
|
|
<Alert
|
|
|
|
key='error'
|
|
|
|
severity='error'
|
|
|
|
sx={{ mt: 2 }}
|
|
|
|
action={
|
|
|
|
<Button
|
|
|
|
color='inherit'
|
|
|
|
size='small'
|
|
|
|
onClick={retry}
|
|
|
|
>
|
2025-02-25 17:29:13 +01:00
|
|
|
{globalize.translate('Retry')}
|
2025-02-20 22:19:36 +01:00
|
|
|
</Button>
|
|
|
|
}
|
|
|
|
>
|
|
|
|
{globalize.translate('LogLoadFailure')}
|
|
|
|
</Alert>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{loading && <Loading />}
|
|
|
|
|
|
|
|
{!error && !loading && (
|
|
|
|
<>
|
|
|
|
<ButtonGroup variant='contained' sx={{ mt: 2 }}>
|
|
|
|
<Button
|
|
|
|
startIcon={<ContentCopy />}
|
|
|
|
onClick={copyToClipboard}
|
|
|
|
>
|
|
|
|
{globalize.translate('Copy')}
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
startIcon={<FileDownload />}
|
|
|
|
onClick={downloadFile}
|
|
|
|
>
|
|
|
|
{globalize.translate('Download')}
|
|
|
|
</Button>
|
|
|
|
</ButtonGroup>
|
|
|
|
|
2025-02-25 22:48:15 +01:00
|
|
|
<Paper sx={{ mt: 2 }}>
|
|
|
|
<code>
|
|
|
|
<pre style={{ overflow:'auto', margin: 0, padding: '16px' }}>{log}</pre>
|
|
|
|
</code>
|
|
|
|
</Paper>
|
2025-02-20 22:19:36 +01:00
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</Box>
|
|
|
|
</Container>
|
|
|
|
</Page>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
Component.displayName = 'LogPage';
|