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): convert insight display config #14075

Merged
merged 49 commits into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
885b749
add retention insight to data exploration feature flag
thmsobrmlr Jan 30, 2023
060fdc6
remove unimplemented query
thmsobrmlr Jan 31, 2023
e2b0991
render retention summary
thmsobrmlr Jan 30, 2023
9471395
lemonify retention summary
thmsobrmlr Jan 30, 2023
6580fc6
convert retention summary
thmsobrmlr Jan 30, 2023
883cdf8
add defaults
thmsobrmlr Jan 30, 2023
85c73b7
update schema
thmsobrmlr Jan 31, 2023
965e4ea
fix comment typo
thmsobrmlr Jan 31, 2023
78860d6
rename retention reference picker
thmsobrmlr Jan 31, 2023
ac6994c
remove unused disabled prop
thmsobrmlr Jan 31, 2023
9dcadcf
rename retentionTableLogic to retentionLogic
thmsobrmlr Jan 31, 2023
25a9412
remove unused setProperties listener from retentionLogic
thmsobrmlr Jan 31, 2023
0935594
extract constants
thmsobrmlr Jan 31, 2023
dfa2237
extract retentionPeopleLogic
thmsobrmlr Feb 1, 2023
94d4bc6
remove unneeded type casts
thmsobrmlr Feb 1, 2023
4352620
extract retentionTableLogic
thmsobrmlr Feb 1, 2023
befc8c7
extract retentionLineGraphLogic
thmsobrmlr Feb 1, 2023
370a8c9
refactor retention modal
thmsobrmlr Feb 1, 2023
7aac20c
remove unnecessary useState hook
thmsobrmlr Feb 1, 2023
af1b5c2
add retentionModalLogic
thmsobrmlr Feb 1, 2023
21228a9
consistent action naming
thmsobrmlr Feb 1, 2023
7e09ce6
selectedRow can't be undefined
thmsobrmlr Feb 1, 2023
a25d4e2
refactor retention modal
thmsobrmlr Feb 1, 2023
e7ba12d
remove retentionReference selector and action
thmsobrmlr Feb 1, 2023
411e671
remove unused actionsLookup
thmsobrmlr Feb 1, 2023
57716f9
remove unused loadedFilters
thmsobrmlr Feb 1, 2023
35755af
remove retentionReference everywhere
thmsobrmlr Feb 1, 2023
38f8895
convert retention date picker
thmsobrmlr Feb 1, 2023
9d3db81
make modal title more clear
thmsobrmlr Feb 1, 2023
ba9a2a5
remove unused disabled prop
thmsobrmlr Feb 1, 2023
e149797
convert retention reference picker
thmsobrmlr Feb 1, 2023
04a36bf
introduce abstractRetentionLogic
thmsobrmlr Feb 2, 2023
dc799a8
remove support for retention breakdowns
thmsobrmlr Feb 2, 2023
c3b6f27
fix people loading
thmsobrmlr Feb 2, 2023
a82354b
fix lint issues
thmsobrmlr Feb 2, 2023
ebaf6b5
graceful defaults for funnel
thmsobrmlr Feb 2, 2023
a7d0e79
fix and add tests
thmsobrmlr Feb 2, 2023
7b50498
add types for retention period
thmsobrmlr Feb 2, 2023
4e73614
update schema
thmsobrmlr Feb 2, 2023
675023e
start separating insight display config
thmsobrmlr Feb 3, 2023
9d035ce
extract variables
thmsobrmlr Feb 3, 2023
f088ad8
fixes
thmsobrmlr Feb 3, 2023
b9998bb
refactor
thmsobrmlr Feb 3, 2023
54f9af2
refactor
thmsobrmlr Feb 3, 2023
9535158
fix issue
thmsobrmlr Feb 3, 2023
c048040
refactor
thmsobrmlr Feb 3, 2023
69cf757
Merge branch 'master' into data-exploration-insight-display-config
thmsobrmlr Feb 6, 2023
9ef5b14
fix types
thmsobrmlr Feb 6, 2023
74bf659
Merge branch 'master' into data-exploration-insight-display-config
thmsobrmlr Feb 7, 2023
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
35 changes: 17 additions & 18 deletions frontend/src/lib/components/ChartFilter/ChartFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ import { isTrendsFilter } from 'scenes/insights/sharedUtils'

interface ChartFilterProps {
filters: FilterType
onChange?: (chartFilter: ChartDisplayType) => void
disabled?: boolean
}

export function ChartFilter({ filters, onChange, disabled }: ChartFilterProps): JSX.Element {
export function ChartFilter({ filters }: ChartFilterProps): JSX.Element {
const { insightProps, isSingleSeries } = useValues(insightLogic)
const { chartFilter } = useValues(chartFilterLogic(insightProps))
const { setChartFilter } = useActions(chartFilterLogic(insightProps))
Expand Down Expand Up @@ -112,20 +110,21 @@ export function ChartFilter({ filters, onChange, disabled }: ChartFilterProps):
]

return (
<LemonSelect
key="2"
value={chartFilter || ChartDisplayType.ActionsLineGraph}
onChange={(value) => {
setChartFilter(value as ChartDisplayType)
onChange?.(value as ChartDisplayType)
}}
dropdownPlacement="bottom-end"
optionTooltipPlacement="left"
dropdownMatchSelectWidth={false}
data-attr="chart-filter"
disabled={disabled}
options={options}
size="small"
/>
<>
<span>Chart type</span>
<LemonSelect
key="2"
value={chartFilter || ChartDisplayType.ActionsLineGraph}
onChange={(value) => {
setChartFilter(value as ChartDisplayType)
}}
dropdownPlacement="bottom-end"
optionTooltipPlacement="left"
dropdownMatchSelectWidth={false}
data-attr="chart-filter"
options={options}
size="small"
/>
</>
)
}
42 changes: 23 additions & 19 deletions frontend/src/lib/components/IntervalFilter/IntervalFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { intervalFilterLogic } from './intervalFilterLogic'
import { useActions, useValues } from 'kea'
import { InsightType, IntervalType } from '~/types'
import { IntervalType } from '~/types'
import { insightLogic } from 'scenes/insights/insightLogic'
import { LemonSelect } from '@posthog/lemon-ui'

interface InvertalFilterProps {
view: InsightType
disabled?: boolean
}

Expand All @@ -15,22 +14,27 @@ export function IntervalFilter({ disabled }: InvertalFilterProps): JSX.Element {
const { setInterval } = useActions(intervalFilterLogic(insightProps))

return (
<LemonSelect
size={'small'}
disabled={disabled}
value={interval || undefined}
dropdownMatchSelectWidth={false}
onChange={(value) => {
if (value) {
setInterval(String(value) as IntervalType)
}
}}
data-attr="interval-filter"
options={Object.entries(enabledIntervals).map(([value, { label, disabledReason }]) => ({
value,
label,
disabledReason,
}))}
/>
<>
<span>
<span className="hide-lte-md">grouped </span>by
</span>
<LemonSelect
size={'small'}
disabled={disabled}
value={interval || undefined}
dropdownMatchSelectWidth={false}
onChange={(value) => {
if (value) {
setInterval(String(value) as IntervalType)
}
}}
data-attr="interval-filter"
options={Object.entries(enabledIntervals).map(([value, { label, disabledReason }]) => ({
value,
label,
disabledReason,
}))}
/>
</>
)
}
30 changes: 8 additions & 22 deletions frontend/src/queries/nodes/InsightViz/EditorFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,10 @@ import {
QueryEditorFilterProps,
ChartDisplayType,
AvailableFeature,
FunnelVizType,
} from '~/types'
import { insightLogic } from 'scenes/insights/insightLogic'
import { userLogic } from 'scenes/userLogic'
import { NON_BREAKDOWN_DISPLAY_TYPES } from 'lib/constants'
import {
isTrendsQuery,
isFunnelsQuery,
isPathsQuery,
isStickinessQuery,
isRetentionQuery,
isLifecycleQuery,
} from '~/queries/utils'

import { InsightQueryNode } from '~/queries/schema'
import { EditorFilterGroup } from './EditorFilterGroup'
Expand All @@ -31,7 +22,6 @@ import { TrendsSeriesLabel } from './TrendsSeriesLabel'
import { TrendsFormulaLabel } from './TrendsFormulaLabel'
import { TrendsFormula } from './TrendsFormula'
import { Breakdown } from './Breakdown'
import { getBreakdown, getDisplay } from './utils'
import { PathsEventsTypesDataExploration } from 'scenes/insights/EditorFilters/PathsEventTypes'
import {
PathsTargetEndDataExploration,
Expand All @@ -45,6 +35,8 @@ import { FunnelsQueryStepsDataExploration } from 'scenes/insights/EditorFilters/
import { AttributionDataExploration } from 'scenes/insights/EditorFilters/AttributionFilter'
import { FunnelsAdvancedDataExploration } from 'scenes/insights/EditorFilters/FunnelsAdvanced'
import { RetentionSummaryDataExploration } from 'scenes/insights/EditorFilters/RetentionSummary'
import { insightDataLogic } from 'scenes/insights/insightDataLogic'
import { funnelDataLogic } from 'scenes/funnels/funnelDataLogic'
export interface EditorFiltersProps {
query: InsightQueryNode
setQuery: (node: InsightQueryNode) => void
Expand All @@ -55,22 +47,16 @@ export function EditorFilters({ query, setQuery }: EditorFiltersProps): JSX.Elem
const availableFeatures = user?.organization?.available_features || []

const { insight, insightProps, filterPropertiesCount } = useValues(insightLogic)

const isTrends = isTrendsQuery(query)
const isFunnels = isFunnelsQuery(query)
const isRetention = isRetentionQuery(query)
const isPaths = isPathsQuery(query)
const isStickiness = isStickinessQuery(query)
const isLifecycle = isLifecycleQuery(query)
const isTrendsLike = isTrends || isLifecycle || isStickiness
const display = getDisplay(query)
const breakdown = getBreakdown(query)
const { isTrends, isFunnels, isRetention, isPaths, isLifecycle, isTrendsLike, display, breakdown } = useValues(
insightDataLogic(insightProps)
)
const { isStepsFunnel } = useValues(funnelDataLogic(insightProps))

const hasBreakdown =
(isTrends && !NON_BREAKDOWN_DISPLAY_TYPES.includes(display || ChartDisplayType.ActionsLineGraph)) ||
(isFunnels && query.funnelsFilter?.funnel_viz_type === FunnelVizType.Steps)
isStepsFunnel
const hasPathsAdvanced = availableFeatures.includes(AvailableFeature.PATHS_ADVANCED)
const hasAttribution = isFunnels && query.funnelsFilter?.funnel_viz_type === FunnelVizType.Steps
const hasAttribution = isStepsFunnel

const showFilters = true // TODO: implement with insightVizLogic

Expand Down
13 changes: 2 additions & 11 deletions frontend/src/queries/nodes/InsightViz/InsightContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Card, Col, Row } from 'antd'
import { InsightDisplayConfig } from 'scenes/insights/InsightDisplayConfig'
import { InsightDisplayConfig } from './InsightDisplayConfig'
import { FunnelCanvasLabel } from 'scenes/funnels/FunnelCanvasLabel'
import {
// ChartDisplayType,
Expand Down Expand Up @@ -207,16 +207,7 @@ export function InsightContainer({
) : null} */}
{/* These are filters that are reused between insight features. They each have generic logic that updates the url */}
<Card
title={
disableHeader ? null : (
<InsightDisplayConfig
activeView={activeView as InsightType}
insightMode={insightMode || ItemMode.View}
filters={filters}
disableTable={!!disableTable}
/>
)
}
title={disableHeader ? null : <InsightDisplayConfig disableTable={!!disableTable} />}
data-attr="insights-graph"
className="insights-graph-container"
>
Expand Down
111 changes: 111 additions & 0 deletions frontend/src/queries/nodes/InsightViz/InsightDisplayConfig.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { PropsWithChildren, ReactNode } from 'react'
import { useActions, useValues } from 'kea'

import { insightLogic } from 'scenes/insights/insightLogic'
import { insightDisplayConfigLogic } from './insightDisplayConfigLogic'

import { InsightDateFilter } from 'scenes/insights/filters/InsightDateFilter'
import { IntervalFilter } from 'lib/components/IntervalFilter'
import { SmoothingFilter } from 'lib/components/SmoothingFilter/SmoothingFilter'
import { RetentionDatePickerDataExploration } from 'scenes/insights/RetentionDatePicker'
import { RetentionReferencePickerDataExploration } from 'scenes/insights/filters/RetentionReferencePicker'
import { PathStepPickerDataExploration } from 'scenes/insights/views/Paths/PathStepPicker'
import { CompareFilter } from 'lib/components/CompareFilter/CompareFilter'
import { UnitPicker } from 'lib/components/UnitPicker/UnitPicker'
import { ChartFilter } from 'lib/components/ChartFilter'
import { FunnelDisplayLayoutPickerDataExploration } from 'scenes/insights/views/Funnels/FunnelDisplayLayoutPicker'
// import { FunnelBinsPicker } from 'scenes/insights/views/Funnels/FunnelBinsPicker'

interface InsightDisplayConfigProps {
disableTable: boolean
}

export function InsightDisplayConfig({ disableTable }: InsightDisplayConfigProps): JSX.Element {
const { insightProps, filters } = useValues(insightLogic)
const { setFilters } = useActions(insightLogic)
const {
showDateRange,
disableDateRange,
showCompare,
showUnit,
showChart,
showInterval,
showSmoothing,
showRetention,
showPaths,
showFunnelDisplayLayout,
// showFunnelBins,
} = useValues(insightDisplayConfigLogic(insightProps))

return (
<div className="flex justify-between items-center flex-wrap" data-attr="insight-filters">
<div className="flex items-center space-x-2 flex-wrap my-2">
{showDateRange && !disableTable && (
<ConfigFilter>
<InsightDateFilter disabled={disableDateRange} />
</ConfigFilter>
)}

{showInterval && (
<ConfigFilter>
<IntervalFilter />
</ConfigFilter>
)}

{showSmoothing && (
<ConfigFilter>
<SmoothingFilter />
</ConfigFilter>
)}

{showRetention && (
<ConfigFilter>
<RetentionDatePickerDataExploration />
<RetentionReferencePickerDataExploration />
</ConfigFilter>
)}

{showPaths && (
<ConfigFilter>
<PathStepPickerDataExploration />
</ConfigFilter>
)}

{showCompare && (
<ConfigFilter>
<CompareFilter />
</ConfigFilter>
)}
</div>
<div className="flex items-center space-x-4 flex-wrap my-2">
{showUnit && (
<ConfigFilter>
<UnitPicker filters={filters} setFilters={setFilters} />
</ConfigFilter>
)}

{showChart && (
<ConfigFilter>
<ChartFilter filters={filters} />
</ConfigFilter>
)}

{showFunnelDisplayLayout && (
<ConfigFilter>
<FunnelDisplayLayoutPickerDataExploration />
</ConfigFilter>
)}

{/* {showFunnelBins && (
<ConfigFilter>
<FunnelBinsPicker />
</ConfigFilter>
)} */}
</div>
</div>
)
}

function ConfigFilter(props: PropsWithChildren<ReactNode>): JSX.Element {
return <span className="space-x-2 flex items-center text-sm">{props.children}</span>
}
73 changes: 73 additions & 0 deletions frontend/src/queries/nodes/InsightViz/insightDisplayConfigLogic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { kea, props, key, path, selectors, connect } from 'kea'
import { ChartDisplayType, InsightLogicProps } from '~/types'
import { keyForInsightLogicProps } from 'scenes/insights/sharedUtils'

import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import { insightDataLogic } from 'scenes/insights/insightDataLogic'
import { funnelDataLogic } from 'scenes/funnels/funnelDataLogic'
import { FEATURE_FLAGS, NON_TIME_SERIES_DISPLAY_TYPES } from 'lib/constants'

import type { insightDisplayConfigLogicType } from './insightDisplayConfigLogicType'

export const insightDisplayConfigLogic = kea<insightDisplayConfigLogicType>([
props({} as InsightLogicProps),
key(keyForInsightLogicProps('new')),
path((key) => ['scenes', 'insights', 'insightDataLogic', key]),

connect((props: InsightLogicProps) => ({
values: [
featureFlagLogic,
['featureFlags'],
insightDataLogic(props),
[
'isTrends',
'isFunnels',
'isRetention',
'isPaths',
'isStickiness',
'isLifecycle',
'supportsDisplay',
'display',
'breakdown',
'trendsFilter',
],
funnelDataLogic(props),
['isEmptyFunnel', 'isStepsFunnel', 'isTimeToConvertFunnel', 'isTrendsFunnel'],
],
})),

selectors({
showDateRange: [(s) => [s.isRetention], (isRetention) => !isRetention],
disableDateRange: [
(s) => [s.isFunnels, s.isEmptyFunnel],
(isFunnels, isEmptyFunnel) => isFunnels && !!isEmptyFunnel,
],
showCompare: [
(s) => [s.isTrends, s.isStickiness, s.display],
(isTrends, isStickiness, display) =>
(isTrends && display !== ChartDisplayType.ActionsAreaGraph) || isStickiness,
],
showUnit: [(s) => [s.supportsDisplay, s.isTrends], (supportsDisplay, isTrends) => supportsDisplay && isTrends],
showChart: [(s) => [s.supportsDisplay], (supportsDisplay) => supportsDisplay],
showInterval: [
(s) => [s.isTrends, s.isStickiness, s.isLifecycle, s.isTrendsFunnel, s.display],
(isTrends, isStickiness, isLifecycle, isTrendsFunnel, display) =>
isTrendsFunnel ||
isLifecycle ||
((isTrends || isStickiness) && !(display && NON_TIME_SERIES_DISPLAY_TYPES.includes(display))),
],
showSmoothing: [
(s) => [s.isTrends, s.breakdown, s.display, s.trendsFilter, s.featureFlags],
(isTrends, breakdown, display, trendsFilter, featureFlags) =>
isTrends &&
!breakdown?.breakdown_type &&
!trendsFilter?.compare &&
(!display || display === ChartDisplayType.ActionsLineGraph) &&
featureFlags[FEATURE_FLAGS.SMOOTHING_INTERVAL],
],
showRetention: [(s) => [s.isRetention], (isRetention) => !!isRetention],
showPaths: [(s) => [s.isPaths], (isPaths) => !!isPaths],
showFunnelDisplayLayout: [(s) => [s.isStepsFunnel], (isStepsFunnel) => !!isStepsFunnel],
showFunnelBins: [(s) => [s.isTimeToConvertFunnel], (isTimeToConvertFunnel) => !!isTimeToConvertFunnel],
}),
])
Loading