Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Move onboarding into the app #20224

Merged
merged 54 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
39bb8f4
bring onboarding panels into the app
Jan 31, 2024
997fed2
tune up product intro page breadcrumbs
Jan 31, 2024
a5fd176
combine verification and config steps
Feb 1, 2024
c32ba42
add breadcrumbs, tune up topbar breadcrumbs
Feb 8, 2024
af9e8dd
tune up some buttons, step order
Feb 8, 2024
18cce74
mostly update the plans page
Feb 8, 2024
7b9ac96
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 8, 2024
3c4b26f
Update UI snapshots for `chromium` (2)
github-actions[bot] Feb 8, 2024
4a9f3f5
tune up state for not first product onboarding
Feb 8, 2024
a898296
Update UI snapshots for `chromium` (2)
github-actions[bot] Feb 8, 2024
8f7b98a
some type fixes
Feb 9, 2024
e693dad
fix up remaining tasks
Feb 9, 2024
9f04994
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 9, 2024
5929dee
make product intro onboarding step
Feb 9, 2024
f8ce3e7
show verification on install screen
Feb 9, 2024
02bb55e
fix a type error, update intro in stories
Feb 9, 2024
d70a43e
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 9, 2024
7df12c8
fix a type generation issue
Feb 12, 2024
9cfaea9
improve verify section
raquelmsmith Feb 13, 2024
78a564b
sentence case
raquelmsmith Feb 13, 2024
a50a5a5
make breadcrumbs smaller
raquelmsmith Feb 13, 2024
d3a2d26
fix intro pages
raquelmsmith Feb 13, 2024
856005b
fix breadcrumbs
raquelmsmith Feb 13, 2024
0d10c05
update padding on onboarding steps, remove other products step
Feb 13, 2024
fdcf860
mostly revert billing page changes?
Feb 14, 2024
5e27d56
highlight the navbar item
Feb 14, 2024
1de6a10
Merge remote-tracking branch 'origin/master' into by/onboarding-in-app
Feb 14, 2024
23bb966
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 14, 2024
5ad464c
fix type errors
Feb 14, 2024
cbe059f
Revert "Update UI snapshots for `chromium` (1)"
Feb 14, 2024
9c8cc78
Revert "Update UI snapshots for `chromium` (2)"
Feb 14, 2024
613b5a1
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 14, 2024
669773a
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 14, 2024
c2fb465
Update UI snapshots for `chromium` (2)
github-actions[bot] Feb 14, 2024
977f2f9
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 14, 2024
19ddf6b
constrain width of onboarding steps, remove new tag from notebooks nav
Feb 14, 2024
895e060
Merge remote-tracking branch 'origin/master' into by/onboarding-in-app
Feb 14, 2024
fc431fd
Update UI snapshots for `webkit` (2)
github-actions[bot] Feb 14, 2024
6f3abb4
fix some onboarding snapshots
Feb 14, 2024
d9760af
Revert "Update UI snapshots for `chromium` (2)"
Feb 14, 2024
5aad7ca
Revert "Update UI snapshots for `chromium` (1)"
Feb 14, 2024
c422e90
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 14, 2024
bdf3868
Update frontend/src/scenes/onboarding/OnboardingBillingStep.tsx
xrdt Feb 15, 2024
d39216a
Update UI snapshots for `webkit` (2)
github-actions[bot] Feb 15, 2024
9bdccae
wip
Feb 15, 2024
fb407d4
address pr comments
Feb 15, 2024
baaf23e
Update UI snapshots for `chromium` (1)
github-actions[bot] Feb 15, 2024
09bb9f6
Update UI snapshots for `webkit` (2)
github-actions[bot] Feb 15, 2024
beea51e
small change to upgrade button
Feb 15, 2024
6e22e3d
remove extraneous files
Feb 15, 2024
81b901c
Merge remote-tracking branch 'origin/master' into by/onboarding-in-app
Feb 15, 2024
0e2065b
Update UI snapshots for `webkit` (2)
github-actions[bot] Feb 15, 2024
f806174
Update UI snapshots for `webkit` (2)
github-actions[bot] Feb 15, 2024
7308e4d
Update UI snapshots for `webkit` (2)
github-actions[bot] Feb 15, 2024
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
159 changes: 93 additions & 66 deletions frontend/src/layout/navigation-3000/navigationLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
IconGraph,
IconHome,
IconLive,
IconLogomark,
IconNotebook,
IconPeople,
IconPieChart,
Expand Down Expand Up @@ -58,7 +59,14 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
path(['layout', 'navigation-3000', 'navigationLogic']),
props({} as { inputElement?: HTMLInputElement | null }),
connect(() => ({
values: [sceneLogic, ['sceneConfig'], navigationLogic, ['mobileLayout'], teamLogic, ['currentTeam']],
values: [
sceneLogic,
['sceneConfig'],
navigationLogic,
['mobileLayout'],
teamLogic,
['currentTeam', 'hasOnboardedAnyProduct'],
],
actions: [navigationLogic, ['closeAccountPopover']],
})),
actions({
Expand Down Expand Up @@ -324,76 +332,95 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
dashboardsModel.selectors.dashboardsLoading,
dashboardsModel.selectors.pinnedDashboards,
s.currentTeam,
s.hasOnboardedAnyProduct,
],
(featureFlags, dashboardsLoading, pinnedDashboards, currentTeam): NavbarItem[][] => {
(
featureFlags,
dashboardsLoading,
pinnedDashboards,
currentTeam,
hasOnboardedAnyProduct
): NavbarItem[][] => {
const isUsingSidebar = featureFlags[FEATURE_FLAGS.POSTHOG_3000_NAV]
const hasOnboardedFeatureFlags = currentTeam?.has_completed_onboarding_for?.[ProductKey.FEATURE_FLAGS]
return [
[
{
identifier: Scene.ProjectHomepage,
label: 'Home',
icon: <IconHome />,
to: urls.projectHomepage(),
},
{
identifier: Scene.Dashboards,
label: 'Dashboards',
icon: <IconDashboard />,
logic: isUsingSidebar ? dashboardsSidebarLogic : undefined,
to: isUsingSidebar ? undefined : urls.dashboards(),
sideAction: {
identifier: 'pinned-dashboards-dropdown',
dropdown: {
overlay: (
<LemonMenuOverlay
items={[
{
title: 'Pinned dashboards',
items: pinnedDashboards.map((dashboard) => ({
label: dashboard.name,
to: urls.dashboard(dashboard.id),
})),
footer: dashboardsLoading && (
<div className="px-2 py-1 text-text-secondary-3000">
<Spinner /> Loading…
</div>
),
},
]}
/>
),
placement: 'bottom-end',
},
const sectionOne: NavbarItem[] = [
{
identifier: Scene.Dashboards,
label: 'Dashboards',
icon: <IconDashboard />,
logic: isUsingSidebar ? dashboardsSidebarLogic : undefined,
to: isUsingSidebar ? undefined : urls.dashboards(),
sideAction: {
identifier: 'pinned-dashboards-dropdown',
dropdown: {
overlay: (
<LemonMenuOverlay
items={[
{
title: 'Pinned dashboards',
items: pinnedDashboards.map((dashboard) => ({
label: dashboard.name,
to: urls.dashboard(dashboard.id),
})),
footer: dashboardsLoading && (
<div className="px-2 py-1 text-text-secondary-3000">
<Spinner /> Loading…
</div>
),
},
]}
/>
),
placement: 'bottom-end',
},
},
{
identifier: Scene.Notebooks,
label: 'Notebooks',
icon: <IconNotebook />,
to: urls.notebooks(),
},
{
identifier: Scene.DataManagement,
label: 'Data management',
icon: <IconDatabase />,
logic: isUsingSidebar ? dataManagementSidebarLogic : undefined,
to: isUsingSidebar ? undefined : urls.eventDefinitions(),
},
{
identifier: Scene.PersonsManagement,
label: 'People',
icon: <IconPeople />,
logic: isUsingSidebar ? personsAndGroupsSidebarLogic : undefined,
to: isUsingSidebar ? undefined : urls.persons(),
},
{
identifier: Scene.Events,
label: 'Activity',
icon: <IconLive />,
to: urls.events(),
},
],
},
{
identifier: Scene.Notebooks,
label: 'Notebooks',
icon: <IconNotebook />,
to: urls.notebooks(),
},
{
identifier: Scene.DataManagement,
label: 'Data management',
icon: <IconDatabase />,
logic: isUsingSidebar ? dataManagementSidebarLogic : undefined,
to: isUsingSidebar ? undefined : urls.eventDefinitions(),
},
{
identifier: Scene.PersonsManagement,
label: 'People',
icon: <IconPeople />,
logic: isUsingSidebar ? personsAndGroupsSidebarLogic : undefined,
to: isUsingSidebar ? undefined : urls.persons(),
},
{
identifier: Scene.Events,
label: 'Activity',
icon: <IconLive />,
to: urls.events(),
},
]

sectionOne.unshift(
hasOnboardedAnyProduct
? {
identifier: Scene.ProjectHomepage,
label: 'Home',
icon: <IconHome />,
to: urls.projectHomepage(),
}
: {
identifier: Scene.Products,
label: 'Welcome to PostHog',
icon: <IconLogomark />,
to: urls.products(),
}
)

return [
sectionOne,
[
{
identifier: Scene.SavedInsights,
Expand Down
1 change: 0 additions & 1 deletion frontend/src/scenes/appScenes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export const appScenes: Record<Scene, () => any> = {
[Scene.Canvas]: () => import('./notebooks/NotebookCanvasScene'),
[Scene.Products]: () => import('./products/Products'),
[Scene.Onboarding]: () => import('./onboarding/Onboarding'),
[Scene.OnboardingProductIntroduction]: () => import('./onboarding/OnboardingProductIntroduction'),
[Scene.Settings]: () => import('./settings/SettingsScene'),
[Scene.MoveToPostHogCloud]: () => import('./moveToPostHogCloud/MoveToPostHogCloud'),
}
73 changes: 9 additions & 64 deletions frontend/src/scenes/billing/PlanComparison.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import './PlanComparison.scss'

import { LemonButton, LemonModal, LemonTag, Link } from '@posthog/lemon-ui'
import { LemonModal, LemonTag } from '@posthog/lemon-ui'
import clsx from 'clsx'
import { useActions, useValues } from 'kea'
import { useValues } from 'kea'
import { IconCheckmark, IconClose, IconWarning } from 'lib/lemon-ui/icons'
import { Tooltip } from 'lib/lemon-ui/Tooltip'
import { eventUsageLogic } from 'lib/utils/eventUsageLogic'
import React from 'react'
import { getProductIcon } from 'scenes/products/Products'
import useResizeObserver from 'use-resize-observer'

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

import { convertLargeNumberToWords, getUpgradeProductLink } from './billing-utils'
import { convertLargeNumberToWords } from './billing-utils'
import { billingLogic } from './billingLogic'

export function PlanIcon({
Expand Down Expand Up @@ -109,44 +108,9 @@ export const PlanComparison = ({
return null
}
const fullyFeaturedPlan = plans[plans.length - 1]
const { reportBillingUpgradeClicked } = useActions(eventUsageLogic)
const { redirectPath, billing } = useValues(billingLogic)
const { billing } = useValues(billingLogic)
const { width, ref: planComparisonRef } = useResizeObserver()

const upgradeButtons = plans?.map((plan) => {
xrdt marked this conversation as resolved.
Show resolved Hide resolved
return (
<td key={`${plan.plan_key}-cta`} className="PlanTable__td__upgradeButton">
<LemonButton
to={getUpgradeProductLink(product, plan.plan_key || '', redirectPath, includeAddons)}
type={plan.current_plan ? 'secondary' : 'primary'}
status={plan.current_plan ? 'default' : 'alt'}
fullWidth
center
disableClientSideRouting
disabled={plan.current_plan}
onClick={() => {
if (!plan.current_plan) {
reportBillingUpgradeClicked(product.type)
}
}}
>
{plan.current_plan ? 'Current plan' : 'Subscribe'}
</LemonButton>
{!plan.current_plan && includeAddons && product.addons?.length > 0 && (
<p className="text-center ml-0 mt-2 mb-0">
<Link
to={`/api/billing-v2/activation?products=${product.type}:${plan.plan_key}&redirect_path=${redirectPath}`}
className="text-muted text-xs"
disableClientSideRouting
>
or subscribe without addons
</Link>
</p>
)}
</td>
)
})

return (
<table className="PlanComparison w-full table-fixed" ref={planComparisonRef}>
<thead>
Expand All @@ -160,15 +124,6 @@ export const PlanComparison = ({
</tr>
</thead>
<tbody>
{/* Pricing section */}
<tr>
<th
colSpan={3}
className="PlanTable__th__section bg-side text-muted justify-left rounded text-left mb-2"
>
<span>Pricing</span>
</th>
</tr>
<tr className="PlanTable__tr__border">
<td className="font-bold">Monthly base price</td>
{plans?.map((plan) => (
Expand Down Expand Up @@ -222,20 +177,10 @@ export const PlanComparison = ({
})}

<tr>
<td />
{upgradeButtons}
</tr>
<tr>
<th colSpan={3} className="PlanTable__th__section bg-side justify-left rounded text-left mb-2">
<div className="flex items-center gap-x-2 my-2">
{getProductIcon(product.icon_key, 'text-2xl')}
<Tooltip title={product.description}>
<span className="font-bold">{product.name}</span>
</Tooltip>
</div>
<th colSpan={1} className="PlanTable__th__section rounded text-left">
<h3 className="mt-6 mb-2">Product Features:</h3>
</th>
</tr>

{fullyFeaturedPlan?.features?.map((feature, i) => (
<tr
key={`tr-${feature.key}`}
Expand Down Expand Up @@ -270,12 +215,12 @@ export const PlanComparison = ({
{!billing?.has_active_subscription && (
<>
<tr>
<th colSpan={3} className="PlanTable__th__section rounded text-left">
<p className="mt-6 mb-2 italic text-center text-muted">
<th colSpan={1} className="PlanTable__th__section rounded text-left">
<h3 className="mt-6 mb-2">
<Tooltip title="Organizations with any paid subscription get access to additional features.">
Included platform features:
</Tooltip>
</p>
</h3>
</th>
</tr>
{billing?.products
Expand Down
43 changes: 3 additions & 40 deletions frontend/src/scenes/onboarding/Onboarding.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const _OnboardingSDKs = (): JSX.Element => {
useEffect(() => {
const product: BillingProductV2Type = billingJson.products[1] as unknown as BillingProductV2Type
setProduct(product)
router.actions.push(urls.onboarding(ProductKey.SESSION_REPLAY) + '?step=sdks')
router.actions.push(urls.onboarding(ProductKey.SESSION_REPLAY) + '?step=install')
}, [])
return <App />
}
Expand All @@ -64,45 +64,8 @@ export const _OnboardingBilling = (): JSX.Element => {
const { setProduct } = useActions(onboardingLogic)

useEffect(() => {
setProduct(billingJson.products[1] as unknown as BillingProductV2Type)
router.actions.push(urls.onboarding(ProductKey.SESSION_REPLAY, OnboardingStepKey.BILLING))
}, [])
return <App />
}

export const _OnboardingOtherProducts = (): JSX.Element => {
useStorybookMocks({
get: {
'/api/billing-v2/': {
...billingJson,
},
},
})

const { setProduct } = useActions(onboardingLogic)

useEffect(() => {
setProduct(billingJson.products[1] as unknown as BillingProductV2Type)
router.actions.push(urls.onboarding(ProductKey.SESSION_REPLAY, OnboardingStepKey.OTHER_PRODUCTS))
}, [])
return <App />
}
_OnboardingOtherProducts.tags = ['test-skip'] // FIXME: For some reason this is captured correctly the first time, but then is written over a second time with SDKs view

export const _OnboardingProductIntroduction = (): JSX.Element => {
useStorybookMocks({
get: {
'/api/billing-v2/': {
...billingJson,
},
},
})

const { setProduct } = useActions(onboardingLogic)

useEffect(() => {
setProduct(billingJson.products[0])
router.actions.push(urls.onboardingProductIntroduction(ProductKey.PRODUCT_ANALYTICS))
setProduct(billingUnsubscribedJson.products[1] as unknown as BillingProductV2Type)
router.actions.push(urls.onboarding(ProductKey.SESSION_REPLAY, OnboardingStepKey.PLANS))
}, [])
return <App />
}
Loading
Loading