Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jurajmajerik committed Dec 28, 2024
1 parent c8ef379 commit c3adb73
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import { SavedMetricModal } from '../Metrics/SavedMetricModal'
import { MetricsView } from '../MetricsView/MetricsView'
import {
ExperimentLoadingAnimation,
ExploreButton,
LoadingState,
NoResultsEmptyState,
PageHeaderCustom,
ResultsHeader,
ResultsQuery,
} from './components'
import { CumulativeExposuresChart } from './CumulativeExposuresChart'
import { DataCollection } from './DataCollection'
Expand All @@ -26,11 +28,14 @@ import { Overview } from './Overview'
import { ReleaseConditionsModal, ReleaseConditionsTable } from './ReleaseConditionsTable'
import { Results } from './Results'
import { SecondaryMetricsTable } from './SecondaryMetricsTable'
import { SummaryTable } from './SummaryTable'

const NewResultsTab = (): JSX.Element => {
const { experiment, metricResults } = useValues(experimentLogic)
const hasSomeResults = metricResults?.some((result) => result?.insight)

const hasSinglePrimaryMetric = experiment.metrics.length === 1

return (
<>
{!hasSomeResults && (
Expand All @@ -42,7 +47,27 @@ const NewResultsTab = (): JSX.Element => {
)}
</>
)}
<MetricsView />
{/* Show overview if there's only a single primary metric */}
{hasSinglePrimaryMetric && (
<div className="mb-4">
<Overview />
</div>
)}
<MetricsView isSecondary={false} />
{/* Show detailed results if there's only a single primary metric */}
{hasSomeResults && hasSinglePrimaryMetric && (
<div>
<div className="pb-4">
<SummaryTable metric={experiment.metrics[0]} metricIndex={0} isSecondary={false} />
</div>
<div className="flex justify-end">
<ExploreButton result={metricResults?.[0] || null} size="xsmall" />
</div>
<div className="pb-4">
<ResultsQuery result={metricResults?.[0] || null} showTable={true} />
</div>
</div>
)}
<MetricsView isSecondary={true} />
</>
)
Expand Down Expand Up @@ -124,6 +149,7 @@ export function ExperimentView(): JSX.Element {
<>
{hasSomeResults && !featureFlags[FEATURE_FLAGS.EXPERIMENTS_MULTIPLE_METRICS] ? (
<div>
<h2 className="font-semibold text-lg">Summary</h2>
<Overview />
<LemonDivider className="mt-4" />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export function Overview({ metricIndex = 0 }: { metricIndex?: number }): JSX.Ele

return (
<div>
<h2 className="font-semibold text-lg">Summary</h2>
<div className="items-center inline-flex flex-wrap">
<WinningVariantText result={result} experimentId={experimentId} />
<SignificanceText metricIndex={metricIndex} />
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/experiments/ExperimentView/Results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function Results(): JSX.Element {
<div>
<ResultsHeader />
<SummaryTable metric={experiment.metrics[0]} />
<ResultsQuery targetResults={result} showTable={true} />
<ResultsQuery result={result} showTable={true} />
</div>
)
}
101 changes: 23 additions & 78 deletions frontend/src/scenes/experiments/ExperimentView/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,23 @@ import { FEATURE_FLAGS } from 'lib/constants'
import { dayjs } from 'lib/dayjs'
import { IconAreaChart } from 'lib/lemon-ui/icons'
import { More } from 'lib/lemon-ui/LemonButton/More'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import { useEffect, useState } from 'react'
import { urls } from 'scenes/urls'

import { groupsModel } from '~/models/groupsModel'
import { filtersToQueryNode } from '~/queries/nodes/InsightQuery/utils/filtersToQueryNode'
import { queryFromFilters } from '~/queries/nodes/InsightViz/utils'
import { Query } from '~/queries/Query/Query'
import {
CachedExperimentFunnelsQueryResponse,
CachedExperimentTrendsQueryResponse,
ExperimentFunnelsQueryResponse,
ExperimentTrendsQueryResponse,
InsightQueryNode,
InsightVizNode,
NodeKind,
} from '~/queries/schema'
import {
Experiment,
Experiment as ExperimentType,
ExperimentIdType,
ExperimentResults,
InsightShortId,
InsightType,
} from '~/types'
import { Experiment, Experiment as ExperimentType, ExperimentIdType, InsightShortId, InsightType } from '~/types'

import { experimentLogic } from '../experimentLogic'
import { getExperimentStatus, getExperimentStatusColor } from '../experimentsLogic'
import { getExperimentInsightColour, transformResultFilters } from '../utils'
import { getExperimentInsightColour } from '../utils'

export function VariantTag({
experimentId,
Expand Down Expand Up @@ -128,79 +116,39 @@ export function ResultsTag({ metricIndex = 0 }: { metricIndex?: number }): JSX.E
}

export function ResultsQuery({
targetResults,
result,
showTable,
}: {
targetResults: ExperimentResults['result'] | ExperimentTrendsQueryResponse | ExperimentFunnelsQueryResponse | null
result: ExperimentTrendsQueryResponse | ExperimentFunnelsQueryResponse | null
showTable: boolean
}): JSX.Element {
const { featureFlags } = useValues(featureFlagLogic)
if (featureFlags[FEATURE_FLAGS.EXPERIMENTS_HOGQL]) {
const newQueryResults = targetResults as unknown as
| CachedExperimentTrendsQueryResponse
| CachedExperimentFunnelsQueryResponse

const query =
newQueryResults.kind === NodeKind.ExperimentTrendsQuery
? newQueryResults.count_query
: newQueryResults.funnels_query
const fakeInsightId = Math.random().toString(36).substring(2, 15)

return (
<Query
query={{
kind: NodeKind.InsightVizNode,
source: query,
showTable,
showLastComputation: true,
showLastComputationRefresh: false,
}}
context={{
insightProps: {
dashboardItemId: fakeInsightId as InsightShortId,
cachedInsight: {
short_id: fakeInsightId as InsightShortId,
query: {
kind: NodeKind.InsightVizNode,
source: query,
} as InsightVizNode,
result: newQueryResults?.insight,
disable_baseline: true,
},
doNotLoad: true,
},
}}
readOnly
/>
)
}

const oldQueryResults = targetResults as ExperimentResults['result']

if (!oldQueryResults?.filters) {
if (!result) {
return <></>
}

const query = result.kind === NodeKind.ExperimentTrendsQuery ? result.count_query : result.funnels_query
const fakeInsightId = Math.random().toString(36).substring(2, 15)

return (
<Query
query={{
kind: NodeKind.InsightVizNode,
source: filtersToQueryNode(transformResultFilters(oldQueryResults?.filters ?? {})),
source: query,
showTable,
showLastComputation: true,
showLastComputationRefresh: false,
}}
context={{
insightProps: {
dashboardItemId: oldQueryResults?.fakeInsightId as InsightShortId,
dashboardItemId: fakeInsightId as InsightShortId,
cachedInsight: {
short_id: oldQueryResults?.fakeInsightId as InsightShortId,
query: oldQueryResults?.filters
? queryFromFilters(transformResultFilters(oldQueryResults.filters))
: null,
result: oldQueryResults?.insight,
short_id: fakeInsightId as InsightShortId,
query: {
kind: NodeKind.InsightVizNode,
source: query,
} as InsightVizNode,
result: result?.insight,
disable_baseline: true,
last_refresh: oldQueryResults?.last_refresh,
},
doNotLoad: true,
},
Expand All @@ -211,15 +159,12 @@ export function ResultsQuery({
}

export function ExploreButton({
metricIndex = 0,
isSecondary = false,
result,
size = 'small',
}: {
metricIndex?: number
isSecondary?: boolean
result: ExperimentTrendsQueryResponse | ExperimentFunnelsQueryResponse | null
size?: 'xsmall' | 'small' | 'large'
}): JSX.Element {
const { metricResults, secondaryMetricResults } = useValues(experimentLogic)
const result = isSecondary ? secondaryMetricResults?.[metricIndex] : metricResults?.[metricIndex]

if (!result) {
return <></>
}
Expand All @@ -234,7 +179,7 @@ export function ExploreButton({
return (
<LemonButton
className="ml-auto -translate-y-2"
size="small"
size={size}
type="primary"
icon={<IconAreaChart />}
to={urls.insightNew(undefined, undefined, query)}
Expand All @@ -260,7 +205,7 @@ export function ResultsHeader(): JSX.Element {
</div>

<div className="w-1/2 flex flex-col justify-end">
<div className="ml-auto">{result && <ExploreButton />}</div>
<div className="ml-auto">{result && <ExploreButton result={result} />}</div>
</div>
</div>
)
Expand Down Expand Up @@ -586,7 +531,7 @@ export function ShipVariantModal({ experimentId }: { experimentId: Experiment['i

const [selectedVariantKey, setSelectedVariantKey] = useState<string | null>()
useEffect(() => {
if (experiment.parameters?.feature_flag_variants?.length > 0) {
if (experiment.parameters?.feature_flag_variants?.length > 1) {
// First test variant selected by default
setSelectedVariantKey(experiment.parameters.feature_flag_variants[1].key)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function SecondaryMetricChartModal({
</LemonButton>
}
>
<ResultsQuery targetResults={targetResults} showTable={false} />
<ResultsQuery result={targetResults} showTable={false} />
</LemonModal>
)
}
72 changes: 55 additions & 17 deletions frontend/src/scenes/experiments/MetricsView/DeltaChart.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { IconActivity, IconGraph, IconMinus, IconPencil, IconTrending } from '@posthog/icons'
import {
IconActivity,
IconArrowRight,
IconFunnels,
IconGraph,
IconMinus,
IconPencil,
IconTrending,
} from '@posthog/icons'
import { LemonBanner, LemonButton, LemonModal, LemonTag, LemonTagType, Tooltip } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { LemonProgress } from 'lib/lemon-ui/LemonProgress'
Expand Down Expand Up @@ -35,6 +43,34 @@ function formatTickValue(value: number): string {

return `${(value * 100).toFixed(decimals)}%`
}
const getMetricTitle = (metric: any, metricType: InsightType): JSX.Element => {
if (metric.name) {
return <span className="truncate">{metric.name}</span>
}

if (metricType === InsightType.TRENDS && metric.count_query?.series?.[0]?.name) {
return <span className="truncate">{metric.count_query.series[0].name}</span>
}

if (metricType === InsightType.FUNNELS && metric.funnels_query?.series) {
const series = metric.funnels_query.series
if (series.length > 0) {
const firstStep = series[0]?.name
const lastStep = series[series.length - 1]?.name

return (
<span className="inline-flex items-center gap-1 min-w-0">
<IconFunnels className="text-muted flex-shrink-0" fontSize="14" />
<span className="truncate">{firstStep}</span>
<IconArrowRight className="text-muted flex-shrink-0" fontSize="14" />
<span className="truncate">{lastStep}</span>
</span>
)
}
}

return <span className="text-muted truncate">Untitled metric</span>
}

export function DeltaChart({
isSecondary,
Expand Down Expand Up @@ -183,9 +219,9 @@ export function DeltaChart({
<div className="text-xs font-semibold whitespace-nowrap overflow-hidden">
<div className="space-y-1 pl-1">
<div className="flex items-center gap-2">
<div className="cursor-default text-xs font-semibold whitespace-nowrap overflow-hidden text-ellipsis flex-grow">
{metricIndex + 1}.{' '}
{metric.name || <span className="text-muted">Untitled metric</span>}
<div className="cursor-default text-xs font-semibold whitespace-nowrap overflow-hidden text-ellipsis flex-grow flex items-center">
<span className="mr-1">{metricIndex + 1}.</span>
{getMetricTitle(metric, metricType)}
</div>
<LemonButton
className="flex-shrink-0"
Expand Down Expand Up @@ -248,17 +284,19 @@ export function DeltaChart({
}}
>
<SignificanceHighlight metricIndex={metricIndex} isSecondary={isSecondary} />
<div className="flex justify-center">
<LemonButton
className="mt-1"
type="secondary"
size="xsmall"
icon={<IconGraph />}
onClick={() => setIsModalOpen(true)}
>
Detailed results
</LemonButton>
</div>
{experiment.metrics.length > 1 && (
<div className="flex justify-center">
<LemonButton
className="mt-1"
type="secondary"
size="xsmall"
icon={<IconGraph />}
onClick={() => setIsModalOpen(true)}
>
Detailed results
</LemonButton>
</div>
)}
</div>
)}
</div>
Expand Down Expand Up @@ -789,7 +827,7 @@ export function DeltaChart({
}
>
<div className="flex justify-end">
<ExploreButton metricIndex={metricIndex} isSecondary={isSecondary} />
<ExploreButton result={result} />
</div>
<LemonBanner type="info" className="mb-4">
<div className="items-center inline-flex flex-wrap">
Expand All @@ -798,7 +836,7 @@ export function DeltaChart({
</div>
</LemonBanner>
<SummaryTable metric={metric} metricIndex={metricIndex} isSecondary={isSecondary} />
<ResultsQuery targetResults={result} showTable={true} />
<ResultsQuery result={result} showTable={true} />
</LemonModal>
</div>
)
Expand Down
Loading

0 comments on commit c3adb73

Please sign in to comment.