Skip to content

Commit d053d29

Browse files
chore(sub v3): prep for EA (#101437)
- Start replay recording every time any of the Usage & Billing settings pages are navigated to - Remove `trackSubscriptionView`; this event has been removed and we can use the automated Page View events instead - Add route analytics param for whether the page view is with the new UI flag - Automatically add analytics params for new checkout and new UI for all events defined in `trackGetsentryAnalytics`, instead of needing to manually add these flags for every relevant event - Adds some missing analytics events - Add feedback form button to every Usage & Billing settings page Closes BIL-1594, BIL-1595, and BIL-1640
1 parent dbed3f2 commit d053d29

26 files changed

+178
-122
lines changed

static/gsApp/components/billingDetails/form.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {useLocation} from 'sentry/utils/useLocation';
1919
import LegacyBillingDetailsForm from 'getsentry/components/billingDetails/legacyForm';
2020
import StripeWrapper from 'getsentry/components/stripeWrapper';
2121
import type {BillingDetails} from 'getsentry/types';
22-
import {hasNewBillingUI, hasStripeComponentsFeature} from 'getsentry/utils/billing';
22+
import {hasStripeComponentsFeature} from 'getsentry/utils/billing';
2323
import {countryCodes} from 'getsentry/utils/ISO3166codes';
2424
import type {TaxFieldInfo} from 'getsentry/utils/salesTax';
2525
import {
@@ -167,7 +167,6 @@ function BillingDetailsForm({
167167
!!initialData?.taxNumber || countryHasSalesTax(initialData?.countryCode),
168168
});
169169
const hasStripeComponents = hasStripeComponentsFeature(organization);
170-
const isNewBillingUI = hasNewBillingUI(organization);
171170
const location = useLocation();
172171

173172
const taxFieldInfo = useMemo(
@@ -228,7 +227,6 @@ function BillingDetailsForm({
228227
if (analyticsEvent) {
229228
trackGetsentryAnalytics(analyticsEvent, {
230229
organization,
231-
isNewBillingUI,
232230
isStripeComponent: hasStripeComponents,
233231
referrer: decodeScalar(location.query?.referrer),
234232
});

static/gsApp/components/creditCardEdit/intentForms/paymentIntentForm.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ import {decodeScalar} from 'sentry/utils/queryString';
1111
import InnerIntentForm from 'getsentry/components/creditCardEdit/intentForms/innerIntentForm';
1212
import type {StripeIntentFormProps} from 'getsentry/components/creditCardEdit/intentForms/types';
1313
import {usePaymentIntentData} from 'getsentry/hooks/useIntentData';
14-
import {hasNewBillingUI} from 'getsentry/utils/billing';
1514
import trackGetsentryAnalytics from 'getsentry/utils/trackGetsentryAnalytics';
1615

1716
function StripePaymentIntentForm(props: StripeIntentFormProps) {
1817
const {organization, referrer, onSuccess} = props;
19-
const isNewBillingUI = hasNewBillingUI(organization);
2018
const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined);
2119
const [isSubmitting, setIsSubmitting] = useState(false);
2220

@@ -76,7 +74,6 @@ function StripePaymentIntentForm(props: StripeIntentFormProps) {
7674
organization,
7775
referrer: decodeScalar(referrer),
7876
isStripeComponent: true,
79-
isNewBillingUI,
8077
});
8178
addSuccessMessage(t('Payment sent successfully.'));
8279
onSuccess?.();

static/gsApp/components/subscriptionSettingsLayout.tsx

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import styled from '@emotion/styled';
22

3+
import {Button} from '@sentry/scraps/button';
4+
35
import {Flex} from 'sentry/components/core/layout';
6+
import {IconMegaphone} from 'sentry/icons';
7+
import {t} from 'sentry/locale';
8+
import {useFeedbackForm} from 'sentry/utils/useFeedbackForm';
49
import {useLocation} from 'sentry/utils/useLocation';
510
import useOrganization from 'sentry/utils/useOrganization';
611
import {useParams} from 'sentry/utils/useParams';
712
import useRouter from 'sentry/utils/useRouter';
813
import {useRoutes} from 'sentry/utils/useRoutes';
914
import SettingsBreadcrumb from 'sentry/views/settings/components/settingsBreadcrumb';
15+
import type {RouteWithName} from 'sentry/views/settings/components/settingsBreadcrumb/types';
1016
import SettingsHeader from 'sentry/views/settings/components/settingsHeader';
1117
import SettingsSearch from 'sentry/views/settings/components/settingsSearch';
1218
import OrganizationSettingsLayout from 'sentry/views/settings/organization/organizationSettingsLayout';
@@ -20,13 +26,21 @@ type Props = {
2026
function SubscriptionSettingsLayout(props: Props) {
2127
const organization = useOrganization();
2228
const isNewBillingUI = hasNewBillingUI(organization);
29+
const openFeedbackForm = useFeedbackForm();
2330

2431
const location = useLocation();
2532
const params = useParams();
2633
const routes = useRoutes();
2734
const router = useRouter();
2835
const {children} = props;
29-
36+
let feedbackSource = location.pathname;
37+
for (let i = routes.length - 1; i >= 0; i--) {
38+
const route = routes[i] as RouteWithName;
39+
if (route?.name) {
40+
feedbackSource = route.name;
41+
break;
42+
}
43+
}
3044
if (!isNewBillingUI) {
3145
return (
3246
<OrganizationSettingsLayout
@@ -46,7 +60,30 @@ function SubscriptionSettingsLayout(props: Props) {
4660
<StyledSettingsHeader>
4761
<Flex align="center" justify="between">
4862
<StyledSettingsBreadcrumb params={params} routes={routes} />
49-
<SettingsSearch />
63+
<Flex align="center" gap="xl">
64+
{openFeedbackForm ? (
65+
<Button
66+
size="sm"
67+
icon={<IconMegaphone />}
68+
onClick={() => {
69+
openFeedbackForm({
70+
formTitle: t('Give feedback'),
71+
messagePlaceholder: t(
72+
'How can we make the %s page better for you?',
73+
feedbackSource
74+
),
75+
tags: {
76+
['feedback.source']: feedbackSource,
77+
['feedback.owner']: 'billing',
78+
},
79+
});
80+
}}
81+
>
82+
{t('Give feedback')}
83+
</Button>
84+
) : null}
85+
<SettingsSearch />
86+
</Flex>
5087
</Flex>
5188
</StyledSettingsHeader>
5289
<Flex minWidth={0} flex="1" direction="column">

static/gsApp/utils/rawTrackAnalyticsEvent.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import localStorage from 'sentry/utils/localStorage';
1010
import sessionStorage from 'sentry/utils/sessionStorage';
1111

1212
import type {Subscription} from 'getsentry/types';
13+
import {hasNewBillingUI} from 'getsentry/utils/billing';
14+
import {GETSENTRY_EVENT_MAP} from 'getsentry/utils/trackGetsentryAnalytics';
15+
import {hasNewCheckout} from 'getsentry/views/amCheckout/utils';
1316

1417
import trackAmplitudeEvent from './trackAmplitudeEvent';
1518
import trackMarketingEvent from './trackMarketingEvent';
@@ -179,6 +182,11 @@ export default function rawTrackAnalyticsEvent(
179182
// pass in properties if we have the full organization
180183
if (isFullOrganization(organization)) {
181184
data.role = organization.orgRole;
185+
186+
if (eventKey in GETSENTRY_EVENT_MAP) {
187+
data.isNewCheckout = hasNewCheckout(organization);
188+
data.isNewBillingUI = hasNewBillingUI(organization);
189+
}
182190
}
183191

184192
// add in plan information

static/gsApp/utils/trackGetsentryAnalytics.tsx

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@ type AddEventCTA = HasSub & {
2222
source: string;
2323
event_types?: string;
2424
};
25-
type CheckoutUI = {
26-
isNewCheckout: boolean;
27-
};
2825
type BillingInfoUpdateEvent = {
29-
isNewBillingUI: boolean;
3026
isStripeComponent: boolean;
3127
referrer?: string;
3228
};
@@ -51,7 +47,7 @@ export type ProductUnavailableUpsellAlert = {
5147

5248
type GetsentryEventParameters = {
5349
'add_event_cta.clicked_cta': AddEventCTA;
54-
'am_checkout.viewed': HasSub & CheckoutUI;
50+
'am_checkout.viewed': HasSub;
5551
'billing_details.updated_billing_details': BillingInfoUpdateEvent;
5652
'billing_details.updated_cc': BillingInfoUpdateEvent;
5753
'billing_failure.button_clicked': {
@@ -80,16 +76,15 @@ type GetsentryEventParameters = {
8076
'checkout.change_contract': Checkout;
8177
'checkout.change_plan': Checkout;
8278
'checkout.click_continue': {step_number: number; step_id?: string} & Checkout;
83-
'checkout.data_slider_changed': {data_type: string; quantity: number} & CheckoutUI;
79+
'checkout.data_slider_changed': {data_type: string; quantity: number};
8480
// no sub here;
85-
'checkout.data_sliders_viewed': Record<PropertyKey, unknown> & CheckoutUI;
81+
'checkout.data_sliders_viewed': Record<PropertyKey, unknown>;
8682
// only used for checkout v3
8783
'checkout.exit': HasSub;
88-
'checkout.ondemand_budget.turned_off': Record<PropertyKey, unknown> & CheckoutUI;
89-
'checkout.ondemand_budget.update': OnDemandBudgetUpdate & CheckoutUI;
84+
'checkout.ondemand_budget.turned_off': Record<PropertyKey, unknown>;
85+
'checkout.ondemand_budget.update': OnDemandBudgetUpdate;
9086
'checkout.ondemand_changed': {cents: number} & Checkout;
91-
'checkout.payg_changed': {cents: number; method?: 'button' | 'textbox'} & Checkout &
92-
CheckoutUI;
87+
'checkout.payg_changed': {cents: number; method?: 'button' | 'textbox'} & Checkout;
9388
'checkout.product_select': Partial<
9489
Record<
9590
AddOnCategory,
@@ -99,8 +94,7 @@ type GetsentryEventParameters = {
9994
}
10095
>
10196
> &
102-
HasSub &
103-
CheckoutUI;
97+
HasSub;
10498
'checkout.transactions_upgrade': {
10599
previous_transactions: number;
106100
transactions: number;
@@ -110,8 +104,7 @@ type GetsentryEventParameters = {
110104
// no sub here
111105
'checkout.upgrade': Partial<
112106
Record<DataCategory | `previous_${DataCategory}`, number | undefined>
113-
> & {previous_plan: string} & Checkout &
114-
CheckoutUI;
107+
> & {previous_plan: string} & Checkout;
115108
'data_consent_modal.learn_more': Record<PropertyKey, unknown>;
116109
'data_consent_priority.viewed': Record<PropertyKey, unknown>;
117110
'data_consent_settings.updated': {setting: string; value: FieldValue};
@@ -165,13 +158,14 @@ type GetsentryEventParameters = {
165158
applyNow: boolean;
166159
daysLeft: number;
167160
partner: undefined | string;
168-
} & HasSub &
169-
CheckoutUI;
161+
} & HasSub;
170162
'partner_billing_migration.modal.clicked_cta': {
171163
daysLeft: number;
172164
partner: undefined | string;
173165
} & HasSub;
174166
'past_due_modal.seen': HasSub;
167+
'payg_inline_form.ondemand_budget.turned_off': Record<PropertyKey, unknown>;
168+
'payg_inline_form.ondemand_budget.update': OnDemandBudgetUpdate;
175169
'performance.quota_exceeded_alert.displayed': {
176170
referrer: string;
177171
traceItemDataset: string;
@@ -196,17 +190,26 @@ type GetsentryEventParameters = {
196190
'replay.list_page.viewed': UpdateProps;
197191
'sales.contact_us_clicked': {
198192
source: string;
199-
} & HasSub &
200-
CheckoutUI;
193+
} & HasSub;
201194
'spend_allocations.open_form': {create_or_edit: string} & HasSub;
202195
'spend_allocations.submit': {create_or_edit: string} & HasSub;
203196
'subscription_page.display_mode.changed': {
204197
display_mode: 'usage' | 'cost';
205198
} & HasSub;
206-
'subscription_page.usagelog_filter.clicked': {selection: string};
207-
'subscription_page.viewed': {
208-
page_tab: string;
199+
'subscription_page.download_reports.clicked': {
200+
reportType: 'summary' | 'project_breakdown';
201+
};
202+
'subscription_page.usage_overview.add_on_toggled': {
203+
addOnCategory: AddOnCategory;
204+
isOpen: boolean;
205+
} & HasSub;
206+
'subscription_page.usage_overview.row_clicked': {
207+
dataCategory: DataCategory;
209208
} & HasSub;
209+
'subscription_page.usage_overview.transform_changed': {
210+
transform: string;
211+
} & HasSub;
212+
'subscription_page.usagelog_filter.clicked': {selection: string};
210213
'trial_ended_notice.dismissed_understood': HasSub;
211214
'trial_reset_notification.modal_dismissed': HasSub;
212215
'upgrade_now.alert.dismiss': UpdateProps;
@@ -240,7 +243,7 @@ type UpdateProps = Pick<Subscription, 'planTier' | 'canSelfServe' | 'channel'> &
240243

241244
export type GetsentryEventKey = keyof GetsentryEventParameters;
242245

243-
const getsentryEventMap: Record<GetsentryEventKey, string> = {
246+
export const GETSENTRY_EVENT_MAP: Record<GetsentryEventKey, string> = {
244247
'power_icon.clicked': 'Clicked Power Icon',
245248
'github.multi_org.upsell': 'Github Multi-Org Upsell Clicked',
246249
'growth.clicked_enter_sandbox': 'Growth: Clicked Enter Sandbox',
@@ -306,16 +309,20 @@ const getsentryEventMap: Record<GetsentryEventKey, string> = {
306309
'billing_failure.updated_cc': 'Billing Failure: Updated CC',
307310
'add_event_cta.clicked_cta': 'Add Event CTA: Clicked CTA',
308311
'subscription_page.usagelog_filter.clicked': 'Usage Log Filter: Clicked',
309-
'subscription_page.viewed': 'Subscription Page: Viewed',
312+
'subscription_page.download_reports.clicked':
313+
'Subscription Page: Download Reports Clicked',
310314
'sales.contact_us_clicked': 'Clicked Contact Sales',
311315
'disabled_member_view.loaded': 'Disabled Member View: Loaded',
312316
'disabled_member_view.clicked_upgrade_request':
313317
'Disabled Member View: Clicked Upgrade Request',
314318
'disabled_member_view.clicked_leave_org': 'Disabled Member View: Clicked Leave Org',
315-
'ondemand_budget_modal.ondemand_budget.turned_off': 'Disabled On-demand Budget',
316-
'ondemand_budget_modal.ondemand_budget.update': 'Update On-demand Budget',
317-
'checkout.ondemand_budget.turned_off': 'Checkout: Disabled On-demand Budget',
318-
'checkout.ondemand_budget.update': 'Checkout: Update On-demand Budget',
319+
'ondemand_budget_modal.ondemand_budget.turned_off': 'Disabled PAYG Budget',
320+
'ondemand_budget_modal.ondemand_budget.update': 'Update PAYG Budget',
321+
'payg_inline_form.ondemand_budget.turned_off':
322+
'PAYG In-line Form: Disabled PAYG Budget',
323+
'payg_inline_form.ondemand_budget.update': 'PAYG In-line Form: Update PAYG Budget',
324+
'checkout.ondemand_budget.turned_off': 'Checkout: Disabled PAYG Budget',
325+
'checkout.ondemand_budget.update': 'Checkout: Update PAYG Budget',
319326
'trial_reset_notification.modal_dismissed': 'Trial Reset Notification: Modal Dismissed',
320327
'growth.disabled_dashboard.viewed': 'Growth: Disabled Dashboard Viewed',
321328
'product_unavailable_upsell_alert.viewed': 'Product Unavailable Upsell: Viewed Alert',
@@ -352,11 +359,17 @@ const getsentryEventMap: Record<GetsentryEventKey, string> = {
352359
'gen_ai_consent.in_drawer_clicked': 'Gen AI Consent: Clicked In Drawer',
353360
'gen_ai_consent.view_in_settings_clicked': 'Gen AI Consent: View in Settings Clicked',
354361
'subscription_page.display_mode.changed': 'Subscription Page: Display Mode Changed',
362+
'subscription_page.usage_overview.row_clicked':
363+
'Subscription Page: Usage Overview Row Clicked',
364+
'subscription_page.usage_overview.transform_changed':
365+
'Subscription Page: Usage Overview Transform Changed',
366+
'subscription_page.usage_overview.add_on_toggled':
367+
'Subscription Page: Usage Overview Add On Toggled',
355368
};
356369

357370
const trackGetsentryAnalytics = makeAnalyticsFunction<
358371
GetsentryEventParameters,
359372
{organization: Organization}
360-
>(getsentryEventMap);
373+
>(GETSENTRY_EVENT_MAP);
361374

362375
export default trackGetsentryAnalytics;

static/gsApp/views/amCheckout/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class AMCheckout extends Component<Props, State> {
196196
state: State;
197197

198198
componentDidMount() {
199-
const {subscription, organization, isNewCheckout} = this.props;
199+
const {subscription, organization} = this.props;
200200
/**
201201
* Preload Stripe so it's ready when the subscription + cc form becomes
202202
* available. `loadStripe` ensures Stripe is not loaded multiple times
@@ -213,7 +213,6 @@ class AMCheckout extends Component<Props, State> {
213213
trackGetsentryAnalytics('am_checkout.viewed', {
214214
organization,
215215
subscription,
216-
isNewCheckout: !!isNewCheckout,
217216
});
218217
}
219218
Sentry.getReplay()?.start();

static/gsApp/views/amCheckout/reserveAdditionalVolume.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ function ReserveAdditionalVolume({
7474
organization,
7575
data_type: category,
7676
quantity: value,
77-
isNewCheckout: true,
7877
});
7978
}
8079
},

static/gsApp/views/amCheckout/steps/planSelect.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ function PlanSelect({
246246
organization,
247247
subscription,
248248
source: 'checkout.plan_select',
249-
isNewCheckout: false,
250249
});
251250
}}
252251
/>

0 commit comments

Comments
 (0)