@haniffalab/cherita-react 1.2.0 → 1.3.0-dev.2025-05-29.ee7e9b72

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 (91) hide show
  1. package/dist/cjs/components/controls/Controls.js +60 -0
  2. package/dist/cjs/components/dotplot/Dotplot.js +47 -38
  3. package/dist/cjs/components/dotplot/DotplotControls.js +77 -114
  4. package/dist/cjs/components/full-page/FullPage.js +29 -33
  5. package/dist/cjs/components/full-page/FullPagePseudospatial.js +30 -33
  6. package/dist/cjs/components/heatmap/Heatmap.js +33 -22
  7. package/dist/cjs/components/heatmap/HeatmapControls.js +2 -19
  8. package/dist/cjs/components/matrixplot/Matrixplot.js +35 -24
  9. package/dist/cjs/components/matrixplot/MatrixplotControls.js +4 -34
  10. package/dist/cjs/components/obs-list/ObsItem.js +63 -51
  11. package/dist/cjs/components/obs-list/ObsList.js +53 -48
  12. package/dist/cjs/components/obsm-list/ObsmList.js +17 -12
  13. package/dist/cjs/components/offcanvas/index.js +14 -11
  14. package/dist/cjs/components/pseudospatial/Pseudospatial.js +78 -68
  15. package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +27 -21
  16. package/dist/cjs/components/scatterplot/Scatterplot.js +82 -76
  17. package/dist/cjs/components/scatterplot/ScatterplotControls.js +18 -31
  18. package/dist/cjs/components/scatterplot/SpatialControls.js +53 -23
  19. package/dist/cjs/components/scatterplot/Toolbox.js +1 -18
  20. package/dist/cjs/components/search-bar/SearchBar.js +156 -59
  21. package/dist/cjs/components/search-bar/SearchInfo.js +182 -0
  22. package/dist/cjs/components/search-bar/SearchResults.js +90 -60
  23. package/dist/cjs/components/var-list/VarItem.js +52 -75
  24. package/dist/cjs/components/var-list/VarList.js +47 -172
  25. package/dist/cjs/components/var-list/VarListToolbar.js +7 -8
  26. package/dist/cjs/components/var-list/VarSet.js +66 -57
  27. package/dist/cjs/components/violin/Violin.js +54 -43
  28. package/dist/cjs/components/violin/ViolinControls.js +4 -20
  29. package/dist/cjs/context/DatasetContext.js +26 -513
  30. package/dist/cjs/context/FilterContext.js +9 -8
  31. package/dist/cjs/context/SettingsContext.js +539 -0
  32. package/dist/cjs/context/ZarrDataContext.js +1 -2
  33. package/dist/cjs/helpers/color-helper.js +8 -8
  34. package/dist/cjs/helpers/zarr-helper.js +19 -16
  35. package/dist/cjs/utils/Filter.js +25 -21
  36. package/dist/cjs/utils/Histogram.js +4 -3
  37. package/dist/cjs/utils/ImageViewer.js +1 -2
  38. package/dist/cjs/utils/Legend.js +18 -12
  39. package/dist/cjs/utils/LoadingIndicators.js +1 -1
  40. package/dist/cjs/utils/VirtualizedList.js +16 -13
  41. package/dist/cjs/utils/errors.js +20 -22
  42. package/dist/cjs/utils/requests.js +13 -10
  43. package/dist/cjs/utils/zarrData.js +31 -50
  44. package/dist/css/cherita.css +84 -24
  45. package/dist/css/cherita.css.map +1 -1
  46. package/dist/esm/components/controls/Controls.js +51 -0
  47. package/dist/esm/components/dotplot/Dotplot.js +47 -37
  48. package/dist/esm/components/dotplot/DotplotControls.js +77 -112
  49. package/dist/esm/components/full-page/FullPage.js +29 -32
  50. package/dist/esm/components/full-page/FullPagePseudospatial.js +30 -32
  51. package/dist/esm/components/heatmap/Heatmap.js +32 -20
  52. package/dist/esm/components/heatmap/HeatmapControls.js +3 -20
  53. package/dist/esm/components/matrixplot/Matrixplot.js +34 -22
  54. package/dist/esm/components/matrixplot/MatrixplotControls.js +5 -35
  55. package/dist/esm/components/obs-list/ObsItem.js +63 -49
  56. package/dist/esm/components/obs-list/ObsList.js +53 -47
  57. package/dist/esm/components/obsm-list/ObsmList.js +17 -11
  58. package/dist/esm/components/offcanvas/index.js +14 -11
  59. package/dist/esm/components/pseudospatial/Pseudospatial.js +77 -66
  60. package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +27 -20
  61. package/dist/esm/components/scatterplot/Scatterplot.js +81 -74
  62. package/dist/esm/components/scatterplot/ScatterplotControls.js +18 -29
  63. package/dist/esm/components/scatterplot/SpatialControls.js +54 -23
  64. package/dist/esm/components/scatterplot/Toolbox.js +1 -18
  65. package/dist/esm/components/search-bar/SearchBar.js +156 -59
  66. package/dist/esm/components/search-bar/SearchInfo.js +173 -0
  67. package/dist/esm/components/search-bar/SearchResults.js +91 -60
  68. package/dist/esm/components/var-list/VarItem.js +53 -76
  69. package/dist/esm/components/var-list/VarList.js +47 -171
  70. package/dist/esm/components/var-list/VarListToolbar.js +6 -6
  71. package/dist/esm/components/var-list/VarSet.js +67 -57
  72. package/dist/esm/components/violin/Violin.js +53 -41
  73. package/dist/esm/components/violin/ViolinControls.js +5 -21
  74. package/dist/esm/context/DatasetContext.js +25 -510
  75. package/dist/esm/context/FilterContext.js +8 -6
  76. package/dist/esm/context/SettingsContext.js +528 -0
  77. package/dist/esm/helpers/color-helper.js +8 -8
  78. package/dist/esm/helpers/zarr-helper.js +19 -16
  79. package/dist/esm/utils/Filter.js +25 -21
  80. package/dist/esm/utils/Histogram.js +4 -3
  81. package/dist/esm/utils/Legend.js +17 -10
  82. package/dist/esm/utils/LoadingIndicators.js +1 -1
  83. package/dist/esm/utils/VirtualizedList.js +15 -11
  84. package/dist/esm/utils/errors.js +20 -22
  85. package/dist/esm/utils/requests.js +13 -10
  86. package/dist/esm/utils/zarrData.js +33 -51
  87. package/package.json +6 -3
  88. package/scss/cherita.scss +50 -9
  89. package/scss/components/layouts.scss +24 -13
  90. package/scss/components/lists.scss +10 -0
  91. package/scss/components/plots.scss +3 -5
@@ -4,14 +4,26 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.SearchBar = SearchBar;
7
+ exports.SearchModal = SearchModal;
7
8
  var _react = _interopRequireWildcard(require("react"));
9
+ var _Close = _interopRequireDefault(require("@mui/icons-material/Close"));
8
10
  var _Search = _interopRequireDefault(require("@mui/icons-material/Search"));
9
- var _lodash = _interopRequireDefault(require("lodash"));
10
11
  var _reactBootstrap = require("react-bootstrap");
12
+ var _Col = _interopRequireDefault(require("react-bootstrap/Col"));
13
+ var _Container = _interopRequireDefault(require("react-bootstrap/Container"));
14
+ var _Nav = _interopRequireDefault(require("react-bootstrap/Nav"));
15
+ var _Row = _interopRequireDefault(require("react-bootstrap/Row"));
16
+ var _Tab = _interopRequireDefault(require("react-bootstrap/Tab"));
17
+ var _SearchInfo = require("./SearchInfo");
11
18
  var _SearchResults = require("./SearchResults");
19
+ var _constants = require("../../constants/constants");
12
20
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
- 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); }
14
- 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; }
21
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
22
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
23
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
24
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
25
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
26
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
15
27
  function onVarSelect(dispatch, item) {
16
28
  dispatch({
17
29
  type: "select.var",
@@ -23,77 +35,162 @@ function onVarSelect(dispatch, item) {
23
35
  });
24
36
  dispatch({
25
37
  type: "set.colorEncoding",
26
- value: "var"
38
+ value: _constants.COLOR_ENCODINGS.VAR
27
39
  });
28
40
  }
29
- function SearchBar(_ref) {
41
+ function addVarSet(dispatch, _ref) {
30
42
  let {
31
- searchVar = true,
32
- searchDiseases = false,
33
- handleSelect = onVarSelect
43
+ name,
44
+ vars
34
45
  } = _ref;
35
- const [showSuggestions, setShowSuggestions] = (0, _react.useState)(false);
36
- const [text, setText] = (0, _react.useState)("");
37
- const inputRef = (0, _react.useRef)(null);
38
- const displayText = [...(searchVar ? ["features"] : []), ...(searchDiseases ? ["diseases"] : [])].join(" and ");
39
- (0, _react.useEffect)(() => {
40
- if (text.length > 0) {
41
- setShowSuggestions(true);
46
+ dispatch({
47
+ type: "add.var",
48
+ var: {
49
+ name: name,
50
+ vars: vars,
51
+ isSet: true
42
52
  }
43
- }, [text]);
44
-
45
- //@TODO: Abstract styles
46
- return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form, {
53
+ });
54
+ }
55
+ const FEATURE_TYPE = {
56
+ VAR: "var",
57
+ DISEASE: "disease"
58
+ };
59
+ function SearchModal(_ref2) {
60
+ let {
61
+ show,
62
+ handleClose,
63
+ text,
64
+ setText,
65
+ displayText,
66
+ handleSelect = onVarSelect,
67
+ searchVar,
68
+ searchDiseases
69
+ } = _ref2;
70
+ const [tab, setTab] = (0, _react.useState)("var");
71
+ const [selectedResult, setSelectedResult] = (0, _react.useState)({
72
+ var: null,
73
+ disease: null
74
+ });
75
+ const [varResultsLength, setVarResultsLength] = (0, _react.useState)(null);
76
+ const [diseaseResultsLength, setDiseaseResultsLength] = (0, _react.useState)(null);
77
+ return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal, {
78
+ show: show,
79
+ onHide: handleClose,
80
+ size: "xl"
81
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Header, {
82
+ className: "bg-primary"
83
+ }, /*#__PURE__*/_react.default.createElement(_Container.default, {
84
+ className: "gx-0"
85
+ }, /*#__PURE__*/_react.default.createElement(_Row.default, null, /*#__PURE__*/_react.default.createElement(_Col.default, {
86
+ xs: 12
87
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form, {
47
88
  onSubmit: e => {
48
89
  e.preventDefault();
49
90
  }
50
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.FormGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
51
- ref: inputRef,
52
- onFocus: () => {
53
- setShowSuggestions(text.length > 0);
54
- },
55
- onBlur: () => {
56
- _lodash.default.delay(() => {
57
- setShowSuggestions(false);
58
- }, 150);
59
- },
91
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.FormGroup, null, /*#__PURE__*/_react.default.createElement("div", {
92
+ className: "d-flex align-items-center"
93
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, /*#__PURE__*/_react.default.createElement(_Search.default, null)), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
94
+ autoFocus: true,
60
95
  type: "text",
61
96
  placeholder: "Search " + displayText,
62
97
  value: text,
63
98
  onChange: e => {
64
99
  setText(e.target.value);
65
- },
66
- style: {
67
- paddingLeft: "2.5rem",
68
- borderRadius: "5px"
69
- }
70
- }), /*#__PURE__*/_react.default.createElement("div", {
71
- style: {
72
- position: "absolute",
73
- left: "10px",
74
- top: "50%",
75
- transform: "translateY(-50%)",
76
- pointerEvents: "none",
77
- zIndex: 10
100
+ setSelectedResult({
101
+ var: null,
102
+ disease: null
103
+ });
104
+ setVarResultsLength(null);
105
+ setDiseaseResultsLength(null);
78
106
  }
79
- }, /*#__PURE__*/_react.default.createElement(_Search.default, null))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown, {
80
- show: showSuggestions,
81
- onMouseDown: e => {
107
+ }), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
108
+ variant: "light",
109
+ onClick: handleClose
110
+ }, /*#__PURE__*/_react.default.createElement(_Close.default, null)))))))))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Body, {
111
+ className: "p-0"
112
+ }, /*#__PURE__*/_react.default.createElement(_Container.default, null, /*#__PURE__*/_react.default.createElement(_Row.default, null, /*#__PURE__*/_react.default.createElement(_Col.default, {
113
+ xs: 12,
114
+ md: 8
115
+ }, /*#__PURE__*/_react.default.createElement(_Tab.default.Container, {
116
+ activeKey: tab,
117
+ onSelect: k => setTab(k)
118
+ }, /*#__PURE__*/_react.default.createElement(_Row.default, {
119
+ className: "w-100"
120
+ }, /*#__PURE__*/_react.default.createElement(_Col.default, {
121
+ sm: 3,
122
+ className: "py-3 border-end"
123
+ }, /*#__PURE__*/_react.default.createElement(_Nav.default, {
124
+ variant: "pills",
125
+ className: "flex-column"
126
+ }, searchVar && /*#__PURE__*/_react.default.createElement(_Nav.default.Item, null, /*#__PURE__*/_react.default.createElement(_Nav.default.Link, {
127
+ eventKey: FEATURE_TYPE.VAR
128
+ }, "Genes", " ", !!varResultsLength && "(".concat(varResultsLength, ")"))), searchDiseases && /*#__PURE__*/_react.default.createElement(_Nav.default.Item, null, /*#__PURE__*/_react.default.createElement(_Nav.default.Link, {
129
+ eventKey: FEATURE_TYPE.DISEASE
130
+ }, "Diseases", " ", !!diseaseResultsLength && "(".concat(diseaseResultsLength, ")"))))), /*#__PURE__*/_react.default.createElement(_Col.default, {
131
+ sm: 9,
132
+ className: "py-3"
133
+ }, /*#__PURE__*/_react.default.createElement(_Tab.default.Content, null, searchVar && /*#__PURE__*/_react.default.createElement(_Tab.default.Pane, {
134
+ eventKey: FEATURE_TYPE.VAR
135
+ }, /*#__PURE__*/_react.default.createElement(_SearchResults.VarSearchResults, {
136
+ text: text,
137
+ handleSelect: handleSelect,
138
+ selectedResult: selectedResult.var,
139
+ setSelectedResult: item => setSelectedResult(prev => {
140
+ return _objectSpread(_objectSpread({}, prev), {}, {
141
+ var: item
142
+ });
143
+ }),
144
+ setResultsLength: setVarResultsLength
145
+ })), searchDiseases && /*#__PURE__*/_react.default.createElement(_Tab.default.Pane, {
146
+ eventKey: FEATURE_TYPE.DISEASE
147
+ }, /*#__PURE__*/_react.default.createElement(_SearchResults.DiseasesSearchResults, {
148
+ text: text,
149
+ selectedResult: selectedResult.disease,
150
+ setSelectedResult: item => setSelectedResult(prev => {
151
+ return _objectSpread(_objectSpread({}, prev), {}, {
152
+ disease: item
153
+ });
154
+ }),
155
+ setResultsLength: setDiseaseResultsLength
156
+ }))))))), /*#__PURE__*/_react.default.createElement(_Col.default, {
157
+ xs: 12,
158
+ md: 4,
159
+ className: "bg-light p-3 search-modal-info"
160
+ }, selectedResult[tab] ? tab === FEATURE_TYPE.DISEASE ? /*#__PURE__*/_react.default.createElement(_SearchInfo.DiseaseInfo, {
161
+ disease: selectedResult.disease,
162
+ handleSelect: handleSelect,
163
+ addVarSet: addVarSet
164
+ }) : /*#__PURE__*/_react.default.createElement(_SearchInfo.VarInfo, {
165
+ varItem: selectedResult.var
166
+ }) : /*#__PURE__*/_react.default.createElement("div", {
167
+ className: "text-muted"
168
+ }, "No result selected"))))));
169
+ }
170
+ function SearchBar(_ref3) {
171
+ let {
172
+ searchVar = true,
173
+ searchDiseases = false
174
+ } = _ref3;
175
+ const [text, setText] = (0, _react.useState)("");
176
+ const displayText = [...(searchVar ? ["features"] : []), ...(searchDiseases ? ["diseases"] : [])].join(" and ");
177
+ const [showModal, setShowModal] = (0, _react.useState)(false);
178
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form, {
179
+ onSubmit: e => {
82
180
  e.preventDefault();
83
- },
84
- onSelect: () => {
85
- inputRef.current.blur();
86
- }
87
- }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Menu, {
88
- style: {
89
- width: "90%"
90
181
  }
91
- }, searchVar && /*#__PURE__*/_react.default.createElement(_SearchResults.VarSearchResults, {
92
- text: text,
93
- setShowSuggestions: setShowSuggestions,
94
- handleSelect: handleSelect
95
- }), searchVar && searchDiseases && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Divider, null), searchDiseases && /*#__PURE__*/_react.default.createElement(_SearchResults.DiseasesSearchResults, {
182
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.FormGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.InputGroup.Text, null, /*#__PURE__*/_react.default.createElement(_Search.default, null)), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Form.Control, {
183
+ onClick: () => setShowModal(true),
184
+ type: "text",
185
+ placeholder: "Search " + displayText,
186
+ defaultValue: text
187
+ })))), /*#__PURE__*/_react.default.createElement(SearchModal, {
188
+ show: showModal,
96
189
  text: text,
97
- setShowSuggestions: setShowSuggestions
98
- }))))));
190
+ setText: setText,
191
+ displayText: displayText,
192
+ searchVar: searchVar,
193
+ searchDiseases: searchDiseases,
194
+ handleClose: () => setShowModal(false)
195
+ }));
99
196
  }
@@ -0,0 +1,182 @@
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 _SettingsContext = require("../../context/SettingsContext");
16
+ var _requests = require("../../utils/requests");
17
+ var _VarItem = require("../var-list/VarItem");
18
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
20
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
21
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
22
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
23
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
24
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
25
+ function VarInfo(_ref) {
26
+ let {
27
+ varItem
28
+ } = _ref;
29
+ const ENDPOINT = "disease/gene";
30
+ const dataset = (0, _DatasetContext.useDataset)();
31
+ const [params, setParams] = (0, _react.useState)({
32
+ geneName: varItem.name,
33
+ diseaseDatasets: dataset.diseaseDatasets
34
+ });
35
+ (0, _react.useEffect)(() => {
36
+ setParams(p => {
37
+ return _objectSpread(_objectSpread({}, p), {}, {
38
+ geneName: varItem.name
39
+ });
40
+ });
41
+ }, [varItem.name]);
42
+ const {
43
+ fetchedData,
44
+ isPending,
45
+ serverError
46
+ } = (0, _requests.useFetch)(ENDPOINT, params, {
47
+ refetchOnMount: false,
48
+ enabled: !!dataset.diseaseDatasets.length
49
+ });
50
+ const hasDiseaseInfo = !isPending && !serverError && !!(fetchedData !== null && fetchedData !== void 0 && fetchedData.length);
51
+ 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, {
52
+ data: fetchedData
53
+ })));
54
+ }
55
+ const useVarMean = function (varKeys) {
56
+ let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
57
+ const ENDPOINT = "matrix/mean";
58
+ const dataset = (0, _DatasetContext.useDataset)();
59
+ const [params, setParams] = (0, _react.useState)({
60
+ url: dataset.url,
61
+ varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
62
+ name: v.name,
63
+ indices: v.vars.map(v => v.index)
64
+ } : v.index),
65
+ // obsIndices:
66
+ varNamesCol: dataset.varNamesCol
67
+ });
68
+ (0, _react.useEffect)(() => {
69
+ setParams(p => {
70
+ return _objectSpread(_objectSpread({}, p), {}, {
71
+ varKeys: _lodash.default.map(varKeys, v => v.isSet ? {
72
+ name: v.name,
73
+ indices: v.vars.map(v => v.index)
74
+ } : v.index)
75
+ });
76
+ });
77
+ }, [varKeys]);
78
+ return (0, _requests.useFetch)(ENDPOINT, params, {
79
+ enabled: enabled,
80
+ refetchOnMount: false
81
+ });
82
+ };
83
+
84
+ // ensure nulls are lowest values
85
+ const sortMeans = (i, means) => {
86
+ return means[i.name] || _lodash.default.min(_lodash.default.values(means)) - 1;
87
+ };
88
+ function DiseaseInfo(_ref2) {
89
+ let {
90
+ disease,
91
+ handleSelect,
92
+ addVarSet
93
+ } = _ref2;
94
+ const ENDPOINT = "disease/genes";
95
+ const dataset = (0, _DatasetContext.useDataset)();
96
+ const settings = (0, _SettingsContext.useSettings)();
97
+ const dispatch = (0, _SettingsContext.useSettingsDispatch)();
98
+ const [diseaseVars, setDiseaseVars] = (0, _react.useState)([]);
99
+ const [sortedDiseaseVars, setSortedDiseaseVars] = (0, _react.useState)([]);
100
+ const [params, setParams] = (0, _react.useState)({
101
+ url: dataset.url,
102
+ col: dataset.varNamesCol,
103
+ diseaseDatasets: dataset.diseaseDatasets,
104
+ diseaseId: disease.id
105
+ });
106
+ (0, _react.useEffect)(() => {
107
+ setParams(p => {
108
+ return _objectSpread(_objectSpread({}, p), {}, {
109
+ diseaseId: disease.id
110
+ });
111
+ });
112
+ }, [disease]);
113
+ const diseaseData = (0, _requests.useFetch)(ENDPOINT, params, {
114
+ enabled: !!params.diseaseId,
115
+ refetchOnMount: true
116
+ });
117
+ (0, _react.useEffect)(() => {
118
+ if (!diseaseData.isPending && !diseaseData.serverError) {
119
+ setDiseaseVars(diseaseData.fetchedData);
120
+ }
121
+ }, [diseaseData.fetchedData, diseaseData.isPending, diseaseData.serverError]);
122
+ const varMeans = useVarMean(diseaseVars, !!(diseaseVars !== null && diseaseVars !== void 0 && diseaseVars.length) && settings.varSort.disease.sort === _constants.VAR_SORT.MATRIX);
123
+ (0, _react.useEffect)(() => {
124
+ if (settings.varSort.disease.sort === _constants.VAR_SORT.MATRIX) {
125
+ if (!varMeans.isPending && !varMeans.serverError) {
126
+ setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, o => {
127
+ return sortMeans(o, varMeans.fetchedData);
128
+ }, settings.varSort.disease.sortOrder));
129
+ }
130
+ } else if (settings.varSort.disease.sort === _constants.VAR_SORT.NAME) {
131
+ setSortedDiseaseVars(_lodash.default.orderBy(diseaseVars, "name", settings.varSort.disease.sortOrder));
132
+ } else {
133
+ setSortedDiseaseVars(diseaseVars);
134
+ }
135
+ }, [settings.varSort.disease.sort, settings.varSort.disease.sortOrder, diseaseVars, varMeans.fetchedData, varMeans.isPending, varMeans.serverError]);
136
+ const diseaseVarList = _lodash.default.map(sortedDiseaseVars, v => {
137
+ return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
138
+ key: v.gene_id
139
+ }, /*#__PURE__*/_react.default.createElement("div", {
140
+ className: "d-flex justify-content-between align-items-center w-100"
141
+ }, v.name, /*#__PURE__*/_react.default.createElement("div", {
142
+ className: "d-flex align-items-center gap-1"
143
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
144
+ type: "button",
145
+ className: "m-0 p-0 px-1",
146
+ variant: "outline-secondary",
147
+ title: "Add to list",
148
+ onClick: () => {
149
+ handleSelect(dispatch, {
150
+ name: v.name,
151
+ index: v.index,
152
+ matrix_index: v.matrix_index
153
+ });
154
+ }
155
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
156
+ icon: _freeSolidSvgIcons.faPlus
157
+ })))));
158
+ });
159
+ const isPending = diseaseData.isPending || varMeans.isPending && settings.varSort.disease.sort === _constants.VAR_SORT.MATRIX;
160
+ 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", {
161
+ className: "d-flex justify-content-end mb-2"
162
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
163
+ size: "sm",
164
+ title: "Add all as a set",
165
+ onClick: () => {
166
+ addVarSet(dispatch, {
167
+ name: disease.disease_name,
168
+ vars: _lodash.default.map(diseaseVars, v => {
169
+ return {
170
+ index: v.index,
171
+ name: v.name,
172
+ matrix_index: v.matrix_index
173
+ };
174
+ })
175
+ });
176
+ }
177
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
178
+ icon: _freeSolidSvgIcons.faPlus
179
+ }), " Add all as a set")), /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
180
+ className: "overflow-scroll"
181
+ }, diseaseVarList)));
182
+ }
@@ -6,21 +6,30 @@ 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
- var _DatasetContext = require("../../context/DatasetContext");
13
+ var _SettingsContext = require("../../context/SettingsContext");
12
14
  var _search = require("../../utils/search");
15
+ var _VirtualizedList = require("../../utils/VirtualizedList");
13
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- 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); }
15
- 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; }
17
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
18
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
19
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
20
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
21
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
22
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
16
23
  function VarSearchResults(_ref) {
17
24
  let {
18
25
  text,
19
- setShowSuggestions,
20
- handleSelect
26
+ handleSelect,
27
+ selectedResult,
28
+ setSelectedResult,
29
+ setResultsLength
21
30
  } = _ref;
22
31
  const [suggestions, setSuggestions] = (0, _react.useState)([]);
23
- const dispatch = (0, _DatasetContext.useDatasetDispatch)();
32
+ const dispatch = (0, _SettingsContext.useSettingsDispatch)();
24
33
  const {
25
34
  setParams,
26
35
  data: {
@@ -35,57 +44,76 @@ function VarSearchResults(_ref) {
35
44
  const setData = text => {
36
45
  if (text.length) {
37
46
  setParams(p => {
38
- return {
39
- ...p,
47
+ return _objectSpread(_objectSpread({}, p), {}, {
40
48
  text: text
41
- };
49
+ });
42
50
  });
43
51
  } else {
44
52
  setSuggestions([]);
45
- setShowSuggestions(false);
46
53
  }
47
54
  };
48
55
  return _lodash.default.debounce(setData, 300);
49
- }, [setParams, setShowSuggestions]);
56
+ }, [setParams]);
50
57
  (0, _react.useEffect)(() => {
51
58
  updateParams(text);
52
59
  }, [text, updateParams]);
53
60
  (0, _react.useEffect)(() => {
54
61
  if (!isPending && !serverError) {
55
62
  setSuggestions(fetchedData);
56
- setShowSuggestions(true);
63
+ setResultsLength(fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.length);
64
+ }
65
+ }, [fetchedData, isPending, serverError, setResultsLength]);
66
+ const getDataAtIndex = index => deferredData[index];
67
+ const ItemComponent = item => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
68
+ className: "virtualized-list-wrapper"
69
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
70
+ key: item,
71
+ onClick: () => {
72
+ setSelectedResult(item);
73
+ },
74
+ active: (selectedResult === null || selectedResult === void 0 ? void 0 : selectedResult.index) === item.index
75
+ }, /*#__PURE__*/_react.default.createElement("div", {
76
+ className: "d-flex justify-content-between align-items-center w-100"
77
+ }, /*#__PURE__*/_react.default.createElement("div", null, item.name), /*#__PURE__*/_react.default.createElement("div", {
78
+ className: "d-flex align-items-center gap-1"
79
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
80
+ type: "button",
81
+ className: "m-0 p-0 px-1",
82
+ variant: "outline-secondary",
83
+ title: "Add to list",
84
+ disabled: isStale,
85
+ onClick: () => {
86
+ handleSelect(dispatch, item);
57
87
  }
58
- }, [fetchedData, isPending, serverError, setShowSuggestions]);
59
- const suggestionsList = (0, _react.useMemo)(() => {
60
- return deferredData?.map(item => {
61
- return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
62
- key: item.name,
63
- as: "button",
64
- disabled: isStale,
65
- onClick: () => {
66
- handleSelect(dispatch, item);
67
- _lodash.default.delay(() => {
68
- setShowSuggestions(false);
69
- }, 150);
70
- }
71
- }, item.name);
72
- });
73
- }, [deferredData, dispatch, handleSelect, isStale, setShowSuggestions]);
74
- return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Header, null, "Features"), /*#__PURE__*/_react.default.createElement("div", {
88
+ }, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
89
+ icon: _freeSolidSvgIcons.faPlus
90
+ })))))));
91
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
75
92
  className: "search-results"
76
- }, deferredData?.length ? suggestionsList : /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
93
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
94
+ variant: "flush",
95
+ className: "cherita-list"
96
+ }, deferredData !== null && deferredData !== void 0 && deferredData.length ? /*#__PURE__*/_react.default.createElement(_VirtualizedList.VirtualizedList, {
97
+ getDataAtIndex: getDataAtIndex,
98
+ count: deferredData.length,
99
+ ItemComponent: ItemComponent,
100
+ overscan: 500,
101
+ estimateSize: 42,
102
+ maxHeight: "70vh"
103
+ }) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
77
104
  key: "empty",
78
105
  as: "button",
79
106
  disabled: true
80
- }, !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data")));
107
+ }, !text.length ? "Search features" : !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data"))));
81
108
  }
82
109
  function DiseasesSearchResults(_ref2) {
83
110
  let {
84
111
  text,
85
- setShowSuggestions
112
+ selectedResult,
113
+ setSelectedResult,
114
+ setResultsLength
86
115
  } = _ref2;
87
116
  const [suggestions, setSuggestions] = (0, _react.useState)([]);
88
- const dispatch = (0, _DatasetContext.useDatasetDispatch)();
89
117
  const {
90
118
  setParams,
91
119
  data: {
@@ -100,10 +128,9 @@ function DiseasesSearchResults(_ref2) {
100
128
  const setData = text => {
101
129
  if (text.length) {
102
130
  setParams(p => {
103
- return {
104
- ...p,
131
+ return _objectSpread(_objectSpread({}, p), {}, {
105
132
  text: text
106
- };
133
+ });
107
134
  });
108
135
  } else {
109
136
  setSuggestions([]);
@@ -117,33 +144,36 @@ function DiseasesSearchResults(_ref2) {
117
144
  (0, _react.useEffect)(() => {
118
145
  if (!isPending && !serverError) {
119
146
  setSuggestions(fetchedData);
120
- setShowSuggestions(true);
147
+ setResultsLength(fetchedData === null || fetchedData === void 0 ? void 0 : fetchedData.length);
121
148
  }
122
- }, [fetchedData, isPending, serverError, setShowSuggestions]);
123
- const suggestionsList = (0, _react.useMemo)(() => {
124
- return deferredData?.map(item => {
125
- return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
126
- key: item.id,
127
- as: "button",
128
- disabled: isStale,
129
- onClick: () => {
130
- dispatch({
131
- type: "select.disease",
132
- id: item.disease_id,
133
- name: item.disease_name
134
- });
135
- _lodash.default.delay(() => {
136
- setShowSuggestions(false);
137
- }, 150);
138
- }
139
- }, item.disease_name);
140
- });
141
- }, [deferredData, dispatch, isStale, setShowSuggestions]);
142
- return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Header, null, "Diseases"), /*#__PURE__*/_react.default.createElement("div", {
149
+ }, [fetchedData, isPending, serverError, setResultsLength]);
150
+ const getDataAtIndex = index => deferredData[index];
151
+ const ItemComponent = item => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
152
+ className: "virtualized-list-wrapper"
153
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
154
+ key: item.name,
155
+ onClick: () => {
156
+ setSelectedResult(item);
157
+ },
158
+ active: (selectedResult === null || selectedResult === void 0 ? void 0 : selectedResult.id) === item.id
159
+ }, /*#__PURE__*/_react.default.createElement("div", {
160
+ className: "d-flex justify-content-between align-items-center w-100"
161
+ }, /*#__PURE__*/_react.default.createElement("div", null, item.disease_name)))));
162
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
143
163
  className: "search-results"
144
- }, deferredData?.length ? suggestionsList : /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
164
+ }, /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
165
+ variant: "flush",
166
+ className: "cherita-list"
167
+ }, deferredData !== null && deferredData !== void 0 && deferredData.length ? /*#__PURE__*/_react.default.createElement(_VirtualizedList.VirtualizedList, {
168
+ getDataAtIndex: getDataAtIndex,
169
+ count: deferredData.length,
170
+ ItemComponent: ItemComponent,
171
+ overscan: 250,
172
+ estimateSize: 32,
173
+ maxHeight: "70vh"
174
+ }) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
145
175
  key: "empty",
146
176
  as: "button",
147
177
  disabled: true
148
- }, !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data")));
178
+ }, !text.length ? "Search diseases" : !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data"))));
149
179
  }