@jbrowse/plugin-linear-genome-view 1.7.7 → 1.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -693,8 +693,6 @@ var BaseLinearDisplay = _mobxStateTree.types.compose('BaseLinearDisplay', _model
693
693
  // version, or just get the default if none available
694
694
 
695
695
 
696
- // regionCannotBeRendered can return jsx so look for plaintext
697
- // version, or just get the default if none available
698
696
  var cannotBeRenderedReason = self.regionCannotBeRenderedText(block) || self.regionCannotBeRendered(block);
699
697
 
700
698
  if (cannotBeRenderedReason) {
@@ -70,35 +70,35 @@ var ImportForm = (0, _mobxReact.observer)(function (_ref) {
70
70
  textSearchManager = session.textSearchManager;
71
71
  var rankSearchResults = model.rankSearchResults,
72
72
  isSearchDialogDisplayed = model.isSearchDialogDisplayed,
73
- modelError = model.error;
73
+ error = model.error;
74
74
 
75
75
  var _useState = (0, _react.useState)(assemblyNames[0]),
76
76
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
77
77
  selectedAsm = _useState2[0],
78
78
  setSelectedAsm = _useState2[1];
79
79
 
80
- var _useState3 = (0, _react.useState)(modelError),
80
+ var _useState3 = (0, _react.useState)(error),
81
81
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
82
- error = _useState4[0],
83
- setError = _useState4[1];
82
+ importError = _useState4[0],
83
+ setImportError = _useState4[1];
84
84
 
85
85
  var searchScope = model.searchScope(selectedAsm);
86
86
  var assembly = assemblyManager.get(selectedAsm);
87
87
  var assemblyError = assemblyNames.length ? assembly === null || assembly === void 0 ? void 0 : assembly.error : 'No configured assemblies';
88
88
  var regions = (assembly === null || assembly === void 0 ? void 0 : assembly.regions) || [];
89
- var err = assemblyError || error;
89
+ var err = assemblyError || importError;
90
90
 
91
- var _useState5 = (0, _react.useState)(),
91
+ var _useState5 = (0, _react.useState)(''),
92
92
  _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
93
- myOption = _useState6[0],
94
- setOption = _useState6[1]; // use this instead of useState initializer because the useState initializer
95
- // won't update in response to an observable
93
+ myVal = _useState6[0],
94
+ setValue = _useState6[1];
96
95
 
96
+ var value = myVal || ((_regions$ = regions[0]) === null || _regions$ === void 0 ? void 0 : _regions$.refName); // use this instead of useState initializer because the useState initializer
97
+ // won't update in response to an observable
97
98
 
98
- var option = myOption || new _BaseResults.default({
99
- label: (_regions$ = regions[0]) === null || _regions$ === void 0 ? void 0 : _regions$.refName
99
+ var option = new _BaseResults.default({
100
+ label: value
100
101
  });
101
- var selectedRegion = option === null || option === void 0 ? void 0 : option.getLocation();
102
102
 
103
103
  function fetchResults(_x, _x2) {
104
104
  return _fetchResults.apply(this, arguments);
@@ -155,7 +155,7 @@ var ImportForm = (0, _mobxReact.observer)(function (_ref) {
155
155
 
156
156
  function _handleSelectedRegion() {
157
157
  _handleSelectedRegion = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(input) {
158
- var trackId, location, _assembly$allRefNames2, results;
158
+ var trackId, location, _location$split, _location$split2, ref, rest, allRefs, results;
159
159
 
160
160
  return _regenerator.default.wrap(function _callee2$(_context2) {
161
161
  while (1) {
@@ -171,61 +171,63 @@ var ImportForm = (0, _mobxReact.observer)(function (_ref) {
171
171
  case 2:
172
172
  trackId = option.getTrackId();
173
173
  location = input || option.getLocation() || '';
174
- _context2.prev = 4;
174
+ _location$split = location.split(':'), _location$split2 = (0, _slicedToArray2.default)(_location$split, 2), ref = _location$split2[0], rest = _location$split2[1];
175
+ allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNames) || [];
176
+ _context2.prev = 6;
175
177
 
176
- if (!(assembly !== null && assembly !== void 0 && (_assembly$allRefNames2 = assembly.allRefNames) !== null && _assembly$allRefNames2 !== void 0 && _assembly$allRefNames2.includes(location))) {
177
- _context2.next = 9;
178
+ if (!(allRefs.includes(location) || allRefs.includes(ref) && rest !== undefined && !Number.isNaN(parseInt(rest, 10)))) {
179
+ _context2.next = 11;
178
180
  break;
179
181
  }
180
182
 
181
183
  model.navToLocString(location, selectedAsm);
182
- _context2.next = 20;
184
+ _context2.next = 22;
183
185
  break;
184
186
 
185
- case 9:
186
- _context2.next = 11;
187
+ case 11:
188
+ _context2.next = 13;
187
189
  return fetchResults(input, 'exact');
188
190
 
189
- case 11:
191
+ case 13:
190
192
  results = _context2.sent;
191
193
 
192
- if (!(results && results.length > 1)) {
193
- _context2.next = 17;
194
+ if (!(results.length > 1)) {
195
+ _context2.next = 19;
194
196
  break;
195
197
  }
196
198
 
197
199
  model.setSearchResults(results, input.toLowerCase());
198
200
  return _context2.abrupt("return");
199
201
 
200
- case 17:
201
- if ((results === null || results === void 0 ? void 0 : results.length) === 1) {
202
+ case 19:
203
+ if (results.length === 1) {
202
204
  location = results[0].getLocation();
203
205
  trackId = results[0].getTrackId();
204
206
  }
205
207
 
206
- case 18:
208
+ case 20:
207
209
  model.navToLocString(location, selectedAsm);
208
210
 
209
211
  if (trackId) {
210
212
  model.showTrack(trackId);
211
213
  }
212
214
 
213
- case 20:
214
- _context2.next = 26;
215
+ case 22:
216
+ _context2.next = 28;
215
217
  break;
216
218
 
217
- case 22:
218
- _context2.prev = 22;
219
- _context2.t0 = _context2["catch"](4);
219
+ case 24:
220
+ _context2.prev = 24;
221
+ _context2.t0 = _context2["catch"](6);
220
222
  console.error(_context2.t0);
221
223
  session.notify("".concat(_context2.t0), 'warning');
222
224
 
223
- case 26:
225
+ case 28:
224
226
  case "end":
225
227
  return _context2.stop();
226
228
  }
227
229
  }
228
- }, _callee2, null, [[4, 22]]);
230
+ }, _callee2, null, [[6, 24]]);
229
231
  }));
230
232
  return _handleSelectedRegion.apply(this, arguments);
231
233
  }
@@ -241,7 +243,12 @@ var ImportForm = (0, _mobxReact.observer)(function (_ref) {
241
243
  className: classes.importFormContainer
242
244
  }, /*#__PURE__*/_react.default.createElement("form", {
243
245
  onSubmit: function onSubmit(event) {
244
- return event.preventDefault();
246
+ event.preventDefault();
247
+ model.setError(undefined);
248
+
249
+ if (value) {
250
+ handleSelectedRegion(value);
251
+ }
245
252
  }
246
253
  }, /*#__PURE__*/_react.default.createElement(_core.Grid, {
247
254
  container: true,
@@ -252,7 +259,7 @@ var ImportForm = (0, _mobxReact.observer)(function (_ref) {
252
259
  item: true
253
260
  }, /*#__PURE__*/_react.default.createElement(_AssemblySelector.default, {
254
261
  onChange: function onChange(val) {
255
- setError(undefined);
262
+ setImportError('');
256
263
  setSelectedAsm(val);
257
264
  },
258
265
  session: session,
@@ -268,15 +275,15 @@ var ImportForm = (0, _mobxReact.observer)(function (_ref) {
268
275
  style: {
269
276
  color: 'red'
270
277
  }
271
- }) : selectedRegion ? /*#__PURE__*/_react.default.createElement(_RefNameAutocomplete.default, {
278
+ }) : value ? /*#__PURE__*/_react.default.createElement(_RefNameAutocomplete.default, {
272
279
  fetchResults: fetchResults,
273
280
  model: model,
274
281
  assemblyName: assemblyError ? undefined : selectedAsm,
275
- value: selectedRegion // note: minWidth 270 accomodates full width of helperText
282
+ value: value // note: minWidth 270 accomodates full width of helperText
276
283
  ,
277
284
  minWidth: 270,
278
- onSelect: function onSelect(option) {
279
- return setOption(option);
285
+ onChange: function onChange(str) {
286
+ return setValue(str);
280
287
  },
281
288
  TextFieldProps: {
282
289
  variant: 'outlined',
@@ -298,19 +305,12 @@ var ImportForm = (0, _mobxReact.observer)(function (_ref) {
298
305
  item: true
299
306
  }, /*#__PURE__*/_react.default.createElement(_core.Button, {
300
307
  type: "submit",
301
- disabled: !selectedRegion,
308
+ disabled: !value,
302
309
  className: classes.button,
303
- onClick: function onClick() {
304
- model.setError(undefined);
305
-
306
- if (selectedRegion) {
307
- handleSelectedRegion(selectedRegion);
308
- }
309
- },
310
310
  variant: "contained",
311
311
  color: "primary"
312
312
  }, "Open"), /*#__PURE__*/_react.default.createElement(_core.Button, {
313
- disabled: !selectedRegion,
313
+ disabled: !value,
314
314
  className: classes.button,
315
315
  onClick: function onClick() {
316
316
  model.setError(undefined);
@@ -6,9 +6,10 @@ export interface Option {
6
6
  group?: string;
7
7
  result: BaseResult;
8
8
  }
9
- declare function RefNameAutocomplete({ model, showHelp, onSelect, assemblyName, style, fetchResults, value, minWidth, TextFieldProps, }: {
9
+ declare function RefNameAutocomplete({ model, onSelect, assemblyName, style, fetchResults, onChange, value, showHelp, minWidth, TextFieldProps, }: {
10
10
  model: LinearGenomeViewModel;
11
- onSelect: (region: BaseResult) => void;
11
+ onSelect?: (region: BaseResult) => void;
12
+ onChange?: (val: string) => void;
12
13
  assemblyName?: string;
13
14
  value?: string;
14
15
  fetchResults: (query: string) => Promise<BaseResult[]>;
@@ -80,13 +80,14 @@ var MyPopper = function MyPopper(props) {
80
80
 
81
81
  function RefNameAutocomplete(_ref) {
82
82
  var model = _ref.model,
83
- _ref$showHelp = _ref.showHelp,
84
- showHelp = _ref$showHelp === void 0 ? true : _ref$showHelp,
85
83
  onSelect = _ref.onSelect,
86
84
  assemblyName = _ref.assemblyName,
87
85
  style = _ref.style,
88
86
  fetchResults = _ref.fetchResults,
87
+ onChange = _ref.onChange,
89
88
  value = _ref.value,
89
+ _ref$showHelp = _ref.showHelp,
90
+ showHelp = _ref$showHelp === void 0 ? true : _ref$showHelp,
90
91
  _ref$minWidth = _ref.minWidth,
91
92
  minWidth = _ref$minWidth === void 0 ? 200 : _ref$minWidth,
92
93
  _ref$TextFieldProps = _ref.TextFieldProps,
@@ -223,7 +224,8 @@ function RefNameAutocomplete(_ref) {
223
224
  loading: !loaded,
224
225
  inputValue: inputValue,
225
226
  onInputChange: function onInputChange(event, newInputValue) {
226
- return setInputValue(newInputValue);
227
+ setInputValue(newInputValue);
228
+ onChange === null || onChange === void 0 ? void 0 : onChange(newInputValue);
227
229
  },
228
230
  loadingText: "loading results",
229
231
  open: open,
@@ -246,11 +248,11 @@ function RefNameAutocomplete(_ref) {
246
248
 
247
249
  if (typeof selectedOption === 'string') {
248
250
  // handles string inputs on keyPress enter
249
- onSelect(new _BaseResults.default({
251
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(new _BaseResults.default({
250
252
  label: selectedOption
251
253
  }));
252
254
  } else {
253
- onSelect(selectedOption.result);
255
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedOption.result);
254
256
  }
255
257
 
256
258
  setInputValue(inputBoxVal);
@@ -130,7 +130,7 @@ declare const _default: React.ForwardRefExoticComponent<{
130
130
  moveTrack(movingTrackId: string, targetTrackId: string): void;
131
131
  closeView(): void;
132
132
  toggleTrack(trackId: string): void;
133
- setTrackLabels(setting: "overlapping" | "offset" | "hidden"): void;
133
+ setTrackLabels(setting: "offset" | "hidden" | "overlapping"): void;
134
134
  toggleCenterLine(): void;
135
135
  setDisplayedRegions(regions: import("@jbrowse/core/util").Region[]): void;
136
136
  activateTrackSelector(): import("@jbrowse/core/util").Widget;
@@ -327,7 +327,7 @@ declare const _default: React.ForwardRefExoticComponent<{
327
327
  moveTrack(movingTrackId: string, targetTrackId: string): void;
328
328
  closeView(): void;
329
329
  toggleTrack(trackId: string): void;
330
- setTrackLabels(setting: "overlapping" | "offset" | "hidden"): void;
330
+ setTrackLabels(setting: "offset" | "hidden" | "overlapping"): void;
331
331
  toggleCenterLine(): void;
332
332
  setDisplayedRegions(regions: import("@jbrowse/core/util").Region[]): void;
333
333
  activateTrackSelector(): import("@jbrowse/core/util").Widget;
@@ -9,6 +9,8 @@ exports.default = void 0;
9
9
 
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
11
 
12
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
+
12
14
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
15
 
14
16
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
@@ -54,7 +56,12 @@ function SearchBox(_ref) {
54
56
 
55
57
  function fetchResults(_x, _x2) {
56
58
  return _fetchResults.apply(this, arguments);
57
- }
59
+ } // gets a string as input, or use stored option results from previous query,
60
+ // then re-query and
61
+ // 1) if it has multiple results: pop a dialog
62
+ // 2) if it's a single result navigate to it
63
+ // 3) else assume it's a locstring and navigate to it
64
+
58
65
 
59
66
  function _fetchResults() {
60
67
  _fetchResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(query, searchType) {
@@ -104,7 +111,7 @@ function SearchBox(_ref) {
104
111
 
105
112
  function _handleSelectedRegion() {
106
113
  _handleSelectedRegion = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(option) {
107
- var trackId, location, label, _assembly$allRefNames2, results;
114
+ var trackId, location, label, _location$split, _location$split2, ref, rest, allRefs, results;
108
115
 
109
116
  return _regenerator.default.wrap(function _callee2$(_context2) {
110
117
  while (1) {
@@ -113,61 +120,63 @@ function SearchBox(_ref) {
113
120
  trackId = option.getTrackId();
114
121
  location = option.getLocation();
115
122
  label = option.getLabel();
116
- _context2.prev = 3;
123
+ _location$split = location.split(':'), _location$split2 = (0, _slicedToArray2.default)(_location$split, 2), ref = _location$split2[0], rest = _location$split2[1];
124
+ allRefs = (assembly === null || assembly === void 0 ? void 0 : assembly.allRefNames) || [];
125
+ _context2.prev = 5;
117
126
 
118
- if (!(assembly !== null && assembly !== void 0 && (_assembly$allRefNames2 = assembly.allRefNames) !== null && _assembly$allRefNames2 !== void 0 && _assembly$allRefNames2.includes(location))) {
119
- _context2.next = 8;
127
+ if (!(allRefs.includes(location) || allRefs.includes(ref) && rest !== undefined && !Number.isNaN(parseInt(rest, 10)))) {
128
+ _context2.next = 10;
120
129
  break;
121
130
  }
122
131
 
123
- model.navToLocString(location);
124
- _context2.next = 19;
132
+ model.navToLocString(location, assemblyName);
133
+ _context2.next = 21;
125
134
  break;
126
135
 
127
- case 8:
128
- _context2.next = 10;
136
+ case 10:
137
+ _context2.next = 12;
129
138
  return fetchResults(label, 'exact');
130
139
 
131
- case 10:
140
+ case 12:
132
141
  results = _context2.sent;
133
142
 
134
- if (!(results && results.length > 1)) {
135
- _context2.next = 16;
143
+ if (!(results.length > 1)) {
144
+ _context2.next = 18;
136
145
  break;
137
146
  }
138
147
 
139
148
  model.setSearchResults(results, label.toLowerCase());
140
149
  return _context2.abrupt("return");
141
150
 
142
- case 16:
143
- if ((results === null || results === void 0 ? void 0 : results.length) === 1) {
151
+ case 18:
152
+ if (results.length === 1) {
144
153
  location = results[0].getLocation();
145
154
  trackId = results[0].getTrackId();
146
155
  }
147
156
 
148
- case 17:
157
+ case 19:
149
158
  model.navToLocString(location, assemblyName);
150
159
 
151
160
  if (trackId) {
152
161
  model.showTrack(trackId);
153
162
  }
154
163
 
155
- case 19:
156
- _context2.next = 25;
164
+ case 21:
165
+ _context2.next = 27;
157
166
  break;
158
167
 
159
- case 21:
160
- _context2.prev = 21;
161
- _context2.t0 = _context2["catch"](3);
168
+ case 23:
169
+ _context2.prev = 23;
170
+ _context2.t0 = _context2["catch"](5);
162
171
  console.error(_context2.t0);
163
172
  session.notify("".concat(_context2.t0), 'warning');
164
173
 
165
- case 25:
174
+ case 27:
166
175
  case "end":
167
176
  return _context2.stop();
168
177
  }
169
178
  }
170
- }, _callee2, null, [[3, 21]]);
179
+ }, _callee2, null, [[5, 23]]);
171
180
  }));
172
181
  return _handleSelectedRegion.apply(this, arguments);
173
182
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-linear-genome-view",
3
- "version": "1.7.7",
3
+ "version": "1.7.8",
4
4
  "description": "JBrowse 2 linear genome view",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -57,5 +57,5 @@
57
57
  "publishConfig": {
58
58
  "access": "public"
59
59
  },
60
- "gitHead": "2c26e04ae942c380bf2f5b79ef7a49cc32b7bfed"
60
+ "gitHead": "b429fa2bb5734fc8a5380988f6dfdd3f7a41a39f"
61
61
  }
@@ -37,13 +37,9 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
37
37
  const classes = useStyles()
38
38
  const session = getSession(model)
39
39
  const { assemblyNames, assemblyManager, textSearchManager } = session
40
- const {
41
- rankSearchResults,
42
- isSearchDialogDisplayed,
43
- error: modelError,
44
- } = model
40
+ const { rankSearchResults, isSearchDialogDisplayed, error } = model
45
41
  const [selectedAsm, setSelectedAsm] = useState(assemblyNames[0])
46
- const [error, setError] = useState<typeof modelError | undefined>(modelError)
42
+ const [importError, setImportError] = useState(error)
47
43
  const searchScope = model.searchScope(selectedAsm)
48
44
 
49
45
  const assembly = assemblyManager.get(selectedAsm)
@@ -51,19 +47,15 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
51
47
  ? assembly?.error
52
48
  : 'No configured assemblies'
53
49
  const regions = assembly?.regions || []
54
- const err = assemblyError || error
55
-
56
- const [myOption, setOption] = useState<BaseResult>()
50
+ const err = assemblyError || importError
51
+ const [myVal, setValue] = useState('')
52
+ const value = myVal || regions[0]?.refName
57
53
 
58
54
  // use this instead of useState initializer because the useState initializer
59
55
  // won't update in response to an observable
60
- const option =
61
- myOption ||
62
- new BaseResult({
63
- label: regions[0]?.refName,
64
- })
65
-
66
- const selectedRegion = option?.getLocation()
56
+ const option = new BaseResult({
57
+ label: value,
58
+ })
67
59
 
68
60
  async function fetchResults(query: string, searchType?: SearchType) {
69
61
  if (!textSearchManager) {
@@ -98,15 +90,26 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
98
90
  }
99
91
  let trackId = option.getTrackId()
100
92
  let location = input || option.getLocation() || ''
93
+ const [ref, rest] = location.split(':')
94
+ const allRefs = assembly?.allRefNames || []
101
95
  try {
102
- if (assembly?.allRefNames?.includes(location)) {
96
+ // instead of querying text-index, first:
97
+ // - check if input matches a refname directly
98
+ // - or looks like locstring
99
+ // then just navigate as if it were a locstring
100
+ if (
101
+ allRefs.includes(location) ||
102
+ (allRefs.includes(ref) &&
103
+ rest !== undefined &&
104
+ !Number.isNaN(parseInt(rest, 10)))
105
+ ) {
103
106
  model.navToLocString(location, selectedAsm)
104
107
  } else {
105
108
  const results = await fetchResults(input, 'exact')
106
- if (results && results.length > 1) {
109
+ if (results.length > 1) {
107
110
  model.setSearchResults(results, input.toLowerCase())
108
111
  return
109
- } else if (results?.length === 1) {
112
+ } else if (results.length === 1) {
110
113
  location = results[0].getLocation()
111
114
  trackId = results[0].getTrackId()
112
115
  }
@@ -130,7 +133,15 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
130
133
  <div className={classes.container}>
131
134
  {err ? <ErrorMessage error={err} /> : null}
132
135
  <Container className={classes.importFormContainer}>
133
- <form onSubmit={event => event.preventDefault()}>
136
+ <form
137
+ onSubmit={event => {
138
+ event.preventDefault()
139
+ model.setError(undefined)
140
+ if (value) {
141
+ handleSelectedRegion(value)
142
+ }
143
+ }}
144
+ >
134
145
  <Grid
135
146
  container
136
147
  spacing={1}
@@ -140,7 +151,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
140
151
  <Grid item>
141
152
  <AssemblySelector
142
153
  onChange={val => {
143
- setError(undefined)
154
+ setImportError('')
144
155
  setSelectedAsm(val)
145
156
  }}
146
157
  session={session}
@@ -152,15 +163,15 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
152
163
  {selectedAsm ? (
153
164
  err ? (
154
165
  <CloseIcon style={{ color: 'red' }} />
155
- ) : selectedRegion ? (
166
+ ) : value ? (
156
167
  <RefNameAutocomplete
157
168
  fetchResults={fetchResults}
158
169
  model={model}
159
170
  assemblyName={assemblyError ? undefined : selectedAsm}
160
- value={selectedRegion}
171
+ value={value}
161
172
  // note: minWidth 270 accomodates full width of helperText
162
173
  minWidth={270}
163
- onSelect={option => setOption(option)}
174
+ onChange={str => setValue(str)}
164
175
  TextFieldProps={{
165
176
  variant: 'outlined',
166
177
  helperText:
@@ -181,21 +192,15 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
181
192
  <Grid item>
182
193
  <Button
183
194
  type="submit"
184
- disabled={!selectedRegion}
195
+ disabled={!value}
185
196
  className={classes.button}
186
- onClick={() => {
187
- model.setError(undefined)
188
- if (selectedRegion) {
189
- handleSelectedRegion(selectedRegion)
190
- }
191
- }}
192
197
  variant="contained"
193
198
  color="primary"
194
199
  >
195
200
  Open
196
201
  </Button>
197
202
  <Button
198
- disabled={!selectedRegion}
203
+ disabled={!value}
199
204
  className={classes.button}
200
205
  onClick={() => {
201
206
  model.setError(undefined)
@@ -66,17 +66,19 @@ const MyPopper = function (
66
66
 
67
67
  function RefNameAutocomplete({
68
68
  model,
69
- showHelp = true,
70
69
  onSelect,
71
70
  assemblyName,
72
71
  style,
73
72
  fetchResults,
73
+ onChange,
74
74
  value,
75
+ showHelp = true,
75
76
  minWidth = 200,
76
77
  TextFieldProps = {},
77
78
  }: {
78
79
  model: LinearGenomeViewModel
79
- onSelect: (region: BaseResult) => void
80
+ onSelect?: (region: BaseResult) => void
81
+ onChange?: (val: string) => void
80
82
  assemblyName?: string
81
83
  value?: string
82
84
  fetchResults: (query: string) => Promise<BaseResult[]>
@@ -171,7 +173,10 @@ function RefNameAutocomplete({
171
173
  value={inputBoxVal}
172
174
  loading={!loaded}
173
175
  inputValue={inputValue}
174
- onInputChange={(event, newInputValue) => setInputValue(newInputValue)}
176
+ onInputChange={(event, newInputValue) => {
177
+ setInputValue(newInputValue)
178
+ onChange?.(newInputValue)
179
+ }}
175
180
  loadingText="loading results"
176
181
  open={open}
177
182
  onOpen={() => setOpen(true)}
@@ -190,9 +195,9 @@ function RefNameAutocomplete({
190
195
 
191
196
  if (typeof selectedOption === 'string') {
192
197
  // handles string inputs on keyPress enter
193
- onSelect(new BaseResult({ label: selectedOption }))
198
+ onSelect?.(new BaseResult({ label: selectedOption }))
194
199
  } else {
195
- onSelect(selectedOption.result)
200
+ onSelect?.(selectedOption.result)
196
201
  }
197
202
  setInputValue(inputBoxVal)
198
203
  }}
@@ -58,19 +58,35 @@ function SearchBox({
58
58
  )
59
59
  }
60
60
 
61
+ // gets a string as input, or use stored option results from previous query,
62
+ // then re-query and
63
+ // 1) if it has multiple results: pop a dialog
64
+ // 2) if it's a single result navigate to it
65
+ // 3) else assume it's a locstring and navigate to it
61
66
  async function handleSelectedRegion(option: BaseResult) {
62
67
  let trackId = option.getTrackId()
63
68
  let location = option.getLocation()
64
69
  const label = option.getLabel()
70
+ const [ref, rest] = location.split(':')
71
+ const allRefs = assembly?.allRefNames || []
65
72
  try {
66
- if (assembly?.allRefNames?.includes(location)) {
67
- model.navToLocString(location)
73
+ // instead of querying text-index, first:
74
+ // - check if input matches a refName directly
75
+ // - or looks like locString
76
+ // then just navigate as if it were a locString
77
+ if (
78
+ allRefs.includes(location) ||
79
+ (allRefs.includes(ref) &&
80
+ rest !== undefined &&
81
+ !Number.isNaN(parseInt(rest, 10)))
82
+ ) {
83
+ model.navToLocString(location, assemblyName)
68
84
  } else {
69
85
  const results = await fetchResults(label, 'exact')
70
- if (results && results.length > 1) {
86
+ if (results.length > 1) {
71
87
  model.setSearchResults(results, label.toLowerCase())
72
88
  return
73
- } else if (results?.length === 1) {
89
+ } else if (results.length === 1) {
74
90
  location = results[0].getLocation()
75
91
  trackId = results[0].getTrackId()
76
92
  }