From c097849dad9fda453186e780a3c3b9cfa33d6f39 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 12 Mar 2026 18:03:27 +0100 Subject: [PATCH] feat(frontend) : add archive/unarchive buttons and delete confirmation to TaskDrawer Co-Authored-By: Claude Opus 4.6 --- frontend/components/task/TaskDrawer.vue | 125 +++++++++++++++++++----- 1 file changed, 98 insertions(+), 27 deletions(-) diff --git a/frontend/components/task/TaskDrawer.vue b/frontend/components/task/TaskDrawer.vue index 9aebad3..b7d8d6f 100644 --- a/frontend/components/task/TaskDrawer.vue +++ b/frontend/components/task/TaskDrawer.vue @@ -50,25 +50,25 @@ />
-

Types

+

Tags

@@ -79,19 +79,44 @@ type="button" class="rounded-md bg-red-500 px-4 py-2 text-sm font-semibold text-white hover:bg-red-600 disabled:cursor-not-allowed disabled:opacity-50" :disabled="isSubmitting" - @click="handleDelete" + @click="confirmDeleteOpen = true" > Supprimer - +
+ + + +
+ + @@ -100,7 +125,7 @@ import type { Task, TaskWrite } from '~/services/dto/task' import type { TaskStatus } from '~/services/dto/task-status' import type { TaskEffort } from '~/services/dto/task-effort' import type { TaskPriority } from '~/services/dto/task-priority' -import type { TaskType } from '~/services/dto/task-type' +import type { TaskTag } from '~/services/dto/task-tag' import type { TaskGroup } from '~/services/dto/task-group' import type { UserData } from '~/services/dto/user-data' import { useTaskService } from '~/services/tasks' @@ -112,7 +137,7 @@ const props = defineProps<{ statuses: TaskStatus[] efforts: TaskEffort[] priorities: TaskPriority[] - types: TaskType[] + tags: TaskTag[] groups: TaskGroup[] users: UserData[] }>() @@ -129,6 +154,7 @@ const isOpen = computed({ const isEditing = computed(() => !!props.task) const isSubmitting = ref(false) +const confirmDeleteOpen = ref(false) const form = reactive({ title: '', @@ -138,7 +164,7 @@ const form = reactive({ priorityId: null as number | null, assigneeId: null as number | null, groupId: null as number | null, - typeIds: [] as number[], + tagIds: [] as number[], }) const touched = reactive({ @@ -165,12 +191,23 @@ const groupOptions = computed(() => props.groups.map(g => ({ label: g.title, value: g.id })) ) -function toggleType(id: number) { - const idx = form.typeIds.indexOf(id) +const canArchive = computed(() => { + if (!isEditing.value || !props.task) return false + if (props.task.archived) return false + const status = props.statuses.find(s => s.id === props.task?.status?.id) + return !!status?.isFinal +}) + +const canUnarchive = computed(() => { + return isEditing.value && !!props.task?.archived +}) + +function toggleTag(id: number) { + const idx = form.tagIds.indexOf(id) if (idx >= 0) { - form.typeIds.splice(idx, 1) + form.tagIds.splice(idx, 1) } else { - form.typeIds.push(id) + form.tagIds.push(id) } } @@ -183,7 +220,7 @@ function populateForm(task: Task | null) { form.priorityId = task.priority?.id ?? null form.assigneeId = task.assignee?.id ?? null form.groupId = task.group?.id ?? null - form.typeIds = task.types.map(t => t.id) + form.tagIds = task.tags.map(t => t.id) } else { form.title = '' form.description = '' @@ -192,7 +229,7 @@ function populateForm(task: Task | null) { form.priorityId = null form.assigneeId = null form.groupId = null - form.typeIds = [] + form.tagIds = [] } touched.title = false } @@ -216,6 +253,40 @@ async function handleDelete() { isSubmitting.value = true try { await remove(props.task.id) + confirmDeleteOpen.value = false + emit('saved') + isOpen.value = false + } finally { + isSubmitting.value = false + } +} + +async function handleArchive() { + if (!props.task) return + const timerStore = useTimerStore() + if (timerStore.activeEntry?.task) { + const taskIri = typeof timerStore.activeEntry.task === 'string' + ? timerStore.activeEntry.task + : (timerStore.activeEntry.task as any)?.['@id'] ?? `/api/tasks/${(timerStore.activeEntry.task as any)?.id}` + if (taskIri === `/api/tasks/${props.task.id}`) { + await timerStore.stop() + } + } + isSubmitting.value = true + try { + await update(props.task.id, { archived: true }) + emit('saved') + isOpen.value = false + } finally { + isSubmitting.value = false + } +} + +async function handleUnarchive() { + if (!props.task) return + isSubmitting.value = true + try { + await update(props.task.id, { archived: false }) emit('saved') isOpen.value = false } finally { @@ -238,7 +309,7 @@ async function handleSubmit() { assignee: form.assigneeId ? `/api/users/${form.assigneeId}` : null, group: form.groupId ? `/api/task_groups/${form.groupId}` : null, project: `/api/projects/${props.projectId}`, - types: form.typeIds.map(id => `/api/task_types/${id}`), + tags: form.tagIds.map(id => `/api/task_tags/${id}`), } if (isEditing.value && props.task) {