Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions frontend/snapshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2580,6 +2580,14 @@ snapshots:
hash: v1.k794b7964.2ff7288bc0a83e48485c4bd195b0cbceb06d5fd2218264cf63c49a72a90f00dd.tsDphOLaTwWpwAxmLc9dw4zQw9og1WJG5vjOGij2UeE
data-warehouse-query-history-modal--with-history--light:
hash: v1.k794b7964.e72700e47a962bf542a5cb857bc6bd98e4d0ca8e280db1ce01c144d3d1b818ef.naPm1iXreZerb2g6MdHDraZEtV7nGY8bi_60zMzf70s
data-warehouse-sourcecatalogskeleton--default--dark:
hash: v1.k794b7964.1a753989f72ea4cf12f04e1140fdb43e91964d3d4de700a405f2fc55a238bf50.ntxtAhZBU5rMQLYlebsHGhXwHY0_TUFEvjKCN8GJ4hI
data-warehouse-sourcecatalogskeleton--default--light:
hash: v1.k794b7964.69344e147573737f68d0ef45d1bb2e83d3953e4497aaf7a28ba6a0db3a0e183e.hj8aZGForlTVna1UKWjgacwciz6e0ozXAu-QHoZc_NU
data-warehouse-sourcecatalogskeleton--narrow-scene--dark:
hash: v1.k794b7964.493527f984dd150ed9590df45c866637a56287c585d69cdcf411ef5bce24dbf8.ocw1FaRlbBWs5pDrll11AbuJkknCONuxdXMhz365RB4
data-warehouse-sourcecatalogskeleton--narrow-scene--light:
hash: v1.k794b7964.b40c7d9b2dec21673858a8d0dc300b4e25d437140ac3c795e904cfff09934683.LIlhXoMvI575ZULUieEZGXzmVaeYYgk1mWwvjsbNC9U
data-warehouse-warehousedestinationstable--default--dark:
hash: v1.k794b7964.6595934174706ea9708694fdfe156d472e769213d8c3d41c59c0678447d20710.ZjAq0JuruCScBFFZXbK-MCQwdIrHPU50EmeRJGlFupY
data-warehouse-warehousedestinationstable--default--light:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import { FILE_UPLOAD_SOURCE_NAME } from './fileUploadSource'
import { selfManagedSourceLogic } from './selfManagedSourceLogic'
import { SourceCatalog } from './SourceCatalog'
import { SourceCatalogSkeleton } from './SourceCatalogSkeleton'
import { WIZARD_DESTINATION_STEP, type SourceWizardLogicProps, sourceWizardLogic } from './sourceWizardLogic'

export const getEffectiveAccessMethod = (
Expand Down Expand Up @@ -107,7 +108,12 @@
const { availableSources, availableSourcesLoading } = useValues(sceneRootLogic)

if (availableSourcesLoading) {
return <LemonSkeleton />
return (
<SceneContent>
<SceneTitleSection name="New data warehouse source" resourceType={{ type: 'data_pipeline' }} />
<SourceCatalogSkeleton />
</SceneContent>
)
}

if (availableSources === null) {
Expand Down Expand Up @@ -202,7 +208,7 @@
const { availableSources, availableSourcesLoading } = useValues(availableSourcesLogic)

if (availableSourcesLoading) {
return <LemonSkeleton />
return <SourceCatalogSkeleton />
}

if (availableSources === null) {
Expand All @@ -222,7 +228,7 @@
)
}

function InternalSourcesWizard(props: NewSourcesWizardProps): JSX.Element {

Check warning on line 231 in products/data_warehouse/frontend/scenes/NewSourceScene/NewSourceScene.tsx

View workflow job for this annotation

GitHub Actions / Frontend formatting

lint:complexity

`InternalSourcesWizard` has cyclomatic complexity 19 (warn >10)
const {
modalTitle,
isWrapped,
Expand Down Expand Up @@ -406,7 +412,7 @@
)
}

function CDCSelfManagedSetupDialog(): JSX.Element | null {

Check warning on line 415 in products/data_warehouse/frontend/scenes/NewSourceScene/NewSourceScene.tsx

View workflow job for this annotation

GitHub Actions / Frontend formatting

lint:complexity

`CDCSelfManagedSetupDialog` has cyclomatic complexity 15 (warn >10)
const {
cdcSelfManagedSetupDialogOpen,
source,
Expand Down Expand Up @@ -562,7 +568,7 @@
)
}

function SecondStep({ sourceWizardLogicProps }: { sourceWizardLogicProps?: SourceWizardLogicProps }): JSX.Element {

Check warning on line 571 in products/data_warehouse/frontend/scenes/NewSourceScene/NewSourceScene.tsx

View workflow job for this annotation

GitHub Actions / Frontend formatting

lint:complexity

`SecondStep` has cyclomatic complexity 12 (warn >10)
const { selectedConnector, source, sourceConnectionDetails } = useValues(sourceWizardLogic)
const selectedAccessMethod = getEffectiveAccessMethod(
2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ import { CatalogItem, sourceCatalogLogic } from './sourceCatalogLogic'

// Horizontal card: logo on the left, name/status/action stacked on the right. `min-h` (not a fixed
// height) so a wrapped name plus the "Notify me" button can never clip.
const TILE_CLASS =
// Exported so `SourceCatalogSkeleton` lays its placeholders out on the same grid, and the tiles
// don't jump when the real catalog lands.
export const CATALOG_TILE_CLASS =
'flex flex-row items-center gap-4 p-5 min-h-[8.5rem] rounded-lg border border-border bg-surface-primary'
export const CATALOG_GRID_CLASS = 'grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-3'

export interface SourceCatalogProps {
allowedSources?: ExternalDataSourceTypeEnumApi[]
Expand Down Expand Up @@ -77,23 +80,23 @@ const SourceTile = memo(function SourceTile({
if (item.status === 'coming_soon') {
return (
<Tooltip title="This source isn't available yet. Choose 'Notify me' and we'll let you know when it launches.">
<div className={`${TILE_CLASS} cursor-default`}>{content}</div>
<div className={`${CATALOG_TILE_CLASS} cursor-default`}>{content}</div>
</Tooltip>
)
}

if (accessDisabledReason) {
return (
<Tooltip title={accessDisabledReason}>
<div className={`${TILE_CLASS} opacity-50 cursor-not-allowed`}>{content}</div>
<div className={`${CATALOG_TILE_CLASS} opacity-50 cursor-not-allowed`}>{content}</div>
</Tooltip>
)
}

return (
<Link
to={item.url}
className={`${TILE_CLASS} hover:border-primary cursor-pointer`}
className={`${CATALOG_TILE_CLASS} hover:border-primary cursor-pointer`}
data-attr="catalog-source"
onClick={() => onSelect(item)}
>
Expand All @@ -106,7 +109,7 @@ function RequestSourceTile({ onRequest }: { onRequest: () => void }): JSX.Elemen
return (
<button
type="button"
className={`${TILE_CLASS} border-dashed hover:border-primary cursor-pointer text-left`}
className={`${CATALOG_TILE_CLASS} border-dashed hover:border-primary cursor-pointer text-left`}
onClick={onRequest}
data-attr="catalog-request-source"
>
Expand Down Expand Up @@ -214,7 +217,7 @@ export function SourceCatalog({ allowedSources }: SourceCatalogProps): JSX.Eleme
</div>
)}

<div className="grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-3">
<div className={CATALOG_GRID_CLASS}>
{filteredItems.map((item) => (
<SourceTile
key={item.name}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Meta, StoryFn } from '@storybook/react'

import { SourceCatalogSkeleton } from './SourceCatalogSkeleton'

const meta: Meta<typeof SourceCatalogSkeleton> = {
title: 'Data Warehouse/SourceCatalogSkeleton',
component: SourceCatalogSkeleton,
parameters: {
// The whole component is LemonSkeletons, which the snapshot runner treats as loaders and
// waits out before it captures. Without this the story never settles.
testOptions: {
waitForLoadersToDisappear: false,
},
},
tags: ['autodocs'],
}
export default meta

export const Default: StoryFn<typeof SourceCatalogSkeleton> = () => <SourceCatalogSkeleton />

// The nav sidebar plus an open side panel leave about this much room for the scene.
export const NarrowScene: StoryFn<typeof SourceCatalogSkeleton> = () => (
<div className="w-[520px]">
<SourceCatalogSkeleton />
</div>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { LemonSkeleton } from '@posthog/lemon-ui'

import { CATALOG_GRID_CLASS, CATALOG_TILE_CLASS } from './SourceCatalog'

// Roughly a screenful at a typical scene width, so the grid reads as a catalog mid-load rather
// than a handful of stray boxes. The real catalog is far longer, so there is nothing to match.
const PLACEHOLDER_TILE_COUNT = 12
const PLACEHOLDER_CATEGORY_COUNT = 8

/** Stands in for `SourceCatalog` while the connector list loads. */
export function SourceCatalogSkeleton(): JSX.Element {
return (
<div className="flex flex-col sm:flex-row gap-4">
<div className="flex flex-row sm:flex-col gap-1 overflow-x-auto sm:w-56 sm:shrink-0">
{Array.from({ length: PLACEHOLDER_CATEGORY_COUNT }, (_, index) => (
// `repeat` wraps each skeleton in a bare div, which a flex row collapses to
// nothing, so each placeholder carries its own width.
<div key={index} className="w-32 shrink-0 sm:w-full">
<LemonSkeleton className="h-8" />
</div>
))}
</div>
<div className="flex flex-col gap-4 flex-1">
<LemonSkeleton className="h-10" />
<div className={CATALOG_GRID_CLASS}>
{Array.from({ length: PLACEHOLDER_TILE_COUNT }, (_, index) => (
<div key={index} className={CATALOG_TILE_CLASS}>
{/* The catalog renders a medium SourceIcon, which is 60px square. */}
<LemonSkeleton className="size-[60px] shrink-0" />
<div className="flex flex-col gap-2 flex-1 min-w-0">
<LemonSkeleton className="h-4 w-3/4" />
<LemonSkeleton className="h-4 w-1/3" />
</div>
</div>
))}
</div>
</div>
</div>
)
}
Loading