Skip to content

feat(ui): replace D3+Dagre attack path graph with React Flow#10686

Merged
Alan-TheGentleman merged 29 commits into
masterfrom
PROWLER-1273/react-flow-migration
May 12, 2026
Merged

feat(ui): replace D3+Dagre attack path graph with React Flow#10686
Alan-TheGentleman merged 29 commits into
masterfrom
PROWLER-1273/react-flow-migration

Conversation

@pfe-nazaries

@pfe-nazaries pfe-nazaries commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

🚀 Feature Complete - Chained PRs

This PR merges the PROWLER-1273/react-flow-migration feature branch.

Included PRs

# PR Sub-task Jira Status
0 #10701 Normalize data types and remove dead state PROWLER-1373 🟢 Merged
1 #10705 Replace D3 rendering with React Flow + Dagre layout PROWLER-1374 🟢 Merged
2 #10756 Implement graph interactions and filtered view (MVP) PROWLER-1375 🟢 Merged
3 #10800 Restore export, adapt fullscreen, add minimap PROWLER-1376 🟢 Merged
4 #10970 Add automated test coverage with Vitest Browser & Harness PROWLER-1405 🟢 Merged
5 #11010 Auto-fit viewport on filter/expand and harden minimap PROWLER-1273 🟢 Merged
6 #11013 Add semantic node visual mapper PROWLER-1273 🟢 Merged
7 #11014 Render provider, service, resource, and finding node icons PROWLER-1273 🟢 Merged
8 #11015 Redesign graph exploration legend and interactions PROWLER-1273 🟢 Merged
9 #11016 Expand Attack Paths node icon and legend coverage PROWLER-1273 🟢 Merged
10 #11017 Improve graph layout orientation and highlight behavior PROWLER-1273 🟢 Merged
11 #11020 Dynamic finding layout, graph hardening, and simplified clicks PROWLER-1273 🟢 Merged

Legend: 🟢 Merged | 🟡 Open | 🔴 Changes Requested | 🔵 In Progress | ⚪ Pending

MVP milestone: After PR2, the graph is fully functional except export.
Phase 1 complete: After PR3.
Hardening complete: After PR4 (automated test coverage).
Polish complete: After PR5 (viewport and minimap fixes).
Visual UX complete: After PR9 (semantic node visuals, icons, and dynamic legend).
Interaction hardening complete: After PR11 (dynamic findings, graph hardening, and simplified click model).

Dependency Diagram

         ┌──────────────────────────┐
         │ PR0: Normalize data      │ ← #10701 🟢
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR1: React Flow core     │ ← #10705 🟢
         │   rendering              │
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR2: Interactions        │ ← #10756 🟢
         │   🎯 MVP                 │
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR3: Export + Minimap    │ ← #10800 🟢
         │   ✅ Phase 1 complete    │
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR4: Test coverage       │ ← #10970 🟢
         │   🛡️ Hardening complete  │
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR5: Auto-fit + minimap  │ ← #11010 🟢
         │   ✨ Polish              │
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR6: Node visual mapper  │ ← #11013 🟢
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR7: Render node icons   │ ← #11014 🟢
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR8: Legend redesign     │ ← #11015 🟢
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR9: Icon coverage       │ ← #11016 🟢
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR10: Layout highlights  │ ← #11017 🟢
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │ PR11: Dynamic findings   │ ← #11020 🟢
         │   + simplified clicks    │
         └────────────┬─────────────┘
                      │
         ┌────────────▼─────────────┐
         │  📍 THIS PR              │
         │   → master               │
         └──────────────────────────┘

Context

The Attack Path graph was an imperative D3 component that bypassed React reconciliation. This feature branch migrates it to React Flow (@xyflow/react v12), the de-facto standard for graph visualization in React, then incrementally hardens the experience through reviewable chained PRs.

The migration is Phase 1 of the RFC: drop-in replacement achieving feature parity plus minimap, export, automated browser coverage, viewport hardening, semantic node visuals, and a simplified graph interaction model. Phase 2 (edge labels, node grouping, multi-select) will follow in a separate initiative.

Technical design: openspec/changes/react-flow-migration/ contains the full proposal, design, specs, and task breakdown.


Description

Key Changes:

Rendering

  • Replace D3 imperative SVG with React Flow declarative components
  • Custom node types for findings, resources, and internet/root nodes
  • Dagre layout via @dagrejs/dagre (maintained fork)
  • Built-in minimap with high-contrast viewport indicator on the dark theme
  • Semantic node visual resolver with provider badges, service icons, resource icons, and finding severity visuals

Interactions

  • Finding clicks focus the connected path and open finding details
  • Resource clicks toggle related findings directly when findings exist
  • Resources without findings do not expose a click action
  • Dynamic hidden-finding layout avoids reserving empty space until findings are revealed
  • Single-open finding expansion keeps only one resource's findings expanded at a time
  • Hover and selected-path highlighting use Prowler green
  • Horizontal layout and side handles improve path readability

Export

  • PNG export via modern-screenshot + React Flow's viewport helpers
  • JSON export preserved

Cleanup

  • Remove deprecated dagre package (keep d3 — used by geo map components)
  • Remove dead Zustand store fields
  • Normalize graph data and preserve parallel graph edges with unique relationship IDs
  • Remove graph node-details/action-selector flows in favor of finding-details only

Testing

  • Vitest Browser mode with Playwright provider (jsdom is insufficient for React Flow DOM layout and image export)
  • Co-located AttackPathPageHarness for page-level flows
  • MSW handlers for Prowler API mocking; real server actions run through them
  • Coverage for rendering, interactions, filtering, export, dynamic findings, icon/legend behavior, viewport behavior, race regressions, and graph edge cases

Steps to review

  1. Review individual chained PRs first (linked in table above)
  2. Verify graph rendering: layout, colors, icons, node labels, and legend
  3. Test interactions: finding click, resource findings toggle, hover highlight, filtered view, zoom/pan
  4. Test export: PNG and JSON download behavior
  5. Test fullscreen: render, controls, export, and graph interactions
  6. Verify dynamic findings: initial graph does not reserve hidden-finding space, only one resource's findings are open at a time, and resources without findings are not clickable
  7. Run pnpm test:browser in ui/ — verify the page-level suite passes

Checklist

Community Checklist
  • This feature/issue is listed in here or roadmap.prowler.com
  • Is it assigned to me, if not, request it via the issue/feature in here or Prowler Community Slack

UI

  • All issue/task requirements work as expected on the UI
  • Screenshots/Video of the functionality flow (if applicable) - Mobile (X < 640px)
  • Screenshots/Video of the functionality flow (if applicable) - Table (640px > X < 1024px)
  • Screenshots/Video of the functionality flow (if applicable) - Desktop (X > 1024px)
  • Ensure new entries are added to CHANGELOG.md, if applicable.

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@pfe-nazaries pfe-nazaries requested a review from a team April 14, 2026 14:27
@pfe-nazaries pfe-nazaries added the no-merge Please, DO NOT MERGE this PR. label Apr 14, 2026
@github-actions

github-actions Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

✅ All necessary CHANGELOG.md files have been updated.

@github-actions

github-actions Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Conflict Markers Resolved

All conflict markers have been successfully resolved in this pull request.

@github-actions

github-actions Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

🔒 Container Security Scan

Image: prowler:776b7b5
Last scan: 2026-05-05 12:32:31 UTC

📊 Vulnerability Summary

Severity Count
🔴 Critical 5
Total 5

5 package(s) affected

⚠️ Action Required

Critical severity vulnerabilities detected. These should be addressed before merging:

  • Review the detailed scan results
  • Update affected packages to patched versions
  • Consider using a different base image if updates are unavailable

📋 Resources:

@github-actions

github-actions Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

🔒 Container Security Scan

Image: prowler-ui:9719e13
Last scan: 2026-05-12 10:57:07 UTC

📊 Vulnerability Summary

Severity Count
🔴 Critical 2
Total 2

2 package(s) affected

⚠️ Action Required

Critical severity vulnerabilities detected. These should be addressed before merging:

  • Review the detailed scan results
  • Update affected packages to patched versions
  • Consider using a different base image if updates are unavailable

📋 Resources:

@pfe-nazaries pfe-nazaries requested a review from a team as a code owner May 5, 2026 11:38
@github-actions github-actions Bot added the github_actions Pull requests that update GitHub Actions code label May 5, 2026
Comment thread ui/public/mockServiceWorker.js Fixed

@alejandrobailo alejandrobailo 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.

Please remove "Attack Paths" as title from the view, as the breadcrumb already mention it.

Pablo F.G and others added 5 commits May 8, 2026 15:04
Adds the openspec repository as a submodule at openspec/ for shared
spec definitions used by SDD tooling across AI coding assistants.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…spec updates

Bumps the openspec submodule to incorporate the linearized task completion
status and spec updates from PR0 (1373), PR1 (1374), and PR2 (1375).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Alan-TheGentleman Alan-TheGentleman force-pushed the PROWLER-1273/react-flow-migration branch from ddee0ef to c175da6 Compare May 8, 2026 13:08
- Remove the duplicated resource-click helper from the harness
- Fix graph formatting required by UI lint hooks
- Restore typecheck and build validation for attack paths
Comment thread ui/scripts/postinstall.js Fixed
Comment thread ui/scripts/postinstall.js Fixed
@Alan-TheGentleman Alan-TheGentleman removed the no-merge Please, DO NOT MERGE this PR. label May 11, 2026

@Alan-TheGentleman Alan-TheGentleman 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.

CI is green and the CodeQL/MSW thread has been resolved.

- Render graph export from data-driven canvas
- Preserve visible graph state and finding markers
- Add export regression coverage

@Alan-TheGentleman Alan-TheGentleman 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.

Approved after addressing the requested changes and validating the latest export fix.

alejandrobailo
alejandrobailo previously approved these changes May 12, 2026

@alejandrobailo alejandrobailo 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.

Awesome work!

- Resolve UI dependency metadata conflicts
- Preserve React Flow migration dependencies
- Include latest master updates before merge
@Alan-TheGentleman Alan-TheGentleman dismissed stale reviews from alejandrobailo and themself via df70754 May 12, 2026 10:18
alejandrobailo
alejandrobailo previously approved these changes May 12, 2026
@Alan-TheGentleman Alan-TheGentleman dismissed stale reviews from alejandrobailo and themself via 73002f5 May 12, 2026 10:46
Comment thread ui/CHANGELOG.md Outdated
@Alan-TheGentleman Alan-TheGentleman self-requested a review May 12, 2026 14:18
@Alan-TheGentleman Alan-TheGentleman merged commit 1090ed5 into master May 12, 2026
26 of 27 checks passed
@Alan-TheGentleman Alan-TheGentleman deleted the PROWLER-1273/react-flow-migration branch May 12, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/ui github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants