mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
c6ab1ddb70
commit
19b239fba0
@ -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,
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
|
@ -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'
|
||||
|
@ -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}
|
||||
|
@ -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]: '',
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user