Skip to content

Commit a2af480

Browse files
authored
feat:(app) Add desktop support for Error Recovery drop tip flows (#15758)
Closes EXEC-554
1 parent 9319ae4 commit a2af480

File tree

14 files changed

+288
-208
lines changed

14 files changed

+288
-208
lines changed

app/src/assets/localization/en/drop_tip_wizard.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
"exit_screen_title": "Exit before completing drop tip?",
1717
"getting_ready": "Getting ready…",
1818
"go_back": "go back",
19+
"jog_too_far": "Jog too far?",
20+
"start_over": "Start over",
1921
"move_to_slot": "move to slot",
2022
"no_proceed_to_drop_tip": "No, proceed to tip removal",
2123
"position_and_blowout": "Ensure that the pipette tip is centered above and level with where you want the liquid to be blown out. If it isn't, use the controls below or your keyboard to jog the pipette until it is properly aligned.",
@@ -25,9 +27,9 @@
2527
"remove_the_tips_from_pipette": "You may want to remove the tips from the pipette before using it again in a protocol.",
2628
"remove_the_tips_manually": "Remove the tips manually. Then home the gantry. Homing with tips attached could pull liquid into the pipette and damage it.",
2729
"remove_tips": "Remove tips",
28-
"select_blowout_slot": "<block>You can blow out liquid into a labware.</block><block>Select the slot where you want to blow out the liquid on the deck map to the right. Once confirmed, the gantry will move to the chosen slot.</block>",
29-
"select_blowout_slot_odd": "<block>You can blow out liquid into a labware.</block><br/><block>After the gantry moves to the chosen slot, use the jog controls to move the pipette to the exact position for blowing out.</block>",
30-
"select_drop_tip_slot": "<block>You can return tips to a tip rack or dispose of them.</block><block>Select the slot where you want to drop the tips on the deck map to the right. Once confirmed, the gantry will move to the chosen slot.</block>",
30+
"select_blowout_slot": "<block>Blowing out into a labware helps remove all liquid from the tip.</block><br/><block>Select the slot where you want to blow out the liquid on the deck map to the right. Once confirmed, the gantry will move to the chosen slot.</block>",
31+
"select_blowout_slot_odd": "<block>Blowing out into a labware helps remove all liquid from the tip.</block><br/><block>After the gantry moves to the chosen slot, use the jog controls to move the pipette to the exact position for blowing out.</block>",
32+
"select_drop_tip_slot": "<block>You can return tips to a tip rack or dispose of them.</block><br/><block>Select the slot where you want to drop the tips on the deck map to the right. Once confirmed, the gantry will move to the chosen slot.</block>",
3133
"select_drop_tip_slot_odd": "<block>You can return tips to a tip rack or dispose of them.</block><br/><block>After the gantry moves to the chosen slot, use the jog controls to move the pipette to the exact position for dropping tips.</block>",
3234
"skip": "Skip",
3335
"stand_back_blowing_out": "Stand back, robot is blowing out liquid",

app/src/assets/localization/en/error_recovery.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"robot_will_retry_with_tips": "The robot will retry the failed step with new tips.",
5959
"run_paused": "Run paused",
6060
"select_tip_pickup_location": "Select tip pick-up location",
61-
"skip": "Skip",
61+
"skip_removal": "Skip removal",
6262
"skip_to_next_step": "Skip to next step",
6363
"skip_to_next_step_new_tips": "Skip to next step with new tips",
6464
"skip_to_next_step_same_tips": "Skip to next step with same tips",
@@ -73,5 +73,5 @@
7373
"view_error_details": "View error details",
7474
"view_recovery_options": "View recovery options",
7575
"you_can_still_drop_tips": "You can still drop the attached tips before proceeding to tip selection.",
76-
"you_may_want_to_remove": "You may want to remove the tips from the {{mount}} pipette before using it again in a protocol"
76+
"remove_tips_from_pipette": "Remove tips from {{mount}} pipette before canceling the run?"
7777
}

app/src/molecules/InProgressModal/InProgressModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const MODAL_STYLE = css`
6060
}
6161
`
6262
const SPINNER_STYLE = css`
63-
color: ${COLORS.grey50};
63+
color: ${COLORS.grey60};
6464
opacity: 100%;
6565
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
6666
color: ${COLORS.black90};

app/src/molecules/SimpleWizardBody/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ export function SimpleWizardBody(props: Props): JSX.Element {
150150
<>
151151
{isSuccess ? (
152152
<img
153-
width={robotType === FLEX_ROBOT_TYPE ? '250px' : '160px'}
154-
height={robotType === FLEX_ROBOT_TYPE ? '208px' : '120px'}
153+
width={robotType === FLEX_ROBOT_TYPE ? '170px' : '160px'}
154+
height={robotType === FLEX_ROBOT_TYPE ? '141px' : '120px'}
155155
src={SuccessIcon}
156156
alt="Success Icon"
157157
/>

app/src/organisms/DropTipWizardFlows/BeforeBeginning.tsx

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
TYPOGRAPHY,
2323
} from '@opentrons/components'
2424

25-
import { SmallButton, MediumButton } from '../../atoms/buttons'
25+
import { SmallButton, MediumButton, TextOnlyButton } from '../../atoms/buttons'
2626
import { DT_ROUTES } from './constants'
2727

2828
import blowoutVideo from '../../assets/videos/droptip-wizard/Blowout-Liquid.webm'
@@ -52,60 +52,59 @@ export const BeforeBeginning = ({
5252
const buildTopText = (): string => {
5353
if (issuedCommandsType === 'fixit') {
5454
return fixitCommandTypeUtils?.copyOverrides
55-
.tipDropCompleteBtnCopy as string
55+
.beforeBeginningTopText as string
5656
} else {
5757
return t('before_you_begin_do_you_want_to_blowout')
5858
}
5959
}
6060

6161
if (isOnDevice) {
6262
return (
63-
<>
64-
<Flex flexDirection={DIRECTION_COLUMN} height="100%">
65-
<Flex css={ODD_TITLE_STYLE}>{buildTopText()}</Flex>
66-
<Flex paddingBottom={SPACING.spacing8}>
67-
<MediumButton
68-
buttonType={flowType === 'blowout' ? 'primary' : 'secondary'}
69-
flex="1"
70-
onClick={() => {
71-
setFlowType('blowout')
72-
}}
73-
buttonText={i18n.format(t('yes_blow_out_liquid'), 'capitalize')}
74-
justifyContent={JUSTIFY_FLEX_START}
75-
paddingLeft={SPACING.spacing24}
76-
height="5.25rem"
77-
/>
78-
</Flex>
79-
<Flex>
80-
<MediumButton
81-
buttonType={flowType === 'drop_tips' ? 'primary' : 'secondary'}
82-
flex="1"
83-
onClick={() => {
84-
setFlowType('drop_tips')
85-
}}
86-
buttonText={i18n.format(
87-
t('no_proceed_to_drop_tip'),
88-
'capitalize'
89-
)}
90-
justifyContent={JUSTIFY_FLEX_START}
91-
paddingLeft={SPACING.spacing24}
92-
height="5.25rem"
93-
/>
94-
</Flex>
95-
<Flex justifyContent={JUSTIFY_FLEX_END} marginTop="auto">
96-
<SmallButton
97-
buttonText={i18n.format(t('shared:continue'), 'capitalize')}
98-
onClick={handleProceed}
99-
disabled={flowType == null}
100-
/>
101-
</Flex>
63+
<Flex
64+
flexDirection={DIRECTION_COLUMN}
65+
height="100%"
66+
padding={issuedCommandsType === 'fixit' ? SPACING.spacing32 : null}
67+
>
68+
<Flex css={ODD_TITLE_STYLE}>{buildTopText()}</Flex>
69+
<Flex paddingBottom={SPACING.spacing8}>
70+
<MediumButton
71+
buttonType={flowType === 'blowout' ? 'primary' : 'secondary'}
72+
flex="1"
73+
onClick={() => {
74+
setFlowType('blowout')
75+
}}
76+
buttonText={i18n.format(t('yes_blow_out_liquid'), 'capitalize')}
77+
justifyContent={JUSTIFY_FLEX_START}
78+
paddingLeft={SPACING.spacing24}
79+
height="5.25rem"
80+
/>
10281
</Flex>
103-
</>
82+
<Flex>
83+
<MediumButton
84+
buttonType={flowType === 'drop_tips' ? 'primary' : 'secondary'}
85+
flex="1"
86+
onClick={() => {
87+
setFlowType('drop_tips')
88+
}}
89+
buttonText={i18n.format(t('no_proceed_to_drop_tip'), 'capitalize')}
90+
justifyContent={JUSTIFY_FLEX_START}
91+
paddingLeft={SPACING.spacing24}
92+
height="5.25rem"
93+
/>
94+
</Flex>
95+
<Flex justifyContent={JUSTIFY_FLEX_END} marginTop="auto">
96+
<SmallButton
97+
buttonText={i18n.format(t('shared:continue'), 'capitalize')}
98+
onClick={handleProceed}
99+
disabled={flowType == null}
100+
/>
101+
</Flex>
102+
</Flex>
104103
)
105104
} else {
106105
return (
107106
<Flex css={TILE_CONTAINER_STYLE}>
108-
<Title>{t('before_you_begin_do_you_want_to_blowout')}</Title>
107+
<Title>{buildTopText()}</Title>
109108
<Flex
110109
justifyContent={JUSTIFY_SPACE_AROUND}
111110
alignItems={ALIGN_CENTER}
@@ -163,8 +162,23 @@ export const BeforeBeginning = ({
163162
</LegacyStyledText>
164163
</Flex>
165164
</Flex>
166-
<Flex flexDirection={DIRECTION_ROW} justifyContent={JUSTIFY_FLEX_END}>
165+
<Flex
166+
flexDirection={DIRECTION_ROW}
167+
justifyContent={
168+
issuedCommandsType === 'fixit'
169+
? JUSTIFY_SPACE_BETWEEN
170+
: JUSTIFY_FLEX_END
171+
}
172+
>
167173
{/* <NeedHelpLink href={NEED_HELP_URL} /> */}
174+
{fixitCommandTypeUtils != null ? (
175+
<TextOnlyButton
176+
onClick={
177+
fixitCommandTypeUtils.buttonOverrides.goBackBeforeBeginning
178+
}
179+
buttonText={t('shared:go_back')}
180+
/>
181+
) : null}
168182
<PrimaryButton disabled={flowType == null} onClick={handleProceed}>
169183
{i18n.format(t('shared:continue'), 'capitalize')}
170184
</PrimaryButton>
@@ -242,6 +256,7 @@ const TILE_CONTAINER_STYLE = css`
242256
flex-direction: ${DIRECTION_COLUMN};
243257
justify-content: ${JUSTIFY_SPACE_BETWEEN};
244258
padding: ${SPACING.spacing32};
259+
height: 100%;
245260
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
246261
height: 29.5rem;
247262
}

app/src/organisms/DropTipWizardFlows/ChooseLocation.tsx

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
ALIGN_CENTER,
77
ALIGN_FLEX_END,
88
Btn,
9-
COLORS,
109
DIRECTION_COLUMN,
1110
Flex,
1211
JUSTIFY_SPACE_BETWEEN,
@@ -20,7 +19,7 @@ import {
2019
} from '@opentrons/components'
2120
import { getDeckDefFromRobotType } from '@opentrons/shared-data'
2221

23-
import { SmallButton } from '../../atoms/buttons'
22+
import { SmallButton, TextOnlyButton } from '../../atoms/buttons'
2423
import { TwoColumn, DeckMapContent } from '../../molecules/InterventionModal'
2524

2625
import type {
@@ -59,6 +58,7 @@ export const ChooseLocation = (
5958
body,
6059
robotType,
6160
moveToAddressableArea,
61+
issuedCommandsType,
6262
} = props
6363
const { i18n, t } = useTranslation(['drop_tip_wizard', 'shared'])
6464
const [
@@ -79,7 +79,10 @@ export const ChooseLocation = (
7979
}
8080
}
8181
return (
82-
<Flex css={CONTAINER_STYLE}>
82+
<Flex
83+
css={CONTAINER_STYLE}
84+
height={issuedCommandsType === 'fixit' ? '100%' : '24.625rem'}
85+
>
8386
<TwoColumn>
8487
<Flex flexDirection={DIRECTION_COLUMN} flex="1" gap={SPACING.spacing16}>
8588
<Title>{title}</Title>
@@ -102,9 +105,10 @@ export const ChooseLocation = (
102105
handleGoBack()
103106
}}
104107
>
105-
<LegacyStyledText css={GO_BACK_BUTTON_STYLE}>
106-
{t('shared:go_back')}
107-
</LegacyStyledText>
108+
<TextOnlyButton
109+
onClick={handleGoBack}
110+
buttonText={t('shared:go_back')}
111+
/>
108112
</Btn>
109113
<PrimaryButton
110114
onClick={handleConfirmPosition}
@@ -130,24 +134,6 @@ export const ChooseLocation = (
130134
)
131135
}
132136

133-
const GO_BACK_BUTTON_STYLE = css`
134-
${TYPOGRAPHY.pSemiBold};
135-
color: ${COLORS.grey50};
136-
137-
&:hover {
138-
opacity: 70%;
139-
}
140-
141-
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
142-
font-weight: ${TYPOGRAPHY.fontWeightSemiBold};
143-
font-size: ${TYPOGRAPHY.fontSize22};
144-
padding-left: 0;
145-
&:hover {
146-
opacity: 100%;
147-
}
148-
}
149-
`
150-
151137
const ALIGN_BUTTONS = css`
152138
align-items: ${ALIGN_FLEX_END};
153139
@@ -160,7 +146,6 @@ const CONTAINER_STYLE = css`
160146
flex-direction: ${DIRECTION_COLUMN};
161147
justify-content: ${JUSTIFY_SPACE_BETWEEN};
162148
padding: ${SPACING.spacing32};
163-
height: 24.625rem;
164149
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
165150
justify-content: ${JUSTIFY_FLEX_START};
166151
gap: ${SPACING.spacing32};

app/src/organisms/DropTipWizardFlows/DropTipWizard.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import * as React from 'react'
22
import { createPortal } from 'react-dom'
33
import { Trans, useTranslation } from 'react-i18next'
44
import { useSelector } from 'react-redux'
5+
import { css } from 'styled-components'
56

67
import {
78
BORDERS,
89
COLORS,
910
DIRECTION_COLUMN,
11+
RESPONSIVENESS,
1012
Flex,
1113
JUSTIFY_FLEX_END,
1214
JUSTIFY_SPACE_BETWEEN,
@@ -109,7 +111,8 @@ export function DropTipWizard(props: DropTipWizardProps): JSX.Element {
109111
)
110112
}
111113

112-
// TODO(jh, 06-07-24): All content views could use refactoring and DQA. Create shared components from designs. EXEC-520.
114+
// TODO(jh, 06-07-24): All content views could use refactoring and DQA. Create shared components from designs.
115+
// Convince design not to use SimpleWizardBody. EXEC-520.
113116
export function DropTipWizardContainer(
114117
props: DropTipWizardContainerProps
115118
): JSX.Element {
@@ -218,7 +221,12 @@ export const DropTipWizardContent = (
218221
}
219222

220223
function buildRobotInMotion(): JSX.Element {
221-
return <InProgressModal description={t('stand_back_robot_in_motion')} />
224+
return (
225+
<>
226+
{issuedCommandsType === 'fixit' ? <Flex /> : null}
227+
<InProgressModal description={t('stand_back_robot_in_motion')} />
228+
</>
229+
)
222230
}
223231

224232
function buildShowExitConfirmation(): JSX.Element {
@@ -244,7 +252,7 @@ export const DropTipWizardContent = (
244252
header={errorDetails?.header ?? t('error_dropping_tips')}
245253
subHeader={subHeader}
246254
justifyContentForOddButton={JUSTIFY_FLEX_END}
247-
marginTop={`-${SPACING.spacing68}`} // See EXEC-520. This clearly isn't ideal.
255+
css={ERROR_MODAL_FIXIT_STYLE}
248256
>
249257
{button}
250258
</SimpleWizardBody>
@@ -397,3 +405,9 @@ function useInitiateExit(): {
397405

398406
return { isExitInitiated, toggleExitInitiated }
399407
}
408+
409+
const ERROR_MODAL_FIXIT_STYLE = css`
410+
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
411+
margin-top: -${SPACING.spacing68}; // See EXEC-520. This clearly isn't ideal.
412+
}
413+
`

0 commit comments

Comments
 (0)