AcadeDoc/apps/client/src/features/acadenice/sync-blocks/slash-command/insert-sync-block.ts
Corentin 23a85267bf feat(acadenice): add sync blocks for cross-page content sharing — R4.2
Implements Notion-style sync blocks: a Tiptap node whose content is shared
across N pages. Editing via the Hocuspocus overlay propagates to all instances
via Yjs collab + SSE broadcast (EventEmitter2 bus).

Server: DB migration, NestJS module (CRUD + BFS cycle detection + broadcast),
Hocuspocus persistence extension extended for sync-block-* docs, 3 new RBAC
permissions (sync_blocks:create/edit/delete), seeded to Admin/Editor/Member.

Client: SyncBlockExtension (Tiptap node), SyncBlockNodeView (NodeView +
Mantine Modal overlay + SSE hook), /sync-block slash command, service client.

Tests: 32 server Jest + 18 client Vitest, all green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 11:40:12 +02:00

21 lines
852 B
TypeScript

import { Editor, Range } from "@tiptap/core";
import { syncBlocksClient } from "../services/sync-blocks-client";
/**
* Slash command handler for `/sync-block` (R4.2).
*
* Creates a new master sync block via the REST API, then inserts a
* `syncBlock` node into the editor with the returned masterId.
*
* The insert is atomic from the user's perspective: if the API call fails,
* the editor is not modified and the error is propagated to the caller.
*/
export async function insertSyncBlock(editor: Editor, range: Range): Promise<void> {
// Delete the slash trigger text before the async operation to prevent
// the slash menu from staying open on slow networks.
editor.chain().focus().deleteRange(range).run();
const block = await syncBlocksClient.create({});
editor.chain().focus().insertSyncBlock({ masterId: block.id }).run();
}