Skip to content

Commit a1c8bf7

Browse files
authored
feat(billing): Update Spend Notifications for Seer (#92069)
Consolidate spend notifications for Seer categories into one notification option.
1 parent 9864199 commit a1c8bf7

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

static/app/views/settings/account/notifications/fields2.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ExternalLink from 'sentry/components/links/externalLink';
66
import QuestionTooltip from 'sentry/components/questionTooltip';
77
import {DATA_CATEGORY_INFO} from 'sentry/constants';
88
import {t, tct} from 'sentry/locale';
9+
import {DataCategoryExact} from 'sentry/types/core';
910
import {getPricingDocsLinkForEventType} from 'sentry/views/settings/account/notifications/utils';
1011

1112
export const NOTIFICATION_SETTING_FIELDS = {
@@ -143,7 +144,13 @@ export const NOTIFICATION_SETTING_FIELDS = {
143144
} satisfies Record<string, Field>;
144145

145146
const CATEGORY_QUOTA_FIELDS = Object.values(DATA_CATEGORY_INFO)
146-
.filter(categoryInfo => categoryInfo.isBilledCategory)
147+
.filter(
148+
categoryInfo =>
149+
categoryInfo.isBilledCategory &&
150+
// Exclude Seer categories as they will be handled by a combined quotaSeerBudget field
151+
categoryInfo.name !== DataCategoryExact.SEER_AUTOFIX &&
152+
categoryInfo.name !== DataCategoryExact.SEER_SCANNER
153+
)
147154
.map(categoryInfo => {
148155
return {
149156
name: 'quota' + upperFirst(categoryInfo.plural),
@@ -164,6 +171,24 @@ const CATEGORY_QUOTA_FIELDS = Object.values(DATA_CATEGORY_INFO)
164171
};
165172
});
166173

174+
// Define the combined Seer budget field
175+
const quotaSeerBudgetField = {
176+
// This maps to NotificationSettingEnum.QUOTA_SEER_BUDGET
177+
name: 'quotaSeerBudget',
178+
label: t('Seer Budget'),
179+
help: tct(`Receive notifications for your Seer budget. [learnMore:Learn more]`, {
180+
learnMore: (
181+
<ExternalLink
182+
href={getPricingDocsLinkForEventType(DataCategoryExact.SEER_AUTOFIX)}
183+
/>
184+
),
185+
}),
186+
choices: [
187+
['always', t('On')],
188+
['never', t('Off')],
189+
] as const,
190+
};
191+
167192
// TODO(isabella): Once spend vis notifs are GA, remove this
168193
// partial field definition for quota sub-categories
169194
export const QUOTA_FIELDS = [
@@ -177,6 +202,7 @@ export const QUOTA_FIELDS = [
177202
] as const,
178203
},
179204
...CATEGORY_QUOTA_FIELDS,
205+
quotaSeerBudgetField,
180206
{
181207
name: 'quotaSpendAllocations',
182208
label: (

static/app/views/settings/account/notifications/notificationSettingsByType.spec.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,7 @@ describe('NotificationSettingsByType', function () {
342342
screen.getByText('Continuous Profile Hours', {exact: true})
343343
).toBeInTheDocument();
344344
expect(screen.getByText('UI Profile Hours', {exact: true})).toBeInTheDocument();
345-
expect(screen.getByText('Issue Fixes')).toBeInTheDocument();
346-
expect(screen.getByText('Issue Scans')).toBeInTheDocument();
345+
expect(screen.getByText('Seer Budget')).toBeInTheDocument();
347346
expect(screen.queryByText('Transactions')).not.toBeInTheDocument();
348347

349348
const editSettingMock = MockApiClient.addMockResponse({
@@ -402,8 +401,7 @@ describe('NotificationSettingsByType', function () {
402401
screen.getByText('Continuous Profile Hours', {exact: true})
403402
).toBeInTheDocument();
404403
expect(screen.getByText('UI Profile Hours', {exact: true})).toBeInTheDocument();
405-
expect(screen.getByText('Issue Fixes')).toBeInTheDocument();
406-
expect(screen.getByText('Issue Scans')).toBeInTheDocument();
404+
expect(screen.getByText('Seer Budget')).toBeInTheDocument();
407405
});
408406

409407
it('spend notifications on org with am1 org only', async function () {
@@ -433,8 +431,7 @@ describe('NotificationSettingsByType', function () {
433431
).not.toBeInTheDocument();
434432
expect(screen.queryByText('UI Profile Hours', {exact: true})).not.toBeInTheDocument();
435433
expect(screen.queryByText('Spans')).not.toBeInTheDocument();
436-
expect(screen.getByText('Issue Fixes')).toBeInTheDocument();
437-
expect(screen.getByText('Issue Scans')).toBeInTheDocument();
434+
expect(screen.getByText('Seer Budget')).toBeInTheDocument();
438435
});
439436

440437
it('spend notifications on org with am3 without spend visibility notifications', async function () {
@@ -459,8 +456,7 @@ describe('NotificationSettingsByType', function () {
459456
).toBeInTheDocument();
460457
expect(screen.getByText('UI Profile Hours', {exact: true})).toBeInTheDocument();
461458
expect(screen.queryByText('Transactions')).not.toBeInTheDocument();
462-
expect(screen.getByText('Issue Fixes')).toBeInTheDocument();
463-
expect(screen.getByText('Issue Scans')).toBeInTheDocument();
459+
expect(screen.getByText('Seer Budget')).toBeInTheDocument();
464460

465461
const editSettingMock = MockApiClient.addMockResponse({
466462
url: `/users/me/notification-options/`,
@@ -520,7 +516,6 @@ describe('NotificationSettingsByType', function () {
520516
).not.toBeInTheDocument();
521517
expect(screen.queryByText('UI Profile Hours', {exact: true})).not.toBeInTheDocument();
522518
expect(screen.queryByText('Transactions')).not.toBeInTheDocument();
523-
expect(screen.queryByText('Issue Fixes')).not.toBeInTheDocument();
524-
expect(screen.queryByText('Issue Scans')).not.toBeInTheDocument();
519+
expect(screen.queryByText('Seer Budget')).not.toBeInTheDocument();
525520
});
526521
});

static/app/views/settings/account/notifications/utils.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ export function getPricingDocsLinkForEventType(event: DataCategoryExact) {
5353
return 'https://docs.sentry.io/pricing/quotas/manage-continuous-profile-hours/';
5454
case DataCategoryExact.PROFILE_DURATION_UI:
5555
return 'https://docs.sentry.io/pricing/quotas/manage-ui-profile-hours/';
56+
case DataCategoryExact.SEER_AUTOFIX:
57+
case DataCategoryExact.SEER_SCANNER:
58+
// TODO(seer): Replace with actual Seer budget quota docs link
59+
return 'https://docs.sentry.io/pricing/quotas/manage-seer-budget/';
5660
default:
5761
return 'https://docs.sentry.io/pricing/quotas/manage-event-stream-guide/';
5862
}

0 commit comments

Comments
 (0)