Skip to content

fix(apollo-react): keep a cleared node name empty instead of the manifest label [MST-17199] - #1453

Merged
snuziale merged 1 commit into
mainfrom
fix/basenode-keep-cleared-label
Oct 22, 2026
Merged

snuziale merged 1 commit into
mainfrom
fix/basenode-keep-cleared-label

Conversation

@snuziale

@snuziale snuziale commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Found by Maestro Flow in MST-17199. Flow works around it in flow-workbench#5404.

  • A user double-clicks a node's label on the canvas, deletes the whole name and presses Enter. The node shows its type name again instead of staying unnamed.
  • BaseNode's handleLabelChange deleted display.label when the committed value was empty. resolveDisplay then fell through to manifest.canvasLabel ?? manifest.label.
  • resolveDisplay already uses ??, so it keeps label: ''. NodeLabel already renders the empty-label-placeholder for an empty label. The delete was the only thing preventing an unnamed node.
  • The two rename surfaces disagreed: the same clear in a consumer's properties panel already writes label: ''.
Node { display: { label: 'Fetch orders' } }, name cleared inline updateNodeData('script1', …) Chip shows
Before { display: {} } the manifest label (e.g. "Script")
After { display: { label: '' } } empty; the placeholder when there is no description either

Fix

  • handleLabelChange always writes label, including ''.
  • An empty subLabel is still deleted, so a label-only edit doesn't add subLabel: '' to every node.
  • useInlineLabelEditing only calls onChange when the trimmed text changed. Opening and closing the editor on a node that was never renamed writes nothing.

Behavior change ⚠️

Clearing a node's name on the canvas no longer resets it to the node type's name. It leaves the node unnamed, which is what the user asked for. A consumer that relied on "clear to reset" must delete display.label itself.

Not in scope

  • ContainerNode keeps its reset-on-clear behavior (ContainerNode.tsx handleLabelChange, documented there as deliberate). It has no empty-title placeholder, so label: '' would render a blank header. That needs its own change if containers should match.
  • A node with no manifest still shows "Unknown Node" for an empty label (label || 'Unknown Node' in resolveDisplay).
  • A node with an instance display.canvasLabel still shows it after an inline clear, because canvasLabel outranks label. This is unchanged.

Follow-up for Flow

After this ships, delete packages/canvas/src/components/hierarchical-canvas/utils/keep-cleared-label.ts, its test and the keepClearedLabelEmpty call in FlowCanvas.tsx's onNodesChange.

Tests

  • BaseNode.test.tsx: updateNodeData is now a hoisted mock, plus a new Inline label editing group:
    • a cleared name is stored as label: '' (fails on main, passes here);
    • an empty subLabel is still dropped;
    • other display fields (icon, color) are kept.
  • manifest-resolver.test.ts: an empty instance.label doesn't fall back to the manifest label. This pins down the contract the fix relies on.

Validation

Automated:

  • vitest run src/canvas: 3,673 tests. JsonTree.import.test.ts failed on a timeout in the full run and passes alone; it's unrelated.
  • tsc --noEmit: clean.
  • pnpm turbo build --filter=@uipath/apollo-react...: green.
  • Biome: no new findings.

Manual, in Storybook (Nodes/BaseNode → Label Resolution, design mode, real updateNodeData):

Step main This branch
Rename the middle node to "Fetch orders", then clear the name and press Enter reverts to "Long Decision Without canvasLabel" stays empty
Clear the description too n/a the empty-label placeholder appears
Double-click the placeholder and type a name n/a the editor opens empty; the new name is saved
On a node with only a description left, double-click the description n/a both editors open, so the name can be retyped
Clear a name that came from manifest.canvasLabel ("Send Email") not run (same delete path, so it would revert to "Send Email") stays empty
Open the editor and press Escape no write no write

No new console errors or warnings.

One UX note: when the name is empty but a description remains, the empty name row has 0px height. Renaming then goes through double-clicking the description. Both editors open, so it works, but it is less discoverable than the placeholder. This is the same state the properties panel already produces today.

🤖 Generated with Claude Code

…fest label [MST-17199]

Clearing a BaseNode's label inline deleted display.label, so resolveDisplay
fell back to the manifest label and the node showed its type name again.
Store label: '' instead; resolveDisplay already keeps it and NodeLabel shows
the empty-label placeholder. An empty subLabel is still dropped.

Behavior change: clearing a name no longer resets it to the type name. A
consumer that wants the reset must delete display.label itself. ContainerNode
keeps its reset-on-clear behavior for now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 18:55

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex October 22, 2026 18:55 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs October 22, 2026 18:55 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing October 22, 2026 18:55 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design October 22, 2026 18:55 Destroyed
@github-actions github-actions Bot added the size:M 30-99 changed lines. label Oct 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Dependency License Review

  • ✅ 1957 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1721
ISC 91
Apache-2.0 57
BSD-3-Clause 28
BSD-2-Clause 23
BlueOak-1.0.0 8
MPL-2.0 4
CC0-1.0 4
MIT-0 3
MIT OR Apache-2.0 2
(MIT OR Apache-2.0) 2
Unlicense 2
LGPL-3.0-or-later 1
Python-2.0 1
CC-BY-4.0 1
(MPL-2.0 OR Apache-2.0) 1
Unknown 1
Artistic-2.0 1
(WTFPL OR MIT) 1
(BSD-2-Clause OR MIT OR Apache-2.0) 1
CC-BY-3.0 1
0BSD 1
(MIT OR CC0-1.0) 1
MIT AND ISC 1
Excluded packages
Package Version License Reason
@img/sharp-libvips-linux-x64 1.3.4 LGPL-3.0-or-later LGPL pre-built binary, not linked
khroma 2.1.0 Unknown MIT per GitHub repo, missing license field in package.json

@bryan-uipath bryan-uipath left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for making the change here @snuziale !

@snuziale
snuziale enabled auto-merge (rebase) October 22, 2026 19:10
@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage + size by package

Per-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.

Package Coverage New-line coverage Packed (gzip) Unpacked vs main
@uipath/apollo-core — — 42.02 MB 50.17 MB ±0
@uipath/apollo-react 58.4% 100.0% (4/4) 8.14 MB 32.17 MB +63 B
@uipath/apollo-ui-icons — — 2.86 MB 6.97 MB ±0
@uipath/apollo-vertex — — — — —
@uipath/apollo-wind — — 810.6 KB 4.68 MB +6 B
@uipath/ap-chat 85.8% — 40.42 MB 45.71 MB ±0

"Coverage" is each package's own coverage.include scope (e.g. apollo-core instruments only scripts/). "Packed"/"Unpacked" come from npm pack --dry-run and only cover built packages — "—" means not measured this run (package not affected / not built). "vs main" is the packed (gzipped) delta against the last successful main build (the package-sizes artifact from the Release workflow); "—" there means no main baseline was available this run. The baseline is main's latest build, not this PR's exact merge-base, so it includes any drift since the branch diverged. Packages with no vitest config are omitted.

@snuziale
snuziale merged commit b797341 into main Oct 22, 2026
36 of 40 checks passed
@snuziale
snuziale deleted the fix/basenode-keep-cleared-label branch October 22, 2026 19:12

This branch was successfully deployed

No deployments
preview/apollo-design — a4de4916 Deployed Oct 22, 2026 by github-actions[bot]
preview/apollo-landing — a4de4916 Deployed Oct 22, 2026 by github-actions[bot]
preview/apollo-vertex — a4de4916 Deployed Oct 22, 2026 by github-actions[bot]
preview/apollo-docs — a4de4916 Deployed Oct 22, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:apollo-react size:M 30-99 changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants