import { SubmissionController, type SubmissionResponse, type SubmissionsResponse } from "@/controllers/submissions"; import type { SubmissionDTO } from "@dwengo-1/common/interfaces/submission"; import { QueryClient, useMutation, useQuery, useQueryClient, type UseMutationReturnType, type UseQueryReturnType, } from "@tanstack/vue-query"; import { computed, toValue, type MaybeRefOrGetter } from "vue"; function submissionsQueryKey(classid: string, assignmentNumber: number, groupNumber: number, full: boolean) { return ["submissions", classid, assignmentNumber, groupNumber, full]; } function submissionQueryKey(classid: string, assignmentNumber: number, groupNumber: number, submissionNumber: number) { return ["submission", classid, assignmentNumber, groupNumber, submissionNumber]; } export async function invalidateAllSubmissionKeys( queryClient: QueryClient, classid?: string, assignmentNumber?: number, groupNumber?: number, submissionNumber?: number, ) { const keys = ["submission"]; for (const key of keys) { const queryKey = [key, classid, assignmentNumber, groupNumber, submissionNumber].filter( (arg) => arg !== undefined, ); await queryClient.invalidateQueries({ queryKey: queryKey }); } await queryClient.invalidateQueries({ queryKey: ["submissions", classid, assignmentNumber, groupNumber].filter((arg) => arg !== undefined), }); await queryClient.invalidateQueries({ queryKey: ["group-submissions", classid, assignmentNumber, groupNumber].filter((arg) => arg !== undefined), }); await queryClient.invalidateQueries({ queryKey: ["assignment-submissions", classid, assignmentNumber].filter((arg) => arg !== undefined), }); } function checkEnabled( classid: string | undefined, assignmentNumber: number | undefined, groupNumber: number | undefined, submissionNumber: number | undefined, ): boolean { return ( Boolean(classid) && !isNaN(Number(groupNumber)) && !isNaN(Number(assignmentNumber)) && !isNaN(Number(submissionNumber)) ); } function toValues( classid: MaybeRefOrGetter, assignmentNumber: MaybeRefOrGetter, groupNumber: MaybeRefOrGetter, submissionNumber: MaybeRefOrGetter, full: MaybeRefOrGetter, ) { return { cid: toValue(classid), an: toValue(assignmentNumber), gn: toValue(groupNumber), sn: toValue(submissionNumber), f: toValue(full), }; } export function useSubmissionsQuery( classid: MaybeRefOrGetter, assignmentNumber: MaybeRefOrGetter, groupNumber: MaybeRefOrGetter, full: MaybeRefOrGetter = true, ): UseQueryReturnType { const { cid, an, gn, sn, f } = toValues(classid, assignmentNumber, groupNumber, 1, full); return useQuery({ queryKey: computed(() => submissionsQueryKey(cid!, an!, gn!, f)), queryFn: async () => new SubmissionController(cid!, an!, gn!).getAll(f), enabled: () => checkEnabled(cid, an, gn, sn), }); } export function useSubmissionQuery( classid: MaybeRefOrGetter, assignmentNumber: MaybeRefOrGetter, groupNumber: MaybeRefOrGetter, ): UseQueryReturnType { const { cid, an, gn, sn, f } = toValues(classid, assignmentNumber, groupNumber, 1, true); return useQuery({ queryKey: computed(() => submissionQueryKey(cid!, an!, gn!, sn!)), queryFn: async () => new SubmissionController(cid!, an!, gn!).getByNumber(sn!), enabled: () => checkEnabled(cid, an, gn, sn), }); } export function useCreateSubmissionMutation(): UseMutationReturnType< SubmissionResponse, Error, { cid: string; an: number; gn: number; data: SubmissionDTO }, unknown > { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ cid, an, gn, data }) => new SubmissionController(cid, an, gn).createSubmission(data), onSuccess: async (response) => { if (!response.submission.group) { await invalidateAllSubmissionKeys(queryClient); } else { const cls = response.submission.group.class; const assignment = response.submission.group.assignment; const cid = typeof cls === "string" ? cls : cls.id; const an = typeof assignment === "number" ? assignment : assignment.id; const gn = response.submission.group.groupNumber; await invalidateAllSubmissionKeys(queryClient, cid, an, gn); } }, }); } export function useDeleteSubmissionMutation(): UseMutationReturnType< SubmissionResponse, Error, { cid: string; an: number; gn: number; sn: number }, unknown > { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ cid, an, gn, sn }) => new SubmissionController(cid, an, gn).deleteSubmission(sn), onSuccess: async (response) => { if (!response.submission.group) { await invalidateAllSubmissionKeys(queryClient); } else { const cls = response.submission.group.class; const assignment = response.submission.group.assignment; const cid = typeof cls === "string" ? cls : cls.id; const an = typeof assignment === "number" ? assignment : assignment.id; const gn = response.submission.group.groupNumber; await invalidateAllSubmissionKeys(queryClient, cid, an, gn); } }, }); }