diff --git a/frontend/src/scenes/billing/BillingLimit.tsx b/frontend/src/scenes/billing/BillingLimit.tsx index 289b9f2d7072c..9415c84945e14 100644 --- a/frontend/src/scenes/billing/BillingLimit.tsx +++ b/frontend/src/scenes/billing/BillingLimit.tsx @@ -12,13 +12,16 @@ import { billingProductLogic } from './billingProductLogic' export const BillingLimit = ({ product }: { product: BillingProductV2Type }): JSX.Element | null => { const limitInputRef = useRef(null) const { billing, billingLoading } = useValues(billingLogic) - const { isEditingBillingLimit, customLimitUsd } = useValues( + const { isEditingBillingLimit, customLimitUsd, currentAndUpgradePlans } = useValues( billingProductLogic({ product, billingLimitInputRef: limitInputRef }) ) const { setIsEditingBillingLimit, setBillingLimitInput, submitBillingLimitInput } = useActions( billingProductLogic({ product }) ) + const initialBillingLimit = currentAndUpgradePlans?.currentPlan?.initial_billing_limit + const usingInitialBillingLimit = customLimitUsd === initialBillingLimit + if (billing?.billing_period?.interval !== 'month' || !product.subscribed) { return null } @@ -32,12 +35,22 @@ export const BillingLimit = ({ product }: { product: BillingProductV2Type }): JS
{customLimitUsd ? ( <> - - - You have a ${customLimitUsd} billing limit set for{' '} - {product?.name?.toLowerCase()}. - - + {usingInitialBillingLimit ? ( + + + This product has a default initial billing limit of{' '} + ${initialBillingLimit}. + + + ) : ( + + + You have a ${customLimitUsd} billing limit set for{' '} + {product?.name?.toLowerCase()}. + + + )} + setIsEditingBillingLimit(true)} status="danger" diff --git a/frontend/src/scenes/billing/InitialBillingLimitNotice.tsx b/frontend/src/scenes/billing/InitialBillingLimitNotice.tsx new file mode 100644 index 0000000000000..84389eaddc476 --- /dev/null +++ b/frontend/src/scenes/billing/InitialBillingLimitNotice.tsx @@ -0,0 +1,41 @@ +import { useValues } from 'kea' +import { LemonBanner } from 'lib/lemon-ui/LemonBanner' +import { urls } from 'scenes/urls' + +import { BillingProductV2Type, ProductKey } from '~/types' + +import { billingLogic } from './billingLogic' +import { billingProductLogic } from './billingProductLogic' + +const InitialBillingLimitNoticeContents = ({ product }: { product: BillingProductV2Type }): JSX.Element | null => { + const { currentAndUpgradePlans, customLimitUsd } = useValues(billingProductLogic({ product })) + const initialBillingLimit = currentAndUpgradePlans?.currentPlan?.initial_billing_limit + const isUsingInitialBillingLimit = currentAndUpgradePlans?.currentPlan?.initial_billing_limit == customLimitUsd + + return isUsingInitialBillingLimit ? ( + +

+ Default initial billing limit of ${initialBillingLimit} active. +

+

+ This protects you from accidentally incurring large unexpected charges. Some features may stop working + and data may be dropped if your usage exceeds your limit. +

+
+ ) : null +} + +export const InitialBillingLimitNotice = ({ product_key }: { product_key: ProductKey }): JSX.Element | null => { + const { billing } = useValues(billingLogic) + const product = billing?.products.find((p) => p.type === product_key) + return product ? : null +} diff --git a/frontend/src/scenes/billing/billingProductLogic.ts b/frontend/src/scenes/billing/billingProductLogic.ts index 2441c100ad43c..cd73d70b56f9a 100644 --- a/frontend/src/scenes/billing/billingProductLogic.ts +++ b/frontend/src/scenes/billing/billingProductLogic.ts @@ -288,41 +288,14 @@ export const billingProductLogic = kea([ }, setScrollToProductKey: ({ scrollToProductKey }) => { if (scrollToProductKey && scrollToProductKey === props.product.type) { - const { currentPlan } = values.currentAndUpgradePlans - - if (currentPlan?.initial_billing_limit) { - actions.setProductSpecificAlert({ - status: 'warning', - title: 'Billing Limit Automatically Applied', - pathName: '/organization/billing', - dismissKey: `auto-apply-billing-limit-${props.product.type}`, - message: `To protect your costs and ours, we've automatically applied a $${currentPlan?.initial_billing_limit} billing limit for ${props.product.name}.`, - action: { - onClick: () => { - actions.setIsEditingBillingLimit(true) - setTimeout(() => { - if (props.billingLimitInputRef?.current) { - props.billingLimitInputRef?.current.focus() - props.billingLimitInputRef?.current.scrollIntoView({ - behavior: 'smooth', - block: 'nearest', - }) - } - }, 0) - }, - children: 'Update billing limit', - }, - }) - } else { - setTimeout(() => { - if (props.productRef?.current) { - props.productRef?.current.scrollIntoView({ - behavior: 'smooth', - block: 'center', - }) - } - }, 0) - } + setTimeout(() => { + if (props.productRef?.current) { + props.productRef?.current.scrollIntoView({ + behavior: 'smooth', + block: 'center', + }) + } + }, 0) } }, initiateProductUpgrade: ({ plan, product, redirectPath }) => { diff --git a/frontend/src/scenes/data-warehouse/DataWarehouseInitialBillingLimitNotice.tsx b/frontend/src/scenes/data-warehouse/DataWarehouseInitialBillingLimitNotice.tsx new file mode 100644 index 0000000000000..707b6c28d6eb0 --- /dev/null +++ b/frontend/src/scenes/data-warehouse/DataWarehouseInitialBillingLimitNotice.tsx @@ -0,0 +1,15 @@ +import { useValues } from 'kea' +import { InitialBillingLimitNotice } from 'scenes/billing/InitialBillingLimitNotice' + +import { ProductKey } from '~/types' + +import { dataWarehouseSettingsLogic } from './settings/dataWarehouseSettingsLogic' + +export const DataWarehouseInitialBillingLimitNotice = (): JSX.Element | null => { + const { dataWarehouseSources, selfManagedTables } = useValues(dataWarehouseSettingsLogic) + + const hasSources = + (dataWarehouseSources?.results && dataWarehouseSources?.results.length > 0) || selfManagedTables?.length > 0 + + return hasSources ? : null +} diff --git a/frontend/src/scenes/data-warehouse/external/DataWarehouseExternalScene.tsx b/frontend/src/scenes/data-warehouse/external/DataWarehouseExternalScene.tsx index aaed2281b1ced..8f2c11076329d 100644 --- a/frontend/src/scenes/data-warehouse/external/DataWarehouseExternalScene.tsx +++ b/frontend/src/scenes/data-warehouse/external/DataWarehouseExternalScene.tsx @@ -11,6 +11,7 @@ import { SceneExport } from 'scenes/sceneTypes' import { urls } from 'scenes/urls' import { DataWarehouseBetaNotice } from '../DataWarehouseBetaNotice' +import { DataWarehouseInitialBillingLimitNotice } from '../DataWarehouseInitialBillingLimitNotice' import { dataWarehouseSceneLogic } from './dataWarehouseSceneLogic' import { DataWarehouseTables } from './DataWarehouseTables' @@ -73,6 +74,7 @@ export function DataWarehouseExternalScene(): JSX.Element { } /> + diff --git a/frontend/src/scenes/data-warehouse/new/NewSourceWizard.tsx b/frontend/src/scenes/data-warehouse/new/NewSourceWizard.tsx index 6d4f669badb4f..231109f991a56 100644 --- a/frontend/src/scenes/data-warehouse/new/NewSourceWizard.tsx +++ b/frontend/src/scenes/data-warehouse/new/NewSourceWizard.tsx @@ -7,6 +7,7 @@ import { SceneExport } from 'scenes/sceneTypes' import { ManualLinkSourceType, SourceConfig } from '~/types' import { DataWarehouseBetaNotice } from '../DataWarehouseBetaNotice' +import { DataWarehouseInitialBillingLimitNotice } from '../DataWarehouseInitialBillingLimitNotice' import PostgresSchemaForm from '../external/forms/PostgresSchemaForm' import SourceForm from '../external/forms/SourceForm' import { SyncProgressStep } from '../external/forms/SyncProgressStep' @@ -73,6 +74,7 @@ export function NewSourceWizard(): JSX.Element { } /> + <>

{modalTitle}

{modalCaption}

diff --git a/frontend/src/scenes/data-warehouse/settings/DataWarehouseSettingsScene.tsx b/frontend/src/scenes/data-warehouse/settings/DataWarehouseSettingsScene.tsx index 2b75670c1101e..85337b829b756 100644 --- a/frontend/src/scenes/data-warehouse/settings/DataWarehouseSettingsScene.tsx +++ b/frontend/src/scenes/data-warehouse/settings/DataWarehouseSettingsScene.tsx @@ -8,6 +8,7 @@ import { urls } from 'scenes/urls' import { DataWarehouseSettingsTab } from '~/types' import { DataWarehouseBetaNotice } from '../DataWarehouseBetaNotice' +import { DataWarehouseInitialBillingLimitNotice } from '../DataWarehouseInitialBillingLimitNotice' import { DataWarehouseManagedSourcesTable } from './DataWarehouseManagedSourcesTable' import { DataWarehouseSelfManagedSourcesTable } from './DataWarehouseSelfManagedSourcesTable' import { dataWarehouseSettingsLogic, humanFriendlyDataWarehouseSettingsTabName } from './dataWarehouseSettingsLogic' @@ -46,6 +47,7 @@ export function DataWarehouseSettingsScene(): JSX.Element { } /> + router.actions.push(urls.dataWarehouseSettings(tab as DataWarehouseSettingsTab))} diff --git a/frontend/src/scenes/onboarding/OnboardingBillingStep.tsx b/frontend/src/scenes/onboarding/OnboardingBillingStep.tsx index c66febd36d5d6..df3164b5b10ab 100644 --- a/frontend/src/scenes/onboarding/OnboardingBillingStep.tsx +++ b/frontend/src/scenes/onboarding/OnboardingBillingStep.tsx @@ -1,5 +1,5 @@ import { IconCheckCircle } from '@posthog/icons' -import { LemonBanner, LemonButton } from '@posthog/lemon-ui' +import { LemonButton } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { BillingUpgradeCTA } from 'lib/components/BillingUpgradeCTA' import { StarHog } from 'lib/components/hedgehogs' @@ -33,7 +33,6 @@ export const OnboardingBillingStep = ({ const { currentAndUpgradePlans } = useValues(billingProductLogic({ product })) const { reportBillingUpgradeClicked } = useActions(eventUsageLogic) const plan = currentAndUpgradePlans?.upgradePlan - const currentPlan = currentAndUpgradePlans?.currentPlan const [showPlanComp, setShowPlanComp] = useState(false) @@ -92,15 +91,6 @@ export const OnboardingBillingStep = ({ > {showPlanComp ? 'Hide' : 'Show'} plans
- {currentPlan?.initial_billing_limit && ( -
- - To protect your costs and ours, this product has an initial billing limit of $ - {currentPlan.initial_billing_limit}. You can change or remove this limit on the - Billing page. - -
- )}
)}