From 78e47b92d3645218ec29759fde7300603cf978c7 Mon Sep 17 00:00:00 2001 From: Jethary Date: Wed, 24 Apr 2024 12:27:44 -0400 Subject: [PATCH 1/2] refactor(protocol-designer): tweak when module cards are disabled in createFileWizard closes AUTH-369 --- .../CreateFileWizard/ModulesAndOtherTile.tsx | 10 ++++-- .../CreateFileWizard/__tests__/utils.test.tsx | 33 ++++++++++++------- .../modals/CreateFileWizard/utils.ts | 28 ++++++++++------ 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/protocol-designer/src/components/modals/CreateFileWizard/ModulesAndOtherTile.tsx b/protocol-designer/src/components/modals/CreateFileWizard/ModulesAndOtherTile.tsx index b1ad18b0752..2c1dd51286a 100644 --- a/protocol-designer/src/components/modals/CreateFileWizard/ModulesAndOtherTile.tsx +++ b/protocol-designer/src/components/modals/CreateFileWizard/ModulesAndOtherTile.tsx @@ -31,6 +31,7 @@ import { getModuleType, FLEX_ROBOT_TYPE, MAGNETIC_BLOCK_TYPE, + THERMOCYCLER_MODULE_TYPE, } from '@opentrons/shared-data' import { getIsCrashablePipetteSelected } from '../../../step-forms' import gripperImage from '../../../images/flex_gripper.png' @@ -44,7 +45,7 @@ import { ModuleFields } from '../FilePipettesModal/ModuleFields' import { GoBack } from './GoBack' import { getCrashableModuleSelected, - getIsSlotAvailable, + getNumSlotsAvailable, getTrashOptionDisabled, } from './utils' import { EquipmentOption } from './EquipmentOption' @@ -221,7 +222,12 @@ function FlexModuleFields(props: WizardTileProps): JSX.Element { const moduleType = getModuleType(moduleModel) const isModuleOnDeck = moduleTypesOnDeck.includes(moduleType) - const isDisabled = !getIsSlotAvailable(modules, additionalEquipment) + let isDisabled = + getNumSlotsAvailable(modules, additionalEquipment) === 0 + // special-casing TC since it takes up 2 slots + if (moduleType === THERMOCYCLER_MODULE_TYPE) { + isDisabled = getNumSlotsAvailable(modules, additionalEquipment) === 1 + } const handleMultiplesClick = (num: number): void => { const temperatureModules = diff --git a/protocol-designer/src/components/modals/CreateFileWizard/__tests__/utils.test.tsx b/protocol-designer/src/components/modals/CreateFileWizard/__tests__/utils.test.tsx index 02289d9277d..a8d59634e0b 100644 --- a/protocol-designer/src/components/modals/CreateFileWizard/__tests__/utils.test.tsx +++ b/protocol-designer/src/components/modals/CreateFileWizard/__tests__/utils.test.tsx @@ -8,7 +8,7 @@ import { getUnoccupiedStagingAreaSlots, getTrashSlot, getTrashOptionDisabled, - getIsSlotAvailable, + getNumSlotsAvailable, } from '../utils' import { STANDARD_EMPTY_SLOTS } from '../StagingAreaTile' import type { FormPipettesByMount } from '../../../../step-forms' @@ -53,12 +53,12 @@ describe('getUnoccupiedStagingAreaSlots', () => { ]) }) }) -describe('getIsSlotAvailable', () => { - it('should return true when there are no modules or additional equipment', () => { - const result = getIsSlotAvailable(null, []) - expect(result).toBe(true) +describe('getNumSlotsAvailable', () => { + it('should return 8 when there are no modules or additional equipment', () => { + const result = getNumSlotsAvailable(null, []) + expect(result).toBe(8) }) - it('should return false when there is a TC and 7 modules', () => { + it('should return 0 when there is a TC and 7 modules', () => { const mockModules = { 0: { model: 'heaterShakerModuleV1', @@ -96,10 +96,10 @@ describe('getIsSlotAvailable', () => { slot: 'C3', }, } as any - const result = getIsSlotAvailable(mockModules, []) - expect(result).toBe(false) + const result = getNumSlotsAvailable(mockModules, []) + expect(result).toBe(0) }) - it('should return true when there are 9 additional equipment and 1 is a waste chute on the staging area and one is a gripper', () => { + it('should return 1 when there are 9 additional equipment and 1 is a waste chute on the staging area and one is a gripper', () => { const mockAdditionalEquipment: AdditionalEquipment[] = [ 'trashBin', 'stagingArea_cutoutA3', @@ -111,8 +111,19 @@ describe('getIsSlotAvailable', () => { 'gripper', 'trashBin', ] - const result = getIsSlotAvailable(null, mockAdditionalEquipment) - expect(result).toBe(true) + const result = getNumSlotsAvailable(null, mockAdditionalEquipment) + expect(result).toBe(1) + }) + it('should return 8 even when there is a magnetic block', () => { + const mockModules = { + 0: { + model: 'magneticBlockV1', + type: 'magneticBlockType', + slot: 'B2', + }, + } as any + const result = getNumSlotsAvailable(mockModules, []) + expect(result).toBe(8) }) }) describe('getTrashSlot', () => { diff --git a/protocol-designer/src/components/modals/CreateFileWizard/utils.ts b/protocol-designer/src/components/modals/CreateFileWizard/utils.ts index 7a23706a680..72cf9bee671 100644 --- a/protocol-designer/src/components/modals/CreateFileWizard/utils.ts +++ b/protocol-designer/src/components/modals/CreateFileWizard/utils.ts @@ -1,4 +1,5 @@ import { + MAGNETIC_BLOCK_TYPE, THERMOCYCLER_MODULE_TYPE, WASTE_CHUTE_CUTOUT, } from '@opentrons/shared-data' @@ -85,17 +86,26 @@ export const getUnoccupiedStagingAreaSlots = ( const TOTAL_MODULE_SLOTS = 8 -export const getIsSlotAvailable = ( +export const getNumSlotsAvailable = ( modules: FormState['modules'], additionalEquipment: FormState['additionalEquipment'] -): boolean => { +): number => { const moduleLength = modules != null ? Object.keys(modules).length : 0 const additionalEquipmentLength = additionalEquipment.length const hasTC = Object.values(modules || {}).some( module => module.type === THERMOCYCLER_MODULE_TYPE ) + const hasMagneticBlock = Object.values(modules || {}).some( + module => module.type === MAGNETIC_BLOCK_TYPE + ) + let filteredModuleLength = moduleLength + if (hasTC) { + filteredModuleLength = filteredModuleLength + 1 + } + if (hasMagneticBlock) { + filteredModuleLength = filteredModuleLength - 1 + } - const filteredModuleLength = hasTC ? moduleLength + 1 : moduleLength const hasWasteChute = additionalEquipment.some(equipment => equipment.includes('wasteChute') ) @@ -113,10 +123,9 @@ export const getIsSlotAvailable = ( if (hasGripper) { filteredAdditionalEquipmentLength = filteredAdditionalEquipmentLength - 1 } - return ( - filteredModuleLength + filteredAdditionalEquipmentLength < - TOTAL_MODULE_SLOTS + TOTAL_MODULE_SLOTS - + (filteredModuleLength + filteredAdditionalEquipmentLength) ) } @@ -130,10 +139,9 @@ export const getTrashOptionDisabled = ( props: TrashOptionDisabledProps ): boolean => { const { additionalEquipment, modules, trashType } = props - return ( - !getIsSlotAvailable(modules, additionalEquipment) && - !additionalEquipment.includes(trashType) - ) + const hasNoSlotsAvailable = + getNumSlotsAvailable(modules, additionalEquipment) === 0 + return hasNoSlotsAvailable && !additionalEquipment.includes(trashType) } export const getTrashSlot = (values: FormState): string => { From 3e42920b21be5619fbaef159b7d91558bfb1e27e Mon Sep 17 00:00:00 2001 From: Jethary Date: Wed, 24 Apr 2024 13:28:29 -0400 Subject: [PATCH 2/2] address feedback --- .../src/components/modals/CreateFileWizard/utils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/protocol-designer/src/components/modals/CreateFileWizard/utils.ts b/protocol-designer/src/components/modals/CreateFileWizard/utils.ts index 72cf9bee671..eb3f0985c20 100644 --- a/protocol-designer/src/components/modals/CreateFileWizard/utils.ts +++ b/protocol-designer/src/components/modals/CreateFileWizard/utils.ts @@ -90,7 +90,6 @@ export const getNumSlotsAvailable = ( modules: FormState['modules'], additionalEquipment: FormState['additionalEquipment'] ): number => { - const moduleLength = modules != null ? Object.keys(modules).length : 0 const additionalEquipmentLength = additionalEquipment.length const hasTC = Object.values(modules || {}).some( module => module.type === THERMOCYCLER_MODULE_TYPE @@ -98,7 +97,7 @@ export const getNumSlotsAvailable = ( const hasMagneticBlock = Object.values(modules || {}).some( module => module.type === MAGNETIC_BLOCK_TYPE ) - let filteredModuleLength = moduleLength + let filteredModuleLength = modules != null ? Object.keys(modules).length : 0 if (hasTC) { filteredModuleLength = filteredModuleLength + 1 }