diff --git a/source/SIL.AppBuilder.Portal/src/routes/(authenticated)/projects/[filter=projectSelector]/[id]/+page.server.ts b/source/SIL.AppBuilder.Portal/src/routes/(authenticated)/projects/[filter=projectSelector]/[id]/+page.server.ts index fff1e931e..0b2644710 100644 --- a/source/SIL.AppBuilder.Portal/src/routes/(authenticated)/projects/[filter=projectSelector]/[id]/+page.server.ts +++ b/source/SIL.AppBuilder.Portal/src/routes/(authenticated)/projects/[filter=projectSelector]/[id]/+page.server.ts @@ -11,7 +11,7 @@ import type { PageServerLoad } from './$types'; const bulkProjectOperationSchema = v.object({ operation: v.nullable(v.picklist(['archive', 'reactivate'])), - projects: v.array(v.object({ Id: idSchema, OwnerId: idSchema, Archived: v.boolean() })) + projects: v.array(v.object({ Id: idSchema, OwnerId: idSchema, DateArchived: v.nullable(v.date()) })) }); function whereStatements( @@ -128,7 +128,7 @@ export const actions: Actions = { return { form, ok: true, query: { data: pruneProjects(projects), count } }; }, - archive: async (event) => { + bulkAction: async (event) => { const session = await event.locals.auth(); if (!session) return fail(403); const orgId = parseInt(event.params.id!); @@ -142,11 +142,11 @@ export const actions: Actions = { return fail(403); } - await Promise.all( - form.data.projects.map(async ({ Id }) => { + form.data.projects = await Promise.all( + form.data.projects.map(async (old) => { const project = await prisma.projects.findUnique({ where: { - Id: Id + Id: old.Id }, select: { Id: true, @@ -154,8 +154,9 @@ export const actions: Actions = { } }); if (form.data.operation === 'archive' && !project?.DateArchived) { - await DatabaseWrites.projects.update(Id, { - DateArchived: new Date() + const timestamp = new Date(); + await DatabaseWrites.projects.update(old.Id, { + DateArchived: timestamp }); /*await Queues.UserTasks.add(`Delete UserTasks for Archived Project #${Id}`, { type: BullMQ.JobType.UserTasks_Modify, @@ -165,8 +166,9 @@ export const actions: Actions = { type: BullMQ.UserTasks.OpType.Delete } });*/ - } else if (form.data.operation === 'reactivate' && !!project?.DateArchived) { - await DatabaseWrites.projects.update(Id, { + return { ...old, DateArchived: timestamp }; + } else if (form.data.operation === 'reactivate' && project?.DateArchived !== null) { + await DatabaseWrites.projects.update(old.Id, { DateArchived: null }); /*await Queues.UserTasks.add(`Create UserTasks for Reactivated Project #${Id}`, { @@ -177,7 +179,9 @@ export const actions: Actions = { type: BullMQ.UserTasks.OpType.Create } });*/ + return { ...old, DateArchived: null }; } + return old; }) ); diff --git a/source/SIL.AppBuilder.Portal/src/routes/(authenticated)/projects/[filter=projectSelector]/[id]/+page.svelte b/source/SIL.AppBuilder.Portal/src/routes/(authenticated)/projects/[filter=projectSelector]/[id]/+page.svelte index ceb674ae9..2a6fd2d90 100644 --- a/source/SIL.AppBuilder.Portal/src/routes/(authenticated)/projects/[filter=projectSelector]/[id]/+page.svelte +++ b/source/SIL.AppBuilder.Portal/src/routes/(authenticated)/projects/[filter=projectSelector]/[id]/+page.svelte @@ -15,7 +15,7 @@ export let data: PageData; - let selectedProjects: { Id: number; OwnerId: number; Archived: boolean }[] = []; + let selectedProjects: { Id: number; OwnerId: number; DateArchived: Date | null }[] = []; const projects = writable(data.projects); const count = writable(data.count); @@ -52,14 +52,14 @@ $: canArchive = selectedProjects.reduce( (p, c) => p && - !c.Archived && + c.DateArchived === null && canModifyProject($page.data.session!, c.OwnerId, parseInt($page.params.id)), true ); $: canReactivate = selectedProjects.reduce( (p, c) => p && - c.Archived && + c.DateArchived !== null && canModifyProject($page.data.session!, c.OwnerId, parseInt($page.params.id)), true ); @@ -70,7 +70,7 @@ submit: actionSubmit } = superForm(data.actionForm, { dataType: 'json', - invalidateAll: true, + invalidateAll: false, onChange: (event) => { if ( event.paths.includes('operation') && @@ -79,6 +79,34 @@ ) { actionSubmit(); } + }, + onUpdated: (event) => { + if (event.form.valid) { + if ( + (event.form.data.operation === 'archive' && $page.params.filter !== 'all') || + (event.form.data.operation === 'reactivate' && $page.params.filter === 'archived') + ) { + projects.update((ps) => + ps.filter((p) => !event.form.data.projects.find((a) => a.Id === p.Id)) + ); + count.update((c) => c - event.form.data.projects.length); + } + if ( + $page.params.filter === 'all' && + (event.form.data.operation === 'archive' || event.form.data.operation === 'reactivate') + ) { + projects.update((ps) => + ps.map((old) => { + const newP = event.form.data.projects.find((p) => p.Id === old.Id); + if (newP) { + return { ...old, DateArchived: newP.DateArchived }; + } + return old; + }) + ); + } + selectedProjects = []; + } } }); @@ -124,7 +152,7 @@
{#if data.allowArchive && (!selectedProjects.length || canArchive)} @@ -160,16 +188,10 @@
- + {m.project_importProjects()} - + {m.sidebar_addProject()}
@@ -183,7 +205,11 @@ type="checkbox" class="mr-2 checkbox checkbox-info" bind:group={selectedProjects} - value={{ Id: project.Id, OwnerId: project.OwnerId, Archived: !!project.DateArchived }} + value={{ + Id: project.Id, + OwnerId: project.OwnerId, + DateArchived: project.DateArchived + }} />