diff --git a/protocol-designer/src/assets/localization/en/application.json b/protocol-designer/src/assets/localization/en/application.json
index 78394f35ab7..b4d1ebf8157 100644
--- a/protocol-designer/src/assets/localization/en/application.json
+++ b/protocol-designer/src/assets/localization/en/application.json
@@ -43,7 +43,7 @@
"thermocycler": "thermocycler"
},
"temperature": "Temperature (˚C)",
- "time": "Time (hh:mm:ss)",
+ "time": "Time",
"units": {
"cycles": "cycles",
"degrees": "°C",
@@ -55,6 +55,7 @@
"rpm": "rpm",
"seconds": "s",
"time": "mm:ss",
+ "time_hms": "hh:mm:ss",
"times": "x"
},
"update": "UPDATE",
diff --git a/protocol-designer/src/assets/localization/en/form.json b/protocol-designer/src/assets/localization/en/form.json
index 80bef5b5a20..995c6ae9d0e 100644
--- a/protocol-designer/src/assets/localization/en/form.json
+++ b/protocol-designer/src/assets/localization/en/form.json
@@ -72,23 +72,24 @@
"range": "between {{min}} and {{max}}"
},
"heaterShaker": {
+ "duration": "Duration",
"latch": {
- "setLatch": "Labware Latch",
- "toggleOff": "Closed & Locked",
+ "setLatch": "Labware latch",
+ "toggleOff": "Close",
"toggleOn": "Open"
},
"shaker": {
- "setShake": "Set shake speed",
- "toggleOff": "Deactivated",
+ "setShake": "Shake speed",
+ "toggleOff": "Deactivate",
"toggleOn": "Active"
},
"temperature": {
- "setTemperature": "Set temperature",
- "toggleOff": "Deactivated",
+ "setTemperature": "Temperature",
+ "toggleOff": "Deactivate",
"toggleOn": "Active"
},
"timer": {
- "heaterShakerSetTimer": "Set timer"
+ "heaterShakerSetTimer": "Timer"
}
},
"location": {
@@ -144,6 +145,7 @@
}
},
"pauseAction": {
+ "duration": "Delay duration",
"options": {
"untilResume": "Pause until told to resume",
"untilTemperature": "Pause until temperature reached",
diff --git a/protocol-designer/src/assets/localization/en/protocol_steps.json b/protocol-designer/src/assets/localization/en/protocol_steps.json
index b2f00290059..4f7e3a00ed6 100644
--- a/protocol-designer/src/assets/localization/en/protocol_steps.json
+++ b/protocol-designer/src/assets/localization/en/protocol_steps.json
@@ -93,6 +93,7 @@
"select_volume": "Select a volume",
"shake": "Shake",
"single": "Single path",
+ "speed": "Speed",
"starting_deck_state": "Starting deck state",
"step_substeps": "{{stepType}} details",
"temperature": "Temperature",
diff --git a/protocol-designer/src/atoms/ToggleButton/index.tsx b/protocol-designer/src/atoms/ToggleButton/index.tsx
index 9bb4c45a330..0dfb605ec7b 100644
--- a/protocol-designer/src/atoms/ToggleButton/index.tsx
+++ b/protocol-designer/src/atoms/ToggleButton/index.tsx
@@ -1,7 +1,7 @@
import type * as React from 'react'
import { css } from 'styled-components'
-import { Btn, Icon, COLORS } from '@opentrons/components'
+import { Btn, Icon, COLORS, Flex } from '@opentrons/components'
import type { StyleProps } from '@opentrons/components'
@@ -38,8 +38,8 @@ const TOGGLE_ENABLED_STYLES = css`
`
interface ToggleButtonProps extends StyleProps {
- label: string
toggledOn: boolean
+ label?: string | null
disabled?: boolean | null
id?: string
onClick?: (e: React.MouseEvent) => void
@@ -59,7 +59,9 @@ export function ToggleButton(props: ToggleButtonProps): JSX.Element {
css={props.toggledOn ? TOGGLE_ENABLED_STYLES : TOGGLE_DISABLED_STYLES}
{...buttonProps}
>
-
+
+
+
)
}
diff --git a/protocol-designer/src/components/StepEditForm/index.tsx b/protocol-designer/src/components/StepEditForm/index.tsx
index 8b54c56c891..747651e7268 100644
--- a/protocol-designer/src/components/StepEditForm/index.tsx
+++ b/protocol-designer/src/components/StepEditForm/index.tsx
@@ -187,7 +187,7 @@ const StepEditFormManager = (
: ''
}
handleCancelClick={saveStepForm}
- handleContinueClick={confirmAddPauseUntilTempStep}
+ handleContinueClick={handleSave}
// TODO (nd: 10/21/2024) can remove this prop once redesign FF removed
moduleType={
showAddPauseUntilTempStepModal
diff --git a/protocol-designer/src/form-types.ts b/protocol-designer/src/form-types.ts
index 0dc4497cdae..58da6b5676b 100644
--- a/protocol-designer/src/form-types.ts
+++ b/protocol-designer/src/form-types.ts
@@ -366,6 +366,7 @@ export interface HydratedHeaterShakerFormData {
heaterShakerSetTimer: 'true' | 'false' | null
heaterShakerTimerMinutes: string | null
heaterShakerTimerSeconds: string | null
+ heaterShakerTimer?: string | null
id: string
latchOpen: boolean
moduleId: string
diff --git a/protocol-designer/src/molecules/ToggleExpandStepFormField/index.tsx b/protocol-designer/src/molecules/ToggleExpandStepFormField/index.tsx
index ed57de37f3b..b27b72b7821 100644
--- a/protocol-designer/src/molecules/ToggleExpandStepFormField/index.tsx
+++ b/protocol-designer/src/molecules/ToggleExpandStepFormField/index.tsx
@@ -18,12 +18,11 @@ interface ToggleExpandStepFormFieldProps extends FieldProps {
fieldTitle: string
isSelected: boolean
units: string
- onLabel: string
- offLabel: string
toggleUpdateValue: (value: unknown) => void
toggleValue: unknown
+ onLabel?: string
+ offLabel?: string
caption?: string
- islabel?: boolean
}
export function ToggleExpandStepFormField(
props: ToggleExpandStepFormFieldProps
@@ -38,16 +37,24 @@ export function ToggleExpandStepFormField(
toggleUpdateValue,
toggleValue,
caption,
- islabel,
...restProps
} = props
+ const resetFieldValue = (): void => {
+ restProps.updateValue('null')
+ }
+
const onToggleUpdateValue = (): void => {
if (typeof toggleValue === 'boolean') {
toggleUpdateValue(!toggleValue)
+ if (toggleValue) {
+ resetFieldValue()
+ }
} else if (toggleValue === 'engage' || toggleValue === 'disengage') {
const newToggleValue = toggleValue === 'engage' ? 'disengage' : 'engage'
toggleUpdateValue(newToggleValue)
+ } else if (toggleValue == null) {
+ toggleUpdateValue(true)
}
}
@@ -60,16 +67,10 @@ export function ToggleExpandStepFormField(
>
{title}
-
- {islabel ? (
-
- {isSelected ? onLabel : offLabel}
-
- ) : null}
-
+
+
+ {isSelected ? onLabel : offLabel ?? null}
+
{
onToggleUpdateValue()
diff --git a/protocol-designer/src/molecules/ToggleStepFormField/index.tsx b/protocol-designer/src/molecules/ToggleStepFormField/index.tsx
index 51bc2a1ef25..9ce244c7d57 100644
--- a/protocol-designer/src/molecules/ToggleStepFormField/index.tsx
+++ b/protocol-designer/src/molecules/ToggleStepFormField/index.tsx
@@ -62,14 +62,16 @@ export function ToggleStepFormField(
>
{isSelected ? onLabel : offLabel}
- {
- toggleUpdateValue(!toggleValue)
- }}
- label={isSelected ? onLabel : offLabel}
- toggledOn={isSelected}
- />
+ {isDisabled ? null : (
+ {
+ toggleUpdateValue(!toggleValue)
+ }}
+ label={isSelected ? onLabel : offLabel}
+ toggledOn={isSelected}
+ />
+ )}
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/HeaterShakerTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/HeaterShakerTools/index.tsx
index eefc9d36717..e82230adeb0 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/HeaterShakerTools/index.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/HeaterShakerTools/index.tsx
@@ -12,9 +12,7 @@ import {
} from '@opentrons/components'
import { getHeaterShakerLabwareOptions } from '../../../../../../ui/modules/selectors'
import {
- CheckboxExpandStepFormField,
DropdownStepFormField,
- InputStepFormField,
ToggleExpandStepFormField,
ToggleStepFormField,
} from '../../../../../../molecules'
@@ -90,7 +88,7 @@ export function HeaterShakerTools(props: StepFormProps): JSX.Element {
toggleValue={propsForFields.setShake.value}
toggleUpdateValue={propsForFields.setShake.updateValue}
title={t('form:step_edit_form.field.heaterShaker.shaker.setShake')}
- fieldTitle={t('protocol_steps:shake')}
+ fieldTitle={t('protocol_steps:speed')}
isSelected={formData.setShake === true}
units={t('units.rpm')}
onLabel={t('form:step_edit_form.field.heaterShaker.shaker.toggleOn')}
@@ -112,25 +110,17 @@ export function HeaterShakerTools(props: StepFormProps): JSX.Element {
: null
}
/>
-
- {/* TODO: wire up the new timer with the combined field */}
- {formData.heaterShakerSetTimer === true ? (
-
- ) : null}
-
+ fieldTitle={t('form:step_edit_form.field.heaterShaker.duration')}
+ isSelected={formData.heaterShakerSetTimer === true}
+ units={t('application:units.time')}
+ />
)
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MagnetTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MagnetTools/index.tsx
index e98727dd045..42768144177 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MagnetTools/index.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MagnetTools/index.tsx
@@ -123,7 +123,6 @@ export function MagnetTools(props: StepFormProps): JSX.Element {
'form:step_edit_form.field.magnetAction.options.disengage'
)}
caption={engageHeightCaption}
- islabel={true}
/>
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/PauseTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/PauseTools/index.tsx
index e76153a102e..1ab9d90ce44 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/PauseTools/index.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/PauseTools/index.tsx
@@ -139,10 +139,11 @@ export function PauseTools(props: StepFormProps): JSX.Element {
>
@@ -193,7 +194,7 @@ export function PauseTools(props: StepFormProps): JSX.Element {
gridGap={SPACING.spacing4}
paddingX={SPACING.spacing16}
>
-
+
{i18n.format(
t('form:step_edit_form.field.pauseMessage.label'),
'capitalize'
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/index.tsx
index 0272a35e618..0b7049bd546 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/index.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/index.tsx
@@ -180,7 +180,7 @@ function StepFormManager(props: StepFormManagerProps): JSX.Element | null {
: ''
}
handleCancelClick={saveStepForm}
- handleContinueClick={confirmAddPauseUntilTempStep}
+ handleContinueClick={handleSave}
moduleType={
showAddPauseUntilTempStepModal
? TEMPERATURE_MODULE_TYPE
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepSummary.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepSummary.tsx
index 0d78ea5dc08..18938c3975b 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepSummary.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepSummary.tsx
@@ -327,8 +327,7 @@ export function StepSummary(props: StepSummaryProps): JSX.Element | null {
case 'heaterShaker':
const {
latchOpen,
- heaterShakerTimerMinutes,
- heaterShakerTimerSeconds,
+ heaterShakerTimer,
moduleId: heaterShakerModuleId,
targetHeaterShakerTemperature,
targetSpeed,
@@ -343,14 +342,14 @@ export function StepSummary(props: StepSummaryProps): JSX.Element | null {
i18nKey="protocol_steps:heater_shaker.active.temperature"
values={{ module: moduleDisplayName }}
tagText={
- targetHeaterShakerTemperature != null
+ targetHeaterShakerTemperature
? `${targetHeaterShakerTemperature}${t(
'application:units.degrees'
)}`
: t('protocol_steps:heater_shaker.active.ambient')
}
/>
- {targetSpeed != null ? (
+ {targetSpeed ? (
- {heaterShakerTimerMinutes != null &&
- heaterShakerTimerSeconds != null ? (
+ {heaterShakerTimer ? (
) : null}
!value ? FIELD_ERRORS.REQUIRED : null
export const isTimeFormat: ErrorChecker = (value: unknown): string | null => {
const timeRegex = new RegExp(/^\d{1,2}:\d{1,2}:\d{1,2}$/g)
- return (typeof value === 'string' && timeRegex.test(value)) || value == null
+ return (typeof value === 'string' && timeRegex.test(value)) || !value
? null
: FIELD_ERRORS.BAD_TIME_HMS
}
@@ -43,7 +43,7 @@ export const isTimeFormatMinutesSeconds: ErrorChecker = (
value: unknown
): string | null => {
const timeRegex = new RegExp(/^\d{1,2}:\d{1,2}$/g)
- return (typeof value === 'string' && timeRegex.test(value)) || value == null
+ return (typeof value === 'string' && timeRegex.test(value)) || !value
? null
: FIELD_ERRORS.BAD_TIME_MS
}
diff --git a/protocol-designer/src/steplist/fieldLevel/index.ts b/protocol-designer/src/steplist/fieldLevel/index.ts
index b9367adaa60..96e04bfed07 100644
--- a/protocol-designer/src/steplist/fieldLevel/index.ts
+++ b/protocol-designer/src/steplist/fieldLevel/index.ts
@@ -8,6 +8,7 @@ import {
temperatureRangeFieldValue,
realNumber,
isTimeFormat,
+ isTimeFormatMinutesSeconds,
} from './errors'
import {
maskToInteger,
@@ -345,6 +346,11 @@ const stepFieldHelperMap: Record = {
maskValue: composeMaskers(maskToInteger, onlyPositiveNumbers),
castValue: Number,
},
+ heaterShakerTimer: {
+ maskValue: composeMaskers(maskToTime),
+ getErrors: composeErrors(isTimeFormatMinutesSeconds),
+ castValue: String,
+ },
pauseAction: {
getErrors: composeErrors(requiredField),
},
diff --git a/protocol-designer/src/steplist/formLevel/errors.ts b/protocol-designer/src/steplist/formLevel/errors.ts
index ada2cef64fc..e5203cdc84e 100644
--- a/protocol-designer/src/steplist/formLevel/errors.ts
+++ b/protocol-designer/src/steplist/formLevel/errors.ts
@@ -15,7 +15,7 @@ import {
import { getPipetteCapacity } from '../../pipettes/pipetteData'
import { canPipetteUseLabware } from '../../utils'
import { getWellRatio } from '../utils'
-import { getTimeFromPauseForm } from '../utils/getTimeFromPauseForm'
+import { getTimeFromForm } from '../utils/getTimeFromForm'
import type { LabwareDefinition2, PipetteV2Specs } from '@opentrons/shared-data'
import type { LabwareEntities, PipetteEntity } from '@opentrons/step-generation'
@@ -137,6 +137,22 @@ const LID_TEMPERATURE_HOLD_REQUIRED: FormError = {
title: 'Temperature is required',
dependentFields: ['lidIsActiveHold', 'lidTargetTempHold'],
}
+const SHAKE_SPEED_REQUIRED: FormError = {
+ title: 'Shake speed required',
+ dependentFields: ['setShake', 'targetSpeed'],
+}
+const SHAKE_TIME_REQUIRED: FormError = {
+ title: 'Shake duration required',
+ dependentFields: ['heaterShakerSetTimer', 'heaterShakerTimer'],
+}
+const HS_TEMPERATURE_REQUIRED: FormError = {
+ title: 'Temperature required',
+ dependentFields: [
+ 'targetHeaterShakerTemperature',
+ 'setHeaterShakerTemperature',
+ ],
+}
+
export interface HydratedFormData {
[key: string]: any
}
@@ -198,7 +214,13 @@ export const pauseForTimeOrUntilTold = (
const { pauseAction, moduleId, pauseTemperature } = fields
if (pauseAction === PAUSE_UNTIL_TIME) {
- const { hours, minutes, seconds } = getTimeFromPauseForm(fields)
+ const { hours, minutes, seconds } = getTimeFromForm(
+ fields,
+ 'pauseTime',
+ 'pauseSeconds',
+ 'pauseMinutes',
+ 'pauseSeconds'
+ )
// user selected pause for amount of time
const totalSeconds = hours * 3600 + minutes * 60 + seconds
return totalSeconds <= 0 ? TIME_PARAM_REQUIRED : null
@@ -342,6 +364,26 @@ export const lidTemperatureHoldRequired = (
? LID_TEMPERATURE_HOLD_REQUIRED
: null
}
+export const shakeSpeedRequired = (
+ fields: HydratedFormData
+): FormError | null => {
+ const { targetSpeed, setShake } = fields
+ return setShake && !targetSpeed ? SHAKE_SPEED_REQUIRED : null
+}
+export const shakeTimeRequired = (
+ fields: HydratedFormData
+): FormError | null => {
+ const { heaterShakerTimer, heaterShakerSetTimer } = fields
+ return heaterShakerSetTimer && !heaterShakerTimer ? SHAKE_TIME_REQUIRED : null
+}
+export const temperatureRequired = (
+ fields: HydratedFormData
+): FormError | null => {
+ const { setHeaterShakerTemperature, targetHeaterShakerTemperature } = fields
+ return setHeaterShakerTemperature && !targetHeaterShakerTemperature
+ ? HS_TEMPERATURE_REQUIRED
+ : null
+}
export const engageHeightRangeExceeded = (
fields: HydratedFormData
): FormError | null => {
diff --git a/protocol-designer/src/steplist/formLevel/getDefaultsForStepType.ts b/protocol-designer/src/steplist/formLevel/getDefaultsForStepType.ts
index b669b865e4e..40b35b3ccad 100644
--- a/protocol-designer/src/steplist/formLevel/getDefaultsForStepType.ts
+++ b/protocol-designer/src/steplist/formLevel/getDefaultsForStepType.ts
@@ -120,6 +120,7 @@ export function getDefaultsForStepType(
return {
moduleId: null,
pauseAction: null,
+ // TODO: (nd: 10/23/2024) remove individual time unit fields
pauseHour: null,
pauseMessage: '',
pauseMinute: null,
@@ -151,8 +152,10 @@ export function getDefaultsForStepType(
case 'heaterShaker':
return {
heaterShakerSetTimer: null,
+ // TODO: (nd: 10/23/2024) remove individual time unit fields
heaterShakerTimerMinutes: null,
heaterShakerTimerSeconds: null,
+ heaterShakerTimer: null,
latchOpen: false,
moduleId: null,
setHeaterShakerTemperature: null,
diff --git a/protocol-designer/src/steplist/formLevel/index.ts b/protocol-designer/src/steplist/formLevel/index.ts
index efa9334315e..1d67206c82b 100644
--- a/protocol-designer/src/steplist/formLevel/index.ts
+++ b/protocol-designer/src/steplist/formLevel/index.ts
@@ -17,6 +17,9 @@ import {
blockTemperatureHoldRequired,
lidTemperatureHoldRequired,
volumeTooHigh,
+ shakeSpeedRequired,
+ temperatureRequired,
+ shakeTimeRequired,
} from './errors'
import {
@@ -51,6 +54,13 @@ interface FormHelpers {
getWarnings?: (arg: unknown) => FormWarning[]
}
const stepFormHelperMap: Partial> = {
+ heaterShaker: {
+ getErrors: composeErrors(
+ shakeSpeedRequired,
+ shakeTimeRequired,
+ temperatureRequired
+ ),
+ },
mix: {
getErrors: composeErrors(incompatibleLabware, volumeTooHigh),
getWarnings: composeWarnings(
diff --git a/protocol-designer/src/steplist/formLevel/stepFormToArgs/heaterShakerFormToArgs.ts b/protocol-designer/src/steplist/formLevel/stepFormToArgs/heaterShakerFormToArgs.ts
index 8366864f190..eda1e073fb2 100644
--- a/protocol-designer/src/steplist/formLevel/stepFormToArgs/heaterShakerFormToArgs.ts
+++ b/protocol-designer/src/steplist/formLevel/stepFormToArgs/heaterShakerFormToArgs.ts
@@ -1,3 +1,4 @@
+import { getTimeFromForm } from '../../utils/getTimeFromForm'
import type { HeaterShakerArgs } from '@opentrons/step-generation'
import type { HydratedHeaterShakerFormData } from '../../../form-types'
@@ -22,6 +23,14 @@ export const heaterShakerFormToArgs = (
setShake ? !Number.isNaN(targetSpeed) : true,
'heaterShakerFormToArgs expected targeShake to be a number when setShake is true'
)
+ const { minutes, seconds } = getTimeFromForm(
+ formData,
+ 'heaterShakerTimer',
+ 'heaterShakerTimerSeconds',
+ 'heaterShakerTimerMinutes'
+ )
+
+ const isNullTime = minutes === 0 && seconds === 0
const targetTemperature =
setHeaterShakerTemperature && targetHeaterShakerTemperature != null
@@ -36,13 +45,7 @@ export const heaterShakerFormToArgs = (
targetTemperature: targetTemperature,
rpm: targetShake,
latchOpen: latchOpen,
- timerMinutes:
- formData.heaterShakerTimerMinutes != null
- ? parseInt(formData.heaterShakerTimerMinutes)
- : null,
- timerSeconds:
- formData.heaterShakerTimerSeconds != null
- ? parseInt(formData.heaterShakerTimerSeconds)
- : null,
+ timerMinutes: isNullTime ? null : minutes,
+ timerSeconds: isNullTime ? null : seconds,
}
}
diff --git a/protocol-designer/src/steplist/formLevel/stepFormToArgs/pauseFormToArgs.ts b/protocol-designer/src/steplist/formLevel/stepFormToArgs/pauseFormToArgs.ts
index cc7a32a13e3..88de52bacec 100644
--- a/protocol-designer/src/steplist/formLevel/stepFormToArgs/pauseFormToArgs.ts
+++ b/protocol-designer/src/steplist/formLevel/stepFormToArgs/pauseFormToArgs.ts
@@ -1,4 +1,4 @@
-import { getTimeFromPauseForm } from '../../utils/getTimeFromPauseForm'
+import { getTimeFromForm } from '../../utils/getTimeFromForm'
import {
PAUSE_UNTIL_TIME,
PAUSE_UNTIL_TEMP,
@@ -13,8 +13,14 @@ import type {
export const pauseFormToArgs = (
formData: FormData
): PauseArgs | WaitForTemperatureArgs | null => {
- const { hours, minutes, seconds } = getTimeFromPauseForm(formData)
- const totalSeconds = hours * 3600 + minutes * 60 + seconds
+ const { hours, minutes, seconds } = getTimeFromForm(
+ formData,
+ 'pauseTime',
+ 'pauseSecond',
+ 'pauseMinute',
+ 'pauseHour'
+ )
+ const totalSeconds = (hours ?? 0) * 3600 + minutes * 60 + seconds
const temperature = parseFloat(formData.pauseTemperature as string)
const message = formData.pauseMessage ?? ''
diff --git a/protocol-designer/src/steplist/formLevel/test/getDefaultsForStepType.test.ts b/protocol-designer/src/steplist/formLevel/test/getDefaultsForStepType.test.ts
index 5af511e500d..ba0897607ac 100644
--- a/protocol-designer/src/steplist/formLevel/test/getDefaultsForStepType.test.ts
+++ b/protocol-designer/src/steplist/formLevel/test/getDefaultsForStepType.test.ts
@@ -164,6 +164,7 @@ describe('getDefaultsForStepType', () => {
heaterShakerSetTimer: null,
heaterShakerTimerMinutes: null,
heaterShakerTimerSeconds: null,
+ heaterShakerTimer: null,
})
})
})
diff --git a/protocol-designer/src/steplist/utils/getTimeFromPauseForm.ts b/protocol-designer/src/steplist/utils/getTimeFromForm.ts
similarity index 62%
rename from protocol-designer/src/steplist/utils/getTimeFromPauseForm.ts
rename to protocol-designer/src/steplist/utils/getTimeFromForm.ts
index ed1b2243b49..ff35bdaeb09 100644
--- a/protocol-designer/src/steplist/utils/getTimeFromPauseForm.ts
+++ b/protocol-designer/src/steplist/utils/getTimeFromForm.ts
@@ -4,28 +4,33 @@ import type { HydratedFormData } from '../formLevel/errors'
const TIME_DELIMITER = ':'
interface TimeData {
- hours: number
minutes: number
seconds: number
+ hours: number
}
-export const getTimeFromPauseForm = (
- formData: FormData | HydratedFormData
+export const getTimeFromForm = (
+ formData: FormData | HydratedFormData,
+ timeField: string,
+ secondsField: string,
+ minutesField: string,
+ hoursField?: string
): TimeData => {
let hoursFromForm
let minutesFromForm
let secondsFromForm
// importing results in stringified "null" value
- if (formData.pauseTime != null && formData.pauseTime !== 'null') {
- const timeSplit = formData.pauseTime.split(TIME_DELIMITER)
- ;[hoursFromForm, minutesFromForm, secondsFromForm] = timeSplit
+ if (formData[timeField] != null && formData[timeField] !== 'null') {
+ const timeSplit = formData[timeField].split(TIME_DELIMITER)
+ ;[hoursFromForm, minutesFromForm, secondsFromForm] =
+ timeSplit.length === 3 ? timeSplit : [0, ...timeSplit]
} else {
// TODO (nd 09/23/2024): remove individual time units after redesign FF is removed
;[hoursFromForm, minutesFromForm, secondsFromForm] = [
- formData.pauseHour,
- formData.pauseMinute,
- formData.pauseSecond,
+ hoursField != null ? formData[hoursField] : null,
+ formData[minutesField],
+ formData[secondsField],
]
}
const hours = isNaN(parseFloat(hoursFromForm as string))