Skip to content

Commit

Permalink
feat(opentrons-ai-client): add ChatContainer component (#14921)
Browse files Browse the repository at this point in the history
* feat(opentrons-ai-client): add ChatContainer component
  • Loading branch information
koji committed Apr 18, 2024
1 parent c096931 commit 0e79a40
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 52 deletions.
15 changes: 13 additions & 2 deletions opentrons-ai-client/src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import React from 'react'
import { screen } from '@testing-library/react'
import { describe, it } from 'vitest'
import { describe, it, vi, beforeEach } from 'vitest'

import { renderWithProviders } from './__testing-utils__'
import { SidePanel } from './molecules/SidePanel'
import { ChatContainer } from './organisms/ChatContainer'

import { App } from './App'

vi.mock('./molecules/SidePanel')
vi.mock('./organisms/ChatContainer')

const render = (): ReturnType<typeof renderWithProviders> => {
return renderWithProviders(<App />)
}

describe('App', () => {
beforeEach(() => {
vi.mocked(SidePanel).mockReturnValue(<div>mock SidePanel</div>)
vi.mocked(ChatContainer).mockReturnValue(<div>mock ChatContainer</div>)
})

it('should render text', () => {
render()
screen.getByText('Opentrons AI')
screen.getByText('mock SidePanel')
screen.getByText('mock ChatContainer')
})
})
11 changes: 8 additions & 3 deletions opentrons-ai-client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React from 'react'
import { Flex, StyledText } from '@opentrons/components'
import { DIRECTION_ROW, Flex } from '@opentrons/components'

import { SidePanel } from './molecules/SidePanel'
import { ChatContainer } from './organisms/ChatContainer'

export function App(): JSX.Element {
return (
<Flex>
<StyledText as="h1">Opentrons AI</StyledText>
<Flex flexDirection={DIRECTION_ROW}>
<SidePanel />
<ChatContainer />
</Flex>
)
}
98 changes: 51 additions & 47 deletions opentrons-ai-client/src/molecules/PromptGuide/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,52 +29,55 @@ export function PromptGuide(): JSX.Element {
<StyledText css={HEADER_TEXT_STYLE}>
{t('what_typeof_protocol')}
</StyledText>
<StyledText css={BODY_TEXT_STYLE}>
{t('make_sure_your_prompt')}
</StyledText>
<Flex
css={BODY_TEXT_STYLE}
flexDirection={DIRECTION_COLUMN}
paddingLeft={SPACING.spacing32}
>
<ul>
<li>
<StyledText>{t('metadata')}</StyledText>
<ul css={NESTED_ITEM_STYLE}>
<li>
<StyledText>{t('application')}</StyledText>
</li>
<li>
<StyledText>{t('robot')}</StyledText>
</li>
<li>
<StyledText>{t('api')}</StyledText>
</li>
</ul>
</li>
<li>
<StyledText>{t('ot2_pipettes')}</StyledText>
</li>
<li>
<StyledText>{t('modules')}</StyledText>
</li>
<li>
<StyledText>{t('well_allocations')}</StyledText>
</li>
<li>
<Trans
t={t}
i18nKey="tipracks_and_labware"
components={{
a: <ExternalLink external href={LABWARE_LIBRARY_URL} />,
span: <StyledText css={BODY_TEXT_STYLE} />,
}}
/>
</li>
<li>
<StyledText>{t('commands')}</StyledText>
</li>
</ul>

<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing16}>
<StyledText css={BODY_TEXT_STYLE}>
{t('make_sure_your_prompt')}
</StyledText>
<Flex
css={BODY_TEXT_STYLE}
flexDirection={DIRECTION_COLUMN}
paddingLeft={SPACING.spacing32}
>
<ul>
<li>
<StyledText>{t('metadata')}</StyledText>
<StyledUl>
<li>
<StyledText>{t('application')}</StyledText>
</li>
<li>
<StyledText>{t('robot')}</StyledText>
</li>
<li>
<StyledText>{t('api')}</StyledText>
</li>
</StyledUl>
</li>
<li>
<StyledText>{t('ot2_pipettes')}</StyledText>
</li>
<li>
<StyledText>{t('modules')}</StyledText>
</li>
<li>
<StyledText>{t('well_allocations')}</StyledText>
</li>
<li>
<Trans
t={t}
i18nKey="tipracks_and_labware"
components={{
a: <ExternalLink external href={LABWARE_LIBRARY_URL} />,
span: <StyledText css={BODY_TEXT_STYLE} />,
}}
/>
</li>
<li>
<StyledText>{t('commands')}</StyledText>
</li>
</ul>
</Flex>
</Flex>
<Trans
t={t}
Expand All @@ -97,10 +100,11 @@ const BODY_TEXT_STYLE = css`
font-size: ${TYPOGRAPHY.fontSize20};
line-height: ${TYPOGRAPHY.lineHeight24};
`
const NESTED_ITEM_STYLE = css`
const StyledUl = styled.ul`
padding-left: ${SPACING.spacing16};
list-style-type: disc;
`

const ExternalLink = styled(Link)`
font-size: ${TYPOGRAPHY.fontSize20};
line-height: ${TYPOGRAPHY.lineHeight24};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import { I18nextProvider } from 'react-i18next'
import { i18n } from '../../i18n'
import { ChatContainer as ChatContainerComponent } from './index'

import type { Meta, StoryObj } from '@storybook/react'

const meta: Meta<typeof ChatContainerComponent> = {
title: 'AI/organisms/ChatContainer',
component: ChatContainerComponent,
decorators: [
Story => (
<I18nextProvider i18n={i18n}>
<Story />
</I18nextProvider>
),
],
}
export default meta
type Story = StoryObj<typeof ChatContainerComponent>
export const ChatContainer: Story = {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import { screen } from '@testing-library/react'
import { describe, it, vi, beforeEach } from 'vitest'
import { renderWithProviders } from '../../../__testing-utils__'
import { i18n } from '../../../i18n'
import { PromptGuide } from '../../../molecules/PromptGuide'
import { ChatContainer } from '../index'

vi.mock('../../../molecules/PromptGuide')

const render = (): ReturnType<typeof renderWithProviders> => {
return renderWithProviders(<ChatContainer />, {
i18nInstance: i18n,
})
}

describe('ChatContainer', () => {
beforeEach(() => {
vi.mocked(PromptGuide).mockReturnValue(<div>mock PromptGuide</div>)
})
it('should render prompt guide and text', () => {
render()
screen.getByText('OpentronsAI')
screen.getByText('mock PromptGuide')
})

// ToDo (kk:04/16/2024) Add more test cases
})
35 changes: 35 additions & 0 deletions opentrons-ai-client/src/organisms/ChatContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
COLORS,
DIRECTION_COLUMN,
FLEX_MAX_CONTENT,
Flex,
SPACING,
StyledText,
} from '@opentrons/components'
import { PromptGuide } from '../../molecules/PromptGuide'

export function ChatContainer(): JSX.Element {
const { t } = useTranslation('protocol_generator')
const isDummyInitial = true
return (
<Flex
padding={SPACING.spacing40}
backgroundColor={COLORS.grey10}
width={FLEX_MAX_CONTENT}
>
{/* This will be updated when input textbox and function are implemented */}
{isDummyInitial ? (
<Flex
flexDirection={DIRECTION_COLUMN}
gridGap={SPACING.spacing12}
width="100%"
>
<StyledText>{t('opentronsai')}</StyledText>
<PromptGuide />
</Flex>
) : null}
</Flex>
)
}

0 comments on commit 0e79a40

Please sign in to comment.