mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 08:18:10 -05:00
Alerting: Fix folder and rule name in groupBy for simplified routing (#82148)
* Fix folder and rule name in groupBy for simplified routing * Review suggestions * Use proper type for MultiValueRemove props * hoist getting groupBy count * Use watch instead of getValues * Bring back validation for required fields
This commit is contained in:
+49
-18
@@ -1,8 +1,8 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import {
|
||||
Field,
|
||||
FieldValidationMessage,
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
Text,
|
||||
useStyles2,
|
||||
} from '@grafana/ui';
|
||||
import { MultiValueRemove, MultiValueRemoveProps } from '@grafana/ui/src/components/Select/MultiValue';
|
||||
import { RuleFormValues } from 'app/features/alerting/unified/types/rule-form';
|
||||
import {
|
||||
commonGroupByOptions,
|
||||
@@ -27,6 +28,15 @@ import { TIMING_OPTIONS_DEFAULTS } from '../../../../notification-policies/timin
|
||||
|
||||
import { RouteTimings } from './RouteTimings';
|
||||
|
||||
const REQUIRED_FIELDS_IN_GROUPBY = ['grafana_folder', 'alertname'];
|
||||
|
||||
const DEFAULTS_TIMINGS = {
|
||||
groupWaitValue: TIMING_OPTIONS_DEFAULTS.group_wait,
|
||||
groupIntervalValue: TIMING_OPTIONS_DEFAULTS.group_interval,
|
||||
repeatIntervalValue: TIMING_OPTIONS_DEFAULTS.repeat_interval,
|
||||
};
|
||||
const DISABLE_GROUPING = '...';
|
||||
|
||||
export interface RoutingSettingsProps {
|
||||
alertManager: string;
|
||||
}
|
||||
@@ -40,12 +50,18 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
formState: { errors },
|
||||
} = useFormContext<RuleFormValues>();
|
||||
const [groupByOptions, setGroupByOptions] = useState(stringsToSelectableValues([]));
|
||||
const { groupIntervalValue, groupWaitValue, repeatIntervalValue } = getDefaultsForRoutingSettings();
|
||||
const { groupIntervalValue, groupWaitValue, repeatIntervalValue } = DEFAULTS_TIMINGS;
|
||||
const overrideGrouping = watch(`contactPoints.${alertManager}.overrideGrouping`);
|
||||
const overrideTimings = watch(`contactPoints.${alertManager}.overrideTimings`);
|
||||
const requiredFieldsInGroupBy = ['grafana_folder', 'alertname'];
|
||||
const disableGrouping = '...';
|
||||
const groupByCount = watch(`contactPoints.${alertManager}.groupBy`)?.length ?? 0;
|
||||
|
||||
const styles = useStyles2(getStyles);
|
||||
useEffect(() => {
|
||||
if (overrideGrouping && groupByCount === 0) {
|
||||
setValue(`contactPoints.${alertManager}.groupBy`, REQUIRED_FIELDS_IN_GROUPBY);
|
||||
}
|
||||
}, [overrideGrouping, setValue, alertManager, groupByCount]);
|
||||
|
||||
return (
|
||||
<Stack direction="column">
|
||||
<Stack direction="row" gap={1} alignItems="center" justifyContent="space-between">
|
||||
@@ -54,7 +70,7 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
</InlineField>
|
||||
{!overrideGrouping && (
|
||||
<Text variant="body" color="secondary">
|
||||
Grouping: <strong>{requiredFieldsInGroupBy.join(', ')}</strong>
|
||||
Grouping: <strong>{REQUIRED_FIELDS_IN_GROUPBY.join(', ')}</strong>
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
@@ -72,14 +88,13 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
if (!value || value.length === 0) {
|
||||
return 'At least one group by option is required.';
|
||||
}
|
||||
// if value includes only the allowedSingleFieldInGroupBy, it is valid
|
||||
if (value.length === 1 && value[0] === disableGrouping) {
|
||||
if (value.length === 1 && value[0] === DISABLE_GROUPING) {
|
||||
return true;
|
||||
}
|
||||
// we need to make sure that the required fields are included
|
||||
const requiredFieldsIncluded = requiredFieldsInGroupBy.every((field) => value.includes(field));
|
||||
const requiredFieldsIncluded = REQUIRED_FIELDS_IN_GROUPBY.every((field) => value.includes(field));
|
||||
if (!requiredFieldsIncluded) {
|
||||
return `Group by must include ${requiredFieldsInGroupBy.join(', ')}`;
|
||||
return `Group by must include ${REQUIRED_FIELDS_IN_GROUPBY.join(', ')}`;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -97,8 +112,30 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
// @ts-ignore-check: react-hook-form made me do this
|
||||
setValue(`contactPoints.${alertManager}.groupBy`, [...field.value, opt]);
|
||||
}}
|
||||
onChange={(value) => onChange(mapMultiSelectValueToStrings(value))}
|
||||
onChange={(value) => {
|
||||
return onChange(mapMultiSelectValueToStrings(value));
|
||||
}}
|
||||
options={[...commonGroupByOptions, ...groupByOptions]}
|
||||
components={{
|
||||
MultiValueRemove(
|
||||
props: React.PropsWithChildren<
|
||||
MultiValueRemoveProps &
|
||||
Array<SelectableValue<string>> & {
|
||||
data: {
|
||||
label: string;
|
||||
value: string;
|
||||
isFixed: boolean;
|
||||
};
|
||||
}
|
||||
>
|
||||
) {
|
||||
const { data } = props;
|
||||
if (data.isFixed) {
|
||||
return null;
|
||||
}
|
||||
return MultiValueRemove(props);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
{error && <FieldValidationMessage>{error.message}</FieldValidationMessage>}
|
||||
</>
|
||||
@@ -129,13 +166,6 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
function getDefaultsForRoutingSettings() {
|
||||
return {
|
||||
groupWaitValue: TIMING_OPTIONS_DEFAULTS.group_wait,
|
||||
groupIntervalValue: TIMING_OPTIONS_DEFAULTS.group_interval,
|
||||
repeatIntervalValue: TIMING_OPTIONS_DEFAULTS.repeat_interval,
|
||||
};
|
||||
}
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
switchElement: css({
|
||||
flexFlow: 'row-reverse',
|
||||
@@ -144,5 +174,6 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
}),
|
||||
optionalContent: css({
|
||||
marginLeft: '49px',
|
||||
marginBottom: theme.spacing(1),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -44,8 +44,8 @@ export const defaultGroupBy = ['grafana_folder', 'alertname'];
|
||||
|
||||
// Common route group_by options for multiselect drop-down
|
||||
export const commonGroupByOptions = [
|
||||
{ label: 'grafana_folder', value: 'grafana_folder' },
|
||||
{ label: 'alertname', value: 'alertname' },
|
||||
{ label: 'grafana_folder', value: 'grafana_folder', isFixed: true },
|
||||
{ label: 'alertname', value: 'alertname', isFixed: true },
|
||||
{ label: 'Disable (...)', value: '...' },
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user