Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(data-exploration): person and cohort tables #13136

Merged
merged 96 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
13a943c
add a big reload button
mariusandra Nov 23, 2022
d32744a
Merge branch 'master' into events-table-parity
mariusandra Nov 24, 2022
ab15ffd
reload button
mariusandra Nov 24, 2022
6262de6
load next data
mariusandra Nov 24, 2022
46d3e71
rename "more" to "actions"
mariusandra Nov 25, 2022
442ef35
new events that load
mariusandra Nov 25, 2022
b1d6577
refactor new/next loading
mariusandra Nov 25, 2022
7ab3888
bug
mariusandra Nov 25, 2022
4ac98bd
autoload
mariusandra Nov 25, 2022
a5d7d8f
Merge branch 'master' into events-table-parity
mariusandra Nov 29, 2022
edab9b6
new scene with a flag
mariusandra Nov 30, 2022
3c2e539
use only string columns
mariusandra Dec 1, 2022
832311a
move around
mariusandra Dec 1, 2022
ff576da
configurator
mariusandra Dec 1, 2022
2b4b05e
refactor again
mariusandra Dec 2, 2022
5757766
column config
mariusandra Dec 2, 2022
b2ec7ab
actually select them
mariusandra Dec 2, 2022
cb9ad0f
actually select them
mariusandra Dec 2, 2022
68c28da
hide on save
mariusandra Dec 2, 2022
c27e8cc
Merge branch 'master' into events-table-parity
mariusandra Dec 2, 2022
32d8e91
make the old events table work with the new events format
mariusandra Dec 2, 2022
079bc13
configure columns
mariusandra Dec 2, 2022
509dbff
clean up, add test
mariusandra Dec 2, 2022
cfb22eb
move away from antd
mariusandra Dec 2, 2022
e043ad0
less ants, move move
mariusandra Dec 2, 2022
f487f42
more cleanup
mariusandra Dec 2, 2022
448a6c5
export
mariusandra Dec 2, 2022
6ff3d47
show icon, store person properties
mariusandra Dec 2, 2022
d34f4a4
delete old code
mariusandra Dec 3, 2022
7d160c3
add readme
mariusandra Dec 3, 2022
32c6281
link properties
mariusandra Dec 3, 2022
691f86a
make it look closer to the old page
mariusandra Dec 3, 2022
a3f54ce
url
mariusandra Dec 3, 2022
8b2b616
show buffer warning
mariusandra Dec 3, 2022
24edb28
rename
mariusandra Dec 3, 2022
27484ed
autoload spinner, fix load order
mariusandra Dec 3, 2022
79250ab
add automatic row highlighting
mariusandra Dec 3, 2022
6c552fe
scope down
mariusandra Dec 3, 2022
bdf36e2
comment
mariusandra Dec 3, 2022
66e5221
more comments
mariusandra Dec 4, 2022
95d63b3
add link to session player
mariusandra Dec 4, 2022
1f138a5
move defaults to logic
mariusandra Dec 4, 2022
b817b2c
enable autoload
mariusandra Dec 4, 2022
6dc3079
sanitize old columns
mariusandra Dec 4, 2022
67c0202
cleanup
mariusandra Dec 4, 2022
dd048e9
refactor
mariusandra Dec 4, 2022
b0c1128
key cleanup
mariusandra Dec 4, 2022
91a9327
kea localstorage with global key
mariusandra Dec 4, 2022
4fc3083
query editor new look
mariusandra Dec 4, 2022
feb6273
empty datatable stories
mariusandra Dec 4, 2022
a5bb236
query edit modal
mariusandra Dec 4, 2022
befb97e
inline editor
mariusandra Dec 5, 2022
4740db0
times of plenty
mariusandra Dec 5, 2022
f483e19
add stories
mariusandra Dec 5, 2022
bf4cbde
add stories
mariusandra Dec 5, 2022
04b66c5
add more stories
mariusandra Dec 5, 2022
f2650e4
friendly hint
mariusandra Dec 5, 2022
686b8e6
update snapshot
mariusandra Dec 5, 2022
467b54c
replace a few more events tables
mariusandra Dec 5, 2022
f650ff1
add custom columns, add web performance table
mariusandra Dec 5, 2022
9a2b18a
set query locally
mariusandra Dec 5, 2022
7f28785
persons page
mariusandra Dec 5, 2022
0ec6f68
fix person id types
mariusandra Dec 5, 2022
f547132
basic persons table
mariusandra Dec 5, 2022
3a69083
persons search
mariusandra Dec 5, 2022
ec213ff
data table on persons scene
mariusandra Dec 5, 2022
8edb48b
default columns depend on source node kind
mariusandra Dec 5, 2022
ad7f21d
add to storybook
mariusandra Dec 5, 2022
ca801a1
enable "load more" on persons
mariusandra Dec 5, 2022
d083292
copy distinct id
mariusandra Dec 5, 2022
7ea159a
inline editor for data nodes
mariusandra Dec 5, 2022
4b48315
replace a few more events tables
mariusandra Dec 5, 2022
f888dc2
add custom columns, add web performance table
mariusandra Dec 5, 2022
98cde37
set query locally
mariusandra Dec 5, 2022
2bf89f9
persons page
mariusandra Dec 5, 2022
2a2c464
fix person id types
mariusandra Dec 5, 2022
38727fe
make all queries locally editable if no setQuery and no readOnly
mariusandra Dec 6, 2022
25bcf66
these are uuids
mariusandra Dec 6, 2022
cd120ce
rename "custom" to "context"
mariusandra Dec 6, 2022
c3101f0
Merge branch 'replace-event-tables' into person-data-tables
mariusandra Dec 7, 2022
0317966
Merge branch 'master' into person-data-tables
mariusandra Dec 7, 2022
0a0f03f
refactor stories
mariusandra Dec 7, 2022
1c24926
rename InlineEditor to InlineEditorButton to avoid confusion
mariusandra Dec 7, 2022
3b39dd5
not in use
mariusandra Dec 7, 2022
fc8cf02
fix wrong filters
mariusandra Dec 7, 2022
eb09509
add more hints
mariusandra Dec 7, 2022
fcc3f0f
persons scene url
mariusandra Dec 7, 2022
44a935f
extract person deletion modal
mariusandra Dec 7, 2022
dc9d581
Merge branch 'master' into person-data-tables
mariusandra Dec 9, 2022
61a16be
backport few fixes
mariusandra Dec 9, 2022
72beda4
fix a few issues
mariusandra Dec 9, 2022
3f10a71
remove delete from export
mariusandra Dec 9, 2022
65dc0f7
export limit
mariusandra Dec 9, 2022
8389f76
show filter count
mariusandra Dec 9, 2022
3f01667
few fixes
mariusandra Dec 9, 2022
eaa0504
call live_events_columns what it is
mariusandra Dec 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 0 additions & 44 deletions frontend/src/queries/Query/Query.stories.tsx

This file was deleted.

30 changes: 30 additions & 0 deletions frontend/src/queries/QueryRunner/QueryRunner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Query } from '~/queries/Query/Query'
import { useEffect, useState } from 'react'
import { QueryEditor } from '~/queries/QueryEditor/QueryEditor'
import { Node } from '~/queries/schema'

export interface QueryRunnerProps {
/** The query to render */
query: Node | string
}

export function QueryRunner(props: QueryRunnerProps): JSX.Element {
const [queryString, setQueryString] = useState(
typeof props.query === 'string' ? props.query : JSON.stringify(props.query)
)
useEffect(() => {
const newQueryString = typeof props.query === 'string' ? props.query : JSON.stringify(props.query)
if (newQueryString !== queryString) {
setQueryString(newQueryString)
}
}, [queryString])

return (
<>
<QueryEditor query={queryString} setQuery={setQueryString} />
<div className="p-4">
<Query key={queryString} query={queryString} />
</div>
</>
)
}
56 changes: 45 additions & 11 deletions frontend/src/queries/examples.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
// This file contains example queries, used in storybook and in the /query interface.
import {
EventsNode,
ActionsNode,
DataTableNode,
EventsNode,
FunnelsQuery,
LegacyQuery,
LifecycleQuery,
Node,
NodeKind,
TrendsQuery,
FunnelsQuery,
RetentionQuery,
ActionsNode,
PathsQuery,
PersonsNode,
RetentionQuery,
StickinessQuery,
LifecycleQuery,
TrendsQuery,
} from '~/queries/schema'
import {
ChartDisplayType,
FilterLogicalOperator,
InsightType,
PropertyFilterType,
PropertyGroupFilter,
PropertyOperator,
// PropertyMathType,
FilterLogicalOperator,
StepOrderValue,
PropertyGroupFilter,
} from '~/types'
import { defaultDataTableStringColumns } from '~/queries/nodes/DataTable/defaults'
import { defaultDataTableColumns } from '~/queries/nodes/DataTable/defaults'
import { ShownAsValue } from '~/lib/constants'

const Events: EventsNode = {
Expand All @@ -36,9 +36,39 @@ const Events: EventsNode = {

const EventsTable: DataTableNode = {
kind: NodeKind.DataTableNode,
columns: defaultDataTableStringColumns,
columns: defaultDataTableColumns({ kind: NodeKind.EventsNode }),
source: Events,
}
const EventsTableFull: DataTableNode = {
...EventsTable,
showPropertyFilter: true,
showEventFilter: true,
showExport: true,
showReload: true,
showColumnConfigurator: true,
showEventsBufferWarning: true,
}

const Persons: PersonsNode = {
kind: NodeKind.PersonsNode,
properties: [
{ type: PropertyFilterType.Person, key: '$browser', operator: PropertyOperator.Exact, value: 'Chrome' },
],
}

const PersonsTable: DataTableNode = {
kind: NodeKind.DataTableNode,
columns: defaultDataTableColumns({ kind: NodeKind.PersonsNode }),
source: Persons,
}

const PersonsTableFull: DataTableNode = {
...PersonsTable,
showSearch: true,
showPropertyFilter: true,
showExport: true,
showReload: true,
}

const LegacyTrendsQuery: LegacyQuery = {
kind: NodeKind.LegacyQuery,
Expand Down Expand Up @@ -196,6 +226,10 @@ const InsightLifecycleQuery: LifecycleQuery = {
export const examples: Record<string, Node> = {
Events,
EventsTable,
EventsTableFull,
Persons,
PersonsTable,
PersonsTableFull,
LegacyTrendsQuery,
InsightTrendsQuery,
InsightFunnelsQuery,
Expand Down
36 changes: 36 additions & 0 deletions frontend/src/queries/nodes/DataNode/DataNode.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ComponentMeta, ComponentStory } from '@storybook/react'
import { QueryRunner } from '~/queries/QueryRunner/QueryRunner'
import { examples } from '~/queries/examples'
import { mswDecorator } from '~/mocks/browser'
import events from './__mocks__/EventsNode.json'
import persons from './__mocks__/PersonsNode.json'

export default {
title: 'Queries/DataNode',
component: QueryRunner,
parameters: {
chromatic: { disableSnapshot: false },
layout: 'fullscreen',
options: { showPanel: false },
viewMode: 'story',
},
argTypes: {
query: { defaultValue: {} },
},
decorators: [
mswDecorator({
get: {
'/api/projects/:projectId/events': events,
'/api/projects/:projectId/persons': persons,
},
}),
],
} as ComponentMeta<typeof QueryRunner>

const QueryTemplate: ComponentStory<typeof QueryRunner> = QueryRunner

export const Events = QueryTemplate.bind({})
Events.args = { query: examples['Events'] }

export const Persons = QueryTemplate.bind({})
Persons.args = { query: examples['Persons'] }
39 changes: 25 additions & 14 deletions frontend/src/queries/nodes/DataNode/DataNode.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import MonacoEditor from '@monaco-editor/react'
import { useState } from 'react'
import { AutoSizer } from 'react-virtualized/dist/es/AutoSizer'
import { DataNode as DataNodeType } from '~/queries/schema'
import { DataNode as DataNodeType, DataTableNode, Node } from '~/queries/schema'
import { useValues } from 'kea'
import { dataNodeLogic } from '~/queries/nodes/DataNode/dataNodeLogic'
import { Spinner } from 'lib/components/Spinner/Spinner'
import { InlineEditorButton } from '~/queries/nodes/Node/InlineEditorButton'

interface DataNodeProps {
query: DataNodeType
setQuery?: (node: DataTableNode) => void
}

let uniqueNode = 0
Expand All @@ -18,19 +20,28 @@ export function DataNode(props: DataNodeProps): JSX.Element {
const logic = dataNodeLogic({ ...props, key })
const { response, responseLoading } = useValues(logic)

return responseLoading ? (
<Spinner />
) : (
<AutoSizer disableWidth>
{({ height }) => (
<MonacoEditor
theme="vs-light"
className="border"
language={'json'}
value={JSON.stringify(response, null, 2)}
height={Math.max(height, 300)}
/>
return (
<div className="relative">
<div className="absolute right-0 z-10 p-1 mr-3">
<InlineEditorButton query={props.query} setQuery={props.setQuery as (node: Node) => void} />
</div>
{responseLoading ? (
<div className="text-2xl">
<Spinner />
</div>
) : (
<AutoSizer disableWidth>
{({ height }) => (
<MonacoEditor
theme="vs-light"
className="border"
language={'json'}
value={JSON.stringify(response, null, 2)}
height={Math.max(height, 300)}
/>
)}
</AutoSizer>
)}
</AutoSizer>
</div>
)
}
58 changes: 58 additions & 0 deletions frontend/src/queries/nodes/DataNode/__mocks__/PersonsNode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"results": [
{
"type": "person",
"id": "0184ae06-9d4a-0000-2b26-a771725cc751",
"uuid": "0184ae06-9d4a-0000-2b26-a771725cc751",
"created_at": "2022-11-25T09:02:59.900000Z",
"properties": {
"$os": "Mac OS X",
"email": "marius@posthog.com",
"$browser": "Chrome",
"$referrer": "http://localhost:8000/events",
"$initial_os": "Mac OS X",
"$geoip_latitude": -33.8715,
"$browser_version": 107,
"$geoip_city_name": "Sydney",
"$geoip_longitude": 151.2006,
"$geoip_time_zone": "Australia/Sydney",
"$initial_browser": "Chrome",
"$initial_pathname": "/ingestion",
"$initial_referrer": "http://localhost:8000/dashboard",
"$referring_domain": "localhost:8000",
"$geoip_postal_code": "2000",
"$geoip_country_code": "AU",
"$geoip_country_name": "Australia",
"$initial_current_url": "http://localhost:8000/ingestion",
"$initial_device_type": "Desktop",
"$geoip_continent_code": "OC",
"$geoip_continent_name": "Oceania",
"$initial_geoip_latitude": -33.8715,
"$initial_browser_version": 107,
"$initial_geoip_city_name": "Sydney",
"$initial_geoip_longitude": 151.2006,
"$initial_geoip_time_zone": "Australia/Sydney",
"$geoip_subdivision_1_code": "NSW",
"$geoip_subdivision_1_name": "New South Wales",
"$initial_referring_domain": "localhost:8000",
"$initial_geoip_postal_code": "2000",
"$initial_geoip_country_code": "AU",
"$initial_geoip_country_name": "Australia",
"$initial_geoip_continent_code": "OC",
"$initial_geoip_continent_name": "Oceania",
"$initial_geoip_subdivision_1_code": "NSW",
"$initial_geoip_subdivision_1_name": "New South Wales"
},
"is_identified": true,
"name": "marius@posthog.com",
"distinct_ids": [
"184ae069d181757-0c7310c8ee02fe-18525635-201b88-184ae069d192e7c",
"FXFWiYV3IHFXVo2DuWESQmHvywBwAEIJpvr0KrHiM2J"
],
"matched_recordings": [],
"value_at_data_point": null
}
],
"next": null,
"previous": null
}
4 changes: 2 additions & 2 deletions frontend/src/queries/nodes/DataNode/dataNodeLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { loaders } from 'kea-loaders'
import type { dataNodeLogicType } from './dataNodeLogicType'
import { DataNode, EventsNode } from '~/queries/schema'
import { query } from '~/queries/query'
import { isEventsNode } from '~/queries/utils'
import { isEventsNode, isPersonsNode } from '~/queries/utils'
import { subscriptions } from 'kea-subscriptions'
import { objectsEqual } from 'lib/utils'
import clsx from 'clsx'
Expand Down Expand Up @@ -124,7 +124,7 @@ export const dataNodeLogic = kea<dataNodeLogicType>([
(s) => [s.query, s.response],
(query, response) => {
return (
isEventsNode(query) &&
(isEventsNode(query) || isPersonsNode(query)) &&
(response as EventsNode['response'])?.next &&
((response as EventsNode['response'])?.results?.length ?? 0) > 0
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types'
import { TeamMembershipLevel } from 'lib/constants'
import { useState } from 'react'
import { columnConfiguratorLogic, ColumnConfiguratorLogicProps } from './columnConfiguratorLogic'
import { defaultDataTableStringColumns } from '../defaults'
import { DataTableNode } from '~/queries/schema'
import { defaultDataTableColumns } from '../defaults'
import { DataTableNode, NodeKind } from '~/queries/schema'
import { LemonModal } from 'lib/components/LemonModal'
import { PropertyFilterType } from '~/types'
import { PropertyFilterIcon } from 'lib/components/PropertyFilters/components/PropertyFilterIcon'
Expand Down Expand Up @@ -104,7 +104,7 @@ function ColumnConfiguratorModal(): JSX.Element {
}

return (
<div className={clsx(['SelectedColumn', 'selected'])} style={{ height: `${rowItemHeight}px` }}>
<div className={clsx(['SelectedColumn', 'selected'])} style={{ height: rowItemHeight }}>
<DragHandle />
{columnType && <PropertyFilterIcon type={columnType} />}
<PropertyKeyInfo className="ml-1" value={columnKey} />
Expand Down Expand Up @@ -160,7 +160,10 @@ function ColumnConfiguratorModal(): JSX.Element {
footer={
<>
<div className="flex-1">
<LemonButton type="secondary" onClick={() => setColumns(defaultDataTableStringColumns)}>
<LemonButton
type="secondary"
onClick={() => setColumns(defaultDataTableColumns({ kind: NodeKind.EventsNode }))}
>
Reset to defaults
</LemonButton>
</div>
Expand Down
Loading