-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
16 changed files
with
427 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
.../Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationEditor.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ( | ||
<Flex gridGap={SPACING.spacing4} flexDirection={DIRECTION_COLUMN}> | ||
<>TODO add wavelength component </> | ||
</Flex> | ||
) | ||
} |
50 changes: 50 additions & 0 deletions
50
...esigner/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/InitializationSettings.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ? ( | ||
<InfoScreen height="12.75rem" content={t('no_settings_defined')} /> | ||
) : ( | ||
initialization.wavelengths.map(wavelength => ( | ||
<ListItem | ||
type="noActive" | ||
key={`listItem_${wavelength}`} | ||
padding={SPACING.spacing12} | ||
> | ||
<StyledText desktopStyle="bodyDefaultRegular">{`${wavelength} ${t( | ||
'application:units.nanometer' | ||
)}`}</StyledText> | ||
</ListItem> | ||
)) | ||
) | ||
|
||
return ( | ||
<Flex | ||
flexDirection={DIRECTION_COLUMN} | ||
gridGap={SPACING.spacing4} | ||
width="100%" | ||
> | ||
<StyledText desktopStyle="bodyDefaultSemiBold"> | ||
{t('current_initialization_settings')} | ||
</StyledText> | ||
{content} | ||
</Flex> | ||
) | ||
} |
45 changes: 45 additions & 0 deletions
45
...src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/LidControls.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ( | ||
<Flex | ||
width="100%" | ||
paddingX={paddingX} | ||
flexDirection={DIRECTION_COLUMN} | ||
gridGap={SPACING.spacing4} | ||
> | ||
{label != null ? ( | ||
<StyledText desktopStyle="bodyDefaultSemiBold">{label}</StyledText> | ||
) : null} | ||
<ToggleStepFormField | ||
title={t('lid_position')} | ||
isSelected={fieldProps.value === true} | ||
onLabel={t('open')} | ||
offLabel={t('closed')} | ||
toggleUpdateValue={() => { | ||
fieldProps.updateValue(!fieldProps.value) | ||
}} | ||
toggleValue={fieldProps.value} | ||
isDisabled={false} | ||
tooltipContent={null} | ||
/> | ||
</Flex> | ||
) | ||
} |
40 changes: 40 additions & 0 deletions
40
...rc/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/ReadSettings.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ( | ||
<Flex | ||
flexDirection={DIRECTION_COLUMN} | ||
paddingX={SPACING.spacing16} | ||
gridGap={SPACING.spacing12} | ||
width="100%" | ||
> | ||
<Flex flexDirection={DIRECTION_COLUMN}> | ||
<StyledText desktopStyle="bodyDefaultSemiBold"> | ||
{t('export_settings')} | ||
</StyledText> | ||
<StyledText desktopStyle="bodyDefaultRegular"> | ||
{t('export_detail')} | ||
</StyledText> | ||
</Flex> | ||
<InputStepFormField | ||
padding="0" | ||
{...propsForFields.filePath} | ||
title={t('exported_file_name')} | ||
/> | ||
</Flex> | ||
) | ||
} |
151 changes: 150 additions & 1 deletion
151
...igner/src/pages/Designer/ProtocolSteps/StepForm/StepTools/AbsorbanceReaderTools/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <div>TODO: ADD PLATE READER TOOLS</div> | ||
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 = ( | ||
<RadioButton | ||
onChange={() => { | ||
propsForFields.absorbanceReaderFormType.updateValue( | ||
ABSORBANCE_READER_LID | ||
) | ||
}} | ||
isSelected={absorbanceReaderFormType === ABSORBANCE_READER_LID} | ||
buttonLabel={t('change_lid_position')} | ||
buttonValue={ABSORBANCE_READER_LID} | ||
largeDesktopBorderRadius | ||
/> | ||
) | ||
const compoundCommandButton = ( | ||
<RadioButton | ||
onChange={() => { | ||
propsForFields.absorbanceReaderFormType.updateValue(compoundCommandType) | ||
}} | ||
isSelected={absorbanceReaderFormType === compoundCommandType} | ||
buttonLabel={t(compoundCommandType)} | ||
buttonValue={compoundCommandType} | ||
largeDesktopBorderRadius | ||
/> | ||
) | ||
|
||
const page1Content = ( | ||
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing12}> | ||
<DropdownStepFormField | ||
options={absorbanceReaderOptions} | ||
title={t('module')} | ||
{...propsForFields.moduleId} | ||
tooltipContent={null} | ||
onEnter={(id: string) => { | ||
dispatch(hoverSelection({ id, text: t('select') })) | ||
}} | ||
onExit={() => { | ||
dispatch(hoverSelection({ id: null, text: null })) | ||
}} | ||
/> | ||
{moduleId != null ? ( | ||
<> | ||
<Divider marginY="0" /> | ||
<Flex paddingX={SPACING.spacing16}> | ||
<InitializationSettings initialization={initialization} /> | ||
</Flex> | ||
<Divider marginY="0" /> | ||
<Flex | ||
flexDirection={DIRECTION_COLUMN} | ||
gridGap={SPACING.spacing4} | ||
paddingX={SPACING.spacing16} | ||
> | ||
<StyledText desktopStyle="bodyDefaultSemiBold"> | ||
{t('module_controls')} | ||
</StyledText> | ||
{enableReadOrInitialization ? ( | ||
<> | ||
{compoundCommandButton} | ||
{lidRadioButton} | ||
</> | ||
) : ( | ||
<LidControls fieldProps={propsForFields.lidOpen} /> | ||
)} | ||
</Flex> | ||
</> | ||
) : null} | ||
</Flex> | ||
) | ||
|
||
const page2ContentMap = { | ||
[ABSORBANCE_READER_READ]: <ReadSettings propsForFields={propsForFields} />, | ||
[ABSORBANCE_READER_INITIALIZE]: ( | ||
<InitializationEditor | ||
formData={formData} | ||
propsForFields={propsForFields} | ||
/> | ||
), | ||
[ABSORBANCE_READER_LID]: ( | ||
<LidControls | ||
fieldProps={propsForFields.lidOpen} | ||
label={t('change_lid_position')} | ||
paddingX={SPACING.spacing16} | ||
/> | ||
), | ||
} | ||
|
||
const contentByPage: JSX.Element[] = [ | ||
page1Content, | ||
page2ContentMap[absorbanceReaderFormType], | ||
] | ||
|
||
return <Flex paddingY={SPACING.spacing16}>{contentByPage[toolboxStep]}</Flex> | ||
} |
Oops, something went wrong.