diff --git a/app/src/assets/localization/en/protocol_details.json b/app/src/assets/localization/en/protocol_details.json index cc6aa6c1e41..c5cc80f2804 100644 --- a/app/src/assets/localization/en/protocol_details.json +++ b/app/src/assets/localization/en/protocol_details.json @@ -66,6 +66,7 @@ "robot_is_busy": "{{robotName}} is busy", "robot": "robot", "run_protocol": "Run protocol", + "select_parameters_for_robot": "Select parameters for {{robot_name}}", "send": "Send", "sending": "Sending", "show_in_folder": "Show in folder", diff --git a/app/src/atoms/InputField/index.tsx b/app/src/atoms/InputField/index.tsx index c791414b77d..c1ff5fbeddd 100644 --- a/app/src/atoms/InputField/index.tsx +++ b/app/src/atoms/InputField/index.tsx @@ -8,12 +8,15 @@ import { COLORS, DIRECTION_COLUMN, Flex, + Icon, RESPONSIVENESS, SPACING, StyledText, TEXT_ALIGN_RIGHT, TYPOGRAPHY, + useHoverTooltip, } from '@opentrons/components' +import { Tooltip } from '../Tooltip' export const INPUT_TYPE_NUMBER = 'number' as const export const INPUT_TYPE_TEXT = 'text' as const @@ -38,6 +41,8 @@ export interface InputFieldProps { error?: string | null /** optional title */ title?: string | null + /** optional text for tooltip */ + tooltipText?: string /** optional caption. hidden when `error` is given */ caption?: string | null /** appears to the right of the caption. Used for character limits, eg '0/45' */ @@ -93,11 +98,13 @@ function Input(props: InputFieldProps): JSX.Element { textAlign = TYPOGRAPHY.textAlignLeft, size = 'small', title, + tooltipText, ...inputProps } = props const error = props.error != null const value = props.isIndeterminate ?? false ? '' : props.value ?? '' const placeHolder = props.isIndeterminate ?? false ? '-' : props.placeholder + const [targetProps, tooltipProps] = useHoverTooltip() const OUTER_CSS = css` @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} { @@ -230,9 +237,23 @@ function Input(props: InputFieldProps): JSX.Element { return ( - {props.title != null ? ( - - {props.title} + {title != null ? ( + + + {title} + + {tooltipText != null ? ( + <> + + + + {tooltipText} + + ) : null} ) : null} diff --git a/app/src/organisms/ChooseRobotSlideout/__tests__/ChooseRobotSlideout.test.tsx b/app/src/organisms/ChooseRobotSlideout/__tests__/ChooseRobotSlideout.test.tsx index a6cda099349..586bc6fe3b9 100644 --- a/app/src/organisms/ChooseRobotSlideout/__tests__/ChooseRobotSlideout.test.tsx +++ b/app/src/organisms/ChooseRobotSlideout/__tests__/ChooseRobotSlideout.test.tsx @@ -211,7 +211,7 @@ describe('ChooseRobotSlideout', () => { screen.getByText('Step 2 / 2') }) - mockRunTimeParameters.forEach((param, index) => { + mockRunTimeParameters.forEach(param => { it('renders runtime parameter with title and caption', () => { render({ onCloseClick: vi.fn(), @@ -226,7 +226,11 @@ describe('ChooseRobotSlideout', () => { }) screen.getByText(param.displayName) - screen.getByText(param.description) + if (param.type === 'boolean' || 'choices' in param) { + screen.getByText(param.description) + } else { + screen.getByText(`${param.min}-${param.max}`) + } }) }) diff --git a/app/src/organisms/ChooseRobotSlideout/index.tsx b/app/src/organisms/ChooseRobotSlideout/index.tsx index b70ba7096bb..ef5bb8c9368 100644 --- a/app/src/organisms/ChooseRobotSlideout/index.tsx +++ b/app/src/organisms/ChooseRobotSlideout/index.tsx @@ -378,7 +378,8 @@ export function ChooseRobotSlideout( placeholder={value.toString()} value={value} title={runtimeParam.displayName} - caption={runtimeParam.description} + tooltipText={runtimeParam.description} + caption={`${runtimeParam.min}-${runtimeParam.max}`} id={id} onChange={e => { const clone = runTimeParametersOverrides.map((parameter, i) => { @@ -523,10 +524,10 @@ const ENABLED_LINK_CSS = css` const DISABLED_LINK_CSS = css` ${TYPOGRAPHY.linkPSemiBold} - color: ${COLORS.grey50}; + color: ${COLORS.grey40}; cursor: default; &:hover { - color: ${COLORS.grey50}; + color: ${COLORS.grey40}; } ` diff --git a/app/src/organisms/ChooseRobotToRunProtocolSlideout/index.tsx b/app/src/organisms/ChooseRobotToRunProtocolSlideout/index.tsx index f9baea8cf3f..56c1d9dd06e 100644 --- a/app/src/organisms/ChooseRobotToRunProtocolSlideout/index.tsx +++ b/app/src/organisms/ChooseRobotToRunProtocolSlideout/index.tsx @@ -63,7 +63,6 @@ export function ChooseRobotToRunProtocolSlideoutComponent( ) // TODO: (nd: 3/20/24) remove stubs and pull parameters from analysis - const mockRunTimeParameters: RunTimeParameter[] = [ { displayName: 'Dry Run', @@ -117,10 +116,11 @@ export function ChooseRobotToRunProtocolSlideoutComponent( default: 'none', }, ] + const runTimeParameters: RunTimeParameter[] = mockRunTimeParameters const [ runTimeParametersOverrides, setRunTimeParametersOverrides, - ] = React.useState(mockRunTimeParameters) + ] = React.useState(runTimeParameters) const offsetCandidates = useOffsetCandidatesForAnalysis( mostRecentAnalysis, @@ -231,14 +231,22 @@ export function ChooseRobotToRunProtocolSlideoutComponent( isSelectedRobotOnDifferentSoftwareVersion } onCloseClick={onCloseClick} - title={t('choose_robot_to_run', { - protocol_name: protocolDisplayName, - })} + title={ + enableRunTimeParametersFF && + runTimeParameters.length > 0 && + currentPage === 2 + ? t('select_parameters_for_robot', { + robot_name: selectedRobot?.name, + }) + : t('choose_robot_to_run', { + protocol_name: protocolDisplayName, + }) + } runTimeParametersOverrides={runTimeParametersOverrides} setRunTimeParametersOverrides={setRunTimeParametersOverrides} footer={ - {enableRunTimeParametersFF ? ( + {enableRunTimeParametersFF && runTimeParameters.length > 0 ? ( currentPage === 1 ? ( <>