Skip to content

Commit cca981e

Browse files
authored
fix(protocol-designer): filter non-tiprack lids for stacker (#20504)
Ensure that you cannot load or move non-tiprack lidded labware on the Flex stacker shuttle or hopper. This impacts both initial deck setup and the move labware stepform UI. Closes EXEC-2225
1 parent 20be385 commit cca981e

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

protocol-designer/src/components/organisms/SelectLabwareModal/SelectLabware.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ export function SelectLabware(props: SelectLabwareProps): JSX.Element | null {
6262
const zoomedInSlotInfo = useSelector(selectors.getZoomedInSlotInfo)
6363
const { selectedTopLabware, selectedAdapterDefURI, selectedLidLabware } =
6464
zoomedInSlotInfo
65+
const isStackerShuttleOrHopper =
66+
zoomedInSlotInfo.selectedModuleModel === FLEX_STACKER_MODULE_V1
6567
const lidLoadNames = Object.values(defs)
6668
.filter(
6769
def =>
@@ -109,6 +111,7 @@ export function SelectLabware(props: SelectLabwareProps): JSX.Element | null {
109111
return (
110112
<>
111113
{ORDERED_CATEGORIES.map(category => {
114+
const isLidValid = category === 'tipRack' || !isStackerShuttleOrHopper
112115
if (filteredLabwareByCategory[category].length > 0) {
113116
return (
114117
<ListButton
@@ -148,9 +151,10 @@ export function SelectLabware(props: SelectLabwareProps): JSX.Element | null {
148151
})
149152

150153
const stackingProps: StackingProps | null =
151-
isOnHopper ||
152-
(stackingLabwareDefUris.length === 1 &&
153-
slot !== 'offDeck')
154+
isLidValid &&
155+
(isOnHopper ||
156+
(stackingLabwareDefUris.length === 1 &&
157+
slot !== 'offDeck'))
154158
? {
155159
inputTitle: t('labware_quantity'),
156160
errorMessage: t('unsupported_range'),

protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MoveLabwareTools/LabwareLocationField.tsx

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ import { useDispatch, useSelector } from 'react-redux'
33

44
import {
55
FLEX_SINGLE_SLOT_ADDRESSABLE_AREAS,
6+
FLEX_STACKER_MODULE_TYPE,
67
FLEX_STAGING_AREA_SLOT_ADDRESSABLE_AREAS,
78
OT2_SINGLE_SLOT_ADDRESSABLE_AREAS,
89
WASTE_CHUTE_CUTOUT,
910
} from '@opentrons/shared-data'
10-
import { getSlotInLocationStack } from '@opentrons/step-generation'
11+
import {
12+
getFullStackFromLabwares,
13+
getSlotInLocationStack,
14+
} from '@opentrons/step-generation'
1115

1216
import { DropdownStepFormField } from '/protocol-designer/components/molecules'
1317
import { getRobotType } from '/protocol-designer/file-data/selectors'
@@ -60,17 +64,30 @@ export function LabwareLocationField(
6064
t,
6165
})
6266
: []
63-
const isLabwareOffDeck =
64-
labware != null
65-
? getSlotInLocationStack(robotState?.labware[labware]?.stack ?? []) ===
66-
'offDeck'
67-
: false
67+
const labwareSlot = getSlotInLocationStack(
68+
robotState?.labware[labware]?.stack ?? []
69+
)
70+
const isLabwareOffDeck = labware != null ? labwareSlot === 'offDeck' : false
6871
const isLabwareALid =
6972
deckSetupLabware[labware]?.def.allowedRoles?.includes('lid') ?? false
7073
const isLabwareATiprackLid =
7174
deckSetupLabware[labware]?.def.parameters.loadName === TIPRACK_LID_LOADNAME
7275
const unoccupiedLabwareLocationsOptionsSelector =
7376
useSelector(getUnoccupiedLabwareLocationOptions) ?? []
77+
const fullStackFromLabwares = getFullStackFromLabwares(
78+
robotState?.labware ?? {},
79+
labwareSlot,
80+
labware
81+
)
82+
const stackHasANonTiprackLid = fullStackFromLabwares.some(id => {
83+
if (!(id in labwareEntities)) {
84+
return false
85+
}
86+
const { def } = labwareEntities[id]
87+
const isLid = def.allowedRoles?.includes('lid') ?? false
88+
return isLid && def.parameters.loadName !== TIPRACK_LID_LOADNAME
89+
})
90+
7491
const robotType = useSelector(getRobotType)
7592
// invalid offDeck move filter
7693
let unoccupiedLabwareLocationsOptions = [
@@ -136,6 +153,16 @@ export function LabwareLocationField(
136153
option => !allSlotNames.includes(option.value as AddressableAreaName)
137154
)
138155
}
156+
157+
if (stackHasANonTiprackLid) {
158+
unoccupiedLabwareLocationsOptions =
159+
unoccupiedLabwareLocationsOptions.filter(
160+
({ value }) =>
161+
robotState?.modules?.[value]?.moduleState.type !==
162+
FLEX_STACKER_MODULE_TYPE
163+
)
164+
}
165+
139166
const optionsSorted =
140167
robotState != null
141168
? getSortedAddressableArea(

0 commit comments

Comments
 (0)