322 lines
8.1 KiB
JavaScript
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;
|