diff --git a/app/src/organisms/Devices/ProtocolRun/ProtocolRunRunTimeParameters.tsx b/app/src/organisms/Devices/ProtocolRun/ProtocolRunRunTimeParameters.tsx index 7a6b07f9ae5..0b3ccb5c141 100644 --- a/app/src/organisms/Devices/ProtocolRun/ProtocolRunRunTimeParameters.tsx +++ b/app/src/organisms/Devices/ProtocolRun/ProtocolRunRunTimeParameters.tsx @@ -2,6 +2,7 @@ import * as React from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' +import { formatRunTimeParameterValue } from '@opentrons/shared-data' import { ALIGN_CENTER, BORDERS, @@ -12,14 +13,13 @@ import { SPACING, StyledText, TYPOGRAPHY, + NoParameters, } from '@opentrons/components' import { Banner } from '../../../atoms/Banner' import { Divider } from '../../../atoms/structure' // import { Chip } from '../../../atoms/Chip' -import { NoParameter } from '../../ProtocolDetails/ProtocolParameters/NoParameter' import { useMostRecentCompletedAnalysis } from '../../LabwarePositionCheck/useMostRecentCompletedAnalysis' -import { formatRunTimeParameterValue } from '../../ProtocolDetails/ProtocolParameters/utils' import type { RunTimeParameter } from '@opentrons/shared-data' @@ -221,7 +221,7 @@ export function ProtocolRunRuntimeParameters({ {!hasParameter ? ( - + ) : ( <> diff --git a/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunRuntimeParameters.test.tsx b/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunRuntimeParameters.test.tsx index 368c666d33f..8844f551d08 100644 --- a/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunRuntimeParameters.test.tsx +++ b/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunRuntimeParameters.test.tsx @@ -3,9 +3,9 @@ import { describe, it, vi, beforeEach, afterEach, expect } from 'vitest' import { screen } from '@testing-library/react' import { when } from 'vitest-when' +import { NoParameters } from '@opentrons/components' import { renderWithProviders } from '../../../../__testing-utils__' import { i18n } from '../../../../i18n' -import { NoParameter } from '../../../ProtocolDetails/ProtocolParameters/NoParameter' import { useMostRecentCompletedAnalysis } from '../../../LabwarePositionCheck/useMostRecentCompletedAnalysis' import { ProtocolRunRuntimeParameters } from '../ProtocolRunRunTimeParameters' @@ -15,7 +15,13 @@ import type { RunTimeParameter, } from '@opentrons/shared-data' -vi.mock('../../../ProtocolDetails/ProtocolParameters/NoParameter') +vi.mock('@opentrons/components', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + NoParameters: vi.fn(), + } +}) vi.mock('../../../LabwarePositionCheck/useMostRecentCompletedAnalysis') const RUN_ID = 'mockId' @@ -88,7 +94,7 @@ describe('ProtocolRunRuntimeParameters', () => { props = { runId: RUN_ID, } - vi.mocked(NoParameter).mockReturnValue(
mock NoParameter
) + vi.mocked(NoParameters).mockReturnValue(
mock NoParameter
) when(vi.mocked(useMostRecentCompletedAnalysis)) .calledWith(RUN_ID) .thenReturn({ diff --git a/app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/ProtocolParameters.test.tsx b/app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/ProtocolParameters.test.tsx index 5e3574200b6..707aa5256cf 100644 --- a/app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/ProtocolParameters.test.tsx +++ b/app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/ProtocolParameters.test.tsx @@ -4,13 +4,10 @@ import { screen } from '@testing-library/react' import { renderWithProviders } from '../../../../__testing-utils__' import { i18n } from '../../../../i18n' -import { NoParameter } from '../NoParameter' import { ProtocolParameters } from '..' import type { RunTimeParameter } from '@opentrons/shared-data' -vi.mock('../NoParameter') - const mockRunTimeParameter: RunTimeParameter[] = [ { displayName: 'Trash Tips', @@ -87,7 +84,6 @@ describe('ProtocolParameters', () => { props = { runTimeParameters: mockRunTimeParameter, } - vi.mocked(NoParameter).mockReturnValue(
mock NoParameter
) }) afterEach(() => { @@ -131,6 +127,6 @@ describe('ProtocolParameters', () => { runTimeParameters: [], } render(props) - screen.getByText('mock NoParameter') + screen.getByText('No parameters specified in this protocol') }) }) diff --git a/app/src/organisms/ProtocolDetails/ProtocolParameters/index.tsx b/app/src/organisms/ProtocolDetails/ProtocolParameters/index.tsx index 00dc73793d4..d7a64fd2396 100644 --- a/app/src/organisms/ProtocolDetails/ProtocolParameters/index.tsx +++ b/app/src/organisms/ProtocolDetails/ProtocolParameters/index.tsx @@ -1,18 +1,16 @@ import * as React from 'react' import { useTranslation } from 'react-i18next' -import styled from 'styled-components' import { - BORDERS, DIRECTION_COLUMN, Flex, SPACING, StyledText, TYPOGRAPHY, + ParametersTable, + NoParameters, } from '@opentrons/components' import { Banner } from '../../../atoms/Banner' -import { NoParameter } from './NoParameter' -import { formatRunTimeParameterValue } from './utils' import type { RunTimeParameter } from '@opentrons/shared-data' @@ -47,112 +45,11 @@ export function ProtocolParameters({ - + ) : ( - + )} ) } - -interface ProtocolParameterItemsProps { - runTimeParameters: RunTimeParameter[] -} - -function ProtocolParameterItems({ - runTimeParameters, -}: ProtocolParameterItemsProps): JSX.Element { - const { t } = useTranslation('protocol_details') - const formatRange = ( - runTimeParameter: RunTimeParameter, - minMax: string - ): string => { - const { type } = runTimeParameter - const choices = - 'choices' in runTimeParameter ? runTimeParameter.choices : [] - const count = choices.length - - switch (type) { - case 'int': - case 'float': - return minMax - case 'boolean': - return t('on_off') - case 'str': - if (count > 2) { - return t('choices', { count }) - } else { - return choices.map(choice => choice.displayName).join(', ') - } - } - return '' - } - - return ( - - - {t('name')} - {t('default_value')} - {t('range')} - - - {runTimeParameters.map((parameter: RunTimeParameter, index: number) => { - const min = 'min' in parameter ? parameter.min : 0 - const max = 'max' in parameter ? parameter.max : 0 - return ( - - - {parameter.displayName} - - - - {formatRunTimeParameterValue(parameter, t)} - - - - - {formatRange(parameter, `${min}-${max}`)} - - - - ) - })} - - - ) -} - -const StyledTable = styled.table` - width: 100%; - border-collapse: collapse; - text-align: left; -` - -const StyledTableHeader = styled.th` - ${TYPOGRAPHY.labelSemiBold} - padding: ${SPACING.spacing8}; - border-bottom: ${BORDERS.lineBorder}; -` - -interface StyledTableRowProps { - isLast: boolean -} - -const StyledTableRow = styled.tr` - padding: ${SPACING.spacing8}; - border-bottom: ${props => (props.isLast ? 'none' : BORDERS.lineBorder)}; -` - -interface StyledTableCellProps { - isLast: boolean -} - -const StyledTableCell = styled.td` - padding-left: ${SPACING.spacing8}; - padding-top: ${SPACING.spacing12}; - padding-bottom: ${props => (props.isLast ? 0 : SPACING.spacing12)}; -` diff --git a/app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx b/app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx index 9fac5f99c56..8eea44ba0cd 100644 --- a/app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx +++ b/app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import { useTranslation } from 'react-i18next' +import { formatRunTimeParameterValue } from '@opentrons/shared-data' import { ALIGN_CENTER, BORDERS, @@ -16,7 +17,6 @@ import { ChildNavigation } from '../ChildNavigation' import { Chip } from '../../atoms/Chip' import { useToaster } from '../ToasterOven' import { mockData } from './index' -import { formatRunTimeParameterValue } from '../ProtocolDetails/ProtocolParameters/utils' import type { SetupScreens } from '../../pages/ProtocolSetup' diff --git a/app/src/organisms/ProtocolSetupParameters/index.tsx b/app/src/organisms/ProtocolSetupParameters/index.tsx index d92e54a6234..c99c4ebeff6 100644 --- a/app/src/organisms/ProtocolSetupParameters/index.tsx +++ b/app/src/organisms/ProtocolSetupParameters/index.tsx @@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next' import { useHistory } from 'react-router-dom' import { useCreateRunMutation, useHost } from '@opentrons/react-api-client' import { useQueryClient } from 'react-query' +import { formatRunTimeParameterValue } from '@opentrons/shared-data' import { ALIGN_CENTER, DIRECTION_COLUMN, @@ -13,7 +14,6 @@ import { import { ProtocolSetupStep } from '../../pages/ProtocolSetup' import { ChildNavigation } from '../ChildNavigation' import { ResetValuesModal } from './ResetValuesModal' -import { formatRunTimeParameterValue } from '../ProtocolDetails/ProtocolParameters/utils' import type { RunTimeParameter } from '@opentrons/shared-data' import type { LabwareOffsetCreateData } from '@opentrons/api-client' diff --git a/app/src/pages/ProtocolDetails/Parameters.tsx b/app/src/pages/ProtocolDetails/Parameters.tsx index f2304893374..0e12e8d7997 100644 --- a/app/src/pages/ProtocolDetails/Parameters.tsx +++ b/app/src/pages/ProtocolDetails/Parameters.tsx @@ -1,6 +1,7 @@ import * as React from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' +import { formatRunTimeParameterValue } from '@opentrons/shared-data' import { BORDERS, COLORS, @@ -13,7 +14,6 @@ import { import { useToaster } from '../../organisms/ToasterOven' import { useRunTimeParameters } from '../Protocols/hooks' import { EmptySection } from './EmptySection' -import { formatRunTimeParameterValue } from '../../organisms/ProtocolDetails/ProtocolParameters/utils' import type { RunTimeParameter } from '@opentrons/shared-data' const Table = styled('table')` diff --git a/app/src/organisms/ProtocolDetails/ProtocolParameters/NoParameter.tsx b/components/src/molecules/ParametersTable/NoParameters.tsx similarity index 52% rename from app/src/organisms/ProtocolDetails/ProtocolParameters/NoParameter.tsx rename to components/src/molecules/ParametersTable/NoParameters.tsx index 2dd3f2d1441..b0afb82530f 100644 --- a/app/src/organisms/ProtocolDetails/ProtocolParameters/NoParameter.tsx +++ b/components/src/molecules/ParametersTable/NoParameters.tsx @@ -1,21 +1,16 @@ import * as React from 'react' -import { useTranslation } from 'react-i18next' -import { - ALIGN_CENTER, - BORDERS, - COLORS, - DIRECTION_COLUMN, - Flex, - Icon, - SPACING, - StyledText, - TYPOGRAPHY, -} from '@opentrons/components' - -export function NoParameter(): JSX.Element { - const { t } = useTranslation('protocol_details') +import { BORDERS, COLORS } from '../../helix-design-system' +import { SPACING, TYPOGRAPHY } from '../../ui-style-constants/index' +import { StyledText } from '../../atoms/StyledText' +import { Icon } from '../../icons' +import { Flex } from '../../primitives' +import { ALIGN_CENTER, DIRECTION_COLUMN } from '../../styles' +interface NoParametersProps { + t?: any +} +export function NoParameters({ t }: NoParametersProps): JSX.Element { return ( - {t('no_parameters')} + {t != null + ? t('no_parameters') + : 'No parameters specified in this protocol'} ) diff --git a/components/src/molecules/ParametersTable/ParametersTable.stories.tsx b/components/src/molecules/ParametersTable/ParametersTable.stories.tsx new file mode 100644 index 00000000000..ce55f700dc3 --- /dev/null +++ b/components/src/molecules/ParametersTable/ParametersTable.stories.tsx @@ -0,0 +1,159 @@ +import * as React from 'react' +import { ParametersTable } from '@opentrons/components' +import type { Story, Meta } from '@storybook/react' +import type { RunTimeParameter } from '@opentrons/shared-data' + +export default { + title: 'Library/Molecules/ParametersTable', +} as Meta + +const Template: Story> = args => ( + +) + +const runTimeParameters: RunTimeParameter[] = [ + { + value: false, + displayName: 'Dry Run', + variableName: 'DRYRUN', + description: 'Is this a dry or wet run? Wet is true, dry is false', + type: 'boolean', + default: false, + }, + { + value: true, + displayName: 'Use Gripper', + variableName: 'USE_GRIPPER', + description: 'For using the gripper.', + type: 'boolean', + default: true, + }, + { + value: true, + displayName: 'Trash Tips', + variableName: 'TIP_TRASH', + description: + 'to throw tip into the trash or to not throw tip into the trash', + type: 'boolean', + default: true, + }, + { + value: true, + displayName: 'Deactivate Temperatures', + variableName: 'DEACTIVATE_TEMP', + description: 'deactivate temperature on the module', + type: 'boolean', + default: true, + }, + { + value: 4, + displayName: 'Columns of Samples', + variableName: 'COLUMNS', + description: 'How many columns do you want?', + type: 'int', + min: 1, + max: 14, + default: 4, + }, + { + value: 6, + displayName: 'PCR Cycles', + variableName: 'PCR_CYCLES', + description: 'number of PCR cycles on a thermocycler', + type: 'int', + min: 1, + max: 10, + default: 6, + }, + { + value: 6.5, + displayName: 'EtoH Volume', + variableName: 'ETOH_VOLUME', + description: '70% ethanol volume', + type: 'float', + suffix: 'mL', + min: 1.5, + max: 10.0, + default: 6.5, + }, + { + value: 'none', + displayName: 'Default Module Offsets', + variableName: 'DEFAULT_OFFSETS', + description: 'default module offsets for temp, H-S, and none', + type: 'str', + choices: [ + { + displayName: 'No offsets', + value: 'none', + }, + { + displayName: 'temp offset', + value: '1', + }, + { + displayName: 'heater-shaker offset', + value: '2', + }, + ], + default: 'none', + }, + { + value: 'left', + displayName: 'pipette mount', + variableName: 'mont', + description: 'pipette mount', + type: 'str', + choices: [ + { + displayName: 'Left', + value: 'left', + }, + { + displayName: 'Right', + value: 'right', + }, + ], + default: 'left', + }, + { + value: 'flex', + displayName: 'short test case', + variableName: 'short 2 options', + description: 'this play 2 short options', + type: 'str', + choices: [ + { + displayName: 'OT-2', + value: 'ot2', + }, + { + displayName: 'Flex', + value: 'flex', + }, + ], + default: 'flex', + }, + { + value: 'flex', + displayName: 'long test case', + variableName: 'long 2 options', + description: 'this play 2 long options', + type: 'str', + choices: [ + { + displayName: 'I am kind of long text version', + value: 'ot2', + }, + { + displayName: 'I am kind of long text version. Today is 3/15', + value: 'flex', + }, + ], + default: 'flex', + }, +] +export const Default = Template.bind({}) +Default.args = { + runTimeParameters: runTimeParameters, +} diff --git a/app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/NoParameter.test.tsx b/components/src/molecules/ParametersTable/__tests__/NoParameters.test.tsx similarity index 55% rename from app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/NoParameter.test.tsx rename to components/src/molecules/ParametersTable/__tests__/NoParameters.test.tsx index 40cfb8f48de..5b2e7f2927d 100644 --- a/app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/NoParameter.test.tsx +++ b/components/src/molecules/ParametersTable/__tests__/NoParameters.test.tsx @@ -2,28 +2,25 @@ import * as React from 'react' import { screen } from '@testing-library/react' import { describe, it, expect } from 'vitest' -import { BORDERS, COLORS } from '@opentrons/components' +import { renderWithProviders } from '../../../testing/utils' +import { BORDERS, COLORS } from '../../../helix-design-system' +import { NoParameters } from '../NoParameters' -import { renderWithProviders } from '../../../../__testing-utils__' -import { i18n } from '../../../../i18n' - -import { NoParameter } from '../NoParameter' - -const render = () => { - return renderWithProviders(, { - i18nInstance: i18n, - }) +const render = (props: React.ComponentProps) => { + return renderWithProviders() } -describe('NoParameter', () => { +const tMock = (key: string) => key + +describe('NoParameters', () => { it('should render text and icon with proper color', () => { - render() + render({}) screen.getByLabelText('alert') screen.getByText('No parameters specified in this protocol') }) it('should have proper styles', () => { - render() + render({}) expect(screen.getByTestId('NoRunTimeParameter')).toHaveStyle( `background-color: ${COLORS.grey30}` ) @@ -34,4 +31,11 @@ describe('NoParameter', () => { `color: ${COLORS.grey60}` ) }) + + it('should render the raw i18n value if a t is provided', () => { + render({ + t: tMock, + }) + screen.getByText('no_parameters') + }) }) diff --git a/components/src/molecules/ParametersTable/__tests__/ParametersTable.test.tsx b/components/src/molecules/ParametersTable/__tests__/ParametersTable.test.tsx new file mode 100644 index 00000000000..1c9cd2d571c --- /dev/null +++ b/components/src/molecules/ParametersTable/__tests__/ParametersTable.test.tsx @@ -0,0 +1,119 @@ +import * as React from 'react' +import { renderWithProviders } from '../../../testing/utils' +import { describe, it, beforeEach } from 'vitest' +import { screen } from '@testing-library/react' +import { ParametersTable } from '../index' + +import type { RunTimeParameter } from '@opentrons/shared-data' + +const tMock = (key: string) => key +const mockRunTimeParameter: RunTimeParameter[] = [ + { + displayName: 'Trash Tips', + variableName: 'TIP_TRASH', + description: + 'to throw tip into the trash or to not throw tip into the trash', + type: 'boolean', + default: true, + value: true, + }, + { + displayName: 'EtoH Volume', + variableName: 'ETOH_VOLUME', + description: '70% ethanol volume', + type: 'float', + suffix: 'mL', + min: 1.5, + max: 10.0, + default: 6.5, + value: 6.5, + }, + { + displayName: 'Default Module Offsets', + variableName: 'DEFAULT_OFFSETS', + description: 'default module offsets for temp, H-S, and none', + type: 'str', + value: 'none', + choices: [ + { + displayName: 'No offsets', + value: 'none', + }, + { + displayName: 'temp offset', + value: '1', + }, + { + displayName: 'heater-shaker offset', + value: '2', + }, + ], + default: 'none', + }, + { + displayName: 'pipette mount', + variableName: 'mont', + description: 'pipette mount', + type: 'str', + value: 'left', + choices: [ + { + displayName: 'Left', + value: 'left', + }, + { + displayName: 'Right', + value: 'right', + }, + ], + default: 'left', + }, +] + +const render = (props: React.ComponentProps) => { + return renderWithProviders() +} + +describe('ParametersTabl', () => { + let props: React.ComponentProps + + beforeEach(() => { + props = { + runTimeParameters: mockRunTimeParameter, + } + }) + + it('should render table header', () => { + render(props) + screen.getByText('Name') + screen.getByText('Default Value') + screen.getByText('Range') + }) + + it('should render parameters default information', () => { + render(props) + screen.getByText('Trash Tips') + screen.getByText('On') + screen.getByText('On, off') + + screen.getByText('EtoH Volume') + screen.getByText('6.5 mL') + screen.getByText('1.5-10') + + screen.getByText('Default Module Offsets') + screen.getByText('No offsets') + screen.getByText('3 choices') + + screen.getByText('pipette mount') + screen.getByText('Left') + screen.getByText('Left, Right') + }) + + it('should render the raw i18n values if a t prop is provided', () => { + props.t = tMock + render(props) + screen.getByText('name') + screen.getByText('default_value') + screen.getByText('range') + }) +}) diff --git a/components/src/molecules/ParametersTable/index.tsx b/components/src/molecules/ParametersTable/index.tsx new file mode 100644 index 00000000000..4ff5cdeeb18 --- /dev/null +++ b/components/src/molecules/ParametersTable/index.tsx @@ -0,0 +1,117 @@ +import * as React from 'react' +import styled from 'styled-components' +import { formatRunTimeParameterValue } from '@opentrons/shared-data' +import { BORDERS } from '../../helix-design-system' +import { SPACING, TYPOGRAPHY } from '../../ui-style-constants/index' +import { StyledText } from '../../atoms/StyledText' + +import type { RunTimeParameter } from '@opentrons/shared-data' + +interface ProtocolParameterItemsProps { + runTimeParameters: RunTimeParameter[] + t?: any +} + +/** used in both the desktop app and Protocol Library + * to display the run time parameters table + */ +export function ParametersTable({ + runTimeParameters, + t, +}: ProtocolParameterItemsProps): JSX.Element { + const formatRange = ( + runTimeParameter: RunTimeParameter, + minMax: string + ): string => { + const { type } = runTimeParameter + const choices = + 'choices' in runTimeParameter ? runTimeParameter.choices : [] + const count = choices.length + + switch (type) { + case 'int': + case 'float': + return minMax + case 'boolean': + return t != null ? t('on_off') : 'On, off' + case 'str': + if (count > 2) { + return t != null ? t('choices', { count }) : `${count} choices` + } else { + return choices.map(choice => choice.displayName).join(', ') + } + } + return '' + } + + return ( + + + {t != null ? t('name') : 'Name'} + + {t != null ? t('default_value') : 'Default Value'} + + + {t != null ? t('range') : 'Range'} + + + + {runTimeParameters.map((parameter: RunTimeParameter, index: number) => { + const min = 'min' in parameter ? parameter.min : 0 + const max = 'max' in parameter ? parameter.max : 0 + return ( + + + {parameter.displayName} + + + + {formatRunTimeParameterValue(parameter, t)} + + + + + {formatRange(parameter, `${min}-${max}`)} + + + + ) + })} + + + ) +} + +const StyledTable = styled.table` + width: 100%; + border-collapse: collapse; + text-align: left; +` + +const StyledTableHeader = styled.th` + ${TYPOGRAPHY.labelSemiBold} + padding: ${SPACING.spacing8}; + border-bottom: ${BORDERS.lineBorder}; +` + +interface StyledTableRowProps { + isLast: boolean +} + +const StyledTableRow = styled.tr` + padding: ${SPACING.spacing8}; + border-bottom: ${props => (props.isLast ? 'none' : BORDERS.lineBorder)}; +` + +interface StyledTableCellProps { + isLast: boolean +} + +const StyledTableCell = styled.td` + padding-left: ${SPACING.spacing8}; + padding-top: ${SPACING.spacing12}; + padding-bottom: ${props => (props.isLast ? 0 : SPACING.spacing12)}; +` diff --git a/components/src/molecules/index.tsx b/components/src/molecules/index.tsx index ce1c0c63e31..3231c2f93a9 100644 --- a/components/src/molecules/index.tsx +++ b/components/src/molecules/index.tsx @@ -1,2 +1,4 @@ export * from './LocationIcon' export * from './RoundTab' +export * from './ParametersTable' +export * from './ParametersTable/NoParameters' diff --git a/app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/utils.test.ts b/shared-data/js/helpers/__tests__/formatRunTimeParameterValue.test.ts similarity index 88% rename from app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/utils.test.ts rename to shared-data/js/helpers/__tests__/formatRunTimeParameterValue.test.ts index 66eddcc0efd..bfdad493913 100644 --- a/app/src/organisms/ProtocolDetails/ProtocolParameters/__tests__/utils.test.ts +++ b/shared-data/js/helpers/__tests__/formatRunTimeParameterValue.test.ts @@ -1,8 +1,7 @@ -import { useTranslation } from 'react-i18next' import { describe, it, expect, vi } from 'vitest' -import { formatRunTimeParameterValue } from '../utils' +import { formatRunTimeParameterValue } from '../formatRunTimeParameterValue' -import type { RunTimeParameter } from '@opentrons/shared-data' +import type { RunTimeParameter } from '../../types' const capitalizeFirstLetter = (str: string): string => { return str.charAt(0).toUpperCase() + str.slice(1) @@ -10,14 +9,6 @@ const capitalizeFirstLetter = (str: string): string => { const mockTFunction = vi.fn(str => capitalizeFirstLetter(str)) -vi.mock('react-i18next', async importOriginal => { - const actual = await importOriginal() - return { - ...actual, - t: mockTFunction, - } -}) - describe('utils-formatRunTimeParameterValue', () => { it('should return value with suffix when type is int', () => { const mockData = { diff --git a/app/src/organisms/ProtocolDetails/ProtocolParameters/utils.ts b/shared-data/js/helpers/formatRunTimeParameterValue.ts similarity index 79% rename from app/src/organisms/ProtocolDetails/ProtocolParameters/utils.ts rename to shared-data/js/helpers/formatRunTimeParameterValue.ts index b21b3eaf3c7..ffbab087849 100644 --- a/app/src/organisms/ProtocolDetails/ProtocolParameters/utils.ts +++ b/shared-data/js/helpers/formatRunTimeParameterValue.ts @@ -1,9 +1,8 @@ -import { useTranslation } from 'react-i18next' -import type { RunTimeParameter } from '@opentrons/shared-data' +import { RunTimeParameter } from '../types' export const formatRunTimeParameterValue = ( runTimeParameter: RunTimeParameter, - t: ReturnType['t'] + t?: any ): string => { const { type, default: defaultValue } = runTimeParameter const suffix = @@ -17,7 +16,11 @@ export const formatRunTimeParameterValue = ( ? `${defaultValue.toString()} ${suffix}` : defaultValue.toString() case 'boolean': - return Boolean(defaultValue) ? t('on') : t('off') + if (t != null) { + return Boolean(defaultValue) ? t('on') : t('off') + } else { + return Boolean(defaultValue) ? 'On' : 'Off' + } case 'str': if ('choices' in runTimeParameter && runTimeParameter.choices != null) { const choice = runTimeParameter.choices.find( diff --git a/shared-data/js/helpers/index.ts b/shared-data/js/helpers/index.ts index 5cddd22336e..2d78f16ca1f 100644 --- a/shared-data/js/helpers/index.ts +++ b/shared-data/js/helpers/index.ts @@ -28,6 +28,7 @@ export * from './getOccludedSlotCountForModule' export * from './labwareInference' export * from './getAddressableAreasInProtocol' export * from './getSimplestFlexDeckConfig' +export * from './formatRunTimeParameterValue' export const getLabwareDefIsStandard = (def: LabwareDefinition2): boolean => def?.namespace === OPENTRONS_LABWARE_NAMESPACE