@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.
- package/dist/cjs/components/full-page/FullPage.js +19 -26
- package/dist/cjs/components/full-page/FullPagePseudospatial.js +20 -26
- package/dist/cjs/components/offcanvas/index.js +1 -2
- package/dist/cjs/components/scatterplot/Scatterplot.js +8 -2
- package/dist/cjs/components/scatterplot/SpatialControls.js +46 -17
- package/dist/cjs/components/scatterplot/Toolbox.js +1 -18
- package/dist/cjs/components/search-bar/SearchBar.js +152 -57
- package/dist/cjs/components/search-bar/SearchInfo.js +175 -0
- package/dist/cjs/components/search-bar/SearchResults.js +58 -33
- package/dist/cjs/components/var-list/VarItem.js +70 -0
- package/dist/cjs/components/var-list/VarList.js +7 -91
- package/dist/cjs/components/var-list/VarSet.js +42 -16
- package/dist/cjs/utils/Legend.js +14 -8
- package/dist/css/cherita.css +60 -10
- package/dist/css/cherita.css.map +1 -1
- package/dist/esm/components/full-page/FullPage.js +20 -27
- package/dist/esm/components/full-page/FullPagePseudospatial.js +21 -27
- package/dist/esm/components/offcanvas/index.js +1 -2
- package/dist/esm/components/scatterplot/Scatterplot.js +8 -2
- package/dist/esm/components/scatterplot/SpatialControls.js +47 -18
- package/dist/esm/components/scatterplot/Toolbox.js +1 -18
- package/dist/esm/components/search-bar/SearchBar.js +153 -59
- package/dist/esm/components/search-bar/SearchInfo.js +165 -0
- package/dist/esm/components/search-bar/SearchResults.js +60 -35
- package/dist/esm/components/var-list/VarItem.js +70 -2
- package/dist/esm/components/var-list/VarList.js +7 -91
- package/dist/esm/components/var-list/VarSet.js +44 -18
- package/dist/esm/utils/Legend.js +14 -8
- package/package.json +2 -2
- package/scss/cherita.scss +44 -5
- package/scss/components/layouts.scss +20 -13
- package/scss/components/lists.scss +11 -0
- 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
|
-
|
|
21
|
-
|
|
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
|
|
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
|
-
|
|
60
|
+
setResultsLength(fetchedData?.length);
|
|
58
61
|
}
|
|
59
|
-
}, [fetchedData, isPending, serverError,
|
|
62
|
+
}, [fetchedData, isPending, serverError, setResultsLength]);
|
|
60
63
|
const getDataAtIndex = index => deferredData[index];
|
|
61
|
-
const ItemComponent = item => /*#__PURE__*/_react.default.createElement(
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
},
|
|
72
|
-
|
|
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:
|
|
80
|
-
maxHeight: "
|
|
81
|
-
}) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.
|
|
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
|
-
|
|
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
|
-
|
|
146
|
+
setResultsLength(fetchedData?.length);
|
|
126
147
|
}
|
|
127
|
-
}, [fetchedData, isPending, serverError,
|
|
148
|
+
}, [fetchedData, isPending, serverError, setResultsLength]);
|
|
128
149
|
const getDataAtIndex = index => deferredData[index];
|
|
129
|
-
const ItemComponent = item => /*#__PURE__*/_react.default.createElement(
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}, item.disease_name);
|
|
144
|
-
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(
|
|
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: "
|
|
153
|
-
}) : /*#__PURE__*/_react.default.createElement(_reactBootstrap.
|
|
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
|
-
|
|
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))))
|
|
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",
|
|
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(
|
|
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 {
|