Skip to content

Commit

Permalink
Merge branch 'master' into fix/whats-new
Browse files Browse the repository at this point in the history
  • Loading branch information
Twixes committed Jan 30, 2024
2 parents c1d1317 + 5fdf645 commit 8825950
Show file tree
Hide file tree
Showing 27 changed files with 266 additions and 73 deletions.
3 changes: 2 additions & 1 deletion .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { withMockDate } from './decorators/withMockDate'
import { defaultMocks } from '~/mocks/handlers'
import { withFeatureFlags } from './decorators/withFeatureFlags'
import { withTheme } from './decorators/withTheme'
import { apiHostOrigin } from 'lib/utils/apiHost'

const setupMsw = () => {
// Make sure the msw worker is started
Expand All @@ -35,7 +36,7 @@ setupMsw()
const setupPosthogJs = () => {
// Make sure we don't hit production posthog. We want to control requests to,
// e.g. `/decide/` for feature flags
window.JS_POSTHOG_HOST = window.location.origin
window.JS_POSTHOG_HOST = apiHostOrigin()

loadPostHogJS()
}
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.
31 changes: 25 additions & 6 deletions frontend/src/layout/navigation/TopBar/AccountPopover.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import './AccountPopover.scss'

import { IconCheckCircle, IconFeatures, IconGear, IconLive, IconPlusSmall, IconServer } from '@posthog/icons'
import {
IconCheckCircle,
IconConfetti,
IconFeatures,
IconGear,
IconLive,
IconPlusSmall,
IconServer,
} from '@posthog/icons'
import { LemonButtonPropsBase } from '@posthog/lemon-ui'
import clsx from 'clsx'
import { useActions, useValues } from 'kea'
Expand All @@ -10,7 +18,6 @@ import { Lettermark } from 'lib/lemon-ui/Lettermark'
import { ProfilePicture } from 'lib/lemon-ui/ProfilePicture'
import { Tooltip } from 'lib/lemon-ui/Tooltip'
import { eventUsageLogic } from 'lib/utils/eventUsageLogic'
import { billingLogic } from 'scenes/billing/billingLogic'
import { inviteLogic } from 'scenes/settings/organization/inviteLogic'
import { ThemeSwitcher } from 'scenes/settings/user/ThemeSwitcher'

Expand Down Expand Up @@ -183,11 +190,10 @@ function SignOutButton(): JSX.Element {
export function AccountPopoverOverlay(): JSX.Element {
const { user, otherOrganizations } = useValues(userLogic)
const { currentOrganization } = useValues(organizationLogic)
const { preflight } = useValues(preflightLogic)
const { mobileLayout } = useValues(navigationLogic)
const { closeAccountPopover } = useActions(navigationLogic)
const { billing } = useValues(billingLogic)
const { openSidePanel } = useActions(sidePanelStateLogic)
const { preflight, isCloudOrDev } = useValues(preflightLogic)
const { closeAccountPopover } = useActions(navigationLogic)

return (
<>
Expand All @@ -196,7 +202,7 @@ export function AccountPopoverOverlay(): JSX.Element {
</AccountPopoverSection>
<AccountPopoverSection title="Current organization">
{currentOrganization && <CurrentOrganization organization={currentOrganization} />}
{preflight?.cloud || !!billing ? (
{isCloudOrDev ? (
<LemonButton
onClick={closeAccountPopover}
to={urls.organizationBilling()}
Expand Down Expand Up @@ -242,6 +248,19 @@ export function AccountPopoverOverlay(): JSX.Element {
<FeaturePreviewsButton />
{user?.is_staff && <InstanceSettings />}
</AccountPopoverSection>
{!isCloudOrDev && (
<AccountPopoverSection>
<LemonButton
onClick={closeAccountPopover}
to={urls.moveToPostHogCloud()}
icon={<IconConfetti />}
fullWidth
data-attr="top-menu-item-upgrade-to-cloud"
>
Try PostHog Cloud
</LemonButton>
</AccountPopoverSection>
)}
<AccountPopoverSection>
<SignOutButton />
</AccountPopoverSection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { encodeParams, urlToAction } from 'kea-router'
import { subscriptions } from 'kea-subscriptions'
import api from 'lib/api'
import { isDomain, isURL } from 'lib/utils'
import { apiHostOrigin } from 'lib/utils/apiHost'
import { teamLogic } from 'scenes/teamLogic'
import { urls } from 'scenes/urls'

Expand Down Expand Up @@ -70,7 +71,7 @@ export function appEditorUrl(appUrl: string, actionId?: number | null, defaultIn
// the toolbar, which isn't correct when used behind a reverse proxy as
// we require e.g. SSO login to the app, which will not work when placed
// behind a proxy unless we register each domain with the OAuth2 client.
apiURL: window.location.origin,
apiURL: apiHostOrigin(),
appUrl,
...(actionId ? { actionId } : {}),
}
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/lib/components/JSSnippet.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useValues } from 'kea'
import { CodeSnippet, Language } from 'lib/components/CodeSnippet'
import { apiHostOrigin } from 'lib/utils/apiHost'
import { teamLogic } from 'scenes/teamLogic'

export function JSSnippet(): JSX.Element {
Expand All @@ -8,9 +9,7 @@ export function JSSnippet(): JSX.Element {
return (
<CodeSnippet language={Language.HTML}>{`<script>
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys onSessionId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('${currentTeam?.api_token}',{api_host:'${
window.location.origin === 'https://us.posthog.com' ? 'https://app.posthog.com' : window.location.origin
}'})
posthog.init('${currentTeam?.api_token}',{api_host:'${apiHostOrigin}'})
</script>`}</CodeSnippet>
)
}
22 changes: 14 additions & 8 deletions frontend/src/lib/components/PayGateMini/PayGateMini.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useValues } from 'kea'
import { FEATURE_MINIMUM_PLAN, POSTHOG_CLOUD_STANDARD_PLAN } from 'lib/constants'
import { IconEmojiPeople, IconLightBulb, IconLock, IconPremium } from 'lib/lemon-ui/icons'
import { LemonButton } from 'lib/lemon-ui/LemonButton'
import { capitalizeFirstLetter } from 'lib/utils'
import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic'
import { userLogic } from 'scenes/userLogic'

Expand Down Expand Up @@ -102,21 +103,22 @@ export function PayGateMini({
children,
overrideShouldShowGate,
}: PayGateMiniProps): JSX.Element | null {
const { preflight } = useValues(preflightLogic)
const { preflight, isCloudOrDev } = useValues(preflightLogic)
const { hasAvailableFeature } = useValues(userLogic)

const featureSummary = FEATURE_SUMMARIES[feature]
const planRequired = FEATURE_MINIMUM_PLAN[feature]
let gateVariant: 'add-card' | 'contact-sales' | 'subscribe' | null = null

let gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null = null
if (!overrideShouldShowGate && !hasAvailableFeature(feature)) {
if (preflight?.cloud) {
if (isCloudOrDev) {
if (planRequired === POSTHOG_CLOUD_STANDARD_PLAN) {
gateVariant = 'add-card'
} else {
gateVariant = 'contact-sales'
}
} else {
gateVariant = 'subscribe'
gateVariant = 'move-to-cloud'
}
}

Expand All @@ -129,7 +131,11 @@ export function PayGateMini({
<div className="PayGateMini__icon">{featureSummary.icon || <IconPremium />}</div>
<div className="PayGateMini__description">{featureSummary.description}</div>
<div className="PayGateMini__cta">
Subscribe to gain {featureSummary.umbrella}.
{gateVariant === 'move-to-cloud' ? (
<>{capitalizeFirstLetter(featureSummary.umbrella)} is available on PostHog Cloud.</>
) : (
<>Subscribe to gain {featureSummary.umbrella}.</>
)}
{featureSummary.docsHref && (
<>
{' '}
Expand All @@ -145,8 +151,8 @@ export function PayGateMini({
? '/organization/billing'
: gateVariant === 'contact-sales'
? `mailto:[email protected]?subject=Inquiring about ${featureSummary.umbrella}`
: gateVariant === 'subscribe'
? '/organization/billing'
: gateVariant === 'move-to-cloud'
? 'https://us.posthog.com/signup?utm_medium=in-product&utm_campaign=move-to-cloud'
: undefined
}
type="primary"
Expand All @@ -156,7 +162,7 @@ export function PayGateMini({
? 'Subscribe now'
: gateVariant === 'contact-sales'
? 'Contact sales'
: 'Subscribe'}
: 'Move to PostHog Cloud'}
</LemonButton>
</div>
) : (
Expand Down
26 changes: 20 additions & 6 deletions frontend/src/lib/components/PayGatePage/PayGatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { useValues } from 'kea'
import { LemonButton } from 'lib/lemon-ui/LemonButton'
import { identifierToHuman } from 'lib/utils'
import { billingLogic } from 'scenes/billing/billingLogic'
import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic'
import { urls } from 'scenes/urls'

import { AvailableFeature } from '~/types'

Expand All @@ -26,19 +28,31 @@ export function PayGatePage({
featureName,
}: PayGatePageInterface): JSX.Element {
const { upgradeLink } = useValues(billingLogic)
const { isCloudOrDev } = useValues(preflightLogic)
featureName = featureName || identifierToHuman(featureKey, 'title')

return (
<div className="pay-gate-page">
<h2>{header}</h2>
<div className="pay-caption">{caption}</div>
<div className="pay-buttons space-y-4">
{!hideUpgradeButton && (
<LemonButton to={upgradeLink} type="primary" data-attr={`${featureKey}-upgrade`} center>
Upgrade now to get {featureName}
</LemonButton>
)}
{docsLink && (
{!isCloudOrDev && <p>This feature is available on PostHog Cloud.</p>}
{!hideUpgradeButton &&
(isCloudOrDev ? (
<LemonButton to={upgradeLink} type="primary" data-attr={`${featureKey}-upgrade`} center>
Upgrade now to get {featureName}
</LemonButton>
) : (
<LemonButton
to={urls.moveToPostHogCloud()}
type="primary"
data-attr={`${featureKey}-upgrade`}
center
>
Learn more about PostHog Cloud
</LemonButton>
))}
{docsLink && isCloudOrDev && (
<LemonButton
type={hideUpgradeButton ? 'primary' : 'secondary'}
to={`${docsLink}?utm_medium=in-product&utm_campaign=${featureKey}-upgrade-learn-more`}
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/lib/utils/apiHost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function apiHostOrigin(): string {
let apiHost = window.location.origin
// similar to https://github.com/PostHog/posthog-js/blob/b79315b7a4fa0caded7026bda2fec01defb0ba73/src/posthog-core.ts#L1742
if (apiHost === 'https://us.posthog.com') {
apiHost = 'https://app.posthog.com'
}
return apiHost
}
1 change: 1 addition & 0 deletions frontend/src/scenes/appScenes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ export const appScenes: Record<Scene, () => any> = {
[Scene.Onboarding]: () => import('./onboarding/Onboarding'),
[Scene.OnboardingProductIntroduction]: () => import('./onboarding/OnboardingProductIntroduction'),
[Scene.Settings]: () => import('./settings/SettingsScene'),
[Scene.MoveToPostHogCloud]: () => import('./moveToPostHogCloud/MoveToPostHogCloud'),
}
41 changes: 8 additions & 33 deletions frontend/src/scenes/billing/Billing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { LemonButton, LemonDivider, LemonInput, Link } from '@posthog/lemon-ui'
import clsx from 'clsx'
import { useActions, useValues } from 'kea'
import { Field, Form } from 'kea-forms'
import { router } from 'kea-router'
import { SurprisedHog } from 'lib/components/hedgehogs'
import { PageHeader } from 'lib/components/PageHeader'
import { supportLogic } from 'lib/components/Support/supportLogic'
Expand All @@ -14,10 +15,10 @@ import { LemonBanner } from 'lib/lemon-ui/LemonBanner'
import { LemonLabel } from 'lib/lemon-ui/LemonLabel/LemonLabel'
import { SpinnerOverlay } from 'lib/lemon-ui/Spinner/Spinner'
import { Tooltip } from 'lib/lemon-ui/Tooltip'
import { capitalizeFirstLetter } from 'lib/utils'
import { useEffect } from 'react'
import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic'
import { SceneExport } from 'scenes/sceneTypes'
import { urls } from 'scenes/urls'

import { BillingHero } from './BillingHero'
import { billingLogic } from './billingLogic'
Expand Down Expand Up @@ -45,10 +46,13 @@ export function Billing(): JSX.Element {
isAnnualPlan,
} = useValues(billingLogic)
const { reportBillingV2Shown } = useActions(billingLogic)
const { preflight } = useValues(preflightLogic)
const cloudOrDev = preflight?.cloud || preflight?.is_debug
const { preflight, isCloudOrDev } = useValues(preflightLogic)
const { openSupportForm } = useActions(supportLogic)

if (preflight && !isCloudOrDev) {
router.actions.push(urls.default())
}

useEffect(() => {
if (billing) {
reportBillingV2Shown()
Expand Down Expand Up @@ -155,7 +159,7 @@ export function Billing(): JSX.Element {
You are currently on a free trial until <b>{billing.free_trial_until.format('LL')}</b>
</LemonBanner>
) : null}
{!billing?.has_active_subscription && cloudOrDev && (
{!billing?.has_active_subscription && (
<>
<div className="my-8">
<BillingHero />
Expand Down Expand Up @@ -238,35 +242,6 @@ export function Billing(): JSX.Element {
</div>
</div>
)}

{!cloudOrDev && (billing?.license?.plan || !billing?.has_active_subscription) && (
<div
className={clsx('space-y-2', {
'p-4': size === 'medium',
})}
// eslint-disable-next-line react/forbid-dom-props
style={{ width: size === 'medium' ? '20rem' : undefined }}
>
{!cloudOrDev && billing?.license?.plan ? (
<div className="bg-primary-alt-highlight text-primary-alt rounded p-2 px-4">
<div className="text-center font-bold">
{capitalizeFirstLetter(billing.license.plan)} license
</div>
<span>
Please contact <Link to="mailto:[email protected]">[email protected]</Link>{' '}
if you would like to make any changes to your license.
</span>
</div>
) : null}

{!cloudOrDev && !billing?.has_active_subscription ? (
<p>
Self-hosted licenses are no longer available for purchase. Please contact{' '}
<Link to="mailto:[email protected]">[email protected]</Link> to discuss options.
</p>
) : null}
</div>
)}
</div>

{!isOnboarding && billing?.has_active_subscription && (
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/scenes/experiments/ExperimentsPayGate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export function ExperimentsPayGate(): JSX.Element {
featureKey={AvailableFeature.EXPERIMENTATION}
header={
<>
Introducing <span className="highlight">Experimentation</span>!
Test changes with <span className="highlight">statistical significance</span>
</>
}
caption="Improve your product by A/B testing new features to discover what works best for your users."
caption="A/B tests, multivariate tests, and robust targeting & exclusion rules. Analyze usage with product analytics and session replay."
docsLink="https://posthog.com/docs/user-guides/experimentation"
/>
)
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/scenes/feature-flags/FeatureFlagSnippets.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useValues } from 'kea'
import { CodeSnippet, Language } from 'lib/components/CodeSnippet'
import { apiHostOrigin } from 'lib/utils/apiHost'
import { teamLogic } from 'scenes/teamLogic'

import { GroupType } from '~/types'
Expand Down Expand Up @@ -444,7 +445,7 @@ export function APISnippet({ groupType }: FeatureFlagSnippet): JSX.Element {
return (
<>
<CodeSnippet language={Language.Bash} wrap>
{`curl ${window.location.origin}/decide?v=3/ \\
{`curl ${apiHostOrigin()}/decide?v=3/ \\
-X POST -H 'Content-Type: application/json' \\
-d '{
"api_key": "${currentTeam ? currentTeam.api_token : '[project_api_key]'}",
Expand Down
Loading

0 comments on commit 8825950

Please sign in to comment.