209 lines
5.6 KiB
JavaScript
209 lines
5.6 KiB
JavaScript
import { useMemo, useState } from 'react';
|
|
import { Box, Typography, Link, Chip } from '@mui/material';
|
|
import { ROLES_ID_RUSSIAN_NAME } from '../../../../constants';
|
|
import {
|
|
ENTITY_RUSSIAN_NAMES,
|
|
getRussianNamesForType,
|
|
} from '../constants/auditLogs';
|
|
import JsonViewModal from './JsonViewModal';
|
|
import StyledTable from '../../components/StyledTable/StyledTable';
|
|
|
|
const formatDateTime = (dateString) => {
|
|
if (!dateString) return '-';
|
|
const date = new Date(dateString);
|
|
return date.toLocaleString('ru-RU', {
|
|
day: '2-digit',
|
|
month: '2-digit',
|
|
year: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
second: '2-digit',
|
|
});
|
|
};
|
|
|
|
const formatDetails = (details) => {
|
|
if (!details) return '-';
|
|
try {
|
|
const parsed = typeof details === 'string' ? JSON.parse(details) : details;
|
|
return JSON.stringify(parsed, null, 2);
|
|
} catch {
|
|
return String(details);
|
|
}
|
|
};
|
|
|
|
const AuditLogsTable = ({
|
|
logs,
|
|
loading,
|
|
totalCount,
|
|
page,
|
|
rowsPerPage,
|
|
onPageChange,
|
|
onRowsPerPageChange,
|
|
}) => {
|
|
const [selectedJson, setSelectedJson] = useState(null);
|
|
const [selectedEventType, setSelectedEventType] = useState(null);
|
|
const [modalOpen, setModalOpen] = useState(false);
|
|
|
|
const handleViewJson = (jsonData, eventType) => {
|
|
setSelectedJson(jsonData);
|
|
setSelectedEventType(eventType);
|
|
setModalOpen(true);
|
|
};
|
|
|
|
const handleCloseModal = () => {
|
|
setModalOpen(false);
|
|
setSelectedJson(null);
|
|
setSelectedEventType(null);
|
|
};
|
|
|
|
const columns = useMemo(
|
|
() => [
|
|
{
|
|
accessorKey: 'at',
|
|
header: 'Дата/Время',
|
|
size: 180,
|
|
Cell: ({ cell }) => (
|
|
<Typography>{formatDateTime(cell.getValue())}</Typography>
|
|
),
|
|
enableColumnActions: false,
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: 'user',
|
|
header: 'Пользователь',
|
|
size: 300,
|
|
Cell: ({ cell, row }) => (
|
|
<Box sx={{ display: 'flex', gap: '.5rem', flexDirection: 'column' }}>
|
|
<Typography component="div" fontWeight="medium">
|
|
{row.original.user
|
|
? row.original.user.full_name +
|
|
' (' +
|
|
row.original.user.email +
|
|
')'
|
|
: '-'}
|
|
</Typography>
|
|
</Box>
|
|
),
|
|
enableColumnActions: false,
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: 'user_role',
|
|
header: 'Роль',
|
|
size: 190,
|
|
Cell: ({ row }) => (
|
|
<Chip
|
|
label={row.original.user ? ROLES_ID_RUSSIAN_NAME[row.original.user.role_id] : ''}
|
|
sx={{
|
|
border: '0.53px solid #D1D5DC',
|
|
borderRadius: '0.5rem',
|
|
padding: '0rem',
|
|
height: '1.69rem',
|
|
backgroundColor: '#F3F4F6',
|
|
'& .MuiChip-label': {
|
|
padding: '0 0.5rem',
|
|
fontSize: '0.75rem',
|
|
lineHeight: '150%',
|
|
color: '#364153',
|
|
},
|
|
}}
|
|
/>
|
|
),
|
|
enableColumnActions: false,
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: 'event_type',
|
|
header: 'Действие',
|
|
size: 250,
|
|
Cell: ({ row }) => (
|
|
<Typography>
|
|
{getRussianNamesForType(row.original.action) ||
|
|
row.original.event_type}
|
|
</Typography>
|
|
),
|
|
enableColumnActions: false,
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: 'context',
|
|
header: 'Контекст',
|
|
size: 160,
|
|
Cell: ({ row }) => (
|
|
<Typography>{`${ENTITY_RUSSIAN_NAMES[row.original.entity.toUpperCase()]} #${row.original.entity_id}`}</Typography>
|
|
),
|
|
enableColumnActions: false,
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
accessorKey: 'payload_json',
|
|
header: 'Детали',
|
|
size: 150,
|
|
Cell: ({ row }) => {
|
|
const details = row.original.payload_json;
|
|
if (!details) return <Typography>-</Typography>;
|
|
|
|
const formattedDetails = formatDetails(details);
|
|
|
|
return (
|
|
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1 }}>
|
|
<Link
|
|
onClick={() =>
|
|
handleViewJson(formattedDetails, row.original.action)
|
|
}
|
|
color="#5FAC43"
|
|
sx={{
|
|
fontSize: '0.75rem',
|
|
lineHeight: '150%',
|
|
color: '#5FAC43',
|
|
cursor: 'pointer',
|
|
}}
|
|
>
|
|
Посмотреть
|
|
</Link>
|
|
</Box>
|
|
);
|
|
},
|
|
enableColumnActions: false,
|
|
enableSorting: false,
|
|
},
|
|
],
|
|
[],
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<StyledTable
|
|
columns={columns}
|
|
data={logs}
|
|
// Опции пагинации
|
|
enablePagination={true}
|
|
page={page}
|
|
rowsPerPage={rowsPerPage}
|
|
totalCount={totalCount}
|
|
onPageChange={onPageChange}
|
|
onRowsPerPageChange={onRowsPerPageChange}
|
|
// Опции высоты
|
|
containerHeight="calc(100vh - 450px)"
|
|
minHeight="400px"
|
|
// Состояние загрузки
|
|
loading={loading}
|
|
// Отключаем ненужные функции
|
|
enableSorting={false}
|
|
enableColumnFilters={false}
|
|
enableGlobalFilter={false}
|
|
enableTopToolbar={false}
|
|
enableRowActions={false}
|
|
/>
|
|
<JsonViewModal
|
|
open={modalOpen}
|
|
onClose={handleCloseModal}
|
|
jsonData={selectedJson}
|
|
eventType={selectedEventType}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default AuditLogsTable;
|