Skip to content

Commit

Permalink
feat: promote data warehouse from taxonomic filter component (#27364)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshsny authored Jan 9, 2025
1 parent 628a6df commit e441bbd
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 2 deletions.
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 />
}

0 comments on commit e441bbd

Please sign in to comment.