Skip to content

Commit 7b5eb51

Browse files
committed
initial implementation of stacker location identify
1 parent b0ca41b commit 7b5eb51

File tree

3 files changed

+124
-35
lines changed

3 files changed

+124
-35
lines changed

app/src/assets/localization/en/device_details.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"abs_reader_lid_status": "Lid status: {{status}}",
77
"abs_reader_status": "Absorbance Plate Reader Status",
88
"add": "Add",
9-
"add_fixture_description": "Add this hardware to your deck configuration. It will be referenced during protocol analysis.",
9+
"add_fixture_description": "Choose an item below to add to your deck configuration. It will be referenced during protocol analysis.",
1010
"add_to_slot": "Add to slot {{slotName}}",
1111
"add_to": "Add to {{slotName}}",
1212
"an_error_occurred_while_updating": "An error occurred while updating your pipette's settings.",
@@ -74,6 +74,7 @@
7474
"heater": "Heater",
7575
"height_ranges": "{{gen}} Height Ranges",
7676
"hot_to_the_touch": "<block>Module is <bold>hot</bold> to the touch</block>",
77+
"identify": "Identify",
7778
"input_out_of_range": "Input out of range",
7879
"instrument_attached": "Instrument attached",
7980
"instruments_and_modules": "Instruments and Modules",

app/src/organisms/DeviceDetailsDeckConfiguration/AddFixtureModal.tsx

Lines changed: 71 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ import type {
4141
CutoutId,
4242
} from '@opentrons/shared-data'
4343
import type { OddModalHeaderBaseProps } from '/app/molecules/OddModal/types'
44+
import { useSendIdentifyStacker } from '../ModuleWizardFlows/hooks'
45+
46+
const FLEX_STACKER_FIXTURE = 'flexStackerModuleV1'
47+
const MODULE_IDENTIFY_TIME_MS = 10000
4448

4549
interface AddFixtureModalProps {
4650
cutoutId: CutoutId
@@ -161,7 +165,10 @@ export function AddFixtureModal({
161165
)
162166
}
163167

164-
const handleAddFixture = (addedCutoutConfigs: CutoutConfigMap[]): void => {
168+
const sendIdentifyStacker = useSendIdentifyStacker()
169+
const attachedModules = useModulesQuery().data?.data
170+
171+
const handleAddFixture = (addedCutoutConfigs: CutoutConfigMap[], fixtureSerialNumber?: string): void => {
165172
const addedCutoutConfigsWithCombo = replaceCutoutFixtureWithComboFixture(
166173
addedCutoutConfigs,
167174
deckConfigWithAA,
@@ -175,10 +182,32 @@ export function AddFixtureModal({
175182
)
176183
}) as CutoutConfig[] // we can do this bc we are mapping each aa to the proper fixture
177184

185+
if (fixtureSerialNumber){
186+
const module = attachedModules?.find(
187+
m => m.serialNumber === fixtureSerialNumber
188+
) ?? null
189+
if ( module !== null){
190+
sendIdentifyStacker(module, false)
191+
}
192+
}
193+
178194
updateDeckConfiguration(newDeckConfig)
179195
closeModal()
180196
}
181197

198+
const handleIdentifyFixture = (fixtureSerialNumber: string): void => {
199+
const module = attachedModules?.find(
200+
m => m.serialNumber === fixtureSerialNumber
201+
) ?? null
202+
if ( module !== null){
203+
// Identify the stacker module
204+
sendIdentifyStacker(module, true, 'blue')
205+
//Ensure that the module reverts after a set time
206+
setTimeout(() =>{sendIdentifyStacker(module, false)}, MODULE_IDENTIFY_TIME_MS)
207+
}
208+
209+
}
210+
182211
const fixtureOptions = availableOptions.map(cutoutConfigs => {
183212
const usbPort = (modulesData?.data ?? []).find(
184213
m => m.serialNumber === cutoutConfigs[0].opentronsModuleSerialNumber
@@ -187,21 +216,44 @@ export function AddFixtureModal({
187216
usbPort?.hubPort != null
188217
? `${usbPort.port}.${usbPort.hubPort}`
189218
: usbPort?.port
190-
191-
return (
192-
<FixtureOption
193-
key={cutoutConfigs[0].cutoutFixtureId}
194-
optionName={getFixtureDisplayName(
195-
cutoutConfigs[0].cutoutFixtureId,
196-
portDisplay
197-
)}
198-
buttonText={t('add')}
199-
onClickHandler={() => {
200-
handleAddFixture(cutoutConfigs)
201-
}}
202-
isOnDevice={isOnDevice}
203-
/>
204-
)
219+
220+
const fixtureSerialNumber = cutoutConfigs[0].opentronsModuleSerialNumber
221+
if (fixtureSerialNumber !== undefined && cutoutConfigs[0].cutoutFixtureId.includes(FLEX_STACKER_FIXTURE)){
222+
return (
223+
<FixtureOption
224+
key={cutoutConfigs[0].cutoutFixtureId}
225+
optionName={getFixtureDisplayName(
226+
cutoutConfigs[0].cutoutFixtureId,
227+
portDisplay
228+
)}
229+
buttonText={t('add')}
230+
onClickHandler={() => {
231+
handleAddFixture(cutoutConfigs, fixtureSerialNumber)
232+
}}
233+
secondaryButtonText={t('identify')}
234+
secondaryOnClickHandler={() => {
235+
handleIdentifyFixture(fixtureSerialNumber)}
236+
}
237+
isOnDevice={isOnDevice}
238+
/>
239+
)
240+
}
241+
else{
242+
return (
243+
<FixtureOption
244+
key={cutoutConfigs[0].cutoutFixtureId}
245+
optionName={getFixtureDisplayName(
246+
cutoutConfigs[0].cutoutFixtureId,
247+
portDisplay
248+
)}
249+
buttonText={t('add')}
250+
onClickHandler={() => {
251+
handleAddFixture(cutoutConfigs)
252+
}}
253+
isOnDevice={isOnDevice}
254+
/>
255+
)
256+
}
205257
})
206258

207259
return (
@@ -224,6 +276,9 @@ export function AddFixtureModal({
224276
</Flex>
225277
</OddModal>
226278
) : (
279+
// This is the modal with the module fixtures
280+
// Something that checks if this is a stacker module with a TODO to remove/update if other identifiable modules are added
281+
// Call to the use identify thing that transitions back to regular after a second?
227282
<Modal {...modalProps}>
228283
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing16}>
229284
<StyledText desktopStyle="bodyDefaultRegular">
Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,67 @@
11
import { TertiaryButton } from '../../atoms/buttons'
22
import { ListItem } from '../../atoms/ListItem/index'
33
import { StyledText } from '../../atoms/StyledText'
4-
import { ALIGN_CENTER, JUSTIFY_SPACE_BETWEEN } from '../../styles'
4+
import { Flex } from '../../primitives'
5+
import { ALIGN_CENTER, JUSTIFY_FLEX_END, JUSTIFY_SPACE_BETWEEN } from '../../styles'
56
import { SPACING } from '../../ui-style-constants'
67

78
import type { MouseEventHandler } from 'react'
89

910
interface FixtureOptionProps {
1011
onClickHandler: MouseEventHandler
12+
secondaryOnClickHandler?: MouseEventHandler
1113
optionName: string
14+
secondaryButtonText?: string
1215
buttonText: string
1316
isOnDevice: boolean
1417
}
1518
export function FixtureOption(props: FixtureOptionProps): JSX.Element {
16-
const { onClickHandler, optionName, buttonText } = props
17-
return (
18-
<ListItem
19-
type="default"
20-
padding={SPACING.spacing16 + ' ' + SPACING.spacing24}
21-
alignItems={ALIGN_CENTER}
22-
justifyContent={JUSTIFY_SPACE_BETWEEN}
23-
>
24-
<StyledText desktopStyle="bodyDefaultSemiBold">{optionName}</StyledText>
25-
<TertiaryButton
26-
buttonType="primary"
27-
onClick={onClickHandler}
28-
data-testid={optionName}
19+
const { onClickHandler, optionName, buttonText, secondaryOnClickHandler, secondaryButtonText } = props
20+
if (secondaryOnClickHandler !== null && secondaryButtonText !== undefined){
21+
return (
22+
<ListItem
23+
type="default"
24+
padding={SPACING.spacing16 + ' ' + SPACING.spacing24}
25+
alignItems={ALIGN_CENTER}
26+
justifyContent={JUSTIFY_SPACE_BETWEEN}
2927
>
30-
{buttonText}
31-
</TertiaryButton>
32-
</ListItem>
33-
)
28+
<StyledText desktopStyle="bodyDefaultSemiBold">{optionName}</StyledText>
29+
<Flex gridGap={SPACING.spacing4} width={"10rem"} justifyContent={JUSTIFY_FLEX_END}>
30+
<TertiaryButton
31+
buttonType="secondary"
32+
onClick={secondaryOnClickHandler}
33+
data-testid={optionName}
34+
>
35+
{secondaryButtonText}
36+
</TertiaryButton>
37+
<TertiaryButton
38+
buttonType="primary"
39+
onClick={onClickHandler}
40+
data-testid={optionName}
41+
>
42+
{buttonText}
43+
</TertiaryButton>
44+
</Flex>
45+
</ListItem>
46+
)
47+
}
48+
else{
49+
return (
50+
<ListItem
51+
type="default"
52+
padding={SPACING.spacing16 + ' ' + SPACING.spacing24}
53+
alignItems={ALIGN_CENTER}
54+
justifyContent={JUSTIFY_SPACE_BETWEEN}
55+
>
56+
<StyledText desktopStyle="bodyDefaultSemiBold">{optionName}</StyledText>
57+
<TertiaryButton
58+
buttonType="primary"
59+
onClick={onClickHandler}
60+
data-testid={optionName}
61+
>
62+
{buttonText}
63+
</TertiaryButton>
64+
</ListItem>
65+
)
66+
}
3467
}

0 commit comments

Comments
 (0)