Skip to content

Commit 986e9ad

Browse files
committed
refactor(app): improve the module setup readiness experience
This is a little nicer. Split up the getNewModules code to separate modules between whether or not they need a pipette to be set up, so we can prompt for modules that can be set up immediately.
1 parent 43f4828 commit 986e9ad

File tree

5 files changed

+48
-50
lines changed

5 files changed

+48
-50
lines changed

app/src/App/hooks.ts

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useContext, useEffect, useRef } from 'react'
1+
import { useCallback, useContext, useEffect, useRef, useState } from 'react'
22
import { useTranslation } from 'react-i18next'
33
import { useQueryClient } from 'react-query'
44
import { useDispatch } from 'react-redux'
@@ -135,7 +135,14 @@ export function useProtocolReceiptToast(): void {
135135
}, [protocolIds])
136136
}
137137

138-
export function useGetNewModules(): AttachedModule[] {
138+
const MODULES_NOT_REQUIRING_PIPETTE_FOR_SETUP: ModuleType[] = [
139+
ABSORBANCE_READER_TYPE,
140+
FLEX_STACKER_MODULE_TYPE,
141+
]
142+
143+
const MODULES_NOT_REQUIRING_CALIBRATION = MODULES_NOT_REQUIRING_PIPETTE_FOR_SETUP
144+
145+
export function useGetUnlocatedModules(): AttachedModule[] {
139146
const attachedModules =
140147
useAttachedModules({
141148
refetchInterval: ATTACHED_MODULE_POLL_MS,
@@ -148,59 +155,54 @@ export function useGetNewModules(): AttachedModule[] {
148155
const modulesInDeckConfig = deckConfig
149156
?.filter(c => c.opentronsModuleSerialNumber)
150157
.map(m => m.opentronsModuleSerialNumber)
151-
const newModules = attachedModules.filter(
152-
m =>
153-
m.moduleOffset === undefined &&
154-
!modulesInDeckConfig.includes(m.serialNumber)
158+
return attachedModules.filter(
159+
m => !modulesInDeckConfig.includes(m.serialNumber)
155160
)
156-
return newModules
157161
}
158162
return []
159163
}
160164

161-
const MODULES_NOT_REQUIRING_PIPETTE_FOR_SETUP: ModuleType[] = [
162-
ABSORBANCE_READER_TYPE,
163-
FLEX_STACKER_MODULE_TYPE,
164-
]
165+
export function useGetModulesNeedingSetup(): AttachedModule[] {
166+
const allNewModules = useGetUnlocatedModules()
167+
console.log(`ugmns: ${allNewModules}`)
168+
return allNewModules.filter(
169+
m =>
170+
MODULES_NOT_REQUIRING_CALIBRATION.includes(m.moduleType) ||
171+
m.moduleOffset === undefined
172+
)
173+
}
174+
175+
export function useGetModulesNeedingSetupThatCanCurrentlyBeSetUp(): AttachedModule[] {
176+
const modulesRequiringSetup = useGetModulesNeedingSetup()
177+
const attachedPipettes = useAttachedPipettes(modulesRequiringSetup.length > 0)
178+
console.log(`ugmnstccbs: ${modulesRequiringSetup}`)
179+
return modulesRequiringSetup.filter(
180+
m =>
181+
MODULES_NOT_REQUIRING_PIPETTE_FOR_SETUP.includes(m.moduleType) ||
182+
attachedPipettes.left != null ||
183+
attachedPipettes.right != null
184+
)
185+
}
165186

166187
export function useModuleAttachedToast(
167188
launchModuleSetupCallback: () => void
168189
): void {
169-
const newModules = useGetNewModules()
170-
const currentRunId = useCurrentRunId({ refetchInterval: CURRENT_RUN_POLL })
171-
const modulesNotRequiringPipette = newModules
172-
.filter(thisModule =>
173-
MODULES_NOT_REQUIRING_PIPETTE_FOR_SETUP.includes(thisModule.moduleType)
174-
)
175-
.map(thisModule => thisModule.serialNumber)
176-
const moduleSerialsRequiringPipette = newModules
177-
.map(thisModule => thisModule.serialNumber)
178-
.filter(thisSerial => !modulesNotRequiringPipette.includes(thisSerial))
190+
const currentlySetuppableModules = useGetModulesNeedingSetupThatCanCurrentlyBeSetUp()
191+
console.log(`umat: ${currentlySetuppableModules}`)
179192

180-
const attachedPipettes = useAttachedPipettes(
181-
moduleSerialsRequiringPipette.length > 0
182-
)
193+
const currentRunId = useCurrentRunId({ refetchInterval: CURRENT_RUN_POLL })
183194
const { t, i18n } = useTranslation(['module_wizard_flows', 'shared'])
184195
const { makeToast } = useToaster()
185-
const moduleSerials = newModules.map(m => m.serialNumber)
196+
const moduleSerials = currentlySetuppableModules.map(m => m.serialNumber)
186197
const moduleSerialsRef = useRef(moduleSerials)
187198
const runInProgress = currentRunId != null
188199

200+
const [firstRun, setFirstRun] = useState<boolean>(true)
201+
189202
useEffect(() => {
190203
const newModuleSerials = difference(moduleSerials, moduleSerialsRef.current)
191-
const newModulesRequiringPipette = newModuleSerials.filter(serial =>
192-
moduleSerialsRequiringPipette.includes(serial)
193-
)
194-
const newModulesNotRequiringPipette = newModuleSerials.filter(
195-
serial => !moduleSerialsRequiringPipette.includes(serial)
196-
)
197-
const hasPipette =
198-
attachedPipettes.left != null || attachedPipettes.right != null
199-
if (
200-
!runInProgress &&
201-
((hasPipette && newModulesRequiringPipette.length > 0) ||
202-
newModulesNotRequiringPipette.length > 0)
203-
) {
204+
console.log(`umat effect: ${newModuleSerials}`)
205+
if (!runInProgress && newModuleSerials.length > 0) {
204206
makeToast(t('module_added') as string, 'info', {
205207
buttonText: i18n.format(t('shared:close'), 'capitalize'),
206208
linkText: t('module_added_link'),
@@ -210,9 +212,10 @@ export function useModuleAttachedToast(
210212
})
211213
}
212214
moduleSerialsRef.current = moduleSerials
215+
setFirstRun(false)
213216
// dont want this hook to rerun when other deps change
214217
// eslint-disable-next-line react-hooks/exhaustive-deps
215-
}, [moduleSerials, runInProgress, moduleSerialsRequiringPipette])
218+
}, [moduleSerials, runInProgress, firstRun])
216219
}
217220

218221
export function useScrollRef(): {

app/src/organisms/ModuleWizardFlows/SelectModule.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
getModuleDisplayName,
1919
} from '@opentrons/shared-data'
2020

21-
import { useGetNewModules } from '/app/App/hooks'
21+
import { useGetModulesNeedingSetupThatCanCurrentlyBeSetUp } from '/app/App/hooks'
2222
import { SmallButton } from '/app/atoms/buttons'
2323
import { i18n } from '/app/i18n'
2424
import { useModuleUSBPort } from '/app/local-resources/modules'
@@ -62,13 +62,13 @@ export function SelectModule(props: SelectModuleProps): JSX.Element | null {
6262
const { t } = useTranslation('module_wizard_flows')
6363

6464
const { parseModuleUSBPort } = useModuleUSBPort()
65-
const availableModules = useGetNewModules()
65+
const availableModules = useGetModulesNeedingSetupThatCanCurrentlyBeSetUp()
66+
const allSettupable = useGetModulesNeedingSetup()
6667
const allNewModules =
6768
attachedModuleOnLaunch !== null
6869
? [attachedModuleOnLaunch]
6970
: availableModules
70-
71-
const modulesNotRequiringPipette = allNewModules.filter(thisModule =>
71+
const modulesNotRequiringPipette = availableModules.filter(thisModule =>
7272
([
7373
ABSORBANCE_READER_TYPE,
7474
FLEX_STACKER_MODULE_TYPE,

app/src/organisms/ModuleWizardFlows/Success.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
} from '@opentrons/components'
1515
import { getModuleDisplayName } from '@opentrons/shared-data'
1616

17-
import { useGetNewModules } from '/app/App/hooks'
17+
import { useGetModulesNeedingSetupThatCanCurrentlyBeSetUp } from '/app/App/hooks'
1818
import { SmallButton } from '/app/atoms/buttons'
1919
import { SimpleWizardBody } from '/app/molecules/SimpleWizardBody'
2020

@@ -50,7 +50,7 @@ export function Success(props: SuccessProps): JSX.Element {
5050
const { t } = useTranslation('module_wizard_flows')
5151
const sendIdentifyStacker = useSendIdentifyStacker()
5252
const moduleDisplayName = getModuleDisplayName(attachedModule.moduleModel)
53-
const newModules = useGetNewModules()
53+
const newModules = useGetModulesNeedingSetupThatCanCurrentlyBeSetUp()
5454

5555
const handleOnClick = (restart: boolean): void => {
5656
if (restart) {

app/src/organisms/ModuleWizardFlows/index.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ export function ModuleWizardFlows(
6363
buildFlowForSelectedModule,
6464
patchModuleAfterUpdate,
6565
deckConfig,
66-
requirePipette,
6766
} = useModuleSetupWizard({ closeFlow, attachedModuleOnLaunch, onComplete })
6867

6968
// build out flow if there is a module passed in at launch
@@ -90,7 +89,6 @@ export function ModuleWizardFlows(
9089

9190
const doorStatus = useIsDoorOpen(robotName).isDoorOpen
9291

93-
if (wizardFlowBaseProps.attachedPipette == null && requirePipette) return null
9492
if (showLaunchSetup || wizardFlowBaseProps.attachedModule == null) {
9593
return (
9694
<ModuleWizardScreen

app/src/organisms/ModuleWizardFlows/useModuleSetupWizard.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ export interface UseModuleSetupWizardResult {
5959
buildFlowForSelectedModule: (module: AttachedModule) => void
6060
patchModuleAfterUpdate: (module: AttachedModule) => void
6161
deckConfig: DeckConfiguration
62-
requirePipette: boolean
6362
}
6463

6564
export interface UseModuleSetupWizardParams {
@@ -264,8 +263,6 @@ export function useModuleSetupWizard(
264263
deckConfig,
265264
buildFlowForSelectedModule,
266265
patchModuleAfterUpdate,
267-
requirePipette:
268-
attachedModuleOnLaunch?.moduleType === FLEX_STACKER_MODULE_TYPE,
269266
}
270267
}
271268

0 commit comments

Comments
 (0)