diff --git a/opentrons-ai-client/src/assets/localization/en/protocol_generator.json b/opentrons-ai-client/src/assets/localization/en/protocol_generator.json index 04509609800..739611e853e 100644 --- a/opentrons-ai-client/src/assets/localization/en/protocol_generator.json +++ b/opentrons-ai-client/src/assets/localization/en/protocol_generator.json @@ -2,6 +2,7 @@ "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 and giving exact source and destination locations.", + "copy_code": "Copy code", "disclaimer": "OpentronsAI can make mistakes. Review your protocol before running it on an Opentrons robot.", "got_feedback": "Got feedback? We love to hear it.", "make_sure_your_prompt": "Make sure your prompt includes the following:", diff --git a/opentrons-ai-client/src/molecules/ChatDisplay/index.tsx b/opentrons-ai-client/src/molecules/ChatDisplay/index.tsx index 3b5c54ebbc6..a8b844af08c 100644 --- a/opentrons-ai-client/src/molecules/ChatDisplay/index.tsx +++ b/opentrons-ai-client/src/molecules/ChatDisplay/index.tsx @@ -1,12 +1,18 @@ import React from 'react' -// import { css } from 'styled-components' +import styled from 'styled-components' import { useTranslation } from 'react-i18next' import Markdown from 'react-markdown' import { + ALIGN_CENTER, BORDERS, COLORS, DIRECTION_COLUMN, Flex, + Icon, + JUSTIFY_CENTER, + POSITION_ABSOLUTE, + POSITION_RELATIVE, + PrimaryButton, SPACING, StyledText, } from '@opentrons/components' @@ -15,12 +21,26 @@ import type { ChatData } from '../../resources/types' interface ChatDisplayProps { chat: ChatData + chatId: string } -export function ChatDisplay({ chat }: ChatDisplayProps): JSX.Element { +export function ChatDisplay({ chat, chatId }: ChatDisplayProps): JSX.Element { const { t } = useTranslation('protocol_generator') + const [isCopied, setIsCopied] = React.useState(false) const { role, content } = chat const isUser = role === 'user' + + const handleClickCopy = async (): Promise => { + const lastCodeBlock = document.querySelector(`#${chatId}`) + const code = lastCodeBlock?.textContent ?? '' + await navigator.clipboard.writeText(code) + setIsCopied(true) + } + + function CodeText(props: JSX.IntrinsicAttributes): JSX.Element { + return + } + return ( - {/* ToDo (kk:05/02/2024) This part is waiting for Mel's design */} - {/* {content} - */} - {content} + + {role === 'assistant' ? ( + + + + + + ) : null} ) } -// ToDo (kk:05/02/2024) This part is waiting for Mel's design -// function ExternalLink(props: JSX.IntrinsicAttributes): JSX.Element { -// return -// } - -// function ParagraphText(props: JSX.IntrinsicAttributes): JSX.Element { -// return -// } +// Note (05/08/2024) the following styles are temp +function ExternalLink(props: JSX.IntrinsicAttributes): JSX.Element { + return +} -// function HeaderText(props: JSX.IntrinsicAttributes): JSX.Element { -// return -// } +function ParagraphText(props: JSX.IntrinsicAttributes): JSX.Element { + return +} -// function ListItemText(props: JSX.IntrinsicAttributes): JSX.Element { -// return -// } +function HeaderText(props: JSX.IntrinsicAttributes): JSX.Element { + return +} -// function UnnumberedListText(props: JSX.IntrinsicAttributes): JSX.Element { -// return -// } +function ListItemText(props: JSX.IntrinsicAttributes): JSX.Element { + return +} -// const CODE_TEXT_STYLE = css` -// padding: ${SPACING.spacing16}; -// font-family: monospace; -// color: ${COLORS.white}; -// background-color: ${COLORS.black90}; -// ` +function UnnumberedListText(props: JSX.IntrinsicAttributes): JSX.Element { + return +} -// function CodeText(props: JSX.IntrinsicAttributes): JSX.Element { -// return -// } +const CodeWrapper = styled(Flex)` + font-family: monospace; + padding: ${SPACING.spacing16}; + color: ${COLORS.white}; + background-color: ${COLORS.black90}; + border-radius: ${BORDERS.borderRadius8}; + overflow: auto; +` diff --git a/opentrons-ai-client/src/molecules/PrimaryFloatingButton/index.tsx b/opentrons-ai-client/src/molecules/PrimaryFloatingButton/index.tsx index 0044355931f..056e4aee2b4 100644 --- a/opentrons-ai-client/src/molecules/PrimaryFloatingButton/index.tsx +++ b/opentrons-ai-client/src/molecules/PrimaryFloatingButton/index.tsx @@ -14,9 +14,9 @@ import { TYPOGRAPHY, } from '@opentrons/components' -import type { IconName } from '@opentrons/components/src/icons' +import type { IconName, StyleProps } from '@opentrons/components' -interface PrimaryFloatingButtonProps { +interface PrimaryFloatingButtonProps extends StyleProps { buttonText: string iconName: IconName disabled?: boolean @@ -26,9 +26,10 @@ export function PrimaryFloatingButton({ buttonText, iconName, disabled = false, + ...buttonProps }: PrimaryFloatingButtonProps): JSX.Element { return ( - + 0 ? chatData.map((chat, index) => ( )) : null} diff --git a/package.json b/package.json index edfb1e0c4ef..4066440cbcc 100755 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "discovery-client", "labware-designer", "labware-library", + "opentrons-ai-client", "protocol-designer", "shared-data", "step-generation", @@ -110,7 +111,6 @@ "handlebars-loader": "^1.7.1", "html-webpack-plugin": "^3.2.0", "identity-obj-proxy": "^3.0.0", - "jotai": "2.8.0", "jsdom": "^16.4.0", "lost": "^8.3.1", "madge": "^3.6.0",