From 67d65b54f426cd52f89dd5921ce6b05254e21ef8 Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Sat, 24 Jan 2026 14:31:40 +0100 Subject: [PATCH] feat: edit mode --- src/modules/record/components/StepRecord.vue | 72 ++++++++++++++++++- src/modules/record/components/TaskRecord.vue | 11 +++ .../record/stores/useTaskRecordStore.ts | 27 +++++++ src/shared/format-date.ts | 2 +- 4 files changed, 109 insertions(+), 3 deletions(-) diff --git a/src/modules/record/components/StepRecord.vue b/src/modules/record/components/StepRecord.vue index 1fb0ede..afe03ef 100644 --- a/src/modules/record/components/StepRecord.vue +++ b/src/modules/record/components/StepRecord.vue @@ -2,7 +2,7 @@ import { useTaskStore } from '@/modules/task/stores/useTask.store' import { formatDiffInMinutes } from '@/shared/format-date' import { toISODate } from '@/shared/types/date' -import { computed, onUnmounted, ref } from 'vue' +import { computed, nextTick, onUnmounted, ref } from 'vue' import { useTaskRecordStore } from '../stores/useTaskRecordStore' import { is10PercentOffThanEstimation } from '@/modules/record/services/compare-with-estimation' @@ -10,6 +10,7 @@ const props = defineProps<{ taskId: string stepId: string stepNumber: number + isLastCompletedStep?: boolean }>() const taskStore = useTaskStore() @@ -67,6 +68,39 @@ const isOffEstimation = computed(() => { duration: duration.value }) }) + +// Duration editing +const isEditing = ref(false) +const editedDuration = ref(0) +const durationInputRef = ref(null) + +const isEditable = computed( + () => props.isLastCompletedStep && record.value && !record.value.end +) + +function startEditing() { + editedDuration.value = duration.value ?? 0 + isEditing.value = true + nextTick(() => { + durationInputRef.value?.focus() + durationInputRef.value?.select() + }) +} + +function confirmEdit() { + if (editedDuration.value >= 1) { + recordStore.updateStepDuration({ + taskId: props.taskId, + stepId: props.stepId, + newDurationMinutes: editedDuration.value + }) + } + isEditing.value = false +} + +function cancelEdit() { + isEditing.value = false +} @@ -145,6 +200,19 @@ $blob-color: $link; .minutes { text-align: right; } + + .is-editable { + cursor: pointer; + text-decoration: underline dotted; + &:hover { + opacity: 0.7; + } + } + + .duration-input { + width: 60px; + display: inline-block; + } } @keyframes pulse { diff --git a/src/modules/record/components/TaskRecord.vue b/src/modules/record/components/TaskRecord.vue index c97b04e..341d7fa 100644 --- a/src/modules/record/components/TaskRecord.vue +++ b/src/modules/record/components/TaskRecord.vue @@ -32,6 +32,16 @@ useAppTitle(task.value?.title ?? '') const record = computed(() => recordStore.getTaskRecord(props.taskId)) const recordNotes = computed(() => recordStore.getRecordNotes(props.taskId)) + +const lastCompletedStepId = computed(() => { + if (!record.value || !task.value || !record.value.currentStepId) return null + + const currentIndex = task.value.steps.findIndex( + (s) => s.id === record.value?.currentStepId + ) + + return currentIndex > 0 ? task.value.steps[currentIndex - 1].id : null +})