feat(admin) : add task reassignment logic to AdminStatusTab

This commit is contained in:
Matthieu
2026-03-12 11:51:15 +01:00
parent 9d5008a21d
commit ae8654d9ca
2 changed files with 63 additions and 6 deletions

View File

@@ -17,7 +17,7 @@
empty-message="Aucun statut trouvé."
deletable
@row-click="openEdit"
@delete="(item) => handleDelete(item.id)"
@delete="requestDelete"
>
<template #cell-color="{ item }">
<span
@@ -32,12 +32,22 @@
:item="selectedItem"
@saved="onSaved"
/>
<ConfirmDeleteStatusModal
v-model="confirmModalOpen"
:status-label="statusToDelete?.label ?? ''"
:task-count="affectedTaskCount"
:available-statuses="reassignTargets"
@confirm="onConfirmDelete"
/>
</div>
</template>
<script setup lang="ts">
import type { TaskStatus } from '~/services/dto/task-status'
import type { Task } from '~/services/dto/task'
import { useTaskStatusService } from '~/services/task-statuses'
import { useTaskService } from '~/services/tasks'
import type { DataTableColumn } from '~/components/ui/DataTable.vue'
@@ -47,16 +57,36 @@ const columns: DataTableColumn[] = [
{ key: 'position', label: 'Position', class: 'text-neutral-700' },
]
const { getAll, remove } = useTaskStatusService()
const statusService = useTaskStatusService()
const taskService = useTaskService()
const items = ref<TaskStatus[]>([])
const tasks = ref<Task[]>([])
const isLoading = ref(true)
const drawerOpen = ref(false)
const selectedItem = ref<TaskStatus | null>(null)
const confirmModalOpen = ref(false)
const statusToDelete = ref<TaskStatus | null>(null)
const affectedTaskCount = computed(() => {
if (!statusToDelete.value) return 0
return tasks.value.filter(t => t.status?.id === statusToDelete.value!.id).length
})
const reassignTargets = computed(() => {
if (!statusToDelete.value) return items.value
return items.value.filter(s => s.id !== statusToDelete.value!.id)
})
async function loadItems() {
isLoading.value = true
try {
items.value = await getAll()
const [statuses, allTasks] = await Promise.all([
statusService.getAll(),
taskService.getAll(),
])
items.value = statuses
tasks.value = allTasks
} finally {
isLoading.value = false
}
@@ -72,8 +102,30 @@ function openEdit(item: TaskStatus) {
drawerOpen.value = true
}
async function handleDelete(id: number) {
await remove(id)
async function requestDelete(item: TaskStatus) {
statusToDelete.value = item
const count = tasks.value.filter(t => t.status?.id === item.id).length
if (count === 0) {
await statusService.remove(item.id)
await loadItems()
} else {
confirmModalOpen.value = true
}
}
async function onConfirmDelete(targetStatusId: number | null) {
if (!statusToDelete.value) return
const affectedTasks = tasks.value.filter(t => t.status?.id === statusToDelete.value!.id)
const statusIri = targetStatusId ? `/api/task_statuses/${targetStatusId}` : null
await Promise.all(
affectedTasks.map(t => taskService.update(t.id, { status: statusIri }))
)
await statusService.remove(statusToDelete.value.id)
confirmModalOpen.value = false
statusToDelete.value = null
await loadItems()
}

View File

@@ -5,6 +5,11 @@ import { extractHydraMembers } from '~/utils/api'
export function useTaskService() {
const api = useApi()
async function getAll(): Promise<Task[]> {
const data = await api.get<HydraCollection<Task>>('/tasks')
return extractHydraMembers(data)
}
async function getByProject(projectId: number): Promise<Task[]> {
const data = await api.get<HydraCollection<Task>>('/tasks', {
project: `/api/projects/${projectId}`,
@@ -30,5 +35,5 @@ export function useTaskService() {
})
}
return { getByProject, create, update, remove }
return { getAll, getByProject, create, update, remove }
}