From b647889a7d519cb777e612c3c0ccc4262c9c266c Mon Sep 17 00:00:00 2001 From: marko-kraemer Date: Fri, 23 May 2025 11:41:14 +0200 Subject: [PATCH] Refactor multi-select: replace icon with checkbox on hover for minimal selection UI --- .../src/components/sidebar/nav-agents.tsx | 193 ++++++++---------- 1 file changed, 84 insertions(+), 109 deletions(-) diff --git a/frontend/src/components/sidebar/nav-agents.tsx b/frontend/src/components/sidebar/nav-agents.tsx index cf3c689d..5356993b 100644 --- a/frontend/src/components/sidebar/nav-agents.tsx +++ b/frontend/src/components/sidebar/nav-agents.tsx @@ -62,7 +62,6 @@ export function NavAgents() { const isPerformingActionRef = useRef(false); const queryClient = useQueryClient(); - const [isMultiSelectActive, setIsMultiSelectActive] = useState(false); const [selectedThreads, setSelectedThreads] = useState>(new Set()); const [deleteProgress, setDeleteProgress] = useState(0); const [totalToDelete, setTotalToDelete] = useState(0); @@ -146,10 +145,9 @@ export function NavAgents() { // Function to handle thread click with loading state const handleThreadClick = (e: React.MouseEvent, threadId: string, url: string) => { - // If multi-select is active, prevent navigation and toggle selection - if (isMultiSelectActive) { + // If thread is selected, prevent navigation + if (selectedThreads.has(threadId)) { e.preventDefault(); - toggleThreadSelection(threadId); return; } @@ -159,7 +157,12 @@ export function NavAgents() { } // Toggle thread selection for multi-select - const toggleThreadSelection = (threadId: string) => { + const toggleThreadSelection = (threadId: string, e?: React.MouseEvent) => { + if (e) { + e.preventDefault(); + e.stopPropagation(); + } + setSelectedThreads(prev => { const newSelection = new Set(prev); if (newSelection.has(threadId)) { @@ -171,15 +174,6 @@ export function NavAgents() { }); }; - // Toggle multi-select mode - const toggleMultiSelect = () => { - setIsMultiSelectActive(!isMultiSelectActive); - // Clear selections when toggling off - if (isMultiSelectActive) { - setSelectedThreads(new Set()); - } - }; - // Select all threads const selectAllThreads = () => { const allThreadIds = combinedThreads.map(thread => thread.threadId); @@ -309,7 +303,6 @@ export function NavAgents() { // Reset states setSelectedThreads(new Set()); - setIsMultiSelectActive(false); setDeleteProgress(0); setTotalToDelete(0); }, @@ -331,7 +324,6 @@ export function NavAgents() { // Reset states setSelectedThreads(new Set()); - setIsMultiSelectActive(false); setThreadToDelete(null); isPerformingActionRef.current = false; setDeleteProgress(0); @@ -351,16 +343,15 @@ export function NavAgents() { return (
- Agents + Tasks {state !== 'collapsed' ? (
- {isMultiSelectActive ? ( + {selectedThreads.size > 0 ? ( <> - ) : ( - <> - - -
- -
-
- Select Multiple -
- - -
- - - New Agent - -
-
- New Agent -
- + + +
+ + + New Agent + +
+
+ New Agent +
)}
) : null} @@ -472,7 +433,7 @@ export function NavAgents() { const isSelected = selectedThreads.has(thread.threadId); return ( - + {state === 'collapsed' ? ( @@ -490,13 +451,7 @@ export function NavAgents() { handleThreadClick(e, thread.threadId, thread.url) } > - {isMultiSelectActive ? ( -
- {isSelected && } -
- ) : isThreadLoading ? ( + {isThreadLoading ? ( ) : ( @@ -509,48 +464,68 @@ export function NavAgents() { {thread.projectName}
) : ( - - - handleThreadClick(e, thread.threadId, thread.url) - } - className="flex items-center" +
+ - {isMultiSelectActive ? ( -
{ - e.preventDefault(); - e.stopPropagation(); - toggleThreadSelection(thread.threadId); - }} - > - {isSelected && } -
- ) : null} - {isThreadLoading ? ( - - ) : ( - - )} - {thread.projectName} - -
+ + handleThreadClick(e, thread.threadId, thread.url) + } + className="flex items-center" + > +
+ {/* Show checkbox on hover or when selected, otherwise show MessagesSquare */} + {isThreadLoading ? ( + + ) : ( + <> + {/* MessagesSquare icon - hidden on hover if not selected */} + + + {/* Checkbox - appears on hover or when selected */} +
toggleThreadSelection(thread.threadId, e)} + > +
+ {isSelected && } +
+
+ + )} +
+ {thread.projectName} + + +
)} - {state !== 'collapsed' && !isMultiSelectActive && ( + {state !== 'collapsed' && !isSelected && ( - + More