From 2bd7c39b9b24d1d3dcd51badc9a191866a3885bf Mon Sep 17 00:00:00 2001 From: rcourtman Date: Wed, 25 Mar 2026 16:52:35 +0000 Subject: [PATCH] Hide idle Patrol filter bar Hide the Patrol findings filter bar when there are no findings or special queues to navigate, keeping empty-state Patrol surfaces focused on the actual assessment rather than inert controls. --- .../v6/internal/subsystems/patrol-intelligence.md | 4 ++++ .../src/components/AI/FindingsPanel.tsx | 14 +++++++++++++- .../components/AI/__tests__/FindingsPanel.test.ts | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md index 1316fd21a0..56952f56c6 100644 --- a/docs/release-control/v6/internal/subsystems/patrol-intelligence.md +++ b/docs/release-control/v6/internal/subsystems/patrol-intelligence.md @@ -195,6 +195,10 @@ That same control bar should also stay proportional to the current findings set. Sort controls belong only when there are multiple Patrol findings to order; the empty state or single-finding state should not spend header space on a no-op sort selector. +The same proportionality rule applies to the findings filter bar itself. When +there are no Patrol findings and no special approval or attention queues to +navigate, the findings surface should not render filter pills that lead only +to the same empty state. When Patrol is currently running, that strip should still stay factual rather than switching to another verdict label: the runtime may add an explicit in-progress indicator, but the primary activity label remains recent activity diff --git a/frontend-modern/src/components/AI/FindingsPanel.tsx b/frontend-modern/src/components/AI/FindingsPanel.tsx index 71a9c69995..24fbaaa1bf 100644 --- a/frontend-modern/src/components/AI/FindingsPanel.tsx +++ b/frontend-modern/src/components/AI/FindingsPanel.tsx @@ -206,6 +206,11 @@ export const FindingsPanel: Component = (props) => { }); // Filter to only show Patrol findings (exclude threshold alerts) + const allPatrolFindings = createMemo(() => + aiIntelligenceStore.findings.filter( + (f) => f.source !== 'threshold' && !f.isThreshold && !hasTriggeringAlert(f), + ), + ); const patrolFindings = createMemo(() => filteredFindings().filter( (f) => f.source !== 'threshold' && !f.isThreshold && !hasTriggeringAlert(f), @@ -226,6 +231,13 @@ export const FindingsPanel: Component = (props) => { }), ); const emptyStateTone = createMemo(() => getSemanticTonePresentation(emptyStateCopy().tone)); + const showFilterControls = createMemo( + () => + props.showControls !== false && + (allPatrolFindings().length > 0 || + aiIntelligenceStore.needsAttentionCount > 0 || + aiIntelligenceStore.pendingApprovalCount > 0), + ); const isOutOfScope = (finding: UnifiedFinding): boolean => { if (!props.showScopeWarnings) { @@ -1009,7 +1021,7 @@ export const FindingsPanel: Component = (props) => { return (
{/* Controls */} - +
diff --git a/frontend-modern/src/components/AI/__tests__/FindingsPanel.test.ts b/frontend-modern/src/components/AI/__tests__/FindingsPanel.test.ts index 46f88e7c2b..32eece73e3 100644 --- a/frontend-modern/src/components/AI/__tests__/FindingsPanel.test.ts +++ b/frontend-modern/src/components/AI/__tests__/FindingsPanel.test.ts @@ -176,6 +176,14 @@ describe('aiFindingPresentation', () => { expect(findingsPanelSource).toContain(' 1}>'); expect(findingsPanelSource).toContain(''); }); + + it('hides the filter bar when there are no Patrol findings or special buckets to navigate', () => { + expect(findingsPanelSource).toContain('const showFilterControls = createMemo('); + expect(findingsPanelSource).toContain('allPatrolFindings().length > 0'); + expect(findingsPanelSource).toContain('aiIntelligenceStore.needsAttentionCount > 0'); + expect(findingsPanelSource).toContain('aiIntelligenceStore.pendingApprovalCount > 0'); + expect(findingsPanelSource).toContain(''); + }); }); describe('sourceColors', () => {