From 62c0573b1cede169c47b46dd28515b5c7268d957 Mon Sep 17 00:00:00 2001
From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com>
Date: Mon, 6 Jul 2026 11:11:53 +0530
Subject: [PATCH] feat(sidebar): enhance document management UI and improve
layout structure
- Updated the FolderTreeView component to clarify upload instructions.
- Introduced a new renderDocumentTree function in DocumentsSidebar for better organization and readability.
- Refactored the Sidebar component to utilize SidebarSection for improved layout consistency.
- Added contentClassName prop to SidebarSection for flexible styling options.
---
.../components/documents/FolderTreeView.tsx | 2 +-
.../layout/ui/sidebar/DocumentsSidebar.tsx | 181 +++++++++++-------
.../components/layout/ui/sidebar/Sidebar.tsx | 9 +-
.../layout/ui/sidebar/SidebarSection.tsx | 6 +-
4 files changed, 126 insertions(+), 72 deletions(-)
diff --git a/surfsense_web/components/documents/FolderTreeView.tsx b/surfsense_web/components/documents/FolderTreeView.tsx
index 7f1c2186e..daa23408f 100644
--- a/surfsense_web/components/documents/FolderTreeView.tsx
+++ b/surfsense_web/components/documents/FolderTreeView.tsx
@@ -336,7 +336,7 @@ export function FolderTreeView({
No documents found
- Use the upload button or connect a source above
+ Use the plus menu to upload files or manage connectors
);
diff --git a/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx b/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx
index 094ecab46..bf2e185a7 100644
--- a/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx
+++ b/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx
@@ -1097,6 +1097,81 @@ function AuthenticatedDocumentsSidebarBase({
currentFilesystemTab === "cloud" &&
(zeroFoldersResult.type !== "complete" || zeroAllDocsResult.type !== "complete");
+ const renderDocumentTree = ({
+ documents = searchFilteredDocuments,
+ activeTypesForTree = activeTypes,
+ searchQuery = debouncedSearch.trim() || undefined,
+ }: {
+ documents?: DocumentNodeDoc[];
+ activeTypesForTree?: DocumentTypeEnum[];
+ searchQuery?: string;
+ } = {}) => (
+
+ {deletableSelectedIds.length > 0 && (
+
+
+
+ )}
+
+ {showCloudSkeleton ? (
+
+ ) : (
+
{
+ if (openMemoryDocument(doc)) return;
+ openEditorPanel({
+ documentId: doc.id,
+ searchSpaceId,
+ title: doc.title,
+ });
+ }}
+ onEditDocument={(doc) => {
+ if (openMemoryDocument(doc)) return;
+ openEditorPanel({
+ documentId: doc.id,
+ searchSpaceId,
+ title: doc.title,
+ });
+ }}
+ onDeleteDocument={(doc) => handleDeleteDocument(doc.id)}
+ onMoveDocument={handleMoveDocument}
+ onResetDocument={handleResetMemoryDocument}
+ onExportDocument={handleExportDocument}
+ onVersionHistory={(doc) => setVersionDocId(doc.id)}
+ activeTypes={activeTypesForTree}
+ onDropIntoFolder={handleDropIntoFolder}
+ onReorderFolder={handleReorderFolder}
+ watchedFolderIds={watchedFolderIds}
+ onRescanFolder={handleRescanFolder}
+ onStopWatchingFolder={handleStopWatching}
+ onExportFolder={handleExportFolder}
+ />
+ )}
+
+ );
+
const cloudContent = (
<>
{isElectron && (
@@ -1124,70 +1199,7 @@ function AuthenticatedDocumentsSidebarBase({
/>
-
- {deletableSelectedIds.length > 0 && (
-
-
-
- )}
-
- {showCloudSkeleton ? (
-
- ) : (
-
{
- if (openMemoryDocument(doc)) return;
- openEditorPanel({
- documentId: doc.id,
- searchSpaceId,
- title: doc.title,
- });
- }}
- onEditDocument={(doc) => {
- if (openMemoryDocument(doc)) return;
- openEditorPanel({
- documentId: doc.id,
- searchSpaceId,
- title: doc.title,
- });
- }}
- onDeleteDocument={(doc) => handleDeleteDocument(doc.id)}
- onMoveDocument={handleMoveDocument}
- onResetDocument={handleResetMemoryDocument}
- onExportDocument={handleExportDocument}
- onVersionHistory={(doc) => setVersionDocId(doc.id)}
- activeTypes={activeTypes}
- onDropIntoFolder={handleDropIntoFolder}
- onReorderFolder={handleReorderFolder}
- watchedFolderIds={watchedFolderIds}
- onRescanFolder={handleRescanFolder}
- onStopWatchingFolder={handleStopWatching}
- onExportFolder={handleExportFolder}
- />
- )}
-
+ {renderDocumentTree()}
>
);
@@ -1459,8 +1471,12 @@ function AuthenticatedDocumentsSidebarBase({
if (embedded) {
return (
-
- {documentsContent}
+
+ {renderDocumentTree({
+ documents: treeDocumentsWithMemory,
+ activeTypesForTree: [],
+ searchQuery: undefined,
+ })}
);
}
@@ -1830,8 +1846,37 @@ function AnonymousDocumentsSidebar({
if (embedded) {
return (
-
- {documentsContent}
+
+ {}}
+ mentionedDocKeys={mentionedDocKeys}
+ onToggleChatMention={handleToggleChatMention}
+ onToggleFolderSelect={() => {}}
+ onRenameFolder={() => gate("rename folders")}
+ onDeleteFolder={() => gate("delete folders")}
+ onMoveFolder={() => gate("organize folders")}
+ onCreateFolder={() => gate("create folders")}
+ onPreviewDocument={() => gate("preview documents")}
+ onEditDocument={() => gate("edit documents")}
+ onDeleteDocument={async () => {
+ handleRemoveDoc();
+ setSidebarDocs((prev) => prev.filter((d) => d.kind !== "doc" || d.id !== -1));
+ return true;
+ }}
+ onMoveDocument={() => gate("organize documents")}
+ onExportDocument={() => gate("export documents")}
+ onVersionHistory={() => gate("view version history")}
+ activeTypes={[]}
+ onDropIntoFolder={async () => gate("organize documents")}
+ onReorderFolder={async () => gate("organize folders")}
+ watchedFolderIds={new Set()}
+ onRescanFolder={() => gate("watch local folders")}
+ onStopWatchingFolder={() => gate("watch local folders")}
+ onExportFolder={() => gate("export folders")}
+ />
);
}
diff --git a/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx b/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx
index 589c82eb8..27370d30f 100644
--- a/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx
+++ b/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx
@@ -336,13 +336,18 @@ export function Sidebar({
)}
{documentsPanel?.open ? (
-
+
-
+
) : null}
)}
diff --git a/surfsense_web/components/layout/ui/sidebar/SidebarSection.tsx b/surfsense_web/components/layout/ui/sidebar/SidebarSection.tsx
index c041dec86..573173cf5 100644
--- a/surfsense_web/components/layout/ui/sidebar/SidebarSection.tsx
+++ b/surfsense_web/components/layout/ui/sidebar/SidebarSection.tsx
@@ -13,6 +13,7 @@ interface SidebarSectionProps {
alwaysShowAction?: boolean;
persistentAction?: React.ReactNode;
className?: string;
+ contentClassName?: string;
fillHeight?: boolean;
}
@@ -24,6 +25,7 @@ export function SidebarSection({
alwaysShowAction = false,
persistentAction,
className,
+ contentClassName,
fillHeight = false,
}: SidebarSectionProps) {
const [isOpen, setIsOpen] = useState(defaultOpen);
@@ -69,7 +71,9 @@ export function SidebarSection({
- {children}
+
+ {children}
+
);