diff --git a/components/projects/UserTable.vue b/components/projects/UserTable.vue index 539f4a6..2d366e9 100644 --- a/components/projects/UserTable.vue +++ b/components/projects/UserTable.vue @@ -3,7 +3,10 @@ - + - + + + + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+ + + +
+
+

Veuillez-confirmer pour supprimer.

+
+ +
+ + +
+
+
diff --git a/pages/projects/update/[id].vue b/pages/projects/update/[id].vue index 8fa068d..119d813 100644 --- a/pages/projects/update/[id].vue +++ b/pages/projects/update/[id].vue @@ -41,6 +41,8 @@ :model-value="members ?? []" :users-available="userList" @member-added="addMember" + @member-edited="updateMember" + @member-deleted="deleteMember" > @@ -112,6 +114,8 @@ const members: Ref< | undefined > = ref(); const newMembers: typeof members = ref([]); +const updatedMembers: typeof members = ref([]); +const deletedMembers: typeof members = ref([]); // Fetch data const loaded = ref(false); @@ -153,6 +157,22 @@ const addMember = ( newMembers.value?.push(member); }; +// Tracl members to update +const updateMember = ( + member: Exclude<(typeof members)["value"], undefined>[number] +) => { + updatedMembers.value?.push(member); +}; + +// Track members to delete +const deleteMember = ( + member: Exclude<(typeof members)["value"], undefined>[number] +) => { + deletedMembers.value?.push(member); +}; + +// Track members to delete + // Form validation const nameErrorMessage = ref(""); const membersErrorMessage = ref(""); @@ -196,6 +216,8 @@ const updateThisProject = async () => { userId: member.user.id, role: member.role, })) ?? [], + updateMembers: updatedMembers.value, + deleteMembers: deletedMembers.value, }); }; diff --git a/plugins/primevue.ts b/plugins/primevue.ts index 117bc4f..9f957c4 100644 --- a/plugins/primevue.ts +++ b/plugins/primevue.ts @@ -13,6 +13,7 @@ import DataTable from "primevue/datatable"; import Column from "primevue/column"; import Dialog from "primevue/dialog"; import Listbox from "primevue/listbox"; +import OverlayPanel from "primevue/overlaypanel"; import ToastService from "primevue/toastservice"; import Toast from "primevue/toast"; @@ -35,4 +36,5 @@ export default defineNuxtPlugin((nuxtApp) => { nuxtApp.vueApp.component("Column", Column); nuxtApp.vueApp.component("Dialog", Dialog); nuxtApp.vueApp.component("Listbox", Listbox); + nuxtApp.vueApp.component("OverlayPanel", OverlayPanel); }); diff --git a/server/api/projects/[id]/index.put.ts b/server/api/projects/[id]/index.put.ts index 3cb148c..513c6a9 100644 --- a/server/api/projects/[id]/index.put.ts +++ b/server/api/projects/[id]/index.put.ts @@ -1,3 +1,4 @@ +import { ProjectMember } from "@prisma/client"; import { prisma } from "~/server/plugins/prisma"; import { ProjectUpdateDTO } from "~/utils/server"; @@ -5,7 +6,7 @@ export default defineEventHandler(async (event) => { const id = event.context.params?.id; const body = await readBody(event); - let project = await prisma.project.findFirst({ + const project = await prisma.project.findFirst({ where: { id: Number(id), }, @@ -16,30 +17,58 @@ export default defineEventHandler(async (event) => { if (!project) throw new Error("Project not found"); - return await prisma.project.update({ - where: { - id: Number(id), - }, - data: { - name: body.name, - description: body.description, - color: body.color, - client: - body.client.length > 0 - ? { - connectOrCreate: { - where: { - name: body.client, - }, - create: { - name: body.client, + const idToDelete = body.deleteMembers?.map(member => member.id); + + return await prisma.$transaction(async (tx) => { + + const updatedProject = await tx.project.update({ + where: { + id: Number(id), + }, + data: { + name: body.name, + description: body.description, + color: body.color, + client: + body.client.length > 0 + ? { + connectOrCreate: { + where: { + name: body.client, + }, + create: { + name: body.client, + }, }, - }, - } - : undefined, - members: { - create: body.newMembers, + } + : undefined, + members: { + create: body.newMembers, + } + }, + }); + + const updatedMembers: Array | undefined = []; + for (let member of body.updateMembers ?? []) { + updatedMembers.push(await tx.projectMember.update({ + where: { + id: member.id, + }, + data: { + role: member.role, + } + })); + } + + await tx.projectMember.deleteMany({ + where: { + id: { + in: idToDelete, + } } - }, + } + ); + + return { updatedProject, updatedMembers }; }); }); diff --git a/utils/server.ts b/utils/server.ts index afb50c8..bbc9f26 100644 --- a/utils/server.ts +++ b/utils/server.ts @@ -157,10 +157,12 @@ export type ProjectUpdateDTO = { description: string; color: string; client: string; - newMembers: Array<{ + newMembers?: Array<{ userId: string, role: Exclude>, undefined>["members"][number]["role"] }>; + updateMembers?: Exclude>, undefined>["members"]; + deleteMembers?: Exclude>, undefined>["members"]; }; export const updateProject = async (id: number, project: ProjectUpdateDTO) => {