@jbrowse/core 1.7.7 → 1.7.10

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.
Files changed (53) hide show
  1. package/BaseFeatureWidget/BaseFeatureDetail.d.ts +3 -6
  2. package/BaseFeatureWidget/BaseFeatureDetail.js +158 -103
  3. package/BaseFeatureWidget/index.d.ts +23 -2
  4. package/BaseFeatureWidget/index.js +98 -3
  5. package/assemblyManager/assemblyManager.d.ts +1 -1
  6. package/assemblyManager/assemblyManager.js +21 -27
  7. package/package.json +6 -2
  8. package/pluggableElementTypes/models/InternetAccountModel.d.ts +2 -2
  9. package/pluggableElementTypes/models/baseTrackConfig.js +20 -13
  10. package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +6 -14
  11. package/pluggableElementTypes/renderers/ServerSideRendererType.d.ts +6 -0
  12. package/pluggableElementTypes/renderers/ServerSideRendererType.js +44 -2
  13. package/pluggableElementTypes/renderers/declare.d.js +1 -0
  14. package/tsconfig.build.tsbuildinfo +1 -1
  15. package/ui/AboutDialog.d.ts +1 -1
  16. package/ui/AboutDialog.js +24 -7
  17. package/ui/CascadingMenu.d.ts +9 -0
  18. package/ui/CascadingMenu.js +211 -0
  19. package/ui/Menu.d.ts +10 -0
  20. package/ui/Menu.js +9 -14
  21. package/ui/SanitizedHTML.js +26 -4
  22. package/ui/SnackbarModel.d.ts +2 -2
  23. package/ui/index.d.ts +1 -0
  24. package/ui/index.js +9 -0
  25. package/util/declare.d.js +1 -0
  26. package/util/index.d.ts +3 -0
  27. package/util/index.js +35 -1
  28. package/util/jexl.js +42 -43
  29. package/util/offscreenCanvasPonyfill.d.ts +8 -1
  30. package/util/offscreenCanvasPonyfill.js +140 -12
  31. package/util/offscreenCanvasUtils.d.ts +19 -1
  32. package/util/offscreenCanvasUtils.js +146 -12
  33. package/util/types/index.d.ts +1 -1
  34. package/util/types/mst.d.ts +9 -9
  35. package/util/offscreenCanvas/Canvas2DContextShim/Canvas2DContextShim.test.js +0 -15
  36. package/util/offscreenCanvas/Canvas2DContextShim/context.d.ts +0 -56
  37. package/util/offscreenCanvas/Canvas2DContextShim/context.js +0 -356
  38. package/util/offscreenCanvas/Canvas2DContextShim/index.d.ts +0 -2
  39. package/util/offscreenCanvas/Canvas2DContextShim/index.js +0 -13
  40. package/util/offscreenCanvas/Canvas2DContextShim/svg.d.ts +0 -3
  41. package/util/offscreenCanvas/Canvas2DContextShim/svg.js +0 -210
  42. package/util/offscreenCanvas/Canvas2DContextShim/types.d.ts +0 -50
  43. package/util/offscreenCanvas/Canvas2DContextShim/types.js +0 -59
  44. package/util/offscreenCanvas/Canvas2DContextShim/util.d.ts +0 -12
  45. package/util/offscreenCanvas/Canvas2DContextShim/util.js +0 -91
  46. package/util/offscreenCanvas/CanvasShim.d.ts +0 -11
  47. package/util/offscreenCanvas/CanvasShim.js +0 -54
  48. package/util/offscreenCanvas/index.d.ts +0 -14
  49. package/util/offscreenCanvas/index.js +0 -170
  50. package/util/offscreenCanvas/ponyfill.d.ts +0 -6
  51. package/util/offscreenCanvas/ponyfill.js +0 -145
  52. package/util/offscreenCanvas/types.d.ts +0 -16
  53. package/util/offscreenCanvas/types.js +0 -14
@@ -4,7 +4,7 @@ import { BaseCardProps, BaseProps } from './types';
4
4
  import { SimpleFeatureSerialized } from '../util/simpleFeature';
5
5
  export declare const useStyles: (props?: any) => import("@material-ui/styles").ClassNameMap<"expandIcon" | "expansionPanelDetails" | "field" | "fieldDescription" | "fieldName" | "fieldValue" | "fieldSubvalue">;
6
6
  export declare function BaseCard({ children, title, defaultExpanded, }: BaseCardProps): JSX.Element;
7
- export declare const FieldName: ({ description, name, prefix, width, }: {
7
+ export declare const FieldName: ({ description, name, width, prefix, }: {
8
8
  description?: React.ReactNode;
9
9
  name: string;
10
10
  prefix?: string[] | undefined;
@@ -28,7 +28,7 @@ interface AttributeProps {
28
28
  descriptions?: Record<string, React.ReactNode>;
29
29
  prefix?: string[];
30
30
  }
31
- export declare const Attributes: React.FunctionComponent<AttributeProps>;
31
+ export declare function Attributes(props: AttributeProps): JSX.Element;
32
32
  export declare const BaseAttributes: (props: BaseProps) => JSX.Element;
33
33
  export interface BaseInputProps extends BaseCardProps {
34
34
  omit?: string[];
@@ -38,10 +38,7 @@ export interface BaseInputProps extends BaseCardProps {
38
38
  }
39
39
  export declare const FeatureDetails: (props: {
40
40
  model: IAnyStateTreeNode;
41
- feature: SimpleFeatureSerialized & {
42
- name?: string;
43
- id?: string;
44
- };
41
+ feature: SimpleFeatureSerialized;
45
42
  depth?: number | undefined;
46
43
  omit?: string[] | undefined;
47
44
  formatter?: ((val: unknown, key: string) => React.ReactElement) | undefined;
@@ -7,7 +7,8 @@ var _typeof = require("@babel/runtime/helpers/typeof");
7
7
  Object.defineProperty(exports, "__esModule", {
8
8
  value: true
9
9
  });
10
- exports.BaseAttributes = exports.Attributes = void 0;
10
+ exports.Attributes = Attributes;
11
+ exports.BaseAttributes = void 0;
11
12
  exports.BaseCard = BaseCard;
12
13
  exports.useStyles = exports.default = exports.SimpleValue = exports.FieldName = exports.FeatureDetails = exports.BasicValue = exports.BaseCoreDetails = void 0;
13
14
 
@@ -47,7 +48,8 @@ var _SequenceFeatureDetails = _interopRequireDefault(require("./SequenceFeatureD
47
48
 
48
49
  var _util2 = require("./util");
49
50
 
50
- var _excluded = ["id"];
51
+ var _excluded = ["id"],
52
+ _excluded2 = ["__jbrowsefmt"];
51
53
 
52
54
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
53
55
 
@@ -59,7 +61,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
59
61
 
60
62
  var MAX_FIELD_NAME_WIDTH = 170; // these are always omitted as too detailed
61
63
 
62
- var globalOmit = ['length', 'position', 'subfeatures', 'uniqueId', 'exonFrames', 'parentId', 'thickStart', 'thickEnd']; // coreDetails are omitted in some circumstances
64
+ var globalOmit = ['__jbrowsefmt', 'length', 'position', 'subfeatures', 'uniqueId', 'exonFrames', 'parentId', 'thickStart', 'thickEnd']; // coreDetails are omitted in some circumstances
63
65
 
64
66
  var coreDetails = ['name', 'start', 'end', 'strand', 'refName', 'description', 'type'];
65
67
  var useStyles = (0, _core.makeStyles)(function (theme) {
@@ -143,9 +145,9 @@ function BaseCard(_ref) {
143
145
  var FieldName = function FieldName(_ref2) {
144
146
  var description = _ref2.description,
145
147
  name = _ref2.name,
148
+ width = _ref2.width,
146
149
  _ref2$prefix = _ref2.prefix,
147
- prefix = _ref2$prefix === void 0 ? [] : _ref2$prefix,
148
- width = _ref2.width;
150
+ prefix = _ref2$prefix === void 0 ? [] : _ref2$prefix;
149
151
  var classes = useStyles();
150
152
  var val = [].concat((0, _toConsumableArray2.default)(prefix), [name]).join('.');
151
153
  return description ? /*#__PURE__*/_react.default.createElement(_core.Tooltip, {
@@ -166,9 +168,12 @@ exports.FieldName = FieldName;
166
168
  var BasicValue = function BasicValue(_ref3) {
167
169
  var value = _ref3.value;
168
170
  var classes = useStyles();
171
+ var isLink = "".concat(value).match(/^https?:\/\//);
169
172
  return /*#__PURE__*/_react.default.createElement("div", {
170
173
  className: classes.fieldValue
171
- }, /*#__PURE__*/_react.default.isValidElement(value) ? value : /*#__PURE__*/_react.default.createElement(_SanitizedHTML.default, {
174
+ }, /*#__PURE__*/_react.default.isValidElement(value) ? value : isLink ? /*#__PURE__*/_react.default.createElement(_SanitizedHTML.default, {
175
+ html: "<a href=\"".concat(value, "\">").concat(value, "</a>")
176
+ }) : /*#__PURE__*/_react.default.createElement(_SanitizedHTML.default, {
172
177
  html: (0, _isObject.default)(value) ? JSON.stringify(value) : String(value)
173
178
  }));
174
179
  };
@@ -203,75 +208,86 @@ var ArrayValue = function ArrayValue(_ref5) {
203
208
  _ref5$prefix = _ref5.prefix,
204
209
  prefix = _ref5$prefix === void 0 ? [] : _ref5$prefix;
205
210
  var classes = useStyles();
206
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, value.length === 1 ? (0, _isObject.default)(value[0]) ? /*#__PURE__*/_react.default.createElement(Attributes, {
207
- attributes: value[0],
208
- prefix: [].concat((0, _toConsumableArray2.default)(prefix), [name])
209
- }) : /*#__PURE__*/_react.default.createElement("div", {
210
- className: classes.field
211
- }, /*#__PURE__*/_react.default.createElement(FieldName, {
212
- prefix: prefix,
213
- description: description,
214
- name: name
215
- }), /*#__PURE__*/_react.default.createElement(BasicValue, {
216
- value: value[0]
217
- })) : value.every(function (val) {
211
+
212
+ if (value.length === 1) {
213
+ return (0, _isObject.default)(value[0]) ? /*#__PURE__*/_react.default.createElement(Attributes, {
214
+ attributes: value[0],
215
+ prefix: [].concat((0, _toConsumableArray2.default)(prefix), [name])
216
+ }) : /*#__PURE__*/_react.default.createElement("div", {
217
+ className: classes.field
218
+ }, /*#__PURE__*/_react.default.createElement(FieldName, {
219
+ prefix: prefix,
220
+ description: description,
221
+ name: name
222
+ }), /*#__PURE__*/_react.default.createElement(BasicValue, {
223
+ value: value[0]
224
+ }));
225
+ } else if (value.every(function (val) {
218
226
  return (0, _isObject.default)(val);
219
- }) ? value.map(function (val, i) {
220
- return /*#__PURE__*/_react.default.createElement(Attributes, {
221
- key: JSON.stringify(val) + '-' + i,
222
- attributes: val,
223
- prefix: [].concat((0, _toConsumableArray2.default)(prefix), [name + '-' + i])
224
- });
225
- }) : /*#__PURE__*/_react.default.createElement("div", {
226
- className: classes.field
227
- }, /*#__PURE__*/_react.default.createElement(FieldName, {
228
- prefix: prefix,
229
- description: description,
230
- name: name
231
- }), value.map(function (val, i) {
227
+ })) {
228
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, value.map(function (val, i) {
229
+ return /*#__PURE__*/_react.default.createElement(Attributes, {
230
+ key: JSON.stringify(val) + '-' + i,
231
+ attributes: val,
232
+ prefix: [].concat((0, _toConsumableArray2.default)(prefix), [name + '-' + i])
233
+ });
234
+ }));
235
+ } else {
232
236
  return /*#__PURE__*/_react.default.createElement("div", {
233
- key: JSON.stringify(val) + '-' + i,
234
- className: classes.fieldSubvalue
235
- }, /*#__PURE__*/_react.default.createElement(BasicValue, {
236
- value: val
237
+ className: classes.field
238
+ }, /*#__PURE__*/_react.default.createElement(FieldName, {
239
+ prefix: prefix,
240
+ description: description,
241
+ name: name
242
+ }), value.map(function (val, i) {
243
+ return /*#__PURE__*/_react.default.createElement("div", {
244
+ key: JSON.stringify(val) + '-' + i,
245
+ className: classes.fieldSubvalue
246
+ }, /*#__PURE__*/_react.default.createElement(BasicValue, {
247
+ value: val
248
+ }));
237
249
  }));
238
- })));
250
+ }
251
+ };
252
+
253
+ var toLocale = function toLocale(n) {
254
+ return n.toLocaleString('en-US');
239
255
  };
240
256
 
241
257
  function CoreDetails(props) {
242
258
  var feature = props.feature;
243
- var _ref6 = feature,
244
- refName = _ref6.refName,
245
- start = _ref6.start,
246
- end = _ref6.end,
247
- strand = _ref6.strand;
259
+ var obj = feature; // eslint-disable-next-line no-underscore-dangle
260
+
261
+ var formattedFeat = _objectSpread(_objectSpread({}, obj), obj.__jbrowsefmt);
262
+
263
+ var start = formattedFeat.start,
264
+ strand = formattedFeat.strand,
265
+ end = formattedFeat.end,
266
+ refName = formattedFeat.refName;
248
267
  var strandMap = {
249
268
  '-1': '-',
250
269
  '0': '',
251
270
  '1': '+'
252
271
  };
253
- var strandStr = strandMap[strand] ? "(".concat(strandMap[strand], ")") : '';
254
- var displayStart = (start + 1).toLocaleString('en-US');
255
- var displayEnd = end.toLocaleString('en-US');
256
- var displayRef = refName ? "".concat(refName, ":") : '';
257
-
258
- var displayedDetails = _objectSpread(_objectSpread({}, feature), {}, {
259
- length: (end - start).toLocaleString('en-US'),
260
- position: "".concat(displayRef).concat(displayStart, "..").concat(displayEnd, " ").concat(strandStr)
272
+ var str = strandMap[strand] ? "(".concat(strandMap[strand], ")") : '';
273
+
274
+ var displayedDetails = _objectSpread(_objectSpread({}, formattedFeat), {}, {
275
+ length: toLocale(end - start),
276
+ position: "".concat(refName, ":").concat(toLocale(start + 1), "..").concat(toLocale(end), " ").concat(str)
261
277
  });
262
278
 
263
279
  var coreRenderedDetails = ['Position', 'Description', 'Name', 'Length', 'Type'];
264
280
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, coreRenderedDetails.map(function (key) {
265
281
  return [key, displayedDetails[key.toLowerCase()]];
266
- }).filter(function (_ref7) {
267
- var _ref8 = (0, _slicedToArray2.default)(_ref7, 2),
268
- value = _ref8[1];
282
+ }).filter(function (_ref6) {
283
+ var _ref7 = (0, _slicedToArray2.default)(_ref6, 2),
284
+ value = _ref7[1];
269
285
 
270
286
  return value !== null && value !== undefined;
271
- }).map(function (_ref9) {
272
- var _ref10 = (0, _slicedToArray2.default)(_ref9, 2),
273
- key = _ref10[0],
274
- value = _ref10[1];
287
+ }).map(function (_ref8) {
288
+ var _ref9 = (0, _slicedToArray2.default)(_ref8, 2),
289
+ key = _ref9[0],
290
+ value = _ref9[1];
275
291
 
276
292
  return /*#__PURE__*/_react.default.createElement(SimpleValue, {
277
293
  key: key,
@@ -289,10 +305,10 @@ var BaseCoreDetails = function BaseCoreDetails(props) {
289
305
 
290
306
  exports.BaseCoreDetails = BaseCoreDetails;
291
307
 
292
- var DataGridDetails = function DataGridDetails(_ref11) {
293
- var value = _ref11.value,
294
- prefix = _ref11.prefix,
295
- name = _ref11.name;
308
+ var DataGridDetails = function DataGridDetails(_ref10) {
309
+ var value = _ref10.value,
310
+ prefix = _ref10.prefix,
311
+ name = _ref10.name;
296
312
  var keys = Object.keys(value[0]).sort();
297
313
  var unionKeys = new Set(keys);
298
314
  value.forEach(function (val) {
@@ -303,10 +319,10 @@ var DataGridDetails = function DataGridDetails(_ref11) {
303
319
 
304
320
  if (unionKeys.size < keys.length + 5) {
305
321
  // avoids key 'id' from being used in row data
306
- var rows = Object.entries(value).map(function (_ref12) {
307
- var _ref13 = (0, _slicedToArray2.default)(_ref12, 2),
308
- k = _ref13[0],
309
- val = _ref13[1];
322
+ var rows = Object.entries(value).map(function (_ref11) {
323
+ var _ref12 = (0, _slicedToArray2.default)(_ref11, 2),
324
+ k = _ref12[0],
325
+ val = _ref12[1];
310
326
 
311
327
  var id = val.id,
312
328
  rest = (0, _objectWithoutProperties2.default)(val, _excluded);
@@ -331,8 +347,7 @@ var DataGridDetails = function DataGridDetails(_ref11) {
331
347
  return {
332
348
  field: val,
333
349
  width: Math.max.apply(Math, (0, _toConsumableArray2.default)(rows.map(function (row) {
334
- var result = String(row[val]);
335
- return Math.min(Math.max((0, _util.measureText)(result, 14) + 50, 80), 1000);
350
+ return Math.min(Math.max((0, _util.measureText)(String(row[val]), 14) + 50, 80), 1000);
336
351
  })))
337
352
  };
338
353
  }); // disableSelection on click helps avoid
@@ -386,7 +401,33 @@ function generateMaxWidth(array, prefix) {
386
401
  return Math.ceil(Math.max.apply(Math, arr)) + 10;
387
402
  }
388
403
 
389
- var Attributes = function Attributes(props) {
404
+ function UriAttribute(_ref13) {
405
+ var value = _ref13.value,
406
+ prefix = _ref13.prefix,
407
+ name = _ref13.name;
408
+ var classes = useStyles();
409
+ var uri = value.uri,
410
+ _value$baseUri = value.baseUri,
411
+ baseUri = _value$baseUri === void 0 ? '' : _value$baseUri;
412
+ var href;
413
+
414
+ try {
415
+ href = new URL(uri, baseUri).href;
416
+ } catch (e) {
417
+ href = uri;
418
+ }
419
+
420
+ return /*#__PURE__*/_react.default.createElement("div", {
421
+ className: classes.field
422
+ }, /*#__PURE__*/_react.default.createElement(FieldName, {
423
+ prefix: prefix,
424
+ name: name
425
+ }), /*#__PURE__*/_react.default.createElement(BasicValue, {
426
+ value: href
427
+ }));
428
+ }
429
+
430
+ function Attributes(props) {
390
431
  var attributes = props.attributes,
391
432
  _props$omit = props.omit,
392
433
  omit = _props$omit === void 0 ? [] : _props$omit,
@@ -398,7 +439,12 @@ var Attributes = function Attributes(props) {
398
439
  _props$prefix = props.prefix,
399
440
  prefix = _props$prefix === void 0 ? [] : _props$prefix;
400
441
  var omits = [].concat((0, _toConsumableArray2.default)(omit), globalOmit);
401
- var maxLabelWidth = generateMaxWidth(Object.entries(attributes).filter(function (_ref14) {
442
+ var __jbrowsefmt = attributes.__jbrowsefmt,
443
+ rest = (0, _objectWithoutProperties2.default)(attributes, _excluded2);
444
+
445
+ var formattedAttributes = _objectSpread(_objectSpread({}, rest), __jbrowsefmt);
446
+
447
+ var maxLabelWidth = generateMaxWidth(Object.entries(formattedAttributes).filter(function (_ref14) {
402
448
  var _ref15 = (0, _slicedToArray2.default)(_ref14, 2),
403
449
  k = _ref15[0],
404
450
  v = _ref15[1];
@@ -406,7 +452,7 @@ var Attributes = function Attributes(props) {
406
452
  return v !== undefined && !omits.includes(k);
407
453
  }), prefix);
408
454
  var labelWidth = maxLabelWidth <= MAX_FIELD_NAME_WIDTH ? maxLabelWidth : MAX_FIELD_NAME_WIDTH;
409
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, Object.entries(attributes).filter(function (_ref16) {
455
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, Object.entries(formattedAttributes).filter(function (_ref16) {
410
456
  var _ref17 = (0, _slicedToArray2.default)(_ref16, 2),
411
457
  k = _ref17[0],
412
458
  v = _ref17[1];
@@ -417,51 +463,50 @@ var Attributes = function Attributes(props) {
417
463
  key = _ref19[0],
418
464
  value = _ref19[1];
419
465
 
420
- if (Array.isArray(value) && value.length > 2 && value.every(function (val) {
421
- return (0, _isObject.default)(val);
422
- })) {
423
- return /*#__PURE__*/_react.default.createElement(DataGridDetails, {
424
- key: key,
425
- prefix: prefix,
426
- name: key,
427
- value: value
428
- });
429
- }
430
-
431
466
  var description = accessNested([].concat((0, _toConsumableArray2.default)(prefix), [key]), descriptions);
432
467
 
433
468
  if (Array.isArray(value)) {
434
- return /*#__PURE__*/_react.default.createElement(ArrayValue, {
469
+ // check if it looks like an array of objects, which could be used
470
+ // in data grid
471
+ return value.length > 2 && value.every(function (val) {
472
+ return (0, _isObject.default)(val);
473
+ }) ? /*#__PURE__*/_react.default.createElement(DataGridDetails, {
474
+ key: key,
475
+ name: key,
476
+ prefix: prefix,
477
+ value: value
478
+ }) : /*#__PURE__*/_react.default.createElement(ArrayValue, {
435
479
  key: key,
436
480
  name: key,
437
481
  value: value,
438
482
  description: description,
439
483
  prefix: prefix
440
484
  });
441
- }
442
-
443
- if ((0, _isObject.default)(value)) {
444
- return /*#__PURE__*/_react.default.createElement(Attributes, {
485
+ } else if ((0, _isObject.default)(value)) {
486
+ return (0, _util.isUriLocation)(value) ? /*#__PURE__*/_react.default.createElement(UriAttribute, {
487
+ key: key,
488
+ name: key,
489
+ prefix: prefix,
490
+ value: value
491
+ }) : /*#__PURE__*/_react.default.createElement(Attributes, {
445
492
  omit: omits,
446
493
  key: key,
447
494
  attributes: value,
448
495
  descriptions: descriptions,
449
496
  prefix: [].concat((0, _toConsumableArray2.default)(prefix), [key])
450
497
  });
498
+ } else {
499
+ return /*#__PURE__*/_react.default.createElement(SimpleValue, {
500
+ key: key,
501
+ name: key,
502
+ value: formatter(value, key),
503
+ description: description,
504
+ prefix: prefix,
505
+ width: labelWidth
506
+ });
451
507
  }
452
-
453
- return /*#__PURE__*/_react.default.createElement(SimpleValue, {
454
- key: key,
455
- name: key,
456
- value: formatter(value, key),
457
- description: description,
458
- prefix: prefix,
459
- width: labelWidth
460
- });
461
508
  }));
462
- };
463
-
464
- exports.Attributes = Attributes;
509
+ }
465
510
 
466
511
  var BaseAttributes = function BaseAttributes(props) {
467
512
  var feature = props.feature;
@@ -478,6 +523,12 @@ function isEmpty(obj) {
478
523
  return Object.keys(obj).length === 0;
479
524
  }
480
525
 
526
+ function generateTitle(name, id, type) {
527
+ return [(0, _util2.ellipses)("".concat(name) || "".concat(id)), "".concat(type)].filter(function (f) {
528
+ return !!f;
529
+ }).join(' - ');
530
+ }
531
+
481
532
  var FeatureDetails = function FeatureDetails(props) {
482
533
  var _props$omit2 = props.omit,
483
534
  omit = _props$omit2 === void 0 ? [] : _props$omit2,
@@ -496,9 +547,7 @@ var FeatureDetails = function FeatureDetails(props) {
496
547
  var defaultSeqTypes = ['mRNA', 'transcript'];
497
548
  var sequenceTypes = (0, _configuration.getConf)(session, ['featureDetails', 'sequenceTypes']) || defaultSeqTypes;
498
549
  return /*#__PURE__*/_react.default.createElement(BaseCard, {
499
- title: [(0, _util2.ellipses)(name || id), type].filter(function (f) {
500
- return !!f;
501
- }).join(' - ')
550
+ title: generateTitle(name, id, type)
502
551
  }, /*#__PURE__*/_react.default.createElement(_core.Typography, null, "Core details"), /*#__PURE__*/_react.default.createElement(CoreDetails, props), /*#__PURE__*/_react.default.createElement(_core.Divider, null), /*#__PURE__*/_react.default.createElement(_core.Typography, null, "Attributes"), /*#__PURE__*/_react.default.createElement(Attributes, (0, _extends2.default)({
503
552
  attributes: feature
504
553
  }, props, {
@@ -508,7 +557,7 @@ var FeatureDetails = function FeatureDetails(props) {
508
557
  var error = _ref20.error;
509
558
  return /*#__PURE__*/_react.default.createElement(_core.Typography, {
510
559
  color: "error"
511
- }, "Failed to fetch sequence for feature: ", "".concat(error));
560
+ }, "".concat(error));
512
561
  }
513
562
  }, /*#__PURE__*/_react.default.createElement(_SequenceFeatureDetails.default, props)) : null, subfeatures !== null && subfeatures !== void 0 && subfeatures.length ? /*#__PURE__*/_react.default.createElement(BaseCard, {
514
563
  title: "Subfeatures",
@@ -530,9 +579,15 @@ var BaseFeatureDetails = (0, _mobxReact.observer)(function (props) {
530
579
 
531
580
  if (!featureData) {
532
581
  return null;
533
- }
582
+ } // replacing undefined with null helps with allowing fields to be hidden,
583
+ // setting null is not allowed by jexl so we set it to undefined to hide. see
584
+ // config guide. this replacement happens both here and when snapshotting the
585
+ // featureData
534
586
 
535
- var feature = JSON.parse(JSON.stringify(featureData));
587
+
588
+ var feature = JSON.parse(JSON.stringify(featureData, function (_, v) {
589
+ return typeof v === 'undefined' ? null : v;
590
+ }));
536
591
 
537
592
  if (isEmpty(feature)) {
538
593
  return null;
@@ -4,9 +4,30 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
4
4
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
5
5
  type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
6
6
  featureData: import("mobx-state-tree").IType<any, any, any>;
7
+ formattedFields: import("mobx-state-tree").IType<any, any, any>;
8
+ unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
7
9
  view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
10
+ track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
8
11
  }, {
9
- setFeatureData(data: Record<string, unknown>): void;
12
+ setFeatureData(featureData: Record<string, unknown>): void;
10
13
  clearFeatureData(): void;
11
- }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
14
+ setFormattedData(feat: Record<string, unknown>): void;
15
+ } & {
16
+ afterCreate(): void;
17
+ }, import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
18
+ id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
19
+ type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
20
+ featureData: import("mobx-state-tree").IType<any, any, any>;
21
+ formattedFields: import("mobx-state-tree").IType<any, any, any>;
22
+ unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
23
+ view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
24
+ track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
25
+ }>>, {
26
+ id: string;
27
+ type: "BaseFeatureWidget";
28
+ formattedFields: any;
29
+ view: import("mobx-state-tree").ReferenceIdentifier | undefined;
30
+ track: import("mobx-state-tree").ReferenceIdentifier | undefined;
31
+ finalizedFeatureData: any;
32
+ }>;
12
33
  export { configSchema, stateModelFactory };
@@ -1,34 +1,129 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
6
8
  exports.configSchema = void 0;
7
9
  exports.stateModelFactory = exports.default = stateModelFactory;
8
10
 
11
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
12
+
13
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
14
+
9
15
  var _mobxStateTree = require("mobx-state-tree");
10
16
 
17
+ var _mobx = require("mobx");
18
+
11
19
  var _configuration = require("../configuration");
12
20
 
21
+ var _clone = _interopRequireDefault(require("clone"));
22
+
13
23
  var _mst = require("../util/types/mst");
14
24
 
25
+ var _excluded = ["featureData", "finalizedFeatureData"],
26
+ _excluded2 = ["unformattedFeatureData", "featureData"];
27
+
28
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
29
+
30
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
31
+
15
32
  var configSchema = (0, _configuration.ConfigurationSchema)('BaseFeatureWidget', {});
16
33
  exports.configSchema = configSchema;
17
34
 
35
+ function formatSubfeatures(obj, depth, parse) {
36
+ var _obj$subfeatures;
37
+
38
+ var currentDepth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
39
+ var returnObj = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
40
+
41
+ if (depth <= currentDepth) {
42
+ return returnObj;
43
+ }
44
+
45
+ returnObj.subfeatures = (_obj$subfeatures = obj.subfeatures) === null || _obj$subfeatures === void 0 ? void 0 : _obj$subfeatures.map(function (sub) {
46
+ formatSubfeatures(sub, depth, parse, currentDepth + 1, returnObj);
47
+ return parse(sub);
48
+ });
49
+ return returnObj;
50
+ }
51
+
18
52
  function stateModelFactory(pluginManager) {
19
53
  return _mobxStateTree.types.model('BaseFeatureWidget', {
20
54
  id: _mst.ElementId,
21
55
  type: _mobxStateTree.types.literal('BaseFeatureWidget'),
22
56
  featureData: _mobxStateTree.types.frozen(),
23
- view: _mobxStateTree.types.safeReference(pluginManager.pluggableMstType('view', 'stateModel'))
57
+ formattedFields: _mobxStateTree.types.frozen(),
58
+ unformattedFeatureData: _mobxStateTree.types.frozen(),
59
+ view: _mobxStateTree.types.safeReference(pluginManager.pluggableMstType('view', 'stateModel')),
60
+ track: _mobxStateTree.types.safeReference(pluginManager.pluggableMstType('track', 'stateModel'))
61
+ }).volatile(function () {
62
+ return {};
24
63
  }).actions(function (self) {
25
64
  return {
26
- setFeatureData: function setFeatureData(data) {
27
- self.featureData = data;
65
+ setFeatureData: function setFeatureData(featureData) {
66
+ self.unformattedFeatureData = featureData;
28
67
  },
29
68
  clearFeatureData: function clearFeatureData() {
30
69
  self.featureData = undefined;
70
+ },
71
+ setFormattedData: function setFormattedData(feat) {
72
+ self.featureData = feat;
31
73
  }
32
74
  };
75
+ }).actions(function (self) {
76
+ return {
77
+ afterCreate: function afterCreate() {
78
+ (0, _mobxStateTree.addDisposer)(self, (0, _mobx.autorun)(function () {
79
+ var unformattedFeatureData = self.unformattedFeatureData,
80
+ track = self.track;
81
+
82
+ if (unformattedFeatureData) {
83
+ var feature = (0, _clone.default)(unformattedFeatureData);
84
+
85
+ if (track) {
86
+ // eslint-disable-next-line no-underscore-dangle
87
+ feature.__jbrowsefmt = (0, _configuration.getConf)(track, ['formatDetails', 'feature'], {
88
+ feature: feature
89
+ });
90
+ var depth = (0, _configuration.getConf)(track, ['formatDetails', 'depth']);
91
+ formatSubfeatures(feature, depth, function (subfeature) {
92
+ // eslint-disable-next-line no-underscore-dangle
93
+ subfeature.__jbrowsefmt = (0, _configuration.getConf)(track, ['formatDetails', 'subfeatures'], {
94
+ feature: subfeature
95
+ });
96
+ });
97
+ }
98
+
99
+ self.setFormattedData(feature);
100
+ }
101
+ }));
102
+ }
103
+ };
104
+ }).preProcessSnapshot(function (snap) {
105
+ // @ts-ignore
106
+ var featureData = snap.featureData,
107
+ finalizedFeatureData = snap.finalizedFeatureData,
108
+ rest = (0, _objectWithoutProperties2.default)(snap, _excluded);
109
+ return _objectSpread({
110
+ unformattedFeatureData: featureData,
111
+ featureData: finalizedFeatureData
112
+ }, rest);
113
+ }).postProcessSnapshot(function (snap) {
114
+ var unformattedFeatureData = snap.unformattedFeatureData,
115
+ featureData = snap.featureData,
116
+ rest = (0, _objectWithoutProperties2.default)(snap, _excluded2); // finalizedFeatureData avoids running formatter twice if loading from
117
+ // snapshot
118
+
119
+ return _objectSpread({
120
+ // replacing undefined with null helps with allowing fields to be
121
+ // hidden, setting null is not allowed by jexl so we set it to
122
+ // undefined to hide. see config guide. this replacement happens both
123
+ // here and when displaying the featureData in base feature widget
124
+ finalizedFeatureData: JSON.parse(JSON.stringify(featureData, function (_, v) {
125
+ return typeof v === 'undefined' ? null : v;
126
+ }))
127
+ }, rest);
33
128
  });
34
129
  }
@@ -297,7 +297,7 @@ export default function assemblyManagerFactory(assemblyConfigType: IAnyType, plu
297
297
  }): Promise<{
298
298
  [k: string]: string;
299
299
  } | undefined>;
300
- isValidRefName(refName: string, assemblyName?: string | undefined): boolean;
300
+ isValidRefName(refName: string, assemblyName?: string): boolean;
301
301
  } & {
302
302
  removeAssembly(asm: import("mobx-state-tree").ModelInstanceTypeProps<{
303
303
  configuration: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<IAnyType>>;