|
1 | 1 | /* eslint-disable prefer-object-spread, function-paren-newline, |
2 | 2 | react/function-component-definition */ |
3 | | -import React from 'react'; |
| 3 | +import React, { useEffect } from 'react'; |
4 | 4 | import PropTypes from 'prop-types'; |
5 | 5 | import classNames from 'classnames'; |
6 | 6 | import { connect } from 'react-redux'; |
@@ -37,44 +37,46 @@ const styles = () => ( |
37 | 37 | const shiftSelect = ( |
38 | 38 | classes, layoutSt, setShiftRefAct, shiftSt, curveSt, |
39 | 39 | ) => { |
40 | | - if (Cfg.hideSolvent(layoutSt)) return null; |
41 | | - // const onChange = (e) => setShiftRefAct(e.target.value); |
| 40 | + if (Cfg.hideSolvent(layoutSt)) { |
| 41 | + return null; |
| 42 | + } |
| 43 | + |
42 | 44 | const { curveIdx } = curveSt; |
43 | 45 | const { shifts } = shiftSt; |
44 | | - const selectedShift = shifts[curveIdx]; |
45 | | - const shiftRef = selectedShift.ref; |
| 46 | + const selectedShift = shifts[curveIdx] || {}; |
| 47 | + const listShift = getListShift(layoutSt) || []; |
| 48 | + |
| 49 | + const shiftRefName = selectedShift?.ref?.name || ''; |
| 50 | + const isInList = listShift.some((r) => r.name === shiftRefName); |
| 51 | + const selectValue = isInList ? shiftRefName : ''; |
46 | 52 |
|
47 | 53 | const onChange = (e) => { |
48 | | - const payload = { dataToSet: e.target.value, curveIdx }; |
49 | | - setShiftRefAct(payload); |
| 54 | + const name = e.target.value; |
| 55 | + const refObj = listShift.find((r) => r.name === name); |
| 56 | + if (refObj) { |
| 57 | + setShiftRefAct({ dataToSet: refObj, curveIdx }); |
| 58 | + } |
50 | 59 | }; |
51 | 60 |
|
52 | | - const listShift = getListShift(layoutSt); |
53 | | - |
54 | | - const content = listShift.map((ref) => ( |
55 | | - <MenuItem value={ref} key={ref.name}> |
56 | | - <span className={classNames(classes.txtOpt, 'option-sv-bar-shift')}> |
57 | | - { `${ref.name}: ${Format.strNumberFixedDecimal(ref.value, 2)} ppm` } |
58 | | - </span> |
59 | | - </MenuItem> |
60 | | - )); |
61 | | - |
62 | 61 | return ( |
63 | | - <FormControl |
64 | | - className={classNames(classes.fieldShift)} |
65 | | - variant="outlined" |
66 | | - > |
| 62 | + <FormControl className={classNames(classes.fieldShift)} variant="outlined"> |
67 | 63 | <InputLabel id="select-solvent-label" className={classNames(classes.selectLabel, 'select-sv-bar-label')}> |
68 | 64 | Reference |
69 | 65 | </InputLabel> |
70 | 66 | <Select |
71 | | - value={shiftRef} |
| 67 | + value={selectValue} |
72 | 68 | labelId="select-solvent-label" |
73 | 69 | label="Solvent" |
74 | 70 | onChange={onChange} |
75 | 71 | className={classNames(classes.selectInput, 'input-sv-bar-shift')} |
76 | 72 | > |
77 | | - { content } |
| 73 | + {listShift.map((ref) => ( |
| 74 | + <MenuItem value={ref.name} key={ref.name}> |
| 75 | + <span className={classNames(classes.txtOpt, 'option-sv-bar-shift')}> |
| 76 | + {`${ref.name}: ${Format.strNumberFixedDecimal(ref.value, 2)} ppm`} |
| 77 | + </span> |
| 78 | + </MenuItem> |
| 79 | + ))} |
78 | 80 | </Select> |
79 | 81 | </FormControl> |
80 | 82 | ); |
@@ -189,16 +191,82 @@ const layoutSelect = (classes, layoutSt, updateLayoutAct) => { |
189 | 191 | ); |
190 | 192 | }; |
191 | 193 |
|
| 194 | +const PLACEHOLDER = '- - -'; |
| 195 | + |
| 196 | +const norm = (s) => (s || '').toString().toLowerCase().normalize('NFKD').replace(/[^a-z0-9]+/g, ''); |
| 197 | + |
| 198 | +function solventKeyOf(feature) { |
| 199 | + const r = feature?.metadata?.solventName ?? feature?.metadata?.solvent |
| 200 | + ?? feature?.meta?.solventName ?? feature?.meta?.solvent |
| 201 | + ?? feature?.solventName ?? feature?.solvent ?? null; |
| 202 | + const a = feature?.metadata?.solvent_label ?? feature?.metadata?.solventLabel ?? null; |
| 203 | + const raw = r && r !== PLACEHOLDER ? r : null; |
| 204 | + const alt = a && a !== PLACEHOLDER ? a : null; |
| 205 | + return norm(raw || alt || ''); |
| 206 | +} |
| 207 | + |
| 208 | +function pickBestRef(list, key) { |
| 209 | + if (!key || !list?.length) return null; |
| 210 | + const scored = []; |
| 211 | + list.forEach((r) => { |
| 212 | + const nLabel = norm(r.label); |
| 213 | + const nName = norm(r.name); |
| 214 | + const nNsdb = norm(r.nsdb); |
| 215 | + let s = 0; |
| 216 | + if (nLabel && nLabel === key) s += 3; |
| 217 | + if (nNsdb && nNsdb.includes(key)) s += 2; |
| 218 | + if (nName && nName.includes(key)) s += 1; |
| 219 | + if (s > 0) scored.push({ r, s }); |
| 220 | + }); |
| 221 | + if (!scored.length) return null; |
| 222 | + let max = 0; |
| 223 | + scored.forEach((x) => { |
| 224 | + if (x.s > max) max = x.s; |
| 225 | + }); |
| 226 | + let cand = scored.filter((x) => x.s === max).map((x) => x.r); |
| 227 | + if (cand.length > 1) { |
| 228 | + const vals = cand.map((c) => (typeof c.value === 'number' ? c.value : null)) |
| 229 | + .filter((v) => v != null).sort((a, b) => a - b); |
| 230 | + if (vals.length) { |
| 231 | + const m = vals[Math.floor(vals.length / 2)]; |
| 232 | + cand = cand.slice().sort((a, b) => Math.abs((a.value ?? m) - m) |
| 233 | + - Math.abs((b.value ?? m) - m)); |
| 234 | + } |
| 235 | + if (cand.length > 1) { |
| 236 | + cand.sort((a, b) => (a.name?.length || 0) - (b.name?.length || 0)); |
| 237 | + } |
| 238 | + } |
| 239 | + return cand[0] || null; |
| 240 | +} |
| 241 | + |
| 242 | +function isRefUnset(shiftSt, curveIdx, list) { |
| 243 | + const name = shiftSt?.shifts?.[curveIdx]?.ref?.name || ''; |
| 244 | + if (!name || name === PLACEHOLDER) return true; |
| 245 | + return !(list || []).some((r) => r.name === name); |
| 246 | +} |
| 247 | + |
192 | 248 | const Layout = ({ |
193 | 249 | classes, feature, hasEdit, layoutSt, |
194 | 250 | setShiftRefAct, updateLayoutAct, curveSt, shiftSt, |
195 | | -}) => ( |
196 | | - <span className={classes.groupRight}> |
197 | | - { layoutSelect(classes, layoutSt, updateLayoutAct) } |
198 | | - { shiftSelect(classes, layoutSt, setShiftRefAct, shiftSt, curveSt) } |
199 | | - <Scan feature={feature} hasEdit={hasEdit} /> |
200 | | - </span> |
201 | | -); |
| 251 | +}) => { |
| 252 | + const { curveIdx } = curveSt; |
| 253 | + const list = getListShift(layoutSt) || []; |
| 254 | + const unset = isRefUnset(shiftSt, curveIdx, list); |
| 255 | + const key = solventKeyOf(feature); |
| 256 | + const best = pickBestRef(list, key); |
| 257 | + |
| 258 | + useEffect(() => { |
| 259 | + if (unset && best) setShiftRefAct({ dataToSet: best, curveIdx }); |
| 260 | + }, [unset, best, curveIdx, setShiftRefAct]); |
| 261 | + |
| 262 | + return ( |
| 263 | + <span className={classes.groupRight}> |
| 264 | + { layoutSelect(classes, layoutSt, updateLayoutAct) } |
| 265 | + { shiftSelect(classes, layoutSt, setShiftRefAct, shiftSt, curveSt) } |
| 266 | + <Scan feature={feature} hasEdit={hasEdit} /> |
| 267 | + </span> |
| 268 | + ); |
| 269 | +}; |
202 | 270 |
|
203 | 271 | const mapStateToProps = (state, props) => ( // eslint-disable-line |
204 | 272 | { |
|
0 commit comments