Skip to content

Commit 525512a

Browse files
authored
feat(app): generate loadLiquidClass in JSON commands for QT (#18943)
closes AUTH-1988
1 parent 8a7dbff commit 525512a

14 files changed

+112
-80
lines changed

app/src/organisms/ODD/QuickTransferFlow/Overview.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from '@opentrons/components'
1515
import {
1616
FLEX_SINGLE_SLOT_BY_CUTOUT_ID,
17+
getAllLiquidClassDefs,
1718
TRASH_BIN_ADAPTER_FIXTURE,
1819
} from '@opentrons/shared-data'
1920

@@ -31,7 +32,7 @@ export function Overview(props: OverviewProps): JSX.Element | null {
3132
const { state } = props
3233
const { t } = useTranslation(['quick_transfer', 'shared'])
3334
const { makeSnackbar } = useToaster()
34-
35+
const allLiquidClasses = getAllLiquidClassDefs()
3536
let transferCopy = t('volume_per_well')
3637
if (state.transferType === CONSOLIDATE) {
3738
transferCopy = t('aspirate_volume')
@@ -90,7 +91,7 @@ export function Overview(props: OverviewProps): JSX.Element | null {
9091
},
9192
{
9293
option: t('liquid_class'),
93-
value: state?.liquidClass?.displayName,
94+
value: allLiquidClasses[state?.liquidClassName]?.displayName,
9495
},
9596
]
9697

app/src/organisms/ODD/QuickTransferFlow/QuickTransferAdvancedSettings/BlowOut.tsx

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,15 @@ import {
1515
StyledText,
1616
} from '@opentrons/components'
1717
import {
18-
ETHANOL_LIQUID_CLASS_NAME,
1918
FLEX_SINGLE_SLOT_BY_CUTOUT_ID,
2019
getAllLiquidClassDefs,
2120
getFlexNameConversion,
2221
getTipTypeFromTipRackDefinition,
23-
GLYCEROL_LIQUID_CLASS_NAME,
2422
linearInterpolate,
2523
LOW_VOLUME_PIPETTES,
2624
NONE_LIQUID_CLASS_NAME,
2725
TRASH_BIN_ADAPTER_FIXTURE,
2826
WASTE_CHUTE_FIXTURES,
29-
WATER_LIQUID_CLASS_NAME,
3027
} from '@opentrons/shared-data'
3128
import { getTransferPlanAndReferenceVolumes } from '@opentrons/step-generation'
3229

@@ -217,16 +214,8 @@ export function BlowOut(props: BlowOutProps): JSX.Element {
217214
: liquidSpecs.default.supportedTips[tipType]
218215

219216
const allLiquidClassDefs = getAllLiquidClassDefs()
220-
const liquidClassMap = new Map<string, string>([
221-
['none', NONE_LIQUID_CLASS_NAME],
222-
['water', WATER_LIQUID_CLASS_NAME],
223-
['glycerol_50', GLYCEROL_LIQUID_CLASS_NAME],
224-
['ethanol_80', ETHANOL_LIQUID_CLASS_NAME],
225-
])
226217

227-
const selectedLiquidClass = liquidClassMap.get(
228-
state.liquidClass?.liquidClassName ?? 'none'
229-
)
218+
const selectedLiquidClass = state.liquidClassName
230219
const liquidClassDef =
231220
allLiquidClassDefs[selectedLiquidClass ?? NONE_LIQUID_CLASS_NAME]
232221
const convertedPipetteName =

app/src/organisms/ODD/QuickTransferFlow/QuickTransferAdvancedSettings/ResetAdvancedSettingsModal.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
SPACING,
99
StyledText,
1010
} from '@opentrons/components'
11+
import { getAllLiquidClassDefs } from '@opentrons/shared-data'
1112

1213
import { getTopPortalEl } from '/app/App/portal'
1314
import { SmallButton } from '/app/atoms/buttons'
@@ -36,7 +37,11 @@ export function ResetAdvancedSettingsModal({
3637
onClose,
3738
}: ResetAdvancedSettingsModalProps): JSX.Element {
3839
const { i18n, t } = useTranslation(['quick_transfer', 'shared'])
39-
const { liquidClass } = state
40+
const { liquidClassName: stateLiquidClassName } = state
41+
const liquidClass =
42+
stateLiquidClassName != null && stateLiquidClassName !== 'none'
43+
? getAllLiquidClassDefs()[stateLiquidClassName]
44+
: { displayName: 'none', liquidClassName: 'none' }
4045
const { displayName, liquidClassName } = liquidClass
4146
const modalHeader = {
4247
title: t('reset_kind_settings', { transferName: kind }),

app/src/organisms/ODD/QuickTransferFlow/QuickTransferAdvancedSettings/__tests__/ResetAdvancedSettingsModal.test.tsx

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { fireEvent, screen } from '@testing-library/react'
22
import { beforeEach, describe, expect, it, vi } from 'vitest'
33

4+
import { WATER_LIQUID_CLASS_NAME } from '@opentrons/shared-data'
5+
46
import { renderWithProviders } from '/app/__testing-utils__'
57
import { i18n } from '/app/i18n'
68

79
import QuickTransferState from '../__fixtures__/QuickTransferState.json'
810
import { ResetAdvancedSettingsModal } from '../ResetAdvancedSettingsModal'
911

1012
import type { ComponentProps } from 'react'
11-
import type { LiquidClass } from '@opentrons/shared-data'
1213

1314
vi.mock('../../utils/retrieveLiquidClassValues')
1415

@@ -26,10 +27,7 @@ describe('ResetAdvancedSettingsModal', () => {
2627
kind: 'aspirate',
2728
state: {
2829
...QuickTransferState,
29-
liquidClass: {
30-
displayName: 'Water',
31-
liquidClassName: 'water',
32-
} as LiquidClass,
30+
liquidClassName: WATER_LIQUID_CLASS_NAME,
3331
} as any,
3432
dispatch: vi.fn(),
3533
onClose: vi.fn(),
@@ -40,17 +38,14 @@ describe('ResetAdvancedSettingsModal', () => {
4038
render(props)
4139
screen.getByText('Reset aspirate settings?')
4240
screen.getByText(
43-
'Continuing will undo any changes and restore the aspirate settings to the values associated with the Water liquid class.'
41+
'Continuing will undo any changes and restore the aspirate settings to the values associated with the Aqueous liquid class.'
4442
)
4543
screen.getByText('Cancel')
4644
screen.getByText('Continue')
4745
})
4846

4947
it('renders the modal with correct title and description - aspirate', () => {
50-
props.state.liquidClass = {
51-
displayName: '',
52-
liquidClassName: 'none',
53-
} as LiquidClass
48+
props.state.liquidClassName = 'none'
5449
render(props)
5550
screen.getByText('Reset aspirate settings?')
5651
screen.getByText(
@@ -65,18 +60,15 @@ describe('ResetAdvancedSettingsModal', () => {
6560
render(props)
6661
screen.getByText('Reset dispense settings?')
6762
screen.getByText(
68-
'Continuing will undo any changes and restore the dispense settings to the values associated with the Water liquid class.'
63+
'Continuing will undo any changes and restore the dispense settings to the values associated with the Aqueous liquid class.'
6964
)
7065
screen.getByText('Cancel')
7166
screen.getByText('Continue')
7267
})
7368

7469
it('renders the modal with correct title and description - dispense', () => {
7570
props.kind = 'dispense'
76-
props.state.liquidClass = {
77-
displayName: '',
78-
liquidClassName: 'none',
79-
} as LiquidClass
71+
props.state.liquidClassName = 'none'
8072
render(props)
8173
screen.getByText('Reset dispense settings?')
8274
screen.getByText(

app/src/organisms/ODD/QuickTransferFlow/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export interface QuickTransferWizardState {
7878
path?: PathOption // this has been added
7979
changeTip?: ChangeTipOptions // this has been added
8080
dropTipLocation?: CutoutConfig // this has been added
81-
liquidClass?: LiquidClass // this has been added
81+
liquidClassName?: string // this has been added
8282
}
8383
```
8484

@@ -157,7 +157,7 @@ export interface QuickTransferSummaryState {
157157
airGapDispense?: number
158158
changeTip: ChangeTipOptions
159159
dropTipLocation: CutoutConfig
160-
liquidClass: LiquidClass // this has been added
160+
liquidClassName: string // this has been added
161161
conditionAspirate?: number // this has been added
162162
disposalVolumeDispenseSettings?: {
163163
volume: number

app/src/organisms/ODD/QuickTransferFlow/SelectLiquidClass.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ import {
88
SPACING,
99
StyledText,
1010
} from '@opentrons/components'
11-
import { getAllLiquidClassDefs } from '@opentrons/shared-data'
11+
import {
12+
ETHANOL_LIQUID_CLASS_NAME,
13+
getAllLiquidClassDefs,
14+
GLYCEROL_LIQUID_CLASS_NAME,
15+
NONE_LIQUID_CLASS_NAME,
16+
WATER_LIQUID_CLASS_NAME,
17+
} from '@opentrons/shared-data'
1218

1319
import { ChildNavigation } from '/app/organisms/ODD/ChildNavigation'
1420
import { useToaster } from '/app/organisms/ToasterOven'
@@ -52,13 +58,25 @@ export function SelectLiquidClass({
5258
schemaVersion: 1,
5359
}
5460

61+
const mapLiquidClassToInternalName: Record<
62+
LiquidClass['liquidClassName'],
63+
string
64+
> = {
65+
ethanol_80: ETHANOL_LIQUID_CLASS_NAME,
66+
glycerol_50: GLYCEROL_LIQUID_CLASS_NAME,
67+
water: WATER_LIQUID_CLASS_NAME,
68+
none: NONE_LIQUID_CLASS_NAME,
69+
}
70+
5571
const liquidClassOptions = [noLiquidClass, ...Object.values(liquidClasses)]
5672
const handleClickNext = (): void => {
57-
dispatch({
58-
type: 'SET_LIQUID_CLASS',
59-
liquidClass: selectedLiquidClass ?? noLiquidClass,
60-
})
61-
73+
if (selectedLiquidClass != null) {
74+
dispatch({
75+
type: 'SET_LIQUID_CLASS',
76+
liquidClassName:
77+
mapLiquidClassToInternalName[selectedLiquidClass.liquidClassName],
78+
})
79+
}
6280
onNext()
6381
}
6482

app/src/organisms/ODD/QuickTransferFlow/__tests__/Overview.test.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { screen } from '@testing-library/react'
22
import { afterEach, beforeEach, describe, it, vi } from 'vitest'
33

4+
import { WATER_LIQUID_CLASS_NAME } from '@opentrons/shared-data'
5+
46
import { renderWithProviders } from '/app/__testing-utils__'
57
import { i18n } from '/app/i18n'
68

@@ -42,14 +44,7 @@ describe('Overview', () => {
4244
} as any,
4345
transferType: 'transfer',
4446
volume: 25,
45-
liquidClass: {
46-
liquidClassName: 'dummyLiquidClass',
47-
displayName: 'Dummy liquid class',
48-
description: 'Dummy liquid class description',
49-
schemaVersion: 0,
50-
namespace: '',
51-
byPipette: [],
52-
},
47+
liquidClassName: WATER_LIQUID_CLASS_NAME,
5348
} as any,
5449
}
5550
})
@@ -141,6 +136,6 @@ describe('Overview', () => {
141136
screen.getByText('Tip change frequency')
142137
screen.getByText('Tip drop location')
143138
screen.getByText('Liquid class')
144-
screen.getByText('Dummy liquid class')
139+
screen.getByText('Aqueous')
145140
})
146141
})

app/src/organisms/ODD/QuickTransferFlow/__tests__/SelectLiquidClass.test.tsx

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import { fireEvent, screen } from '@testing-library/react'
22
import { beforeEach, describe, expect, it, vi } from 'vitest'
33

4-
import { getAllLiquidClassDefs } from '@opentrons/shared-data'
4+
import {
5+
ETHANOL_LIQUID_CLASS_NAME,
6+
getAllLiquidClassDefs,
7+
GLYCEROL_LIQUID_CLASS_NAME,
8+
NONE_LIQUID_CLASS_NAME,
9+
WATER_LIQUID_CLASS_NAME,
10+
} from '@opentrons/shared-data'
511

612
import { renderWithProviders } from '/app/__testing-utils__'
713
import { i18n } from '/app/i18n'
@@ -23,15 +29,6 @@ vi.mock('@opentrons/shared-data', async importOriginal => {
2329
})
2430
const mockMakeSnackbar = vi.fn()
2531

26-
const mockNoLiquidClass = {
27-
byPipette: [],
28-
description: 'Default',
29-
displayName: "Don't use liquid class settings",
30-
liquidClassName: 'none',
31-
namespace: 'opentrons',
32-
schemaVersion: 1,
33-
}
34-
3532
const mockByPipette = [
3633
{
3734
tiprack: 'opentrons/opentrons_flex_96_tiprack_50ul/1',
@@ -58,25 +55,25 @@ const mockByPipette = [
5855
]
5956

6057
const mockLiquidClasses = {
61-
ethanol: {
62-
liquidClassName: 'mock ethanol',
58+
[ETHANOL_LIQUID_CLASS_NAME]: {
59+
liquidClassName: 'ethanol_80',
6360
displayName: 'Volatile',
6461
description: '80% ethanol',
6562
schemaVersion: 0,
6663
namespace: '',
6764
byPipette: mockByPipette,
6865
},
69-
glyeral: {
70-
liquidClassName: 'mock glyeral',
66+
[GLYCEROL_LIQUID_CLASS_NAME]: {
67+
liquidClassName: 'glycerol_50',
7168
displayName: 'Viscous',
7269
description: '50% glycerol',
7370
schemaVersion: 0,
7471
namespace: '',
7572
byPipette: mockByPipette,
7673
},
77-
water: {
74+
[WATER_LIQUID_CLASS_NAME]: {
7875
displayName: 'Aqueous',
79-
liquidClassName: 'mock water',
76+
liquidClassName: 'water',
8077
description: 'Deionized water',
8178
schemaVersion: 0,
8279
namespace: '',
@@ -211,7 +208,7 @@ describe('SelectLiquidClass', () => {
211208
expect(props.onNext).toHaveBeenCalled()
212209
expect(props.dispatch).toHaveBeenCalledWith({
213210
type: 'SET_LIQUID_CLASS',
214-
liquidClass: mockNoLiquidClass,
211+
liquidClassName: NONE_LIQUID_CLASS_NAME,
215212
})
216213
})
217214

@@ -223,7 +220,7 @@ describe('SelectLiquidClass', () => {
223220
expect(props.onNext).toHaveBeenCalled()
224221
expect(props.dispatch).toHaveBeenCalledWith({
225222
type: 'SET_LIQUID_CLASS',
226-
liquidClass: mockLiquidClasses.water,
223+
liquidClassName: WATER_LIQUID_CLASS_NAME,
227224
})
228225
})
229226

app/src/organisms/ODD/QuickTransferFlow/reducers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export function quickTransferWizardReducer(
111111
case 'SET_LIQUID_CLASS': {
112112
return {
113113
...state,
114-
liquidClass: action.liquidClass,
114+
liquidClassName: action.liquidClassName,
115115
}
116116
}
117117
}

app/src/organisms/ODD/QuickTransferFlow/types.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import type { Mount } from '@opentrons/api-client'
22
import type {
33
CutoutConfig,
44
LabwareDefinition2,
5-
LiquidClass,
65
PipetteV2Specs,
76
} from '@opentrons/shared-data'
87
import type {
@@ -28,7 +27,7 @@ export interface QuickTransferWizardState {
2827
path?: PathOption
2928
changeTip?: ChangeTipOptions
3029
dropTipLocation?: CutoutConfig
31-
liquidClass?: LiquidClass
30+
liquidClassName?: string
3231
}
3332
export type PathOption = 'single' | 'multiAspirate' | 'multiDispense'
3433
export type ChangeTipOptions =
@@ -115,7 +114,7 @@ export interface QuickTransferSummaryState {
115114
airGapDispense?: number
116115
changeTip: ChangeTipOptions
117116
dropTipLocation: CutoutConfig
118-
liquidClass: LiquidClass
117+
liquidClassName: string
119118
conditionAspirate?: number
120119
disposalVolumeDispenseSettings?: {
121120
volume: number
@@ -285,7 +284,7 @@ interface SetDropTipLocation {
285284

286285
interface SetLiquidClassAction {
287286
type: typeof ACTIONS.SET_LIQUID_CLASS
288-
liquidClass: LiquidClass
287+
liquidClassName: string
289288
}
290289

291290
interface SelectPipetteAction {

0 commit comments

Comments
 (0)