Skip to content

Commit

Permalink
feat: event debugger UI
Browse files Browse the repository at this point in the history
  • Loading branch information
pauldambra committed Apr 26, 2024
1 parent 2d25f2e commit b6c126c
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 26 deletions.
65 changes: 51 additions & 14 deletions frontend/src/toolbar/debug/EventDebugMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,61 @@ 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 { LemonCheckbox } from 'lib/lemon-ui/LemonCheckbox'
import { LemonInput } from 'lib/lemon-ui/LemonInput'
import { LemonSegmentedButton } from 'lib/lemon-ui/LemonSegmentedButton'
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)
const {
searchType,
searchText,
filteredEvents,
isCollapsedEventRow,
expandedEvent,
showRecordingSnapshots,
snapshotCount,
eventCount,
filteredProperties,
} = useValues(eventDebugMenuLogic)
const { setSearchType, markExpanded, setShowRecordingSnapshots, setSearchText } = 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
<div className="flex flex-row justify-around items-center">
<span className="text-xs">Seen {eventCount} events.</span>
<LemonCheckbox
checked={showRecordingSnapshots}
onChange={(c) => setShowRecordingSnapshots(c)}
label="Show recording snapshot events"
label={`Show ${snapshotCount} snapshot events`}
size="small"
/>
</div>
<div className="flex justify-center flex-col">
<div className="flex flex-row items-center justify-between space-x-2">
<span>search:</span>
<LemonSegmentedButton
size="small"
value={searchType}
options={[
{
value: 'events',
label: 'events',
},
{ value: 'properties', label: 'properties' },
]}
onChange={setSearchType}
/>

<LemonInput fullWidth={true} type="search" value={searchText} onChange={setSearchText} />
</div>
</div>
</div>
</ToolbarMenu.Header>
<ToolbarMenu.Body>
Expand All @@ -52,16 +80,25 @@ export const EventDebugMenu = (): JSX.Element => {
<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 className="my-1 ml-1 pl-2 border-l-2">
<SimpleKeyValueList
item={filteredProperties(e.properties)}
emptyMessage={
searchText && searchType === 'properties'
? 'No matching properties'
: 'No 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.
{searchText && searchType === 'events'
? 'No events match your search.'
: 'Interact with your page and then come back to the toolbar to see what events were generated.'}
</div>
)}
</div>
Expand Down
58 changes: 46 additions & 12 deletions frontend/src/toolbar/debug/eventDebugMenuLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,27 @@ export const eventDebugMenuLogic = kea<eventDebugMenuLogicType>([
addEvent: (event: EventType) => ({ event }),
markExpanded: (id: string | null) => ({ id }),
setShowRecordingSnapshots: (show: boolean) => ({ show }),
setSearchText: (searchText: string) => ({ searchText }),
setSearchType: (searchType: 'events' | 'properties') => ({ searchType }),
}),
reducers({
searchType: [
'events' as 'events' | 'properties',
{
setSearchType: (_, { searchType }) => searchType,
},
],
searchText: [
'',
{
setSearchText: (_, { searchText }) => searchText,
},
],
events: [
[] as EventType[],
{
addEvent: (state, { event }) => {
if (event.uuid) {
if (!event.uuid) {
event.uuid = uuid()
}
return [event, ...state]
Expand Down Expand Up @@ -51,25 +65,45 @@ export const eventDebugMenuLogic = kea<eventDebugMenuLogicType>([
}
},
],
snapshotCount: [(s) => [s.events], (events) => events.filter((e) => e.event !== '$snapshot').length],
eventCount: [(s) => [s.events], (events) => events.filter((e) => e.event === '$snapshot').length],
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) {
(s) => [s.showRecordingSnapshots, s.events, s.searchText, s.searchType],
(showRecordingSnapshots, events, searchText, searchType) => {
return events
.filter((e) => {
if (showRecordingSnapshots) {
return true
}
return e.event !== '$snapshot'
})
.filter((e) => {
if (searchType === 'events') {
return e.event.includes(searchText)
}
return true
})
},
],
filteredProperties: [
(s) => [s.searchText, s.searchType],
(searchText, searchType) => {
return (p: Record<string, any>): Record<string, any> => {
// return a new object with only the properties where key or value match the search text
if (searchType === 'properties') {
return Object.fromEntries(
Object.entries(p).filter(([key, value]) => {
return key.includes(searchText) || (value && value.toString().includes(searchText))
})
)
}
return e.event !== '$snapshot'
})
return p
}
},
],
}),
afterMount(({ values, actions }) => {
values.posthog?.on('eventCaptured', (e) => {
if (!e.uuid) {
e.uuid = uuid()
}
actions.addEvent(e)
})
}),
Expand Down

0 comments on commit b6c126c

Please sign in to comment.