diff --git a/surfsense_backend/app/routes/editor_routes.py b/surfsense_backend/app/routes/editor_routes.py
index f54f18def..0fcbc475d 100644
--- a/surfsense_backend/app/routes/editor_routes.py
+++ b/surfsense_backend/app/routes/editor_routes.py
@@ -127,9 +127,16 @@ async def get_editor_content(
chunks = sorted(document.chunks, key=lambda c: c.id)
if not chunks:
+ doc_status = document.status or {}
+ state = doc_status.get("state", "ready") if isinstance(doc_status, dict) else "ready"
+ if state in ("pending", "processing"):
+ raise HTTPException(
+ status_code=409,
+ detail="This document is still being processed. Please wait a moment and try again.",
+ )
raise HTTPException(
status_code=400,
- detail="This document has no content and cannot be edited. Please re-upload to enable editing.",
+ detail="This document has no viewable content yet. It may still be syncing. Try again in a few seconds, or re-upload if the issue persists.",
)
markdown_content = "\n\n".join(chunk.content for chunk in chunks)
@@ -137,7 +144,7 @@ async def get_editor_content(
if not markdown_content.strip():
raise HTTPException(
status_code=400,
- detail="This document has empty content and cannot be edited.",
+ detail="This document appears to be empty. Try re-uploading or editing it to add content.",
)
# Persist the lazy migration
diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx
index 92ced6e47..0758307f7 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx
@@ -748,6 +748,7 @@ export function DocumentsTableShell({
onClick={() =>
onOpenInTab ? onOpenInTab(doc) : handleViewDocument(doc)
}
+ disabled={isBeingProcessed}
>
Open
@@ -1020,6 +1021,10 @@ export function DocumentsTableShell({
e.stopPropagation()}>
- onPreview(doc)}>
+ onPreview(doc)} disabled={isProcessing}>
Open
@@ -259,7 +259,7 @@ export const DocumentNode = React.memo(function DocumentNode({
{contextMenuOpen && (
e.stopPropagation()}>
- onPreview(doc)}>
+ onPreview(doc)} disabled={isProcessing}>
Open
diff --git a/surfsense_web/components/documents/FolderTreeView.tsx b/surfsense_web/components/documents/FolderTreeView.tsx
index f63d5da5c..7695923e3 100644
--- a/surfsense_web/components/documents/FolderTreeView.tsx
+++ b/surfsense_web/components/documents/FolderTreeView.tsx
@@ -1,7 +1,7 @@
"use client";
import { useAtom } from "jotai";
-import { CirclePlus } from "lucide-react";
+import { Search } from "lucide-react";
import { useCallback, useMemo, useState } from "react";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
@@ -250,8 +250,9 @@ export function FolderTreeView({
if (treeNodes.length === 0 && (activeTypes.length > 0 || searchQuery)) {
return (
-
-
No matching documents
+
+
No matching documents
+
Try a different search term
);
}
diff --git a/surfsense_web/components/editor-panel/editor-panel.tsx b/surfsense_web/components/editor-panel/editor-panel.tsx
index 3ea36f800..7496e6aec 100644
--- a/surfsense_web/components/editor-panel/editor-panel.tsx
+++ b/surfsense_web/components/editor-panel/editor-panel.tsx
@@ -1,7 +1,7 @@
"use client";
import { useAtomValue, useSetAtom } from "jotai";
-import { AlertCircle, XIcon } from "lucide-react";
+import { FileQuestionMark, RefreshCw, XIcon } from "lucide-react";
import dynamic from "next/dynamic";
import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "sonner";
@@ -200,10 +200,22 @@ export function EditorPanelContent({
) : error || !editorDoc ? (
-
-
-
Failed to load document
-
{error || "An unknown error occurred"}
+ {error?.toLowerCase().includes("still being processed") ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
+
+ {error?.toLowerCase().includes("still being processed")
+ ? "Document is processing"
+ : "Document unavailable"}
+
+
{error || "An unknown error occurred"}
) : isEditableType ? (
diff --git a/surfsense_web/components/layout/ui/tabs/DocumentTabContent.tsx b/surfsense_web/components/layout/ui/tabs/DocumentTabContent.tsx
index ac279cd4d..849bdbea5 100644
--- a/surfsense_web/components/layout/ui/tabs/DocumentTabContent.tsx
+++ b/surfsense_web/components/layout/ui/tabs/DocumentTabContent.tsx
@@ -1,6 +1,6 @@
"use client";
-import { AlertCircle, Pencil } from "lucide-react";
+import { FileQuestionMark, PenLine, RefreshCw } from "lucide-react";
import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { PlateEditor } from "@/components/editor/plate-editor";
@@ -160,15 +160,35 @@ export function DocumentTabContent({ documentId, searchSpaceId, title }: Documen
if (isLoading) return ;
if (error || !doc) {
+ const isProcessing = error?.toLowerCase().includes("still being processed");
return (
-
-
-
-
Failed to load document
-
+
+
+ {isProcessing ? (
+
+ ) : (
+
+ )}
+
+
+
+ {isProcessing ? "Document is processing" : "Document unavailable"}
+
+
{error || "An unknown error occurred"}
+ {!isProcessing && (
+
+ )}
);
}
@@ -229,7 +249,7 @@ export function DocumentTabContent({ documentId, searchSpaceId, title }: Documen
onClick={() => setIsEditing(true)}
className="gap-1.5"
>
-
+
Edit
)}
diff --git a/surfsense_web/components/new-chat/source-detail-panel.tsx b/surfsense_web/components/new-chat/source-detail-panel.tsx
index b02b2e217..9c1167efe 100644
--- a/surfsense_web/components/new-chat/source-detail-panel.tsx
+++ b/surfsense_web/components/new-chat/source-detail-panel.tsx
@@ -1,7 +1,7 @@
"use client";
import { useQuery } from "@tanstack/react-query";
-import { BookOpen, ChevronDown, ExternalLink, FileText, Hash, Sparkles, X } from "lucide-react";
+import { BookOpen, ChevronDown, ExternalLink, FileQuestionMark, FileText, Hash, Sparkles, X } from "lucide-react";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import { useTranslations } from "next-intl";
import type React from "react";
@@ -392,12 +392,12 @@ export function SourceDetailPanel({
animate={{ opacity: 1, scale: 1 }}
className="flex flex-col items-center gap-4 text-center px-6"
>
-