Skip to content

Commit

Permalink
feat(protocol-designer): transfer tools advanced settings
Browse files Browse the repository at this point in the history
closes AUTH-870
  • Loading branch information
jerader committed Oct 15, 2024
1 parent 80176ba commit 5286092
Show file tree
Hide file tree
Showing 14 changed files with 1,198 additions and 9 deletions.
1 change: 1 addition & 0 deletions components/src/atoms/InputField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ export const InputField = React.forwardRef<HTMLInputElement, InputFieldProps>(

return (
<Flex
width="100%"
alignItems={ALIGN_CENTER}
lineHeight={1}
fontSize={TYPOGRAPHY.fontSizeP}
Expand Down
21 changes: 20 additions & 1 deletion protocol-designer/src/assets/localization/en/protocol_steps.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
{
"add_details": "Add step details",
"advanced_settings": "Advanced pipetting settings",
"air_gap_volume": "Air gap volume",
"aspirate": "Aspirate",
"aspirated": "Aspirated",
"batch_edit_steps": "Batch edit steps",
"batch_edit": "Batch edit",
"batch_edits_saved": "Batch edits saved",
"blowout_location": "Blowout location",
"blowout_position": "Blowout position from bottom",
"change_tips": "Change tips",
"default_tip_option": "Default - get next tip",
"delay_duration": "Delay duration",
"delay_position": "Delay position from bottom",
"delete_steps": "Delete steps",
"delete": "Delete step",
"dispense": "Dispense",
"dispensed": "Dispensed",
"disposal_volume": "Disposal volume",
"duplicate_steps": "Duplicate steps",
"duplicate": "Duplicate step",
"edit_step": "Edit step",
"engage_height": "Engage height",
"final_deck_state": "Final deck state",
"flow_type_title": "{{type}} flow rate",
"from": "from",
"heater_shaker_settings": "Heater-shaker settings",
"in": "in",
"into": "into",
"max_disposal_volume": "Max {{vol}} {{unit}}",
"mix_times": "Mix repititions",
"mix_volume": "Mix volume",
"mix": "Mix",
"module": "Module",
"multi_dispense_options": "Distribute options",
"multiAspirate": "Consolidate path",
"multiDispense": "Distribute path",
"new_location": "New location",
Expand Down Expand Up @@ -48,6 +62,11 @@
"step_substeps": "{{stepType}} details",
"temperature": "Temperature",
"time": "Time",
"tip_position": "{{prefix}} tip position",
"touch_tip_position": "Touch tip position from top",
"valid_range": "Valid range between {{min}} - {{max}} {{unit}}",
"view_details": "View details",
"well_name": "Well {{wellName}}"
"well_name": "Well {{wellName}}",
"well_order_title": "{{prefix}} well order",
"well_position": "Well position (x,y,z): "
}
1 change: 1 addition & 0 deletions protocol-designer/src/assets/localization/en/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"destination_well": "Destination Well",
"developer_ff": "Developer feature flags",
"done": "Done",
"pipette": "Pipette",
"edit_existing": "Edit existing protocol",
"edit_instruments": "Edit Instruments",
"edit_pipette": "Edit Pipette",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface CheckboxExpandStepFormFieldProps {
checkboxUpdateValue: (value: unknown) => void
checkboxValue: unknown
isChecked: boolean
children: React.ReactNode
children?: React.ReactNode
}
export function CheckboxExpandStepFormField(
props: CheckboxExpandStepFormFieldProps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import type { FieldProps } from '../../pages/Designer/ProtocolSteps/StepForm/typ
export interface DropdownStepFormFieldProps extends FieldProps {
options: Options
title: string
addPadding?: boolean
width?: string
}

export function DropdownStepFormField(
Expand All @@ -18,15 +20,17 @@ export function DropdownStepFormField(
title,
errorToShow,
tooltipContent,
addPadding = true,
width = '17.5rem',
} = props
const { t } = useTranslation('tooltip')
const availableOptionId = options.find(opt => opt.value === value)

return (
<Flex padding={SPACING.spacing16}>
<Flex padding={addPadding ? SPACING.spacing16 : 0}>
<DropdownMenu
tooltipText={tooltipContent != null ? t(`${tooltipContent}`) : null}
width="17.5rem"
width={width}
error={errorToShow}
dropdownType="neutral"
filterOptions={options}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
import { selectors as uiLabwareSelectors } from '../../../../../ui/labware'
import { DropdownStepFormField } from '../../../../../molecules'
import type { Options } from '@opentrons/components'
import type { FieldProps } from '../types'

type BlowoutLocationDropdownProps = FieldProps & {
options: Options
}

export const BlowoutLocationField = (
props: BlowoutLocationDropdownProps
): JSX.Element => {
const { options: propOptions, ...restProps } = props
const { t } = useTranslation('protocol_steps')
const disposalOptions = useSelector(uiLabwareSelectors.getDisposalOptions)
const options = [...disposalOptions, ...propOptions]

return (
<DropdownStepFormField
title={t('blowout_location')}
options={options}
addPadding={false}
{...restProps}
width="16.5rem"
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { useState } from 'react'
import { useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
import {
DEST_WELL_BLOWOUT_DESTINATION,
SOURCE_WELL_BLOWOUT_DESTINATION,
} from '@opentrons/step-generation'
import { getWellDepth } from '@opentrons/shared-data'
import {
Flex,
InputField,
Tooltip,
useHoverTooltip,
} from '@opentrons/components'
import { ZTipPositionModal } from '../../../../../components/StepEditForm/fields/TipPositionField/ZTipPositionModal'
import { getLabwareEntities } from '../../../../../step-forms/selectors'
import type { FieldProps } from '../types'

interface BlowoutZOffsetFieldProps extends FieldProps {
destLabwareId: unknown
sourceLabwareId?: unknown
blowoutLabwareId?: unknown
}

export function BlowoutZOffsetField(
props: BlowoutZOffsetFieldProps
): JSX.Element {
const {
disabled,
value,
destLabwareId,
sourceLabwareId,
blowoutLabwareId,
tooltipContent,
name,
isIndeterminate,
updateValue,
} = props
const { t } = useTranslation(['application', 'protocol_steps'])
const [isModalOpen, setModalOpen] = useState<boolean>(false)
const [targetProps, tooltipProps] = useHoverTooltip()
const labwareEntities = useSelector(getLabwareEntities)

let labwareId = null
if (blowoutLabwareId === SOURCE_WELL_BLOWOUT_DESTINATION) {
labwareId = sourceLabwareId
} else if (blowoutLabwareId === DEST_WELL_BLOWOUT_DESTINATION) {
labwareId = destLabwareId
}

const labwareWellDepth =
labwareId != null && labwareEntities[String(labwareId)]?.def != null
? getWellDepth(labwareEntities[String(labwareId)].def, 'A1')
: 0

return (
<>
<Tooltip tooltipProps={tooltipProps}>{tooltipContent}</Tooltip>
{isModalOpen ? (
<ZTipPositionModal
closeModal={() => {
setModalOpen(false)
}}
name={name}
zValue={Number(value)}
updateValue={updateValue}
wellDepthMm={labwareWellDepth}
/>
) : null}

<Flex {...targetProps}>
<InputField
title={t('protocol_steps:blowout_position')}
disabled={disabled}
readOnly
onClick={
disabled
? undefined
: () => {
setModalOpen(true)
}
}
value={String(value)}
isIndeterminate={isIndeterminate}
units={t('units.millimeter')}
id={`TipPositionField_${name}`}
/>
</Flex>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import { Flex, DIRECTION_COLUMN, SPACING } from '@opentrons/components'
import { getMaxDisposalVolumeForMultidispense } from '../../../../../steplist/formLevel/handleFormChange/utils'
import { selectors as stepFormSelectors } from '../../../../../step-forms'
import { selectors as uiLabwareSelectors } from '../../../../../ui/labware'
import {
CheckboxExpandStepFormField,
DropdownStepFormField,
InputStepFormField,
} from '../../../../../molecules'
import { getBlowoutLocationOptionsForForm } from '../utils'
import { FlowRateField } from './FlowRateField'
import { BlowoutZOffsetField } from './BlowoutZOffsetField'

import type { PathOption, StepType } from '../../../../../form-types'
import type { FieldPropsByName } from '../types'

interface DisposalVolumeFieldProps {
path: PathOption
pipette: string | null
propsForFields: FieldPropsByName
stepType: StepType
volume: string | null
aspirate_airGap_checkbox?: boolean | null
aspirate_airGap_volume?: string | null
tipRack?: string | null
}

export const DisposalVolumeField = (
props: DisposalVolumeFieldProps
): JSX.Element => {
const {
path,
stepType,
volume,
pipette,
propsForFields,
aspirate_airGap_checkbox,
aspirate_airGap_volume,
tipRack,
} = props
const { t } = useTranslation(['application', 'form'])

const disposalOptions = useSelector(uiLabwareSelectors.getDisposalOptions)
const pipetteEntities = useSelector(stepFormSelectors.getPipetteEntities)
const blowoutLocationOptions = getBlowoutLocationOptionsForForm({
path,
stepType,
})
const maxDisposalVolume = getMaxDisposalVolumeForMultidispense(
{
aspirate_airGap_checkbox,
aspirate_airGap_volume,
path,
pipette,
volume,
tipRack,
},
pipetteEntities
)
const disposalDestinationOptions = [
...disposalOptions,
...blowoutLocationOptions,
]

const volumeBoundsCaption =
maxDisposalVolume != null
? t('protocol_steps:max_disposal_volume', {
vol: maxDisposalVolume,
unit: t('units.microliter'),
})
: ''

const { value, updateValue } = propsForFields.disposalVolume_checkbox
return (
<CheckboxExpandStepFormField
title={t('protocol_steps:multi_dispense_options')}
checkboxValue={value}
isChecked={value === true}
checkboxUpdateValue={updateValue}
>
{value ? (
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing6}>
<InputStepFormField
{...propsForFields.disposalVolume_volume}
title={t('protocol_steps:disposal_volume')}
units={t('units.microliter')}
padding="0"
showTooltip={false}
caption={volumeBoundsCaption}
/>
<DropdownStepFormField
{...propsForFields.blowout_location}
options={disposalDestinationOptions}
title={t('protocol_steps:blowout_location')}
addPadding={false}
width="16.5rem"
/>
<FlowRateField
{...propsForFields.blowout_flowRate}
pipetteId={pipette}
flowRateType="blowout"
volume={propsForFields.volume?.value ?? 0}
tiprack={propsForFields.tipRack.value}
/>
<BlowoutZOffsetField
{...propsForFields.blowout_z_offset}
sourceLabwareId={propsForFields.aspirate_labware.value}
destLabwareId={propsForFields.dispense_labware.value}
blowoutLabwareId={propsForFields.blowout_location.value}
/>
</Flex>
) : null}
</CheckboxExpandStepFormField>
)
}
Loading

0 comments on commit 5286092

Please sign in to comment.