@@ -347,7 +347,13 @@ function ClusterIssues({groupIds}: {groupIds: number[]}) {
347347 ) ;
348348}
349349
350- function ClusterCard ( { cluster} : { cluster : ClusterSummary } ) {
350+ interface ClusterCardProps {
351+ cluster : ClusterSummary ;
352+ filterByEscalating ?: boolean ;
353+ filterByRegressed ?: boolean ;
354+ }
355+
356+ function ClusterCard ( { cluster, filterByRegressed, filterByEscalating} : ClusterCardProps ) {
351357 const api = useApi ( ) ;
352358 const organization = useOrganization ( ) ;
353359 const { selection} = usePageFilters ( ) ;
@@ -446,6 +452,17 @@ function ClusterCard({cluster}: {cluster: ClusterSummary}) {
446452 ] ;
447453 } , [ cluster . error_type_tags , cluster . code_area_tags , cluster . service_tags ] ) ;
448454
455+ // Apply filters - hide card if it doesn't match active filters
456+ // Only filter once stats are loaded to avoid hiding cards prematurely
457+ if ( ! clusterStats . isPending ) {
458+ if ( filterByRegressed && ! clusterStats . hasRegressedIssues ) {
459+ return null ;
460+ }
461+ if ( filterByEscalating && ! clusterStats . isEscalating ) {
462+ return null ;
463+ }
464+ }
465+
449466 return (
450467 < CardContainer >
451468 < CardHeader >
@@ -693,6 +710,8 @@ function DynamicGrouping() {
693710 const [ disableFilters , setDisableFilters ] = useState ( false ) ;
694711 const [ showDevTools , setShowDevTools ] = useState ( false ) ;
695712 const [ visibleClusterCount , setVisibleClusterCount ] = useState ( CLUSTERS_PER_PAGE ) ;
713+ const [ filterByRegressed , setFilterByRegressed ] = useState ( false ) ;
714+ const [ filterByEscalating , setFilterByEscalating ] = useState ( false ) ;
696715
697716 // Fetch cluster data from API
698717 const { data : topIssuesResponse , isPending} = useApiQuery < TopIssuesResponse > (
@@ -1019,6 +1038,30 @@ function DynamicGrouping() {
10191038 </ Flex >
10201039 </ Flex >
10211040 ) }
1041+
1042+ < Flex direction = "column" gap = "sm" >
1043+ < FilterLabel > { t ( 'Filter by status' ) } </ FilterLabel >
1044+ < Flex direction = "column" gap = "xs" style = { { paddingLeft : 8 } } >
1045+ < Flex gap = "sm" align = "center" >
1046+ < Checkbox
1047+ checked = { filterByRegressed }
1048+ onChange = { e => setFilterByRegressed ( e . target . checked ) }
1049+ aria-label = { t ( 'Show only clusters with regressed issues' ) }
1050+ size = "sm"
1051+ />
1052+ < FilterLabel > { t ( 'Has regressed issues' ) } </ FilterLabel >
1053+ </ Flex >
1054+ < Flex gap = "sm" align = "center" >
1055+ < Checkbox
1056+ checked = { filterByEscalating }
1057+ onChange = { e => setFilterByEscalating ( e . target . checked ) }
1058+ aria-label = { t ( 'Show only escalating clusters' ) }
1059+ size = "sm"
1060+ />
1061+ < FilterLabel > { t ( 'Escalating (>1.5x events)' ) } </ FilterLabel >
1062+ </ Flex >
1063+ </ Flex >
1064+ </ Flex >
10221065 </ Flex >
10231066 </ Disclosure . Content >
10241067 </ Disclosure >
@@ -1043,14 +1086,24 @@ function DynamicGrouping() {
10431086 { displayedClusters
10441087 . filter ( ( _ , index ) => index % 2 === 0 )
10451088 . map ( cluster => (
1046- < ClusterCard key = { cluster . cluster_id } cluster = { cluster } />
1089+ < ClusterCard
1090+ key = { cluster . cluster_id }
1091+ cluster = { cluster }
1092+ filterByRegressed = { filterByRegressed }
1093+ filterByEscalating = { filterByEscalating }
1094+ />
10471095 ) ) }
10481096 </ CardsColumn >
10491097 < CardsColumn >
10501098 { displayedClusters
10511099 . filter ( ( _ , index ) => index % 2 === 1 )
10521100 . map ( cluster => (
1053- < ClusterCard key = { cluster . cluster_id } cluster = { cluster } />
1101+ < ClusterCard
1102+ key = { cluster . cluster_id }
1103+ cluster = { cluster }
1104+ filterByRegressed = { filterByRegressed }
1105+ filterByEscalating = { filterByEscalating }
1106+ />
10541107 ) ) }
10551108 </ CardsColumn >
10561109 </ CardsGrid >
0 commit comments