sidebar remake

This commit is contained in:
tusharmagar 2026-02-06 14:51:15 +05:30
parent eefc6a9700
commit cbe34aec8e
3 changed files with 51 additions and 111 deletions

View file

@ -13,7 +13,6 @@ import { ChatInputBar } from './components/chat-button';
import { ChatSidebar } from './components/chat-sidebar';
import { GraphView, type GraphEdge, type GraphNode } from '@/components/graph-view';
import { useDebounce } from './hooks/use-debounce';
import { SidebarIcon } from '@/components/sidebar-icon';
import { SidebarContentPanel } from '@/components/sidebar-content';
import { SidebarSectionProvider, type ActiveSection } from '@/contexts/sidebar-context';
import {
@ -1786,16 +1785,9 @@ function App() {
<TooltipProvider delayDuration={0}>
<SidebarSectionProvider defaultSection="tasks" onSectionChange={handleSectionChange}>
<div className="flex h-svh w-full">
{/* Icon sidebar - always visible, fixed position */}
<SidebarIcon />
{/* Spacer for the fixed icon sidebar */}
<div className="w-14 shrink-0" />
{/* Content sidebar with SidebarProvider for collapse functionality */}
<SidebarProvider
style={{
"--sidebar-offset": "3.5rem",
"--sidebar-width": `${DEFAULT_SIDEBAR_WIDTH}px`,
} as React.CSSProperties}
>

View file

@ -12,10 +12,13 @@ import {
FilePlus,
Folder,
FolderPlus,
HelpCircle,
Mic,
Network,
Pencil,
Plug,
LoaderIcon,
Settings,
Square,
SquarePen,
Trash2,
@ -53,7 +56,11 @@ import {
ContextMenuTrigger,
} from "@/components/ui/context-menu"
import { Input } from "@/components/ui/input"
import { useSidebarSection } from "@/contexts/sidebar-context"
import { cn } from "@/lib/utils"
import { type ActiveSection, useSidebarSection } from "@/contexts/sidebar-context"
import { ConnectorsPopover } from "@/components/connectors-popover"
import { HelpPopover } from "@/components/help-popover"
import { SettingsDialog } from "@/components/settings-dialog"
import { toast } from "@/lib/toast"
import { ServiceEvent } from "@x/shared/src/service-events.js"
import z from "zod"
@ -126,10 +133,10 @@ type SidebarContentPanelProps = {
selectedBackgroundTask?: string | null
} & React.ComponentProps<typeof Sidebar>
const sectionTitles = {
knowledge: "Knowledge",
tasks: "Chats",
}
const sectionTabs: { id: ActiveSection; label: string }[] = [
{ id: "tasks", label: "Chat" },
{ id: "knowledge", label: "Knowledge" },
]
function formatEventTime(ts: string): string {
const date = new Date(ts)
@ -199,7 +206,7 @@ function SyncStatusBar() {
{!isMobile && isCollapsed && isSyncing && (
<div
className="fixed bottom-4 z-40 flex h-8 w-8 items-center justify-center rounded-full border border-border bg-background shadow-sm"
style={{ left: "calc(var(--sidebar-offset) + 0.5rem)" }}
style={{ left: "0.5rem" }}
aria-label="Syncing"
>
<LoaderIcon className="h-4 w-4 animate-spin text-muted-foreground" />
@ -256,13 +263,28 @@ export function SidebarContentPanel({
selectedBackgroundTask,
...props
}: SidebarContentPanelProps) {
const { activeSection } = useSidebarSection()
const { activeSection, setActiveSection } = useSidebarSection()
return (
<Sidebar className="border-r-0" {...props}>
<SidebarHeader>
<div className="flex items-center gap-2 px-2 py-1.5">
<span className="font-semibold text-lg">{sectionTitles[activeSection]}</span>
<div className="flex items-center px-2 py-1.5">
<div className="flex w-full rounded-lg bg-sidebar-accent/50 p-0.5">
{sectionTabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveSection(tab.id)}
className={cn(
"flex-1 rounded-md px-3 py-1 text-sm font-medium transition-colors",
activeSection === tab.id
? "bg-sidebar-accent text-sidebar-accent-foreground shadow-sm"
: "text-sidebar-foreground/70 hover:text-sidebar-foreground"
)}
>
{tab.label}
</button>
))}
</div>
</div>
</SidebarHeader>
<SidebarContent>
@ -286,6 +308,26 @@ export function SidebarContentPanel({
/>
)}
</SidebarContent>
{/* Bottom actions */}
<div className="border-t border-sidebar-border px-2 py-2">
<div className="flex items-center justify-center gap-1">
<ConnectorsPopover tooltip="Connectors">
<button className="flex h-8 w-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground transition-colors">
<Plug className="size-4" />
</button>
</ConnectorsPopover>
<SettingsDialog>
<button className="flex h-8 w-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground transition-colors">
<Settings className="size-4" />
</button>
</SettingsDialog>
<HelpPopover tooltip="Help">
<button className="flex h-8 w-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground transition-colors">
<HelpCircle className="size-4" />
</button>
</HelpPopover>
</div>
</div>
<SyncStatusBar />
<SidebarRail />
</Sidebar>

View file

@ -1,94 +0,0 @@
"use client"
import * as React from "react"
import {
Brain,
HelpCircle,
MessageSquare,
Plug,
Settings,
} from "lucide-react"
import { cn } from "@/lib/utils"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip"
import { type ActiveSection, useSidebarSection } from "@/contexts/sidebar-context"
import { ConnectorsPopover } from "@/components/connectors-popover"
import { HelpPopover } from "@/components/help-popover"
import { SettingsDialog } from "@/components/settings-dialog"
type NavItem = {
id: ActiveSection
title: string
icon: React.ElementType
}
const navItems: NavItem[] = [
{ id: "tasks", title: "Chats", icon: MessageSquare },
{ id: "knowledge", title: "Knowledge", icon: Brain },
]
export function SidebarIcon() {
const { activeSection, setActiveSection } = useSidebarSection()
return (
<div className="bg-sidebar border-r border-sidebar-border flex h-svh w-14 flex-col items-center py-2 fixed left-0 top-0 z-50 shrink-0">
{/* Main navigation */}
<nav className="flex flex-1 flex-col items-center gap-1">
{navItems.map((item) => (
<Tooltip key={item.id}>
<TooltipTrigger asChild>
<button
onClick={() => setActiveSection(item.id)}
className={cn(
"flex h-10 w-10 items-center justify-center rounded-md transition-colors",
activeSection === item.id
? "bg-sidebar-accent text-sidebar-accent-foreground"
: "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
)}
>
<item.icon className="size-5" />
</button>
</TooltipTrigger>
<TooltipContent side="right" sideOffset={8}>
{item.title}
</TooltipContent>
</Tooltip>
))}
</nav>
{/* Secondary navigation (bottom) */}
<nav className="flex flex-col items-center gap-1">
{/* Connectors */}
<ConnectorsPopover tooltip="Connectors">
<button
className="flex h-10 w-10 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground transition-colors"
>
<Plug className="size-5" />
</button>
</ConnectorsPopover>
{/* Settings */}
<SettingsDialog>
<button
className="flex h-10 w-10 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground transition-colors"
>
<Settings className="size-5" />
</button>
</SettingsDialog>
{/* Help */}
<HelpPopover tooltip="Help">
<button
className="flex h-10 w-10 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground transition-colors"
>
<HelpCircle className="size-5" />
</button>
</HelpPopover>
</nav>
</div>
)
}