Skip to content

feat: add mindmap wysiwyg editing - #105

Merged
peter6055 merged 2 commits into
mainfrom
feat/mindmap-wysiwyg
Jul 7, 2026
Merged

peter6055 merged 2 commits into
mainfrom
feat/mindmap-wysiwyg

Conversation

@peter6055

@peter6055 peter6055 commented Jul 7, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • register mindmap as an editable diagram plugin and expose it in the create dialog
  • add source-driven mindmap parsing/mutations for root, child, delete subtree, shape changes, and canvas selection
  • add mindmap toolbar, purple click-to-add child affordance, comment anchoring, and unit coverage

Verification

  • npm run prepush
  • browser-verified create/render/select/add child/change shape/delete/comment flows during implementation

Summary by CodeRabbit

  • New Features
    • Added Mindmap as a new diagram type, including a new creation template option.
    • Introduced mindmap node editing tools: shape selection, inline node toolbar, and “add child” actions.
    • Enabled mindmap-aware commenting and node anchoring for better visual alignment.
  • Bug Fixes
    • Improved mindmap selection persistence and comment positioning as the diagram updates.
    • Suppressed empty-state mindmap parse error UI when no nodes exist yet.
  • Tests
    • Expanded mindmap parser and mutation coverage.

@railway-app
railway-app Bot temporarily deployed to livemaid / livemaid-pr-105 July 7, 2026 06:48 Destroyed
@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c5dead15-7a2b-4e19-8c6e-405adcf7733d

📥 Commits

Reviewing files that changed from the base of the PR and between aee2596 and 515b9c3.

📒 Files selected for processing (2)
  • src/lib/diagrams/mindmap.tsx
  • src/test/mindmap.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/test/mindmap.test.ts
  • src/lib/diagrams/mindmap.tsx

📝 Walkthrough

Walkthrough

This PR adds Mindmap support end to end: a new diagram model and plugin, editor canvas selection and toolbar wiring, source-update handlers, comment anchoring, a dashboard template entry, and tests.

Changes

Mindmap diagram feature

Layer / File(s) Summary
Mindmap parsing and mutation model
src/lib/diagrams/mindmap.tsx, src/lib/diagrams/registry.ts, src/components/Dashboard.tsx, src/test/mindmap.test.ts
Defines mindmap types, parsing, formatting, node CRUD helpers, SVG-to-node mapping, plugin export, registry registration, and a new dashboard template entry; adds parser and mutation tests.
Canvas click resolution and selection for mindmap nodes
src/hooks/useCanvasInteraction.ts
Resolves clicks on mindmap SVG nodes to MINDMAP_ ids, bypasses generic id normalization for these ids, and re-resolves selection after re-render.
EditorCanvas mindmap toolbar and add-child UI
src/components/editor/EditorCanvas.tsx
Adds mindmap callback props, computes selected node/empty-state, suppresses parse errors for empty mindmaps, renders the node toolbar and add-child button, and excludes mindmap from generic connection UI.
MindmapNodeToolbar component
src/components/editor/MindmapNodeToolbar.tsx
New toolbar rendering a shape-selector dropdown and delete button with outside-click handling.
LiveMaidEditor mindmap handlers and highlight mapping
src/components/editor/LiveMaidEditor.tsx
Adds add/delete/shape-change handlers that update code and selection, maps selected mindmap ids to source lines for highlighting, and wires handlers into EditorCanvas.
Comment anchoring on mindmap nodes
src/components/editor/CommentLayer.tsx
Adds a required code prop and resolves MINDMAP_-prefixed comment anchors to SVG bounding boxes with fallback positioning.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant EditorCanvas
  participant useCanvasInteraction
  participant LiveMaidEditor
  participant MindmapModel

  User->>EditorCanvas: click mindmap node
  EditorCanvas->>useCanvasInteraction: getClickedNode(event)
  useCanvasInteraction->>MindmapModel: mindmapNodeIdFromSvgElement()
  MindmapModel-->>useCanvasInteraction: MINDMAP_ nodeId
  useCanvasInteraction-->>EditorCanvas: selectedNodeId

  User->>EditorCanvas: click shape / delete / add-child
  EditorCanvas->>LiveMaidEditor: callback for selected node action
  LiveMaidEditor->>MindmapModel: addMindmapChild / deleteMindmapNode / changeMindmapNodeShape
  MindmapModel-->>LiveMaidEditor: updated code
  LiveMaidEditor->>EditorCanvas: handleCodeChange(updated code)
Loading

Poem

A rabbit drew a mindmap bright,
With leafy branches left and right.
A shape, a click, a node to grow,
Then hop! the code begins to flow.
🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding WYSIWYG editing support for mindmaps.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/lib/diagrams/mindmap.tsx (1)

258-267: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Minor: redundant getBoundingClientRect() calls.

getBoundingClientRect() is invoked twice per element in the same filter predicate (once for .width, once for .height). Cache the rect once per element.

♻️ Proposed fix
   const groups = candidates
     .map((el) => el.closest("g") ?? el)
     .filter((el, index, arr) => arr.indexOf(el) === index)
-    .filter((el) => el.getBoundingClientRect().width > 0 && el.getBoundingClientRect().height > 0);
+    .filter((el) => {
+      const rect = el.getBoundingClientRect();
+      return rect.width > 0 && rect.height > 0;
+    });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/diagrams/mindmap.tsx` around lines 258 - 267, The
mindmapRenderedNodes helper is calling getBoundingClientRect() twice for each
element in the filter predicate. Update the filtering logic in
mindmapRenderedNodes to read the bounding rect once per element, store it in a
local variable, and then use that cached rect for both width and height checks.
src/components/editor/MindmapNodeToolbar.tsx (1)

13-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shape icons don't visually distinguish "Default"/"Square"/"Rounded", and "Bang" uses a loading-spinner icon.

default, square, and rounded all render the same Square glyph (the rounded-sm class has no effect on an SVG icon's own path), so those three rows look identical besides their labels. More notably, bang uses Loader, which conventionally signals a "loading" state — likely to confuse users scanning the shape picker.

♻️ Suggested icon swap
-import { Check, Circle, Cloud, Hexagon, Loader, Square, Trash2 } from "lucide-react";
+import { Check, Circle, Cloud, Hexagon, Square, Trash2, Zap } from "lucide-react";
...
-  { id: "bang", label: "Bang", icon: <Loader className="h-3.5 w-3.5" /> },
+  { id: "bang", label: "Bang", icon: <Zap className="h-3.5 w-3.5" /> },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/editor/MindmapNodeToolbar.tsx` around lines 13 - 21, The icon
mapping in MINDMAP_SHAPES within MindmapNodeToolbar is too ambiguous because
Default, Square, and Rounded all use the same Square glyph, and Bang uses a
Loader icon that reads as a loading state. Update the icon selection for these
shape entries so each MindmapShapeKind has a visually distinct, appropriate
icon, and replace the Bang icon with something that better represents the shape
instead of a spinner-like loader.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/diagrams/mindmap.tsx`:
- Around line 103-118: `formatMindmapNodeText` only trims whitespace, so
embedded newline/carriage-return characters can still be written into the
mermaid source and split a node across lines. Update `formatMindmapNodeText` to
sanitize `label` by removing or replacing internal `\n`/`\r` before composing
the final node text, and make sure the callers `renameMindmapNode`,
`addMindmapChild`, and `addRootMindmapNode` continue to rely on this normalized
output when splicing into `code.split("\n")` / `lines.join("\n")`.
- Around line 258-290: The mindmap SVG lookup logic still relies on array
position in mindmapRenderedNodes and parseMindmap(...).nodes, which can
mis-associate elements if Mermaid changes render order. Update
mindmapNodeIdFromSvgElement and findMindmapSvgElementByNodeId to resolve nodes
using a stable key from the rendered SVG node itself (such as data-id or the
node’s own id attribute) instead of DOM index matching, while keeping the
existing mindmapRenderedNodes helper only for filtering visible candidate nodes.

---

Nitpick comments:
In `@src/components/editor/MindmapNodeToolbar.tsx`:
- Around line 13-21: The icon mapping in MINDMAP_SHAPES within
MindmapNodeToolbar is too ambiguous because Default, Square, and Rounded all use
the same Square glyph, and Bang uses a Loader icon that reads as a loading
state. Update the icon selection for these shape entries so each
MindmapShapeKind has a visually distinct, appropriate icon, and replace the Bang
icon with something that better represents the shape instead of a spinner-like
loader.

In `@src/lib/diagrams/mindmap.tsx`:
- Around line 258-267: The mindmapRenderedNodes helper is calling
getBoundingClientRect() twice for each element in the filter predicate. Update
the filtering logic in mindmapRenderedNodes to read the bounding rect once per
element, store it in a local variable, and then use that cached rect for both
width and height checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0e85f236-1445-4435-8c3f-767c115db619

📥 Commits

Reviewing files that changed from the base of the PR and between 94e1eb6 and aee2596.

📒 Files selected for processing (9)
  • src/components/Dashboard.tsx
  • src/components/editor/CommentLayer.tsx
  • src/components/editor/EditorCanvas.tsx
  • src/components/editor/LiveMaidEditor.tsx
  • src/components/editor/MindmapNodeToolbar.tsx
  • src/hooks/useCanvasInteraction.ts
  • src/lib/diagrams/mindmap.tsx
  • src/lib/diagrams/registry.ts
  • src/test/mindmap.test.ts

Comment thread src/lib/diagrams/mindmap.tsx
Comment thread src/lib/diagrams/mindmap.tsx
@railway-app

railway-app Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the livemaid-pr-105 environment in livemaid

Service Status Web Updated (UTC)
livemaid ✅ Success (View Logs) Web Jul 7, 2026 at 11:53 am

@railway-app
railway-app Bot temporarily deployed to livemaid / livemaid-pr-105 July 7, 2026 11:52 Destroyed
@peter6055

Copy link
Copy Markdown
Owner Author

Addressed CodeRabbit feedback in 515b9c3:

  • sanitized embedded CR/LF in mindmap labels before source insertion
  • updated root/child insertion to use the formatter path
  • resolved rendered mindmap nodes by Mermaid's rendered node key instead of DOM order
  • cached bounding rect during visible-node filtering
  • added unit coverage for multiline label normalization

Skipped the Bang icon suggestion intentionally because the product request in this PR was to use the loader icon for Bang.

@peter6055
peter6055 merged commit 372a3cc into main Jul 7, 2026
6 checks passed
@peter6055
peter6055 deleted the feat/mindmap-wysiwyg branch July 7, 2026 12:15

This branch was successfully deployed

No deployments
livemaid / livemaid-pr-105 — 515b9c3b Deployed Jul 7, 2026 by railway-app[bot]
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