Skip to content

Commit

Permalink
chore(data-warehouse): Tree UI for data warehouse (#19611)
Browse files Browse the repository at this point in the history
* initial version

* working

* defaults

* updated frontend logic and links

* styling

* remove bad merge

* address comments

* use tailwind

* usecallback

* update types and migration

* types

* Update query snapshots

* Update UI snapshots for `chromium` (1)

* Update query snapshots

* Update UI snapshots for `chromium` (1)

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
EDsCODE and github-actions[bot] authored Jan 9, 2024
1 parent 5fd1631 commit ba398da
Show file tree
Hide file tree
Showing 20 changed files with 486 additions and 380 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { DataWarehouseTableType } from 'scenes/data-warehouse/types'

import { TreeFolderRow, TreeRow } from './TreeRow'

export interface TreeProps extends React.HTMLAttributes<HTMLUListElement> {
children?: React.ReactNode
className?: string
items: TreeItem[]
depth?: number
onSelectRow?: (row: DataWarehouseTableType) => void
selectedRow?: DataWarehouseTableType | null
}

export type TreeItem = TreeItemFolder | TreeItemLeaf

export interface TreeItemFolder {
name: string
items: TreeItemLeaf[]
emptyLabel?: JSX.Element
}

export interface TreeItemLeaf {
table: DataWarehouseTableType
icon?: React.ReactNode
}

export function DatabaseTableTree({
className = '',
items,
onSelectRow,
selectedRow,
depth = 1,
...props
}: TreeProps): JSX.Element {
return (
<ul className={`bg-bg-light p-4 rounded-lg ${className}`} {...props}>
{items.map((item, index) => {
if ('items' in item) {
return (
<TreeFolderRow
key={depth + '_' + index}
item={item}
depth={depth}
onClick={onSelectRow}
selectedRow={selectedRow}
/>
)
}
return (
<TreeRow
key={depth + '_' + index}
item={item}
depth={depth}
onClick={onSelectRow}
selected={!!(selectedRow?.name == item.table.name)}
/>
)
})}
</ul>
)
}
10 changes: 10 additions & 0 deletions frontend/src/lib/components/DatabaseTableTree/TreeRow.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.TreeRow {
&:hover {
cursor: pointer;
background-color: var(--primary-bg-hover);
}
}

.TreeRow__selected {
background-color: var(--primary-bg-hover);
}
75 changes: 75 additions & 0 deletions frontend/src/lib/components/DatabaseTableTree/TreeRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import './TreeRow.scss'

import { IconChevronDown } from '@posthog/icons'
import clsx from 'clsx'
import { IconChevronRight } from 'lib/lemon-ui/icons'
import { useCallback, useState } from 'react'
import { DataWarehouseTableType } from 'scenes/data-warehouse/types'

import { DatabaseTableTree, TreeItemFolder, TreeItemLeaf } from './DatabaseTableTree'

export interface TreeRowProps {
item: TreeItemLeaf
depth: number
onClick?: (row: DataWarehouseTableType) => void
selected?: boolean
}

export function TreeRow({ item, onClick, selected }: TreeRowProps): JSX.Element {
const _onClick = useCallback(() => {
onClick && onClick(item.table)
}, [])

return (
<li>
<div className={clsx('TreeRow', selected ? 'TreeRow__selected' : '')} onClick={_onClick}>
<span className="mr-2">{item.icon}</span>
{item.table.name}
</div>
</li>
)
}

export interface TreeFolderRowProps {
item: TreeItemFolder
depth: number
onClick?: (row: DataWarehouseTableType) => void
selectedRow?: DataWarehouseTableType | null
}

export function TreeFolderRow({ item, depth, onClick, selectedRow }: TreeFolderRowProps): JSX.Element {
const [collapsed, setCollapsed] = useState(false)
const { name, items, emptyLabel } = item

const _onClick = useCallback(() => {
setCollapsed(!collapsed)
}, [collapsed])

return (
<li>
<div className={clsx('TreeRow', 'font-bold')} onClick={_onClick}>
<span className="mr-2">{collapsed ? <IconChevronRight /> : <IconChevronDown />}</span>
{name}
</div>
{!collapsed &&
(items.length > 0 ? (
<DatabaseTableTree
items={items}
depth={depth + 1}
onSelectRow={onClick}
selectedRow={selectedRow}
style={{ marginLeft: `${2 * depth}rem`, padding: 0 }}
/>
) : (
<div
// eslint-disable-next-line react/forbid-dom-props
style={{
marginLeft: `${2 * depth}rem`,
}}
>
{emptyLabel ? emptyLabel : <span className="text-muted">No tables found</span>}
</div>
))}
</li>
)
}
2 changes: 0 additions & 2 deletions frontend/src/scenes/appScenes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ export const appScenes: Record<Scene, () => any> = {
[Scene.SurveyTemplates]: () => import('./surveys/SurveyTemplates'),
[Scene.DataWarehouse]: () => import('./data-warehouse/external/DataWarehouseExternalScene'),
[Scene.DataWarehouseTable]: () => import('./data-warehouse/new_table/DataWarehouseTableScene'),
[Scene.DataWarehousePosthog]: () => import('./data-warehouse/posthog/DataWarehousePosthogScene'),
[Scene.DataWarehouseExternal]: () => import('./data-warehouse/external/DataWarehouseExternalScene'),
[Scene.DataWarehouseSavedQueries]: () => import('./data-warehouse/saved_queries/DataWarehouseSavedQueriesScene'),
[Scene.DataWarehouseSettings]: () => import('./data-warehouse/settings/DataWarehouseSettingsScene'),
[Scene.DataWarehouseRedirect]: () => import('./data-warehouse/redirect/DataWarehouseRedirectScene'),
[Scene.OrganizationCreateFirst]: () => import('./organization/Create'),
Expand Down
82 changes: 0 additions & 82 deletions frontend/src/scenes/data-warehouse/DataWarehousePageTabs.tsx

This file was deleted.

Loading

0 comments on commit ba398da

Please sign in to comment.