@jbrowse/plugin-linear-genome-view 1.7.5 → 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.
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +0 -2
- package/dist/LinearGenomeView/components/ImportForm.js +47 -47
- package/dist/LinearGenomeView/components/RefNameAutocomplete.d.ts +3 -2
- package/dist/LinearGenomeView/components/RefNameAutocomplete.js +7 -5
- package/dist/LinearGenomeView/components/SearchBox.js +31 -22
- package/package.json +2 -2
- package/src/LinearGenomeView/components/ImportForm.tsx +37 -32
- package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +10 -5
- package/src/LinearGenomeView/components/SearchBox.tsx +20 -4
|
@@ -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
|
-
|
|
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)(
|
|
80
|
+
var _useState3 = (0, _react.useState)(error),
|
|
81
81
|
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
82
|
-
|
|
83
|
-
|
|
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 ||
|
|
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
|
-
|
|
94
|
-
|
|
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 =
|
|
99
|
-
label:
|
|
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,
|
|
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
|
-
|
|
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 (!(
|
|
177
|
-
_context2.next =
|
|
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 =
|
|
184
|
+
_context2.next = 22;
|
|
183
185
|
break;
|
|
184
186
|
|
|
185
|
-
case
|
|
186
|
-
_context2.next =
|
|
187
|
+
case 11:
|
|
188
|
+
_context2.next = 13;
|
|
187
189
|
return fetchResults(input, 'exact');
|
|
188
190
|
|
|
189
|
-
case
|
|
191
|
+
case 13:
|
|
190
192
|
results = _context2.sent;
|
|
191
193
|
|
|
192
|
-
if (!(results
|
|
193
|
-
_context2.next =
|
|
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
|
|
201
|
-
if (
|
|
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
|
|
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
|
|
214
|
-
_context2.next =
|
|
215
|
+
case 22:
|
|
216
|
+
_context2.next = 28;
|
|
215
217
|
break;
|
|
216
218
|
|
|
217
|
-
case
|
|
218
|
-
_context2.prev =
|
|
219
|
-
_context2.t0 = _context2["catch"](
|
|
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
|
|
225
|
+
case 28:
|
|
224
226
|
case "end":
|
|
225
227
|
return _context2.stop();
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
|
-
}, _callee2, null, [[
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
}) :
|
|
278
|
+
}) : value ? /*#__PURE__*/_react.default.createElement(_RefNameAutocomplete.default, {
|
|
272
279
|
fetchResults: fetchResults,
|
|
273
280
|
model: model,
|
|
274
281
|
assemblyName: assemblyError ? undefined : selectedAsm,
|
|
275
|
-
value:
|
|
282
|
+
value: value // note: minWidth 270 accomodates full width of helperText
|
|
276
283
|
,
|
|
277
284
|
minWidth: 270,
|
|
278
|
-
|
|
279
|
-
return
|
|
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: !
|
|
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: !
|
|
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,
|
|
9
|
+
declare function RefNameAutocomplete({ model, onSelect, assemblyName, style, fetchResults, onChange, value, showHelp, minWidth, TextFieldProps, }: {
|
|
10
10
|
model: LinearGenomeViewModel;
|
|
11
|
-
onSelect
|
|
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
|
-
|
|
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);
|
|
@@ -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,
|
|
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
|
-
|
|
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 (!(
|
|
119
|
-
_context2.next =
|
|
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 =
|
|
132
|
+
model.navToLocString(location, assemblyName);
|
|
133
|
+
_context2.next = 21;
|
|
125
134
|
break;
|
|
126
135
|
|
|
127
|
-
case
|
|
128
|
-
_context2.next =
|
|
136
|
+
case 10:
|
|
137
|
+
_context2.next = 12;
|
|
129
138
|
return fetchResults(label, 'exact');
|
|
130
139
|
|
|
131
|
-
case
|
|
140
|
+
case 12:
|
|
132
141
|
results = _context2.sent;
|
|
133
142
|
|
|
134
|
-
if (!(results
|
|
135
|
-
_context2.next =
|
|
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
|
|
143
|
-
if (
|
|
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
|
|
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
|
|
156
|
-
_context2.next =
|
|
164
|
+
case 21:
|
|
165
|
+
_context2.next = 27;
|
|
157
166
|
break;
|
|
158
167
|
|
|
159
|
-
case
|
|
160
|
-
_context2.prev =
|
|
161
|
-
_context2.t0 = _context2["catch"](
|
|
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
|
|
174
|
+
case 27:
|
|
166
175
|
case "end":
|
|
167
176
|
return _context2.stop();
|
|
168
177
|
}
|
|
169
178
|
}
|
|
170
|
-
}, _callee2, null, [[
|
|
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.
|
|
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": "
|
|
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 [
|
|
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 ||
|
|
55
|
-
|
|
56
|
-
const
|
|
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
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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
|
|
109
|
+
if (results.length > 1) {
|
|
107
110
|
model.setSearchResults(results, input.toLowerCase())
|
|
108
111
|
return
|
|
109
|
-
} else if (results
|
|
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
|
|
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
|
-
|
|
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
|
-
) :
|
|
166
|
+
) : value ? (
|
|
156
167
|
<RefNameAutocomplete
|
|
157
168
|
fetchResults={fetchResults}
|
|
158
169
|
model={model}
|
|
159
170
|
assemblyName={assemblyError ? undefined : selectedAsm}
|
|
160
|
-
value={
|
|
171
|
+
value={value}
|
|
161
172
|
// note: minWidth 270 accomodates full width of helperText
|
|
162
173
|
minWidth={270}
|
|
163
|
-
|
|
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={!
|
|
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={!
|
|
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
|
|
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) =>
|
|
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
|
-
|
|
67
|
-
|
|
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
|
|
86
|
+
if (results.length > 1) {
|
|
71
87
|
model.setSearchResults(results, label.toLowerCase())
|
|
72
88
|
return
|
|
73
|
-
} else if (results
|
|
89
|
+
} else if (results.length === 1) {
|
|
74
90
|
location = results[0].getLocation()
|
|
75
91
|
trackId = results[0].getTrackId()
|
|
76
92
|
}
|