From 7e05d04324d966a40a47da435ef0e2f46a8d3a31 Mon Sep 17 00:00:00 2001 From: koji Date: Fri, 14 Feb 2025 11:33:16 -0500 Subject: [PATCH 1/7] fix(protocol-designer): remove dropdown menu for module quantity remove dropdown menu for module quantity close AUTH-1451 --- .../AddModuleEmptySelectorButton.tsx | 56 +++++ .../AddModuleEmptySelectorButton.test.tsx | 59 +++++ .../__tests__/SelectModules.test.tsx | 31 ++- .../src/organisms/SelectModules/index.tsx | 206 ++++++++++++++++++ .../CreateNewProtocolWizard/SelectModules.tsx | 148 +++---------- .../pages/CreateNewProtocolWizard/index.tsx | 2 +- 6 files changed, 381 insertions(+), 121 deletions(-) create mode 100644 protocol-designer/src/organisms/SelectModules/AddModuleEmptySelectorButton.tsx create mode 100644 protocol-designer/src/organisms/SelectModules/__tests__/AddModuleEmptySelectorButton.test.tsx rename protocol-designer/src/{pages/CreateNewProtocolWizard => organisms/SelectModules}/__tests__/SelectModules.test.tsx (77%) create mode 100644 protocol-designer/src/organisms/SelectModules/index.tsx diff --git a/protocol-designer/src/organisms/SelectModules/AddModuleEmptySelectorButton.tsx b/protocol-designer/src/organisms/SelectModules/AddModuleEmptySelectorButton.tsx new file mode 100644 index 00000000000..8e07f72a538 --- /dev/null +++ b/protocol-designer/src/organisms/SelectModules/AddModuleEmptySelectorButton.tsx @@ -0,0 +1,56 @@ +import { + EmptySelectorButton, + FLEX_MAX_CONTENT, + Flex, + Tooltip, + TYPOGRAPHY, + useHoverTooltip, +} from '@opentrons/components' +import { + ABSORBANCE_READER_V1, + getModuleDisplayName, +} from '@opentrons/shared-data' + +import type { ModuleModel } from '@opentrons/shared-data' + +interface AddModuleEmptySelectorButtonProps { + moduleModel: ModuleModel + areSlotsAvailable: boolean + hasGripper: boolean + handleAddModule: (arg0: ModuleModel, arg1: boolean) => void + tooltipText: string +} + +export function AddModuleEmptySelectorButton( + props: AddModuleEmptySelectorButtonProps +): JSX.Element { + const { + moduleModel, + areSlotsAvailable, + hasGripper, + handleAddModule, + tooltipText, + } = props + const [targetProps, tooltipProps] = useHoverTooltip() + const disableGripperRequired = + !hasGripper && moduleModel === ABSORBANCE_READER_V1 + + return ( + <> + + { + handleAddModule(moduleModel, !areSlotsAvailable) + }} + /> + + {disableGripperRequired ? ( + {tooltipText} + ) : null} + + ) +} diff --git a/protocol-designer/src/organisms/SelectModules/__tests__/AddModuleEmptySelectorButton.test.tsx b/protocol-designer/src/organisms/SelectModules/__tests__/AddModuleEmptySelectorButton.test.tsx new file mode 100644 index 00000000000..e51ef27b1f5 --- /dev/null +++ b/protocol-designer/src/organisms/SelectModules/__tests__/AddModuleEmptySelectorButton.test.tsx @@ -0,0 +1,59 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { fireEvent, screen, waitFor } from '@testing-library/react' +import { ABSORBANCE_READER_V1 } from '@opentrons/shared-data' + +import { renderWithProviders } from '../../../__testing-utils__' +import { AddModuleEmptySelectorButton } from '../AddModuleEmptySelectorButton' + +import type { ComponentProps } from 'react' +import type { EmptySelectorButton } from '@opentrons/components' + +vi.mock('@opentrons/components', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + EmptySelectorButton: ({ onClick }: { onClick: () => void }) => ( + + ), + Tooltip: vi.fn(({ children }) =>
{children}
), + } +}) +const mockHandleAddModule = vi.fn() + +const render = (props: ComponentProps) => { + return renderWithProviders() +} + +describe('AddModuleEmptySelectorButton', () => { + let props: ComponentProps + + beforeEach(() => { + props = { + moduleModel: ABSORBANCE_READER_V1, + areSlotsAvailable: true, + hasGripper: true, + handleAddModule: mockHandleAddModule, + tooltipText: 'tooltipText', + } + }) + + it('renders mock emptySelector button', () => { + render(props) + screen.getByText('mock EmptySelectorButton') + }) + + it('should call mock handleAddModule when clicked', () => { + render(props) + fireEvent.click(screen.getByText('mock EmptySelectorButton')) + expect(mockHandleAddModule).toHaveBeenCalled() + }) + + it('renders tooltip text', async () => { + props = { ...props, hasGripper: false } + render(props) + fireEvent.mouseOver(screen.getByText('mock EmptySelectorButton')) + await waitFor(() => { + screen.getByText('tooltipText') + }) + }) +}) diff --git a/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/SelectModules.test.tsx b/protocol-designer/src/organisms/SelectModules/__tests__/SelectModules.test.tsx similarity index 77% rename from protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/SelectModules.test.tsx rename to protocol-designer/src/organisms/SelectModules/__tests__/SelectModules.test.tsx index 2d23f3a1fef..9513a211816 100644 --- a/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/SelectModules.test.tsx +++ b/protocol-designer/src/organisms/SelectModules/__tests__/SelectModules.test.tsx @@ -4,10 +4,13 @@ import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE } from '@opentrons/shared-data' import { fireEvent, screen } from '@testing-library/react' import { i18n } from '../../../assets/localization' import { renderWithProviders } from '../../../__testing-utils__' -import { SelectModules } from '../SelectModules' +import { SelectModules } from '../../../pages/CreateNewProtocolWizard/SelectModules' import type { ComponentProps } from 'react' -import type { WizardFormState, WizardTileProps } from '../types' +import type { + WizardFormState, + WizardTileProps, +} from '../../../pages/CreateNewProtocolWizard/types' vi.mock('../../../feature-flags/selectors') @@ -84,6 +87,30 @@ describe('SelectModules', () => { screen.getByText('Thermocycler Module GEN1') }) + it('renders the Flex options', () => { + const values = { + fields: { + name: '', + description: '', + organizationOrAuthor: '', + robotType: FLEX_ROBOT_TYPE, + }, + additionalEquipment: ['trashBin'], + modules: {}, + pipettesByMount: {} as any, + } as WizardFormState + props = { + ...props, + watch: vi.fn((name: keyof typeof values) => values[name]) as any, + } + render(props) + screen.getByText('Absorbance Plate Reader Module GEN1') + screen.getByText('Heater-Shaker Module GEN1') + screen.getByText('Magnetic Block GEN1') + screen.getByText('Temperature Module GEN2') + screen.getByText('Thermocycler Module GEN2') + }) + it('calls setValue when clicking to add a Magnetic Block GEN1', () => { render(props) fireEvent.click(screen.getByText('Magnetic Block GEN1')) diff --git a/protocol-designer/src/organisms/SelectModules/index.tsx b/protocol-designer/src/organisms/SelectModules/index.tsx new file mode 100644 index 00000000000..e82fe14c317 --- /dev/null +++ b/protocol-designer/src/organisms/SelectModules/index.tsx @@ -0,0 +1,206 @@ +import { useTranslation } from 'react-i18next' +import { + ALIGN_CENTER, + BORDERS, + COLORS, + DIRECTION_COLUMN, + Flex, + ListItem, + SPACING, + StyledText, + WRAP, +} from '@opentrons/components' +import { + FLEX_ROBOT_TYPE, + getModuleDisplayName, + getModuleType, +} from '@opentrons/shared-data' + +import { uuid } from '../../utils' +import { ModuleDiagram } from '../../pages/CreateNewProtocolWizard/ModuleDiagram' +import { WizardBody } from '../../pages/CreateNewProtocolWizard/WizardBody' +import { + DEFAULT_SLOT_MAP_FLEX, + DEFAULT_SLOT_MAP_OT2, + FLEX_SUPPORTED_MODULE_MODELS, + OT2_SUPPORTED_MODULE_MODELS, +} from '../../pages/CreateNewProtocolWizard/constants' +import { getNumSlotsAvailable } from '../../pages/CreateNewProtocolWizard/utils' +import { HandleEnter } from '../../atoms/HandleEnter' +import { PDListItemCustomize as ListItemCustomize } from '../../pages/CreateNewProtocolWizard/PDListItemCustomize' +import { AddModuleEmptySelectorButton } from './AddModuleEmptySelectorButton' + +import type { ModuleModel, ModuleType } from '@opentrons/shared-data' +import type { FormModule } from '../../step-forms' +import type { WizardTileProps } from '../../pages/CreateNewProtocolWizard/types' + +export function SelectModules(props: WizardTileProps): JSX.Element | null { + const { goBack, proceed, watch, setValue } = props + const { t } = useTranslation(['create_new_protocol', 'shared']) + const fields = watch('fields') + const modules = watch('modules') + const additionalEquipment = watch('additionalEquipment') + const robotType = fields.robotType + const supportedModules = + robotType === FLEX_ROBOT_TYPE + ? FLEX_SUPPORTED_MODULE_MODELS + : OT2_SUPPORTED_MODULE_MODELS + const filteredSupportedModules = supportedModules.filter( + moduleModel => + !( + modules != null && + Object.values(modules).some(module => + robotType === FLEX_ROBOT_TYPE + ? module.model === moduleModel + : module.type === getModuleType(moduleModel) + ) + ) + ) + const hasGripper = additionalEquipment.some(aE => aE === 'gripper') + + const handleAddModule = ( + moduleModel: ModuleModel, + hasNoAvailableSlots: boolean + ): void => { + setValue('modules', { + ...modules, + [uuid()]: { + model: moduleModel, + type: getModuleType(moduleModel), + slot: + robotType === FLEX_ROBOT_TYPE + ? DEFAULT_SLOT_MAP_FLEX[moduleModel] + : DEFAULT_SLOT_MAP_OT2[getModuleType(moduleModel)], + }, + }) + } + + const handleRemoveModule = (moduleType: ModuleType): void => { + const updatedModules = + modules != null + ? Object.fromEntries( + Object.entries(modules).filter( + ([key, value]) => value.type !== moduleType + ) + ) + : {} + setValue('modules', updatedModules) + } + + return ( + + { + goBack(1) + setValue('modules', null) + }} + proceed={() => { + proceed(1) + }} + > + + + {filteredSupportedModules.length > 0 || + !( + filteredSupportedModules.length === 1 && + filteredSupportedModules[0] === 'absorbanceReaderV1' + ) ? ( + + {t('which_modules')} + + ) : null} + + {filteredSupportedModules + .sort((moduleA, moduleB) => moduleA.localeCompare(moduleB)) + .map(moduleModel => { + const numSlotsAvailable = getNumSlotsAvailable( + modules, + additionalEquipment, + moduleModel + ) + return ( + 0} + hasGripper={hasGripper} + handleAddModule={handleAddModule} + tooltipText={t('add_gripper_for_absorbance_reader')} + /> + ) + })} + + {modules != null && Object.keys(modules).length > 0 ? ( + + + {t('modules_added')} + + + {Object.entries(modules) + .sort(([, moduleA], [, moduleB]) => + moduleA.model.localeCompare(moduleB.model) + ) + .reduce>( + (acc, [key, module]) => { + const existingModule = acc.find( + m => m.type === module.type + ) + if (existingModule != null) { + existingModule.count++ + } else { + acc.push({ ...module, count: 1, key }) + } + return acc + }, + [] + ) + .map(module => ( + + { + handleRemoveModule(module.type) + }} + header={getModuleDisplayName(module.model)} + leftHeaderItem={ + + + + } + /> + + ))} + + + ) : null} + + + + + ) +} diff --git a/protocol-designer/src/pages/CreateNewProtocolWizard/SelectModules.tsx b/protocol-designer/src/pages/CreateNewProtocolWizard/SelectModules.tsx index fc09ad03517..dd38784f7b6 100644 --- a/protocol-designer/src/pages/CreateNewProtocolWizard/SelectModules.tsx +++ b/protocol-designer/src/pages/CreateNewProtocolWizard/SelectModules.tsx @@ -20,10 +20,8 @@ import { FLEX_ROBOT_TYPE, getModuleDisplayName, getModuleType, - HEATERSHAKER_MODULE_TYPE, - MAGNETIC_BLOCK_TYPE, - TEMPERATURE_MODULE_TYPE, } from '@opentrons/shared-data' + import { uuid } from '../../utils' import { useKitchen } from '../../organisms/Kitchen/hooks' import { ModuleDiagram } from './ModuleDiagram' @@ -34,13 +32,12 @@ import { FLEX_SUPPORTED_MODULE_MODELS, OT2_SUPPORTED_MODULE_MODELS, } from './constants' -import { getNumOptions, getNumSlotsAvailable } from './utils' +import { getNumSlotsAvailable } from './utils' import { HandleEnter } from '../../atoms/HandleEnter' import { PDListItemCustomize as ListItemCustomize } from '../CreateNewProtocolWizard/PDListItemCustomize' -import type { DropdownBorder } from '@opentrons/components' import type { ModuleModel, ModuleType } from '@opentrons/shared-data' -import type { FormModule, FormModules } from '../../step-forms' +import type { FormModule } from '../../step-forms' import type { WizardTileProps } from './types' export function SelectModules(props: WizardTileProps): JSX.Element | null { @@ -66,11 +63,6 @@ export function SelectModules(props: WizardTileProps): JSX.Element | null { ) ) ) - const MOAM_MODULE_TYPES: ModuleType[] = [ - TEMPERATURE_MODULE_TYPE, - HEATERSHAKER_MODULE_TYPE, - MAGNETIC_BLOCK_TYPE, - ] const hasGripper = additionalEquipment.some(aE => aE === 'gripper') const handleAddModule = ( @@ -106,48 +98,6 @@ export function SelectModules(props: WizardTileProps): JSX.Element | null { setValue('modules', updatedModules) } - const handleQuantityChange = ( - modules: FormModules, - module: FormModule, - newQuantity: number - ): void => { - if (!modules) return - - const modulesOfType = Object.entries(modules).filter( - ([, mod]) => mod.type === module.type - ) - const otherModules = Object.entries(modules).filter( - ([, mod]) => mod.type !== module.type - ) - - if (newQuantity > modulesOfType.length) { - const additionalModules: FormModules = {} - for (let i = 0; i < newQuantity - modulesOfType.length; i++) { - // @ts-expect-error: TS can't determine modules's type correctly - additionalModules[uuid()] = { - model: module.model, - type: module.type, - slot: null, - } - } - - const newModules = Object.fromEntries([ - ...otherModules, - ...modulesOfType, - ...Object.entries(additionalModules), - ]) - setValue('modules', newModules) - } else if (newQuantity < modulesOfType.length) { - const modulesToKeep = modulesOfType.slice(0, newQuantity) - const updatedModules = Object.fromEntries([ - ...otherModules, - ...modulesToKeep, - ]) - - setValue('modules', updatedModules) - } - } - return ( { - const numSlotsAvailable = getNumSlotsAvailable( - modules, - additionalEquipment, - module.model - ) - const dropdownProps = { - currentOption: { - name: `${module.count}`, - value: `${module.count}`, - }, - onClick: (value: string) => { - handleQuantityChange( - modules, - module as FormModule, - parseInt(value) - ) - }, - dropdownType: 'neutral' as DropdownBorder, - filterOptions: getNumOptions( - module.model !== ABSORBANCE_READER_V1 - ? numSlotsAvailable + module.count - : numSlotsAvailable - ), - } - return ( - - { - handleRemoveModule(module.type) - }} - header={getModuleDisplayName(module.model)} - leftHeaderItem={ - - - - } - /> - - ) - })} + .map(module => ( + + { + handleRemoveModule(module.type) + }} + header={getModuleDisplayName(module.model)} + leftHeaderItem={ + + + + } + /> + + ))} ) : null} @@ -314,8 +226,8 @@ function AddModuleEmptySelectorButton( props: AddModuleEmptySelectorButtonProps ): JSX.Element { const { moduleModel, areSlotsAvailable, hasGripper, handleAddModule } = props - const [targetProps, tooltipProps] = useHoverTooltip() const { t } = useTranslation('create_new_protocol') + const [targetProps, tooltipProps] = useHoverTooltip() const disableGripperRequired = !hasGripper && moduleModel === ABSORBANCE_READER_V1 diff --git a/protocol-designer/src/pages/CreateNewProtocolWizard/index.tsx b/protocol-designer/src/pages/CreateNewProtocolWizard/index.tsx index 2e29273b9ac..0a6e42b6ebe 100644 --- a/protocol-designer/src/pages/CreateNewProtocolWizard/index.tsx +++ b/protocol-designer/src/pages/CreateNewProtocolWizard/index.tsx @@ -40,10 +40,10 @@ import { toggleIsGripperRequired, } from '../../step-forms/actions/additionalItems' import { getNewProtocolModal } from '../../navigation/selectors' +import { SelectModules } from '../../organisms/SelectModules' import { SelectRobot } from './SelectRobot' import { SelectPipettes } from './SelectPipettes' import { SelectGripper } from './SelectGripper' -import { SelectModules } from './SelectModules' import { SelectFixtures } from './SelectFixtures' import { AddMetadata } from './AddMetadata' import { getTrashSlot } from './utils' From 48a2eac6e5dc529eff7b9d3433dbb9b67cc4c54b Mon Sep 17 00:00:00 2001 From: koji Date: Fri, 14 Feb 2025 11:39:21 -0500 Subject: [PATCH 2/7] remove SelectModules from page --- .../CreateNewProtocolWizard/SelectModules.tsx | 254 ------------------ 1 file changed, 254 deletions(-) delete mode 100644 protocol-designer/src/pages/CreateNewProtocolWizard/SelectModules.tsx diff --git a/protocol-designer/src/pages/CreateNewProtocolWizard/SelectModules.tsx b/protocol-designer/src/pages/CreateNewProtocolWizard/SelectModules.tsx deleted file mode 100644 index dd38784f7b6..00000000000 --- a/protocol-designer/src/pages/CreateNewProtocolWizard/SelectModules.tsx +++ /dev/null @@ -1,254 +0,0 @@ -import { useTranslation } from 'react-i18next' -import { - ALIGN_CENTER, - BORDERS, - COLORS, - DIRECTION_COLUMN, - EmptySelectorButton, - FLEX_MAX_CONTENT, - Flex, - ListItem, - SPACING, - StyledText, - Tooltip, - TYPOGRAPHY, - useHoverTooltip, - WRAP, -} from '@opentrons/components' -import { - ABSORBANCE_READER_V1, - FLEX_ROBOT_TYPE, - getModuleDisplayName, - getModuleType, -} from '@opentrons/shared-data' - -import { uuid } from '../../utils' -import { useKitchen } from '../../organisms/Kitchen/hooks' -import { ModuleDiagram } from './ModuleDiagram' -import { WizardBody } from './WizardBody' -import { - DEFAULT_SLOT_MAP_FLEX, - DEFAULT_SLOT_MAP_OT2, - FLEX_SUPPORTED_MODULE_MODELS, - OT2_SUPPORTED_MODULE_MODELS, -} from './constants' -import { getNumSlotsAvailable } from './utils' -import { HandleEnter } from '../../atoms/HandleEnter' -import { PDListItemCustomize as ListItemCustomize } from '../CreateNewProtocolWizard/PDListItemCustomize' - -import type { ModuleModel, ModuleType } from '@opentrons/shared-data' -import type { FormModule } from '../../step-forms' -import type { WizardTileProps } from './types' - -export function SelectModules(props: WizardTileProps): JSX.Element | null { - const { goBack, proceed, watch, setValue } = props - const { t } = useTranslation(['create_new_protocol', 'shared']) - const { makeSnackbar } = useKitchen() - const fields = watch('fields') - const modules = watch('modules') - const additionalEquipment = watch('additionalEquipment') - const robotType = fields.robotType - const supportedModules = - robotType === FLEX_ROBOT_TYPE - ? FLEX_SUPPORTED_MODULE_MODELS - : OT2_SUPPORTED_MODULE_MODELS - const filteredSupportedModules = supportedModules.filter( - moduleModel => - !( - modules != null && - Object.values(modules).some(module => - robotType === FLEX_ROBOT_TYPE - ? module.model === moduleModel - : module.type === getModuleType(moduleModel) - ) - ) - ) - const hasGripper = additionalEquipment.some(aE => aE === 'gripper') - - const handleAddModule = ( - moduleModel: ModuleModel, - hasNoAvailableSlots: boolean - ): void => { - if (hasNoAvailableSlots) { - makeSnackbar(t('slots_limit_reached') as string) - } else { - setValue('modules', { - ...modules, - [uuid()]: { - model: moduleModel, - type: getModuleType(moduleModel), - slot: - robotType === FLEX_ROBOT_TYPE - ? DEFAULT_SLOT_MAP_FLEX[moduleModel] - : DEFAULT_SLOT_MAP_OT2[getModuleType(moduleModel)], - }, - }) - } - } - - const handleRemoveModule = (moduleType: ModuleType): void => { - const updatedModules = - modules != null - ? Object.fromEntries( - Object.entries(modules).filter( - ([key, value]) => value.type !== moduleType - ) - ) - : {} - setValue('modules', updatedModules) - } - - return ( - - { - goBack(1) - setValue('modules', null) - }} - proceed={() => { - proceed(1) - }} - > - - - {filteredSupportedModules.length > 0 || - !( - filteredSupportedModules.length === 1 && - filteredSupportedModules[0] === 'absorbanceReaderV1' - ) ? ( - - {t('which_modules')} - - ) : null} - - {filteredSupportedModules - .sort((moduleA, moduleB) => moduleA.localeCompare(moduleB)) - .map(moduleModel => { - const numSlotsAvailable = getNumSlotsAvailable( - modules, - additionalEquipment, - moduleModel - ) - return ( - 0} - hasGripper={hasGripper} - handleAddModule={handleAddModule} - /> - ) - })} - - {modules != null && Object.keys(modules).length > 0 ? ( - - - {t('modules_added')} - - - {Object.entries(modules) - .sort(([, moduleA], [, moduleB]) => - moduleA.model.localeCompare(moduleB.model) - ) - .reduce>( - (acc, [key, module]) => { - const existingModule = acc.find( - m => m.type === module.type - ) - if (existingModule != null) { - existingModule.count++ - } else { - acc.push({ ...module, count: 1, key }) - } - return acc - }, - [] - ) - .map(module => ( - - { - handleRemoveModule(module.type) - }} - header={getModuleDisplayName(module.model)} - leftHeaderItem={ - - - - } - /> - - ))} - - - ) : null} - - - - - ) -} - -interface AddModuleEmptySelectorButtonProps { - moduleModel: ModuleModel - areSlotsAvailable: boolean - hasGripper: boolean - handleAddModule: (arg0: ModuleModel, arg1: boolean) => void -} - -function AddModuleEmptySelectorButton( - props: AddModuleEmptySelectorButtonProps -): JSX.Element { - const { moduleModel, areSlotsAvailable, hasGripper, handleAddModule } = props - const { t } = useTranslation('create_new_protocol') - const [targetProps, tooltipProps] = useHoverTooltip() - const disableGripperRequired = - !hasGripper && moduleModel === ABSORBANCE_READER_V1 - - return ( - <> - - { - handleAddModule(moduleModel, !areSlotsAvailable) - }} - /> - - {disableGripperRequired ? ( - - {t('add_gripper_for_absorbance_reader')} - - ) : null} - - ) -} From abdf845ae026127f7c0712ba58d252a682952a18 Mon Sep 17 00:00:00 2001 From: koji Date: Fri, 14 Feb 2025 12:07:36 -0500 Subject: [PATCH 3/7] fix file path issue --- .../organisms/SelectModules/__tests__/SelectModules.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol-designer/src/organisms/SelectModules/__tests__/SelectModules.test.tsx b/protocol-designer/src/organisms/SelectModules/__tests__/SelectModules.test.tsx index 9513a211816..afe95b61234 100644 --- a/protocol-designer/src/organisms/SelectModules/__tests__/SelectModules.test.tsx +++ b/protocol-designer/src/organisms/SelectModules/__tests__/SelectModules.test.tsx @@ -4,7 +4,7 @@ import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE } from '@opentrons/shared-data' import { fireEvent, screen } from '@testing-library/react' import { i18n } from '../../../assets/localization' import { renderWithProviders } from '../../../__testing-utils__' -import { SelectModules } from '../../../pages/CreateNewProtocolWizard/SelectModules' +import { SelectModules } from '..' import type { ComponentProps } from 'react' import type { From 41a5386af1174abb41b3ea00e19b6cf7116ceae8 Mon Sep 17 00:00:00 2001 From: koji Date: Wed, 19 Feb 2025 13:42:18 -0500 Subject: [PATCH 4/7] remove unused lines --- .../src/organisms/SelectModules/index.tsx | 27 +++++++------------ .../pages/CreateNewProtocolWizard/utils.tsx | 22 --------------- 2 files changed, 10 insertions(+), 39 deletions(-) diff --git a/protocol-designer/src/organisms/SelectModules/index.tsx b/protocol-designer/src/organisms/SelectModules/index.tsx index e82fe14c317..082fe7107c8 100644 --- a/protocol-designer/src/organisms/SelectModules/index.tsx +++ b/protocol-designer/src/organisms/SelectModules/index.tsx @@ -115,23 +115,16 @@ export function SelectModules(props: WizardTileProps): JSX.Element | null { {filteredSupportedModules .sort((moduleA, moduleB) => moduleA.localeCompare(moduleB)) - .map(moduleModel => { - const numSlotsAvailable = getNumSlotsAvailable( - modules, - additionalEquipment, - moduleModel - ) - return ( - 0} - hasGripper={hasGripper} - handleAddModule={handleAddModule} - tooltipText={t('add_gripper_for_absorbance_reader')} - /> - ) - })} + .map(moduleModel => ( + + ))} {modules != null && Object.keys(modules).length > 0 ? ( 7) { - return 0 - } else { - return 2 - } - } - case 'trashBin': case HEATERSHAKER_MODULE_V1: case TEMPERATURE_MODULE_V2: { From a20c5c344a0309f938ba58ada76fa038a2d06edb Mon Sep 17 00:00:00 2001 From: koji Date: Wed, 19 Feb 2025 13:58:53 -0500 Subject: [PATCH 5/7] fix linting error --- protocol-designer/src/organisms/SelectModules/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/protocol-designer/src/organisms/SelectModules/index.tsx b/protocol-designer/src/organisms/SelectModules/index.tsx index 082fe7107c8..c0d8a3c5426 100644 --- a/protocol-designer/src/organisms/SelectModules/index.tsx +++ b/protocol-designer/src/organisms/SelectModules/index.tsx @@ -25,7 +25,6 @@ import { FLEX_SUPPORTED_MODULE_MODELS, OT2_SUPPORTED_MODULE_MODELS, } from '../../pages/CreateNewProtocolWizard/constants' -import { getNumSlotsAvailable } from '../../pages/CreateNewProtocolWizard/utils' import { HandleEnter } from '../../atoms/HandleEnter' import { PDListItemCustomize as ListItemCustomize } from '../../pages/CreateNewProtocolWizard/PDListItemCustomize' import { AddModuleEmptySelectorButton } from './AddModuleEmptySelectorButton' From 7a3ec4fa22c092486bf35fe06b6ea96f17c89f8f Mon Sep 17 00:00:00 2001 From: koji Date: Wed, 19 Feb 2025 15:07:56 -0500 Subject: [PATCH 6/7] remove unused test cases --- .../__tests__/utils.test.ts | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts b/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts index 908aa24b1f1..9e2d94d703c 100644 --- a/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts +++ b/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts @@ -42,41 +42,6 @@ describe('getNumSlotsAvailable', () => { expect(result).toBe(0) }) - it('should return 1 for a non MoaM module - temperature module', () => { - const result = getNumSlotsAvailable(null, [], TEMPERATURE_MODULE_V1) - expect(result).toBe(1) - }) - - it('should return 1 for a non MoaM module - absorbance plate reader', () => { - const result = getNumSlotsAvailable(null, [], ABSORBANCE_READER_V1) - expect(result).toBe(1) - }) - - it('should return 1 for a non MoaM module - thermocycler v1', () => { - const result = getNumSlotsAvailable(null, [], THERMOCYCLER_MODULE_V1) - expect(result).toBe(1) - }) - - it('should return 1 for a non MoaM module - magnetic module v1', () => { - const result = getNumSlotsAvailable(null, [], MAGNETIC_MODULE_V1) - expect(result).toBe(1) - }) - - it('should return 1 for a non MoaM module - magnetic module v2', () => { - const result = getNumSlotsAvailable(null, [], MAGNETIC_MODULE_V2) - expect(result).toBe(1) - }) - - it('should return 2 for a thermocycler', () => { - const result = getNumSlotsAvailable(null, [], THERMOCYCLER_MODULE_V2) - expect(result).toBe(2) - }) - - it('should return 8 when there are no modules or additional equipment for a heater-shaker', () => { - const result = getNumSlotsAvailable(null, [], HEATERSHAKER_MODULE_V1) - expect(result).toBe(8) - }) - it('should return 3 when there a plate reader', () => { const mockModules = { 0: { From 8a6d92cf2bd794145f89d535bf3143c8b1bf7967 Mon Sep 17 00:00:00 2001 From: koji Date: Wed, 19 Feb 2025 16:54:09 -0500 Subject: [PATCH 7/7] fix linting errors --- .../src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts b/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts index 9e2d94d703c..3f9624e0008 100644 --- a/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts +++ b/protocol-designer/src/pages/CreateNewProtocolWizard/__tests__/utils.test.ts @@ -7,13 +7,9 @@ import { HEATERSHAKER_MODULE_V1, MAGNETIC_BLOCK_TYPE, MAGNETIC_BLOCK_V1, - MAGNETIC_MODULE_V1, - MAGNETIC_MODULE_V2, TEMPERATURE_MODULE_TYPE, - TEMPERATURE_MODULE_V1, TEMPERATURE_MODULE_V2, THERMOCYCLER_MODULE_TYPE, - THERMOCYCLER_MODULE_V1, THERMOCYCLER_MODULE_V2, } from '@opentrons/shared-data' import { getNumSlotsAvailable, getTrashSlot } from '../utils'