@haniffalab/cherita-react 1.2.0-dev.2025-04-30.0a204a1c → 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.
@@ -4,13 +4,13 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
4
4
  import _ from "lodash";
5
5
  import { Alert, Button, ListGroup } from "react-bootstrap";
6
6
  import ButtonGroup from "react-bootstrap/ButtonGroup";
7
+ import { VarItem } from "./VarItem";
8
+ import { VarListToolbar } from "./VarListToolbar";
9
+ import { VarSet } from "./VarSet";
7
10
  import { SELECTION_MODES, VAR_SORT } from "../../constants/constants";
8
11
  import { useDataset, useDatasetDispatch } from "../../context/DatasetContext";
9
12
  import { LoadingSpinner } from "../../utils/LoadingIndicators";
10
13
  import { useFetch } from "../../utils/requests";
11
- import { VarItem } from "./VarItem";
12
- import { VarListToolbar } from "./VarListToolbar";
13
- import { VarSet } from "./VarSet";
14
14
  const useVarMean = function (varKeys) {
15
15
  let enabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
16
16
  const ENDPOINT = "matrix/mean";
@@ -45,93 +45,11 @@ const useVarMean = function (varKeys) {
45
45
  const sortMeans = (i, means) => {
46
46
  return means[i.name] || _.min(_.values(means)) - 1;
47
47
  };
48
-
49
- // @TODO: display where disease data comes from
50
- // add to disease dataset metadata
51
- function DiseaseVarList(_ref) {
52
- let {
53
- makeListItem
54
- } = _ref;
55
- const ENDPOINT = "disease/genes";
56
- const dataset = useDataset();
57
- const dispatch = useDatasetDispatch();
58
- const [diseaseVars, setDiseaseVars] = useState([]);
59
- const [sortedDiseaseVars, setSortedDiseaseVars] = useState([]);
60
- const [params, setParams] = useState({
61
- url: dataset.url,
62
- col: dataset.varNamesCol,
63
- diseaseId: dataset.selectedDisease?.id,
64
- diseaseDatasets: dataset.diseaseDatasets
65
- });
66
- useEffect(() => {
67
- setParams(p => {
68
- return {
69
- ...p,
70
- diseaseId: dataset.selectedDisease?.id
71
- };
72
- });
73
- }, [dataset.selectedDisease]);
74
- const diseaseData = useFetch(ENDPOINT, params, {
75
- enabled: !!params.diseaseId,
76
- refetchOnMount: false
77
- });
78
- useEffect(() => {
79
- if (!diseaseData.isPending && !diseaseData.serverError) {
80
- setDiseaseVars(diseaseData.fetchedData);
81
- }
82
- }, [diseaseData.fetchedData, diseaseData.isPending, diseaseData.serverError]);
83
- const varMeans = useVarMean(diseaseVars, !!diseaseVars?.length && dataset.varSort.disease.sort === VAR_SORT.MATRIX);
84
- useEffect(() => {
85
- if (dataset.varSort.disease.sort === VAR_SORT.MATRIX) {
86
- if (!varMeans.isPending && !varMeans.serverError) {
87
- setSortedDiseaseVars(_.orderBy(diseaseVars, o => {
88
- return sortMeans(o, varMeans.fetchedData);
89
- }, dataset.varSort.disease.sortOrder));
90
- }
91
- } else if (dataset.varSort.disease.sort === VAR_SORT.NAME) {
92
- setSortedDiseaseVars(_.orderBy(diseaseVars, "name", dataset.varSort.disease.sortOrder));
93
- } else {
94
- setSortedDiseaseVars(diseaseVars);
95
- }
96
- }, [dataset.varSort.disease.sort, dataset.varSort.disease.sortOrder, diseaseVars, varMeans.fetchedData, varMeans.isPending, varMeans.serverError]);
97
- const diseaseVarList = _.map(sortedDiseaseVars, item => {
98
- return makeListItem(item, true);
99
- });
100
- const isPending = diseaseData.isPending || varMeans.isPending && dataset.varSort.disease.sort === VAR_SORT.MATRIX;
101
- return /*#__PURE__*/React.createElement(React.Fragment, null, dataset.selectedDisease && (!isPending && !diseaseVars?.length ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
102
- className: "d-flex justify-content-between mt-3"
103
- }, /*#__PURE__*/React.createElement("h5", null, "Disease genes")), /*#__PURE__*/React.createElement(Alert, {
104
- variant: "light"
105
- }, "No disease genes found.")) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
106
- className: "d-flex justify-content-between my-2"
107
- }, /*#__PURE__*/React.createElement("h5", null, "Disease genes"), /*#__PURE__*/React.createElement(ButtonGroup, {
108
- "aria-label": "Feature options",
109
- size: "sm"
110
- }, /*#__PURE__*/React.createElement(Button, {
111
- variant: "info",
112
- onClick: () => {
113
- dispatch({
114
- type: "reset.disease"
115
- });
116
- }
117
- }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
118
- icon: faTimes,
119
- className: "me-1"
120
- }), "Clear"))), /*#__PURE__*/React.createElement("p", null, dataset.selectedDisease?.name), /*#__PURE__*/React.createElement(VarListToolbar, {
121
- varType: "disease"
122
- }), /*#__PURE__*/React.createElement("div", {
123
- className: "position-relative"
124
- }, isPending && /*#__PURE__*/React.createElement(LoadingSpinner, null), /*#__PURE__*/React.createElement(ListGroup, {
125
- variant: "flush",
126
- className: "cherita-list"
127
- }, diseaseVarList)))));
128
- }
129
- export function VarNamesList(_ref2) {
48
+ export function VarNamesList(_ref) {
130
49
  let {
131
50
  mode = SELECTION_MODES.SINGLE,
132
- displayName = "genes",
133
- showDiseaseVarList = true
134
- } = _ref2;
51
+ displayName = "genes"
52
+ } = _ref;
135
53
  const dataset = useDataset();
136
54
  const dispatch = useDatasetDispatch();
137
55
  const [varButtons, setVarButtons] = useState(mode === SELECTION_MODES.SINGLE ? dataset.selectedVar ? _.unionWith([dataset.selectedVar], dataset.varSets, _.isEqual) : [...dataset.varSets] : [...dataset.selectedMultiVar, ...dataset.varSets]);
@@ -285,7 +203,5 @@ export function VarNamesList(_ref2) {
285
203
  }, isPending && /*#__PURE__*/React.createElement(LoadingSpinner, null), /*#__PURE__*/React.createElement(ListGroup, {
286
204
  variant: "flush",
287
205
  className: "cherita-list"
288
- }, varList)))), /*#__PURE__*/React.createElement(React.Fragment, null, showDiseaseVarList && /*#__PURE__*/React.createElement(DiseaseVarList, {
289
- makeListItem: makeListItem
290
- }))));
206
+ }, varList))))));
291
207
  }
@@ -1,13 +1,12 @@
1
1
  import React, { useState } from "react";
2
- import { faCircleInfo, faDroplet, faTrash } from "@fortawesome/free-solid-svg-icons";
2
+ import { faChevronDown, faChevronUp, faCircleInfo, faDroplet, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
3
3
  import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
4
- import { List } from "@mui/icons-material";
5
4
  import _ from "lodash";
6
5
  import { Button, Collapse, ListGroup, OverlayTrigger, Tooltip } from "react-bootstrap";
6
+ import { SingleSelectionItem } from "./VarItem";
7
7
  import { COLOR_ENCODINGS, SELECTION_MODES } from "../../constants/constants";
8
8
  import { useDataset, useDatasetDispatch } from "../../context/DatasetContext";
9
- import { SearchBar } from "../search-bar/SearchBar";
10
- import { SingleSelectionItem } from "./VarItem";
9
+ import { SearchModal } from "../search-bar/SearchBar";
11
10
 
12
11
  // @TODO: add button to score genes and plot
13
12
 
@@ -24,10 +23,11 @@ function SingleSelectionSet(_ref) {
24
23
  isActive,
25
24
  selectSet,
26
25
  removeSet,
27
- removeSetVar,
28
- showSearchBar = true
26
+ removeSetVar
29
27
  } = _ref;
30
28
  const [openSet, setOpenSet] = useState(false);
29
+ const [showModal, setShowModal] = useState(false);
30
+ const [searchText, setSearchText] = useState("");
31
31
  const varList = set.vars.length ? _.map(set.vars, v => {
32
32
  return /*#__PURE__*/React.createElement(ListGroup.Item, {
33
33
  key: v.name
@@ -46,16 +46,38 @@ function SingleSelectionSet(_ref) {
46
46
  }
47
47
  }, /*#__PURE__*/React.createElement("div", {
48
48
  className: "d-flex justify-content-between align-items-center w-100"
49
- }, /*#__PURE__*/React.createElement("div", null, set.name), /*#__PURE__*/React.createElement("div", {
49
+ }, /*#__PURE__*/React.createElement("div", {
50
+ className: "ellipsis-text",
51
+ title: set.name
52
+ }, set.name), /*#__PURE__*/React.createElement("div", {
50
53
  className: "d-flex align-items-center gap-1"
51
54
  }, /*#__PURE__*/React.createElement(OverlayTrigger, {
52
55
  placement: "top",
53
56
  overlay: /*#__PURE__*/React.createElement(Tooltip, null, "This set represents the mean value of its features")
54
57
  }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
55
58
  icon: faCircleInfo
56
- })), /*#__PURE__*/React.createElement(List, null), /*#__PURE__*/React.createElement(Button, {
59
+ })), /*#__PURE__*/React.createElement(Button, {
60
+ type: "button",
61
+ variant: "outline-primary",
62
+ className: "m-0 p-0 px-1",
63
+ disabled: !set.vars.length,
64
+ title: "Open set"
65
+ }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
66
+ icon: openSet ? faChevronUp : faChevronDown
67
+ })), /*#__PURE__*/React.createElement(Button, {
68
+ type: "button",
69
+ variant: "outline-primary",
70
+ className: "m-0 p-0 px-1",
71
+ onClick: e => {
72
+ e.stopPropagation();
73
+ setShowModal(true);
74
+ },
75
+ disabled: !set.vars.length,
76
+ title: "Add to set"
77
+ }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
78
+ icon: faPlus
79
+ })), /*#__PURE__*/React.createElement(Button, {
57
80
  type: "button",
58
- key: set.name,
59
81
  variant: isActive ? "primary" : "outline-primary",
60
82
  className: "m-0 p-0 px-1",
61
83
  onClick: e => {
@@ -81,17 +103,21 @@ function SingleSelectionSet(_ref) {
81
103
  in: openSet
82
104
  }, /*#__PURE__*/React.createElement("div", {
83
105
  className: "mt-2"
84
- }, showSearchBar &&
85
- /*#__PURE__*/
86
- // @TODO: fix how results are displayed, should be placed on top of parent components
87
- React.createElement(SearchBar, {
88
- handleSelect: (d, i) => addVarToSet(d, set, i)
89
- }), /*#__PURE__*/React.createElement("div", {
90
- className: "mx-2"
91
106
  }, /*#__PURE__*/React.createElement(ListGroup, {
92
107
  variant: "flush",
93
- className: "cherita-list"
94
- }, varList)))));
108
+ className: "cherita-list var-set-list"
109
+ }, varList))), /*#__PURE__*/React.createElement(SearchModal, {
110
+ show: showModal,
111
+ handleClose: () => setShowModal(false),
112
+ text: searchText,
113
+ setText: setSearchText,
114
+ displayText: "features",
115
+ handleSelect: (d, i) => {
116
+ addVarToSet(d, set, i);
117
+ },
118
+ searchVar: true,
119
+ searchDiseases: false
120
+ }));
95
121
  }
96
122
  function MultipleSelectionSet(_ref2) {
97
123
  let {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haniffalab/cherita-react",
3
- "version": "1.2.0-dev.2025-04-30.0a204a1c",
3
+ "version": "1.2.0-dev.2025-05-16.4367ee63",
4
4
  "author": "Haniffa Lab",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -124,5 +124,5 @@
124
124
  "url": "https://github.com/haniffalab/cherita-react/issues"
125
125
  },
126
126
  "homepage": "https://github.com/haniffalab/cherita-react#readme",
127
- "prereleaseSha": "0a204a1c659c6b7f9438049af143289feccd943b"
127
+ "prereleaseSha": "4367ee63df5209cda070f21e714ac5c6ccaa1e2c"
128
128
  }
package/scss/cherita.scss CHANGED
@@ -395,3 +395,9 @@ $gauge-padding: 0.15rem;
395
395
  margin-right: 0.4rem;
396
396
  width: 1rem;
397
397
  }
398
+
399
+ .ellipsis-text {
400
+ white-space: nowrap;
401
+ overflow: hidden;
402
+ text-overflow: ellipsis;
403
+ }
@@ -102,3 +102,8 @@
102
102
  }
103
103
  }
104
104
  }
105
+
106
+ .search-modal-info {
107
+ overflow-y: auto;
108
+ border-left: 1px solid #dee2e6;
109
+ }
@@ -13,6 +13,10 @@
13
13
  color: var(--#{$prefix}body-color);
14
14
  background-color: var(--#{$prefix}tertiary-bg);
15
15
  border-radius: var(--#{$prefix}border-radius);
16
+ cursor: pointer;
17
+ }
18
+ .list-group-item.active {
19
+ background-color: var(--#{$prefix}secondary-bg);
16
20
  }
17
21
  }
18
22
  .obs-statistics {
@@ -24,3 +28,10 @@
24
28
  background-color: var(--#{$prefix}tertiary-bg);
25
29
  border-radius: var(--#{$prefix}border-radius);
26
30
  }
31
+
32
+ .cherita-list.var-set-list {
33
+ .list-group-item {
34
+ padding-right: 0;
35
+ padding-left: 0.35rem;
36
+ }
37
+ }