diff --git a/surfsense_web/components/layout/providers/LayoutDataProvider.tsx b/surfsense_web/components/layout/providers/LayoutDataProvider.tsx index 322e136c0..96a2ce771 100644 --- a/surfsense_web/components/layout/providers/LayoutDataProvider.tsx +++ b/surfsense_web/components/layout/providers/LayoutDataProvider.tsx @@ -119,6 +119,19 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid // Documents sidebar state (shared atom so Composer can toggle it) const [isDocumentsSidebarOpen, setIsDocumentsSidebarOpen] = useAtom(documentsSidebarOpenAtom); + const [isDocumentsDocked, setIsDocumentsDocked] = useState(true); + + // Open documents sidebar by default on desktop (docked mode) + const documentsInitialized = useRef(false); + useEffect(() => { + if (!documentsInitialized.current) { + documentsInitialized.current = true; + const isDesktop = typeof window !== "undefined" && window.innerWidth >= 768; + if (isDesktop) { + setIsDocumentsSidebarOpen(true); + } + } + }, [setIsDocumentsSidebarOpen]); // Announcements sidebar state const [isAnnouncementsSidebarOpen, setIsAnnouncementsSidebarOpen] = useState(false); @@ -678,6 +691,8 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid documentsPanel={{ open: isDocumentsSidebarOpen, onOpenChange: setIsDocumentsSidebarOpen, + isDocked: isDocumentsDocked, + onDockedChange: setIsDocumentsDocked, }} > {children} diff --git a/surfsense_web/components/layout/ui/shell/LayoutShell.tsx b/surfsense_web/components/layout/ui/shell/LayoutShell.tsx index e872ab84a..64acc2a0f 100644 --- a/surfsense_web/components/layout/ui/shell/LayoutShell.tsx +++ b/surfsense_web/components/layout/ui/shell/LayoutShell.tsx @@ -97,6 +97,8 @@ interface LayoutShellProps { documentsPanel?: { open: boolean; onOpenChange: (open: boolean) => void; + isDocked?: boolean; + onDockedChange?: (docked: boolean) => void; }; } @@ -319,6 +321,16 @@ export function LayoutShell({ /> )} + {/* Docked Documents Sidebar - renders as flex sibling between sidebar and content */} + {documentsPanel?.isDocked && ( + + )} +
@@ -340,11 +352,13 @@ export function LayoutShell({ /> )} - {/* Documents Sidebar - slide-out panel */} - {documentsPanel && ( + {/* Documents Sidebar - floating slide-out panel (non-docked mode) */} + {documentsPanel && !documentsPanel.isDocked && ( )} diff --git a/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx b/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx index 1a21c4b54..e1ccc867b 100644 --- a/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx @@ -1,7 +1,7 @@ "use client"; import { useAtom, useAtomValue } from "jotai"; -import { ChevronLeft } from "lucide-react"; +import { ChevronLeft, ChevronRight } from "lucide-react"; import { useParams } from "next/navigation"; import { useTranslations } from "next-intl"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; @@ -14,6 +14,7 @@ import { import { sidebarSelectedDocumentsAtom } from "@/atoms/chat/mentioned-documents.atom"; import { deleteDocumentMutationAtom } from "@/atoms/documents/document-mutation.atoms"; import { Button } from "@/components/ui/button"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import type { DocumentTypeEnum } from "@/contracts/types/document.types"; import { useDebouncedValue } from "@/hooks/use-debounced-value"; import { useDocumentSearch } from "@/hooks/use-document-search"; @@ -24,9 +25,11 @@ import { SidebarSlideOutPanel } from "./SidebarSlideOutPanel"; interface DocumentsSidebarProps { open: boolean; onOpenChange: (open: boolean) => void; + isDocked?: boolean; + onDockedChange?: (docked: boolean) => void; } -export function DocumentsSidebar({ open, onOpenChange }: DocumentsSidebarProps) { +export function DocumentsSidebar({ open, onOpenChange, isDocked = false, onDockedChange }: DocumentsSidebarProps) { const t = useTranslations("documents"); const tSidebar = useTranslations("sidebar"); const params = useParams(); @@ -164,6 +167,37 @@ export function DocumentsSidebar({ open, onOpenChange }: DocumentsSidebarProps) )}

{t("title") || "Documents"}

+
+ {!isMobile && onDockedChange && ( + + + + + + {isDocked ? "Collapse panel" : "Expand panel"} + + + )} +
@@ -199,6 +233,17 @@ export function DocumentsSidebar({ open, onOpenChange }: DocumentsSidebarProps) ); + if (isDocked && open && !isMobile) { + return ( + + ); + } + return ( );