From 5030e9d842bd3af1e25adadd81764d5151a1e812 Mon Sep 17 00:00:00 2001 From: Jethary Date: Thu, 19 Dec 2024 12:23:15 -0500 Subject: [PATCH 1/6] refactor the dropdown text --- .../hardware-sim/DeckConfigurator/index.tsx | 2 + .../src/molecules/DropdownMenu/index.tsx | 28 +++++- .../assets/localization/en/application.json | 1 + .../molecules/DropdownStepFormField/index.tsx | 28 +++++- .../top-selectors/labware-locations/index.ts | 14 +-- .../ui/labware/__tests__/selectors.test.ts | 50 +++++----- protocol-designer/src/ui/labware/selectors.ts | 72 +++++++------- protocol-designer/src/ui/labware/utils.ts | 94 ++++++++++++------- protocol-designer/src/ui/modules/utils.ts | 19 ++-- 9 files changed, 196 insertions(+), 112 deletions(-) diff --git a/components/src/hardware-sim/DeckConfigurator/index.tsx b/components/src/hardware-sim/DeckConfigurator/index.tsx index 4a03ff6c866..65bb6968a45 100644 --- a/components/src/hardware-sim/DeckConfigurator/index.tsx +++ b/components/src/hardware-sim/DeckConfigurator/index.tsx @@ -38,6 +38,8 @@ import { MagneticBlockFixture } from './MagneticBlockFixture' import { ThermocyclerFixture } from './ThermocyclerFixture' import { AbsorbanceReaderFixture } from './AbsorbanceReaderFixture' +export * from './constants' + interface DeckConfiguratorProps { deckConfig: DeckConfiguration handleClickAdd: (cutoutId: CutoutId) => void diff --git a/components/src/molecules/DropdownMenu/index.tsx b/components/src/molecules/DropdownMenu/index.tsx index 3fb38f8f531..719ae413b7c 100644 --- a/components/src/molecules/DropdownMenu/index.tsx +++ b/components/src/molecules/DropdownMenu/index.tsx @@ -24,6 +24,7 @@ import { MenuItem } from '../../atoms/MenuList/MenuItem' import { Tooltip } from '../../atoms/Tooltip' import { StyledText } from '../../atoms/StyledText' import { LiquidIcon } from '../LiquidIcon' +import { DeckInfoLabel } from '..' export interface DropdownOption { name: string @@ -32,6 +33,8 @@ export interface DropdownOption { liquidColor?: string /** optional dropdown option for adding the deck label */ deckLabel?: string + /** subtext below the name */ + subtext?: string disabled?: boolean tooltipText?: string } @@ -250,7 +253,11 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element { {currentOption.liquidColor != null ? ( ) : null} + {currentOption.deckLabel != null ? ( + + ) : null} ) : null} - {option.name} + {option.deckLabel != null ? ( + + ) : null} + + + {option.name} + + + {option.subtext} + + {option.tooltipText != null ? ( diff --git a/protocol-designer/src/assets/localization/en/application.json b/protocol-designer/src/assets/localization/en/application.json index 3692c9a1fac..eec2fbd585b 100644 --- a/protocol-designer/src/assets/localization/en/application.json +++ b/protocol-designer/src/assets/localization/en/application.json @@ -16,6 +16,7 @@ "magnet_height_caption": "Must be between {{low}} to {{high}}.", "magnet_recommended": "The recommended height is {{default}}", "manually": "Manually", + "mix": "Mix", "module_and_slot": "{{moduleLongName}} in Slot {{slotName}}", "n_steps_selected": "{{n}} steps selected", "networking": { diff --git a/protocol-designer/src/molecules/DropdownStepFormField/index.tsx b/protocol-designer/src/molecules/DropdownStepFormField/index.tsx index 2714a73156b..d40fcc7063f 100644 --- a/protocol-designer/src/molecules/DropdownStepFormField/index.tsx +++ b/protocol-designer/src/molecules/DropdownStepFormField/index.tsx @@ -1,8 +1,10 @@ import { useTranslation } from 'react-i18next' import { useDispatch } from 'react-redux' import { + ALIGN_CENTER, COLORS, DIRECTION_COLUMN, + DeckInfoLabel, DropdownMenu, Flex, ListItem, @@ -108,10 +110,28 @@ export function DropdownStepFormField( {title} - - - {options[0].name} - + + {options[0].deckLabel != null ? ( + + ) : null} + + + {options[0].name} + + + {options[0].subtext} + + diff --git a/protocol-designer/src/top-selectors/labware-locations/index.ts b/protocol-designer/src/top-selectors/labware-locations/index.ts index 34cd5fad561..6a2c5143b00 100644 --- a/protocol-designer/src/top-selectors/labware-locations/index.ts +++ b/protocol-designer/src/top-selectors/labware-locations/index.ts @@ -166,8 +166,8 @@ export const getUnoccupiedLabwareLocationOptions: Selector< { name: modIdWithAdapter != null - ? `${adapterDisplayName} on top of ${moduleUnderAdapter} in slot ${moduleSlotInfo}` - : `${adapterDisplayName} on slot ${adapterSlotInfo}`, + ? `${moduleSlotInfo} on ${moduleUnderAdapter} with ${adapterDisplayName}` + : `${adapterSlotInfo} with ${adapterDisplayName}`, value: labwareId, }, ] @@ -186,13 +186,9 @@ export const getUnoccupiedLabwareLocationOptions: Selector< : [ ...acc, { - name: `${getModuleDisplayName( + name: `${modOnDeck.slot} on ${getModuleDisplayName( moduleEntities[modId].model - )} in slot ${ - modOnDeck.slot === 'span7_8_10_11' - ? '7, 8, 10, 11' - : modOnDeck.slot - }`, + )}`, value: modId, }, ] @@ -234,7 +230,7 @@ export const getUnoccupiedLabwareLocationOptions: Selector< ) }) .map(slotId => ({ name: slotId, value: slotId })) - const offDeck = { name: 'Off-Deck', value: 'offDeck' } + const offDeck = { name: 'Off-deck', value: 'offDeck' } const wasteChuteSlot = { name: 'Waste Chute in D3', value: WASTE_CHUTE_CUTOUT, diff --git a/protocol-designer/src/ui/labware/__tests__/selectors.test.ts b/protocol-designer/src/ui/labware/__tests__/selectors.test.ts index 00359673dbb..e2d514ba787 100644 --- a/protocol-designer/src/ui/labware/__tests__/selectors.test.ts +++ b/protocol-designer/src/ui/labware/__tests__/selectors.test.ts @@ -23,6 +23,7 @@ import { } from '@opentrons/shared-data/labware/fixtures/2' import type { LabwareEntities } from '@opentrons/step-generation' +import type { InitialDeckSetup } from '../../../step-forms' describe('labware selectors', () => { let names: Record @@ -102,7 +103,7 @@ describe('labware selectors', () => { expect( // @ts-expect-error(sa, 2021-6-15): resultFunc getDisposalOptions.resultFunc(additionalEquipmentEntities) - ).toEqual([{ name: 'Trash Bin', value: mockTrashId }]) + ).toEqual([{ name: 'Trash bin', value: mockTrashId }]) }) it('filters out additional equipment that is NOT trash when multiple trash bins present', () => { const mockTrashId = 'mockTrashId' @@ -129,8 +130,8 @@ describe('labware selectors', () => { // @ts-expect-error(sa, 2021-6-15): resultFunc getDisposalOptions.resultFunc(additionalEquipmentEntities) ).toEqual([ - { name: 'Trash Bin', value: mockTrashId }, - { name: 'Trash Bin', value: mockTrashId2 }, + { name: 'Trash bin', value: mockTrashId }, + { name: 'Trash bin', value: mockTrashId2 }, ]) }) }) @@ -142,7 +143,12 @@ describe('labware selectors', () => { getLabwareOptions.resultFunc( {}, {}, - { labware: {}, modules: {}, pipettes: {} }, + { + labware: {}, + modules: {}, + pipettes: {}, + additionalEquipmentOnDeck: {}, + }, {}, {}, {} @@ -153,13 +159,13 @@ describe('labware selectors', () => { it('should return labware options when no modules are present, with no tipracks', () => { const labwareEntities = { ...tipracks, - ...trash, ...otherLabware, } - const initialDeckSetup = { + const initialDeckSetup: InitialDeckSetup = { labware: labwareEntities, modules: {}, pipettes: {}, + additionalEquipmentOnDeck: {}, } expect( // @ts-expect-error(sa, 2021-6-15): resultFunc @@ -171,13 +177,10 @@ describe('labware selectors', () => { {}, {} ) - ).toEqual([ - { name: 'Source Plate', value: 'wellPlateId' }, - { name: 'Trash', value: mockTrash }, - ]) + ).toEqual([{ name: 'Source Plate', value: 'wellPlateId' }]) }) - it('should return labware options with module prefixes when a labware is on module', () => { + it('should return labware options with no module prefixes even when a labware is on module', () => { const labware = { wellPlateId: { ...otherLabware.wellPlateId, @@ -200,12 +203,15 @@ describe('labware selectors', () => { }, } const labwareEntities = { ...trash, ...labware } - const initialDeckSetup = { + const initialDeckSetup: InitialDeckSetup = { pipettes: {}, labware: { ...trash, ...labware, }, + additionalEquipmentOnDeck: { + trash: { id: 'trash', location: 'cutout12', name: 'trashBin' }, + }, modules: { magModuleId: { id: 'magModuleId', @@ -223,7 +229,7 @@ describe('labware selectors', () => { id: 'thermocyclerId', type: THERMOCYCLER_MODULE_TYPE, model: THERMOCYCLER_MODULE_V1, - slot: SPAN7_8_10_11_SLOT, + slot: '8', }, heaterShakerId: { id: 'heaterShakerId', @@ -253,11 +259,11 @@ describe('labware selectors', () => { {} ) ).toEqual([ - { name: 'HS Plate in Heater-Shaker', value: 'hsPlateId' }, - { name: 'TC Plate in Thermocycler', value: 'tcPlateId' }, - { name: 'Temp Plate in Temperature Module', value: 'tempPlateId' }, + { name: 'HS Plate in 6', value: 'hsPlateId' }, + { name: 'TC Plate in A1+B1', value: 'tcPlateId' }, + { name: 'Temp Plate in 3', value: 'tempPlateId' }, { name: 'Trash', value: mockTrash }, - { name: 'Well Plate in Magnetic Module', value: 'wellPlateId' }, + { name: 'Well Plate in 1', value: 'wellPlateId' }, ]) }) @@ -269,10 +275,9 @@ describe('labware selectors', () => { }, } const labwareEntities = { ...trash, ...labware } - const initialDeckSetup = { + const initialDeckSetup: InitialDeckSetup = { pipettes: {}, labware: { - ...trash, ...labware, }, modules: { @@ -283,6 +288,9 @@ describe('labware selectors', () => { slot: '1', }, }, + additionalEquipmentOnDeck: { + trash: { id: 'trash', name: 'trashBin', location: 'cutout12' }, + }, } const nicknames: Record = { @@ -312,14 +320,14 @@ describe('labware selectors', () => { ) ).toEqual([ { name: 'Trash', value: mockTrash }, - { name: 'Well Plate in Magnetic Module', value: 'wellPlateId' }, + { name: 'Well Plate in 1', value: 'wellPlateId' }, ]) }) }) describe('_sortLabwareDropdownOptions', () => { const trashOption = { - name: 'Trash Bin', + name: 'Trash bin', value: mockTrash, } const zzzPlateOption = { name: 'Zzz Plate', value: 'zzz' } diff --git a/protocol-designer/src/ui/labware/selectors.ts b/protocol-designer/src/ui/labware/selectors.ts index 2839d001078..522b758ca30 100644 --- a/protocol-designer/src/ui/labware/selectors.ts +++ b/protocol-designer/src/ui/labware/selectors.ts @@ -1,11 +1,20 @@ import { createSelector } from 'reselect' import mapValues from 'lodash/mapValues' import reduce from 'lodash/reduce' -import { getIsTiprack, getLabwareDisplayName } from '@opentrons/shared-data' +import { + WASTE_CHUTE_DISPLAY_NAME, + TRASH_BIN_DISPLAY_NAME, +} from '@opentrons/components' +import { + FLEX_ROBOT_TYPE, + OT2_ROBOT_TYPE, + RobotType, + getIsTiprack, + getLabwareDisplayName, +} from '@opentrons/shared-data' import * as stepFormSelectors from '../../step-forms/selectors' import { selectors as labwareIngredSelectors } from '../../labware-ingred/selectors' -import { getModuleShortNames, getModuleUnderLabware } from '../modules/utils' -import { getLabwareOffDeck, getLabwareInColumn4 } from './utils' +import { getLabwareLatestSlot } from './utils' import type { LabwareEntity, @@ -18,8 +27,6 @@ import type { SavedStepFormState, } from '../../step-forms' -const TRASH = 'Trash Bin' - export const getLabwareNicknamesById: Selector< Record > = createSelector( @@ -37,8 +44,8 @@ export const _sortLabwareDropdownOptions = ( ): DropdownOption[] => options.sort((a, b) => { // special case for trash (always at the bottom of the list) - if (a.name === TRASH) return 1 - if (b.name === TRASH) return -1 + if (a.name === TRASH_BIN_DISPLAY_NAME) return 1 + if (b.name === TRASH_BIN_DISPLAY_NAME) return -1 // sort by name everything else by name return a.name.localeCompare(b.name) }) @@ -47,35 +54,21 @@ const getNickname = ( nicknamesById: Record, initialDeckSetup: AllTemporalPropertiesForTimelineFrame, labwareId: string, - savedStepForms: SavedStepFormState + savedStepForms: SavedStepFormState, + robotType: RobotType ): string => { - const isOffDeck = getLabwareOffDeck( - initialDeckSetup, - savedStepForms ?? {}, - labwareId - ) - - const moduleOnDeck = getModuleUnderLabware( - initialDeckSetup, - savedStepForms ?? {}, - labwareId - ) - const module = - moduleOnDeck != null ? getModuleShortNames(moduleOnDeck.type) : null - - const isLabwareInColumn4 = getLabwareInColumn4( + const latestSlot = getLabwareLatestSlot( initialDeckSetup, savedStepForms ?? {}, - labwareId + labwareId, + robotType ) let nickName: string = nicknamesById[labwareId] - if (module != null) { - nickName = `${nicknamesById[labwareId]} in ${module}` - } else if (isOffDeck) { + if (latestSlot != null && latestSlot !== 'offDeck') { + nickName = `${nicknamesById[labwareId]} in ${latestSlot}` + } else if (latestSlot != null && latestSlot === 'offDeck') { nickName = `${nicknamesById[labwareId]} off-deck` - } else if (isLabwareInColumn4) { - nickName = `${nicknamesById[labwareId]} in staging area slot` } return nickName } @@ -110,6 +103,11 @@ export const getMoveLabwareOptions: Selector = createSelector( const wasteChuteLocation = Object.values(additionalEquipmentEntities).find( aE => aE.name === 'wasteChute' )?.location + const trashBinLocation = Object.values(additionalEquipmentEntities).find( + aE => aE.name === 'trashBin' + )?.location + const robotType = + trashBinLocation === 'cutout12' ? OT2_ROBOT_TYPE : FLEX_ROBOT_TYPE const moveLabwareOptions = reduce( labwareEntities, ( @@ -131,7 +129,8 @@ export const getMoveLabwareOptions: Selector = createSelector( nicknamesById, initialDeckSetup, labwareId, - savedStepForms + savedStepForms, + robotType ) // filter out moving trash, adapters, and labware in @@ -171,6 +170,12 @@ export const getLabwareOptions: Selector = createSelector( const wasteChuteLocation = Object.values(additionalEquipmentEntities).find( aE => aE.name === 'wasteChute' )?.location + const trashBinLocation = Object.values(additionalEquipmentEntities).find( + aE => aE.name === 'trashBin' + )?.location + const robotType = + trashBinLocation === 'cutout12' ? OT2_ROBOT_TYPE : FLEX_ROBOT_TYPE + const labwareOptions = reduce( labwareEntities, ( @@ -191,7 +196,8 @@ export const getLabwareOptions: Selector = createSelector( nicknamesById, initialDeckSetup, labwareId, - savedStepForms + savedStepForms, + robotType ) return getIsTiprack(labwareEntity.def) || @@ -222,7 +228,7 @@ export const getWasteChuteOption: Selector = createSelect const wasteChuteOption: DropdownOption | null = wasteChuteEntity != null ? { - name: 'Waste Chute', + name: WASTE_CHUTE_DISPLAY_NAME, value: wasteChuteEntity.id, } : null @@ -246,7 +252,7 @@ export const getDisposalOptions = createSelector( ? [ ...acc, { - name: TRASH, + name: TRASH_BIN_DISPLAY_NAME, value: additionalEquipment.id ?? '', }, ] diff --git a/protocol-designer/src/ui/labware/utils.ts b/protocol-designer/src/ui/labware/utils.ts index 2377f7976db..cfa2922ea54 100644 --- a/protocol-designer/src/ui/labware/utils.ts +++ b/protocol-designer/src/ui/labware/utils.ts @@ -1,39 +1,49 @@ -import { COLUMN_4_SLOTS } from '@opentrons/step-generation' +import { getHasWasteChute } from '@opentrons/step-generation' +import { + FLEX_ROBOT_TYPE, + RobotType, + THERMOCYCLER_MODULE_TYPE, +} from '@opentrons/shared-data' +import { WASTE_CHUTE_DISPLAY_NAME } from '@opentrons/components' import type { InitialDeckSetup, SavedStepFormState } from '../../step-forms' -export function getLabwareOffDeck( - initialDeckSetup: InitialDeckSetup, - savedStepFormState: SavedStepFormState, - labwareId: string -): boolean { - // latest moveLabware step related to labwareId - const moveLabwareStep = Object.values(savedStepFormState) - .filter( - state => - state.stepType === 'moveLabware' && - labwareId != null && - state.labware === labwareId - ) - .reverse()[0] - - if (moveLabwareStep?.newLocation === 'offDeck') { - return true - } else if ( - moveLabwareStep == null && - initialDeckSetup.labware[labwareId]?.slot === 'offDeck' - ) { - return true - } else return false +function resolveSlotLocation( + modules: InitialDeckSetup['modules'], + labware: InitialDeckSetup['labware'], + location: string, + robotType: RobotType +): string { + const TCSlot = robotType === FLEX_ROBOT_TYPE ? 'A1+B1' : '8,9,10,11' + if (location === 'offDeck') { + return 'offDeck' + } else if (modules[location] != null) { + return modules[location].type === THERMOCYCLER_MODULE_TYPE + ? TCSlot + : modules[location].slot + } else if (labware[location] != null) { + const adapter = labware[location] + if (modules[adapter.slot] != null) { + return modules[adapter.slot].type === THERMOCYCLER_MODULE_TYPE + ? TCSlot + : modules[adapter.slot].slot + } else { + return adapter.slot + } + } else { + return location + } } -export function getLabwareInColumn4( +export function getLabwareLatestSlot( initialDeckSetup: InitialDeckSetup, savedStepForms: SavedStepFormState, - labwareId: string -): boolean { - const isStartingInColumn4 = COLUMN_4_SLOTS.includes( - initialDeckSetup.labware[labwareId]?.slot - ) + labwareId: string, + robotType: RobotType +): string | null { + const { modules, labware, additionalEquipmentOnDeck } = initialDeckSetup + const initialSlot = labware[labwareId]?.slot + const hasWasteChute = getHasWasteChute(additionalEquipmentOnDeck) + // latest moveLabware step related to labwareId const moveLabwareStep = Object.values(savedStepForms) .filter( @@ -45,13 +55,25 @@ export function getLabwareInColumn4( .reverse()[0] if ( - moveLabwareStep?.newLocation != null && - COLUMN_4_SLOTS.includes(moveLabwareStep.newLocation as string) + hasWasteChute && + (initialSlot === 'D3' || moveLabwareStep?.newLocation === 'D3') ) { - return true - } else if (moveLabwareStep == null && isStartingInColumn4) { - return true + return WASTE_CHUTE_DISPLAY_NAME + } + + if (moveLabwareStep?.newLocation != null) { + return resolveSlotLocation( + modules, + labware, + moveLabwareStep.newLocation, + robotType + ) + } else if (moveLabwareStep == null) { + return resolveSlotLocation(modules, labware, initialSlot, robotType) } else { - return false + console.warn( + `Expected to find labware's location but could not with initial slot ${initialSlot}` + ) + return null } } diff --git a/protocol-designer/src/ui/modules/utils.ts b/protocol-designer/src/ui/modules/utils.ts index e1d26bb840c..e0470d9623f 100644 --- a/protocol-designer/src/ui/modules/utils.ts +++ b/protocol-designer/src/ui/modules/utils.ts @@ -77,7 +77,7 @@ export function getModuleUnderLabware( export const getModuleShortNames = (type: ModuleType): string => { switch (type) { case 'heaterShakerModuleType': - return 'Heater-Shaker' + return 'Heater-Shaker Module' case 'magneticBlockType': return 'Magnetic Block' case 'magneticModuleType': @@ -110,22 +110,25 @@ export function getModuleLabwareOptions( )?.id if (labwareOnAdapterId != null) { return { - name: `${nicknamesById[labwareOnAdapterId]} in ${ - nicknamesById[labware.id] - } in ${module} in slot ${moduleOnDeck.slot}`, + name: `${nicknamesById[labware.id]} with ${ + nicknamesById[labwareOnAdapterId] + }`, + deckLabel: moduleOnDeck.slot, + subtext: module, value: moduleOnDeck.id, } } else { return { - name: `${nicknamesById[labware.id]} in ${module} in slot ${ - moduleOnDeck.slot - }`, + name: nicknamesById[labware.id], + deckLabel: moduleOnDeck.slot, + subtext: module, value: moduleOnDeck.id, } } } else { return { - name: `No labware in ${module} in slot ${moduleOnDeck.slot}`, + name: module, + deckLabel: moduleOnDeck.slot, value: moduleOnDeck.id, } } From cda3432f7f5e6fc9f49945ea87e90eb0282f2ad5 Mon Sep 17 00:00:00 2001 From: Jethary Date: Thu, 19 Dec 2024 12:35:57 -0500 Subject: [PATCH 2/6] fix(protocol-designer): dropdown option text refinement closes RQA-3773 RQA-3774 RQA-3777 --- .../src/hardware-sim/DeckConfigurator/index.tsx | 2 -- .../__tests__/MaterialsListModal.test.tsx | 2 +- .../src/ui/labware/__tests__/selectors.test.ts | 8 +++----- protocol-designer/src/ui/labware/selectors.ts | 14 ++++++-------- protocol-designer/src/ui/labware/utils.ts | 3 +-- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/components/src/hardware-sim/DeckConfigurator/index.tsx b/components/src/hardware-sim/DeckConfigurator/index.tsx index 65bb6968a45..4a03ff6c866 100644 --- a/components/src/hardware-sim/DeckConfigurator/index.tsx +++ b/components/src/hardware-sim/DeckConfigurator/index.tsx @@ -38,8 +38,6 @@ import { MagneticBlockFixture } from './MagneticBlockFixture' import { ThermocyclerFixture } from './ThermocyclerFixture' import { AbsorbanceReaderFixture } from './AbsorbanceReaderFixture' -export * from './constants' - interface DeckConfiguratorProps { deckConfig: DeckConfiguration handleClickAdd: (cutoutId: CutoutId) => void diff --git a/protocol-designer/src/organisms/MaterialsListModal/__tests__/MaterialsListModal.test.tsx b/protocol-designer/src/organisms/MaterialsListModal/__tests__/MaterialsListModal.test.tsx index d18fa1e52de..26e2d0fb098 100644 --- a/protocol-designer/src/organisms/MaterialsListModal/__tests__/MaterialsListModal.test.tsx +++ b/protocol-designer/src/organisms/MaterialsListModal/__tests__/MaterialsListModal.test.tsx @@ -137,7 +137,7 @@ describe('MaterialsListModal', () => { lidTargetTemp: null, lidOpen: false, }, - slot: 'span7_8_10_11', + slot: '7', type: 'thermocyclerModuleType', }, ] as ModuleOnDeck[] diff --git a/protocol-designer/src/ui/labware/__tests__/selectors.test.ts b/protocol-designer/src/ui/labware/__tests__/selectors.test.ts index e2d514ba787..e2c74b75508 100644 --- a/protocol-designer/src/ui/labware/__tests__/selectors.test.ts +++ b/protocol-designer/src/ui/labware/__tests__/selectors.test.ts @@ -9,7 +9,6 @@ import { THERMOCYCLER_MODULE_TYPE, THERMOCYCLER_MODULE_V1, } from '@opentrons/shared-data' -import { SPAN7_8_10_11_SLOT } from '../../../constants' import { getDisposalOptions, getLabwareOptions, @@ -23,7 +22,6 @@ import { } from '@opentrons/shared-data/labware/fixtures/2' import type { LabwareEntities } from '@opentrons/step-generation' -import type { InitialDeckSetup } from '../../../step-forms' describe('labware selectors', () => { let names: Record @@ -161,7 +159,7 @@ describe('labware selectors', () => { ...tipracks, ...otherLabware, } - const initialDeckSetup: InitialDeckSetup = { + const initialDeckSetup = { labware: labwareEntities, modules: {}, pipettes: {}, @@ -203,7 +201,7 @@ describe('labware selectors', () => { }, } const labwareEntities = { ...trash, ...labware } - const initialDeckSetup: InitialDeckSetup = { + const initialDeckSetup = { pipettes: {}, labware: { ...trash, @@ -275,7 +273,7 @@ describe('labware selectors', () => { }, } const labwareEntities = { ...trash, ...labware } - const initialDeckSetup: InitialDeckSetup = { + const initialDeckSetup = { pipettes: {}, labware: { ...labware, diff --git a/protocol-designer/src/ui/labware/selectors.ts b/protocol-designer/src/ui/labware/selectors.ts index 522b758ca30..d531b4b3d6d 100644 --- a/protocol-designer/src/ui/labware/selectors.ts +++ b/protocol-designer/src/ui/labware/selectors.ts @@ -1,10 +1,6 @@ import { createSelector } from 'reselect' import mapValues from 'lodash/mapValues' import reduce from 'lodash/reduce' -import { - WASTE_CHUTE_DISPLAY_NAME, - TRASH_BIN_DISPLAY_NAME, -} from '@opentrons/components' import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE, @@ -27,6 +23,8 @@ import type { SavedStepFormState, } from '../../step-forms' +const TRASH_BIN = 'Trash bin' + export const getLabwareNicknamesById: Selector< Record > = createSelector( @@ -44,8 +42,8 @@ export const _sortLabwareDropdownOptions = ( ): DropdownOption[] => options.sort((a, b) => { // special case for trash (always at the bottom of the list) - if (a.name === TRASH_BIN_DISPLAY_NAME) return 1 - if (b.name === TRASH_BIN_DISPLAY_NAME) return -1 + if (a.name === TRASH_BIN) return 1 + if (b.name === TRASH_BIN) return -1 // sort by name everything else by name return a.name.localeCompare(b.name) }) @@ -228,7 +226,7 @@ export const getWasteChuteOption: Selector = createSelect const wasteChuteOption: DropdownOption | null = wasteChuteEntity != null ? { - name: WASTE_CHUTE_DISPLAY_NAME, + name: 'Waste chute', value: wasteChuteEntity.id, } : null @@ -252,7 +250,7 @@ export const getDisposalOptions = createSelector( ? [ ...acc, { - name: TRASH_BIN_DISPLAY_NAME, + name: TRASH_BIN, value: additionalEquipment.id ?? '', }, ] diff --git a/protocol-designer/src/ui/labware/utils.ts b/protocol-designer/src/ui/labware/utils.ts index cfa2922ea54..382a8677d15 100644 --- a/protocol-designer/src/ui/labware/utils.ts +++ b/protocol-designer/src/ui/labware/utils.ts @@ -4,7 +4,6 @@ import { RobotType, THERMOCYCLER_MODULE_TYPE, } from '@opentrons/shared-data' -import { WASTE_CHUTE_DISPLAY_NAME } from '@opentrons/components' import type { InitialDeckSetup, SavedStepFormState } from '../../step-forms' function resolveSlotLocation( @@ -58,7 +57,7 @@ export function getLabwareLatestSlot( hasWasteChute && (initialSlot === 'D3' || moveLabwareStep?.newLocation === 'D3') ) { - return WASTE_CHUTE_DISPLAY_NAME + return 'Waste chute' } if (moveLabwareStep?.newLocation != null) { From c521f5df7b2b135081604deae24afe5260a1fe1f Mon Sep 17 00:00:00 2001 From: Jethary Date: Thu, 19 Dec 2024 12:37:31 -0500 Subject: [PATCH 3/6] fix circular dependency --- components/src/molecules/DropdownMenu/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/src/molecules/DropdownMenu/index.tsx b/components/src/molecules/DropdownMenu/index.tsx index 719ae413b7c..3b692c0b3dc 100644 --- a/components/src/molecules/DropdownMenu/index.tsx +++ b/components/src/molecules/DropdownMenu/index.tsx @@ -24,7 +24,7 @@ import { MenuItem } from '../../atoms/MenuList/MenuItem' import { Tooltip } from '../../atoms/Tooltip' import { StyledText } from '../../atoms/StyledText' import { LiquidIcon } from '../LiquidIcon' -import { DeckInfoLabel } from '..' +import { DeckInfoLabel } from '../DeckInfoLabel' export interface DropdownOption { name: string From 820df7baec9f6066e27915910d4b2a32d71b52bd Mon Sep 17 00:00:00 2001 From: Jethary Date: Thu, 19 Dec 2024 12:47:45 -0500 Subject: [PATCH 4/6] clean up --- .../src/hardware-sim/DeckConfigurator/index.tsx | 2 ++ .../src/assets/localization/en/application.json | 1 - protocol-designer/src/ui/labware/selectors.ts | 15 +++++++++------ protocol-designer/src/ui/labware/utils.ts | 3 ++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/components/src/hardware-sim/DeckConfigurator/index.tsx b/components/src/hardware-sim/DeckConfigurator/index.tsx index 4a03ff6c866..65bb6968a45 100644 --- a/components/src/hardware-sim/DeckConfigurator/index.tsx +++ b/components/src/hardware-sim/DeckConfigurator/index.tsx @@ -38,6 +38,8 @@ import { MagneticBlockFixture } from './MagneticBlockFixture' import { ThermocyclerFixture } from './ThermocyclerFixture' import { AbsorbanceReaderFixture } from './AbsorbanceReaderFixture' +export * from './constants' + interface DeckConfiguratorProps { deckConfig: DeckConfiguration handleClickAdd: (cutoutId: CutoutId) => void diff --git a/protocol-designer/src/assets/localization/en/application.json b/protocol-designer/src/assets/localization/en/application.json index eec2fbd585b..3692c9a1fac 100644 --- a/protocol-designer/src/assets/localization/en/application.json +++ b/protocol-designer/src/assets/localization/en/application.json @@ -16,7 +16,6 @@ "magnet_height_caption": "Must be between {{low}} to {{high}}.", "magnet_recommended": "The recommended height is {{default}}", "manually": "Manually", - "mix": "Mix", "module_and_slot": "{{moduleLongName}} in Slot {{slotName}}", "n_steps_selected": "{{n}} steps selected", "networking": { diff --git a/protocol-designer/src/ui/labware/selectors.ts b/protocol-designer/src/ui/labware/selectors.ts index d531b4b3d6d..cda94767fd2 100644 --- a/protocol-designer/src/ui/labware/selectors.ts +++ b/protocol-designer/src/ui/labware/selectors.ts @@ -1,6 +1,10 @@ import { createSelector } from 'reselect' import mapValues from 'lodash/mapValues' import reduce from 'lodash/reduce' +import { + TRASH_BIN_DISPLAY_NAME, + WASTE_CHUTE_DISPLAY_NAME, +} from '@opentrons/components' import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE, @@ -23,8 +27,6 @@ import type { SavedStepFormState, } from '../../step-forms' -const TRASH_BIN = 'Trash bin' - export const getLabwareNicknamesById: Selector< Record > = createSelector( @@ -42,8 +44,8 @@ export const _sortLabwareDropdownOptions = ( ): DropdownOption[] => options.sort((a, b) => { // special case for trash (always at the bottom of the list) - if (a.name === TRASH_BIN) return 1 - if (b.name === TRASH_BIN) return -1 + if (a.name === TRASH_BIN_DISPLAY_NAME) return 1 + if (b.name === TRASH_BIN_DISPLAY_NAME) return -1 // sort by name everything else by name return a.name.localeCompare(b.name) }) @@ -106,6 +108,7 @@ export const getMoveLabwareOptions: Selector = createSelector( )?.location const robotType = trashBinLocation === 'cutout12' ? OT2_ROBOT_TYPE : FLEX_ROBOT_TYPE + const moveLabwareOptions = reduce( labwareEntities, ( @@ -226,7 +229,7 @@ export const getWasteChuteOption: Selector = createSelect const wasteChuteOption: DropdownOption | null = wasteChuteEntity != null ? { - name: 'Waste chute', + name: WASTE_CHUTE_DISPLAY_NAME, value: wasteChuteEntity.id, } : null @@ -250,7 +253,7 @@ export const getDisposalOptions = createSelector( ? [ ...acc, { - name: TRASH_BIN, + name: TRASH_BIN_DISPLAY_NAME, value: additionalEquipment.id ?? '', }, ] diff --git a/protocol-designer/src/ui/labware/utils.ts b/protocol-designer/src/ui/labware/utils.ts index 382a8677d15..f559c418deb 100644 --- a/protocol-designer/src/ui/labware/utils.ts +++ b/protocol-designer/src/ui/labware/utils.ts @@ -1,4 +1,5 @@ import { getHasWasteChute } from '@opentrons/step-generation' +import { WASTE_CHUTE_DISPLAY_NAME } from '@opentrons/components' import { FLEX_ROBOT_TYPE, RobotType, @@ -57,7 +58,7 @@ export function getLabwareLatestSlot( hasWasteChute && (initialSlot === 'D3' || moveLabwareStep?.newLocation === 'D3') ) { - return 'Waste chute' + return WASTE_CHUTE_DISPLAY_NAME } if (moveLabwareStep?.newLocation != null) { From 016020be8ec47cffb8967184cc452c99381f2576 Mon Sep 17 00:00:00 2001 From: Jethary Date: Thu, 19 Dec 2024 12:50:36 -0500 Subject: [PATCH 5/6] resolve lint errors --- protocol-designer/src/ui/labware/selectors.ts | 2 +- protocol-designer/src/ui/labware/utils.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol-designer/src/ui/labware/selectors.ts b/protocol-designer/src/ui/labware/selectors.ts index cda94767fd2..34d5818611f 100644 --- a/protocol-designer/src/ui/labware/selectors.ts +++ b/protocol-designer/src/ui/labware/selectors.ts @@ -8,7 +8,6 @@ import { import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE, - RobotType, getIsTiprack, getLabwareDisplayName, } from '@opentrons/shared-data' @@ -21,6 +20,7 @@ import type { AdditionalEquipmentEntity, } from '@opentrons/step-generation' import type { DropdownOption } from '@opentrons/components' +import type { RobotType } from '@opentrons/shared-data' import type { Selector } from '../../types' import type { AllTemporalPropertiesForTimelineFrame, diff --git a/protocol-designer/src/ui/labware/utils.ts b/protocol-designer/src/ui/labware/utils.ts index f559c418deb..a566a411243 100644 --- a/protocol-designer/src/ui/labware/utils.ts +++ b/protocol-designer/src/ui/labware/utils.ts @@ -2,9 +2,9 @@ import { getHasWasteChute } from '@opentrons/step-generation' import { WASTE_CHUTE_DISPLAY_NAME } from '@opentrons/components' import { FLEX_ROBOT_TYPE, - RobotType, THERMOCYCLER_MODULE_TYPE, } from '@opentrons/shared-data' +import type { RobotType } from '@opentrons/shared-data' import type { InitialDeckSetup, SavedStepFormState } from '../../step-forms' function resolveSlotLocation( @@ -65,7 +65,7 @@ export function getLabwareLatestSlot( return resolveSlotLocation( modules, labware, - moveLabwareStep.newLocation, + moveLabwareStep.newLocation as string, robotType ) } else if (moveLabwareStep == null) { From 1d279511ca44dcd09ecfb1ca3a71fc7903d7b529 Mon Sep 17 00:00:00 2001 From: Jethary Date: Thu, 19 Dec 2024 14:26:07 -0500 Subject: [PATCH 6/6] address comments --- protocol-designer/src/ui/labware/utils.ts | 7 ++++++- protocol-designer/src/ui/modules/utils.ts | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/protocol-designer/src/ui/labware/utils.ts b/protocol-designer/src/ui/labware/utils.ts index a566a411243..d55c35b578f 100644 --- a/protocol-designer/src/ui/labware/utils.ts +++ b/protocol-designer/src/ui/labware/utils.ts @@ -2,6 +2,8 @@ import { getHasWasteChute } from '@opentrons/step-generation' import { WASTE_CHUTE_DISPLAY_NAME } from '@opentrons/components' import { FLEX_ROBOT_TYPE, + TC_MODULE_LOCATION_OT2, + TC_MODULE_LOCATION_OT3, THERMOCYCLER_MODULE_TYPE, } from '@opentrons/shared-data' import type { RobotType } from '@opentrons/shared-data' @@ -13,7 +15,10 @@ function resolveSlotLocation( location: string, robotType: RobotType ): string { - const TCSlot = robotType === FLEX_ROBOT_TYPE ? 'A1+B1' : '8,9,10,11' + const TCSlot = + robotType === FLEX_ROBOT_TYPE + ? TC_MODULE_LOCATION_OT3 + : TC_MODULE_LOCATION_OT2 if (location === 'offDeck') { return 'offDeck' } else if (modules[location] != null) { diff --git a/protocol-designer/src/ui/modules/utils.ts b/protocol-designer/src/ui/modules/utils.ts index e0470d9623f..d347c1b5388 100644 --- a/protocol-designer/src/ui/modules/utils.ts +++ b/protocol-designer/src/ui/modules/utils.ts @@ -1,7 +1,13 @@ import values from 'lodash/values' import { - MAGNETIC_MODULE_V1, + ABSORBANCE_READER_TYPE, getLabwareDefaultEngageHeight, + HEATERSHAKER_MODULE_TYPE, + MAGNETIC_BLOCK_TYPE, + MAGNETIC_MODULE_TYPE, + MAGNETIC_MODULE_V1, + TEMPERATURE_MODULE_TYPE, + THERMOCYCLER_MODULE_TYPE, } from '@opentrons/shared-data' import type { DropdownOption } from '@opentrons/components' import type { ModuleType } from '@opentrons/shared-data' @@ -76,17 +82,17 @@ export function getModuleUnderLabware( export const getModuleShortNames = (type: ModuleType): string => { switch (type) { - case 'heaterShakerModuleType': + case HEATERSHAKER_MODULE_TYPE: return 'Heater-Shaker Module' - case 'magneticBlockType': + case MAGNETIC_BLOCK_TYPE: return 'Magnetic Block' - case 'magneticModuleType': + case MAGNETIC_MODULE_TYPE: return 'Magnetic Module' - case 'temperatureModuleType': + case TEMPERATURE_MODULE_TYPE: return 'Temperature Module' - case 'thermocyclerModuleType': + case THERMOCYCLER_MODULE_TYPE: return 'Thermocycler' - case 'absorbanceReaderType': + case ABSORBANCE_READER_TYPE: return 'Absorbance Reader' } }