feat: Added the ability to delete task lists
All checks were successful
Build and Push App Image / build-and-push (push) Successful in 1m48s
All checks were successful
Build and Push App Image / build-and-push (push) Successful in 1m48s
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
<SearchResultsPage
|
||||
v-else-if="isSearchRoute"
|
||||
@@ -1294,6 +1297,36 @@ const createTaskList = async (taskListData) => {
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
@@ -185,6 +185,12 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section v-if="selectedTaskList && canDeleteTaskList" class="danger-zone" aria-labelledby="task-list-danger-zone-title">
|
||||
<h6 id="task-list-danger-zone-title" class="danger-zone-title">Danger Zone</h6>
|
||||
<p class="danger-zone-copy mb-2">Delete this task list and all associated tasks permanently.</p>
|
||||
<button type="button" class="btn btn-outline-danger" @click="emitDeleteTaskList">Delete Task List</button>
|
||||
</section>
|
||||
|
||||
<teleport to="body">
|
||||
<div v-if="showStatusModal" class="modal fade show d-block" tabindex="-1" role="dialog" aria-modal="true" @click.self="closeStatusModal">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
@@ -235,9 +241,17 @@ const props = defineProps({
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
selectedTaskList: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
canDeleteTaskList: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["create-task", "select-task", "filter-change", "reorder-status", "create-status", "rename-status", "delete-status", "update-task-status"]);
|
||||
const emit = defineEmits(["create-task", "select-task", "filter-change", "reorder-status", "create-status", "rename-status", "delete-status", "update-task-status", "delete-task-list"]);
|
||||
|
||||
const filterStatus = ref("");
|
||||
const filterParent = ref("");
|
||||
@@ -470,6 +484,13 @@ const deleteStatusFromModal = () => {
|
||||
});
|
||||
closeStatusModal();
|
||||
};
|
||||
|
||||
const emitDeleteTaskList = () => {
|
||||
if (!props.selectedTaskList?.id || !props.canDeleteTaskList) {
|
||||
return;
|
||||
}
|
||||
emit("delete-task-list", props.selectedTaskList);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped src="../assets/styles/scoped/components/TaskBoard.css"></style>
|
||||
|
||||
Reference in New Issue
Block a user