Skip to content

Commit

Permalink
feat: event debug view in the toolbar (#21523)
Browse files Browse the repository at this point in the history
* feat: toolbar-live-activity

* Update UI snapshots for `chromium` (2)

* fangling

* Update UI snapshots for `chromium` (2)

* rename as event debugger

* fiddl

* simple list

* don't commit yalc

* Update frontend/src/toolbar/debug/EventDebugMenu.tsx

Co-authored-by: Ben White <[email protected]>

* move some logic to the logic

* more logic for the logic gods

* fix filters and make it easier to see what's the extended props area

* empty state message

* stories

* name

* Update UI snapshots for `webkit` (2)

* Update UI snapshots for `chromium` (2)

* Update UI snapshots for `webkit` (2)

* Update UI snapshots for `chromium` (2)

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ben White <[email protected]>
  • Loading branch information
3 people authored Apr 15, 2024
1 parent 2be5fc1 commit 74ce620
Show file tree
Hide file tree
Showing 30 changed files with 207 additions and 40 deletions.
35 changes: 17 additions & 18 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@

name: Bug report
description: Something not working as expected? Let us look into it.
labels: ["bug"]
labels: ['bug']
body:
- type: textarea
id: bug-description
attributes:
label: Bug Description
value: "## Bug description\n\n*Please describe.*\n*If this affects the front-end, screenshots would be of great help.*\n\n*If you are on PostHog Cloud it would be really valuable if you can share any links where the problem occurs. This speeds up our ability to troubleshoot tremendously.*\n\n## How to reproduce\n\n1. \n2.\n3. \n\n## Additional context\n\n"
- type: textarea
id: debug-info
attributes:
label: Debug info
value: "- [ ] PostHog Cloud, Debug information: [please copy/paste from https://us.posthog.com/settings/project-details#variables]\n- [ ] PostHog Hobby self-hosted with `docker compose`, version/commit: [please provide]\n- [ ] PostHog self-hosted with Kubernetes (deprecated, see [`Sunsetting Kubernetes support`](https://posthog.com/blog/sunsetting-helm-support-posthog)), version/commit: [please provide]\n"
render: shell
- type: markdown
attributes:
value: "#### *Thank you* for your bug report – we love squashing them!"
- type: textarea
id: bug-description
attributes:
label: Bug Description
value: "## Bug description\n\n*Please describe.*\n*If this affects the front-end, screenshots would be of great help.*\n\n*If you are on PostHog Cloud it would be really valuable if you can share any links where the problem occurs. This speeds up our ability to troubleshoot tremendously.*\n\n## How to reproduce\n\n1. \n2.\n3. \n\n## Additional context\n\n"

- type: textarea
id: debug-info
attributes:
label: Debug info
value: "- [ ] PostHog Cloud, Debug information: [please copy/paste from https://us.posthog.com/settings/project-details#variables]\n- [ ] PostHog Hobby self-hosted with `docker compose`, version/commit: [please provide]\n- [ ] PostHog self-hosted with Kubernetes (deprecated, see [`Sunsetting Kubernetes support`](https://posthog.com/blog/sunsetting-helm-support-posthog)), version/commit: [please provide]\n"
render: shell

- type: markdown
attributes:
value: '#### *Thank you* for your bug report – we love squashing them!'
39 changes: 20 additions & 19 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
name: Feature request
description: "Suggest a feature for PostHog"
labels: ["enhancement, feature"]
description: 'Suggest a feature for PostHog'
labels: ['enhancement, feature']
body:
- type: textarea
id: feature_request
attributes:
label: Feature request
value: "## Is your feature request related to a problem?\n\n*Please describe.*\n\n## Describe the solution you'd like\n\n\n## Describe alternatives you've considered\n\n\n## Additional context\n\n\n
"
- type: textarea
id: debug-info
attributes:
label: Debug info
value: "- [ ] PostHog Cloud, Debug information: [please copy/paste from https://us.posthog.com/settings/project-details#variables]\n- [ ] PostHog Hobby self-hosted with `docker compose`, version/commit: [please provide]\n- [ ] PostHog self-hosted with Kubernetes (deprecated, see [`Sunsetting Kubernetes support`](https://posthog.com/blog/sunsetting-helm-support-posthog)), version/commit: [please provide]\n"
render: shell

- type: markdown
attributes:
value: "#### *Thank you* for your bug report – we love squashing them!"
- type: textarea
id: feature_request
attributes:
label: Feature request
value:
"## Is your feature request related to a problem?\n\n*Please describe.*\n\n## Describe the solution you'd like\n\n\n## Describe alternatives you've considered\n\n\n## Additional context\n\n\n
"
- type: textarea
id: debug-info
attributes:
label: Debug info
value: "- [ ] PostHog Cloud, Debug information: [please copy/paste from https://us.posthog.com/settings/project-details#variables]\n- [ ] PostHog Hobby self-hosted with `docker compose`, version/commit: [please provide]\n- [ ] PostHog self-hosted with Kubernetes (deprecated, see [`Sunsetting Kubernetes support`](https://posthog.com/blog/sunsetting-helm-support-posthog)), version/commit: [please provide]\n"
render: shell

- type: markdown
attributes:
value: '#### *Thank you* for your bug report – we love squashing them!'
Binary file modified frontend/__snapshots__/scenes-other-toolbar--actions--light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-toolbar--actions-dark--dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-toolbar--default--dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-toolbar--default--light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-toolbar--default-dark--dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-toolbar--heatmap--light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-toolbar--inspect--dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-toolbar--inspect--light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-toolbar--inspect-dark--dark.png
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.
2 changes: 1 addition & 1 deletion frontend/src/lib/components/AnimatedCollapsible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function AnimatedCollapsible({
}): JSX.Element {
const collapsibleSectionRef = useRef<HTMLHeadingElement>(null)

const [height, setHeight] = useState<number | undefined>()
const [height, setHeight] = useState<number | undefined>(collapsed ? 0 : undefined)

useEffect(() => {
if (!collapsed) {
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/toolbar/Toolbar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ export const FeatureFlags = (): JSX.Element => {
return <BasicTemplate menu="flags" />
}

export const EventsDebuggerEmpty = (): JSX.Element => {
return <BasicTemplate menu="debugger" />
}

// Dark theme
export const DefaultDark = (): JSX.Element => {
return <BasicTemplate theme="dark" />
Expand All @@ -155,3 +159,7 @@ export const ActionsDark = (): JSX.Element => {
export const FeatureFlagsDark = (): JSX.Element => {
return <BasicTemplate theme="dark" menu="flags" />
}

export const EventsDebuggerEmptyDark = (): JSX.Element => {
return <BasicTemplate theme="dark" menu="debugger" />
}
2 changes: 1 addition & 1 deletion frontend/src/toolbar/bar/Toolbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
justify-content: space-between;

// fixed width so that animations work when changing width
width: 15.2rem;
width: 18.2rem;
overflow: hidden;
color: var(--text-3000);
background-color: var(--bg-3000);
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/toolbar/bar/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
IconBolt,
IconCursorClick,
IconDay,
IconLive,
IconLogomark,
IconNight,
IconQuestion,
Expand All @@ -20,6 +21,7 @@ import { useEffect, useRef } from 'react'

import { ActionsToolbarMenu } from '~/toolbar/actions/ActionsToolbarMenu'
import { toolbarLogic } from '~/toolbar/bar/toolbarLogic'
import { EventDebugMenu } from '~/toolbar/debug/EventDebugMenu'
import { FlagsToolbarMenu } from '~/toolbar/flags/FlagsToolbarMenu'
import { HeatmapToolbarMenu } from '~/toolbar/stats/HeatmapToolbarMenu'
import { toolbarConfigLogic } from '~/toolbar/toolbarConfigLogic'
Expand Down Expand Up @@ -98,6 +100,8 @@ export function ToolbarInfoMenu(): JSX.Element | null {
<ActionsToolbarMenu />
) : visibleMenu === 'hedgehog' ? (
<HedgehogMenu />
) : visibleMenu === 'debugger' ? (
<EventDebugMenu />
) : null

useEffect(() => {
Expand Down Expand Up @@ -204,6 +208,9 @@ export function Toolbar(): JSX.Element {
<ToolbarButton menuId="flags" title="Feature flags">
<IconToggle />
</ToolbarButton>
<ToolbarButton menuId="debugger" title="Event debugger">
<IconLive />
</ToolbarButton>
</>
) : (
<ToolbarButton flex onClick={authenticate}>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/toolbar/bar/toolbarLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { toolbarLogicType } from './toolbarLogicType'

const MARGIN = 2

export type MenuState = 'none' | 'heatmap' | 'actions' | 'flags' | 'inspect' | 'hedgehog'
export type MenuState = 'none' | 'heatmap' | 'actions' | 'flags' | 'inspect' | 'hedgehog' | 'debugger'

export const toolbarLogic = kea<toolbarLogicType>([
path(['toolbar', 'bar', 'toolbarLogic']),
Expand Down
74 changes: 74 additions & 0 deletions frontend/src/toolbar/debug/EventDebugMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import clsx from 'clsx'
import { useActions, useValues } from 'kea'
import { AnimatedCollapsible } from 'lib/components/AnimatedCollapsible'
import { TZLabel } from 'lib/components/TZLabel'
import { LemonSwitch } from 'lib/lemon-ui/LemonSwitch'
import { SimpleKeyValueList } from 'scenes/session-recordings/player/inspector/components/SimpleKeyValueList'

import { eventDebugMenuLogic } from '~/toolbar/debug/eventDebugMenuLogic'

import { ToolbarMenu } from '../bar/ToolbarMenu'

export const EventDebugMenu = (): JSX.Element => {
const { filteredEvents, isCollapsedEventRow, expandedEvent, showRecordingSnapshots, snapshotCount, eventCount } =
useValues(eventDebugMenuLogic)
const { markExpanded, setShowRecordingSnapshots } = useActions(eventDebugMenuLogic)

return (
<ToolbarMenu>
<ToolbarMenu.Header>
<div className="flex flex-col pb-2 space-y-1">
<div className="flex flex-row justify-around">
<span className="text-xs">Seen {snapshotCount} events.</span>
<span className="text-xs">Seen {eventCount} recording snapshots.</span>
</div>
<div className="flex justify-center">
<LemonSwitch
checked={showRecordingSnapshots}
onChange={(c) => setShowRecordingSnapshots(c)}
label="Show recording snapshot events"
/>
</div>
</div>
</ToolbarMenu.Header>
<ToolbarMenu.Body>
<div className="flex flex-col space-y-1">
{filteredEvents.length ? (
filteredEvents.map((e, i) => {
return (
<div
className={clsx('-mx-1 py-1 px-2 cursor-pointer', i === 0 && 'bg-mark')}
key={e.uuid}
onClick={() => {
expandedEvent === e.uuid ? markExpanded(null) : markExpanded(e.uuid || null)
}}
>
<div className="flex flex-row justify-between">
<div>{e.event}</div>
<div>
<TZLabel time={e.timestamp} />
</div>
</div>
<AnimatedCollapsible
collapsed={e.uuid === undefined ? true : isCollapsedEventRow(e.uuid)}
>
<div className="mt-1 ml-1 pl-2 border-l-2">
<SimpleKeyValueList item={e.event === '$snapshot' ? e : e.properties} />
</div>
</AnimatedCollapsible>
</div>
)
})
) : (
<div className="px-4 py-2">
Interact with your page and then come back to the toolbar to see what events were generated.
</div>
)}
</div>
</ToolbarMenu.Body>
<ToolbarMenu.Footer>
<span className="text-xs">View events from this page as they are sent to PostHog.</span>
</ToolbarMenu.Footer>
</ToolbarMenu>
)
}
78 changes: 78 additions & 0 deletions frontend/src/toolbar/debug/eventDebugMenuLogic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { actions, afterMount, connect, kea, path, reducers, selectors } from 'kea'
import { uuid } from 'lib/utils'
import { permanentlyMount } from 'lib/utils/kea-logic-builders'

import { toolbarConfigLogic } from '~/toolbar/toolbarConfigLogic'
import { EventType } from '~/types'

import type { eventDebugMenuLogicType } from './eventDebugMenuLogicType'

export const eventDebugMenuLogic = kea<eventDebugMenuLogicType>([
path(['toolbar', 'debug', 'eventDebugMenuLogic']),
connect(() => ({
values: [toolbarConfigLogic, ['posthog']],
})),
actions({
addEvent: (event: EventType) => ({ event }),
markExpanded: (id: string | null) => ({ id }),
setShowRecordingSnapshots: (show: boolean) => ({ show }),
}),
reducers({
events: [
[] as EventType[],
{
addEvent: (state, { event }) => {
if (event.uuid) {
event.uuid = uuid()
}
return [event, ...state]
},
},
],
expandedEvent: [
null as string | null,
{
markExpanded: (_, { id }) => id,
},
],
showRecordingSnapshots: [
false,
{
setShowRecordingSnapshots: (_, { show }) => show,
},
],
}),
selectors({
isCollapsedEventRow: [
(s) => [s.expandedEvent],
(expandedEvent) => {
return (eventId: string | null): boolean => {
return eventId !== expandedEvent
}
},
],
snapshotCount: [(s) => [s.events], (events) => events.filter((e) => e.event !== '$snapshot').length],
eventCount: [(s) => [s.events], (events) => events.filter((e) => e.event === '$snapshot').length],
filteredEvents: [
(s) => [s.showRecordingSnapshots, s.events],
(showRecordingSnapshots, events) => {
return events.filter((e) => {
if (showRecordingSnapshots) {
return true
} else {
return e.event !== '$snapshot'
}
})
},
],
}),
afterMount(({ values, actions }) => {
values.posthog?.on('eventCaptured', (e) => {
if (!e.uuid) {
e.uuid = uuid()
}
actions.addEvent(e)
})
}),
permanentlyMount(),
])

0 comments on commit 74ce620

Please sign in to comment.