Skip to content

[CHAIN] fix(ui): simplify attack paths graph interactions#11020

Merged
Alan-TheGentleman merged 13 commits intoPROWLER-1273/react-flow-migrationfrom
PROWLER-1273/attack-path-dynamic-finding-layout
May 8, 2026
Merged

[CHAIN] fix(ui): simplify attack paths graph interactions#11020
Alan-TheGentleman merged 13 commits intoPROWLER-1273/react-flow-migrationfrom
PROWLER-1273/attack-path-dynamic-finding-layout

Conversation

@Alan-TheGentleman
Copy link
Copy Markdown
Contributor

@Alan-TheGentleman Alan-TheGentleman commented May 5, 2026

🔗 Part of Chained PRs

Field Value
Feature Branch PROWLER-1273/react-flow-migration
Main PR #10686
Sub-task PROWLER-1273
Chain Position 11 of 11
Depends on #11017 (PR10 — Layout highlights) 🟡 Open

Chain Overview

#10701 → #10705 → #10756 → #10800 → #10970 → #11010 → #11013 → #11014 → #11015 → #11016 → #11017 → 📍 #11020 → #10686

Context

Final interaction-hardening slice for the Attack Paths React Flow migration chain tracked by #10686. This PR builds on #11017 and focuses on dynamic finding layout, graph correctness regressions, and a simplified click model.


Description

Changes:

  • Excludes hidden finding nodes and edges before Dagre layout so the initial graph does not reserve empty finding space.
  • Reflows the graph only when findings are explicitly shown/hidden.
  • Keeps only one resource's findings expanded at a time.
  • Preserves parallel graph edges with unique relationship IDs.
  • Keeps unattached findings visible and shares the hidden-finding rule between graph and legend.
  • Makes selected node styling override finding-alert border styling.
  • Simplifies graph clicks:
    • finding click opens finding details and filtered path
    • resource with findings toggles findings directly
    • resource without findings has no click action
  • Narrows related unit-test workflow execution to the unit project to avoid duplicating browser tests.
  • Strengthens Attack Paths unit/browser regression coverage for graph layout, legend visibility, hover highlighting, rapid finding clicks, and simplified graph interactions.

Steps to review

  1. Review this PR after [CHAIN] fix(ui): improve attack paths graph layout highlights #11017.
  2. Open Attack Paths and execute a graph query.
  3. Verify the initial graph is compact and does not reserve empty space for hidden findings.
  4. Click a resource with findings and verify findings show directly without an intermediate action modal.
  5. Click the same resource again and verify findings hide.
  6. Click a resource without findings and verify no modal/details panel opens.
  7. Click a finding and verify the filtered path and finding details open.
  8. Verify legend entries match the currently visible graph nodes and finding sections.
  9. Run focused tests if validating locally:
pnpm exec vitest run --project unit "app/(prowler)/attack-paths/(workflow)/query-builder/_hooks/use-graph-state.test.ts" "app/(prowler)/attack-paths/(workflow)/query-builder/_lib/layout.test.ts" "app/(prowler)/attack-paths/(workflow)/query-builder/_components/graph/graph-legend.test.tsx"
pnpm test:browser -- --run attack-paths-page

Commit hooks also passed TypeScript, ESLint, unit tests, and UI build for the latest commits.


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) - Tablet (640px > X < 1024px)
  • Screenshots/Video of the functionality flow (if applicable) - Desktop (X > 1024px)
  • Ensure new entries are added to ui/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.

@Alan-TheGentleman Alan-TheGentleman requested review from a team as code owners May 5, 2026 23:08
@Alan-TheGentleman Alan-TheGentleman changed the title fix(ui): avoid reserving attack path finding space [CHAIN] fix(ui): simplify attack paths graph interactions May 6, 2026
.spyOn(harness.user, "click")
.mockRejectedValue(pointerError);
const domClickSpy = vi.spyOn(node, "click");

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.

I think is overkill to test the test util / harness / page object model

? graphState.expandedResources.has(nodeAction.node.id)
: false;
try {
await finding.navigateToFinding(findingId);
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.

Optional: add catch block to log the error if you find value on it

@pfe-nazaries pfe-nazaries self-requested a review May 8, 2026 08:06
@Alan-TheGentleman Alan-TheGentleman force-pushed the PROWLER-1273/attack-path-layout-highlights branch from d8bd77c to 544b9e4 Compare May 8, 2026 12:21
@Alan-TheGentleman Alan-TheGentleman force-pushed the PROWLER-1273/attack-path-dynamic-finding-layout branch from f0c5621 to a0826db Compare May 8, 2026 12:39
@Alan-TheGentleman Alan-TheGentleman force-pushed the PROWLER-1273/attack-path-layout-highlights branch from 544b9e4 to a505e10 Compare May 8, 2026 12:56
Base automatically changed from PROWLER-1273/attack-path-layout-highlights to PROWLER-1273/react-flow-migration May 8, 2026 12:57
Alan-TheGentleman and others added 13 commits May 8, 2026 14:59
- Drop the repeated page heading from the query builder view
- Add a regression test for the review feedback
- Remove an unused icon import blocking UI lint checks
The Attack Path graph now re-fits its viewport when the user enters
the filtered view (click on a finding) or returns to the full graph
("Back to Full View"), so the focused subgraph and the restored
full graph are always centered instead of leaving the viewport
pointing at the previous coordinates. Resource expansion no longer
re-fits — the initial fit already includes hidden findings, so newly
revealed nodes sit inside the framing the user already has.

The minimap viewport indicator (mask cut-out) is darkened and given
a thicker border to stand out against the dark theme, where it was
previously hard to see.
…ings

Recover the expand-time auto-fit lost while smoothing the filter
fix. Hidden findings are not measured by React Flow on initial
render, so `fitViewOptions.includeHiddenNodes` cannot extend the
initial viewport to cover them — clicking a resource that has its
findings laid out beyond the framed area would leave the user with
empty space and no way to discover the newly revealed nodes.

The expand-fit only fires for resources that just transitioned from
collapsed to expanded, and only when at least one of the connected
findings sits entirely past the current viewport (full bounding box
beyond the edge). Partially clipped edge nodes are left alone so
the framing the user already has is preserved when nothing has
actually moved off-screen.

Auto-fits now use asymmetric padding (extra room on the right and
bottom) to keep the minimap clear after a fit. Without it, fitted
nodes could land underneath the bottom-right minimap and become
unclickable.

The expand-without-re-fit test was a lock-in for the previous
behaviour and is replaced with one asserting the new behaviour:
expanding resources whose findings sit off-screen re-fits the
viewport.
The Attack Path graph now re-fits its viewport when the user enters
the filtered view (click on a finding) or returns to the full graph
("Back to Full View"), so the focused subgraph and the restored
full graph are always centered instead of leaving the viewport
pointing at the previous coordinates. Resource expansion no longer
re-fits — the initial fit already includes hidden findings, so newly
revealed nodes sit inside the framing the user already has.

The minimap viewport indicator (mask cut-out) is darkened and given
a thicker border to stand out against the dark theme, where it was
previously hard to see.

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

Recover the expand-time auto-fit lost while smoothing the filter
fix. Hidden findings are not measured by React Flow on initial
render, so `fitViewOptions.includeHiddenNodes` cannot extend the
initial viewport to cover them — clicking a resource that has its
findings laid out beyond the framed area would leave the user with
empty space and no way to discover the newly revealed nodes.

The expand-fit only fires for resources that just transitioned from
collapsed to expanded, and only when at least one of the connected
findings sits entirely past the current viewport (full bounding box
beyond the edge). Partially clipped edge nodes are left alone so
the framing the user already has is preserved when nothing has
actually moved off-screen.

Auto-fits now use asymmetric padding (extra room on the right and
bottom) to keep the minimap clear after a fit. Without it, fitted
nodes could land underneath the bottom-right minimap and become
unclickable.

The expand-without-re-fit test was a lock-in for the previous
behaviour and is replaced with one asserting the new behaviour:
expanding resources whose findings sit off-screen re-fits the
viewport.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Restore supported graph scroll zoom behavior
- Add node action selector for ambiguous resource clicks
- Open finding and node details in existing drawers
- Cover resource actions with browser tests
- Reuse shared measured-fit scheduling for graph viewport updates
- Consolidate node action dialog state
- Tighten browser harness dialog detection
- preserve graph edges and hidden-finding visibility rules
- align workflow scripts and graph legend behavior
- strengthen browser and unit regressions for graph flows
- remove graph node action and details flows
- toggle findings directly from resource clicks
- keep finding details as the only graph detail view
@Alan-TheGentleman Alan-TheGentleman force-pushed the PROWLER-1273/attack-path-dynamic-finding-layout branch from a0826db to 983237d Compare May 8, 2026 13:01
@Alan-TheGentleman Alan-TheGentleman merged commit ddee0ef into PROWLER-1273/react-flow-migration May 8, 2026
3 checks passed
@Alan-TheGentleman Alan-TheGentleman deleted the PROWLER-1273/attack-path-dynamic-finding-layout branch May 8, 2026 13:02
Alan-TheGentleman added a commit that referenced this pull request May 8, 2026
Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants