@@ -11,6 +11,7 @@ import {
11
11
OutlineButton ,
12
12
RadioGroup ,
13
13
} from '@opentrons/components'
14
+ import { DEFAULT_MM_BLOWOUT_OFFSET_FROM_TOP } from '../../../../constants'
14
15
import { getMainPagePortalEl } from '../../../portals/MainPageModalPortal'
15
16
import { getIsTouchTipField } from '../../../../form-types'
16
17
import { TipPositionZAxisViz } from './TipPositionZAxisViz'
@@ -24,7 +25,7 @@ import styles from './TipPositionInput.module.css'
24
25
25
26
interface ZTipPositionModalProps {
26
27
closeModal : ( ) => void
27
- mmFromBottom : number | null
28
+ zValue : number | null
28
29
name : StepFieldName
29
30
updateValue : ( val ?: number | null ) => unknown
30
31
wellDepthMm : number
@@ -36,21 +37,26 @@ export function ZTipPositionModal(props: ZTipPositionModalProps): JSX.Element {
36
37
isIndeterminate,
37
38
name,
38
39
wellDepthMm,
39
- mmFromBottom ,
40
+ zValue ,
40
41
closeModal,
41
42
updateValue,
42
43
} = props
43
44
const { t } = useTranslation ( [ 'modal' , 'button' ] )
44
- const defaultMmFromBottom = utils . getDefaultMmFromBottom ( {
45
- name,
46
- wellDepthMm,
47
- } )
45
+
46
+ const isBlowout = name === 'blowout_z_offset'
47
+ const defaultMm = isBlowout
48
+ ? 0
49
+ : utils . getDefaultMmFromBottom ( {
50
+ name,
51
+ wellDepthMm,
52
+ } )
48
53
49
54
const [ value , setValue ] = React . useState < string | null > (
50
- mmFromBottom === null ? null : String ( mmFromBottom )
55
+ zValue !== null ? String ( zValue ) : null
51
56
)
57
+ const isSetDefault = isBlowout ? zValue === 0 : zValue === null
52
58
const [ isDefault , setIsDefault ] = React . useState < boolean > (
53
- ! isIndeterminate && mmFromBottom === null
59
+ ! isIndeterminate && isSetDefault
54
60
)
55
61
// in this modal, pristinity hides the OUT_OF_BOUNDS error only.
56
62
const [ isPristine , setPristine ] = React . useState < boolean > ( true )
@@ -71,20 +77,29 @@ export function ZTipPositionModal(props: ZTipPositionModalProps): JSX.Element {
71
77
}
72
78
}
73
79
const { maxMmFromBottom, minMmFromBottom } = getMinMaxMmFromBottom ( )
80
+
81
+ // For blowout from the top of the well
82
+ const minFromTop = DEFAULT_MM_BLOWOUT_OFFSET_FROM_TOP
83
+ const maxFromTop = - wellDepthMm
84
+
85
+ const minMm = isBlowout ? maxFromTop : minMmFromBottom
86
+ const maxMm = isBlowout ? minFromTop : maxMmFromBottom
87
+
74
88
const errors = utils . getErrors ( {
75
89
isDefault,
76
- minMm : minMmFromBottom ,
77
- maxMm : maxMmFromBottom ,
90
+ minMm,
91
+ maxMm,
78
92
value,
79
93
} )
80
94
const hasErrors = errors . length > 0
81
95
const hasVisibleErrors = isPristine
82
96
? errors . includes ( TOO_MANY_DECIMALS )
83
97
: hasErrors
98
+
84
99
const errorText = utils . getErrorText ( {
85
100
errors,
86
- minMm : maxMmFromBottom ,
87
- maxMm : minMmFromBottom ,
101
+ minMm,
102
+ maxMm,
88
103
isPristine,
89
104
t,
90
105
} )
@@ -110,13 +125,17 @@ export function ZTipPositionModal(props: ZTipPositionModalProps): JSX.Element {
110
125
// if string, strip non-number characters from string and cast to number
111
126
const newValue =
112
127
typeof newValueRaw === 'string'
113
- ? newValueRaw . replace ( / [ ^ . 0 - 9 ] / , '' )
128
+ ? newValueRaw . replace ( / [ ^ - . 0 - 9 ] / , '' )
114
129
: String ( newValueRaw )
115
130
116
131
if ( newValue === '.' ) {
117
132
setValue ( '0.' )
133
+ } else if ( newValue === '-0' ) {
134
+ setValue ( '0' )
118
135
} else {
119
- setValue ( Number ( newValue ) >= 0 ? newValue : '0' )
136
+ isBlowout
137
+ ? setValue ( newValue )
138
+ : setValue ( Number ( newValue ) >= 0 ? newValue : '0' )
120
139
}
121
140
}
122
141
@@ -127,7 +146,7 @@ export function ZTipPositionModal(props: ZTipPositionModalProps): JSX.Element {
127
146
}
128
147
129
148
const handleIncrementDecrement = ( delta : number ) : void => {
130
- const prevValue = value === null ? defaultMmFromBottom : Number ( value )
149
+ const prevValue = value === null ? defaultMm : Number ( value )
131
150
setIsDefault ( false )
132
151
handleChange ( utils . roundValue ( prevValue + delta ) )
133
152
}
@@ -143,8 +162,8 @@ export function ZTipPositionModal(props: ZTipPositionModalProps): JSX.Element {
143
162
const TipPositionInputField = ! isDefault && (
144
163
< InputField
145
164
caption = { t ( 'tip_position.caption' , {
146
- min : minMmFromBottom ,
147
- max : maxMmFromBottom ,
165
+ min : minMm ,
166
+ max : maxMm ,
148
167
} ) }
149
168
className = { styles . position_from_bottom_input }
150
169
error = { errorText }
@@ -210,9 +229,11 @@ export function ZTipPositionModal(props: ZTipPositionModalProps): JSX.Element {
210
229
} }
211
230
options = { [
212
231
{
213
- name : t ( 'tip_position.radio_button.default' , {
214
- defaultMmFromBottom,
215
- } ) ,
232
+ name : isBlowout
233
+ ? t ( 'tip_position.radio_button.blowout' )
234
+ : t ( 'tip_position.radio_button.default' , {
235
+ defaultMm,
236
+ } ) ,
216
237
value : 'default' ,
217
238
} ,
218
239
{
@@ -246,7 +267,18 @@ export function ZTipPositionModal(props: ZTipPositionModalProps): JSX.Element {
246
267
) : null }
247
268
< TipPositionZAxisViz
248
269
mmFromBottom = {
249
- value !== null ? Number ( value ) : defaultMmFromBottom
270
+ isBlowout
271
+ ? undefined
272
+ : value !== null
273
+ ? Number ( value )
274
+ : defaultMm
275
+ }
276
+ mmFromTop = {
277
+ isBlowout
278
+ ? value !== null
279
+ ? Number ( value )
280
+ : defaultMm
281
+ : undefined
250
282
}
251
283
wellDepthMm = { wellDepthMm }
252
284
/>
0 commit comments