From 3b73b43712e2f1792704182c7f313afe4fef7130 Mon Sep 17 00:00:00 2001 From: Arsen Muk Date: Thu, 30 Jul 2026 16:32:01 +0200 Subject: [PATCH] Chat sidebar: add Archive action to session menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The session ⋯ menu offered only Star / Rename / Delete (hard delete). Archive was already backend-ready (POST /api/sessions/{id}/archive, api.archiveSession, session_archived WS handler) but not surfaced in the UI. Add an Archive action (above Delete) that soft-removes the session from the sidebar (recoverable), mirroring the Star/Rename wiring and the optimistic-reload pattern of deleteSession. Co-Authored-By: Claude Opus 4.8 --- web/src/components/Chat/SessionSidebar.tsx | 23 +++++++++++++++++++--- web/src/stores/chatStore.ts | 19 ++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/web/src/components/Chat/SessionSidebar.tsx b/web/src/components/Chat/SessionSidebar.tsx index c629a64c..6ecd3237 100644 --- a/web/src/components/Chat/SessionSidebar.tsx +++ b/web/src/components/Chat/SessionSidebar.tsx @@ -1,6 +1,6 @@ import { useState, useMemo, useRef, useEffect, useCallback, useLayoutEffect } from 'react'; import { Link } from 'react-router-dom'; -import { Plus, X, MessageSquare, ChevronRight, ChevronDown, Bot, Loader2, Search, Hammer, MoreHorizontal, Star, Pencil, Trash2, Repeat } from 'lucide-react'; +import { Plus, X, MessageSquare, ChevronRight, ChevronDown, Bot, Loader2, Search, Hammer, MoreHorizontal, Star, Pencil, Trash2, Archive, Repeat } from 'lucide-react'; import type { Session, AgentStatus } from '../../types/chat'; import { groupByDate, parseTimestamp } from '../../utils/dateGroups'; import { useChatStore } from '../../stores/chatStore'; @@ -53,7 +53,7 @@ export function SessionSidebar({ sessions, activeSession, agentStatus, onCreate, const debounceRef = useRef | null>(null); const inputRef = useRef(null); - const { searchResults, searchLoading, searchSessions, clearSearch, renameSession, toggleStar, virtualSession, discardVirtualSession, sidebarWidth, setSidebarWidth } = useChatStore(); + const { searchResults, searchLoading, searchSessions, clearSearch, renameSession, toggleStar, archiveSession, virtualSession, discardVirtualSession, sidebarWidth, setSidebarWidth } = useChatStore(); const searchFocusNonce = useChatStore(s => s.searchFocusNonce); // Drag-to-resize the session list. It is left-anchored against the nav rail, @@ -321,6 +321,7 @@ export function SessionSidebar({ sessions, activeSession, agentStatus, onCreate, onDelete={onDelete} onRename={renameSession} onToggleStar={toggleStar} + onArchive={archiveSession} showDate /> )) @@ -373,6 +374,7 @@ export function SessionSidebar({ sessions, activeSession, agentStatus, onCreate, onDelete={onDelete} onRename={renameSession} onToggleStar={toggleStar} + onArchive={archiveSession} /> ))} @@ -394,6 +396,7 @@ export function SessionSidebar({ sessions, activeSession, agentStatus, onCreate, onDelete={onDelete} onRename={renameSession} onToggleStar={toggleStar} + onArchive={archiveSession} /> ))} @@ -418,6 +421,7 @@ export function SessionSidebar({ sessions, activeSession, agentStatus, onCreate, onDelete={onDelete} onRename={renameSession} onToggleStar={toggleStar} + onArchive={archiveSession} /> ))} @@ -564,13 +568,14 @@ function StatusIndicator({ session, isActive, isRunning }: { } -function SessionItem({ session, isActive, isRunning, onDelete, onRename, onToggleStar, showDate }: { +function SessionItem({ session, isActive, isRunning, onDelete, onRename, onToggleStar, onArchive, showDate }: { session: Session; isActive: boolean; isRunning: boolean; onDelete: (id: string) => void; onRename: (id: string, title: string) => Promise; onToggleStar: (id: string) => Promise; + onArchive: (id: string) => Promise; showDate?: boolean; }) { const [menuOpen, setMenuOpen] = useState(false); @@ -708,6 +713,18 @@ function SessionItem({ session, isActive, isRunning, onDelete, onRename, onToggl Rename +