mirror of
https://github.com/docmost/docmost.git
synced 2026-05-15 13:14:11 +08:00
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
This commit is contained in:
@@ -20,11 +20,17 @@ import {
|
||||
replaceInternalLinks,
|
||||
updateAttachmentUrlsToLocalPaths,
|
||||
} from './utils';
|
||||
import {
|
||||
ExportMetadata,
|
||||
ExportPageMetadata,
|
||||
} from '../../common/helpers/types/export-metadata.types';
|
||||
import { PageRepo } from '@docmost/db/repos/page/page.repo';
|
||||
import { Node } from '@tiptap/pm/model';
|
||||
import { EditorState } from '@tiptap/pm/state';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import slugify = require('@sindresorhus/slugify');
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const packageJson = require('../../../package.json');
|
||||
import { EnvironmentService } from '../environment/environment.service';
|
||||
import {
|
||||
getAttachmentIds,
|
||||
@@ -155,12 +161,15 @@ export class ExportService {
|
||||
'pages.id',
|
||||
'pages.slugId',
|
||||
'pages.title',
|
||||
'pages.icon',
|
||||
'pages.position',
|
||||
'pages.content',
|
||||
'pages.parentPageId',
|
||||
'pages.spaceId',
|
||||
'pages.workspaceId',
|
||||
])
|
||||
.where('spaceId', '=', spaceId)
|
||||
.where('deletedAt', 'is', null)
|
||||
.execute();
|
||||
|
||||
const tree = buildTree(pages as Page[]);
|
||||
@@ -189,10 +198,12 @@ export class ExportService {
|
||||
includeAttachments: boolean,
|
||||
): Promise<void> {
|
||||
const slugIdToPath: Record<string, string> = {};
|
||||
const pageIdToFilePath: Record<string, string> = {};
|
||||
const pagesMetadata: Record<string, ExportPageMetadata> = {};
|
||||
|
||||
computeLocalPath(tree, format, null, '', slugIdToPath);
|
||||
|
||||
const stack: { folder: JSZip; parentPageId: string }[] = [
|
||||
const stack: { folder: JSZip; parentPageId: string | null }[] = [
|
||||
{ folder: zip, parentPageId: null },
|
||||
];
|
||||
|
||||
@@ -232,12 +243,33 @@ export class ExportService {
|
||||
`${pageTitle}${getExportExtension(format)}`,
|
||||
pageExportContent,
|
||||
);
|
||||
|
||||
pageIdToFilePath[page.id] = currentPagePath;
|
||||
|
||||
const parentPath = parentPageId ? pageIdToFilePath[parentPageId] : null;
|
||||
pagesMetadata[currentPagePath] = {
|
||||
pageId: page.id,
|
||||
slugId: page.slugId,
|
||||
icon: page.icon ?? null,
|
||||
position: page.position,
|
||||
parentPath,
|
||||
};
|
||||
|
||||
if (childPages.length > 0) {
|
||||
const pageFolder = folder.folder(pageTitle);
|
||||
stack.push({ folder: pageFolder, parentPageId: page.id });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const metadata: ExportMetadata = {
|
||||
exportedAt: new Date().toISOString(),
|
||||
source: 'docmost',
|
||||
version: packageJson.version,
|
||||
pages: pagesMetadata,
|
||||
};
|
||||
|
||||
zip.file('docmost-metadata.json', JSON.stringify(metadata, null, 2));
|
||||
}
|
||||
|
||||
async zipAttachments(prosemirrorJson: any, spaceId: string, zip: JSZip) {
|
||||
|
||||
Reference in New Issue
Block a user