diff --git a/packages/grafana-alerting/src/grafana/rules/components/state/types.ts b/packages/grafana-alerting/src/grafana/rules/components/state/types.ts index c37ff0851f4..65e2c165f2f 100644 --- a/packages/grafana-alerting/src/grafana/rules/components/state/types.ts +++ b/packages/grafana-alerting/src/grafana/rules/components/state/types.ts @@ -1,3 +1,3 @@ -export type Health = 'nodata' | 'error'; +export type Health = 'ok' | 'nodata' | 'error'; export type State = 'normal' | 'firing' | 'pending' | 'unknown' | 'recovering'; export type Type = 'alerting' | 'recording'; diff --git a/public/app/features/alerting/unified/rule-list/components/util.ts b/public/app/features/alerting/unified/rule-list/components/util.ts index c04ad5b3f0b..60e5f6d5352 100644 --- a/public/app/features/alerting/unified/rule-list/components/util.ts +++ b/public/app/features/alerting/unified/rule-list/components/util.ts @@ -93,7 +93,7 @@ export function normalizeHealth(health?: RuleHealth): NormalizedHealth { } function isValidHealth(health: string): health is NonNullable { - const valid: Array> = ['nodata', 'error'] as const; + const valid: Array> = ['ok', 'nodata', 'error'] as const; return valid.some((v) => v === health); } diff --git a/public/app/features/alerting/unified/rule-list/hooks/filters.test.ts b/public/app/features/alerting/unified/rule-list/hooks/filters.test.ts index 18e4af4f40f..729576da9f2 100644 --- a/public/app/features/alerting/unified/rule-list/hooks/filters.test.ts +++ b/public/app/features/alerting/unified/rule-list/hooks/filters.test.ts @@ -138,9 +138,26 @@ describe('ruleFilter', () => { health: RuleHealth.Error, }); + const prometheusErrorRule = mockPromAlertingRule({ + name: 'Error Rule', + health: 'err', + }); + expect(ruleFilter(healthyRule, getFilter({ ruleHealth: RuleHealth.Ok }))).toBe(true); expect(ruleFilter(healthyRule, getFilter({ ruleHealth: RuleHealth.Error }))).toBe(false); expect(ruleFilter(errorRule, getFilter({ ruleHealth: RuleHealth.Error }))).toBe(true); + expect(ruleFilter(prometheusErrorRule, getFilter({ ruleHealth: RuleHealth.Error }))).toBe(true); + }); + + it('should normalize health values when filtering', () => { + // Legacy Prometheus health value 'err' should be normalized to 'error' + const legacyErrorRule = mockPromAlertingRule({ + name: 'Legacy Error Rule', + health: 'err', + }); + + // When filtering for 'error', it should match rules with health 'err' (legacy) or 'error' + expect(ruleFilter(legacyErrorRule, getFilter({ ruleHealth: RuleHealth.Error }))).toBe(true); }); it('should filter by dashboard UID', () => { diff --git a/public/app/features/alerting/unified/rule-list/hooks/filters.ts b/public/app/features/alerting/unified/rule-list/hooks/filters.ts index 2e9535dd97f..96db43ad35a 100644 --- a/public/app/features/alerting/unified/rule-list/hooks/filters.ts +++ b/public/app/features/alerting/unified/rule-list/hooks/filters.ts @@ -11,6 +11,7 @@ import { getDatasourceAPIUid } from '../../utils/datasource'; import { fuzzyMatches } from '../../utils/fuzzySearch'; import { parseMatcher } from '../../utils/matchers'; import { isPluginProvidedRule, prometheusRuleType } from '../../utils/rules'; +import { normalizeHealth } from '../components/util'; /** * @returns True if the group matches the filter, false otherwise. Keeps rules intact @@ -79,7 +80,7 @@ export function ruleFilter(rule: PromRuleDTO, filterState: RulesFilter) { } } - if (filterState.ruleHealth && health !== filterState.ruleHealth) { + if (filterState.ruleHealth && normalizeHealth(health) !== filterState.ruleHealth) { return false; }