feat(tasks) : add delete button to TaskDrawer and toggle timer from TaskCard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 23:19:53 +01:00
parent 576922200c
commit d4c5660ba6
2 changed files with 67 additions and 25 deletions

View File

@@ -9,10 +9,11 @@
<div class="flex items-start justify-between gap-2">
<h4 class="text-sm font-semibold text-neutral-900">{{ task.title }}</h4>
<button
class="shrink-0 text-neutral-400 hover:text-primary-500"
@click.stop="onPlay"
class="shrink-0 transition-colors"
:class="isTimerOnTask ? 'text-red-500 hover:text-red-600' : 'text-neutral-400 hover:text-primary-500'"
@click.stop="isTimerOnTask ? timerStore.stop() : onPlay()"
>
<Icon name="mdi:play-circle-outline" size="20" />
<Icon :name="isTimerOnTask ? 'mdi:stop-circle-outline' : 'mdi:play-circle-outline'" size="20" />
</button>
</div>
@@ -62,6 +63,16 @@ const emit = defineEmits<{
const timerStore = useTimerStore()
const isTimerOnTask = computed(() => {
const entry = timerStore.activeEntry
if (!entry?.task) return false
const entryTaskId = typeof entry.task === 'string'
? entry.task
: (entry.task['@id'] ?? entry.task.id)
const taskId = props.task['@id'] ?? props.task.id
return entryTaskId === taskId || entryTaskId === `/api/tasks/${props.task.id}`
})
function onPlay() {
timerStore.startFromTask(props.task)
}

View File

@@ -73,7 +73,16 @@
</div>
</div>
<div class="mt-6 flex justify-end">
<div class="mt-6 flex items-center" :class="isEditing ? 'justify-between' : 'justify-end'">
<button
v-if="isEditing"
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"
>
Supprimer
</button>
<button
type="submit"
class="rounded-md bg-primary-500 px-6 py-2 text-sm font-semibold text-white hover:bg-secondary-500 disabled:cursor-not-allowed disabled:opacity-50"
@@ -165,32 +174,54 @@ function toggleType(id: number) {
}
}
function populateForm(task: Task | null) {
if (task) {
form.title = task.title ?? ''
form.description = task.description ?? ''
form.statusId = task.status?.id ?? null
form.effortId = task.effort?.id ?? 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)
} else {
form.title = ''
form.description = ''
form.statusId = null
form.effortId = null
form.priorityId = null
form.assigneeId = null
form.groupId = null
form.typeIds = []
}
touched.title = false
}
watch(() => props.modelValue, (open) => {
if (open) {
if (props.task) {
form.title = props.task.title ?? ''
form.description = props.task.description ?? ''
form.statusId = props.task.status?.id ?? null
form.effortId = props.task.effort?.id ?? null
form.priorityId = props.task.priority?.id ?? null
form.assigneeId = props.task.assignee?.id ?? null
form.groupId = props.task.group?.id ?? null
form.typeIds = props.task.types.map(t => t.id)
} else {
form.title = ''
form.description = ''
form.statusId = null
form.effortId = null
form.priorityId = null
form.assigneeId = null
form.groupId = null
form.typeIds = []
}
touched.title = false
populateForm(props.task)
}
})
const { create, update } = useTaskService()
watch(() => props.task, (task) => {
if (props.modelValue) {
populateForm(task)
}
})
const { create, update, remove } = useTaskService()
async function handleDelete() {
if (!props.task) return
isSubmitting.value = true
try {
await remove(props.task.id)
emit('saved')
isOpen.value = false
} finally {
isSubmitting.value = false
}
}
async function handleSubmit() {
touched.title = true