diff --git a/public/app/features/alerting/unified/components/AlertRuleDrawerForm.tsx b/public/app/features/alerting/unified/components/AlertRuleDrawerForm.tsx index 440579a0468..41be22ab514 100644 --- a/public/app/features/alerting/unified/components/AlertRuleDrawerForm.tsx +++ b/public/app/features/alerting/unified/components/AlertRuleDrawerForm.tsx @@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data'; import { t } from '@grafana/i18n'; import { Button, Drawer, Stack, useStyles2 } from '@grafana/ui'; import { useAppNotification } from 'app/core/copy/appNotification'; +import { getMessageFromError } from 'app/core/utils/errors'; import { RuleDefinitionSection } from 'app/features/alerting/unified/components/RuleDefinitionSection'; import { isGrafanaGroupUpdatedResponse } from '../api/alertRuleModel'; @@ -22,14 +23,20 @@ export interface AlertRuleDrawerFormProps { isOpen: boolean; onClose: () => void; title?: string; - onContinueInAlerting?: () => void; + onContinueInAlerting?: (values: RuleFormValues) => void; prefill?: Partial; } -export function AlertRuleDrawerForm({ isOpen, onClose, title, onContinueInAlerting, prefill }: AlertRuleDrawerFormProps) { +export function AlertRuleDrawerForm({ + isOpen, + onClose, + title, + onContinueInAlerting, + prefill, +}: AlertRuleDrawerFormProps) { const baseDefaults = useMemo(() => getDefaultFormValues(RuleFormType.grafana), []); const methods = useForm({ - defaultValues: prefill ? { ...baseDefaults, ...(prefill as Partial) } : baseDefaults, + defaultValues: prefill ? { ...baseDefaults, ...prefill } : baseDefaults, }); const styles = useStyles2(getStyles); const [addRuleToRuleGroup] = useAddRuleToRuleGroup(); @@ -38,9 +45,9 @@ export function AlertRuleDrawerForm({ isOpen, onClose, title, onContinueInAlerti // Keep form in sync if prefill changes between openings useEffect(() => { if (prefill) { - methods.reset({ ...baseDefaults, ...(prefill as Partial) }); + methods.reset({ ...baseDefaults, ...prefill }); } - }, [prefill, methods]); + }, [prefill, methods, baseDefaults]); if (!isOpen) { return null; @@ -48,7 +55,8 @@ export function AlertRuleDrawerForm({ isOpen, onClose, title, onContinueInAlerti const submit = async (values: RuleFormValues) => { try { - const groupName = values.group && values.group.trim().length > 0 ? values.group : (values.name?.trim() || 'default'); + const groupName = + values.group && values.group.trim().length > 0 ? values.group : values.name?.trim() || 'default'; const effectiveValues: RuleFormValues = { ...values, group: groupName }; const dto = formValuesToRulerGrafanaRuleDTO(effectiveValues); @@ -59,9 +67,9 @@ export function AlertRuleDrawerForm({ isOpen, onClose, title, onContinueInAlerti return; } notifyApp.error('Failed to create rule', 'The rule was not created. Please review the form and try again.'); - } catch (err: any) { - const msg = err?.data?.message || err?.message || 'Unknown error while creating the rule.'; - notifyApp.error('Failed to create rule', msg); + } catch (err) { + const errorMessage = getMessageFromError(err); + notifyApp.error('Failed to create rule', errorMessage); } }; @@ -93,7 +101,7 @@ export function AlertRuleDrawerForm({ isOpen, onClose, title, onContinueInAlerti {t('alerting.common.cancel', 'Cancel')} {onContinueInAlerting && ( - )} diff --git a/public/app/features/alerting/unified/components/RuleDefinitionSection.tsx b/public/app/features/alerting/unified/components/RuleDefinitionSection.tsx index 672b3f2d1bd..197f741e764 100644 --- a/public/app/features/alerting/unified/components/RuleDefinitionSection.tsx +++ b/public/app/features/alerting/unified/components/RuleDefinitionSection.tsx @@ -83,7 +83,9 @@ export function RuleDefinitionSection({ type }: { type: RuleFormType }) { isOpen={showLabelsEditor} onClose={(labelsToUpdate) => { if (labelsToUpdate) { - const filtered = labelsToUpdate.filter((l) => (l?.key ?? '').length > 0 || (l?.value ?? '').length > 0); + const filtered = labelsToUpdate.filter( + (l) => (l?.key ?? '').length > 0 || (l?.value ?? '').length > 0 + ); setValue('labels', filtered, { shouldDirty: true, shouldValidate: true }); } setShowLabelsEditor(false); 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 0194a4e8a79..002a2baf8b9 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 @@ -12,6 +12,7 @@ import { useSelector } from 'app/types/store'; import { LogMessages } from '../../Analytics'; import { AlertRuleDrawerForm } from '../../components/AlertRuleDrawerForm'; +import type { RuleFormValues } from '../../types/rule-form'; import { panelToRuleFormValues } from '../../utils/rule-form'; interface Props { @@ -58,10 +59,10 @@ export const NewRuleFromPanelButton = ({ dashboard, panel, className }: Props) = ); } - const onContinueInAlerting = async () => { + const navigateToAlerting = async (currentValues?: RuleFormValues) => { logInfo(LogMessages.alertRuleFromPanel); - // Refresh values to ensure they're up-to-date with current panel state - const updateToDateFormValues = await panelToRuleFormValues(panel, dashboard); + // 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, @@ -69,6 +70,14 @@ export const NewRuleFromPanelButton = ({ dashboard, panel, className }: Props) = locationService.push(ruleFormUrl); }; + const onContinueInAlertingFromDrawer = (values: RuleFormValues) => { + void navigateToAlerting(values); + }; + + const onContinueInAlertingButton = () => { + void navigateToAlerting(undefined); + }; + const shouldUseDrawer = config.featureToggles.createAlertRuleFromPanel; if (shouldUseDrawer) { @@ -85,7 +94,7 @@ export const NewRuleFromPanelButton = ({ dashboard, panel, className }: Props) = setIsOpen(false)} - onContinueInAlerting={onContinueInAlerting} + onContinueInAlerting={onContinueInAlertingFromDrawer} prefill={formValues ?? undefined} /> @@ -95,7 +104,7 @@ export const NewRuleFromPanelButton = ({ dashboard, panel, className }: Props) = return ( { + const navigateToAlerting = async (currentValues?: RuleFormValues) => { logInfo(LogMessages.alertRuleFromPanel); - const updateToDateFormValues = await scenesPanelToRuleFormValues(panel); + const updateToDateFormValues = currentValues ?? (await scenesPanelToRuleFormValues(panel)); const ruleFormUrl = urlUtil.renderUrl('/alerting/new', { defaults: JSON.stringify(updateToDateFormValues), @@ -58,6 +59,14 @@ export const ScenesNewRuleFromPanelButton = ({ panel, className }: ScenesNewRule locationService.push(ruleFormUrl); }; + const onContinueInAlertingFromDrawer = (values: RuleFormValues) => { + void navigateToAlerting(values); + }; + + const onButtonClick = () => { + void navigateToAlerting(undefined); + }; + const shouldUseDrawer = config.featureToggles.createAlertRuleFromPanel; if (shouldUseDrawer) { @@ -76,7 +85,7 @@ export const ScenesNewRuleFromPanelButton = ({ panel, className }: ScenesNewRule setIsOpen(false)} - onContinueInAlerting={onClick} + onContinueInAlerting={onContinueInAlertingFromDrawer} prefill={formValues ?? undefined} /> @@ -84,7 +93,7 @@ export const ScenesNewRuleFromPanelButton = ({ panel, className }: ScenesNewRule } return ( - );