From bd6e21d0c2131ecf8184229318d50e1352ea9998 Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Thu, 5 Sep 2024 13:23:55 -0700 Subject: [PATCH 01/17] hook into the iframe a bit, save actions automatically --- .../IframedToolbarBrowser.tsx | 4 +- .../iframedToolbarBrowserLogic.ts | 29 ++++++++++++-- .../components/IframedToolbarBrowser/utils.ts | 2 + .../DashboardTemplateConfigureStep.tsx | 2 +- .../DashboardTemplateVariables.tsx | 29 ++++++++++++-- .../src/toolbar/actions/actionsTabLogic.tsx | 40 ++++++++++++++++--- frontend/src/toolbar/bar/toolbarLogic.ts | 12 +++++- .../src/toolbar/elements/elementsLogic.ts | 1 + 8 files changed, 102 insertions(+), 17 deletions(-) diff --git a/frontend/src/lib/components/IframedToolbarBrowser/IframedToolbarBrowser.tsx b/frontend/src/lib/components/IframedToolbarBrowser/IframedToolbarBrowser.tsx index 3e34575b31c96..aa32b83e36ee7 100644 --- a/frontend/src/lib/components/IframedToolbarBrowser/IframedToolbarBrowser.tsx +++ b/frontend/src/lib/components/IframedToolbarBrowser/IframedToolbarBrowser.tsx @@ -35,10 +35,10 @@ export function IframedToolbarBrowser({ iframeRef, userIntent, }: { - iframeRef?: React.MutableRefObject + iframeRef: React.MutableRefObject userIntent: ToolbarUserIntent }): JSX.Element | null { - const logic = iframedToolbarBrowserLogic() + const logic = iframedToolbarBrowserLogic({ iframeRef, userIntent: userIntent }) const { browserUrl } = useValues(logic) const { onIframeLoad, setIframeWidth } = useActions(logic) diff --git a/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts b/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts index 71a59fdde32a1..f60838e83eed5 100644 --- a/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts +++ b/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts @@ -10,11 +10,14 @@ import { LemonBannerProps } from 'lib/lemon-ui/LemonBanner' import posthog from 'posthog-js' import { RefObject } from 'react' +import { ToolbarUserIntent } from '~/types' + import type { iframedToolbarBrowserLogicType } from './iframedToolbarBrowserLogicType' export type IframedToolbarBrowserLogicProps = { iframeRef: RefObject clearBrowserUrlOnUnmount?: boolean + userIntent?: ToolbarUserIntent } export interface IFrameBanner { @@ -50,6 +53,9 @@ export const iframedToolbarBrowserLogic = kea([ setIframeBanner: (banner: IFrameBanner | null) => ({ banner }), startTrackingLoading: true, stopTrackingLoading: true, + enableElementSelector: true, + disableElementSelector: true, + setNewActionName: (name: string | null) => ({ name }), }), reducers({ @@ -138,7 +144,7 @@ export const iframedToolbarBrowserLogic = kea([ '*' ) }, - + // heatmaps patchHeatmapFilters: ({ filters }) => { actions.sendToolbarMessage(PostHogAppToolbarEvent.PH_PATCH_HEATMAP_FILTERS, { filters }) }, @@ -159,6 +165,17 @@ export const iframedToolbarBrowserLogic = kea([ actions.sendToolbarMessage(PostHogAppToolbarEvent.PH_HEATMAPS_COMMON_FILTERS, { commonFilters: filters }) }, + // actions + enableElementSelector: () => { + actions.sendToolbarMessage(PostHogAppToolbarEvent.PH_ELEMENT_SELECTOR, { enabled: true }) + }, + disableElementSelector: () => { + actions.sendToolbarMessage(PostHogAppToolbarEvent.PH_ELEMENT_SELECTOR, { enabled: false }) + }, + setNewActionName: ({ name }) => { + actions.sendToolbarMessage(PostHogAppToolbarEvent.PH_NEW_ACTION_NAME, { name }) + }, + onIframeLoad: () => { // we get this callback whether the iframe loaded successfully or not // and don't get a signal if the load was successful, so we have to check @@ -171,9 +188,13 @@ export const iframedToolbarBrowserLogic = kea([ fixedPositionMode: values.heatmapFixedPositionMode, commonFilters: values.commonFilters, }) - actions.sendToolbarMessage(PostHogAppToolbarEvent.PH_HEATMAPS_CONFIG, { - enabled: true, - }) + switch (props.userIntent) { + case 'heatmaps': + actions.sendToolbarMessage(PostHogAppToolbarEvent.PH_HEATMAPS_CONFIG, { + enabled: true, + }) + break + } } const onIframeMessage = (e: MessageEvent): void => { diff --git a/frontend/src/lib/components/IframedToolbarBrowser/utils.ts b/frontend/src/lib/components/IframedToolbarBrowser/utils.ts index dbb47dd057d3c..1fc509d407f6c 100644 --- a/frontend/src/lib/components/IframedToolbarBrowser/utils.ts +++ b/frontend/src/lib/components/IframedToolbarBrowser/utils.ts @@ -14,6 +14,8 @@ export enum PostHogAppToolbarEvent { PH_TOOLBAR_HEATMAP_LOADING = 'ph-toolbar-heatmap-loading', PH_TOOLBAR_HEATMAP_LOADED = 'ph-toolbar-heatmap-loaded', PH_TOOLBAR_HEATMAP_FAILED = 'ph-toolbar-heatmap-failed', + PH_ELEMENT_SELECTOR = 'ph-element-selector', + PH_NEW_ACTION_NAME = 'ph-new-action-name', } export const DEFAULT_HEATMAP_FILTERS: HeatmapFilters = { diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx index 2bed8e8a07d2f..e9f87cbadefff 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx @@ -116,7 +116,7 @@ export const OnboardingDashboardTemplateConfigureStep = ({ {' '} (no need to send it now) .

- + }): JSX.Element { const { activeDashboardTemplate } = useValues(newDashboardLogic) const theDashboardTemplateVariablesLogic = dashboardTemplateVariablesLogic({ @@ -23,6 +26,9 @@ function VariableSelector({ const { allVariablesAreTouched, variables, activeVariableIndex } = useValues(theDashboardTemplateVariablesLogic) const [customEventName, setCustomEventName] = useState(null) const [showCustomEventField, setShowCustomEventField] = useState(false) + const { enableElementSelector, disableElementSelector, setNewActionName } = useActions( + iframedToolbarBrowserLogic({ iframeRef, clearBrowserUrlOnUnmount: true }) + ) const FALLBACK_EVENT = { id: '$other_event', @@ -131,12 +137,21 @@ function VariableSelector({ status="alt" onClick={() => { setShowCustomEventField(false) + enableElementSelector() + setNewActionName(variable.name) setVariable(variable.name, { events: [FALLBACK_EVENT] }) }} > Select from site - setShowCustomEventField(true)}> + { + disableElementSelector() + setNewActionName(null) + setShowCustomEventField(true) + }} + > Use custom event @@ -147,7 +162,13 @@ function VariableSelector({ ) } -export function DashboardTemplateVariables({ hasSelectedSite }: { hasSelectedSite: boolean }): JSX.Element { +export function DashboardTemplateVariables({ + hasSelectedSite, + iframeRef, +}: { + hasSelectedSite: boolean + iframeRef: React.RefObject +}): JSX.Element { const { activeDashboardTemplate } = useValues(newDashboardLogic) const theDashboardTemplateVariablesLogic = dashboardTemplateVariablesLogic({ variables: activeDashboardTemplate?.variables || [], @@ -172,7 +193,9 @@ export function DashboardTemplateVariables({ hasSelectedSite }: { hasSelectedSit {v.touched && } ), - content: , + content: ( + + ), className: 'p-4 bg-white', onHeaderClick: () => { setActiveVariableIndex(i) diff --git a/frontend/src/toolbar/actions/actionsTabLogic.tsx b/frontend/src/toolbar/actions/actionsTabLogic.tsx index 759d410d00f97..e59353d4c287a 100644 --- a/frontend/src/toolbar/actions/actionsTabLogic.tsx +++ b/frontend/src/toolbar/actions/actionsTabLogic.tsx @@ -15,9 +15,9 @@ import { ActionType, ElementType } from '~/types' import type { actionsTabLogicType } from './actionsTabLogicType' -function newAction(element: HTMLElement | null, dataAttributes: string[] = []): ActionDraftType { +function newAction(element: HTMLElement | null, dataAttributes: string[] = [], name: string | null): ActionDraftType { return { - name: '', + name: name || '', steps: [element ? actionStepToActionStepFormItem(elementToActionStep(element, dataAttributes), true) : {}], pinned_at: null, } @@ -67,6 +67,7 @@ export const actionsTabLogic = kea([ hideButtonActions: true, setShowActionsTooltip: (showActionsTooltip: boolean) => ({ showActionsTooltip }), setElementSelector: (selector: string, index: number) => ({ selector, index }), + setAutomaticActionCreationEnabled: (enabled: boolean, name?: string) => ({ enabled, name }), }), connect(() => ({ @@ -142,6 +143,18 @@ export const actionsTabLogic = kea([ setShowActionsTooltip: (_, { showActionsTooltip }) => showActionsTooltip, }, ], + automaticActionCreationEnabled: [ + false as boolean, + { + setAutomaticActionCreationEnabled: (_, { enabled }) => enabled, + }, + ], + newActionName: [ + null as string | null, + { + setAutomaticActionCreationEnabled: (_, { enabled, name }) => (enabled && name ? name : null), + }, + ], }), forms(({ values, actions }) => ({ @@ -211,22 +224,34 @@ export const actionsTabLogic = kea([ }, ], selectedAction: [ - (s) => [s.selectedActionId, s.newActionForElement, s.allActions, s.dataAttributes], + (s) => [s.selectedActionId, s.newActionForElement, s.allActions, s.dataAttributes, s.newActionName], ( selectedActionId, newActionForElement, allActions, - dataAttributes + dataAttributes, + newActionName ): ActionType | ActionDraftType | null => { if (selectedActionId === 'new') { - return newAction(newActionForElement, dataAttributes) + return newAction(newActionForElement, dataAttributes, newActionName) } return allActions.find((a) => a.id === selectedActionId) || null }, ], + isReadyForAutomaticSubmit: [ + (s) => [s.automaticActionCreationEnabled, s.selectedAction, s.actionForm], + (automaticActionCreationEnabled, selectedAction, actionForm): boolean => { + return ( + (automaticActionCreationEnabled && + selectedAction?.name && + actionForm.steps?.[0]?.selector_selected) || + false // annoying type requirement + ) + }, + ], }), - subscriptions(({ actions }) => ({ + subscriptions(({ actions, values }) => ({ selectedAction: (selectedAction: ActionType | ActionDraftType | null) => { if (!selectedAction) { actions.setActionFormValues({ name: null, steps: [{}] }) @@ -237,6 +262,9 @@ export const actionsTabLogic = kea([ ? selectedAction.steps.map((step) => actionStepToActionStepFormItem(step, false)) : [{}], }) + if (values.isReadyForAutomaticSubmit) { + actions.submitActionForm() + } } }, })), diff --git a/frontend/src/toolbar/bar/toolbarLogic.ts b/frontend/src/toolbar/bar/toolbarLogic.ts index 20148d0ca3b40..67d0a3b1dda30 100644 --- a/frontend/src/toolbar/bar/toolbarLogic.ts +++ b/frontend/src/toolbar/bar/toolbarLogic.ts @@ -31,7 +31,7 @@ export const toolbarLogic = kea([ connect(() => ({ actions: [ actionsTabLogic, - ['showButtonActions', 'hideButtonActions', 'selectAction'], + ['showButtonActions', 'hideButtonActions', 'selectAction', 'setAutomaticActionCreationEnabled'], elementsLogic, ['enableInspect', 'disableInspect', 'createAction'], heatmapLogic, @@ -440,6 +440,16 @@ export const toolbarLogic = kea([ case PostHogAppToolbarEvent.PH_HEATMAPS_COMMON_FILTERS: actions.setCommonFilters(e.data.payload.commonFilters) return + case PostHogAppToolbarEvent.PH_ELEMENT_SELECTOR: + if (e.data.payload.enabled) { + actions.enableInspect() + } else { + actions.disableInspect() + } + return + case PostHogAppToolbarEvent.PH_NEW_ACTION_NAME: + actions.setAutomaticActionCreationEnabled(true, e.data.payload.name) + return default: console.warn(`[PostHog Toolbar] Received unknown parent window message: ${type}`) } diff --git a/frontend/src/toolbar/elements/elementsLogic.ts b/frontend/src/toolbar/elements/elementsLogic.ts index eb019fdfe3edb..c7060ea5ba547 100644 --- a/frontend/src/toolbar/elements/elementsLogic.ts +++ b/frontend/src/toolbar/elements/elementsLogic.ts @@ -405,6 +405,7 @@ export const elementsLogic = kea([ }, createAction: ({ element }) => { actions.selectElement(null) + // this just sets the action form actions.newAction(element) }, })), From 22113a5eeefd3c32bb8808f3423b2a109e0012f7 Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 10:55:49 -0700 Subject: [PATCH 02/17] accept actions in the variables --- .../dashboardTemplateVariablesLogic.ts | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts index da23d22466d25..68a95508bb995 100644 --- a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts +++ b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts @@ -1,7 +1,7 @@ import { actions, kea, listeners, path, props, propsChanged, reducers, selectors } from 'kea' import { isEmptyObject } from 'lib/utils' -import { DashboardTemplateVariableType, FilterType, Optional } from '~/types' +import { DashboardTemplateVariableType, EntityType, FilterType, Optional } from '~/types' import type { dashboardTemplateVariablesLogicType } from './dashboardTemplateVariablesLogicType' @@ -43,10 +43,23 @@ export const dashboardTemplateVariablesLogic = kea { - // TODO: handle actions as well as events + // There is only one type with contents at a time + // So iterate through the types to find the first one with contents + const typeWithContents: EntityType = Object.keys(filterGroup).filter( + (group) => (filterGroup[group as EntityType] || [])?.length > 0 + )?.[0] as EntityType + + if (!typeWithContents) { + return state + } + return state.map((v: DashboardTemplateVariableType) => { - if (v.name === variableName && filterGroup?.events?.length && filterGroup.events[0]) { - return { ...v, default: filterGroup.events[0], touched: true } + if ( + v.name === variableName && + filterGroup?.[typeWithContents]?.length && + filterGroup[typeWithContents][0] + ) { + return { ...v, default: filterGroup[typeWithContents][0], touched: true } } return { ...v } }) From c92be08d1a8507530e6aac60826debb338e5f1de Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 12:26:48 -0700 Subject: [PATCH 03/17] make it work kinda --- .../iframedToolbarBrowserLogic.ts | 8 ++++ .../components/IframedToolbarBrowser/utils.ts | 1 + .../dashboardTemplateVariablesLogic.ts | 41 ++++++++++++++++++- .../DashboardTemplateVariables.tsx | 27 +++++++----- .../src/toolbar/actions/actionsTabLogic.tsx | 3 ++ frontend/src/toolbar/bar/toolbarLogic.ts | 12 +++++- frontend/src/types.ts | 3 ++ 7 files changed, 82 insertions(+), 13 deletions(-) diff --git a/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts b/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts index f60838e83eed5..31f2a49fa1781 100644 --- a/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts +++ b/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts @@ -56,6 +56,7 @@ export const iframedToolbarBrowserLogic = kea([ enableElementSelector: true, disableElementSelector: true, setNewActionName: (name: string | null) => ({ name }), + toolbarMessageReceived: (type: PostHogAppToolbarEvent, payload: Record) => ({ type, payload }), }), reducers({ @@ -199,6 +200,9 @@ export const iframedToolbarBrowserLogic = kea([ const onIframeMessage = (e: MessageEvent): void => { const type: PostHogAppToolbarEvent = e?.data?.type + const payload = e?.data?.payload + + actions.toolbarMessageReceived(type, payload) if (!type || !type.startsWith('ph-')) { return @@ -244,6 +248,10 @@ export const iframedToolbarBrowserLogic = kea([ actions.stopTrackingLoading() actions.setIframeBanner({ level: 'error', message: 'The heatmap failed to load.' }) return + case PostHogAppToolbarEvent.PH_NEW_ACTION_CREATED: + actions.setNewActionName(null) + actions.disableElementSelector() + return default: console.warn(`[PostHog Heatmaps] Received unknown child window message: ${type}`) } diff --git a/frontend/src/lib/components/IframedToolbarBrowser/utils.ts b/frontend/src/lib/components/IframedToolbarBrowser/utils.ts index 1fc509d407f6c..87d9cae13cf9f 100644 --- a/frontend/src/lib/components/IframedToolbarBrowser/utils.ts +++ b/frontend/src/lib/components/IframedToolbarBrowser/utils.ts @@ -16,6 +16,7 @@ export enum PostHogAppToolbarEvent { PH_TOOLBAR_HEATMAP_FAILED = 'ph-toolbar-heatmap-failed', PH_ELEMENT_SELECTOR = 'ph-element-selector', PH_NEW_ACTION_NAME = 'ph-new-action-name', + PH_NEW_ACTION_CREATED = 'ph-new-action-created', } export const DEFAULT_HEATMAP_FILTERS: HeatmapFilters = { diff --git a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts index 68a95508bb995..b15011282801a 100644 --- a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts +++ b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts @@ -1,7 +1,17 @@ -import { actions, kea, listeners, path, props, propsChanged, reducers, selectors } from 'kea' +import { actions, connect, kea, listeners, path, props, propsChanged, reducers, selectors } from 'kea' +import { iframedToolbarBrowserLogic } from 'lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic' +import { PostHogAppToolbarEvent } from 'lib/components/IframedToolbarBrowser/utils' import { isEmptyObject } from 'lib/utils' -import { DashboardTemplateVariableType, EntityType, FilterType, Optional } from '~/types' +import { + ActionType, + BaseMathType, + DashboardTemplateVariableType, + EntityType, + EntityTypes, + FilterType, + Optional, +} from '~/types' import type { dashboardTemplateVariablesLogicType } from './dashboardTemplateVariablesLogicType' @@ -18,12 +28,16 @@ const FALLBACK_EVENT = { export const dashboardTemplateVariablesLogic = kea([ path(['scenes', 'dashboard', 'DashboardTemplateVariablesLogic']), props({ variables: [] } as DashboardTemplateVariablesLogicProps), + connect({ + actions: [iframedToolbarBrowserLogic, ['toolbarMessageReceived']], + }), actions({ setVariables: (variables: DashboardTemplateVariableType[]) => ({ variables }), setVariable: (variableName: string, filterGroup: Optional) => ({ variable_name: variableName, filterGroup, }), + setVariableFromAction: (variableName: string, action: ActionType) => ({ variableName, action }), setActiveVariableIndex: (index: number) => ({ index }), incrementActiveVariableIndex: true, possiblyIncrementActiveVariableIndex: true, @@ -116,6 +130,29 @@ export const dashboardTemplateVariablesLogic = kea { + const filterGroup: FilterType = { + actions: [ + // TODO: This needs a type + { + id: action.id, + math: BaseMathType.UniqueUsers, + name: action.name, + order: 0, + type: EntityTypes.ACTIONS, + selector: action.steps?.[0]?.selector, + href: action.steps?.[0]?.href, + url: action.steps?.[0]?.url, + }, + ], + } + actions.setVariable(variableName, filterGroup) + }, + toolbarMessageReceived: ({ type, payload }) => { + if (type === PostHogAppToolbarEvent.PH_NEW_ACTION_CREATED) { + actions.setVariableFromAction(payload.action.name, payload.action as ActionType) + } + }, })), propsChanged(({ actions, props }, oldProps) => { if (props.variables !== oldProps.variables) { diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx index 148d3227fbb74..902c67568b929 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx @@ -1,4 +1,4 @@ -import { IconCheckCircle, IconInfo, IconTrash } from '@posthog/icons' +import { IconCheckCircle, IconCursorClick, IconInfo, IconTrash } from '@posthog/icons' import { LemonBanner, LemonButton, LemonCollapse, LemonInput, LemonLabel } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { iframedToolbarBrowserLogic } from 'lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic' @@ -9,11 +9,11 @@ import { newDashboardLogic } from 'scenes/dashboard/newDashboardLogic' import { DashboardTemplateVariableType } from '~/types' function VariableSelector({ - variable, + variableName, hasSelectedSite, iframeRef, }: { - variable: DashboardTemplateVariableType + variableName: string hasSelectedSite: boolean iframeRef: React.RefObject }): JSX.Element { @@ -30,10 +30,9 @@ function VariableSelector({ iframedToolbarBrowserLogic({ iframeRef, clearBrowserUrlOnUnmount: true }) ) - const FALLBACK_EVENT = { - id: '$other_event', - math: 'dau', - type: 'events', + const variable: DashboardTemplateVariableType | undefined = variables.find((v) => v.name === variableName) + if (!variable) { + return <> } return ( @@ -48,7 +47,11 @@ function VariableSelector({
{' '} Selected -

.md-invite-button

+

+ {variable.default.selector} +

+

{variable.default.href}

+

{variable.default.url}

Select from site @@ -194,7 +196,12 @@ export function DashboardTemplateVariables({
), content: ( - + ), className: 'p-4 bg-white', onHeaderClick: () => { diff --git a/frontend/src/toolbar/actions/actionsTabLogic.tsx b/frontend/src/toolbar/actions/actionsTabLogic.tsx index e59353d4c287a..1650edfb71002 100644 --- a/frontend/src/toolbar/actions/actionsTabLogic.tsx +++ b/frontend/src/toolbar/actions/actionsTabLogic.tsx @@ -68,6 +68,7 @@ export const actionsTabLogic = kea([ setShowActionsTooltip: (showActionsTooltip: boolean) => ({ showActionsTooltip }), setElementSelector: (selector: string, index: number) => ({ selector, index }), setAutomaticActionCreationEnabled: (enabled: boolean, name?: string) => ({ enabled, name }), + actionCreatedSuccess: (action: ActionType) => ({ action }), }), connect(() => ({ @@ -194,6 +195,8 @@ export const actionsTabLogic = kea([ action: () => window.open(`${apiURL}${urls.action(response.id)}`, '_blank'), }, }) + + actions.actionCreatedSuccess(response) }, // whether we show errors after touch (true) or submit (false) diff --git a/frontend/src/toolbar/bar/toolbarLogic.ts b/frontend/src/toolbar/bar/toolbarLogic.ts index 67d0a3b1dda30..a126593dbd005 100644 --- a/frontend/src/toolbar/bar/toolbarLogic.ts +++ b/frontend/src/toolbar/bar/toolbarLogic.ts @@ -31,7 +31,13 @@ export const toolbarLogic = kea([ connect(() => ({ actions: [ actionsTabLogic, - ['showButtonActions', 'hideButtonActions', 'selectAction', 'setAutomaticActionCreationEnabled'], + [ + 'showButtonActions', + 'hideButtonActions', + 'selectAction', + 'setAutomaticActionCreationEnabled', + 'actionCreatedSuccess', + ], elementsLogic, ['enableInspect', 'disableInspect', 'createAction'], heatmapLogic, @@ -393,6 +399,10 @@ export const toolbarLogic = kea([ // if embedded we need to signal start and finish of heatmap loading to the parent window.parent.postMessage({ type: PostHogAppToolbarEvent.PH_TOOLBAR_HEATMAP_FAILED }, '*') }, + actionCreatedSuccess: (action) => { + // if embedded, we need to tell the parent window that a new action was created + window.parent.postMessage({ type: PostHogAppToolbarEvent.PH_NEW_ACTION_CREATED, payload: action }, '*') + }, })), afterMount(({ actions, values, cache }) => { cache.clickListener = (e: MouseEvent): void => { diff --git a/frontend/src/types.ts b/frontend/src/types.ts index d1aaa92a6007f..72312cf58ef0c 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -1801,6 +1801,9 @@ export interface DashboardTemplateVariableType { default: Record required: boolean touched?: boolean + selector?: string + href?: string + url?: string } export type DashboardLayoutSize = 'sm' | 'xs' From 6ba5a1a168b1f9f6bb7358b98f2a99d66164d672 Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 13:25:16 -0700 Subject: [PATCH 04/17] handle duplicate action names --- frontend/src/toolbar/actions/actionsTabLogic.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/frontend/src/toolbar/actions/actionsTabLogic.tsx b/frontend/src/toolbar/actions/actionsTabLogic.tsx index 1650edfb71002..ac18cce316149 100644 --- a/frontend/src/toolbar/actions/actionsTabLogic.tsx +++ b/frontend/src/toolbar/actions/actionsTabLogic.tsx @@ -172,6 +172,19 @@ export const actionsTabLogic = kea([ const { apiURL, temporaryToken } = values const { selectedActionId } = values + const findUniqueActionName = (baseName: string, index = 0): string => { + const proposedName = index === 0 ? baseName : `${baseName} - ${index}` + if (!values.allActions.find((action) => action.name === proposedName)) { + return proposedName + } + return findUniqueActionName(baseName, index + 1) + } + + if (values.newActionName) { + // newActionName is programmatically set, but they may already have an existing action with that name. Append an index. + actionToSave.name = findUniqueActionName(values.newActionName) + } + let response: ActionType if (selectedActionId && selectedActionId !== 'new') { response = await api.update( From e9a7a1e104c255b55dfe1a07bdd8af3e8294f5db Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 14:00:07 -0700 Subject: [PATCH 05/17] disable the selector after action created --- .../scenes/dashboard/dashboardTemplateVariablesLogic.ts | 6 ++++-- .../productAnalyticsSteps/DashboardTemplateVariables.tsx | 7 +++++++ frontend/src/toolbar/actions/actionsTabLogic.tsx | 2 +- frontend/src/toolbar/bar/toolbarLogic.ts | 1 + 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts index b15011282801a..a09230b086356 100644 --- a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts +++ b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts @@ -29,7 +29,7 @@ export const dashboardTemplateVariablesLogic = kea ({ variables }), @@ -131,6 +131,7 @@ export const dashboardTemplateVariablesLogic = kea { + const originalVariableName = variableName.replace(/\s-\s\d+/g, '') const filterGroup: FilterType = { actions: [ // TODO: This needs a type @@ -146,11 +147,12 @@ export const dashboardTemplateVariablesLogic = kea { if (type === PostHogAppToolbarEvent.PH_NEW_ACTION_CREATED) { actions.setVariableFromAction(payload.action.name, payload.action as ActionType) + actions.disableElementSelector() } }, })), diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx index 902c67568b929..29050b1058734 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx @@ -101,6 +101,8 @@ function VariableSelector({ type="tertiary" size="small" onClick={() => { + disableElementSelector() + setNewActionName(null) resetVariable(variable.id) setCustomEventName(null) setShowCustomEventField(false) @@ -177,6 +179,9 @@ export function DashboardTemplateVariables({ }) const { variables, activeVariableIndex } = useValues(theDashboardTemplateVariablesLogic) const { setVariables, setActiveVariableIndex } = useActions(theDashboardTemplateVariablesLogic) + const { setNewActionName, disableElementSelector } = useActions( + iframedToolbarBrowserLogic({ iframeRef, clearBrowserUrlOnUnmount: true }) + ) // TODO: onboarding-dashboard-templates: this is a hack, I'm not sure why it's not set properly initially. useEffect(() => { @@ -206,6 +211,8 @@ export function DashboardTemplateVariables({ className: 'p-4 bg-white', onHeaderClick: () => { setActiveVariableIndex(i) + disableElementSelector() + setNewActionName(null) }, }))} embedded diff --git a/frontend/src/toolbar/actions/actionsTabLogic.tsx b/frontend/src/toolbar/actions/actionsTabLogic.tsx index ac18cce316149..f976b56a3bfd9 100644 --- a/frontend/src/toolbar/actions/actionsTabLogic.tsx +++ b/frontend/src/toolbar/actions/actionsTabLogic.tsx @@ -147,7 +147,7 @@ export const actionsTabLogic = kea([ automaticActionCreationEnabled: [ false as boolean, { - setAutomaticActionCreationEnabled: (_, { enabled }) => enabled, + setAutomaticActionCreationEnabled: (_, { enabled, name }) => (enabled && !!name) || false, }, ], newActionName: [ diff --git a/frontend/src/toolbar/bar/toolbarLogic.ts b/frontend/src/toolbar/bar/toolbarLogic.ts index a126593dbd005..75b510881c64d 100644 --- a/frontend/src/toolbar/bar/toolbarLogic.ts +++ b/frontend/src/toolbar/bar/toolbarLogic.ts @@ -455,6 +455,7 @@ export const toolbarLogic = kea([ actions.enableInspect() } else { actions.disableInspect() + actions.hideButtonActions() } return case PostHogAppToolbarEvent.PH_NEW_ACTION_NAME: From f5316276accf786d1fcb57ea6a12429b4e7dbf7b Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 14:11:54 -0700 Subject: [PATCH 06/17] design --- .../DashboardTemplateVariables.tsx | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx index 29050b1058734..a6b726007b5d6 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx @@ -1,4 +1,4 @@ -import { IconCheckCircle, IconCursorClick, IconInfo, IconTrash } from '@posthog/icons' +import { IconCheckCircle, IconInfo, IconTarget, IconTrash } from '@posthog/icons' import { LemonBanner, LemonButton, LemonCollapse, LemonInput, LemonLabel } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { iframedToolbarBrowserLogic } from 'lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic' @@ -45,13 +45,22 @@ function VariableSelector({ {variable.touched && !customEventName && (
- {' '} - Selected -

- {variable.default.selector} +

+ {' '} + Selected

-

{variable.default.href}

-

{variable.default.url}

+
+

+ CSS selector:{' '} + {variable.default.selector || 'not set'} +

+

+ Element href: {variable.default.href || 'not set'} +

+

+ Page URL: {variable.default.url || 'any url'} +

+
} > Select from site From 0787087241cbf9fca90743c246c14104d46b8553 Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 14:17:59 -0700 Subject: [PATCH 07/17] fix duplicate creation --- frontend/src/toolbar/actions/actionsTabLogic.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/toolbar/actions/actionsTabLogic.tsx b/frontend/src/toolbar/actions/actionsTabLogic.tsx index f976b56a3bfd9..45d209145bf4d 100644 --- a/frontend/src/toolbar/actions/actionsTabLogic.tsx +++ b/frontend/src/toolbar/actions/actionsTabLogic.tsx @@ -199,8 +199,8 @@ export const actionsTabLogic = kea([ } breakpoint() - actionsLogic.actions.updateAction({ action: response }) actions.selectAction(null) + actionsLogic.actions.updateAction({ action: response }) lemonToast.success('Action saved', { button: { From 6c4441ccc0920f53420b6a06c5074a465795c0d3 Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 14:20:25 -0700 Subject: [PATCH 08/17] don't show the creation success banner in automatic mode --- frontend/src/toolbar/actions/actionsTabLogic.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/frontend/src/toolbar/actions/actionsTabLogic.tsx b/frontend/src/toolbar/actions/actionsTabLogic.tsx index 45d209145bf4d..46729c1fa8263 100644 --- a/frontend/src/toolbar/actions/actionsTabLogic.tsx +++ b/frontend/src/toolbar/actions/actionsTabLogic.tsx @@ -144,6 +144,7 @@ export const actionsTabLogic = kea([ setShowActionsTooltip: (_, { showActionsTooltip }) => showActionsTooltip, }, ], + // we automatically create actions for people from analytics onboarding. This flag controls that experience. automaticActionCreationEnabled: [ false as boolean, { @@ -202,12 +203,14 @@ export const actionsTabLogic = kea([ actions.selectAction(null) actionsLogic.actions.updateAction({ action: response }) - lemonToast.success('Action saved', { - button: { - label: 'Open in PostHog', - action: () => window.open(`${apiURL}${urls.action(response.id)}`, '_blank'), - }, - }) + if (!values.automaticActionCreationEnabled) { + lemonToast.success('Action saved', { + button: { + label: 'Open in PostHog', + action: () => window.open(`${apiURL}${urls.action(response.id)}`, '_blank'), + }, + }) + } actions.actionCreatedSuccess(response) }, From 50006e0bed3be228fc808e100199a85ea5eaf02e Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 14:32:31 -0700 Subject: [PATCH 09/17] don't track loading success fo rnow.. --- .../iframedToolbarBrowserLogic.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts b/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts index 31f2a49fa1781..2d21dc51b8305 100644 --- a/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts +++ b/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts @@ -220,14 +220,17 @@ export const iframedToolbarBrowserLogic = kea([ case PostHogAppToolbarEvent.PH_TOOLBAR_INIT: return init() case PostHogAppToolbarEvent.PH_TOOLBAR_READY: - posthog.capture('in-app heatmap frame loaded', { - inapp_heatmap_page_url_visited: values.browserUrl, - inapp_heatmap_filters: values.heatmapFilters, - inapp_heatmap_color_palette: values.heatmapColorPalette, - inapp_heatmap_fixed_position_mode: values.heatmapFixedPositionMode, - }) - // reset loading tracking - if we're e.g. slow this will avoid a flash of warning message - return actions.startTrackingLoading() + if (props.userIntent === 'heatmaps') { + posthog.capture('in-app heatmap frame loaded', { + inapp_heatmap_page_url_visited: values.browserUrl, + inapp_heatmap_filters: values.heatmapFilters, + inapp_heatmap_color_palette: values.heatmapColorPalette, + inapp_heatmap_fixed_position_mode: values.heatmapFixedPositionMode, + }) + // reset loading tracking - if we're e.g. slow this will avoid a flash of warning message + return actions.startTrackingLoading() + } + return case PostHogAppToolbarEvent.PH_TOOLBAR_HEATMAP_LOADING: return actions.startTrackingLoading() case PostHogAppToolbarEvent.PH_TOOLBAR_HEATMAP_LOADED: From cf5d96e595378f0fc9e6084a3aa526cdd363a4ab Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Fri, 6 Sep 2024 14:38:37 -0700 Subject: [PATCH 10/17] fix types --- .../src/scenes/dashboard/dashboardTemplateVariablesLogic.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts index a09230b086356..3546a3c8d61bf 100644 --- a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts +++ b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts @@ -71,9 +71,9 @@ export const dashboardTemplateVariablesLogic = kea Date: Mon, 9 Sep 2024 13:04:39 -0700 Subject: [PATCH 11/17] let people cancel the element selection explicitly --- .../iframedToolbarBrowserLogic.ts | 6 +- .../dashboardTemplateVariablesLogic.ts | 8 +++ .../DashboardTemplateVariables.tsx | 60 +++++++++++++------ 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts b/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts index 2d21dc51b8305..a2d74018d6aa8 100644 --- a/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts +++ b/frontend/src/lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic.ts @@ -59,7 +59,7 @@ export const iframedToolbarBrowserLogic = kea([ toolbarMessageReceived: (type: PostHogAppToolbarEvent, payload: Record) => ({ type, payload }), }), - reducers({ + reducers(({ props }) => ({ // they're called common filters in the toolbar because they're shared between heatmaps and clickmaps // the name is continued here since they're passed down into the embedded iframe commonFilters: [ @@ -94,7 +94,7 @@ export const iframedToolbarBrowserLogic = kea([ ], browserUrl: [ null as string | null, - { persist: true }, + { persist: props.userIntent == 'heatmaps' }, { setBrowserUrl: (_, { url }) => url, }, @@ -114,7 +114,7 @@ export const iframedToolbarBrowserLogic = kea([ setIframeBanner: (_, { banner }) => banner, }, ], - }), + })), selectors({ isBrowserUrlAuthorized: [ diff --git a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts index 3546a3c8d61bf..4e2b706f1f484 100644 --- a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts +++ b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts @@ -43,6 +43,7 @@ export const dashboardTemplateVariablesLogic = kea ({ variableId }), goToNextUntouchedActiveVariableIndex: true, + setIsCurrentlySelectingElement: (isSelecting: boolean) => ({ isSelecting }), }), reducers({ variables: [ @@ -95,6 +96,12 @@ export const dashboardTemplateVariablesLogic = kea state + 1, }, ], + isCurrentlySelectingElement: [ + false as boolean, + { + setIsCurrentlySelectingElement: (_, { isSelecting }) => isSelecting, + }, + ], }), selectors(() => ({ activeVariable: [ @@ -148,6 +155,7 @@ export const dashboardTemplateVariablesLogic = kea { if (type === PostHogAppToolbarEvent.PH_NEW_ACTION_CREATED) { diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx index a6b726007b5d6..04fc5512b7639 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx @@ -1,5 +1,5 @@ import { IconCheckCircle, IconInfo, IconTarget, IconTrash } from '@posthog/icons' -import { LemonBanner, LemonButton, LemonCollapse, LemonInput, LemonLabel } from '@posthog/lemon-ui' +import { LemonBanner, LemonButton, LemonCollapse, LemonInput, LemonLabel, Spinner } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { iframedToolbarBrowserLogic } from 'lib/components/IframedToolbarBrowser/iframedToolbarBrowserLogic' import { useEffect, useState } from 'react' @@ -21,9 +21,16 @@ function VariableSelector({ const theDashboardTemplateVariablesLogic = dashboardTemplateVariablesLogic({ variables: activeDashboardTemplate?.variables || [], }) - const { setVariable, resetVariable, goToNextUntouchedActiveVariableIndex, incrementActiveVariableIndex } = - useActions(theDashboardTemplateVariablesLogic) - const { allVariablesAreTouched, variables, activeVariableIndex } = useValues(theDashboardTemplateVariablesLogic) + const { + setVariable, + resetVariable, + goToNextUntouchedActiveVariableIndex, + incrementActiveVariableIndex, + setIsCurrentlySelectingElement, + } = useActions(theDashboardTemplateVariablesLogic) + const { allVariablesAreTouched, variables, activeVariableIndex, isCurrentlySelectingElement } = useValues( + theDashboardTemplateVariablesLogic + ) const [customEventName, setCustomEventName] = useState(null) const [showCustomEventField, setShowCustomEventField] = useState(false) const { enableElementSelector, disableElementSelector, setNewActionName } = useActions( @@ -146,24 +153,40 @@ function VariableSelector({ ) : (
- { - setShowCustomEventField(false) - enableElementSelector() - setNewActionName(variable.name) - }} - icon={} - > - Select from site - + {isCurrentlySelectingElement ? ( + { + disableElementSelector() + setNewActionName(null) + setIsCurrentlySelectingElement(false) + }} + icon={} + > + Cancel selection + + ) : ( + { + setShowCustomEventField(false) + enableElementSelector() + setNewActionName(variable.name) + setIsCurrentlySelectingElement(true) + }} + icon={} + > + Select from site + + )} { disableElementSelector() setNewActionName(null) setShowCustomEventField(true) + setIsCurrentlySelectingElement(false) }} > Use custom event @@ -188,7 +211,9 @@ export function DashboardTemplateVariables({ variables: activeDashboardTemplate?.variables || [], }) const { variables, activeVariableIndex } = useValues(theDashboardTemplateVariablesLogic) - const { setVariables, setActiveVariableIndex } = useActions(theDashboardTemplateVariablesLogic) + const { setVariables, setActiveVariableIndex, setIsCurrentlySelectingElement } = useActions( + theDashboardTemplateVariablesLogic + ) const { setNewActionName, disableElementSelector } = useActions( iframedToolbarBrowserLogic({ iframeRef, clearBrowserUrlOnUnmount: true }) ) @@ -223,6 +248,7 @@ export function DashboardTemplateVariables({ setActiveVariableIndex(i) disableElementSelector() setNewActionName(null) + setIsCurrentlySelectingElement(false) }, }))} embedded From a5ba68f580d1afcf095210c8b5043e744fe38947 Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Mon, 9 Sep 2024 13:44:34 -0700 Subject: [PATCH 12/17] Fix dashboard creation for actions --- .../dashboardTemplateVariablesLogic.ts | 25 +++++++++---------- frontend/src/types.ts | 11 ++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts index 4e2b706f1f484..c00b6db484370 100644 --- a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts +++ b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts @@ -11,6 +11,7 @@ import { EntityTypes, FilterType, Optional, + TemplateVariableStep, } from '~/types' import type { dashboardTemplateVariablesLogicType } from './dashboardTemplateVariablesLogicType' @@ -139,20 +140,18 @@ export const dashboardTemplateVariablesLogic = kea { const originalVariableName = variableName.replace(/\s-\s\d+/g, '') + const step: TemplateVariableStep = { + id: action.id.toString(), + math: BaseMathType.UniqueUsers, + name: action.name, + order: 0, + type: EntityTypes.ACTIONS, + selector: action.steps?.[0]?.selector, + href: action.steps?.[0]?.href, + url: action.steps?.[0]?.url, + } const filterGroup: FilterType = { - actions: [ - // TODO: This needs a type - { - id: action.id, - math: BaseMathType.UniqueUsers, - name: action.name, - order: 0, - type: EntityTypes.ACTIONS, - selector: action.steps?.[0]?.selector, - href: action.steps?.[0]?.href, - url: action.steps?.[0]?.url, - }, - ], + actions: [step], } actions.setVariable(originalVariableName, filterGroup) actions.setIsCurrentlySelectingElement(false) diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 72312cf58ef0c..cd436d848ce99 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -2135,6 +2135,17 @@ export interface FilterType { aggregation_group_type_index?: integer // Groups aggregation } +export interface TemplateVariableStep { + id: string + math: BaseMathType + name: string | null + order: number + type: EntityTypes + selector?: string | null + href?: string | null + url?: string | null +} + export interface PropertiesTimelineFilterType { date_from?: string | null // DateMixin date_to?: string | null // DateMixin From a6f2515e757e661f2cd411eb68f10b5fda604af4 Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Mon, 9 Sep 2024 13:45:45 -0700 Subject: [PATCH 13/17] fix --- frontend/src/toolbar/actions/actionsTabLogic.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/toolbar/actions/actionsTabLogic.tsx b/frontend/src/toolbar/actions/actionsTabLogic.tsx index 46729c1fa8263..f9d00f60cb003 100644 --- a/frontend/src/toolbar/actions/actionsTabLogic.tsx +++ b/frontend/src/toolbar/actions/actionsTabLogic.tsx @@ -264,7 +264,7 @@ export const actionsTabLogic = kea([ (automaticActionCreationEnabled && selectedAction?.name && actionForm.steps?.[0]?.selector_selected) || - false // annoying type requirement + false ) }, ], From 7f07577e38c3d3ffb822416cbc8c54f8c095f72d Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Mon, 9 Sep 2024 14:12:38 -0700 Subject: [PATCH 14/17] add tip for navigating before selecting --- .../productAnalyticsSteps/DashboardTemplateVariables.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx index 04fc5512b7639..8440a5146f2a7 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx @@ -49,6 +49,13 @@ function VariableSelector({ {variable.description}

+ {!showCustomEventField && activeVariableIndex == 0 && hasSelectedSite && ( + +

+ Tip: Navigate to the page you want before you start selecting. +

+
+ )} {variable.touched && !customEventName && (
From bd771411baf0d2ceab65939869c78d18f8611eec Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Mon, 9 Sep 2024 19:06:10 -0700 Subject: [PATCH 15/17] let people toggle the different attributes --- .../DashboardTemplateVariables.tsx | 2 +- .../src/toolbar/actions/ActionAttribute.tsx | 28 +++++++++- frontend/src/toolbar/actions/ActionStep.tsx | 14 ++++- .../src/toolbar/actions/actionsTabLogic.tsx | 51 +++++++++++++++++-- frontend/src/toolbar/elements/ElementInfo.tsx | 19 ++++--- frontend/src/toolbar/utils.ts | 22 +++++--- frontend/src/types.ts | 1 + 7 files changed, 113 insertions(+), 24 deletions(-) diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx index 8440a5146f2a7..02a7450dbe165 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx @@ -49,7 +49,7 @@ function VariableSelector({ {variable.description}

- {!showCustomEventField && activeVariableIndex == 0 && hasSelectedSite && ( + {!showCustomEventField && activeVariableIndex == 0 && hasSelectedSite && !variable.touched && (

Tip: Navigate to the page you want before you start selecting. diff --git a/frontend/src/toolbar/actions/ActionAttribute.tsx b/frontend/src/toolbar/actions/ActionAttribute.tsx index c8cd2c68898b0..ca74a79363c07 100644 --- a/frontend/src/toolbar/actions/ActionAttribute.tsx +++ b/frontend/src/toolbar/actions/ActionAttribute.tsx @@ -1,6 +1,10 @@ -import { Link } from '@posthog/lemon-ui' +import { LemonSwitch, Link } from '@posthog/lemon-ui' +import { useActions, useValues } from 'kea' import { IconBranch, IconClipboardEdit, IconLink, IconTextSize } from 'lib/lemon-ui/icons' +import { actionsTabLogic } from './actionsTabLogic' +import { ActionStepPropertyKey } from './ActionStep' + function SelectorString({ value }: { value: string }): JSX.Element { const [last, ...rest] = value.split(' ').reverse() return ( @@ -10,7 +14,16 @@ function SelectorString({ value }: { value: string }): JSX.Element { ) } -export function ActionAttribute({ attribute, value }: { attribute: string; value?: string }): JSX.Element { +export function ActionAttribute({ + attribute, + value, +}: { + attribute: ActionStepPropertyKey + value?: string +}): JSX.Element { + const { automaticCreationIncludedPropertyKeys, automaticActionCreationEnabled } = useValues(actionsTabLogic) + const { removeAutomaticCreationIncludedPropertyKey, addAutomaticCreationIncludedPropertyKey } = + useActions(actionsTabLogic) const icon = attribute === 'text' ? ( @@ -44,6 +57,17 @@ export function ActionAttribute({ attribute, value }: { attribute: string; value return (

+ {automaticActionCreationEnabled && ( + + checked + ? addAutomaticCreationIncludedPropertyKey(attribute) + : removeAutomaticCreationIncludedPropertyKey(attribute) + } + /> + )}
{icon}
{text}
diff --git a/frontend/src/toolbar/actions/ActionStep.tsx b/frontend/src/toolbar/actions/ActionStep.tsx index f0d6272d01b8b..a2a34a43412a7 100644 --- a/frontend/src/toolbar/actions/ActionStep.tsx +++ b/frontend/src/toolbar/actions/ActionStep.tsx @@ -1,16 +1,26 @@ +import { useValues } from 'kea' + import { ActionAttribute } from '~/toolbar/actions/ActionAttribute' import { ActionStepType } from '~/types' +import { actionsTabLogic } from './actionsTabLogic' + interface ActionStepProps { actionStep: ActionStepType } -type ActionStepPropertyKey = 'text' | 'name' | 'href' | 'selector' +export type ActionStepPropertyKey = 'text' | 'name' | 'href' | 'selector' | 'url' export function ActionStep({ actionStep }: ActionStepProps): JSX.Element { + const { automaticActionCreationEnabled } = useValues(actionsTabLogic) + + const stepTypes = ['text', 'name', 'href', 'selector', automaticActionCreationEnabled ? 'url' : null].filter( + (key) => key + ) as ActionStepPropertyKey[] + return (
- {(['text', 'name', 'href', 'selector'] as ActionStepPropertyKey[]).map((attr) => + {stepTypes.map((attr) => actionStep[attr] || attr === 'selector' ? ( ) : null diff --git a/frontend/src/toolbar/actions/actionsTabLogic.tsx b/frontend/src/toolbar/actions/actionsTabLogic.tsx index f9d00f60cb003..be2b0fa13f160 100644 --- a/frontend/src/toolbar/actions/actionsTabLogic.tsx +++ b/frontend/src/toolbar/actions/actionsTabLogic.tsx @@ -14,11 +14,25 @@ import { actionStepToActionStepFormItem, elementToActionStep, stepToDatabaseForm import { ActionType, ElementType } from '~/types' import type { actionsTabLogicType } from './actionsTabLogicType' +import { ActionStepPropertyKey } from './ActionStep' -function newAction(element: HTMLElement | null, dataAttributes: string[] = [], name: string | null): ActionDraftType { +function newAction( + element: HTMLElement | null, + dataAttributes: string[] = [], + name: string | null, + includedPropertyKeys?: ActionStepPropertyKey[] +): ActionDraftType { return { name: name || '', - steps: [element ? actionStepToActionStepFormItem(elementToActionStep(element, dataAttributes), true) : {}], + steps: [ + element + ? actionStepToActionStepFormItem( + elementToActionStep(element, dataAttributes), + true, + includedPropertyKeys + ) + : {}, + ], pinned_at: null, } } @@ -69,6 +83,9 @@ export const actionsTabLogic = kea([ setElementSelector: (selector: string, index: number) => ({ selector, index }), setAutomaticActionCreationEnabled: (enabled: boolean, name?: string) => ({ enabled, name }), actionCreatedSuccess: (action: ActionType) => ({ action }), + setautomaticCreationIncludedPropertyKeys: (keys: ActionStepPropertyKey[]) => ({ keys }), + removeAutomaticCreationIncludedPropertyKey: (key: ActionStepPropertyKey) => ({ key }), + addAutomaticCreationIncludedPropertyKey: (key: ActionStepPropertyKey) => ({ key }), }), connect(() => ({ @@ -157,6 +174,17 @@ export const actionsTabLogic = kea([ setAutomaticActionCreationEnabled: (_, { enabled, name }) => (enabled && name ? name : null), }, ], + automaticCreationIncludedPropertyKeys: [ + [] as ActionStepPropertyKey[], + { + setAutomaticActionCreationEnabled: (_, { enabled }) => + enabled ? ['text', 'href', 'name', 'selector', 'url'] : [], + setautomaticCreationIncludedPropertyKeys: (_, { keys }) => keys || [], + removeAutomaticCreationIncludedPropertyKey: (state, { key }) => state.filter((k) => k !== key), + addAutomaticCreationIncludedPropertyKey: (state, { key }) => + !state.includes(key) ? [...state, key] : state, + }, + ], }), forms(({ values, actions }) => ({ @@ -243,16 +271,29 @@ export const actionsTabLogic = kea([ }, ], selectedAction: [ - (s) => [s.selectedActionId, s.newActionForElement, s.allActions, s.dataAttributes, s.newActionName], + (s) => [ + s.selectedActionId, + s.newActionForElement, + s.allActions, + s.dataAttributes, + s.newActionName, + s.automaticCreationIncludedPropertyKeys, + ], ( selectedActionId, newActionForElement, allActions, dataAttributes, - newActionName + newActionName, + automaticCreationIncludedPropertyKeys ): ActionType | ActionDraftType | null => { if (selectedActionId === 'new') { - return newAction(newActionForElement, dataAttributes, newActionName) + return newAction( + newActionForElement, + dataAttributes, + newActionName, + automaticCreationIncludedPropertyKeys + ) } return allActions.find((a) => a.id === selectedActionId) || null }, diff --git a/frontend/src/toolbar/elements/ElementInfo.tsx b/frontend/src/toolbar/elements/ElementInfo.tsx index 151367d229ad3..c4459838ed561 100644 --- a/frontend/src/toolbar/elements/ElementInfo.tsx +++ b/frontend/src/toolbar/elements/ElementInfo.tsx @@ -7,6 +7,8 @@ import { ActionStep } from '~/toolbar/actions/ActionStep' import { elementsLogic } from '~/toolbar/elements/elementsLogic' import { heatmapLogic } from '~/toolbar/elements/heatmapLogic' +import { actionsTabLogic } from '../actions/actionsTabLogic' + function ElementStatistic({ prefix, suffix, @@ -34,6 +36,7 @@ export function ElementInfo(): JSX.Element | null { const { activeMeta } = useValues(elementsLogic) const { createAction } = useActions(elementsLogic) + const { automaticActionCreationEnabled } = useValues(actionsTabLogic) if (!activeMeta) { return null @@ -79,16 +82,20 @@ export function ElementInfo(): JSX.Element | null { ) : null} {/* eslint-disable-next-line react/forbid-dom-props */}
-

Actions ({activeMeta.actions.length})

+ {!automaticActionCreationEnabled && ( + <> +

Actions ({activeMeta.actions.length})

- {activeMeta.actions.length === 0 ? ( -

No actions include this element

- ) : ( - a.action)} /> + {activeMeta.actions.length === 0 ? ( +

No actions include this element

+ ) : ( + a.action)} /> + )} + )} createAction(element)} icon={}> - Create a new action + {automaticActionCreationEnabled ? 'Select element' : 'Create a new action'}
diff --git a/frontend/src/toolbar/utils.ts b/frontend/src/toolbar/utils.ts index ade5110122b76..65f8285cbc189 100644 --- a/frontend/src/toolbar/utils.ts +++ b/frontend/src/toolbar/utils.ts @@ -7,6 +7,8 @@ import { CSSProperties } from 'react' import { ActionStepForm, ElementRect } from '~/toolbar/types' import { ActionStepType } from '~/types' +import { ActionStepPropertyKey } from './actions/ActionStep' + export const TOOLBAR_ID = '__POSTHOG_TOOLBAR__' export const LOCALSTORAGE_KEY = '_postHogToolbarParams' @@ -265,7 +267,11 @@ export function getBoxColors(color: 'blue' | 'red' | 'green', hover = false, opa } } -export function actionStepToActionStepFormItem(step: ActionStepType, isNew = false): ActionStepForm { +export function actionStepToActionStepFormItem( + step: ActionStepType, + isNew = false, + includedPropertyKeys?: ActionStepPropertyKey[] +): ActionStepForm { if (!step) { return {} } @@ -281,24 +287,24 @@ export function actionStepToActionStepFormItem(step: ActionStepType, isNew = fal ...step, href_selected: true, selector_selected: hasSelector, - text_selected: false, - url_selected: false, + text_selected: includedPropertyKeys?.includes('text') || false, + url_selected: includedPropertyKeys?.includes('url') || false, } } else if (step.tag_name === 'button') { return { ...step, text_selected: true, selector_selected: hasSelector, - href_selected: false, - url_selected: false, + href_selected: includedPropertyKeys?.includes('href') || false, + url_selected: includedPropertyKeys?.includes('url') || false, } } return { ...step, selector_selected: hasSelector, - text_selected: false, - url_selected: false, - href_selected: false, + text_selected: includedPropertyKeys?.includes('text') || false, + url_selected: includedPropertyKeys?.includes('url') || false, + href_selected: includedPropertyKeys?.includes('href') || false, } } diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 2929f2828599a..a6db8171f301e 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -568,6 +568,7 @@ export interface ActionStepType { url?: string | null /** @default StringMatching.Contains */ url_matching?: ActionStepStringMatching | null + name?: string | null } export interface ElementType { From 564a678386cc52daa600becd4a69f043414e43ce Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Mon, 9 Sep 2024 20:37:48 -0700 Subject: [PATCH 16/17] let people cancel --- .../dashboardTemplateVariablesLogic.ts | 6 +++ .../DashboardTemplateConfigureStep.tsx | 50 ++++++++++++------- .../DashboardTemplateVariables.tsx | 11 +++- 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts index c00b6db484370..e12513e025d38 100644 --- a/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts +++ b/frontend/src/scenes/dashboard/dashboardTemplateVariablesLogic.ts @@ -117,6 +117,12 @@ export const dashboardTemplateVariablesLogic = kea v.touched) }, ], + hasTouchedAnyVariable: [ + (s) => [s.variables], + (variables: DashboardTemplateVariableType[]) => { + return variables.some((v) => v.touched) + }, + ], })), listeners(({ actions, props, values }) => ({ possiblyIncrementActiveVariableIndex: () => { diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx index e9f87cbadefff..6e7d41d87c24b 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx @@ -8,7 +8,7 @@ import { useRef, useState } from 'react' import { dashboardTemplateVariablesLogic } from 'scenes/dashboard/dashboardTemplateVariablesLogic' import { newDashboardLogic } from 'scenes/dashboard/newDashboardLogic' -import { OnboardingStepKey } from '../onboardingLogic' +import { onboardingLogic, OnboardingStepKey } from '../onboardingLogic' import { OnboardingStep } from '../OnboardingStep' import { sdksLogic } from '../sdks/sdksLogic' import { DashboardTemplateVariables } from './DashboardTemplateVariables' @@ -30,7 +30,8 @@ export const OnboardingDashboardTemplateConfigureStep = ({ const theDashboardTemplateVariablesLogic = dashboardTemplateVariablesLogic({ variables: activeDashboardTemplate?.variables || [], }) - const { variables, allVariablesAreTouched } = useValues(theDashboardTemplateVariablesLogic) + const { variables, allVariablesAreTouched, hasTouchedAnyVariable } = useValues(theDashboardTemplateVariablesLogic) + const { goToNextStep } = useActions(onboardingLogic) const [isSubmitting, setIsSubmitting] = useState(false) @@ -117,23 +118,34 @@ export const OnboardingDashboardTemplateConfigureStep = ({ (no need to send it now) .

- { - if (activeDashboardTemplate) { - setIsSubmitting(true) - createDashboardFromTemplate(activeDashboardTemplate, variables, false) - } - }} - loading={isLoading} - fullWidth - center - className="mt-6" - disabledReason={!allVariablesAreTouched && 'Please select an event for each variable'} - > - Create dashboard - +
+
+ { + if (activeDashboardTemplate) { + setIsSubmitting(true) + createDashboardFromTemplate(activeDashboardTemplate, variables, false) + } + }} + loading={isLoading} + fullWidth + center + className="grow" + disabledReason={ + !allVariablesAreTouched && 'Please select an event for each variable' + } + > + Create dashboard + +
+
+ goToNextStep()} fullWidth center> + {hasTouchedAnyVariable ? 'Discard dashboard & skip' : 'Skip for now'} + +
+
diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx index 02a7450dbe165..83a7fd30f9fe1 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx @@ -159,7 +159,7 @@ function VariableSelector({ ) : null} ) : ( -
+
{isCurrentlySelectingElement ? ( } + fullWidth + center + className="max-w-44" > Cancel selection @@ -183,6 +186,9 @@ function VariableSelector({ setIsCurrentlySelectingElement(true) }} icon={} + fullWidth + center + className="max-w-44" > Select from site @@ -195,6 +201,9 @@ function VariableSelector({ setShowCustomEventField(true) setIsCurrentlySelectingElement(false) }} + fullWidth + center + className="max-w-44" > Use custom event From e406b86c57d4a04dcc49cc4d7de7377433740479 Mon Sep 17 00:00:00 2001 From: Raquel Smith Date: Mon, 9 Sep 2024 21:23:11 -0700 Subject: [PATCH 17/17] handle people not ingesting web events yet, fix query --- .../DashboardTemplateConfigureStep.tsx | 68 ++++++---- .../DashboardTemplateVariables.tsx | 128 +++++++++--------- .../src/scenes/onboarding/sdks/sdksLogic.tsx | 9 +- 3 files changed, 109 insertions(+), 96 deletions(-) diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx index 6e7d41d87c24b..476cef6de6275 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateConfigureStep.tsx @@ -31,7 +31,7 @@ export const OnboardingDashboardTemplateConfigureStep = ({ variables: activeDashboardTemplate?.variables || [], }) const { variables, allVariablesAreTouched, hasTouchedAnyVariable } = useValues(theDashboardTemplateVariablesLogic) - const { goToNextStep } = useActions(onboardingLogic) + const { goToNextStep, setStepKey } = useActions(onboardingLogic) const [isSubmitting, setIsSubmitting] = useState(false) @@ -59,32 +59,50 @@ export const OnboardingDashboardTemplateConfigureStep = ({

Select where you want to track events from.

-

- Not seeing the site you want? Install posthog-js or the HTML snippet - wherever you want to track events, then come back here. -

{snippetHosts.length > 0 ? ( -
- {snippetHosts.map((host) => ( - { - addUrl(host) - setBrowserUrl(host) - }} - sideIcon={} - > - {host} - - ))} -
+ <> +

+ Not seeing the site you want? Install posthog-js or the HTML + snippet wherever you want to track events, then come back here. +

+
+ {snippetHosts.map((host) => ( + { + addUrl(host) + setBrowserUrl(host) + }} + sideIcon={} + > + {host} + + ))} +
+ ) : ( -

- Hm, we're not finding any available hosts. Head back to the install - step to install posthog-js in your frontend. -

+ <> +

+ Hm, it looks like you haven't ingested any events from a website + yet. To select actions from your site, head back to the{' '} + setStepKey(OnboardingStepKey.INSTALL)}> + install step + {' '} + to install posthog-js in your frontend. +

+

+ You can still create a dashboard using custom event names, + though it's not quite as fun. +

+ setStepKey(OnboardingStepKey.INSTALL)} + type="primary" + > + Install posthog-js + + )}
diff --git a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx index 83a7fd30f9fe1..9f87ff0aeb0f4 100644 --- a/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx +++ b/frontend/src/scenes/onboarding/productAnalyticsSteps/DashboardTemplateVariables.tsx @@ -135,82 +135,78 @@ function VariableSelector({
)} - {!hasSelectedSite ? ( - Please select a site to continue. - ) : ( -
- {variable.touched ? ( - <> - {!allVariablesAreTouched || - (allVariablesAreTouched && variables.length !== activeVariableIndex + 1) ? ( - - !allVariablesAreTouched - ? goToNextUntouchedActiveVariableIndex() - : variables.length !== activeVariableIndex + 1 - ? incrementActiveVariableIndex() - : null - } - > - Continue - - ) : null} - - ) : ( -
- {isCurrentlySelectingElement ? ( - { - disableElementSelector() - setNewActionName(null) - setIsCurrentlySelectingElement(false) - }} - icon={} - fullWidth - center - className="max-w-44" - > - Cancel selection - - ) : ( - { - setShowCustomEventField(false) - enableElementSelector() - setNewActionName(variable.name) - setIsCurrentlySelectingElement(true) - }} - icon={} - fullWidth - center - className="max-w-44" - > - Select from site - - )} + +
+ {variable.touched ? ( + <> + {!allVariablesAreTouched || + (allVariablesAreTouched && variables.length !== activeVariableIndex + 1) ? ( + + !allVariablesAreTouched + ? goToNextUntouchedActiveVariableIndex() + : variables.length !== activeVariableIndex + 1 + ? incrementActiveVariableIndex() + : null + } + > + Continue + + ) : null} + + ) : ( +
+ {isCurrentlySelectingElement ? ( { disableElementSelector() setNewActionName(null) - setShowCustomEventField(true) setIsCurrentlySelectingElement(false) }} - fullWidth + icon={} center - className="max-w-44" + className="min-w-44" > - Use custom event + Cancel selection -
- )} -
- )} + ) : ( + { + setShowCustomEventField(false) + enableElementSelector() + setNewActionName(variable.name) + setIsCurrentlySelectingElement(true) + }} + icon={} + center + className="min-w-44" + disabledReason={!hasSelectedSite && 'Please select a site to continue'} + > + Select from site + + )} + { + disableElementSelector() + setNewActionName(null) + setShowCustomEventField(true) + setIsCurrentlySelectingElement(false) + }} + fullWidth + center + className="grow max-w-44" + > + Use custom event + +
+ )} +
) } diff --git a/frontend/src/scenes/onboarding/sdks/sdksLogic.tsx b/frontend/src/scenes/onboarding/sdks/sdksLogic.tsx index 0ab48594d2825..6d4a0d4641eb2 100644 --- a/frontend/src/scenes/onboarding/sdks/sdksLogic.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdksLogic.tsx @@ -126,26 +126,25 @@ export const sdksLogic = kea([ loadSnippetEvents: async () => { const query: HogQLQuery = { kind: NodeKind.HogQLQuery, - query: hogql`SELECT properties.$lib_version AS lib_version, + query: hogql`SELECT max(timestamp) AS latest_timestamp, - count(lib_version) AS count, concat( if(startsWith(properties.current_url, 'https://'), 'https://', 'http://'), properties.$host ) AS full_host FROM events - WHERE timestamp >= now() - INTERVAL 3 DAY + WHERE timestamp >= now() - INTERVAL 5 DAY AND timestamp <= now() AND properties.$lib = 'web' AND properties.$host is not null - GROUP BY lib_version, full_host + GROUP BY full_host ORDER BY latest_timestamp DESC LIMIT 10`, } const res = await api.query(query) const hasEvents = !!(res.results?.length ?? 0 > 0) - const snippetHosts = res.results?.map((result) => result[3]).filter((val) => !!val) ?? [] + const snippetHosts = res.results?.map((result) => result[1]).filter((val) => !!val) ?? [] if (hasEvents) { actions.setSnippetHosts(snippetHosts) }