mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 00:36:31 +02:00
refactor: improve document processing error handling and UI state management
This commit is contained in:
parent
635cdde0eb
commit
ec27807644
3 changed files with 80 additions and 69 deletions
|
|
@ -139,9 +139,19 @@ async def get_editor_content(
|
|||
status_code=409,
|
||||
detail="This document is still being processed. Please wait a moment and try again.",
|
||||
)
|
||||
if state == "failed":
|
||||
reason = (
|
||||
doc_status.get("reason", "Unknown error")
|
||||
if isinstance(doc_status, dict)
|
||||
else "Unknown error"
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=422,
|
||||
detail=f"Processing failed: {reason}. You can delete this document and re-upload it.",
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
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.",
|
||||
detail="This document has no content. It may not have been processed correctly. Try deleting and re-uploading it.",
|
||||
)
|
||||
|
||||
markdown_content = "\n\n".join(chunk_contents)
|
||||
|
|
|
|||
|
|
@ -82,11 +82,12 @@ export const DocumentNode = React.memo(function DocumentNode({
|
|||
onContextMenuOpenChange,
|
||||
}: DocumentNodeProps) {
|
||||
const statusState = doc.status?.state ?? "ready";
|
||||
const isSelectable = statusState !== "pending" && statusState !== "processing";
|
||||
const isFailed = statusState === "failed";
|
||||
const isProcessing = statusState === "pending" || statusState === "processing";
|
||||
const isUnavailable = isProcessing || isFailed;
|
||||
const isSelectable = !isUnavailable;
|
||||
const isEditable =
|
||||
EDITABLE_DOCUMENT_TYPES.has(doc.document_type) &&
|
||||
statusState !== "pending" &&
|
||||
statusState !== "processing";
|
||||
EDITABLE_DOCUMENT_TYPES.has(doc.document_type) && !isUnavailable;
|
||||
|
||||
const handleCheckChange = useCallback(() => {
|
||||
if (isSelectable) {
|
||||
|
|
@ -103,7 +104,6 @@ export const DocumentNode = React.memo(function DocumentNode({
|
|||
[doc.id]
|
||||
);
|
||||
|
||||
const isProcessing = statusState === "pending" || statusState === "processing";
|
||||
const [dropdownOpen, setDropdownOpen] = useState(false);
|
||||
const [exporting, setExporting] = useState<string | null>(null);
|
||||
const [titleTooltipOpen, setTitleTooltipOpen] = useState(false);
|
||||
|
|
@ -261,38 +261,38 @@ export const DocumentNode = React.memo(function DocumentNode({
|
|||
className="w-40"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<DropdownMenuItem onClick={() => onPreview(doc)} disabled={isProcessing}>
|
||||
<Eye className="mr-2 h-4 w-4" />
|
||||
Open
|
||||
<DropdownMenuItem onClick={() => onPreview(doc)} disabled={isUnavailable}>
|
||||
<Eye className="mr-2 h-4 w-4" />
|
||||
Open
|
||||
</DropdownMenuItem>
|
||||
{isEditable && (
|
||||
<DropdownMenuItem onClick={() => onEdit(doc)}>
|
||||
<PenLine className="mr-2 h-4 w-4" />
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
{isEditable && (
|
||||
<DropdownMenuItem onClick={() => onEdit(doc)}>
|
||||
<PenLine className="mr-2 h-4 w-4" />
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem onClick={() => onMove(doc)}>
|
||||
<Move className="mr-2 h-4 w-4" />
|
||||
Move to...
|
||||
)}
|
||||
<DropdownMenuItem onClick={() => onMove(doc)}>
|
||||
<Move className="mr-2 h-4 w-4" />
|
||||
Move to...
|
||||
</DropdownMenuItem>
|
||||
{onExport && (
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger disabled={isUnavailable}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export
|
||||
</DropdownMenuSubTrigger>
|
||||
<DropdownMenuSubContent className="min-w-[180px]">
|
||||
<ExportDropdownItems onExport={handleExport} exporting={exporting} />
|
||||
</DropdownMenuSubContent>
|
||||
</DropdownMenuSub>
|
||||
)}
|
||||
{onVersionHistory && isVersionableType(doc.document_type) && (
|
||||
<DropdownMenuItem disabled={isUnavailable} onClick={() => onVersionHistory(doc)}>
|
||||
<History className="mr-2 h-4 w-4" />
|
||||
Versions
|
||||
</DropdownMenuItem>
|
||||
{onExport && (
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger disabled={isProcessing}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export
|
||||
</DropdownMenuSubTrigger>
|
||||
<DropdownMenuSubContent className="min-w-[180px]">
|
||||
<ExportDropdownItems onExport={handleExport} exporting={exporting} />
|
||||
</DropdownMenuSubContent>
|
||||
</DropdownMenuSub>
|
||||
)}
|
||||
{onVersionHistory && isVersionableType(doc.document_type) && (
|
||||
<DropdownMenuItem disabled={isProcessing} onClick={() => onVersionHistory(doc)}>
|
||||
<History className="mr-2 h-4 w-4" />
|
||||
Versions
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem disabled={isProcessing} onClick={() => onDelete(doc)}>
|
||||
)}
|
||||
<DropdownMenuItem disabled={isProcessing} onClick={() => onDelete(doc)}>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Delete
|
||||
</DropdownMenuItem>
|
||||
|
|
@ -304,38 +304,38 @@ export const DocumentNode = React.memo(function DocumentNode({
|
|||
|
||||
{contextMenuOpen && (
|
||||
<ContextMenuContent className="w-40" onClick={(e) => e.stopPropagation()}>
|
||||
<ContextMenuItem onClick={() => onPreview(doc)} disabled={isProcessing}>
|
||||
<Eye className="mr-2 h-4 w-4" />
|
||||
Open
|
||||
<ContextMenuItem onClick={() => onPreview(doc)} disabled={isUnavailable}>
|
||||
<Eye className="mr-2 h-4 w-4" />
|
||||
Open
|
||||
</ContextMenuItem>
|
||||
{isEditable && (
|
||||
<ContextMenuItem onClick={() => onEdit(doc)}>
|
||||
<PenLine className="mr-2 h-4 w-4" />
|
||||
Edit
|
||||
</ContextMenuItem>
|
||||
{isEditable && (
|
||||
<ContextMenuItem onClick={() => onEdit(doc)}>
|
||||
<PenLine className="mr-2 h-4 w-4" />
|
||||
Edit
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
<ContextMenuItem onClick={() => onMove(doc)}>
|
||||
<Move className="mr-2 h-4 w-4" />
|
||||
Move to...
|
||||
)}
|
||||
<ContextMenuItem onClick={() => onMove(doc)}>
|
||||
<Move className="mr-2 h-4 w-4" />
|
||||
Move to...
|
||||
</ContextMenuItem>
|
||||
{onExport && (
|
||||
<ContextMenuSub>
|
||||
<ContextMenuSubTrigger disabled={isUnavailable}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export
|
||||
</ContextMenuSubTrigger>
|
||||
<ContextMenuSubContent className="min-w-[180px]">
|
||||
<ExportContextItems onExport={handleExport} exporting={exporting} />
|
||||
</ContextMenuSubContent>
|
||||
</ContextMenuSub>
|
||||
)}
|
||||
{onVersionHistory && isVersionableType(doc.document_type) && (
|
||||
<ContextMenuItem disabled={isUnavailable} onClick={() => onVersionHistory(doc)}>
|
||||
<History className="mr-2 h-4 w-4" />
|
||||
Versions
|
||||
</ContextMenuItem>
|
||||
{onExport && (
|
||||
<ContextMenuSub>
|
||||
<ContextMenuSubTrigger disabled={isProcessing}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export
|
||||
</ContextMenuSubTrigger>
|
||||
<ContextMenuSubContent className="min-w-[180px]">
|
||||
<ExportContextItems onExport={handleExport} exporting={exporting} />
|
||||
</ContextMenuSubContent>
|
||||
</ContextMenuSub>
|
||||
)}
|
||||
{onVersionHistory && isVersionableType(doc.document_type) && (
|
||||
<ContextMenuItem disabled={isProcessing} onClick={() => onVersionHistory(doc)}>
|
||||
<History className="mr-2 h-4 w-4" />
|
||||
Versions
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
<ContextMenuItem disabled={isProcessing} onClick={() => onDelete(doc)}>
|
||||
)}
|
||||
<ContextMenuItem disabled={isProcessing} onClick={() => onDelete(doc)}>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Delete
|
||||
</ContextMenuItem>
|
||||
|
|
|
|||
|
|
@ -627,9 +627,10 @@ export function DocumentsSidebar({
|
|||
function collectSubtreeDocs(parentId: number): DocumentNodeDoc[] {
|
||||
const directDocs = (treeDocuments ?? []).filter(
|
||||
(d) =>
|
||||
d.folderId === parentId &&
|
||||
d.status?.state !== "pending" &&
|
||||
d.status?.state !== "processing"
|
||||
d.folderId === parentId &&
|
||||
d.status?.state !== "pending" &&
|
||||
d.status?.state !== "processing" &&
|
||||
d.status?.state !== "failed"
|
||||
);
|
||||
const childFolders = foldersByParent[String(parentId)] ?? [];
|
||||
const descendantDocs = childFolders.flatMap((cf) => collectSubtreeDocs(cf.id));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue