Skip to content

Commit

Permalink
feat(protocol-designer): allow 2 temp modules for OT-2 behind userFac… (
Browse files Browse the repository at this point in the history
#17465)

…ing flag

closes AUTH-1422
  • Loading branch information
jerader authored Feb 7, 2025
1 parent 632eb64 commit 8b833e7
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 34 deletions.
18 changes: 14 additions & 4 deletions protocol-designer/cypress/e2e/settings.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,20 @@ describe('The Settings Page', () => {
cy.openSettingsPage()
cy.verifySettingsPage()
// Timeline editing tips defaults to true
cy.getByAriaLabel('Settings_hotKeys')
cy.getByAriaLabel('Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY')
.should('exist')
.should('be.visible')
.should('have.attr', 'aria-checked', 'true')
// Multiple temp modules on OT-2 defaults to false
cy.getByAriaLabel('Settings_OT_PD_ENABLE_MULTIPLE_TEMPS_OT2')
.should('exist')
.should('be.visible')
.should('have.attr', 'aria-checked', 'false')
// Disable module restrictions defaults to false
cy.getByAriaLabel('Settings_OT_PD_DISABLE_MODULE_RESTRICTIONS')
.should('exist')
.should('be.visible')
.should('have.attr', 'aria-checked', 'false')
// Share sessions with Opentrons toggle defaults to off
cy.getByTestId('analyticsToggle')
.should('exist')
Expand All @@ -37,15 +47,15 @@ describe('The Settings Page', () => {
// Toggle off editing timeline tips
// Navigate away from the settings page
// Then return to see timeline tips remains toggled on
cy.getByAriaLabel('Settings_hotKeys').click()
cy.getByAriaLabel('Settings_hotKeys').should(
cy.getByAriaLabel('Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY').click()
cy.getByAriaLabel('Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY').should(
'have.attr',
'aria-checked',
'false'
)
cy.visit('/')
cy.openSettingsPage()
cy.getByAriaLabel('Settings_hotKeys').should(
cy.getByAriaLabel('Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY').should(
'have.attr',
'aria-checked',
'false'
Expand Down
2 changes: 1 addition & 1 deletion protocol-designer/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const locators = {
settings: 'Settings',
privacyPolicy: 'a[href="https://opentrons.com/privacy-policy"]',
eula: 'a[href="https://opentrons.com/eula"]',
privacyToggle: 'Settings_hotKeys',
privacyToggle: 'Settings_OT_PD_ENABLE_HOT_KEYS_DISPLAY',
analyticsToggleTestId: 'analyticsToggle',
confirm: 'Confirm',
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
},
"OT_PD_DISABLE_MODULE_RESTRICTIONS": {
"title": "Disable module placement restrictions",
"description_1": "Turn off all restrictions on module placement and related pipette crash guidance.",
"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. "
"description": "Turn off all restrictions on module placement and related pipette crash guidance."
},
"OT_PD_ALLOW_ALL_TIPRACKS": {
"title": "Allow all tip rack options",
Expand All @@ -31,5 +30,9 @@
"OT_PD_ENABLE_LIQUID_CLASSES": {
"title": "Enable liquid classes",
"description": "Enable liquid classes support"
},
"OT_PD_ENABLE_MULTIPLE_TEMPS_OT2": {
"title": "Allow two temperature modules on OT-2",
"description": "This experimental setting may cause collisions, and Opentrons will not be responsible for any damage resulting from its use."
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"trash_no_labware": "Cannot load labware into Trash Bin",
"trash_required": "A trash bin or waste chute is required",
"tubeRack": "Tube racks",
"two_item": "No more than 2 {{hardware}} allowed on the deck at one time",
"untitled_protocol": "Untitled protocol",
"upload_custom_labware": "Upload custom labware",
"waste_chute_no_labware": "Cannot load labware into Waste Chute",
Expand Down
2 changes: 2 additions & 0 deletions protocol-designer/src/feature-flags/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const initialFlags: Flags = {
OT_PD_ENABLE_REACT_SCAN: process.env.OT_PD_ENABLE_REACT_SCAN === '1' || false,
OT_PD_ENABLE_LIQUID_CLASSES:
process.env.OT_PD_ENABLE_LIQUID_CLASSES === '1' || false,
OT_PD_ENABLE_MULTIPLE_TEMPS_OT2:
process.env.OT_PD_ENABLE_MULTIPLE_TEMPS_OT2 === '1' || false,
}
// @ts-expect-error(sa, 2021-6-10): cannot use string literals as action type
// 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
Expand Down
4 changes: 4 additions & 0 deletions protocol-designer/src/feature-flags/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ export const getEnableLiquidClasses: Selector<boolean> = createSelector(
getFeatureFlagData,
flags => flags.OT_PD_ENABLE_LIQUID_CLASSES ?? false
)
export const getEnableMutlipleTempsOT2: Selector<boolean> = createSelector(
getFeatureFlagData,
flags => flags.OT_PD_ENABLE_MULTIPLE_TEMPS_OT2 ?? false
)
2 changes: 2 additions & 0 deletions protocol-designer/src/feature-flags/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ export type FlagTypes =
| 'OT_PD_ENABLE_HOT_KEYS_DISPLAY'
| 'OT_PD_ENABLE_REACT_SCAN'
| 'OT_PD_ENABLE_LIQUID_CLASSES'
| 'OT_PD_ENABLE_MULTIPLE_TEMPS_OT2'
// flags that are not in this list only show in prerelease mode
export const userFacingFlags: FlagTypes[] = [
'OT_PD_DISABLE_MODULE_RESTRICTIONS',
'OT_PD_ALLOW_ALL_TIPRACKS',
'OT_PD_ENABLE_HOT_KEYS_DISPLAY',
'OT_PD_ENABLE_MULTIPLE_TEMPS_OT2',
]
export const allFlags: FlagTypes[] = [
...userFacingFlags,
Expand Down
29 changes: 27 additions & 2 deletions protocol-designer/src/pages/Designer/DeckSetup/DeckSetupTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
MAGNETIC_MODULE_V2,
MODULE_MODELS,
OT2_ROBOT_TYPE,
TEMPERATURE_MODULE_TYPE,
} from '@opentrons/shared-data'

import { getRobotType } from '../../../file-data/selectors'
Expand All @@ -49,6 +50,7 @@ import {
selectNestedLabware,
selectZoomedIntoSlot,
} from '../../../labware-ingred/actions'
import { getEnableMutlipleTempsOT2 } from '../../../feature-flags/selectors'
import { useBlockingHint } from '../../../organisms/BlockingHintModal/useBlockingHint'
import { selectors } from '../../../labware-ingred/selectors'
import { useKitchen } from '../../../organisms/Kitchen/hooks'
Expand Down Expand Up @@ -102,6 +104,7 @@ export function DeckSetupTools(props: DeckSetupToolsProps): JSX.Element | null {
const selectedSlotInfo = useSelector(selectors.getZoomedInSlotInfo)
const robotType = useSelector(getRobotType)
const savedSteps = useSelector(getSavedStepForms)
const enableMultipleTempsOt2 = useSelector(getEnableMutlipleTempsOT2)
const [showDeleteLabwareModal, setShowDeleteLabwareModal] = useState<
ModuleModel | 'clear' | null
>(null)
Expand Down Expand Up @@ -612,8 +615,14 @@ export function DeckSetupTools(props: DeckSetupToolsProps): JSX.Element | null {
}) as string
)
} else if (
typeSomewhereOnDeck.length > 0 &&
robotType === OT2_ROBOT_TYPE
(!enableMultipleTempsOt2 &&
typeSomewhereOnDeck.length > 0 &&
robotType === OT2_ROBOT_TYPE) ||
(enableMultipleTempsOt2 &&
typeSomewhereOnDeck.length > 0 &&
getModuleType(model as ModuleModel) !==
TEMPERATURE_MODULE_TYPE &&
robotType === OT2_ROBOT_TYPE)
) {
makeSnackbar(
t('one_item', {
Expand All @@ -624,6 +633,22 @@ export function DeckSetupTools(props: DeckSetupToolsProps): JSX.Element | null {
),
}) as string
)
} else if (
enableMultipleTempsOt2 &&
typeSomewhereOnDeck.length > 1 &&
getModuleType(model as ModuleModel) ===
TEMPERATURE_MODULE_TYPE &&
robotType === OT2_ROBOT_TYPE
) {
makeSnackbar(
t('two_item', {
hardware: t(
`shared:${getModuleType(
selectedModel
).toLowerCase()}`
),
}) as string
)
} else if (collisionError != null) {
makeSnackbar(t(`${collisionError}`) as string)
} else if (
Expand Down
59 changes: 34 additions & 25 deletions protocol-designer/src/pages/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import { actions as featureFlagActions } from '../../feature-flags'
import { getFeatureFlagData } from '../../feature-flags/selectors'
import type { FlagTypes } from '../../feature-flags'

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

Expand Down Expand Up @@ -90,8 +89,14 @@ export function Settings(): JSX.Element {
)
}

const userFacingFlags: FlagTypes[] = [
'OT_PD_ENABLE_HOT_KEYS_DISPLAY',
'OT_PD_ENABLE_MULTIPLE_TEMPS_OT2',
'OT_PD_DISABLE_MODULE_RESTRICTIONS',
]

const prereleaseFlagRows = allFlags
.filter(flag => flag !== 'OT_PD_ENABLE_HOT_KEYS_DISPLAY')
.filter(flag => !userFacingFlags.includes(flag))
.map(toFlagRow)

return (
Expand Down Expand Up @@ -206,31 +211,35 @@ export function Settings(): JSX.Element {
</StyledText>
</Btn>
</ListItem>
<ListItem
padding={SPACING.spacing16}
justifyContent={JUSTIFY_SPACE_BETWEEN}
type="noActive"
>
<Flex flexDirection={DIRECTION_COLUMN}>
<StyledText desktopStyle="bodyDefaultSemiBold">
{t('OT_PD_ENABLE_HOT_KEYS_DISPLAY.title')}
</StyledText>
<Flex color={COLORS.grey60}>
<StyledText desktopStyle="bodyDefaultRegular">
{t('OT_PD_ENABLE_HOT_KEYS_DISPLAY.description')}
{userFacingFlags.map(flag => (
<ListItem
key={flag}
padding={SPACING.spacing16}
justifyContent={JUSTIFY_SPACE_BETWEEN}
type="noActive"
alignItems={ALIGN_CENTER}
>
<Flex flexDirection={DIRECTION_COLUMN}>
<StyledText desktopStyle="bodyDefaultSemiBold">
{t(`${flag}.title`)}
</StyledText>
<Flex color={COLORS.grey60}>
<StyledText desktopStyle="bodyDefaultRegular">
{t(`${flag}.description`)}
</StyledText>
</Flex>
</Flex>
</Flex>
<ToggleButton
label="Settings_hotKeys"
toggledOn={Boolean(flags[HOT_KEY_FLAG])}
onClick={() => {
setFeatureFlags({
OT_PD_ENABLE_HOT_KEYS_DISPLAY: !flags[HOT_KEY_FLAG],
})
}}
/>
</ListItem>
<ToggleButton
label={`Settings_${flag}`}
toggledOn={Boolean(flags[flag])}
onClick={() => {
setFeatureFlags({
[flag]: !flags[flag],
})
}}
/>
</ListItem>
))}
</Flex>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing8}>
<StyledText desktopStyle="bodyLargeSemiBold">
Expand Down

0 comments on commit 8b833e7

Please sign in to comment.