Mind map nodes truncate text with ellipsis instead of showing full content #153
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_whiteboard#153
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Mind-map nodes have a fixed
NODE_W × NODE_H(140×36) and the label is rendered withellipsis: true, wrap: 'none', so any text longer than what fits on one line gets cut off with an ellipsis. The full content the user typed is not visible.Expected
Each node should show its entire text content. Either the node grows in width to fit a single line up to a sensible maximum, or the text wraps onto multiple lines and the node grows in height. Layout (parent/child connections, sibling spacing) should still look right.
Actual
Long labels are truncated: e.g.
"hello this is a test scenario"renders as"hello this is a test scen…".Repro
Implementation Spec
Root cause
crates/hero_whiteboard_ui/static/web/js/whiteboard/mindmap.js:NODE_W = 140,NODE_H = 36,H_GAP = 60,V_GAP = 16are hardcoded constants used by every layout, render, and overlay path.drawNodes): theKonva.Textis created withwidth: NODE_W - 16, ellipsis: true, wrap: 'none'— that is the direct truncation.layoutTree(L150–199),getLayoutBounds,drawConnections,drawNodes,editMindmapNode(L656–657 width/height), andshowCommentPopup(L480 anchors aty: NODE_H) all bake the fixed sizes in.Approach: hybrid (grow width to a soft cap, then wrap)
Short labels stay compact (look like a normal mind map); longer labels grow the width up to a cap; even longer text wraps. Avoids the failure modes of "always wrap tall" (option A) and "grow arbitrarily wide" (option B).
Files to Modify
crates/hero_whiteboard_ui/static/web/js/whiteboard/mindmap.js— only file.Implementation Plan
Step 1 — variable per-node sizing
Files:
mindmap.jsNew constants (replace
NODE_W/NODE_Hliterals with these where used as the node's minimum size):Text-measure helper (Konva pattern — detached Text node,
.destroy()after read):layoutTree— measure each node up front, store on the layout result, use per-depth max for cross-axis spacing so all nodes at depthdstill share a row (vertical) / column (horizontal). Two-pass:nodeW/nodeHfor every layout entry.maxW[depth](horizontal) ormaxH[depth](vertical), then usecumsum(max[0..d-1] + gap)for the depth-axis coordinate. Keeps siblings of different parents aligned.nodeW/nodeH(no longer the constants).getLayoutBounds— replace+ NODE_W/+ NODE_Hwith+ layout.nodeW/+ layout.nodeH.drawConnections—from/toedge points useparent.nodeW/parent.nodeHandchild.nodeW/child.nodeHinstead of the constants.drawNodes:width: layout.nodeW, height: layout.nodeH.x: x + 8, y: y + 8, width: layout.nodeW - H_PADDING, wrap: 'word'. Removeellipsis: trueand changewrap: 'none'→wrap: 'word'.+/−indicator:x + layout.nodeW - 18,y + layout.nodeH - 14(vertical).+button:addX = x + layout.nodeW + 4(horizontal), oraddX = x + layout.nodeW/2 - 4, addY = y + layout.nodeH + 4(vertical).x + 2, y + 2.editMindmapNode— read size from the rect itself:nodeRect.width() * absScale,nodeRect.height() * absScale(no extra params).showCommentPopup— anchor below the actual node:transform.point({ x: 0, y: nodeRect.height() }).Dependencies: none
Acceptance Criteria
"hello this is a test scenario"is fully visible — no ellipsis — on both vertical and horizontal mind maps."Leaf 1.1") keep the previous compact look (≈140×36).+/−collapse, add-child+, comment 💬 stay at the correct corners on resized nodes.WhiteboardSync.onUpdate.Notes / regressions to watch
wrap: 'word'doesn't break inside a word; an extreme single token can still push pastMAX_NODE_W. Acceptable for v1.Konva.Textper node per render. Fine for typical mindmaps; cache by(text, fontSize, fontStyle)only if profiling shows it matters.b7d21f1(in-place edit) or8fa6da3(shared comment popover styling).Validation
cargo check --workspacecargo test --workspace --libImplementation summary
Changes
crates/hero_whiteboard_ui/static/web/js/whiteboard/mindmap.js— every node now has a measured per-node size instead of the fixed 140×36 box.MIN_NODE_W=140,MAX_NODE_W=280,MIN_NODE_H=36,H_PADDING=16,V_PADDING=16.NODE_W/NODE_Hremoved entirely.measureNodeText(text, fontSize, fontStyle)helper using a detachedKonva.Textprobe — measures unwrapped width, clamps to[MIN_NODE_W, MAX_NODE_W]plus padding, then re-measures withwrap: 'word'for the wrapped height.layoutTreemeasures each node up front and storesnodeW/nodeH/depthon the layout entry.assignDepthAxis(layout, dir)second pass computes per-depth max sizes and writes cumulative depth-axis coordinates so siblings of different parents at the same depth still share a row (vertical) or column (horizontal).getLayoutBounds,drawConnections,drawNodesall uselayout.nodeW/layout.nodeHinstead of the constants. The+/−collapse toggle, the add-child+button, and the comment 💬 indicator anchor to per-node corners.drawNodeslabel:wrap: 'word',ellipsis: trueremoved.editMindmapNode: input width/height now fromnodeRect.width()/nodeRect.height()× abs scale — inline editor tracks the variable node size automatically.showCommentPopup: anchors attransform.point({ x: 0, y: nodeRect.height() })so the popover sits below the actual bottom of the (possibly taller) node.Validation
cargo check --workspace: passcargo test --workspace --lib: passNotes
UI-only change. Verify visually: a node labelled
"hello this is a test scenario"should now render fully (no ellipsis) on both vertical and horizontal mind maps, short labels still look compact, very long labels wrap onto multiple lines and the node grows in height. Connectors, collapse toggle, add-child, comment indicator, inline editor, and comment popover all track the new variable size.