From 6ccb2bb8727549239562774e886ddbef01993c8c Mon Sep 17 00:00:00 2001
From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com>
Date: Tue, 27 Jan 2026 16:39:39 +0000
Subject: [PATCH] feat(export): add metadata file to preserve page icons and
ordering on import (#1877)
* feat(export): add metadata file to preserve page icons and ordering on import
- Export includes `docmost-metadata.json`
- Import reads metadata to restore icons and sort siblings by original position
* cleanup
* bonus fixes
* handle unknown prosemirror nodes
* add docmost app version
---
.../page/components/page-import-modal.tsx | 4 ++
.../space/components/delete-space-modal.tsx | 7 ++-
.../src/collaboration/collaboration.util.ts | 49 ++++++++++++++++++-
.../helpers/types/export-metadata.types.ts | 14 ++++++
.../src/integrations/export/export.service.ts | 34 ++++++++++++-
.../integrations/import/dto/file-task-dto.ts | 1 +
.../services/file-import-task.service.ts | 44 +++++++++++++++--
.../integrations/import/utils/import.utils.ts | 34 ++++++++++++-
8 files changed, 178 insertions(+), 9 deletions(-)
create mode 100644 apps/server/src/common/helpers/types/export-metadata.types.ts
diff --git a/apps/client/src/features/page/components/page-import-modal.tsx b/apps/client/src/features/page/components/page-import-modal.tsx
index a2df380e..be0264b6 100644
--- a/apps/client/src/features/page/components/page-import-modal.tsx
+++ b/apps/client/src/features/page/components/page-import-modal.tsx
@@ -172,6 +172,10 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) {
queryKey: ["root-sidebar-pages", fileTask.spaceId],
});
+ await queryClient.invalidateQueries({
+ queryKey: ["recent-changes", fileTask.spaceId],
+ });
+
setTimeout(() => {
emit({
operation: "refetchRootTreeNodeEvent",
diff --git a/apps/client/src/features/space/components/delete-space-modal.tsx b/apps/client/src/features/space/components/delete-space-modal.tsx
index f697322d..8a89e720 100644
--- a/apps/client/src/features/space/components/delete-space-modal.tsx
+++ b/apps/client/src/features/space/components/delete-space-modal.tsx
@@ -6,6 +6,7 @@ import { ISpace } from "../types/space.types";
import { useNavigate } from "react-router-dom";
import APP_ROUTE from "@/lib/app-route";
import { Trans, useTranslation } from "react-i18next";
+import { useState } from "react";
interface DeleteSpaceModalProps {
space: ISpace;
@@ -14,6 +15,7 @@ interface DeleteSpaceModalProps {
export default function DeleteSpaceModal({ space }: DeleteSpaceModalProps) {
const { t } = useTranslation();
const [opened, { open, close }] = useDisclosure(false);
+ const [isDeleting, setIsDeleting] = useState(false);
const deleteSpaceMutation = useDeleteSpaceMutation();
const navigate = useNavigate();
@@ -35,12 +37,15 @@ export default function DeleteSpaceModal({ space }: DeleteSpaceModalProps) {
return;
}
+ setIsDeleting(true);
try {
// pass slug too so we can clear the local cache
await deleteSpaceMutation.mutateAsync({ id: space.id, slug: space.slug });
navigate(APP_ROUTE.HOME);
} catch (error) {
console.error("Failed to delete space", error);
+ } finally {
+ setIsDeleting(false);
}
};
@@ -79,7 +84,7 @@ export default function DeleteSpaceModal({ space }: DeleteSpaceModalProps) {
-