From dd73fe33601958f21d7240aefe43d9501a44b94c Mon Sep 17 00:00:00 2001 From: Brendan Hy Date: Tue, 18 Mar 2025 10:47:04 -0700 Subject: [PATCH 1/2] feat(profile hours): add ui profile hours to overage banners --- static/gsApp/components/addEventsCTA.tsx | 1 + static/gsApp/components/gsBanner.spec.tsx | 36 +++++++++++++++++++++-- static/gsApp/components/gsBanner.tsx | 27 ++++++++++++++++- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/static/gsApp/components/addEventsCTA.tsx b/static/gsApp/components/addEventsCTA.tsx index 8a4add99c9ece1..015aa6fa897f46 100644 --- a/static/gsApp/components/addEventsCTA.tsx +++ b/static/gsApp/components/addEventsCTA.tsx @@ -21,6 +21,7 @@ export type EventType = | 'monitorSeat' | 'span' | 'profileDuration' + | 'profileDurationUI' | 'uptime'; type Props = { diff --git a/static/gsApp/components/gsBanner.spec.tsx b/static/gsApp/components/gsBanner.spec.tsx index 073d406044d722..d224d583dd8405 100644 --- a/static/gsApp/components/gsBanner.spec.tsx +++ b/static/gsApp/components/gsBanner.spec.tsx @@ -331,6 +331,7 @@ describe('GSBanner', function () { attachments: MetricHistoryFixture({usageExceeded: false}), monitorSeats: MetricHistoryFixture({usageExceeded: false}), profileDuration: MetricHistoryFixture({usageExceeded: false}), + profileDurationUI: MetricHistoryFixture({usageExceeded: false}), }, canSelfServe: true, productTrials: [ @@ -367,6 +368,7 @@ describe('GSBanner', function () { attachments: MetricHistoryFixture({usageExceeded: false}), monitorSeats: MetricHistoryFixture({usageExceeded: false}), profileDuration: MetricHistoryFixture({usageExceeded: false}), + profileDurationUI: MetricHistoryFixture({usageExceeded: false}), }, canSelfServe: true, productTrials: [ @@ -528,6 +530,7 @@ describe('GSBanner', function () { attachments: MetricHistoryFixture({sentUsageWarning: false}), monitorSeats: MetricHistoryFixture({sentUsageWarning: false}), profileDuration: MetricHistoryFixture({sentUsageWarning: false}), + profileDurationUI: MetricHistoryFixture({sentUsageWarning: false}), }, canSelfServe: true, productTrials: [ @@ -564,8 +567,8 @@ describe('GSBanner', function () { replays: MetricHistoryFixture({usageExceeded: true}), attachments: MetricHistoryFixture({sentUsageWarning: false}), monitorSeats: MetricHistoryFixture({sentUsageWarning: false}), + profileDurationUI: MetricHistoryFixture({sentUsageWarning: false}), }, - canSelfServe: true, productTrials: [ { category: 'replays', @@ -2112,11 +2115,40 @@ describe('GSBanner', function () { }); const subscription = SubscriptionFixture({ organization, - plan: 'am1_team', + plan: 'am3_team', categories: { errors: MetricHistoryFixture({sentUsageWarning: false}), spans: MetricHistoryFixture({sentUsageWarning: false}), profileDuration: MetricHistoryFixture({sentUsageWarning: true}), // Warning sent + profileDurationUI: MetricHistoryFixture({sentUsageWarning: false}), + replays: MetricHistoryFixture({usageExceeded: false}), + attachments: MetricHistoryFixture({sentUsageWarning: false}), + monitorSeats: MetricHistoryFixture({sentUsageWarning: false}), + }, + canSelfServe: true, + }); + SubscriptionStore.set(organization.slug, subscription); + + render(, {organization}); + + expect( + await screen.findByRole('button', {name: /increase reserved limits/i}) + ).toBeInTheDocument(); + }); + + it('shows overage warning banner for profileDurationUI', async function () { + const organization = OrganizationFixture({ + access: ['org:billing'], + slug: 'another-slug-1', + }); + const subscription = SubscriptionFixture({ + organization, + plan: 'am3_team', + categories: { + errors: MetricHistoryFixture({sentUsageWarning: false}), + spans: MetricHistoryFixture({sentUsageWarning: false}), + profileDuration: MetricHistoryFixture({sentUsageWarning: false}), + profileDurationUI: MetricHistoryFixture({sentUsageWarning: true}), replays: MetricHistoryFixture({usageExceeded: false}), attachments: MetricHistoryFixture({sentUsageWarning: false}), monitorSeats: MetricHistoryFixture({sentUsageWarning: false}), diff --git a/static/gsApp/components/gsBanner.tsx b/static/gsApp/components/gsBanner.tsx index 099a28a93eecfa..d7de910b285c5f 100644 --- a/static/gsApp/components/gsBanner.tsx +++ b/static/gsApp/components/gsBanner.tsx @@ -90,6 +90,7 @@ const ALERTS_OFF: Record = { monitorSeat: false, span: false, profileDuration: false, + profileDurationUI: false, uptime: false, }; @@ -319,6 +320,7 @@ class GSBanner extends Component { monitorSeat: true, span: true, profileDuration: true, + profileDurationUI: true, uptime: true, }, overageWarningDismissed: { @@ -329,6 +331,7 @@ class GSBanner extends Component { monitorSeat: true, span: true, profileDuration: true, + profileDurationUI: true, uptime: true, }, productTrialDismissed: { @@ -339,6 +342,7 @@ class GSBanner extends Component { monitorSeat: true, span: true, profileDuration: true, + profileDurationUI: true, uptime: true, }, }; @@ -669,6 +673,7 @@ class GSBanner extends Component { 'monitor_seats_overage_alert', 'spans_overage_alert', 'profile_duration_overage_alert', + 'profile_duration_ui_overage_alert', 'uptime_overage_alert', // warning alerts @@ -679,6 +684,7 @@ class GSBanner extends Component { 'monitor_seats_warning_alert', 'spans_warning_alert', 'profile_duration_warning_alert', + 'profile_duration_ui_warning_alert', 'uptime_warning_alert', // product trial alerts @@ -689,6 +695,7 @@ class GSBanner extends Component { 'monitor_seats_product_trial_alert', 'spans_product_trial_alert', 'profile_duration_product_trial_alert', + 'profile_duration_ui_product_trial_alert', 'uptime_product_trial_alert', ], { @@ -731,6 +738,9 @@ class GSBanner extends Component { profileDuration: promptIsDismissedForBillingPeriod( checkResults.profile_duration_overage_alert! ), + profileDurationUI: promptIsDismissedForBillingPeriod( + checkResults.profile_duration_ui_overage_alert! + ), uptime: promptIsDismissedForBillingPeriod(checkResults.uptime_overage_alert!), }, overageWarningDismissed: { @@ -749,6 +759,9 @@ class GSBanner extends Component { profileDuration: promptIsDismissedForBillingPeriod( checkResults.profile_duration_warning_alert! ), + profileDurationUI: promptIsDismissedForBillingPeriod( + checkResults.profile_duration_ui_warning_alert! + ), uptime: promptIsDismissedForBillingPeriod(checkResults.uptime_warning_alert!), }, @@ -781,6 +794,10 @@ class GSBanner extends Component { checkResults.profile_duration_product_trial_alert!, subscription ), + profileDurationUI: trialPromptIsDismissed( + checkResults.profile_duration_ui_product_trial_alert!, + subscription + ), uptime: trialPromptIsDismissed( checkResults.uptime_product_trial_alert!, subscription @@ -820,6 +837,9 @@ class GSBanner extends Component { profileDuration: !this.state.overageAlertDismissed.profileDuration && !!subscription.categories.profileDuration?.usageExceeded, + profileDurationUI: + !this.state.overageAlertDismissed.profileDurationUI && + !!subscription.categories.profileDurationUI?.usageExceeded, uptime: !this.state.overageAlertDismissed.uptime && !!subscription.categories.uptime?.usageExceeded, @@ -857,6 +877,9 @@ class GSBanner extends Component { profileDuration: !this.state.overageWarningDismissed.profileDuration && !!subscription.categories.profileDuration?.sentUsageWarning, + profileDurationUI: + !this.state.overageWarningDismissed.profileDurationUI && + !!subscription.categories.profileDurationUI?.sentUsageWarning, uptime: !this.state.overageWarningDismissed.uptime && !!subscription.categories.uptime?.sentUsageWarning, @@ -924,6 +947,7 @@ class GSBanner extends Component { monitorSeat: `monitor_seats_${key}_alert`, span: `spans_${key}_alert`, profileDuration: `profile_duration_${key}_alert`, + profileDurationUI: `profile_duration_ui_${key}_alert`, uptime: `uptime_${key}_alert`, }; @@ -942,6 +966,7 @@ class GSBanner extends Component { monitorSeat: true, span: true, profileDuration: true, + profileDurationUI: true, uptime: true, }; // Suppress all warnings and alerts @@ -1060,7 +1085,7 @@ class GSBanner extends Component { })} ), - // TODO: Uncomment when we have a continuous profile doc link + // TODO(continuous profiling): Uncomment when we have a continuous profile doc link // profile: ( // Date: Tue, 18 Mar 2025 16:15:41 -0700 Subject: [PATCH 2/2] ref --- static/gsApp/components/gsBanner.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/gsApp/components/gsBanner.spec.tsx b/static/gsApp/components/gsBanner.spec.tsx index d224d583dd8405..4f41baf1219d48 100644 --- a/static/gsApp/components/gsBanner.spec.tsx +++ b/static/gsApp/components/gsBanner.spec.tsx @@ -567,8 +567,8 @@ describe('GSBanner', function () { replays: MetricHistoryFixture({usageExceeded: true}), attachments: MetricHistoryFixture({sentUsageWarning: false}), monitorSeats: MetricHistoryFixture({sentUsageWarning: false}), - profileDurationUI: MetricHistoryFixture({sentUsageWarning: false}), }, + canSelfServe: true, productTrials: [ { category: 'replays',