Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ai client chat page #16696

Closed
wants to merge 67 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
c7123ad
feat: initial commit add landing page and replace App
fbelginetw Oct 17, 2024
e6071a8
refactor: cleanup code and add basic tests
fbelginetw Oct 18, 2024
8d5fd11
feat: add useIsMobile hook
fbelginetw Oct 18, 2024
64d1996
feat: add tests and button onClicks
fbelginetw Oct 18, 2024
5b2022d
feat: add mixpanel analytics
fbelginetw Oct 18, 2024
567b39f
Merge branch 'edge' into opentrons-ai-client-landing-page
fbelginetw Oct 21, 2024
2514383
refactor: add and fix tests
fbelginetw Oct 21, 2024
fde8b2c
Merge branch 'edge' into opentrons-ai-client-landing-page
fbelginetw Oct 21, 2024
ddb7ebc
Merge branch 'edge' into opentrons-ai-client-landing-page
fbelginetw Oct 21, 2024
77ab903
feat: add create protocol page
fbelginetw Oct 22, 2024
4173ea2
refactor: separate translation file and adjust layout
fbelginetw Oct 22, 2024
002550e
refactor: create controlled dropdown and input field
fbelginetw Oct 22, 2024
ee9c997
Moved a copy of uploadinput into the ai-client and added UpdateProtoc…
connected-znaim Oct 22, 2024
9a3a48a
added upload input styling for text
connected-znaim Oct 22, 2024
54a6eca
fixed import issue
connected-znaim Oct 22, 2024
16cd6af
refactor: simplify accordion to avoid issues with dropdowns
fbelginetw Oct 22, 2024
6295513
fixed build
connected-znaim Oct 22, 2024
73ec6c2
feat: add application section, update translation files
fbelginetw Oct 22, 2024
4562b25
refactor: add new section and adjust layout
fbelginetw Oct 22, 2024
94cea0f
Merge branch 'edge' into opentrons-ai-client-landing-page
fbelginetw Oct 22, 2024
7ed7f2b
refactor: add header and adjust for wide screens
fbelginetw Oct 22, 2024
f126f11
added incomplete file upload functionality
connected-znaim Oct 23, 2024
b4bc268
Merge branch 'edge' into opentrons-ai-client-landing-page
fbelginetw Oct 23, 2024
76bd334
refactor: add Footer, update analytics capture for logout, and add tests
fbelginetw Oct 23, 2024
a010d83
refactor: mock useTrackEvent to stop warnings
fbelginetw Oct 23, 2024
760e940
refactor: alphabetical order
fbelginetw Oct 23, 2024
fe51246
Merge branch 'opentrons-ai-client-landing-page' into opentrons-ai-cli…
fbelginetw Oct 23, 2024
2016a5b
feat: add atom to control header with meter
fbelginetw Oct 23, 2024
4031568
Merge branch 'edge' into opentrons-ai-client-application
fbelginetw Oct 23, 2024
db352a4
fix: pr comments from lading page
fbelginetw Oct 23, 2024
a660cd9
feat: add isInitialized to mixpanel to avoid calling it twice
fbelginetw Oct 23, 2024
17fc268
fixed the dropdown menu and added error states to file upload
connected-znaim Oct 24, 2024
5d1ff6c
Merge branch 'edge' into ai_client_update_protocol
connected-znaim Oct 24, 2024
8bc408a
feat: add atom to control current section
fbelginetw Oct 24, 2024
20e8814
added route to updateprotocol and fixed some design issues
connected-znaim Oct 24, 2024
8eb5b9f
fix: remove unused imports
fbelginetw Oct 24, 2024
9b85412
feat: add logic for focus/current steps, progress bar and isCompleted…
fbelginetw Oct 24, 2024
493125e
refactor: protocol section container and create protocol tests
fbelginetw Oct 24, 2024
e4e0eb6
refactor: add more section tests
fbelginetw Oct 24, 2024
2bdde5e
refactor: sticky header
fbelginetw Oct 24, 2024
5d0df2b
refactor: remame createProtocolTestUtils
fbelginetw Oct 24, 2024
d40330a
added chat page and passed in the result of the existing protocol flow
connected-znaim Oct 24, 2024
e406b00
fixed chat screen
connected-znaim Oct 25, 2024
1736018
refactor: update renderWithProviders to use jotai
fbelginetw Oct 25, 2024
73faf1c
refactor: remove todo
fbelginetw Oct 25, 2024
a512b8a
test file for existing protocol
connected-znaim Oct 25, 2024
66632df
update protocol fixes for test
connected-znaim Oct 28, 2024
33e5300
Merge branch 'edge' into ai_client_update_protocol
connected-znaim Oct 28, 2024
96b5fc3
Merge remote-tracking branch 'origin/opentrons-ai-client-application'…
connected-znaim Oct 28, 2024
cc49be8
switched to apps progress header
connected-znaim Oct 28, 2024
73a89f9
added a csstransition to fade the components in and out
connected-znaim Oct 28, 2024
f7e5912
added a new atom to pass in the generated prompt from the existing an…
connected-znaim Oct 28, 2024
d372bc3
removed some spacing and text
connected-znaim Oct 28, 2024
2082bcd
Merge branch 'edge' into ai_client_update_protocol
connected-znaim Oct 28, 2024
63acf35
fixed unused imports
connected-znaim Oct 28, 2024
7f1de84
fixed broken test
connected-znaim Oct 28, 2024
7c86e8d
fixed bug that showed progress bar when navigating back to the landin…
connected-znaim Oct 28, 2024
0b28a6b
fixed code formatting and spacing and started consolidating mainconta…
connected-znaim Oct 28, 2024
794197e
moved over the maincontainer code into the chat page
connected-znaim Oct 29, 2024
4649270
adjusted padding
connected-znaim Oct 29, 2024
7e2ea62
added UI for feedback modal
connected-znaim Oct 30, 2024
b202388
added icons for reload, feedback, copy and download
connected-znaim Oct 30, 2024
8feaa08
added file download functionality
connected-znaim Oct 31, 2024
94e5493
fixed formatting and text changes
connected-znaim Nov 1, 2024
41556f4
added ability to regenerate response by clicking the button and scrol…
connected-znaim Nov 4, 2024
b9f6884
unused import fix
connected-znaim Nov 5, 2024
ab6ca06
fixed formatting
connected-znaim Nov 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions components/src/icons/icon-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,11 @@ export const ICON_DATA_BY_NAME: Record<
'M18.793 34.9163C15.3763 34.6386 12.5013 33.2358 10.168 30.708C7.83464 28.1802 6.66797 25.1802 6.66797 21.708C6.66797 19.5691 7.16102 17.5552 8.14714 15.6663C9.13325 13.7775 10.5152 12.2358 12.293 11.0413L14.0846 12.833C12.5291 13.7497 11.3207 15.0066 10.4596 16.6038C9.59852 18.2011 9.16797 19.9025 9.16797 21.708C9.16797 24.4858 10.0846 26.8886 11.918 28.9163C13.7513 30.9441 16.043 32.1108 18.793 32.4163V34.9163ZM21.293 34.9163V32.4163C24.0707 32.083 26.3624 30.9094 28.168 28.8955C29.9735 26.8816 30.8763 24.4858 30.8763 21.708C30.8763 18.6802 29.8277 16.1177 27.7305 14.0205C25.6332 11.9233 23.0707 10.8747 20.043 10.8747H19.2096L21.7096 13.3747L19.918 15.1663L14.3763 9.62467L19.918 4.08301L21.7096 5.87467L19.2096 8.37467H20.043C23.7652 8.37467 26.918 9.67329 29.5013 12.2705C32.0846 14.8677 33.3763 18.0136 33.3763 21.708C33.3763 25.1802 32.2166 28.1802 29.8971 30.708C27.5777 33.2358 24.7096 34.6386 21.293 34.9163Z',
viewBox: '0 0 40 40',
},
reload: {
path:
'M15.1406 23.6501C11.9581 23.6501 9.25062 22.5457 7.01813 20.337C4.78562 18.1282 3.66937 15.4326 3.66937 12.2501V12.0007L2.38687 13.2832C2.12562 13.5445 1.79312 13.6751 1.38937 13.6751C0.985625 13.6751 0.653125 13.5445 0.391875 13.2832C0.130625 13.022 0 12.6895 0 12.2857C0 11.882 0.130625 11.5495 0.391875 11.2882L4.09687 7.58322C4.38188 7.29822 4.71438 7.15572 5.09438 7.15572C5.47437 7.15572 5.80687 7.29822 6.09188 7.58322L9.79688 11.2882C10.0581 11.5495 10.1888 11.882 10.1888 12.2857C10.1888 12.6895 10.0581 13.022 9.79688 13.2832C9.53562 13.5445 9.20312 13.6751 8.79937 13.6751C8.39563 13.6751 8.06312 13.5445 7.80188 13.2832L6.51937 12.0007V12.2501C6.51937 14.6251 7.35656 16.6438 9.03094 18.3063C10.7053 19.9688 12.7419 20.8001 15.1406 20.8001C15.5206 20.8001 15.8947 20.7764 16.2628 20.7288C16.6309 20.6813 16.9931 20.5982 17.3494 20.4795C17.7531 20.3607 18.1331 20.3726 18.4894 20.5151C18.8456 20.6576 19.1187 20.907 19.3088 21.2632C19.4988 21.6432 19.5166 22.0173 19.3622 22.3854C19.2078 22.7535 18.9287 22.997 18.525 23.1157C17.9788 23.3057 17.4206 23.4423 16.8506 23.5254C16.2806 23.6085 15.7106 23.6501 15.1406 23.6501ZM14.9981 3.7001C14.6181 3.7001 14.2441 3.72385 13.8759 3.77135C13.5078 3.81885 13.1456 3.90197 12.7894 4.02072C12.3856 4.13947 11.9997 4.1276 11.6316 3.9851C11.2634 3.8426 10.9844 3.59322 10.7944 3.23697C10.6044 2.88072 10.5866 2.51854 10.7409 2.15041C10.8953 1.78229 11.1625 1.53885 11.5425 1.4201C12.1125 1.2301 12.6825 1.0876 13.2525 0.992598C13.8225 0.897598 14.4044 0.850098 14.9981 0.850098C18.1806 0.850098 20.8881 1.95447 23.1206 4.16322C25.3531 6.37197 26.4694 9.0676 26.4694 12.2501V12.4995L27.7519 11.217C28.0131 10.9557 28.3456 10.8251 28.7494 10.8251C29.1531 10.8251 29.4856 10.9557 29.7469 11.217C30.0081 11.4782 30.1388 11.8107 30.1388 12.2145C30.1388 12.6182 30.0081 12.9507 29.7469 13.212L26.0419 16.917C25.7569 17.202 25.4244 17.3445 25.0444 17.3445C24.6644 17.3445 24.3319 17.202 24.0469 16.917L20.3419 13.212C20.0806 12.9507 19.95 12.6182 19.95 12.2145C19.95 11.8107 20.0806 11.4782 20.3419 11.217C20.6031 10.9557 20.9356 10.8251 21.3394 10.8251C21.7431 10.8251 22.0756 10.9557 22.3369 11.217L23.6194 12.4995V12.2501C23.6194 9.8751 22.7822 7.85635 21.1078 6.19385C19.4334 4.53135 17.3969 3.7001 14.9981 3.7001Z',
viewBox: '0 0 31 24',
},
reticle: {
path:
'M8.01487 8.84912C8.47511 8.84912 8.84821 8.47603 8.84821 8.01579C8.84821 7.55555 8.47511 7.18245 8.01487 7.18245C7.55464 7.18245 7.18154 7.55555 7.18154 8.01579C7.18154 8.47603 7.55464 8.84912 8.01487 8.84912Z M8.66654 0.928711V2.36089C11.27 2.66533 13.3354 4.73075 13.6398 7.33418H15.072V8.66751H13.6398C13.3354 11.2709 11.27 13.3363 8.66654 13.6408V15.073H7.3332V13.6408C4.72979 13.3363 2.66437 11.2709 2.35992 8.66751H0.927734V7.33418H2.35992C2.66436 4.73075 4.72978 2.66533 7.3332 2.36089V0.928711H8.66654ZM12.2944 7.33418H11.6184C11.2502 7.33418 10.9518 7.63266 10.9518 8.00085C10.9518 8.36904 11.2502 8.66751 11.6184 8.66751H12.2944C12.0071 10.5336 10.5326 12.008 8.66654 12.2953V11.6194C8.66654 11.2512 8.36806 10.9527 7.99987 10.9527C7.63168 10.9527 7.3332 11.2512 7.3332 11.6194V12.2953C5.46716 12.008 3.99268 10.5336 3.70536 8.66751H4.38132C4.74951 8.66751 5.04798 8.36904 5.04798 8.00085C5.04798 7.63266 4.74951 7.33418 4.38132 7.33418H3.70536C3.99267 5.46812 5.46715 3.99364 7.3332 3.70632V4.38229C7.3332 4.75048 7.63168 5.04896 7.99987 5.04896C8.36806 5.04896 8.66654 4.75048 8.66654 4.38229V3.70632C10.5326 3.99364 12.0071 5.46812 12.2944 7.33418Z',
Expand Down Expand Up @@ -729,6 +734,11 @@ export const ICON_DATA_BY_NAME: Record<
'M10.8307 8.3335L1.66406 31.6668H4.78906L7.16406 25.4168H17.8307L20.2057 31.6668H23.3307L14.1641 8.3335H10.8307ZM16.8307 22.7502H8.16406L12.4141 11.4585H12.5807L16.8307 22.7502ZM30.1577 16.6668L24.1641 31.6668H26.2073L27.7602 27.649H34.7346L36.2875 31.6668H38.3307L32.3371 16.6668H30.1577ZM34.0807 25.9347H28.4141L31.1929 18.6758H31.3019L34.0807 25.9347Z',
viewBox: '0 0 40 40',
},
'thumbs-down': {
path:
'M2.99062 18.9525C2.23062 18.9525 1.56562 18.6675 0.995625 18.0975C0.425625 17.5275 0.140625 16.8625 0.140625 16.1025V13.2525C0.140625 13.0862 0.164375 12.9081 0.211875 12.7181C0.259375 12.5281 0.306875 12.35 0.354375 12.1837L4.62937 2.13749C4.84312 1.66249 5.19938 1.25874 5.69812 0.92624C6.19688 0.59374 6.71938 0.42749 7.26562 0.42749H22.9406V18.9525L14.3906 27.4312C14.0344 27.7875 13.6128 27.9953 13.1259 28.0547C12.6391 28.1141 12.17 28.025 11.7188 27.7875C11.2675 27.55 10.935 27.2175 10.7212 26.79C10.5075 26.3625 10.46 25.9231 10.5787 25.4719L12.1819 18.9525H2.99062ZM20.0906 17.7412V3.27749H7.26562L2.99062 13.2525V16.1025H15.8156L13.8919 23.94L20.0906 17.7412ZM27.2156 0.42749C27.9994 0.42749 28.6703 0.706553 29.2284 1.26468C29.7866 1.8228 30.0656 2.49374 30.0656 3.27749V16.1025C30.0656 16.8862 29.7866 17.5572 29.2284 18.1153C28.6703 18.6734 27.9994 18.9525 27.2156 18.9525H22.9406V16.1025H27.2156V3.27749H22.9406V0.42749H27.2156Z',
viewBox: '0 0 31 29',
},
'tip-position': {
path:
'M10.75 2H9.25V4.75H10.75V2ZM10.75 9.25V7.25H9.25V9.25H7.25V10.75H9.25V12.75H10.75V10.75H12.75V9.25H10.75ZM10.75 18V15.25H9.25V18H10.75ZM2 9.25V10.75H4.75V9.25H2ZM18 9.25H15.25V10.75H18V9.25Z',
Expand Down
10 changes: 9 additions & 1 deletion opentrons-ai-client/src/OpentronsAIRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import { Route, Navigate, Routes } from 'react-router-dom'
import { Landing } from './pages/Landing'
import { UpdateProtocol } from './organisms/UpdateProtocol'

import type { RouteProps } from './resources/types'
import { Chat } from './pages/Chat'
import { CreateProtocol } from './pages/CreateProtocol'

const opentronsAIRoutes: RouteProps[] = [
{
Component: Chat,
name: 'Chat',
navLinkTo: '/chat',
path: '/chat',
},
{
Component: CreateProtocol,
name: 'Create A New Protocol',
navLinkTo: '/new-protocol',
path: '/new-protocol',
},
{
Component: Landing,
Component: UpdateProtocol,
name: 'Update An Existing Protocol',
navLinkTo: '/update-protocol',
path: '/update-protocol',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
"api": "API: An API level is 2.15",
"application": "Application: Your protocol's name, describing what it does.",
"commands": "Commands: List the protocol's steps, specifying quantities in microliters (uL) and giving exact source and destination locations.",
"cancel": "Cancel",
"copyright": "Copyright © 2024 Opentrons",
"copy_code": "Copy code",
"choose_file": "Choose file",
"disclaimer": "OpentronsAI can make mistakes. Review your protocol before running it on an Opentrons robot.",
"drag_and_drop": "Drag and drop or <a>browse</a> your files",
"example": "For example prompts, click the buttons in the left panel.",
"file_length_error": "The length of the file contents is 0. Please upload a file with content.",
"got_feedback": "Got feedback? We love to hear it.",
"key_info": "Here are some key pieces of information to provide in your prompt:",
"labware_and_tipracks": "Labware and tip racks: Use names from the <a>Opentrons Labware Library</a>.",
Expand All @@ -30,17 +34,26 @@
"pcr": "PCR",
"pipettes": "Pipettes: Specify your pipettes, including the volume, number of channels, and whether they’re mounted on the left or right.",
"privacy_policy": "By continuing, you agree to the Opentrons <privacyPolicyLink>Privacy Policy</privacyPolicyLink> and <EULALink>End user license agreement</EULALink>",
"protocol_file": "Protocol file",
"provide_details_of_changes": "Provide details of changes you want to make",
"python_file_type_error": "Python file type required",
"reagent_transfer_flex": "Reagent Transfer (Flex)",
"reagent_transfer": "Reagent Transfer",
"reload_page": "To start over and create a new protocol, simply reload the page.",
"robot_type": "Robot type: Choose the OT-2 or Opentrons Flex.",
"robot": "Robot: OT-2.",
"share_your_thoughts": "Share your thoughts here",
"send_feedback": "Send feedback",
"send_feedback_input_title": "Share why the response was not helpful",
"send_feedback_to_opentrons": "Send feedback to Opentrons",
"side_panel_body": "Write a prompt in natural language to generate a Reagent Transfer or a PCR protocol for the OT-2 or Opentrons Flex using the Opentrons Python Protocol API.",
"side_panel_header": "Use natural language to generate protocols with OpentronsAI powered by OpenAI",
"simulate_description": "Once OpentronsAI has written your protocol, type `simulate` in the prompt box to try it out.",
"submit_prompt": "Submit prompt",
"try_example_prompts": "Stuck? Try these example prompts to get started.",
"type_of_update": "Type of update",
"type_your_prompt": "Type your prompt...",
"update_existing_protocol": "Update an existing protocol",
"well_allocations": "Well allocations: Describe where liquids should go in labware.",
"what_if_you": "<span>What if you don’t provide all of those pieces of information? <bold>OpentronsAI asks you to provide it!</bold></span>",
"what_typeof_protocol": "What type of protocol do you need?",
Expand Down
134 changes: 107 additions & 27 deletions opentrons-ai-client/src/molecules/ChatDisplay/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react'
import { useEffect, useState } from 'react'
import styled from 'styled-components'
import { useTranslation } from 'react-i18next'
import Markdown from 'react-markdown'
Expand All @@ -12,56 +12,113 @@ import {
JUSTIFY_CENTER,
JUSTIFY_FLEX_END,
JUSTIFY_FLEX_START,
POSITION_ABSOLUTE,
POSITION_RELATIVE,
PrimaryButton,
SPACING,
LegacyStyledText,
TYPOGRAPHY,
StyledText,
DIRECTION_ROW,
} from '@opentrons/components'

import type { ChatData } from '../../resources/types'
import { useAtom } from 'jotai'
import {
chatDataAtom,
feedbackModalAtom,
scrollToBottomAtom,
} from '../../resources/atoms'
import { delay } from 'lodash'
import { useFormContext } from 'react-hook-form'

interface ChatDisplayProps {
chat: ChatData
chatId: string
}

const HoverShadow = styled(Flex)`
alignitems: ${ALIGN_CENTER};
justifycontent: ${JUSTIFY_CENTER};
padding: ${SPACING.spacing8};
transition: box-shadow 0.3s ease;
border-radius: ${BORDERS.borderRadius8};

&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
border-radius: ${BORDERS.borderRadius8};
}
`

const StyledIcon = styled(Icon)`
color: ${COLORS.blue50};
`

export function ChatDisplay({ chat, chatId }: ChatDisplayProps): JSX.Element {
const { t } = useTranslation('protocol_generator')
const [isCopied, setIsCopied] = useState<boolean>(false)
const { role, reply } = chat
const [, setShowFeedbackModal] = useAtom(feedbackModalAtom)
const { setValue } = useFormContext()
const [chatdata] = useAtom(chatDataAtom)
const [scrollToBottom, setScrollToBottom] = useAtom(scrollToBottomAtom)
const { role, reply, requestId } = chat
const isUser = role === 'user'

const setInputFieldToCorrespondingRequest = (): void => {
const prompt = chatdata.find(
chat => chat.role === 'user' && chat.requestId === requestId
)?.reply
setScrollToBottom(!scrollToBottom)
setValue('userPrompt', prompt)
}

const handleFileDownload = (): void => {
const lastCodeBlock = document.querySelector(`#${chatId}`)
const code = lastCodeBlock?.textContent ?? ''
const blobParts: BlobPart[] = [code]

const file = new File(blobParts, 'OpentronsAI.py', { type: 'text/python' })
const url = URL.createObjectURL(file)
const a = document.createElement('a')

document.body.appendChild(a)
a.href = url
a.download = 'OpentronsAI.py'
a.click()
window.URL.revokeObjectURL(url)
}

const handleClickCopy = async (): Promise<void> => {
const lastCodeBlock = document.querySelector(`#${chatId}`)
const code = lastCodeBlock?.textContent ?? ''
await navigator.clipboard.writeText(code)
setIsCopied(true)
}

useEffect(() => {
if (isCopied)
delay(() => {
setIsCopied(false)
}, 2000)
}, [isCopied])

function CodeText(props: JSX.IntrinsicAttributes): JSX.Element {
return <CodeWrapper {...props} id={chatId} />
}

return (
<Flex
flexDirection={DIRECTION_COLUMN}
gridGap={SPACING.spacing12}
paddingLeft={isUser ? SPACING.spacing40 : undefined}
paddingRight={isUser ? undefined : SPACING.spacing40}
>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing12}>
<Flex justifyContent={isUser ? JUSTIFY_FLEX_END : JUSTIFY_FLEX_START}>
<LegacyStyledText>
<StyledText paddingTop={SPACING.spacing12}>
{isUser ? t('you') : t('opentronsai')}
</LegacyStyledText>
</StyledText>
</Flex>
{/* text should be markdown so this component will have a package or function to parse markdown */}
<Flex
padding={SPACING.spacing32}
padding={`${SPACING.spacing40} ${SPACING.spacing40} ${
isUser ? SPACING.spacing40 : SPACING.spacing12
} ${SPACING.spacing40}`}
backgroundColor={isUser ? COLORS.blue30 : COLORS.grey30}
data-testid={`ChatDisplay_from_${isUser ? 'user' : 'backend'}`}
borderRadius={BORDERS.borderRadius12}
borderRadius={SPACING.spacing12}
width="100%"
flexDirection={DIRECTION_COLUMN}
gridGap={SPACING.spacing16}
Expand All @@ -82,21 +139,44 @@ export function ChatDisplay({ chat, chatId }: ChatDisplayProps): JSX.Element {
</Markdown>

{!isUser ? (
<PrimaryButton
position={POSITION_ABSOLUTE}
right={SPACING.spacing16}
bottom={`-${SPACING.spacing24}`}
borderRadius={BORDERS.borderRadiusFull}
onClick={handleClickCopy}
<Flex
flexDirection={DIRECTION_ROW}
justifyContent={JUSTIFY_FLEX_END}
gridGap={SPACING.spacing20}
paddingTop={SPACING.spacing12}
>
<Flex alignItems={ALIGN_CENTER} justifyContent={JUSTIFY_CENTER}>
<Icon
size="2rem"
name={isCopied ? 'check' : 'copy-text'}
color={COLORS.white}
<HoverShadow
onClick={() => {
setInputFieldToCorrespondingRequest()
}}
>
<StyledIcon size={SPACING.spacing20} name={'reload'} />
</HoverShadow>
<HoverShadow
onClick={() => {
setShowFeedbackModal(true)
}}
>
<StyledIcon size={SPACING.spacing20} name={'thumbs-down'} />
</HoverShadow>
<HoverShadow
onClick={async () => {
await handleClickCopy()
}}
>
<StyledIcon
size={SPACING.spacing20}
name={isCopied ? 'check' : 'content-copy'}
/>
</Flex>
</PrimaryButton>
</HoverShadow>
<HoverShadow
onClick={() => {
handleFileDownload()
}}
>
<StyledIcon size={SPACING.spacing20} name={'download'} />
</HoverShadow>
</Flex>
) : null}
</Flex>
</Flex>
Expand Down
3 changes: 1 addition & 2 deletions opentrons-ai-client/src/molecules/ChatFooter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export function ChatFooter(): JSX.Element {

return (
<Flex
paddingTop={SPACING.spacing24}
gridGap={SPACING.spacing24}
flexDirection={DIRECTION_COLUMN}
paddingBottom={SPACING.spacing24}
>
<InputPrompt />
<LegacyStyledText css={DISCLAIMER_TEXT_STYLE}>
Expand All @@ -32,5 +32,4 @@ const DISCLAIMER_TEXT_STYLE = css`
font-size: ${TYPOGRAPHY.fontSize20};
line-height: ${TYPOGRAPHY.lineHeight24};
text-align: ${TYPOGRAPHY.textAlignCenter};
padding-bottom: ${SPACING.spacing24};
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { FeedbackModal } from '..'
import { renderWithProviders } from '../../../__testing-utils__'
import { screen } from '@testing-library/react'
import { describe, it, expect } from 'vitest'
import { i18n } from '../../../i18n'
import { feedbackModalAtom } from '../../../resources/atoms'

const initialValues: Array<[any, any]> = [[feedbackModalAtom, true]]

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

describe('FeedbackModal', () => {
it('should render Feedback modal', () => {
render()
screen.getByText('Send feedback to Opentrons')
screen.getByText('Share why the response was not helpful')
screen.getByText('Cancel')
screen.getByText('Send feedback')
})

// should move this test to the chat page
it.skip('should set the showFeedbackModel atom to be false when cancel button is clicked', () => {
render()
expect(feedbackModalAtom.init).toBe(true)

const cancelButton = screen.getByText('Cancel')
cancelButton.click()
// check if the feedbackModalAtom is set to false
expect(feedbackModalAtom.read).toBe(false)
})
})
Loading
Loading