From 83471e55d428e3dec2c81ec319ccce57b6e8e447 Mon Sep 17 00:00:00 2001 From: Aneurin Barker Snook Date: Fri, 4 Sep 2026 23:35:33 +0100 Subject: [PATCH] Extract StatusManager, dedupe ColumnChange type, add useDialog composable - Pull the status-management feature (drag reorder, add, delete with reassignment) out of ProjectConfigureView into its own StatusManager component. It fetches its own status list independently, so the view is left with just page chrome and the rename form (316 -> 106 lines). - Define ColumnChange once in lib/cardOrder.ts instead of duplicating the same type in AppSidebar.vue and ProjectView.vue. - Add composables/useDialog.ts for the Escape-to-close + focus-on-open behaviour shared by every confirm/reassign modal (and, without a focus target, plain dropdown menus). Used by ProjectManageMenu's delete-confirmation modal + its own menu, and StatusManager's reassignment modal. --- web/src/components/AppSidebar.vue | 7 +- web/src/components/ProjectManageMenu.vue | 22 +-- web/src/components/StatusManager.vue | 230 +++++++++++++++++++++++ web/src/composables/useDialog.ts | 28 +++ web/src/lib/cardOrder.ts | 8 + web/src/views/ProjectConfigureView.vue | 220 +--------------------- web/src/views/ProjectView.vue | 7 +- 7 files changed, 280 insertions(+), 242 deletions(-) create mode 100644 web/src/components/StatusManager.vue create mode 100644 web/src/composables/useDialog.ts diff --git a/web/src/components/AppSidebar.vue b/web/src/components/AppSidebar.vue index 87cf704..546e9f8 100644 --- a/web/src/components/AppSidebar.vue +++ b/web/src/components/AppSidebar.vue @@ -3,7 +3,7 @@ import { computed, onMounted, ref } from 'vue' import { RouterLink, useRoute, useRouter } from 'vue-router' import draggable from 'vuedraggable' import { ApiError } from '../lib/api' -import { reorderColumn } from '../lib/cardOrder' +import { reorderColumn, type ColumnChange } from '../lib/cardOrder' import { useCardsStore } from '../stores/cards' import { useInboxStore } from '../stores/inbox' import { useProjectsStore } from '../stores/projects' @@ -52,11 +52,6 @@ const newInboxText = ref('') const addingToInbox = ref(false) const inboxError = ref(null) -type ColumnChange = { - added?: { element: Card; newIndex: number } - moved?: { element: Card; oldIndex: number; newIndex: number } -} - async function loadInbox() { inboxError.value = null try { diff --git a/web/src/components/ProjectManageMenu.vue b/web/src/components/ProjectManageMenu.vue index 1511398..cb26afd 100644 --- a/web/src/components/ProjectManageMenu.vue +++ b/web/src/components/ProjectManageMenu.vue @@ -1,6 +1,7 @@ diff --git a/web/src/views/ProjectView.vue b/web/src/views/ProjectView.vue index f347f57..8680bdc 100644 --- a/web/src/views/ProjectView.vue +++ b/web/src/views/ProjectView.vue @@ -6,7 +6,7 @@ import CardRow from '../components/CardRow.vue' import KanbanCard from '../components/KanbanCard.vue' import ProjectManageMenu from '../components/ProjectManageMenu.vue' import { ApiError, apiRequest } from '../lib/api' -import { reorderColumn } from '../lib/cardOrder' +import { reorderColumn, type ColumnChange } from '../lib/cardOrder' import { useCardsStore } from '../stores/cards' import { useInboxStore } from '../stores/inbox' import type { Card, CardStatus, Project } from '../types' @@ -51,11 +51,6 @@ interface Column { statusId: number cards: Card[] } -type ColumnChange = { - added?: { element: Card; newIndex: number } - removed?: { element: Card; oldIndex: number } - moved?: { element: Card; oldIndex: number; newIndex: number } -} const board = ref([])