288 lines
6.8 KiB
JavaScript
288 lines
6.8 KiB
JavaScript
import { Box, Checkbox, Typography, styled } from '@mui/material';
|
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
import { ROLES_NAME_ID } from '../../../../constants/constants';
|
|
import { ROLES_ID_RUSSIAN_NAME_ARRAY as ROLES, ROLES_ID_NAME } from '../../../../constants/constants';
|
|
import { CheckIcon, CheckedIcon, IndeterminateIcon } from '../../IconsForTable/icons';
|
|
import SelectWithOptions from '../../components/SelectWithOptions';
|
|
import StyledTable from '../../components/StyledTable/StyledTable';
|
|
import { createFilterData } from '../../utils/filters';
|
|
import DepartmentCell from './DepartmentCell';
|
|
import RowActionsMenu from './RowActionMenu';
|
|
|
|
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' sx={{ 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;
|