@jbrowse/plugin-data-management 2.8.0 → 2.10.0

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 (85) hide show
  1. package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.js +4 -8
  2. package/dist/AddTrackWidget/model.d.ts +81 -0
  3. package/dist/AddTrackWidget/model.js +81 -0
  4. package/dist/HierarchicalTrackSelectorWidget/components/ShoppingCart.d.ts +1 -1
  5. package/dist/HierarchicalTrackSelectorWidget/components/ShoppingCart.js +11 -53
  6. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetFilter.d.ts +5 -7
  7. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetFilter.js +12 -11
  8. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetFilters.d.ts +5 -7
  9. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetFilters.js +11 -8
  10. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.d.ts +1 -11
  11. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.js +9 -7
  12. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.js +40 -135
  13. package/dist/HierarchicalTrackSelectorWidget/components/tree/DropdownTrackSelector.d.ts +12 -0
  14. package/dist/HierarchicalTrackSelectorWidget/components/tree/DropdownTrackSelector.js +59 -0
  15. package/dist/HierarchicalTrackSelectorWidget/components/tree/FavoriteTracks.d.ts +6 -0
  16. package/dist/HierarchicalTrackSelectorWidget/components/tree/FavoriteTracks.js +45 -0
  17. package/dist/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.js +71 -46
  18. package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.js +5 -34
  19. package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalTree.js +8 -3
  20. package/dist/HierarchicalTrackSelectorWidget/components/tree/RecentlyUsedTracks.d.ts +6 -0
  21. package/dist/HierarchicalTrackSelectorWidget/components/tree/RecentlyUsedTracks.js +42 -0
  22. package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackCategory.js +7 -6
  23. package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackLabel.js +9 -28
  24. package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackLabelMenu.d.ts +12 -0
  25. package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackLabelMenu.js +50 -0
  26. package/dist/HierarchicalTrackSelectorWidget/components/util.d.ts +3 -0
  27. package/dist/HierarchicalTrackSelectorWidget/components/util.js +5 -1
  28. package/dist/HierarchicalTrackSelectorWidget/facetedModel.d.ts +128 -0
  29. package/dist/HierarchicalTrackSelectorWidget/facetedModel.js +206 -0
  30. package/dist/HierarchicalTrackSelectorWidget/facetedUtil.d.ts +2 -0
  31. package/dist/HierarchicalTrackSelectorWidget/{components/faceted/util.js → facetedUtil.js} +5 -1
  32. package/dist/HierarchicalTrackSelectorWidget/generateHierarchy.d.ts +17 -5
  33. package/dist/HierarchicalTrackSelectorWidget/generateHierarchy.js +27 -21
  34. package/dist/HierarchicalTrackSelectorWidget/model.d.ts +193 -15
  35. package/dist/HierarchicalTrackSelectorWidget/model.js +209 -22
  36. package/dist/ucsc-trackhub/doConnect.d.ts +1 -0
  37. package/dist/ucsc-trackhub/doConnect.js +131 -0
  38. package/dist/ucsc-trackhub/model.d.ts +19 -2
  39. package/dist/ucsc-trackhub/model.js +16 -71
  40. package/dist/ucsc-trackhub/ucscTrackHub.d.ts +161 -4
  41. package/dist/ucsc-trackhub/ucscTrackHub.js +49 -166
  42. package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.js +4 -8
  43. package/esm/AddTrackWidget/model.d.ts +81 -0
  44. package/esm/AddTrackWidget/model.js +81 -0
  45. package/esm/HierarchicalTrackSelectorWidget/components/ShoppingCart.d.ts +1 -1
  46. package/esm/HierarchicalTrackSelectorWidget/components/ShoppingCart.js +12 -31
  47. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetFilter.d.ts +5 -7
  48. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetFilter.js +13 -11
  49. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetFilters.d.ts +5 -7
  50. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetFilters.js +12 -8
  51. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.d.ts +1 -11
  52. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.js +9 -7
  53. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.js +41 -113
  54. package/esm/HierarchicalTrackSelectorWidget/components/tree/DropdownTrackSelector.d.ts +12 -0
  55. package/esm/HierarchicalTrackSelectorWidget/components/tree/DropdownTrackSelector.js +31 -0
  56. package/esm/HierarchicalTrackSelectorWidget/components/tree/FavoriteTracks.d.ts +6 -0
  57. package/esm/HierarchicalTrackSelectorWidget/components/tree/FavoriteTracks.js +40 -0
  58. package/esm/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.js +71 -46
  59. package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.js +6 -12
  60. package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalTree.js +8 -3
  61. package/esm/HierarchicalTrackSelectorWidget/components/tree/RecentlyUsedTracks.d.ts +6 -0
  62. package/esm/HierarchicalTrackSelectorWidget/components/tree/RecentlyUsedTracks.js +37 -0
  63. package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackCategory.js +7 -6
  64. package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackLabel.js +8 -27
  65. package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackLabelMenu.d.ts +12 -0
  66. package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackLabelMenu.js +45 -0
  67. package/esm/HierarchicalTrackSelectorWidget/components/util.d.ts +3 -0
  68. package/esm/HierarchicalTrackSelectorWidget/components/util.js +5 -1
  69. package/esm/HierarchicalTrackSelectorWidget/facetedModel.d.ts +128 -0
  70. package/esm/HierarchicalTrackSelectorWidget/facetedModel.js +202 -0
  71. package/esm/HierarchicalTrackSelectorWidget/facetedUtil.d.ts +2 -0
  72. package/esm/HierarchicalTrackSelectorWidget/{components/faceted/util.js → facetedUtil.js} +3 -0
  73. package/esm/HierarchicalTrackSelectorWidget/generateHierarchy.d.ts +17 -5
  74. package/esm/HierarchicalTrackSelectorWidget/generateHierarchy.js +27 -21
  75. package/esm/HierarchicalTrackSelectorWidget/model.d.ts +193 -15
  76. package/esm/HierarchicalTrackSelectorWidget/model.js +211 -24
  77. package/esm/ucsc-trackhub/doConnect.d.ts +1 -0
  78. package/esm/ucsc-trackhub/doConnect.js +127 -0
  79. package/esm/ucsc-trackhub/model.d.ts +19 -2
  80. package/esm/ucsc-trackhub/model.js +17 -72
  81. package/esm/ucsc-trackhub/ucscTrackHub.d.ts +161 -4
  82. package/esm/ucsc-trackhub/ucscTrackHub.js +48 -141
  83. package/package.json +3 -4
  84. package/dist/HierarchicalTrackSelectorWidget/components/faceted/util.d.ts +0 -1
  85. package/esm/HierarchicalTrackSelectorWidget/components/faceted/util.d.ts +0 -1
@@ -32,8 +32,8 @@ const react_vtree_1 = require("react-vtree");
32
32
  const util_1 = require("@jbrowse/core/util");
33
33
  const TrackListNode_1 = __importDefault(require("./TrackListNode"));
34
34
  function getNodeData(node, nestingLevel, extra, selection) {
35
- const isLeaf = !!node.conf;
36
- const selected = !!selection[node.id];
35
+ const isLeaf = node.type === 'track';
36
+ const selected = isLeaf ? selection[node.trackId] : false;
37
37
  return {
38
38
  data: {
39
39
  defaultHeight: isLeaf ? 22 : 40,
@@ -58,7 +58,12 @@ const HierarchicalTree = (0, mobx_react_1.observer)(function HierarchicalTree({
58
58
  const { drawerPosition } = session;
59
59
  const obj = (0, react_1.useMemo)(() => Object.fromEntries(selection.map(s => [s.trackId, s])), [selection]);
60
60
  const extra = (0, react_1.useMemo)(() => ({
61
- onChange: (trackId) => view.toggleTrack(trackId),
61
+ onChange: (trackId) => {
62
+ const trackTurnedOn = view.toggleTrack(trackId);
63
+ if (trackTurnedOn) {
64
+ model.addToRecentlyUsed(trackId);
65
+ }
66
+ },
62
67
  toggleCollapse: (pathName) => model.toggleCategory(pathName),
63
68
  tree,
64
69
  model,
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { HierarchicalTrackSelectorModel } from '../../model';
3
+ declare const RecentlyUsedTracks: ({ model, }: {
4
+ model: HierarchicalTrackSelectorModel;
5
+ }) => React.JSX.Element | null;
6
+ export default RecentlyUsedTracks;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const material_1 = require("@mui/material");
8
+ const mobx_react_1 = require("mobx-react");
9
+ // icons
10
+ const History_1 = __importDefault(require("@mui/icons-material/History"));
11
+ const DropdownTrackSelector_1 = __importDefault(require("./DropdownTrackSelector"));
12
+ const mui_1 = require("tss-react/mui");
13
+ const useStyles = (0, mui_1.makeStyles)()({
14
+ smallBadge: {
15
+ height: 14,
16
+ },
17
+ });
18
+ const RecentlyUsedTracks = (0, mobx_react_1.observer)(function ({ model, }) {
19
+ const { classes } = useStyles();
20
+ const { view, recentlyUsedCounter, recentlyUsedTracks } = model;
21
+ return view ? (react_1.default.createElement(DropdownTrackSelector_1.default, { onClick: () => model.setRecentlyUsedCounter(0), model: model, tracks: recentlyUsedTracks, extraMenuItems: recentlyUsedTracks.length
22
+ ? [
23
+ { type: 'divider' },
24
+ {
25
+ label: 'Clear recently used',
26
+ onClick: () => model.clearRecentlyUsed(),
27
+ },
28
+ ]
29
+ : [
30
+ {
31
+ label: 'No recently used',
32
+ onClick: () => { },
33
+ },
34
+ ] },
35
+ react_1.default.createElement(material_1.Tooltip, { title: "Recently used tracks" },
36
+ react_1.default.createElement(material_1.Badge, { classes: { badge: classes.smallBadge }, anchorOrigin: {
37
+ vertical: 'bottom',
38
+ horizontal: 'right',
39
+ }, color: "secondary", badgeContent: recentlyUsedCounter },
40
+ react_1.default.createElement(History_1.default, null))))) : null;
41
+ });
42
+ exports.default = RecentlyUsedTracks;
@@ -50,10 +50,10 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
50
50
  function Category({ isOpen, setOpen, data, }) {
51
51
  const { classes } = useStyles();
52
52
  const [menuEl, setMenuEl] = (0, react_1.useState)(null);
53
- const { name, model, id, tree, toggleCollapse } = data;
53
+ const { menuItems = [], name, model, id, tree } = data;
54
54
  return (react_1.default.createElement("div", { className: classes.accordionText, onClick: () => {
55
55
  if (!menuEl) {
56
- toggleCollapse(id);
56
+ data.toggleCollapse(id);
57
57
  setOpen(!isOpen);
58
58
  }
59
59
  } },
@@ -85,8 +85,8 @@ function Category({ isOpen, setOpen, data, }) {
85
85
  onClick: () => {
86
86
  var _a;
87
87
  for (const entry of ((_a = (0, util_1.treeToMap)(tree).get(id)) === null || _a === void 0 ? void 0 : _a.children) || []) {
88
- if (!entry.children.length) {
89
- model.view.showTrack(entry.id);
88
+ if (entry.type === 'track') {
89
+ model.view.showTrack(entry.trackId);
90
90
  }
91
91
  }
92
92
  },
@@ -96,12 +96,13 @@ function Category({ isOpen, setOpen, data, }) {
96
96
  onClick: () => {
97
97
  var _a;
98
98
  for (const entry of ((_a = (0, util_1.treeToMap)(tree).get(id)) === null || _a === void 0 ? void 0 : _a.children) || []) {
99
- if (!entry.children.length) {
100
- model.view.hideTrack(entry.id);
99
+ if (entry.type === 'track') {
100
+ model.view.hideTrack(entry.trackId);
101
101
  }
102
102
  }
103
103
  },
104
104
  },
105
+ ...menuItems,
105
106
  ], onMenuItemClick: (_event, callback) => {
106
107
  callback();
107
108
  setMenuEl(null);
@@ -6,14 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const material_1 = require("@mui/material");
8
8
  const mui_1 = require("tss-react/mui");
9
- const util_1 = require("@jbrowse/core/util");
10
9
  const SanitizedHTML_1 = __importDefault(require("@jbrowse/core/ui/SanitizedHTML"));
11
10
  const configuration_1 = require("@jbrowse/core/configuration");
12
- // icons
13
- const MoreHoriz_1 = __importDefault(require("@mui/icons-material/MoreHoriz"));
14
11
  // locals
15
- const util_2 = require("../util");
16
- const CascadingMenuButton_1 = __importDefault(require("@jbrowse/core/ui/CascadingMenuButton"));
12
+ const util_1 = require("../util");
13
+ const TrackLabelMenu_1 = __importDefault(require("./TrackLabelMenu"));
17
14
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
18
15
  compactCheckbox: {
19
16
  padding: 0,
@@ -24,37 +21,21 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
24
21
  backgroundColor: theme.palette.action.selected,
25
22
  },
26
23
  },
24
+ selected: {
25
+ background: '#cccc',
26
+ },
27
27
  }));
28
28
  function TrackLabel({ data }) {
29
29
  const { classes } = useStyles();
30
- const { checked, conf, model, drawerPosition, id, name, onChange, selected } = data;
31
- const description = (conf && (0, configuration_1.readConfObject)(conf, ['description'])) || '';
30
+ const { checked, conf, model, drawerPosition, id, trackId, name, onChange, selected, } = data;
31
+ const description = (conf && (0, configuration_1.readConfObject)(conf, 'description')) || '';
32
32
  return (react_1.default.createElement(react_1.default.Fragment, null,
33
33
  react_1.default.createElement(material_1.Tooltip, { title: description + (selected ? ' (in selection)' : ''), placement: drawerPosition === 'left' ? 'right' : 'left' },
34
- react_1.default.createElement(material_1.FormControlLabel, { className: classes.checkboxLabel, control: react_1.default.createElement(material_1.Checkbox, { className: classes.compactCheckbox, checked: checked, onChange: () => onChange(id), disabled: (0, util_2.isUnsupported)(name), inputProps: {
34
+ react_1.default.createElement(material_1.FormControlLabel, { className: classes.checkboxLabel, control: react_1.default.createElement(material_1.Checkbox, { className: classes.compactCheckbox, checked: checked, onChange: () => onChange(trackId), disabled: (0, util_1.isUnsupported)(name), inputProps: {
35
35
  // @ts-expect-error
36
36
  'data-testid': `htsTrackEntry-${id}`,
37
37
  } }), label: react_1.default.createElement("div", { "data-testid": `htsTrackLabel-${id}`, style: { background: selected ? '#cccc' : undefined } },
38
38
  react_1.default.createElement(SanitizedHTML_1.default, { html: name })) })),
39
- react_1.default.createElement(TrackMenuButton, { model: model, selected: selected, id: id, conf: conf })));
39
+ react_1.default.createElement(TrackLabelMenu_1.default, { model: model, trackId: trackId, id: id, conf: conf })));
40
40
  }
41
41
  exports.default = TrackLabel;
42
- function TrackMenuButton({ id, model, selected, conf, }) {
43
- var _a, _b;
44
- return (react_1.default.createElement(CascadingMenuButton_1.default, { style: { padding: 0 }, "data-testid": `htsTrackEntryMenu-${id}`, menuItems: [
45
- ...(((_b = (_a = (0, util_1.getSession)(model)).getTrackActionMenuItems) === null || _b === void 0 ? void 0 : _b.call(_a, conf)) || []),
46
- {
47
- label: 'Add to selection',
48
- onClick: () => model.addToSelection([conf]),
49
- },
50
- ...(selected
51
- ? [
52
- {
53
- label: 'Remove from selection',
54
- onClick: () => model.removeFromSelection([conf]),
55
- },
56
- ]
57
- : []),
58
- ] },
59
- react_1.default.createElement(MoreHoriz_1.default, null)));
60
- }
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
+ import { HierarchicalTrackSelectorModel } from '../../model';
4
+ declare const TrackLabelMenu: ({ id, trackId, stopPropagation, model, setOpen, conf, }: {
5
+ id: string;
6
+ trackId: string;
7
+ stopPropagation?: boolean | undefined;
8
+ conf: AnyConfigurationModel;
9
+ setOpen?: ((arg: boolean) => void) | undefined;
10
+ model: HierarchicalTrackSelectorModel;
11
+ }) => React.JSX.Element;
12
+ export default TrackLabelMenu;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const mui_1 = require("tss-react/mui");
8
+ const util_1 = require("@jbrowse/core/util");
9
+ const CascadingMenuButton_1 = __importDefault(require("@jbrowse/core/ui/CascadingMenuButton"));
10
+ // icons
11
+ const MoreHoriz_1 = __importDefault(require("@mui/icons-material/MoreHoriz"));
12
+ const StarBorderOutlined_1 = __importDefault(require("@mui/icons-material/StarBorderOutlined"));
13
+ const Star_1 = __importDefault(require("@mui/icons-material/Star"));
14
+ const useStyles = (0, mui_1.makeStyles)()({
15
+ cascadingStyle: {
16
+ padding: 0,
17
+ },
18
+ });
19
+ const TrackLabelMenu = function ({ id, trackId, stopPropagation, model, setOpen, conf, }) {
20
+ var _a, _b;
21
+ const { classes } = useStyles();
22
+ return (react_1.default.createElement(CascadingMenuButton_1.default, { className: classes.cascadingStyle, stopPropagation: stopPropagation, setOpen: setOpen, "data-testid": `htsTrackEntryMenu-${id}`, menuItems: [
23
+ ...(((_b = (_a = (0, util_1.getSession)(model)).getTrackActionMenuItems) === null || _b === void 0 ? void 0 : _b.call(_a, conf)) || []),
24
+ model.isFavorite(trackId)
25
+ ? {
26
+ label: 'Remove from favorites',
27
+ onClick: () => model.removeFromFavorites(trackId),
28
+ icon: StarBorderOutlined_1.default,
29
+ }
30
+ : {
31
+ label: 'Add to favorites',
32
+ onClick: () => model.addToFavorites(trackId),
33
+ icon: Star_1.default,
34
+ },
35
+ {
36
+ label: 'Add to selection',
37
+ onClick: () => model.addToSelection([conf]),
38
+ },
39
+ ...(model.isSelected(conf)
40
+ ? [
41
+ {
42
+ label: 'Remove from selection',
43
+ onClick: () => model.removeFromSelection([conf]),
44
+ },
45
+ ]
46
+ : []),
47
+ ] },
48
+ react_1.default.createElement(MoreHoriz_1.default, null)));
49
+ };
50
+ exports.default = TrackLabelMenu;
@@ -1,18 +1,21 @@
1
1
  import { AnyConfigurationModel } from '@jbrowse/core/configuration';
2
2
  import { HierarchicalTrackSelectorModel } from '../model';
3
3
  import { TreeNode } from '../generateHierarchy';
4
+ import { MenuItem } from '@jbrowse/core/ui';
4
5
  export interface NodeData {
5
6
  nestingLevel: number;
6
7
  checked: boolean;
7
8
  conf: AnyConfigurationModel;
8
9
  drawerPosition: unknown;
9
10
  id: string;
11
+ trackId: string;
10
12
  isLeaf: boolean;
11
13
  name: string;
12
14
  onChange: Function;
13
15
  toggleCollapse: (arg: string) => void;
14
16
  tree: TreeNode;
15
17
  selected: boolean;
18
+ menuItems?: MenuItem[];
16
19
  model: HierarchicalTrackSelectorModel;
17
20
  }
18
21
  export declare function getAllChildren(subtree?: TreeNode): AnyConfigurationModel[];
@@ -3,7 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isUnsupported = exports.treeToMap = exports.getAllChildren = void 0;
4
4
  function getAllChildren(subtree) {
5
5
  // @ts-expect-error
6
- return ((subtree === null || subtree === void 0 ? void 0 : subtree.children.map(t => t.children.length ? getAllChildren(t) : t.conf)) || []).flat(Infinity);
6
+ return (subtree === null || subtree === void 0 ? void 0 : subtree.type) === 'category'
7
+ ? subtree.children
8
+ .map(t => (t.type === 'category' ? getAllChildren(t) : t.conf))
9
+ .flat(Infinity)
10
+ : [];
7
11
  }
8
12
  exports.getAllChildren = getAllChildren;
9
13
  function treeToMap(tree, map = new Map()) {
@@ -0,0 +1,128 @@
1
+ import { Instance } from 'mobx-state-tree';
2
+ /**
3
+ * #stateModel FacetedModel
4
+ */
5
+ export declare function facetedStateTreeF(): import("mobx-state-tree").IModelType<{
6
+ /**
7
+ * #property
8
+ */
9
+ filterText: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
10
+ /**
11
+ * #property
12
+ */
13
+ showSparse: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
14
+ /**
15
+ * #property
16
+ */
17
+ showFilters: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
18
+ /**
19
+ * #property
20
+ */
21
+ showOptions: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
22
+ /**
23
+ * #property
24
+ */
25
+ panelWidth: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
26
+ }, {
27
+ visible: Record<string, boolean>;
28
+ widths: Record<string, number | undefined>;
29
+ useShoppingCart: boolean;
30
+ filters: import("mobx").ObservableMap<string, string[]>;
31
+ } & {
32
+ /**
33
+ * #action
34
+ */
35
+ setFilter(key: string, value: string[]): void;
36
+ /**
37
+ * #action
38
+ */
39
+ setPanelWidth(width: number): void;
40
+ /**
41
+ * #action
42
+ */
43
+ setUseShoppingCart(f: boolean): void;
44
+ /**
45
+ * #action
46
+ */
47
+ setFilterText(str: string): void;
48
+ /**
49
+ * #action
50
+ */
51
+ setShowSparse(f: boolean): void;
52
+ /**
53
+ * #action
54
+ */
55
+ setShowOptions(f: boolean): void;
56
+ /**
57
+ * #action
58
+ */
59
+ setShowFilters(f: boolean): void;
60
+ } & {
61
+ /**
62
+ * #getter
63
+ */
64
+ readonly allTrackConfigurations: ({
65
+ [x: string]: any;
66
+ } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
67
+ setSubschema(slotName: string, data: unknown): any;
68
+ } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>)[];
69
+ } & {
70
+ /**
71
+ * #getter
72
+ */
73
+ readonly rows: {
74
+ readonly id: string;
75
+ readonly conf: {
76
+ [x: string]: any;
77
+ } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
78
+ setSubschema(slotName: string, data: unknown): any;
79
+ } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>;
80
+ readonly name: string;
81
+ readonly category: string;
82
+ readonly adapter: string;
83
+ readonly description: string;
84
+ readonly metadata: any;
85
+ }[];
86
+ } & {
87
+ /**
88
+ * #getter
89
+ */
90
+ readonly filteredNonMetadataKeys: string[] | readonly ["category", "adapter", "description"];
91
+ /**
92
+ * #getter
93
+ */
94
+ readonly metadataKeys: string[];
95
+ readonly filteredMetadataKeys: string[];
96
+ /**
97
+ * #getter
98
+ */
99
+ readonly fields: string[];
100
+ /**
101
+ * #getter
102
+ */
103
+ readonly filteredRows: {
104
+ readonly id: string;
105
+ readonly conf: {
106
+ [x: string]: any;
107
+ } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
108
+ setSubschema(slotName: string, data: unknown): any;
109
+ } & import("mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>;
110
+ readonly name: string;
111
+ readonly category: string;
112
+ readonly adapter: string;
113
+ readonly description: string;
114
+ readonly metadata: any;
115
+ }[];
116
+ } & {
117
+ /**
118
+ * #action
119
+ */
120
+ setVisible(args: Record<string, boolean>): void;
121
+ /**
122
+ * #action
123
+ */
124
+ setWidths(args: Record<string, number | undefined>): void;
125
+ afterAttach(): void;
126
+ }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
127
+ export type FacetedStateModel = ReturnType<typeof facetedStateTreeF>;
128
+ export type FacetedModel = Instance<FacetedStateModel>;
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.facetedStateTreeF = void 0;
4
+ const mobx_state_tree_1 = require("mobx-state-tree");
5
+ const util_1 = require("./util");
6
+ const configuration_1 = require("@jbrowse/core/configuration");
7
+ const tracks_1 = require("@jbrowse/core/util/tracks");
8
+ const util_2 = require("@jbrowse/core/util");
9
+ const mobx_1 = require("mobx");
10
+ const facetedUtil_1 = require("./facetedUtil");
11
+ const nonMetadataKeys = ['category', 'adapter', 'description'];
12
+ /**
13
+ * #stateModel FacetedModel
14
+ */
15
+ function facetedStateTreeF() {
16
+ return mobx_state_tree_1.types
17
+ .model('FacetedModel', {
18
+ /**
19
+ * #property
20
+ */
21
+ filterText: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, ''),
22
+ /**
23
+ * #property
24
+ */
25
+ showSparse: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => JSON.parse((0, util_2.localStorageGetItem)('facet-showSparse') || 'false')),
26
+ /**
27
+ * #property
28
+ */
29
+ showFilters: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => JSON.parse((0, util_2.localStorageGetItem)('facet-showFilters') || 'true')),
30
+ /**
31
+ * #property
32
+ */
33
+ showOptions: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => JSON.parse((0, util_2.localStorageGetItem)('facet-showTableOptions') || 'false')),
34
+ /**
35
+ * #property
36
+ */
37
+ panelWidth: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.number, () => JSON.parse((0, util_2.localStorageGetItem)('facet-panelWidth') || '400')),
38
+ })
39
+ .volatile(() => ({
40
+ visible: {},
41
+ widths: {},
42
+ useShoppingCart: false,
43
+ filters: mobx_1.observable.map(),
44
+ }))
45
+ .actions(self => ({
46
+ /**
47
+ * #action
48
+ */
49
+ setFilter(key, value) {
50
+ self.filters.set(key, value);
51
+ },
52
+ /**
53
+ * #action
54
+ */
55
+ setPanelWidth(width) {
56
+ self.panelWidth = width;
57
+ },
58
+ /**
59
+ * #action
60
+ */
61
+ setUseShoppingCart(f) {
62
+ self.useShoppingCart = f;
63
+ },
64
+ /**
65
+ * #action
66
+ */
67
+ setFilterText(str) {
68
+ self.filterText = str;
69
+ },
70
+ /**
71
+ * #action
72
+ */
73
+ setShowSparse(f) {
74
+ self.showSparse = f;
75
+ },
76
+ /**
77
+ * #action
78
+ */
79
+ setShowOptions(f) {
80
+ self.showOptions = f;
81
+ },
82
+ /**
83
+ * #action
84
+ */
85
+ setShowFilters(f) {
86
+ self.showFilters = f;
87
+ },
88
+ }))
89
+ .views(self => ({
90
+ /**
91
+ * #getter
92
+ */
93
+ get allTrackConfigurations() {
94
+ return (0, mobx_state_tree_1.getParent)(self).allTrackConfigurations;
95
+ },
96
+ }))
97
+ .views(self => ({
98
+ /**
99
+ * #getter
100
+ */
101
+ get rows() {
102
+ const session = (0, util_2.getSession)(self);
103
+ const { allTrackConfigurations, filterText } = self;
104
+ // metadata is spread onto the object for easier access and sorting
105
+ // by the mui data grid (it's unable to sort by nested objects)
106
+ return allTrackConfigurations
107
+ .filter(conf => (0, util_1.matches)(filterText, conf, session))
108
+ .map(track => {
109
+ var _a, _b;
110
+ const metadata = (0, configuration_1.readConfObject)(track, 'metadata');
111
+ return {
112
+ id: track.trackId,
113
+ conf: track,
114
+ name: (0, tracks_1.getTrackName)(track, session),
115
+ category: (_a = (0, configuration_1.readConfObject)(track, 'category')) === null || _a === void 0 ? void 0 : _a.join(', '),
116
+ adapter: (_b = (0, configuration_1.readConfObject)(track, 'adapter')) === null || _b === void 0 ? void 0 : _b.type,
117
+ description: (0, configuration_1.readConfObject)(track, 'description'),
118
+ metadata,
119
+ };
120
+ });
121
+ },
122
+ }))
123
+ .views(self => ({
124
+ /**
125
+ * #getter
126
+ */
127
+ get filteredNonMetadataKeys() {
128
+ return self.showSparse
129
+ ? nonMetadataKeys
130
+ : (0, facetedUtil_1.findNonSparseKeys)(nonMetadataKeys, self.rows, (r, f) => r[f]);
131
+ },
132
+ /**
133
+ * #getter
134
+ */
135
+ get metadataKeys() {
136
+ return [...new Set(self.rows.flatMap(row => (0, facetedUtil_1.getRootKeys)(row.metadata)))];
137
+ },
138
+ get filteredMetadataKeys() {
139
+ return self.showSparse
140
+ ? this.metadataKeys
141
+ : (0, facetedUtil_1.findNonSparseKeys)(this.metadataKeys, self.rows,
142
+ // @ts-expect-error
143
+ (r, f) => r.metadata[f]);
144
+ },
145
+ /**
146
+ * #getter
147
+ */
148
+ get fields() {
149
+ return [
150
+ 'name',
151
+ ...this.filteredNonMetadataKeys,
152
+ ...this.filteredMetadataKeys.map(m => `metadata.${m}`),
153
+ ];
154
+ },
155
+ /**
156
+ * #getter
157
+ */
158
+ get filteredRows() {
159
+ const arrFilters = [...self.filters.entries()]
160
+ .filter(f => f[1].length > 0)
161
+ .map(([key, val]) => [key, new Set(val)]);
162
+ return self.rows.filter(row =>
163
+ // @ts-expect-error
164
+ arrFilters.every(([key, val]) => val.has(row[key])));
165
+ },
166
+ }))
167
+ .actions(self => ({
168
+ /**
169
+ * #action
170
+ */
171
+ setVisible(args) {
172
+ self.visible = args;
173
+ },
174
+ /**
175
+ * #action
176
+ */
177
+ setWidths(args) {
178
+ self.widths = args;
179
+ },
180
+ afterAttach() {
181
+ (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
182
+ this.setVisible(Object.fromEntries(self.fields.map(c => [c, true])));
183
+ }));
184
+ (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
185
+ this.setWidths({
186
+ name: (0, util_2.measureGridWidth)(self.rows.map(r => r.name), { maxWidth: 500, stripHTML: true }) + 15,
187
+ ...Object.fromEntries(self.filteredNonMetadataKeys
188
+ .filter(f => self.visible[f])
189
+ .map(e => [
190
+ e,
191
+ (0, util_2.measureGridWidth)(self.rows.map(r => r[e]), { maxWidth: 400, stripHTML: true }),
192
+ ])),
193
+ ...Object.fromEntries(self.filteredMetadataKeys
194
+ .filter(f => self.visible['metadata.' + f])
195
+ .map(e => {
196
+ return [
197
+ 'metadata.' + e,
198
+ (0, util_2.measureGridWidth)(self.rows.map(r => r.metadata[e]), { maxWidth: 400, stripHTML: true }),
199
+ ];
200
+ })),
201
+ });
202
+ }));
203
+ },
204
+ }));
205
+ }
206
+ exports.facetedStateTreeF = facetedStateTreeF;
@@ -0,0 +1,2 @@
1
+ export declare function findNonSparseKeys(keys: readonly string[], rows: Record<string, unknown>[], cb: (row: Record<string, unknown>, f: string) => unknown): string[];
2
+ export declare function getRootKeys(obj: Record<string, unknown>): string[];
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRootKeys = void 0;
3
+ exports.getRootKeys = exports.findNonSparseKeys = void 0;
4
+ function findNonSparseKeys(keys, rows, cb) {
5
+ return keys.filter(f => rows.map(r => cb(r, f)).filter(f => !!f).length > 5);
6
+ }
7
+ exports.findNonSparseKeys = findNonSparseKeys;
4
8
  function getRootKeys(obj) {
5
9
  return Object.entries(obj)
6
10
  .map(([key, val]) => (typeof val === 'string' ? key : ''))
@@ -1,13 +1,23 @@
1
1
  import { AnyConfigurationModel } from '@jbrowse/core/configuration';
2
- export interface TreeNode {
2
+ import { MenuItem } from '@jbrowse/core/ui';
3
+ export interface TreeTrackNode {
3
4
  name: string;
4
5
  id: string;
5
- conf?: AnyConfigurationModel;
6
- checked?: boolean;
7
- isOpenByDefault?: boolean;
6
+ trackId: string;
7
+ conf: AnyConfigurationModel;
8
+ checked: boolean;
8
9
  children: TreeNode[];
10
+ type: 'track';
9
11
  }
10
- export declare function generateHierarchy({ model, trackConfs, extra, }: {
12
+ export interface TreeCategoryNode {
13
+ name: string;
14
+ id: string;
15
+ isOpenByDefault: boolean;
16
+ children: TreeNode[];
17
+ type: 'category';
18
+ }
19
+ export type TreeNode = TreeTrackNode | TreeCategoryNode;
20
+ export declare function generateHierarchy({ model, trackConfs, extra, noCategories, menuItems, }: {
11
21
  model: {
12
22
  filterText: string;
13
23
  activeSortTrackNames: boolean;
@@ -19,6 +29,8 @@ export declare function generateHierarchy({ model, trackConfs, extra, }: {
19
29
  }[];
20
30
  };
21
31
  };
32
+ noCategories?: boolean;
33
+ menuItems?: MenuItem[];
22
34
  trackConfs: AnyConfigurationModel[];
23
35
  extra?: string;
24
36
  }): TreeNode[];