@bento-core/query-bar 1.0.0-c3dc.6 → 1.0.0-c3dc.8

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.
@@ -22,7 +22,8 @@ const QueryUrl = _ref => {
22
22
  filterItems,
23
23
  localFind = {},
24
24
  rootPath,
25
- queryUrlCharacterLimit = 70
25
+ queryUrlCharacterLimit = 70,
26
+ generateUrl
26
27
  } = _ref;
27
28
  const [display, setDisplay] = (0, _react.useState)(false);
28
29
  const toggleDisplay = () => setDisplay(prevDisplay => !prevDisplay);
@@ -36,13 +37,18 @@ const QueryUrl = _ref => {
36
37
  acc[datafield] = items;
37
38
  return acc;
38
39
  }, {});
39
- const query = JSON.stringify(_objectSpread(_objectSpread({}, pathFilterParams), localFind));
40
- const url = rootPath.slice(0, -1).concat("?filterQuery=".concat(encodeURIComponent(query)));
40
+ const queryString = JSON.stringify(_objectSpread(_objectSpread({}, pathFilterParams), localFind));
41
+ const [url, setUrl] = (0, _react.useState)('');
41
42
  const copyUrl = async () => {
42
43
  toggleOpen();
43
44
  await navigator.clipboard.writeText(url);
44
45
  };
45
46
  const queryRef = (0, _react.useRef)(null);
47
+ (0, _react.useEffect)(() => {
48
+ if (display && generateUrl) {
49
+ generateUrl(queryString, rootPath, setUrl);
50
+ }
51
+ }, [display]);
46
52
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
47
53
  ref: queryRef,
48
54
  className: classes.urlContainer
@@ -45,6 +45,7 @@ const QueryBarGenerator = function QueryBarGenerator() {
45
45
  const resetFacetSection = functions && typeof functions.resetFacetSection === 'function' ? functions.resetFacetSection : _config.default.functions.resetFacetSection;
46
46
  const resetFacetCheckbox = functions && typeof functions.resetFacetCheckbox === 'function' ? functions.resetFacetCheckbox : _config.default.functions.resetFacetCheckbox;
47
47
  const resetFacetSlider = functions && typeof functions.resetFacetSlider === 'function' ? functions.resetFacetSlider : _config.default.functions.resetFacetSlider;
48
+ const generateUrl = functions && typeof functions.generateUrl === 'function' ? functions.generateUrl : _config.default.functions.generateUrl;
48
49
  return {
49
50
  QueryBar: (0, _core.withStyles)(customStyles || _styles.default, {
50
51
  withTheme: true
@@ -96,26 +97,60 @@ const QueryBarGenerator = function QueryBarGenerator() {
96
97
  className: classes.divider
97
98
  }), /*#__PURE__*/_react.default.createElement("span", {
98
99
  className: classes.queryContainer
99
- }, autocomplete.length || upload.length ? /*#__PURE__*/_react.default.createElement("span", null, upload.length && !autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", {
100
- className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindBackground),
101
- onClick: clearUpload
102
- }, "INPUT PARTICIPANT SET") : null, autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
103
- className: (0, _clsx.default)(classes.filterName, classes.localFindBackground),
104
- onClick: clearAutocomplete
105
- }, "Participant ID"), ' ', ' ', /*#__PURE__*/_react.default.createElement("span", {
100
+ }, (autocomplete.length || upload.length) > 0 && /*#__PURE__*/_react.default.createElement("span", null, (() => {
101
+ const participantItems = autocomplete.filter(i => i.type === 'participantIds');
102
+ const participantCount = upload.length + participantItems.length;
103
+ if (upload.length > 0 && participantItems.length === 0) {
104
+ // Only upload, no participant autocomplete
105
+ return /*#__PURE__*/_react.default.createElement("span", {
106
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindBackground),
107
+ onClick: clearUpload
108
+ }, "INPUT PARTICIPANT SET");
109
+ }
110
+ if (participantCount > 0) {
111
+ const operator = participantCount === 1 ? 'IS' : 'IN';
112
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
113
+ className: (0, _clsx.default)(classes.filterName, classes.localFindBackground),
114
+ onClick: clearAutocomplete
115
+ }, "Participant ID"), /*#__PURE__*/_react.default.createElement("span", {
116
+ className: classes.operators
117
+ }, operator), operator === 'IN' && /*#__PURE__*/_react.default.createElement("span", {
118
+ className: classes.bracketsOpen
119
+ }, "("), upload.length > 0 && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
120
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFind),
121
+ onClick: clearUpload
122
+ }, "INPUT PARTICIPANT SET")), participantItems.slice(0, maxItems).map((d, idx, arr) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
123
+ key: "pid-".concat(idx)
124
+ }, /*#__PURE__*/_react.default.createElement("span", {
125
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.facetSectionCases),
126
+ onClick: () => deleteAutocompleteItem(d.title)
127
+ }, d.title), idx < arr.length - 1 && ' ')), participantItems.length > maxItems && '...', operator === 'IN' && /*#__PURE__*/_react.default.createElement("span", {
128
+ className: classes.bracketsClose
129
+ }, ")"));
130
+ }
131
+ return null;
132
+ })(), (upload.length > 0 || autocomplete.some(i => i.type === 'participantIds')) && autocomplete.some(i => i.type === 'associatedIds') && /*#__PURE__*/_react.default.createElement("span", {
106
133
  className: classes.operators
107
- }, autocomplete.length === 1 && !upload.length ? 'IS ' : 'IN ')) : null, /*#__PURE__*/_react.default.createElement("span", null, (upload.length > 0 ? 1 : 0) + autocomplete.length > 1 ? /*#__PURE__*/_react.default.createElement("span", {
108
- className: classes.bracketsOpen
109
- }, "(") : null, upload.length && autocomplete.length ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, ' ', /*#__PURE__*/_react.default.createElement("span", {
110
- className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFind),
111
- onClick: clearUpload
112
- }, "INPUT PARTICIPANT SET"), ' ') : null, autocomplete.slice(0, maxItems).map((d, idx) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
113
- className: (0, _clsx.default)(classes.filterCheckboxes, classes.facetSectionCases),
114
- key: idx,
115
- onClick: () => deleteAutocompleteItem(d.title)
116
- }, d.title), idx === maxItems - 1 ? null : ' ')), autocomplete.length > maxItems && '...', (upload.length > 0 ? 1 : 0) + autocomplete.length > 1 ? /*#__PURE__*/_react.default.createElement("span", {
117
- className: classes.bracketsClose
118
- }, ")") : null)) : null, (autocomplete.length || upload.length) && mappedInputs.length ? /*#__PURE__*/_react.default.createElement("span", {
134
+ }, "OR"), (() => {
135
+ const associatedItems = autocomplete.filter(i => i.type === 'associatedIds');
136
+ if (associatedItems.length === 0) return null;
137
+ const operator = associatedItems.length === 1 ? 'IS' : 'IN';
138
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
139
+ className: (0, _clsx.default)(classes.filterName, classes.localFindAssociatedIdsBackground),
140
+ onClick: clearAutocomplete
141
+ }, "Synonym"), /*#__PURE__*/_react.default.createElement("span", {
142
+ className: classes.operators
143
+ }, operator), operator === 'IN' && /*#__PURE__*/_react.default.createElement("span", {
144
+ className: classes.bracketsOpen
145
+ }, "("), associatedItems.slice(0, maxItems).map((d, idx, arr) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
146
+ key: "aid-".concat(idx)
147
+ }, /*#__PURE__*/_react.default.createElement("span", {
148
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindAssociatedIdsText),
149
+ onClick: () => deleteAutocompleteItem(d.title)
150
+ }, d.synonym), idx < arr.length - 1 && ' ')), associatedItems.length > maxItems && '...', operator === 'IN' && /*#__PURE__*/_react.default.createElement("span", {
151
+ className: classes.bracketsClose
152
+ }, ")"));
153
+ })()), (autocomplete.length || upload.length) && mappedInputs.length ? /*#__PURE__*/_react.default.createElement("span", {
119
154
  className: classes.operators
120
155
  }, " AND ") : null, mappedInputs.map((filter, index) => /*#__PURE__*/_react.default.createElement(_FilterMap.Filter, {
121
156
  index: index,
@@ -130,7 +165,8 @@ const QueryBarGenerator = function QueryBarGenerator() {
130
165
  localFind: localFind,
131
166
  filterItems: mappedInputs,
132
167
  rootPath: queryURLRootPath,
133
- queryUrlCharacterLimit: queryUrlCharacterLimit
168
+ queryUrlCharacterLimit: queryUrlCharacterLimit,
169
+ generateUrl: generateUrl
134
170
  }));
135
171
  })
136
172
  };
@@ -77,7 +77,16 @@ var _default = {
77
77
  * @param {object} section the configuration object for the section
78
78
  * @returns {void}
79
79
  */
80
- resetFacetSlider: section => {}
80
+ resetFacetSlider: section => {},
81
+ /**
82
+ * Generate a query URL by calling the interop service
83
+ *
84
+ * @param {string} queryStr the query string to encode
85
+ * @param {string} root the root path for the URL
86
+ * @param {function} setUrlCallback callback function to set the generated URL
87
+ * @returns {Promise<void>}
88
+ */
89
+ generateUrl: async (queryStr, root, setUrlCallback) => {}
81
90
  }
82
91
  };
83
92
  exports.default = _default;
@@ -152,6 +152,12 @@ var _default = () => ({
152
152
  facetSectionLibraryBackground: {
153
153
  backgroundColor: '#DDEAE540',
154
154
  border: '1px solid #646464'
155
+ },
156
+ localFindAssociatedIdsBackground: {
157
+ backgroundColor: '#F6A700'
158
+ },
159
+ localFindAssociatedIdsText: {
160
+ color: '#B36B00'
155
161
  }
156
162
  });
157
163
  exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bento-core/query-bar",
3
- "version": "1.0.0-c3dc.6",
3
+ "version": "1.0.0-c3dc.8",
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
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef } from 'react';
1
+ import React, { useState, useRef, useEffect } from 'react';
2
2
  import clsx from 'clsx';
3
3
  import {
4
4
  Button,
@@ -18,6 +18,7 @@ const QueryUrl = ({
18
18
  localFind = {},
19
19
  rootPath,
20
20
  queryUrlCharacterLimit = 70,
21
+ generateUrl,
21
22
  }) => {
22
23
  const [display, setDisplay] = useState(false);
23
24
  const toggleDisplay = () => setDisplay((prevDisplay) => !prevDisplay);
@@ -31,11 +32,11 @@ const QueryUrl = ({
31
32
  return acc;
32
33
  }, {});
33
34
 
34
- const query = JSON.stringify({
35
+ const queryString = JSON.stringify({
35
36
  ...pathFilterParams,
36
37
  ...localFind,
37
38
  });
38
- const url = rootPath.slice(0, -1).concat(`?filterQuery=${encodeURIComponent(query)}`);
39
+ const [url, setUrl] = useState('');
39
40
 
40
41
  const copyUrl = async () => {
41
42
  toggleOpen();
@@ -44,6 +45,12 @@ const QueryUrl = ({
44
45
 
45
46
  const queryRef = useRef(null);
46
47
 
48
+ useEffect(() => {
49
+ if (display && generateUrl) {
50
+ generateUrl(queryString, rootPath, setUrl);
51
+ }
52
+ }, [display]);
53
+
47
54
  return (
48
55
  <>
49
56
  <div ref={queryRef} className={classes.urlContainer}>
@@ -61,6 +61,10 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
61
61
  ? functions.resetFacetSlider
62
62
  : DEFAULT_CONFIG.functions.resetFacetSlider;
63
63
 
64
+ const generateUrl = functions && typeof functions.generateUrl === 'function'
65
+ ? functions.generateUrl
66
+ : DEFAULT_CONFIG.functions.generateUrl;
67
+
64
68
  return {
65
69
  QueryBar: withStyles(customStyles || DEFAULT_STYLES,
66
70
  { withTheme: true })((props) => {
@@ -107,70 +111,117 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
107
111
  <span className={classes.queryContainer}>
108
112
  {/* Local Find Selections */}
109
113
  {/* TODO: Refactor this into a separate component */}
110
- {(autocomplete.length || upload.length) ? (
111
- <span>
112
- {/* Standalone case set button */}
113
- {(upload.length && !autocomplete.length)
114
- ? (
114
+ {/* Section: Localfind Results */}
115
+ {(autocomplete.length || upload.length) > 0 && (
116
+ <span>
117
+ {/* Participant ID Section */}
118
+ {(() => {
119
+ const participantItems = autocomplete.filter((i) => i.type === 'participantIds');
120
+ const participantCount = upload.length + participantItems.length;
121
+
122
+ if (upload.length > 0 && participantItems.length === 0) {
123
+ // Only upload, no participant autocomplete
124
+ return (
115
125
  <span
116
126
  className={clsx(classes.filterCheckboxes, classes.localFindBackground)}
117
127
  onClick={clearUpload}
118
128
  >
119
129
  INPUT PARTICIPANT SET
120
130
  </span>
121
- ) : null}
122
- {autocomplete.length
123
- ? (
124
- <span>
125
- {' '}
131
+ );
132
+ }
133
+
134
+ if (participantCount > 0) {
135
+ const operator = participantCount === 1 ? 'IS' : 'IN';
136
+
137
+ return (
138
+ <>
126
139
  <span
127
140
  className={clsx(classes.filterName, classes.localFindBackground)}
128
141
  onClick={clearAutocomplete}
129
142
  >
130
143
  Participant ID
131
144
  </span>
132
- {' '}
133
- {' '}
134
- <span className={classes.operators}>
135
- {(autocomplete.length === 1 && !upload.length) ? 'IS ' : 'IN '}
136
- </span>
137
- </span>
138
- ) : null}
139
- <span>
140
- {(((upload.length > 0 ? 1 : 0) + autocomplete.length) > 1)
141
- ? <span className={classes.bracketsOpen}>(</span>
142
- : null}
143
- {upload.length && autocomplete.length ? (
144
- <>
145
- {' '}
146
- <span
147
- className={clsx(classes.filterCheckboxes, classes.localFind)}
148
- onClick={clearUpload}
149
- >
150
- INPUT PARTICIPANT SET
151
- </span>
152
- {' '}
153
- </>
154
- ) : null}
155
- {autocomplete.slice(0, maxItems).map((d, idx) => (
156
- <>
157
- <span
158
- className={clsx(classes.filterCheckboxes, classes.facetSectionCases)}
159
- key={idx}
160
- onClick={() => deleteAutocompleteItem(d.title)}
161
- >
162
- {d.title}
163
- </span>
164
- {idx === (maxItems - 1) ? null : ' '}
145
+ <span className={classes.operators}>{operator}</span>
146
+
147
+ {operator === 'IN' && <span className={classes.bracketsOpen}>(</span>}
148
+
149
+ {upload.length > 0 && (
150
+ <>
151
+ <span
152
+ className={clsx(classes.filterCheckboxes, classes.localFind)}
153
+ onClick={clearUpload}
154
+ >
155
+ INPUT PARTICIPANT SET
156
+ </span>
157
+ </>
158
+ )}
159
+
160
+ {participantItems.slice(0, maxItems).map((d, idx, arr) => (
161
+ <React.Fragment key={`pid-${idx}`}>
162
+ <span
163
+ className={clsx(classes.filterCheckboxes, classes.facetSectionCases)}
164
+ onClick={() => deleteAutocompleteItem(d.title)}
165
+ >
166
+ {d.title}
167
+ </span>
168
+ {idx < arr.length - 1 && ' '}
169
+ </React.Fragment>
170
+ ))}
171
+ {participantItems.length > maxItems && '...'}
172
+ {operator === 'IN' && <span className={classes.bracketsClose}>)</span>}
165
173
  </>
166
- ))}
167
- {autocomplete.length > maxItems && '...'}
168
- {(((upload.length > 0 ? 1 : 0) + autocomplete.length) > 1)
169
- ? <span className={classes.bracketsClose}>)</span>
170
- : null}
171
- </span>
172
- </span>
173
- ) : null}
174
+ );
175
+ }
176
+
177
+ return null;
178
+ })()}
179
+
180
+ {/* 'or' logic */}
181
+ {(upload.length > 0 || autocomplete.some((i) => i.type === 'participantIds'))
182
+ && autocomplete.some((i) => i.type === 'associatedIds')
183
+ && (<span className={classes.operators}>OR</span>)}
184
+
185
+ {/* Associated ID Section */}
186
+ {(() => {
187
+ const associatedItems = autocomplete.filter((i) => i.type === 'associatedIds');
188
+ if (associatedItems.length === 0) return null;
189
+
190
+ const operator = associatedItems.length === 1 ? 'IS' : 'IN';
191
+
192
+ return (
193
+ <>
194
+ <span
195
+ className={clsx(classes.filterName, classes.localFindAssociatedIdsBackground)}
196
+ onClick={clearAutocomplete}
197
+ >
198
+ Synonym
199
+ </span>
200
+ <span className={classes.operators}>{operator}</span>
201
+ {operator === 'IN' && <span className={classes.bracketsOpen}>(</span>}
202
+
203
+ {associatedItems.slice(0, maxItems).map((d, idx, arr) => (
204
+ <React.Fragment key={`aid-${idx}`}>
205
+ <span
206
+ className={
207
+ clsx(classes.filterCheckboxes, classes.localFindAssociatedIdsText)
208
+ }
209
+ onClick={() => deleteAutocompleteItem(d.title)}
210
+ >
211
+ {d.synonym}
212
+ </span>
213
+ {idx < arr.length - 1 && ' '}
214
+ </React.Fragment>
215
+ ))}
216
+ {associatedItems.length > maxItems && '...'}
217
+ {operator === 'IN' && <span className={classes.bracketsClose}>)</span>}
218
+ </>
219
+ );
220
+ })()}
221
+ </span>
222
+ )}
223
+
224
+ {/* --------------------- */}
174
225
 
175
226
  {/* Facet Sidebar Selections */}
176
227
  {((autocomplete.length || upload.length) && mappedInputs.length)
@@ -200,6 +251,7 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
200
251
  filterItems={mappedInputs}
201
252
  rootPath={queryURLRootPath}
202
253
  queryUrlCharacterLimit={queryUrlCharacterLimit}
254
+ generateUrl={generateUrl}
203
255
  />
204
256
  )
205
257
  }
@@ -80,5 +80,15 @@ export default {
80
80
  * @returns {void}
81
81
  */
82
82
  resetFacetSlider: (section) => {},
83
+
84
+ /**
85
+ * Generate a query URL by calling the interop service
86
+ *
87
+ * @param {string} queryStr the query string to encode
88
+ * @param {string} root the root path for the URL
89
+ * @param {function} setUrlCallback callback function to set the generated URL
90
+ * @returns {Promise<void>}
91
+ */
92
+ generateUrl: async (queryStr, root, setUrlCallback) => {},
83
93
  },
84
94
  };
@@ -147,4 +147,10 @@ export default () => ({
147
147
  backgroundColor: '#DDEAE540',
148
148
  border: '1px solid #646464',
149
149
  },
150
+ localFindAssociatedIdsBackground: {
151
+ backgroundColor: '#F6A700',
152
+ },
153
+ localFindAssociatedIdsText: {
154
+ color: '#B36B00',
155
+ },
150
156
  });