367 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useEffect } from 'react';
import { PageContainer } from '../../StyledForPage';
import { HeaderSwitch } from '../../../components/HeaderMenu/HeaderSwitch';
import { SwitchUserSsp } from '../../../components/AdminPanel/SwitchUserSsp';
import { ROLES_ID_RUSSIAN_NAME_ARRAY, ROLES_NAME_ID } from '../../../constants';
import { useAuth } from '../../../app/context/AuthProvider';
import { Box, TextField, Autocomplete, FormLabel } from '@mui/material';
import SearchComponent from '../../../components/common/SearchComponent';
import { toast } from 'react-toastify';
import { SspApi } from '../../../api/ssp';
import { UsersApi } from '../../../api/users';
import UserTable from './UserTable/UserTable';
import { ROLES_ID_RUSSIAN_NAME } from '../../../constants';
import { ModalEditUserSsp } from './ModalEditUserSsp';
import { ModalAddUsers } from './ModalAddUsers';
import UsersActionBar from './UsersActionBar';
import { PrimaryButton } from '../../../components/common/Buttons/Buttons';
import { WhitePlus } from '../../../components/common/icons/icons';
const UsersPage = () => {
const { user } = useAuth();
const [deps, setDeps] = useState([]);
const [roles, setRoles] = useState([]);
const [dep, setDep] = useState(null);
const [role, setRole] = useState(null);
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(false);
const [filterString, setFilterString] = useState('');
const [editableUser, setEditableUser] = useState(null);
const [selectedUsersId, setSelectedUsersId] = useState(new Set());
const [openEditUsers, setOpenEditUserSsp] = useState(false);
const [openModalAddUsers, setOpenModalAddUser] = useState(false);
const loadUsers = async () => {
setLoading(true);
try {
const data = await UsersApi.getAll();
if (!data.success) {
toast.error('Ошибка получения пользователей ' + data.message);
return;
}
setUsers(data.result.sort((a, b) => a.id - b.id));
} catch {
toast.error('Ошибка получения пользователей');
} finally {
setLoading(false);
}
};
useEffect(() => {
setRoles(ROLES_ID_RUSSIAN_NAME_ARRAY);
SspApi.getAll().then((data) => {
if (!data.success) {
toast.error(
'Ошибка получения ССП/Региональные филиалы ' + data.message,
);
return;
}
const activeDeps = data.result.filter((v) => v.is_active);
setDeps(activeDeps);
});
loadUsers();
}, []);
const handleEditUserSsp = (user) => {
setEditableUser(user);
setOpenEditUserSsp(true);
};
const handleSaveEditableUser = async (user, depsData = null) => {
try {
if (depsData !== null) {
if (depsData.delete.length > 0) {
try {
const deleteResult = await SspApi.deleteManySsps(user.id, {
user_id: user.id,
ssp_ids: depsData.delete,
});
if (deleteResult.success) {
toast.success('Подразделение у пользователя удалено');
} else {
toast.error('Ошибка удаления подразделения у пользователя');
return;
}
} catch (error) {
toast.error('Ошибка удаления подразделения у пользователя');
return;
}
}
if (depsData.update.length > 0) {
try {
const updateResult = await SspApi.putManySsps(user.id, {
ssp_ids: depsData.update,
});
if (updateResult.success) {
toast.success('Подразделение у пользователя добавлено');
} else {
toast.error('Ошибка добавления подразделения у пользователя');
}
} catch (error) {
toast.error('Ошибка добавления подразделения у пользователя');
}
}
}
const data = await UsersApi.update(user.id, { ...user, load_orgs: true });
if (!data.success) {
toast.error('Не удалось обновить данные', data.message);
return;
}
const updatedUser = data.result;
if (updatedUser?.id) {
setUsers((prev) =>
prev
.map((u) => (u.id === updatedUser.id ? updatedUser : u))
.sort((a, b) => a.id - b.id),
);
}
} catch (error) {
toast.error(error?.detail || 'Не удалось обновить данные');
}
};
const handleUserAdded = (newUser) => {
if (!newUser?.id) return;
setUsers((prev) => {
if (prev.some((u) => u.id === newUser.id)) return prev;
return [...prev, newUser].sort((a, b) => a.id - b.id);
});
};
const handleOpenModalAddUsers = () => {
setOpenModalAddUser(true);
};
const handleCloseModalAddUsers = () => {
setOpenModalAddUser(false);
};
const handleSelectedUser = (users) => {
setSelectedUsersId(users);
};
const handleDeleteSelectedUsers = () => {
for (const userId of selectedUsersId) {
handleDeleteUser(userId);
}
};
const handleDeleteUser = (userId) => {
UsersApi.delete(userId)
.then((data) => {
if (data.success) {
setUsers((prev) => prev.filter((u) => u.id != userId));
} else {
toast.error('Ошибка удаления пользователя ' + data.message);
}
})
.catch(() => {
toast.error('Ошибка удаления пользователя ');
});
};
const handleUsersChange = (changeData) => {
const { sspId, roleId } = changeData;
const selectedUsers = users.filter((u) => selectedUsersId.has(u.id));
for (const user of selectedUsers) {
let depsData;
if (roleId) {
user.role_id = roleId;
}
if (sspId) {
depsData = {
update: [sspId],
delete:
user.role_id === ROLES_NAME_ID.executor_rf &&
user.org_units?.[0]?.id !== undefined
? [user.org_units[0].id]
: [],
};
user.ssp_id = sspId;
}
handleSaveEditableUser(user, depsData);
}
};
const handleUnselectUsers = () => {
setSelectedUsersId(new Set());
};
if (!user || user.role_id != ROLES_NAME_ID.admin) return;
return (
<>
<PageContainer>
<HeaderSwitch />
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<SwitchUserSsp />
<Box sx={{ display: 'flex', gap: '1rem', alignItems: 'end' }}>
<PrimaryButton
onClick={handleOpenModalAddUsers}
sx={{ marginLeft: '2rem', maxWidth: 'max-content' }}
startIcon={<WhitePlus />}
>
Добавить
</PrimaryButton>
</Box>
</Box>
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<Box sx={{ display: 'flex', gap: '1rem', alignItems: 'end' }}>
<SearchComponent
placeholder="Поиск по пользователям..."
onChange={setFilterString}
height="2.5rem"
/>
<Box
sx={{ display: 'flex', flexDirection: 'column', gap: '0.125rem' }}
>
<FormLabel
sx={{
fontWeight: '400',
fontSize: '0.75rem',
color: '#4a5565',
margin: '0',
}}
>
Роли
</FormLabel>
<Autocomplete
size="small"
options={roles}
noOptionsText="Не найдено"
getOptionLabel={(option) =>
ROLES_ID_RUSSIAN_NAME[option.id] || option.name || ''
}
value={role ? roles.find((f) => f.id === role.id) : null}
onChange={(event, newValue) => {
setRole(
newValue ? roles.find((f) => f.id === newValue.id) : null,
);
}}
sx={{ height: '2.5rem', minWidth: '20.25rem' }}
renderInput={(params) => (
<TextField
{...params}
placeholder="Все"
sx={{
height: '2.5rem',
width: '20.25rem',
'& .MuiOutlinedInput-root': {
height: '2.5rem',
'& fieldset': {
borderRadius: '0.5rem',
borderColor: 'rgba(0,0,0,0.1)',
},
},
}}
/>
)}
/>
</Box>
<Box
sx={{ display: 'flex', flexDirection: 'column', gap: '0.125rem' }}
>
<FormLabel
sx={{
fontWeight: '400',
fontSize: '0.75rem',
color: '#4a5565',
margin: '0',
}}
>
ССП/Региональные филиалы
</FormLabel>
<Autocomplete
size="small"
options={[{ id: null, title: 'Без ССП' }, ...deps]}
noOptionsText="Не найдено"
getOptionLabel={(option) => option.title || option.name || ''}
value={
dep
? dep.id === null
? { id: null, title: 'Без ССП' }
: deps.find((f) => f.id === dep.id)
: null
}
onChange={(event, newValue) => {
setDep(
newValue
? newValue.id === null
? { id: null, title: 'Без ССП' }
: deps.find((f) => f.id === newValue.id)
: null,
);
}}
sx={{ height: '2.5rem', minWidth: '11.25rem' }}
renderInput={(params) => (
<TextField
{...params}
placeholder="Все"
sx={{
height: '2.5rem',
width: '11.25rem',
'& .MuiOutlinedInput-root': {
height: '2.5rem',
'& fieldset': {
borderRadius: '0.5rem',
borderColor: 'rgba(0,0,0,0.1)',
},
},
}}
/>
)}
/>
</Box>
</Box>
{selectedUsersId.size > 0 && (
<UsersActionBar
countUser={selectedUsersId.size}
onDelete={handleDeleteSelectedUsers}
onSave={handleUsersChange}
onClose={handleUnselectUsers}
sspOptions={deps}
/>
)}
</Box>
<UserTable
data={users}
loading={loading}
filterString={filterString}
ssp={dep !== null ? dep : null}
roleId={role !== null ? role.id : ''}
onEditSsp={handleEditUserSsp}
onEdit={handleSaveEditableUser}
onDelete={handleDeleteUser}
onRoleChange={handleSaveEditableUser}
onSelectedUsers={handleSelectedUser}
selectedUsersId={selectedUsersId}
/>
</PageContainer>
<ModalEditUserSsp
open={openEditUsers}
onClose={() => {
setOpenEditUserSsp(false);
}}
user={editableUser}
deps={deps}
onEdit={handleSaveEditableUser}
/>
<ModalAddUsers
open={openModalAddUsers}
onClose={handleCloseModalAddUsers}
sspOptions={deps}
onAddUser={handleUserAdded}
/>
</>
);
};
export default UsersPage;