Skip to content

Commit 06bdf5e

Browse files
authored
fix(protocol-designer): fix tips selection inline notification conditional rendering (#20323)
Automatically show selected tips error on mount if opening an existing step
1 parent a84cb45 commit 06bdf5e

File tree

3 files changed

+36
-22
lines changed

3 files changed

+36
-22
lines changed

protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/PipetteFields/TipSelectionWizard/SelectTips.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ import type {
5555
import type {
5656
AccessibilityStatus,
5757
InaccessibleReason,
58-
TipSelectionBannerReason,
5958
TipSelectionBaseProps,
6059
} from './types'
6160

@@ -68,9 +67,7 @@ export function SelectTips(
6867
numTotalPickups: number
6968
selectedTips: string[][]
7069
setSelectedTips: Dispatch<SetStateAction<string[][]>>
71-
setErrorBannerReason: Dispatch<
72-
SetStateAction<TipSelectionBannerReason | null>
73-
>
70+
setShowErrorBanner: Dispatch<SetStateAction<boolean>>
7471
primaryNozzle: string
7572
tipAccessibilityStatus: Record<string, Record<string, AccessibilityStatus>>
7673
}
@@ -90,7 +87,7 @@ export function SelectTips(
9087
selectedTips,
9188
setSelectedTips,
9289
numTotalPickups,
93-
setErrorBannerReason,
90+
setShowErrorBanner,
9491
tipAccessibilityStatus,
9592
nozzles,
9693
primaryNozzle,
@@ -183,7 +180,7 @@ export function SelectTips(
183180
) {
184181
return
185182
}
186-
setErrorBannerReason(null)
183+
setShowErrorBanner(false)
187184

188185
if (channels === 1 || nozzles === SINGLE) {
189186
if (wellName in prevSelectedTipsByIndex) {

protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/PipetteFields/TipSelectionWizard/TipSelectionModal.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ interface TipSelectionModalProps {
2727
totalSteps: number
2828
showBackButton?: boolean
2929
continueText?: string
30-
errorBannerReason: TipSelectionBannerReason | null
30+
showErrorBanner: boolean
3131
numPickupsRemaining: number
3232
showReusingTipsBanner: boolean
33+
errorReason: TipSelectionBannerReason | null
3334
}
3435

3536
export function TipSelectionModal(props: TipSelectionModalProps): JSX.Element {
@@ -42,9 +43,10 @@ export function TipSelectionModal(props: TipSelectionModalProps): JSX.Element {
4243
continueText,
4344
currentStepIndex,
4445
totalSteps,
45-
errorBannerReason,
46+
showErrorBanner,
4647
numPickupsRemaining,
4748
showReusingTipsBanner,
49+
errorReason,
4850
} = props
4951
const { t } = useTranslation('tip_selection')
5052

@@ -59,19 +61,19 @@ export function TipSelectionModal(props: TipSelectionModalProps): JSX.Element {
5961

6062
const footerElement = (
6163
<div className={styles.modal_footer}>
62-
{errorBannerReason != null ? (
64+
{errorReason != null && showErrorBanner && currentStepIndex === 1 ? (
6365
<InlineNotification
6466
type="error"
6567
message={t(
66-
`error_banner.${errorBannerReason}`,
67-
errorBannerReason === 'pickupsRequired'
68+
`error_banner.${errorReason}`,
69+
errorReason === 'pickupsRequired'
6870
? { count: numPickupsRemaining }
6971
: {}
7072
)}
7173
hug
7274
/>
7375
) : null}
74-
{errorBannerReason == null &&
76+
{(errorReason == null || !showErrorBanner) &&
7577
showReusingTipsBanner &&
7678
currentStepIndex === 1 ? (
7779
<InlineNotification

protocol-designer/src/pages/Designer/ProtocolSteps/StepForm/PipetteFields/TipSelectionWizard/index.tsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@ export function TipSelectionWizard(
6868
const [selectedTiprackId, setSelectedTiprackId] = useState<string | null>(
6969
tiprackSelected
7070
)
71-
const [errorBannerReason, setErrorBannerReason] =
72-
useState<TipSelectionBannerReason | null>(null)
71+
const [showErrorBanner, setShowErrorBanner] = useState<boolean>(
72+
selectedTips.flat().length > 0
73+
)
7374
const robotState = useSelector(getRobotStateAtActiveItem)
7475
const tipState =
7576
selectedTiprackId != null
@@ -113,16 +114,29 @@ export function TipSelectionWizard(
113114
INACCESSIBLE_INCOMPLETE
114115
)
115116

117+
const errorReason = ((): TipSelectionBannerReason | null => {
118+
if (isAnySelectedWellTooManyPickups) {
119+
return 'tooManyTips'
120+
}
121+
if (isAnySelectedWellIncomplete) {
122+
return 'incompletePickup'
123+
}
124+
if (selectedTips.length !== numPickups) {
125+
return 'pickupsRequired'
126+
}
127+
return null
128+
})()
129+
116130
const handleContinue = (): void => {
117131
if (selectedTiprackId == null) {
118132
makeSnackbar(t('no_tiprack_selected') as string)
119133
} else if (currentStepIndex === NUM_TOTAL_STEPS - 1) {
120-
if (selectedTips.length !== numPickups) {
121-
setErrorBannerReason('pickupsRequired')
122-
} else if (isAnySelectedWellTooManyPickups) {
123-
setErrorBannerReason('tooManyTips')
124-
} else if (isAnySelectedWellIncomplete) {
125-
setErrorBannerReason('incompletePickup')
134+
if (
135+
selectedTips.length !== numPickups ||
136+
isAnySelectedWellTooManyPickups ||
137+
isAnySelectedWellIncomplete
138+
) {
139+
setShowErrorBanner(true)
126140
} else {
127141
handleSave()
128142
}
@@ -164,7 +178,7 @@ export function TipSelectionWizard(
164178
primaryNozzle={primaryNozzle}
165179
selectedTips={selectedTips}
166180
setSelectedTips={setSelectedTips}
167-
setErrorBannerReason={setErrorBannerReason}
181+
setShowErrorBanner={setShowErrorBanner}
168182
numTotalPickups={numPickups}
169183
nozzles={nozzles}
170184
tipAccessibilityStatus={tipAccessibilityStatus}
@@ -191,9 +205,10 @@ export function TipSelectionWizard(
191205
}
192206
currentStepIndex={currentStepIndex}
193207
totalSteps={NUM_TOTAL_STEPS}
194-
errorBannerReason={errorBannerReason}
208+
showErrorBanner={showErrorBanner}
195209
numPickupsRemaining={numPickups - selectedTips.length}
196210
showReusingTipsBanner={isAnySelectedWellUsed}
211+
errorReason={errorReason}
197212
>
198213
{currentComponent}
199214
</TipSelectionModal>

0 commit comments

Comments
 (0)