Skip to content

Commit f10b7e2

Browse files
authored
fix(spans-migration): Disable duplication of transaction alerts (#96432)
As part of the transactions dataset deprecation, we want to also disable duplication for transactions alerts. Currently the deprecation logic is under the `performance-transaction-deprecation-alerts` flag. This is in addition to the disabling logic in the form when editing transaction widgets. Closes [ENG-4641](https://linear.app/getsentry/issue/ENG-4641/prevent-duplicating-transaction-alerts)
1 parent 7c0dcf4 commit f10b7e2

File tree

3 files changed

+97
-4
lines changed

3 files changed

+97
-4
lines changed

static/app/views/alerts/list/rules/row.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ import {UptimeMonitorMode} from 'sentry/views/alerts/rules/uptime/types';
3535
import type {CombinedAlerts} from 'sentry/views/alerts/types';
3636
import {CombinedAlertType} from 'sentry/views/alerts/types';
3737
import {isIssueAlert} from 'sentry/views/alerts/utils';
38+
import {DEPRECATED_TRANSACTION_ALERTS} from 'sentry/views/alerts/wizard/options';
39+
import {getAlertTypeFromAggregateDataset} from 'sentry/views/alerts/wizard/utils';
40+
import {deprecateTransactionAlerts} from 'sentry/views/insights/common/utils/hasEAPAlerts';
3841

3942
type Props = {
4043
hasEditAccess: boolean;
@@ -67,6 +70,21 @@ function RuleListRow({
6770
? rule.project.slug
6871
: rule.projects[0]!;
6972

73+
const ruleType =
74+
rule &&
75+
rule.type === CombinedAlertType.METRIC &&
76+
getAlertTypeFromAggregateDataset({
77+
aggregate: rule.aggregate,
78+
dataset: rule.dataset,
79+
eventTypes: rule.eventTypes,
80+
organization,
81+
});
82+
83+
const deprecateTransactionsAlerts =
84+
deprecateTransactionAlerts(organization) &&
85+
ruleType &&
86+
DEPRECATED_TRANSACTION_ALERTS.includes(ruleType);
87+
7088
const editKey = {
7189
[CombinedAlertType.ISSUE]: 'rules',
7290
[CombinedAlertType.METRIC]: 'metric-rules',
@@ -107,7 +125,9 @@ function RuleListRow({
107125

108126
const activeActions = {
109127
[CombinedAlertType.ISSUE]: ['edit', 'duplicate', 'delete'],
110-
[CombinedAlertType.METRIC]: ['edit', 'duplicate', 'delete'],
128+
[CombinedAlertType.METRIC]: deprecateTransactionsAlerts
129+
? ['edit', 'delete']
130+
: ['edit', 'duplicate', 'delete'],
111131
[CombinedAlertType.UPTIME]: ['edit', 'delete'],
112132
[CombinedAlertType.CRONS]: ['edit', 'delete'],
113133
};

static/app/views/alerts/rules/metric/details/header.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@ import type {Project} from 'sentry/types/project';
1515
import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
1616
import type {MetricRule} from 'sentry/views/alerts/rules/metric/types';
1717
import {getAlertRuleActionCategory} from 'sentry/views/alerts/rules/utils';
18-
import {AlertWizardAlertNames} from 'sentry/views/alerts/wizard/options';
18+
import {
19+
AlertWizardAlertNames,
20+
DEPRECATED_TRANSACTION_ALERTS,
21+
} from 'sentry/views/alerts/wizard/options';
1922
import {getAlertTypeFromAggregateDataset} from 'sentry/views/alerts/wizard/utils';
23+
import {
24+
deprecateTransactionAlerts,
25+
hasEAPAlerts,
26+
} from 'sentry/views/insights/common/utils/hasEAPAlerts';
2027

2128
type Props = {
2229
hasMetricRuleDetailsError: boolean;
@@ -70,6 +77,11 @@ function DetailsHeader({
7077
organization,
7178
});
7279

80+
const deprecateTransactionsAlerts =
81+
deprecateTransactionAlerts(organization) &&
82+
ruleType &&
83+
DEPRECATED_TRANSACTION_ALERTS.includes(ruleType);
84+
7385
return (
7486
<Layout.Header>
7587
<Layout.HeaderContent>
@@ -118,7 +130,21 @@ function DetailsHeader({
118130
)}
119131
</Access>
120132
)}
121-
<LinkButton size="sm" icon={<IconCopy />} to={duplicateLink}>
133+
<LinkButton
134+
size="sm"
135+
icon={<IconCopy />}
136+
to={duplicateLink}
137+
disabled={deprecateTransactionsAlerts}
138+
title={
139+
deprecateTransactionsAlerts
140+
? hasEAPAlerts(organization)
141+
? t(
142+
'Transaction alerts are being deprecated. Please create Span alerts instead.'
143+
)
144+
: t('Transaction alerts are being deprecated.')
145+
: undefined
146+
}
147+
>
122148
{t('Duplicate')}
123149
</LinkButton>
124150
<LinkButton size="sm" icon={<IconEdit />} to={settingsLink}>

static/app/views/alerts/rules/metric/details/index.spec.tsx

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
1010
import ProjectsStore from 'sentry/stores/projectsStore';
1111
import {trackAnalytics} from 'sentry/utils/analytics';
1212
import MetricAlertDetails from 'sentry/views/alerts/rules/metric/details';
13-
import {Dataset} from 'sentry/views/alerts/rules/metric/types';
13+
import {Dataset, EventTypes} from 'sentry/views/alerts/rules/metric/types';
1414

1515
jest.mock('sentry/utils/analytics');
1616

@@ -243,4 +243,51 @@ describe('MetricAlertDetails', () => {
243243
expect(button).toBeEnabled();
244244
expect(button).toHaveAttribute('href', expect.stringContaining('dataset=errors'));
245245
});
246+
247+
it('disables duplicate button if deprecation flag is on', async () => {
248+
const {organization, routerProps} = initializeOrg({
249+
organization: {
250+
features: ['discover-basic', 'performance-transaction-deprecation-alerts'],
251+
},
252+
});
253+
const rule = MetricRuleFixture({
254+
projects: [project.slug],
255+
dataset: Dataset.TRANSACTIONS,
256+
eventTypes: [EventTypes.TRANSACTION],
257+
});
258+
259+
MockApiClient.addMockResponse({
260+
url: '/organizations/org-slug/events/',
261+
body: {
262+
data: [],
263+
},
264+
});
265+
266+
MockApiClient.addMockResponse({
267+
url: `/organizations/org-slug/alert-rules/${rule.id}/`,
268+
body: rule,
269+
});
270+
MockApiClient.addMockResponse({
271+
url: `/organizations/org-slug/incidents/`,
272+
body: [],
273+
});
274+
275+
render(
276+
<MetricAlertDetails
277+
organization={organization}
278+
{...routerProps}
279+
params={{ruleId: rule.id}}
280+
/>,
281+
{
282+
organization,
283+
}
284+
);
285+
286+
expect(await screen.findByText(rule.name)).toBeInTheDocument();
287+
288+
expect(await screen.findByRole('button', {name: 'Duplicate'})).toHaveAttribute(
289+
'aria-disabled',
290+
'true'
291+
);
292+
});
246293
});

0 commit comments

Comments
 (0)