From 88408a2f17c59cd109fef1204ef5565723fb7b8e Mon Sep 17 00:00:00 2001
From: Nick Diehl <47604184+ncdiehl11@users.noreply.github.com>
Date: Wed, 15 Jan 2025 17:33:07 -0500
Subject: [PATCH] feat(protocol-designer): initial absorbance reader stepform
UI (#17280)
This PR adds the initial UI for absorbance reader steps. It creates the
new AbsorbanceReaderTools component in line with our other step form
toolbox components, and modularizes its children components for
cleanliness. The content of both pages 1 and 2 of the form are
determined by:
1) module initialization state, and
2) labware presence or lack thereof.
According to designs, the UI will funnel the user into the correct step
form type (lid, initializaton, or reading) based on those 2 inputs. Also
implicated here are creation and wiring up of the following methods:
- patch to pre-select an absorbance reader module if only one is
available
- form change handlers for absorbance reader dependent fields
- absorbance reader module option getter
Closes AUTH-1264
---
.../assets/localization/en/application.json | 3 +-
protocol-designer/src/constants.ts | 9 +-
protocol-designer/src/form-types.ts | 11 +-
.../StepForm/StepFormToolbox.tsx | 1 +
.../InitializationEditor.tsx | 18 +++
.../InitializationSettings.tsx | 50 ++++++
.../AbsorbanceReaderTools/LidControls.tsx | 45 ++++++
.../AbsorbanceReaderTools/ReadSettings.tsx | 40 +++++
.../StepTools/AbsorbanceReaderTools/index.tsx | 151 +++++++++++++++++-
.../utils/createPresavedStepForm.ts | 36 +++++
.../src/steplist/formLevel/createBlankForm.ts | 3 +
.../formLevel/getDefaultsForStepType.ts | 2 +-
.../dependentFieldsUpdateAbsorbanceReader.ts | 40 +++++
.../formLevel/handleFormChange/index.ts | 9 ++
protocol-designer/src/ui/modules/selectors.ts | 19 ++-
protocol-designer/src/ui/modules/utils.ts | 2 +-
16 files changed, 427 insertions(+), 12 deletions(-)
create mode 100644 protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationEditor.tsx
create mode 100644 protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationSettings.tsx
create mode 100644 protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/LidControls.tsx
create mode 100644 protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/ReadSettings.tsx
create mode 100644 protocol-designer/src/steplist/formLevel/handleFormChange/dependentFieldsUpdateAbsorbanceReader.ts
diff --git a/protocol-designer/src/assets/localization/en/application.json b/protocol-designer/src/assets/localization/en/application.json
index c825037224b..9db3ff0ede5 100644
--- a/protocol-designer/src/assets/localization/en/application.json
+++ b/protocol-designer/src/assets/localization/en/application.json
@@ -31,6 +31,7 @@
"protocol_name": "Protocol Name",
"save": "save",
"stepType": {
+ "absorbanceReader": "absorbance plate reader",
"comment": "comment",
"ending_hold": "ending hold",
"heaterShaker": "heater-shaker",
@@ -39,7 +40,6 @@
"moveLabware": "move",
"moveLiquid": "transfer",
"pause": "pause",
- "plateReader": "absorbance reader",
"profile_settings": "profile settings",
"profile_steps": "profile steps",
"temperature": "temperature",
@@ -57,6 +57,7 @@
"microliter": "μL",
"microliterPerSec": "μL/s",
"millimeter": "mm",
+ "nanometer": "nm",
"minutes": "m",
"rpm": "rpm",
"seconds": "s",
diff --git a/protocol-designer/src/constants.ts b/protocol-designer/src/constants.ts
index d8a81595a2e..5f6938de7f6 100644
--- a/protocol-designer/src/constants.ts
+++ b/protocol-designer/src/constants.ts
@@ -177,6 +177,9 @@ export const STAGING_AREA_CUTOUTS_ORDERED: CutoutId[] = [
]
export const ABSORBANCE_READER_INITIALIZE_MODE_SINGLE = 'single'
export const ABSORBANCE_READER_INITIALIZE_MODE_MULTI = 'multi'
-export const ABSORBANCE_READER_INITIALIZE: 'initialize' = 'initialize'
-export const ABSORBANCE_READER_READ: 'read' = 'read'
-export const ABSORBANCE_READER_LID: 'lid' = 'lid'
+export const ABSORBANCE_READER_INITIALIZE: 'absorbanceReaderInitialize' =
+ 'absorbanceReaderInitialize'
+export const ABSORBANCE_READER_READ: 'absorbanceReaderRead' =
+ 'absorbanceReaderRead'
+export const ABSORBANCE_READER_LID: 'absorbanceReaderLid' =
+ 'absorbanceReaderLid'
diff --git a/protocol-designer/src/form-types.ts b/protocol-designer/src/form-types.ts
index a4b69d23404..cf127a2468e 100644
--- a/protocol-designer/src/form-types.ts
+++ b/protocol-designer/src/form-types.ts
@@ -379,11 +379,14 @@ export interface HydratedHeaterShakerFormData {
targetHeaterShakerTemperature: string | null
targetSpeed: string | null
}
+
+export type AbsorbanceReaderFormType =
+ | typeof ABSORBANCE_READER_INITIALIZE
+ | typeof ABSORBANCE_READER_READ
+ | typeof ABSORBANCE_READER_LID
+
export interface HydratedAbsorbanceReaderFormData {
- absorbanceReaderFormType:
- | typeof ABSORBANCE_READER_INITIALIZE
- | typeof ABSORBANCE_READER_READ
- | typeof ABSORBANCE_READER_LID
+ absorbanceReaderFormType: AbsorbanceReaderFormType | null
filePath: string | null
lidOpen: boolean | null
mode:
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormToolbox.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormToolbox.tsx
index 00d2ba8f41d..a9b7b0603eb 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormToolbox.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormToolbox.tsx
@@ -205,6 +205,7 @@ export function StepFormToolbox(props: StepFormToolboxProps): JSX.Element {
}
const isMultiStepToolbox =
+ formData.stepType === 'absorbanceReader' ||
formData.stepType === 'moveLiquid' ||
formData.stepType === 'mix' ||
formData.stepType === 'thermocycler'
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationEditor.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationEditor.tsx
new file mode 100644
index 00000000000..26db4d89f69
--- /dev/null
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationEditor.tsx
@@ -0,0 +1,18 @@
+import { DIRECTION_COLUMN, Flex, SPACING } from '@opentrons/components'
+import type { FormData } from '../../../../../../form-types'
+import type { FieldPropsByName } from '../../types'
+
+interface InitializationEditorProps {
+ formData: FormData
+ propsForFields: FieldPropsByName
+}
+
+export function InitializationEditor(
+ props: InitializationEditorProps
+): JSX.Element {
+ return (
+
+ <>TODO add wavelength component >
+
+ )
+}
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationSettings.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationSettings.tsx
new file mode 100644
index 00000000000..afd6333593d
--- /dev/null
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationSettings.tsx
@@ -0,0 +1,50 @@
+import { useTranslation } from 'react-i18next'
+import {
+ Flex,
+ DIRECTION_COLUMN,
+ SPACING,
+ ListItem,
+ StyledText,
+ InfoScreen,
+} from '@opentrons/components'
+import type { Initialization } from '../../../../../../step-forms/types'
+
+interface InitializationSettingsProps {
+ initialization: Initialization | null
+}
+
+export function InitializationSettings(
+ props: InitializationSettingsProps
+): JSX.Element {
+ const { initialization } = props
+ const { t } = useTranslation('form')
+ const content =
+ initialization == null ? (
+
+ ) : (
+ initialization.wavelengths.map(wavelength => (
+
+ {`${wavelength} ${t(
+ 'application:units.nanometer'
+ )}`}
+
+ ))
+ )
+
+ return (
+
+
+ {t('current_initialization_settings')}
+
+ {content}
+
+ )
+}
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/LidControls.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/LidControls.tsx
new file mode 100644
index 00000000000..fd260685106
--- /dev/null
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/LidControls.tsx
@@ -0,0 +1,45 @@
+import { useTranslation } from 'react-i18next'
+import {
+ DIRECTION_COLUMN,
+ Flex,
+ SPACING,
+ StyledText,
+} from '@opentrons/components'
+import { ToggleStepFormField } from '../../../../../../molecules'
+
+import type { FieldProps } from '../../types'
+
+interface LidControlsProps {
+ fieldProps: FieldProps
+ label?: string
+ paddingX?: string
+}
+
+export function LidControls(props: LidControlsProps): JSX.Element {
+ const { fieldProps, label, paddingX = '0' } = props
+ const { t } = useTranslation('form')
+ return (
+
+ {label != null ? (
+ {label}
+ ) : null}
+ {
+ fieldProps.updateValue(!fieldProps.value)
+ }}
+ toggleValue={fieldProps.value}
+ isDisabled={false}
+ tooltipContent={null}
+ />
+
+ )
+}
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/ReadSettings.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/ReadSettings.tsx
new file mode 100644
index 00000000000..b899b7d75e2
--- /dev/null
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/ReadSettings.tsx
@@ -0,0 +1,40 @@
+import { useTranslation } from 'react-i18next'
+import {
+ DIRECTION_COLUMN,
+ Flex,
+ SPACING,
+ StyledText,
+} from '@opentrons/components'
+import { InputStepFormField } from '../../../../../../molecules'
+import type { FieldPropsByName } from '../../types'
+
+interface ReadSettingsProps {
+ propsForFields: FieldPropsByName
+}
+
+export function ReadSettings(props: ReadSettingsProps): JSX.Element {
+ const { propsForFields } = props
+ const { t } = useTranslation('form')
+ return (
+
+
+
+ {t('export_settings')}
+
+
+ {t('export_detail')}
+
+
+
+
+ )
+}
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/index.tsx
index 3b07a003fa3..8c831d29b94 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/index.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/index.tsx
@@ -1,5 +1,154 @@
+import { useEffect } from 'react'
+import { useTranslation } from 'react-i18next'
+import { useDispatch, useSelector } from 'react-redux'
+import {
+ DIRECTION_COLUMN,
+ Divider,
+ Flex,
+ RadioButton,
+ SPACING,
+ StyledText,
+} from '@opentrons/components'
+import {
+ ABSORBANCE_READER_INITIALIZE,
+ ABSORBANCE_READER_LID,
+ ABSORBANCE_READER_READ,
+} from '../../../../../../constants'
+import { DropdownStepFormField } from '../../../../../../molecules'
+import { getRobotStateAtActiveItem } from '../../../../../../top-selectors/labware-locations'
+import { getAbsorbanceReaderLabwareOptions } from '../../../../../../ui/modules/selectors'
+import { hoverSelection } from '../../../../../../ui/steps/actions/actions'
+import { InitializationSettings } from './InitializationSettings'
+import { InitializationEditor } from './InitializationEditor'
+import { LidControls } from './LidControls'
+import { ReadSettings } from './ReadSettings'
+
+import type { AbsorbanceReaderState } from '@opentrons/step-generation'
+import type { AbsorbanceReaderFormType } from '../../../../../../form-types'
import type { StepFormProps } from '../../types'
export function AbsorbanceReaderTools(props: StepFormProps): JSX.Element {
- return
TODO: ADD PLATE READER TOOLS
+ const { formData, propsForFields, toolboxStep } = props
+ const { moduleId } = formData
+ const dispatch = useDispatch()
+ const { t } = useTranslation('form')
+ const robotState = useSelector(getRobotStateAtActiveItem)
+ const absorbanceReaderOptions = useSelector(getAbsorbanceReaderLabwareOptions)
+ const { labware = {}, modules = {} } = robotState ?? {}
+ const isLabwareOnAbsorbanceReader = Object.values(labware).some(
+ lw => lw.slot === propsForFields.moduleId.value
+ )
+ const absorbanceReaderFormType = formData.absorbanceReaderFormType as AbsorbanceReaderFormType
+ const absorbanceReaderState = modules[moduleId]
+ ?.moduleState as AbsorbanceReaderState | null
+ const initialization = absorbanceReaderState?.initialization ?? null
+
+ const enableReadOrInitialization =
+ !isLabwareOnAbsorbanceReader || initialization != null
+ const compoundCommandType = isLabwareOnAbsorbanceReader
+ ? ABSORBANCE_READER_READ
+ : ABSORBANCE_READER_INITIALIZE
+
+ // pre-select radio button on mount and module change if not previously set
+ useEffect(() => {
+ if (formData.absorbanceReaderFormType == null) {
+ if (enableReadOrInitialization) {
+ propsForFields.absorbanceReaderFormType.updateValue(compoundCommandType)
+ return
+ }
+ propsForFields.absorbanceReaderFormType.updateValue(ABSORBANCE_READER_LID)
+ }
+ }, [formData.moduleId])
+
+ const lidRadioButton = (
+ {
+ propsForFields.absorbanceReaderFormType.updateValue(
+ ABSORBANCE_READER_LID
+ )
+ }}
+ isSelected={absorbanceReaderFormType === ABSORBANCE_READER_LID}
+ buttonLabel={t('change_lid_position')}
+ buttonValue={ABSORBANCE_READER_LID}
+ largeDesktopBorderRadius
+ />
+ )
+ const compoundCommandButton = (
+ {
+ propsForFields.absorbanceReaderFormType.updateValue(compoundCommandType)
+ }}
+ isSelected={absorbanceReaderFormType === compoundCommandType}
+ buttonLabel={t(compoundCommandType)}
+ buttonValue={compoundCommandType}
+ largeDesktopBorderRadius
+ />
+ )
+
+ const page1Content = (
+
+ {
+ dispatch(hoverSelection({ id, text: t('select') }))
+ }}
+ onExit={() => {
+ dispatch(hoverSelection({ id: null, text: null }))
+ }}
+ />
+ {moduleId != null ? (
+ <>
+
+
+
+
+
+
+
+ {t('module_controls')}
+
+ {enableReadOrInitialization ? (
+ <>
+ {compoundCommandButton}
+ {lidRadioButton}
+ >
+ ) : (
+
+ )}
+
+ >
+ ) : null}
+
+ )
+
+ const page2ContentMap = {
+ [ABSORBANCE_READER_READ]: ,
+ [ABSORBANCE_READER_INITIALIZE]: (
+
+ ),
+ [ABSORBANCE_READER_LID]: (
+
+ ),
+ }
+
+ const contentByPage: JSX.Element[] = [
+ page1Content,
+ page2ContentMap[absorbanceReaderFormType],
+ ]
+
+ return {contentByPage[toolboxStep]}
}
diff --git a/protocol-designer/src/step-forms/utils/createPresavedStepForm.ts b/protocol-designer/src/step-forms/utils/createPresavedStepForm.ts
index 5951fbf0a04..137e0afc60d 100644
--- a/protocol-designer/src/step-forms/utils/createPresavedStepForm.ts
+++ b/protocol-designer/src/step-forms/utils/createPresavedStepForm.ts
@@ -1,5 +1,6 @@
import last from 'lodash/last'
import {
+ ABSORBANCE_READER_TYPE,
HEATERSHAKER_MODULE_TYPE,
MAGNETIC_MODULE_TYPE,
TEMPERATURE_MODULE_TYPE,
@@ -284,6 +285,33 @@ const _patchHeaterShakerModuleId = (args: {
return null
}
+const _patchAbsorbanceReaderModuleId = (args: {
+ initialDeckSetup: InitialDeckSetup
+ orderedStepIds: OrderedStepIdsState
+ savedStepForms: SavedStepFormState
+ stepType: StepType
+}): FormUpdater => () => {
+ const { initialDeckSetup, stepType } = args
+ const numOfModules =
+ Object.values(initialDeckSetup.modules).filter(
+ module => module.type === ABSORBANCE_READER_TYPE
+ )?.length ?? 1
+ const hasAbsorbanceReaderModuleId = stepType === 'absorbanceReader'
+
+ if (hasAbsorbanceReaderModuleId && numOfModules === 1) {
+ const moduleId =
+ getModuleOnDeckByType(initialDeckSetup, ABSORBANCE_READER_TYPE)?.id ??
+ null
+ if (moduleId != null) {
+ return {
+ moduleId,
+ }
+ }
+ }
+
+ return null
+}
+
const _patchThermocyclerFields = (args: {
initialDeckSetup: InitialDeckSetup
stepType: StepType
@@ -376,6 +404,13 @@ export const createPresavedStepForm = ({
stepType,
})
+ const updateAbsorbanceReaderModuleId = _patchAbsorbanceReaderModuleId({
+ initialDeckSetup,
+ orderedStepIds,
+ savedStepForms,
+ stepType,
+ })
+
const updateThermocyclerFields = _patchThermocyclerFields({
initialDeckSetup,
stepType,
@@ -391,6 +426,7 @@ export const createPresavedStepForm = ({
updateThermocyclerFields,
updateHeaterShakerModuleId,
updateMagneticModuleId,
+ updateAbsorbanceReaderModuleId,
updateDefaultLabwareLocations,
].reduce(
(acc, updater: FormUpdater) => {
diff --git a/protocol-designer/src/steplist/formLevel/createBlankForm.ts b/protocol-designer/src/steplist/formLevel/createBlankForm.ts
index 764529dc379..270544188f6 100644
--- a/protocol-designer/src/steplist/formLevel/createBlankForm.ts
+++ b/protocol-designer/src/steplist/formLevel/createBlankForm.ts
@@ -13,6 +13,9 @@ interface NewFormArgs {
// TODO(jr, 1/17/24): add to i18n
const getStepType = (stepType: StepType): string => {
switch (stepType) {
+ case 'absorbanceReader': {
+ return 'absorbance plate reader'
+ }
case 'heaterShaker': {
return 'heater-shaker'
}
diff --git a/protocol-designer/src/steplist/formLevel/getDefaultsForStepType.ts b/protocol-designer/src/steplist/formLevel/getDefaultsForStepType.ts
index 5aaecf70d86..1e6231fe7f3 100644
--- a/protocol-designer/src/steplist/formLevel/getDefaultsForStepType.ts
+++ b/protocol-designer/src/steplist/formLevel/getDefaultsForStepType.ts
@@ -177,7 +177,7 @@ export function getDefaultsForStepType(
}
case 'absorbanceReader':
return {
- absorbanceReaderFormType: 'initialize',
+ absorbanceReaderFormType: null,
filePath: null,
lidOpen: null,
mode: null,
diff --git a/protocol-designer/src/steplist/formLevel/handleFormChange/dependentFieldsUpdateAbsorbanceReader.ts b/protocol-designer/src/steplist/formLevel/handleFormChange/dependentFieldsUpdateAbsorbanceReader.ts
new file mode 100644
index 00000000000..930cf130920
--- /dev/null
+++ b/protocol-designer/src/steplist/formLevel/handleFormChange/dependentFieldsUpdateAbsorbanceReader.ts
@@ -0,0 +1,40 @@
+import pick from 'lodash/pick'
+import { chainPatchUpdaters, fieldHasChanged } from './utils'
+import { getDefaultsForStepType } from '../getDefaultsForStepType'
+import type { FormData, StepFieldName } from '../../../form-types'
+import type { FormPatch } from '../../actions/types'
+
+const getDefaultFields = (...fields: StepFieldName[]): FormPatch =>
+ pick(getDefaultsForStepType('absorbanceReader'), fields)
+
+const updatePatchOnAbsorbanceReaderFormType = (
+ patch: FormPatch,
+ rawForm: FormData
+): FormPatch => {
+ if (
+ rawForm.absorbanceReaderFormType !== null &&
+ fieldHasChanged(rawForm, patch, 'absorbanceReaderFormType')
+ ) {
+ return {
+ ...patch,
+ ...getDefaultFields(
+ 'wavelengths',
+ 'referenceWavelength',
+ 'lidOpen',
+ 'mode',
+ 'filePath'
+ ),
+ }
+ }
+
+ return patch
+}
+
+export const dependentFieldsUpdateAbsorbanceReader = (
+ originalPatch: FormPatch,
+ rawForm: FormData
+): FormPatch => {
+ return chainPatchUpdaters(originalPatch, [
+ chainPatch => updatePatchOnAbsorbanceReaderFormType(chainPatch, rawForm),
+ ])
+}
diff --git a/protocol-designer/src/steplist/formLevel/handleFormChange/index.ts b/protocol-designer/src/steplist/formLevel/handleFormChange/index.ts
index a86737aa037..320a0d88755 100644
--- a/protocol-designer/src/steplist/formLevel/handleFormChange/index.ts
+++ b/protocol-designer/src/steplist/formLevel/handleFormChange/index.ts
@@ -1,3 +1,4 @@
+import { dependentFieldsUpdateAbsorbanceReader } from './dependentFieldsUpdateAbsorbanceReader'
import { dependentFieldsUpdateMoveLiquid } from './dependentFieldsUpdateMoveLiquid'
import { dependentFieldsUpdateMix } from './dependentFieldsUpdateMix'
import { dependentFieldsUpdateMagnet } from './dependentFieldsUpdateMagnet'
@@ -73,5 +74,13 @@ export function handleFormChange(
return { ...patch, ...dependentFieldsPatch }
}
+ if (rawForm.stepType === 'absorbanceReader') {
+ const dependentFieldsPatch = dependentFieldsUpdateAbsorbanceReader(
+ patch,
+ rawForm
+ )
+ return { ...patch, ...dependentFieldsPatch }
+ }
+
return patch
}
diff --git a/protocol-designer/src/ui/modules/selectors.ts b/protocol-designer/src/ui/modules/selectors.ts
index 8fdd6e10c0d..c0b9da78da7 100644
--- a/protocol-designer/src/ui/modules/selectors.ts
+++ b/protocol-designer/src/ui/modules/selectors.ts
@@ -1,10 +1,11 @@
import { createSelector } from 'reselect'
import mapValues from 'lodash/mapValues'
import {
+ ABSORBANCE_READER_TYPE,
getLabwareDisplayName,
+ HEATERSHAKER_MODULE_TYPE,
MAGNETIC_MODULE_TYPE,
TEMPERATURE_MODULE_TYPE,
- HEATERSHAKER_MODULE_TYPE,
} from '@opentrons/shared-data'
import { getInitialDeckSetup } from '../../step-forms/selectors'
import { getLabwareNicknamesById } from '../labware/selectors'
@@ -81,6 +82,22 @@ export const getHeaterShakerLabwareOptions: Selector<
}
)
+/** Returns dropdown option for labware placed on absorbance reader module */
+export const getAbsorbanceReaderLabwareOptions: Selector<
+ DropdownOption[]
+> = createSelector(
+ getInitialDeckSetup,
+ getLabwareNicknamesById,
+ (initialDeckSetup, nicknamesById) => {
+ const absorbanceReaderModuleOptions = getModuleLabwareOptions(
+ initialDeckSetup,
+ nicknamesById,
+ ABSORBANCE_READER_TYPE
+ )
+ return absorbanceReaderModuleOptions
+ }
+)
+
/** Get single magnetic module (assumes no multiples) */
export const getSingleMagneticModuleId: Selector<
string | null
diff --git a/protocol-designer/src/ui/modules/utils.ts b/protocol-designer/src/ui/modules/utils.ts
index d347c1b5388..6aaa6fe2d80 100644
--- a/protocol-designer/src/ui/modules/utils.ts
+++ b/protocol-designer/src/ui/modules/utils.ts
@@ -93,7 +93,7 @@ export const getModuleShortNames = (type: ModuleType): string => {
case THERMOCYCLER_MODULE_TYPE:
return 'Thermocycler'
case ABSORBANCE_READER_TYPE:
- return 'Absorbance Reader'
+ return 'Absorbance Plate Reader'
}
}