Skip to content

Commit

Permalink
Merge branch 'master' into aspicer/3.11
Browse files Browse the repository at this point in the history
  • Loading branch information
aspicer authored Jun 21, 2024
2 parents 7187455 + 01a9f36 commit aaad5e7
Show file tree
Hide file tree
Showing 58 changed files with 1,995 additions and 584 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/build-hogql-parser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ jobs:
with:
python-version: '3.11'

# # This is an alternative way to install Python 3.11 on ARM if the above fails
# - if: ${{ endsWith(matrix.os, '-arm') }}
# name: Install Python 3.11 on ARM (compile from source)
# run: |
# sudo apt-get update
# sudo apt-get install -y build-essential libssl-dev zlib1g-dev \
# libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev \
# libgdbm-dev libdb5.3-dev libbz2-dev libexpat1-dev liblzma-dev tk-dev
# wget https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tar.xz
# tar -xf Python-3.11.0.tar.xz
# cd Python-3.11.0
# ./configure --enable-optimizations
# make -j 2
# sudo make altinstall

- name: Build sdist
if: matrix.os == 'ubuntu-22.04' # Only build the sdist once
run: cd hogql_parser && python setup.py sdist
Expand Down
5 changes: 5 additions & 0 deletions ee/api/billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class ActivateSerializer(serializers.Serializer):
required=False
) # This is required but in order to support an error for the legacy 'plan' param we need to set required=False
redirect_path = serializers.CharField(required=False)
intent_product = serializers.CharField(required=False)

def validate(self, data):
plan = data.get("plan")
Expand Down Expand Up @@ -137,6 +138,10 @@ def handle_activate(self, request: Request, *args: Any, **kwargs: Any) -> HttpRe
products = serializer.validated_data.get("products")
url = f"{url}&products={products}"

intent_product = serializer.validated_data.get("intent_product")
if intent_product:
url = f"{url}&intent_product={intent_product}"

if license:
billing_service_token = build_billing_token(license, organization)
url = f"{url}&token={billing_service_token}"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 40 additions & 5 deletions frontend/src/lib/components/PayGateMini/PayGateButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { LemonButton } from '@posthog/lemon-ui'
import { useValues } from 'kea'
import { FEATURE_FLAGS } from 'lib/constants'
import { featureFlagLogic, FeatureFlagsSet } from 'lib/logic/featureFlagLogic'
import { urls } from 'scenes/urls'

import { BillingProductV2AddonType, BillingProductV2Type, BillingV2FeatureType, BillingV2Type } from '~/types'

Expand All @@ -8,6 +12,7 @@ interface PayGateButtonProps {
featureInfo: BillingV2FeatureType
onCtaClick: () => void
billing: BillingV2Type | null
isAddonProduct?: boolean
scrollToProduct: boolean
}

Expand All @@ -17,16 +22,27 @@ export const PayGateButton = ({
featureInfo,
onCtaClick,
billing,
isAddonProduct,
scrollToProduct = true,
}: PayGateButtonProps): JSX.Element => {
const { featureFlags } = useValues(featureFlagLogic)
return (
<LemonButton
to={getCtaLink(gateVariant, productWithFeature, featureInfo, scrollToProduct)}
to={getCtaLink(
gateVariant,
productWithFeature,
featureInfo,
featureFlags,
billing?.subscription_level,
isAddonProduct,
scrollToProduct
)}
disableClientSideRouting={gateVariant === 'add-card' && !isAddonProduct}
type="primary"
center
onClick={onCtaClick}
>
{getCtaLabel(gateVariant, billing)}
{getCtaLabel(gateVariant, billing, featureFlags)}
</LemonButton>
)
}
Expand All @@ -35,9 +51,21 @@ const getCtaLink = (
gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null,
productWithFeature: BillingProductV2AddonType | BillingProductV2Type,
featureInfo: BillingV2FeatureType,
featureFlags: FeatureFlagsSet,
subscriptionLevel?: BillingV2Type['subscription_level'],
isAddonProduct?: boolean,
scrollToProduct: boolean = true
): string | undefined => {
if (gateVariant === 'add-card') {
if (
gateVariant === 'add-card' &&
!isAddonProduct &&
featureFlags[FEATURE_FLAGS.SUBSCRIBE_TO_ALL_PRODUCTS] === 'test' &&
subscriptionLevel === 'free'
) {
return `/api/billing/activate?products=all_products:&redirect_path=${urls.organizationBilling()}&intent_product=${
productWithFeature.type
}`
} else if (gateVariant === 'add-card') {
return `/organization/billing${scrollToProduct ? `?products=${productWithFeature.type}` : ''}`
} else if (gateVariant === 'contact-sales') {
return `mailto:[email protected]?subject=Inquiring about ${featureInfo.name}`
Expand All @@ -49,9 +77,16 @@ const getCtaLink = (

const getCtaLabel = (
gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null,
billing: BillingV2Type | null
billing: BillingV2Type | null,
featureFlags: FeatureFlagsSet
): string => {
if (gateVariant === 'add-card') {
if (
gateVariant === 'add-card' &&
featureFlags[FEATURE_FLAGS.SUBSCRIBE_TO_ALL_PRODUCTS] === 'test' &&
billing?.subscription_level === 'free'
) {
return 'Upgrade now'
} else if (gateVariant === 'add-card') {
return billing?.has_active_subscription ? 'Upgrade now' : 'Subscribe now'
} else if (gateVariant === 'contact-sales') {
return 'Contact sales'
Expand Down
35 changes: 32 additions & 3 deletions frontend/src/lib/components/PayGateMini/PayGateMini.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@ import { IconInfo, IconOpenSidebar } from '@posthog/icons'
import { LemonButton, Link, Tooltip } from '@posthog/lemon-ui'
import clsx from 'clsx'
import { useActions, useValues } from 'kea'
import { FEATURE_FLAGS } from 'lib/constants'
import { featureFlagLogic, FeatureFlagsSet } from 'lib/logic/featureFlagLogic'
import posthog from 'posthog-js'
import { useEffect } from 'react'
import { billingLogic } from 'scenes/billing/billingLogic'
import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic'
import { getProductIcon } from 'scenes/products/Products'

import { AvailableFeature, BillingProductV2AddonType, BillingProductV2Type, BillingV2FeatureType } from '~/types'
import {
AvailableFeature,
BillingProductV2AddonType,
BillingProductV2Type,
BillingV2FeatureType,
BillingV2Type,
} from '~/types'

import { upgradeModalLogic } from '../UpgradeModal/upgradeModalLogic'
import { PayGateButton } from './PayGateButton'
Expand Down Expand Up @@ -95,6 +103,7 @@ export function PayGateMini({
productWithFeature={productWithFeature}
isGrandfathered={isGrandfathered}
isAddonProduct={isAddonProduct}
billing={billing}
featureInfoOnNextPlan={featureInfoOnNextPlan}
handleCtaClick={handleCtaClick}
>
Expand All @@ -106,6 +115,7 @@ export function PayGateMini({
onCtaClick={handleCtaClick}
billing={billing}
scrollToProduct={scrollToProduct}
isAddonProduct={isAddonProduct}
/>
{docsLink && isCloudOrDev && (
<LemonButton
Expand Down Expand Up @@ -135,6 +145,7 @@ interface PayGateContentProps {
productWithFeature: BillingProductV2AddonType | BillingProductV2Type
isGrandfathered?: boolean
isAddonProduct?: boolean
billing: BillingV2Type | null
featureInfoOnNextPlan?: BillingV2FeatureType
children: React.ReactNode
handleCtaClick: () => void
Expand All @@ -149,10 +160,12 @@ function PayGateContent({
productWithFeature,
isGrandfathered,
isAddonProduct,
billing,
featureInfoOnNextPlan,
children,
handleCtaClick,
}: PayGateContentProps): JSX.Element {
const { featureFlags } = useValues(featureFlagLogic)
return (
<div
className={clsx(
Expand All @@ -171,6 +184,8 @@ function PayGateContent({
gateVariant,
featureInfo,
productWithFeature,
billing,
featureFlags,
isAddonProduct,
handleCtaClick
)}
Expand All @@ -187,6 +202,8 @@ const renderUsageLimitMessage = (
gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null,
featureInfo: BillingV2FeatureType,
productWithFeature: BillingProductV2AddonType | BillingProductV2Type,
billing: BillingV2Type | null,
featureFlags: FeatureFlagsSet,
isAddonProduct?: boolean,
handleCtaClick?: () => void
): JSX.Element => {
Expand Down Expand Up @@ -223,9 +240,13 @@ const renderUsageLimitMessage = (
.
</p>
</>
) : featureFlags[FEATURE_FLAGS.SUBSCRIBE_TO_ALL_PRODUCTS] === 'test' &&
billing?.subscription_level === 'free' &&
!isAddonProduct ? (
<p>Upgrade to create more {featureInfo.name}</p>
) : (
<p>
Please upgrade your <b>{productWithFeature.name}</b> plan to create more {featureInfo.name}
Upgrade your <b>{productWithFeature.name}</b> plan to create more {featureInfo.name}
</p>
)}
</div>
Expand All @@ -234,14 +255,16 @@ const renderUsageLimitMessage = (
return (
<>
<p className="max-w-140">{featureInfo.description}</p>
<p>{renderGateVariantMessage(gateVariant, productWithFeature, isAddonProduct)}</p>
<p>{renderGateVariantMessage(gateVariant, productWithFeature, billing, featureFlags, isAddonProduct)}</p>
</>
)
}

const renderGateVariantMessage = (
gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null,
productWithFeature: BillingProductV2AddonType | BillingProductV2Type,
billing: BillingV2Type | null,
featureFlags: FeatureFlagsSet,
isAddonProduct?: boolean
): JSX.Element => {
if (gateVariant === 'move-to-cloud') {
Expand All @@ -252,7 +275,13 @@ const renderGateVariantMessage = (
Subscribe to the <b>{productWithFeature?.name}</b> addon to use this feature.
</>
)
} else if (
featureFlags[FEATURE_FLAGS.SUBSCRIBE_TO_ALL_PRODUCTS] === 'test' &&
billing?.subscription_level === 'free'
) {
return <>Upgrade to use this feature.</>
}

return (
<>
Upgrade your <b>{productWithFeature?.name}</b> plan to use this feature.
Expand Down
1 change: 1 addition & 0 deletions frontend/src/lib/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ export const FEATURE_FLAGS = {
PERSONLESS_EVENTS_NOT_SUPPORTED: 'personless-events-not-supported', // owner: @raquelmsmith
SESSION_REPLAY_UNIVERSAL_FILTERS: 'session-replay-universal-filters', // owner: #team-replay
ALERTS: 'alerts', // owner: github.com/nikitaevg
SUBSCRIBE_TO_ALL_PRODUCTS: 'subscribe-to-all-products', // owner: #team-growth
ERROR_TRACKING: 'error-tracking', // owner: #team-replay
SETTINGS_BOUNCE_RATE_PAGE_VIEW_MODE: 'settings-bounce-rate-page-view-mode', // owner: @robbie-c
SURVEYS_BRANCHING_LOGIC: 'surveys-branching-logic', // owner: @jurajmajerik #team-feature-success
Expand Down
13 changes: 8 additions & 5 deletions frontend/src/lib/lemon-ui/LemonBanner/LemonBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface LemonBannerProps {
className?: string
/** If provided, the banner will be dismissed and hidden when the key is set in localStorage. */
dismissKey?: string
hideIcon?: boolean
}

/** Generic alert message. */
Expand All @@ -29,6 +30,7 @@ export function LemonBanner({
action,
className,
dismissKey = '',
hideIcon = false,
}: LemonBannerProps): JSX.Element | null {
const logic = lemonBannerLogic({ dismissKey })
const { isDismissed } = useValues(logic)
Expand All @@ -49,11 +51,12 @@ export function LemonBanner({
return (
<div className={clsx('LemonBanner @container', `LemonBanner--${type}`, className)}>
<div className="flex items-center gap-2 grow @md:px-1">
{type === 'warning' || type === 'error' ? (
<IconWarning className="LemonBanner__icon hidden @md:block" />
) : (
<IconInfo className="LemonBanner__icon hidden @md:block" />
)}
{!hideIcon &&
(type === 'warning' || type === 'error' ? (
<IconWarning className="LemonBanner__icon hidden @md:block" />
) : (
<IconInfo className="LemonBanner__icon hidden @md:block" />
))}
<div className="grow overflow-hidden">{children}</div>
{action && <LemonButton className="hidden @md:flex" type="secondary" {...action} />}
{showCloseButton && <LemonButton size="small" icon={<IconX />} onClick={_onClose} aria-label="close" />}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/mocks/fixtures/_billing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3835,4 +3835,5 @@ export const billingJson: BillingV2Type = {
custom_limits_usd: {},
stripe_portal_url:
'https://billing.stripe.com/p/session/test_YWNjdF8xSElNRERFdUlhdFJYU2R6LF9QaEVJR3VyemlvMDZzRzdiQXZrc1AxSjNXZk1BellP0100ZsforDQG',
subscription_level: 'paid',
}
Loading

0 comments on commit aaad5e7

Please sign in to comment.