Skip to content

Commit

Permalink
Merge branch 'master' into feat/flag-db-operations-validation
Browse files Browse the repository at this point in the history
  • Loading branch information
dmarticus authored Aug 9, 2024
2 parents fad7f0b + 0d07fe8 commit 3a72b41
Show file tree
Hide file tree
Showing 219 changed files with 387 additions and 147 deletions.
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__/lemon-ui-lemon-field--pure-fields--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__/lemon-ui-lemon-field--pure-fields--light.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.
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-app-surveys--new-survey--dark.png
Binary file modified frontend/__snapshots__/scenes-app-surveys--new-survey--light.png
Binary file modified frontend/__snapshots__/scenes-other-invitesignup--cloud--dark.png
Binary file modified frontend/__snapshots__/scenes-other-login--cloud--dark.png
Binary file modified frontend/__snapshots__/scenes-other-login--cloud--light.png
Binary file modified frontend/__snapshots__/scenes-other-login--cloud-eu--dark.png
Binary file modified frontend/__snapshots__/scenes-other-login--cloud-eu--light.png
Binary file modified frontend/__snapshots__/scenes-other-login--second-factor--dark.png
Binary file modified frontend/__snapshots__/scenes-other-login--self-hosted--dark.png
Binary file modified frontend/__snapshots__/scenes-other-login--self-hosted--light.png
Binary file modified frontend/__snapshots__/scenes-other-login--sso-error--dark.png
Binary file modified frontend/__snapshots__/scenes-other-login--sso-error--light.png
Binary file modified frontend/__snapshots__/scenes-other-signup--cloud--dark.png
Binary file modified frontend/__snapshots__/scenes-other-signup--cloud--light.png
Binary file modified frontend/__snapshots__/scenes-other-signup--self-hosted--light.png
2 changes: 1 addition & 1 deletion frontend/src/lib/lemon-ui/LemonField/LemonField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const LemonPureField = ({
onClick={onClick}
className={clsx(
'Field flex',
{ 'gap-2': className && className.indexOf('gap-') === -1 },
{ 'gap-2': className ? className.indexOf('gap-') === -1 : true },
className,
error && 'Field--error',
inline ? 'flex-row' : 'flex-col'
Expand Down
13 changes: 12 additions & 1 deletion frontend/src/queries/nodes/DataTable/dataTableLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,18 @@ export const dataTableLogic = kea<dataTableLogicType>([
})),
selectors({
sourceKind: [(_, p) => [p.query], (query): NodeKind | null => query.source?.kind],
sourceFeatures: [(_, p) => [p.query], (query): Set<QueryFeature> => getQueryFeatures(query.source)],
sourceFeatures: [
(_, p) => [p.query, (_, props) => props.context],
(query, context): Set<QueryFeature> => {
const sourceFeatures = getQueryFeatures(query.source)
if (context?.extraDataTableQueryFeatures) {
for (const feature of context.extraDataTableQueryFeatures) {
sourceFeatures.add(feature)
}
}
return sourceFeatures
},
],
orderBy: [
(s, p) => [p.query, s.sourceFeatures],
(query, sourceFeatures): string[] | null =>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/queries/nodes/DataTable/renderColumnMeta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export function renderColumnMeta(key: string, query: DataTableNode, context?: Qu
let align: ColumnMeta['align']

const queryContextColumnName = key.startsWith('context.columns.') ? trimQuotes(key.substring(16)) : undefined
const queryContextColumn = queryContextColumnName ? context?.columns?.[queryContextColumnName] : undefined
const queryContextColumn =
(queryContextColumnName ? context?.columns?.[queryContextColumnName] : undefined) ?? context?.columns?.[key]

if (queryContextColumnName && queryContextColumn && (queryContextColumn.title || queryContextColumn.renderTitle)) {
const Component = queryContextColumn.renderTitle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function PropertyDefinitionsTable(): JSX.Element {
Query with SQL
</Link>
</LemonBanner>
<div className="flex justify-between mb-4 gap-2 flex-wrap">
<div className="flex mb-4 gap-2 flex-wrap">
<LemonInput
type="search"
placeholder="Search for properties"
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/scenes/error-tracking/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,19 @@ export const errorTrackingQuery = ({
filterTestAccounts,
filterGroup,
sparklineSelectedPeriod,
columns,
}: {
order: ErrorTrackingQuery['order']
dateRange: DateRange
filterTestAccounts: boolean
filterGroup: UniversalFiltersGroup
sparklineSelectedPeriod: string | null
columns?: ('error' | 'volume' | 'occurrences' | 'sessions' | 'users' | 'assignee')[]
}): DataTableNode => {
const select: string[] = []

const columns = ['error', 'occurrences', 'sessions', 'users', 'assignee']
if (!columns) {
columns = ['error', 'occurrences', 'sessions', 'users', 'assignee']
}

if (sparklineSelectedPeriod) {
const { value, displayAs, offsetHours } = parseSparklineSelection(sparklineSelectedPeriod)
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/scenes/experiments/Experiment.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,10 @@ const MOCK_EXPERIMENT_RESULTS: FunnelExperimentResults = {
failure_count: 28,
},
],
credible_intervals: {
control: [0.0126, 0.0526],
test: [0.0526, 0.0826],
},
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function Overview(): JSX.Element {
comparisonVariant = sortedWinProbabilities.find(({ key }) => key === 'control')
}

if (!comparisonVariant) {
if (!winningVariant?.conversionRate || !comparisonVariant?.conversionRate) {
return <></>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,15 @@ export function SecondaryMetricsTable({
),
render: function Key(_, item: TabularSecondaryMetricResults): JSX.Element {
const { variant } = item
return <div>{targetResults ? countDataForVariant(targetResults, variant) : '--'}</div>
return <div>{targetResults ? countDataForVariant(targetResults, variant) : ''}</div>
},
},
{
title: 'Exposure',
render: function Key(_, item: TabularSecondaryMetricResults): JSX.Element {
const { variant } = item
return (
<div>{targetResults ? exposureCountDataForVariant(targetResults, variant) : '--'}</div>
<div>{targetResults ? exposureCountDataForVariant(targetResults, variant) : ''}</div>
)
},
},
Expand All @@ -233,7 +233,7 @@ export function SecondaryMetricsTable({
<b>
{targetResults?.probability?.[variant] != undefined
? `${(targetResults.probability?.[variant] * 100).toFixed(1)}%`
: '--'}
: ''}
</b>
</div>
)
Expand All @@ -250,7 +250,10 @@ export function SecondaryMetricsTable({
render: function Key(_, item: TabularSecondaryMetricResults): JSX.Element {
const { variant } = item
const conversionRate = conversionRateForVariant(targetResults || null, variant)
return <div>{conversionRate === '--' ? conversionRate : `${conversionRate}%`}</div>
if (!conversionRate) {
return <></>
}
return <div>{`${conversionRate.toFixed(2)}%`}</div>
},
},
{
Expand All @@ -262,7 +265,7 @@ export function SecondaryMetricsTable({
<b>
{targetResults?.probability?.[variant] != undefined
? `${(targetResults.probability?.[variant] * 100).toFixed(1)}%`
: '--'}
: ''}
</b>
</div>
)
Expand Down
71 changes: 63 additions & 8 deletions frontend/src/scenes/experiments/ExperimentView/SummaryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useValues } from 'kea'
import { EntityFilterInfo } from 'lib/components/EntityFilterInfo'
import { LemonProgress } from 'lib/lemon-ui/LemonProgress'

import { FunnelExperimentVariant, InsightType, TrendExperimentVariant } from '~/types'
import { _FunnelExperimentResults, FunnelExperimentVariant, InsightType, TrendExperimentVariant } from '~/types'

import { experimentLogic } from '../experimentLogic'
import { VariantTag } from './components'
Expand Down Expand Up @@ -88,13 +88,68 @@ export function SummaryTable(): JSX.Element {
title: 'Conversion rate',
render: function Key(_, item): JSX.Element {
const conversionRate = conversionRateForVariant(experimentResults, item.key)
return (
<div className="font-semibold">
{conversionRate === '--' ? conversionRate : `${conversionRate}%`}
</div>
)
if (!conversionRate) {
return <></>
}

return <div className="font-semibold">{`${conversionRate.toFixed(2)}%`}</div>
},
})
}),
columns.push({
key: 'delta',
title: (
<div className="inline-flex items-center space-x-1">
<div className="">Delta %</div>
<Tooltip title="Delta % indicates the percentage change in the conversion rate between the control and the test variant.">
<IconInfo className="text-muted-alt text-base" />
</Tooltip>
</div>
),
render: function Key(_, item): JSX.Element {
if (item.key === 'control') {
return <em>Baseline</em>
}

const controlConversionRate = conversionRateForVariant(experimentResults, 'control')
const variantConversionRate = conversionRateForVariant(experimentResults, item.key)

if (!controlConversionRate || !variantConversionRate) {
return <></>
}

const delta = variantConversionRate - controlConversionRate

return (
<div
className={`font-semibold ${delta > 0 ? 'text-success' : delta < 0 ? 'text-danger' : ''}`}
>{`${delta > 0 ? '+' : ''}${delta.toFixed(2)}%`}</div>
)
},
}),
columns.push({
key: 'credibleInterval',
title: (
<div className="inline-flex items-center space-x-1">
<div className="">Credible interval (95%)</div>
<Tooltip title="A credible interval represents a range within which we believe the true parameter value lies with a certain probability (often 95%), based on the posterior distribution derived from the observed data and our prior beliefs.">
<IconInfo className="text-muted-alt text-base" />
</Tooltip>
</div>
),
render: function Key(_, item): JSX.Element {
const credibleInterval = (experimentResults as _FunnelExperimentResults)?.credible_intervals?.[
item.key
]
if (!credibleInterval) {
return <></>
}

const lowerBound = (credibleInterval[0] * 100).toFixed(2)
const upperBound = (credibleInterval[1] * 100).toFixed(2)

return <div className="font-semibold">{`[${lowerBound}%, ${upperBound}%]`}</div>
},
})
}

columns.push({
Expand Down Expand Up @@ -122,7 +177,7 @@ export function SummaryTable(): JSX.Element {
</span>
</span>
) : (
'--'
''
)}
</>
)
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/scenes/experiments/Experiments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { LemonButton } from 'lib/lemon-ui/LemonButton'
import { More } from 'lib/lemon-ui/LemonButton/More'
import { LemonDivider } from 'lib/lemon-ui/LemonDivider'
import { LemonTable, LemonTableColumn, LemonTableColumns } from 'lib/lemon-ui/LemonTable'
import { createdAtColumn, createdByColumn } from 'lib/lemon-ui/LemonTable/columnUtils'
import { atColumn, createdAtColumn, createdByColumn } from 'lib/lemon-ui/LemonTable/columnUtils'
import { LemonTableLink } from 'lib/lemon-ui/LemonTable/LemonTableLink'
import { LemonTabs } from 'lib/lemon-ui/LemonTabs'
import { Link } from 'lib/lemon-ui/Link'
Expand Down Expand Up @@ -64,13 +64,14 @@ export function Experiments(): JSX.Element {
},
createdByColumn<Experiment>() as LemonTableColumn<Experiment, keyof Experiment | undefined>,
createdAtColumn<Experiment>() as LemonTableColumn<Experiment, keyof Experiment | undefined>,
atColumn('start_date', 'Started') as LemonTableColumn<Experiment, keyof Experiment | undefined>,
{
title: 'Duration',
key: 'duration',
render: function Render(_, experiment: Experiment) {
const duration = getExperimentDuration(experiment)

return <div>{duration !== undefined ? `${duration} day${duration !== 1 ? 's' : ''}` : '--'}</div>
return <div>{duration !== undefined ? `${duration} day${duration !== 1 ? 's' : ''}` : ''}</div>
},
sorter: (a, b) => {
const durationA = getExperimentDuration(a) ?? -1
Expand Down
21 changes: 11 additions & 10 deletions frontend/src/scenes/experiments/experimentLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1051,20 +1051,21 @@ export const experimentLogic = kea<experimentLogicType>([
conversionRateForVariant: [
() => [],
() =>
(experimentResults: Partial<ExperimentResults['result']> | null, variant: string): string => {
const errorResult = '--'
(experimentResults: Partial<ExperimentResults['result']> | null, variantKey: string): number | null => {
if (!experimentResults || !experimentResults.insight) {
return errorResult
return null
}
const variantResults = (experimentResults.insight as FunnelStep[][]).find(
(variantFunnel: FunnelStep[]) => variantFunnel[0]?.breakdown_value?.[0] === variant
(variantFunnel: FunnelStep[]) => {
const breakdownValue = variantFunnel[0]?.breakdown_value
return Array.isArray(breakdownValue) && breakdownValue[0] === variantKey
}
)

if (!variantResults) {
return errorResult
return null
}
return ((variantResults[variantResults.length - 1].count / variantResults[0].count) * 100).toFixed(
1
)
return (variantResults[variantResults.length - 1].count / variantResults[0].count) * 100
},
],
getIndexForVariant: [
Expand Down Expand Up @@ -1285,7 +1286,7 @@ export const experimentLogic = kea<experimentLogicType>([
(
experimentResults,
conversionRateForVariant
): { key: string; winProbability: number; conversionRate: number }[] => {
): { key: string; winProbability: number; conversionRate: number | null }[] => {
if (!experimentResults) {
return []
}
Expand All @@ -1294,7 +1295,7 @@ export const experimentLogic = kea<experimentLogicType>([
.map((key) => ({
key,
winProbability: experimentResults.probability[key],
conversionRate: parseFloat(conversionRateForVariant(experimentResults, key)),
conversionRate: conversionRateForVariant(experimentResults, key),
}))
.sort((a, b) => b.winProbability - a.winProbability)
},
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/scenes/retention/RetentionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function RetentionModal(): JSX.Element | null {
footer={
<div className="flex justify-between gap-2 w-full">
<div className="flex gap-2">
{people.result?.length && !exploreUrl && (
{!!people.result?.length && !exploreUrl && (
<LemonButton
type="secondary"
onClick={() =>
Expand All @@ -68,7 +68,7 @@ export function RetentionModal(): JSX.Element | null {
Download CSV
</LemonButton>
)}
{people.result?.length && !!dataTableNodeQuery && (
{!!people.result?.length && !!dataTableNodeQuery && (
<LemonButton
type="secondary"
onClick={() => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/web-analytics/WebAnalyticsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { IconOpenInNew } from 'lib/lemon-ui/icons'
import { LemonButton } from 'lib/lemon-ui/LemonButton'
import { LemonModal } from 'lib/lemon-ui/LemonModal'
import { urls } from 'scenes/urls'
import { WebQuery } from 'scenes/web-analytics/tiles/WebAnalyticsTile'
import { webAnalyticsLogic } from 'scenes/web-analytics/webAnalyticsLogic'
import { WebQuery } from 'scenes/web-analytics/WebAnalyticsTile'
import { WebPropertyFilters } from 'scenes/web-analytics/WebPropertyFilters'

export const WebAnalyticsModal = (): JSX.Element | null => {
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/scenes/web-analytics/WebDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { PostHogComDocsURL } from 'lib/lemon-ui/Link/Link'
import { Popover } from 'lib/lemon-ui/Popover'
import { isNotNil } from 'lib/utils'
import React, { useState } from 'react'
import { WebAnalyticsErrorTrackingTile } from 'scenes/web-analytics/tiles/WebAnalyticsErrorTracking'
import { WebAnalyticsRecordingsTile } from 'scenes/web-analytics/tiles/WebAnalyticsRecordings'
import { WebQuery } from 'scenes/web-analytics/tiles/WebAnalyticsTile'
import { WebAnalyticsHealthCheck } from 'scenes/web-analytics/WebAnalyticsHealthCheck'
import {
QueryTile,
Expand All @@ -21,8 +24,6 @@ import {
webAnalyticsLogic,
} from 'scenes/web-analytics/webAnalyticsLogic'
import { WebAnalyticsModal } from 'scenes/web-analytics/WebAnalyticsModal'
import { WebAnalyticsRecordingsTile } from 'scenes/web-analytics/WebAnalyticsRecordings'
import { WebQuery } from 'scenes/web-analytics/WebAnalyticsTile'
import { WebPropertyFilters } from 'scenes/web-analytics/WebPropertyFilters'

import { navigationLogic } from '~/layout/navigation/navigationLogic'
Expand Down Expand Up @@ -72,6 +73,8 @@ const Tiles = (): JSX.Element => {
return <TabsTileItem key={i} tile={tile} />
} else if (tile.kind === 'replay') {
return <WebAnalyticsRecordingsTile key={i} tile={tile} />
} else if (tile.kind === 'error_tracking') {
return <WebAnalyticsErrorTrackingTile key={i} tile={tile} />
}
return null
})}
Expand Down
Loading

0 comments on commit 3a72b41

Please sign in to comment.