mirror of
https://github.com/grafana/grafana.git
synced 2024-12-02 05:29:42 -06:00
Alerting: Allow disabling override timings for notification policies (#48648)
This commit is contained in:
parent
1a7ca3f0de
commit
fa37c6c9d3
@ -646,6 +646,7 @@ const clickSelectOption = async (selectElement: HTMLElement, optionText: string)
|
||||
const updateTiming = async (selectElement: HTMLElement, value: string, timeUnit: string): Promise<void> => {
|
||||
const input = byRole('textbox').get(selectElement);
|
||||
const select = byRole('combobox').get(selectElement);
|
||||
await userEvent.clear(input);
|
||||
await userEvent.type(input, value);
|
||||
await userEvent.click(select);
|
||||
await selectOptionInTest(selectElement, timeUnit);
|
||||
|
@ -36,7 +36,7 @@ export const AmRootRouteForm: FC<AmRootRouteFormProps> = ({
|
||||
const [groupByOptions, setGroupByOptions] = useState(stringsToSelectableValues(routes.groupBy));
|
||||
|
||||
return (
|
||||
<Form defaultValues={routes} onSubmit={onSave}>
|
||||
<Form defaultValues={{ ...routes, overrideTimings: true }} onSubmit={onSave}>
|
||||
{({ control, errors, setValue }) => (
|
||||
<>
|
||||
<Field label="Default contact point" invalid={!!errors.receiver} error={errors.receiver?.message}>
|
||||
@ -111,12 +111,7 @@ export const AmRootRouteForm: FC<AmRootRouteFormProps> = ({
|
||||
<div className={cx(styles.container, styles.timingContainer)}>
|
||||
<InputControl
|
||||
render={({ field, fieldState: { invalid } }) => (
|
||||
<Input
|
||||
{...field}
|
||||
className={styles.smallInput}
|
||||
invalid={invalid}
|
||||
placeholder={'Default 30 seconds'}
|
||||
/>
|
||||
<Input {...field} className={styles.smallInput} invalid={invalid} placeholder={'30'} />
|
||||
)}
|
||||
control={control}
|
||||
name="groupWaitValue"
|
||||
@ -151,12 +146,7 @@ export const AmRootRouteForm: FC<AmRootRouteFormProps> = ({
|
||||
<div className={cx(styles.container, styles.timingContainer)}>
|
||||
<InputControl
|
||||
render={({ field, fieldState: { invalid } }) => (
|
||||
<Input
|
||||
{...field}
|
||||
className={styles.smallInput}
|
||||
invalid={invalid}
|
||||
placeholder={'Default 5 minutes'}
|
||||
/>
|
||||
<Input {...field} className={styles.smallInput} invalid={invalid} placeholder={'5'} />
|
||||
)}
|
||||
control={control}
|
||||
name="groupIntervalValue"
|
||||
@ -191,7 +181,7 @@ export const AmRootRouteForm: FC<AmRootRouteFormProps> = ({
|
||||
<div className={cx(styles.container, styles.timingContainer)}>
|
||||
<InputControl
|
||||
render={({ field, fieldState: { invalid } }) => (
|
||||
<Input {...field} className={styles.smallInput} invalid={invalid} placeholder="Default 4 hours" />
|
||||
<Input {...field} className={styles.smallInput} invalid={invalid} placeholder="4" />
|
||||
)}
|
||||
control={control}
|
||||
name="repeatIntervalValue"
|
||||
|
@ -45,15 +45,12 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
const styles = useStyles2(getStyles);
|
||||
const formStyles = useStyles2(getFormStyles);
|
||||
const [overrideGrouping, setOverrideGrouping] = useState(routes.groupBy.length > 0);
|
||||
const [overrideTimings, setOverrideTimings] = useState(
|
||||
!!routes.groupWaitValue || !!routes.groupIntervalValue || !!routes.repeatIntervalValue
|
||||
);
|
||||
const [groupByOptions, setGroupByOptions] = useState(stringsToSelectableValues(routes.groupBy));
|
||||
const muteTimingOptions = useMuteTimingOptions();
|
||||
|
||||
return (
|
||||
<Form defaultValues={routes} onSubmit={onSave}>
|
||||
{({ control, register, errors, setValue }) => (
|
||||
{({ control, register, errors, setValue, watch }) => (
|
||||
<>
|
||||
{/* @ts-ignore-check: react-hook-form made me do this */}
|
||||
<input type="hidden" {...register('id')} />
|
||||
@ -169,7 +166,10 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
/>
|
||||
</Field>
|
||||
{overrideGrouping && (
|
||||
<Field label="Group by" description="Group alerts when you receive a notification based on labels.">
|
||||
<Field
|
||||
label="Group by"
|
||||
description="Group alerts when you receive a notification based on labels. If empty it will be inherited from the parent policy."
|
||||
>
|
||||
<InputControl
|
||||
render={({ field: { onChange, ref, ...field } }) => (
|
||||
<MultiSelect
|
||||
@ -193,17 +193,13 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
</Field>
|
||||
)}
|
||||
<Field label="Override general timings">
|
||||
<Switch
|
||||
id="override-timings-toggle"
|
||||
value={overrideTimings}
|
||||
onChange={() => setOverrideTimings((overrideTimings) => !overrideTimings)}
|
||||
/>
|
||||
<Switch id="override-timings-toggle" {...register('overrideTimings')} />
|
||||
</Field>
|
||||
{overrideTimings && (
|
||||
{watch().overrideTimings && (
|
||||
<>
|
||||
<Field
|
||||
label="Group wait"
|
||||
description="The waiting time until the initial notification is sent for a new group created by an incoming alert."
|
||||
description="The waiting time until the initial notification is sent for a new group created by an incoming alert. If empty it will be inherited from the parent policy."
|
||||
invalid={!!errors.groupWaitValue}
|
||||
error={errors.groupWaitValue?.message}
|
||||
>
|
||||
@ -215,7 +211,6 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
{...field}
|
||||
className={formStyles.smallInput}
|
||||
invalid={invalid}
|
||||
placeholder="Time"
|
||||
aria-label="Group wait value"
|
||||
/>
|
||||
)}
|
||||
@ -243,7 +238,7 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
</Field>
|
||||
<Field
|
||||
label="Group interval"
|
||||
description="The waiting time to send a batch of new alerts for that group after the first notification was sent."
|
||||
description="The waiting time to send a batch of new alerts for that group after the first notification was sent. If empty it will be inherited from the parent policy."
|
||||
invalid={!!errors.groupIntervalValue}
|
||||
error={errors.groupIntervalValue?.message}
|
||||
>
|
||||
@ -255,7 +250,6 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
{...field}
|
||||
className={formStyles.smallInput}
|
||||
invalid={invalid}
|
||||
placeholder="Time"
|
||||
aria-label="Group interval value"
|
||||
/>
|
||||
)}
|
||||
@ -295,7 +289,6 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
|
||||
{...field}
|
||||
className={formStyles.smallInput}
|
||||
invalid={invalid}
|
||||
placeholder="Time"
|
||||
aria-label="Repeat interval value"
|
||||
/>
|
||||
)}
|
||||
|
@ -11,6 +11,7 @@ const defaultAmRoute: FormAmRoute = {
|
||||
continue: false,
|
||||
receiver: '',
|
||||
groupBy: [],
|
||||
overrideTimings: false,
|
||||
groupWaitValue: '',
|
||||
groupWaitValueType: '',
|
||||
groupIntervalValue: '',
|
||||
|
@ -6,6 +6,7 @@ export interface FormAmRoute {
|
||||
continue: boolean;
|
||||
receiver: string;
|
||||
groupBy: string[];
|
||||
overrideTimings: boolean;
|
||||
groupWaitValue: string;
|
||||
groupWaitValueType: string;
|
||||
groupIntervalValue: string;
|
||||
|
@ -11,7 +11,7 @@ import { matcherToMatcherField, parseMatcher } from './alertmanager';
|
||||
import { GRAFANA_RULES_SOURCE_NAME } from './datasource';
|
||||
import { parseInterval, timeOptions } from './time';
|
||||
|
||||
const defaultValueAndType: [string, string] = ['', timeOptions[0].value];
|
||||
const defaultValueAndType: [string, string] = ['', ''];
|
||||
|
||||
const matchersToArrayFieldMatchers = (
|
||||
matchers: Record<string, string> | undefined,
|
||||
@ -29,9 +29,12 @@ const matchersToArrayFieldMatchers = (
|
||||
[] as MatcherFieldValue[]
|
||||
);
|
||||
|
||||
const intervalToValueAndType = (strValue: string | undefined): [string, string] => {
|
||||
const intervalToValueAndType = (
|
||||
strValue: string | undefined,
|
||||
defaultValue?: typeof defaultValueAndType
|
||||
): [string, string] => {
|
||||
if (!strValue) {
|
||||
return defaultValueAndType;
|
||||
return defaultValue ?? defaultValueAndType;
|
||||
}
|
||||
|
||||
const [value, valueType] = strValue ? parseInterval(strValue) : [undefined, undefined];
|
||||
@ -63,6 +66,7 @@ export const emptyRoute: FormAmRoute = {
|
||||
routes: [],
|
||||
continue: false,
|
||||
receiver: '',
|
||||
overrideTimings: false,
|
||||
groupWaitValue: '',
|
||||
groupWaitValueType: timeOptions[0].value,
|
||||
groupIntervalValue: '',
|
||||
@ -78,9 +82,9 @@ export const amRouteToFormAmRoute = (route: Route | undefined): [FormAmRoute, Re
|
||||
return [emptyRoute, {}];
|
||||
}
|
||||
|
||||
const [groupWaitValue, groupWaitValueType] = intervalToValueAndType(route.group_wait);
|
||||
const [groupIntervalValue, groupIntervalValueType] = intervalToValueAndType(route.group_interval);
|
||||
const [repeatIntervalValue, repeatIntervalValueType] = intervalToValueAndType(route.repeat_interval);
|
||||
const [groupWaitValue, groupWaitValueType] = intervalToValueAndType(route.group_wait, ['', 's']);
|
||||
const [groupIntervalValue, groupIntervalValueType] = intervalToValueAndType(route.group_interval, ['', 'm']);
|
||||
const [repeatIntervalValue, repeatIntervalValueType] = intervalToValueAndType(route.repeat_interval, ['', 'h']);
|
||||
|
||||
const id = String(Math.random());
|
||||
const id2route = {
|
||||
@ -111,6 +115,7 @@ export const amRouteToFormAmRoute = (route: Route | undefined): [FormAmRoute, Re
|
||||
continue: route.continue ?? false,
|
||||
receiver: route.receiver ?? '',
|
||||
groupBy: route.group_by ?? [],
|
||||
overrideTimings: [groupWaitValue, groupIntervalValue, repeatIntervalValue].some(Boolean),
|
||||
groupWaitValue,
|
||||
groupWaitValueType,
|
||||
groupIntervalValue,
|
||||
@ -130,6 +135,26 @@ export const formAmRouteToAmRoute = (
|
||||
id2ExistingRoute: Record<string, Route>
|
||||
): Route => {
|
||||
const existing: Route | undefined = id2ExistingRoute[formAmRoute.id];
|
||||
|
||||
const {
|
||||
overrideTimings,
|
||||
groupWaitValue,
|
||||
groupWaitValueType,
|
||||
groupIntervalValue,
|
||||
groupIntervalValueType,
|
||||
repeatIntervalValue,
|
||||
repeatIntervalValueType,
|
||||
} = formAmRoute;
|
||||
|
||||
const overrideGroupWait = overrideTimings && groupWaitValue;
|
||||
const group_wait = overrideGroupWait ? `${groupWaitValue}${groupWaitValueType}` : undefined;
|
||||
|
||||
const overrideGroupInterval = overrideTimings && groupIntervalValue;
|
||||
const group_interval = overrideGroupInterval ? `${groupIntervalValue}${groupIntervalValueType}` : undefined;
|
||||
|
||||
const overrideRepeatInterval = overrideTimings && repeatIntervalValue;
|
||||
const repeat_interval = overrideRepeatInterval ? `${repeatIntervalValue}${repeatIntervalValueType}` : undefined;
|
||||
|
||||
const amRoute: Route = {
|
||||
...(existing ?? {}),
|
||||
continue: formAmRoute.continue,
|
||||
@ -137,17 +162,11 @@ export const formAmRouteToAmRoute = (
|
||||
object_matchers: formAmRoute.object_matchers.length
|
||||
? formAmRoute.object_matchers.map((matcher) => [matcher.name, matcher.operator, matcher.value])
|
||||
: undefined,
|
||||
match: undefined,
|
||||
match_re: undefined,
|
||||
group_wait: formAmRoute.groupWaitValue
|
||||
? `${formAmRoute.groupWaitValue}${formAmRoute.groupWaitValueType}`
|
||||
: undefined,
|
||||
group_interval: formAmRoute.groupIntervalValue
|
||||
? `${formAmRoute.groupIntervalValue}${formAmRoute.groupIntervalValueType}`
|
||||
: undefined,
|
||||
repeat_interval: formAmRoute.repeatIntervalValue
|
||||
? `${formAmRoute.repeatIntervalValue}${formAmRoute.repeatIntervalValueType}`
|
||||
: undefined,
|
||||
match: undefined, // DEPRECATED: Use matchers
|
||||
match_re: undefined, // DEPRECATED: Use matchers
|
||||
group_wait,
|
||||
group_interval,
|
||||
repeat_interval,
|
||||
routes: formAmRoute.routes.map((subRoute) =>
|
||||
formAmRouteToAmRoute(alertManagerSourceName, subRoute, id2ExistingRoute)
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user