diff --git a/public/app/features/alerting/unified/components/rule-editor/AlertRuleForm.tsx b/public/app/features/alerting/unified/components/rule-editor/AlertRuleForm.tsx index e250922e515..83b9c87c8bf 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AlertRuleForm.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AlertRuleForm.tsx @@ -122,7 +122,18 @@ export const AlertRuleForm: FC = ({ existing, prefill }) => { const submitState = useUnifiedAlertingSelector((state) => state.ruleForm.saveRule) || initialAsyncRequestState; useCleanup((state) => (state.unifiedAlerting.ruleForm.saveRule = initialAsyncRequestState)); + const [conditionErrorMsg, setConditionErrorMsg] = useState(''); + + const checkAlertCondition = (msg = '') => { + setConditionErrorMsg(msg); + }; + const submit = (values: RuleFormValues, exitOnSave: boolean) => { + if (conditionErrorMsg !== '') { + notifyApp.error(conditionErrorMsg); + return; + } + dispatch( saveRuleFormAction({ values: { @@ -236,7 +247,7 @@ export const AlertRuleForm: FC = ({ existing, prefill }) => {
- + {showStep2 && ( <> {type === RuleFormType.grafana ? ( diff --git a/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx b/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx index dc7ea4c1377..4b426163f84 100644 --- a/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx @@ -16,7 +16,7 @@ import { ExpressionEditor } from '../ExpressionEditor'; import { ExpressionsEditor } from '../ExpressionsEditor'; import { QueryEditor } from '../QueryEditor'; import { RuleEditorSection } from '../RuleEditorSection'; -import { refIdExists } from '../util'; +import { errorFromSeries, refIdExists } from '../util'; import { AlertType } from './AlertType'; import { @@ -35,9 +35,10 @@ import { interface Props { editingExistingRule: boolean; + onDataChange: (error: string) => void; } -export const QueryAndExpressionsStep: FC = ({ editingExistingRule }) => { +export const QueryAndExpressionsStep: FC = ({ editingExistingRule, onDataChange }) => { const runner = useRef(new AlertingQueryRunner()); const { setValue, @@ -104,6 +105,30 @@ export const QueryAndExpressionsStep: FC = ({ editingExistingRule }) => { const emptyQueries = queries.length === 0; + useEffect(() => { + const currentCondition = getValues('condition'); + + if (!currentCondition) { + return; + } + + const error = errorFromSeries(panelData[currentCondition]?.series || []); + onDataChange(error?.message || ''); + }, [panelData, getValues, onDataChange]); + + const handleSetCondition = useCallback( + (refId: string | null) => { + if (!refId) { + return; + } + + runQueries(); //we need to run the queries to know if the condition is valid + + setValue('condition', refId); + }, + [runQueries, setValue] + ); + const onUpdateRefId = useCallback( (oldRefId: string, newRefId: string) => { const newRefIdExists = refIdExists(queries, newRefId); @@ -116,10 +141,10 @@ export const QueryAndExpressionsStep: FC = ({ editingExistingRule }) => { // update condition too if refId was updated if (condition === oldRefId) { - setValue('condition', newRefId); + handleSetCondition(newRefId); } }, - [condition, queries, setValue] + [condition, queries, handleSetCondition] ); const onChangeQueries = useCallback( @@ -147,9 +172,9 @@ export const QueryAndExpressionsStep: FC = ({ editingExistingRule }) => { useEffect(() => { if (!refIdExists(queries, condition)) { const lastRefId = queries.at(-1)?.refId ?? null; - setValue('condition', lastRefId); + handleSetCondition(lastRefId); } - }, [condition, queries, setValue]); + }, [condition, queries, handleSetCondition]); return ( @@ -189,18 +214,14 @@ export const QueryAndExpressionsStep: FC = ({ editingExistingRule }) => { onDuplicateQuery={onDuplicateQuery} panelData={panelData} condition={condition} - onSetCondition={(refId) => { - setValue('condition', refId); - }} + onSetCondition={handleSetCondition} /> {/* Expression Queries */} { - setValue('condition', refId); - }} + onSetCondition={handleSetCondition} onRemoveExpression={(refId) => { dispatch(removeExpression(refId)); }}