mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
fix(core): fix duplicate in all page (#11229)
This commit is contained in:
@@ -168,6 +168,93 @@ export class DocsService extends Service {
|
||||
release();
|
||||
}
|
||||
|
||||
async duplicate(sourceDocId: string, _targetDocId?: string) {
|
||||
const targetDocId = _targetDocId ?? this.createDoc().id;
|
||||
|
||||
// check if source doc is removed
|
||||
if (this.list.doc$(sourceDocId).value?.trash$.value) {
|
||||
console.warn(
|
||||
`Template doc(id: ${sourceDocId}) is removed, skip duplicate`
|
||||
);
|
||||
return targetDocId;
|
||||
}
|
||||
|
||||
const { release: sourceRelease, doc: sourceDoc } = this.open(sourceDocId);
|
||||
const { release: targetRelease, doc: targetDoc } = this.open(targetDocId);
|
||||
await sourceDoc.waitForSyncReady();
|
||||
|
||||
// duplicate doc content
|
||||
try {
|
||||
const sourceBsDoc = this.store.getBlockSuiteDoc(sourceDocId);
|
||||
const targetBsDoc = this.store.getBlockSuiteDoc(targetDocId);
|
||||
if (!sourceBsDoc) throw new Error('Source doc not found');
|
||||
if (!targetBsDoc) throw new Error('Target doc not found');
|
||||
|
||||
// clear the target doc (both surface and note)
|
||||
targetBsDoc.root?.children.forEach(child =>
|
||||
targetBsDoc.deleteBlock(child)
|
||||
);
|
||||
|
||||
const collection = this.store.getBlocksuiteCollection();
|
||||
const transformer = new Transformer({
|
||||
schema: getAFFiNEWorkspaceSchema(),
|
||||
blobCRUD: collection.blobSync,
|
||||
docCRUD: {
|
||||
create: (id: string) => collection.createDoc(id).getStore({ id }),
|
||||
get: (id: string) => collection.getDoc(id)?.getStore({ id }) ?? null,
|
||||
delete: (id: string) => collection.removeDoc(id),
|
||||
},
|
||||
middlewares: [replaceIdMiddleware(collection.idGenerator)],
|
||||
});
|
||||
const slice = Slice.fromModels(sourceBsDoc, [
|
||||
...(sourceBsDoc.root?.children ?? []),
|
||||
]);
|
||||
const snapshot = transformer.sliceToSnapshot(slice);
|
||||
if (!snapshot) {
|
||||
throw new Error('Failed to create snapshot');
|
||||
}
|
||||
await transformer.snapshotToSlice(
|
||||
snapshot,
|
||||
targetBsDoc,
|
||||
targetBsDoc.root?.id
|
||||
);
|
||||
} catch (e) {
|
||||
logger.error('Failed to duplicate doc', {
|
||||
sourceDocId,
|
||||
targetDocId,
|
||||
originalTargetDocId: _targetDocId,
|
||||
error: e,
|
||||
});
|
||||
} finally {
|
||||
sourceRelease();
|
||||
targetRelease();
|
||||
}
|
||||
|
||||
// duplicate doc meta
|
||||
targetDoc.record.setMeta({
|
||||
tags: sourceDoc.meta$.value.tags,
|
||||
});
|
||||
|
||||
// duplicate doc title
|
||||
const originalTitle = sourceDoc.title$.value;
|
||||
const lastDigitRegex = /\((\d+)\)$/;
|
||||
const match = originalTitle.match(lastDigitRegex);
|
||||
const newNumber = match ? parseInt(match[1], 10) + 1 : 1;
|
||||
const newPageTitle =
|
||||
originalTitle.replace(lastDigitRegex, '') + `(${newNumber})`;
|
||||
targetDoc.changeDocTitle(newPageTitle);
|
||||
|
||||
// duplicate doc properties
|
||||
const properties = sourceDoc.getProperties();
|
||||
const removedProperties = ['id', 'isTemplate', 'journal'];
|
||||
removedProperties.forEach(key => {
|
||||
delete properties[key];
|
||||
});
|
||||
targetDoc.updateProperties(properties);
|
||||
|
||||
return targetDocId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a doc from template
|
||||
* @param sourceDocId - the id of the source doc to be duplicated
|
||||
|
||||
Reference in New Issue
Block a user