diff --git a/public/app/features/alerting/unified/api/prometheusApi.ts b/public/app/features/alerting/unified/api/prometheusApi.ts index aaa484f7556..69b19725bf0 100644 --- a/public/app/features/alerting/unified/api/prometheusApi.ts +++ b/public/app/features/alerting/unified/api/prometheusApi.ts @@ -1,7 +1,13 @@ import { useCallback } from 'react'; import { useDispatch } from 'app/types'; -import { GrafanaPromRuleGroupDTO, PromRuleDTO, PromRuleGroupDTO } from 'app/types/unified-alerting-dto'; +import { RuleHealth } from 'app/types/unified-alerting'; +import { + GrafanaPromRuleGroupDTO, + PromAlertingRuleState, + PromRuleDTO, + PromRuleGroupDTO, +} from 'app/types/unified-alerting-dto'; import { GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; @@ -33,6 +39,9 @@ type GrafanaPromRulesOptions = Omit, GrafanaPromRulesOptions>({ - query: ({ folderUid, groupName, ruleName, groupLimit, limitAlerts, groupNextToken }) => ({ + query: ({ + folderUid, + groupName, + ruleName, + contactPoint, + health, + state, + groupLimit, + limitAlerts, + groupNextToken, + }) => ({ url: `api/prometheus/grafana/api/v1/rules`, params: { folder_uid: folderUid, rule_group: groupName, rule_name: ruleName, + receiver_name: contactPoint, + health: health, + state: state, limit_alerts: limitAlerts, group_limit: groupLimit?.toFixed(0), group_next_token: groupNextToken, diff --git a/public/app/features/alerting/unified/components/rules/Filter/RulesFilter.v1.tsx b/public/app/features/alerting/unified/components/rules/Filter/RulesFilter.v1.tsx index 7f0502fa2ee..f80198f1a77 100644 --- a/public/app/features/alerting/unified/components/rules/Filter/RulesFilter.v1.tsx +++ b/public/app/features/alerting/unified/components/rules/Filter/RulesFilter.v1.tsx @@ -48,10 +48,12 @@ interface RulesFilerProps { onViewModeChange?: (viewMode: SupportedView) => void; } -const RuleStateOptions = Object.entries(PromAlertingRuleState).map(([key, value]) => ({ - label: alertStateToReadable(value), - value, -})); +const RuleStateOptions = Object.entries(PromAlertingRuleState) + .filter(([key, value]) => value !== PromAlertingRuleState.Unknown) // Exclude Unknown state from filter options + .map(([key, value]) => ({ + label: alertStateToReadable(value), + value, + })); const RulesFilter = ({ onClear = () => undefined, viewMode, onViewModeChange }: RulesFilerProps) => { const styles = useStyles2(getStyles); diff --git a/public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts b/public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts index 649594f893e..40d786f03f7 100644 --- a/public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts +++ b/public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts @@ -1,8 +1,8 @@ import { useCallback } from 'react'; import { useDispatch } from 'app/types/store'; -import { DataSourceRulesSourceIdentifier } from 'app/types/unified-alerting'; -import { PromRuleGroupDTO } from 'app/types/unified-alerting-dto'; +import { DataSourceRulesSourceIdentifier, RuleHealth } from 'app/types/unified-alerting'; +import { PromAlertingRuleState, PromRuleGroupDTO } from 'app/types/unified-alerting-dto'; import { alertRuleApi } from '../../api/alertRuleApi'; import { PromRulesResponse, prometheusApi } from '../../api/prometheusApi'; @@ -57,13 +57,27 @@ export function usePrometheusGroupsGenerator(hookOptions: UseGeneratorHookOption ); } +interface GrafanaPromApiFilter { + state?: PromAlertingRuleState[]; + health?: RuleHealth[]; + contactPoint?: string; +} + +interface GrafanaFetchGroupsOptions extends FetchGroupsOptions { + filter?: GrafanaPromApiFilter; +} + export function useGrafanaGroupsGenerator(hookOptions: UseGeneratorHookOptions = {}) { const dispatch = useDispatch(); const [getGrafanaGroups] = useLazyGetGrafanaGroupsQuery(); const getGroupsAndProvideCache = useCallback( - async (fetchOptions: FetchGroupsOptions) => { - const response = await getGrafanaGroups({ ...fetchOptions, limitAlerts: hookOptions.limitAlerts }).unwrap(); + async (fetchOptions: GrafanaFetchGroupsOptions) => { + const response = await getGrafanaGroups({ + ...fetchOptions, + limitAlerts: hookOptions.limitAlerts, + ...fetchOptions.filter, + }).unwrap(); // This is not mandatory to preload ruler rules, but it improves the UX // Because the user waits a bit longer for the initial load but doesn't need to wait for each group to be loaded @@ -94,8 +108,11 @@ export function useGrafanaGroupsGenerator(hookOptions: UseGeneratorHookOptions = ); return useCallback( - async function* (groupLimit: number) { - yield* genericGroupsGenerator(getGroupsAndProvideCache, groupLimit); + async function* (groupLimit: number, filter?: GrafanaPromApiFilter) { + yield* genericGroupsGenerator( + (fetchOptions) => getGroupsAndProvideCache({ ...fetchOptions, filter }), + groupLimit + ); }, [getGroupsAndProvideCache] ); diff --git a/public/app/features/alerting/unified/rule-list/hooks/useFilteredRulesIterator.ts b/public/app/features/alerting/unified/rule-list/hooks/useFilteredRulesIterator.ts index 56178cee913..73095e0acff 100644 --- a/public/app/features/alerting/unified/rule-list/hooks/useFilteredRulesIterator.ts +++ b/public/app/features/alerting/unified/rule-list/hooks/useFilteredRulesIterator.ts @@ -65,7 +65,13 @@ export function useFilteredRulesIteratorProvider() { const normalizedFilterState = normalizeFilterState(filterState); const hasDataSourceFilterActive = Boolean(filterState.dataSourceNames.length); - const grafanaRulesGenerator = from(grafanaGroupsGenerator(groupLimit)).pipe( + const grafanaRulesGenerator = from( + grafanaGroupsGenerator(groupLimit, { + contactPoint: filterState.contactPoint ?? undefined, + health: filterState.ruleHealth ? [filterState.ruleHealth] : [], + state: filterState.ruleState ? [filterState.ruleState] : [], + }) + ).pipe( withAbort(abortController.signal), concatMap((groups) => groups