From 3a27a37acb7a811ef7f2fc225d4ea089149e3479 Mon Sep 17 00:00:00 2001 From: Sandro Date: Thu, 29 Oct 2026 18:49:35 +0100 Subject: [PATCH] feat(triage): skip list selector when only one writable list exists --- .../features/capture/InstantCaptureBar.tsx | 19 +- frontend/src/features/triage/TriageDeck.tsx | 71 ++++++-- .../__tests__/TriageDeck.lists.test.tsx | 163 ++++++++++++++++++ 3 files changed, 232 insertions(+), 21 deletions(-) create mode 100644 frontend/src/features/triage/__tests__/TriageDeck.lists.test.tsx diff --git a/frontend/src/features/capture/InstantCaptureBar.tsx b/frontend/src/features/capture/InstantCaptureBar.tsx index cffc170..4097356 100644 --- a/frontend/src/features/capture/InstantCaptureBar.tsx +++ b/frontend/src/features/capture/InstantCaptureBar.tsx @@ -38,6 +38,7 @@ export const InstantCaptureBar: React.FC = ({ hideTargetPicker = false, fixedTarget, }) => { + const writableLists = lists.filter((l) => l.isOwner || l.role !== 'viewer'); const [content, setContent] = useState(''); const [priority, setPriority] = useState('normal'); const [dueDate, setDueDate] = useState(''); @@ -77,10 +78,10 @@ export const InstantCaptureBar: React.FC = ({ }, [autoFocusTrigger]); useEffect(() => { - if (!targetListId && lists.length > 0) { - setTargetListId(lists[0].id); + if (!targetListId && writableLists.length > 0) { + setTargetListId(writableLists[0].id); } - }, [lists, targetListId]); + }, [writableLists, targetListId]); // Close dropdown on outside click useEffect(() => { @@ -180,7 +181,7 @@ export const InstantCaptureBar: React.FC = ({ const effectiveTarget = fixedTarget || overrideTarget || target; const effectiveListId = - overrideListId || targetListId || (lists.length > 0 ? lists[0].id : ''); + overrideListId || targetListId || (writableLists.length > 0 ? writableLists[0].id : ''); const capturedPriority = priority; const capturedDueDate = dueDate; const capturedSource = hasVoiceInputRef.current || isListening ? 'voice' : 'manual'; @@ -236,7 +237,7 @@ export const InstantCaptureBar: React.FC = ({ await executeCapture(); }; - const selectedList = lists.find((l) => l.id === targetListId) || lists[0]; + const selectedList = writableLists.find((l) => l.id === targetListId) || writableLists[0]; const getTargetLabel = () => { if (target === 'task') return 'Direkt-Aufgabe'; @@ -449,8 +450,8 @@ export const InstantCaptureBar: React.FC = ({ type="button" onClick={() => { setTarget('list_item'); - if (!targetListId && lists.length > 0) { - setTargetListId(lists[0].id); + if (!targetListId && writableLists.length > 0) { + setTargetListId(writableLists[0].id); } }} className={`min-h-[36px] px-2.5 border rounded-btn flex items-center gap-1.5 text-left transition-colors cursor-pointer ${ @@ -485,13 +486,13 @@ export const InstantCaptureBar: React.FC = ({ {/* Optional Sub-Row: Shared List Picker */} - {lists.length > 0 && ( + {writableLists.length > 0 && (
Liste: - {lists.map((lst) => { + {writableLists.map((lst) => { const isSelected = target === 'list_item' && targetListId === lst.id; return ( @@ -999,8 +1046,8 @@ export const TriageDeck: React.FC = ({ Auf welche Liste soll dieser Punkt gesetzt werden?

- {lists.length > 0 ? ( - lists.map((lst) => ( + {writableLists.length > 0 ? ( + writableLists.map((lst) => (