mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: defaults for simplified routing (#82050)
* Expand route settings by default when alert rule has values in these fields * Default to manual routing option if FF is enabled and local storage is not set to false * Add test for getDefautManualRouting function * Update seting local storage item to false in case of policy routing * Only save to local storage when creating a new alert rule
This commit is contained in:
parent
3e93a0991f
commit
beca6a08b0
@ -1,11 +1,11 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { FormProvider, SubmitErrorHandler, useForm, UseFormWatch } from 'react-hook-form';
|
||||
import { FormProvider, SubmitErrorHandler, UseFormWatch, useForm } from 'react-hook-form';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Button, ConfirmModal, CustomScrollbar, HorizontalGroup, Spinner, useStyles2, Stack } from '@grafana/ui';
|
||||
import { Button, ConfirmModal, CustomScrollbar, HorizontalGroup, Spinner, Stack, useStyles2 } from '@grafana/ui';
|
||||
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
@ -14,17 +14,18 @@ import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import { useDispatch } from 'app/types';
|
||||
import { RuleWithLocation } from 'app/types/unified-alerting';
|
||||
|
||||
import { logInfo, LogMessages, trackNewAlerRuleFormError } from '../../../Analytics';
|
||||
import { LogMessages, logInfo, trackNewAlerRuleFormError } from '../../../Analytics';
|
||||
import { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector';
|
||||
import { deleteRuleAction, saveRuleFormAction } from '../../../state/actions';
|
||||
import { RuleFormType, RuleFormValues } from '../../../types/rule-form';
|
||||
import { initialAsyncRequestState } from '../../../utils/redux';
|
||||
import {
|
||||
MANUAL_ROUTING_KEY,
|
||||
MINUTE,
|
||||
formValuesFromExistingRule,
|
||||
getDefaultFormValues,
|
||||
getDefaultQueries,
|
||||
ignoreHiddenQueries,
|
||||
MINUTE,
|
||||
normalizeDefaultAnnotations,
|
||||
} from '../../../utils/rule-form';
|
||||
import * as ruleId from '../../../utils/rule-id';
|
||||
@ -108,6 +109,14 @@ export const AlertRuleForm = ({ existing, prefill }: Props) => {
|
||||
notifyApp.error(conditionErrorMsg);
|
||||
return;
|
||||
}
|
||||
// when creating a new rule, we save the manual routing setting in local storage
|
||||
if (!existing) {
|
||||
if (values.manualRouting) {
|
||||
localStorage.setItem(MANUAL_ROUTING_KEY, 'true');
|
||||
} else {
|
||||
localStorage.setItem(MANUAL_ROUTING_KEY, 'false');
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(
|
||||
saveRuleFormAction({
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, CollapsableSection, LoadingPlaceholder, Stack, useStyles2 } from '@grafana/ui';
|
||||
import { RuleFormValues } from 'app/features/alerting/unified/types/rule-form';
|
||||
import { AlertManagerDataSource } from 'app/features/alerting/unified/utils/datasource';
|
||||
|
||||
import { ContactPointReceiverSummary } from '../../../contact-points/ContactPoints';
|
||||
@ -36,6 +38,12 @@ export function AlertManagerManualRouting({ alertManager }: AlertManagerManualRo
|
||||
setSelectedContactPointWithMetadata(contactPoint);
|
||||
};
|
||||
|
||||
const { watch } = useFormContext<RuleFormValues>();
|
||||
const hasRouteSettings =
|
||||
watch(`contactPoints.${alertManagerName}.overrideGrouping`) ||
|
||||
watch(`contactPoints.${alertManagerName}.overrideTimings`) ||
|
||||
watch(`contactPoints.${alertManagerName}.muteTimeIntervals`)?.length > 0;
|
||||
|
||||
const options = contactPoints.map((receiver) => {
|
||||
const integrations = receiver?.grafana_managed_receiver_configs;
|
||||
const description = <ContactPointReceiverSummary receivers={integrations ?? []} />;
|
||||
@ -74,7 +82,7 @@ export function AlertManagerManualRouting({ alertManager }: AlertManagerManualRo
|
||||
<div className={styles.routingSection}>
|
||||
<CollapsableSection
|
||||
label="Muting, grouping and timings (optional)"
|
||||
isOpen={false}
|
||||
isOpen={hasRouteSettings}
|
||||
className={styles.collapsableSection}
|
||||
>
|
||||
<Stack direction="column" gap={1}>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { config } from '@grafana/runtime';
|
||||
import { PromQuery } from 'app/plugins/datasource/prometheus/types';
|
||||
import { GrafanaAlertStateDecision, GrafanaRuleDefinition, RulerAlertingRuleDTO } from 'app/types/unified-alerting-dto';
|
||||
|
||||
@ -5,11 +6,13 @@ import { AlertManagerManualRouting, RuleFormType, RuleFormValues } from '../type
|
||||
|
||||
import { GRAFANA_RULES_SOURCE_NAME } from './datasource';
|
||||
import {
|
||||
MANUAL_ROUTING_KEY,
|
||||
alertingRulerRuleToRuleForm,
|
||||
formValuesToRulerGrafanaRuleDTO,
|
||||
formValuesToRulerRuleDTO,
|
||||
getContactPointsFromDTO,
|
||||
getDefaultFormValues,
|
||||
getDefautManualRouting,
|
||||
getNotificationSettingsForDTO,
|
||||
} from './rule-form';
|
||||
|
||||
@ -207,3 +210,33 @@ describe('getNotificationSettingsForDTO', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDefautManualRouting', () => {
|
||||
afterEach(() => {
|
||||
window.localStorage.clear();
|
||||
});
|
||||
|
||||
it('returns false if the feature toggle is not enabled', () => {
|
||||
config.featureToggles.alertingSimplifiedRouting = false;
|
||||
expect(getDefautManualRouting()).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true if the feature toggle is enabled and localStorage is not set', () => {
|
||||
config.featureToggles.alertingSimplifiedRouting = true;
|
||||
expect(getDefautManualRouting()).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false if the feature toggle is enabled and localStorage is set to "false"', () => {
|
||||
config.featureToggles.alertingSimplifiedRouting = true;
|
||||
localStorage.setItem(MANUAL_ROUTING_KEY, 'false');
|
||||
expect(getDefautManualRouting()).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true if the feature toggle is enabled and localStorage is set to any value other than "false"', () => {
|
||||
config.featureToggles.alertingSimplifiedRouting = true;
|
||||
localStorage.setItem(MANUAL_ROUTING_KEY, 'true');
|
||||
expect(getDefautManualRouting()).toBe(true);
|
||||
localStorage.removeItem(MANUAL_ROUTING_KEY);
|
||||
expect(getDefautManualRouting()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
ScopedVars,
|
||||
TimeRange,
|
||||
} from '@grafana/data';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { config, getDataSourceSrv } from '@grafana/runtime';
|
||||
import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend';
|
||||
import { sceneGraph, VizPanel } from '@grafana/scenes';
|
||||
import { DataSourceJsonData } from '@grafana/schema';
|
||||
@ -54,6 +54,8 @@ export type PromOrLokiQuery = PromQuery | LokiQuery;
|
||||
|
||||
export const MINUTE = '1m';
|
||||
|
||||
export const MANUAL_ROUTING_KEY = 'grafana.alerting.manualRouting';
|
||||
|
||||
export const getDefaultFormValues = (): RuleFormValues => {
|
||||
const { canCreateGrafanaRules, canCreateCloudRules } = getRulesAccess();
|
||||
|
||||
@ -75,7 +77,7 @@ export const getDefaultFormValues = (): RuleFormValues => {
|
||||
execErrState: GrafanaAlertStateDecision.Error,
|
||||
evaluateFor: '5m',
|
||||
evaluateEvery: MINUTE,
|
||||
manualRouting: false, // let's decide this later
|
||||
manualRouting: getDefautManualRouting(), // we default to true if the feature toggle is enabled and the user hasn't set local storage to false
|
||||
contactPoints: {},
|
||||
overrideGrouping: false,
|
||||
overrideTimings: false,
|
||||
@ -89,6 +91,18 @@ export const getDefaultFormValues = (): RuleFormValues => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getDefautManualRouting = () => {
|
||||
// first check if feature toggle for simplified routing is enabled
|
||||
const simplifiedRoutingToggleEnabled = config.featureToggles.alertingSimplifiedRouting ?? false;
|
||||
if (!simplifiedRoutingToggleEnabled) {
|
||||
return false;
|
||||
}
|
||||
//then, check in local storage if the user has enabled simplified routing
|
||||
// if it's not set, we'll default to true
|
||||
const manualRouting = localStorage.getItem(MANUAL_ROUTING_KEY);
|
||||
return manualRouting !== 'false';
|
||||
};
|
||||
|
||||
export function formValuesToRulerRuleDTO(values: RuleFormValues): RulerRuleDTO {
|
||||
const { name, expression, forTime, forTimeUnit, keepFiringForTime, keepFiringForTimeUnit, type } = values;
|
||||
if (type === RuleFormType.cloudAlerting) {
|
||||
|
Loading…
Reference in New Issue
Block a user