mirror of
https://github.com/grafana/grafana.git
synced 2025-02-15 01:53:33 -06:00
Alerting: Refactor AlertRuleForm and fix annotations step description for cloud rules (#74168)
Refactor AlertRuleForm and fix annotations step description for cloud rules
This commit is contained in:
parent
34a831c83e
commit
2a2689a7c2
@ -9,7 +9,7 @@ import { Button, Card, Modal, RadioButtonGroup, useStyles2 } from '@grafana/ui';
|
||||
import { TestTemplateAlert } from 'app/plugins/datasource/alertmanager/types';
|
||||
|
||||
import { KeyValueField } from '../../../api/templateApi';
|
||||
import AnnotationsField from '../../rule-editor/AnnotationsField';
|
||||
import AnnotationsStep from '../../rule-editor/AnnotationsStep';
|
||||
import LabelsField from '../../rule-editor/LabelsField';
|
||||
|
||||
interface Props {
|
||||
@ -99,7 +99,7 @@ export const GenerateAlertDataModal = ({ isOpen, onDismiss, onAccept }: Props) =
|
||||
<Card>
|
||||
<Stack direction="column" gap={1}>
|
||||
<div className={styles.section}>
|
||||
<AnnotationsField />
|
||||
<AnnotationsStep />
|
||||
</div>
|
||||
<div className={styles.section}>
|
||||
<LabelsField />
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useState } from 'react';
|
||||
import { useForm, FormProvider } from 'react-hook-form';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Modal, Button, Label, useStyles2, RadioButtonGroup } from '@grafana/ui';
|
||||
import { Button, Label, Modal, RadioButtonGroup, useStyles2 } from '@grafana/ui';
|
||||
import { TestReceiversAlert } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { Annotations, Labels } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { defaultAnnotations } from '../../../utils/constants';
|
||||
import AnnotationsField from '../../rule-editor/AnnotationsField';
|
||||
import AnnotationsStep from '../../rule-editor/AnnotationsStep';
|
||||
import LabelsField from '../../rule-editor/LabelsField';
|
||||
|
||||
interface Props {
|
||||
@ -90,7 +90,7 @@ export const TestContactPointModal = ({ isOpen, onDismiss, onTest }: Props) => {
|
||||
use custom templates and messages.
|
||||
</div>
|
||||
<div className={styles.section}>
|
||||
<AnnotationsField />
|
||||
<AnnotationsStep />
|
||||
</div>
|
||||
<div className={styles.section}>
|
||||
<LabelsField />
|
||||
|
@ -30,11 +30,12 @@ import {
|
||||
} from '../../utils/rule-form';
|
||||
import * as ruleId from '../../utils/rule-id';
|
||||
|
||||
import AnnotationsStep from './AnnotationsStep';
|
||||
import { CloudEvaluationBehavior } from './CloudEvaluationBehavior';
|
||||
import { DetailsStep } from './DetailsStep';
|
||||
import { GrafanaEvaluationBehavior } from './GrafanaEvaluationBehavior';
|
||||
import { GrafanaRuleInspector } from './GrafanaRuleInspector';
|
||||
import { NotificationsStep } from './NotificationsStep';
|
||||
import { RecordingRulesNameSpaceAndGroupStep } from './RecordingRulesNameSpaceAndGroupStep';
|
||||
import { RuleEditorSection } from './RuleEditorSection';
|
||||
import { RuleInspector } from './RuleInspector';
|
||||
import { QueryAndExpressionsStep } from './query-and-alert-condition/QueryAndExpressionsStep';
|
||||
@ -130,7 +131,7 @@ export const AlertRuleForm = ({ existing, prefill }: Props) => {
|
||||
const type = watch('type');
|
||||
const dataSourceName = watch('dataSourceName');
|
||||
|
||||
const showStep2 = Boolean(type && (type === RuleFormType.grafana || !!dataSourceName));
|
||||
const showDataSourceDependantStep = Boolean(type && (type === RuleFormType.grafana || !!dataSourceName));
|
||||
|
||||
const submitState = useUnifiedAlertingSelector((state) => state.ruleForm.saveRule) || initialAsyncRequestState;
|
||||
useCleanup((state) => (state.unifiedAlerting.ruleForm.saveRule = initialAsyncRequestState));
|
||||
@ -254,20 +255,30 @@ export const AlertRuleForm = ({ existing, prefill }: Props) => {
|
||||
<div className={styles.contentOuter}>
|
||||
<CustomScrollbar autoHeightMin="100%" hideHorizontalTrack={true}>
|
||||
<div className={styles.contentInner}>
|
||||
{/* Step 1 */}
|
||||
<AlertRuleNameInput />
|
||||
{/* Step 2 */}
|
||||
<QueryAndExpressionsStep editingExistingRule={!!existing} onDataChange={checkAlertCondition} />
|
||||
{showStep2 && (
|
||||
{/* Step 3-4-5 */}
|
||||
{showDataSourceDependantStep && (
|
||||
<>
|
||||
{type === RuleFormType.grafana ? (
|
||||
{/* Step 3 */}
|
||||
{type === RuleFormType.grafana && (
|
||||
<GrafanaEvaluationBehavior
|
||||
evaluateEvery={evaluateEvery}
|
||||
setEvaluateEvery={setEvaluateEvery}
|
||||
existing={Boolean(existing)}
|
||||
/>
|
||||
) : (
|
||||
<CloudEvaluationBehavior />
|
||||
)}
|
||||
<DetailsStep />
|
||||
|
||||
{type === RuleFormType.cloudAlerting && <CloudEvaluationBehavior />}
|
||||
|
||||
{type === RuleFormType.cloudRecording && <RecordingRulesNameSpaceAndGroupStep />}
|
||||
|
||||
{/* Step 4 & 5 */}
|
||||
{/* Annotations only for cloud and Grafana */}
|
||||
{type !== RuleFormType.cloudRecording && <AnnotationsStep />}
|
||||
{/* Notifications step*/}
|
||||
<NotificationsStep alertUid={uidFromParams} />
|
||||
</>
|
||||
)}
|
||||
|
@ -21,7 +21,7 @@ import { getDefaultFormValues } from '../../utils/rule-form';
|
||||
|
||||
import 'whatwg-fetch';
|
||||
|
||||
import AnnotationsField from './AnnotationsField';
|
||||
import AnnotationsStep from './AnnotationsStep';
|
||||
|
||||
// To get anything displayed inside the Autosize component we need to mock it
|
||||
// Ref https://github.com/bvaughn/react-window/issues/454#issuecomment-646031139
|
||||
@ -65,7 +65,7 @@ function FormWrapper({ formValues }: { formValues?: Partial<RuleFormValues> }) {
|
||||
return (
|
||||
<TestProvider store={store}>
|
||||
<FormProvider {...formApi}>
|
||||
<AnnotationsField />
|
||||
<AnnotationsStep />
|
||||
</FormProvider>
|
||||
</TestProvider>
|
||||
);
|
||||
|
@ -16,8 +16,10 @@ import { Annotation, annotationLabels } from '../../utils/constants';
|
||||
import AnnotationHeaderField from './AnnotationHeaderField';
|
||||
import DashboardAnnotationField from './DashboardAnnotationField';
|
||||
import { DashboardPicker, PanelDTO } from './DashboardPicker';
|
||||
import { NeedHelpInfo } from './NeedHelpInfo';
|
||||
import { RuleEditorSection } from './RuleEditorSection';
|
||||
|
||||
const AnnotationsField = () => {
|
||||
const AnnotationsStep = () => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const [showPanelSelector, setShowPanelSelector] = useToggle(false);
|
||||
|
||||
@ -90,8 +92,27 @@ const AnnotationsField = () => {
|
||||
setShowPanelSelector(true);
|
||||
};
|
||||
|
||||
function getAnnotationsSectionDescription() {
|
||||
const docsLink =
|
||||
'https://grafana.com/docs/grafana/latest/alerting/fundamentals/annotation-label/variables-label-annotation';
|
||||
|
||||
return (
|
||||
<Stack gap={0.5}>
|
||||
Add annotations to provide more context in your alert notifications.
|
||||
<NeedHelpInfo
|
||||
contentText={`Annotations add metadata to provide more information on the alert in your alert notifications.
|
||||
For example, add a Summary annotation to tell you which value caused the alert to fire or which server it happened on.
|
||||
Annotations can contain a combination of text and template code.`}
|
||||
externalLink={docsLink}
|
||||
linkText={`Read about annotations`}
|
||||
title="Annotations"
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<RuleEditorSection stepNo={4} title="Add annotations" description={getAnnotationsSectionDescription()}>
|
||||
<div className={styles.flexColumn}>
|
||||
{fields.map((annotationField, index: number) => {
|
||||
const isUrl = annotations[index]?.key?.toLocaleLowerCase().endsWith('url');
|
||||
@ -186,7 +207,7 @@ const AnnotationsField = () => {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
</RuleEditorSection>
|
||||
);
|
||||
};
|
||||
|
||||
@ -242,4 +263,4 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
`,
|
||||
});
|
||||
|
||||
export default AnnotationsField;
|
||||
export default AnnotationsStep;
|
@ -24,11 +24,6 @@ export const CloudEvaluationBehavior = () => {
|
||||
const type = watch('type');
|
||||
const dataSourceName = watch('dataSourceName');
|
||||
|
||||
// cloud recording rules do not have alert conditions
|
||||
if (type === RuleFormType.cloudRecording) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<RuleEditorSection stepNo={3} title="Set alert evaluation behavior">
|
||||
<Field
|
||||
|
@ -1,108 +0,0 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Stack } from '@grafana/experimental';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { RuleFormType, RuleFormValues } from '../../types/rule-form';
|
||||
|
||||
import AnnotationsField from './AnnotationsField';
|
||||
import { GroupAndNamespaceFields } from './GroupAndNamespaceFields';
|
||||
import { NeedHelpInfo } from './NeedHelpInfo';
|
||||
import { RuleEditorSection } from './RuleEditorSection';
|
||||
|
||||
function getDescription(ruleType: RuleFormType | undefined, styles: { [key: string]: string }) {
|
||||
const annotationsText = 'Add annotations to provide more context in your alert notifications.';
|
||||
|
||||
if (ruleType === RuleFormType.cloudRecording) {
|
||||
return 'Select the Namespace and Group for your recording rule.';
|
||||
}
|
||||
const docsLink =
|
||||
'https://grafana.com/docs/grafana/latest/alerting/fundamentals/annotation-label/variables-label-annotation';
|
||||
|
||||
const textToRender =
|
||||
ruleType === RuleFormType.grafana
|
||||
? ` ${annotationsText} `
|
||||
: ruleType === RuleFormType.cloudAlerting
|
||||
? `Select the Namespace and evaluation group for your alert. ${annotationsText} `
|
||||
: '';
|
||||
|
||||
return (
|
||||
<Stack gap={0.5}>
|
||||
{`${textToRender}`}
|
||||
<NeedHelpInfo
|
||||
contentText={`Annotations add metadata to provide more information on the alert in your alert notifications.
|
||||
For example, add a Summary annotation to tell you which value caused the alert to fire or which server it happened on.
|
||||
Annotations can contain a combination of text and template code.`}
|
||||
externalLink={docsLink}
|
||||
linkText={`Read about annotations`}
|
||||
title="Annotations"
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
export function DetailsStep() {
|
||||
const { watch } = useFormContext<RuleFormValues & { location?: string }>();
|
||||
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const ruleFormType = watch('type');
|
||||
const dataSourceName = watch('dataSourceName');
|
||||
const type = watch('type');
|
||||
|
||||
return (
|
||||
<RuleEditorSection
|
||||
stepNo={type === RuleFormType.cloudRecording ? 3 : 4}
|
||||
title={type === RuleFormType.cloudRecording ? 'Add namespace and group' : 'Add annotations'}
|
||||
description={getDescription(type, styles)}
|
||||
>
|
||||
{ruleFormType === RuleFormType.cloudRecording && dataSourceName && (
|
||||
<GroupAndNamespaceFields rulesSourceName={dataSourceName} />
|
||||
)}
|
||||
|
||||
{type !== RuleFormType.cloudRecording && <AnnotationsField />}
|
||||
</RuleEditorSection>
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
needHelpText: css`
|
||||
color: ${theme.colors.text.primary};
|
||||
font-size: ${theme.typography.size.sm};
|
||||
margin-bottom: ${theme.spacing(0.5)};
|
||||
cursor: pointer;
|
||||
text-underline-position: under;
|
||||
`,
|
||||
|
||||
needHelpTooltip: css`
|
||||
max-width: 300px;
|
||||
font-size: ${theme.typography.size.sm};
|
||||
margin-left: 5px;
|
||||
|
||||
div {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
`,
|
||||
|
||||
tooltipHeader: css`
|
||||
color: ${theme.colors.text.primary};
|
||||
font-weight: bold;
|
||||
`,
|
||||
|
||||
tooltipLink: css`
|
||||
color: ${theme.colors.text.link};
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
`,
|
||||
|
||||
underline: css`
|
||||
text-decoration: underline;
|
||||
`,
|
||||
});
|
@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { RuleFormValues } from '../../types/rule-form';
|
||||
|
||||
import { GroupAndNamespaceFields } from './GroupAndNamespaceFields';
|
||||
import { RuleEditorSection } from './RuleEditorSection';
|
||||
|
||||
export function RecordingRulesNameSpaceAndGroupStep() {
|
||||
const { watch } = useFormContext<RuleFormValues & { location?: string }>();
|
||||
|
||||
const dataSourceName = watch('dataSourceName');
|
||||
|
||||
if (!dataSourceName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<RuleEditorSection
|
||||
stepNo={3}
|
||||
title={'Add namespace and group'}
|
||||
description="Select the Namespace and Group for your recording rule."
|
||||
>
|
||||
<GroupAndNamespaceFields rulesSourceName={dataSourceName} />
|
||||
</RuleEditorSection>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user