diff --git a/ui/src/api/queries/alerts.ts b/ui/src/api/queries/alerts.ts index eab53cb0..72fd04a0 100644 --- a/ui/src/api/queries/alerts.ts +++ b/ui/src/api/queries/alerts.ts @@ -11,6 +11,8 @@ type AlertSeverity = NonNullable; export interface AlertsFilter { state?: AlertState | AlertState[]; severity?: AlertSeverity | AlertSeverity[]; + acked?: boolean; + read?: boolean; ruleId?: string; limit?: number; } @@ -47,7 +49,7 @@ export function useAlerts(filter: AlertsFilter = {}) { const severityKey = severityArr ? [...severityArr].sort() : null; return useQuery({ - queryKey: ['alerts', env, 'list', fetchLimit, stateKey, severityKey], + queryKey: ['alerts', env, 'list', fetchLimit, stateKey, severityKey, filter.acked ?? null, filter.read ?? null], enabled: !!env, refetchInterval: 30_000, refetchIntervalInBackground: false, @@ -56,6 +58,8 @@ export function useAlerts(filter: AlertsFilter = {}) { const query: Record = { limit: fetchLimit }; if (stateArr && stateArr.length > 0) query.state = stateArr; if (severityArr && severityArr.length > 0) query.severity = severityArr; + if (filter.acked !== undefined) query.acked = filter.acked; + if (filter.read !== undefined) query.read = filter.read; const { data, error } = await apiClient.GET( '/environments/{envSlug}/alerts', { @@ -180,3 +184,80 @@ export function useBulkReadAlerts() { }, }); } + +/** Acknowledge a batch of alert instances. */ +export function useBulkAckAlerts() { + const env = useSelectedEnv(); + const qc = useQueryClient(); + return useMutation({ + mutationFn: async (ids: string[]) => { + if (!env) throw new Error('no env'); + const { error } = await apiClient.POST( + '/environments/{envSlug}/alerts/bulk-ack', + { params: { path: { envSlug: env } }, body: { instanceIds: ids } } as any, + ); + if (error) throw error; + }, + onSuccess: () => qc.invalidateQueries({ queryKey: ['alerts', env] }), + }); +} + +/** Delete (soft) a single alert instance. */ +export function useDeleteAlert() { + const env = useSelectedEnv(); + const qc = useQueryClient(); + return useMutation({ + mutationFn: async (id: string) => { + if (!env) throw new Error('no env'); + const { error } = await apiClient.DELETE( + '/environments/{envSlug}/alerts/{id}', + { params: { path: { envSlug: env, id } } } as any, + ); + if (error) throw error; + }, + onSuccess: () => { + qc.invalidateQueries({ queryKey: ['alerts', env] }); + qc.invalidateQueries({ queryKey: ['alerts', env, 'unread-count'] }); + }, + }); +} + +/** Delete (soft) a batch of alert instances. */ +export function useBulkDeleteAlerts() { + const env = useSelectedEnv(); + const qc = useQueryClient(); + return useMutation({ + mutationFn: async (ids: string[]) => { + if (!env) throw new Error('no env'); + const { error } = await apiClient.POST( + '/environments/{envSlug}/alerts/bulk-delete', + { params: { path: { envSlug: env } }, body: { instanceIds: ids } } as any, + ); + if (error) throw error; + }, + onSuccess: () => { + qc.invalidateQueries({ queryKey: ['alerts', env] }); + qc.invalidateQueries({ queryKey: ['alerts', env, 'unread-count'] }); + }, + }); +} + +/** Restore a soft-deleted alert instance. */ +export function useRestoreAlert() { + const env = useSelectedEnv(); + const qc = useQueryClient(); + return useMutation({ + mutationFn: async (id: string) => { + if (!env) throw new Error('no env'); + const { error } = await apiClient.POST( + '/environments/{envSlug}/alerts/{id}/restore', + { params: { path: { envSlug: env, id } } } as any, + ); + if (error) throw error; + }, + onSuccess: () => { + qc.invalidateQueries({ queryKey: ['alerts', env] }); + qc.invalidateQueries({ queryKey: ['alerts', env, 'unread-count'] }); + }, + }); +}