/
sweetebin
/
hackaton_26
Обзор
Документация
Войти
/
sweetebin
/
hackaton_26
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
web-form-project/src/hooks/useProject.js
108 строк
3 KB
sweetebin
serve-first: экран сборки пула в дашборде (файлы/папка, живой СберТрек через фасад), старт анализа кнопкой; fbminer sbertrack в CLI; техдолг
28 июл 2026, 15:32
28 июл 2026, 15:32
8dbd2f7
Код
Авторство
О чём код?
import { useCallback, useEffect, useRef, useState } from 'react'; import { addProjectData, approveTask, getProject, rejectTask, startAnalysis as startAnalysisApi, } from '../api/client'; const POLL_INTERVAL_MS = 1500; // Загрузка проекта с сервера + поллинг, пока идёт (пере)анализ пула, // добавление данных и аппрув/отклонение предложенных задач. export function useProject(projectId) { const [project, setProject] = useState(null); const [phase, setPhase] = useState('loading'); // loading | setup | processing | done | error const [error, setError] = useState(null); const pollTimer = useRef(null); const stopPolling = () => { if (pollTimer.current) { clearTimeout(pollTimer.current); pollTimer.current = null; } }; const load = useCallback(() => { getProject(projectId) .then((p) => { setProject(p); if (p.status === 'processing') { setPhase('processing'); pollTimer.current = setTimeout(load, POLL_INTERVAL_MS); } else if (p.status === 'error') { setError('Сервер не смог обработать данные проекта.'); setPhase('error'); } else if (p.status === 'new') { setPhase('setup'); } else { setPhase('done'); } }) .catch((e) => { setError(e.message); setPhase('error'); }); }, [projectId]); useEffect(() => { setProject(null); setPhase('loading'); setError(null); load(); return stopPolling; }, [load]); const addData = useCallback( async (payload) => { await addProjectData(projectId, payload); stopPolling(); setPhase('processing'); load(); }, [projectId, load] ); // Старт анализа с экрана сборки пула const startAnalysis = useCallback(async () => { await startAnalysisApi(projectId); stopPolling(); setPhase('processing'); load(); }, [projectId, load]); const patchTask = (taskId, patch) => { setProject((prev) => prev?.result ? { ...prev, result: { ...prev.result, suggestedTasks: prev.result.suggestedTasks.map((t) => t.id === taskId ? { ...t, ...patch } : t ), }, } : prev ); }; const approve = useCallback( async (taskId) => { const { jiraId, jiraUrl } = await approveTask(projectId, taskId); patchTask(taskId, { status: 'approved', jiraId, jiraUrl }); }, [projectId] ); const reject = useCallback( async (taskId) => { await rejectTask(projectId, taskId); patchTask(taskId, { status: 'rejected' }); }, [projectId] ); return { project, phase, error, addData, startAnalysis, approve, reject, reload: load }; }