mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-25 19:15:18 +02:00
feat: enhance document export functionality for memory documents and update UI components
This commit is contained in:
parent
43c8aaeaa7
commit
659007bc4d
3 changed files with 48 additions and 5 deletions
|
|
@ -328,7 +328,12 @@ export const DocumentNode = React.memo(function DocumentNode({
|
||||||
Move to...
|
Move to...
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
{onExport && (
|
{onExport && isMemoryDocument ? (
|
||||||
|
<DropdownMenuItem disabled={isUnavailable} onClick={() => handleExport("md")}>
|
||||||
|
<Download className="mr-2 h-4 w-4" />
|
||||||
|
Export as MD
|
||||||
|
</DropdownMenuItem>
|
||||||
|
) : onExport ? (
|
||||||
<DropdownMenuSub>
|
<DropdownMenuSub>
|
||||||
<DropdownMenuSubTrigger disabled={isUnavailable}>
|
<DropdownMenuSubTrigger disabled={isUnavailable}>
|
||||||
<Download className="mr-2 h-4 w-4" />
|
<Download className="mr-2 h-4 w-4" />
|
||||||
|
|
@ -338,7 +343,7 @@ export const DocumentNode = React.memo(function DocumentNode({
|
||||||
<ExportDropdownItems onExport={handleExport} exporting={exporting} />
|
<ExportDropdownItems onExport={handleExport} exporting={exporting} />
|
||||||
</DropdownMenuSubContent>
|
</DropdownMenuSubContent>
|
||||||
</DropdownMenuSub>
|
</DropdownMenuSub>
|
||||||
)}
|
) : null}
|
||||||
{onVersionHistory && isVersionableType(doc.document_type) && (
|
{onVersionHistory && isVersionableType(doc.document_type) && (
|
||||||
<DropdownMenuItem disabled={isUnavailable} onClick={() => onVersionHistory(doc)}>
|
<DropdownMenuItem disabled={isUnavailable} onClick={() => onVersionHistory(doc)}>
|
||||||
<History className="mr-2 h-4 w-4" />
|
<History className="mr-2 h-4 w-4" />
|
||||||
|
|
@ -381,7 +386,12 @@ export const DocumentNode = React.memo(function DocumentNode({
|
||||||
Move to...
|
Move to...
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
)}
|
)}
|
||||||
{onExport && (
|
{onExport && isMemoryDocument ? (
|
||||||
|
<ContextMenuItem disabled={isUnavailable} onClick={() => handleExport("md")}>
|
||||||
|
<Download className="mr-2 h-4 w-4" />
|
||||||
|
Export as MD
|
||||||
|
</ContextMenuItem>
|
||||||
|
) : onExport ? (
|
||||||
<ContextMenuSub>
|
<ContextMenuSub>
|
||||||
<ContextMenuSubTrigger disabled={isUnavailable}>
|
<ContextMenuSubTrigger disabled={isUnavailable}>
|
||||||
<Download className="mr-2 h-4 w-4" />
|
<Download className="mr-2 h-4 w-4" />
|
||||||
|
|
@ -391,7 +401,7 @@ export const DocumentNode = React.memo(function DocumentNode({
|
||||||
<ExportContextItems onExport={handleExport} exporting={exporting} />
|
<ExportContextItems onExport={handleExport} exporting={exporting} />
|
||||||
</ContextMenuSubContent>
|
</ContextMenuSubContent>
|
||||||
</ContextMenuSub>
|
</ContextMenuSub>
|
||||||
)}
|
) : null}
|
||||||
{onVersionHistory && isVersionableType(doc.document_type) && (
|
{onVersionHistory && isVersionableType(doc.document_type) && (
|
||||||
<ContextMenuItem disabled={isUnavailable} onClick={() => onVersionHistory(doc)}>
|
<ContextMenuItem disabled={isUnavailable} onClick={() => onVersionHistory(doc)}>
|
||||||
<History className="mr-2 h-4 w-4" />
|
<History className="mr-2 h-4 w-4" />
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ export function FolderTreeView({
|
||||||
onDelete={onDeleteDocument}
|
onDelete={onDeleteDocument}
|
||||||
onMove={onMoveDocument}
|
onMove={onMoveDocument}
|
||||||
onReset={onResetDocument}
|
onReset={onResetDocument}
|
||||||
onExport={isMemoryDocument ? undefined : onExportDocument}
|
onExport={onExportDocument}
|
||||||
onVersionHistory={isMemoryDocument ? undefined : onVersionHistory}
|
onVersionHistory={isMemoryDocument ? undefined : onVersionHistory}
|
||||||
canDelete={!isMemoryDocument}
|
canDelete={!isMemoryDocument}
|
||||||
canMove={!isMemoryDocument}
|
canMove={!isMemoryDocument}
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,18 @@ const MEMORY_DOCUMENTS: DocumentNodeDoc[] = [
|
||||||
function isMemoryDocument(doc: { document_type: string }) {
|
function isMemoryDocument(doc: { document_type: string }) {
|
||||||
return doc.document_type === "USER_MEMORY" || doc.document_type === "TEAM_MEMORY";
|
return doc.document_type === "USER_MEMORY" || doc.document_type === "TEAM_MEMORY";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function downloadTextFile(content: string, fileName: string, type = "text/markdown;charset=utf-8") {
|
||||||
|
const blob = new Blob([content], { type });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
a.download = fileName;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
const LOCAL_FILESYSTEM_TRUST_KEY = "surfsense.local-filesystem-trust.v1";
|
const LOCAL_FILESYSTEM_TRUST_KEY = "surfsense.local-filesystem-trust.v1";
|
||||||
const MAX_LOCAL_FILESYSTEM_ROOTS = 10;
|
const MAX_LOCAL_FILESYSTEM_ROOTS = 10;
|
||||||
|
|
||||||
|
|
@ -808,6 +820,27 @@ function AuthenticatedDocumentsSidebarBase({
|
||||||
|
|
||||||
const handleExportDocument = useCallback(
|
const handleExportDocument = useCallback(
|
||||||
async (doc: DocumentNodeDoc, format: string) => {
|
async (doc: DocumentNodeDoc, format: string) => {
|
||||||
|
if (isMemoryDocument(doc)) {
|
||||||
|
try {
|
||||||
|
const endpoint =
|
||||||
|
doc.document_type === "USER_MEMORY"
|
||||||
|
? `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/users/me/memory`
|
||||||
|
: `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${searchSpaceId}/memory`;
|
||||||
|
const response = await authenticatedFetch(endpoint, { method: "GET" });
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json().catch(() => ({ detail: "Export failed" }));
|
||||||
|
throw new Error(errorData.detail || "Export failed");
|
||||||
|
}
|
||||||
|
const data = (await response.json()) as { memory_md?: string };
|
||||||
|
downloadTextFile(data.memory_md ?? "", doc.title.endsWith(".md") ? doc.title : `${doc.title}.md`);
|
||||||
|
return;
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Memory export failed:", err);
|
||||||
|
toast.error(err instanceof Error ? err.message : "Export failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const safeTitle =
|
const safeTitle =
|
||||||
doc.title
|
doc.title
|
||||||
.replace(/[^a-zA-Z0-9 _-]/g, "_")
|
.replace(/[^a-zA-Z0-9 _-]/g, "_")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue