diff --git a/frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.tsx b/frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.tsx index 9dc79c902c10d..b252a4a7a0757 100644 --- a/frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.tsx +++ b/frontend/src/lib/lemon-ui/LemonSwitch/LemonSwitch.tsx @@ -21,6 +21,8 @@ export interface LemonSwitchProps { tooltip?: string | JSX.Element | null handleContent?: React.ReactElement | null 'aria-label'?: string + sliderColorOverrideChecked?: string + sliderColorOverrideUnchecked?: string } /** Counter used for collision-less automatic switch IDs. */ @@ -44,6 +46,8 @@ export const LemonSwitch: React.FunctionComponent -
+
{handleContent}
) diff --git a/frontend/src/scenes/activity/live/liveEventsTableLogic.tsx b/frontend/src/scenes/activity/live/liveEventsTableLogic.tsx index a3fe1e9651635..5c18b2a266aef 100644 --- a/frontend/src/scenes/activity/live/liveEventsTableLogic.tsx +++ b/frontend/src/scenes/activity/live/liveEventsTableLogic.tsx @@ -26,6 +26,7 @@ export const liveEventsTableLogic = kea([ pollStats: true, setStats: (stats) => ({ stats }), showLiveStreamErrorToast: true, + addEventHost: (eventHost) => ({ eventHost }), })), reducers({ events: [ @@ -83,6 +84,17 @@ export const liveEventsTableLogic = kea([ }, }, ], + eventHosts: [ + [] as string[], + { + addEventHost: (state, { eventHost }) => { + if (!state.includes(eventHost)) { + return [...state, eventHost] + } + return state + }, + }, + ], }), selectors(({ selectors }) => ({ eventCount: [() => [selectors.events], (events: any) => events.length], @@ -177,6 +189,17 @@ export const liveEventsTableLogic = kea([ console.error('Failed to poll stats:', error) } }, + addEvents: ({ events }) => { + if (events.length > 0) { + const event = events[0] + const eventUrl = event.properties?.$current_url + if (eventUrl) { + const eventHost = new URL(eventUrl).host + const eventProtocol = new URL(eventUrl).protocol + actions.addEventHost(`${eventProtocol}//${eventHost}`) + } + } + }, })), events(({ actions, cache }) => ({ afterMount: () => { diff --git a/frontend/src/scenes/onboarding/Onboarding.tsx b/frontend/src/scenes/onboarding/Onboarding.tsx index 37c6bc42cdb7f..46427d3f4e0ee 100644 --- a/frontend/src/scenes/onboarding/Onboarding.tsx +++ b/frontend/src/scenes/onboarding/Onboarding.tsx @@ -109,6 +109,9 @@ const ProductAnalyticsOnboarding = (): JSX.Element => { // not sure if there is a better way to do this useValues(newDashboardLogic) + const showTemplateSteps = + featureFlags[FEATURE_FLAGS.ONBOARDING_DASHBOARD_TEMPLATES] == 'test' && window.innerWidth > 1000 + const options: ProductConfigOption[] = [ { title: 'Autocapture frontend interactions', @@ -165,10 +168,12 @@ const ProductAnalyticsOnboarding = (): JSX.Element => { stepKey={OnboardingStepKey.INSTALL} /> - {featureFlags[FEATURE_FLAGS.ONBOARDING_DASHBOARD_TEMPLATES] == 'test' ? ( + + {/* this is two conditionals because they need to be direct children of the wrapper */} + {showTemplateSteps ? ( ) : null} - {featureFlags[FEATURE_FLAGS.ONBOARDING_DASHBOARD_TEMPLATES] == 'test' ? ( + {showTemplateSteps ? ( ) : null} diff --git a/frontend/src/scenes/onboarding/onboardingLogic.tsx b/frontend/src/scenes/onboarding/onboardingLogic.tsx index 3446001b5f37f..19c29f133ad0c 100644 --- a/frontend/src/scenes/onboarding/onboardingLogic.tsx +++ b/frontend/src/scenes/onboarding/onboardingLogic.tsx @@ -2,6 +2,7 @@ import { actions, connect, kea, listeners, path, props, reducers, selectors } fr import { actionToUrl, router, urlToAction } from 'kea-router' import { featureFlagLogic } from 'lib/logic/featureFlagLogic' import { eventUsageLogic } from 'lib/utils/eventUsageLogic' +import { liveEventsTableLogic } from 'scenes/activity/live/liveEventsTableLogic' import { billingLogic } from 'scenes/billing/billingLogic' import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' import { Scene } from 'scenes/sceneTypes' @@ -110,6 +111,8 @@ export const getProductUri = (productKey: ProductKey): string => { export const onboardingLogic = kea([ props({} as OnboardingLogicProps), path(['scenes', 'onboarding', 'onboardingLogic']), + // connect this so we start collecting live events the whole time during onboarding + connect(liveEventsTableLogic), connect({ values: [ billingLogic, diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx index 38f67a46b7fee..483487e985b4e 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx @@ -17,6 +17,7 @@ import { iframedToolbarBrowserLogic } from 'lib/components/IframedToolbarBrowser import { useEffect, useRef, useState } from 'react' import { dashboardTemplateVariablesLogic } from 'scenes/dashboard/dashboardTemplateVariablesLogic' import { newDashboardLogic } from 'scenes/dashboard/newDashboardLogic' +import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' import { onboardingLogic, OnboardingStepKey } from '../onboardingLogic' import { OnboardingStep } from '../OnboardingStep' @@ -31,7 +32,7 @@ const UrlInput = ({ iframeRef }: { iframeRef: React.RefObject const { browserUrl, currentPath } = useValues( iframedToolbarBrowserLogic({ iframeRef, clearBrowserUrlOnUnmount: true }) ) - const { snippetHosts } = useValues(sdksLogic) + const { combinedSnippetAndLiveEventsHosts } = useValues(sdksLogic) const { addUrl } = useActions(authorizedUrlListLogic({ actionId: null, type: AuthorizedUrlListType.TOOLBAR_URLS })) const [inputValue, setInputValue] = useState(currentPath) @@ -56,7 +57,7 @@ const UrlInput = ({ iframeRef }: { iframeRef: React.RefObject ({ key: host, label: host }))} + options={combinedSnippetAndLiveEventsHosts.map((host) => ({ key: host, label: host }))} allowCustomValues={false} onChange={(v) => { addUrl(v[0]) @@ -86,7 +87,9 @@ const UrlInput = ({ iframeRef }: { iframeRef: React.RefObject export const SiteChooser = (): JSX.Element => { const iframeRef = useRef(null) - const { snippetHosts, hasSnippetEventsLoading } = useValues(sdksLogic) + const { combinedSnippetAndLiveEventsHosts, hasSnippetEventsLoading } = useValues(sdksLogic) + const { setStepKey } = useActions(onboardingLogic) + const { isCloud } = useValues(preflightLogic) const { setProposedBrowserUrl } = useActions( iframedToolbarBrowserLogic({ iframeRef, @@ -101,7 +104,6 @@ export const SiteChooser = (): JSX.Element => { automaticallyAuthorizeBrowserUrl: true, }) ) - const { setStepKey } = useActions(onboardingLogic) return ( <> @@ -122,15 +124,21 @@ export const SiteChooser = (): JSX.Element => {

Select where you want to track events from.

{hasSnippetEventsLoading ? ( - ) : snippetHosts.length > 0 ? ( + ) : combinedSnippetAndLiveEventsHosts.length > 0 ? ( <>

- Not seeing the site you want?{' '} - setStepKey(OnboardingStepKey.INSTALL)}>Install posthog-js or + Not seeing the site you want? Try clikcing around on your site to trigger a few events. + If you haven't yet,{' '} + setStepKey(OnboardingStepKey.INSTALL)}>install posthog-js or the HTML snippet wherever you want to track events, then come back here.

+ {isCloud && ( +

+ Note: Sites must be served over HTTPS to be selected. +

+ )}
- {snippetHosts.map((host) => ( + {combinedSnippetAndLiveEventsHosts.concat('https://posthog.com').map((host) => ( ) : (
-
+
{browserUrl && iframeBanner?.level != 'error' ? (
-
+
diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/onboardingTemplateConfigLogic.ts b/frontend/src/scenes/onboarding/productAnalyticsSteps/onboardingTemplateConfigLogic.ts index bb1080cd0c41a..dcc1d4ac6e0f3 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/onboardingTemplateConfigLogic.ts +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/onboardingTemplateConfigLogic.ts @@ -6,6 +6,7 @@ import { dashboardTemplateVariablesLogic } from 'scenes/dashboard/dashboardTempl import { newDashboardLogic } from 'scenes/dashboard/newDashboardLogic' import { urls } from 'scenes/urls' +import { sidePanelStateLogic } from '~/layout/navigation-3000/sidepanel/sidePanelStateLogic' import { DashboardTemplateType, DashboardType } from '~/types' import { onboardingLogic, OnboardingStepKey } from '../onboardingLogic' @@ -30,6 +31,8 @@ export const onboardingTemplateConfigLogic = kea([ path(['scenes', 'onboarding', 'sdks', 'sdksLogic']), connect({ - values: [onboardingLogic, ['productKey']], + values: [onboardingLogic, ['productKey'], liveEventsTableLogic, ['eventHosts']], }), actions({ setSourceFilter: (sourceFilter: string | null) => ({ sourceFilter }), @@ -118,6 +119,20 @@ export const sdksLogic = kea([ return Object.keys(availableSDKInstructionsMap).length > 5 && sourceOptions.length > 2 }, ], + combinedSnippetAndLiveEventsHosts: [ + (selectors) => [selectors.snippetHosts, selectors.eventHosts], + (snippetHosts: string[], eventHosts: string[]): string[] => { + const combinedSnippetAndLiveEventsHosts = snippetHosts + for (const host of eventHosts) { + const hostProtocol = new URL(host).protocol + const currentProtocol = window.location.protocol + if (hostProtocol === currentProtocol && !combinedSnippetAndLiveEventsHosts.includes(host)) { + combinedSnippetAndLiveEventsHosts.push(host) + } + } + return combinedSnippetAndLiveEventsHosts + }, + ], }), loaders(({ actions }) => ({ hasSnippetEvents: [ diff --git a/frontend/src/toolbar/actions/ActionAttribute.tsx b/frontend/src/toolbar/actions/ActionAttribute.tsx index ca74a79363c07..9e264edd4d753 100644 --- a/frontend/src/toolbar/actions/ActionAttribute.tsx +++ b/frontend/src/toolbar/actions/ActionAttribute.tsx @@ -58,15 +58,19 @@ export function ActionAttribute({ return (
{automaticActionCreationEnabled && ( - - checked - ? addAutomaticCreationIncludedPropertyKey(attribute) - : removeAutomaticCreationIncludedPropertyKey(attribute) - } - /> + <> + + checked + ? addAutomaticCreationIncludedPropertyKey(attribute) + : removeAutomaticCreationIncludedPropertyKey(attribute) + } + sliderColorOverrideChecked="primary-3000-light" + sliderColorOverrideUnchecked="muted-3000-light" + /> + )}
{icon}
{text}