From 360e21eee4ec4ab0458f82ce813d583a6d059a62 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Tue, 28 Apr 2026 23:58:00 +0530 Subject: [PATCH] feat(icon-rail, layout): enhance IconRail with new chat functionality and navigation items; update LayoutShell to support collapsible sidebar and integrate new actions --- .../layout/ui/icon-rail/IconRail.tsx | 62 +++++++++++- .../layout/ui/shell/LayoutShell.tsx | 96 +++++++++++-------- .../components/layout/ui/sidebar/Sidebar.tsx | 6 +- .../layout/ui/sidebar/SidebarButton.tsx | 7 +- .../ui/sidebar/SidebarCollapseButton.tsx | 2 +- .../components/layout/ui/tabs/TabBar.tsx | 24 ++++- 6 files changed, 145 insertions(+), 52 deletions(-) diff --git a/surfsense_web/components/layout/ui/icon-rail/IconRail.tsx b/surfsense_web/components/layout/ui/icon-rail/IconRail.tsx index 756d6ffaf..c4b127c63 100644 --- a/surfsense_web/components/layout/ui/icon-rail/IconRail.tsx +++ b/surfsense_web/components/layout/ui/icon-rail/IconRail.tsx @@ -1,11 +1,11 @@ "use client"; -import { Plus } from "lucide-react"; +import { Plus, SquarePen } from "lucide-react"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; -import type { SearchSpace } from "../../types/layout.types"; +import type { NavItem, SearchSpace } from "../../types/layout.types"; import type { User } from "../../types/layout.types"; import { SidebarUserProfile } from "../sidebar/SidebarUserProfile"; import { SearchSpaceAvatar } from "./SearchSpaceAvatar"; @@ -17,6 +17,10 @@ interface IconRailProps { onSearchSpaceDelete?: (searchSpace: SearchSpace) => void; onSearchSpaceSettings?: (searchSpace: SearchSpace) => void; onAddSearchSpace: () => void; + isSingleRailMode?: boolean; + onNewChat?: () => void; + navItems?: NavItem[]; + onNavItemClick?: (item: NavItem) => void; user: User; onUserSettings?: () => void; onLogout?: () => void; @@ -32,6 +36,10 @@ export function IconRail({ onSearchSpaceDelete, onSearchSpaceSettings, onAddSearchSpace, + isSingleRailMode = false, + onNewChat, + navItems = [], + onNavItemClick, user, onUserSettings, onLogout, @@ -39,6 +47,29 @@ export function IconRail({ setTheme, className, }: IconRailProps) { + const actionItems = isSingleRailMode + ? [ + ...(onNewChat + ? [ + { + key: "new-chat", + label: "New chat", + onClick: onNewChat, + icon: SquarePen, + isActive: false, + }, + ] + : []), + ...navItems.map((item) => ({ + key: item.url, + label: item.title, + onClick: () => onNavItemClick?.(item), + icon: item.icon, + isActive: !!item.isActive, + })), + ] + : []; + return (
@@ -75,6 +106,33 @@ export function IconRail({ Add search space + + {actionItems.length > 0 && ( + <> +
+ {actionItems.map(({ key, label, onClick, icon: Icon, isActive }) => ( + + + + + + {label} + + + ))} + + )}
void; onNewChat?: () => void; + leftActions?: React.ReactNode; children: React.ReactNode; }) { const activeTab = useAtomValue(activeTabAtom); @@ -136,6 +139,7 @@ function MainContentPanel({ } className="min-w-0" /> @@ -377,9 +381,9 @@ export function LayoutShell({
-
+