From 1f979ddd089aa2f7a1198464f5b499112c21919a Mon Sep 17 00:00:00 2001 From: Katie Adee Date: Fri, 13 Mar 2020 17:19:43 -0400 Subject: [PATCH] feat(protocol-designer): Add module prefix to labware (#5205) closes #5119 --- .../ui/labware/__tests__/selectors.test.js | 146 +++++++++++++++++- protocol-designer/src/ui/labware/selectors.js | 17 +- protocol-designer/src/ui/modules/utils.js | 10 ++ 3 files changed, 162 insertions(+), 11 deletions(-) diff --git a/protocol-designer/src/ui/labware/__tests__/selectors.test.js b/protocol-designer/src/ui/labware/__tests__/selectors.test.js index 1c079ea76b6..90156fb30f8 100644 --- a/protocol-designer/src/ui/labware/__tests__/selectors.test.js +++ b/protocol-designer/src/ui/labware/__tests__/selectors.test.js @@ -1,12 +1,24 @@ -import { getDisposalLabwareOptions } from '../selectors' +// @flow +import { + MAGNETIC_MODULE_TYPE, + MAGNETIC_MODULE_V1, + TEMPERATURE_MODULE_TYPE, + TEMPERATURE_MODULE_V1, + THERMOCYCLER_MODULE_TYPE, + THERMOCYCLER_MODULE_V1, +} from '@opentrons/shared-data' +import { SPAN7_8_10_11_SLOT } from '../../../constants' +import { getDisposalLabwareOptions, getLabwareOptions } from '../selectors' import fixture_tiprack_1000_ul from '@opentrons/shared-data/labware/fixtures/2/fixture_tiprack_1000_ul.json' import fixture_tiprack_10_ul from '@opentrons/shared-data/labware/fixtures/2/fixture_tiprack_10_ul.json' +import fixture_96_plate from '@opentrons/shared-data/labware/fixtures/2/fixture_96_plate.json' import fixture_trash from '@opentrons/shared-data/labware/fixtures/2/fixture_trash.json' describe('labware selectors', () => { let names let tipracks let trash + let otherLabware beforeEach(() => { trash = { @@ -16,32 +28,47 @@ describe('labware selectors', () => { } tipracks = { - fixture_tiprack_1000_ul: { - id: 'fixture_tiprack_1000_ul', + tiprack100Id: { + id: 'tiprack100Id', def: { ...fixture_tiprack_1000_ul }, }, - fixture_tiprack_10_ul: { - id: 'fixture_tiprack_10_ul', + tiprack10Id: { + id: 'tiprack10Id', def: { ...fixture_tiprack_10_ul }, }, } + otherLabware = { + wellPlateId: { + id: 'wellPlateId', + def: { ...fixture_96_plate }, + }, + } + names = { trashId: 'Trash', trashId2: 'Trash', - fixture_tiprack_1000_ul: 'Opentrons Tip Rack 1000 µL', - fixture_tiprack_10_ul: 'Opentrons Tip Rack 10 µL', + + tiprack100Id: 'Opentrons Tip Rack 1000 µL', + tiprack10Id: 'Opentrons Tip Rack 10 µL', + + wellPlateId: 'Source Plate', } }) + describe('getDisposalLabwareOptions', () => { it('returns an empty list when labware is NOT provided', () => { - expect(getDisposalLabwareOptions.resultFunc([], names)).toEqual([]) + expect( + // $FlowFixMe(IL, 2020-03-12): resultFunc + getDisposalLabwareOptions.resultFunc([], names) + ).toEqual([]) }) it('returns empty list when trash is NOT present', () => { const labwareEntities = { ...tipracks, } expect( + // $FlowFixMe(IL, 2020-03-12): resultFunc getDisposalLabwareOptions.resultFunc(labwareEntities, names) ).toEqual([]) }) @@ -52,6 +79,7 @@ describe('labware selectors', () => { } expect( + // $FlowFixMe(IL, 2020-03-12): resultFunc getDisposalLabwareOptions.resultFunc(labwareEntities, names) ).toEqual([{ name: 'Trash', value: 'trashId' }]) }) @@ -68,6 +96,7 @@ describe('labware selectors', () => { } expect( + // $FlowFixMe(IL, 2020-03-12): resultFunc getDisposalLabwareOptions.resultFunc(labwareEntities, names) ).toEqual([ { name: 'Trash', value: 'trashId' }, @@ -75,4 +104,105 @@ describe('labware selectors', () => { ]) }) }) + + describe('getLabwareOptions', () => { + it('should return an empty list when no labware is present', () => { + expect( + // $FlowFixMe(IL, 2020-03-12): resultFunc + getDisposalLabwareOptions.resultFunc( + {}, + {}, + { labware: {}, modules: {}, pipettes: {} } + ) + ).toEqual([]) + }) + + it('should return labware options when no modules are present, with no tipracks', () => { + const labwareEntities = { + ...tipracks, + ...trash, + ...otherLabware, + } + const initialDeckSetup = { + labware: labwareEntities, + modules: {}, + pipettes: {}, + } + expect( + // $FlowFixMe(IL, 2020-03-12): resultFunc + getLabwareOptions.resultFunc(labwareEntities, names, initialDeckSetup) + ).toEqual([ + { name: 'Trash', value: 'trashId' }, + { name: 'Source Plate', value: 'wellPlateId' }, + ]) + }) + + it('should return labware options with module prefixes when a labware is on module', () => { + const labware = { + wellPlateId: { + ...otherLabware.wellPlateId, + slot: 'magModuleId', // On magnetic module + }, + tempPlateId: { + ...otherLabware.wellPlateId, + id: 'tempPlateId', + slot: 'tempModuleId', // On temperature module + }, + tcPlateId: { + ...otherLabware.wellPlateId, + id: 'tcPlateId', + slot: 'thermocyclerId', // On thermocycler + }, + } + const labwareEntities = { ...trash, ...labware } + const initialDeckSetup = { + pipettes: {}, + labware: { + ...trash, + ...labware, + }, + modules: { + magModuleId: { + id: 'magModuleId', + type: MAGNETIC_MODULE_TYPE, + model: MAGNETIC_MODULE_V1, + slot: '1', + }, + tempModuleId: { + id: 'tempModuleId', + type: TEMPERATURE_MODULE_TYPE, + model: TEMPERATURE_MODULE_V1, + slot: '3', + }, + thermocyclerId: { + id: 'thermocyclerId', + type: THERMOCYCLER_MODULE_TYPE, + model: THERMOCYCLER_MODULE_V1, + slot: SPAN7_8_10_11_SLOT, + }, + }, + } + + const nicknames: { [string]: string } = { + ...names, + wellPlateId: 'Well Plate', + tempPlateId: 'Temp Plate', + tcPlateId: 'TC Plate', + } + + expect( + // $FlowFixMe(IL, 2020-03-12): resultFunc + getLabwareOptions.resultFunc( + labwareEntities, + nicknames, + initialDeckSetup + ) + ).toEqual([ + { name: 'Trash', value: 'trashId' }, + { name: 'MAG Well Plate', value: 'wellPlateId' }, + { name: 'TEMP Temp Plate', value: 'tempPlateId' }, + { name: 'THERMO TC Plate', value: 'tcPlateId' }, + ]) + }) + }) }) diff --git a/protocol-designer/src/ui/labware/selectors.js b/protocol-designer/src/ui/labware/selectors.js index b8405ead0b1..0548c761ee4 100644 --- a/protocol-designer/src/ui/labware/selectors.js +++ b/protocol-designer/src/ui/labware/selectors.js @@ -7,10 +7,11 @@ import { getLabwareDisplayName, getLabwareHasQuirk, } from '@opentrons/shared-data' +import { i18n } from '../../localization' import * as stepFormSelectors from '../../step-forms/selectors' import { selectors as labwareIngredSelectors } from '../../labware-ingred/selectors' - +import { getModuleUnderLabware } from '../modules/utils' import type { Options } from '@opentrons/components' import type { Selector } from '../../types' import type { LabwareEntity } from '../../step-forms' @@ -32,16 +33,26 @@ export const getLabwareNicknamesById: Selector<{ export const getLabwareOptions: Selector = createSelector( stepFormSelectors.getLabwareEntities, getLabwareNicknamesById, - (labwareEntities, nicknamesById) => + stepFormSelectors.getInitialDeckSetup, + (labwareEntities, nicknamesById, initialDeckSetup) => reduce( labwareEntities, (acc: Options, l: LabwareEntity, labwareId: string): Options => { + const module = getModuleUnderLabware(initialDeckSetup, labwareId) + const prefix = module + ? i18n.t( + `form.step_edit_form.field.moduleLabwarePrefix.${module.type}` + ) + : null + const nickName = prefix + ? `${prefix} ${nicknamesById[labwareId]}` + : nicknamesById[labwareId] return getIsTiprack(l.def) ? acc : [ ...acc, { - name: nicknamesById[labwareId], + name: nickName, value: labwareId, }, ] diff --git a/protocol-designer/src/ui/modules/utils.js b/protocol-designer/src/ui/modules/utils.js index 4d4900d4c20..bd449006293 100644 --- a/protocol-designer/src/ui/modules/utils.js +++ b/protocol-designer/src/ui/modules/utils.js @@ -27,6 +27,16 @@ export function getLabwareOnModule( ) } +export function getModuleUnderLabware( + initialDeckSetup: InitialDeckSetup, + labwareId: string +): ?ModuleOnDeck { + return values(initialDeckSetup.modules).find( + (module: ModuleOnDeck) => + initialDeckSetup.labware[labwareId]?.slot === module.id + ) +} + export function getModuleLabwareOptions( initialDeckSetup: InitialDeckSetup, nicknamesById: { [labwareId: string]: string },