From b1810013e5b6412aabe9bb43ecb307430d0c36f7 Mon Sep 17 00:00:00 2001 From: Paolo Insogna Date: Fri, 12 Jun 2026 22:13:41 +0200 Subject: [PATCH] feat: Add delete session in the sessions menu. (#1557) Signed-off-by: Paolo Insogna Co-authored-by: Bohdan Triapitsyn --- .../components/session/sidebar/SessionNodeItem.tsx | 14 ++++++++++---- .../session/sidebar/hooks/useSessionActions.ts | 13 +++++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/ui/src/components/session/sidebar/SessionNodeItem.tsx b/packages/ui/src/components/session/sidebar/SessionNodeItem.tsx index 56897ad3..54149bc3 100644 --- a/packages/ui/src/components/session/sidebar/SessionNodeItem.tsx +++ b/packages/ui/src/components/session/sidebar/SessionNodeItem.tsx @@ -81,7 +81,7 @@ type Props = { addSessionToFolder: (scopeKey: string, folderId: string, sessionId: string) => void; createFolderAndStartRename: (scopeKey: string, parentId?: string | null) => { id: string } | null; openContextPanelTab: (directory: string, options: { mode: 'chat'; dedupeKey: string; label: string; readOnly?: boolean }) => void; - handleDeleteSession: (session: Session, source?: { archivedBucket?: boolean }) => void; + handleDeleteSession: (session: Session, source?: { archivedBucket?: boolean; hardDelete?: boolean }) => void; mobileVariant: boolean; alwaysShowActions: boolean; renderSessionNode: (node: SessionNode, depth?: number, groupDirectory?: string | null, projectId?: string | null, archivedBucket?: boolean, secondaryMeta?: SecondaryMeta | null, renderContext?: 'project' | 'recent') => React.ReactNode; @@ -849,9 +849,15 @@ function SessionNodeItemComponent(props: Props): React.ReactNode { ) : null} - handleDeleteSession(session, { archivedBucket })}> - - {archivedBucket ? t('sessions.sidebar.bulkActions.delete') : t('sessions.sidebar.bulkActions.archive')} + {!archivedBucket ? ( + handleDeleteSession(session, { archivedBucket })}> + + {t('sessions.sidebar.bulkActions.archive')} + + ) : null} + handleDeleteSession(session, { archivedBucket, hardDelete: true })}> + + {t('sessions.sidebar.bulkActions.delete')} ); diff --git a/packages/ui/src/components/session/sidebar/hooks/useSessionActions.ts b/packages/ui/src/components/session/sidebar/hooks/useSessionActions.ts index 11eb1337..3c04d461 100644 --- a/packages/ui/src/components/session/sidebar/hooks/useSessionActions.ts +++ b/packages/ui/src/components/session/sidebar/hooks/useSessionActions.ts @@ -12,6 +12,11 @@ type DeleteSessionConfirmSetter = React.Dispatch>; +type DeleteSessionSource = { + archivedBucket?: boolean; + hardDelete?: boolean; +}; + type Args = { activeProjectId: string | null; currentDirectory: string | null; @@ -187,10 +192,10 @@ export const useSessionActions = (args: Args) => { const executeDeleteSession = React.useCallback( async ( session: Session, - source?: { archivedBucket?: boolean }, + source?: DeleteSessionSource, precomputed?: { descendantIds: string[] }, ) => { - const shouldHardDelete = source?.archivedBucket === true; + const shouldHardDelete = source?.archivedBucket === true || source?.hardDelete === true; // Use the snapshot taken when the dialog opened (if any) so the // executed list matches what the user was told. Fall back to a fresh // collection for direct-execute (no-dialog) callers. @@ -246,8 +251,8 @@ export const useSessionActions = (args: Args) => { ); const handleDeleteSession = React.useCallback( - (session: Session, source?: { archivedBucket?: boolean }) => { - const shouldHardDelete = source?.archivedBucket === true; + (session: Session, source?: DeleteSessionSource) => { + const shouldHardDelete = source?.archivedBucket === true || source?.hardDelete === true; const effectiveDescendantIds = filterDescendantsForAction( collectDescendants(session.id), shouldHardDelete,