From e7de730c71dafafe8fff591bef57514c0b8bb91d Mon Sep 17 00:00:00 2001 From: rcourtman Date: Sat, 27 Jun 2026 14:58:00 +0100 Subject: [PATCH] feat(alerts): per-group acknowledge button for related alert groups Adds an 'Ack all (N)' button next to the '+N related' toggle on grouped alerts. Acknowledges the primary and all related alerts in one action using the existing bulkAcknowledge API endpoint, without touching unrelated alerts. --- .../AlertOverviewActiveAlertsSection.tsx | 34 +++++++++++++----- .../alerts/useAlertAcknowledgementState.ts | 36 +++++++++++++++++++ .../features/alerts/useAlertOverviewState.ts | 2 ++ 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/frontend-modern/src/features/alerts/AlertOverviewActiveAlertsSection.tsx b/frontend-modern/src/features/alerts/AlertOverviewActiveAlertsSection.tsx index 2233b6298..6b43ea74e 100644 --- a/frontend-modern/src/features/alerts/AlertOverviewActiveAlertsSection.tsx +++ b/frontend-modern/src/features/alerts/AlertOverviewActiveAlertsSection.tsx @@ -128,15 +128,31 @@ export function AlertOverviewActiveAlertsSection(props: AlertOverviewActiveAlert /> 0}>
- +
+ + !a.acknowledged)}> + + +
diff --git a/frontend-modern/src/features/alerts/useAlertAcknowledgementState.ts b/frontend-modern/src/features/alerts/useAlertAcknowledgementState.ts index c1199c86f..24b80d998 100644 --- a/frontend-modern/src/features/alerts/useAlertAcknowledgementState.ts +++ b/frontend-modern/src/features/alerts/useAlertAcknowledgementState.ts @@ -184,6 +184,41 @@ export function useAlertAcknowledgementState(props: UseAlertAcknowledgementState } }; + const handleGroupAcknowledge = async (alerts: Alert[]) => { + const pending = alerts.filter((alert) => { + const id = getCanonicalAlertId(alert); + return !effectiveAlerts().find((e) => getCanonicalAlertId(e) === id)?.acknowledged; + }); + if (pending.length === 0) return; + + const identifiers = pending.map((alert) => getCanonicalAlertId(alert)); + const groupProcessing = new Set(identifiers); + setProcessingAlerts((previous) => new Set([...previous, ...groupProcessing])); + + try { + const result = await AlertsAPI.bulkAcknowledge(identifiers); + const acknowledgedAt = new Date().toISOString(); + const successes = result.results.filter((entry) => entry.success); + + successes.forEach((entry) => { + applyAlertUpdate(entry.alertIdentifier, { + acknowledged: true, + ackTime: acknowledgedAt, + ackUser: undefined, + }); + }); + + if (successes.length > 0) { + notificationStore.success(getAlertOverviewBulkAcknowledgedNotification(successes.length)); + } + } catch (error) { + logger.error('Group acknowledge failed', error); + notificationStore.error(getAlertOverviewBulkAcknowledgeGenericFailureNotification()); + } finally { + groupProcessing.forEach((id) => releaseAlertProcessing(id)); + } + }; + return { effectiveAlerts, unacknowledgedAlerts, @@ -191,5 +226,6 @@ export function useAlertAcknowledgementState(props: UseAlertAcknowledgementState bulkAckProcessing, handleAlertAcknowledgement, handleBulkAcknowledge, + handleGroupAcknowledge, }; } diff --git a/frontend-modern/src/features/alerts/useAlertOverviewState.ts b/frontend-modern/src/features/alerts/useAlertOverviewState.ts index 6a46eba96..32465f160 100644 --- a/frontend-modern/src/features/alerts/useAlertOverviewState.ts +++ b/frontend-modern/src/features/alerts/useAlertOverviewState.ts @@ -38,6 +38,7 @@ export function useAlertOverviewState(props: UseAlertOverviewStateProps) { bulkAckProcessing, handleAlertAcknowledgement, handleBulkAcknowledge, + handleGroupAcknowledge, } = useAlertAcknowledgementState({ alerts: activeAlerts, updateAlert: props.updateAlert, @@ -109,6 +110,7 @@ export function useAlertOverviewState(props: UseAlertOverviewStateProps) { bulkAckProcessing, handleAlertAcknowledgement, handleBulkAcknowledge, + handleGroupAcknowledge, }; }