diff --git a/public/app/features/alerting/unified/components/AlertRuleDrawerForm.tsx b/public/app/features/alerting/unified/components/AlertRuleDrawerForm.tsx index af327c43be9..ec6ad0af0d7 100644 --- a/public/app/features/alerting/unified/components/AlertRuleDrawerForm.tsx +++ b/public/app/features/alerting/unified/components/AlertRuleDrawerForm.tsx @@ -12,13 +12,44 @@ import { RuleDefinitionSection } from 'app/features/alerting/unified/components/ import { isGrafanaGroupUpdatedResponse } from '../api/alertRuleModel'; import { useAddRuleToRuleGroup } from '../hooks/ruleGroup/useUpsertRuleFromRuleGroup'; import { getDefaultFormValues } from '../rule-editor/formDefaults'; -import { RuleFormType, RuleFormValues } from '../types/rule-form'; +import { AlertManagerManualRouting, ContactPoint, RuleFormType, RuleFormValues } from '../types/rule-form'; import { formValuesToRulerGrafanaRuleDTO } from '../utils/rule-form'; import { getRuleGroupLocationFromFormValues } from '../utils/rules'; import { RuleConditionSection } from './RuleConditionSection'; import { RuleNotificationSection } from './RuleNotificationSection'; +function normalizeContactPoints( + contactPoints: AlertManagerManualRouting | undefined +): AlertManagerManualRouting | undefined { + if (!contactPoints) { + return contactPoints; + } + + const normalized: AlertManagerManualRouting = {}; + + for (const [alertManager, contactPoint] of Object.entries(contactPoints)) { + if (contactPoint.selectedContactPoint) { + const defaultContactPoint: ContactPoint = { + selectedContactPoint: contactPoint.selectedContactPoint, + overrideGrouping: contactPoint.overrideGrouping ?? false, + groupBy: contactPoint.groupBy ?? [], + overrideTimings: contactPoint.overrideTimings ?? false, + groupWaitValue: contactPoint.groupWaitValue ?? '', + groupIntervalValue: contactPoint.groupIntervalValue ?? '', + repeatIntervalValue: contactPoint.repeatIntervalValue ?? '', + muteTimeIntervals: contactPoint.muteTimeIntervals ?? [], + activeTimeIntervals: contactPoint.activeTimeIntervals ?? [], + }; + normalized[alertManager] = defaultContactPoint; + } else { + normalized[alertManager] = contactPoint; + } + } + + return normalized; +} + export interface AlertRuleDrawerFormProps { isOpen: boolean; onClose: () => void; @@ -102,7 +133,17 @@ export function AlertRuleDrawerForm({ {t('alerting.common.cancel', 'Cancel')} {onContinueInAlerting && ( - )} diff --git a/public/app/features/alerting/unified/components/panel-alerts-tab/NewRuleFromPanelButton.tsx b/public/app/features/alerting/unified/components/panel-alerts-tab/NewRuleFromPanelButton.tsx index 002a2baf8b9..1a165d04c1b 100644 --- a/public/app/features/alerting/unified/components/panel-alerts-tab/NewRuleFromPanelButton.tsx +++ b/public/app/features/alerting/unified/components/panel-alerts-tab/NewRuleFromPanelButton.tsx @@ -4,15 +4,14 @@ import { useAsync } from 'react-use'; import { urlUtil } from '@grafana/data'; import { Trans, t } from '@grafana/i18n'; -import { config, locationService, logInfo } from '@grafana/runtime'; +import { config } from '@grafana/runtime'; import { Alert, Button, LinkButton } from '@grafana/ui'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; import { PanelModel } from 'app/features/dashboard/state/PanelModel'; import { useSelector } from 'app/types/store'; -import { LogMessages } from '../../Analytics'; import { AlertRuleDrawerForm } from '../../components/AlertRuleDrawerForm'; -import type { RuleFormValues } from '../../types/rule-form'; +import { createPanelAlertRuleNavigation } from '../../utils/navigation'; import { panelToRuleFormValues } from '../../utils/rule-form'; interface Props { @@ -59,24 +58,10 @@ export const NewRuleFromPanelButton = ({ dashboard, panel, className }: Props) = ); } - const navigateToAlerting = async (currentValues?: RuleFormValues) => { - logInfo(LogMessages.alertRuleFromPanel); - // Prefer current drawer values if provided; otherwise refresh from panel state - const updateToDateFormValues = currentValues ?? (await panelToRuleFormValues(panel, dashboard)); - const ruleFormUrl = urlUtil.renderUrl('alerting/new', { - defaults: JSON.stringify(updateToDateFormValues), - returnTo: location.pathname + location.search, - }); - locationService.push(ruleFormUrl); - }; - - const onContinueInAlertingFromDrawer = (values: RuleFormValues) => { - void navigateToAlerting(values); - }; - - const onContinueInAlertingButton = () => { - void navigateToAlerting(undefined); - }; + const { onContinueInAlertingFromDrawer, onButtonClick: onContinueInAlertingButton } = createPanelAlertRuleNavigation( + () => panelToRuleFormValues(panel, dashboard), + location + ); const shouldUseDrawer = config.featureToggles.createAlertRuleFromPanel; diff --git a/public/app/features/alerting/unified/utils/navigation.ts b/public/app/features/alerting/unified/utils/navigation.ts index a77828af2c6..4ccea7c9a86 100644 --- a/public/app/features/alerting/unified/utils/navigation.ts +++ b/public/app/features/alerting/unified/utils/navigation.ts @@ -1,7 +1,11 @@ +import { urlUtil } from '@grafana/data'; +import { locationService, logInfo } from '@grafana/runtime'; import { ObjectMatcher } from 'app/plugins/datasource/alertmanager/types'; import { RuleGroupIdentifierV2, RuleIdentifier } from 'app/types/unified-alerting'; +import { LogMessages } from '../Analytics'; import { createReturnTo } from '../hooks/useReturnTo'; +import { RuleFormValues } from '../types/rule-form'; import { stringifyIdentifier } from './rule-id'; import { createRelativeUrl } from './url'; @@ -99,3 +103,35 @@ export const notificationPolicies = { }); }, }; + +export const createPanelAlertRuleNavigation = ( + getFormValues: () => Promise | undefined>, + location: { pathname: string; search: string } +) => { + const navigateToAlerting = async (currentValues?: RuleFormValues) => { + logInfo(LogMessages.alertRuleFromPanel); + + const updateToDateFormValues = currentValues ?? (await getFormValues()); + + const ruleFormUrl = urlUtil.renderUrl('/alerting/new', { + defaults: JSON.stringify(updateToDateFormValues), + returnTo: location.pathname + location.search, + }); + + locationService.push(ruleFormUrl); + }; + + const onContinueInAlertingFromDrawer = (values: RuleFormValues) => { + void navigateToAlerting(values); + }; + + const onButtonClick = () => { + void navigateToAlerting(undefined); + }; + + return { + navigateToAlerting, + onContinueInAlertingFromDrawer, + onButtonClick, + }; +}; diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/NewAlertRuleButton.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/NewAlertRuleButton.tsx index 2f22234c550..844a1021177 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/NewAlertRuleButton.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/NewAlertRuleButton.tsx @@ -2,14 +2,12 @@ import { useState } from 'react'; import { useLocation } from 'react-router-dom-v5-compat'; import { useAsync } from 'react-use'; -import { urlUtil } from '@grafana/data'; import { Trans, t } from '@grafana/i18n'; -import { config, locationService, logInfo } from '@grafana/runtime'; +import { config } from '@grafana/runtime'; import { VizPanel } from '@grafana/scenes'; import { Alert, Button } from '@grafana/ui'; -import { LogMessages } from 'app/features/alerting/unified/Analytics'; import { AlertRuleDrawerForm } from 'app/features/alerting/unified/components/AlertRuleDrawerForm'; -import type { RuleFormValues } from 'app/features/alerting/unified/types/rule-form'; +import { createPanelAlertRuleNavigation } from 'app/features/alerting/unified/utils/navigation'; import { scenesPanelToRuleFormValues } from 'app/features/alerting/unified/utils/rule-form'; interface ScenesNewRuleFromPanelButtonProps { @@ -46,26 +44,10 @@ export const ScenesNewRuleFromPanelButton = ({ panel, className }: ScenesNewRule ); } - const navigateToAlerting = async (currentValues?: RuleFormValues) => { - logInfo(LogMessages.alertRuleFromPanel); - - const updateToDateFormValues = currentValues ?? (await scenesPanelToRuleFormValues(panel)); - - const ruleFormUrl = urlUtil.renderUrl('/alerting/new', { - defaults: JSON.stringify(updateToDateFormValues), - returnTo: location.pathname + location.search, - }); - - locationService.push(ruleFormUrl); - }; - - const onContinueInAlertingFromDrawer = (values: RuleFormValues) => { - void navigateToAlerting(values); - }; - - const onButtonClick = () => { - void navigateToAlerting(undefined); - }; + const { onContinueInAlertingFromDrawer, onButtonClick } = createPanelAlertRuleNavigation( + () => scenesPanelToRuleFormValues(panel), + location + ); const shouldUseDrawer = config.featureToggles.createAlertRuleFromPanel; diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index dfc00dcc236..c0f4a188de7 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -2849,10 +2849,7 @@ }, "title": "Notification" }, - "rule-definition": "Rule Definition", - "step-number-one": "1", - "step-number-three": "3", - "step-number-two": "2" + "rule-definition": "Rule Definition" }, "smart-alert-type-detector": { "data-source-managed": "Data source-managed",