diff --git a/static/app/views/alerts/list/rules/alertRuleStatus.tsx b/static/app/views/alerts/list/rules/alertRuleStatus.tsx index e2c611038ccb2e..4af320f34067c1 100644 --- a/static/app/views/alerts/list/rules/alertRuleStatus.tsx +++ b/static/app/views/alerts/list/rules/alertRuleStatus.tsx @@ -69,6 +69,9 @@ export default function AlertRuleStatus({rule}: Props) { ? t('Above') : t('Below'); + // Anomaly detection alerts have different labels + const statusLabel = activeIncident ? t('Bad') : t('Good'); + if (activeIncident) { iconColor = trigger?.label === AlertRuleTriggerType.CRITICAL @@ -86,20 +89,26 @@ export default function AlertRuleStatus({rule}: Props) { return ( - - - {`${thresholdTypeText} ${ - rule.latestIncident || (!rule.latestIncident && !resolvedTrigger) - ? trigger?.alertThreshold?.toLocaleString() - : resolvedTrigger?.toLocaleString() - }`} - {getThresholdUnits( - rule.aggregate, - rule.comparisonDelta - ? AlertRuleComparisonType.CHANGE - : AlertRuleComparisonType.COUNT - )} - + {rule.detectionType !== AlertRuleComparisonType.DYNAMIC && ( + + )} + {rule.detectionType !== AlertRuleComparisonType.DYNAMIC ? ( + + {`${thresholdTypeText} ${ + rule.latestIncident || (!rule.latestIncident && !resolvedTrigger) + ? trigger?.alertThreshold?.toLocaleString() + : resolvedTrigger?.toLocaleString() + }`} + {getThresholdUnits( + rule.aggregate, + rule.comparisonDelta + ? AlertRuleComparisonType.CHANGE + : AlertRuleComparisonType.COUNT + )} + + ) : ( + {statusLabel} + )} ); } diff --git a/static/app/views/alerts/rules/metric/constants.tsx b/static/app/views/alerts/rules/metric/constants.tsx index 55b89617864df4..faa94df601f961 100644 --- a/static/app/views/alerts/rules/metric/constants.tsx +++ b/static/app/views/alerts/rules/metric/constants.tsx @@ -172,7 +172,7 @@ export function createDefaultRule( environment: null, resolveThreshold: '', thresholdType: AlertRuleThresholdType.ABOVE, - detectionType: AlertRuleComparisonType.COUNT, + detectionType: AlertRuleComparisonType.STATIC, ...defaultRuleOptions, }; } diff --git a/static/app/views/alerts/rules/metric/details/sidebar.tsx b/static/app/views/alerts/rules/metric/details/sidebar.tsx index 16cee54e67b558..7b0a63d12f2701 100644 --- a/static/app/views/alerts/rules/metric/details/sidebar.tsx +++ b/static/app/views/alerts/rules/metric/details/sidebar.tsx @@ -20,6 +20,7 @@ import {capitalize} from 'sentry/utils/string/capitalize'; import {COMPARISON_DELTA_OPTIONS} from 'sentry/views/alerts/rules/metric/constants'; import type {Action, MetricRule} from 'sentry/views/alerts/rules/metric/types'; import { + AlertRuleComparisonType, AlertRuleThresholdType, AlertRuleTriggerType, } from 'sentry/views/alerts/rules/metric/types'; @@ -90,11 +91,13 @@ function TriggerDescription({ ).label, } ) - : tct('[metric] is [condition] in [timeWindow]', { - metric: metricName, - condition: `${thresholdTypeText} ${threshold}`, - timeWindow, - }); + : rule.detectionType === AlertRuleComparisonType.DYNAMIC + ? 'Dynamic threshold is reached' + : tct('[metric] is [condition] in [timeWindow]', { + metric: metricName, + condition: `${thresholdTypeText} ${threshold}`, + timeWindow, + }); return ( @@ -260,6 +263,30 @@ export function MetricDetailsSidebar({ teamActor ? : t('Unassigned') } /> + {rule.detectionType === AlertRuleComparisonType.DYNAMIC && ( + + )} + {rule.detectionType === AlertRuleComparisonType.DYNAMIC && ( + + {rule.thresholdType === AlertRuleThresholdType.ABOVE + ? 'Above threshold' + : rule.thresholdType === AlertRuleThresholdType.ABOVE_AND_BELOW + ? 'Above and below threshold' + : 'Below threshold'} + + } + /> + )} diff --git a/static/app/views/alerts/rules/metric/ruleForm.tsx b/static/app/views/alerts/rules/metric/ruleForm.tsx index 52f78c3963a06b..b0bb7d2d304c9a 100644 --- a/static/app/views/alerts/rules/metric/ruleForm.tsx +++ b/static/app/views/alerts/rules/metric/ruleForm.tsx @@ -938,7 +938,7 @@ class RuleFormContainer extends DeprecatedAsyncComponent { ? this.state.sensitivity || AlertRuleSensitivity.MEDIUM : undefined; const seasonality = - value === AlertRuleComparisonType.DYNAMIC ? AlertRuleSeasonality.AUTO : undefined; // TODO: replace "auto" with the correct constant + value === AlertRuleComparisonType.DYNAMIC ? AlertRuleSeasonality.AUTO : undefined; this.setState({ comparisonType: value, comparisonDelta, diff --git a/static/app/views/alerts/rules/metric/types.tsx b/static/app/views/alerts/rules/metric/types.tsx index dce46532a68556..3bb2c0fc95f260 100644 --- a/static/app/views/alerts/rules/metric/types.tsx +++ b/static/app/views/alerts/rules/metric/types.tsx @@ -26,6 +26,7 @@ export enum AlertRuleComparisonType { CHANGE = 'change', PERCENT = 'percent', DYNAMIC = 'dynamic', + STATIC = 'static', } export enum Dataset {