From 45db1bcf541a63acd702e619932fad90611faa6d Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 12 Mar 2026 12:03:29 -0700 Subject: [PATCH] feat: merge file tree and chat history into single left sidebar with tabs Made-with: Cursor --- .../workspace/chat-sessions-sidebar.tsx | 47 +++--- .../workspace/workspace-sidebar.tsx | 138 +++++++++++++--- apps/web/app/workspace/workspace-content.tsx | 152 +++++------------- 3 files changed, 182 insertions(+), 155 deletions(-) diff --git a/apps/web/app/components/workspace/chat-sessions-sidebar.tsx b/apps/web/app/components/workspace/chat-sessions-sidebar.tsx index b3e9e5b7bf4..1edb752928e 100644 --- a/apps/web/app/components/workspace/chat-sessions-sidebar.tsx +++ b/apps/web/app/components/workspace/chat-sessions-sidebar.tsx @@ -9,7 +9,7 @@ import { DropdownMenuTrigger, } from "../ui/dropdown-menu"; -type WebSession = { +export type WebSession = { id: string; title: string; createdAt: number; @@ -55,6 +55,8 @@ type ChatSessionsSidebarProps = { onCollapse?: () => void; /** When true, show a loader instead of empty state (e.g. initial sessions fetch). */ loading?: boolean; + /** When true, renders just the content without the aside wrapper (for embedding in another sidebar). */ + embedded?: boolean; }; /** Format a timestamp into a human-readable relative time string. */ @@ -164,6 +166,7 @@ export function ChatSessionsSidebar({ onClose, width: widthProp, loading = false, + embedded = false, }: ChatSessionsSidebarProps) { const [hoveredId, setHoveredId] = useState(null); const [renamingId, setRenamingId] = useState(null); @@ -229,24 +232,13 @@ export function ChatSessionsSidebar({ const grouped = groupSessions(filteredSessions); const width = mobile ? "280px" : (widthProp ?? 260); - const headerHeight = 40; // px — match padding so list content clears the overlay - const sidebar = ( -