From d08e2cb3b9bd106f51ef1275e3fa95e012f7ed4c Mon Sep 17 00:00:00 2001 From: Michal Masrna <38047051+michalmasrna1@users.noreply.github.com> Date: Sun, 24 Nov 2024 13:55:48 +0100 Subject: [PATCH] Semester administration enhancements (#499) * SemesterAdministration layout changes * SemesterAdministration only display Freeze buttons if the series/semester is not yet complete * Refetching semester on successful freeze of semester or series * SemesterAdministration separate errors for each series * SemesterAdmin removed semester freezing. Semester freezes automatically when all series are frozen. * Unset error message on success --------- Co-authored-by: matushl --- .../SemesterAdministration.tsx | 75 +++++++++---------- src/types/api/generated/competition.ts | 2 + 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/components/SemesterAdministration/SemesterAdministration.tsx b/src/components/SemesterAdministration/SemesterAdministration.tsx index c4f27e57..43cf2b05 100644 --- a/src/components/SemesterAdministration/SemesterAdministration.tsx +++ b/src/components/SemesterAdministration/SemesterAdministration.tsx @@ -1,5 +1,5 @@ import {Stack, Typography} from '@mui/material' -import {useQuery} from '@tanstack/react-query' +import {useMutation, useQuery} from '@tanstack/react-query' import axios, {AxiosError} from 'axios' import {FC, useState} from 'react' @@ -33,7 +33,11 @@ export const SemesterAdministration: FC = () => { const {hasPermissions, permissionsIsLoading} = useHasPermissions() - const {data: semesterData, isLoading: semesterIsLoading} = useQuery({ + const { + data: semesterData, + isLoading: semesterIsLoading, + refetch, + } = useQuery({ queryKey: ['competition', 'semester', semesterId], queryFn: () => axios.get(`/api/competition/semester/${semesterId}`), // router.query.params su v prvom renderi undefined, tak pustime query az so spravnym semesterId @@ -84,34 +88,22 @@ export const SemesterAdministration: FC = () => { ) } - const [semesterFreezeError, setSemesterFreezeError] = useState() - const [seriesFreezeError, setSeriesFreezeError] = useState() - - const freezeSemester = async (semester: SemesterWithProblems) => { - setSemesterFreezeError('') - try { - await axios.post(`/api/competition/semester/${semester.id}/results/freeze`) - } catch (error: unknown) { - if (error instanceof AxiosError) { - setSemesterFreezeError(error.response?.data.detail) - } else { - setSemesterFreezeError('Nastala neznáma chyba.') - } - } - } + const [seriesFreezeErrors, setSeriesFreezeErrors] = useState>() - const freezeSeries = async (series: SeriesWithProblems) => { - setSeriesFreezeError('') - try { - await axios.post(`/api/competition/series/${series.id}/results/freeze`) - } catch (error: unknown) { + const {mutate: freezeSeries} = useMutation({ + mutationFn: (series: SeriesWithProblems) => axios.post(`/api/competition/series/${series.id}/results/freeze`), + onSuccess: (_, variables: SeriesWithProblems) => { + setSeriesFreezeErrors((prev) => new Map(prev).set(variables.id, '')) + refetch() + }, + onError: (error: unknown, variables: SeriesWithProblems) => { if (error instanceof AxiosError) { - setSeriesFreezeError(error.response?.data.detail) + setSeriesFreezeErrors((prev) => new Map(prev).set(variables.id, error.response?.data.detail)) } else { - setSeriesFreezeError('Nastala neznáma chyba.') + setSeriesFreezeErrors((prev) => new Map(prev).set(variables.id, 'Nastala neznáma chyba.')) } - } - } + }, + }) if ( urlDataLoading.currentSeriesIsLoading || @@ -130,24 +122,29 @@ export const SemesterAdministration: FC = () => { return ( <> - Administrácia semestra pre opravovateľov. - - - {semesterFreezeError && {semesterFreezeError}} + + Semester + {semester.complete && Semester je uzavretý} {semester.series_set.map((series) => ( - {series.order}. séria - - - {seriesFreezeError && {seriesFreezeError}} + + {series.order}. séria + {series.complete ? ( + Séria je uzavretá + ) : ( + + )} + {seriesFreezeErrors?.get(series.id) && ( + {seriesFreezeErrors?.get(series.id)} + )} - Opravovanie úloh: + + Opravovanie úloh: + Termín série: {formatDateTime(series.deadline)} diff --git a/src/types/api/generated/competition.ts b/src/types/api/generated/competition.ts index 7f9d0dae..78610e60 100644 --- a/src/types/api/generated/competition.ts +++ b/src/types/api/generated/competition.ts @@ -142,6 +142,7 @@ export interface Semester { start: string end: string additional_name?: string | null + complete: boolean frozen_results?: string | null competition?: any | null late_tags?: any[] @@ -159,6 +160,7 @@ export interface SemesterWithProblems { start: string end: string additional_name?: string | null + complete: boolean frozen_results?: string | null competition?: any | null late_tags?: any[]