Repository navigation
fix: inline editing, edge labels, code panel, and dashboard improvements - #117
Conversation
When clicking a flowchart subgraph in the canvas, the corresponding `subgraph <id>` line in the code editor was not highlighted because `findFlowchartNodeLine` skips structural lines (subgraph/end) and its declaration regex does not match subgraph syntax. Add `findFlowchartSubgraphLine` to scan for `subgraph <id>` declarations specifically, and wire it into the `highlightRange` memo before the generic flowchart node fallback.
…itle
- Remove hover-opacity from list view action buttons (DiagramCard, FolderCard)
- Add Duplicate action in the three-dot menu on DiagramCard
- Highlight newly duplicated diagram with pulsing animation
- Set editor tab title to "{diagramName} — LiveMaid"
Nodes with quoted ids containing spaces (e.g. "IPsec S2S") failed to highlight because Mermaid sanitises SVG element ids by stripping quotes and spaces, so the normalised id (IPsecS2S) could not be found in the source code. - findFlowchartNodeLine: add fallback that scans for quoted source ids whose space-stripped form matches the sanitised node id - findFlowchartEdgeLine: extract endpoint ids from the portion before the first shape bracket (to skip labels), prefer quoted ids, and normalise both sides before comparing
When a flowchart node has an SVG ID that starts with L_ (e.g. L_CF_AZ_CNAME), isEdgeId() would return true, causing the inline edit to show the raw ID instead of the actual label text. Fix: check the DOM element's class before treating the target as an edge. If the element is a .node or .cluster (not a .flowchart-link or .edgeLabel), fall through to the generic node text extraction.
When double-clicking a flowchart edge, the inline editor showed the raw edge ID (e.g. L_CLIENTS_VM3_0) instead of the visible label (e.g. 'Exit Node: HK'). Root cause: edge labels are rendered in a separate <g class='edgeLabels'> container, not as children of the edge path element. The SVG fallback query only searched inside the edge path element, so it found no text. Additionally, when the dblclick target fell outside the canvas (e.g. on the code editor textarea), handleEditClick was never called. Fix: - Add selectedSvgIdRef for synchronous access to the selected SVG ID - When result is null (dblclick on external element), use selectedSvgId as fallback for DOM element lookup and edge label extraction - Search for edge labels in the edgeLabels container by matching the edge path's position among sibling paths
When double-clicking a flowchart edge on the canvas, the inline editor displayed the raw edge ID (e.g. L_TPE_VM2_0) or the source-code label text rather than what the user actually sees on the canvas. Root causes: 1. Edge labels are rendered in <g class='edgeLabels'>, not as children of the edge path element. The SVG fallback searched inside the edge path and found no text. 2. getClickedNode couldn't find the edge path when clicking on an edgeLabel <g> because it lacks a data-id attribute and the sibling- path fallback assumed a different DOM structure. 3. When a dblclick landed on the edgeLabel element, the position-based label lookup used edgePaths (which finds <path> elements) but the target was a <g>, so edgeIdx was always -1. Fix: - In getClickedNode, resolve edgeLabels without data-id by matching their position in the edgeLabels container to edge paths in edgePaths. - In handleEditClick, try SVG DOM label extraction FIRST (what the user sees) before falling back to the source-code regex. Handle both <path> (hit-target / actual) and <g.edgeLabel> element types when finding the label index.
Add two buttons to the left code panel title bar: - Copy All: copies all code to clipboard with toast feedback - Format: cleans up whitespace and re-indents Mermaid code based on block structure (subgraph, loop, alt, opt, par, critical, break, rect, section blocks, with else/and/option at same level)
matchFlowchartLinkLine's regex used non-greedy matching after the connector, which stopped too early when the label text was the same as the destination node name. For example, 'MEL ===|VM2|VM2' was parsed with middle='===|' instead of '===|VM2|', causing updateLinkStyleAndLabel to produce 'MEL ===|VM2|VM2|VM2'. Fix: change the post-connector [^\n]*? to greedy [^\n]* so the regex captures the full connector + label before the destination. Also add a guard in handleEditSubmit to skip the edge label update when the label hasn't changed, avoiding unnecessary re-renders.
|
Warning Review limit reached
Next review available in: 30 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThe PR updates Mermaid selection and inline editing, adds source formatting and copying controls, introduces dashboard diagram duplication with visual feedback, hardens storage and serialization handling, strengthens telemetry fallback generation, expands development-origin defaults, and revises repository workflow guidance. ChangesEditor interaction improvements
Dashboard diagram duplication
Data and runtime hardening
Development guidance and configuration
Estimated code review effort: 4 (Complex) | ~60 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/editor/EditorCanvas.tsx (1)
863-873: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winKeep the smallest-node fallback scoped to generic container targets
findBestAtPoint()is called in both branches, so this unconditional fallback also overwrites resolved concrete diagram elements with the smallest overlapping.node/.cluster/path.flowchart-link/.edgeLabel. Since the goal is to rescue tiny Mermaid hits that are resolved only as generic containers, keep the fallback in theifbranch only.🤖 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/EditorCanvas.tsx` around lines 863 - 873, The smallest-node fallback should only run for generic container targets. In the target-resolution logic, keep the findBestAtPoint() call and target assignment inside the isGenericContainerTarget branch, and remove the duplicate fallback from the else branch so resolved concrete diagram elements remain unchanged.
🤖 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 `@AGENTS.md`:
- Around line 96-108: The retry logic after restarting the livemaid-test session
must fail when the server remains unavailable. Update the second polling loop in
the retry block to perform a final readiness check after polling and exit 1 if
curl still cannot reach localhost:3435; preserve the success path and readiness
message when the server becomes available.
- Around line 149-153: Update the pre-commit/push instruction in AGENTS.md to
run npm run prepush with the repository’s required byte-cap mechanism, ensuring
the command’s potentially large output is capped while preserving the mandatory
prepush validation.
In `@next.config.ts`:
- Around line 3-5: Update DEV_ORIGINS_DEFAULTS and the allowedDevOrigins
configuration so the wildcard *.tail1f8d1a.ts.net origin is not enabled by
default; require it to be explicitly supplied through ALLOWED_DEV_ORIGINS, while
preserving any intended narrowly scoped development origin defaults.
In `@src/components/Dashboard.tsx`:
- Around line 419-420: Update the highlight state flow around setHighlightedId
in Dashboard to store the timeout handle in a ref, clear any existing timer
before scheduling a replacement, and ensure the replacement timer clears the
latest highlight only after the full duration. Clean up the active timeout when
the component unmounts.
In `@src/components/editor/EditorCodePanel.tsx`:
- Around line 95-162: Update handleFormat to preserve Mermaid YAML front matter
verbatim, including indentation under nested config, and exclude that region
from trimming, blank-line collapsing, and re-indentation. Remove section from
BLOCK_OPEN so repeated Gantt sections remain at the correct level, and limit
block formatting to constructs supported by the repository’s Mermaid version
rather than applying unverified grammar rules.
In `@src/hooks/useCanvasInteraction.ts`:
- Around line 3492-3496: Escape effectiveRawSvgId with CSS.escape before
interpolating it into the document.querySelector selector in handleEditClick,
matching the other ID-based lookups in this function. Preserve the existing
fallback selection behavior and descendant selector targets while ensuring IDs
containing CSS-special characters do not cause selector parsing errors.
---
Outside diff comments:
In `@src/components/editor/EditorCanvas.tsx`:
- Around line 863-873: The smallest-node fallback should only run for generic
container targets. In the target-resolution logic, keep the findBestAtPoint()
call and target assignment inside the isGenericContainerTarget branch, and
remove the duplicate fallback from the else branch so resolved concrete diagram
elements remain unchanged.
🪄 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 Plus
Run ID: 95272cc1-23b2-419f-adce-e8c718ae711c
📒 Files selected for processing (13)
AGENTS.mdnext.config.tssrc/app/globals.csssrc/components/Dashboard.tsxsrc/components/DiagramCard.tsxsrc/components/FolderCard.tsxsrc/components/editor/EditorCanvas.tsxsrc/components/editor/EditorCodePanel.tsxsrc/components/editor/LiveMaidEditor.tsxsrc/hooks/useCanvasInteraction.tssrc/hooks/useEditorState.tssrc/lib/diagrams/selectionLineMap.tssrc/lib/diagrams/utils.ts
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/editor/LiveMaidEditor.tsx (2)
269-275: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAvoid resetting
document.titleduring dependency updates.The cleanup runs before every
doc?.namechange, briefly setting the title to"LiveMaid Editor"before the new title is applied. Keep the unmount reset separate from the name-update effect to avoid visible title flicker.🤖 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/LiveMaidEditor.tsx` around lines 269 - 275, Separate the document-title update from the unmount cleanup in the LiveMaidEditor effect: keep the effect keyed by doc?.name responsible only for applying the current title, and move the “LiveMaid Editor” reset into a mount-only cleanup effect so dependency updates do not briefly reset the title.
3073-3104: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winNormalize multiline text on the cluster rename path too.
The
.clusterbranch earlier writes raweditingTextand bypasseseditingTextForSave. Consequently, renaming a subgraph with multiline text can persist literal newlines instead of<br/>formatting, violating the multiline-label behavior. Compute the normalized value before that branch and use it for the cluster declaration replacement as well.🤖 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/LiveMaidEditor.tsx` around lines 3073 - 3104, The cluster rename branch should use the same normalized multiline label value as the regular node path. Compute editingTextForSave before the .cluster handling and replace the cluster declaration with that value instead of raw editingText, preserving the existing <br/> conversion behavior.
🤖 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/api/storageFsAdapter.ts`:
- Around line 68-76: Update validateId to reject empty IDs as invalid, alongside
existing character validation. In getDiagram, move ID validation inside the
existing try/error boundary so invalid route IDs follow the same not-found
behavior as getFolder, while preserving valid read behavior.
In `@src/lib/diagrams/erDiagram.tsx`:
- Line 425: Update parseAttributeParts to unescape doubled backslashes as well
as escaped quotes, using an order that preserves the serialized C:\tmp value
without repeated doubling on save. Add a round-trip test covering a comment
containing backslashes and verify serializeAttributeParts followed by
parseAttributeParts restores the original comment.
In `@src/lib/telemetry/index.ts`:
- Around line 135-137: Update the random identifier fallback in initTelemetry so
it checks that crypto and crypto.getRandomValues are available before invoking
getRandomValues on the Uint32Array. Preserve a non-throwing fallback when either
is unavailable, while retaining the existing randomUUID path when supported.
---
Outside diff comments:
In `@src/components/editor/LiveMaidEditor.tsx`:
- Around line 269-275: Separate the document-title update from the unmount
cleanup in the LiveMaidEditor effect: keep the effect keyed by doc?.name
responsible only for applying the current title, and move the “LiveMaid Editor”
reset into a mount-only cleanup effect so dependency updates do not briefly
reset the title.
- Around line 3073-3104: The cluster rename branch should use the same
normalized multiline label value as the regular node path. Compute
editingTextForSave before the .cluster handling and replace the cluster
declaration with that value instead of raw editingText, preserving the existing
<br/> conversion behavior.
🪄 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 Plus
Run ID: 575e42cc-64ed-412e-87dc-2963c1da1b4d
📒 Files selected for processing (11)
AGENTS.mdnext.config.tssrc/components/Dashboard.tsxsrc/components/editor/EditorCanvas.tsxsrc/components/editor/EditorCodePanel.tsxsrc/components/editor/LiveMaidEditor.tsxsrc/hooks/useCanvasInteraction.tssrc/lib/api/storageFsAdapter.tssrc/lib/diagrams/classDiagram.tsxsrc/lib/diagrams/erDiagram.tsxsrc/lib/telemetry/index.ts
💤 Files with no reviewable changes (2)
- src/components/editor/EditorCanvas.tsx
- next.config.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/components/editor/EditorCodePanel.tsx
- src/components/Dashboard.tsx
- AGENTS.md
- src/hooks/useCanvasInteraction.ts
- Validate empty IDs and move validation inside try/catch in storageFsAdapter - Guard crypto.getRandomValues availability in telemetry fallback - Unescape doubled backslashes in erDiagram parseAttributeParts for round-trip - Separate document-title effect from unmount cleanup to avoid flicker - Use normalized multiline label for cluster renames
- Fix double-unescaping order in erDiagram parseAttributeParts - Use safeFilePath with path.basename validation in storageFsAdapter - Escape angle brackets after HTML tag stripping to prevent injection
Summary
Fixes issues #115 and #116 — inline editing improvements, edge label visibility, code panel enhancements, and dashboard duplicate feature.
Changes
Editor / Canvas
L_from being misidentified as edgesCode Panel
Testing
Closes #115, Closes #116
Summary by CodeRabbit