@haniffalab/cherita-react 1.2.0-dev.2025-04-29.181538d6 → 1.2.0-dev.2025-05-16.4367ee63

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 (33) hide show
  1. package/dist/cjs/components/full-page/FullPage.js +19 -26
  2. package/dist/cjs/components/full-page/FullPagePseudospatial.js +20 -26
  3. package/dist/cjs/components/offcanvas/index.js +1 -2
  4. package/dist/cjs/components/scatterplot/Scatterplot.js +8 -2
  5. package/dist/cjs/components/scatterplot/SpatialControls.js +46 -17
  6. package/dist/cjs/components/scatterplot/Toolbox.js +1 -18
  7. package/dist/cjs/components/search-bar/SearchBar.js +152 -57
  8. package/dist/cjs/components/search-bar/SearchInfo.js +175 -0
  9. package/dist/cjs/components/search-bar/SearchResults.js +58 -33
  10. package/dist/cjs/components/var-list/VarItem.js +70 -0
  11. package/dist/cjs/components/var-list/VarList.js +7 -91
  12. package/dist/cjs/components/var-list/VarSet.js +42 -16
  13. package/dist/cjs/utils/Legend.js +14 -8
  14. package/dist/css/cherita.css +60 -10
  15. package/dist/css/cherita.css.map +1 -1
  16. package/dist/esm/components/full-page/FullPage.js +20 -27
  17. package/dist/esm/components/full-page/FullPagePseudospatial.js +21 -27
  18. package/dist/esm/components/offcanvas/index.js +1 -2
  19. package/dist/esm/components/scatterplot/Scatterplot.js +8 -2
  20. package/dist/esm/components/scatterplot/SpatialControls.js +47 -18
  21. package/dist/esm/components/scatterplot/Toolbox.js +1 -18
  22. package/dist/esm/components/search-bar/SearchBar.js +153 -59
  23. package/dist/esm/components/search-bar/SearchInfo.js +165 -0
  24. package/dist/esm/components/search-bar/SearchResults.js +60 -35
  25. package/dist/esm/components/var-list/VarItem.js +70 -2
  26. package/dist/esm/components/var-list/VarList.js +7 -91
  27. package/dist/esm/components/var-list/VarSet.js +44 -18
  28. package/dist/esm/utils/Legend.js +14 -8
  29. package/package.json +2 -2
  30. package/scss/cherita.scss +44 -5
  31. package/scss/components/layouts.scss +20 -13
  32. package/scss/components/lists.scss +11 -0
  33. package/scss/components/plots.scss +3 -5
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DiseaseInfo = DiseaseInfo;
7
+ exports.VarInfo = VarInfo;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
10
+ var _reactFontawesome = require("@fortawesome/react-fontawesome");
11
+ var _lodash = _interopRequireDefault(require("lodash"));
12
+ var _reactBootstrap = require("react-bootstrap");
13
+ var _constants = require("../../constants/constants");
14
+ var _DatasetContext = require("../../context/DatasetContext");
15
+ var _requests = require("../../utils/requests");
16
+ var _VarItem = require("../var-list/VarItem");
17
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
19
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
20
+ function VarInfo(_ref) {
21
+ let {
22
+ varItem
23
+ } = _ref;
24
+ const ENDPOINT = "disease/gene";
25
+ const dataset = (0, _DatasetContext.useDataset)();
26
+ const [params, setParams] = (0, _react.useState)({
27
+ geneName: varItem.name,
28
+ diseaseDatasets: dataset.diseaseDatasets
29
+ });
30
+ (0, _react.useEffect)(() => {
31
+ setParams(p => {
32
+ return {
33
+ ...p,
34
+ geneName: varItem.name
35
+ };
36
+ });
37
+ }, [varItem.name]);
38
+ const {
39
+ fetchedData,
40
+ isPending,
41
+ serverError
42
+ } = (0, _requests.useFetch)(ENDPOINT, params, {
43
+ refetchOnMount: false,
44
+ enabled: !!dataset.diseaseDatasets.length
45
+ });
46
+ const hasDiseaseInfo = !isPending && !serverError && !!fetchedData?.length;
47
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h5", null, varItem.name), !!dataset.diseaseDatasets.length && isPending && /*#__PURE__*/_react.default.createElement("p", null, "Loading..."), hasDiseaseInfo && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("h6", null, "Associated diseases"), /*#__PURE__*/_react.default.createElement(_VarItem.VarDiseaseInfo, {
48
+ data: fetchedData
49
+ })));
50
+ }
51
+ const useVarMean = function (varKeys) {
52
+ let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
53
+ const ENDPOINT = "matrix/mean";
54
+ const dataset = (0, _DatasetContext.useDataset)();
55
+ const [params, setParams] = (0, _react.useState)({
56
+ url: dataset.url,
57
+ varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
58
+ name: v.name,
59
+ indices: v.vars.map(v => v.index)
60
+ } : v.index),
61
+ // obsIndices:
62
+ varNamesCol: dataset.varNamesCol
63
+ });
64
+ (0, _react.useEffect)(() => {
65
+ setParams(p => {
66
+ return {
67
+ ...p,
68
+ varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
69
+ name: v.name,
70
+ indices: v.vars.map(v => v.index)
71
+ } : v.index)
72
+ };
73
+ });
74
+ }, [varKeys]);
75
+ return (0, _requests.useFetch)(ENDPOINT, params, {
76
+ enabled: enabled,
77
+ refetchOnMount: false
78
+ });
79
+ };
80
+
81
+ // ensure nulls are lowest values
82
+ const sortMeans = (i, means) => {
83
+ return means[i.name] || _lodash.default.min(_lodash.default.values(means)) - 1;
84
+ };
85
+ function DiseaseInfo(_ref2) {
86
+ let {
87
+ disease,
88
+ handleSelect,
89
+ addVarSet
90
+ } = _ref2;
91
+ const ENDPOINT = "disease/genes";
92
+ const dataset = (0, _DatasetContext.useDataset)();
93
+ const dispatch = (0, _DatasetContext.useDatasetDispatch)();
94
+ const [diseaseVars, setDiseaseVars] = (0, _react.useState)([]);
95
+ const [sortedDiseaseVars, setSortedDiseaseVars] = (0, _react.useState)([]);
96
+ const [params, setParams] = (0, _react.useState)({
97
+ url: dataset.url,
98
+ col: dataset.varNamesCol,
99
+ diseaseDatasets: dataset.diseaseDatasets,
100
+ diseaseId: disease.id
101
+ });
102
+ (0, _react.useEffect)(() => {
103
+ setParams(p => {
104
+ return {
105
+ ...p,
106
+ diseaseId: disease.id
107
+ };
108
+ });
109
+ }, [disease]);
110
+ const diseaseData = (0, _requests.useFetch)(ENDPOINT, params, {
111
+ enabled: !!params.diseaseId,
112
+ refetchOnMount: true
113
+ });
114
+ (0, _react.useEffect)(() => {
115
+ if (!diseaseData.isPending && !diseaseData.serverError) {
116
+ setDiseaseVars(diseaseData.fetchedData);
117
+ }
118
+ }, [diseaseData.fetchedData, diseaseData.isPending, diseaseData.serverError]);
119
+ const varMeans = useVarMean(diseaseVars, !!diseaseVars?.length && dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX);
120
+ (0, _react.useEffect)(() => {
121
+ if (dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX) {
122
+ if (!varMeans.isPending && !varMeans.serverError) {
123
+ setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, o => {
124
+ return sortMeans(o, varMeans.fetchedData);
125
+ }, dataset.varSort.disease.sortOrder));
126
+ }
127
+ } else if (dataset.varSort.disease.sort === _constants.VAR_SORT.NAME) {
128
+ setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, "name", dataset.varSort.disease.sortOrder));
129
+ } else {
130
+ setSortedDiseaseVars(diseaseVars);
131
+ }
132
+ }, [dataset.varSort.disease.sort, dataset.varSort.disease.sortOrder, diseaseVars, varMeans.fetchedData, varMeans.isPending, varMeans.serverError]);
133
+ const diseaseVarList = _lodash.default.map(sortedDiseaseVars, v => {
134
+ return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
135
+ key: v.gene_id
136
+ }, /*#__PURE__*/_react.default.createElement("div", {
137
+ className: "d-flex justify-content-between align-items-center w-100"
138
+ }, v.name, /*#__PURE__*/_react.default.createElement("div", {
139
+ className: "d-flex align-items-center gap-1"
140
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
141
+ type: "button",
142
+ className: "m-0 p-0 px-1",
143
+ variant: "outline-secondary",
144
+ title: "Add to list",
145
+ onClick: () => {
146
+ handleSelect(dispatch, v);
147
+ }
148
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
149
+ icon: _freeSolidSvgIcons.faPlus
150
+ })))));
151
+ });
152
+ const isPending = diseaseData.isPending || varMeans.isPending && dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX;
153
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h5", null, disease.disease_name), /*#__PURE__*/_react.default.createElement("h6", null, "Implicated genes"), isPending ? /*#__PURE__*/_react.default.createElement("p", null, "Loading...") : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
154
+ className: "d-flex justify-content-end mb-2"
155
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
156
+ size: "sm",
157
+ title: "Add all as a set",
158
+ onClick: () => {
159
+ addVarSet(dispatch, {
160
+ name: disease.disease_name,
161
+ vars: _lodash.default.map(diseaseVars, v => {
162
+ return {
163
+ index: v.index,
164
+ name: v.name,
165
+ matrix_index: v.matrix_index
166
+ };
167
+ })
168
+ });
169
+ }
170
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
171
+ icon: _freeSolidSvgIcons.faPlus
172
+ }), " Add all as a set")), /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
173
+ className: "overflow-scroll"
174
+ }, diseaseVarList)));
175
+ }
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.DiseasesSearchResults = DiseasesSearchResults;
7
7
  exports.VarSearchResults = VarSearchResults;
8
8
  var _react = _interopRequireWildcard(require("react"));
9
+ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
10
+ var _reactFontawesome = require("@fortawesome/react-fontawesome");
9
11
  var _lodash = _interopRequireDefault(require("lodash"));
10
12
  var _reactBootstrap = require("react-bootstrap");
11
13
  var _DatasetContext = require("../../context/DatasetContext");
@@ -17,8 +19,10 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
17
19
  function VarSearchResults(_ref) {
18
20
  let {
19
21
  text,
20
- setShowSuggestions,
21
- handleSelect
22
+ handleSelect,
23
+ selectedResult,
24
+ setSelectedResult,
25
+ setResultsLength
22
26
  } = _ref;
23
27
  const [suggestions, setSuggestions] = (0, _react.useState)([]);
24
28
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
@@ -43,51 +47,68 @@ function VarSearchResults(_ref) {
43
47
  });
44
48
  } else {
45
49
  setSuggestions([]);
46
- setShowSuggestions(false);
47
50
  }
48
51
  };
49
52
  return _lodash.default.debounce(setData, 300);
50
- }, [setParams, setShowSuggestions]);
53
+ }, [setParams]);
51
54
  (0, _react.useEffect)(() => {
52
55
  updateParams(text);
53
56
  }, [text, updateParams]);
54
57
  (0, _react.useEffect)(() => {
55
58
  if (!isPending && !serverError) {
56
59
  setSuggestions(fetchedData);
57
- setShowSuggestions(true);
60
+ setResultsLength(fetchedData?.length);
58
61
  }
59
- }, [fetchedData, isPending, serverError, setShowSuggestions]);
62
+ }, [fetchedData, isPending, serverError, setResultsLength]);
60
63
  const getDataAtIndex = index => deferredData[index];
61
- const ItemComponent = item => /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
62
- key: item.name,
63
- as: "button",
64
+ const ItemComponent = item => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
65
+ className: "virtualized-list-wrapper"
66
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
67
+ key: item,
68
+ onClick: () => {
69
+ setSelectedResult(item);
70
+ },
71
+ active: selectedResult?.index === item.index
72
+ }, /*#__PURE__*/_react.default.createElement("div", {
73
+ className: "d-flex justify-content-between align-items-center w-100"
74
+ }, /*#__PURE__*/_react.default.createElement("div", null, item.name), /*#__PURE__*/_react.default.createElement("div", {
75
+ className: "d-flex align-items-center gap-1"
76
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
77
+ type: "button",
78
+ className: "m-0 p-0 px-1",
79
+ variant: "outline-secondary",
80
+ title: "Add to list",
64
81
  disabled: isStale,
65
82
  onClick: () => {
66
83
  handleSelect(dispatch, item);
67
- _lodash.default.delay(() => {
68
- setShowSuggestions(false);
69
- }, 150);
70
84
  }
71
- }, item.name);
72
- return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Header, null, "Features"), /*#__PURE__*/_react.default.createElement("div", {
85
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
86
+ icon: _freeSolidSvgIcons.faPlus
87
+ })))))));
88
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
73
89
  className: "search-results"
90
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
91
+ variant: "flush",
92
+ className: "cherita-list"
74
93
  }, deferredData?.length ? /*#__PURE__*/_react.default.createElement(_VirtualizedList.VirtualizedList, {
75
94
  getDataAtIndex: getDataAtIndex,
76
95
  count: deferredData.length,
77
96
  ItemComponent: ItemComponent,
78
97
  overscan: 500,
79
- estimateSize: 32,
80
- maxHeight: "25vh"
81
- }) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
98
+ estimateSize: 42,
99
+ maxHeight: "70vh"
100
+ }) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
82
101
  key: "empty",
83
102
  as: "button",
84
103
  disabled: true
85
- }, !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data")));
104
+ }, !text.length ? "Search features" : !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data"))));
86
105
  }
87
106
  function DiseasesSearchResults(_ref2) {
88
107
  let {
89
108
  text,
90
- setShowSuggestions
109
+ selectedResult,
110
+ setSelectedResult,
111
+ setResultsLength
91
112
  } = _ref2;
92
113
  const [suggestions, setSuggestions] = (0, _react.useState)([]);
93
114
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
@@ -122,37 +143,41 @@ function DiseasesSearchResults(_ref2) {
122
143
  (0, _react.useEffect)(() => {
123
144
  if (!isPending && !serverError) {
124
145
  setSuggestions(fetchedData);
125
- setShowSuggestions(true);
146
+ setResultsLength(fetchedData?.length);
126
147
  }
127
- }, [fetchedData, isPending, serverError, setShowSuggestions]);
148
+ }, [fetchedData, isPending, serverError, setResultsLength]);
128
149
  const getDataAtIndex = index => deferredData[index];
129
- const ItemComponent = item => /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
150
+ const ItemComponent = item => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
151
+ className: "virtualized-list-wrapper"
152
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
130
153
  key: item.name,
131
- as: "button",
132
- disabled: isStale,
133
154
  onClick: () => {
155
+ setSelectedResult(item);
134
156
  dispatch({
135
157
  type: "select.disease",
136
158
  id: item.disease_id,
137
159
  name: item.disease_name
138
160
  });
139
- _lodash.default.delay(() => {
140
- setShowSuggestions(false);
141
- }, 150);
142
- }
143
- }, item.disease_name);
144
- return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Header, null, "Diseases"), /*#__PURE__*/_react.default.createElement("div", {
161
+ },
162
+ active: selectedResult?.id === item.id
163
+ }, /*#__PURE__*/_react.default.createElement("div", {
164
+ className: "d-flex justify-content-between align-items-center w-100"
165
+ }, /*#__PURE__*/_react.default.createElement("div", null, item.disease_name)))));
166
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
145
167
  className: "search-results"
168
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
169
+ variant: "flush",
170
+ className: "cherita-list"
146
171
  }, deferredData?.length ? /*#__PURE__*/_react.default.createElement(_VirtualizedList.VirtualizedList, {
147
172
  getDataAtIndex: getDataAtIndex,
148
173
  count: deferredData.length,
149
174
  ItemComponent: ItemComponent,
150
175
  overscan: 250,
151
176
  estimateSize: 32,
152
- maxHeight: "25vh"
153
- }) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
177
+ maxHeight: "70vh"
178
+ }) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
154
179
  key: "empty",
155
180
  as: "button",
156
181
  disabled: true
157
- }, !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data")));
182
+ }, !text.length ? "Search diseases" : !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data"))));
158
183
  }
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.SearchResultItem = SearchResultItem;
6
7
  exports.SingleSelectionItem = SingleSelectionItem;
8
+ exports.VarDiseaseInfo = VarDiseaseInfo;
7
9
  exports.VarItem = VarItem;
8
10
  var _react = _interopRequireWildcard(require("react"));
9
11
  var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
@@ -265,4 +267,72 @@ function VarItem(_ref5) {
265
267
  } else {
266
268
  return null;
267
269
  }
270
+ }
271
+ function SearchResultItem(_ref6) {
272
+ let {
273
+ item,
274
+ isActive,
275
+ selectVar,
276
+ removeVar,
277
+ isDiseaseGene = false,
278
+ showSetColorEncoding = true,
279
+ showRemove = true
280
+ } = _ref6;
281
+ const ENDPOINT = "disease/gene";
282
+ const [openInfo, setOpenInfo] = (0, _react.useState)(false);
283
+ const dataset = (0, _DatasetContext.useDataset)();
284
+ const params = {
285
+ geneName: item.name,
286
+ diseaseDatasets: dataset.diseaseDatasets
287
+ };
288
+ const isNotInData = item.matrix_index === -1;
289
+ const {
290
+ fetchedData,
291
+ isPending,
292
+ serverError
293
+ } = (0, _requests.useFetch)(ENDPOINT, params, {
294
+ refetchOnMount: false,
295
+ enabled: !!dataset.diseaseDatasets.length
296
+ });
297
+ const hasDiseaseInfo = !isPending && !serverError && !!fetchedData?.length;
298
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
299
+ className: `d-flex justify-content-between ${hasDiseaseInfo ? "cursor-pointer" : ""}`,
300
+ onClick: () => {
301
+ setOpenInfo(o => !o);
302
+ }
303
+ }, /*#__PURE__*/_react.default.createElement("div", {
304
+ className: "d-flex justify-content-between align-items-center w-100"
305
+ }, /*#__PURE__*/_react.default.createElement("div", null, item.name), /*#__PURE__*/_react.default.createElement("div", {
306
+ className: "d-flex align-items-center gap-1"
307
+ }, hasDiseaseInfo && /*#__PURE__*/_react.default.createElement(_iconsMaterial.MoreVert, null), showSetColorEncoding && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
308
+ type: "button",
309
+ key: item.matrix_index,
310
+ variant: isActive ? "primary" : isNotInData ? "outline-secondary" : "outline-primary",
311
+ className: "m-0 p-0 px-1",
312
+ onClick: e => {
313
+ e.stopPropagation();
314
+ selectVar();
315
+ },
316
+ disabled: isNotInData,
317
+ title: isNotInData ? "Not present in data" : "Set as color encoding"
318
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
319
+ icon: _freeSolidSvgIcons.faDroplet
320
+ })), (!isDiseaseGene || !showRemove) && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
321
+ type: "button",
322
+ className: "m-0 p-0 px-1",
323
+ variant: "outline-secondary",
324
+ title: "Remove from list",
325
+ onClick: e => {
326
+ e.stopPropagation();
327
+ removeVar();
328
+ }
329
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
330
+ icon: _freeSolidSvgIcons.faTrash
331
+ }))))), hasDiseaseInfo && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Collapse, {
332
+ in: openInfo
333
+ }, /*#__PURE__*/_react.default.createElement("div", {
334
+ className: "mt-2 var-disease-info-collapse"
335
+ }, /*#__PURE__*/_react.default.createElement(VarDiseaseInfo, {
336
+ data: fetchedData
337
+ }))));
268
338
  }
@@ -10,13 +10,13 @@ var _reactFontawesome = require("@fortawesome/react-fontawesome");
10
10
  var _lodash = _interopRequireDefault(require("lodash"));
11
11
  var _reactBootstrap = require("react-bootstrap");
12
12
  var _ButtonGroup = _interopRequireDefault(require("react-bootstrap/ButtonGroup"));
13
+ var _VarItem = require("./VarItem");
14
+ var _VarListToolbar = require("./VarListToolbar");
15
+ var _VarSet = require("./VarSet");
13
16
  var _constants = require("../../constants/constants");
14
17
  var _DatasetContext = require("../../context/DatasetContext");
15
18
  var _LoadingIndicators = require("../../utils/LoadingIndicators");
16
19
  var _requests = require("../../utils/requests");
17
- var _VarItem = require("./VarItem");
18
- var _VarListToolbar = require("./VarListToolbar");
19
- var _VarSet = require("./VarSet");
20
20
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
21
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
22
22
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -54,93 +54,11 @@ const useVarMean = function (varKeys) {
54
54
  const sortMeans = (i, means) => {
55
55
  return means[i.name] || _lodash.default.min(_lodash.default.values(means)) - 1;
56
56
  };
57
-
58
- // @TODO: display where disease data comes from
59
- // add to disease dataset metadata
60
- function DiseaseVarList(_ref) {
61
- let {
62
- makeListItem
63
- } = _ref;
64
- const ENDPOINT = "disease/genes";
65
- const dataset = (0, _DatasetContext.useDataset)();
66
- const dispatch = (0, _DatasetContext.useDatasetDispatch)();
67
- const [diseaseVars, setDiseaseVars] = (0, _react.useState)([]);
68
- const [sortedDiseaseVars, setSortedDiseaseVars] = (0, _react.useState)([]);
69
- const [params, setParams] = (0, _react.useState)({
70
- url: dataset.url,
71
- col: dataset.varNamesCol,
72
- diseaseId: dataset.selectedDisease?.id,
73
- diseaseDatasets: dataset.diseaseDatasets
74
- });
75
- (0, _react.useEffect)(() => {
76
- setParams(p => {
77
- return {
78
- ...p,
79
- diseaseId: dataset.selectedDisease?.id
80
- };
81
- });
82
- }, [dataset.selectedDisease]);
83
- const diseaseData = (0, _requests.useFetch)(ENDPOINT, params, {
84
- enabled: !!params.diseaseId,
85
- refetchOnMount: false
86
- });
87
- (0, _react.useEffect)(() => {
88
- if (!diseaseData.isPending && !diseaseData.serverError) {
89
- setDiseaseVars(diseaseData.fetchedData);
90
- }
91
- }, [diseaseData.fetchedData, diseaseData.isPending, diseaseData.serverError]);
92
- const varMeans = useVarMean(diseaseVars, !!diseaseVars?.length && dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX);
93
- (0, _react.useEffect)(() => {
94
- if (dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX) {
95
- if (!varMeans.isPending && !varMeans.serverError) {
96
- setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, o => {
97
- return sortMeans(o, varMeans.fetchedData);
98
- }, dataset.varSort.disease.sortOrder));
99
- }
100
- } else if (dataset.varSort.disease.sort === _constants.VAR_SORT.NAME) {
101
- setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, "name", dataset.varSort.disease.sortOrder));
102
- } else {
103
- setSortedDiseaseVars(diseaseVars);
104
- }
105
- }, [dataset.varSort.disease.sort, dataset.varSort.disease.sortOrder, diseaseVars, varMeans.fetchedData, varMeans.isPending, varMeans.serverError]);
106
- const diseaseVarList = _lodash.default.map(sortedDiseaseVars, item => {
107
- return makeListItem(item, true);
108
- });
109
- const isPending = diseaseData.isPending || varMeans.isPending && dataset.varSort.disease.sort === _constants.VAR_SORT.MATRIX;
110
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, dataset.selectedDisease && (!isPending && !diseaseVars?.length ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
111
- className: "d-flex justify-content-between mt-3"
112
- }, /*#__PURE__*/_react.default.createElement("h5", null, "Disease genes")), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
113
- variant: "light"
114
- }, "No disease genes found.")) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
115
- className: "d-flex justify-content-between my-2"
116
- }, /*#__PURE__*/_react.default.createElement("h5", null, "Disease genes"), /*#__PURE__*/_react.default.createElement(_ButtonGroup.default, {
117
- "aria-label": "Feature options",
118
- size: "sm"
119
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
120
- variant: "info",
121
- onClick: () => {
122
- dispatch({
123
- type: "reset.disease"
124
- });
125
- }
126
- }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
127
- icon: _freeSolidSvgIcons.faTimes,
128
- className: "me-1"
129
- }), "Clear"))), /*#__PURE__*/_react.default.createElement("p", null, dataset.selectedDisease?.name), /*#__PURE__*/_react.default.createElement(_VarListToolbar.VarListToolbar, {
130
- varType: "disease"
131
- }), /*#__PURE__*/_react.default.createElement("div", {
132
- className: "position-relative"
133
- }, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
134
- variant: "flush",
135
- className: "cherita-list"
136
- }, diseaseVarList)))));
137
- }
138
- function VarNamesList(_ref2) {
57
+ function VarNamesList(_ref) {
139
58
  let {
140
59
  mode = _constants.SELECTION_MODES.SINGLE,
141
- displayName = "genes",
142
- showDiseaseVarList = true
143
- } = _ref2;
60
+ displayName = "genes"
61
+ } = _ref;
144
62
  const dataset = (0, _DatasetContext.useDataset)();
145
63
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
146
64
  const [varButtons, setVarButtons] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? dataset.selectedVar ? _lodash.default.unionWith([dataset.selectedVar], dataset.varSets, _lodash.default.isEqual) : [...dataset.varSets] : [...dataset.selectedMultiVar, ...dataset.varSets]);
@@ -294,7 +212,5 @@ function VarNamesList(_ref2) {
294
212
  }, isPending && /*#__PURE__*/_react.default.createElement(_LoadingIndicators.LoadingSpinner, null), /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
295
213
  variant: "flush",
296
214
  className: "cherita-list"
297
- }, varList)))), /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, showDiseaseVarList && /*#__PURE__*/_react.default.createElement(DiseaseVarList, {
298
- makeListItem: makeListItem
299
- }))));
215
+ }, varList))))));
300
216
  }
@@ -7,13 +7,12 @@ exports.VarSet = VarSet;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
9
9
  var _reactFontawesome = require("@fortawesome/react-fontawesome");
10
- var _iconsMaterial = require("@mui/icons-material");
11
10
  var _lodash = _interopRequireDefault(require("lodash"));
12
11
  var _reactBootstrap = require("react-bootstrap");
12
+ var _VarItem = require("./VarItem");
13
13
  var _constants = require("../../constants/constants");
14
14
  var _DatasetContext = require("../../context/DatasetContext");
15
15
  var _SearchBar = require("../search-bar/SearchBar");
16
- var _VarItem = require("./VarItem");
17
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
17
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
19
18
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -32,10 +31,11 @@ function SingleSelectionSet(_ref) {
32
31
  isActive,
33
32
  selectSet,
34
33
  removeSet,
35
- removeSetVar,
36
- showSearchBar = true
34
+ removeSetVar
37
35
  } = _ref;
38
36
  const [openSet, setOpenSet] = (0, _react.useState)(false);
37
+ const [showModal, setShowModal] = (0, _react.useState)(false);
38
+ const [searchText, setSearchText] = (0, _react.useState)("");
39
39
  const varList = set.vars.length ? _lodash.default.map(set.vars, v => {
40
40
  return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
41
41
  key: v.name
@@ -54,16 +54,38 @@ function SingleSelectionSet(_ref) {
54
54
  }
55
55
  }, /*#__PURE__*/_react.default.createElement("div", {
56
56
  className: "d-flex justify-content-between align-items-center w-100"
57
- }, /*#__PURE__*/_react.default.createElement("div", null, set.name), /*#__PURE__*/_react.default.createElement("div", {
57
+ }, /*#__PURE__*/_react.default.createElement("div", {
58
+ className: "ellipsis-text",
59
+ title: set.name
60
+ }, set.name), /*#__PURE__*/_react.default.createElement("div", {
58
61
  className: "d-flex align-items-center gap-1"
59
62
  }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.OverlayTrigger, {
60
63
  placement: "top",
61
64
  overlay: /*#__PURE__*/_react.default.createElement(_reactBootstrap.Tooltip, null, "This set represents the mean value of its features")
62
65
  }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
63
66
  icon: _freeSolidSvgIcons.faCircleInfo
64
- })), /*#__PURE__*/_react.default.createElement(_iconsMaterial.List, null), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
67
+ })), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
68
+ type: "button",
69
+ variant: "outline-primary",
70
+ className: "m-0 p-0 px-1",
71
+ disabled: !set.vars.length,
72
+ title: "Open set"
73
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
74
+ icon: openSet ? _freeSolidSvgIcons.faChevronUp : _freeSolidSvgIcons.faChevronDown
75
+ })), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
76
+ type: "button",
77
+ variant: "outline-primary",
78
+ className: "m-0 p-0 px-1",
79
+ onClick: e => {
80
+ e.stopPropagation();
81
+ setShowModal(true);
82
+ },
83
+ disabled: !set.vars.length,
84
+ title: "Add to set"
85
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
86
+ icon: _freeSolidSvgIcons.faPlus
87
+ })), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
65
88
  type: "button",
66
- key: set.name,
67
89
  variant: isActive ? "primary" : "outline-primary",
68
90
  className: "m-0 p-0 px-1",
69
91
  onClick: e => {
@@ -89,17 +111,21 @@ function SingleSelectionSet(_ref) {
89
111
  in: openSet
90
112
  }, /*#__PURE__*/_react.default.createElement("div", {
91
113
  className: "mt-2"
92
- }, showSearchBar &&
93
- /*#__PURE__*/
94
- // @TODO: fix how results are displayed, should be placed on top of parent components
95
- _react.default.createElement(_SearchBar.SearchBar, {
96
- handleSelect: (d, i) => addVarToSet(d, set, i)
97
- }), /*#__PURE__*/_react.default.createElement("div", {
98
- className: "mx-2"
99
114
  }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
100
115
  variant: "flush",
101
- className: "cherita-list"
102
- }, varList)))));
116
+ className: "cherita-list var-set-list"
117
+ }, varList))), /*#__PURE__*/_react.default.createElement(_SearchBar.SearchModal, {
118
+ show: showModal,
119
+ handleClose: () => setShowModal(false),
120
+ text: searchText,
121
+ setText: setSearchText,
122
+ displayText: "features",
123
+ handleSelect: (d, i) => {
124
+ addVarToSet(d, set, i);
125
+ },
126
+ searchVar: true,
127
+ searchDiseases: false
128
+ }));
103
129
  }
104
130
  function MultipleSelectionSet(_ref2) {
105
131
  let {