diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormComponent.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormComponent.tsx deleted file mode 100644 index 6de21bb206e..00000000000 --- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormComponent.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import * as React from 'react' -import get from 'lodash/get' - -import type { StepFieldName } from '../../../../steplist/fieldLevel' -import type { FormData, StepType } from '../../../../form-types' -import type { FieldPropsByName, FocusHandlers, StepFormProps } from './types' -import { - MixForm, - MoveLabwareForm, - MoveLiquidForm, - PauseForm, - CommentForm, - MagnetForm, - TemperatureForm, - ThermocyclerForm, - HeaterShakerForm, -} from '../../../../components/StepEditForm/forms' -import { Alerts } from '../../../../components/alerts/Alerts' - -type StepFormMap = { - [K in StepType]?: React.ComponentType | null -} - -const STEP_FORM_MAP: StepFormMap = { - mix: MixForm, - pause: PauseForm, - moveLabware: MoveLabwareForm, - moveLiquid: MoveLiquidForm, - magnet: MagnetForm, - temperature: TemperatureForm, - thermocycler: ThermocyclerForm, - heaterShaker: HeaterShakerForm, - comment: CommentForm, -} - -interface StepFormComponentProps { - canSave: boolean - dirtyFields: string[] - focusHandlers: FocusHandlers - focusedField: StepFieldName | null - formData: FormData - propsForFields: FieldPropsByName - handleClose: () => void - handleDelete: () => void - handleSave: () => void - showMoreOptionsModal: boolean - toggleMoreOptionsModal: () => void -} - -export const StepFormComponent = ( - props: StepFormComponentProps -): JSX.Element => { - const { - formData, - focusHandlers, - canSave, - handleClose, - handleDelete, - dirtyFields, - handleSave, - propsForFields, - showMoreOptionsModal, - toggleMoreOptionsModal, - focusedField, - } = props - - const FormComponent: typeof STEP_FORM_MAP[keyof typeof STEP_FORM_MAP] = get( - STEP_FORM_MAP, - formData.stepType - ) - if (!FormComponent) { - // early-exit if step form doesn't exist - return ( -
-
Todo: support {formData && formData.stepType} step
-
- ) - } - - return ( - <> - {/* {showMoreOptionsModal && ( - - )} */} - {/* TODO: update alerts */} - -
- - {/* */} -
- - ) -} diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormToolbox.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormToolbox.tsx new file mode 100644 index 00000000000..640cc07c99d --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepFormToolbox.tsx @@ -0,0 +1,119 @@ +import * as React from 'react' +import get from 'lodash/get' +import { useTranslation } from 'react-i18next' + +import { + ALIGN_CENTER, + Flex, + Icon, + PrimaryButton, + SPACING, + StyledText, + Toolbox, +} from '@opentrons/components' +import { stepIconsByType } from '../../../../form-types' +import { + CommentTools, + HeaterShakerTools, + MagnetTools, + MixTools, + MoveLabwareTools, + MoveLiquidTools, + PauseTools, + TemperatureTools, + ThermocyclerTools, +} from './StepTools' +import type { StepFieldName } from '../../../../steplist/fieldLevel' +import type { FormData, StepType } from '../../../../form-types' +import type { FieldPropsByName, FocusHandlers, StepFormProps } from './types' + +type StepFormMap = { + [K in StepType]?: React.ComponentType | null +} + +const STEP_FORM_MAP: StepFormMap = { + mix: MixTools, + pause: PauseTools, + moveLabware: MoveLabwareTools, + moveLiquid: MoveLiquidTools, + magnet: MagnetTools, + temperature: TemperatureTools, + thermocycler: ThermocyclerTools, + heaterShaker: HeaterShakerTools, + comment: CommentTools, +} + +interface StepFormToolboxProps { + canSave: boolean + dirtyFields: string[] + focusHandlers: FocusHandlers + focusedField: StepFieldName | null + formData: FormData + propsForFields: FieldPropsByName + handleClose: () => void + // TODO: add abiltiy to delete step? + handleDelete: () => void + handleSave: () => void +} + +export const StepFormToolbox = (props: StepFormToolboxProps): JSX.Element => { + const { + formData, + focusHandlers, + canSave, + handleClose, + handleSave, + propsForFields, + } = props + const { t, i18n } = useTranslation(['shared', 'application']) + const icon = stepIconsByType[formData.stepType] + + const Tools: typeof STEP_FORM_MAP[keyof typeof STEP_FORM_MAP] = get( + STEP_FORM_MAP, + formData.stepType + ) + + if (!Tools) { + // early-exit if step form doesn't exist + return ( +
+
Todo: support {formData && formData.stepType} step
+
+ ) + } + + return ( + <> + {/* TODO: update alerts */} + {/* */} + + + {t('save')} + + } + height="calc(100vh - 64px)" + title={ + + + + {i18n.format( + t(`application:stepType.${formData.stepType}`), + 'capitalize' + )} + + + } + > + + + + ) +} diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/CommentTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/CommentTools/index.tsx new file mode 100644 index 00000000000..56299f7ac9b --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/CommentTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function CommentTools(): JSX.Element { + return
TODO: wire this up
+} 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 new file mode 100644 index 00000000000..741d28124fd --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/HeaterShakerTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function HeaterShakerTools(): JSX.Element { + return
TODO: wire this up
+} 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 new file mode 100644 index 00000000000..3d636116f87 --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MagnetTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function MagnetTools(): JSX.Element { + return
TODO: wire this up
+} diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MixTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MixTools/index.tsx new file mode 100644 index 00000000000..8f3b8a826c5 --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MixTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function MixTools(): JSX.Element { + return
TODO: wire this up
+} diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MoveLabwareTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MoveLabwareTools/index.tsx new file mode 100644 index 00000000000..1343331cbaf --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MoveLabwareTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function MoveLabwareTools(): JSX.Element { + return
TODO: wire this up
+} diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MoveLiquidTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MoveLiquidTools/index.tsx new file mode 100644 index 00000000000..1115172241a --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/MoveLiquidTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function MoveLiquidTools(): JSX.Element { + return
TODO: wire this up
+} 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 new file mode 100644 index 00000000000..2549d8aa6da --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/PauseTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function PauseTools(): JSX.Element { + return
TODO: wire this up
+} diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/TemperatureTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/TemperatureTools/index.tsx new file mode 100644 index 00000000000..ea7c0065077 --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/TemperatureTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function TemperatureTools(): JSX.Element { + return
TODO: wire this up
+} diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/ThermocyclerTools/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/ThermocyclerTools/index.tsx new file mode 100644 index 00000000000..6d475a006c6 --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/ThermocyclerTools/index.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function ThermocyclerTools(): JSX.Element { + return
TODO: wire this up
+} diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/index.ts b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/index.ts new file mode 100644 index 00000000000..7f0eff60340 --- /dev/null +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/StepTools/index.ts @@ -0,0 +1,9 @@ +export { CommentTools } from './CommentTools' +export { HeaterShakerTools } from './HeaterShakerTools' +export { MagnetTools } from './MagnetTools' +export { MixTools } from './MixTools' +export { MoveLabwareTools } from './MoveLabwareTools' +export { MoveLiquidTools } from './MoveLiquidTools' +export { PauseTools } from './PauseTools' +export { TemperatureTools } from './TemperatureTools' +export { ThermocyclerTools } from './ThermocyclerTools' diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/index.tsx index 6932750ce57..94287c43ff2 100644 --- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/index.tsx +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/index.tsx @@ -4,7 +4,6 @@ import { connect } from 'react-redux' import { useConditionalConfirm } from '@opentrons/components' import { actions } from '../../../../steplist' import { actions as stepsActions } from '../../../../ui/steps' -import { resetScrollElements } from '../../../../ui/steps/utils' import { getHydratedForm, selectors as stepFormSelectors, @@ -20,7 +19,7 @@ import { import { AutoAddPauseUntilTempStepModal } from '../../../../components/modals/AutoAddPauseUntilTempStepModal' import { AutoAddPauseUntilHeaterShakerTempStepModal } from '../../../../components/modals/AutoAddPauseUntilHeaterShakerTempStepModal' import { getDirtyFields, makeSingleEditFieldProps } from './utils' -import { StepFormComponent } from './StepFormComponent' +import { StepFormToolbox } from './StepFormToolbox' import type { InvariantContext } from '@opentrons/step-generation' import type { BaseState, ThunkDispatch } from '../../../../types' @@ -49,7 +48,7 @@ interface DispatchProps { } type StepEditFormManagerProps = StateProps & DispatchProps -const StepEditFormManager = ( +const StepFormManager = ( props: StepEditFormManagerProps ): JSX.Element | null => { const { @@ -68,18 +67,10 @@ const StepEditFormManager = ( invariantContext, } = props const { t } = useTranslation('tooltip') - const [ - showMoreOptionsModal, - setShowMoreOptionsModal, - ] = React.useState(false) const [focusedField, setFocusedField] = React.useState(null) const [dirtyFields, setDirtyFields] = React.useState( getDirtyFields(isNewStep, formData) ) - const toggleMoreOptionsModal = (): void => { - resetScrollElements() - setShowMoreOptionsModal(!showMoreOptionsModal) - } const focus = setFocusedField const blur = (fieldName: StepFieldName): void => { if (fieldName === focusedField) { @@ -184,7 +175,7 @@ const StepEditFormManager = ( handleContinueClick={confirmAddPauseUntilHeaterShakerTempStep} /> )} - @@ -251,13 +240,13 @@ const mapDispatchToProps = (dispatch: ThunkDispatch): DispatchProps => { // It doesn't matter if the children are using connect or useSelector, // only the parent matters.) // https://react-redux.js.org/api/hooks#stale-props-and-zombie-children -export const StepEditForm = connect( +export const StepForm = connect( mapStateToProps, mapDispatchToProps )((props: StepEditFormManagerProps) => { const { formData } = props return ( // key by ID so manager state doesn't persist across different forms - + ) }) diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/types.ts b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/types.ts index 8d1f9f05a71..7bc84689fe1 100644 --- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/types.ts +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/types.ts @@ -2,7 +2,6 @@ import type { FormData, StepFieldName } from '../../../../form-types' export interface FocusHandlers { focusedField: StepFieldName | null dirtyFields: StepFieldName[] - // NOTE: focus & blur take a field name as an arg, unlike onFieldBlur/onFieldFocus in FieldProps focus: (arg0: StepFieldName) => void blur: (arg0: StepFieldName) => void } @@ -11,13 +10,14 @@ export interface FieldProps { errorToShow?: string | null isIndeterminate?: boolean name: string - onFieldBlur: () => unknown - onFieldFocus: () => unknown + onFieldBlur: () => void + onFieldFocus: () => void tooltipContent?: string | null updateValue: (arg0: unknown) => void value: unknown } export type FieldPropsByName = Record + // Shared props across all step forms export interface StepFormProps { formData: FormData diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/utils.ts b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/utils.ts index ae2bb8dbf3f..89d2e29b4a0 100644 --- a/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/utils.ts +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/utils.ts @@ -1,10 +1,3 @@ -import { getFieldErrors } from '../../../../steplist/fieldLevel' -import { - getDisabledFields, - getDefaultsForStepType, -} from '../../../../steplist/formLevel' -import type { FieldProps, FieldPropsByName, FocusHandlers } from './types' - import difference from 'lodash/difference' import isEqual from 'lodash/isEqual' import without from 'lodash/without' @@ -13,6 +6,11 @@ import { DEST_WELL_BLOWOUT_DESTINATION, } from '@opentrons/step-generation' import { ALL, COLUMN } from '@opentrons/shared-data' +import { getFieldErrors } from '../../../../steplist/fieldLevel' +import { + getDisabledFields, + getDefaultsForStepType, +} from '../../../../steplist/formLevel' import { PROFILE_CYCLE } from '../../../../form-types' import type { PipetteEntity } from '@opentrons/step-generation' import type { Options } from '@opentrons/components' @@ -27,6 +25,7 @@ import type { PathOption, } from '../../../../form-types' import type { NozzleType } from '../../../../types' +import type { FieldProps, FieldPropsByName, FocusHandlers } from './types' export function getBlowoutLocationOptionsForForm(args: { stepType: StepType diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/index.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/index.tsx index e69875a5b93..62189202c96 100644 --- a/protocol-designer/src/pages/Designer/ProtocolSteps/index.tsx +++ b/protocol-designer/src/pages/Designer/ProtocolSteps/index.tsx @@ -1,15 +1,14 @@ import * as React from 'react' import { COLORS, Flex, POSITION_ABSOLUTE, SPACING } from '@opentrons/components' -import { StepEditForm } from '../../../components/StepEditForm' import { DeckSetupContainer } from '../DeckSetup' import { TimelineToolbox } from './Timeline' +import { StepForm } from './StepForm' export function ProtocolSteps(): JSX.Element { return ( <> - {/* TODO: wire up the step edit form designs */} - +