diff --git a/protocol-designer/src/components/StepEditForm/fields/MoveLabwareField.tsx b/protocol-designer/src/components/StepEditForm/fields/MoveLabwareField.tsx
new file mode 100644
index 00000000000..b0a6d51b463
--- /dev/null
+++ b/protocol-designer/src/components/StepEditForm/fields/MoveLabwareField.tsx
@@ -0,0 +1,10 @@
+import * as React from 'react'
+import { useSelector } from 'react-redux'
+import { getMoveLabwareOptions } from '../../../ui/labware/selectors'
+import { StepFormDropdown } from './StepFormDropdownField'
+import type { FieldProps } from '../types'
+
+export function MoveLabwareField(props: FieldProps): JSX.Element {
+ const options = useSelector(getMoveLabwareOptions)
+ return
+}
diff --git a/protocol-designer/src/components/StepEditForm/fields/index.ts b/protocol-designer/src/components/StepEditForm/fields/index.ts
index b59231db01a..15d7f4bb21f 100644
--- a/protocol-designer/src/components/StepEditForm/fields/index.ts
+++ b/protocol-designer/src/components/StepEditForm/fields/index.ts
@@ -13,6 +13,7 @@ export { DisposalVolumeField } from './DisposalVolumeField'
export { FlowRateField } from './FlowRateField'
export { LabwareField } from './LabwareField'
export { LabwareLocationField } from './LabwareLocationField'
+export { MoveLabwareField } from './MoveLabwareField'
export { PathField } from './PathField/PathField'
export { PipetteField } from './PipetteField'
export { ProfileItemRows } from './ProfileItemRows'
diff --git a/protocol-designer/src/components/StepEditForm/forms/MoveLabwareForm/index.tsx b/protocol-designer/src/components/StepEditForm/forms/MoveLabwareForm/index.tsx
index e7dde2d26fb..9de9709cbc0 100644
--- a/protocol-designer/src/components/StepEditForm/forms/MoveLabwareForm/index.tsx
+++ b/protocol-designer/src/components/StepEditForm/forms/MoveLabwareForm/index.tsx
@@ -12,9 +12,9 @@ import {
useHoverTooltip,
} from '@opentrons/components'
import {
- LabwareField,
LabwareLocationField,
CheckboxRowField,
+ MoveLabwareField,
} from '../../fields'
import styles from '../../StepEditForm.module.css'
import { FLEX_ROBOT_TYPE } from '@opentrons/shared-data'
@@ -50,7 +50,7 @@ export const MoveLabwareForm = (props: StepFormProps): JSX.Element => {
label={t('form:step_edit_form.labwareLabel.movedLabware')}
className={styles.large_field}
>
-
+
{robotType === FLEX_ROBOT_TYPE ? (
{
])
})
- it('should return labware options for move labware with tips and trash', () => {
- const labwareEntities = {
- ...tipracks,
- ...trash,
- ...otherLabware,
- }
- const initialDeckSetup = {
- labware: labwareEntities,
- modules: {},
- pipettes: {},
- }
-
- const presavedStepForm = {
- stepType: 'moveLabware',
- }
- expect(
- // @ts-expect-error(jr, 7/17/23): resultFunc doesn't exist on type Selector
- getLabwareOptions.resultFunc(
- labwareEntities,
- names,
- initialDeckSetup,
- presavedStepForm,
- {},
- {}
- )
- ).toEqual([
- { name: 'Opentrons Tip Rack 10 µL', value: 'tiprack10Id' },
- { name: 'Opentrons Tip Rack 1000 µL', value: 'tiprack100Id' },
- { name: 'Source Plate', value: 'wellPlateId' },
- { name: 'Trash', value: mockTrash },
- ])
- })
-
it('should return labware options with module prefixes when a labware is on module', () => {
const labware = {
wellPlateId: {
@@ -345,7 +312,7 @@ describe('labware selectors', () => {
)
).toEqual([
{ name: 'Trash', value: mockTrash },
- { name: 'Well Plate', value: 'wellPlateId' },
+ { name: 'Well Plate in Magnetic Module', value: 'wellPlateId' },
])
})
})
diff --git a/protocol-designer/src/ui/labware/selectors.ts b/protocol-designer/src/ui/labware/selectors.ts
index 24790e7174f..61d5f5dab7a 100644
--- a/protocol-designer/src/ui/labware/selectors.ts
+++ b/protocol-designer/src/ui/labware/selectors.ts
@@ -11,6 +11,10 @@ import { getLabwareOffDeck, getLabwareInColumn4 } from './utils'
import type { LabwareEntity } from '@opentrons/step-generation'
import type { DropdownOption, Options } from '@opentrons/components'
import type { Selector } from '../../types'
+import type {
+ AllTemporalPropertiesForTimelineFrame,
+ SavedStepFormState,
+} from '../../step-forms'
const TRASH = 'Trash Bin'
@@ -35,30 +39,63 @@ export const _sortLabwareDropdownOptions = (options: Options): Options =>
return a.name.localeCompare(b.name)
})
-/** Returns options for labware dropdowns.
+const getNickname = (
+ nicknamesById: Record,
+ initialDeckSetup: AllTemporalPropertiesForTimelineFrame,
+ labwareId: string,
+ savedStepForms: SavedStepFormState
+): string => {
+ const isOffDeck = getLabwareOffDeck(
+ initialDeckSetup,
+ savedStepForms ?? {},
+ labwareId
+ )
+
+ const moduleOnDeck = getModuleUnderLabware(
+ initialDeckSetup,
+ savedStepForms ?? {},
+ labwareId
+ )
+ const module =
+ moduleOnDeck != null ? getModuleShortNames(moduleOnDeck.type) : null
+
+ const isLabwareInColumn4 = getLabwareInColumn4(
+ initialDeckSetup,
+ savedStepForms ?? {},
+ labwareId
+ )
+
+ let nickName: string = nicknamesById[labwareId]
+ if (module != null) {
+ nickName = `${nicknamesById[labwareId]} in ${module}`
+ } else if (isOffDeck) {
+ nickName = `${nicknamesById[labwareId]} off-deck`
+ } else if (isLabwareInColumn4) {
+ nickName = `${nicknamesById[labwareId]} in staging area slot`
+ }
+ return nickName
+}
+
+/** Returns options for labware dropdowns for moveLabware.
* Ordered by display name / nickname, but with trash at the bottom.
*/
-export const getLabwareOptions: Selector = createSelector(
+export const getMoveLabwareOptions: Selector = createSelector(
stepFormSelectors.getLabwareEntities,
getLabwareNicknamesById,
stepFormSelectors.getInitialDeckSetup,
- stepFormSelectors.getPresavedStepForm,
stepFormSelectors.getSavedStepForms,
stepFormSelectors.getAdditionalEquipmentEntities,
(
labwareEntities,
nicknamesById,
initialDeckSetup,
- presavedStepForm,
savedStepForms,
additionalEquipmentEntities
) => {
- const moveLabwarePresavedStep = presavedStepForm?.stepType === 'moveLabware'
const wasteChuteLocation = Object.values(additionalEquipmentEntities).find(
aE => aE.name === 'wasteChute'
)?.location
-
- const labwareOptions = reduce(
+ const moveLabwareOptions = reduce(
labwareEntities,
(
acc: Options,
@@ -72,67 +109,89 @@ export const getLabwareOptions: Selector = createSelector(
form.newLocation === wasteChuteLocation
)
- const isAdapter = labwareEntity.def.allowedRoles?.includes('adapter')
- const isOffDeck = getLabwareOffDeck(
+ const isAdapter =
+ labwareEntity.def.allowedRoles?.includes('adapter') ?? false
+ const nickName = getNickname(
+ nicknamesById,
initialDeckSetup,
- savedStepForms ?? {},
- labwareId
+ labwareId,
+ savedStepForms
)
- const moduleOnDeck = getModuleUnderLabware(
- initialDeckSetup,
- savedStepForms ?? {},
- labwareId
+ // filter out moving trash, adapters, and labware in
+ // waste chute for moveLabware
+ return isAdapter || isLabwareInWasteChute
+ ? acc
+ : [
+ ...acc,
+ {
+ name: nickName,
+ value: labwareId,
+ },
+ ]
+ },
+ []
+ )
+ return _sortLabwareDropdownOptions(moveLabwareOptions)
+ }
+)
+
+/** Returns options for labware dropdowns for moveLiquids.
+ * Ordered by display name / nickname, but with trash at the bottom.
+ */
+export const getLabwareOptions: Selector = createSelector(
+ stepFormSelectors.getLabwareEntities,
+ getLabwareNicknamesById,
+ stepFormSelectors.getInitialDeckSetup,
+ stepFormSelectors.getSavedStepForms,
+ stepFormSelectors.getAdditionalEquipmentEntities,
+ (
+ labwareEntities,
+ nicknamesById,
+ initialDeckSetup,
+ savedStepForms,
+ additionalEquipmentEntities
+ ) => {
+ const wasteChuteLocation = Object.values(additionalEquipmentEntities).find(
+ aE => aE.name === 'wasteChute'
+ )?.location
+ const labwareOptions = reduce(
+ labwareEntities,
+ (
+ acc: Options,
+ labwareEntity: LabwareEntity,
+ labwareId: string
+ ): Options => {
+ const isLabwareInWasteChute = Object.values(savedStepForms).find(
+ form =>
+ form.stepType === 'moveLabware' &&
+ form.labware === labwareId &&
+ form.newLocation === wasteChuteLocation
)
- const module =
- moduleOnDeck != null ? getModuleShortNames(moduleOnDeck.type) : null
- const isLabwareInColumn4 = getLabwareInColumn4(
+ const isAdapter =
+ labwareEntity.def.allowedRoles?.includes('adapter') ?? false
+ const nickName = getNickname(
+ nicknamesById,
initialDeckSetup,
- savedStepForms ?? {},
- labwareId
+ labwareId,
+ savedStepForms
)
- let nickName = nicknamesById[labwareId]
- if (module != null) {
- nickName = `${nicknamesById[labwareId]} in ${module}`
- } else if (isOffDeck) {
- nickName = `${nicknamesById[labwareId]} off-deck`
- } else if (isLabwareInColumn4) {
- nickName = `${nicknamesById[labwareId]} in staging area slot`
- }
-
- if (!moveLabwarePresavedStep) {
- // filter out tip racks, adapters, and labware in waste chute
- // for aspirating/dispensing/mixing into
- return getIsTiprack(labwareEntity.def) ||
- isAdapter ||
- isLabwareInWasteChute
- ? acc
- : [
- ...acc,
- {
- name: nickName,
- value: labwareId,
- },
- ]
- } else {
- // filter out moving trash, adapters, and labware in
- // waste chute for moveLabware
- return isAdapter || isLabwareInWasteChute
- ? acc
- : [
- ...acc,
- {
- name: nickName,
- value: labwareId,
- },
- ]
- }
+ return getIsTiprack(labwareEntity.def) ||
+ isAdapter ||
+ isLabwareInWasteChute
+ ? acc
+ : [
+ ...acc,
+ {
+ name: nickName,
+ value: labwareId,
+ },
+ ]
},
[]
)
-
return _sortLabwareDropdownOptions(labwareOptions)
}
)