@haniffalab/cherita-react 0.2.0-dev.2024-05-09.97c686f2 → 0.2.0-dev.2024-05-09.07fb18ed

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.
@@ -11,6 +11,7 @@ exports.OffcanvasVars = OffcanvasVars;
11
11
  var _react = require("react");
12
12
  var _Offcanvas = _interopRequireDefault(require("react-bootstrap/Offcanvas"));
13
13
  var _cheritaReact = require("@haniffalab/cherita-react");
14
+ var _SearchBar = require("../search-bar/SearchBar");
14
15
  var _jsxRuntime = require("react/jsx-runtime");
15
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
17
  function OffcanvasObs(_ref) {
@@ -65,10 +66,12 @@ function OffcanvasVars(_ref3) {
65
66
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Offcanvas.default.Title, {
66
67
  children: "Features"
67
68
  })
68
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Offcanvas.default.Body, {
69
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_cheritaReact.VarNamesList, {
69
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Offcanvas.default.Body, {
70
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_SearchBar.SearchBar, {
71
+ searchDiseases: true
72
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_cheritaReact.VarNamesList, {
70
73
  mode: mode
71
- })
74
+ })]
72
75
  })]
73
76
  });
74
77
  }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.SearchBar = SearchBar;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _lodash = _interopRequireDefault(require("lodash"));
9
+ var _reactBootstrap = require("react-bootstrap");
10
+ var _SearchResults = require("./SearchResults");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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 && Object.prototype.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; }
15
+ function SearchBar(_ref) {
16
+ let {
17
+ searchVar = true,
18
+ searchDiseases = false
19
+ } = _ref;
20
+ const [showSuggestions, setShowSuggestions] = (0, _react.useState)(false);
21
+ const [text, setText] = (0, _react.useState)("");
22
+ const inputRef = (0, _react.useRef)(null);
23
+ const displayText = [...(searchVar ? ["features"] : []), ...(searchDiseases ? ["diseases"] : [])].join(" and ");
24
+ (0, _react.useEffect)(() => {
25
+ if (text.length > 0) {
26
+ setShowSuggestions(true);
27
+ }
28
+ }, [text]);
29
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
30
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form, {
31
+ onSubmit: e => {
32
+ e.preventDefault();
33
+ },
34
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.FormGroup, {
35
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
36
+ ref: inputRef,
37
+ onFocus: () => {
38
+ setShowSuggestions(text.length > 0);
39
+ },
40
+ onBlur: () => {
41
+ _lodash.default.delay(() => {
42
+ setShowSuggestions(false);
43
+ }, 150);
44
+ },
45
+ type: "text",
46
+ placeholder: "Search " + displayText,
47
+ value: text,
48
+ onChange: e => {
49
+ setText(e.target.value);
50
+ }
51
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown, {
52
+ show: showSuggestions,
53
+ onMouseDown: e => {
54
+ e.preventDefault();
55
+ },
56
+ onSelect: () => {
57
+ inputRef.current.blur();
58
+ },
59
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Dropdown.Menu, {
60
+ style: {
61
+ width: "90%"
62
+ },
63
+ children: [searchVar && /*#__PURE__*/(0, _jsxRuntime.jsx)(_SearchResults.VarSearchResults, {
64
+ text: text,
65
+ setShowSuggestions: setShowSuggestions
66
+ }), searchVar && searchDiseases && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Divider, {}), searchDiseases && /*#__PURE__*/(0, _jsxRuntime.jsx)(_SearchResults.DiseasesSearchResults, {
67
+ text: text,
68
+ setShowSuggestions: setShowSuggestions
69
+ })]
70
+ })
71
+ })]
72
+ })
73
+ })
74
+ });
75
+ }
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DiseasesSearchResults = DiseasesSearchResults;
7
+ exports.VarSearchResults = VarSearchResults;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _lodash = _interopRequireDefault(require("lodash"));
10
+ var _reactBootstrap = require("react-bootstrap");
11
+ var _DatasetContext = require("../../context/DatasetContext");
12
+ var _search = require("../../utils/search");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ 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); }
16
+ 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 && Object.prototype.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 VarSearchResults(_ref) {
18
+ let {
19
+ text,
20
+ setShowSuggestions
21
+ } = _ref;
22
+ const [suggestions, setSuggestions] = (0, _react.useState)([]);
23
+ const {
24
+ setParams,
25
+ data: {
26
+ fetchedData = [],
27
+ isPending,
28
+ serverError
29
+ },
30
+ onSelect
31
+ } = (0, _search.useVarSearch)();
32
+ const deferredData = (0, _react.useDeferredValue)(suggestions);
33
+ const isStale = deferredData !== fetchedData;
34
+ const updateParams = (0, _react.useMemo)(() => {
35
+ const setData = text => {
36
+ if (text.length) {
37
+ setParams(p => {
38
+ return {
39
+ ...p,
40
+ text: text
41
+ };
42
+ });
43
+ } else {
44
+ setSuggestions([]);
45
+ setShowSuggestions(false);
46
+ }
47
+ };
48
+ return _lodash.default.debounce(setData, 300);
49
+ }, [setParams, setShowSuggestions]);
50
+ (0, _react.useEffect)(() => {
51
+ updateParams(text);
52
+ }, [text, updateParams]);
53
+ (0, _react.useEffect)(() => {
54
+ if (!isPending && !serverError) {
55
+ setSuggestions(fetchedData);
56
+ setShowSuggestions(true);
57
+ }
58
+ }, [fetchedData, isPending, serverError, setShowSuggestions]);
59
+ const suggestionsList = (0, _react.useMemo)(() => {
60
+ return deferredData === null || deferredData === void 0 ? void 0 : deferredData.map(item => {
61
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
62
+ as: "button",
63
+ disabled: isStale,
64
+ onClick: () => {
65
+ onSelect(item);
66
+ _lodash.default.delay(() => {
67
+ setShowSuggestions(false);
68
+ }, 150);
69
+ },
70
+ children: item.name
71
+ }, item.name);
72
+ });
73
+ }, [deferredData, isStale, onSelect, setShowSuggestions]);
74
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
75
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Header, {
76
+ children: "Features"
77
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
78
+ style: {
79
+ maxHeight: "25vh",
80
+ overflowY: "scroll"
81
+ },
82
+ children: deferredData !== null && deferredData !== void 0 && deferredData.length ? suggestionsList : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
83
+ as: "button",
84
+ disabled: true,
85
+ children: !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data"
86
+ }, "empty")
87
+ })]
88
+ });
89
+ }
90
+ function DiseasesSearchResults(_ref2) {
91
+ let {
92
+ text,
93
+ setShowSuggestions
94
+ } = _ref2;
95
+ const [suggestions, setSuggestions] = (0, _react.useState)([]);
96
+ const dispatch = (0, _DatasetContext.useDatasetDispatch)();
97
+ const {
98
+ setParams,
99
+ data: {
100
+ fetchedData = [],
101
+ isPending,
102
+ serverError
103
+ }
104
+ } = (0, _search.useDiseaseSearch)();
105
+ (0, _search.useGetDisease)();
106
+ const deferredData = (0, _react.useDeferredValue)(suggestions);
107
+ const isStale = deferredData !== fetchedData;
108
+ const updateParams = (0, _react.useMemo)(() => {
109
+ const setData = text => {
110
+ if (text.length) {
111
+ setParams(p => {
112
+ return {
113
+ ...p,
114
+ text: text
115
+ };
116
+ });
117
+ } else {
118
+ setSuggestions([]);
119
+ }
120
+ };
121
+ return _lodash.default.debounce(setData, 300);
122
+ }, [setParams]);
123
+ (0, _react.useEffect)(() => {
124
+ updateParams(text);
125
+ }, [text, updateParams]);
126
+ (0, _react.useEffect)(() => {
127
+ if (!isPending && !serverError) {
128
+ setSuggestions(fetchedData);
129
+ setShowSuggestions(true);
130
+ }
131
+ }, [fetchedData, isPending, serverError, setShowSuggestions]);
132
+ const suggestionsList = (0, _react.useMemo)(() => {
133
+ return deferredData === null || deferredData === void 0 ? void 0 : deferredData.map(item => {
134
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
135
+ as: "button",
136
+ disabled: isStale,
137
+ onClick: () => {
138
+ dispatch({
139
+ type: "select.disease",
140
+ id: item === null || item === void 0 ? void 0 : item.disease_id,
141
+ name: item === null || item === void 0 ? void 0 : item.disease_name
142
+ });
143
+ _lodash.default.delay(() => {
144
+ setShowSuggestions(false);
145
+ }, 150);
146
+ },
147
+ children: item.disease_name
148
+ }, item.id);
149
+ });
150
+ }, [deferredData, dispatch, isStale, setShowSuggestions]);
151
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
152
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Header, {
153
+ children: "Diseases"
154
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
155
+ style: {
156
+ maxHeight: "25vh",
157
+ overflowY: "scroll"
158
+ },
159
+ children: deferredData !== null && deferredData !== void 0 && deferredData.length ? suggestionsList : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
160
+ as: "button",
161
+ disabled: true,
162
+ children: !serverError ? isStale || isPending ? "Loading..." : "No items found" : "Failed to fetch data"
163
+ }, "empty")
164
+ })]
165
+ });
166
+ }
@@ -4,164 +4,52 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.VarNamesList = VarNamesList;
7
- exports.VarSearchBar = VarSearchBar;
8
7
  require("bootstrap/dist/css/bootstrap.min.css");
9
8
  var _react = _interopRequireWildcard(require("react"));
10
9
  var _lodash = _interopRequireDefault(require("lodash"));
11
- var _requests = require("../../utils/requests");
12
10
  var _DatasetContext = require("../../context/DatasetContext");
13
11
  var _constants = require("../../constants/constants");
14
12
  var _reactBootstrap = require("react-bootstrap");
15
- var _LoadingSpinner = require("../../utils/LoadingSpinner");
16
13
  var _jsxRuntime = require("react/jsx-runtime");
17
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
15
  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
16
  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 && Object.prototype.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 VarSearchBar(_ref) {
17
+ function VarNamesList(_ref) {
18
+ var _dataset$selectedVar, _dataset$selectedDise, _dataset$selectedDise2, _dataset$selectedDise3;
21
19
  let {
22
- varNames = [],
23
- onSelect
20
+ mode = _constants.SELECTION_MODES.SINGLE,
21
+ displayName = "genes"
24
22
  } = _ref;
25
- const [suggestions, setSuggestions] = (0, _react.useState)([]);
26
- const [showSuggestions, setShowSuggestions] = (0, _react.useState)(false);
27
- const [text, setText] = (0, _react.useState)("");
28
- const getSuggestions = (0, _react.useMemo)(() => {
29
- const filter = text => {
30
- if (text.length > 0) {
31
- const regex = new RegExp("^".concat(text), "i");
32
- const filter = varNames.sort().filter(v => regex.test(v.name));
33
- setSuggestions(filter);
34
- setShowSuggestions(true);
35
- } else {
36
- setShowSuggestions(false);
37
- }
38
- };
39
- return _lodash.default.debounce(filter, 300);
40
- }, [varNames]);
41
- (0, _react.useEffect)(() => {
42
- getSuggestions(text);
43
- }, [getSuggestions, text]);
44
- const suggestionsList = suggestions.map(item => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
45
- as: "button",
46
- onClick: () => {
47
- onSelect(item);
48
- },
49
- children: item.name
50
- }, item.name));
51
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
52
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form, {
53
- onSubmit: e => {
54
- e.preventDefault();
55
- },
56
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.FormGroup, {
57
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Label, {
58
- children: "Feature:"
59
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Form.Control, {
60
- onFocus: () => {
61
- setShowSuggestions(text.length > 0);
62
- },
63
- onBlur: () => {
64
- _lodash.default.delay(() => {
65
- setShowSuggestions(false);
66
- }, 150);
67
- },
68
- type: "text",
69
- placeholder: "Search for a feature",
70
- value: text,
71
- onChange: e => {
72
- setText(e.target.value);
73
- }
74
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Menu, {
75
- style: {
76
- width: "90%",
77
- maxHeight: "25vh",
78
- overflowY: "scroll"
79
- },
80
- show: showSuggestions,
81
- children: suggestionsList
82
- })]
83
- })
84
- })
85
- });
86
- }
87
- function VarNamesList(_ref2) {
88
- let {
89
- mode = _constants.SELECTION_MODES.SINGLE
90
- } = _ref2;
91
- const ENDPOINT = "var/names";
92
23
  const dataset = (0, _DatasetContext.useDataset)();
93
24
  const dispatch = (0, _DatasetContext.useDatasetDispatch)();
94
- const [varNames, setVarNames] = (0, _react.useState)([]);
95
- const [updatedVarNames, setUpdatedVarNames] = (0, _react.useState)(false);
96
- const [varButtons, setVarButtons] = (0, _react.useState)(mode ? mode === _constants.SELECTION_MODES.SINGLE ? [dataset.selectVar] : dataset.selectedMultiVar : []);
97
- const [active, setActive] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? dataset.selectVar : dataset.selectedMultiVar);
98
- const [params, setParams] = (0, _react.useState)({
99
- url: dataset.url,
100
- col: dataset.varNamesCol
101
- });
25
+ const [varButtons, setVarButtons] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? [dataset.selectedVar] : dataset.selectedMultiVar);
26
+ const [active, setActive] = (0, _react.useState)(mode === _constants.SELECTION_MODES.SINGLE ? (_dataset$selectedVar = dataset.selectedVar) === null || _dataset$selectedVar === void 0 ? void 0 : _dataset$selectedVar.matrix_index : dataset.selectedMultiVar.map(i => i.matrix_index));
102
27
  (0, _react.useEffect)(() => {
103
- setParams(p => {
104
- return {
105
- ...p,
106
- url: dataset.url,
107
- col: dataset.varNamesCol
108
- };
109
- });
110
- }, [dataset.url, dataset.varNamesCol]);
111
- const {
112
- fetchedData,
113
- isPending,
114
- serverError
115
- } = (0, _requests.useFetch)(ENDPOINT, params, {
116
- refetchOnMount: false
117
- });
118
- const validateSelection = (0, _react.useCallback)((selectedVar, mode) => {
119
- if (updatedVarNames) {
120
- if (mode === _constants.SELECTION_MODES.SINGLE) {
121
- if (selectedVar && !_lodash.default.some(varNames, selectedVar)) {
122
- setActive(null);
123
- dispatch({
124
- type: "varSelected",
125
- var: null
126
- });
127
- }
128
- } else {
129
- if (selectedVar.length && !_lodash.default.every(selectedVar, v => _lodash.default.some(varNames, v))) {
130
- setActive([]);
131
- dispatch({
132
- type: "multiVarReset",
133
- var: []
134
- });
28
+ if (mode === _constants.SELECTION_MODES.SINGLE) {
29
+ var _dataset$selectedVar2;
30
+ setVarButtons(v => {
31
+ if (dataset.selectedVar) {
32
+ return _lodash.default.unionWith(v, [dataset.selectedVar], _lodash.default.isEqual);
33
+ } else {
34
+ return [];
135
35
  }
136
- }
137
- }
138
- }, [dispatch, varNames, updatedVarNames]);
139
- (0, _react.useEffect)(() => {
140
- if (!isPending && !serverError) {
141
- setVarNames(fetchedData);
142
- setUpdatedVarNames(true);
143
- }
144
- }, [fetchedData, isPending, serverError]);
145
- (0, _react.useEffect)(() => {
146
- if (mode === _constants.SELECTION_MODES.SINGLE && dataset.selectedVar) {
147
- validateSelection(dataset.selectVar, mode);
148
- setActive(dataset.selectedVar.matrix_index);
36
+ });
37
+ setActive((_dataset$selectedVar2 = dataset.selectedVar) === null || _dataset$selectedVar2 === void 0 ? void 0 : _dataset$selectedVar2.matrix_index);
149
38
  }
150
- }, [mode, dataset.selectedVar, dataset.selectVar, validateSelection]);
39
+ }, [mode, dataset.selectedVar]);
151
40
  (0, _react.useEffect)(() => {
152
41
  if (mode === _constants.SELECTION_MODES.MULTIPLE) {
153
- validateSelection(dataset.selectedMultiVar, mode);
42
+ setVarButtons(v => {
43
+ if (dataset.selectedMultiVar.length) {
44
+ return _lodash.default.unionWith(v, dataset.selectedMultiVar, _lodash.default.isEqual);
45
+ } else {
46
+ return [];
47
+ }
48
+ });
154
49
  setActive(dataset.selectedMultiVar.map(i => i.matrix_index));
155
50
  }
156
- }, [mode, dataset.selectedMultiVar, validateSelection]);
157
- const selectVar = item => {
158
- setVarButtons(() => {
159
- if (varButtons[0] && varButtons.find(v => v.matrix_index === item.matrix_index)) {
160
- return varButtons;
161
- } else {
162
- return [...varButtons, item];
163
- }
164
- });
51
+ }, [mode, dataset.selectedMultiVar]);
52
+ const selectVar = (0, _react.useCallback)(item => {
165
53
  if (mode === _constants.SELECTION_MODES.SINGLE) {
166
54
  dispatch({
167
55
  type: "varSelected",
@@ -173,26 +61,25 @@ function VarNamesList(_ref2) {
173
61
  var: item
174
62
  });
175
63
  }
176
- };
177
- const varList = (0, _react.useMemo)(() => {
178
- return varButtons.map(item => {
64
+ }, [dispatch, mode]);
65
+ const makeList = (0, _react.useCallback)(vars => {
66
+ return vars.map(item => {
179
67
  if (item && mode === _constants.SELECTION_MODES.SINGLE) {
180
68
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
181
69
  type: "button",
182
- variant: "outline-primary",
70
+ variant: item.matrix_index !== -1 ? "outline-primary" : "outline-secondary",
183
71
  className: "".concat(active === item.matrix_index && "active", " m-1"),
184
72
  onClick: () => {
185
- dispatch({
186
- type: "varSelected",
187
- var: item
188
- });
73
+ selectVar(item);
189
74
  },
75
+ disabled: item.matrix_index === -1,
76
+ title: item.matrix_index === -1 ? "Not present in data" : "",
190
77
  children: item.name
191
78
  }, item.matrix_index);
192
79
  } else if (mode === _constants.SELECTION_MODES.MULTIPLE) {
193
80
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
194
81
  type: "button",
195
- variant: "outline-primary",
82
+ variant: item.matrix_index !== -1 ? "outline-primary" : "outline-secondary",
196
83
  className: "".concat(active.includes(item.matrix_index) && "active", " m-1"),
197
84
  onClick: () => {
198
85
  if (active.includes(item.matrix_index)) {
@@ -201,38 +88,63 @@ function VarNamesList(_ref2) {
201
88
  var: item
202
89
  });
203
90
  } else {
204
- dispatch({
205
- type: "multiVarSelected",
206
- var: item
207
- });
91
+ selectVar(item);
208
92
  }
209
93
  },
94
+ disabled: item.matrix_index === -1,
95
+ title: item.matrix_index === -1 ? "Not present in data" : "",
210
96
  children: item.name
211
97
  }, item.matrix_index);
212
98
  } else {
213
99
  return null;
214
100
  }
215
101
  });
216
- }, [active, dispatch, mode, varButtons]);
217
- if (!serverError) {
218
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
219
- className: "position-relative",
220
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h4", {
221
- children: mode
222
- }), isPending && /*#__PURE__*/(0, _jsxRuntime.jsx)(_LoadingSpinner.LoadingSpinner, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(VarSearchBar, {
223
- varNames: varNames,
224
- onSelect: selectVar
102
+ }, [active, dispatch, mode, selectVar]);
103
+ const varList = (0, _react.useMemo)(() => {
104
+ return makeList(varButtons);
105
+ }, [makeList, varButtons]);
106
+ const diseaseVarList = (0, _react.useMemo)(() => {
107
+ return makeList(dataset.selectedDisease.genes);
108
+ }, [makeList, dataset.selectedDisease.genes]);
109
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
110
+ className: "position-relative",
111
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
112
+ className: "overflow-auto mt-2",
113
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
114
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
115
+ className: "d-flex justify-content-between",
116
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h5", {
117
+ children: _lodash.default.capitalize(displayName)
118
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
119
+ variant: "link",
120
+ onClick: () => {
121
+ dispatch({
122
+ type: mode === _constants.SELECTION_MODES.SINGLE ? "reset.var" : "reset.multiVar"
123
+ });
124
+ },
125
+ children: "clear"
126
+ })]
127
+ }), varList]
225
128
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
226
- className: "overflow-auto mt-2",
227
- children: varList
129
+ children: ((_dataset$selectedDise = dataset.selectedDisease) === null || _dataset$selectedDise === void 0 ? void 0 : _dataset$selectedDise.id) && ((_dataset$selectedDise2 = dataset.selectedDisease) === null || _dataset$selectedDise2 === void 0 || (_dataset$selectedDise2 = _dataset$selectedDise2.genes) === null || _dataset$selectedDise2 === void 0 ? void 0 : _dataset$selectedDise2.length) > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
130
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
131
+ className: "d-flex justify-content-between",
132
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h5", {
133
+ children: "Disease genes"
134
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
135
+ variant: "link",
136
+ onClick: () => {
137
+ dispatch({
138
+ type: "reset.disease"
139
+ });
140
+ },
141
+ children: "clear"
142
+ })]
143
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
144
+ children: (_dataset$selectedDise3 = dataset.selectedDisease) === null || _dataset$selectedDise3 === void 0 ? void 0 : _dataset$selectedDise3.name
145
+ }), diseaseVarList]
146
+ })
228
147
  })]
229
- });
230
- } else {
231
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
232
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Alert, {
233
- variant: "danger",
234
- children: serverError.message
235
- })
236
- });
237
- }
148
+ })
149
+ });
238
150
  }
@@ -74,6 +74,12 @@ const initialDataset = {
74
74
  },
75
75
  state: {
76
76
  obs: {}
77
+ },
78
+ diseaseDatasets: [],
79
+ selectedDisease: {
80
+ id: null,
81
+ name: null,
82
+ genes: []
77
83
  }
78
84
  };
79
85
  const initializer = initialState => {
@@ -125,10 +131,6 @@ function useDatasetDispatch() {
125
131
  }
126
132
  function datasetReducer(dataset, action) {
127
133
  switch (action.type) {
128
- case "setDataset":
129
- {
130
- return action.dataset;
131
- }
132
134
  case "set.obs":
133
135
  {
134
136
  return {
@@ -159,7 +161,7 @@ function datasetReducer(dataset, action) {
159
161
  }
160
162
  case "multiVarSelected":
161
163
  {
162
- if (dataset.selectedMultiVar.find(i => i === action.var)) {
164
+ if (dataset.selectedMultiVar.find(i => _lodash.default.isEqual(i, action.var))) {
163
165
  return dataset;
164
166
  } else {
165
167
  return {
@@ -172,7 +174,7 @@ function datasetReducer(dataset, action) {
172
174
  {
173
175
  return {
174
176
  ...dataset,
175
- selectedMultiVar: dataset.selectedMultiVar.filter(a => a !== action.var)
177
+ selectedMultiVar: dataset.selectedMultiVar.filter(a => a.matrix_index !== action.var.matrix_index)
176
178
  };
177
179
  }
178
180
  case "set.colorEncoding":
@@ -182,13 +184,52 @@ function datasetReducer(dataset, action) {
182
184
  colorEncoding: action.value
183
185
  };
184
186
  }
185
- case "multiVarReset":
187
+ case "reset.multiVar":
186
188
  {
187
189
  return {
188
190
  ...dataset,
189
191
  selectedMultiVar: []
190
192
  };
191
193
  }
194
+ case "reset.var":
195
+ {
196
+ return {
197
+ ...dataset,
198
+ selectedVar: null
199
+ };
200
+ }
201
+ case "select.disease":
202
+ {
203
+ return {
204
+ ...dataset,
205
+ selectedDisease: {
206
+ id: action.id,
207
+ name: action.name,
208
+ genes: []
209
+ }
210
+ };
211
+ }
212
+ case "set.disease.genes":
213
+ {
214
+ return {
215
+ ...dataset,
216
+ selectedDisease: {
217
+ ...dataset.selectedDisease,
218
+ genes: action.genes
219
+ }
220
+ };
221
+ }
222
+ case "reset.disease":
223
+ {
224
+ return {
225
+ ...dataset,
226
+ selectedDisease: {
227
+ id: null,
228
+ name: null,
229
+ genes: []
230
+ }
231
+ };
232
+ }
192
233
  case "set.controls.colorScale":
193
234
  {
194
235
  return {
@@ -21,7 +21,7 @@ class ColorHelper {
21
21
  if (colorEncoding === "var") {
22
22
  return scale(value).rgb();
23
23
  } else if (colorEncoding === "obs") {
24
- return state.hasOwnProperty(value) ? state[value]["color"] : null;
24
+ return state !== null && state !== void 0 && state.hasOwnProperty(value) ? state[value]["color"] : null;
25
25
  }
26
26
  });
27
27
  }
package/dist/index.js CHANGED
@@ -111,6 +111,12 @@ Object.defineProperty(exports, "ScatterplotControls", {
111
111
  return _Scatterplot.ScatterplotControls;
112
112
  }
113
113
  });
114
+ Object.defineProperty(exports, "SearchBar", {
115
+ enumerable: true,
116
+ get: function () {
117
+ return _SearchBar.SearchBar;
118
+ }
119
+ });
114
120
  Object.defineProperty(exports, "VIOLIN_MODES", {
115
121
  enumerable: true,
116
122
  get: function () {
@@ -138,6 +144,7 @@ Object.defineProperty(exports, "ViolinControls", {
138
144
  var _ObsList = require("./components/obs-list/ObsList");
139
145
  var _ObsmList = require("./components/obsm-list/ObsmList");
140
146
  var _VarList = require("./components/var-list/VarList");
147
+ var _SearchBar = require("./components/search-bar/SearchBar");
141
148
  var _Heatmap = require("./components/heatmap/Heatmap");
142
149
  var _Dotplot = require("./components/dotplot/Dotplot");
143
150
  var _Scatterplot = require("./components/scatterplot/Scatterplot");
@@ -11,7 +11,8 @@ var _errors = require("./errors");
11
11
  async function fetchData(endpoint, params) {
12
12
  let signal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
13
13
  let ms = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 300000;
14
- const apiUrl = process.env.REACT_APP_API_URL;
14
+ let apiUrl = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
15
+ apiUrl = apiUrl || process.env.REACT_APP_API_URL;
15
16
  const controller = new AbortController();
16
17
  const timeout = setTimeout(() => {
17
18
  controller.abort(DOMException.TIMEOUT_ERR);
@@ -40,6 +41,10 @@ async function fetchData(endpoint, params) {
40
41
  }
41
42
  const useFetch = function (endpoint, params) {
42
43
  let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
44
+ let apiUrl = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
45
+ const {
46
+ enabled = true
47
+ } = opts;
43
48
  const {
44
49
  data: fetchedData,
45
50
  isLoading: isPending,
@@ -50,7 +55,11 @@ const useFetch = function (endpoint, params) {
50
55
  let {
51
56
  signal
52
57
  } = _ref;
53
- return fetchData(endpoint, params, signal);
58
+ if (enabled) {
59
+ return fetchData(endpoint, params, signal, apiUrl);
60
+ } else {
61
+ return;
62
+ }
54
63
  },
55
64
  ...opts
56
65
  });
@@ -64,6 +73,10 @@ exports.useFetch = useFetch;
64
73
  const useDebouncedFetch = function (endpoint, params) {
65
74
  let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500;
66
75
  let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
76
+ let apiUrl = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
77
+ const {
78
+ enabled = true
79
+ } = opts;
67
80
  const debouncedParams = (0, _usehooks.useDebounce)(params, delay);
68
81
  const {
69
82
  data: fetchedData,
@@ -75,7 +88,11 @@ const useDebouncedFetch = function (endpoint, params) {
75
88
  let {
76
89
  signal
77
90
  } = _ref2;
78
- return fetchData(endpoint, debouncedParams, signal);
91
+ if (enabled) {
92
+ return fetchData(endpoint, debouncedParams, signal, apiUrl);
93
+ } else {
94
+ return;
95
+ }
79
96
  },
80
97
  ...opts
81
98
  });
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useVarSearch = exports.useGetDisease = exports.useDiseaseSearch = void 0;
7
+ var _react = require("react");
8
+ var _DatasetContext = require("../context/DatasetContext");
9
+ var _requests = require("./requests");
10
+ const useDiseaseSearch = () => {
11
+ const ENDPOINT = "diseases";
12
+ const dataset = (0, _DatasetContext.useDataset)();
13
+ const [params, setParams] = (0, _react.useState)({
14
+ url: dataset.url,
15
+ diseaseDatasets: dataset.diseaseDatasets,
16
+ text: ""
17
+ });
18
+ const data = (0, _requests.useFetch)(ENDPOINT, params, {
19
+ enabled: !!params.text.length
20
+ });
21
+ return {
22
+ params,
23
+ setParams,
24
+ data
25
+ };
26
+ };
27
+ exports.useDiseaseSearch = useDiseaseSearch;
28
+ const useVarSearch = () => {
29
+ const ENDPOINT = "var/names";
30
+ const dataset = (0, _DatasetContext.useDataset)();
31
+ const dispatch = (0, _DatasetContext.useDatasetDispatch)();
32
+ const [params, setParams] = (0, _react.useState)({
33
+ url: dataset.url,
34
+ text: ""
35
+ });
36
+ const data = (0, _requests.useFetch)(ENDPOINT, params, {
37
+ enabled: !!params.text.length
38
+ });
39
+ const onSelect = item => {
40
+ dispatch({
41
+ type: "varSelected",
42
+ var: item
43
+ });
44
+ dispatch({
45
+ type: "multiVarSelected",
46
+ var: item
47
+ });
48
+ };
49
+ return {
50
+ params,
51
+ setParams,
52
+ data,
53
+ onSelect
54
+ };
55
+ };
56
+ exports.useVarSearch = useVarSearch;
57
+ const useGetDisease = () => {
58
+ var _dataset$selectedDise, _dataset$selectedDise2, _params$diseaseName;
59
+ const ENDPOINT = "disease/genes";
60
+ const dataset = (0, _DatasetContext.useDataset)();
61
+ const dispatch = (0, _DatasetContext.useDatasetDispatch)();
62
+ const [params, setParams] = (0, _react.useState)({
63
+ url: dataset.url,
64
+ col: dataset.varNamesCol,
65
+ diseaseName: (_dataset$selectedDise = dataset.selectedDisease) === null || _dataset$selectedDise === void 0 ? void 0 : _dataset$selectedDise.name,
66
+ diseaseDatasets: dataset.diseaseDatasets
67
+ });
68
+ (0, _react.useEffect)(() => {
69
+ setParams(p => {
70
+ return {
71
+ ...p,
72
+ diseaseName: dataset.selectedDisease.name
73
+ };
74
+ });
75
+ }, [(_dataset$selectedDise2 = dataset.selectedDisease) === null || _dataset$selectedDise2 === void 0 ? void 0 : _dataset$selectedDise2.name]);
76
+ const {
77
+ fetchedData,
78
+ isPending,
79
+ serverError
80
+ } = (0, _requests.useFetch)(ENDPOINT, params, {
81
+ enabled: !!((_params$diseaseName = params.diseaseName) !== null && _params$diseaseName !== void 0 && _params$diseaseName.length)
82
+ });
83
+ (0, _react.useEffect)(() => {
84
+ if (!isPending && !serverError) {
85
+ dispatch({
86
+ type: "set.disease.genes",
87
+ genes: fetchedData
88
+ });
89
+ }
90
+ }, [dispatch, fetchedData, isPending, serverError]);
91
+ return;
92
+ };
93
+ exports.useGetDisease = useGetDisease;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haniffalab/cherita-react",
3
- "version": "0.2.0-dev.2024-05-09.97c686f2",
3
+ "version": "0.2.0-dev.2024-05-09.07fb18ed",
4
4
  "author": "",
5
5
  "license": "",
6
6
  "main": "dist/index.js",
@@ -78,5 +78,5 @@
78
78
  "url": "https://github.com/haniffalab/cherita-react/issues"
79
79
  },
80
80
  "homepage": "https://github.com/haniffalab/cherita-react#readme",
81
- "prereleaseSha": "97c686f2f71b9fd317123f14ba380ca42cbbbe7f"
81
+ "prereleaseSha": "07fb18ed8d66be9ecd7817e41b76b1b5cdf3ba7b"
82
82
  }