From d2adc68262ebedb8733dfc88c5c4012cb36cc3d2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 15 Feb 2026 19:33:25 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20address=20code=20review=20findings=20?= =?UTF-8?q?=E2=80=94=20data=20loss,=20race=20condition,=20broken=20feature?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TopBar: call closeBoard() before navigating back to prevent data loss - board-store: guard debouncedSave against race condition when board is closed during an in-flight save - board-store: add missing updatedAt to setColumnWidth - useKeyboardShortcuts: remove duplicate Ctrl+K handler that prevented command palette from toggling closed - AttachmentSection: wire up Tauri file dialog for adding attachments with link/copy mode support --- .../card-detail/AttachmentSection.tsx | 26 ++++++++++++++++--- src/components/layout/TopBar.tsx | 5 +++- src/hooks/useKeyboardShortcuts.ts | 8 +----- src/stores/board-store.ts | 13 +++++++--- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/components/card-detail/AttachmentSection.tsx b/src/components/card-detail/AttachmentSection.tsx index fae56cd..38d744d 100644 --- a/src/components/card-detail/AttachmentSection.tsx +++ b/src/components/card-detail/AttachmentSection.tsx @@ -1,6 +1,8 @@ import { FileIcon, X, Plus } from "lucide-react"; +import { open } from "@tauri-apps/plugin-dialog"; import { Button } from "@/components/ui/button"; import { useBoardStore } from "@/stores/board-store"; +import { copyAttachment } from "@/lib/storage"; import type { Attachment } from "@/types/board"; interface AttachmentSectionProps { @@ -12,11 +14,29 @@ export function AttachmentSection({ cardId, attachments, }: AttachmentSectionProps) { + const addAttachment = useBoardStore((s) => s.addAttachment); const removeAttachment = useBoardStore((s) => s.removeAttachment); - function handleAdd() { - // Placeholder: Tauri file dialog will be wired in a later task - console.log("Add attachment (file dialog not yet wired)"); + async function handleAdd() { + const selected = await open({ + multiple: false, + title: "Select attachment", + }); + if (!selected) return; + + const fileName = selected.split(/[\\/]/).pop() ?? "attachment"; + + const board = useBoardStore.getState().board; + if (!board) return; + + const mode = board.settings.attachmentMode; + + if (mode === "copy") { + const destPath = await copyAttachment(board.id, selected, fileName); + addAttachment(cardId, { name: fileName, path: destPath, mode: "copy" }); + } else { + addAttachment(cardId, { name: fileName, path: selected, mode: "link" }); + } } return ( diff --git a/src/components/layout/TopBar.tsx b/src/components/layout/TopBar.tsx index 7e1ea67..43c6ff6 100644 --- a/src/components/layout/TopBar.tsx +++ b/src/components/layout/TopBar.tsx @@ -75,7 +75,10 @@ export function TopBar() {