enable toggling between manual routing
This commit is contained in:
@@ -1,15 +1,35 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { notificationsAPIv0alpha1 } from '@grafana/alerting/unstable';
|
||||
import type { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { Button, Combobox, ComboboxOption, Field, Input, Stack, TextArea, TextLink, useStyles2 } from '@grafana/ui';
|
||||
import {
|
||||
Button,
|
||||
Combobox,
|
||||
ComboboxOption,
|
||||
Field,
|
||||
Input,
|
||||
Stack,
|
||||
Switch,
|
||||
Text,
|
||||
TextArea,
|
||||
TextLink,
|
||||
useStyles2,
|
||||
} from '@grafana/ui';
|
||||
|
||||
import { RuleFormValues } from '../types/rule-form';
|
||||
|
||||
import { NeedHelpInfoForNotificationPolicy } from './rule-editor/NotificationsStep';
|
||||
|
||||
export function RuleNotificationSection() {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const [contactPoint, setContactPoint] = useState<ComboboxOption<string> | null>(null);
|
||||
const { watch, setValue } = useFormContext<RuleFormValues>();
|
||||
const manualRouting = watch('manualRouting');
|
||||
const useNotificationPolicy = !manualRouting;
|
||||
const selectedContactPoint = watch('contactPoints.grafana.selectedContactPoint');
|
||||
// Fetch contact points from Alerting API v0alpha1
|
||||
const { currentData, status, refetch } = notificationsAPIv0alpha1.endpoints.listReceiver.useQuery({});
|
||||
const options = useMemo<Array<ComboboxOption<string>>>(
|
||||
@@ -35,49 +55,95 @@ export function RuleNotificationSection() {
|
||||
<div className={styles.contentIndented}>
|
||||
<Stack direction="column" gap={2}>
|
||||
<Field
|
||||
label={t('alerting.simplified.notification.contact-point.label', 'Contact point')}
|
||||
description={t(
|
||||
'alerting.simplified.notification.contact-point.description',
|
||||
'Select who should receive a notification when the alert rule fires'
|
||||
)}
|
||||
label={
|
||||
<Stack direction="row" alignItems="center" justifyContent="space-between" gap={1}>
|
||||
<span>{t('alerting.simplified.notification.recipient.label', 'Recipient')}</span>
|
||||
<Stack direction="row" alignItems="center" gap={0.5}>
|
||||
<Text variant="bodySmall" color="secondary">
|
||||
{t('alerting.simplified.notification.manual-routing.label', 'Manual routing')}
|
||||
</Text>
|
||||
<Switch
|
||||
value={manualRouting}
|
||||
onChange={(e) => {
|
||||
const next = e.currentTarget.checked;
|
||||
setValue('manualRouting', next, { shouldDirty: true });
|
||||
setValue('editorSettings.simplifiedNotificationEditor', next, { shouldDirty: true });
|
||||
}}
|
||||
aria-label={t('alerting.simplified.notification.manual-routing.aria', 'Toggle manual routing')}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
}
|
||||
noMargin
|
||||
>
|
||||
<Stack direction="row" gap={1} alignItems="center">
|
||||
<Combobox<ComboboxOption<string>['value']>
|
||||
options={options}
|
||||
value={contactPoint}
|
||||
onChange={(opt) => setContactPoint(opt)}
|
||||
width={30}
|
||||
placeholder={t('alerting.simplified.notification.select-contact-point', 'Select a contact point...')}
|
||||
isClearable
|
||||
data-testid="contact-point"
|
||||
loading={status === 'pending'}
|
||||
/>
|
||||
<Button
|
||||
icon="sync"
|
||||
variant="secondary"
|
||||
fill="text"
|
||||
size="sm"
|
||||
aria-label={t('alerting.common.refresh', 'Refresh')}
|
||||
onClick={() => {
|
||||
if (refetch) {
|
||||
refetch();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<TextLink
|
||||
external
|
||||
href={'/alerting/notifications'}
|
||||
aria-label={t(
|
||||
'alerting.link-to-contact-points.aria-label-view-or-create-contact-points',
|
||||
'View or create contact points'
|
||||
)}
|
||||
>
|
||||
<Trans i18nKey="alerting.link-to-contact-points.view-or-create-contact-points">
|
||||
View or create contact points
|
||||
</Trans>
|
||||
</TextLink>
|
||||
</Stack>
|
||||
{useNotificationPolicy ? (
|
||||
<div className={styles.contentTopSpacer}>
|
||||
<Stack direction="column" gap={1} alignItems="start">
|
||||
<Text variant="bodySmall" color="secondary">
|
||||
<Trans i18nKey="alerting.simplified.notification.policy-selected">
|
||||
Notifications for firing alerts are routed to contact points based on matching labels and the
|
||||
notification policy tree.
|
||||
</Trans>
|
||||
</Text>
|
||||
<NeedHelpInfoForNotificationPolicy />
|
||||
</Stack>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.contentTopSpacer}>
|
||||
<Stack direction="column" gap={1}>
|
||||
<Text variant="bodySmall" color="secondary">
|
||||
<Trans i18nKey="alerting.simplified.notification.contact-point-selected">
|
||||
Notifications for firing alerts are routed to a selected contact point.
|
||||
</Trans>
|
||||
</Text>
|
||||
<Stack direction="row" gap={1} alignItems="center">
|
||||
<Combobox<ComboboxOption<string>['value']>
|
||||
options={options}
|
||||
value={
|
||||
selectedContactPoint ? (options.find((o) => o.value === selectedContactPoint) ?? null) : null
|
||||
}
|
||||
onChange={(opt) =>
|
||||
setValue('contactPoints.grafana.selectedContactPoint', opt?.value ?? '', {
|
||||
shouldDirty: true,
|
||||
})
|
||||
}
|
||||
width={30}
|
||||
placeholder={t(
|
||||
'alerting.simplified.notification.select-contact-point',
|
||||
'Select a contact point...'
|
||||
)}
|
||||
isClearable
|
||||
data-testid="contact-point"
|
||||
loading={status === 'pending'}
|
||||
/>
|
||||
<Button
|
||||
icon="sync"
|
||||
variant="secondary"
|
||||
fill="text"
|
||||
size="sm"
|
||||
aria-label={t('alerting.common.refresh', 'Refresh')}
|
||||
onClick={() => {
|
||||
if (refetch) {
|
||||
refetch();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<TextLink
|
||||
external
|
||||
href={'/alerting/notifications'}
|
||||
aria-label={t(
|
||||
'alerting.link-to-contact-points.aria-label-view-or-create-contact-points',
|
||||
'View or create contact points'
|
||||
)}
|
||||
>
|
||||
<Trans i18nKey="alerting.link-to-contact-points.view-or-create-contact-points">
|
||||
View or create contact points
|
||||
</Trans>
|
||||
</TextLink>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</div>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<Field label={t('alerting.simplified.notification.summary.label', 'Summary (optional)')} noMargin>
|
||||
@@ -139,5 +205,6 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
fontWeight: 600,
|
||||
}),
|
||||
contentIndented: css({ marginLeft: `calc(20px + ${theme.spacing(1)})` }),
|
||||
contentTopSpacer: css({ marginTop: theme.spacing(0.5) }),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ function AutomaticRooting({ alertUid }: AutomaticRootingProps) {
|
||||
}
|
||||
|
||||
// Auxiliar components to build the texts and descriptions in the NotificationsStep
|
||||
function NeedHelpInfoForNotificationPolicy() {
|
||||
export function NeedHelpInfoForNotificationPolicy() {
|
||||
return (
|
||||
<NeedHelpInfo
|
||||
contentText={
|
||||
|
||||
@@ -2824,14 +2824,19 @@
|
||||
"immediate-warning": "Immediate firing might lead to unnecessary alerts being sent for temporary issues"
|
||||
},
|
||||
"notification": {
|
||||
"contact-point": {
|
||||
"description": "Select who should receive a notification when the alert rule fires",
|
||||
"label": "Contact point"
|
||||
},
|
||||
"contact-point-selected": "Notifications for firing alerts are routed to a selected contact point.",
|
||||
"description": {
|
||||
"label": "Description (optional)",
|
||||
"placeholder": "Enter a description of what the alert rule does…"
|
||||
},
|
||||
"manual-routing": {
|
||||
"aria": "Toggle manual routing",
|
||||
"label": "Manual routing"
|
||||
},
|
||||
"policy-selected": "Notifications for firing alerts are routed to contact points based on matching labels and the notification policy tree.",
|
||||
"recipient": {
|
||||
"label": "Recipient"
|
||||
},
|
||||
"runbook-url": {
|
||||
"label": "Runbook URL (optional)",
|
||||
"placeholder": "Enter the webpage where you keep your runbook for the alert…"
|
||||
|
||||
Reference in New Issue
Block a user