From 45c9ca9f1cc0973bb6d900b2ed96841aa825952f Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Wed, 30 Sep 2026 01:15:11 +0100 Subject: [PATCH] fix: copy page labels when duplicating pages --- .../src/core/page/services/page.service.ts | 10 ++++++- .../src/database/repos/label/label.repo.ts | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/apps/server/src/core/page/services/page.service.ts b/apps/server/src/core/page/services/page.service.ts index 990d8fae2..fbe8a4d5d 100644 --- a/apps/server/src/core/page/services/page.service.ts +++ b/apps/server/src/core/page/services/page.service.ts @@ -56,6 +56,7 @@ import { markdownToHtml } from '@docmost/editor-ext'; import { WatcherService } from '../../watcher/watcher.service'; import { sql } from 'kysely'; import { TransclusionService } from '../transclusion/transclusion.service'; +import { LabelRepo } from '@docmost/db/repos/label/label.repo'; @Injectable() export class PageService { @@ -74,6 +75,7 @@ export class PageService { private collaborationGateway: CollaborationGateway, private readonly watcherService: WatcherService, private readonly transclusionService: TransclusionService, + private readonly labelRepo: LabelRepo, ) {} async findById( @@ -715,7 +717,13 @@ export class PageService { }), ); - await this.db.insertInto('pages').values(insertablePages).execute(); + await executeTx(this.db, async (trx) => { + await trx.insertInto('pages').values(insertablePages).execute(); + await this.labelRepo.copyLabelsToPages( + new Map([...pageMap].map(([oldId, entry]) => [oldId, entry.newPageId])), + trx, + ); + }); // Extract transclusions from every duplicated page and persist them in // one statement. Duplication bypasses Yjs onStoreDocument; brand-new diff --git a/apps/server/src/database/repos/label/label.repo.ts b/apps/server/src/database/repos/label/label.repo.ts index bac199ed4..e2a6e7ed5 100644 --- a/apps/server/src/database/repos/label/label.repo.ts +++ b/apps/server/src/database/repos/label/label.repo.ts @@ -176,6 +176,32 @@ export class LabelRepo { .execute(); } + async copyLabelsToPages( + pageIdMap: Map, + trx?: KyselyTransaction, + ): Promise { + if (pageIdMap.size === 0) return; + const db = dbOrTx(this.db, trx); + + const sourceLabels = await db + .selectFrom('pageLabels') + .select(['pageId', 'labelId']) + .where('pageId', 'in', [...pageIdMap.keys()]) + .execute(); + if (sourceLabels.length === 0) return; + + await db + .insertInto('pageLabels') + .values( + sourceLabels.map((row) => ({ + pageId: pageIdMap.get(row.pageId), + labelId: row.labelId, + })), + ) + .onConflict((oc) => oc.doNothing()) + .execute(); + } + async removeLabelFromPage( pageId: string, labelId: string,