Alerting: Fix inconsistencies in alert rule form depending on alert type (#72287)

* Fix inconsistencies in alert rule form depending on alert type

* Fix default annotations when comming from dashboard panel

* Update texts following pr review comments

* Fix texts

---------

Co-authored-by: Virginia Cepeda <virginia.cepeda@grafana.com>
This commit is contained in:
Sonia Aguilar 2023-07-25 22:34:14 +02:00 committed by GitHub
parent c6ab1ddb70
commit 19b239fba0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 39 additions and 18 deletions

View File

@ -21,7 +21,13 @@ import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelect
import { deleteRuleAction, saveRuleFormAction } from '../../state/actions';
import { RuleFormType, RuleFormValues } from '../../types/rule-form';
import { initialAsyncRequestState } from '../../utils/redux';
import { getDefaultFormValues, getDefaultQueries, MINUTE, rulerRuleToFormValues } from '../../utils/rule-form';
import {
getDefaultFormValues,
getDefaultQueries,
MINUTE,
normalizeDefaultAnnotations,
rulerRuleToFormValues,
} from '../../utils/rule-form';
import * as ruleId from '../../utils/rule-id';
import { CloudEvaluationBehavior } from './CloudEvaluationBehavior';
@ -50,7 +56,7 @@ const AlertRuleNameInput = () => {
const ruleFormType = watch('type');
return (
<RuleEditorSection stepNo={1} title="Set alert rule name">
<RuleEditorSection stepNo={1} title="Set alert rule name.">
<Field
className={styles.formInput}
label="Rule name"
@ -323,6 +329,7 @@ function formValuesFromQueryParams(ruleDefinition: string, type: RuleFormType):
return ignoreHiddenQueries({
...getDefaultFormValues(),
...ruleFromQueryParams,
annotations: normalizeDefaultAnnotations(ruleFromQueryParams.annotations ?? []),
queries: ruleFromQueryParams.queries ?? getDefaultQueries(),
type: type || RuleFormType.grafana,
evaluateEvery: MINUTE,

View File

@ -8,6 +8,7 @@ import { Field, Input, InputControl, Select, useStyles2 } from '@grafana/ui';
import { RuleFormType, RuleFormValues } from '../../types/rule-form';
import { timeOptions } from '../../utils/time';
import { GroupAndNamespaceFields } from './GroupAndNamespaceFields';
import { PreviewRule } from './PreviewRule';
import { RuleEditorSection } from './RuleEditorSection';
@ -21,6 +22,7 @@ export const CloudEvaluationBehavior = () => {
} = useFormContext<RuleFormValues>();
const type = watch('type');
const dataSourceName = watch('dataSourceName');
// cloud recording rules do not have alert conditions
if (type === RuleFormType.cloudRecording) {
@ -28,8 +30,11 @@ export const CloudEvaluationBehavior = () => {
}
return (
<RuleEditorSection stepNo={3} title="Alert evaluation behavior">
<Field label="For" description="Expression has to be true for this long for the alert to be fired.">
<RuleEditorSection stepNo={3} title="Set alert evaluation behavior">
<Field
label="Pending period"
description="Period in which an alert rule can be in breach of the condition until the alert rule fires."
>
<div className={styles.flexRow}>
<Field invalid={!!errors.forTime?.message} error={errors.forTime?.message} className={styles.inlineField}>
<Input
@ -52,6 +57,10 @@ export const CloudEvaluationBehavior = () => {
/>
</div>
</Field>
{type === RuleFormType.cloudAlerting && dataSourceName && (
<GroupAndNamespaceFields rulesSourceName={dataSourceName} />
)}
<PreviewRule />
</RuleEditorSection>
);

View File

@ -56,11 +56,12 @@ export function DetailsStep() {
return (
<RuleEditorSection
stepNo={type === RuleFormType.cloudRecording ? 3 : 4}
title={type === RuleFormType.cloudRecording ? 'Folder and group' : 'Add annotations'}
title={type === RuleFormType.cloudRecording ? 'Add namespace and group' : 'Add annotations'}
description={getDescription(type, styles)}
>
{(ruleFormType === RuleFormType.cloudRecording || ruleFormType === RuleFormType.cloudAlerting) &&
dataSourceName && <GroupAndNamespaceFields rulesSourceName={dataSourceName} />}
{ruleFormType === RuleFormType.cloudRecording && dataSourceName && (
<GroupAndNamespaceFields rulesSourceName={dataSourceName} />
)}
{type !== RuleFormType.cloudRecording && <AnnotationsField />}
</RuleEditorSection>

View File

@ -182,7 +182,7 @@ export function FolderAndGroup({ groupfoldersForGrafana }: { groupfoldersForGraf
<Field
label="Evaluation group"
data-testid="group-picker"
description="Rules within the same group are evaluated sequentially over the same time interval"
description="Rules within the same group are evaluated sequentially over the same time interval."
className={styles.formInput}
error={errors.group?.message}
invalid={!!errors.group?.message}

View File

@ -168,7 +168,7 @@ function ForInput({ evaluateEvery }: { evaluateEvery: string }) {
label={
<Label
htmlFor="evaluateFor"
description="Period in which an alert rule can be in breach of the condition until the alert rule fires"
description="Period in which an alert rule can be in breach of the condition until the alert rule fires."
>
Pending period
</Label>

View File

@ -86,7 +86,7 @@ export const NotificationsStep = ({ alertUid }: NotificationsStepProps) => {
return (
<RuleEditorSection
stepNo={type === RuleFormType.cloudRecording ? 4 : 5}
title={type === RuleFormType.cloudRecording ? 'Labels' : 'Configure notifications'}
title={type === RuleFormType.cloudRecording ? 'Add labels' : 'Configure notifications'}
description={
type === RuleFormType.cloudRecording ? (
'Add labels to help you better manage your recording rules'

View File

@ -25,7 +25,7 @@ import { NeedHelpInfo } from '../NeedHelpInfo';
import { QueryEditor } from '../QueryEditor';
import { RecordingRuleEditor } from '../RecordingRuleEditor';
import { RuleEditorSection } from '../RuleEditorSection';
import { errorFromSeries, refIdExists, findRenamedDataQueryReferences } from '../util';
import { errorFromSeries, findRenamedDataQueryReferences, refIdExists } from '../util';
import { CloudDataSourceSelector } from './CloudDataSourceSelector';
import { SmartAlertTypeDetector } from './SmartAlertTypeDetector';
@ -334,7 +334,10 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange }: P
]);
return (
<RuleEditorSection stepNo={2} title="Define query and alert condition">
<RuleEditorSection
stepNo={2}
title={type !== RuleFormType.cloudRecording ? 'Define query and alert condition' : 'Define query'}
>
{/* This is the cloud data source selector */}
{(type === RuleFormType.cloudRecording || type === RuleFormType.cloudAlerting) && (
<CloudDataSourceSelector onChangeCloudDatasource={onChangeCloudDatasource} />
@ -436,7 +439,7 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange }: P
/>
{/* Expression Queries */}
<Text element="h5">Expressions</Text>
<div className={styles.mutedText}>Manipulate data returned from queries with math and other operations</div>
<div className={styles.mutedText}>Manipulate data returned from queries with math and other operations.</div>
<ExpressionsEditor
queries={queries}
panelData={queryPreviewData}

View File

@ -31,9 +31,9 @@ export const annotationLabels: Record<Annotation, string> = {
};
export const annotationDescriptions: Record<Annotation, string> = {
[Annotation.description]: 'Description of what the alert rule does',
[Annotation.summary]: 'Short summary of what happened and why',
[Annotation.runbookURL]: 'Webpage where you keep your runbook for the alert',
[Annotation.description]: 'Description of what the alert rule does.',
[Annotation.summary]: 'Short summary of what happened and why.',
[Annotation.runbookURL]: 'Webpage where you keep your runbook for the alert.',
[Annotation.dashboardUID]: '',
[Annotation.panelID]: '',
[Annotation.alertId]: '',

View File

@ -94,7 +94,7 @@ export function formValuesToRulerRuleDTO(values: RuleFormValues): RulerRuleDTO {
throw new Error(`unexpected rule type: ${type}`);
}
function listifyLabelsOrAnnotations(
export function listifyLabelsOrAnnotations(
item: Labels | Annotations | undefined,
addEmpty: boolean
): Array<{ key: string; value: string }> {
@ -106,7 +106,7 @@ function listifyLabelsOrAnnotations(
}
//make sure default annotations are always shown in order even if empty
function normalizeDefaultAnnotations(annotations: Array<{ key: string; value: string }>) {
export function normalizeDefaultAnnotations(annotations: Array<{ key: string; value: string }>) {
const orderedAnnotations = [...annotations];
const defaultAnnotationKeys = defaultAnnotations.map((annotation) => annotation.key);
@ -179,6 +179,7 @@ export function rulerRuleToFormValues(ruleWithLocation: RuleWithLocation): RuleF
return {
...defaultFormValues,
...alertingRuleValues,
annotations: normalizeDefaultAnnotations(listifyLabelsOrAnnotations(rule.annotations, false)),
type: RuleFormType.cloudAlerting,
dataSourceName: ruleSourceName,
namespace,