1- import { Fragment , useMemo , useState } from 'react' ;
1+ import { Fragment , useCallback , useMemo , useState } from 'react' ;
22import styled from '@emotion/styled' ;
33
44import { Tag } from '@sentry/scraps/badge' ;
55import { Container , Flex } from '@sentry/scraps/layout' ;
66import { Heading , Text } from '@sentry/scraps/text' ;
77
8+ import { bulkUpdate } from 'sentry/actionCreators/group' ;
9+ import { openConfirmModal } from 'sentry/components/confirm' ;
810import { Button } from 'sentry/components/core/button' ;
911import { ButtonBar } from 'sentry/components/core/button/buttonBar' ;
1012import { Checkbox } from 'sentry/components/core/checkbox' ;
@@ -41,8 +43,10 @@ import {
4143import { t , tn } from 'sentry/locale' ;
4244import { space } from 'sentry/styles/space' ;
4345import type { Group } from 'sentry/types/group' ;
46+ import { GroupStatus } from 'sentry/types/group' ;
4447import { getMessage , getTitle } from 'sentry/utils/events' ;
4548import { useApiQuery } from 'sentry/utils/queryClient' ;
49+ import useApi from 'sentry/utils/useApi' ;
4650import useCopyToClipboard from 'sentry/utils/useCopyToClipboard' ;
4751import useOrganization from 'sentry/utils/useOrganization' ;
4852import usePageFilters from 'sentry/utils/usePageFilters' ;
@@ -362,7 +366,9 @@ function ClusterCard({
362366 onTagClick ?: ( tag : string ) => void ;
363367 selectedTags ?: Set < string > ;
364368} ) {
369+ const api = useApi ( ) ;
365370 const organization = useOrganization ( ) ;
371+ const { selection} = usePageFilters ( ) ;
366372 const [ showDescription , setShowDescription ] = useState ( false ) ;
367373 const clusterStats = useClusterStats ( cluster . group_ids ) ;
368374 const { copy} = useCopyToClipboard ( ) ;
@@ -380,9 +386,60 @@ function ClusterCard({
380386 copy ( formatClusterInfoForClipboard ( cluster ) ) ;
381387 } ;
382388
389+ const handleResolve = useCallback ( ( ) => {
390+ openConfirmModal ( {
391+ header : t ( 'Resolve All Issues in Cluster' ) ,
392+ message : t (
393+ 'Are you sure you want to resolve all %s issues in this cluster?.' ,
394+ cluster . group_ids . length
395+ ) ,
396+ confirmText : t ( 'Resolve All' ) ,
397+ onConfirm : ( ) => {
398+ bulkUpdate (
399+ api ,
400+ {
401+ orgId : organization . slug ,
402+ itemIds : cluster . group_ids . map ( String ) ,
403+ data : { status : GroupStatus . RESOLVED } ,
404+ project : selection . projects ,
405+ environment : selection . environments ,
406+ ...selection . datetime ,
407+ } ,
408+ { }
409+ ) ;
410+ } ,
411+ } ) ;
412+ } , [ api , cluster . group_ids , organization . slug , selection ] ) ;
413+
414+ const handleArchive = useCallback ( ( ) => {
415+ openConfirmModal ( {
416+ header : t ( 'Archive All Issues in Cluster' ) ,
417+ message : t (
418+ 'Are you sure you want to archive all %s issues in this cluster?.' ,
419+ cluster . group_ids . length
420+ ) ,
421+ confirmText : t ( 'Archive All' ) ,
422+ onConfirm : ( ) => {
423+ bulkUpdate (
424+ api ,
425+ {
426+ orgId : organization . slug ,
427+ itemIds : cluster . group_ids . map ( String ) ,
428+ data : { status : GroupStatus . IGNORED } ,
429+ project : selection . projects ,
430+ environment : selection . environments ,
431+ ...selection . datetime ,
432+ } ,
433+ { }
434+ ) ;
435+ } ,
436+ } ) ;
437+ } , [ api , cluster . group_ids , organization . slug , selection ] ) ;
438+
439+ const handleDismiss = ( ) => { } ;
440+
383441 return (
384442 < CardContainer >
385- { /* Zone 1: Title + Description (Primary Focus) */ }
386443 < CardHeader >
387444 < ClusterTitle > { renderWithInlineCode ( cluster . title ) } </ ClusterTitle >
388445 < ClusterTags
@@ -403,7 +460,6 @@ function ClusterCard({
403460 ) }
404461 </ CardHeader >
405462
406- { /* Zone 2: Stats (Secondary Context) */ }
407463 < ClusterStatsBar >
408464 { cluster . fixability_score !== null && cluster . fixability_score !== undefined && (
409465 < StatItem >
@@ -470,7 +526,6 @@ function ClusterCard({
470526 ) }
471527 </ ClusterStatsBar >
472528
473- { /* Zone 3: Nested Issues (Detail Content) */ }
474529 < IssuesSection >
475530 < IssuesSectionHeader >
476531 < Text size = "sm" bold uppercase >
@@ -482,7 +537,6 @@ function ClusterCard({
482537 </ IssuesList >
483538 </ IssuesSection >
484539
485- { /* Zone 4: Actions (Tertiary) */ }
486540 < CardFooter >
487541 < ButtonBar merged gap = "0" >
488542 < SeerButton
@@ -525,18 +579,18 @@ function ClusterCard({
525579 items = { [
526580 {
527581 key : 'resolve' ,
528- label : t ( 'Resolve' ) ,
529- onAction : ( ) => { } ,
582+ label : t ( 'Resolve All ' ) ,
583+ onAction : handleResolve ,
530584 } ,
531585 {
532586 key : 'archive' ,
533- label : t ( 'Archive' ) ,
534- onAction : ( ) => { } ,
587+ label : t ( 'Archive All ' ) ,
588+ onAction : handleArchive ,
535589 } ,
536590 {
537591 key : 'dismiss' ,
538592 label : t ( 'Dismiss' ) ,
539- onAction : ( ) => { } ,
593+ onAction : handleDismiss ,
540594 } ,
541595 ] }
542596 trigger = { triggerProps => (
0 commit comments