From b54d160a3b6da85c40c1ccf587ce3259d098924d Mon Sep 17 00:00:00 2001 From: Stijnus <72551117+Stijnus@users.noreply.github.com> Date: Sun, 6 Apr 2025 20:36:53 +0200 Subject: [PATCH] feat: bulk delete chats from sidebar (#1586) * feat: Bulk Delete Chats from Sidebar feat(sidebar): Implement bulk chat deletion Adds the ability for users to select multiple chats from the history sidebar and delete them in bulk. **Key Changes:** * **Selection Mode:** Introduced a selection mode toggled by a dedicated button next to "Start new chat". * **Checkboxes:** Added checkboxes to each `HistoryItem` visible only when selection mode is active. * **Bulk Actions:** Added "Select All" / "Deselect All" and "Delete Selected" buttons (`Button` component with `ghost` variant) that appear above the chat list in selection mode. * **Confirmation Dialog:** Implemented a confirmation dialog (`Dialog` component) to prevent accidental deletion, listing the chats selected for removal. * **Deletion Logic:** Updated `Menu.client.tsx` to handle the selection state and perform bulk deletion using `deleteById` from persistence layer. * **Styling:** Ensured all new UI elements (`Checkbox`, `Button`) adhere to the existing project design system and support both light and dark themes using appropriate CSS classes and UnoCSS icons (`i-ph:` prefix). * **Refinement:** Replaced initial plain ` +
- +
{ />
-
Your Chats
+
+
Your Chats
+ {selectionMode && ( +
+ + +
+ )} +
{filteredList.length === 0 && (
@@ -235,8 +431,16 @@ export const Menu = () => { key={item.id} item={item} exportChat={exportChat} - onDelete={(event) => handleDeleteClick(event, item)} + onDelete={(event) => { + event.preventDefault(); + event.stopPropagation(); + console.log('Delete triggered for item:', item); + setDialogContentWithLogging({ type: 'delete', item }); + }} onDuplicate={() => handleDuplicate(item.id)} + selectionMode={selectionMode} + isSelected={selectedItems.includes(item.id)} + onToggleSelection={toggleItemSelection} /> ))}
@@ -264,6 +468,7 @@ export const Menu = () => { { + console.log('Dialog delete button clicked for item:', dialogContent.item); deleteItem(event, dialogContent.item); closeDialog(); }} @@ -273,6 +478,49 @@ export const Menu = () => {
)} + {dialogContent?.type === 'bulkDelete' && ( + <> +
+ Delete Selected Chats? + +

+ You are about to delete {dialogContent.items.length}{' '} + {dialogContent.items.length === 1 ? 'chat' : 'chats'}: +

+
+
    + {dialogContent.items.map((item) => ( +
  • + {item.description} +
  • + ))} +
+
+

Are you sure you want to delete these chats?

+
+
+
+ + Cancel + + { + /* + * Pass the current selectedItems to the delete function. + * This captures the state at the moment the user confirms. + */ + const itemsToDeleteNow = [...selectedItems]; + console.log('Bulk delete confirmed for', itemsToDeleteNow.length, 'items', itemsToDeleteNow); + deleteSelectedItems(itemsToDeleteNow); + closeDialog(); + }} + > + Delete + +
+ + )} diff --git a/app/components/ui/Checkbox.tsx b/app/components/ui/Checkbox.tsx index 7fa0d9fe..e21e9e25 100644 --- a/app/components/ui/Checkbox.tsx +++ b/app/components/ui/Checkbox.tsx @@ -10,13 +10,20 @@ const Checkbox = React.forwardRef< - - + + ));