From 7bee08537a67f0a10863d1d21a4b2b807cb999d8 Mon Sep 17 00:00:00 2001 From: Adriaan Jacquet Date: Sun, 13 Apr 2025 14:37:29 +0200 Subject: [PATCH] fix/refactor: cache keys gefixt, useMutation argumenten rerefactord --- frontend/src/queries/assignments.ts | 77 ++++++++++++++--------------- frontend/src/queries/classes.ts | 38 +++++++++----- frontend/src/queries/groups.ts | 22 ++++++++- frontend/src/queries/submissions.ts | 21 +++++++- 4 files changed, 104 insertions(+), 54 deletions(-) diff --git a/frontend/src/queries/assignments.ts b/frontend/src/queries/assignments.ts index e3bf6d39..ddfe0bc4 100644 --- a/frontend/src/queries/assignments.ts +++ b/frontend/src/queries/assignments.ts @@ -3,9 +3,11 @@ import type { QuestionsResponse } from "@/controllers/questions"; import type { SubmissionsResponse } from "@/controllers/submissions"; import { useMutation, useQuery, useQueryClient, type UseMutationReturnType, type UseQueryReturnType } from "@tanstack/vue-query"; import { computed, toValue, type MaybeRefOrGetter } from "vue"; -import { groupsQueryKey } from "./groups"; +import { groupsQueryKey, invalidateAllGroupKeys } from "./groups"; import type { GroupsResponse } from "@/controllers/groups"; import type { AssignmentDTO } from "@dwengo-1/common/interfaces/assignment"; +import type { QueryClient } from "@tanstack/react-query"; +import { invalidateAllSubmissionKeys } from "./submissions"; function assignmentsQueryKey(classid: string, full: boolean) { return [ "assignments", classid, full ]; @@ -20,6 +22,21 @@ function assignmentQuestionsQueryKey(classid: string, assignmentNumber: number, return [ "assignment-questions", classid, assignmentNumber, full ]; } +export async function invalidateAllAssignmentKeys(queryClient: QueryClient, classid?: string, assignmentNumber?: number) { + const keys = [ + "assignment", + "assignment-submissions", + "assignment-questions", + ]; + + for (let key of keys) { + const queryKey = [key, classid, assignmentNumber].filter(arg => arg !== undefined); + await queryClient.invalidateQueries({ queryKey: queryKey }); + } + + await queryClient.invalidateQueries({ queryKey: [ "assignments", classid ].filter(arg => arg !== undefined) }); +} + function checkEnabled( classid: string | undefined, assignmentNumber: number | undefined, @@ -62,64 +79,44 @@ export function useAssignmentQuery( }); } -export function useCreateAssignmentMutation( - classid: MaybeRefOrGetter, -): UseMutationReturnType { +export function useCreateAssignmentMutation(): UseMutationReturnType { const queryClient = useQueryClient(); - const { cid } = toValues(classid, 1, 1, true); return useMutation({ - mutationFn: async (data) => new AssignmentController(cid!).createAssignment(data), - onSuccess: async () => { - await queryClient.invalidateQueries({ queryKey: assignmentsQueryKey(cid!, true) }); - await queryClient.invalidateQueries({ queryKey: assignmentsQueryKey(cid!, false) }); + mutationFn: async ({ cid, data }) => new AssignmentController(cid).createAssignment(data), + onSuccess: async (_) => { + await queryClient.invalidateQueries({ queryKey: [ "assignments" ] }); }, }); } -export function useDeleteAssignmentMutation( - classid: MaybeRefOrGetter, - assignmentNumber: MaybeRefOrGetter, -): UseMutationReturnType { +export function useDeleteAssignmentMutation(): UseMutationReturnType { const queryClient = useQueryClient(); - const { cid, an } = toValues(classid, assignmentNumber, 1, true); return useMutation({ - mutationFn: async (id) => new AssignmentController(cid!).deleteAssignment(id), - onSuccess: async () => { - await queryClient.invalidateQueries({ queryKey: assignmentQueryKey(cid!, an!) }); + mutationFn: async ({ cid, an }) => new AssignmentController(cid).deleteAssignment(an), + onSuccess: async (response) => { + const cid = response.assignment.within; + const an = response.assignment.id; - await queryClient.invalidateQueries({ queryKey: assignmentsQueryKey(cid!, true) }); - await queryClient.invalidateQueries({ queryKey: assignmentsQueryKey(cid!, false) }); - - await queryClient.invalidateQueries({ queryKey: assignmentSubmissionsQueryKey(cid!, an!, true) }); - await queryClient.invalidateQueries({ queryKey: assignmentSubmissionsQueryKey(cid!, an!, false) }); - - await queryClient.invalidateQueries({ queryKey: assignmentQuestionsQueryKey(cid!, an!, false) }); - await queryClient.invalidateQueries({ queryKey: assignmentQuestionsQueryKey(cid!, an!, true) }); - - // should probably invalidate all groups related to assignment - await queryClient.invalidateQueries({ queryKey: groupsQueryKey(cid!, an!, false) }); - await queryClient.invalidateQueries({ queryKey: groupsQueryKey(cid!, an!, true) }); + await invalidateAllAssignmentKeys(queryClient, cid, an); + await invalidateAllGroupKeys(queryClient, cid, an); + await invalidateAllSubmissionKeys(queryClient, cid, an); }, }); } -export function useUpdateAssignmentMutation( - classid: MaybeRefOrGetter, - assignmentNumber: MaybeRefOrGetter, -): UseMutationReturnType, unknown> { +export function useUpdateAssignmentMutation(): UseMutationReturnType}, unknown> { const queryClient = useQueryClient(); - const { cid, an } = toValues(classid, assignmentNumber, 1, true); return useMutation({ - mutationFn: async (data) => new AssignmentController(cid!).updateAssignment(an!, data), - onSuccess: async () => { - await queryClient.invalidateQueries({ queryKey: groupsQueryKey(cid!, an!, true) }); - await queryClient.invalidateQueries({ queryKey: groupsQueryKey(cid!, an!, false) }); + mutationFn: async ({ cid, an, data }) => new AssignmentController(cid).updateAssignment(an, data), + onSuccess: async (response) => { + const cid = response.assignment.within; + const an = response.assignment.id; - await queryClient.invalidateQueries({ queryKey: assignmentsQueryKey(cid!, true) }); - await queryClient.invalidateQueries({ queryKey: assignmentsQueryKey(cid!, false) }); + await invalidateAllGroupKeys(queryClient, cid, an); + await queryClient.invalidateQueries({ queryKey: [ "assignments" ] }); }, }); } diff --git a/frontend/src/queries/classes.ts b/frontend/src/queries/classes.ts index 4faf5b19..a6d1c157 100644 --- a/frontend/src/queries/classes.ts +++ b/frontend/src/queries/classes.ts @@ -3,6 +3,9 @@ import type { StudentsResponse } from "@/controllers/students"; import type { ClassDTO } from "@dwengo-1/common/interfaces/class"; import { QueryClient, useMutation, useQuery, useQueryClient, type UseMutationReturnType, type UseQueryReturnType } from "@tanstack/vue-query"; import { computed, toValue, type MaybeRefOrGetter } from "vue"; +import { invalidateAllAssignmentKeys } from "./assignments"; +import { invalidateAllGroupKeys } from "./groups"; +import { invalidateAllSubmissionKeys } from "./submissions"; const classController = new ClassController(); @@ -23,19 +26,24 @@ function classTeacherInvitationsKey(classid: string, full: boolean) { return ["class-teacher-invitations", classid, full]; } function classAssignmentsKey(classid: string, full: boolean) { - return ["class-assignments", classid]; + return ["class-assignments", classid, full]; } -/* Function to invalidate all caches with certain class id */ -async function invalidateAll(classid: string, queryClient: QueryClient): Promise { - await queryClient.invalidateQueries({ queryKey: ["classes"] }); - await queryClient.invalidateQueries({ queryKey: classQueryKey(classid) }); - for (let v of [true, false]) { - await queryClient.invalidateQueries({ queryKey: classStudentsKey(classid, v) }); - await queryClient.invalidateQueries({ queryKey: classTeachersKey(classid, v) }); - await queryClient.invalidateQueries({ queryKey: classAssignmentsKey(classid, v) }); - await queryClient.invalidateQueries({ queryKey: classTeacherInvitationsKey(classid, v) }); +export async function invalidateAllClassKeys(queryClient: QueryClient, classid?: string) { + const keys = [ + "class", + "class-students", + "class-teachers", + "class-teacher-invitations", + "class-assignments", + ]; + + for (let key of keys) { + const queryKey = [key, classid].filter(arg => arg !== undefined); + await queryClient.invalidateQueries({ queryKey: queryKey }); } + + await queryClient.invalidateQueries({ queryKey: [ "classes" ] }); } /* Queries */ @@ -74,7 +82,10 @@ export function useDeleteClassMutation(): UseMutationReturnType classController.deleteClass(id), onSuccess: async (data) => { - await invalidateAll(data.class.id, queryClient); + await invalidateAllClassKeys(queryClient, data.class.id); + await invalidateAllAssignmentKeys(queryClient, data.class.id); + await invalidateAllGroupKeys(queryClient, data.class.id); + await invalidateAllSubmissionKeys(queryClient, data.class.id); }, }); } @@ -85,7 +96,10 @@ export function useUpdateClassMutation(): UseMutationReturnType classController.updateClass(data.id, data), onSuccess: async (data) => { - await invalidateAll(data.class.id, queryClient); + await invalidateAllClassKeys(queryClient, data.class.id); + await invalidateAllAssignmentKeys(queryClient, data.class.id); + await invalidateAllGroupKeys(queryClient, data.class.id); + await invalidateAllSubmissionKeys(queryClient, data.class.id); }, }); } diff --git a/frontend/src/queries/groups.ts b/frontend/src/queries/groups.ts index 50a5d92a..37270953 100644 --- a/frontend/src/queries/groups.ts +++ b/frontend/src/queries/groups.ts @@ -3,7 +3,7 @@ import { GroupController, type GroupResponse, type GroupsResponse } from "@/cont import type { QuestionsResponse } from "@/controllers/questions"; import type { SubmissionsResponse } from "@/controllers/submissions"; import type { GroupDTO } from "@dwengo-1/common/interfaces/group"; -import { 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"; export function groupsQueryKey(classid: string, assignmentNumber: number, full: boolean) { @@ -19,6 +19,26 @@ function groupQuestionsQueryKey(classid: string, assignmentNumber: number, group return [ "group-questions", classid, assignmentNumber, groupNumber, full ]; } +export async function invalidateAllGroupKeys( + queryClient: QueryClient, + classid?: string, + assignmentNumber?: number, + groupNumber?: number, +) { + const keys = [ + "group", + "group-submissions", + "group-questions", + ]; + + for (let key of keys) { + const queryKey = [key, classid, assignmentNumber, groupNumber].filter(arg => arg !== undefined); + await queryClient.invalidateQueries({ queryKey: queryKey }); + } + + await queryClient.invalidateQueries({ queryKey: [ "groups", classid, assignmentNumber ].filter(arg => arg !== undefined) }); +} + function checkEnabled( classid: string | undefined, assignmentNumber: number | undefined, diff --git a/frontend/src/queries/submissions.ts b/frontend/src/queries/submissions.ts index 3a15f16e..5b8d5691 100644 --- a/frontend/src/queries/submissions.ts +++ b/frontend/src/queries/submissions.ts @@ -1,6 +1,6 @@ import { SubmissionController, type SubmissionResponse, type SubmissionsResponse } from "@/controllers/submissions"; import type { SubmissionDTO } from "@dwengo-1/common/interfaces/submission"; -import { 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"; function submissionsQueryKey(classid: string, assignmentNumber: number, groupNumber: number, full: boolean) { @@ -10,6 +10,25 @@ function submissionQueryKey(classid: string, assignmentNumber: number, groupNumb return [ "submission", classid, assignmentNumber, groupNumber, submissionNumber ]; } +export async function invalidateAllSubmissionKeys( + queryClient: QueryClient, + classid?: string, + assignmentNumber?: number, + groupNumber?: number, + submissionNumber?: number, +) { + const keys = [ + "submission", + ]; + + for (let 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) }); +} + function checkEnabled( classid: string | undefined, assignmentNumber: number | undefined,