Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(app): create utils to format value for rtp (#14720)
Browse files Browse the repository at this point in the history
* refactor(app): create utils to format value for rtp
koji authored and Carlos-fernandez committed May 20, 2024
1 parent 1ba6166 commit 7c39473
Showing 8 changed files with 151 additions and 142 deletions.
4 changes: 2 additions & 2 deletions app/src/assets/localization/en/protocol_setup.json
Original file line number Diff line number Diff line change
@@ -175,15 +175,15 @@
"not_calibrated": "Not calibrated yet",
"not_configured": "not configured",
"off_deck": "Off deck",
"off": "off",
"off": "Off",
"offset_data": "Offset Data",
"offsets_applied_plural": "{{count}} offsets applied",
"offsets_applied": "{{count}} offset applied",
"on_adapter_in_mod": "on {{adapterName}} in {{moduleName}}",
"on_adapter": "on {{adapterName}}",
"on_deck": "On deck",
"on-deck_labware": "{{count}} on-deck labware",
"on": "on",
"on": "On",
"opening": "Opening...",
"parameters": "Parameters",
"pipette_mismatch": "Pipette generation mismatch.",
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ 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'

@@ -171,40 +172,12 @@ interface ProtocolRunRuntimeParametersProps {
export function ProtocolRunRuntimeParameters({
runId,
}: ProtocolRunRuntimeParametersProps): JSX.Element {
const { i18n, t } = useTranslation('protocol_setup')
const { t } = useTranslation('protocol_setup')
const mostRecentAnalysis = useMostRecentCompletedAnalysis(runId)
// ToDo (kk:03/18/2024) mockData will be replaced with []
const runTimeParameters = mostRecentAnalysis?.runTimeParameters ?? mockData
const hasParameter = runTimeParameters.length > 0

const formattedValue = (runTimeParameter: RunTimeParameter): string => {
const { type, default: defaultValue } = runTimeParameter
const suffix =
'suffix' in runTimeParameter && runTimeParameter.suffix != null
? runTimeParameter.suffix
: ''
switch (type) {
case 'int':
case 'float':
return `${defaultValue.toString()} ${suffix}`
case 'boolean':
return Boolean(defaultValue)
? i18n.format(t('on'), 'capitalize')
: i18n.format(t('off'), 'capitalize')
case 'str':
if ('choices' in runTimeParameter && runTimeParameter.choices != null) {
const choice = runTimeParameter.choices.find(
choice => choice.value === defaultValue
)
if (choice != null) {
return choice.displayName
}
}
break
}
return ''
}

// ToDo (kk:03/19/2024) this will be replaced with the boolean from values check result
const dummyBoolean = true

@@ -282,7 +255,7 @@ export function ProtocolRunRuntimeParameters({
gridGap={SPACING.spacing16}
>
<StyledText as="p">
{formattedValue(parameter)}
{formatRunTimeParameterValue(parameter, t)}
</StyledText>
{/* ToDo (kk:03/19/2024) chip will be here with conditional render */}
{/* {index % 2 === 0 ? (
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { useTranslation } from 'react-i18next'
import { describe, it, expect, vi } from 'vitest'
import { formatRunTimeParameterValue } from '../utils'

import type { RunTimeParameter } from '@opentrons/shared-data'

const capitalizeFirstLetter = (str: string): string => {
return str.charAt(0).toUpperCase() + str.slice(1)
}

const mockTFunction = vi.fn(str => capitalizeFirstLetter(str))

vi.mock('react-i18next', async importOriginal => {
const actual = await importOriginal<typeof useTranslation>()
return {
...actual,
t: mockTFunction,
}
})

describe('utils-formatRunTimeParameterValue', () => {
it('should return value with suffix when type is int', () => {
const mockData = {
value: 6,
displayName: 'PCR Cycles',
variableName: 'PCR_CYCLES',
description: 'number of PCR cycles on a thermocycler',
type: 'int',
min: 1,
max: 10,
default: 6,
} as RunTimeParameter
const result = formatRunTimeParameterValue(mockData, mockTFunction)
expect(result).toEqual('6')
})

it('should return value with suffix when type is float', () => {
const mockData = {
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,
} as RunTimeParameter
const result = formatRunTimeParameterValue(mockData, mockTFunction)
expect(result).toEqual('6.5 mL')
})

it('should return value with suffix when type is str', () => {
const mockData = {
value: 'left',
displayName: 'pipette mount',
variableName: 'mont',
description: 'pipette mount',
type: 'str',
choices: [
{
displayName: 'Left',
value: 'left',
},
{
displayName: 'Right',
value: 'right',
},
],
default: 'left',
} as RunTimeParameter
const result = formatRunTimeParameterValue(mockData, mockTFunction)
expect(result).toEqual('Left')
})

it('should return value with suffix when type is boolean true', () => {
const mockData = {
value: true,
displayName: 'Deactivate Temperatures',
variableName: 'DEACTIVATE_TEMP',
description: 'deactivate temperature on the module',
type: 'boolean',
default: true,
} as RunTimeParameter
const result = formatRunTimeParameterValue(mockData, mockTFunction)
expect(result).toEqual('On')
})

it('should return value with suffix when type is boolean false', () => {
const mockData = {
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,
} as RunTimeParameter
const result = formatRunTimeParameterValue(mockData, mockTFunction)
expect(result).toEqual('Off')
})
})
32 changes: 4 additions & 28 deletions app/src/organisms/ProtocolDetails/ProtocolParameters/index.tsx
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ import {
import { StyledText } from '../../../atoms/text'
import { Banner } from '../../../atoms/Banner'
import { NoParameter } from './NoParameter'
import { formatRunTimeParameterValue } from './utils'

import type { RunTimeParameter } from '@opentrons/shared-data'

@@ -63,33 +64,6 @@ function ProtocolParameterItems({
runTimeParameters,
}: ProtocolParameterItemsProps): JSX.Element {
const { t } = useTranslation('protocol_details')

const formattedValue = (runTimeParameter: RunTimeParameter): string => {
const { type, default: defaultValue } = runTimeParameter
const suffix =
'suffix' in runTimeParameter && runTimeParameter.suffix != null
? runTimeParameter.suffix
: ''
switch (type) {
case 'int':
case 'float':
return `${defaultValue.toString()} ${suffix}`
case 'boolean':
return Boolean(defaultValue) ? t('on') : t('off')
case 'str':
if ('choices' in runTimeParameter && runTimeParameter.choices != null) {
const choice = runTimeParameter.choices.find(
choice => choice.value === defaultValue
)
if (choice != null) {
return choice.displayName
}
}
break
}
return ''
}

const formatRange = (
runTimeParameter: RunTimeParameter,
minMax: string
@@ -135,7 +109,9 @@ function ProtocolParameterItems({
<StyledText as="p">{parameter.displayName}</StyledText>
</StyledTableCell>
<StyledTableCell isLast={index === runTimeParameters.length - 1}>
<StyledText as="p">{formattedValue(parameter)}</StyledText>
<StyledText as="p">
{formatRunTimeParameterValue(parameter, t)}
</StyledText>
</StyledTableCell>
<StyledTableCell isLast={index === runTimeParameters.length - 1}>
<StyledText as="p">
33 changes: 33 additions & 0 deletions app/src/organisms/ProtocolDetails/ProtocolParameters/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useTranslation } from 'react-i18next'
import type { RunTimeParameter } from '@opentrons/shared-data'

export const formatRunTimeParameterValue = (
runTimeParameter: RunTimeParameter,
t: ReturnType<typeof useTranslation>['t']
): string => {
const { type, default: defaultValue } = runTimeParameter
const suffix =
'suffix' in runTimeParameter && runTimeParameter.suffix != null
? runTimeParameter.suffix
: null
switch (type) {
case 'int':
case 'float':
return suffix !== null
? `${defaultValue.toString()} ${suffix}`
: defaultValue.toString()
case 'boolean':
return Boolean(defaultValue) ? t('on') : t('off')
case 'str':
if ('choices' in runTimeParameter && runTimeParameter.choices != null) {
const choice = runTimeParameter.choices.find(
choice => choice.value === defaultValue
)
if (choice != null) {
return choice.displayName
}
}
break
}
return ''
}
32 changes: 3 additions & 29 deletions app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx
Original file line number Diff line number Diff line change
@@ -16,8 +16,8 @@ import { StyledText } from '../../atoms/text'
import { Chip } from '../../atoms/Chip'
import { useToaster } from '../ToasterOven'
import { mockData } from './index'
import { formatRunTimeParameterValue } from '../ProtocolDetails/ProtocolParameters/utils'

import type { RunTimeParameter } from '@opentrons/shared-data'
import type { SetupScreens } from '../../pages/ProtocolSetup'

export interface ViewOnlyParametersProps {
@@ -29,7 +29,7 @@ export function ViewOnlyParameters({
runId,
setSetupScreen,
}: ViewOnlyParametersProps): JSX.Element {
const { t, i18n } = useTranslation('protocol_setup')
const { t } = useTranslation('protocol_setup')
const { makeSnackbar } = useToaster()
const mostRecentAnalysis = useMostRecentCompletedAnalysis(runId)
const handleOnClick = (): void => {
@@ -39,32 +39,6 @@ export function ViewOnlyParameters({
// TODO(jr, 3/18/24): remove mockData
const parameters = mostRecentAnalysis?.runTimeParameters ?? mockData

const getDefault = (parameter: RunTimeParameter): string => {
const { type, default: defaultValue } = parameter
const suffix =
'suffix' in parameter && parameter.suffix != null ? parameter.suffix : ''
switch (type) {
case 'int':
case 'float':
return `${defaultValue.toString()} ${suffix}`
case 'boolean':
return Boolean(defaultValue)
? i18n.format(t('on'), 'capitalize')
: i18n.format(t('off'), 'capitalize')
case 'str':
if ('choices' in parameter && parameter.choices != null) {
const choice = parameter.choices.find(
choice => choice.value === defaultValue
)
if (choice != null) {
return choice.displayName
}
}
break
}
return ''
}

return (
<>
<ChildNavigation
@@ -120,7 +94,7 @@ export function ViewOnlyParameters({
gridGap={SPACING.spacing8}
>
<StyledText as="p" maxWidth="15rem" color={COLORS.grey60}>
{getDefault(parameter)}
{formatRunTimeParameterValue(parameter, t)}
</StyledText>
{hasCustomValue ? (
<Chip
31 changes: 3 additions & 28 deletions app/src/organisms/ProtocolSetupParameters/index.tsx
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ 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'
@@ -171,7 +172,7 @@ export function ProtocolSetupParameters({
labwareOffsets,
runTimeParameters,
}: ProtocolSetupParametersProps): JSX.Element {
const { t, i18n } = useTranslation('protocol_setup')
const { t } = useTranslation('protocol_setup')
const history = useHistory()
const host = useHost()
const queryClient = useQueryClient()
@@ -193,32 +194,6 @@ export function ProtocolSetupParameters({
createRun({ protocolId, labwareOffsets })
}

const getDefault = (parameter: RunTimeParameter): string => {
const { type, default: defaultValue } = parameter
const suffix =
'suffix' in parameter && parameter.suffix != null ? parameter.suffix : ''
switch (type) {
case 'int':
case 'float':
return `${defaultValue.toString()} ${suffix}`
case 'boolean':
return Boolean(defaultValue)
? i18n.format(t('on'), 'capitalize')
: i18n.format(t('off'), 'capitalize')
case 'str':
if ('choices' in parameter && parameter.choices != null) {
const choice = parameter.choices.find(
choice => choice.value === defaultValue
)
if (choice != null) {
return choice.displayName
}
}
break
}
return ''
}

return (
<>
{resetValuesModal ? (
@@ -253,7 +228,7 @@ export function ProtocolSetupParameters({
status="general"
title={parameter.displayName}
onClickSetupStep={() => console.log('TODO: wire this up')}
detail={getDefault(parameter)}
detail={formatRunTimeParameterValue(parameter, t)}
description={parameter.description}
fontSize="h4"
/>
27 changes: 2 additions & 25 deletions app/src/pages/ProtocolDetails/Parameters.tsx
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ import { StyledText } from '../../atoms/text'
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')`
@@ -85,30 +86,6 @@ export const Parameters = (props: { protocolId: string }): JSX.Element => {
}
}

const getDefault = (parameter: RunTimeParameter): string => {
const { type, default: defaultValue } = parameter
const suffix =
'suffix' in parameter && parameter.suffix != null ? parameter.suffix : ''
switch (type) {
case 'int':
case 'float':
return `${defaultValue.toString()} ${suffix}`
case 'boolean':
return Boolean(defaultValue) ? t('on') : t('off')
case 'str':
if ('choices' in parameter && parameter.choices != null) {
const choice = parameter.choices.find(
choice => choice.value === defaultValue
)
if (choice != null) {
return choice.displayName
}
}
break
}
return ''
}

return runTimeParameters.length > 0 ? (
<Table onClick={makeSnack} data-testid="Parameters_table">
<thead>
@@ -141,7 +118,7 @@ export const Parameters = (props: { protocolId: string }): JSX.Element => {
</TableDatum>
<TableDatum>
<Flex paddingLeft={SPACING.spacing24} color={COLORS.grey60}>
{getDefault(parameter)}
{formatRunTimeParameterValue(parameter, t)}
</Flex>
</TableDatum>
<TableDatum>

0 comments on commit 7c39473

Please sign in to comment.