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
pull/82308/head
Sonia Aguilar 1 year ago committed by GitHub
parent d65d2ceb1b
commit 730e1d2485
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 67
      public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/route-settings/RouteSettings.tsx
  2. 4
      public/app/features/alerting/unified/utils/amroutes.ts

@ -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: '...' },
];

Loading…
Cancel
Save