Skip to content

Commit 8b833e7

Browse files
authored
feat(protocol-designer): allow 2 temp modules for OT-2 behind userFac… (#17465)
…ing flag closes AUTH-1422
1 parent 632eb64 commit 8b833e7

File tree

9 files changed

+90
-34
lines changed

9 files changed

+90
-34
lines changed

protocol-designer/cypress/e2e/settings.cy.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,20 @@ describe('The Settings Page', () => {
1212
cy.openSettingsPage()
1313
cy.verifySettingsPage()
1414
// Timeline editing tips defaults to true
15-
cy.getByAriaLabel('Settings_hotKeys')
15+
cy.getByAriaLabel('Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY')
1616
.should('exist')
1717
.should('be.visible')
1818
.should('have.attr', 'aria-checked', 'true')
19+
// Multiple temp modules on OT-2 defaults to false
20+
cy.getByAriaLabel('Settings_OT_PD_ENABLE_MULTIPLE_TEMPS_OT2')
21+
.should('exist')
22+
.should('be.visible')
23+
.should('have.attr', 'aria-checked', 'false')
24+
// Disable module restrictions defaults to false
25+
cy.getByAriaLabel('Settings_OT_PD_DISABLE_MODULE_RESTRICTIONS')
26+
.should('exist')
27+
.should('be.visible')
28+
.should('have.attr', 'aria-checked', 'false')
1929
// Share sessions with Opentrons toggle defaults to off
2030
cy.getByTestId('analyticsToggle')
2131
.should('exist')
@@ -37,15 +47,15 @@ describe('The Settings Page', () => {
3747
// Toggle off editing timeline tips
3848
// Navigate away from the settings page
3949
// Then return to see timeline tips remains toggled on
40-
cy.getByAriaLabel('Settings_hotKeys').click()
41-
cy.getByAriaLabel('Settings_hotKeys').should(
50+
cy.getByAriaLabel('Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY').click()
51+
cy.getByAriaLabel('Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY').should(
4252
'have.attr',
4353
'aria-checked',
4454
'false'
4555
)
4656
cy.visit('/')
4757
cy.openSettingsPage()
48-
cy.getByAriaLabel('Settings_hotKeys').should(
58+
cy.getByAriaLabel('Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY').should(
4959
'have.attr',
5060
'aria-checked',
5161
'false'

protocol-designer/cypress/support/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export const locators = {
6262
settings: 'Settings',
6363
privacyPolicy: 'a[href="https://opentrons.com/privacy-policy"]',
6464
eula: 'a[href="https://opentrons.com/eula"]',
65-
privacyToggle: 'Settings_hotKeys',
65+
privacyToggle: 'Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY',
6666
analyticsToggleTestId: 'analyticsToggle',
6767
confirm: 'Confirm',
6868
}

protocol-designer/src/assets/localization/en/feature_flags.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
},
66
"OT_PD_DISABLE_MODULE_RESTRICTIONS": {
77
"title": "Disable module placement restrictions",
8-
"description_1": "Turn off all restrictions on module placement and related pipette crash guidance.",
9-
"description_2": "NOT recommended! Switching from default positions may cause crashes and the Protocol Designer cannot yet give guidance on what to expect. Use at your own discretion. "
8+
"description": "Turn off all restrictions on module placement and related pipette crash guidance."
109
},
1110
"OT_PD_ALLOW_ALL_TIPRACKS": {
1211
"title": "Allow all tip rack options",
@@ -31,5 +30,9 @@
3130
"OT_PD_ENABLE_LIQUID_CLASSES": {
3231
"title": "Enable liquid classes",
3332
"description": "Enable liquid classes support"
33+
},
34+
"OT_PD_ENABLE_MULTIPLE_TEMPS_OT2": {
35+
"title": "Allow two temperature modules on OT-2",
36+
"description": "This experimental setting may cause collisions, and Opentrons will not be responsible for any damage resulting from its use."
3437
}
3538
}

protocol-designer/src/assets/localization/en/starting_deck_state.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"trash_no_labware": "Cannot load labware into Trash Bin",
6363
"trash_required": "A trash bin or waste chute is required",
6464
"tubeRack": "Tube racks",
65+
"two_item": "No more than 2 {{hardware}} allowed on the deck at one time",
6566
"untitled_protocol": "Untitled protocol",
6667
"upload_custom_labware": "Upload custom labware",
6768
"waste_chute_no_labware": "Cannot load labware into Waste Chute",

protocol-designer/src/feature-flags/reducers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ const initialFlags: Flags = {
3030
OT_PD_ENABLE_REACT_SCAN: process.env.OT_PD_ENABLE_REACT_SCAN === '1' || false,
3131
OT_PD_ENABLE_LIQUID_CLASSES:
3232
process.env.OT_PD_ENABLE_LIQUID_CLASSES === '1' || false,
33+
OT_PD_ENABLE_MULTIPLE_TEMPS_OT2:
34+
process.env.OT_PD_ENABLE_MULTIPLE_TEMPS_OT2 === '1' || false,
3335
}
3436
// @ts-expect-error(sa, 2021-6-10): cannot use string literals as action type
3537
// TODO IMMEDIATELY: refactor this to the old fashioned way if we cannot have type safety: https://github.com/redux-utilities/redux-actions/issues/282#issuecomment-595163081

protocol-designer/src/feature-flags/selectors.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,7 @@ export const getEnableLiquidClasses: Selector<boolean> = createSelector(
4545
getFeatureFlagData,
4646
flags => flags.OT_PD_ENABLE_LIQUID_CLASSES ?? false
4747
)
48+
export const getEnableMutlipleTempsOT2: Selector<boolean> = createSelector(
49+
getFeatureFlagData,
50+
flags => flags.OT_PD_ENABLE_MULTIPLE_TEMPS_OT2 ?? false
51+
)

protocol-designer/src/feature-flags/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ export type FlagTypes =
3737
| 'OT_PD_ENABLE_HOT_KEYS_DISPLAY'
3838
| 'OT_PD_ENABLE_REACT_SCAN'
3939
| 'OT_PD_ENABLE_LIQUID_CLASSES'
40+
| 'OT_PD_ENABLE_MULTIPLE_TEMPS_OT2'
4041
// flags that are not in this list only show in prerelease mode
4142
export const userFacingFlags: FlagTypes[] = [
4243
'OT_PD_DISABLE_MODULE_RESTRICTIONS',
4344
'OT_PD_ALLOW_ALL_TIPRACKS',
4445
'OT_PD_ENABLE_HOT_KEYS_DISPLAY',
46+
'OT_PD_ENABLE_MULTIPLE_TEMPS_OT2',
4547
]
4648
export const allFlags: FlagTypes[] = [
4749
...userFacingFlags,

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
MAGNETIC_MODULE_V2,
3030
MODULE_MODELS,
3131
OT2_ROBOT_TYPE,
32+
TEMPERATURE_MODULE_TYPE,
3233
} from '@opentrons/shared-data'
3334

3435
import { getRobotType } from '../../../file-data/selectors'
@@ -49,6 +50,7 @@ import {
4950
selectNestedLabware,
5051
selectZoomedIntoSlot,
5152
} from '../../../labware-ingred/actions'
53+
import { getEnableMutlipleTempsOT2 } from '../../../feature-flags/selectors'
5254
import { useBlockingHint } from '../../../organisms/BlockingHintModal/useBlockingHint'
5355
import { selectors } from '../../../labware-ingred/selectors'
5456
import { useKitchen } from '../../../organisms/Kitchen/hooks'
@@ -102,6 +104,7 @@ export function DeckSetupTools(props: DeckSetupToolsProps): JSX.Element | null {
102104
const selectedSlotInfo = useSelector(selectors.getZoomedInSlotInfo)
103105
const robotType = useSelector(getRobotType)
104106
const savedSteps = useSelector(getSavedStepForms)
107+
const enableMultipleTempsOt2 = useSelector(getEnableMutlipleTempsOT2)
105108
const [showDeleteLabwareModal, setShowDeleteLabwareModal] = useState<
106109
ModuleModel | 'clear' | null
107110
>(null)
@@ -612,8 +615,14 @@ export function DeckSetupTools(props: DeckSetupToolsProps): JSX.Element | null {
612615
}) as string
613616
)
614617
} else if (
615-
typeSomewhereOnDeck.length > 0 &&
616-
robotType === OT2_ROBOT_TYPE
618+
(!enableMultipleTempsOt2 &&
619+
typeSomewhereOnDeck.length > 0 &&
620+
robotType === OT2_ROBOT_TYPE) ||
621+
(enableMultipleTempsOt2 &&
622+
typeSomewhereOnDeck.length > 0 &&
623+
getModuleType(model as ModuleModel) !==
624+
TEMPERATURE_MODULE_TYPE &&
625+
robotType === OT2_ROBOT_TYPE)
617626
) {
618627
makeSnackbar(
619628
t('one_item', {
@@ -624,6 +633,22 @@ export function DeckSetupTools(props: DeckSetupToolsProps): JSX.Element | null {
624633
),
625634
}) as string
626635
)
636+
} else if (
637+
enableMultipleTempsOt2 &&
638+
typeSomewhereOnDeck.length > 1 &&
639+
getModuleType(model as ModuleModel) ===
640+
TEMPERATURE_MODULE_TYPE &&
641+
robotType === OT2_ROBOT_TYPE
642+
) {
643+
makeSnackbar(
644+
t('two_item', {
645+
hardware: t(
646+
`shared:${getModuleType(
647+
selectedModel
648+
).toLowerCase()}`
649+
),
650+
}) as string
651+
)
627652
} else if (collisionError != null) {
628653
makeSnackbar(t(`${collisionError}`) as string)
629654
} else if (

protocol-designer/src/pages/Settings/index.tsx

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import { actions as featureFlagActions } from '../../feature-flags'
3232
import { getFeatureFlagData } from '../../feature-flags/selectors'
3333
import type { FlagTypes } from '../../feature-flags'
3434

35-
const HOT_KEY_FLAG = 'OT_PD_ENABLE_HOT_KEYS_DISPLAY'
3635
const PRIVACY_POLICY_URL = 'https://opentrons.com/privacy-policy'
3736
const EULA_URL = 'https://opentrons.com/eula'
3837

@@ -90,8 +89,14 @@ export function Settings(): JSX.Element {
9089
)
9190
}
9291

92+
const userFacingFlags: FlagTypes[] = [
93+
'OT_PD_ENABLE_HOT_KEYS_DISPLAY',
94+
'OT_PD_ENABLE_MULTIPLE_TEMPS_OT2',
95+
'OT_PD_DISABLE_MODULE_RESTRICTIONS',
96+
]
97+
9398
const prereleaseFlagRows = allFlags
94-
.filter(flag => flag !== 'OT_PD_ENABLE_HOT_KEYS_DISPLAY')
99+
.filter(flag => !userFacingFlags.includes(flag))
95100
.map(toFlagRow)
96101

97102
return (
@@ -206,31 +211,35 @@ export function Settings(): JSX.Element {
206211
</StyledText>
207212
</Btn>
208213
</ListItem>
209-
<ListItem
210-
padding={SPACING.spacing16}
211-
justifyContent={JUSTIFY_SPACE_BETWEEN}
212-
type="noActive"
213-
>
214-
<Flex flexDirection={DIRECTION_COLUMN}>
215-
<StyledText desktopStyle="bodyDefaultSemiBold">
216-
{t('OT_PD_ENABLE_HOT_KEYS_DISPLAY.title')}
217-
</StyledText>
218-
<Flex color={COLORS.grey60}>
219-
<StyledText desktopStyle="bodyDefaultRegular">
220-
{t('OT_PD_ENABLE_HOT_KEYS_DISPLAY.description')}
214+
{userFacingFlags.map(flag => (
215+
<ListItem
216+
key={flag}
217+
padding={SPACING.spacing16}
218+
justifyContent={JUSTIFY_SPACE_BETWEEN}
219+
type="noActive"
220+
alignItems={ALIGN_CENTER}
221+
>
222+
<Flex flexDirection={DIRECTION_COLUMN}>
223+
<StyledText desktopStyle="bodyDefaultSemiBold">
224+
{t(`${flag}.title`)}
221225
</StyledText>
226+
<Flex color={COLORS.grey60}>
227+
<StyledText desktopStyle="bodyDefaultRegular">
228+
{t(`${flag}.description`)}
229+
</StyledText>
230+
</Flex>
222231
</Flex>
223-
</Flex>
224-
<ToggleButton
225-
label="Settings_hotKeys"
226-
toggledOn={Boolean(flags[HOT_KEY_FLAG])}
227-
onClick={() => {
228-
setFeatureFlags({
229-
OT_PD_ENABLE_HOT_KEYS_DISPLAY: !flags[HOT_KEY_FLAG],
230-
})
231-
}}
232-
/>
233-
</ListItem>
232+
<ToggleButton
233+
label={`Settings_${flag}`}
234+
toggledOn={Boolean(flags[flag])}
235+
onClick={() => {
236+
setFeatureFlags({
237+
[flag]: !flags[flag],
238+
})
239+
}}
240+
/>
241+
</ListItem>
242+
))}
234243
</Flex>
235244
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing8}>
236245
<StyledText desktopStyle="bodyLargeSemiBold">

0 commit comments

Comments
 (0)