diff --git a/static/app/types/hooks.tsx b/static/app/types/hooks.tsx
index 8e31d6f2311cd7..7969e149b7d5c4 100644
--- a/static/app/types/hooks.tsx
+++ b/static/app/types/hooks.tsx
@@ -280,6 +280,7 @@ type InterfaceChromeHooks = {
footer: GenericComponentHook;
'help-modal:footer': HelpModalFooterHook;
'sidebar:billing-status': GenericOrganizationComponentHook;
+ 'sidebar:chonk-opt-in-banner': () => React.ReactNode;
'sidebar:help-menu': GenericOrganizationComponentHook;
'sidebar:item-label': SidebarItemLabelHook;
'sidebar:organization-dropdown-menu': GenericOrganizationComponentHook;
diff --git a/static/app/utils/theme/ChonkOptInBanner.tsx b/static/app/utils/theme/ChonkOptInBanner.tsx
index d92d1512cc99d8..794077930497df 100644
--- a/static/app/utils/theme/ChonkOptInBanner.tsx
+++ b/static/app/utils/theme/ChonkOptInBanner.tsx
@@ -4,6 +4,7 @@ import {ThemeProvider} from '@emotion/react';
import styled from '@emotion/styled';
import {Button} from 'sentry/components/core/button';
+import HookOrDefault from 'sentry/components/hookOrDefault';
import Panel from 'sentry/components/panels/panel';
import {IconClose} from 'sentry/icons';
import {t} from 'sentry/locale';
@@ -15,7 +16,7 @@ import useMutateUserOptions from 'sentry/utils/useMutateUserOptions';
import {useChonkPrompt} from './useChonkPrompt';
-export function ChonkOptInBanner(props: {collapsed: boolean | 'never'}) {
+export function ChonkOptInBannerComponent(props: {collapsed: boolean | 'never'}) {
const chonkPrompt = useChonkPrompt();
const config = useLegacyStore(ConfigStore);
const {mutate: mutateUserOptions} = useMutateUserOptions();
@@ -63,6 +64,11 @@ export function ChonkOptInBanner(props: {collapsed: boolean | 'never'}) {
);
}
+export const ChonkOptInBanner = HookOrDefault({
+ hookName: 'sidebar:chonk-opt-in-banner',
+ defaultComponent: () => ,
+});
+
const TranslucentBackgroundPanel = styled(Panel)<{
isDarkMode: boolean;
position: 'absolute' | 'relative';
diff --git a/static/app/views/nav/primary/index.tsx b/static/app/views/nav/primary/index.tsx
index d720df983a4e50..2825233dd382a8 100644
--- a/static/app/views/nav/primary/index.tsx
+++ b/static/app/views/nav/primary/index.tsx
@@ -14,7 +14,6 @@ import {
IconPrevent,
IconSettings,
} from 'sentry/icons';
-import {ChonkOptInBanner} from 'sentry/utils/theme/ChonkOptInBanner';
import useOrganization from 'sentry/utils/useOrganization';
import {getDefaultExploreRoute} from 'sentry/views/explore/utils';
import {useNavContext} from 'sentry/views/nav/context';
@@ -179,7 +178,9 @@ export function PrimaryNavigationItems() {
-
+
+
+
diff --git a/static/gsApp/components/chonkOptInBanner.tsx b/static/gsApp/components/chonkOptInBanner.tsx
new file mode 100644
index 00000000000000..fdc3a24805af9c
--- /dev/null
+++ b/static/gsApp/components/chonkOptInBanner.tsx
@@ -0,0 +1,16 @@
+import {ChonkOptInBannerComponent} from 'sentry/utils/theme/ChonkOptInBanner';
+
+import useSubscription from 'getsentry/hooks/useSubscription';
+
+import {useExceededSubscriptionCategories} from './navBillingStatus';
+
+export function ChonkOptInBanner() {
+ const subscription = useSubscription();
+ const exceededCategories = useExceededSubscriptionCategories(subscription);
+
+ if (exceededCategories.length > 0) {
+ return null;
+ }
+
+ return ;
+}
diff --git a/static/gsApp/components/navBillingStatus.tsx b/static/gsApp/components/navBillingStatus.tsx
index 82e723a6f2691b..6aff194cf4bd84 100644
--- a/static/gsApp/components/navBillingStatus.tsx
+++ b/static/gsApp/components/navBillingStatus.tsx
@@ -149,10 +149,15 @@ function QuotaExceededContent({
);
}
-function PrimaryNavigationQuotaExceeded({organization}: {organization: Organization}) {
- const subscription = useSubscription();
+export function useExceededSubscriptionCategories(
+ subscription: Subscription | null
+): DataCategory[] {
+ if (!subscription) {
+ return [];
+ }
+
const exceededCategories = (
- sortCategoriesWithKeys(subscription?.categories ?? {}) as Array<
+ sortCategoriesWithKeys(subscription.categories) as Array<
[DataCategory, BillingMetricHistory]
>
)
@@ -181,6 +186,14 @@ function PrimaryNavigationQuotaExceeded({organization}: {organization: Organizat
}
return acc;
}, [] as DataCategory[]);
+
+ return exceededCategories;
+}
+
+function PrimaryNavigationQuotaExceeded({organization}: {organization: Organization}) {
+ const subscription = useSubscription();
+ const exceededCategories = useExceededSubscriptionCategories(subscription);
+
const promptsToCheck = exceededCategories
.map(category => {
return `${snakeCase(category)}_overage_alert`;
@@ -278,6 +291,7 @@ function PrimaryNavigationQuotaExceeded({organization}: {organization: Organizat
subscription &&
subscription.canSelfServe &&
!subscription.hasOverageNotificationsDisabled;
+
if (!shouldShow || isLoading || isError) {
return null;
}
diff --git a/static/gsApp/registerHooks.tsx b/static/gsApp/registerHooks.tsx
index db1d648ee96451..b18a4a39d77619 100644
--- a/static/gsApp/registerHooks.tsx
+++ b/static/gsApp/registerHooks.tsx
@@ -70,6 +70,7 @@ import {useMetricDetectorLimit} from 'getsentry/hooks/useMetricDetectorLimit';
import rawTrackAnalyticsEvent from 'getsentry/utils/rawTrackAnalyticsEvent';
import trackMetric from 'getsentry/utils/trackMetric';
+import {ChonkOptInBanner} from './components/chonkOptInBanner';
import {CodecovSettingsLink} from './components/codecovSettingsLink';
import PrimaryNavigationQuotaExceeded from './components/navBillingStatus';
import OpenInDiscoverBtn from './components/openInDiscoverBtn';
@@ -132,6 +133,9 @@ const GETSENTRY_HOOKS: Partial = {
organization={props.organization}
/>
),
+ 'sidebar:chonk-opt-in-banner': () => {
+ return ;
+ },
/**
* Augment the global help search modal with a contat support button