322 lines
8.1 KiB
JavaScript

import { useCallback, useEffect, useMemo, useState } from 'react';
import { Box, Typography, Checkbox, styled } from '@mui/material';
import {
CheckIcon,
CheckedIcon,
IndeterminateIcon,
} from '../../IconsForTable/icons';
import { ROLES_NAME_ID } from '../../../../constants/constants';
import { createFilterData } from '../../utils/filters';
import {
ROLES_ID_RUSSIAN_NAME_ARRAY as ROLES,
ROLES_ID_NAME,
} from '../../../../constants/constants';
import SelectWithOptions from '../../components/SelectWithOptions';
import RowActionsMenu from './RowActionMenu';
import DepartmentCell from './DepartmentCell';
import StyledTable from '../../components/StyledTable/StyledTable';
const StyledCheckbox = styled(Checkbox)({
padding: '0',
svg: {
width: '1rem',
height: '1rem',
},
});
const UserTable = ({
data = [],
onEdit,
onEditSsp,
onDelete,
filterString,
ssp,
roleId,
onRoleChange,
onSelectedUsers,
selectedUsersId,
// Пропсы высоты
maxHeight = 'calc(100vh - 17rem)',
loading = false,
}) => {
const [selectedUsers, setSelectedUsers] = useState(new Set());
useEffect(() => {
setSelectedUsers(selectedUsersId);
}, [selectedUsersId]);
const filteredData = useMemo(() => {
const filterFunc = createFilterData({
search: filterString,
ssp_id: ssp?.id,
role_id: roleId,
});
return data.filter(filterFunc);
}, [data, filterString, ssp, roleId]);
const handleEditSsp = useCallback(
(user) => {
if (user) {
onEditSsp?.(user);
}
},
[onEditSsp],
);
const handleEdit = (user) => {
if (user) {
onEdit?.(user);
}
};
const handleDelete = (user) => {
if (user) {
onDelete?.(user);
}
};
const handleSelectUser = useCallback(
(userId) => {
const newSelectedUsers = new Set(selectedUsers);
if (newSelectedUsers.has(userId)) {
newSelectedUsers.delete(userId);
} else {
newSelectedUsers.add(userId);
}
setSelectedUsers(newSelectedUsers);
onSelectedUsers(newSelectedUsers);
},
[selectedUsers, onSelectedUsers],
);
const handleSelectAll = useCallback(() => {
if (selectedUsers.size === filteredData.length) {
setSelectedUsers(new Set());
onSelectedUsers(new Set());
} else {
const userIds = new Set(filteredData.map((user) => user.id));
setSelectedUsers(userIds);
onSelectedUsers(userIds);
}
}, [filteredData, selectedUsers.size]);
const handleRoleChange = useCallback(
(user, role) => {
user.role_id = ROLES_NAME_ID[role];
onRoleChange(user);
},
[onRoleChange],
);
const columns = useMemo(
() => [
{
id: 'selection',
header: (
<Box>
<StyledCheckbox
checked={
selectedUsers.size === filteredData.length &&
filteredData.length > 0
}
indeterminate={
selectedUsers.size > 0 &&
selectedUsers.size < filteredData.length
}
onChange={handleSelectAll}
size="small"
icon={<CheckIcon />}
checkedIcon={<CheckedIcon />}
indeterminateIcon={<IndeterminateIcon />}
/>
</Box>
),
Cell: ({ row }) => (
<Box>
<StyledCheckbox
checked={!!selectedUsers.has(row.original.id)}
onChange={() => handleSelectUser(row.original.id)}
size="16"
icon={<CheckIcon />}
checkedIcon={<CheckedIcon />}
/>
</Box>
),
muiTableHeadCellProps: {
sx: {
boxSizing: 'border-box',
width: '2.75rem',
minWidth: '2.75rem',
maxWidth: '2.75rem',
},
},
muiTableBodyCellProps: {
sx: {
boxSizing: 'border-box',
width: '2.75rem',
minWidth: '2.75rem',
maxWidth: '2.75rem',
},
},
enableEditing: false,
enableSorting: false,
enableColumnFilter: false,
enableColumnActions: false,
enableHiding: false,
},
{
accessorKey: 'id',
header: 'ID',
size: 50,
enableHiding: false,
enableEditing: false,
enableColumnActions: false,
},
{
accessorKey: 'user_info',
header: 'Пользователь',
muiTableHeadCellProps: {
sx: {
boxSizing: 'border-box',
width: '26.75rem',
minWidth: '26.75rem',
maxWidth: '26.75rem',
},
},
muiTableBodyCellProps: {
sx: {
boxSizing: 'border-box',
width: '26.75rem',
minWidth: '26.75rem',
maxWidth: '26.75rem',
},
},
Cell: ({ row }) => (
<Box sx={{ display: 'flex', gap: '.5rem', flexDirection: 'column' }}>
<Typography variant="body2" component="div" fontWeight="medium">
{row.original.full_name}
</Typography>
<Typography
variant="body2"
component="div"
sx={{
fontSize: '0.75rem',
lineHeight: '150%',
color: '#4A5565',
}}
>
{row.original.email}
</Typography>
</Box>
),
enableEditing: false,
enableColumnActions: false,
},
{
accessorKey: 'role_id',
header: 'Роль',
muiTableHeadCellProps: {
sx: {
boxSizing: 'border-box',
width: '18.75rem',
minWidth: '18.75rem',
maxWidth: '18.75rem',
},
},
muiTableBodyCellProps: {
sx: {
boxSizing: 'border-box',
width: '18.75rem',
minWidth: '18.75rem',
maxWidth: '18.75rem',
},
},
Cell: ({ cell, row }) => (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<SelectWithOptions
value={cell.getValue()}
options={ROLES}
width="11.25rem"
placeholder="Роль"
onChange={(selectedId) => {
handleRoleChange(row.original, ROLES_ID_NAME[selectedId]);
}}
/>
</Box>
),
enableColumnActions: false,
},
{
accessorKey: 'org_units',
header: 'Подразделения',
muiTableHeadCellProps: {
sx: {
boxSizing: 'border-box',
width: '40.75rem',
minWidth: '40.75rem',
maxWidth: '40.75rem',
},
},
muiTableBodyCellProps: {
sx: {
boxSizing: 'border-box',
width: '40.75rem',
minWidth: '40.75rem',
maxWidth: '40.75rem',
},
},
Cell: ({ cell, row }) => (
<DepartmentCell
values={cell.getValue()}
user={row.original}
onEdit={handleEditSsp}
/>
),
enableColumnActions: false,
},
],
[
selectedUsers,
filteredData.length,
handleSelectAll,
handleSelectUser,
handleRoleChange,
handleEditSsp,
],
);
return (
<StyledTable
columns={columns}
data={filteredData}
maxHeight={maxHeight}
containerHeight={maxHeight}
minHeight={maxHeight}
loading={loading}
enableRowActions={true}
renderRowActions={({ row }) => (
<RowActionsMenu
row={row}
onEditSsp={onEditSsp}
onEdit={handleEdit}
onDelete={handleDelete}
/>
)}
positionActionsColumn="last"
// Начальное состояние
initialState={{
columnVisibility: { id: false },
}}
tableOptions={{
displayColumnDefOptions: {
'mrt-row-actions': {
header: '',
},
},
}}
/>
);
};
export default UserTable;