@bento-core/query-bar 1.0.1-ccdihub.9 → 1.0.1-ccdiintegrated.2

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.
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="19" viewBox="0 0 16 19" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M13 9.75715C13 10.0452 12.78 10.2714 12.5 10.2714H7.5C7.22 10.2714 7 10.0452 7 9.75715C7 9.46915 7.22 9.24287 7.5 9.24287H12.5C12.78 9.24287 13 9.46915 13 9.75715ZM12.5 11.3H7.5C7.22 11.3 7 11.5263 7 11.8143C7 12.1023 7.22 12.3286 7.5 12.3286H12.5C12.78 12.3286 13 12.1023 13 11.8143C13 11.5263 12.78 11.3 12.5 11.3ZM12.5 13.3572H7.5C7.22 13.3572 7 13.5834 7 13.8714C7 14.1594 7.22 14.3857 7.5 14.3857H12.5C12.78 14.3857 13 14.1594 13 13.8714C13 13.5834 12.78 13.3572 12.5 13.3572ZM16 8.21429V16.4429C16 17.5743 15.1 18.5 14 18.5H6C4.9 18.5 4 17.5743 4 16.4429V15.4143H2C0.9 15.4143 0 14.4886 0 13.3572V4.10001C0 2.96858 0.9 2.04286 2 2.04286H4.5C4.5 1.18915 5.17 0.500008 6 0.500008C6.83 0.500008 7.5 1.18915 7.5 2.04286H10C11.1 2.04286 12 2.96858 12 4.10001V6.15715H14C15.1 6.15715 16 7.08287 16 8.21429ZM6 6.15715H11V4.10001C11 3.53429 10.55 3.07144 10 3.07144H9V4.10001H3V3.07144H2C1.45 3.07144 1 3.53429 1 4.10001V13.3572C1 13.9229 1.45 14.3857 2 14.3857H4V8.21429C4 7.08287 4.9 6.15715 6 6.15715ZM15 8.21429C15 7.64858 14.55 7.18572 14 7.18572H6C5.45 7.18572 5 7.64858 5 8.21429V16.4429C5 17.0086 5.45 17.4714 6 17.4714H14C14.55 17.4714 15 17.0086 15 16.4429V8.21429Z" fill="#142D64"/>
3
+ </svg>
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _clsx = _interopRequireDefault(require("clsx"));
9
+ var _core = require("@material-ui/core");
10
+ var _CopyIcon = _interopRequireDefault(require("../assets/CopyIcon.svg"));
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
13
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
14
+ const QueryUrl = _ref => {
15
+ let {
16
+ classes,
17
+ queryUrlCharacterLimit = 70
18
+ } = _ref;
19
+ const [display, setDisplay] = (0, _react.useState)(false);
20
+ const toggleDisplay = () => setDisplay(prevDisplay => !prevDisplay);
21
+ const [open, setOpen] = (0, _react.useState)(false);
22
+ const toggleOpen = () => setOpen(prevOpen => !prevOpen);
23
+ const url = window.location.href;
24
+ const copyUrl = async () => {
25
+ toggleOpen();
26
+ await navigator.clipboard.writeText(url);
27
+ };
28
+ const queryRef = (0, _react.useRef)(null);
29
+ return /*#__PURE__*/_react.default.createElement("div", {
30
+ style: {
31
+ position: 'relative',
32
+ right: '6px'
33
+ }
34
+ }, /*#__PURE__*/_react.default.createElement("div", {
35
+ ref: queryRef,
36
+ className: classes.urlContainer
37
+ }, /*#__PURE__*/_react.default.createElement(_core.Button, {
38
+ onClick: toggleDisplay,
39
+ className: classes.viewLinkToggleBtn
40
+ }, display ? 'Hide Query URL' : 'Show Query URL'), display && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
41
+ type: "button",
42
+ className: (0, _clsx.default)(classes.viewLink)
43
+ }, url.length > queryUrlCharacterLimit ? "".concat(url.substring(0, queryUrlCharacterLimit), "...") : url), /*#__PURE__*/_react.default.createElement(_core.Tooltip, {
44
+ arrow: true,
45
+ title: "Copy to Clipboard"
46
+ }, /*#__PURE__*/_react.default.createElement(_core.IconButton, {
47
+ onClick: copyUrl,
48
+ className: classes.copyIconBtn
49
+ }, /*#__PURE__*/_react.default.createElement("img", {
50
+ src: _CopyIcon.default,
51
+ alt: "copy icon"
52
+ }))))), /*#__PURE__*/_react.default.createElement(_core.Dialog, {
53
+ open: open,
54
+ onClose: () => toggleOpen(),
55
+ "aria-labelledby": "alert-dialog-title",
56
+ "aria-describedby": "alert-dialog-description",
57
+ className: (0, _clsx.default)(classes.dialogBox, 'dialogBox')
58
+ }, /*#__PURE__*/_react.default.createElement(_core.DialogContent, {
59
+ className: classes.okText
60
+ }, /*#__PURE__*/_react.default.createElement(_core.DialogContentText, {
61
+ id: "alert-dialog-description"
62
+ }, "Your query URL has been copied!")), /*#__PURE__*/_react.default.createElement(_core.DialogActions, null, /*#__PURE__*/_react.default.createElement(_core.Button, {
63
+ onClick: () => toggleOpen()
64
+ }, "OK"))));
65
+ };
66
+ const styles = () => ({
67
+ urlContainer: {
68
+ display: 'flex',
69
+ marginTop: '3px',
70
+ minHeight: '10px'
71
+ },
72
+ viewLink: {
73
+ overflow: 'hidden',
74
+ textOverflow: 'ellipsis',
75
+ fontFamily: 'Nunito',
76
+ fontSize: '12px',
77
+ fontWeight: '500',
78
+ lineHeight: '16px',
79
+ letterSpacing: '0em',
80
+ padding: '2px 5px',
81
+ borderRadius: '5px',
82
+ float: 'left',
83
+ color: '#1D79A8',
84
+ backgroundColor: '#fff',
85
+ margin: '0',
86
+ whiteSpace: 'nowrap',
87
+ wordBreak: 'break-all',
88
+ '@media (max-width: 2560px)': {
89
+ maxWidth: '1800px'
90
+ },
91
+ '@media (max-width: 2000px)': {
92
+ maxWidth: '1500px'
93
+ },
94
+ '@media (max-width: 1600px)': {
95
+ maxWidth: '1100px'
96
+ },
97
+ '@media (max-width: 1300px)': {
98
+ maxWidth: '900px'
99
+ }
100
+ },
101
+ urlViewBtn: {
102
+ cursor: 'pointer'
103
+ },
104
+ viewLinkToggleBtn: {
105
+ padding: '5px 10px 5px 10px',
106
+ height: '20px',
107
+ fontFamily: 'Nunito',
108
+ fontSize: '12px',
109
+ fontWeight: '500',
110
+ lineHeight: '16px',
111
+ letterSpacing: '0em',
112
+ textAlign: 'left',
113
+ backgroundColor: '#1D79A8',
114
+ textTransform: 'none',
115
+ color: '#fff',
116
+ float: 'left',
117
+ margin: '0px 10px 0px 0px',
118
+ whiteSpace: 'nowrap',
119
+ '&:hover': {
120
+ backgroundColor: '#1D79A8',
121
+ color: '#fff'
122
+ }
123
+ },
124
+ copyIconBtn: {
125
+ padding: '0px',
126
+ height: '20px',
127
+ marginLeft: '10px',
128
+ float: 'left'
129
+ }
130
+ });
131
+ var _default = (0, _core.withStyles)(styles)(QueryUrl);
132
+ exports.default = _default;
@@ -17,18 +17,49 @@ var _default = _ref => {
17
17
  } = _ref;
18
18
  const {
19
19
  items,
20
- section
20
+ section,
21
+ unknownAges
21
22
  } = data;
23
+
24
+ // Determine the display logic based on unknownAges selection
25
+ const getDisplayContent = () => {
26
+ const baseLabel = data.label;
27
+ if (unknownAges === 'only') {
28
+ // Only: Show base label with unknown ages only, no range
29
+ return {
30
+ label: "".concat(baseLabel, " (Unknown Ages Only)"),
31
+ showRange: false,
32
+ rangeText: ''
33
+ };
34
+ }
35
+ if (unknownAges === 'exclude') {
36
+ // Exclude: Show base label with unknown ages excluded, with range only if items exist
37
+ const hasRange = items && items.length >= 2;
38
+ return {
39
+ label: "".concat(baseLabel, " (Unknown Ages Excluded)"),
40
+ showRange: hasRange,
41
+ rangeText: hasRange ? "".concat(items[0], " \u2013 ").concat(items[1]) : ''
42
+ };
43
+ }
44
+
45
+ // Include: Normal display (base label with range)
46
+ return {
47
+ label: baseLabel,
48
+ showRange: true,
49
+ rangeText: items && items.length >= 2 ? "".concat(items[0], " \u2013 ").concat(items[1]) : ''
50
+ };
51
+ };
52
+ const displayContent = getDisplayContent();
22
53
  return /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement("span", null, ' ', index !== 0 ? /*#__PURE__*/_react.default.createElement("span", {
23
54
  className: classes.operators
24
55
  }, " AND ") : '', /*#__PURE__*/_react.default.createElement("span", {
25
56
  className: (0, _clsx.default)(classes.filterName, classes["facetSection".concat(section, "Background")]),
26
57
  onClick: () => onSectionClick(data)
27
- }, data.label), ' '), /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
58
+ }, displayContent.label), ' '), displayContent.showRange && /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
28
59
  className: classes.operators
29
60
  }, "IS BETWEEN", ' '), /*#__PURE__*/_react.default.createElement("span", {
30
61
  className: (0, _clsx.default)(classes.filterCheckboxes, classes["facetSection".concat(section)]),
31
62
  onClick: () => onItemClick(data, items[0])
32
- }, "".concat(items[0], " \u2013 ").concat(items[1]))));
63
+ }, displayContent.rangeText)));
33
64
  };
34
65
  exports.default = _default;
@@ -11,6 +11,7 @@ var _clsx = _interopRequireDefault(require("clsx"));
11
11
  var _FilterMap = require("../components/FilterMap");
12
12
  var _styles = _interopRequireDefault(require("./styles"));
13
13
  var _config = _interopRequireDefault(require("./config"));
14
+ var _QueryUrl = _interopRequireDefault(require("../components/QueryUrl"));
14
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
16
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
16
17
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -34,17 +35,21 @@ const QueryBarGenerator = function QueryBarGenerator() {
34
35
  } = _facetFilter.InputTypes;
35
36
  const maxItems = config && typeof config.maxItems === 'number' ? config.maxItems : _config.default.config.maxItems;
36
37
  const clearAll = functions && typeof functions.clearAll === 'function' ? functions.clearAll : _config.default.functions.clearAll;
38
+ const clearImportFrom = functions && typeof functions.clearImportFrom === 'function' ? functions.clearImportFrom : _config.default.functions.clearImportFrom;
37
39
  const clearUpload = functions && typeof functions.clearUpload === 'function' ? functions.clearUpload : _config.default.functions.clearUpload;
38
40
  const clearAutocomplete = functions && typeof functions.clearAutocomplete === 'function' ? functions.clearAutocomplete : _config.default.functions.clearAutocomplete;
39
41
  const deleteAutocompleteItem = functions && typeof functions.deleteAutocompleteItem === 'function' ? functions.deleteAutocompleteItem : _config.default.functions.deleteAutocompleteItem;
40
42
  const resetFacetSection = functions && typeof functions.resetFacetSection === 'function' ? functions.resetFacetSection : _config.default.functions.resetFacetSection;
41
43
  const resetFacetCheckbox = functions && typeof functions.resetFacetCheckbox === 'function' ? functions.resetFacetCheckbox : _config.default.functions.resetFacetCheckbox;
42
44
  const resetFacetSlider = functions && typeof functions.resetFacetSlider === 'function' ? functions.resetFacetSlider : _config.default.functions.resetFacetSlider;
45
+ const viewQueryURL = config && typeof config.viewQueryURL === 'boolean' ? config.viewQueryURL : _config.default.config.viewQueryURL;
46
+ const queryUrlCharacterLimit = config && typeof config.queryUrlCharacterLimit === 'number' ? config.queryUrlCharacterLimit : _config.default.config.queryUrlCharacterLimit;
43
47
  return {
44
48
  QueryBar: (0, _core.withStyles)(_styles.default, {
45
49
  withTheme: true
46
50
  })(props => {
47
51
  const {
52
+ hasImportFrom,
48
53
  statusReducer,
49
54
  localFind,
50
55
  classes
@@ -76,8 +81,8 @@ const QueryBarGenerator = function QueryBarGenerator() {
76
81
  return _objectSpread(_objectSpread({}, facet), {}, {
77
82
  items: itemKeys
78
83
  });
79
- }).filter(facet => facet.items.length > 0);
80
- if ((mappedInputs.length || autocomplete.length || upload.length) <= 0) {
84
+ }).filter(facet => facet.items.length > 0 || facet.unknownAges && facet.unknownAges !== 'include');
85
+ if (!hasImportFrom && (mappedInputs.length || autocomplete.length || upload.length) <= 0) {
81
86
  return null;
82
87
  }
83
88
  return /*#__PURE__*/_react.default.createElement("div", {
@@ -91,10 +96,15 @@ const QueryBarGenerator = function QueryBarGenerator() {
91
96
  className: classes.divider
92
97
  }), /*#__PURE__*/_react.default.createElement("span", {
93
98
  className: classes.queryContainer
94
- }, autocomplete.length || upload.length ? /*#__PURE__*/_react.default.createElement("span", null, upload.length && !autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", {
99
+ }, hasImportFrom && /*#__PURE__*/_react.default.createElement("span", {
100
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindBackground),
101
+ onClick: clearImportFrom
102
+ }, "IMPORTED PARTICIPANT SET"), hasImportFrom && (mappedInputs.length || autocomplete.length || upload.length) ? /*#__PURE__*/_react.default.createElement("span", {
103
+ className: classes.operators
104
+ }, " AND ") : null, autocomplete.length || upload.length ? /*#__PURE__*/_react.default.createElement("span", null, upload.length && !autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", {
95
105
  className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindBackground),
96
106
  onClick: clearUpload
97
- }, "INPUT CASE SET") : null, autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
107
+ }, "INPUT PARTICIPANT SET") : null, autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
98
108
  className: (0, _clsx.default)(classes.filterName, classes.localFindBackground),
99
109
  onClick: clearAutocomplete
100
110
  }, "Participant ID"), ' ', ' ', /*#__PURE__*/_react.default.createElement("span", {
@@ -104,7 +114,7 @@ const QueryBarGenerator = function QueryBarGenerator() {
104
114
  }, "(") : null, upload.length && autocomplete.length ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, ' ', /*#__PURE__*/_react.default.createElement("span", {
105
115
  className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFind),
106
116
  onClick: clearUpload
107
- }, "INPUT CASE SET"), ' ') : null, autocomplete.slice(0, maxItems).map((d, idx) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
117
+ }, "INPUT PARTICIPANT SET"), ' ') : null, autocomplete.slice(0, maxItems).map((d, idx) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
108
118
  className: (0, _clsx.default)(classes.filterCheckboxes, classes.facetSectionCases),
109
119
  key: idx,
110
120
  onClick: () => deleteAutocompleteItem(d.title)
@@ -120,7 +130,12 @@ const QueryBarGenerator = function QueryBarGenerator() {
120
130
  classes: classes,
121
131
  onSectionClick: filter.type === CHECKBOX ? resetFacetSection : resetFacetSlider,
122
132
  onItemClick: filter.type === CHECKBOX ? resetFacetCheckbox : resetFacetSlider
123
- }))));
133
+ }))), viewQueryURL && /*#__PURE__*/_react.default.createElement(_QueryUrl.default, {
134
+ classes: classes,
135
+ localFind: localFind,
136
+ filterItems: mappedInputs,
137
+ queryUrlCharacterLimit: queryUrlCharacterLimit
138
+ }));
124
139
  })
125
140
  };
126
141
  };
@@ -12,7 +12,17 @@ var _default = {
12
12
  * The maximum number of items to display in a query bar facet section
13
13
  * @var {number}
14
14
  */
15
- maxItems: 2
15
+ maxItems: 2,
16
+ /**
17
+ * display copy url button
18
+ * @var {boolean}
19
+ */
20
+ viewQueryURL: true,
21
+ /**
22
+ * display copy url button
23
+ * @var {boolean}
24
+ */
25
+ queryUrlCharacterLimit: 70
16
26
  },
17
27
  /* Component Helper Functions */
18
28
  functions: {
@@ -22,6 +32,12 @@ var _default = {
22
32
  * @returns {void}
23
33
  */
24
34
  clearAll: () => {},
35
+ /**
36
+ * Clear import from filter
37
+ *
38
+ * @returns {void}
39
+ */
40
+ clearImportFrom: () => {},
25
41
  /**
26
42
  * Clear all active Local Find file upload filters
27
43
  *
@@ -9,9 +9,8 @@ exports.default = void 0;
9
9
  */
10
10
  var _default = () => ({
11
11
  queryWrapper: {
12
- height: '120px',
13
12
  backgroundColor: '#f1f1f1',
14
- padding: '14px 14px 0px 35px',
13
+ padding: '5px 15px 15px 15px',
15
14
  overflowY: 'auto'
16
15
  },
17
16
  queryContainer: {
@@ -111,47 +110,75 @@ var _default = () => ({
111
110
  facetSectionFilesBackground: {
112
111
  backgroundColor: '#F5C3F1'
113
112
  },
114
- facetSectionDemographics: {
113
+ facetSectionDiagnosis: {
115
114
  color: '#357288'
116
115
  },
117
- facetSectionDemographicsBackground: {
116
+ facetSectionDiagnosisBackground: {
118
117
  backgroundColor: '#E4ECE9',
119
118
  border: '1px solid #646464'
120
119
  },
121
- facetSectionDiagnosis: {
120
+ facetSectionDemographics: {
122
121
  color: '#8C3F8D'
123
122
  },
124
- facetSectionDiagnosisBackground: {
123
+ facetSectionDemographicsBackground: {
125
124
  backgroundColor: '#E1C9E140',
126
125
  border: '1px solid #646464'
127
126
  },
128
- facetSectionSamples: {
127
+ facetSectionGeneticanalysis: {
128
+ color: '#4555AB'
129
+ },
130
+ facetSectionGeneticanalysisBackground: {
131
+ backgroundColor: '#4555AB30',
132
+ border: '1px solid #646464'
133
+ },
134
+ facetSectionTreatment: {
129
135
  color: '#907642'
130
136
  },
131
- facetSectionSamplesBackground: {
137
+ facetSectionTreatmentBackground: {
132
138
  backgroundColor: '#F0DFBD40',
133
139
  border: '1px solid #646464'
134
140
  },
135
- facetSectionDatacategory: {
141
+ facetSectionTreatmentresponse: {
136
142
  color: '#A85348'
137
143
  },
138
- facetSectionDatacategoryBackground: {
144
+ facetSectionTreatmentresponseBackground: {
139
145
  backgroundColor: '#F8D7D240',
140
146
  border: '1px solid #646464'
141
147
  },
142
- facetSectionStudy: {
148
+ facetSectionSurvival: {
143
149
  color: '#1F6BBF'
144
150
  },
145
- facetSectionStudyBackground: {
151
+ facetSectionSurvivalBackground: {
146
152
  backgroundColor: '#CEDEF040',
147
153
  border: '1px solid #646464'
148
154
  },
149
- facetSectionSequencinglibrary: {
155
+ facetSectionSamples: {
150
156
  color: '#14A773'
151
157
  },
152
- facetSectionSequencinglibraryBackground: {
158
+ facetSectionSamplesBackground: {
153
159
  backgroundColor: '#DDEAE540',
154
160
  border: '1px solid #646464'
161
+ },
162
+ facetSectionDatacategory: {
163
+ color: '#357288'
164
+ },
165
+ facetSectionDatacategoryBackground: {
166
+ backgroundColor: '#E4ECE9',
167
+ border: '1px solid #646464'
168
+ },
169
+ facetSectionStudy: {
170
+ color: '#357288'
171
+ },
172
+ facetSectionStudyBackground: {
173
+ backgroundColor: '#E4ECE9',
174
+ border: '1px solid #646464'
175
+ },
176
+ facetSectionSequencinglibrary: {
177
+ color: '#8C3F8D'
178
+ },
179
+ facetSectionSequencinglibraryBackground: {
180
+ backgroundColor: '#E1C9E140',
181
+ border: '1px solid #646464'
155
182
  }
156
183
  });
157
184
  exports.default = _default;
package/package.json CHANGED
@@ -1,20 +1,29 @@
1
1
  {
2
2
  "name": "@bento-core/query-bar",
3
- "version": "1.0.1-ccdihub.9",
3
+ "version": "1.0.1-ccdiintegrated.2",
4
4
  "description": "This package provides the Query Bar component that displays the current Facet Search and Local Find filters on the Dashboard/Explore page. It also provides the direct ability to reset all or some of the filters with the click of a button. It is designed to be implemented directly with the:",
5
+ "homepage": "https://github.com/CBIIT/bento-frontend#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/CBIIT/bento-frontend/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/CBIIT/bento-frontend.git"
12
+ },
13
+ "license": "ISC",
14
+ "author": "CTOS Bento Team",
15
+ "type": "commonjs",
5
16
  "main": "dist/index.js",
6
17
  "scripts": {
7
18
  "build": "npm run lint && cross-env-shell rm -rf dist && NODE_ENV=production BABEL_ENV=es babel src --out-dir dist --copy-files",
8
19
  "test": "echo \"Error: no test specified\" && exit 1",
9
20
  "lint": "eslint src"
10
21
  },
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/CBIIT/bento-frontend.git"
14
- },
15
- "publishConfig": {
16
- "access": "public"
22
+ "dependencies": {
23
+ "@bento-core/facet-filter": "1.0.1-ccdiintegrated.1",
24
+ "lodash": "^4.17.20"
17
25
  },
26
+ "devDependencies": {},
18
27
  "peerDependencies": {
19
28
  "@material-ui/core": "^4.10.0",
20
29
  "clsx": "^1.2.1",
@@ -22,15 +31,7 @@
22
31
  "react-dom": "^17.0.0",
23
32
  "react-redux": "^7.2.1"
24
33
  },
25
- "dependencies": {
26
- "@bento-core/facet-filter": "^1.0.0",
27
- "lodash": "^4.17.20"
28
- },
29
- "author": "CTOS Bento Team",
30
- "license": "ISC",
31
- "bugs": {
32
- "url": "https://github.com/CBIIT/bento-frontend/issues"
33
- },
34
- "homepage": "https://github.com/CBIIT/bento-frontend#readme",
35
- "devDependencies": {}
34
+ "publishConfig": {
35
+ "access": "public"
36
+ }
36
37
  }
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="19" viewBox="0 0 16 19" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M13 9.75715C13 10.0452 12.78 10.2714 12.5 10.2714H7.5C7.22 10.2714 7 10.0452 7 9.75715C7 9.46915 7.22 9.24287 7.5 9.24287H12.5C12.78 9.24287 13 9.46915 13 9.75715ZM12.5 11.3H7.5C7.22 11.3 7 11.5263 7 11.8143C7 12.1023 7.22 12.3286 7.5 12.3286H12.5C12.78 12.3286 13 12.1023 13 11.8143C13 11.5263 12.78 11.3 12.5 11.3ZM12.5 13.3572H7.5C7.22 13.3572 7 13.5834 7 13.8714C7 14.1594 7.22 14.3857 7.5 14.3857H12.5C12.78 14.3857 13 14.1594 13 13.8714C13 13.5834 12.78 13.3572 12.5 13.3572ZM16 8.21429V16.4429C16 17.5743 15.1 18.5 14 18.5H6C4.9 18.5 4 17.5743 4 16.4429V15.4143H2C0.9 15.4143 0 14.4886 0 13.3572V4.10001C0 2.96858 0.9 2.04286 2 2.04286H4.5C4.5 1.18915 5.17 0.500008 6 0.500008C6.83 0.500008 7.5 1.18915 7.5 2.04286H10C11.1 2.04286 12 2.96858 12 4.10001V6.15715H14C15.1 6.15715 16 7.08287 16 8.21429ZM6 6.15715H11V4.10001C11 3.53429 10.55 3.07144 10 3.07144H9V4.10001H3V3.07144H2C1.45 3.07144 1 3.53429 1 4.10001V13.3572C1 13.9229 1.45 14.3857 2 14.3857H4V8.21429C4 7.08287 4.9 6.15715 6 6.15715ZM15 8.21429C15 7.64858 14.55 7.18572 14 7.18572H6C5.45 7.18572 5 7.64858 5 8.21429V16.4429C5 17.0086 5.45 17.4714 6 17.4714H14C14.55 17.4714 15 17.0086 15 16.4429V8.21429Z" fill="#142D64"/>
3
+ </svg>
@@ -0,0 +1,152 @@
1
+ import React, { useState, useRef } from 'react';
2
+ import clsx from 'clsx';
3
+ import {
4
+ Button,
5
+ IconButton,
6
+ Tooltip,
7
+ Dialog,
8
+ DialogActions,
9
+ DialogContent,
10
+ DialogContentText,
11
+ withStyles,
12
+ } from '@material-ui/core';
13
+ import CopyIcon from '../assets/CopyIcon.svg';
14
+
15
+ const QueryUrl = ({
16
+ classes,
17
+ queryUrlCharacterLimit = 70,
18
+ }) => {
19
+ const [display, setDisplay] = useState(false);
20
+ const toggleDisplay = () => setDisplay((prevDisplay) => !prevDisplay);
21
+
22
+ const [open, setOpen] = useState(false);
23
+ const toggleOpen = () => setOpen((prevOpen) => !prevOpen);
24
+
25
+ const url = window.location.href;
26
+
27
+ const copyUrl = async () => {
28
+ toggleOpen();
29
+ await navigator.clipboard.writeText(url);
30
+ };
31
+
32
+ const queryRef = useRef(null);
33
+
34
+ return (
35
+ <div style={{ position: 'relative', right: '6px' }}>
36
+ <div ref={queryRef} className={classes.urlContainer}>
37
+ <Button
38
+ onClick={toggleDisplay}
39
+ className={classes.viewLinkToggleBtn}
40
+ >
41
+ {(display) ? 'Hide Query URL' : 'Show Query URL'}
42
+ </Button>
43
+ {
44
+ (display) && (
45
+ <>
46
+ <div
47
+ type="button"
48
+ className={clsx(classes.viewLink)}
49
+ >
50
+ {url.length > queryUrlCharacterLimit ? `${url.substring(0, queryUrlCharacterLimit)}...` : url}
51
+ </div>
52
+ <Tooltip
53
+ arrow
54
+ title="Copy to Clipboard"
55
+ >
56
+ <IconButton onClick={copyUrl} className={classes.copyIconBtn}>
57
+ <img src={CopyIcon} alt="copy icon" />
58
+ </IconButton>
59
+ </Tooltip>
60
+ </>
61
+ )
62
+ }
63
+ </div>
64
+ <Dialog
65
+ open={open}
66
+ onClose={() => toggleOpen()}
67
+ aria-labelledby="alert-dialog-title"
68
+ aria-describedby="alert-dialog-description"
69
+ className={clsx(classes.dialogBox, 'dialogBox')}
70
+ >
71
+ <DialogContent className={classes.okText}>
72
+ <DialogContentText id="alert-dialog-description">
73
+ Your query URL has been copied!
74
+ </DialogContentText>
75
+ </DialogContent>
76
+ <DialogActions>
77
+ <Button onClick={() => toggleOpen()}>
78
+ OK
79
+ </Button>
80
+ </DialogActions>
81
+ </Dialog>
82
+ </div>
83
+ );
84
+ };
85
+
86
+ const styles = () => ({
87
+ urlContainer: {
88
+ display: 'flex',
89
+ marginTop: '3px',
90
+ minHeight: '10px',
91
+ },
92
+ viewLink: {
93
+ overflow: 'hidden',
94
+ textOverflow: 'ellipsis',
95
+ fontFamily: 'Nunito',
96
+ fontSize: '12px',
97
+ fontWeight: '500',
98
+ lineHeight: '16px',
99
+ letterSpacing: '0em',
100
+ padding: '2px 5px',
101
+ borderRadius: '5px',
102
+ float: 'left',
103
+ color: '#1D79A8',
104
+ backgroundColor: '#fff',
105
+ margin: '0',
106
+ whiteSpace: 'nowrap',
107
+ wordBreak: 'break-all',
108
+ '@media (max-width: 2560px)': {
109
+ maxWidth: '1800px',
110
+ },
111
+ '@media (max-width: 2000px)': {
112
+ maxWidth: '1500px',
113
+ },
114
+ '@media (max-width: 1600px)': {
115
+ maxWidth: '1100px',
116
+ },
117
+ '@media (max-width: 1300px)': {
118
+ maxWidth: '900px',
119
+ },
120
+ },
121
+ urlViewBtn: {
122
+ cursor: 'pointer',
123
+ },
124
+ viewLinkToggleBtn: {
125
+ padding: '5px 10px 5px 10px',
126
+ height: '20px',
127
+ fontFamily: 'Nunito',
128
+ fontSize: '12px',
129
+ fontWeight: '500',
130
+ lineHeight: '16px',
131
+ letterSpacing: '0em',
132
+ textAlign: 'left',
133
+ backgroundColor: '#1D79A8',
134
+ textTransform: 'none',
135
+ color: '#fff',
136
+ float: 'left',
137
+ margin: '0px 10px 0px 0px',
138
+ whiteSpace: 'nowrap',
139
+ '&:hover': {
140
+ backgroundColor: '#1D79A8',
141
+ color: '#fff',
142
+ },
143
+ },
144
+ copyIconBtn: {
145
+ padding: '0px',
146
+ height: '20px',
147
+ marginLeft: '10px',
148
+ float: 'left',
149
+ },
150
+ });
151
+
152
+ export default withStyles(styles)(QueryUrl);
@@ -5,7 +5,40 @@ export default ({
5
5
  index, data, classes,
6
6
  onSectionClick, onItemClick,
7
7
  }) => {
8
- const { items, section } = data;
8
+ const { items, section, unknownAges } = data;
9
+
10
+ // Determine the display logic based on unknownAges selection
11
+ const getDisplayContent = () => {
12
+ const baseLabel = data.label;
13
+
14
+ if (unknownAges === 'only') {
15
+ // Only: Show base label with unknown ages only, no range
16
+ return {
17
+ label: `${baseLabel} (Unknown Ages Only)`,
18
+ showRange: false,
19
+ rangeText: '',
20
+ };
21
+ }
22
+
23
+ if (unknownAges === 'exclude') {
24
+ // Exclude: Show base label with unknown ages excluded, with range only if items exist
25
+ const hasRange = items && items.length >= 2;
26
+ return {
27
+ label: `${baseLabel} (Unknown Ages Excluded)`,
28
+ showRange: hasRange,
29
+ rangeText: hasRange ? `${items[0]} – ${items[1]}` : '',
30
+ };
31
+ }
32
+
33
+ // Include: Normal display (base label with range)
34
+ return {
35
+ label: baseLabel,
36
+ showRange: true,
37
+ rangeText: items && items.length >= 2 ? `${items[0]} – ${items[1]}` : '',
38
+ };
39
+ };
40
+
41
+ const displayContent = getDisplayContent();
9
42
 
10
43
  return (
11
44
  <span>
@@ -16,23 +49,25 @@ export default ({
16
49
  className={clsx(classes.filterName, classes[`facetSection${section}Background`])}
17
50
  onClick={() => onSectionClick(data)}
18
51
  >
19
- {data.label}
52
+ {displayContent.label}
20
53
  </span>
21
54
  {' '}
22
55
  </span>
23
- <span>
24
- {' '}
25
- <span className={classes.operators}>
26
- IS BETWEEN
56
+ {displayContent.showRange && (
57
+ <span>
27
58
  {' '}
59
+ <span className={classes.operators}>
60
+ IS BETWEEN
61
+ {' '}
62
+ </span>
63
+ <span
64
+ className={clsx(classes.filterCheckboxes, classes[`facetSection${section}`])}
65
+ onClick={() => onItemClick(data, items[0])}
66
+ >
67
+ {displayContent.rangeText}
68
+ </span>
28
69
  </span>
29
- <span
30
- className={clsx(classes.filterCheckboxes, classes[`facetSection${section}`])}
31
- onClick={() => onItemClick(data, items[0])}
32
- >
33
- {`${items[0]} – ${items[1]}`}
34
- </span>
35
- </span>
70
+ )}
36
71
  </span>
37
72
  );
38
73
  };
@@ -5,6 +5,7 @@ import clsx from 'clsx';
5
5
  import { Filter } from '../components/FilterMap';
6
6
  import DEFAULT_STYLES from './styles';
7
7
  import DEFAULT_CONFIG from './config';
8
+ import QueryUrl from '../components/QueryUrl';
8
9
 
9
10
  /**
10
11
  * Generate a pre-configured Explore Query Bar component
@@ -24,6 +25,10 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
24
25
  ? functions.clearAll
25
26
  : DEFAULT_CONFIG.functions.clearAll;
26
27
 
28
+ const clearImportFrom = functions && typeof functions.clearImportFrom === 'function'
29
+ ? functions.clearImportFrom
30
+ : DEFAULT_CONFIG.functions.clearImportFrom;
31
+
27
32
  const clearUpload = functions && typeof functions.clearUpload === 'function'
28
33
  ? functions.clearUpload
29
34
  : DEFAULT_CONFIG.functions.clearUpload;
@@ -48,10 +53,19 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
48
53
  ? functions.resetFacetSlider
49
54
  : DEFAULT_CONFIG.functions.resetFacetSlider;
50
55
 
56
+ const viewQueryURL = config && typeof config.viewQueryURL === 'boolean'
57
+ ? config.viewQueryURL
58
+ : DEFAULT_CONFIG.config.viewQueryURL;
59
+
60
+ const queryUrlCharacterLimit = config && typeof config.queryUrlCharacterLimit === 'number'
61
+ ? config.queryUrlCharacterLimit
62
+ : DEFAULT_CONFIG.config.queryUrlCharacterLimit;
63
+
51
64
  return {
52
65
  QueryBar: withStyles(DEFAULT_STYLES, { withTheme: true })((props) => {
53
- const { statusReducer, localFind, classes } = props;
54
-
66
+ const {
67
+ hasImportFrom, statusReducer, localFind, classes,
68
+ } = props;
55
69
  const { autocomplete, upload } = localFind;
56
70
 
57
71
  // Remove any sections without checkboxes selected
@@ -73,12 +87,11 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
73
87
 
74
88
  return { ...facet, items: itemKeys };
75
89
  })
76
- .filter((facet) => facet.items.length > 0);
90
+ .filter((facet) => facet.items.length > 0 || (facet.unknownAges && facet.unknownAges !== 'include'));
77
91
 
78
- if ((mappedInputs.length || autocomplete.length || upload.length) <= 0) {
92
+ if (!hasImportFrom && (mappedInputs.length || autocomplete.length || upload.length) <= 0) {
79
93
  return null;
80
94
  }
81
-
82
95
  return (
83
96
  <div className={classes.queryWrapper}>
84
97
  <Button
@@ -93,6 +106,21 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
93
106
  <span className={classes.queryContainer}>
94
107
  {/* Local Find Selections */}
95
108
  {/* TODO: Refactor this into a separate component */}
109
+ {
110
+ hasImportFrom
111
+ && (
112
+ <span
113
+ className={clsx(classes.filterCheckboxes, classes.localFindBackground)}
114
+ onClick={clearImportFrom}
115
+ >
116
+ IMPORTED PARTICIPANT SET
117
+ </span>
118
+ )
119
+ }
120
+
121
+ {hasImportFrom && (mappedInputs.length || autocomplete.length || upload.length)
122
+ ? <span className={classes.operators}> AND </span>
123
+ : null}
96
124
  {(autocomplete.length || upload.length) ? (
97
125
  <span>
98
126
  {/* Standalone case set button */}
@@ -102,7 +130,7 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
102
130
  className={clsx(classes.filterCheckboxes, classes.localFindBackground)}
103
131
  onClick={clearUpload}
104
132
  >
105
- INPUT CASE SET
133
+ INPUT PARTICIPANT SET
106
134
  </span>
107
135
  ) : null}
108
136
  {autocomplete.length
@@ -133,7 +161,7 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
133
161
  className={clsx(classes.filterCheckboxes, classes.localFind)}
134
162
  onClick={clearUpload}
135
163
  >
136
- INPUT CASE SET
164
+ INPUT PARTICIPANT SET
137
165
  </span>
138
166
  {' '}
139
167
  </>
@@ -178,6 +206,16 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
178
206
  />
179
207
  ))}
180
208
  </span>
209
+ {
210
+ viewQueryURL && (
211
+ <QueryUrl
212
+ classes={classes}
213
+ localFind={localFind}
214
+ filterItems={mappedInputs}
215
+ queryUrlCharacterLimit={queryUrlCharacterLimit}
216
+ />
217
+ )
218
+ }
181
219
  </div>
182
220
  );
183
221
  }),
@@ -7,6 +7,16 @@ export default {
7
7
  * @var {number}
8
8
  */
9
9
  maxItems: 2,
10
+ /**
11
+ * display copy url button
12
+ * @var {boolean}
13
+ */
14
+ viewQueryURL: true,
15
+ /**
16
+ * display copy url button
17
+ * @var {boolean}
18
+ */
19
+ queryUrlCharacterLimit: 70,
10
20
  },
11
21
 
12
22
  /* Component Helper Functions */
@@ -16,21 +26,28 @@ export default {
16
26
  *
17
27
  * @returns {void}
18
28
  */
19
- clearAll: () => {},
29
+ clearAll: () => { },
30
+
31
+ /**
32
+ * Clear import from filter
33
+ *
34
+ * @returns {void}
35
+ */
36
+ clearImportFrom: () => { },
20
37
 
21
38
  /**
22
39
  * Clear all active Local Find file upload filters
23
40
  *
24
41
  * @returns {void}
25
42
  */
26
- clearUpload: () => {},
43
+ clearUpload: () => { },
27
44
 
28
45
  /**
29
46
  * Clear all active Local Find searchbox filters
30
47
  *
31
48
  * @returns {void}
32
49
  */
33
- clearAutocomplete: () => {},
50
+ clearAutocomplete: () => { },
34
51
 
35
52
  /**
36
53
  * Delete a specific Local Find searchbox filter (case)
@@ -38,7 +55,7 @@ export default {
38
55
  * @param {string} title
39
56
  * @returns {void}
40
57
  */
41
- deleteAutocompleteItem: (title) => {},
58
+ deleteAutocompleteItem: (title) => { },
42
59
 
43
60
  /**
44
61
  * Reset a specific facet section (e.g. Program)
@@ -46,7 +63,7 @@ export default {
46
63
  * @param {object} section the configuration object for the section
47
64
  * @returns {void}
48
65
  */
49
- resetFacetSection: (section) => {},
66
+ resetFacetSection: (section) => { },
50
67
 
51
68
  /**
52
69
  * Reset a specific facet checkbox (e.g. Program > TAILORx)
@@ -55,7 +72,7 @@ export default {
55
72
  * @param {string} checkbox the name of the checkbox
56
73
  * @returns {void}
57
74
  */
58
- resetFacetCheckbox: (section, checkbox) => {},
75
+ resetFacetCheckbox: (section, checkbox) => { },
59
76
 
60
77
  /**
61
78
  * Reset a specific slider section (e.g. Age)
@@ -63,6 +80,6 @@ export default {
63
80
  * @param {object} section the configuration object for the section
64
81
  * @returns {void}
65
82
  */
66
- resetFacetSlider: (section) => {},
83
+ resetFacetSlider: (section) => { },
67
84
  },
68
85
  };
@@ -3,9 +3,8 @@
3
3
  */
4
4
  export default () => ({
5
5
  queryWrapper: {
6
- height: '120px',
7
6
  backgroundColor: '#f1f1f1',
8
- padding: '14px 14px 0px 35px',
7
+ padding: '5px 15px 15px 15px',
9
8
  overflowY: 'auto',
10
9
  },
11
10
  queryContainer: {
@@ -105,46 +104,74 @@ export default () => ({
105
104
  facetSectionFilesBackground: {
106
105
  backgroundColor: '#F5C3F1',
107
106
  },
108
- facetSectionDemographics: {
107
+ facetSectionDiagnosis: {
109
108
  color: '#357288',
110
109
  },
111
- facetSectionDemographicsBackground: {
110
+ facetSectionDiagnosisBackground: {
112
111
  backgroundColor: '#E4ECE9',
113
112
  border: '1px solid #646464',
114
113
  },
115
- facetSectionDiagnosis: {
114
+ facetSectionDemographics: {
116
115
  color: '#8C3F8D',
117
116
  },
118
- facetSectionDiagnosisBackground: {
117
+ facetSectionDemographicsBackground: {
119
118
  backgroundColor: '#E1C9E140',
120
119
  border: '1px solid #646464',
121
120
  },
122
- facetSectionSamples: {
121
+ facetSectionGeneticanalysis: {
122
+ color: '#4555AB',
123
+ },
124
+ facetSectionGeneticanalysisBackground: {
125
+ backgroundColor: '#4555AB30',
126
+ border: '1px solid #646464',
127
+ },
128
+ facetSectionTreatment: {
123
129
  color: '#907642',
124
130
  },
125
- facetSectionSamplesBackground: {
131
+ facetSectionTreatmentBackground: {
126
132
  backgroundColor: '#F0DFBD40',
127
133
  border: '1px solid #646464',
128
134
  },
129
- facetSectionDatacategory: {
135
+ facetSectionTreatmentresponse: {
130
136
  color: '#A85348',
131
137
  },
132
- facetSectionDatacategoryBackground: {
138
+ facetSectionTreatmentresponseBackground: {
133
139
  backgroundColor: '#F8D7D240',
134
140
  border: '1px solid #646464',
135
141
  },
136
- facetSectionStudy: {
142
+ facetSectionSurvival: {
137
143
  color: '#1F6BBF',
138
144
  },
139
- facetSectionStudyBackground: {
145
+ facetSectionSurvivalBackground: {
140
146
  backgroundColor: '#CEDEF040',
141
147
  border: '1px solid #646464',
142
148
  },
143
- facetSectionSequencinglibrary: {
149
+ facetSectionSamples: {
144
150
  color: '#14A773',
145
151
  },
146
- facetSectionSequencinglibraryBackground: {
152
+ facetSectionSamplesBackground: {
147
153
  backgroundColor: '#DDEAE540',
148
154
  border: '1px solid #646464',
149
155
  },
156
+ facetSectionDatacategory: {
157
+ color: '#357288',
158
+ },
159
+ facetSectionDatacategoryBackground: {
160
+ backgroundColor: '#E4ECE9',
161
+ border: '1px solid #646464',
162
+ },
163
+ facetSectionStudy: {
164
+ color: '#357288',
165
+ },
166
+ facetSectionStudyBackground: {
167
+ backgroundColor: '#E4ECE9',
168
+ border: '1px solid #646464',
169
+ },
170
+ facetSectionSequencinglibrary: {
171
+ color: '#8C3F8D',
172
+ },
173
+ facetSectionSequencinglibraryBackground: {
174
+ backgroundColor: '#E1C9E140',
175
+ border: '1px solid #646464',
176
+ },
150
177
  });