Block plugins: plugin_block node with sandboxed rendering and editing #76

Closed
opened 2026-07-04 14:52:40 +02:00 by fable-5 · 1 comment
Collaborator

Context

Code plugins provide custom block types — the powerful end of the plugin spectrum (diagrams, embeds).

Scope

Add the reserved plugin_block node (attrs: pluginId, blockType, data) to the shared schema; editor integration: insert menu lists block types from active plugins, node view hosts the sandbox iframe (#73) in render mode, edit affordance switches the frame to edit mode (plugin UI), data persisted via the blockData capability into node attrs (collaborative-safe: attrs updates go through the Yjs document); unknown/disabled plugin renders the manifest fallback (from stored manifest snapshot) or a neutral placeholder.

Acceptance criteria

  • a fixture block plugin round-trips: insert → edit data → reload → render (e2e)
  • two collaborating users see block-data changes live
  • disabling the plugin renders fallback without document mutation; re-enabling restores function
  • copy/paste of a plugin block within and across pages of the same pond preserves data

Technical notes

  • ADR 0008, plugin-architecture.md, ADR 0003 (attrs via Yjs).

Dependencies

Depends on #73, #74.

Size: ~2 days


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context Code plugins provide custom block types — the powerful end of the plugin spectrum (diagrams, embeds). ## Scope Add the reserved `plugin_block` node (attrs: pluginId, blockType, data) to the shared schema; editor integration: insert menu lists block types from active plugins, node view hosts the sandbox iframe (#73) in render mode, edit affordance switches the frame to edit mode (plugin UI), data persisted via the `blockData` capability into node attrs (collaborative-safe: attrs updates go through the Yjs document); unknown/disabled plugin renders the manifest fallback (from stored manifest snapshot) or a neutral placeholder. ## Acceptance criteria - [ ] a fixture block plugin round-trips: insert → edit data → reload → render (e2e) - [ ] two collaborating users see block-data changes live - [ ] disabling the plugin renders fallback without document mutation; re-enabling restores function - [ ] copy/paste of a plugin block within and across pages of the same pond preserves data ## Technical notes - ADR 0008, plugin-architecture.md, ADR 0003 (attrs via Yjs). ## Dependencies Depends on #73, #74. **Size**: ~2 days --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M7 — Plugins milestone 2026-07-04 14:52:40 +02:00
fable-5 added the
frontend
plugins
labels 2026-07-04 14:52:40 +02:00
Author
Collaborator

Umgesetzt in 923532f (CI grün, alle 8 Kontexte).

Akzeptanzkriterien (alle als e2e in plugin-blocks.spec.ts):

  • Fixture-Block-Plugin round-trippt: insert → edit data → reload → render
  • Zwei kollaborierende Nutzer sehen Block-Daten-Änderungen live (Attrs via Yjs; der Frame des Partners re-rendert beim Datenwechsel)
  • Deaktivieren rendert den Manifest-Fallback ohne Dokument-Mutation (Markdown-Export behält Fence+Daten), Reaktivieren stellt die Funktion wieder her
  • Copy/Paste innerhalb und über Seiten desselben Teichs erhält die Daten (DOM-Attrs + Markdown-Clipboard-Fence)

Bausteine: plugin_block-Node im shared Schema (Markdown = reservierter Fence ```dorfteich-plugin <plugin>/<type> mit JSON-Body), React-NodeView hostet die #73-Sandbox (render/edit-Lifecycle, blockData-Capability mit Read-only-Guard und Echo-Unterdrückung), Insert-Picker in der Toolbar, GET /plugins/:id/fallback (Manifest-Snapshot, überlebt Uninstall als Tombstone; nur angemeldet).

Bewusst verschoben wie in #74: getBlock (Cross-Page-Block-Embedding) — das Schema hat weiterhin keine per-Block-IDs; kommt mit dem Feature, das sie braucht.

Umgesetzt in `923532f` (CI grün, alle 8 Kontexte). **Akzeptanzkriterien (alle als e2e in `plugin-blocks.spec.ts`):** - [x] Fixture-Block-Plugin round-trippt: insert → edit data → reload → render - [x] Zwei kollaborierende Nutzer sehen Block-Daten-Änderungen live (Attrs via Yjs; der Frame des Partners re-rendert beim Datenwechsel) - [x] Deaktivieren rendert den Manifest-Fallback ohne Dokument-Mutation (Markdown-Export behält Fence+Daten), Reaktivieren stellt die Funktion wieder her - [x] Copy/Paste innerhalb und über Seiten desselben Teichs erhält die Daten (DOM-Attrs + Markdown-Clipboard-Fence) **Bausteine:** `plugin_block`-Node im shared Schema (Markdown = reservierter Fence ```` ```dorfteich-plugin <plugin>/<type> ```` mit JSON-Body), React-NodeView hostet die #73-Sandbox (render/edit-Lifecycle, blockData-Capability mit Read-only-Guard und Echo-Unterdrückung), Insert-Picker in der Toolbar, `GET /plugins/:id/fallback` (Manifest-Snapshot, überlebt Uninstall als Tombstone; nur angemeldet). **Bewusst verschoben wie in #74:** `getBlock` (Cross-Page-Block-Embedding) — das Schema hat weiterhin keine per-Block-IDs; kommt mit dem Feature, das sie braucht.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#76
No description provided.