Skip to content

fix(ui): hide muted finding groups immediately on /findings#11170

Open
HugoPBrito wants to merge 3 commits into
masterfrom
PROWLER-1454-findings-groups-update-table-immediately-after-muting-a-group
Open

fix(ui): hide muted finding groups immediately on /findings#11170
HugoPBrito wants to merge 3 commits into
masterfrom
PROWLER-1454-findings-groups-update-table-immediately-after-muting-a-group

Conversation

@HugoPBrito
Copy link
Copy Markdown
Member

@HugoPBrito HugoPBrito commented May 14, 2026

Context

Muting a finding group on /findings left the row visible until the user reloaded manually. The default /finding-groups/latest endpoint reads from FindingGroupDailySummary, which is rebuilt asynchronously by the Celery chain queued in MuteRuleViewSet.create (mute_historical_findings_taskreaggregate_all_finding_group_summaries_task). A router.refresh() fired right after POST /mute-rules therefore returns the same stale aggregate, so the row reappears even though the mute was applied. After a slower manual reload the chain has typically finished and the row disappears, which matches what users expect.

A previous attempt to make the reaggregation synchronous inside the request handler added 100ms–2s to every mute and scaled poorly on tenants with many scans, so the fix lives entirely in the UI.

Description

UI-only optimistic hide with a short sessionStorage safety net so a fast reload does not break the illusion while the Celery chain catches up:

  • New utility ui/lib/optimistic-muted-groups.ts (+ unit tests): persists muted check_ids under prowler:optimistic-muted-groups with a 90s TTL per entry. Each entry tracks its own expiresAt (no shared TTL extension across mutes), expired entries are pruned on read, defensive against sessionStorage exceptions (Safari private mode, quota).
  • findings-group-table.tsx: hydrates the optimistic Set<string> from storage on mount, derives visibleData from data ⊖ optimistic set, and clears entries from storage when the server payload no longer includes a check_id (the natural confirmation signal). Replaces every previous safeData reference with visibleData so selection indices, row counts and the table stay coherent. Honors filter[muted]=include: when the user opted in to seeing muted groups, the row stays visible (with the muted indicator) so the optimistic state does not diverge from the post-reload view.
  • Three mute paths now feed the same hide pipeline:
    • Group-level mute via FloatingMuteButton (checkbox + bulk button) – existing path.
    • Group-level mute via the row dropdown – data-table-row-actions.tsx now reads onMuteComplete from the selection context as a fallback so the parent FindingsGroupTable is notified (previously fell back to a bare router.refresh()).
    • Resource-level mute inside the drill-down (row dropdown or floating button with resources selected) – propagated through a new onResourceMuteCompleted prop on InlineResourceContainer, with column-finding-resources.tsx passing the muted finding IDs through the context.
  • Defensive heuristic willResourceMuteEmptyGroup: when a resource-level mute leaves the expanded group fully muted on the server (every unmuted FAIL covered AND no unmuted PASS/MANUAL), we hide the group too. Conservative on purpose so we do not pre-hide a group that would still be visible post-reload.
  • Drill-down auto-collapses when the expanded group is hidden.
  • findings-selection-context.tsx: onMuteComplete signature widened to (mutedIds?: string[]) => void. Backward-compatible.

No API, MCP, or SDK changes. The Celery chain in MuteRuleViewSet.create continues to run untouched.

Steps to review

  1. cd ui && pnpm install
  2. pnpm vitest run lib/optimistic-muted-groups.test.ts components/findings/table/findings-group-table.test.tsx components/findings/table/data-table-row-actions.test.tsx components/findings/table/column-finding-resources.test.tsx components/findings/table/column-finding-groups.test.tsx → 35 tests pass.
  3. pnpm run typecheck && pnpm run lint:check → clean.
  4. Local stack: open /findings.
    • Group mute (floating button): select one or more group rows, click Mute, submit modal → rows disappear instantly.
    • Group mute (row dropdown): from the row’s menu pick Mute Finding Group → row disappears instantly.
    • Resource mute that empties the group: drill into a group whose only failing resource is a single one, mute it from its row dropdown → resource disappears from the drill-down AND the parent group row disappears.
    • Resource mute that does NOT empty the group: mute one of several failing resources → drill-down updates, parent row remains (correct, group still has unmuted findings).
    • Fast reload (F5) within ~90s of a mute: muted groups remain hidden because sessionStorage was hydrated on mount.
    • Include muted findings toggle: muted groups reappear with the muted indicator and the optimistic hide does not kick in (no divergence from post-reload state).
    • Wait until Celery chain catches up + reload: the muted group is gone from the server payload and the corresponding sessionStorage entry is auto-removed (no leftover state).

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 (if applicable)

  • All issue/task requirements work as expected on the UI
  • Screenshots/Video - Mobile (X < 640px)
  • Screenshots/Video - Tablet (640px > X < 1024px)
  • Screenshots/Video - Desktop (X > 1024px)
  • Ensure new entries are added to ui/CHANGELOG.md

License

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

- Track optimistically-muted check_ids in sessionStorage with 90s TTL
- Wire row-action and floating-mute paths through selection context
- Hide expanded group when its last unmuted resource is muted
- Honor Include muted findings filter to stay in sync with reload
@HugoPBrito HugoPBrito requested a review from a team as a code owner May 14, 2026 09:51
@HugoPBrito
Copy link
Copy Markdown
Member Author

Screen.Recording.2026-05-14.at.11.13.37.mov

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.

1 participant