Alerting: Only show DMA button when query datasource supports it (#104158)
This commit is contained in:
+6
-2
@@ -78,6 +78,7 @@ import {
|
||||
} from './reducer';
|
||||
import { useAdvancedMode } from './useAdvancedMode';
|
||||
import { useAlertQueryRunner } from './useAlertQueryRunner';
|
||||
import { onlyOneDSInQueries } from './utils';
|
||||
|
||||
interface Props {
|
||||
editingExistingRule: boolean;
|
||||
@@ -474,7 +475,10 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange, mod
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const hasDatasourcesForDataSourceManaged = Boolean(rulesSourcesWithRuler.length);
|
||||
const canSelectDataSourceManaged =
|
||||
onlyOneDSInQueries(queries) &&
|
||||
Boolean(rulesSourcesWithRuler.length) &&
|
||||
queries.some((query) => rulesSourcesWithRuler.some((source) => source.uid === query.datasourceUid));
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -594,7 +598,7 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange, mod
|
||||
</Tooltip>
|
||||
)}
|
||||
{/* We only show Switch for Grafana managed alerts */}
|
||||
{hasDatasourcesForDataSourceManaged && isGrafanaAlertingType && !simplifiedQueryStep && mode === 'edit' && (
|
||||
{canSelectDataSourceManaged && isGrafanaAlertingType && !simplifiedQueryStep && mode === 'edit' && (
|
||||
<>
|
||||
<Divider />
|
||||
<SmartAlertTypeDetector
|
||||
|
||||
+2
-59
@@ -3,72 +3,15 @@ import { useFormContext } from 'react-hook-form';
|
||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||
import { DataSourceJsonData } from '@grafana/schema';
|
||||
import { RadioButtonGroup, Stack, Text } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
import { ExpressionDatasourceUID } from 'app/features/expressions/types';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
import { AlertQuery } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { RuleFormType, RuleFormValues } from '../../../types/rule-form';
|
||||
import { NeedHelpInfo } from '../NeedHelpInfo';
|
||||
|
||||
function getAvailableRuleTypes() {
|
||||
const canCreateGrafanaRules = contextSrv.hasPermission(AccessControlAction.AlertingRuleCreate);
|
||||
const canCreateCloudRules = contextSrv.hasPermission(AccessControlAction.AlertingRuleExternalWrite);
|
||||
const defaultRuleType = canCreateGrafanaRules ? RuleFormType.grafana : RuleFormType.cloudAlerting;
|
||||
import { getCanSwitch } from './utils';
|
||||
|
||||
const enabledRuleTypes: RuleFormType[] = [];
|
||||
if (canCreateGrafanaRules) {
|
||||
enabledRuleTypes.push(RuleFormType.grafana);
|
||||
}
|
||||
if (canCreateCloudRules) {
|
||||
enabledRuleTypes.push(RuleFormType.cloudAlerting, RuleFormType.cloudRecording);
|
||||
}
|
||||
|
||||
return { enabledRuleTypes, defaultRuleType };
|
||||
}
|
||||
|
||||
const onlyOneDSInQueries = (queries: AlertQuery[]) => {
|
||||
return queries.filter((q) => q.datasourceUid !== ExpressionDatasourceUID).length === 1;
|
||||
};
|
||||
const getCanSwitch = ({
|
||||
queries,
|
||||
ruleFormType,
|
||||
rulesSourcesWithRuler,
|
||||
}: {
|
||||
rulesSourcesWithRuler: Array<DataSourceInstanceSettings<DataSourceJsonData>>;
|
||||
queries: AlertQuery[];
|
||||
ruleFormType: RuleFormType | undefined;
|
||||
}) => {
|
||||
// get available rule types
|
||||
const availableRuleTypes = getAvailableRuleTypes();
|
||||
|
||||
// check if we have only one query in queries and if it's a cloud datasource
|
||||
const onlyOneDS = onlyOneDSInQueries(queries);
|
||||
const dataSourceIdFromQueries = queries[0]?.datasourceUid ?? '';
|
||||
const isRecordingRuleType = ruleFormType === RuleFormType.cloudRecording;
|
||||
|
||||
//let's check if we switch to cloud type
|
||||
const canSwitchToCloudRule =
|
||||
!isRecordingRuleType &&
|
||||
onlyOneDS &&
|
||||
rulesSourcesWithRuler.some((dsJsonData) => dsJsonData.uid === dataSourceIdFromQueries);
|
||||
|
||||
const canSwitchToGrafanaRule = !isRecordingRuleType;
|
||||
// check for enabled types
|
||||
const grafanaTypeEnabled = availableRuleTypes.enabledRuleTypes.includes(RuleFormType.grafana);
|
||||
const cloudTypeEnabled = availableRuleTypes.enabledRuleTypes.includes(RuleFormType.cloudAlerting);
|
||||
|
||||
// can we switch to the other type? (cloud or grafana)
|
||||
const canSwitchFromCloudToGrafana =
|
||||
ruleFormType === RuleFormType.cloudAlerting && grafanaTypeEnabled && canSwitchToGrafanaRule;
|
||||
const canSwitchFromGrafanaToCloud =
|
||||
ruleFormType === RuleFormType.grafana && canSwitchToCloudRule && cloudTypeEnabled && canSwitchToCloudRule;
|
||||
|
||||
return canSwitchFromCloudToGrafana || canSwitchFromGrafanaToCloud;
|
||||
};
|
||||
|
||||
export interface SmartAlertTypeDetectorProps {
|
||||
interface SmartAlertTypeDetectorProps {
|
||||
editingExistingRule: boolean;
|
||||
rulesSourcesWithRuler: Array<DataSourceInstanceSettings<DataSourceJsonData>>;
|
||||
queries: AlertQuery[];
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||
import { DataSourceJsonData } from '@grafana/schema/dist/esm/index';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { ExpressionDatasourceUID } from 'app/features/expressions/types';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
import { AlertQuery } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { RuleFormType } from '../../../types/rule-form';
|
||||
|
||||
export const onlyOneDSInQueries = (queries: AlertQuery[]) => {
|
||||
return queries.filter((q) => q.datasourceUid !== ExpressionDatasourceUID).length === 1;
|
||||
};
|
||||
|
||||
function getAvailableRuleTypes() {
|
||||
const canCreateGrafanaRules = contextSrv.hasPermission(AccessControlAction.AlertingRuleCreate);
|
||||
const canCreateCloudRules = contextSrv.hasPermission(AccessControlAction.AlertingRuleExternalWrite);
|
||||
const defaultRuleType = canCreateGrafanaRules ? RuleFormType.grafana : RuleFormType.cloudAlerting;
|
||||
|
||||
const enabledRuleTypes: RuleFormType[] = [];
|
||||
if (canCreateGrafanaRules) {
|
||||
enabledRuleTypes.push(RuleFormType.grafana);
|
||||
}
|
||||
if (canCreateCloudRules) {
|
||||
enabledRuleTypes.push(RuleFormType.cloudAlerting, RuleFormType.cloudRecording);
|
||||
}
|
||||
|
||||
return { enabledRuleTypes, defaultRuleType };
|
||||
}
|
||||
|
||||
export const getCanSwitch = ({
|
||||
queries,
|
||||
ruleFormType,
|
||||
rulesSourcesWithRuler,
|
||||
}: {
|
||||
rulesSourcesWithRuler: Array<DataSourceInstanceSettings<DataSourceJsonData>>;
|
||||
queries: AlertQuery[];
|
||||
ruleFormType: RuleFormType | undefined;
|
||||
}) => {
|
||||
// get available rule types
|
||||
const availableRuleTypes = getAvailableRuleTypes();
|
||||
|
||||
// check if we have only one query in queries and if it's a cloud datasource
|
||||
const onlyOneDS = onlyOneDSInQueries(queries);
|
||||
const dataSourceIdFromQueries = queries[0]?.datasourceUid ?? '';
|
||||
const isRecordingRuleType = ruleFormType === RuleFormType.cloudRecording;
|
||||
|
||||
//let's check if we switch to cloud type
|
||||
const canSwitchToCloudRule =
|
||||
!isRecordingRuleType &&
|
||||
onlyOneDS &&
|
||||
rulesSourcesWithRuler.some((dsJsonData) => dsJsonData.uid === dataSourceIdFromQueries);
|
||||
|
||||
const canSwitchToGrafanaRule = !isRecordingRuleType;
|
||||
// check for enabled types
|
||||
const grafanaTypeEnabled = availableRuleTypes.enabledRuleTypes.includes(RuleFormType.grafana);
|
||||
const cloudTypeEnabled = availableRuleTypes.enabledRuleTypes.includes(RuleFormType.cloudAlerting);
|
||||
|
||||
// can we switch to the other type? (cloud or grafana)
|
||||
const canSwitchFromCloudToGrafana =
|
||||
ruleFormType === RuleFormType.cloudAlerting && grafanaTypeEnabled && canSwitchToGrafanaRule;
|
||||
const canSwitchFromGrafanaToCloud =
|
||||
ruleFormType === RuleFormType.grafana && canSwitchToCloudRule && cloudTypeEnabled && canSwitchToCloudRule;
|
||||
|
||||
return canSwitchFromCloudToGrafana || canSwitchFromGrafanaToCloud;
|
||||
};
|
||||
@@ -75,7 +75,7 @@ export const CloudRules = ({ namespaces, expandAll }: Props) => {
|
||||
<div />
|
||||
)}
|
||||
<Stack gap={1}>
|
||||
{canMigrateToGMA && <MigrateToGMAButton />}
|
||||
{canMigrateToGMA && hasSomeResults && <MigrateToGMAButton />}
|
||||
<CreateRecordingRuleButton />
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user