Alerting: List V2 - Use backend filters for GMA rules (#106897)
* Use state, health and receiver_name query params for server-side filtering * Remove Unknown option from state filters
This commit is contained in:
@@ -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<PromRulesOptions, 'ruleSource' | 'namespace'
|
||||
dashboardUid?: string;
|
||||
panelId?: number;
|
||||
limitAlerts?: number;
|
||||
contactPoint?: string;
|
||||
health?: RuleHealth[];
|
||||
state?: PromAlertingRuleState[];
|
||||
};
|
||||
|
||||
export const prometheusApi = alertingApi.injectEndpoints({
|
||||
@@ -72,12 +81,25 @@ export const prometheusApi = alertingApi.injectEndpoints({
|
||||
},
|
||||
}),
|
||||
getGrafanaGroups: build.query<PromRulesResponse<GrafanaPromRuleGroupDTO>, 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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user