fix(editor): table data lost when converted to linked doc (#11212)

Closes: BS-2908
This commit is contained in:
Saul-Mirone
2025-03-26 13:07:22 +00:00
parent 42259f5546
commit ce39117953
2 changed files with 22 additions and 36 deletions
@@ -230,6 +230,7 @@ export const moreActions = [
if (!surfaceId) return; if (!surfaceId) return;
const linkedDoc = createLinkedDocFromNote(ctx.store, model, title); const linkedDoc = createLinkedDocFromNote(ctx.store, model, title);
if (!linkedDoc) return;
// Inserts linked doc card // Inserts linked doc card
const cardId = ctx.std.get(EdgelessCRUDIdentifier).addBlock( const cardId = ctx.std.get(EdgelessCRUDIdentifier).addBlock(
@@ -1,12 +1,12 @@
import { isFrameBlock } from '@blocksuite/affine-block-frame'; import { isFrameBlock } from '@blocksuite/affine-block-frame';
import { getSurfaceBlock, isNoteBlock } from '@blocksuite/affine-block-surface'; import { getSurfaceBlock, isNoteBlock } from '@blocksuite/affine-block-surface';
import type { FrameBlockModel, NoteBlockModel } from '@blocksuite/affine-model'; import type { FrameBlockModel, NoteBlockModel } from '@blocksuite/affine-model';
import { NoteDisplayMode } from '@blocksuite/affine-model'; import { replaceIdMiddleware } from '@blocksuite/affine-shared/adapters';
import { DocModeProvider } from '@blocksuite/affine-shared/services'; import { DocModeProvider } from '@blocksuite/affine-shared/services';
import { getBlockProps } from '@blocksuite/affine-shared/utils'; import { getBlockProps } from '@blocksuite/affine-shared/utils';
import type { EditorHost } from '@blocksuite/block-std'; import type { EditorHost } from '@blocksuite/block-std';
import { GfxBlockElementModel, type GfxModel } from '@blocksuite/block-std/gfx'; import { GfxBlockElementModel, type GfxModel } from '@blocksuite/block-std/gfx';
import { type BlockModel, type Store, Text } from '@blocksuite/store'; import { type Store, Text } from '@blocksuite/store';
import { import {
getElementProps, getElementProps,
@@ -14,46 +14,29 @@ import {
sortEdgelessElements, sortEdgelessElements,
} from '../../../edgeless/utils/clone-utils.js'; } from '../../../edgeless/utils/clone-utils.js';
function addBlocksToDoc(targetDoc: Store, model: BlockModel, parentId: string) {
// Add current block to linked doc
const blockProps = getBlockProps(model);
const newModelId = targetDoc.addBlock(model.flavour, blockProps, parentId);
// Add children to linked doc, parent is the new model
const children = model.children;
if (children.length > 0) {
children.forEach(child => {
addBlocksToDoc(targetDoc, child, newModelId);
});
}
}
export function createLinkedDocFromNote( export function createLinkedDocFromNote(
doc: Store, doc: Store,
note: NoteBlockModel, note: NoteBlockModel,
docTitle?: string docTitle?: string
) { ) {
const _doc = doc.workspace.createDoc(); const _doc = doc.workspace.createDoc();
const linkedDoc = _doc.getStore(); const transformer = doc.getTransformer([
replaceIdMiddleware(doc.workspace.idGenerator),
]);
const blockSnapshot = transformer.blockToSnapshot(note);
if (!blockSnapshot) {
console.error('Failed to create linked doc from note');
return;
}
const linkedDoc = _doc.getStore({ id: doc.id });
linkedDoc.load(() => { linkedDoc.load(() => {
const rootId = linkedDoc.addBlock('affine:page', { const rootId = linkedDoc.addBlock('affine:page', {
title: new Text(docTitle), title: new Text(docTitle),
}); });
linkedDoc.addBlock('affine:surface', {}, rootId); linkedDoc.addBlock('affine:surface', {}, rootId);
const blockProps = getBlockProps(note); transformer
// keep note props & show in both mode .snapshotToBlock(blockSnapshot, linkedDoc, rootId)
const noteId = linkedDoc.addBlock( .catch(console.error);
'affine:note',
{
...blockProps,
hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless,
},
rootId
);
// Add note to linked doc recursively
note.children.forEach(model => {
addBlocksToDoc(linkedDoc, model, noteId);
});
}); });
return linkedDoc; return linkedDoc;
@@ -65,6 +48,7 @@ export function createLinkedDocFromEdgelessElements(
docTitle?: string docTitle?: string
) { ) {
const _doc = host.doc.workspace.createDoc(); const _doc = host.doc.workspace.createDoc();
const transformer = host.doc.getTransformer();
const linkedDoc = _doc.getStore(); const linkedDoc = _doc.getStore();
linkedDoc.load(() => { linkedDoc.load(() => {
const rootId = linkedDoc.addBlock('affine:page', { const rootId = linkedDoc.addBlock('affine:page', {
@@ -81,11 +65,12 @@ export function createLinkedDocFromEdgelessElements(
if (model instanceof GfxBlockElementModel) { if (model instanceof GfxBlockElementModel) {
const blockProps = getBlockProps(model); const blockProps = getBlockProps(model);
if (isNoteBlock(model)) { if (isNoteBlock(model)) {
newId = linkedDoc.addBlock('affine:note', blockProps, rootId); const blockSnapshot = transformer.blockToSnapshot(model);
// Add note children to linked doc recursively if (blockSnapshot) {
model.children.forEach(model => { transformer
addBlocksToDoc(linkedDoc, model, newId); .snapshotToBlock(blockSnapshot, linkedDoc, rootId)
}); .catch(console.error);
}
} else { } else {
if (isFrameBlock(model)) { if (isFrameBlock(model)) {
mapFrameIds(blockProps as FrameBlockModel['props'], ids); mapFrameIds(blockProps as FrameBlockModel['props'], ids);