diff --git a/frontend/__snapshots__/scenes-app-insights-error-empty-states--long-loading--dark.png b/frontend/__snapshots__/scenes-app-insights-error-empty-states--long-loading--dark.png index 7d5857c234223..0cd9c156ed787 100644 Binary files a/frontend/__snapshots__/scenes-app-insights-error-empty-states--long-loading--dark.png and b/frontend/__snapshots__/scenes-app-insights-error-empty-states--long-loading--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-insights-error-empty-states--long-loading--light.png b/frontend/__snapshots__/scenes-app-insights-error-empty-states--long-loading--light.png index 287a3cbef91e0..07f7adc141c90 100644 Binary files a/frontend/__snapshots__/scenes-app-insights-error-empty-states--long-loading--light.png and b/frontend/__snapshots__/scenes-app-insights-error-empty-states--long-loading--light.png differ diff --git a/frontend/__snapshots__/scenes-app-max-ai--empty-thread-loading--dark.png b/frontend/__snapshots__/scenes-app-max-ai--empty-thread-loading--dark.png new file mode 100644 index 0000000000000..d6fe88cab16e5 Binary files /dev/null and b/frontend/__snapshots__/scenes-app-max-ai--empty-thread-loading--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-max-ai--empty-thread-loading--light.png b/frontend/__snapshots__/scenes-app-max-ai--empty-thread-loading--light.png new file mode 100644 index 0000000000000..50e2dea81e948 Binary files /dev/null and b/frontend/__snapshots__/scenes-app-max-ai--empty-thread-loading--light.png differ diff --git a/frontend/__snapshots__/scenes-app-max-ai--thread--dark.png b/frontend/__snapshots__/scenes-app-max-ai--thread--dark.png new file mode 100644 index 0000000000000..b6706129af789 Binary files /dev/null and b/frontend/__snapshots__/scenes-app-max-ai--thread--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-max-ai--thread--light.png b/frontend/__snapshots__/scenes-app-max-ai--thread--light.png new file mode 100644 index 0000000000000..c28a32b736a5e Binary files /dev/null and b/frontend/__snapshots__/scenes-app-max-ai--thread--light.png differ diff --git a/frontend/__snapshots__/scenes-app-max-ai--welcome--dark.png b/frontend/__snapshots__/scenes-app-max-ai--welcome--dark.png new file mode 100644 index 0000000000000..023ee3bb7c7cb Binary files /dev/null and b/frontend/__snapshots__/scenes-app-max-ai--welcome--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-max-ai--welcome--light.png b/frontend/__snapshots__/scenes-app-max-ai--welcome--light.png new file mode 100644 index 0000000000000..38686893a504a Binary files /dev/null and b/frontend/__snapshots__/scenes-app-max-ai--welcome--light.png differ diff --git a/frontend/src/layout/navigation-3000/Navigation.scss b/frontend/src/layout/navigation-3000/Navigation.scss index f1dafe9a8df79..882e4c5acac7f 100644 --- a/frontend/src/layout/navigation-3000/Navigation.scss +++ b/frontend/src/layout/navigation-3000/Navigation.scss @@ -48,6 +48,7 @@ &.Navigation3000__scene--raw { --scene-padding: 0px; + --scene-padding-bottom: 0px; display: flex; flex-direction: column; diff --git a/frontend/src/lib/components/HedgehogBuddy/HedgehogBuddy.tsx b/frontend/src/lib/components/HedgehogBuddy/HedgehogBuddy.tsx index c9fb0932a05d7..026a450acca42 100644 --- a/frontend/src/lib/components/HedgehogBuddy/HedgehogBuddy.tsx +++ b/frontend/src/lib/components/HedgehogBuddy/HedgehogBuddy.tsx @@ -838,9 +838,11 @@ export class HedgehogActor { ))} {this.overlayAnimation ? (
, 'onFocus' | 'onBlur' | 'maxLength' | 'autoFocus' | 'onKeyDown' @@ -18,9 +18,6 @@ export interface LemonTextAreaProps disabled?: boolean ref?: React.Ref onChange?: (newValue: string) => void - /** Callback called when Cmd + Enter (or Ctrl + Enter) is pressed. - * This checks for Cmd/Ctrl, as opposed to LemonInput, to avoid blocking multi-line input. */ - onPressCmdEnter?: (newValue: string) => void minRows?: number maxRows?: number rows?: number @@ -29,9 +26,22 @@ export interface LemonTextAreaProps 'data-attr'?: string } +interface LemonTextAreaWithCmdEnterProps extends LemonTextAreaPropsBase { + /** Callback for when Cmd/Ctrl + Enter is pressed. In this case, the user adds new lines with Enter like always. */ + onPressCmdEnter?: (currentValue: string) => void + onPressEnter?: never +} + +interface LemonTextAreaWithEnterProps extends LemonTextAreaPropsBase { + /** Callback for when Enter is pressed. In this case, to add a new line the user must press Cmd + Enter. */ + onPressEnter: (currentValue: string) => void + onPressCmdEnter?: never +} +export type LemonTextAreaProps = LemonTextAreaWithEnterProps | LemonTextAreaWithCmdEnterProps + /** A `textarea` component for multi-line text. */ export const LemonTextArea = React.forwardRef(function _LemonTextArea( - { className, onChange, onPressCmdEnter: onPressEnter, minRows = 3, onKeyDown, stopPropagation, ...textProps }, + { className, onChange, onPressEnter, onPressCmdEnter, minRows = 3, onKeyDown, stopPropagation, ...textProps }, ref ): JSX.Element { const _ref = useRef(null) @@ -46,10 +56,29 @@ export const LemonTextArea = React.forwardRef { diff --git a/frontend/src/lib/lemon-ui/LoadingBar/LoadingBar.scss b/frontend/src/lib/lemon-ui/LoadingBar/LoadingBar.scss index a3d281eceaaea..2f71c1fb79d00 100644 --- a/frontend/src/lib/lemon-ui/LoadingBar/LoadingBar.scss +++ b/frontend/src/lib/lemon-ui/LoadingBar/LoadingBar.scss @@ -18,4 +18,9 @@ left: 0; height: 100%; background: var(--primary-3000-active); + + .storybook-test-runner & { + // When taking UI snapshots, we hard-code progress width to 50% + width: 50% !important; + } } diff --git a/frontend/src/scenes/insights/EmptyStates/EmptyStates.stories.tsx b/frontend/src/scenes/insights/EmptyStates/EmptyStates.stories.tsx index 5ac9451001c14..15e23154d2fef 100644 --- a/frontend/src/scenes/insights/EmptyStates/EmptyStates.stories.tsx +++ b/frontend/src/scenes/insights/EmptyStates/EmptyStates.stories.tsx @@ -130,11 +130,7 @@ export const LongLoading: StoryFn = () => { ], }, post: { - '/api/projects/:team_id/insights/trend/': (_, __, ctx) => [ - ctx.delay(86400000), - ctx.status(200), - ctx.json({ result: insight.result }), - ], + '/api/projects/:team_id/query/': (_, __, ctx) => [ctx.delay('infinite')], }, }) useEffect(() => { diff --git a/frontend/src/scenes/max/Intro.tsx b/frontend/src/scenes/max/Intro.tsx new file mode 100644 index 0000000000000..c714495b72f86 --- /dev/null +++ b/frontend/src/scenes/max/Intro.tsx @@ -0,0 +1,51 @@ +import { useValues } from 'kea' +import { HedgehogBuddy } from 'lib/components/HedgehogBuddy/HedgehogBuddy' +import { hedgehogBuddyLogic } from 'lib/components/HedgehogBuddy/hedgehogBuddyLogic' +import { useMemo } from 'react' + +import { maxLogic } from './maxLogic' + +const HEADLINES = [ + 'How can I help you build?', + 'What are you curious about?', + 'How can I help you understand users?', + 'What do you want to know today?', +] + +export function Intro(): JSX.Element { + const { hedgehogConfig } = useValues(hedgehogBuddyLogic) + const { sessionId } = useValues(maxLogic) + + const headline = useMemo(() => { + return HEADLINES[parseInt(sessionId.split('-').at(-1) as string, 16) % HEADLINES.length] + }, []) + + return ( + <> +
+ { + if (Math.random() < 0.01) { + actor.setOnFire() + } else { + actor.setRandomAnimation() + } + }} + onActorLoaded={(actor) => setTimeout(() => actor.setAnimation('wave'), 100)} + /> +
+
+

{headline}

+ + I'm Max, here to help you build a succesful product. Ask me about your product and your users. + +
+ + ) +} diff --git a/frontend/src/scenes/max/Max.stories.tsx b/frontend/src/scenes/max/Max.stories.tsx new file mode 100644 index 0000000000000..812c87f0fd423 --- /dev/null +++ b/frontend/src/scenes/max/Max.stories.tsx @@ -0,0 +1,74 @@ +import { Meta, StoryFn } from '@storybook/react' +import { BindLogic, useActions } from 'kea' +import { useEffect } from 'react' + +import { mswDecorator, useStorybookMocks } from '~/mocks/browser' + +import chatResponse from './__mocks__/chatResponse.json' +import { MaxInstance } from './Max' +import { maxLogic } from './maxLogic' + +const meta: Meta = { + title: 'Scenes-App/Max AI', + decorators: [ + mswDecorator({ + post: { + '/api/projects/:team_id/query/chat/': chatResponse, + }, + }), + ], + parameters: { + layout: 'fullscreen', + viewMode: 'story', + mockDate: '2023-01-28', // To stabilize relative dates + }, +} +export default meta + +const Template = ({ sessionId }: { sessionId: string }): JSX.Element => { + return ( +
+ + + +
+ ) +} + +export const Welcome: StoryFn = () => { + const sessionId = 'd210b263-8521-4c5b-b3c4-8e0348df574b' + return