Skip to content

feat(apollo-react): multi-strategy Tidy up menu for CanvasZoomControls#957

Draft
dbacomputer wants to merge 2 commits into
mainfrom
improve-tidy-up
Draft

feat(apollo-react): multi-strategy Tidy up menu for CanvasZoomControls#957
dbacomputer wants to merge 2 commits into
mainfrom
improve-tidy-up

Conversation

@dbacomputer

@dbacomputer dbacomputer commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a "Tidy up" dropdown to CanvasZoomControls offering four layout strategies (Subtle align, Compact layout, Horizontal layout, Vertical layout) plus a Reset to original action, on top of the existing single-action onOrganize prop (unchanged, still used by AgentCanvas).
  • New reusable subtleAlignNodes / compactAlignNodes utilities in canvas/utils/tidy-up.ts, with unit tests.
  • Vertical layout also flips node handles to top/bottom (new HandleConfigs-style presets) so edges stay straight instead of zigzagging around side-mounted handles; Horizontal/Vertical also use wider node spacing than Compact for a less cramped look. Compact layout and Subtle align are untouched throughout.
  • A second trigger point: the same tidy-up strategies are also available from a "Tidy up" overflow entry in each node's own NodeToolbar, scoped to the demo story only (via BaseNodeOverrideConfigProvider) — no effect on any other story or on production usage of these node types.
  • Menu items render icon + label everywhere (corner control and NodeToolbar), matching format.
  • Story pages under Components/Controls/CanvasZoomControls: Vertical, Horizontal (both now show the full toolbar including Tidy up), Tidy up (the single-action onOrganize demo, matching AgentCanvas's real production usage), and Tidy up: workflow (the full interactive demo — messy 8-node workflow, both entry points, real repositioning/handle-flipping).

Test plan

  • vitest run src/canvas/utils/tidy-up.test.ts (7 passing)
  • tsc --noEmit clean
  • biome check clean on touched files
  • Manually verified all four strategies + reset from both entry points (corner control and NodeToolbar overflow) in Storybook
  • Confirmed onOrganize (AgentCanvas's existing single-action usage) still renders unchanged
  • Confirmed no overlap between handle captions and node labels on Horizontal/Vertical

🤖 Generated with Claude Code

…rols

Adds a "Tidy up" dropdown to CanvasZoomControls with four layout
strategies (Subtle align, Compact layout, Horizontal layout, Vertical
layout) plus a Reset to original action, backed by new subtleAlignNodes
and compactAlignNodes utilities in canvas/utils/tidy-up.ts. Vertical
layout also flips node handles to top/bottom via a new
HandleConfigs.topBottom preset so edges stay straight instead of
zigzagging around side-mounted handles. The single-action onOrganize
prop used by AgentCanvas is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 23, 2026 03:19
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (PT)
apollo-design 🟢 Ready Preview, Logs Jul 22, 2026, 08:25:16 PM
apollo-docs 🟢 Ready Preview, Logs Jul 22, 2026, 08:25:16 PM
apollo-landing 🟢 Ready Preview, Logs Jul 22, 2026, 08:25:16 PM
apollo-vertex 🟢 Ready Preview, Logs Jul 22, 2026, 08:25:16 PM

@github-actions

Copy link
Copy Markdown
Contributor

Dependency License Review

  • 1950 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1720
ISC 89
Apache-2.0 55
BSD-3-Clause 27
BSD-2-Clause 23
BlueOak-1.0.0 8
MPL-2.0 4
MIT-0 3
CC0-1.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.2.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

@github-actions

github-actions Bot commented Jul 23, 2026

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 9.0% 43.84 MB 57.45 MB ±0
@uipath/apollo-react 37.5% 31.0% (27/87) 7.40 MB 28.32 MB +523 B
@uipath/apollo-wind 41.0% 397.6 KB 2.58 MB −10 B
@uipath/ap-chat 85.8% 43.43 MB 55.93 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.

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.

Pull request overview

Adds multi-strategy “Tidy up” support around CanvasZoomControls, including reusable layout utilities and Storybook demos, while preserving the existing single-action onOrganize behavior for current consumers.

Changes:

  • Introduces new tidy-up utilities (subtleAlignNodes, compactAlignNodes) with unit tests.
  • Extends CanvasZoomControls to optionally render a dropdown strategy menu (and exports the new option type).
  • Enhances Storybook demos and adds a new vertical-flow handle preset (HandleConfigs.topBottom) for straighter vertical routing.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/apollo-react/src/canvas/utils/tidy-up.ts Adds tidy-up strategy constants and two node-layout utilities (snap-to-grid + compact hierarchy layout).
packages/apollo-react/src/canvas/utils/tidy-up.test.ts Adds unit tests covering subtle snapping behavior and compact layout direction overrides.
packages/apollo-react/src/canvas/storybook-utils/mocks/nodes.ts Adds HandleConfigs.topBottom preset for vertical/top-down flows.
packages/apollo-react/src/canvas/components/CanvasZoomControls/index.ts Re-exports the new TidyUpMenuOption type from the component.
packages/apollo-react/src/canvas/components/CanvasZoomControls/CanvasZoomControls.tsx Implements the new dropdown menu variant for tidy-up strategies (while keeping onOrganize fallback).
packages/apollo-react/src/canvas/components/CanvasZoomControls/CanvasZoomControls.stories.tsx Adds stories demonstrating the tidy-up menu and interactive application of strategies on a “messy” workflow.

<BrushCleaning />
</ToolbarButton>
{tidyUpOptions && tidyUpOptions.length > 0 ? (
<DropdownMenu>
>
<BrushCleaning />
</ToolbarButton>
{tidyUpOptions && tidyUpOptions.length > 0 ? (
Comment on lines +33 to +37
/**
* Runs a single "Tidy up" action immediately on click. Ignored when
* `tidyUpOptions` is provided -- pass that instead to offer a choice of
* strategies via a menu.
*/
…y point

- Vertical/Horizontal now show the full toolbar (including Tidy up) instead
  of just zoom/fit, doubling as the canonical full-toolbar reference for
  each orientation; the now-redundant standalone "Tidy up menu" story is
  removed.
- Tidy up: workflow (renamed from "Tidy up interactions") wires the same
  tidy-up strategies into a per-node NodeToolbar overflow menu, scoped to
  that one story via BaseNodeOverrideConfigProvider, alongside the existing
  corner control -- two entry points, one set of actions.
- Tidy up menu items now render icon + label (matching NodeToolbar's
  overflow format) instead of label + description text.
- Horizontal/Vertical layout use label-free handle presets and wider node
  spacing than Compact layout, fixing overlap between handle captions and
  neighboring node labels. Subtle align and Compact layout are unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 23, 2026 16:38

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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

packages/apollo-react/src/canvas/components/CanvasZoomControls/CanvasZoomControls.stories.tsx:120

  • Storybook story titles contain an em dash with spaces (), which is disallowed in Storybook story copy per repo guidelines. Replace it with a colon or a period-separated phrase.
      <StoryInfoPanel
        title="Zoom controls — horizontal"
        description={`Horizontal orientation. Buttons, including Tidy up, are laid out in a row. Last selected: ${lastSelected ?? 'none'}.`}
      />

packages/apollo-react/src/canvas/components/CanvasZoomControls/CanvasZoomControls.stories.tsx:140

  • Storybook story titles contain an em dash with spaces (), which is disallowed in Storybook story copy per repo guidelines. Replace it with a colon or a period-separated phrase.
      <StoryInfoPanel
        title="Zoom controls — with organize"
        description={`Uses "onOrganize" -- a single hardcoded action on click, no menu. This is what AgentCanvas uses in production today. Compare to Vertical/Horizontal, which use "tidyUpOptions" for a menu of strategies instead. Organize pressed: ${organizeCount} time${organizeCount === 1 ? '' : 's'}.`}
      />

Comment on lines 96 to 99
<StoryInfoPanel
title="Zoom controls — vertical"
description="Default vertical orientation. Zoom in, zoom out, and fit to screen buttons are stacked vertically."
description={`Default vertical orientation. Zoom in, zoom out, fit to screen, and Tidy up are stacked vertically. Last selected: ${lastSelected ?? 'none'}.`}
/>
Comment on lines +1 to +4
import type { Edge, Node } from '@uipath/apollo-react/canvas/xyflow/react';
import { d3HierarchyLayout } from './coded-agents/d3-layout';

export type TidyUpStrategyId = 'subtle' | 'compact';
Comment on lines +131 to +171
{tidyUpOptions && tidyUpOptions.length > 0 ? (
<DropdownMenu>
<Tooltip>
<TooltipTrigger asChild>
<DropdownMenuTrigger asChild>
<Button
data-testid="tidy-up-menu-button"
aria-label={_({ id: 'canvas.zoom.tidy_up', message: 'Tidy up' })}
variant="ghost"
size="xs"
icon
className={ZOOM_ICON_BUTTON_CLASS}
>
<BrushCleaning />
</Button>
</DropdownMenuTrigger>
</TooltipTrigger>
<TooltipContent side={tooltipSide}>
{_({ id: 'canvas.zoom.tidy_up', message: 'Tidy up' })}
</TooltipContent>
</Tooltip>
<DropdownMenuContent align="end" side={tooltipSide} sideOffset={8} className="w-48">
{tidyUpOptions.map((option) => (
<Fragment key={option.id}>
{option.separatorBefore && <DropdownMenuSeparator />}
<DropdownMenuItem
data-testid={`tidy-up-option-${option.id}`}
disabled={option.disabled}
onSelect={() => onTidyUpSelect?.(option.id)}
>
{typeof option.icon === 'string' ? (
<CanvasIcon icon={option.icon} size={16} />
) : (
option.icon
)}
<span>{option.label}</span>
</DropdownMenuItem>
</Fragment>
))}
</DropdownMenuContent>
</DropdownMenu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:apollo-react size:XL 500-999 changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants