From bb151e6f5770b74fe5698399675d16d6a4226cf4 Mon Sep 17 00:00:00 2001 From: Eric Duong Date: Thu, 4 Apr 2024 10:24:22 -0400 Subject: [PATCH] chore(data-warehouse): refactor wizard (#21316) * Updated the source sync flow to allow users to select the initial tables to sync * change from modal to scene * types * add settings --------- Co-authored-by: Tom Owers --- frontend/src/scenes/appScenes.ts | 2 +- .../external/DataWarehouseExternalScene.tsx | 4 +- .../external/DataWarehouseTables.tsx | 15 +--- .../external/forms/PostgresSchemaForm.tsx | 6 +- .../external/forms/SourceForm.tsx | 2 +- .../external/forms/sourceFormLogic.ts | 4 +- .../DataWarehouseTableForm.tsx | 0 .../NewSourceWizard.tsx} | 72 +++++++++++-------- .../dataWarehouseTableLogic.tsx | 15 +--- .../sourceWizardLogic.tsx} | 27 +++++-- .../new_table/DataWarehouseTableScene.tsx | 65 ----------------- .../settings/DataWarehouseSettingsScene.tsx | 7 +- .../settings/dataWarehouseSettingsLogic.ts | 5 ++ 13 files changed, 84 insertions(+), 140 deletions(-) rename frontend/src/scenes/data-warehouse/{new_table => new}/DataWarehouseTableForm.tsx (100%) rename frontend/src/scenes/data-warehouse/{external/SourceModal.tsx => new/NewSourceWizard.tsx} (70%) rename frontend/src/scenes/data-warehouse/{new_table => new}/dataWarehouseTableLogic.tsx (92%) rename frontend/src/scenes/data-warehouse/{external/sourceModalLogic.tsx => new/sourceWizardLogic.tsx} (92%) delete mode 100644 frontend/src/scenes/data-warehouse/new_table/DataWarehouseTableScene.tsx diff --git a/frontend/src/scenes/appScenes.ts b/frontend/src/scenes/appScenes.ts index 7fb0842ccf568..a5cdf17ca7f4b 100644 --- a/frontend/src/scenes/appScenes.ts +++ b/frontend/src/scenes/appScenes.ts @@ -38,7 +38,7 @@ export const appScenes: Record any> = { [Scene.Survey]: () => import('./surveys/Survey'), [Scene.SurveyTemplates]: () => import('./surveys/SurveyTemplates'), [Scene.DataWarehouse]: () => import('./data-warehouse/external/DataWarehouseExternalScene'), - [Scene.DataWarehouseTable]: () => import('./data-warehouse/new_table/DataWarehouseTableScene'), + [Scene.DataWarehouseTable]: () => import('./data-warehouse/new/NewSourceWizard'), [Scene.DataWarehouseExternal]: () => import('./data-warehouse/external/DataWarehouseExternalScene'), [Scene.DataWarehouseSettings]: () => import('./data-warehouse/settings/DataWarehouseSettingsScene'), [Scene.DataWarehouseRedirect]: () => import('./data-warehouse/redirect/DataWarehouseRedirectScene'), diff --git a/frontend/src/scenes/data-warehouse/external/DataWarehouseExternalScene.tsx b/frontend/src/scenes/data-warehouse/external/DataWarehouseExternalScene.tsx index c74bd4ec67fe9..a696bed401896 100644 --- a/frontend/src/scenes/data-warehouse/external/DataWarehouseExternalScene.tsx +++ b/frontend/src/scenes/data-warehouse/external/DataWarehouseExternalScene.tsx @@ -32,7 +32,7 @@ const TABS_TO_CONTENT = { export function DataWarehouseExternalScene(): JSX.Element { const { activeSceneTab } = useValues(dataWarehouseSceneLogic) - const { toggleSourceModal, setSceneTab } = useActions(dataWarehouseSceneLogic) + const { setSceneTab } = useActions(dataWarehouseSceneLogic) const { featureFlags } = useValues(featureFlagLogic) const { toggleNewJoinModal } = useActions(viewLinkLogic) @@ -57,7 +57,7 @@ export function DataWarehouseExternalScene(): JSX.Element { type="primary" data-attr="new-data-warehouse-easy-link" key="new-data-warehouse-easy-link" - onClick={() => toggleSourceModal()} + to={urls.dataWarehouseTable()} > Link Source diff --git a/frontend/src/scenes/data-warehouse/external/DataWarehouseTables.tsx b/frontend/src/scenes/data-warehouse/external/DataWarehouseTables.tsx index 6d5969a45aee5..ad84797b14f45 100644 --- a/frontend/src/scenes/data-warehouse/external/DataWarehouseTables.tsx +++ b/frontend/src/scenes/data-warehouse/external/DataWarehouseTables.tsx @@ -4,15 +4,14 @@ import { useActions, useValues } from 'kea' import { DatabaseTableTree, TreeItem } from 'lib/components/DatabaseTableTree/DatabaseTableTree' import { FEATURE_FLAGS } from 'lib/constants' import { featureFlagLogic } from 'lib/logic/featureFlagLogic' +import { urls } from 'scenes/urls' import { ViewLinkModal } from '../ViewLinkModal' import { dataWarehouseSceneLogic } from './dataWarehouseSceneLogic' -import SourceModal from './SourceModal' import { TableData } from './TableData' export const DataWarehouseTables = (): JSX.Element => { const { - isSourceModalOpen, externalTablesBySourceType, dataWarehouseLoading, posthogTables, @@ -20,7 +19,7 @@ export const DataWarehouseTables = (): JSX.Element => { selectedRow, dataWarehouseSavedQueriesLoading, } = useValues(dataWarehouseSceneLogic) - const { toggleSourceModal, selectRow } = useActions(dataWarehouseSceneLogic) + const { selectRow } = useActions(dataWarehouseSceneLogic) const { featureFlags } = useValues(featureFlagLogic) const treeItems = (): TreeItem[] => { @@ -36,14 +35,7 @@ export const DataWarehouseTables = (): JSX.Element => { })), emptyLabel: ( - No tables found.{' '} - { - toggleSourceModal() - }} - > - Link source - + No tables found. Link source ), isLoading: dataWarehouseLoading, @@ -80,7 +72,6 @@ export const DataWarehouseTables = (): JSX.Element => { - toggleSourceModal(false)} /> ) diff --git a/frontend/src/scenes/data-warehouse/external/forms/PostgresSchemaForm.tsx b/frontend/src/scenes/data-warehouse/external/forms/PostgresSchemaForm.tsx index 423ca4fdbe016..182467ec04432 100644 --- a/frontend/src/scenes/data-warehouse/external/forms/PostgresSchemaForm.tsx +++ b/frontend/src/scenes/data-warehouse/external/forms/PostgresSchemaForm.tsx @@ -1,13 +1,13 @@ import { LemonSwitch, LemonTable } from '@posthog/lemon-ui' import { useActions, useMountedLogic, useValues } from 'kea' -import { sourceModalLogic } from '../sourceModalLogic' +import { sourceWizardLogic } from '../../new/sourceWizardLogic' import { sourceFormLogic } from './sourceFormLogic' export default function PostgresSchemaForm(): JSX.Element { useMountedLogic(sourceFormLogic({ sourceType: 'Postgres' })) - const { selectSchema } = useActions(sourceModalLogic) - const { databaseSchema } = useValues(sourceModalLogic) + const { selectSchema } = useActions(sourceWizardLogic) + const { databaseSchema } = useValues(sourceWizardLogic) return (
diff --git a/frontend/src/scenes/data-warehouse/external/forms/SourceForm.tsx b/frontend/src/scenes/data-warehouse/external/forms/SourceForm.tsx index 035bde1ba439a..ce5b045c718a8 100644 --- a/frontend/src/scenes/data-warehouse/external/forms/SourceForm.tsx +++ b/frontend/src/scenes/data-warehouse/external/forms/SourceForm.tsx @@ -4,7 +4,7 @@ import { LemonField } from 'lib/lemon-ui/LemonField' import { ExternalDataSourceType } from '~/types' -import { SOURCE_DETAILS } from '../sourceModalLogic' +import { SOURCE_DETAILS } from '../../new/sourceWizardLogic' import { sourceFormLogic } from './sourceFormLogic' interface SourceFormProps { diff --git a/frontend/src/scenes/data-warehouse/external/forms/sourceFormLogic.ts b/frontend/src/scenes/data-warehouse/external/forms/sourceFormLogic.ts index 2ec811cfd7589..d8d25f98fdab3 100644 --- a/frontend/src/scenes/data-warehouse/external/forms/sourceFormLogic.ts +++ b/frontend/src/scenes/data-warehouse/external/forms/sourceFormLogic.ts @@ -7,7 +7,7 @@ import { urls } from 'scenes/urls' import { ExternalDataSourceCreatePayload, ExternalDataSourceType } from '~/types' -import { getHubspotRedirectUri, sourceModalLogic } from '../sourceModalLogic' +import { getHubspotRedirectUri, sourceWizardLogic } from '../../new/sourceWizardLogic' import type { sourceFormLogicType } from './sourceFormLogicType' export interface SourceFormProps { @@ -83,7 +83,7 @@ export const sourceFormLogic = kea([ props({} as SourceFormProps), connect({ actions: [ - sourceModalLogic, + sourceWizardLogic, ['setDatabaseSchemas', 'onBack', 'onNext', 'selectConnector', 'toggleSourceModal', 'loadSources'], ], }), diff --git a/frontend/src/scenes/data-warehouse/new_table/DataWarehouseTableForm.tsx b/frontend/src/scenes/data-warehouse/new/DataWarehouseTableForm.tsx similarity index 100% rename from frontend/src/scenes/data-warehouse/new_table/DataWarehouseTableForm.tsx rename to frontend/src/scenes/data-warehouse/new/DataWarehouseTableForm.tsx diff --git a/frontend/src/scenes/data-warehouse/external/SourceModal.tsx b/frontend/src/scenes/data-warehouse/new/NewSourceWizard.tsx similarity index 70% rename from frontend/src/scenes/data-warehouse/external/SourceModal.tsx rename to frontend/src/scenes/data-warehouse/new/NewSourceWizard.tsx index 204b0ef71982e..f35811424a699 100644 --- a/frontend/src/scenes/data-warehouse/external/SourceModal.tsx +++ b/frontend/src/scenes/data-warehouse/new/NewSourceWizard.tsx @@ -1,24 +1,28 @@ -import { LemonButton, LemonModal, LemonModalProps } from '@posthog/lemon-ui' +import { LemonButton } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' +import { PageHeader } from 'lib/components/PageHeader' import { FEATURE_FLAGS } from 'lib/constants' import { featureFlagLogic } from 'lib/logic/featureFlagLogic' import hubspotLogo from 'public/hubspot-logo.svg' import postgresLogo from 'public/postgres-logo.svg' import stripeLogo from 'public/stripe-logo.svg' import zendeskLogo from 'public/zendesk-logo.png' +import { SceneExport } from 'scenes/sceneTypes' +import { urls } from 'scenes/urls' -import { DatawarehouseTableForm } from '../new_table/DataWarehouseTableForm' -import PostgresSchemaForm from './forms/PostgresSchemaForm' -import SourceForm from './forms/SourceForm' -import { SourceConfig } from './sourceModalLogic' -import { sourceModalLogic } from './sourceModalLogic' +import PostgresSchemaForm from '../external/forms/PostgresSchemaForm' +import SourceForm from '../external/forms/SourceForm' +import { DatawarehouseTableForm } from '../new/DataWarehouseTableForm' +import { SourceConfig, sourceWizardLogic } from './sourceWizardLogic' -interface SourceModalProps extends LemonModalProps {} - -export default function SourceModal(props: SourceModalProps): JSX.Element { - const { modalTitle, modalCaption } = useValues(sourceModalLogic) - const { onClear, onBack, onSubmit } = useActions(sourceModalLogic) - const { currentStep } = useValues(sourceModalLogic) +export const scene: SceneExport = { + component: NewSourceWizard, + logic: sourceWizardLogic, +} +export function NewSourceWizard(): JSX.Element { + const { modalTitle, modalCaption } = useValues(sourceWizardLogic) + const { onBack, onSubmit } = useActions(sourceWizardLogic) + const { currentStep } = useValues(sourceWizardLogic) const footer = (): JSX.Element | null => { if (currentStep === 1) { @@ -38,18 +42,30 @@ export default function SourceModal(props: SourceModalProps): JSX.Element { } return ( - onClear()} - title={modalTitle} - description={modalCaption} - footer={footer()} - > - - - - + <> + + + Cancel + + + } + /> + <> +

{modalTitle}

+

{modalCaption}

+ + + + {footer()} + + ) } @@ -59,7 +75,7 @@ interface ModalPageProps { } function ModalPage({ children, page }: ModalPageProps): JSX.Element { - const { currentStep } = useValues(sourceModalLogic) + const { currentStep } = useValues(sourceWizardLogic) if (currentStep !== page) { return <> @@ -69,8 +85,8 @@ function ModalPage({ children, page }: ModalPageProps): JSX.Element { } function FirstStep(): JSX.Element { - const { connectors, addToHubspotButtonUrl } = useValues(sourceModalLogic) - const { selectConnector, toggleManualLinkFormVisible, onNext } = useActions(sourceModalLogic) + const { connectors, addToHubspotButtonUrl } = useValues(sourceWizardLogic) + const { selectConnector, toggleManualLinkFormVisible, onNext } = useActions(sourceWizardLogic) const { featureFlags } = useValues(featureFlagLogic) const MenuButton = (config: SourceConfig): JSX.Element => { @@ -135,7 +151,7 @@ function FirstStep(): JSX.Element { } function SecondStep(): JSX.Element { - const { selectedConnector } = useValues(sourceModalLogic) + const { selectedConnector } = useValues(sourceWizardLogic) return ( diff --git a/frontend/src/scenes/data-warehouse/new_table/dataWarehouseTableLogic.tsx b/frontend/src/scenes/data-warehouse/new/dataWarehouseTableLogic.tsx similarity index 92% rename from frontend/src/scenes/data-warehouse/new_table/dataWarehouseTableLogic.tsx rename to frontend/src/scenes/data-warehouse/new/dataWarehouseTableLogic.tsx index ce3b4846df0ac..cd213362e305e 100644 --- a/frontend/src/scenes/data-warehouse/new_table/dataWarehouseTableLogic.tsx +++ b/frontend/src/scenes/data-warehouse/new/dataWarehouseTableLogic.tsx @@ -1,5 +1,5 @@ import { lemonToast } from '@posthog/lemon-ui' -import { actions, connect, kea, listeners, path, props, reducers, selectors } from 'kea' +import { actions, connect, kea, listeners, path, props, reducers } from 'kea' import { forms } from 'kea-forms' import { loaders } from 'kea-loaders' import { router } from 'kea-router' @@ -8,7 +8,7 @@ import { databaseTableListLogic } from 'scenes/data-management/database/database import { urls } from 'scenes/urls' import { DataTableNode } from '~/queries/schema' -import { AnyPropertyFilter, Breadcrumb, DataWarehouseTable } from '~/types' +import { AnyPropertyFilter, DataWarehouseTable } from '~/types' import { dataWarehouseSceneLogic } from '../external/dataWarehouseSceneLogic' import type { dataWarehouseTableLogicType } from './dataWarehouseTableLogicType' @@ -97,17 +97,6 @@ export const dataWarehouseTableLogic = kea([ }, ], }), - selectors({ - breadcrumbs: [ - () => [], - (): Breadcrumb[] => [ - { - key: 'new', - name: 'New', - }, - ], - ], - }), forms(({ actions, props }) => ({ table: { defaults: { ...NEW_WAREHOUSE_TABLE } as DataWarehouseTable, diff --git a/frontend/src/scenes/data-warehouse/external/sourceModalLogic.tsx b/frontend/src/scenes/data-warehouse/new/sourceWizardLogic.tsx similarity index 92% rename from frontend/src/scenes/data-warehouse/external/sourceModalLogic.tsx rename to frontend/src/scenes/data-warehouse/new/sourceWizardLogic.tsx index 62a25aa56511d..e8c283fb862ef 100644 --- a/frontend/src/scenes/data-warehouse/external/sourceModalLogic.tsx +++ b/frontend/src/scenes/data-warehouse/new/sourceWizardLogic.tsx @@ -1,14 +1,16 @@ import { Link } from '@posthog/lemon-ui' import { actions, connect, kea, listeners, path, reducers, selectors } from 'kea' import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' +import { Scene } from 'scenes/sceneTypes' +import { urls } from 'scenes/urls' -import { ExternalDataSourceSyncSchema, ExternalDataSourceType } from '~/types' +import { Breadcrumb, ExternalDataSourceSyncSchema, ExternalDataSourceType } from '~/types' -import { dataWarehouseTableLogic } from '../new_table/dataWarehouseTableLogic' +import { dataWarehouseSceneLogic } from '../external/dataWarehouseSceneLogic' +import { sourceFormLogic } from '../external/forms/sourceFormLogic' import { dataWarehouseSettingsLogic } from '../settings/dataWarehouseSettingsLogic' -import { dataWarehouseSceneLogic } from './dataWarehouseSceneLogic' -import { sourceFormLogic } from './forms/sourceFormLogic' -import type { sourceModalLogicType } from './sourceModalLogicType' +import { dataWarehouseTableLogic } from './dataWarehouseTableLogic' +import type { sourceWizardLogicType } from './sourceWizardLogicType' export const getHubspotRedirectUri = (): string => `${window.location.origin}/data-warehouse/hubspot/redirect` @@ -153,8 +155,8 @@ export const SOURCE_DETAILS: Record = { }, } -export const sourceModalLogic = kea([ - path(['scenes', 'data-warehouse', 'external', 'sourceModalLogic']), +export const sourceWizardLogic = kea([ + path(['scenes', 'data-warehouse', 'external', 'sourceWizardLogic']), actions({ selectConnector: (connector: SourceConfig | null) => ({ connector }), toggleManualLinkFormVisible: (visible: boolean) => ({ visible }), @@ -220,6 +222,17 @@ export const sourceModalLogic = kea([ ], }), selectors({ + breadcrumbs: [ + () => [], + (): Breadcrumb[] => [ + { + key: Scene.DataWarehouse, + name: 'Data Warehouse', + path: urls.dataWarehouse(), + }, + { key: [Scene.DataWarehouse, 'New'], name: 'New' }, + ], + ], showFooter: [ (s) => [s.selectedConnector, s.isManualLinkFormVisible], (selectedConnector, isManualLinkFormVisible) => selectedConnector || isManualLinkFormVisible, diff --git a/frontend/src/scenes/data-warehouse/new_table/DataWarehouseTableScene.tsx b/frontend/src/scenes/data-warehouse/new_table/DataWarehouseTableScene.tsx deleted file mode 100644 index 72affd8a0c7cc..0000000000000 --- a/frontend/src/scenes/data-warehouse/new_table/DataWarehouseTableScene.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { LemonButton, Link } from '@posthog/lemon-ui' -import { useActions, useValues } from 'kea' -import { router } from 'kea-router' -import { PageHeader } from 'lib/components/PageHeader' -import { SceneExport } from 'scenes/sceneTypes' -import { urls } from 'scenes/urls' - -import { DatawarehouseTableForm } from './DataWarehouseTableForm' -import { dataWarehouseTableLogic } from './dataWarehouseTableLogic' - -export const scene: SceneExport = { - component: DataWarehouseTable, - logic: dataWarehouseTableLogic, -} -export function DataWarehouseTable(): JSX.Element { - const { isEditingTable, tableLoading, table } = useValues(dataWarehouseTableLogic) - const { editingTable, loadTable, createTable } = useActions(dataWarehouseTableLogic) - return ( - <> - - { - if (isEditingTable) { - editingTable(false) - loadTable() - } else { - router.actions.push(urls.dataWarehouse()) - } - }} - > - Cancel - - { - createTable(table) - }} - loading={tableLoading} - > - Save - -
- } - caption={ -
- External tables are supported through object storage systems like S3.{' '} - - Learn how to set up your data - -
- } - /> - - - ) -} diff --git a/frontend/src/scenes/data-warehouse/settings/DataWarehouseSettingsScene.tsx b/frontend/src/scenes/data-warehouse/settings/DataWarehouseSettingsScene.tsx index 749dba2c42957..678139b7223be 100644 --- a/frontend/src/scenes/data-warehouse/settings/DataWarehouseSettingsScene.tsx +++ b/frontend/src/scenes/data-warehouse/settings/DataWarehouseSettingsScene.tsx @@ -9,8 +9,6 @@ import { urls } from 'scenes/urls' import { DataTableNode, NodeKind } from '~/queries/schema' import { ExternalDataSourceSchema, ExternalDataStripeSource } from '~/types' -import { dataWarehouseSceneLogic } from '../external/dataWarehouseSceneLogic' -import SourceModal from '../external/SourceModal' import { dataWarehouseSettingsLogic } from './dataWarehouseSettingsLogic' export const scene: SceneExport = { @@ -29,8 +27,6 @@ export function DataWarehouseSettingsScene(): JSX.Element { const { dataWarehouseSources, dataWarehouseSourcesLoading, sourceReloadingById } = useValues(dataWarehouseSettingsLogic) const { deleteSource, reloadSource } = useActions(dataWarehouseSettingsLogic) - const { toggleSourceModal } = useActions(dataWarehouseSceneLogic) - const { isSourceModalOpen } = useValues(dataWarehouseSceneLogic) const renderExpandable = (source: ExternalDataStripeSource): JSX.Element => { return ( @@ -52,7 +48,7 @@ export function DataWarehouseSettingsScene(): JSX.Element { type="primary" data-attr="new-data-warehouse-easy-link" key="new-data-warehouse-easy-link" - onClick={() => toggleSourceModal()} + to={urls.dataWarehouseTable()} > Link Source @@ -175,7 +171,6 @@ export function DataWarehouseSettingsScene(): JSX.Element { noIndent: true, }} /> - toggleSourceModal(false)} /> ) } diff --git a/frontend/src/scenes/data-warehouse/settings/dataWarehouseSettingsLogic.ts b/frontend/src/scenes/data-warehouse/settings/dataWarehouseSettingsLogic.ts index b79a264f8a1cc..bbd06a45ce9c3 100644 --- a/frontend/src/scenes/data-warehouse/settings/dataWarehouseSettingsLogic.ts +++ b/frontend/src/scenes/data-warehouse/settings/dataWarehouseSettingsLogic.ts @@ -54,6 +54,11 @@ export const dataWarehouseSettingsLogic = kea([ breadcrumbs: [ () => [], (): Breadcrumb[] => [ + { + key: Scene.DataWarehouse, + name: 'Data Warehouse', + path: urls.dataWarehouse(), + }, { key: Scene.DataWarehouseSettings, name: 'Data Warehouse Settings',