Alerting: Move logic for simple mode in QueryAndExpressionsStep to a separate hook (#94709)
* Move logic for simple mode in QueryAndExpressionsStep to a separate hook and add tests * remove unnecessary jest.clearAllMocks
This commit is contained in:
+9
-21
@@ -3,7 +3,7 @@ import { cloneDeep } from 'lodash';
|
||||
import { useCallback, useEffect, useMemo, useReducer, useState } from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
|
||||
import { getDefaultRelativeTimeRange, GrafanaTheme2, ReducerID } from '@grafana/data';
|
||||
import { getDefaultRelativeTimeRange, GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { config, getDataSourceSrv } from '@grafana/runtime';
|
||||
import {
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
} from '@grafana/ui';
|
||||
import { Text } from '@grafana/ui/src/components/Text/Text';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { EvalFunction } from 'app/features/alerting/state/alertDef';
|
||||
import { isExpressionQuery } from 'app/features/expressions/guards';
|
||||
import {
|
||||
ExpressionDatasourceUID,
|
||||
@@ -60,7 +59,6 @@ import {
|
||||
SIMPLE_CONDITION_QUERY_ID,
|
||||
SIMPLE_CONDITION_REDUCER_ID,
|
||||
SIMPLE_CONDITION_THRESHOLD_ID,
|
||||
SimpleCondition,
|
||||
SimpleConditionEditor,
|
||||
} from './SimpleCondition';
|
||||
import { SmartAlertTypeDetector } from './SmartAlertTypeDetector';
|
||||
@@ -82,6 +80,7 @@ import {
|
||||
updateExpressionTimeRange,
|
||||
updateExpressionType,
|
||||
} from './reducer';
|
||||
import { useAdvancedMode } from './useAdvancedMode';
|
||||
import { useAlertQueryRunner } from './useAlertQueryRunner';
|
||||
|
||||
export function areQueriesTransformableToSimpleCondition(
|
||||
@@ -168,25 +167,14 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange }: P
|
||||
const isGrafanaAlertingType = isGrafanaAlertingRuleByType(type);
|
||||
const isRecordingRuleType = isCloudRecordingRuleByType(type);
|
||||
const isCloudAlertRuleType = isCloudAlertingRuleByType(type);
|
||||
const queryParamsAreTransformable = areQueriesTransformableToSimpleCondition(dataQueries, expressionQueries);
|
||||
|
||||
const isAdvancedMode =
|
||||
Boolean(editorSettings?.simplifiedQueryEditor) === false ||
|
||||
!isGrafanaAlertingType ||
|
||||
(isNewFromQueryParams && !queryParamsAreTransformable);
|
||||
|
||||
const [showResetModeModal, setShowResetModal] = useState(false);
|
||||
|
||||
const [simpleCondition, setSimpleCondition] = useState<SimpleCondition>(
|
||||
isGrafanaAlertingType && areQueriesTransformableToSimpleCondition(dataQueries, expressionQueries)
|
||||
? getSimpleConditionFromExpressions(expressionQueries)
|
||||
: {
|
||||
whenField: ReducerID.last,
|
||||
evaluator: {
|
||||
params: [0],
|
||||
type: EvalFunction.IsAbove,
|
||||
},
|
||||
}
|
||||
const { isAdvancedMode, simpleCondition, setSimpleCondition } = useAdvancedMode(
|
||||
editorSettings,
|
||||
isGrafanaAlertingType,
|
||||
isNewFromQueryParams,
|
||||
dataQueries,
|
||||
expressionQueries
|
||||
);
|
||||
|
||||
// If we switch to simple mode we need to update the simple condition with the data in the queries reducer
|
||||
@@ -194,7 +182,7 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange }: P
|
||||
if (!isAdvancedMode && isGrafanaAlertingType) {
|
||||
setSimpleCondition(getSimpleConditionFromExpressions(expressionQueries));
|
||||
}
|
||||
}, [isAdvancedMode, expressionQueries, isGrafanaAlertingType]);
|
||||
}, [isAdvancedMode, expressionQueries, isGrafanaAlertingType, setSimpleCondition]);
|
||||
|
||||
const dispatchReduxAction = useDispatch();
|
||||
useEffect(() => {
|
||||
|
||||
+2
-33
@@ -3,42 +3,11 @@
|
||||
import { produce } from 'immer';
|
||||
|
||||
import { EvalFunction } from 'app/features/alerting/state/alertDef';
|
||||
import { ExpressionQuery, ExpressionQueryType, ReducerMode } from 'app/features/expressions/types';
|
||||
import { dataQuery, reduceExpression, thresholdExpression } from 'app/features/alerting/unified/mocks';
|
||||
import { ExpressionQuery, ReducerMode } from 'app/features/expressions/types';
|
||||
import { AlertDataQuery, AlertQuery } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { areQueriesTransformableToSimpleCondition } from '../QueryAndExpressionsStep';
|
||||
import {
|
||||
SIMPLE_CONDITION_QUERY_ID,
|
||||
SIMPLE_CONDITION_REDUCER_ID,
|
||||
SIMPLE_CONDITION_THRESHOLD_ID,
|
||||
} from '../SimpleCondition';
|
||||
|
||||
const dataQuery: AlertQuery<AlertDataQuery | ExpressionQuery> = {
|
||||
refId: SIMPLE_CONDITION_QUERY_ID,
|
||||
datasourceUid: 'abc123',
|
||||
queryType: '',
|
||||
model: { refId: SIMPLE_CONDITION_QUERY_ID },
|
||||
};
|
||||
|
||||
const reduceExpression: AlertQuery<ExpressionQuery> = {
|
||||
refId: SIMPLE_CONDITION_REDUCER_ID,
|
||||
queryType: 'expression',
|
||||
datasourceUid: '__expr__',
|
||||
model: {
|
||||
type: ExpressionQueryType.reduce,
|
||||
refId: SIMPLE_CONDITION_REDUCER_ID,
|
||||
settings: { mode: ReducerMode.Strict },
|
||||
},
|
||||
};
|
||||
const thresholdExpression: AlertQuery<ExpressionQuery> = {
|
||||
refId: SIMPLE_CONDITION_THRESHOLD_ID,
|
||||
queryType: 'expression',
|
||||
datasourceUid: '__expr__',
|
||||
model: {
|
||||
type: ExpressionQueryType.threshold,
|
||||
refId: SIMPLE_CONDITION_THRESHOLD_ID,
|
||||
},
|
||||
};
|
||||
|
||||
const expressionQueries: Array<AlertQuery<ExpressionQuery>> = [reduceExpression, thresholdExpression];
|
||||
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
import { produce } from 'immer';
|
||||
|
||||
import { dataQuery, reduceExpression, thresholdExpression } from '../../../mocks';
|
||||
|
||||
import { determineAdvancedMode } from './useAdvancedMode';
|
||||
|
||||
const dataQueries = [dataQuery];
|
||||
const expressionQueries = [reduceExpression, thresholdExpression];
|
||||
|
||||
describe('determineAdvancedMode', () => {
|
||||
it('should return true if simplifiedQueryEditor is false', () => {
|
||||
const editorSettings = { simplifiedQueryEditor: false };
|
||||
const isGrafanaAlertingType = true;
|
||||
const isNewFromQueryParams = false;
|
||||
|
||||
const result = determineAdvancedMode(
|
||||
editorSettings,
|
||||
isGrafanaAlertingType,
|
||||
isNewFromQueryParams,
|
||||
dataQueries,
|
||||
expressionQueries
|
||||
);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true if isGrafanaAlertingType is false', () => {
|
||||
const editorSettings = { simplifiedQueryEditor: true };
|
||||
const isGrafanaAlertingType = false;
|
||||
const isNewFromQueryParams = false;
|
||||
|
||||
const result = determineAdvancedMode(
|
||||
editorSettings,
|
||||
isGrafanaAlertingType,
|
||||
isNewFromQueryParams,
|
||||
dataQueries,
|
||||
expressionQueries
|
||||
);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true if isNewFromQueryParams is true and queries are not transformable', () => {
|
||||
const editorSettings = { simplifiedQueryEditor: true };
|
||||
const isGrafanaAlertingType = true;
|
||||
const isNewFromQueryParams = true;
|
||||
|
||||
const newQuery = produce(dataQuery, (draft) => {
|
||||
draft.refId = 'whatever';
|
||||
});
|
||||
|
||||
const result = determineAdvancedMode(
|
||||
editorSettings,
|
||||
isGrafanaAlertingType,
|
||||
isNewFromQueryParams,
|
||||
[newQuery],
|
||||
expressionQueries
|
||||
);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if all conditions are false', () => {
|
||||
const editorSettings = { simplifiedQueryEditor: true };
|
||||
const isGrafanaAlertingType = true;
|
||||
const isNewFromQueryParams = false;
|
||||
|
||||
const result = determineAdvancedMode(
|
||||
editorSettings,
|
||||
isGrafanaAlertingType,
|
||||
isNewFromQueryParams,
|
||||
dataQueries,
|
||||
expressionQueries
|
||||
);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { ReducerID } from '@grafana/data';
|
||||
import { EvalFunction } from 'app/features/alerting/state/alertDef';
|
||||
import { ExpressionQuery } from 'app/features/expressions/types';
|
||||
import { AlertDataQuery, AlertQuery } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { SimplifiedEditor } from '../../../types/rule-form';
|
||||
|
||||
import { areQueriesTransformableToSimpleCondition } from './QueryAndExpressionsStep';
|
||||
import { getSimpleConditionFromExpressions, SimpleCondition } from './SimpleCondition';
|
||||
|
||||
function initializeSimpleCondition(
|
||||
isGrafanaAlertingType: boolean,
|
||||
dataQueries: Array<AlertQuery<AlertDataQuery>>,
|
||||
expressionQueries: Array<AlertQuery<ExpressionQuery>>
|
||||
) {
|
||||
if (isGrafanaAlertingType && areQueriesTransformableToSimpleCondition(dataQueries, expressionQueries)) {
|
||||
return getSimpleConditionFromExpressions(expressionQueries);
|
||||
} else {
|
||||
return {
|
||||
whenField: ReducerID.last,
|
||||
evaluator: {
|
||||
params: [0],
|
||||
type: EvalFunction.IsAbove,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
export function determineAdvancedMode(
|
||||
editorSettings: SimplifiedEditor | undefined,
|
||||
isGrafanaAlertingType: boolean,
|
||||
isNewFromQueryParams: boolean,
|
||||
dataQueries: Array<AlertQuery<ExpressionQuery | AlertDataQuery>>,
|
||||
expressionQueries: Array<AlertQuery<ExpressionQuery>>
|
||||
) {
|
||||
const queryParamsAreTransformable = areQueriesTransformableToSimpleCondition(dataQueries, expressionQueries);
|
||||
return (
|
||||
Boolean(editorSettings?.simplifiedQueryEditor) === false ||
|
||||
!isGrafanaAlertingType ||
|
||||
(isNewFromQueryParams && !queryParamsAreTransformable)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
This hook is used mantain the state of the advanced mode, and the simple condition,
|
||||
depending on the editor settings, the alert type, and the queries.
|
||||
*/
|
||||
export const useAdvancedMode = (
|
||||
editorSettings: SimplifiedEditor | undefined,
|
||||
isGrafanaAlertingType: boolean,
|
||||
isNewFromQueryParams: boolean,
|
||||
dataQueries: Array<AlertQuery<ExpressionQuery | AlertDataQuery>>,
|
||||
expressionQueries: Array<AlertQuery<ExpressionQuery>>
|
||||
) => {
|
||||
const isAdvancedMode = determineAdvancedMode(
|
||||
editorSettings,
|
||||
isGrafanaAlertingType,
|
||||
isNewFromQueryParams,
|
||||
dataQueries,
|
||||
expressionQueries
|
||||
);
|
||||
|
||||
const [simpleCondition, setSimpleCondition] = useState<SimpleCondition>(
|
||||
initializeSimpleCondition(isGrafanaAlertingType, dataQueries, expressionQueries)
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAdvancedMode && isGrafanaAlertingType) {
|
||||
setSimpleCondition(getSimpleConditionFromExpressions(expressionQueries));
|
||||
}
|
||||
}, [isAdvancedMode, expressionQueries, isGrafanaAlertingType]);
|
||||
|
||||
return { isAdvancedMode, simpleCondition, setSimpleCondition };
|
||||
};
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
DataSourceRef,
|
||||
PluginExtensionLink,
|
||||
PluginExtensionTypes,
|
||||
ReducerID,
|
||||
ScopedVars,
|
||||
TestDataSourceResponse,
|
||||
} from '@grafana/data';
|
||||
@@ -19,6 +20,7 @@ import { DataSourceSrv, GetDataSourceListFilters, config } from '@grafana/runtim
|
||||
import { defaultDashboard } from '@grafana/schema';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { MOCK_GRAFANA_ALERT_RULE_TITLE } from 'app/features/alerting/unified/mocks/server/handlers/grafanaRuler';
|
||||
import { ExpressionQuery, ExpressionQueryType, ReducerMode } from 'app/features/expressions/types';
|
||||
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import {
|
||||
AlertManagerCortexConfig,
|
||||
@@ -45,6 +47,7 @@ import {
|
||||
RuleWithLocation,
|
||||
} from 'app/types/unified-alerting';
|
||||
import {
|
||||
AlertDataQuery,
|
||||
AlertQuery,
|
||||
GrafanaAlertState,
|
||||
GrafanaAlertStateDecision,
|
||||
@@ -61,6 +64,11 @@ import {
|
||||
|
||||
import { DashboardSearchItem, DashboardSearchItemType } from '../../search/types';
|
||||
|
||||
import {
|
||||
SIMPLE_CONDITION_QUERY_ID,
|
||||
SIMPLE_CONDITION_REDUCER_ID,
|
||||
SIMPLE_CONDITION_THRESHOLD_ID,
|
||||
} from './components/rule-editor/query-and-alert-condition/SimpleCondition';
|
||||
import { parsePromQLStyleMatcherLooseSafe } from './utils/matchers';
|
||||
|
||||
let nextDataSourceId = 1;
|
||||
@@ -845,3 +853,31 @@ export function mockDashboardDto(
|
||||
meta: { ...meta },
|
||||
};
|
||||
}
|
||||
|
||||
export const dataQuery: AlertQuery<AlertDataQuery | ExpressionQuery> = {
|
||||
refId: SIMPLE_CONDITION_QUERY_ID,
|
||||
datasourceUid: 'abc123',
|
||||
queryType: '',
|
||||
model: { refId: SIMPLE_CONDITION_QUERY_ID },
|
||||
};
|
||||
|
||||
export const reduceExpression: AlertQuery<ExpressionQuery> = {
|
||||
refId: SIMPLE_CONDITION_REDUCER_ID,
|
||||
queryType: 'expression',
|
||||
datasourceUid: '__expr__',
|
||||
model: {
|
||||
type: ExpressionQueryType.reduce,
|
||||
refId: SIMPLE_CONDITION_REDUCER_ID,
|
||||
settings: { mode: ReducerMode.Strict },
|
||||
reducer: ReducerID.last,
|
||||
},
|
||||
};
|
||||
export const thresholdExpression: AlertQuery<ExpressionQuery> = {
|
||||
refId: SIMPLE_CONDITION_THRESHOLD_ID,
|
||||
queryType: 'expression',
|
||||
datasourceUid: '__expr__',
|
||||
model: {
|
||||
type: ExpressionQueryType.threshold,
|
||||
refId: SIMPLE_CONDITION_THRESHOLD_ID,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user