207 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/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) }
</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}
// Опции высоты
minHeight='calc(100vh - 29rem)'
// Состояние загрузки
loading={loading}
// Отключаем ненужные функции
enableSorting={false}
enableColumnFilters={false}
enableGlobalFilter={false}
enableTopToolbar={false}
enableRowActions={false}
/>
<JsonViewModal
open={modalOpen}
onClose={handleCloseModal}
jsonData={selectedJson}
eventType={selectedEventType}
/>
</>
);
};
export default AuditLogsTable;