diff --git a/frontend/taskdeck-web/src/components/board/BoardCanvas.vue b/frontend/taskdeck-web/src/components/board/BoardCanvas.vue index 0fb0b7d92..5a26d7db2 100644 --- a/frontend/taskdeck-web/src/components/board/BoardCanvas.vue +++ b/frontend/taskdeck-web/src/components/board/BoardCanvas.vue @@ -14,7 +14,7 @@ defineProps<{ selectedCardId: string | null }>() -defineEmits<{ +const emit = defineEmits<{ columnDragStart: [column: Column, event: DragEvent] columnDragEnd: [] columnDragOver: [column: Column, event: DragEvent] @@ -24,6 +24,23 @@ defineEmits<{ cardDragEnd: [] cardEditorSavingChange: [saving: boolean] }>() + +// One CardModal lives inside each ColumnLane. The route boundary needs the +// aggregate, not whichever lane happened to emit last: a clean modal closing +// in column B must not clear column A's unanswered assignment PUT. +const savingColumnIds = new Set() +let aggregateCardEditorSaving = false + +function handleCardEditorSavingChange(columnId: string, saving: boolean) { + if (saving) savingColumnIds.add(columnId) + else savingColumnIds.delete(columnId) + + const nextAggregate = savingColumnIds.size > 0 + if (nextAggregate === aggregateCardEditorSaving) return + + aggregateCardEditorSaving = nextAggregate + emit('cardEditorSavingChange', nextAggregate) +}