Skip to content

Commit

Permalink
fix(app): fix various drop tip wizard issues (#14207)
Browse files Browse the repository at this point in the history
This PR is a general second-pass of the drop tip wizard. There's a good bit refactoring, but in terms of functional changes:

  - The wizard doesn't render BeforeBeginning until the maintenance run has been successfully created - renders a spinner now. This prevents some bugs and is better UX.
  - Exiting the drop tip wizard now renders a spinner and exits properly.
  - The home command occurs in a predictable spot - no more instantly homing after completing blowout.
  - Use moveToAddressableArea instead of moveRelative to prevent unexpected pipette movements (you CANNOT move to a slot with a moveable trash or waste chute loaded -- this is a known issue and currently being fixed).
  - Fixes an issue where an unreachable step could be hit.
  - More error messaging!
NOTE: you CANNOT move to a slot with a moveable trash or waste chute loaded -- this is a known issue and currently being addressed separately.

Closes RQA-2083, RQA-2094, RQA-2066, RQA-2068, RQA-2024
  • Loading branch information
mjhuff authored Dec 14, 2023
1 parent 4ab142a commit a7d1187
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 154 deletions.
36 changes: 10 additions & 26 deletions app/src/organisms/DropTipWizard/BeforeBeginning.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react'
import styled, { css } from 'styled-components'
import { useTranslation } from 'react-i18next'

import {
Flex,
SPACING,
Expand All @@ -19,45 +20,33 @@ import {
JUSTIFY_FLEX_END,
JUSTIFY_SPACE_AROUND,
} from '@opentrons/components'

import { StyledText } from '../../atoms/text'
import { SmallButton, MediumButton } from '../../atoms/buttons'
import { InProgressModal } from '../../molecules/InProgressModal/InProgressModal'
// import { NeedHelpLink } from '../CalibrationPanels'

import blowoutVideo from '../../assets/videos/droptip-wizard/Blowout-Liquid.webm'
import droptipVideo from '../../assets/videos/droptip-wizard/Drop-tip.webm'

import type { UseMutateFunction } from 'react-query'
import type { AxiosError } from 'axios'
import type {
CreateMaintenanceRunData,
MaintenanceRun,
} from '@opentrons/api-client'

// TODO: get help link article URL
// const NEED_HELP_URL = ''

interface BeforeBeginningProps {
setShouldDispenseLiquid: (shouldDispenseLiquid: boolean) => void
createMaintenanceRun: UseMutateFunction<
MaintenanceRun,
AxiosError<any>,
CreateMaintenanceRunData,
unknown
>
createdMaintenanceRunId: string | null
isCreateLoading: boolean
isOnDevice: boolean
isRobotMoving: boolean
}

export const BeforeBeginning = (
props: BeforeBeginningProps
): JSX.Element | null => {
const {
setShouldDispenseLiquid,
createMaintenanceRun,
createdMaintenanceRunId,
isCreateLoading,
isOnDevice,
isRobotMoving,
} = props
const { i18n, t } = useTranslation(['drop_tip_wizard', 'shared'])
const [flowType, setFlowType] = React.useState<
Expand All @@ -68,11 +57,9 @@ export const BeforeBeginning = (
setShouldDispenseLiquid(flowType === 'liquid_and_tips')
}

React.useEffect(() => {
if (createdMaintenanceRunId == null) {
createMaintenanceRun({})
}
}, [])
if (isRobotMoving || createdMaintenanceRunId == null) {
return <InProgressModal description={t('stand_back_exiting')} />
}

if (isOnDevice) {
return (
Expand Down Expand Up @@ -118,7 +105,7 @@ export const BeforeBeginning = (
<SmallButton
buttonText={i18n.format(t('shared:continue'), 'capitalize')}
onClick={handleProceed}
disabled={isCreateLoading || flowType == null}
disabled={flowType == null}
/>
</Flex>
</Flex>
Expand Down Expand Up @@ -180,10 +167,7 @@ export const BeforeBeginning = (
</Flex>
<Flex flexDirection={DIRECTION_ROW} justifyContent={JUSTIFY_FLEX_END}>
{/* <NeedHelpLink href={NEED_HELP_URL} /> */}
<PrimaryButton
disabled={isCreateLoading || flowType == null}
onClick={handleProceed}
>
<PrimaryButton disabled={flowType == null} onClick={handleProceed}>
{i18n.format(t('shared:continue'), 'capitalize')}
</PrimaryButton>
</Flex>
Expand Down
33 changes: 8 additions & 25 deletions app/src/organisms/DropTipWizard/ChooseLocation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ import {
SPACING,
TYPOGRAPHY,
} from '@opentrons/components'
import {
getDeckDefFromRobotType,
getPositionFromSlotId,
} from '@opentrons/shared-data'
import { getDeckDefFromRobotType } from '@opentrons/shared-data'

import { SmallButton } from '../../atoms/buttons'
import { StyledText } from '../../atoms/text'
Expand All @@ -41,7 +38,9 @@ interface ChooseLocationProps {
title: string
body: string | JSX.Element
robotType: RobotType
moveToXYCoordinate: (x: number, y: number) => Promise<CommandData[] | null>
moveToAddressableArea: (
addressableArea: string
) => Promise<CommandData | null>
isRobotMoving: boolean
isOnDevice: boolean
setErrorMessage: (arg0: string) => void
Expand All @@ -56,7 +55,7 @@ export const ChooseLocation = (
title,
body,
robotType,
moveToXYCoordinate,
moveToAddressableArea,
isRobotMoving,
isOnDevice,
setErrorMessage,
Expand All @@ -70,26 +69,10 @@ export const ChooseLocation = (
const handleConfirmPosition = (): void => {
const deckSlot = deckDef.locations.addressableAreas.find(
l => l.id === selectedLocation.slotName
)

const slotPosition = getPositionFromSlotId(
selectedLocation.slotName,
deckDef
)
)?.id

const slotX = slotPosition?.[0]
const slotY = slotPosition?.[1]
const xDimension = deckSlot?.boundingBox.xDimension
const yDimension = deckSlot?.boundingBox.yDimension
if (
slotX != null &&
slotY != null &&
xDimension != null &&
yDimension != null
) {
const targetX = slotX + xDimension / 2
const targetY = slotY + yDimension / 2
moveToXYCoordinate(targetX, targetY)
if (deckSlot != null) {
moveToAddressableArea(deckSlot)
.then(() => handleProceed())
.catch(e => setErrorMessage(`${e.message}`))
}
Expand Down
8 changes: 5 additions & 3 deletions app/src/organisms/DropTipWizard/ExitConfirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ export function ExitConfirmation(props: ExitConfirmationProps): JSX.Element {
const flowTitle = t('drop_tips')
const isOnDevice = useSelector(getIsOnDevice)

return isRobotMoving ? (
<InProgressModal description={t('stand_back_exiting')} />
) : (
if (isRobotMoving) {
return <InProgressModal description={t('stand_back_exiting')} />
}

return (
<SimpleWizardBody
iconColor={COLORS.warningEnabled}
header={t('exit_screen_title', { flow: flowTitle })}
Expand Down
23 changes: 19 additions & 4 deletions app/src/organisms/DropTipWizard/JogToPosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,16 @@ export const JogToPosition = (
showPositionConfirmation,
setShowPositionConfirmation,
] = React.useState(false)
// Includes special case homing only present in this step.
const [isRobotInMotion, setIsRobotInMotion] = React.useState(isRobotMoving)

const onGoBack = (): void => {
setIsRobotInMotion(() => true)
handleGoBack()
}

if (showPositionConfirmation) {
return isRobotMoving ? (
return isRobotInMotion ? (
<InProgressModal
alternativeSpinner={null}
description={
Expand All @@ -183,14 +190,22 @@ export const JogToPosition = (
/>
) : (
<ConfirmPosition
handlePipetteAction={handleProceed}
handlePipetteAction={() => {
setIsRobotInMotion(true)
handleProceed()
}}
handleGoBack={() => setShowPositionConfirmation(false)}
isOnDevice={isOnDevice}
currentStep={currentStep}
/>
)
}

// Moving due to "Exit" or "Go back" click.
if (isRobotInMotion) {
return <InProgressModal description={t('stand_back_exiting')} />
}

if (isOnDevice) {
return (
<Flex
Expand All @@ -206,7 +221,7 @@ export const JogToPosition = (
<SmallButton
buttonType="tertiaryLowLight"
buttonText={t('shared:go_back')}
onClick={handleGoBack}
onClick={onGoBack}
/>
</Flex>
<Flex justifyContent={JUSTIFY_FLEX_END} width="100%">
Expand Down Expand Up @@ -254,7 +269,7 @@ export const JogToPosition = (
>
{/* <NeedHelpLink href={NEED_HELP_URL} /> */}
<Flex gridGap={SPACING.spacing8}>
<SecondaryButton onClick={handleGoBack}>
<SecondaryButton onClick={onGoBack}>
{t('shared:go_back')}
</SecondaryButton>
<PrimaryButton onClick={() => setShowPositionConfirmation(true)}>
Expand Down
21 changes: 6 additions & 15 deletions app/src/organisms/DropTipWizard/Success.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,19 @@ interface SuccessProps {
message: string
proceedText: string
handleProceed: () => void
isRobotMoving: boolean
isExiting: boolean
isOnDevice: boolean
}
export const Success = (props: SuccessProps): JSX.Element => {
const {
message,
proceedText,
handleProceed,
isRobotMoving,
isExiting,
isOnDevice,
} = props
const { message, proceedText, handleProceed, isExiting, isOnDevice } = props

const { i18n, t } = useTranslation(['drop_tip_wizard', 'shared'])

return isRobotMoving && !isExiting ? (
<InProgressModal
alternativeSpinner={null}
description={t('stand_back_exiting')}
/>
) : (
if (isExiting) {
return <InProgressModal description={t('stand_back_exiting')} />
}

return (
<SimpleWizardBody
iconColor={COLORS.successEnabled}
header={i18n.format(message, 'capitalize')}
Expand Down
Loading

0 comments on commit a7d1187

Please sign in to comment.