Merge branch 'feat/queries-adriaan' of github.com:SELab-2/Dwengo-1 into feat/queries-adriaan
This commit is contained in:
		
						commit
						428c7ddfde
					
				
					 4 changed files with 250 additions and 151 deletions
				
			
		|  | @ -1,7 +1,13 @@ | ||||||
| import { AssignmentController, type AssignmentResponse, type AssignmentsResponse } from "@/controllers/assignments"; | import { AssignmentController, type AssignmentResponse, type AssignmentsResponse } from "@/controllers/assignments"; | ||||||
| import type { QuestionsResponse } from "@/controllers/questions"; | import type { QuestionsResponse } from "@/controllers/questions"; | ||||||
| import type { SubmissionsResponse } from "@/controllers/submissions"; | import type { SubmissionsResponse } from "@/controllers/submissions"; | ||||||
| import { useMutation, useQuery, useQueryClient, type UseMutationReturnType, type UseQueryReturnType } from "@tanstack/vue-query"; | import { | ||||||
|  |     useMutation, | ||||||
|  |     useQuery, | ||||||
|  |     useQueryClient, | ||||||
|  |     type UseMutationReturnType, | ||||||
|  |     type UseQueryReturnType, | ||||||
|  | } from "@tanstack/vue-query"; | ||||||
| import { computed, toValue, type MaybeRefOrGetter } from "vue"; | import { computed, toValue, type MaybeRefOrGetter } from "vue"; | ||||||
| import { groupsQueryKey, invalidateAllGroupKeys } from "./groups"; | import { groupsQueryKey, invalidateAllGroupKeys } from "./groups"; | ||||||
| import type { GroupsResponse } from "@/controllers/groups"; | import type { GroupsResponse } from "@/controllers/groups"; | ||||||
|  | @ -10,31 +16,31 @@ import type { QueryClient } from "@tanstack/react-query"; | ||||||
| import { invalidateAllSubmissionKeys } from "./submissions"; | import { invalidateAllSubmissionKeys } from "./submissions"; | ||||||
| 
 | 
 | ||||||
| function assignmentsQueryKey(classid: string, full: boolean) { | function assignmentsQueryKey(classid: string, full: boolean) { | ||||||
|     return [ "assignments", classid, full ]; |     return ["assignments", classid, full]; | ||||||
| } | } | ||||||
| function assignmentQueryKey(classid: string, assignmentNumber: number) { | function assignmentQueryKey(classid: string, assignmentNumber: number) { | ||||||
|     return [ "assignment", classid, assignmentNumber ]; |     return ["assignment", classid, assignmentNumber]; | ||||||
| } | } | ||||||
| function assignmentSubmissionsQueryKey(classid: string, assignmentNumber: number, full: boolean) { | function assignmentSubmissionsQueryKey(classid: string, assignmentNumber: number, full: boolean) { | ||||||
|     return [ "assignment-submissions", classid, assignmentNumber, full ]; |     return ["assignment-submissions", classid, assignmentNumber, full]; | ||||||
| } | } | ||||||
| function assignmentQuestionsQueryKey(classid: string, assignmentNumber: number, full: boolean) { | function assignmentQuestionsQueryKey(classid: string, assignmentNumber: number, full: boolean) { | ||||||
|     return [ "assignment-questions", classid, assignmentNumber, full ]; |     return ["assignment-questions", classid, assignmentNumber, full]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function invalidateAllAssignmentKeys(queryClient: QueryClient, classid?: string, assignmentNumber?: number) { | export async function invalidateAllAssignmentKeys( | ||||||
|     const keys = [ |     queryClient: QueryClient, | ||||||
|         "assignment", |     classid?: string, | ||||||
|         "assignment-submissions", |     assignmentNumber?: number, | ||||||
|         "assignment-questions", | ) { | ||||||
|     ]; |     const keys = ["assignment", "assignment-submissions", "assignment-questions"]; | ||||||
| 
 | 
 | ||||||
|     for (let key of keys) { |     for (const key of keys) { | ||||||
|         const queryKey = [key, classid, assignmentNumber].filter(arg => arg !== undefined); |         const queryKey = [key, classid, assignmentNumber].filter((arg) => arg !== undefined); | ||||||
|         await queryClient.invalidateQueries({ queryKey: queryKey }); |         await queryClient.invalidateQueries({ queryKey: queryKey }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     await queryClient.invalidateQueries({ queryKey: [ "assignments", classid ].filter(arg => arg !== undefined) }); |     await queryClient.invalidateQueries({ queryKey: ["assignments", classid].filter((arg) => arg !== undefined) }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkEnabled( | function checkEnabled( | ||||||
|  | @ -60,7 +66,7 @@ export function useAssignmentsQuery( | ||||||
|     const { cid, f } = toValues(classid, 1, 1, full); |     const { cid, f } = toValues(classid, 1, 1, full); | ||||||
| 
 | 
 | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => (assignmentsQueryKey(cid!, f))), |         queryKey: computed(() => assignmentsQueryKey(cid!, f)), | ||||||
|         queryFn: async () => new AssignmentController(cid!).getAll(f), |         queryFn: async () => new AssignmentController(cid!).getAll(f), | ||||||
|         enabled: () => checkEnabled(cid, 1, 1), |         enabled: () => checkEnabled(cid, 1, 1), | ||||||
|     }); |     }); | ||||||
|  | @ -79,18 +85,28 @@ export function useAssignmentQuery( | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useCreateAssignmentMutation(): UseMutationReturnType<AssignmentResponse, Error, {cid: string, data: AssignmentDTO}, unknown> { | export function useCreateAssignmentMutation(): UseMutationReturnType< | ||||||
|  |     AssignmentResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; data: AssignmentDTO }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|         mutationFn: async ({ cid, data }) => new AssignmentController(cid).createAssignment(data), |         mutationFn: async ({ cid, data }) => new AssignmentController(cid).createAssignment(data), | ||||||
|         onSuccess: async (_) => { |         onSuccess: async (_) => { | ||||||
|             await queryClient.invalidateQueries({ queryKey: [ "assignments" ] }); |             await queryClient.invalidateQueries({ queryKey: ["assignments"] }); | ||||||
|         }, |         }, | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useDeleteAssignmentMutation(): UseMutationReturnType<AssignmentResponse, Error, {cid: string, an: number}, unknown> { | export function useDeleteAssignmentMutation(): UseMutationReturnType< | ||||||
|  |     AssignmentResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; an: number }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|  | @ -106,7 +122,12 @@ export function useDeleteAssignmentMutation(): UseMutationReturnType<AssignmentR | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useUpdateAssignmentMutation(): UseMutationReturnType<AssignmentResponse, Error, {cid: string, an: number, data: Partial<AssignmentDTO>}, unknown> { | export function useUpdateAssignmentMutation(): UseMutationReturnType< | ||||||
|  |     AssignmentResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; an: number; data: Partial<AssignmentDTO> }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|  | @ -116,7 +137,7 @@ export function useUpdateAssignmentMutation(): UseMutationReturnType<AssignmentR | ||||||
|             const an = response.assignment.id; |             const an = response.assignment.id; | ||||||
| 
 | 
 | ||||||
|             await invalidateAllGroupKeys(queryClient, cid, an); |             await invalidateAllGroupKeys(queryClient, cid, an); | ||||||
|             await queryClient.invalidateQueries({ queryKey: [ "assignments" ] }); |             await queryClient.invalidateQueries({ queryKey: ["assignments"] }); | ||||||
|         }, |         }, | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,7 +1,14 @@ | ||||||
| import { ClassController, type ClassesResponse, type ClassResponse } from "@/controllers/classes"; | import { ClassController, type ClassesResponse, type ClassResponse } from "@/controllers/classes"; | ||||||
| import type { StudentsResponse } from "@/controllers/students"; | import type { StudentsResponse } from "@/controllers/students"; | ||||||
| import type { ClassDTO } from "@dwengo-1/common/interfaces/class"; | import type { ClassDTO } from "@dwengo-1/common/interfaces/class"; | ||||||
| import { QueryClient, useMutation, useQuery, useQueryClient, type UseMutationReturnType, type UseQueryReturnType } from "@tanstack/vue-query"; | import { | ||||||
|  |     QueryClient, | ||||||
|  |     useMutation, | ||||||
|  |     useQuery, | ||||||
|  |     useQueryClient, | ||||||
|  |     type UseMutationReturnType, | ||||||
|  |     type UseQueryReturnType, | ||||||
|  | } from "@tanstack/vue-query"; | ||||||
| import { computed, toValue, type MaybeRefOrGetter } from "vue"; | import { computed, toValue, type MaybeRefOrGetter } from "vue"; | ||||||
| import { invalidateAllAssignmentKeys } from "./assignments"; | import { invalidateAllAssignmentKeys } from "./assignments"; | ||||||
| import { invalidateAllGroupKeys } from "./groups"; | import { invalidateAllGroupKeys } from "./groups"; | ||||||
|  | @ -30,33 +37,25 @@ function classAssignmentsKey(classid: string, full: boolean) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function invalidateAllClassKeys(queryClient: QueryClient, classid?: string) { | export async function invalidateAllClassKeys(queryClient: QueryClient, classid?: string) { | ||||||
|     const keys = [ |     const keys = ["class", "class-students", "class-teachers", "class-teacher-invitations", "class-assignments"]; | ||||||
|         "class", |  | ||||||
|         "class-students", |  | ||||||
|         "class-teachers", |  | ||||||
|         "class-teacher-invitations", |  | ||||||
|         "class-assignments", |  | ||||||
|     ]; |  | ||||||
| 
 | 
 | ||||||
|     for (let key of keys) { |     for (const key of keys) { | ||||||
|         const queryKey = [key, classid].filter(arg => arg !== undefined); |         const queryKey = [key, classid].filter((arg) => arg !== undefined); | ||||||
|         await queryClient.invalidateQueries({ queryKey: queryKey }); |         await queryClient.invalidateQueries({ queryKey: queryKey }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     await queryClient.invalidateQueries({ queryKey: [ "classes" ] }); |     await queryClient.invalidateQueries({ queryKey: ["classes"] }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Queries */ | /* Queries */ | ||||||
| export function useClassesQuery(full: MaybeRefOrGetter<boolean> = true): UseQueryReturnType<ClassesResponse, Error> { | export function useClassesQuery(full: MaybeRefOrGetter<boolean> = true): UseQueryReturnType<ClassesResponse, Error> { | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => (classesQueryKey(toValue(full)))), |         queryKey: computed(() => classesQueryKey(toValue(full))), | ||||||
|         queryFn: async () => classController.getAll(toValue(full)), |         queryFn: async () => classController.getAll(toValue(full)), | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useClassQuery( | export function useClassQuery(id: MaybeRefOrGetter<string | undefined>): UseQueryReturnType<ClassResponse, Error> { | ||||||
|     id: MaybeRefOrGetter<string | undefined>, |  | ||||||
| ): UseQueryReturnType<ClassResponse, Error> { |  | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => classQueryKey(toValue(id)!)), |         queryKey: computed(() => classQueryKey(toValue(id)!)), | ||||||
|         queryFn: async () => classController.getById(toValue(id)!), |         queryFn: async () => classController.getById(toValue(id)!), | ||||||
|  | @ -70,7 +69,7 @@ export function useCreateClassMutation(): UseMutationReturnType<ClassResponse, E | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|         mutationFn: async (data) => classController.createClass(data), |         mutationFn: async (data) => classController.createClass(data), | ||||||
|         onSuccess: async () => { |         onSuccess: async () => { | ||||||
|             await queryClient.invalidateQueries({ queryKey: [ "classes" ] }); |             await queryClient.invalidateQueries({ queryKey: ["classes"] }); | ||||||
|         }, |         }, | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  | @ -89,7 +88,12 @@ export function useDeleteClassMutation(): UseMutationReturnType<ClassResponse, E | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useUpdateClassMutation(): UseMutationReturnType<ClassResponse, Error, {cid: string, data: Partial<ClassDTO>}, unknown> { | export function useUpdateClassMutation(): UseMutationReturnType< | ||||||
|  |     ClassResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; data: Partial<ClassDTO> }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|  | @ -105,16 +109,21 @@ export function useUpdateClassMutation(): UseMutationReturnType<ClassResponse, E | ||||||
| 
 | 
 | ||||||
| export function useClassStudentsQuery( | export function useClassStudentsQuery( | ||||||
|     id: MaybeRefOrGetter<string | undefined>, |     id: MaybeRefOrGetter<string | undefined>, | ||||||
|     full: MaybeRefOrGetter<boolean> = true |     full: MaybeRefOrGetter<boolean> = true, | ||||||
| ): UseQueryReturnType<StudentsResponse, Error> { | ): UseQueryReturnType<StudentsResponse, Error> { | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => classStudentsKey(toValue(id)!, toValue(full))), |         queryKey: computed(() => classStudentsKey(toValue(id)!, toValue(full))), | ||||||
|         queryFn: async () => classController.getStudents(toValue(id)!, toValue(full)!), |         queryFn: async () => classController.getStudents(toValue(id)!, toValue(full)), | ||||||
|         enabled: () => Boolean(toValue(id)), |         enabled: () => Boolean(toValue(id)), | ||||||
|     }) |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useClassAddStudentMutation(): UseMutationReturnType<ClassResponse, Error, {id: string, username: string}, unknown> { | export function useClassAddStudentMutation(): UseMutationReturnType< | ||||||
|  |     ClassResponse, | ||||||
|  |     Error, | ||||||
|  |     { id: string; username: string }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|  | @ -127,7 +136,12 @@ export function useClassAddStudentMutation(): UseMutationReturnType<ClassRespons | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useClassDeleteStudentMutation(): UseMutationReturnType<ClassResponse, Error, {id: string, username: string}, unknown> { | export function useClassDeleteStudentMutation(): UseMutationReturnType< | ||||||
|  |     ClassResponse, | ||||||
|  |     Error, | ||||||
|  |     { id: string; username: string }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|  | @ -142,16 +156,21 @@ export function useClassDeleteStudentMutation(): UseMutationReturnType<ClassResp | ||||||
| 
 | 
 | ||||||
| export function useClassTeachersQuery( | export function useClassTeachersQuery( | ||||||
|     id: MaybeRefOrGetter<string | undefined>, |     id: MaybeRefOrGetter<string | undefined>, | ||||||
|     full: MaybeRefOrGetter<boolean> = true |     full: MaybeRefOrGetter<boolean> = true, | ||||||
| ): UseQueryReturnType<StudentsResponse, Error> { | ): UseQueryReturnType<StudentsResponse, Error> { | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => classTeachersKey(toValue(id)!, toValue(full))), |         queryKey: computed(() => classTeachersKey(toValue(id)!, toValue(full))), | ||||||
|         queryFn: async () => classController.getTeachers(toValue(id)!, toValue(full)!), |         queryFn: async () => classController.getTeachers(toValue(id)!, toValue(full)), | ||||||
|         enabled: () => Boolean(toValue(id)), |         enabled: () => Boolean(toValue(id)), | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useClassAddTeacherMutation(): UseMutationReturnType<ClassResponse, Error, {id: string, username: string}, unknown> { | export function useClassAddTeacherMutation(): UseMutationReturnType< | ||||||
|  |     ClassResponse, | ||||||
|  |     Error, | ||||||
|  |     { id: string; username: string }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|  | @ -164,7 +183,12 @@ export function useClassAddTeacherMutation(): UseMutationReturnType<ClassRespons | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useClassDeleteTeacherMutation(): UseMutationReturnType<ClassResponse, Error, {id: string, username: string}, unknown> { | export function useClassDeleteTeacherMutation(): UseMutationReturnType< | ||||||
|  |     ClassResponse, | ||||||
|  |     Error, | ||||||
|  |     { id: string; username: string }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|  | @ -179,22 +203,22 @@ export function useClassDeleteTeacherMutation(): UseMutationReturnType<ClassResp | ||||||
| 
 | 
 | ||||||
| export function useClassTeacherInvitationsQuery( | export function useClassTeacherInvitationsQuery( | ||||||
|     id: MaybeRefOrGetter<string | undefined>, |     id: MaybeRefOrGetter<string | undefined>, | ||||||
|     full: MaybeRefOrGetter<boolean> = true |     full: MaybeRefOrGetter<boolean> = true, | ||||||
| ): UseQueryReturnType<StudentsResponse, Error> { | ): UseQueryReturnType<StudentsResponse, Error> { | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => classTeacherInvitationsKey(toValue(id)!, toValue(full))), |         queryKey: computed(() => classTeacherInvitationsKey(toValue(id)!, toValue(full))), | ||||||
|         queryFn: async () => classController.getTeacherInvitations(toValue(id)!, toValue(full)!), |         queryFn: async () => classController.getTeacherInvitations(toValue(id)!, toValue(full)), | ||||||
|         enabled: () => Boolean(toValue(id)), |         enabled: () => Boolean(toValue(id)), | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useClassAssignmentsQuery( | export function useClassAssignmentsQuery( | ||||||
|     id: MaybeRefOrGetter<string | undefined>, |     id: MaybeRefOrGetter<string | undefined>, | ||||||
|     full: MaybeRefOrGetter<boolean> = true |     full: MaybeRefOrGetter<boolean> = true, | ||||||
| ): UseQueryReturnType<StudentsResponse, Error> { | ): UseQueryReturnType<StudentsResponse, Error> { | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => classAssignmentsKey(toValue(id)!, toValue(full))), |         queryKey: computed(() => classAssignmentsKey(toValue(id)!, toValue(full))), | ||||||
|         queryFn: async () => classController.getAssignments(toValue(id)!, toValue(full)!), |         queryFn: async () => classController.getAssignments(toValue(id)!, toValue(full)), | ||||||
|         enabled: () => Boolean(toValue(id)), |         enabled: () => Boolean(toValue(id)), | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  | @ -3,22 +3,29 @@ import { GroupController, type GroupResponse, type GroupsResponse } from "@/cont | ||||||
| import type { QuestionsResponse } from "@/controllers/questions"; | import type { QuestionsResponse } from "@/controllers/questions"; | ||||||
| import type { SubmissionsResponse } from "@/controllers/submissions"; | import type { SubmissionsResponse } from "@/controllers/submissions"; | ||||||
| import type { GroupDTO } from "@dwengo-1/common/interfaces/group"; | import type { GroupDTO } from "@dwengo-1/common/interfaces/group"; | ||||||
| import { QueryClient, useMutation, useQuery, useQueryClient, type UseMutationReturnType, type UseQueryReturnType } from "@tanstack/vue-query"; | import { | ||||||
|  |     QueryClient, | ||||||
|  |     useMutation, | ||||||
|  |     useQuery, | ||||||
|  |     useQueryClient, | ||||||
|  |     type UseMutationReturnType, | ||||||
|  |     type UseQueryReturnType, | ||||||
|  | } from "@tanstack/vue-query"; | ||||||
| import { computed, toValue, type MaybeRefOrGetter } from "vue"; | import { computed, toValue, type MaybeRefOrGetter } from "vue"; | ||||||
| import { invalidateAllAssignmentKeys } from "./assignments"; | import { invalidateAllAssignmentKeys } from "./assignments"; | ||||||
| import { invalidateAllSubmissionKeys } from "./submissions"; | import { invalidateAllSubmissionKeys } from "./submissions"; | ||||||
| 
 | 
 | ||||||
| export function groupsQueryKey(classid: string, assignmentNumber: number, full: boolean) { | export function groupsQueryKey(classid: string, assignmentNumber: number, full: boolean) { | ||||||
|     return [ "groups", classid, assignmentNumber, full ]; |     return ["groups", classid, assignmentNumber, full]; | ||||||
| } | } | ||||||
| function groupQueryKey(classid: string, assignmentNumber: number, groupNumber: number) { | function groupQueryKey(classid: string, assignmentNumber: number, groupNumber: number) { | ||||||
|     return [ "group", classid, assignmentNumber, groupNumber ]; |     return ["group", classid, assignmentNumber, groupNumber]; | ||||||
| } | } | ||||||
| function groupSubmissionsQueryKey(classid: string, assignmentNumber: number, groupNumber: number, full: boolean) { | function groupSubmissionsQueryKey(classid: string, assignmentNumber: number, groupNumber: number, full: boolean) { | ||||||
|     return [ "group-submissions", classid, assignmentNumber, groupNumber, full ]; |     return ["group-submissions", classid, assignmentNumber, groupNumber, full]; | ||||||
| } | } | ||||||
| function groupQuestionsQueryKey(classid: string, assignmentNumber: number, groupNumber: number, full: boolean) { | function groupQuestionsQueryKey(classid: string, assignmentNumber: number, groupNumber: number, full: boolean) { | ||||||
|     return [ "group-questions", classid, assignmentNumber, groupNumber, full ]; |     return ["group-questions", classid, assignmentNumber, groupNumber, full]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function invalidateAllGroupKeys( | export async function invalidateAllGroupKeys( | ||||||
|  | @ -27,18 +34,16 @@ export async function invalidateAllGroupKeys( | ||||||
|     assignmentNumber?: number, |     assignmentNumber?: number, | ||||||
|     groupNumber?: number, |     groupNumber?: number, | ||||||
| ) { | ) { | ||||||
|     const keys = [ |     const keys = ["group", "group-submissions", "group-questions"]; | ||||||
|         "group", |  | ||||||
|         "group-submissions", |  | ||||||
|         "group-questions", |  | ||||||
|     ]; |  | ||||||
| 
 | 
 | ||||||
|     for (let key of keys) { |     for (const key of keys) { | ||||||
|         const queryKey = [key, classid, assignmentNumber, groupNumber].filter(arg => arg !== undefined); |         const queryKey = [key, classid, assignmentNumber, groupNumber].filter((arg) => arg !== undefined); | ||||||
|         await queryClient.invalidateQueries({ queryKey: queryKey }); |         await queryClient.invalidateQueries({ queryKey: queryKey }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     await queryClient.invalidateQueries({ queryKey: [ "groups", classid, assignmentNumber ].filter(arg => arg !== undefined) }); |     await queryClient.invalidateQueries({ | ||||||
|  |         queryKey: ["groups", classid, assignmentNumber].filter((arg) => arg !== undefined), | ||||||
|  |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function checkEnabled( | function checkEnabled( | ||||||
|  | @ -65,7 +70,7 @@ export function useGroupsQuery( | ||||||
|     const { cid, an, f } = toValues(classid, assignmentNumber, 1, full); |     const { cid, an, f } = toValues(classid, assignmentNumber, 1, full); | ||||||
| 
 | 
 | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => (groupsQueryKey(cid!, an!, f))), |         queryKey: computed(() => groupsQueryKey(cid!, an!, f)), | ||||||
|         queryFn: async () => new GroupController(cid!, an!).getAll(f), |         queryFn: async () => new GroupController(cid!, an!).getAll(f), | ||||||
|         enabled: () => checkEnabled(cid, an, 1), |         enabled: () => checkEnabled(cid, an, 1), | ||||||
|     }); |     }); | ||||||
|  | @ -85,14 +90,22 @@ export function useGroupQuery( | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useCreateGroupMutation(): UseMutationReturnType<GroupResponse, Error, {cid: string, an: number, data: GroupDTO}, unknown> { | export function useCreateGroupMutation(): UseMutationReturnType< | ||||||
|  |     GroupResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; an: number; data: GroupDTO }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|         mutationFn: async ({ cid, an, data }) => new GroupController(cid, an).createGroup(data), |         mutationFn: async ({ cid, an, data }) => new GroupController(cid, an).createGroup(data), | ||||||
|         onSuccess: async (response) => { |         onSuccess: async (response) => { | ||||||
|             const cid = typeof(response.group.class) === 'string' ? response.group.class : response.group.class.id; |             const cid = typeof response.group.class === "string" ? response.group.class : response.group.class.id; | ||||||
|             const an = typeof(response.group.assignment) === 'number' ? response.group.assignment : response.group.assignment.id; |             const an = | ||||||
|  |                 typeof response.group.assignment === "number" | ||||||
|  |                     ? response.group.assignment | ||||||
|  |                     : response.group.assignment.id; | ||||||
| 
 | 
 | ||||||
|             await queryClient.invalidateQueries({ queryKey: groupsQueryKey(cid, an, true) }); |             await queryClient.invalidateQueries({ queryKey: groupsQueryKey(cid, an, true) }); | ||||||
|             await queryClient.invalidateQueries({ queryKey: groupsQueryKey(cid, an, false) }); |             await queryClient.invalidateQueries({ queryKey: groupsQueryKey(cid, an, false) }); | ||||||
|  | @ -100,14 +113,22 @@ export function useCreateGroupMutation(): UseMutationReturnType<GroupResponse, E | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useDeleteGroupMutation(): UseMutationReturnType<GroupResponse, Error, {cid: string, an: number, gn: number}, unknown> { | export function useDeleteGroupMutation(): UseMutationReturnType< | ||||||
|  |     GroupResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; an: number; gn: number }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|         mutationFn: async ({cid, an, gn}) => new GroupController(cid, an).deleteGroup(gn), |         mutationFn: async ({ cid, an, gn }) => new GroupController(cid, an).deleteGroup(gn), | ||||||
|         onSuccess: async (response) => { |         onSuccess: async (response) => { | ||||||
|             const cid = typeof(response.group.class) === 'string' ? response.group.class : response.group.class.id; |             const cid = typeof response.group.class === "string" ? response.group.class : response.group.class.id; | ||||||
|             const an = typeof(response.group.assignment) === 'number' ? response.group.assignment : response.group.assignment.id; |             const an = | ||||||
|  |                 typeof response.group.assignment === "number" | ||||||
|  |                     ? response.group.assignment | ||||||
|  |                     : response.group.assignment.id; | ||||||
|             const gn = response.group.groupNumber; |             const gn = response.group.groupNumber; | ||||||
| 
 | 
 | ||||||
|             await invalidateAllGroupKeys(queryClient, cid, an, gn); |             await invalidateAllGroupKeys(queryClient, cid, an, gn); | ||||||
|  | @ -116,14 +137,22 @@ export function useDeleteGroupMutation(): UseMutationReturnType<GroupResponse, E | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useUpdateGroupMutation(): UseMutationReturnType<GroupResponse, Error, {cid: string, an: number, gn: number, data: Partial<GroupDTO>}, unknown> { | export function useUpdateGroupMutation(): UseMutationReturnType< | ||||||
|  |     GroupResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; an: number; gn: number; data: Partial<GroupDTO> }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|         mutationFn: async ({cid, an, gn, data}) => new GroupController(cid, an).updateGroup(gn, data), |         mutationFn: async ({ cid, an, gn, data }) => new GroupController(cid, an).updateGroup(gn, data), | ||||||
|         onSuccess: async (response) => { |         onSuccess: async (response) => { | ||||||
|             const cid = typeof(response.group.class) === 'string' ? response.group.class : response.group.class.id; |             const cid = typeof response.group.class === "string" ? response.group.class : response.group.class.id; | ||||||
|             const an = typeof(response.group.assignment) === 'number' ? response.group.assignment : response.group.assignment.id; |             const an = | ||||||
|  |                 typeof response.group.assignment === "number" | ||||||
|  |                     ? response.group.assignment | ||||||
|  |                     : response.group.assignment.id; | ||||||
|             const gn = response.group.groupNumber; |             const gn = response.group.groupNumber; | ||||||
| 
 | 
 | ||||||
|             await invalidateAllGroupKeys(queryClient, cid, an, gn); |             await invalidateAllGroupKeys(queryClient, cid, an, gn); | ||||||
|  |  | ||||||
|  | @ -1,13 +1,20 @@ | ||||||
| import { SubmissionController, type SubmissionResponse, type SubmissionsResponse } from "@/controllers/submissions"; | import { SubmissionController, type SubmissionResponse, type SubmissionsResponse } from "@/controllers/submissions"; | ||||||
| import type { SubmissionDTO } from "@dwengo-1/common/interfaces/submission"; | import type { SubmissionDTO } from "@dwengo-1/common/interfaces/submission"; | ||||||
| import { QueryClient, useMutation, useQuery, useQueryClient, type UseMutationReturnType, type UseQueryReturnType } from "@tanstack/vue-query"; | import { | ||||||
|  |     QueryClient, | ||||||
|  |     useMutation, | ||||||
|  |     useQuery, | ||||||
|  |     useQueryClient, | ||||||
|  |     type UseMutationReturnType, | ||||||
|  |     type UseQueryReturnType, | ||||||
|  | } from "@tanstack/vue-query"; | ||||||
| import { computed, toValue, type MaybeRefOrGetter } from "vue"; | import { computed, toValue, type MaybeRefOrGetter } from "vue"; | ||||||
| 
 | 
 | ||||||
| function submissionsQueryKey(classid: string, assignmentNumber: number, groupNumber: number, full: boolean) { | function submissionsQueryKey(classid: string, assignmentNumber: number, groupNumber: number, full: boolean) { | ||||||
|     return [ "submissions", classid, assignmentNumber, groupNumber, full ]; |     return ["submissions", classid, assignmentNumber, groupNumber, full]; | ||||||
| } | } | ||||||
| function submissionQueryKey(classid: string, assignmentNumber: number, groupNumber: number, submissionNumber: number) { | function submissionQueryKey(classid: string, assignmentNumber: number, groupNumber: number, submissionNumber: number) { | ||||||
|     return [ "submission", classid, assignmentNumber, groupNumber, submissionNumber ]; |     return ["submission", classid, assignmentNumber, groupNumber, submissionNumber]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function invalidateAllSubmissionKeys( | export async function invalidateAllSubmissionKeys( | ||||||
|  | @ -17,30 +24,38 @@ export async function invalidateAllSubmissionKeys( | ||||||
|     groupNumber?: number, |     groupNumber?: number, | ||||||
|     submissionNumber?: number, |     submissionNumber?: number, | ||||||
| ) { | ) { | ||||||
|     const keys = [ |     const keys = ["submission"]; | ||||||
|         "submission", |  | ||||||
|     ]; |  | ||||||
| 
 | 
 | ||||||
|     for (let key of keys) { |     for (const key of keys) { | ||||||
|         const queryKey = [key, classid, assignmentNumber, groupNumber, submissionNumber].filter(arg => arg !== undefined); |         const queryKey = [key, classid, assignmentNumber, groupNumber, submissionNumber].filter( | ||||||
|  |             (arg) => arg !== undefined, | ||||||
|  |         ); | ||||||
|         await queryClient.invalidateQueries({ queryKey: queryKey }); |         await queryClient.invalidateQueries({ queryKey: queryKey }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     await queryClient.invalidateQueries({ queryKey: [ "submissions", classid, assignmentNumber, groupNumber ].filter(arg => arg !== undefined) }); |     await queryClient.invalidateQueries({ | ||||||
|     await queryClient.invalidateQueries({ queryKey: [ "group-submissions", classid, assignmentNumber, groupNumber ].filter(arg => arg !== undefined) }); |         queryKey: ["submissions", classid, assignmentNumber, groupNumber].filter((arg) => arg !== undefined), | ||||||
|     await queryClient.invalidateQueries({ queryKey: [ "assignment-submissions", classid, assignmentNumber ].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( | function checkEnabled( | ||||||
|     classid: string | undefined, |     classid: string | undefined, | ||||||
|     assignmentNumber: number | undefined, |     assignmentNumber: number | undefined, | ||||||
|     groupNumber: number | undefined, |     groupNumber: number | undefined, | ||||||
|     submissionNumber: number | undefined |     submissionNumber: number | undefined, | ||||||
| ): boolean { | ): boolean { | ||||||
|     return  Boolean(classid)  |     return ( | ||||||
|         && !isNaN(Number(groupNumber))  |         Boolean(classid) && | ||||||
|         && !isNaN(Number(assignmentNumber)) |         !isNaN(Number(groupNumber)) && | ||||||
|         && !isNaN(Number(submissionNumber)); |         !isNaN(Number(assignmentNumber)) && | ||||||
|  |         !isNaN(Number(submissionNumber)) | ||||||
|  |     ); | ||||||
| } | } | ||||||
| function toValues( | function toValues( | ||||||
|     classid: MaybeRefOrGetter<string | undefined>, |     classid: MaybeRefOrGetter<string | undefined>, | ||||||
|  | @ -54,7 +69,7 @@ function toValues( | ||||||
|         an: toValue(assignmentNumber), |         an: toValue(assignmentNumber), | ||||||
|         gn: toValue(groupNumber), |         gn: toValue(groupNumber), | ||||||
|         sn: toValue(submissionNumber), |         sn: toValue(submissionNumber), | ||||||
|         f: toValue(full)  |         f: toValue(full), | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -67,7 +82,7 @@ export function useSubmissionsQuery( | ||||||
|     const { cid, an, gn, sn, f } = toValues(classid, assignmentNumber, groupNumber, 1, full); |     const { cid, an, gn, sn, f } = toValues(classid, assignmentNumber, groupNumber, 1, full); | ||||||
| 
 | 
 | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => (submissionsQueryKey(cid!, an!, gn!, f))), |         queryKey: computed(() => submissionsQueryKey(cid!, an!, gn!, f)), | ||||||
|         queryFn: async () => new SubmissionController(cid!, an!, gn!).getAll(f), |         queryFn: async () => new SubmissionController(cid!, an!, gn!).getAll(f), | ||||||
|         enabled: () => checkEnabled(cid, an, gn, sn), |         enabled: () => checkEnabled(cid, an, gn, sn), | ||||||
|     }); |     }); | ||||||
|  | @ -87,11 +102,16 @@ export function useSubmissionQuery( | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useCreateSubmissionMutation(): UseMutationReturnType<SubmissionResponse, Error, {cid: string, an: number, gn: number, data: SubmissionDTO}, unknown> { | export function useCreateSubmissionMutation(): UseMutationReturnType< | ||||||
|  |     SubmissionResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; an: number; gn: number; data: SubmissionDTO }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|         mutationFn: async ({cid, an, gn, data}) => new SubmissionController(cid, an, gn).createSubmission(data), |         mutationFn: async ({ cid, an, gn, data }) => new SubmissionController(cid, an, gn).createSubmission(data), | ||||||
|         onSuccess: async (response) => { |         onSuccess: async (response) => { | ||||||
|             if (!response.submission.group) { |             if (!response.submission.group) { | ||||||
|                 await invalidateAllSubmissionKeys(queryClient); |                 await invalidateAllSubmissionKeys(queryClient); | ||||||
|  | @ -99,8 +119,8 @@ export function useCreateSubmissionMutation(): UseMutationReturnType<SubmissionR | ||||||
|                 const cls = response.submission.group.class; |                 const cls = response.submission.group.class; | ||||||
|                 const assignment = response.submission.group.assignment; |                 const assignment = response.submission.group.assignment; | ||||||
| 
 | 
 | ||||||
|                 const cid = typeof(cls) === 'string' ? cls : cls.id; |                 const cid = typeof cls === "string" ? cls : cls.id; | ||||||
|                 const an = typeof(assignment) === 'number' ? assignment : assignment.id; |                 const an = typeof assignment === "number" ? assignment : assignment.id; | ||||||
|                 const gn = response.submission.group.groupNumber; |                 const gn = response.submission.group.groupNumber; | ||||||
| 
 | 
 | ||||||
|                 await invalidateAllSubmissionKeys(queryClient, cid, an, gn); |                 await invalidateAllSubmissionKeys(queryClient, cid, an, gn); | ||||||
|  | @ -109,11 +129,16 @@ export function useCreateSubmissionMutation(): UseMutationReturnType<SubmissionR | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function useDeleteSubmissionMutation(): UseMutationReturnType<SubmissionResponse, Error, {cid: string, an: number, gn: number, sn: number}, unknown> { | export function useDeleteSubmissionMutation(): UseMutationReturnType< | ||||||
|  |     SubmissionResponse, | ||||||
|  |     Error, | ||||||
|  |     { cid: string; an: number; gn: number; sn: number }, | ||||||
|  |     unknown | ||||||
|  | > { | ||||||
|     const queryClient = useQueryClient(); |     const queryClient = useQueryClient(); | ||||||
| 
 | 
 | ||||||
|     return useMutation({ |     return useMutation({ | ||||||
|         mutationFn: async ({cid, an, gn, sn}) => new SubmissionController(cid, an, gn).deleteSubmission(sn), |         mutationFn: async ({ cid, an, gn, sn }) => new SubmissionController(cid, an, gn).deleteSubmission(sn), | ||||||
|         onSuccess: async (response) => { |         onSuccess: async (response) => { | ||||||
|             if (!response.submission.group) { |             if (!response.submission.group) { | ||||||
|                 await invalidateAllSubmissionKeys(queryClient); |                 await invalidateAllSubmissionKeys(queryClient); | ||||||
|  | @ -121,8 +146,8 @@ export function useDeleteSubmissionMutation(): UseMutationReturnType<SubmissionR | ||||||
|                 const cls = response.submission.group.class; |                 const cls = response.submission.group.class; | ||||||
|                 const assignment = response.submission.group.assignment; |                 const assignment = response.submission.group.assignment; | ||||||
| 
 | 
 | ||||||
|                 const cid = typeof(cls) === 'string' ? cls : cls.id; |                 const cid = typeof cls === "string" ? cls : cls.id; | ||||||
|                 const an = typeof(assignment) === 'number' ? assignment : assignment.id; |                 const an = typeof assignment === "number" ? assignment : assignment.id; | ||||||
|                 const gn = response.submission.group.groupNumber; |                 const gn = response.submission.group.groupNumber; | ||||||
| 
 | 
 | ||||||
|                 await invalidateAllSubmissionKeys(queryClient, cid, an, gn); |                 await invalidateAllSubmissionKeys(queryClient, cid, an, gn); | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Adriaan Jacquet
						Adriaan Jacquet