Skip to content

feat(er-diagram): export the schema as Mermaid or DBML#521

Open
gcapellib wants to merge 1 commit into
TabularisDB:mainfrom
gcapellib:feat/export-er-diagram-mermaid
Open

feat(er-diagram): export the schema as Mermaid or DBML#521
gcapellib wants to merge 1 commit into
TabularisDB:mainfrom
gcapellib:feat/export-er-diagram-mermaid

Conversation

@gcapellib

Copy link
Copy Markdown
Contributor

What

The ER diagram had no export at all. This adds an Export button to the toolbar, opening a menu with two text formats generated from the schema data already in memory — no new dependency.

Why two formats

They cover different needs:

  • Mermaid (erDiagram) renders natively on GitHub, GitLab, Notion and most docs tools, so the output can be pasted straight into a README. Its relationships are entity-level, so the FK column only appears as a label.
  • DBML keeps relationships at column level (Ref: commandes.client_id > clients.id) and round-trips through dbdiagram.io and dbml-to-sql. Composite primary keys use an Indexes block, as inline [pk] cannot express them.

For reference, DBeaver's ER export is image/GraphML only. Its open request for Mermaid export (#36058) shows users falling back to exporting GraphML and hunting for converters that don't seem to exist.

Also fixed: permissions in the ER diagram window

src-tauri/capabilities/default.json allowed the literal window name "er-diagram", but the window is created as er-diagram:{connectionId}:{database}:{schema} (commands.rs:3874). Every permission-gated call was therefore rejected in that window:

dialog.save not allowed on window "er-diagram_..._boutique_"
allowed on: [..., "er-diagram", ...]

Changed to "er-diagram*", matching the wildcard already used by json-viewer-*, results-window-* and connection-window-*. This is a pre-existing bug independent of the feature — any plugin call needing a permission in that window was blocked.

Implementation

  • Generators live in src/utils/schemaExport.ts, separate from the component so they can be unit-tested.
  • Export uses allNodes/allEdges rather than the rendered set, so the file stays complete even while a single table is focused.
  • The format menu reuses the existing ContextMenu component.
  • Both generators de-duplicate edges: the diagram currently emits duplicate edges for some FKs (React logs Encountered two children with the same key), which would otherwise produce repeated relationships. Worth a separate look, but the export is defensive about it.

Testing

14 unit tests (Vitest) covering identifier sanitising, PK/FK markers, relationship direction, composite keys, de-duplication and empty tables.

Manually verified on MariaDB against a 15-table schema exercising self-references (employes.manager_id, categories.parent_id), two FKs from one table to the same target (commandes.adresse_livraison_id and adresse_facturation_id), three composite PKs and a table referenced by five others. Both outputs render correctly in mermaid.live and dbdiagram.io.

npm run typecheck clean.

Possible follow-up

Image export (PNG/SVG) would cover a different need — pasting the diagram into a slide or a document. React Flow documents a path for it but it needs html-to-image as a new dependency, so I left it out rather than decide that here. Happy to add it in a follow-up if you'd want it.

The ER diagram had no export at all. Add an Export button in the toolbar
opening a menu with two text formats, generated from the schema data
already in memory — no new dependency.

Mermaid erDiagram renders natively on GitHub, GitLab and most docs tools,
so the output can be pasted straight into a README. DBML keeps
relationships at column level and round-trips through dbdiagram.io and
dbml-to-sql, which Mermaid's entity-level edges cannot express.

Also widen the er-diagram window pattern in the capabilities file. The
window is created as 'er-diagram:{id}:{db}:{schema}' but only the literal
'er-diagram' was allowed, so every permission-gated call was rejected in
that window — dialog.save included. Other dynamic windows already use a
wildcard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant