From b09137eca59be1bfeff75f71b02342010b5043e1 Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Mon, 30 Mar 2026 10:14:07 +0100 Subject: [PATCH] feat: Added the ability to delete task lists --- .../application/services/task_service.go | 6 +--- .../domain/repositories/interfaces.go | 1 + .../database/task_repository.go | 5 +++ frontend/src/App.vue | 33 +++++++++++++++++++ frontend/src/components/TaskBoard.vue | 23 ++++++++++++- 5 files changed, 62 insertions(+), 6 deletions(-) diff --git a/backend/internal/application/services/task_service.go b/backend/internal/application/services/task_service.go index 0daf053..19b0f13 100644 --- a/backend/internal/application/services/task_service.go +++ b/backend/internal/application/services/task_service.go @@ -812,13 +812,9 @@ func (s *TaskService) DeleteTaskList(ctx context.Context, spaceID, taskListID, u return errors.New("task list not found") } - tasks, err := s.taskRepo.ListTasks(ctx, spaceID, map[string]any{"task_list_id": taskListID}) - if err != nil { + if err := s.taskRepo.DeleteTasksByTaskListID(ctx, taskListID); err != nil { return err } - if len(tasks) > 0 { - return errors.New("cannot delete task list with tasks") - } return s.taskListRepo.DeleteTaskList(ctx, taskListID) } diff --git a/backend/internal/domain/repositories/interfaces.go b/backend/internal/domain/repositories/interfaces.go index 4432152..dc2a467 100644 --- a/backend/internal/domain/repositories/interfaces.go +++ b/backend/internal/domain/repositories/interfaces.go @@ -225,6 +225,7 @@ type TaskRepository interface { SearchTasks(ctx context.Context, spaceID bson.ObjectID, query string) ([]*entities.Task, error) UpdateTask(ctx context.Context, task *entities.Task) error DeleteTask(ctx context.Context, id bson.ObjectID) error + DeleteTasksByTaskListID(ctx context.Context, taskListID bson.ObjectID) error DeleteTasksBySpaceID(ctx context.Context, spaceID bson.ObjectID) error CountChildren(ctx context.Context, parentTaskID bson.ObjectID) (int64, error) } diff --git a/backend/internal/infrastructure/database/task_repository.go b/backend/internal/infrastructure/database/task_repository.go index 688ec0e..199e092 100644 --- a/backend/internal/infrastructure/database/task_repository.go +++ b/backend/internal/infrastructure/database/task_repository.go @@ -95,6 +95,11 @@ func (r *TaskRepository) DeleteTask(ctx context.Context, id bson.ObjectID) error return err } +func (r *TaskRepository) DeleteTasksByTaskListID(ctx context.Context, taskListID bson.ObjectID) error { + _, err := r.collection.DeleteMany(ctx, bson.M{"task_list_id": taskListID}) + return err +} + func (r *TaskRepository) DeleteTasksBySpaceID(ctx context.Context, spaceID bson.ObjectID) error { _, err := r.collection.DeleteMany(ctx, bson.M{"space_id": spaceID}) return err diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 7a75c3d..15e1374 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -212,6 +212,8 @@ v-if="activeView === 'tasks'" :tasks="tasks" :statuses="taskStatuses" + :selected-task-list="selectedTaskList" + :can-delete-task-list="canDeleteTasks" @select-task="openTaskDetail" @filter-change="applyTaskFilters" @reorder-status="reorderTaskStatuses" @@ -219,6 +221,7 @@ @rename-status="renameTaskStatus" @delete-status="deleteTaskStatus" @update-task-status="updateTaskStatusFromBoard" + @delete-task-list="removeTaskList" /> { } }; +const removeTaskList = async (taskList) => { + if (!currentSpace.value?.id || !taskList?.id || !canDeleteTasks.value) { + return; + } + + if (!confirm(`Delete task list "${taskList.name}" and all associated tasks?`)) { + return; + } + + try { + await spaceStore.deleteTaskList(currentSpace.value.id, taskList.id); + + if (selectedTaskList.value?.id === taskList.id) { + selectedTaskList.value = null; + taskDetail.value = null; + taskModalDraft.value = null; + showTaskModal.value = false; + taskFilters.value = { + taskListId: null, + statusId: null, + parentTaskId: null, + }; + await spaceStore.fetchTasks(currentSpace.value.id, taskFilters.value); + activeView.value = "notes"; + } + } catch (error) { + alert(error?.response?.data || "Unable to delete task list."); + } +}; + const createSpace = async (spaceData) => { showCreateSpaceModal.value = false; await spaceStore.createSpace(spaceData); diff --git a/frontend/src/components/TaskBoard.vue b/frontend/src/components/TaskBoard.vue index 5f8b12a..4c1ca74 100644 --- a/frontend/src/components/TaskBoard.vue +++ b/frontend/src/components/TaskBoard.vue @@ -185,6 +185,12 @@ +
+
Danger Zone
+

Delete this task list and all associated tasks permanently.

+ +
+