Alerting: validate alert condition on saving rule (#61958)

* Validate alert condition on saving rule

* Remove unused const
This commit is contained in:
Virginia Cepeda 2023-01-26 09:27:08 -03:00 committed by GitHub
parent bfbc8c3c4f
commit a20d1eec32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 13 deletions

View File

@ -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 ? (

View File

@ -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));
}}