Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions static/app/types/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 7 additions & 1 deletion static/app/utils/theme/ChonkOptInBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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();
Expand Down Expand Up @@ -63,6 +64,11 @@ export function ChonkOptInBanner(props: {collapsed: boolean | 'never'}) {
);
}

export const ChonkOptInBanner = HookOrDefault({
hookName: 'sidebar:chonk-opt-in-banner',
defaultComponent: () => <ChonkOptInBannerComponent collapsed="never" />,
});

const TranslucentBackgroundPanel = styled(Panel)<{
isDarkMode: boolean;
position: 'absolute' | 'relative';
Expand Down
5 changes: 3 additions & 2 deletions static/app/views/nav/primary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -179,7 +178,9 @@ export function PrimaryNavigationItems() {
</SidebarBody>

<SidebarFooter>
<ChonkOptInBanner collapsed="never" />
<ErrorBoundary customComponent={null}>
<Hook name="sidebar:chonk-opt-in-banner" />
</ErrorBoundary>
<PrimaryNavigationHelp />
<ErrorBoundary customComponent={null}>
<PrimaryNavigationWhatsNew />
Expand Down
16 changes: 16 additions & 0 deletions static/gsApp/components/chonkOptInBanner.tsx
Original file line number Diff line number Diff line change
@@ -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 <ChonkOptInBannerComponent collapsed="never" />;
}
20 changes: 17 additions & 3 deletions static/gsApp/components/navBillingStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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]
>
)
Expand Down Expand Up @@ -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`;
Expand Down Expand Up @@ -278,6 +291,7 @@ function PrimaryNavigationQuotaExceeded({organization}: {organization: Organizat
subscription &&
subscription.canSelfServe &&
!subscription.hasOverageNotificationsDisabled;

if (!shouldShow || isLoading || isError) {
return null;
}
Expand Down
4 changes: 4 additions & 0 deletions static/gsApp/registerHooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -132,6 +133,9 @@ const GETSENTRY_HOOKS: Partial<Hooks> = {
organization={props.organization}
/>
),
'sidebar:chonk-opt-in-banner': () => {
return <ChonkOptInBanner key="chonk-opt-in-banner-sidebar-item" />;
},

/**
* Augment the global help search modal with a contat support button
Expand Down
Loading