Skip to content

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

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

feat(apollo-react): multi-strategy Tidy up menu for CanvasZoomControls#957
dbacomputer wants to merge 4 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

github-actions Bot commented Jul 23, 2026

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.3.2 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 38.6% 52.4% (870/1660) 7.52 MB 28.95 MB +16.3 KB
@uipath/apollo-wind 42.2% 88.3% (121/137) 420.5 KB 2.73 MB ±0
@uipath/ap-chat 85.8% 43.45 MB 56.01 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>
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Apollo Coded App preview deployments are ready.

Project Status Preview Updated (PT)
apollo-design Ready Preview · Logs Aug 06, 2026, 07:31:44 AM
apollo-docs Ready Preview · Logs Aug 06, 2026, 07:31:44 AM
apollo-landing Ready Preview · Logs Aug 06, 2026, 07:31:44 AM
apollo-vertex Ready Preview · Logs Aug 06, 2026, 07:31:44 AM

@github-actions github-actions Bot added size:XXL 1,000+ changed lines. and removed size:XL 500-999 changed lines. labels Jul 28, 2026
Copilot AI review requested due to automatic review settings August 6, 2026 14:24

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 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (5)

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

  • tidyUpOptions can be provided without onTidyUpSelect, which renders a menu whose items are effectively no-ops. Tighten the prop types so providing options requires a selection handler (while still allowing onOrganize for back-compat).
   * When provided (with at least one option), the "Tidy up" button opens a
   * menu of strategies instead of running a single hardcoded action.
   */
  tidyUpOptions?: TidyUpMenuOption[];
  onTidyUpSelect?: (optionId: string) => void;

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

  • Storybook copy should avoid the spaced em dash " — " per repo guidance for .stories.tsx content. Consider using a colon or parentheses instead.
        title="Zoom controls — vertical"

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

  • Storybook copy should avoid the spaced em dash " — " per repo guidance for .stories.tsx content. Consider using a colon or parentheses instead.
        title="Zoom controls — horizontal"

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

  • The new dropdown-menu rendering/selection path isn’t covered by unit tests (unlike many other canvas components). Adding a CanvasZoomControls.test.tsx that asserts the menu opens and calls onTidyUpSelect for a chosen option would help prevent regressions.
        {tidyUpOptions && tidyUpOptions.length > 0 ? (
          <DropdownMenu>
            <Tooltip>
              <TooltipTrigger asChild>
                <DropdownMenuTrigger asChild>

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

  • Storybook copy should avoid the spaced em dash " — " per repo guidance for .stories.tsx content. Consider using a colon or parentheses instead.
        title="Zoom controls — with organize"

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Storybook visual diff

⚠️ Visual changes detected: 12 changed, 2 added (of 302 compared, 288 unchanged). View report

Baseline is the deployed main Storybook, so changes merged to main after this branch was last updated can also appear here. Logs

Updated (PT): Aug 06, 2026, 07:49:23 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:apollo-react size:XXL 1,000+ changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants