diff --git a/frontend/__snapshots__/scenes-app-insights--retention-breakdown--webkit.png b/frontend/__snapshots__/scenes-app-insights--retention-breakdown--webkit.png index 5d4b625ed232f..fd40f5ea3d016 100644 Binary files a/frontend/__snapshots__/scenes-app-insights--retention-breakdown--webkit.png and b/frontend/__snapshots__/scenes-app-insights--retention-breakdown--webkit.png differ diff --git a/frontend/src/stories/How to build a scene.stories.mdx b/frontend/src/stories/How to build a scene.stories.mdx index f394caa8de19f..2ddd3573c517e 100644 --- a/frontend/src/stories/How to build a scene.stories.mdx +++ b/frontend/src/stories/How to build a scene.stories.mdx @@ -6,11 +6,11 @@ import { Meta } from '@storybook/addon-docs'; If you want to add a new scene in the PostHog App frontend, here are 7 easy steps for fun and profit. -## 1. Create the component, logic and styles. - But first, you must answer one question: Does your scene depend on an `id` in the URL, like `/dashboard/:id`? -## 1.1. I'm buliding a global scene that does not depend on an `id` in the URL. +## Option A: I'm buliding a global scene that does not depend on an `id` in the URL. + +### 1. Create the component, logic and styles. Create a component like: `frontend/src/scenes/dashboard/Dashboards.tsx` @@ -22,13 +22,13 @@ import { useValues } from 'kea' export function Dashboards (): JSX.Element { const { - dashboard: dashboard - } = useValues(dashboardLogic) + counter + } = useValues(dashboardsLogic) return ( // TODO: consolidate on a recommended naming convention
- Dashboard Scene! + Dashboard Scene {counter}!
) } @@ -42,11 +42,14 @@ export const scene: SceneExport = { Create the logic: `frontend/src/scenes/dashboard/dashboardsLogic.tsx` ```ts -import { dashboardsLogicType } from './dashboardsLogicType' - -export const dashboardsLogic = kea({ - path: ['scenes', 'dashboard', 'dashboardsLogic'], -}) +import { kea, reducers, path } from 'kea' + +export const dashboardsLogic = kea([ + path(['scenes', 'dashboard', 'dashboardsLogic']), + reducers({ + counter: [1, {}], + }), +]) ``` Create the styles `frontend/src/scenes/dashboard/Dashboards.scss`. @@ -57,7 +60,62 @@ Create the styles `frontend/src/scenes/dashboard/Dashboards.scss`. } ``` -## 1.2. My scene depends on an `id` in the URL (`/dashboard/:id`). +Run kea type generation and check, which will created `dashboardsLogicType.ts` and update imports in `dashboardsLogic.tsx` + +```bash +pnpm typegen:write && pnpm typescript:check +``` + +### 2. Add a URL function + +in `frontend/src/scenes/urls.ts` + +```ts +export const urls = { + dashboards: () => `/dashboard`, +} +``` + +### 3. Add a scene to the enum + +in `frontend/src/scenes/sceneTypes.ts` + +```ts +export enum Scene { + Dashboards = 'Dashboards', +} +``` + +### 4. Add a scene configuration and a route to scene mapping + +in `frontend/src/scenes/scenes.ts` + +```ts +export const sceneConfigurations: Partial> = { + [Scene.Dashboards]: { + projectBased: true, + name: 'Dashboards', + }, +} + +export const routes: Record = { + [urls.dashboards()]: Scene.Dashboards, +} +``` + +### 5. Add a scene import + +in `frontend/src/scenes/appScenes.ts` + +```ts +export const appScenes: Record any> = { + [Scene.Dashboards]: () => import('./dashboard/Dashboards'), +} +``` + +## Option B: My scene depends on an `id` in the URL (`/dashboard/:id`). + +### 1. Create the component, logic and styles. Create a component like: `frontend/src/scenes/dashboard/Dashboard.tsx` @@ -65,7 +123,7 @@ Create a component like: `frontend/src/scenes/dashboard/Dashboard.tsx` import './Dashboard.scss' import { dashboardLogic } from './dashboardLogic' import { SceneExport } from 'scenes/sceneTypes' -import { useActions, useValues } from 'kea' +import { useValues } from 'kea' export const scene: SceneExport = { component: Dashboard, @@ -73,17 +131,19 @@ export const scene: SceneExport = { // paramsToProps - Convert url _string_ params to logic props. // This mounts the right logic with turbo mode before the component renders. // This wraps the scene's logic in - paramsToProps: ({ id }) => ({ id: id ? parseInt(id) : 'new' }), + paramsToProps: ({ params: {id} }:{ params: { id?: string }}) => ({ id: id ? parseInt(id) : 'new' }), } export function Dashboard ({ id }: { id?: string } = {}): JSX.Element { // dashboardLogic is automatically bound to the props above with BindLogic - const { dashboard } = useValues(dashboardLogic) - const { reloadDashboard } = useActions(dashboardLogic) + const { + counter + } = useValues(dashboardLogic) + return ( // TODO: consolidate on a recommended naming convention
- Dashboard Scene! + Dashboard Scene {id} {counter}!
) } @@ -92,18 +152,20 @@ export function Dashboard ({ id }: { id?: string } = {}): JSX.Element { Create the logic: `frontend/src/scenes/dashboard/dashboardLogic.tsx` ```ts -import { dashboardLogicType } from './dashboardLogicType' +import { kea, reducers, path, props, key } from 'kea' export interface DashboardLogicProps { id: number | 'new' } -export const dashboardLogic = kea>({ - path: ['scenes', 'dashboard', 'dashboardLogic'], - props: {} as DashboardLogicProps, - key: (props) => props.id, - -}) +export const dashboardLogic = kea([ + props({} as DashboardLogicProps), + key(({ id }) => id), + path((id) => ['scenes', 'dashboard', 'dashboardLogic', id]), + reducers({ + counter: [1, {}], + }), +]) ``` Create the styles `frontend/src/scenes/dashboard/Dashboard.scss`. @@ -114,18 +176,23 @@ Create the styles `frontend/src/scenes/dashboard/Dashboard.scss`. } ``` -## 2. Add a URL function +Run kea type generation and check, which will created `dashboardLogicType.ts` and update imports in `dashboardLogic.tsx` + +```bash +pnpm typegen:write && pnpm typescript:check +``` + +### 2. Add a URL function in `frontend/src/scenes/urls.ts` ```ts export const urls = { dashboard: (id: string | number) => `/dashboard{id ? `/${id}` : ''}`, - dashboards: () => `/dashboard`, } ``` -## 3. Add a scene to the enum +### 3. Add a scene to the enum in `frontend/src/scenes/sceneTypes.ts` @@ -135,7 +202,7 @@ export enum Scene { } ``` -## 4. Add a scene configuration and a route to scene mapping +### 4. Add a scene configuration and a route to scene mapping in `frontend/src/scenes/scenes.ts` @@ -150,11 +217,10 @@ export const sceneConfigurations: Partial> = { export const routes: Record = { // this `:id` gets used in "params" in "paramsToProps" and passed to the component [urls.dashboard(':id')]: Scene.Dashboard, - [urls.dashboards()]: Scene.Dashboard, } ``` -## 5. Add a scene import +### 5. Add a scene import in `frontend/src/scenes/appScenes.ts`