Skip to content

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

Open
pfe-nazaries wants to merge 21 commits intomasterfrom
PROWLER-1273/react-flow-migration
Open

feat(ui): replace D3+Dagre attack path graph with React Flow#10686
pfe-nazaries wants to merge 21 commits intomasterfrom
PROWLER-1273/react-flow-migration

Conversation

@pfe-nazaries
Copy link
Copy Markdown
Contributor

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

🚀 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 🟡 Open
6 #11013 Add semantic node visual mapper PROWLER-1273 🟡 Open
7 #11014 Render provider, service, resource, and finding node icons PROWLER-1273 🟡 Open
8 #11015 Redesign graph exploration legend and interactions PROWLER-1273 🟡 Open
9 #11016 Expand Attack Paths node icon and legend coverage PROWLER-1273 🟡 Open
10 #11017 Improve graph layout orientation and highlight behavior PROWLER-1273 🟡 Open
11 #11020 Dynamic finding layout, graph hardening, and simplified clicks PROWLER-1273 🟡 Open

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
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 14, 2026

✅ All necessary CHANGELOG.md files have been updated.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 14, 2026

Conflict Markers Resolved

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 14, 2026

🔒 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
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

🔒 Container Security Scan

Image: prowler-ui:f7a274e
Last scan: 2026-05-08 16:38:12 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
event.waitUntil(self.clients.claim())
})

addEventListener('message', async function (event) {
Copy link
Copy Markdown
Contributor

@alejandrobailo alejandrobailo left a comment

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>
Pablo F.G and others added 15 commits May 8, 2026 15:04
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#10701)

Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
)

Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…0800)

Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…10970)

Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detach the openspec submodule so the directory is managed as a
local clone instead. /openspec/ remains in .gitignore so the cloned
working tree is never tracked by this repo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rden minimap (#11010)

Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Alan Buscaglia <gentlemanprogramming@gmail.com>
Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
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
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 no-merge Please, DO NOT MERGE this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants