Skip to content

Improve flow builder auto-layout and lazy-load the ELK engine - #4153

Merged
DonOmalVindula merged 1 commit into
thunder-id:mainfrom
DonOmalVindula:improve-flow-auto-layout
Jul 20, 2026
Merged

Improve flow builder auto-layout and lazy-load the ELK engine#4153
DonOmalVindula merged 1 commit into
thunder-id:mainfrom
DonOmalVindula:improve-flow-auto-layout

Conversation

@DonOmalVindula

@DonOmalVindula DonOmalVindula commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Purpose

Auto-layout in the flow builder sometimes produces incoherent results: Call nodes stranded far off the main line, long edge detours from view links, and inconsistent vertical alignment (see the issue's parent, flow builder UX). Refs #3871.

Two root causes:

  1. A dead and destructive post-processing pass. After ELK computed a layout, a post-pass re-centered VIEW/START/END nodes onto one line and was supposed to reposition execution nodes too, but it compared against 'EXECUTION' while canvas executor nodes have type 'TASK_EXECUTION', so that branch never ran, and CALL/RULE nodes were not handled at all. The result mixed two coordinate systems: some node types were moved after the fact while others kept positions from ELK's original (now torn apart) layout. This is exactly the "floating Call node" symptom.
  2. ELK had no handle information. Edges were fed as node-to-node connections, so placement decisions ignored where edges actually attach (success on the right, failure at the bottom, incomplete on top).

Approach

Give ELK the canvas semantics and trust its output, instead of correcting it afterwards:

  • Handles are modeled as fixed-side ports derived from the canvas conventions (*_NEXT → east, failure → south, *_INCOMPLETE → north, *_PREVIOUS → west; targets are west ports). ELK then places failure branches below their source and routes view-link branches sensibly.
  • The happy path is straightened: the success chain from START to END gets elk.layered.priority.straightness, which the NETWORK_SIMPLEX placement honors, so the main flow reads as one left-to-right row with branches hanging off it.
  • The per-type post-processing pass is removed entirely. ELK positions are applied uniformly to every node type, eliminating the mixed-coordinate failure mode.
  • Edge deduplication now keys on the source handle too, so success and failure edges between the same pair of nodes both inform the layout.
  • Edge clearance options are reduced to moderate values; the canvas draws its own smart edges, so ELK's own routing only needs to influence placement, and oversized clearances inflated the layout's footprint.

Verified against real ELK (not just the test mock) with a graph mirroring the reported layout: the executor chain lands on a single aligned row, START aligns with the view it feeds, and both CALL nodes stack cleanly below the credentials column.

The test suite is rewritten to assert the semantics handed to ELK (ports, layer constraints, straightness priorities, dedup) plus uniform position mapping, rather than the removed post-pass behavior.

Note for reviewers: layout quality is visual; a manual pass on the starter templates and a flow with link widgets (self sign up / recovery) is recommended.

Related Issues

Related PRs

Checklist

  • Followed the contribution guidelines.
  • Manual test round performed and verified.
  • Documentation provided. (Add links if there are any)
    • Ran Vale and fixed all errors and warnings
  • Tests provided. (Add links if there are any)
    • Unit Tests
    • Integration Tests
  • Breaking changes. (Fill if applicable)
    • Breaking changes section filled.
    • breaking change label added.

Security checks

  • Followed secure coding standards in WSO2 Secure Coding Guidelines
  • Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.

Summary by CodeRabbit

  • Improvements
    • Improved automatic flow layout to preserve success paths as the primary straight-through route.
    • Improved edge placement by respecting success, failure, and incomplete connection directions.
    • Prevented duplicate or invalid connections from affecting layout.
    • Improved node sizing and positioning, including measured dimensions and configured offsets.
    • Preserved the original layout when automatic layout cannot be completed.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@DonOmalVindula, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e9462990-d90c-46ec-9dad-6164627fe52d

📥 Commits

Reviewing files that changed from the base of the PR and between 739c99c and c343923.

📒 Files selected for processing (3)
  • frontend/apps/console/src/features/flows/components/visual-flow/DecoratedVisualFlow.tsx
  • frontend/apps/console/src/features/flows/utils/__tests__/applyAutoLayout.test.ts
  • frontend/apps/console/src/features/flows/utils/applyAutoLayout.ts
📝 Walkthrough

Walkthrough

applyAutoLayout now models React Flow handles as fixed-side ELK ports, prioritizes the START-to-END success chain, normalizes edges, forwards updated spacing options, and maps ELK coordinates directly to nodes. Tests capture ELK input and cover positioning, dimensions, ports, edge handling, and failures.

Changes

ELK Auto-layout graph construction

Layer / File(s) Summary
Port-aware graph construction
frontend/apps/console/src/features/flows/utils/applyAutoLayout.ts, frontend/apps/console/src/features/flows/utils/__tests__/applyAutoLayout.test.ts
Handle sides, port constraints, success-path priorities, edge de-duplication, and invalid-node filtering are represented and tested in the ELK graph.
Coordinate mapping and fallback
frontend/apps/console/src/features/flows/utils/applyAutoLayout.ts, frontend/apps/console/src/features/flows/utils/__tests__/applyAutoLayout.test.ts
ELK coordinates are returned with offsets, node dimensions follow the measured/declared/default precedence, node data is preserved, and layout failures return the original nodes.
Typed layout harness and options
frontend/apps/console/src/features/flows/utils/__tests__/applyAutoLayout.test.ts
The ELK mock captures typed input graphs and tests layout direction, spacing, layer constraints, and nodes without a type.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReactFlow
  participant applyAutoLayout
  participant ELK
  ReactFlow->>applyAutoLayout: provide nodes and edges
  applyAutoLayout->>ELK: submit fixed-side ports and prioritized edges
  ELK-->>applyAutoLayout: return layout coordinates
  applyAutoLayout-->>ReactFlow: return positioned nodes
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title matches the main changes: auto-layout improvements plus lazy-loading the ELK engine.
Description check ✅ Passed The description follows the template with Purpose, Approach, Related Issues, Related PRs, Checklist, and Security checks.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@DonOmalVindula
DonOmalVindula force-pushed the improve-flow-auto-layout branch from 739c99c to ff3d628 Compare July 20, 2026 08:18
@DonOmalVindula DonOmalVindula changed the title Improve flow builder auto-layout with handle-aware ports and happy-path alignment Improve flow builder auto-layout and lazy-load the ELK engine Jul 20, 2026
@DonOmalVindula
DonOmalVindula force-pushed the improve-flow-auto-layout branch from ff3d628 to bbcb7ef Compare July 20, 2026 08:25

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
frontend/apps/console/src/features/flows/utils/__tests__/applyAutoLayout.test.ts (1)

215-233: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assertion doesn't verify handle-to-side correspondence.

Sorting sides before comparing to ['NORTH', 'SOUTH'] only checks that both sides exist somewhere, not that failureSOUTH and exec_INCOMPLETENORTH specifically. A swapped mapping would still pass.

🧪 Suggested stronger assertion
       const byId = new Map(lastGraph?.children.map((child) => [child.id, child]));
       const ports = byId.get('exec')?.ports ?? [];
-      const sides = ports.map((port) => port.layoutOptions['elk.port.side']).sort();
-
-      expect(sides).toEqual(['NORTH', 'SOUTH']);
+
+      expect(ports.find((port) => port.id === 'exec__failure')?.layoutOptions['elk.port.side']).toBe('SOUTH');
+      expect(ports.find((port) => port.id === 'exec__exec_INCOMPLETE')?.layoutOptions['elk.port.side']).toBe('NORTH');
🤖 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
`@frontend/apps/console/src/features/flows/utils/__tests__/applyAutoLayout.test.ts`
around lines 215 - 233, Update the test around applyAutoLayout to assert each
port’s side by its handle identifier, rather than sorting the collected sides.
Verify that the failure handle maps to SOUTH and the exec_INCOMPLETE handle maps
to NORTH, so swapped port assignments fail the test.
🤖 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 `@frontend/apps/console/src/features/flows/utils/applyAutoLayout.ts`:
- Around line 55-75: The sourcePortSide helper currently ignores the layout
direction, causing DOWN/UP layouts to assign incorrect port sides. Update
sourcePortSide and its callers to derive EAST/WEST/NORTH/SOUTH from the active
direction while preserving the failure, incomplete, previous, and default handle
distinctions; alternatively remove or narrow the direction option if only RIGHT
is supported.

---

Nitpick comments:
In
`@frontend/apps/console/src/features/flows/utils/__tests__/applyAutoLayout.test.ts`:
- Around line 215-233: Update the test around applyAutoLayout to assert each
port’s side by its handle identifier, rather than sorting the collected sides.
Verify that the failure handle maps to SOUTH and the exec_INCOMPLETE handle maps
to NORTH, so swapped port assignments fail the test.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 57f7059f-f7f7-44af-9dca-8cb820338255

📥 Commits

Reviewing files that changed from the base of the PR and between cc16eaa and 739c99c.

📒 Files selected for processing (2)
  • frontend/apps/console/src/features/flows/utils/__tests__/applyAutoLayout.test.ts
  • frontend/apps/console/src/features/flows/utils/applyAutoLayout.ts

Comment thread frontend/apps/console/src/features/flows/utils/applyAutoLayout.ts
@DonOmalVindula
DonOmalVindula force-pushed the improve-flow-auto-layout branch from bbcb7ef to 03b68f9 Compare July 20, 2026 08:27
Model canvas handles as fixed-side ELK ports, straighten the success path,
and drop the per-type post-processing pass that tore layouts apart. Load the
~1.5MB ELK engine on demand instead of bundling it into the builder chunk,
clearing the cached import on failure so layout can retry.

Refs thunder-id#3871
@DonOmalVindula
DonOmalVindula force-pushed the improve-flow-auto-layout branch from 03b68f9 to c343923 Compare July 20, 2026 08:44
@DonOmalVindula
DonOmalVindula enabled auto-merge July 20, 2026 08:54
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.16129% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...onsole/src/features/flows/utils/applyAutoLayout.ts 95.16% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@DonOmalVindula
DonOmalVindula added this pull request to the merge queue Jul 20, 2026
Merged via the queue into thunder-id:main with commit e0fde27 Jul 20, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants