Skip to content

Commit

Permalink
Merge branch 'master' into element-text-match
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusandra committed Sep 4, 2024
2 parents e82219b + cb2f99a commit 60b11e3
Show file tree
Hide file tree
Showing 277 changed files with 5,145 additions and 2,586 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
- Analyze data with ready-made visualizations, or do it yourself with SQL
- Only capture properties on the people you want to track, save money when you don't
- Gather insights by capturing session replays, console logs, and network monitoring
- Improve your product with A/B testing that automatically analyzes performance
- Improve your product with Experiments that automatically analyze performance
- Safely roll out features to select users or cohorts with feature flags
- Send out fully customizable surveys to specific cohorts of users
- Connect to external services and manage data flows with PostHog CDP
Expand Down Expand Up @@ -81,7 +81,7 @@ PostHog brings all the tools and data you need to build better products.
- **Session replays:** [Watch videos](https://posthog.com/docs/features/session-recording) of your users' behavior, with fine-grained filters and privacy controls, as well as network monitoring and captured console logs
- **Heatmaps:** See where users click and get a visual representation of their behaviour with the [PostHog Toolbar](https://posthog.com/docs/features/toolbar)
- **Feature flags:** Test and manage the rollout of [new features](https://posthog.com/docs/feature-flags/installation) to specific users and groups, or deploy flags as kill-switches
- **A/B and multivariate experimentation:** run simple or complex changes as [experiments](https://posthog.com/manual/experimentation) and get automatic significance calculations
- **Experiments:** run simple or complex changes as [experiments](https://posthog.com/manual/experimentation) and get automatic significance calculations
- **Correlation analysis:** Discover what events and properties [correlate](https://posthog.com/manual/correlation) with success and failure
- **Surveys:** Collect qualitative feedback from your users using fully customizable [surveys](https://posthog.com/docs/surveys/installation)

Expand Down
7 changes: 7 additions & 0 deletions bin/upgrade-hobby
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ else
exit
fi

if [ "$REGISTRY_URL" == "" ]
then
export REGISTRY_URL="posthog/posthog"
fi

export POSTHOG_APP_TAG="${POSTHOG_APP_TAG:-latest}"

echo "Checking for named postgres and clickhouse volumes to avoid data loss when upgrading from < 1.39"
if docker volume ls | grep -Pzoq 'clickhouse-data\n(.|\n)*postgres-data\n'
then
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/experiments.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('Experiments', () => {

it('create experiment', () => {
cy.visit('/experiments')
cy.get('[data-attr=top-bar-name]').should('contain', 'A/B testing')
cy.get('[data-attr=top-bar-name]').should('contain', 'Experiments')

// Name, flag key, description
cy.get('[data-attr=create-experiment]').first().click()
Expand Down
11 changes: 11 additions & 0 deletions docker-compose.hobby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ services:
service: redis
volumes:
- redis-data:/data

redis7:
extends:
file: docker-compose.base.yml
service: redis7
volumes:
- redis7-data:/data

clickhouse:
#
# Note: please keep the default version in sync across
Expand Down Expand Up @@ -112,9 +120,11 @@ services:
OBJECT_STORAGE_SECRET_ACCESS_KEY: 'object_storage_root_password'
OBJECT_STORAGE_ENDPOINT: http://objectstorage:19000
OBJECT_STORAGE_ENABLED: true
CDP_REDIS_HOST: redis7
depends_on:
- db
- redis
- redis7
- clickhouse
- kafka
- objectstorage
Expand Down Expand Up @@ -215,4 +225,5 @@ volumes:
caddy-data:
caddy-config:
redis-data:
redis7-data:
kafka-data:
2 changes: 1 addition & 1 deletion ee/api/feature_flag_role_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class FeatureFlagRoleAccessViewSet(
permission_classes = [FeatureFlagRoleAccessPermissions]
serializer_class = FeatureFlagRoleAccessSerializer
queryset = FeatureFlagRoleAccess.objects.select_related("feature_flag")
filter_rewrite_rules = {"team_id": "feature_flag__team_id"}
filter_rewrite_rules = {"project_id": "feature_flag__team__project_id"}

def safely_get_queryset(self, queryset):
filters = self.request.GET.dict()
Expand Down
2 changes: 1 addition & 1 deletion ee/billing/test/test_billing_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def create_default_products_response(**kwargs) -> dict[str, list[Product]]:
Product(
name="Product analytics",
headline="Product analytics with autocapture",
description="A comprehensive product analytics platform built to natively work with session replay, feature flags, A/B testing, and surveys.",
description="A comprehensive product analytics platform built to natively work with session replay, feature flags, experiments, and surveys.",
usage_key="events",
image_url="https://posthog.com/images/products/product-analytics/product-analytics.png",
docs_url="https://posthog.com/docs/product-analytics",
Expand Down
6 changes: 3 additions & 3 deletions ee/clickhouse/queries/experiments/funnel_experiment_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ def calculate_results(

if len(test_variants) >= 10:
raise ValidationError(
"Can't calculate A/B test results for more than 10 variants",
"Can't calculate experiment results for more than 10 variants",
code="too_much_data",
)

if len(test_variants) < 1:
raise ValidationError(
"Can't calculate A/B test results for less than 2 variants",
"Can't calculate experiment results for less than 2 variants",
code="no_data",
)

Expand Down Expand Up @@ -311,7 +311,7 @@ def calculate_probability_of_winning_for_each(variants: list[Variant]) -> list[P
"""
if len(variants) > 10:
raise ValidationError(
"Can't calculate A/B test results for more than 10 variants",
"Can't calculate experiment results for more than 10 variants",
code="too_much_data",
)

Expand Down
8 changes: 4 additions & 4 deletions ee/clickhouse/queries/experiments/trend_experiment_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,13 @@ def calculate_results(control_variant: Variant, test_variants: list[Variant]) ->

if len(test_variants) >= 10:
raise ValidationError(
"Can't calculate A/B test results for more than 10 variants",
"Can't calculate experiment results for more than 10 variants",
code="too_much_data",
)

if len(test_variants) < 1:
raise ValidationError(
"Can't calculate A/B test results for less than 2 variants",
"Can't calculate experiment results for less than 2 variants",
code="no_data",
)

Expand Down Expand Up @@ -413,7 +413,7 @@ def calculate_probability_of_winning_for_each(variants: list[Variant]) -> list[P

if len(variants) > 10:
raise ValidationError(
"Can't calculate A/B test results for more than 10 variants",
"Can't calculate experiment results for more than 10 variants",
code="too_much_data",
)

Expand Down Expand Up @@ -447,7 +447,7 @@ def intermediate_poisson_term(count: int, iterator: int, relative_exposure: floa

def poisson_p_value(control_count, control_exposure, test_count, test_exposure):
"""
Calculates the p-value of the A/B test.
Calculates the p-value of the experiment.
Calculations from: https://www.evanmiller.org/statistical-formulas-for-programmers.html#count_test
"""
relative_exposure = test_exposure / (control_exposure + test_exposure)
Expand Down
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.
2 changes: 1 addition & 1 deletion frontend/src/layout/navigation-3000/navigationLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
},
{
identifier: Scene.Experiments,
label: 'A/B testing',
label: 'Experiments',
icon: <IconTestTube />,
logic: isUsingSidebar ? experimentsSidebarLogic : undefined,
to: isUsingSidebar ? undefined : urls.experiments(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export const dataManagementSidebarLogic = kea<dataManagementSidebarLogicType>([
menuItems: [
{
label: 'View recordings',
to: urls.replay(ReplayTabs.Recent, {
to: urls.replay(ReplayTabs.Home, {
filter_group: {
type: FilterLogicalOperator.And,
values: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const PRODUCTS = [
icon: <IconToggle className="text-success h-5 w-5" />,
},
{
name: 'A/B testing',
name: 'Experiments',
slug: 'experiments',
icon: <IconFlask className="text-purple h-5 w-5" />,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@
outline: 1px solid var(--primary-3000);
}

&.react-draggable::after {
// During dashboard layout editing, we need an overlay to prevent accidental interaction with card content
position: absolute;
inset: 0;
z-index: var(--z-content-overlay);
content: '';
}

.ErrorBoundary {
width: 100%;
height: 100%;
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/lib/components/Cards/handles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export function ResizeHandle1D({ orientation }: { orientation: 'horizontal' | 'v
return (
<div className={clsx('handle', orientation)}>
<svg fill="none" height="24" viewBox="0 0 16 24" width="16" xmlns="http://www.w3.org/2000/svg">
<rect fill="#fff" height="23" rx="3.5" width="15" x=".5" y=".5" />
<g fill="#5375ff">
<rect fill="var(--bg-light)" height="23" rx="3.5" width="15" x=".5" y=".5" />
<g fill="var(--primary)">
<rect height="2" rx=".25" width="2" x="5" y="5" />
<rect height="2" rx=".25" width="2" x="9" y="5" />
<rect height="2" rx=".25" width="2" x="5" y="9" />
Expand All @@ -16,7 +16,7 @@ export function ResizeHandle1D({ orientation }: { orientation: 'horizontal' | 'v
<rect height="2" rx=".25" width="2" x="5" y="13" />
<rect height="2" rx=".25" width="2" x="5" y="17" />
</g>
<rect height="23" rx="3.5" stroke="#d9d9d9" width="15" x=".5" y=".5" />
<rect height="23" rx="3.5" stroke="var(--border)" width="15" x=".5" y=".5" />
</svg>
</div>
)
Expand All @@ -27,16 +27,16 @@ export function ResizeHandle2D(): JSX.Element {
return (
<div className="handle corner">
<svg fill="none" height="18" viewBox="0 0 18 18" width="18" xmlns="http://www.w3.org/2000/svg">
<rect fill="#fff" height="17" rx="3.5" width="17" x=".5" y=".5" />
<g fill="#5375ff">
<rect fill="var(--bg-light)" height="17" rx="3.5" width="17" x=".5" y=".5" />
<g fill="var(--primary)">
<rect height="2" rx=".25" width="2" x="8" y="8" />
<rect height="2" rx=".25" width="2" x="8" y="12" />
<rect height="2" rx=".25" width="2" x="12" y="4" />
<rect height="2" rx=".25" width="2" x="4" y="12" />
<rect height="2" rx=".25" width="2" x="12" y="8" />
<rect height="2" rx=".25" width="2" x="12" y="12" />
</g>
<rect height="17" rx="3.5" stroke="#d9d9d9" width="17" x=".5" y=".5" />
<rect height="17" rx="3.5" stroke="var(--border)" width="17" x=".5" y=".5" />
</svg>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ export const commandPaletteLogic = kea<commandPaletteLogicType>([
},
{
icon: IconTestTube,
display: 'Go to A/B testing',
display: 'Go to Experiments',
executor: () => {
push(urls.experiments())
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { LemonBanner, Spinner } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { useEffect } from 'react'
import useResizeObserver from 'use-resize-observer'

import { ToolbarUserIntent } from '~/types'

import { appEditorUrl } from '../AuthorizedUrlList/authorizedUrlListLogic'
import { iframedToolbarBrowserLogic } from './iframedToolbarBrowserLogic'

function IframeErrorOverlay(): JSX.Element | null {
const logic = iframedToolbarBrowserLogic()
const { iframeBanner } = useValues(logic)
return iframeBanner ? (
<div className="absolute flex flex-col w-full h-full bg-blend-overlay items-start py-4 px-8 pointer-events-none">
<LemonBanner className="w-full" type={iframeBanner.level}>
{iframeBanner.message}. Your site might not allow being embedded in an iframe. You can click "Open in
toolbar" above to visit your site and view the heatmap there.
</LemonBanner>
</div>
) : null
}

function LoadingOverlay(): JSX.Element | null {
const logic = iframedToolbarBrowserLogic()
const { loading } = useValues(logic)
return loading ? (
<div className="absolute flex flex-col w-full h-full items-center justify-center pointer-events-none">
<Spinner className="text-5xl" textColored={true} />
</div>
) : null
}

export function IframedToolbarBrowser({
iframeRef,
userIntent,
}: {
iframeRef?: React.MutableRefObject<HTMLIFrameElement | null>
userIntent: ToolbarUserIntent
}): JSX.Element | null {
const logic = iframedToolbarBrowserLogic()

const { browserUrl } = useValues(logic)
const { onIframeLoad, setIframeWidth } = useActions(logic)

const { width: iframeWidth } = useResizeObserver<HTMLIFrameElement>({ ref: iframeRef })
useEffect(() => {
setIframeWidth(iframeWidth ?? null)
}, [iframeWidth])

return browserUrl ? (
<div className="relative flex-1 w-full h-full">
<IframeErrorOverlay />
<LoadingOverlay />
<iframe
ref={iframeRef}
className="w-full h-full"
src={appEditorUrl(browserUrl, {
userIntent: userIntent,
})}
// eslint-disable-next-line react/forbid-dom-props
style={{
background: '#FFF',
}}
onLoad={onIframeLoad}
// these two sandbox values are necessary so that the site and toolbar can run
// this is a very loose sandbox,
// but we specify it so that at least other capabilities are denied
sandbox="allow-scripts allow-same-origin"
// we don't allow things such as camera access though
allow=""
/>
</div>
) : null
}
Loading

0 comments on commit 60b11e3

Please sign in to comment.