diff --git a/public/app/features/alerting/unified/components/rule-editor/alert-rule-form/AlertRuleForm.tsx b/public/app/features/alerting/unified/components/rule-editor/alert-rule-form/AlertRuleForm.tsx index 57c385d856e..a22616ff227 100644 --- a/public/app/features/alerting/unified/components/rule-editor/alert-rule-form/AlertRuleForm.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/alert-rule-form/AlertRuleForm.tsx @@ -1,6 +1,6 @@ import { css } from '@emotion/css'; import { useCallback, useEffect, useMemo, useState } from 'react'; -import { FormProvider, SubmitErrorHandler, UseFormWatch, useForm } from 'react-hook-form'; +import { FormProvider, SubmitErrorHandler, useForm, UseFormWatch } from 'react-hook-form'; import { useParams } from 'react-router-dom-v5-compat'; import { GrafanaTheme2 } from '@grafana/data'; @@ -20,12 +20,13 @@ import { isGrafanaRulerRulePaused, isRecordingRuleByType, } from 'app/features/alerting/unified/utils/rules'; +import { isExpressionQuery } from 'app/features/expressions/guards'; import { RuleGroupIdentifier, RuleIdentifier, RuleWithLocation } from 'app/types/unified-alerting'; import { PostableRuleGrafanaRuleDTO, RulerRuleDTO } from 'app/types/unified-alerting-dto'; import { - LogMessages, logInfo, + LogMessages, trackAlertRuleFormCancelled, trackAlertRuleFormError, trackAlertRuleFormSaved, @@ -35,20 +36,21 @@ import { useDeleteRuleFromGroup } from '../../../hooks/ruleGroup/useDeleteRuleFr import { useAddRuleToRuleGroup, useUpdateRuleInRuleGroup } from '../../../hooks/ruleGroup/useUpsertRuleFromRuleGroup'; import { useURLSearchParams } from '../../../hooks/useURLSearchParams'; import { RuleFormType, RuleFormValues } from '../../../types/rule-form'; +import { DataSourceType } from '../../../utils/datasource'; import { DEFAULT_GROUP_EVALUATION_INTERVAL, - MANUAL_ROUTING_KEY, - SIMPLIFIED_QUERY_EDITOR_KEY, formValuesFromExistingRule, formValuesToRulerGrafanaRuleDTO, formValuesToRulerRuleDTO, getDefaultFormValues, getDefaultQueries, ignoreHiddenQueries, + MANUAL_ROUTING_KEY, normalizeDefaultAnnotations, + SIMPLIFIED_QUERY_EDITOR_KEY, } from '../../../utils/rule-form'; -import { fromRulerRule, fromRulerRuleAndRuleGroupIdentifier, stringifyIdentifier } from '../../../utils/rule-id'; import * as ruleId from '../../../utils/rule-id'; +import { fromRulerRule, fromRulerRuleAndRuleGroupIdentifier, stringifyIdentifier } from '../../../utils/rule-id'; import { createRelativeUrl } from '../../../utils/url'; import { GrafanaRuleExporter } from '../../export/GrafanaRuleExporter'; import { AlertRuleNameAndMetric } from '../AlertRuleNameInput'; @@ -384,14 +386,16 @@ function formValuesFromQueryParams(ruleDefinition: string, type: RuleFormType): }; } - return ignoreHiddenQueries({ - ...getDefaultFormValues(), - ...ruleFromQueryParams, - annotations: normalizeDefaultAnnotations(ruleFromQueryParams.annotations ?? []), - queries: ruleFromQueryParams.queries ?? getDefaultQueries(), - type: type || RuleFormType.grafana, - evaluateEvery: DEFAULT_GROUP_EVALUATION_INTERVAL, - }); + return setInstantOrRange( + ignoreHiddenQueries({ + ...getDefaultFormValues(), + ...ruleFromQueryParams, + annotations: normalizeDefaultAnnotations(ruleFromQueryParams.annotations ?? []), + queries: ruleFromQueryParams.queries ?? getDefaultQueries(), + type: type || RuleFormType.grafana, + evaluateEvery: DEFAULT_GROUP_EVALUATION_INTERVAL, + }) + ); } function formValuesFromPrefill(rule: Partial): RuleFormValues { @@ -401,6 +405,31 @@ function formValuesFromPrefill(rule: Partial): RuleFormValues { }); } +function setInstantOrRange(values: RuleFormValues): RuleFormValues { + return { + ...values, + queries: values.queries?.map((query) => { + if (isExpressionQuery(query.model)) { + return query; + } + // data query + const defaultToInstant = + query.model.datasource?.type === DataSourceType.Loki || + query.model.datasource?.type === DataSourceType.Prometheus; + const isInstant = + 'instant' in query.model && query.model.instant !== undefined ? query.model.instant : defaultToInstant; + return { + ...query, + model: { + ...query.model, + instant: isInstant, + range: !isInstant, // we cannot have both instant and range queries in alerting + }, + }; + }), + }; +} + function storeInLocalStorageValues(values: RuleFormValues) { if (values.manualRouting) { localStorage.setItem(MANUAL_ROUTING_KEY, 'true'); diff --git a/public/app/types/unified-alerting-dto.ts b/public/app/types/unified-alerting-dto.ts index 0c379f929b1..bf149896c12 100644 --- a/public/app/types/unified-alerting-dto.ts +++ b/public/app/types/unified-alerting-dto.ts @@ -201,6 +201,8 @@ export interface AlertDataQuery extends DataQuery { maxDataPoints?: number; intervalMs?: number; expression?: string; + instant?: boolean; + range?: boolean; } export interface AlertQuery {