@jbrowse/plugin-data-management 2.6.2 → 2.7.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 (161) hide show
  1. package/dist/AddConnectionWidget/components/AddConnectionWidget.d.ts +2 -2
  2. package/dist/AddConnectionWidget/components/AddConnectionWidget.js +17 -8
  3. package/dist/AddConnectionWidget/components/ConfigureConnection.d.ts +2 -2
  4. package/dist/AddConnectionWidget/components/ConfigureConnection.js +2 -1
  5. package/dist/AddConnectionWidget/components/ConnectionTypeSelect.d.ts +2 -2
  6. package/dist/AddConnectionWidget/components/ConnectionTypeSelect.js +5 -3
  7. package/dist/AddTrackWidget/components/AddTrackWidget.d.ts +3 -4
  8. package/dist/AddTrackWidget/components/AddTrackWidget.js +3 -3
  9. package/dist/AddTrackWidget/components/ConfirmTrack.d.ts +2 -2
  10. package/dist/AddTrackWidget/components/ConfirmTrack.js +3 -2
  11. package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.d.ts +3 -4
  12. package/dist/AddTrackWidget/components/DefaultAddTrackWorkflow.js +32 -27
  13. package/dist/AddTrackWidget/components/PasteConfigWorkflow.d.ts +3 -4
  14. package/dist/AddTrackWidget/components/PasteConfigWorkflow.js +10 -7
  15. package/dist/AddTrackWidget/components/TrackAdapterSelector.js +1 -1
  16. package/dist/AddTrackWidget/components/TrackSourceSelect.d.ts +3 -4
  17. package/dist/AddTrackWidget/components/TrackSourceSelect.js +3 -3
  18. package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalFab.d.ts +2 -2
  19. package/dist/HierarchicalTrackSelectorWidget/components/HierarchicalFab.js +2 -1
  20. package/dist/HierarchicalTrackSelectorWidget/components/ShoppingCart.d.ts +2 -2
  21. package/dist/HierarchicalTrackSelectorWidget/components/ShoppingCart.js +2 -1
  22. package/dist/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.d.ts +3 -5
  23. package/dist/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.js +2 -1
  24. package/dist/HierarchicalTrackSelectorWidget/components/dialogs/DeleteConnectionDialog.d.ts +3 -4
  25. package/dist/HierarchicalTrackSelectorWidget/components/dialogs/DeleteConnectionDialog.js +5 -8
  26. package/dist/HierarchicalTrackSelectorWidget/components/dialogs/ManageConnectionsDialog.d.ts +3 -4
  27. package/dist/HierarchicalTrackSelectorWidget/components/dialogs/ManageConnectionsDialog.js +3 -3
  28. package/dist/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.d.ts +2 -3
  29. package/dist/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.js +2 -3
  30. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetFilter.d.ts +13 -0
  31. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetFilter.js +72 -0
  32. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetFilters.js +31 -77
  33. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedDialog.d.ts +3 -4
  34. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedDialog.js +3 -3
  35. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.d.ts +5 -3
  36. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.js +10 -4
  37. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.d.ts +2 -2
  38. package/dist/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.js +53 -33
  39. package/dist/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.d.ts +2 -2
  40. package/dist/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.js +39 -21
  41. package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.d.ts +3 -4
  42. package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.js +13 -9
  43. package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalTree.d.ts +4 -3
  44. package/dist/HierarchicalTrackSelectorWidget/components/tree/HierarchicalTree.js +5 -6
  45. package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackCategory.js +22 -0
  46. package/dist/HierarchicalTrackSelectorWidget/components/tree/TrackLabel.js +3 -3
  47. package/dist/HierarchicalTrackSelectorWidget/components/util.d.ts +2 -1
  48. package/dist/HierarchicalTrackSelectorWidget/components/util.js +1 -2
  49. package/dist/HierarchicalTrackSelectorWidget/filterTracks.d.ts +12 -0
  50. package/dist/HierarchicalTrackSelectorWidget/filterTracks.js +32 -0
  51. package/dist/HierarchicalTrackSelectorWidget/generateHierarchy.d.ts +21 -0
  52. package/dist/HierarchicalTrackSelectorWidget/generateHierarchy.js +98 -0
  53. package/dist/HierarchicalTrackSelectorWidget/model.d.ts +68 -28
  54. package/dist/HierarchicalTrackSelectorWidget/model.js +147 -117
  55. package/dist/HierarchicalTrackSelectorWidget/util.d.ts +12 -0
  56. package/dist/HierarchicalTrackSelectorWidget/util.js +53 -0
  57. package/dist/PluginStoreWidget/components/AddCustomPluginDialog.d.ts +7 -0
  58. package/dist/PluginStoreWidget/components/{CustomPluginForm.js → AddCustomPluginDialog.js} +13 -21
  59. package/dist/PluginStoreWidget/components/DeletePluginDialog.d.ts +5 -0
  60. package/dist/PluginStoreWidget/components/DeletePluginDialog.js +28 -0
  61. package/dist/PluginStoreWidget/components/InstalledPlugin.d.ts +3 -6
  62. package/dist/PluginStoreWidget/components/InstalledPlugin.js +24 -51
  63. package/dist/PluginStoreWidget/components/InstalledPluginsList.d.ts +3 -4
  64. package/dist/PluginStoreWidget/components/InstalledPluginsList.js +7 -9
  65. package/dist/PluginStoreWidget/components/PluginCard.d.ts +2 -2
  66. package/dist/PluginStoreWidget/components/PluginCard.js +5 -6
  67. package/dist/PluginStoreWidget/components/PluginStoreWidget.d.ts +3 -4
  68. package/dist/PluginStoreWidget/components/PluginStoreWidget.js +14 -42
  69. package/dist/PluginStoreWidget/components/util.d.ts +5 -0
  70. package/dist/PluginStoreWidget/components/util.js +29 -0
  71. package/dist/PluginStoreWidget/model.d.ts +2 -2
  72. package/dist/PluginStoreWidget/model.js +2 -2
  73. package/dist/index.d.ts +1 -9
  74. package/dist/index.js +1 -4
  75. package/dist/ucsc-trackhub/model.js +2 -2
  76. package/esm/AddConnectionWidget/components/AddConnectionWidget.d.ts +2 -2
  77. package/esm/AddConnectionWidget/components/AddConnectionWidget.js +19 -10
  78. package/esm/AddConnectionWidget/components/ConfigureConnection.d.ts +2 -2
  79. package/esm/AddConnectionWidget/components/ConfigureConnection.js +2 -1
  80. package/esm/AddConnectionWidget/components/ConnectionTypeSelect.d.ts +2 -2
  81. package/esm/AddConnectionWidget/components/ConnectionTypeSelect.js +5 -3
  82. package/esm/AddTrackWidget/components/AddTrackWidget.d.ts +3 -4
  83. package/esm/AddTrackWidget/components/AddTrackWidget.js +3 -3
  84. package/esm/AddTrackWidget/components/ConfirmTrack.d.ts +2 -2
  85. package/esm/AddTrackWidget/components/ConfirmTrack.js +4 -3
  86. package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.d.ts +3 -4
  87. package/esm/AddTrackWidget/components/DefaultAddTrackWorkflow.js +33 -28
  88. package/esm/AddTrackWidget/components/PasteConfigWorkflow.d.ts +3 -4
  89. package/esm/AddTrackWidget/components/PasteConfigWorkflow.js +11 -8
  90. package/esm/AddTrackWidget/components/TrackAdapterSelector.js +1 -1
  91. package/esm/AddTrackWidget/components/TrackSourceSelect.d.ts +3 -4
  92. package/esm/AddTrackWidget/components/TrackSourceSelect.js +3 -3
  93. package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalFab.d.ts +2 -2
  94. package/esm/HierarchicalTrackSelectorWidget/components/HierarchicalFab.js +2 -1
  95. package/esm/HierarchicalTrackSelectorWidget/components/ShoppingCart.d.ts +2 -2
  96. package/esm/HierarchicalTrackSelectorWidget/components/ShoppingCart.js +2 -1
  97. package/esm/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.d.ts +3 -5
  98. package/esm/HierarchicalTrackSelectorWidget/components/dialogs/CloseConnectionDialog.js +2 -1
  99. package/esm/HierarchicalTrackSelectorWidget/components/dialogs/DeleteConnectionDialog.d.ts +3 -4
  100. package/esm/HierarchicalTrackSelectorWidget/components/dialogs/DeleteConnectionDialog.js +6 -9
  101. package/esm/HierarchicalTrackSelectorWidget/components/dialogs/ManageConnectionsDialog.d.ts +3 -4
  102. package/esm/HierarchicalTrackSelectorWidget/components/dialogs/ManageConnectionsDialog.js +3 -3
  103. package/esm/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.d.ts +2 -3
  104. package/esm/HierarchicalTrackSelectorWidget/components/dialogs/ToggleConnectionsDialog.js +3 -2
  105. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetFilter.d.ts +13 -0
  106. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetFilter.js +43 -0
  107. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetFilters.js +31 -54
  108. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedDialog.d.ts +3 -4
  109. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedDialog.js +3 -3
  110. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.d.ts +5 -3
  111. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedHeader.js +10 -4
  112. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.d.ts +2 -2
  113. package/esm/HierarchicalTrackSelectorWidget/components/faceted/FacetedSelector.js +51 -31
  114. package/esm/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.d.ts +2 -2
  115. package/esm/HierarchicalTrackSelectorWidget/components/tree/HamburgerMenu.js +38 -20
  116. package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.d.ts +3 -4
  117. package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalHeader.js +13 -9
  118. package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalTree.d.ts +4 -3
  119. package/esm/HierarchicalTrackSelectorWidget/components/tree/HierarchicalTree.js +5 -6
  120. package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackCategory.js +22 -0
  121. package/esm/HierarchicalTrackSelectorWidget/components/tree/TrackLabel.js +2 -2
  122. package/esm/HierarchicalTrackSelectorWidget/components/util.d.ts +2 -1
  123. package/esm/HierarchicalTrackSelectorWidget/components/util.js +1 -2
  124. package/esm/HierarchicalTrackSelectorWidget/filterTracks.d.ts +12 -0
  125. package/esm/HierarchicalTrackSelectorWidget/filterTracks.js +28 -0
  126. package/esm/HierarchicalTrackSelectorWidget/generateHierarchy.d.ts +21 -0
  127. package/esm/HierarchicalTrackSelectorWidget/generateHierarchy.js +94 -0
  128. package/esm/HierarchicalTrackSelectorWidget/model.d.ts +68 -28
  129. package/esm/HierarchicalTrackSelectorWidget/model.js +149 -116
  130. package/esm/HierarchicalTrackSelectorWidget/util.d.ts +12 -0
  131. package/esm/HierarchicalTrackSelectorWidget/util.js +45 -0
  132. package/esm/PluginStoreWidget/components/AddCustomPluginDialog.d.ts +7 -0
  133. package/esm/PluginStoreWidget/components/{CustomPluginForm.js → AddCustomPluginDialog.js} +13 -21
  134. package/esm/PluginStoreWidget/components/DeletePluginDialog.d.ts +5 -0
  135. package/esm/PluginStoreWidget/components/DeletePluginDialog.js +22 -0
  136. package/esm/PluginStoreWidget/components/InstalledPlugin.d.ts +3 -6
  137. package/esm/PluginStoreWidget/components/InstalledPlugin.js +27 -54
  138. package/esm/PluginStoreWidget/components/InstalledPluginsList.d.ts +3 -4
  139. package/esm/PluginStoreWidget/components/InstalledPluginsList.js +7 -9
  140. package/esm/PluginStoreWidget/components/PluginCard.d.ts +2 -2
  141. package/esm/PluginStoreWidget/components/PluginCard.js +5 -6
  142. package/esm/PluginStoreWidget/components/PluginStoreWidget.d.ts +3 -4
  143. package/esm/PluginStoreWidget/components/PluginStoreWidget.js +15 -43
  144. package/esm/PluginStoreWidget/components/util.d.ts +5 -0
  145. package/esm/PluginStoreWidget/components/util.js +25 -0
  146. package/esm/PluginStoreWidget/model.d.ts +2 -2
  147. package/esm/PluginStoreWidget/model.js +1 -1
  148. package/esm/index.d.ts +1 -9
  149. package/esm/index.js +1 -3
  150. package/esm/ucsc-trackhub/model.js +2 -2
  151. package/package.json +5 -4
  152. package/dist/PluginStoreWidget/components/CustomPluginForm.d.ts +0 -9
  153. package/dist/SetDefaultSession/SetDefaultSession.d.ts +0 -6
  154. package/dist/SetDefaultSession/SetDefaultSession.js +0 -38
  155. package/dist/SetDefaultSession/index.d.ts +0 -1
  156. package/dist/SetDefaultSession/index.js +0 -8
  157. package/esm/PluginStoreWidget/components/CustomPluginForm.d.ts +0 -9
  158. package/esm/SetDefaultSession/SetDefaultSession.d.ts +0 -6
  159. package/esm/SetDefaultSession/SetDefaultSession.js +0 -33
  160. package/esm/SetDefaultSession/index.d.ts +0 -1
  161. package/esm/SetDefaultSession/index.js +0 -1
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const react_1 = __importStar(require("react"));
30
+ const material_1 = require("@mui/material");
31
+ const mui_1 = require("tss-react/mui");
32
+ // icon
33
+ const Clear_1 = __importDefault(require("@mui/icons-material/Clear"));
34
+ const Minimize_1 = __importDefault(require("@mui/icons-material/Minimize"));
35
+ const Add_1 = __importDefault(require("@mui/icons-material/Add"));
36
+ const useStyles = (0, mui_1.makeStyles)()(theme => ({
37
+ facet: {
38
+ margin: 0,
39
+ marginLeft: theme.spacing(2),
40
+ },
41
+ select: {
42
+ marginBottom: theme.spacing(2),
43
+ },
44
+ }));
45
+ function FacetFilter({ column, vals, width, dispatch, filters, }) {
46
+ const { classes } = useStyles();
47
+ const [visible, setVisible] = (0, react_1.useState)(true);
48
+ return (react_1.default.createElement(material_1.FormControl, { key: column.field, className: classes.facet, style: { width } },
49
+ react_1.default.createElement("div", { style: { display: 'flex' } },
50
+ react_1.default.createElement(material_1.Typography, null, column.field),
51
+ react_1.default.createElement(material_1.Tooltip, { title: "Clear selection on this facet filter" },
52
+ react_1.default.createElement(material_1.IconButton, { onClick: () => dispatch({ key: column.field, val: [] }), size: "small" },
53
+ react_1.default.createElement(Clear_1.default, null))),
54
+ react_1.default.createElement(material_1.Tooltip, { title: "Minimize/expand this facet filter" },
55
+ react_1.default.createElement(material_1.IconButton, { onClick: () => setVisible(!visible), size: "small" }, visible ? react_1.default.createElement(Minimize_1.default, null) : react_1.default.createElement(Add_1.default, null)))),
56
+ visible ? (react_1.default.createElement(material_1.Select, { multiple: true, native: true, className: classes.select, value: filters[column.field], onChange: event => {
57
+ dispatch({
58
+ key: column.field,
59
+ // @ts-expect-error
60
+ val: [...event.target.options]
61
+ .filter(opt => opt.selected)
62
+ .map(opt => opt.value),
63
+ });
64
+ } }, vals
65
+ .sort((a, b) => a[0].localeCompare(b[0]))
66
+ .map(([name, count]) => (react_1.default.createElement("option", { key: name, value: name },
67
+ name,
68
+ " (",
69
+ count,
70
+ ")"))))) : null));
71
+ }
72
+ exports.default = FacetFilter;
@@ -1,86 +1,34 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const react_1 = __importStar(require("react"));
30
- const material_1 = require("@mui/material");
31
- const mui_1 = require("tss-react/mui");
32
- // icon
33
- const Clear_1 = __importDefault(require("@mui/icons-material/Clear"));
34
- const Minimize_1 = __importDefault(require("@mui/icons-material/Minimize"));
35
- const Add_1 = __importDefault(require("@mui/icons-material/Add"));
36
- const useStyles = (0, mui_1.makeStyles)()(theme => ({
37
- facet: {
38
- margin: 0,
39
- marginLeft: theme.spacing(2),
40
- },
41
- select: {
42
- marginBottom: theme.spacing(2),
43
- },
44
- }));
45
- function FacetFilter({ column, vals, width, dispatch, filters, }) {
46
- const { classes } = useStyles();
47
- const [visible, setVisible] = (0, react_1.useState)(true);
48
- return (react_1.default.createElement(material_1.FormControl, { key: column.field, className: classes.facet, style: { width } },
49
- react_1.default.createElement("div", { style: { display: 'flex' } },
50
- react_1.default.createElement(material_1.Typography, null, column.field),
51
- react_1.default.createElement(material_1.Tooltip, { title: "Clear selection on this facet filter" },
52
- react_1.default.createElement(material_1.IconButton, { onClick: () => {
53
- dispatch({ key: column.field, val: [] });
54
- }, size: "small" },
55
- react_1.default.createElement(Clear_1.default, null))),
56
- react_1.default.createElement(material_1.Tooltip, { title: "Minimize/expand this facet filter" },
57
- react_1.default.createElement(material_1.IconButton, { onClick: () => setVisible(!visible), size: "small" }, visible ? react_1.default.createElement(Minimize_1.default, null) : react_1.default.createElement(Add_1.default, null)))),
58
- visible ? (react_1.default.createElement(material_1.Select, { multiple: true, native: true, className: classes.select, value: filters[column.field], onChange: event => {
59
- // @ts-expect-error
60
- const { options } = event.target;
61
- const val = [];
62
- const len = options.length;
63
- for (let i = 0; i < len; i++) {
64
- if (options[i].selected) {
65
- val.push(options[i].value);
66
- }
67
- }
68
- dispatch({ key: column.field, val });
69
- } }, vals
70
- .sort((a, b) => a[0].localeCompare(b[0]))
71
- .map(([name, count]) => (react_1.default.createElement("option", { key: name, value: name },
72
- name,
73
- " (",
74
- count,
75
- ")"))))) : null));
76
- }
6
+ const react_1 = __importDefault(require("react"));
7
+ const FacetFilter_1 = __importDefault(require("./FacetFilter"));
77
8
  function FacetFilters({ rows, columns, dispatch, filters, width, }) {
9
+ var _a, _b;
78
10
  const facets = columns.slice(1);
79
- const uniqs = facets.map(() => new Map());
80
- for (const row of rows) {
81
- for (const [index, column] of facets.entries()) {
82
- const elt = uniqs[index];
83
- const key = `${row[column.field] || ''}`;
11
+ const uniqs = new Map(facets.map(f => [f.field, new Map()]));
12
+ // this code "stages the facet filters" in order that the user has selected
13
+ // them, which relies on the js behavior that the order of the returned keys is
14
+ // related to the insertion order.
15
+ const filterKeys = Object.keys(filters);
16
+ const facetKeys = facets.map(f => f.field);
17
+ const ret = new Set();
18
+ for (const entry of filterKeys) {
19
+ // give non-empty filters priority
20
+ if ((_a = filters[entry]) === null || _a === void 0 ? void 0 : _a.length) {
21
+ ret.add(entry);
22
+ }
23
+ }
24
+ for (const entry of facetKeys) {
25
+ ret.add(entry);
26
+ }
27
+ let currentRows = rows;
28
+ for (const facet of ret) {
29
+ const elt = uniqs.get(facet);
30
+ for (const row of currentRows) {
31
+ const key = `${row[facet] || ''}`;
84
32
  const val = elt.get(key);
85
33
  // we don't allow filtering on empty yet
86
34
  if (key) {
@@ -92,7 +40,13 @@ function FacetFilters({ rows, columns, dispatch, filters, width, }) {
92
40
  }
93
41
  }
94
42
  }
43
+ const filter = ((_b = filters[facet]) === null || _b === void 0 ? void 0 : _b.length) ? new Set(filters[facet]) : undefined;
44
+ currentRows = currentRows.filter(row => {
45
+ return filter !== undefined ? filter.has(row[facet]) : true;
46
+ });
95
47
  }
96
- return (react_1.default.createElement("div", null, facets.map((column, index) => (react_1.default.createElement(FacetFilter, { key: column.field, vals: [...uniqs[index]], column: column, width: width, dispatch: dispatch, filters: filters })))));
48
+ return (react_1.default.createElement("div", null, facets.map(column => {
49
+ return (react_1.default.createElement(FacetFilter_1.default, { key: column.field, vals: [...uniqs.get(column.field)], column: column, width: width, dispatch: dispatch, filters: filters }));
50
+ })));
97
51
  }
98
52
  exports.default = FacetFilters;
@@ -1,8 +1,7 @@
1
1
  import React from 'react';
2
2
  import { HierarchicalTrackSelectorModel } from '../../model';
3
- declare function FacetedDlg(props: {
3
+ declare const FacetedTrackSelectorDialog: (props: {
4
4
  handleClose: () => void;
5
5
  model: HierarchicalTrackSelectorModel;
6
- }): React.JSX.Element;
7
- declare const _default: typeof FacetedDlg;
8
- export default _default;
6
+ }) => React.JSX.Element;
7
+ export default FacetedTrackSelectorDialog;
@@ -8,10 +8,10 @@ const material_1 = require("@mui/material");
8
8
  const ui_1 = require("@jbrowse/core/ui");
9
9
  const mobx_react_1 = require("mobx-react");
10
10
  const FacetedSelector_1 = __importDefault(require("./FacetedSelector"));
11
- function FacetedDlg(props) {
11
+ const FacetedTrackSelectorDialog = (0, mobx_react_1.observer)(function (props) {
12
12
  const { handleClose } = props;
13
13
  return (react_1.default.createElement(ui_1.Dialog, { open: true, onClose: handleClose, maxWidth: "xl", title: "Faceted track selector" },
14
14
  react_1.default.createElement(material_1.DialogContent, null,
15
15
  react_1.default.createElement(FacetedSelector_1.default, { ...props }))));
16
- }
17
- exports.default = (0, mobx_react_1.observer)(FacetedDlg);
16
+ });
17
+ exports.default = FacetedTrackSelectorDialog;
@@ -1,13 +1,15 @@
1
1
  import React from 'react';
2
2
  import { HierarchicalTrackSelectorModel } from '../../model';
3
- export default function FacetedHeader({ setFilterText, setUseShoppingCart, setHideSparse, setShowOptions, showOptions, hideSparse, useShoppingCart, filterText, model, }: {
3
+ export default function FacetedHeader({ setFilterText, setUseShoppingCart, setShowSparse, setShowFilters, setShowOptions, showOptions, showSparse, showFilters, useShoppingCart, filterText, model, }: {
4
4
  setFilterText: (arg: string) => void;
5
5
  setUseShoppingCart: (arg: boolean) => void;
6
- setHideSparse: (arg: boolean) => void;
6
+ setShowSparse: (arg: boolean) => void;
7
+ setShowFilters: (arg: boolean) => void;
7
8
  setShowOptions: (arg: boolean) => void;
8
9
  filterText: string;
9
10
  showOptions: boolean;
10
11
  useShoppingCart: boolean;
11
- hideSparse: boolean;
12
+ showSparse: boolean;
13
+ showFilters: boolean;
12
14
  model: HierarchicalTrackSelectorModel;
13
15
  }): React.JSX.Element;
@@ -34,7 +34,7 @@ const Clear_1 = __importDefault(require("@mui/icons-material/Clear"));
34
34
  const MoreVert_1 = __importDefault(require("@mui/icons-material/MoreVert"));
35
35
  // locals
36
36
  const ShoppingCart_1 = __importDefault(require("../ShoppingCart"));
37
- function FacetedHeader({ setFilterText, setUseShoppingCart, setHideSparse, setShowOptions, showOptions, hideSparse, useShoppingCart, filterText, model, }) {
37
+ function FacetedHeader({ setFilterText, setUseShoppingCart, setShowSparse, setShowFilters, setShowOptions, showOptions, showSparse, showFilters, useShoppingCart, filterText, model, }) {
38
38
  const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
39
39
  return (react_1.default.createElement(react_1.default.Fragment, null,
40
40
  react_1.default.createElement(material_1.Grid, { container: true, spacing: 4, alignItems: "center" },
@@ -60,9 +60,15 @@ function FacetedHeader({ setFilterText, setUseShoppingCart, setHideSparse, setSh
60
60
  checked: useShoppingCart,
61
61
  },
62
62
  {
63
- label: 'Hide sparse metadata columns',
64
- onClick: () => setHideSparse(!hideSparse),
65
- checked: hideSparse,
63
+ label: 'Show sparse metadata columns',
64
+ onClick: () => setShowSparse(!showSparse),
65
+ checked: showSparse,
66
+ type: 'checkbox',
67
+ },
68
+ {
69
+ label: 'Show facet filters',
70
+ onClick: () => setShowFilters(!showFilters),
71
+ checked: showFilters,
66
72
  type: 'checkbox',
67
73
  },
68
74
  {
@@ -6,7 +6,7 @@ export interface InfoArgs {
6
6
  id: string;
7
7
  conf: AnyConfigurationModel;
8
8
  }
9
- declare const _default: ({ model, }: {
9
+ declare const FacetedSelector: ({ model, }: {
10
10
  model: HierarchicalTrackSelectorModel;
11
11
  }) => React.JSX.Element;
12
- export default _default;
12
+ export default FacetedSelector;
@@ -37,40 +37,48 @@ const tracks_1 = require("@jbrowse/core/util/tracks");
37
37
  const ui_1 = require("@jbrowse/core/ui");
38
38
  const SanitizedHTML_1 = __importDefault(require("@jbrowse/core/ui/SanitizedHTML"));
39
39
  const Menu_1 = __importDefault(require("@jbrowse/core/ui/Menu"));
40
- const ResizeBar_1 = __importStar(require("@jbrowse/core/ui/ResizeBar"));
40
+ const ResizeBar_1 = __importDefault(require("@jbrowse/core/ui/ResizeBar"));
41
41
  const util_1 = require("@jbrowse/core/util");
42
42
  const configuration_1 = require("@jbrowse/core/configuration");
43
+ const useResizeBar_1 = require("@jbrowse/core/ui/useResizeBar");
44
+ const mui_1 = require("tss-react/mui");
43
45
  // icons
44
46
  const MoreHoriz_1 = __importDefault(require("@mui/icons-material/MoreHoriz"));
45
- // locals
46
- const model_1 = require("../../model");
47
+ const util_2 = require("../../util");
47
48
  const FacetedHeader_1 = __importDefault(require("./FacetedHeader"));
48
49
  const FacetFilters_1 = __importDefault(require("./FacetFilters"));
49
- const util_2 = require("./util");
50
+ const util_3 = require("./util");
50
51
  const nonMetadataKeys = ['category', 'adapter', 'description'];
52
+ const useStyles = (0, mui_1.makeStyles)()({
53
+ cell: {
54
+ whiteSpace: 'nowrap',
55
+ overflow: 'hidden',
56
+ textOverflow: 'ellipsis',
57
+ },
58
+ });
51
59
  const frac = 0.75;
52
- exports.default = (0, mobx_react_1.observer)(function FacetedSelector({ model, }) {
60
+ const FacetedSelector = (0, mobx_react_1.observer)(function FacetedSelector({ model, }) {
53
61
  var _a, _b;
62
+ const { classes } = useStyles();
54
63
  const { view, selection } = model;
55
64
  const { pluginManager } = (0, util_1.getEnv)(model);
56
- const { ref, scrollLeft } = (0, ResizeBar_1.useResizeBar)();
65
+ const { ref, scrollLeft } = (0, useResizeBar_1.useResizeBar)();
57
66
  const [filterText, setFilterText] = (0, react_1.useState)('');
58
- const [showOptions, setShowOptions] = (0, react_1.useState)(false);
67
+ const [showOptions, setShowOptions] = (0, util_1.useLocalStorage)('facet-showTableOptions', false);
59
68
  const [info, setInfo] = (0, react_1.useState)();
60
69
  const [useShoppingCart, setUseShoppingCart] = (0, react_1.useState)(false);
61
- const [hideSparse, setHideSparse] = (0, react_1.useState)(true);
62
- const [panelWidth, setPanelWidth] = (0, react_1.useState)(400);
70
+ const [showSparse, setShowSparse] = (0, util_1.useLocalStorage)('facet-showSparse', false);
71
+ const [showFilters, setShowFilters] = (0, util_1.useLocalStorage)('facet-showFilters', true);
72
+ const [panelWidth, setPanelWidth] = (0, util_1.useLocalStorage)('facet-panelWidth', 400);
63
73
  const session = (0, util_1.getSession)(model);
64
74
  const filterDebounced = (0, util_1.useDebounce)(filterText, 400);
65
75
  const tracks = view.tracks;
66
- const [filters, dispatch] = (0, react_1.useReducer)((state, update) => {
67
- return { ...state, [update.key]: update.val };
68
- }, {});
76
+ const [filters, dispatch] = (0, react_1.useReducer)((state, update) => ({ ...state, [update.key]: update.val }), {});
69
77
  const rows = (0, react_1.useMemo)(() => {
70
78
  // metadata is spread onto the object for easier access and sorting
71
79
  // by the mui data grid (it's unable to sort by nested objects)
72
80
  return model.trackConfigurations
73
- .filter(conf => (0, model_1.matches)(filterDebounced, conf, session))
81
+ .filter(conf => (0, util_2.matches)(filterDebounced, conf, session))
74
82
  .map(track => {
75
83
  var _a, _b;
76
84
  const metadata = (0, configuration_1.readConfObject)(track, 'metadata');
@@ -86,10 +94,10 @@ exports.default = (0, mobx_react_1.observer)(function FacetedSelector({ model, }
86
94
  };
87
95
  });
88
96
  }, [model, filterDebounced, session]);
89
- const filteredNonMetadataKeys = (0, react_1.useMemo)(() => nonMetadataKeys.filter(f => !hideSparse ? true : rows.map(r => r[f]).filter(f => !!f).length > 5), [hideSparse, rows]);
90
- const filteredMetadataKeys = (0, react_1.useMemo)(() => [...new Set(rows.flatMap(row => (0, util_2.getRootKeys)(row.metadata)))].filter(f => !hideSparse
97
+ const filteredNonMetadataKeys = (0, react_1.useMemo)(() => nonMetadataKeys.filter(f => showSparse ? true : rows.map(r => r[f]).filter(f => !!f).length > 5), [showSparse, rows]);
98
+ const filteredMetadataKeys = (0, react_1.useMemo)(() => [...new Set(rows.flatMap(row => (0, util_3.getRootKeys)(row.metadata)))].filter(f => showSparse
91
99
  ? true
92
- : rows.map(r => r.metadata[f]).filter(f => !!f).length > 5), [hideSparse, rows]);
100
+ : rows.map(r => r.metadata[f]).filter(f => !!f).length > 5), [showSparse, rows]);
93
101
  const fields = (0, react_1.useMemo)(() => ['name', ...filteredNonMetadataKeys, ...filteredMetadataKeys], [filteredNonMetadataKeys, filteredMetadataKeys]);
94
102
  const [widths, setWidths] = (0, react_1.useState)({
95
103
  name: (0, util_1.measureGridWidth)(rows.map(r => r.name), { maxWidth: 500, stripHTML: true }) + 15,
@@ -125,15 +133,15 @@ exports.default = (0, mobx_react_1.observer)(function FacetedSelector({ model, }
125
133
  (0, util_1.measureGridWidth)(rows.map(r => r.metadata[e]), { stripHTML: true, maxWidth: 400 }),
126
134
  ])),
127
135
  }));
128
- }, [filteredMetadataKeys, visible, filteredNonMetadataKeys, hideSparse, rows]);
129
- const widthsDebounced = (0, util_1.useDebounce)(widths, 400);
136
+ }, [filteredMetadataKeys, visible, filteredNonMetadataKeys, showSparse, rows]);
137
+ const widthsDebounced = (0, util_1.useDebounce)(widths, 200);
130
138
  const columns = [
131
139
  {
132
140
  field: 'name',
133
141
  hideable: false,
134
142
  renderCell: (params) => {
135
143
  const { value, id, row } = params;
136
- return (react_1.default.createElement(react_1.default.Fragment, null,
144
+ return (react_1.default.createElement("div", { className: classes.cell },
137
145
  react_1.default.createElement(SanitizedHTML_1.default, { html: value }),
138
146
  react_1.default.createElement(material_1.IconButton, { onClick: e => setInfo({
139
147
  target: e.currentTarget,
@@ -151,7 +159,7 @@ exports.default = (0, mobx_react_1.observer)(function FacetedSelector({ model, }
151
159
  width: (_a = widthsDebounced[e]) !== null && _a !== void 0 ? _a : 100,
152
160
  renderCell: (params) => {
153
161
  const { value } = params;
154
- return value ? react_1.default.createElement(SanitizedHTML_1.default, { html: value }) : '';
162
+ return (react_1.default.createElement("div", { className: classes.cell }, value ? react_1.default.createElement(SanitizedHTML_1.default, { html: value }) : ''));
155
163
  },
156
164
  });
157
165
  }),
@@ -162,19 +170,22 @@ exports.default = (0, mobx_react_1.observer)(function FacetedSelector({ model, }
162
170
  width: (_a = widthsDebounced[e]) !== null && _a !== void 0 ? _a : 100,
163
171
  renderCell: (params) => {
164
172
  const { value } = params;
165
- return value ? react_1.default.createElement(SanitizedHTML_1.default, { html: value }) : '';
173
+ return (react_1.default.createElement("div", { className: classes.cell }, value ? react_1.default.createElement(SanitizedHTML_1.default, { html: value }) : ''));
166
174
  },
167
175
  });
168
176
  }),
169
177
  ];
170
- const shownTrackIds = tracks.map(t => t.configuration.trackId);
171
- const arrFilters = Object.entries(filters).filter(f => f[1].length > 0);
178
+ const shownTrackIds = new Set(tracks.map(t => t.configuration.trackId));
179
+ const arrFilters = Object.entries(filters)
180
+ .filter(f => f[1].length > 0)
181
+ .map(([key, val]) => [key, new Set(val)]);
182
+ const filteredRows = rows.filter(row => arrFilters.every(([key, val]) => val.has(row[key])));
172
183
  return (react_1.default.createElement(react_1.default.Fragment, null,
173
184
  info ? (react_1.default.createElement(Menu_1.default, { anchorEl: info === null || info === void 0 ? void 0 : info.target, menuItems: ((_b = session.getTrackActionMenuItems) === null || _b === void 0 ? void 0 : _b.call(session, info.conf)) || [], onMenuItemClick: (_event, callback) => {
174
185
  callback();
175
186
  setInfo(undefined);
176
187
  }, open: !!info, onClose: () => setInfo(undefined) })) : null,
177
- react_1.default.createElement(FacetedHeader_1.default, { setHideSparse: setHideSparse, setShowOptions: setShowOptions, setFilterText: setFilterText, setUseShoppingCart: setUseShoppingCart, hideSparse: hideSparse, showOptions: showOptions, filterText: filterText, useShoppingCart: useShoppingCart, model: model }),
188
+ react_1.default.createElement(FacetedHeader_1.default, { setShowSparse: setShowSparse, setShowFilters: setShowFilters, setShowOptions: setShowOptions, setFilterText: setFilterText, setUseShoppingCart: setUseShoppingCart, showFilters: showFilters, showSparse: showSparse, showOptions: showOptions, filterText: filterText, useShoppingCart: useShoppingCart, model: model }),
178
189
  react_1.default.createElement("div", { ref: ref, style: {
179
190
  display: 'flex',
180
191
  overflow: 'hidden',
@@ -183,21 +194,22 @@ exports.default = (0, mobx_react_1.observer)(function FacetedSelector({ model, }
183
194
  } },
184
195
  react_1.default.createElement("div", { style: {
185
196
  height: window.innerHeight * frac,
186
- width: window.innerWidth * frac - panelWidth,
197
+ width: window.innerWidth * frac - (showFilters ? panelWidth : 0),
187
198
  } },
188
199
  react_1.default.createElement(ResizeBar_1.default, { checkbox: true, widths: Object.values(widths).map(f => f !== null && f !== void 0 ? f : 100), setWidths: newWidths => setWidths(Object.fromEntries(Object.entries(widths).map((entry, idx) => [
189
200
  entry[0],
190
201
  newWidths[idx],
191
202
  ]))), scrollLeft: scrollLeft }),
192
- react_1.default.createElement(x_data_grid_1.DataGrid, { rows: rows.filter(row => arrFilters.every(([key, val]) => val.includes(row[key]))), columnVisibilityModel: visible, onColumnVisibilityModelChange: newModel => setVisible(newModel), columnHeaderHeight: 35, checkboxSelection: true, disableRowSelectionOnClick: true, keepNonExistentRowsSelected: true, onRowSelectionModelChange: userSelectedIds => {
203
+ react_1.default.createElement(x_data_grid_1.DataGrid, { rows: filteredRows, columnVisibilityModel: visible, onColumnVisibilityModelChange: newModel => setVisible(newModel), columnHeaderHeight: 35, checkboxSelection: true, disableRowSelectionOnClick: true, keepNonExistentRowsSelected: true, onRowSelectionModelChange: userSelectedIds => {
193
204
  if (!useShoppingCart) {
194
205
  const a1 = shownTrackIds;
195
- const a2 = userSelectedIds;
206
+ const a2 = new Set(userSelectedIds);
196
207
  // synchronize the user selection with the view
197
208
  // see share https://stackoverflow.com/a/33034768/2129219
198
209
  (0, mobx_1.transaction)(() => {
199
- a1.filter(x => !a2.includes(x)).map(t => view.hideTrack(t));
200
- a2.filter(x => !a1.includes(x)).map(t => view.showTrack(t));
210
+ ;
211
+ [...a1].filter(x => !a2.has(x)).map(t => view.hideTrack(t));
212
+ [...a2].filter(x => !a1.has(x)).map(t => view.showTrack(t));
201
213
  });
202
214
  }
203
215
  else {
@@ -206,10 +218,18 @@ exports.default = (0, mobx_react_1.observer)(function FacetedSelector({ model, }
206
218
  const tracks = userSelectedIds.map(id => (0, mobx_state_tree_1.resolveIdentifier)(schema, root, id));
207
219
  model.setSelection(tracks);
208
220
  }
209
- }, rowSelectionModel: useShoppingCart ? selection.map(s => s.trackId) : shownTrackIds, slots: { toolbar: showOptions ? x_data_grid_1.GridToolbar : null }, slotProps: {
221
+ }, rowSelectionModel: useShoppingCart
222
+ ? selection.map(s => s.trackId)
223
+ : [...shownTrackIds], slots: { toolbar: showOptions ? x_data_grid_1.GridToolbar : null }, slotProps: {
210
224
  toolbar: { printOptions: { disableToolbarButton: true } },
211
225
  }, columns: columns, rowHeight: 25 })),
212
- react_1.default.createElement(ui_1.ResizeHandle, { vertical: true, onDrag: dist => setPanelWidth(panelWidth - dist), style: { background: 'grey', width: 5 } }),
213
- react_1.default.createElement("div", { style: { width: panelWidth, overflowY: 'auto', overflowX: 'hidden' } },
214
- react_1.default.createElement(FacetFilters_1.default, { width: panelWidth - 10, rows: rows, columns: columns, dispatch: dispatch, filters: filters })))));
226
+ showFilters ? (react_1.default.createElement(react_1.default.Fragment, null,
227
+ react_1.default.createElement(ui_1.ResizeHandle, { vertical: true, onDrag: dist => setPanelWidth(panelWidth - dist), style: { marginLeft: 5, background: 'grey', width: 5 } }),
228
+ react_1.default.createElement("div", { style: {
229
+ width: panelWidth,
230
+ overflowY: 'auto',
231
+ overflowX: 'hidden',
232
+ } },
233
+ react_1.default.createElement(FacetFilters_1.default, { width: panelWidth - 10, rows: rows, columns: columns, dispatch: dispatch, filters: filters })))) : null)));
215
234
  });
235
+ exports.default = FacetedSelector;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { HierarchicalTrackSelectorModel } from '../../model';
3
- declare const _default: ({ model, }: {
3
+ declare const HamburgerMenu: ({ model, }: {
4
4
  model: HierarchicalTrackSelectorModel;
5
5
  }) => React.JSX.Element;
6
- export default _default;
6
+ export default HamburgerMenu;
@@ -27,36 +27,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const react_1 = __importStar(require("react"));
30
- const material_1 = require("@mui/material");
31
- const mui_1 = require("tss-react/mui");
32
30
  const mobx_react_1 = require("mobx-react");
33
- const Menu_1 = __importDefault(require("@jbrowse/core/ui/Menu"));
34
31
  const util_1 = require("@jbrowse/core/util");
35
32
  const configuration_1 = require("@jbrowse/core/configuration");
33
+ const CascadingMenuButton_1 = __importDefault(require("@jbrowse/core/ui/CascadingMenuButton"));
36
34
  // icons
37
- const Menu_2 = __importDefault(require("@mui/icons-material/Menu"));
35
+ const Menu_1 = __importDefault(require("@mui/icons-material/Menu"));
38
36
  // lazy components
39
37
  const CloseConnectionDlg = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../dialogs/CloseConnectionDialog'))));
40
38
  const DeleteConnectionDlg = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../dialogs/DeleteConnectionDialog'))));
41
39
  const ManageConnectionsDlg = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../dialogs/ManageConnectionsDialog'))));
42
40
  const ToggleConnectionsDlg = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../dialogs/ToggleConnectionsDialog'))));
43
- const useStyles = (0, mui_1.makeStyles)()(theme => ({
44
- menuIcon: {
45
- marginRight: theme.spacing(1),
46
- marginBottom: 0,
47
- },
48
- }));
49
- exports.default = (0, mobx_react_1.observer)(function HamburgerMenu({ model, }) {
41
+ const HamburgerMenu = (0, mobx_react_1.observer)(function ({ model, }) {
50
42
  const session = (0, util_1.getSession)(model);
51
- const [menuEl, setMenuEl] = (0, react_1.useState)();
52
43
  const [modalInfo, setModalInfo] = (0, react_1.useState)();
53
44
  const [deleteDlgDetails, setDeleteDlgDetails] = (0, react_1.useState)();
54
45
  const [connectionToggleOpen, setConnectionToggleOpen] = (0, react_1.useState)(false);
55
46
  const [connectionManagerOpen, setConnectionManagerOpen] = (0, react_1.useState)(false);
56
- const { classes } = useStyles();
57
47
  function breakConnection(connectionConf, deletingConnection) {
48
+ var _a;
58
49
  const name = (0, configuration_1.readConfObject)(connectionConf, 'name');
59
- const result = session.prepareToBreakConnection(connectionConf);
50
+ const result = (_a = session.prepareToBreakConnection) === null || _a === void 0 ? void 0 : _a.call(session, connectionConf);
60
51
  if (result) {
61
52
  const [safelyBreakConnection, dereferenceTypeCount] = result;
62
53
  if (Object.keys(dereferenceTypeCount).length > 0) {
@@ -76,12 +67,7 @@ exports.default = (0, mobx_react_1.observer)(function HamburgerMenu({ model, })
76
67
  }
77
68
  }
78
69
  return (react_1.default.createElement(react_1.default.Fragment, null,
79
- react_1.default.createElement(material_1.IconButton, { className: classes.menuIcon, onClick: event => setMenuEl(event.currentTarget) },
80
- react_1.default.createElement(Menu_2.default, null)),
81
- react_1.default.createElement(Menu_1.default, { anchorEl: menuEl, open: Boolean(menuEl), onMenuItemClick: (_, callback) => {
82
- callback();
83
- setMenuEl(undefined);
84
- }, onClose: () => setMenuEl(undefined), menuItems: [
70
+ react_1.default.createElement(CascadingMenuButton_1.default, { menuItems: [
85
71
  ...((0, util_1.isSessionWithAddTracks)(session)
86
72
  ? [
87
73
  {
@@ -120,10 +106,42 @@ exports.default = (0, mobx_react_1.observer)(function HamburgerMenu({ model, })
120
106
  },
121
107
  ]
122
108
  : []),
123
- ] }),
109
+ { type: 'divider' },
110
+ {
111
+ label: 'Sort tracks by name',
112
+ type: 'checkbox',
113
+ checked: model.activeSortTrackNames,
114
+ onClick: () => model.setSortTrackNames(!model.activeSortTrackNames),
115
+ },
116
+ {
117
+ label: 'Sort categories by name',
118
+ type: 'checkbox',
119
+ checked: model.activeSortCategories,
120
+ onClick: () => model.setSortCategories(!model.activeSortCategories),
121
+ },
122
+ { type: 'divider' },
123
+ ...(model.hasAnySubcategories
124
+ ? [
125
+ {
126
+ label: 'Collapse subcategories',
127
+ onClick: () => model.collapseSubCategories(),
128
+ },
129
+ ]
130
+ : []),
131
+ {
132
+ label: 'Collapse top-level categories',
133
+ onClick: () => model.collapseTopLevelCategories(),
134
+ },
135
+ {
136
+ label: 'Expand all categories',
137
+ onClick: () => model.expandAllCategories(),
138
+ },
139
+ ] },
140
+ react_1.default.createElement(Menu_1.default, null)),
124
141
  react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(react_1.default.Fragment, null) },
125
142
  modalInfo ? (react_1.default.createElement(CloseConnectionDlg, { modalInfo: modalInfo, onClose: () => setModalInfo(undefined) })) : null,
126
143
  deleteDlgDetails ? (react_1.default.createElement(DeleteConnectionDlg, { handleClose: () => setDeleteDlgDetails(undefined), deleteDialogDetails: deleteDlgDetails, session: session })) : null,
127
144
  connectionManagerOpen ? (react_1.default.createElement(ManageConnectionsDlg, { handleClose: () => setConnectionManagerOpen(false), breakConnection: breakConnection, session: session })) : null,
128
145
  connectionToggleOpen ? (react_1.default.createElement(ToggleConnectionsDlg, { handleClose: () => setConnectionToggleOpen(false), session: session, breakConnection: breakConnection })) : null)));
129
146
  });
147
+ exports.default = HamburgerMenu;
@@ -1,8 +1,7 @@
1
1
  import React from 'react';
2
2
  import { HierarchicalTrackSelectorModel } from '../../model';
3
- declare function HierarchicalTrackSelectorHeader({ model, setHeaderHeight, }: {
3
+ declare const HierarchicalTrackSelectorHeader: ({ model, setHeaderHeight, }: {
4
4
  model: HierarchicalTrackSelectorModel;
5
5
  setHeaderHeight: (n: number) => void;
6
- }): React.JSX.Element;
7
- declare const _default: typeof HierarchicalTrackSelectorHeader;
8
- export default _default;
6
+ }) => React.JSX.Element;
7
+ export default HierarchicalTrackSelectorHeader;
@@ -45,20 +45,24 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
45
45
  marginBottom: 0,
46
46
  },
47
47
  }));
48
- function HierarchicalTrackSelectorHeader({ model, setHeaderHeight, }) {
48
+ const SearchTracksTextField = (0, mobx_react_1.observer)(function ({ model, }) {
49
+ const { filterText } = model;
50
+ const { classes } = useStyles();
51
+ return (react_1.default.createElement(material_1.TextField, { className: classes.searchBox, label: "Filter tracks", value: filterText, onChange: event => model.setFilterText(event.target.value), fullWidth: true, InputProps: {
52
+ endAdornment: (react_1.default.createElement(material_1.InputAdornment, { position: "end" },
53
+ react_1.default.createElement(material_1.IconButton, { onClick: () => model.clearFilterText() },
54
+ react_1.default.createElement(Clear_1.default, null)))),
55
+ } }));
56
+ });
57
+ const HierarchicalTrackSelectorHeader = (0, mobx_react_1.observer)(function ({ model, setHeaderHeight, }) {
49
58
  const { classes } = useStyles();
50
59
  const [facetedOpen, setFacetedOpen] = (0, react_1.useState)(false);
51
- const { filterText } = model;
52
60
  return (react_1.default.createElement("div", { ref: ref => setHeaderHeight((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().height) || 0), "data-testid": "hierarchical_track_selector" },
53
61
  react_1.default.createElement("div", { style: { display: 'flex' } },
54
62
  react_1.default.createElement(HamburgerMenu_1.default, { model: model }),
55
63
  react_1.default.createElement(ShoppingCart_1.default, { model: model }),
56
- react_1.default.createElement(material_1.TextField, { className: classes.searchBox, label: "Filter tracks", value: filterText, onChange: event => model.setFilterText(event.target.value), fullWidth: true, InputProps: {
57
- endAdornment: (react_1.default.createElement(material_1.InputAdornment, { position: "end" },
58
- react_1.default.createElement(material_1.IconButton, { onClick: () => model.clearFilterText() },
59
- react_1.default.createElement(Clear_1.default, null)))),
60
- } }),
64
+ react_1.default.createElement(SearchTracksTextField, { model: model }),
61
65
  react_1.default.createElement(material_1.Button, { className: classes.menuIcon, onClick: () => setFacetedOpen(true) }, "Open faceted selector")),
62
66
  react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement("div", null) }, facetedOpen ? (react_1.default.createElement(FacetedDialog, { handleClose: () => setFacetedOpen(false), model: model })) : null)));
63
- }
64
- exports.default = (0, mobx_react_1.observer)(HierarchicalTrackSelectorHeader);
67
+ });
68
+ exports.default = HierarchicalTrackSelectorHeader;