Skip to content

Commit

Permalink
feat(protocol-designer): stepForm skeleton
Browse files Browse the repository at this point in the history
closes AUTH-828
  • Loading branch information
jerader committed Sep 18, 2024
1 parent a98e7f4 commit f0b98db
Show file tree
Hide file tree
Showing 16 changed files with 189 additions and 132 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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<StepFormProps> | 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 (
<div>
<div>Todo: support {formData && formData.stepType} step</div>
</div>
)
}

return (
<>
{/* TODO: update alerts */}
{/* <Alerts
focusedField={focusedField}
dirtyFields={dirtyFields}
componentType="Form"
/> */}

<Toolbox
onCloseClick={handleClose}
closeButtonText={t('cancel')}
confirmButton={
<PrimaryButton onClick={handleSave} disabled={!canSave} width="100%">
{t('save')}
</PrimaryButton>
}
height="calc(100vh - 64px)"
title={
<Flex gridGap={SPACING.spacing8} alignItems={ALIGN_CENTER}>
<Icon size="1rem" name={icon} />
<StyledText desktopStyle="bodyLargeSemiBold">
{i18n.format(
t(`application:stepType.${formData.stepType}`),
'capitalize'
)}
</StyledText>
</Flex>
}
>
<Tools {...{ formData, propsForFields, focusHandlers }} />
</Toolbox>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function CommentTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function HeaterShakerTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function MagnetTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function MixTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function MoveLabwareTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function MoveLiquidTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function PauseTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function TemperatureTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react'

export function ThermocyclerTools(): JSX.Element {
return <div>TODO: wire this up</div>
}
Original file line number Diff line number Diff line change
@@ -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'
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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'
Expand Down Expand Up @@ -49,7 +48,7 @@ interface DispatchProps {
}
type StepEditFormManagerProps = StateProps & DispatchProps

const StepEditFormManager = (
const StepFormManager = (
props: StepEditFormManagerProps
): JSX.Element | null => {
const {
Expand All @@ -68,18 +67,10 @@ const StepEditFormManager = (
invariantContext,
} = props
const { t } = useTranslation('tooltip')
const [
showMoreOptionsModal,
setShowMoreOptionsModal,
] = React.useState<boolean>(false)
const [focusedField, setFocusedField] = React.useState<string | null>(null)
const [dirtyFields, setDirtyFields] = React.useState<StepFieldName[]>(
getDirtyFields(isNewStep, formData)
)
const toggleMoreOptionsModal = (): void => {
resetScrollElements()
setShowMoreOptionsModal(!showMoreOptionsModal)
}
const focus = setFocusedField
const blur = (fieldName: StepFieldName): void => {
if (fieldName === focusedField) {
Expand Down Expand Up @@ -184,7 +175,7 @@ const StepEditFormManager = (
handleContinueClick={confirmAddPauseUntilHeaterShakerTempStep}
/>
)}
<StepFormComponent
<StepFormToolbox
{...{
canSave,
dirtyFields,
Expand All @@ -195,8 +186,6 @@ const StepEditFormManager = (
handleDelete: confirmDelete,
handleSave,
propsForFields,
showMoreOptionsModal,
toggleMoreOptionsModal,
}}
/>
</>
Expand Down Expand Up @@ -251,13 +240,13 @@ const mapDispatchToProps = (dispatch: ThunkDispatch<any>): 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
<StepEditFormManager key={formData?.id ?? 'empty'} {...props} />
<StepFormManager key={formData?.id ?? 'empty'} {...props} />
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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<StepFieldName, FieldProps>

// Shared props across all step forms
export interface StepFormProps {
formData: FormData
Expand Down
Loading

0 comments on commit f0b98db

Please sign in to comment.