UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

462 lines (460 loc) 14.8 kB
// src/utils/categoryDataUtils.ts async function fetchStudentsByFilters(apiClient, filters) { if ((!filters.schoolIds || filters.schoolIds.length === 0) && (!filters.schoolYearIds || filters.schoolYearIds.length === 0) && (!filters.classIds || filters.classIds.length === 0)) { return []; } const response = await apiClient.post("/students/filters", { ...filters.schoolIds && filters.schoolIds.length > 0 && { schoolIds: filters.schoolIds }, ...filters.schoolYearIds && filters.schoolYearIds.length > 0 && { schoolYearIds: filters.schoolYearIds }, ...filters.classIds && filters.classIds.length > 0 && { classIds: filters.classIds } }); return response.data.data.students || []; } async function fetchClassesByFilters(apiClient, filters) { const hasSchools = !!filters.schoolIds && filters.schoolIds.length > 0; const hasYears = !!filters.schoolYearIds && filters.schoolYearIds.length > 0; if (!hasSchools && !hasYears) return []; return fetchAllPages( apiClient, "/classes", (data) => { const d = data; return { items: d.classes ?? [], totalPages: d.pagination?.totalPages ?? 1 }; }, { ...hasSchools && { schoolId: filters.schoolIds.join(",") }, ...hasYears && { schoolYearId: filters.schoolYearIds.join(",") } } ); } async function fetchAllPages(apiClient, url, extract, extraParams = {}) { const firstResponse = await apiClient.get( url, { params: { ...extraParams, page: 1, limit: 100 } } ); const first = extract(firstResponse.data.data); const totalPages = first.totalPages || 1; const all = [...first.items ?? []]; if (totalPages <= 1) { return all; } const remainingPages = Array.from( { length: totalPages - 1 }, (_, i) => i + 2 ); const responses = await Promise.all( remainingPages.map( (page) => apiClient.get(url, { params: { ...extraParams, page, limit: 100 } }) ) ); for (const response of responses) { const { items } = extract(response.data.data); all.push(...items ?? []); } return all; } async function loadCategoriesData(apiClient, existingCategories) { if (existingCategories.length > 0) { return existingCategories; } const [schools, schoolYears] = await Promise.all([ fetchAllPages(apiClient, "/school", (data) => { const d = data; return { items: d.schools, totalPages: d.pagination?.totalPages ?? 1 }; }), fetchAllPages(apiClient, "/schoolYear", (data) => { const d = data; return { items: d.schoolYears, totalPages: d.pagination?.totalPages ?? 1 }; }) ]); const transformedCategories = [ { key: "escola", label: "Escola", itens: schools.map((s) => ({ id: s.id, name: s.companyName })), selectedIds: [] }, { key: "serie", label: "S\xE9rie", dependsOn: ["escola"], filteredBy: [{ key: "escola", internalField: "schoolId" }], itens: schoolYears.map((sy) => ({ id: sy.id, name: sy.name, schoolId: sy.schoolId })), selectedIds: [] }, { key: "turma", label: "Turma", dependsOn: ["serie"], filteredBy: [{ key: "serie", internalField: "schoolYearId" }], // Classes are loaded dynamically based on selected schools/schoolYears itens: [], selectedIds: [] }, { key: "students", label: "Alunos", dependsOn: ["turma"], filteredBy: [ { key: "escola", internalField: "escolaId" }, { key: "serie", internalField: "serieId" }, { key: "turma", internalField: "turmaId" } ], // Students will be loaded dynamically based on selections itens: [], selectedIds: [] } ]; return transformedCategories; } function formatTime(date) { const hours = date.getHours().toString().padStart(2, "0"); const minutes = date.getMinutes().toString().padStart(2, "0"); return `${hours}:${minutes}`; } // src/utils/useDynamicStudentFetching.ts import { useCallback, useRef } from "react"; function extractSelectedIds(updatedCategories) { const escolaCategory = updatedCategories.find((c) => c.key === "escola"); const serieCategory = updatedCategories.find((c) => c.key === "serie"); const turmaCategory = updatedCategories.find((c) => c.key === "turma"); const studentsCategory = updatedCategories.find((c) => c.key === "students"); return { schoolIds: escolaCategory?.selectedIds || [], schoolYearIds: serieCategory?.selectedIds || [], classIds: turmaCategory?.selectedIds || [], studentsCategory }; } function detectSelectionChanges(previousSelections, currentSelections) { const isInitialState = previousSelections.schoolIds.length === 0 && previousSelections.schoolYearIds.length === 0 && previousSelections.classIds.length === 0; const arraysEqual = (a, b) => { if (a.length !== b.length) return false; return a.every((id) => b.includes(id)) && b.every((id) => a.includes(id)); }; const schoolIdsChanged = isInitialState || !arraysEqual(previousSelections.schoolIds, currentSelections.schoolIds); const schoolYearIdsChanged = isInitialState || !arraysEqual( previousSelections.schoolYearIds, currentSelections.schoolYearIds ); const classIdsChanged = isInitialState || !arraysEqual(previousSelections.classIds, currentSelections.classIds); const shouldFetchStudents = schoolIdsChanged || schoolYearIdsChanged || classIdsChanged; return { schoolIdsChanged, schoolYearIdsChanged, classIdsChanged, shouldFetchStudents }; } function transformStudentsToItems(students) { return students.map((s) => ({ id: `${s.userInstitutionId}-${s.class.id}`, name: s.name, classId: String(s.class.id), schoolId: String(s.school.id), schoolYearId: String(s.schoolYear.id), studentId: s.id, userInstitutionId: s.userInstitutionId, escolaId: String(s.school.id), serieId: String(s.schoolYear.id), turmaId: String(s.class.id) })); } function transformClassesToItems(classes) { return classes.map((c) => ({ id: c.id, name: c.name, schoolYearId: c.schoolYearId })); } function setCategoryItems(categories, key, itens) { return categories.map((cat) => cat.key === key ? { ...cat, itens } : cat); } function commitSelectionsPreservingItems(updatedCategories, prev) { return updatedCategories.map((cat) => { const prior = prev.find((p) => p.key === cat.key); return prior ? { ...cat, itens: prior.itens } : cat; }); } function useDynamicStudentFetching(setCategories, options = {}) { const { apiClient, fetchStudentsByFilters: customFetchStudents, fetchClassesByFilters: fetchClasses = fetchClassesByFilters, onError } = options; const previousSelectionsRef = useRef({ schoolIds: [], schoolYearIds: [], classIds: [] }); const fetchRequestId = useRef(0); const fetchClassesRequestId = useRef(0); const buildStudentFilters = useCallback( (selectedSchoolIds, selectedSchoolYearIds, selectedClassIds) => ({ schoolIds: selectedSchoolIds.length > 0 ? selectedSchoolIds : void 0, schoolYearIds: selectedSchoolYearIds.length > 0 ? selectedSchoolYearIds : void 0, classIds: selectedClassIds.length > 0 ? selectedClassIds : void 0 }), [] ); const fetchWithCustomFunction = useCallback( async (selectedSchoolIds, selectedSchoolYearIds, selectedClassIds, localRequestId) => { if (!customFetchStudents) { return null; } const filters = buildStudentFilters( selectedSchoolIds, selectedSchoolYearIds, selectedClassIds ); const students = await customFetchStudents(filters); if (localRequestId !== fetchRequestId.current) { return null; } return students; }, [customFetchStudents, buildStudentFilters] ); const fetchWithApiClient = useCallback( async (selectedSchoolIds, selectedSchoolYearIds, selectedClassIds, localRequestId) => { if (!apiClient) { return null; } const filters = buildStudentFilters( selectedSchoolIds, selectedSchoolYearIds, selectedClassIds ); const students = await fetchStudentsByFilters(apiClient, filters); if (localRequestId !== fetchRequestId.current) { return null; } return students; }, [apiClient, buildStudentFilters] ); const performStudentFetch = useCallback( async (selectedSchoolIds, selectedSchoolYearIds, selectedClassIds, localRequestId) => { const students = await fetchWithCustomFunction( selectedSchoolIds, selectedSchoolYearIds, selectedClassIds, localRequestId ); if (students !== null) { return students; } return fetchWithApiClient( selectedSchoolIds, selectedSchoolYearIds, selectedClassIds, localRequestId ); }, [fetchWithCustomFunction, fetchWithApiClient] ); const performClassFetch = useCallback( async (selectedSchoolIds, selectedSchoolYearIds, localRequestId) => { if (!apiClient) { return null; } const filters = { schoolIds: selectedSchoolIds.length > 0 ? selectedSchoolIds : void 0, schoolYearIds: selectedSchoolYearIds.length > 0 ? selectedSchoolYearIds : void 0 }; const classes = await fetchClasses(apiClient, filters); if (localRequestId !== fetchClassesRequestId.current) { return null; } return classes; }, [apiClient, fetchClasses] ); const handleSuccessfulFetch = useCallback( (students, localRequestId) => { if (localRequestId !== fetchRequestId.current) { return false; } const studentItems = transformStudentsToItems(students); setCategories((prev) => setCategoryItems(prev, "students", studentItems)); return true; }, [setCategories] ); const handleFetchError = useCallback( (error, localRequestId) => { console.error("Error fetching students:", error); if (onError && error instanceof Error) { onError(error); } if (localRequestId !== fetchRequestId.current) { return false; } setCategories((prev) => setCategoryItems(prev, "students", [])); return true; }, [onError, setCategories] ); const handleSuccessfulClassFetch = useCallback( (classes, localRequestId) => { if (localRequestId !== fetchClassesRequestId.current) { return false; } const classItems = transformClassesToItems(classes); setCategories((prev) => setCategoryItems(prev, "turma", classItems)); return true; }, [setCategories] ); const handleClassFetchError = useCallback( (error, localRequestId) => { console.error("Error fetching classes:", error); if (onError && error instanceof Error) { onError(error); } if (localRequestId !== fetchClassesRequestId.current) { return false; } setCategories((prev) => setCategoryItems(prev, "turma", [])); return true; }, [onError, setCategories] ); const handleClassesChange = useCallback( async (selectedSchoolIds, selectedSchoolYearIds) => { if (!apiClient) return; if (selectedSchoolYearIds.length > 0) { fetchClassesRequestId.current += 1; const localRequestId = fetchClassesRequestId.current; try { const classes = await performClassFetch( selectedSchoolIds, selectedSchoolYearIds, localRequestId ); if (classes === null) { return; } handleSuccessfulClassFetch(classes, localRequestId); } catch (error) { handleClassFetchError(error, localRequestId); } } else { fetchClassesRequestId.current += 1; setCategories((prev) => setCategoryItems(prev, "turma", [])); } }, [ apiClient, performClassFetch, handleSuccessfulClassFetch, handleClassFetchError, setCategories ] ); const handleStudentsChange = useCallback( async (selectedSchoolIds, selectedSchoolYearIds, selectedClassIds, studentsCategory) => { if (selectedClassIds.length > 0 && studentsCategory) { fetchRequestId.current += 1; const localRequestId = fetchRequestId.current; try { const students = await performStudentFetch( selectedSchoolIds, selectedSchoolYearIds, selectedClassIds, localRequestId ); if (students === null) { return; } handleSuccessfulFetch(students, localRequestId); } catch (error) { handleFetchError(error, localRequestId); } } else if (studentsCategory) { fetchRequestId.current += 1; setCategories((prev) => setCategoryItems(prev, "students", [])); } }, [ performStudentFetch, handleSuccessfulFetch, handleFetchError, setCategories ] ); const handleCategoriesChange = useCallback( async (updatedCategories) => { if (!customFetchStudents && !apiClient) { setCategories(updatedCategories); return; } const { schoolIds: selectedSchoolIds, schoolYearIds: selectedSchoolYearIds, classIds: selectedClassIds, studentsCategory } = extractSelectedIds(updatedCategories); const previousSelections = previousSelectionsRef.current; const { schoolIdsChanged, schoolYearIdsChanged, shouldFetchStudents } = detectSelectionChanges(previousSelections, { schoolIds: selectedSchoolIds, schoolYearIds: selectedSchoolYearIds, classIds: selectedClassIds }); previousSelectionsRef.current = { schoolIds: [...selectedSchoolIds], schoolYearIds: [...selectedSchoolYearIds], classIds: [...selectedClassIds] }; setCategories( (prev) => commitSelectionsPreservingItems(updatedCategories, prev) ); if (schoolIdsChanged || schoolYearIdsChanged) { await handleClassesChange(selectedSchoolIds, selectedSchoolYearIds); } if (shouldFetchStudents) { await handleStudentsChange( selectedSchoolIds, selectedSchoolYearIds, selectedClassIds, studentsCategory ); } }, [ apiClient, customFetchStudents, setCategories, handleClassesChange, handleStudentsChange ] ); return { handleCategoriesChange }; } export { loadCategoriesData, formatTime, useDynamicStudentFetching }; //# sourceMappingURL=chunk-5WLR5TLU.mjs.map