Skip to content

Commit ee3acc7

Browse files
authored
refactor(protocol-designer): allow for duplicating stacks (#20046)
closes AUTH-2452 AUTH-2451
1 parent dd7a684 commit ee3acc7

File tree

2 files changed

+49
-52
lines changed

2 files changed

+49
-52
lines changed

protocol-designer/src/labware-ingred/actions/thunks.ts

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -123,68 +123,70 @@ export const createContainer: (
123123
}
124124

125125
export const duplicateLabware: (
126-
templateLabwareId: string
126+
templateLabwareIds: string[]
127127
) => ThunkAction<DuplicateLabwareAction> =
128-
templateLabwareId => (dispatch, getState) => {
128+
templateLabwareIds => (dispatch, getState) => {
129129
const state = getState()
130130
const robotType = state.fileData.robotType
131-
const templateLabwareDefURI =
132-
stepFormSelectors.getLabwareEntities(state)[templateLabwareId]
133-
.labwareDefURI
134-
console.assert(
135-
templateLabwareDefURI,
136-
`no labwareDefURI for labware ${templateLabwareId}, cannot run duplicateLabware thunk`
137-
)
131+
const labwareEntities = stepFormSelectors.getLabwareEntities(state)
132+
const labwareDefsByURI = labwareDefSelectors.getLabwareDefsByURI(state)
138133
const initialDeckSetup = stepFormSelectors.getInitialDeckSetup(state)
139-
const templateLabwareIdIsOffDeck =
140-
getSlotInLocationStack(
141-
initialDeckSetup.labware[templateLabwareId].stack
142-
) === 'offDeck'
143-
const labwareDef =
144-
labwareDefSelectors.getLabwareDefsByURI(state)[templateLabwareDefURI]
145-
const displayCategory = labwareDef.metadata.displayCategory
146-
const duplicateSlot = getNextAvailableDeckSlot(
147-
initialDeckSetup,
148-
robotType,
149-
labwareDef
150-
)
151-
if (duplicateSlot == null && !templateLabwareIdIsOffDeck) {
152-
console.error('no slots available, cannot duplicate labware')
153-
}
154134
const allNicknamesById = uiLabwareSelectors.getLabwareNicknamesById(state)
155-
const templateNickname = allNicknamesById[templateLabwareId]
156-
const duplicateLabwareNickname = getNextNickname(
157-
Object.keys(allNicknamesById).map((id: string) => allNicknamesById[id]), // NOTE: flow won't do Object.values here >:(
158-
templateNickname
135+
136+
const templateLabwareDefURIs = templateLabwareIds.map(
137+
id => labwareEntities[id]?.labwareDefURI
159138
)
160-
const duplicateLabwareId = uuid() + ':' + templateLabwareDefURI
161139

162-
if (templateLabwareDefURI) {
163-
if (templateLabwareIdIsOffDeck) {
164-
dispatch({
165-
type: 'DUPLICATE_LABWARE',
166-
payload: {
167-
duplicateLabwareNickname,
168-
templateLabwareId,
169-
duplicateLabwareId,
170-
slot: 'offDeck',
171-
displayCategory,
172-
},
173-
})
174-
}
140+
console.assert(
141+
!templateLabwareDefURIs.some(uri => uri == null),
142+
'Missing labwareDefURI for one or more templateLabwareIds:',
143+
templateLabwareIds
144+
)
145+
146+
// determine if duplicating off-deck
147+
const firstTemplateId = templateLabwareIds[0]
148+
const firstLabwareStack = initialDeckSetup.labware[firstTemplateId].stack
149+
const isOffDeck = getSlotInLocationStack(firstLabwareStack) === 'offDeck'
150+
151+
const firstLabwareDefURI = templateLabwareDefURIs[0] as string
152+
const labwareDef = labwareDefsByURI[firstLabwareDefURI]
153+
const displayCategory = labwareDef?.metadata?.displayCategory
154+
155+
const templateSlot = isOffDeck
156+
? 'offDeck'
157+
: getNextAvailableDeckSlot(initialDeckSetup, robotType, labwareDef)
158+
159+
// ensure templateSlot is not null
160+
if (templateSlot == null) {
161+
console.error('no slots available, cannot duplicate labware')
162+
return
175163
}
176-
if (duplicateSlot != null && !templateLabwareIdIsOffDeck) {
164+
165+
const duplicateNicknames = templateLabwareIds.map(id => {
166+
const templateNickname = allNicknamesById[id]
167+
return getNextNickname(Object.values(allNicknamesById), templateNickname)
168+
})
169+
170+
let slot: string = templateSlot as string
171+
templateLabwareIds.reverse().forEach((templateLabwareId, index) => {
172+
const defURI = labwareEntities[templateLabwareId].labwareDefURI
173+
const duplicateLabwareId = `${uuid()}:${defURI}`
174+
177175
dispatch({
178176
type: 'DUPLICATE_LABWARE',
179177
payload: {
180-
duplicateLabwareNickname,
178+
duplicateLabwareNickname: duplicateNicknames[index],
181179
templateLabwareId,
182180
duplicateLabwareId,
183-
slot: duplicateSlot,
181+
slot,
184182
displayCategory,
185183
},
186184
})
187-
}
185+
186+
if (!isOffDeck) {
187+
slot = duplicateLabwareId
188+
}
189+
})
188190
}
189191

190192
export interface EditMultipleLabwareAction {

protocol-designer/src/pages/Designer/DeckSetup/SlotOverflowMenu.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,7 @@ export function SlotOverflowMenu(
138138
makeSnackbar(t('deck_slots_full') as string)
139139
return
140140
}
141-
142-
labwareStackOnSlot.forEach(labware => {
143-
if (!deckSetupLabware[labware].def.allowedRoles?.includes('adapter')) {
144-
dispatch(duplicateLabware(deckSetupLabware[labware].id))
145-
}
146-
})
141+
dispatch(duplicateLabware(labwareStackOnSlot))
147142
setShowMenuList(false)
148143
}
149144

0 commit comments

Comments
 (0)