Skip to content

Commit

Permalink
Merge branch 'master' into fix/remove-targetting-options-from-survey
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasheriques committed Jan 9, 2025
2 parents 4119d87 + b62d9eb commit 4e7c62b
Show file tree
Hide file tree
Showing 223 changed files with 2,661 additions and 886 deletions.
2 changes: 1 addition & 1 deletion ee/hogai/taxonomy_agent/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from langgraph.errors import NodeInterrupt
from pydantic import ValidationError

from ee.hogai.taxonomy import CORE_FILTER_DEFINITIONS_BY_GROUP
from posthog.taxonomy.taxonomy import CORE_FILTER_DEFINITIONS_BY_GROUP
from ee.hogai.taxonomy_agent.parsers import (
ReActParserException,
ReActParserMissingActionException,
Expand Down
2 changes: 1 addition & 1 deletion ee/hogai/taxonomy_agent/toolkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from pydantic import BaseModel, Field, RootModel

from ee.hogai.taxonomy import CORE_FILTER_DEFINITIONS_BY_GROUP
from posthog.taxonomy.taxonomy import CORE_FILTER_DEFINITIONS_BY_GROUP
from posthog.hogql.database.schema.channel_type import DEFAULT_CHANNEL_TYPES
from posthog.hogql_queries.ai.actors_property_taxonomy_query_runner import ActorsPropertyTaxonomyQueryRunner
from posthog.hogql_queries.ai.event_taxonomy_query_runner import EventTaxonomyQueryRunner
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.
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-dashboards--list--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__/scenes-app-dashboards--list--light.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__/scenes-app-dashboards--new--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__/scenes-app-dashboards--new--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.
Binary file modified frontend/__snapshots__/scenes-app-events--event-explorer--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__/scenes-app-events--event-explorer--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.
2 changes: 0 additions & 2 deletions frontend/src/layout/navigation-3000/Navigation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,6 @@
}

.Sidebar3000__content {
position: fixed;
top: 0;
box-sizing: content-box;
display: flex;
flex-direction: column;
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/layout/navigation-3000/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function Navigation({
{activeNavbarItem && <Sidebar key={activeNavbarItem.identifier} navbarItem={activeNavbarItem} />}
</FlaggedFeature>
<main>
{sceneConfig?.layout !== 'app-raw-no-header' && <TopBar />}
{(sceneConfig?.layout !== 'app-raw-no-header' || mobileLayout) && <TopBar />}
<div
className={clsx(
'Navigation3000__scene',
Expand All @@ -58,8 +58,10 @@ export function Navigation({
sceneConfig?.layout === 'app-canvas' && 'Navigation3000__scene--canvas'
)}
>
{!sceneConfig?.hideBillingNotice && <BillingAlertsV2 />}
{!sceneConfig?.hideProjectNotice && <ProjectNotice />}
<div className={sceneConfig?.layout === 'app-raw-no-header' ? 'px-4' : ''}>
{!sceneConfig?.hideBillingNotice && <BillingAlertsV2 />}
{!sceneConfig?.hideProjectNotice && <ProjectNotice />}
</div>
{children}
</div>
</main>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/layout/navigation/OrganizationSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IconPlus } from '@posthog/icons'
import { IconPlusSmall } from '@posthog/icons'
import { useActions, useValues } from 'kea'
import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic'
import { LemonButton } from 'lib/lemon-ui/LemonButton'
Expand Down Expand Up @@ -57,7 +57,7 @@ export function NewOrganizationButton(): JSX.Element {

return (
<LemonButton
icon={<IconPlus />}
icon={<IconPlusSmall />}
onClick={() =>
guardAvailableFeature(
AvailableFeature.ORGANIZATIONS_PROJECTS,
Expand Down
1 change: 1 addition & 0 deletions frontend/src/lib/api.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export const MOCK_DEFAULT_TEAM: TeamType = {
person_on_events_querying_enabled: true,
live_events_token: '123',
capture_dead_clicks: false,
human_friendly_comparison_periods: false,
}

export const MOCK_DEFAULT_PROJECT: ProjectType = {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/components/InsightLabel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function MathTag({ math, mathProperty, mathHogQL, mathGroupTypeIndex }: MathTagP
if (math === 'unique_group' && mathGroupTypeIndex != undefined) {
return <LemonTag>Unique {aggregationLabel(mathGroupTypeIndex).plural}</LemonTag>
}
if (math && ['sum', 'avg', 'min', 'max', 'median', 'p90', 'p95', 'p99'].includes(math || '')) {
if (math && ['sum', 'avg', 'min', 'max', 'median', 'p75', 'p90', 'p95', 'p99'].includes(math)) {
return (
<>
<LemonTag>{mathDefinitions[math]?.name || capitalizeFirstLetter(math)}</LemonTag>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { InfiniteList } from 'lib/components/TaxonomicFilter/InfiniteList'
import { infiniteListLogic } from 'lib/components/TaxonomicFilter/infiniteListLogic'
import { TaxonomicFilterGroupType, TaxonomicFilterLogicProps } from 'lib/components/TaxonomicFilter/types'

import { TaxonomicFilterEmptyState, taxonomicFilterGroupTypesWithEmptyStates } from './TaxonomicFilterEmptyState'
import { taxonomicFilterLogic } from './taxonomicFilterLogic'

export interface InfiniteSelectResultsProps {
Expand All @@ -31,7 +32,7 @@ function CategoryPill({
const group = taxonomicGroups.find((g) => g.type === groupType)

// :TRICKY: use `totalListCount` (results + extra) to toggle interactivity, while showing `totalResultCount`
const canInteract = totalListCount > 0
const canInteract = totalListCount > 0 || taxonomicFilterGroupTypesWithEmptyStates.includes(groupType)

return (
<LemonTag
Expand Down Expand Up @@ -61,7 +62,12 @@ export function InfiniteSelectResults({
}: InfiniteSelectResultsProps): JSX.Element {
const { activeTab, taxonomicGroups, taxonomicGroupTypes, activeTaxonomicGroup, value } =
useValues(taxonomicFilterLogic)
const logic = infiniteListLogic({ ...taxonomicFilterLogicProps, listGroupType: activeTab })

const { setActiveTab, selectItem } = useActions(taxonomicFilterLogic)

const { totalListCount } = useValues(logic)

const RenderComponent = activeTaxonomicGroup?.render

const openTab = activeTab || taxonomicGroups[0].type
Expand All @@ -84,6 +90,8 @@ export function InfiniteSelectResults({
</>
)

const showEmptyState = totalListCount === 0 && taxonomicFilterGroupTypesWithEmptyStates.includes(openTab)

return (
<>
{hasMultipleGroups && (
Expand All @@ -107,14 +115,16 @@ export function InfiniteSelectResults({
</div>
</div>
)}

{taxonomicGroupTypes.map((groupType) => {
return (
<div key={groupType} className={clsx(groupType === openTab ? 'block' : 'hidden')}>
<BindLogic
logic={infiniteListLogic}
props={{ ...taxonomicFilterLogicProps, listGroupType: groupType }}
>
{listComponent}
{showEmptyState && <TaxonomicFilterEmptyState groupType={groupType} />}
{!showEmptyState && listComponent}
</BindLogic>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { IconOpenSidebar, IconPlus } from '@posthog/icons'
import { LemonButton } from '@posthog/lemon-ui'
import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types'
import type React from 'react'
import { urls } from 'scenes/urls'

import { PipelineStage } from '~/types'

import { BuilderHog3 } from '../hedgehogs'

type EmptyStateProps = {
title: string
description: string
action: {
to: string
text: string
}
docsUrl?: string
hog: React.ComponentType<{ className?: string }>
groupType: TaxonomicFilterGroupType
}

const EmptyState = ({ title, description, action, docsUrl, hog: Hog, groupType }: EmptyStateProps): JSX.Element => {
return (
<div className="w-full p-8 rounded mt-4 flex items-center gap-4">
<div className="w-32 h-32">
<Hog className="w-full h-full" />
</div>
<div className="flex-1 text-center">
<h2 className="text-lg font-semibold">{title}</h2>
<p className="text-sm text-muted mt-2">{description}</p>
<div className="flex items-center justify-center gap-4 mt-4">
<LemonButton
type="primary"
icon={<IconPlus />}
to={action.to}
data-attr={`taxonomic-filter-empty-state-${groupType}-new-button`}
>
{action.text}
</LemonButton>
<LemonButton
type="tertiary"
sideIcon={<IconOpenSidebar className="w-4 h-4" />}
to={`${docsUrl}?utm_medium=in-product&utm_campaign=taxonomic-filter-empty-state-docs-link`}
data-attr="product-introduction-docs-link"
targetBlank
>
Learn more
</LemonButton>
</div>
</div>
</div>
)
}

type Props = {
groupType: TaxonomicFilterGroupType
}

const DataWarehouseEmptyState = (): JSX.Element => {
return (
<EmptyState
title="Connect external data"
groupType={TaxonomicFilterGroupType.DataWarehouse}
description="Use data warehouse sources to import data from your external data into PostHog."
action={{
to: urls.pipelineNodeNew(PipelineStage.Source),
text: 'New source',
}}
docsUrl="https://posthog.com/docs/data-warehouse"
hog={BuilderHog3}
/>
)
}

const DefaultEmptyState = (): JSX.Element | null => {
return null
}

const EMPTY_STATES: Partial<Record<TaxonomicFilterGroupType, () => JSX.Element>> = {
[TaxonomicFilterGroupType.DataWarehouse]: DataWarehouseEmptyState,
[TaxonomicFilterGroupType.DataWarehouseProperties]: DataWarehouseEmptyState,
[TaxonomicFilterGroupType.DataWarehousePersonProperties]: DataWarehouseEmptyState,
} as const

export const taxonomicFilterGroupTypesWithEmptyStates = Object.keys(EMPTY_STATES) as TaxonomicFilterGroupType[]

export const TaxonomicFilterEmptyState = (props: Props): JSX.Element => {
const EmptyState = EMPTY_STATES[props.groupType]

if (EmptyState) {
return <EmptyState />
}

return <DefaultEmptyState />
}
12 changes: 11 additions & 1 deletion frontend/src/lib/lemon-ui/LemonFileInput/LemonFileInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface LemonFileInputProps extends Pick<HTMLInputElement, 'multiple' |
* are the files currently being uploaded?
*/
loading?: boolean
/** Whether input field is disabled */
disabled?: boolean
/** if this is not provided then this component is the drop target
* and is styled when a file is dragged over it
* if this alternativeDropTargetRef is provided,
Expand All @@ -35,6 +37,7 @@ export const LemonFileInput = ({
onChange,
multiple,
loading,
disabled,
// e.g. '.json' or 'image/*'
accept,
alternativeDropTargetRef,
Expand Down Expand Up @@ -142,14 +145,21 @@ export const LemonFileInput = ({
'FileDropTarget flex flex-col gap-1',
!alternativeDropTargetRef?.current && drag && 'FileDropTarget--active'
)}
aria-disabled={disabled}
>
<label className="text-muted inline-flex flow-row items-center gap-1 cursor-pointer">
<label
className={clsx(
'text-muted inline-flex flow-row items-center gap-1',
disabled ? 'cursor-not-allowed' : 'cursor-pointer'
)}
>
<input
className="hidden"
type="file"
multiple={multiple}
accept={accept}
onChange={onInputChange}
disabled={disabled}
/>
{callToAction || (
<>
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/lib/taxonomy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ export const SESSION_INITIAL_PROPERTIES_ADAPTED_FROM_EVENTS = new Set([
'rdt_cid',
])

// If adding event properties with labels, check whether they should be added to
// PROPERTY_NAME_ALIASES in posthog/api/property_definition.py
// see code to output JSON below this
// changing values in here you need to sync to python posthog/posthog/taxonomy/taxonomy.py
export const CORE_FILTER_DEFINITIONS_BY_GROUP = {
events: {
'': {
Expand Down
5 changes: 1 addition & 4 deletions frontend/src/lib/utils/eventUsageLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -647,10 +647,7 @@ export const eventUsageLogic = kea<eventUsageLogicType>([
// "insight created" essentially means that the user clicked "New insight"
await breakpoint(500) // Debounce to avoid multiple quick "New insight" clicks being reported

posthog.capture('insight created', {
query_kind: query?.kind,
query_source_kind: isNodeWithSource(query) ? query.source.kind : undefined,
})
posthog.capture('insight created', sanitizeQuery(query))
},
reportInsightSaved: async ({ query, isNewInsight }) => {
// "insight saved" is a proxy for the new insight's results being valuable to the user
Expand Down
1 change: 1 addition & 0 deletions frontend/src/loadPostHogJS.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export function loadPostHogJS(): void {
autocapture: {
capture_copied_text: true,
},
capture_performance: { web_vitals: true },
person_profiles: 'always',
__preview_remote_config: true,

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3906,6 +3906,7 @@
"min_count_per_actor",
"max_count_per_actor",
"median_count_per_actor",
"p75_count_per_actor",
"p90_count_per_actor",
"p95_count_per_actor",
"p99_count_per_actor"
Expand Down Expand Up @@ -9099,7 +9100,7 @@
"type": "object"
},
"PropertyMathType": {
"enum": ["avg", "sum", "min", "max", "median", "p90", "p95", "p99"],
"enum": ["avg", "sum", "min", "max", "median", "p75", "p90", "p95", "p99"],
"type": "string"
},
"PropertyOperator": {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/scenes/appScenes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export const appScenes: Record<Scene, () => any> = {
[Scene.Group]: () => import('./groups/Group'),
[Scene.Action]: () => import('./actions/Action'),
[Scene.Experiments]: () => import('./experiments/Experiments'),
[Scene.ExperimentsSavedMetrics]: () => import('./experiments/SavedMetrics/SavedMetrics'),
[Scene.ExperimentsSavedMetric]: () => import('./experiments/SavedMetrics/SavedMetric'),
[Scene.ExperimentsSharedMetrics]: () => import('./experiments/SharedMetrics/SharedMetrics'),
[Scene.ExperimentsSharedMetric]: () => import('./experiments/SharedMetrics/SharedMetric'),
[Scene.Experiment]: () => import('./experiments/Experiment'),
[Scene.FeatureFlags]: () => import('./feature-flags/FeatureFlags'),
[Scene.FeatureManagement]: () => import('./feature-flags/FeatureManagement'),
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/scenes/billing/Billing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import clsx from 'clsx'
import { useActions, useValues } from 'kea'
import { Field, Form } from 'kea-forms'
import { router } from 'kea-router'
import { RestrictionScope, useRestrictedArea } from 'lib/components/RestrictedArea'
import { supportLogic } from 'lib/components/Support/supportLogic'
import { OrganizationMembershipLevel } from 'lib/constants'
import { dayjs } from 'lib/dayjs'
import { useResizeBreakpoints } from 'lib/hooks/useResizeObserver'
import { LemonBanner } from 'lib/lemon-ui/LemonBanner'
Expand Down Expand Up @@ -36,6 +38,11 @@ export function Billing(): JSX.Element {
const { preflight, isCloudOrDev } = useValues(preflightLogic)
const { openSupportForm } = useActions(supportLogic)

const restrictionReason = useRestrictedArea({
minimumAccessLevel: OrganizationMembershipLevel.Admin,
scope: RestrictionScope.Organization,
})

if (preflight && !isCloudOrDev) {
router.actions.push(urls.default())
}
Expand All @@ -59,6 +66,20 @@ export function Billing(): JSX.Element {
)
}

if (restrictionReason) {
return (
<div className="space-y-4">
<h1>Billing</h1>
<LemonBanner type="warning">{restrictionReason}</LemonBanner>
<div className="flex">
<LemonButton type="primary" to={urls.default()}>
Go back home
</LemonButton>
</div>
</div>
)
}

if (!billing && !billingLoading) {
return (
<div className="space-y-4">
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/scenes/cohorts/CohortFilters/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ export const FIELD_VALUES: Record<FieldOptionsType, FieldValues> = {
[PropertyMathType.Median]: {
label: 'Median',
},
[PropertyMathType.P75]: {
label: '75th percentile',
},
[PropertyMathType.P90]: {
label: '90th percentile',
},
Expand Down
Loading

0 comments on commit 4e7c62b

Please sign in to comment.