Skip to content

refactor(ui): consolidate provider selectors and fetch full provider list#11286

Open
alejandrobailo wants to merge 4 commits into
feat/PROWLER-1761-new-scans-viewfrom
refactor/providers-selectors-improvements
Open

refactor(ui): consolidate provider selectors and fetch full provider list#11286
alejandrobailo wants to merge 4 commits into
feat/PROWLER-1761-new-scans-viewfrom
refactor/providers-selectors-improvements

Conversation

@alejandrobailo
Copy link
Copy Markdown
Contributor

Context

While reviewing the new scans view (#PROWLER-1761) we uncovered three independent issues affecting every provider/account selector across the UI:

  1. The launch scan modal showed disconnected providers as selectable. The page was pre-filtering the providers list down to connected accounts before passing it to ScansPageShell, so the modal's existing disabledValues logic never had inputs to act on. Users couldn't see — let alone understand — why some accounts were unavailable.
  2. Every selector and chart truncated its provider list silently. Different pages used arbitrary pageSize values (50, 100, 200, 500). A tenant with 51 providers would see 50 in a dropdown and never know one was missing.
  3. AccountsSelector + ProviderTypeSelector were repeated in three places (Findings, Resources, Scans) with subtly different cascade logic for clearing incompatible accounts when the provider type filter changed.

This PR addresses all three so the new scans view (and every other surface that uses these filters) behaves consistently.

Description

  • feat(ui): support disabled options in MultiSelect — Adds a disabled prop to MultiSelectItem wired to cmdk (which removes the click handler and excludes the item from keyboard nav), aria-disabled, data-disabled="true", and a defensive onSelect guard.
  • refactor(ui): consolidate provider/account selectors into ProviderAccountSelectors — Introduces a composed filter component that encapsulates both selectors and the cascading cleanup in one place. Migrates Findings, Resources and Scans to it. AccountsSelector swaps the unused selectedProviderTypes description prop for a disabledValues prop, surfacing disabled options with a Badge (variant tag) labelled "Disconnected". ScansPageShell computes its own connectedProviders count locally so the launch button gates on a local invariant.
  • fix(ui): show disconnected providers as disabled in launch scan modal — Passes the full provider list to ScansPageShell so the modal can render disconnected accounts as disabled instead of hiding them.
  • refactor(ui): fetch all providers in selectors and charts — Migrates every selector and provider-driven chart (Overview, Findings, Resources, Alerts, S3/SecHub integrations, risk-plot, risk-pipeline-view, provider groups, provider-type filter on the providers list) to getAllProviders, which paginates internally. The paginated providers list page is left on getProviders since it has real pagination UI.

Steps to review

  1. Pull the branch, run pnpm dev in ui/.
  2. Launch modal: in /scans, click Launch Scan. Verify the dropdown lists every provider in your tenant; disconnected ones appear with a "Disconnected" badge, are visually faded, and don't select on click or keyboard navigation.
  3. Pagination coverage: connect (or seed) more providers than the old per-page tope (e.g. 51 if you previously had 50) and check the dropdowns on /findings, /resources, /, /alerts and the two integrations pages. All entries should appear.
  4. Cascade behavior: on /findings, select a provider type, then a couple of accounts. Change the provider type — the incompatible accounts should clear in the same navigation (no flicker, no stale chips).
  5. Tests: cd ui && pnpm typecheck && pnpm vitest run — should be 910/910 passing.

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

SDK/CLI

  • Are there new checks included in this PR? No

UI

  • All issue/task requirements work as expected on the UI
  • If this PR adds or updates npm dependencies, include package-health evidence (maintenance, popularity, known vulnerabilities, license, release age) and explain why existing/native alternatives are insufficient. — N/A, no dependency changes.
  • 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.

API

  • All issue/task requirements work as expected on the API — N/A, UI-only PR.

License

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

Adds a `disabled` prop to `MultiSelectItem` so individual options can be
rendered as non-interactive while remaining visible. Wires `disabled` to
cmdk (which removes the click handler and excludes the item from keyboard
navigation), sets `aria-disabled` and `data-disabled="true"` for styling
and accessibility, and short-circuits the `onSelect` callback as a
defensive guard.
…ountSelectors

Introduces `ProviderAccountSelectors`, a composed filter component that
encapsulates the `ProviderTypeSelector` + `AccountsSelector` pair together
with the cascading cleanup logic (when a provider type is deselected, its
incompatible accounts are cleared in the same navigation). Supports both
instant (URL-driven) and batch modes via a discriminated union to keep
the prop surface tight.

The findings, resources and scans pages migrate to the shared component,
removing duplicated cascade logic. `AccountsSelector` drops the now-unused
`selectedProviderTypes` description prop in favour of a `disabledValues`
prop so callers can render specific accounts as disabled, surfaced visually
through a `Badge` (variant `tag`) labelled "Disconnected".

`ScansPageShell` also computes a local `connectedProviders` count to gate
the launch button on its own invariants rather than depending on a parent
to pre-filter the providers list.
The scans page was pre-filtering its providers list down to connected ones
before passing it to `ScansPageShell`, which meant the launch scan modal
never received disconnected providers and could not disable them. The
modal already had the logic to compute disconnected ids and pass them to
`AccountsSelector` via `disabledValues`, but the input was empty.

Pass the full providers list down so the modal can render all accounts
with disconnected ones disabled and labelled, giving users visibility
into accounts that exist but can't currently be scanned.
Migrates every provider/account selector and provider-driven chart to
`getAllProviders` so users always see their full provider list instead
of being silently truncated by arbitrary page sizes (50, 100, 200, 500).

`getAllProviders` paginates internally and returns a single combined
response. For tenants under 100 providers the cost is identical to the
old single-shot fetch; only larger tenants pay for additional internal
requests, which is exactly when the missing entries become visible.

Pages migrated:

- Overview, Findings, Resources, Alerts and Integrations (S3, Security
  Hub) — all use the shared `ProviderAccountSelectors`, where truncating
  hid valid provider/account options from filters.
- Risk plot and Risk pipeline charts — both iterate the full provider
  list to build series data, so truncation produced incomplete charts.
- Providers page utils (unfiltered fetch for `ProviderTypeSelector`)
  and `provider-groups-content` (group-assignment selector) — both
  build flat selector lists where pagination has no UI affordance.

The paginated `getProviders` call for the actual providers list page
remains untouched (line 460 of `providers-page.utils.ts`), since that
view has real pagination UI.
@alejandrobailo alejandrobailo requested a review from a team as a code owner May 21, 2026 11:28
@alejandrobailo alejandrobailo self-assigned this May 21, 2026
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.

2 participants