mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: validate alert condition on saving rule (#61958)
* Validate alert condition on saving rule * Remove unused const
This commit is contained in:
parent
bfbc8c3c4f
commit
a20d1eec32
@ -122,7 +122,18 @@ export const AlertRuleForm: FC<Props> = ({ 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<Props> = ({ existing, prefill }) => {
|
||||
<CustomScrollbar autoHeightMin="100%" hideHorizontalTrack={true}>
|
||||
<div className={styles.contentInner}>
|
||||
<AlertRuleNameInput />
|
||||
<QueryAndExpressionsStep editingExistingRule={!!existing} />
|
||||
<QueryAndExpressionsStep editingExistingRule={!!existing} onDataChange={checkAlertCondition} />
|
||||
{showStep2 && (
|
||||
<>
|
||||
{type === RuleFormType.grafana ? (
|
||||
|
@ -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<Props> = ({ editingExistingRule }) => {
|
||||
export const QueryAndExpressionsStep: FC<Props> = ({ editingExistingRule, onDataChange }) => {
|
||||
const runner = useRef(new AlertingQueryRunner());
|
||||
const {
|
||||
setValue,
|
||||
@ -104,6 +105,30 @@ export const QueryAndExpressionsStep: FC<Props> = ({ 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<Props> = ({ 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<Props> = ({ 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 (
|
||||
<RuleEditorSection stepNo={2} title="Set a query and alert condition">
|
||||
@ -189,18 +214,14 @@ export const QueryAndExpressionsStep: FC<Props> = ({ editingExistingRule }) => {
|
||||
onDuplicateQuery={onDuplicateQuery}
|
||||
panelData={panelData}
|
||||
condition={condition}
|
||||
onSetCondition={(refId) => {
|
||||
setValue('condition', refId);
|
||||
}}
|
||||
onSetCondition={handleSetCondition}
|
||||
/>
|
||||
{/* Expression Queries */}
|
||||
<ExpressionsEditor
|
||||
queries={queries}
|
||||
panelData={panelData}
|
||||
condition={condition}
|
||||
onSetCondition={(refId) => {
|
||||
setValue('condition', refId);
|
||||
}}
|
||||
onSetCondition={handleSetCondition}
|
||||
onRemoveExpression={(refId) => {
|
||||
dispatch(removeExpression(refId));
|
||||
}}
|
||||
|
Loading…
Reference in New Issue
Block a user