diff --git a/frontend/__snapshots__/lemon-ui-icons--shelf-p.png b/frontend/__snapshots__/lemon-ui-icons--shelf-p.png index ed1853f8297e6..4c18318a5a42a 100644 Binary files a/frontend/__snapshots__/lemon-ui-icons--shelf-p.png and b/frontend/__snapshots__/lemon-ui-icons--shelf-p.png differ diff --git a/frontend/__snapshots__/scenes-app-pipeline--pipeline-landing-page.png b/frontend/__snapshots__/scenes-app-pipeline--pipeline-landing-page.png new file mode 100644 index 0000000000000..f71305149b638 Binary files /dev/null and b/frontend/__snapshots__/scenes-app-pipeline--pipeline-landing-page.png differ diff --git a/frontend/src/layout/navigation/SideBar/SideBar.tsx b/frontend/src/layout/navigation/SideBar/SideBar.tsx index c37c2f0284631..b7e4b38ad165c 100644 --- a/frontend/src/layout/navigation/SideBar/SideBar.tsx +++ b/frontend/src/layout/navigation/SideBar/SideBar.tsx @@ -18,6 +18,7 @@ import { IconOpenInApp, IconPerson, IconPinOutline, + IconPipeline, IconPlus, IconRecording, IconRocketLaunch, @@ -226,6 +227,9 @@ function Pages(): JSX.Element { to={urls.persons()} title={`Persons${showGroupsOptions ? ' & Groups' : ''}`} /> + + } identifier={Scene.Pipeline} to={urls.pipeline()} /> + } diff --git a/frontend/src/lib/constants.tsx b/frontend/src/lib/constants.tsx index 6343b341614ef..9cfcf1ba136c7 100644 --- a/frontend/src/lib/constants.tsx +++ b/frontend/src/lib/constants.tsx @@ -165,6 +165,7 @@ export const FEATURE_FLAGS = { SURVEYS_PAYGATES: 'surveys-paygates', CONSOLE_RECORDING_SEARCH: 'console-recording-search', // owner: #team-monitoring PERSONS_HOGQL_QUERY: 'persons-hogql-query', // owner: @mariusandra + PIPELINE_UI: 'pipeline-ui', // owner: #team-pipeline NOTEBOOK_CANVASES: 'notebook-canvases', // owner: #team-monitoring SESSION_RECORDING_SAMPLING: 'session-recording-sampling', // owner: #team-monitoring PERSON_FEED_CANVAS: 'person-feed-canvas', // owner: #project-canvas diff --git a/frontend/src/lib/lemon-ui/icons/icons.tsx b/frontend/src/lib/lemon-ui/icons/icons.tsx index 8d5048e4aad10..429bd17c3c6eb 100644 --- a/frontend/src/lib/lemon-ui/icons/icons.tsx +++ b/frontend/src/lib/lemon-ui/icons/icons.tsx @@ -2383,6 +2383,17 @@ export function IconDatabase(props: LemonIconProps): JSX.Element { ) } +export function IconPipeline(props: LemonIconProps): JSX.Element { + return ( + + + + ) +} + export function IconDragHandle(props: LemonIconProps): JSX.Element { return ( diff --git a/frontend/src/scenes/appScenes.ts b/frontend/src/scenes/appScenes.ts index 494f7668f4bfe..7955d08dc045a 100644 --- a/frontend/src/scenes/appScenes.ts +++ b/frontend/src/scenes/appScenes.ts @@ -28,6 +28,7 @@ export const appScenes: Record any> = { [Scene.ReplayPlaylist]: () => import('./session-recordings/playlist/SessionRecordingsPlaylistScene'), [Scene.Person]: () => import('./persons/PersonScene'), [Scene.Persons]: () => import('./persons/PersonsScene'), + [Scene.Pipeline]: () => import('./pipeline/Pipeline'), [Scene.Groups]: () => import('./groups/Groups'), [Scene.Group]: () => import('./groups/Group'), [Scene.Action]: () => import('./actions/Action'), diff --git a/frontend/src/scenes/pipeline/Pipeline.stories.tsx b/frontend/src/scenes/pipeline/Pipeline.stories.tsx new file mode 100644 index 0000000000000..dd0b1641b9e72 --- /dev/null +++ b/frontend/src/scenes/pipeline/Pipeline.stories.tsx @@ -0,0 +1,18 @@ +import { useEffect } from 'react' +import { Meta } from '@storybook/react' +import { App } from 'scenes/App' +import { router } from 'kea-router' +import { urls } from 'scenes/urls' + +export default { + title: 'Scenes-App/Pipeline', + decorators: [], + parameters: { layout: 'fullscreen', options: { showPanel: false }, viewMode: 'story' }, // scene mode +} as Meta + +export function PipelineLandingPage(): JSX.Element { + useEffect(() => { + router.actions.push(urls.pipeline()) + }, []) + return +} diff --git a/frontend/src/scenes/pipeline/Pipeline.tsx b/frontend/src/scenes/pipeline/Pipeline.tsx new file mode 100644 index 0000000000000..42ee27cc7c66b --- /dev/null +++ b/frontend/src/scenes/pipeline/Pipeline.tsx @@ -0,0 +1,19 @@ +import { SceneExport } from 'scenes/sceneTypes' +import { pipelineLogic } from './pipelineLogic' +import { PageHeader } from 'lib/components/PageHeader' + +export function Pipeline(): JSX.Element { + return ( +
+ +
+ ) +} + +export const scene: SceneExport = { + component: Pipeline, + logic: pipelineLogic, +} + +// TODO: error from import ./pipeline/PipelineScene +// TODO: update https://storybook.posthog.net/?path=/docs/how-to-build-a-scene--docs <- about kea stuff to exclude and have run pnpm ... for type creation diff --git a/frontend/src/scenes/pipeline/pipelineLogic.tsx b/frontend/src/scenes/pipeline/pipelineLogic.tsx new file mode 100644 index 0000000000000..9d74a469558e0 --- /dev/null +++ b/frontend/src/scenes/pipeline/pipelineLogic.tsx @@ -0,0 +1,6 @@ +import { kea } from 'kea' +import type { pipelineLogicType } from './pipelineLogicType' + +export const pipelineLogic = kea({ + path: ['scenes', 'pipeline', 'pipelineLogic'], +}) diff --git a/frontend/src/scenes/sceneTypes.ts b/frontend/src/scenes/sceneTypes.ts index 0e35998cd8887..3ff7072ca8404 100644 --- a/frontend/src/scenes/sceneTypes.ts +++ b/frontend/src/scenes/sceneTypes.ts @@ -27,6 +27,7 @@ export enum Scene { ReplayPlaylist = 'ReplayPlaylist', Person = 'Person', Persons = 'Persons', + Pipeline = 'Pipeline', Groups = 'Groups', Group = 'Group', Action = 'Action', diff --git a/frontend/src/scenes/scenes.ts b/frontend/src/scenes/scenes.ts index d8f43290d737f..311a72f6f5c34 100644 --- a/frontend/src/scenes/scenes.ts +++ b/frontend/src/scenes/scenes.ts @@ -140,6 +140,10 @@ export const sceneConfigurations: Partial> = { projectBased: true, name: 'Persons & Groups', }, + [Scene.Pipeline]: { + projectBased: true, + name: 'Pipeline', + }, [Scene.Experiments]: { projectBased: true, name: 'Experiments', @@ -432,6 +436,7 @@ export const routes: Record = { [urls.personByDistinctId('*', false)]: Scene.Person, [urls.personByUUID('*', false)]: Scene.Person, [urls.persons()]: Scene.Persons, + [urls.pipeline()]: Scene.Pipeline, [urls.groups(':groupTypeIndex')]: Scene.Groups, [urls.group(':groupTypeIndex', ':groupKey', false)]: Scene.Group, [urls.group(':groupTypeIndex', ':groupKey', false, ':groupTab')]: Scene.Group, diff --git a/frontend/src/scenes/urls.ts b/frontend/src/scenes/urls.ts index 930aa0c14d6a1..9e454a67f9f81 100644 --- a/frontend/src/scenes/urls.ts +++ b/frontend/src/scenes/urls.ts @@ -93,6 +93,7 @@ export const urls = { personByUUID: (uuid: string, encode: boolean = true): string => encode ? `/persons/${encodeURIComponent(uuid)}` : `/persons/${uuid}`, persons: (): string => '/persons', + pipeline: (): string => '/pipeline', groups: (groupTypeIndex: string | number): string => `/groups/${groupTypeIndex}`, // :TRICKY: Note that groupKey is provided by user. We need to override urlPatternOptions for kea-router. group: (groupTypeIndex: string | number, groupKey: string, encode: boolean = true, tab?: string | null): string =>