import { message } from 'antd'; import { useCallback, useEffect, useRef, useState } from 'react'; import { ApiError } from '../../api/client'; import { hasPendingFiles, listLegalEntityFiles } from '../../services/api/files'; import type { FileOut } from '../../types/api'; const POLL_MS = 5000; /** * Файлы рабочего стола консолидации (`consolidationId`) или все файлы ЮЛ (`null`); * пока панель открыта и есть UPLOADED/PROCESSING — перечитываем раз в 5 с. */ export function useLegalEntityFiles(legalEntityId: string | null, consolidationId: string | null, open: boolean) { const [files, setFiles] = useState([]); const [loading, setLoading] = useState(false); const requestRef = useRef(0); const inFlightRef = useRef(false); const errorShownRef = useRef(false); const reload = useCallback(async () => { if (!legalEntityId) return; const requestId = ++requestRef.current; inFlightRef.current = true; setLoading(true); try { const items = await listLegalEntityFiles(legalEntityId, consolidationId); if (requestId === requestRef.current) { setFiles(items); errorShownRef.current = false; } } catch (e: unknown) { // при опросе показываем ошибку один раз на серию; флаг сбрасывается после первого успешного ответа if (requestId === requestRef.current && !errorShownRef.current) { errorShownRef.current = true; message.error(e instanceof ApiError ? e.message : 'Не удалось получить файлы'); } } finally { if (requestId === requestRef.current) { inFlightRef.current = false; setLoading(false); } } }, [legalEntityId, consolidationId]); // смена режима (consolidationId) приходит через reload: он пересоздаётся и перезапускает этот эффект useEffect(() => { // при смене ЮЛ, режима (консолидация/все) или закрытии панели: старые ответы не применяем, прежние файлы очищаем requestRef.current++; inFlightRef.current = false; errorShownRef.current = false; setFiles([]); if (open && legalEntityId) void reload(); }, [open, legalEntityId, reload]); const pending = hasPendingFiles(files); useEffect(() => { if (!open || !pending) return; const timer = window.setInterval(() => { if (!inFlightRef.current) void reload(); // не копим параллельные запросы при медленном ответе }, POLL_MS); return () => window.clearInterval(timer); }, [open, pending, reload]); return { files, loading, reload }; }