import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { NameTask, TaskInfoContainer } from '../../components/common/SwitchFormTask/SwitchFormTask.style'; import { Box, CircularProgress, Stack } from '@mui/material'; import { toast } from 'react-toastify'; import { DictVspApi } from '../../api/dict-vsp'; import { SspApi } from '../../api/ssp'; import { useAuth } from '../../app/context/AuthProvider'; import { BackButton } from '../../components/common/Buttons/BackButton'; import { HeaderPortal } from '../../components/common/HeaderPortal'; import { ROLES_NAME_ID } from '../../constants/constants'; import { PageContainer } from '../../components/common/PageContainer'; import DictVspFilters from './components/DictVspFilters'; import DictVspModals from './components/DictVspModals'; import TableDictVsp from './components/TableDictVsp'; import { buildVspListParams, vspMatchesStatus } from './utils/vspListParams'; const DictVspInfo = () => { const portalContent = ( Справочник ); return {portalContent}; }; function DictVspPage() { const [isLoading, setIsLoading] = useState(true); const [dictVspData, setDictVspData] = useState([]); const [ssps, setSsps] = useState([]); const [selectedSsp, setSelectedSsp] = useState(null); // AURORA-1883: статус ВСП и период закрытия; список ВСП перезагружается с сервера при их смене. const [status, setStatus] = useState('active'); const [closeDates, setCloseDates] = useState({ closeDateStart: '', closeDateEnd: '' }); const [isListLoading, setIsListLoading] = useState(true); const listRequestRef = useRef(0); const { user } = useAuth(); const modalsRef = useRef(null); const listFilter = useMemo(() => ({ status, ...closeDates }), [status, closeDates]); const loadVspList = useCallback(async () => { if (!user) return; const requestId = ++listRequestRef.current; setIsListLoading(true); try { const vspResponse = await DictVspApi.get(buildVspListParams(listFilter)); if (requestId !== listRequestRef.current) return; if (!vspResponse.success) { toast.error('Ошибка загрузки справочника'); return; } setDictVspData(vspResponse.result || []); } catch (error) { if (requestId !== listRequestRef.current) return; toast.error(error.response?.data?.message || 'Ошибка загрузки справочника'); } finally { if (requestId === listRequestRef.current) setIsListLoading(false); } }, [user, listFilter]); useEffect(() => { loadVspList(); }, [loadVspList]); const loadData = useCallback(async () => { if (!user) return; setIsLoading(true); try { const isAdmin = user.role_id === ROLES_NAME_ID.admin; const sspResponse = isAdmin ? await SspApi.getAll({ is_active: true }) : null; if (isAdmin) { if (!sspResponse.success) { toast.error('Ошибка загрузки списка ССП'); return; } setSsps(sspResponse.result); } else { setSsps(user.org_units ?? []); } } catch (error) { console.error('Error loading data:', error); toast.error(error.response?.data?.message || 'Ошибка загрузки данных'); } finally { setIsLoading(false); } }, [user]); useEffect(() => { loadData(); }, [loadData]); const handleAdd = useCallback( async (formData) => { try { const response = await DictVspApi.create(formData); if (response.success) { toast.success('ВСП успешно создан'); if (vspMatchesStatus(response.result, status)) { setDictVspData((prev) => [...prev, response.result]); } } else { toast.error(response.message || 'Ошибка создания ВСП'); } } catch (error) { console.error('Error adding VSP:', error); toast.error(error.response?.data?.message || 'Ошибка создания ВСП'); throw error; } }, [status], ); const handleEdit = useCallback( async (formData) => { try { const response = await DictVspApi.update(formData.id, formData); if (response.success) { toast.success('ВСП успешно обновлен'); // AURORA-1883: ВСП, переставший подходить под статус (например, закрыт в «Действующих»), уходит из списка. setDictVspData((prev) => { const rest = prev.filter((v) => v.id !== formData.id); return vspMatchesStatus(response.result, status) ? [...rest, response.result] : rest; }); } else { toast.error(response.message || 'Ошибка обновления ВСП'); } } catch (error) { console.error('Error editing VSP:', error); toast.error(error.response?.data?.message || 'Ошибка обновления ВСП'); throw error; } }, [status], ); const handleDelete = useCallback(async (vspId) => { try { const response = await DictVspApi.delete(vspId); if (response.success) { toast.success('ВСП успешно удален'); setDictVspData((prev) => [...prev.filter((v) => v.id !== vspId)]); } else { toast.error(response.message || 'Ошибка удаления ВСП'); } } catch (error) { console.error('Error deleting VSP:', error); toast.error(error.response?.data?.message || 'Ошибка удаления ВСП'); throw error; } }, []); const handleAddClick = useCallback(() => modalsRef.current?.openAdd(), []); const handleEditClick = useCallback((item) => modalsRef.current?.openEdit(item), []); const handleExportClick = useCallback(() => modalsRef.current?.openExport(), []); if (isLoading) { return ( <>
); } return ( <> {/* */} ); } export default DictVspPage;