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

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/README.md CHANGED
@@ -84,12 +84,19 @@ const CONFIG = {
84
84
  clearAutocomplete: () => {},
85
85
 
86
86
  /**
87
- * Delete a specific Local Find searchbox filter (case)
87
+ * Delete a specific Local Find searchbox filter item. The full
88
+ * autocomplete item object is passed (not just the title) so consumers
89
+ * can disambiguate between participant IDs and synonym/associated IDs
90
+ * that may share the same title.
88
91
  *
89
- * @param {string} title
92
+ * @param {object} item the full autocomplete item to remove
93
+ * @param {string} item.title the participant identifier
94
+ * @param {string} [item.type] 'associatedIds' for synonym entries, any
95
+ * other value for participant IDs
96
+ * @param {string} [item.synonym] synonym value (associated-IDs only)
90
97
  * @returns {void}
91
98
  */
92
- deleteAutocompleteItem: (title) => {},
99
+ deleteAutocompleteItem: (item) => {},
93
100
 
94
101
  /**
95
102
  * Reset a specific facet section (e.g. Program)
@@ -101,26 +101,59 @@ const QueryBarGenerator = function QueryBarGenerator() {
101
101
  onClick: clearImportFrom
102
102
  }, "IMPORTED PARTICIPANT SET"), hasImportFrom && (mappedInputs.length || autocomplete.length || upload.length) ? /*#__PURE__*/_react.default.createElement("span", {
103
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", {
105
- className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindBackground),
106
- onClick: clearUpload
107
- }, "INPUT PARTICIPANT SET") : null, autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
108
- className: (0, _clsx.default)(classes.filterName, classes.localFindBackground),
109
- onClick: clearAutocomplete
110
- }, "Participant ID"), ' ', ' ', /*#__PURE__*/_react.default.createElement("span", {
104
+ }, " AND ") : null, (autocomplete.length || upload.length) > 0 && /*#__PURE__*/_react.default.createElement("span", null, (() => {
105
+ const participantItems = autocomplete.filter(i => i.type !== 'associatedIds');
106
+ const participantCount = upload.length + participantItems.length;
107
+ if (upload.length > 0 && participantItems.length === 0) {
108
+ return /*#__PURE__*/_react.default.createElement("span", {
109
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindBackground),
110
+ onClick: clearUpload
111
+ }, "INPUT PARTICIPANT SET");
112
+ }
113
+ if (participantCount > 0) {
114
+ const operator = participantCount === 1 ? 'IS' : 'IN';
115
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
116
+ className: (0, _clsx.default)(classes.filterName, classes.localFindBackground),
117
+ onClick: clearAutocomplete
118
+ }, "Participant ID"), /*#__PURE__*/_react.default.createElement("span", {
119
+ className: classes.operators
120
+ }, operator), operator === 'IN' && /*#__PURE__*/_react.default.createElement("span", {
121
+ className: classes.bracketsOpen
122
+ }, "("), upload.length > 0 && /*#__PURE__*/_react.default.createElement("span", {
123
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFind),
124
+ onClick: clearUpload
125
+ }, "INPUT PARTICIPANT SET"), participantItems.slice(0, maxItems).map((d, idx, arr) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
126
+ key: "pid-".concat(idx)
127
+ }, /*#__PURE__*/_react.default.createElement("span", {
128
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.facetSectionCases),
129
+ onClick: () => deleteAutocompleteItem(d)
130
+ }, d.title), idx < arr.length - 1 && ' ')), participantItems.length > maxItems && '...', operator === 'IN' && /*#__PURE__*/_react.default.createElement("span", {
131
+ className: classes.bracketsClose
132
+ }, ")"));
133
+ }
134
+ return null;
135
+ })(), (upload.length > 0 || autocomplete.some(i => i.type !== 'associatedIds')) && autocomplete.some(i => i.type === 'associatedIds') && /*#__PURE__*/_react.default.createElement("span", {
111
136
  className: classes.operators
112
- }, 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", {
113
- className: classes.bracketsOpen
114
- }, "(") : null, upload.length && autocomplete.length ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, ' ', /*#__PURE__*/_react.default.createElement("span", {
115
- className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFind),
116
- onClick: clearUpload
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", {
118
- className: (0, _clsx.default)(classes.filterCheckboxes, classes.facetSectionCases),
119
- key: idx,
120
- onClick: () => deleteAutocompleteItem(d.title)
121
- }, d.title), idx === maxItems - 1 ? null : ' ')), autocomplete.length > maxItems && '...', (upload.length > 0 ? 1 : 0) + autocomplete.length > 1 ? /*#__PURE__*/_react.default.createElement("span", {
122
- className: classes.bracketsClose
123
- }, ")") : null)) : null, (autocomplete.length || upload.length) && mappedInputs.length ? /*#__PURE__*/_react.default.createElement("span", {
137
+ }, "OR"), (() => {
138
+ const associatedItems = autocomplete.filter(i => i.type === 'associatedIds');
139
+ if (associatedItems.length === 0) return null;
140
+ const operator = associatedItems.length === 1 ? 'IS' : 'IN';
141
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
142
+ className: (0, _clsx.default)(classes.filterName, classes.localFindAssociatedIdsBackground),
143
+ onClick: clearAutocomplete
144
+ }, "Synonym"), /*#__PURE__*/_react.default.createElement("span", {
145
+ className: classes.operators
146
+ }, operator), operator === 'IN' && /*#__PURE__*/_react.default.createElement("span", {
147
+ className: classes.bracketsOpen
148
+ }, "("), associatedItems.slice(0, maxItems).map((d, idx, arr) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
149
+ key: "aid-".concat(idx)
150
+ }, /*#__PURE__*/_react.default.createElement("span", {
151
+ className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindAssociatedIdsText),
152
+ onClick: () => deleteAutocompleteItem(d)
153
+ }, d.synonym), idx < arr.length - 1 && ' ')), associatedItems.length > maxItems && '...', operator === 'IN' && /*#__PURE__*/_react.default.createElement("span", {
154
+ className: classes.bracketsClose
155
+ }, ")"));
156
+ })()), (autocomplete.length || upload.length) && mappedInputs.length ? /*#__PURE__*/_react.default.createElement("span", {
124
157
  className: classes.operators
125
158
  }, " AND ") : null, mappedInputs.map((filter, index) => /*#__PURE__*/_react.default.createElement(_FilterMap.Filter, {
126
159
  index: index,
@@ -51,12 +51,20 @@ var _default = {
51
51
  */
52
52
  clearAutocomplete: () => {},
53
53
  /**
54
- * Delete a specific Local Find searchbox filter (case)
54
+ * Delete a specific Local Find searchbox filter item.
55
+ * The full autocomplete item is passed (not just the title) so consumers
56
+ * can disambiguate between participant IDs and synonym/associated IDs that
57
+ * may share the same title.
55
58
  *
56
- * @param {string} title
59
+ * @param {object} item the autocomplete item to remove
60
+ * @param {string} item.title the participant identifier
61
+ * @param {string} [item.type] either 'associatedIds' for synonym entries
62
+ * or any other value (e.g. 'subjectIds', 'participantIds') for
63
+ * participant IDs
64
+ * @param {string} [item.synonym] the synonym value (associated-IDs only)
57
65
  * @returns {void}
58
66
  */
59
- deleteAutocompleteItem: title => {},
67
+ deleteAutocompleteItem: item => {},
60
68
  /**
61
69
  * Reset a specific facet section (e.g. Program)
62
70
  *
@@ -124,46 +124,39 @@ var _default = () => ({
124
124
  backgroundColor: '#E1C9E140',
125
125
  border: '1px solid #646464'
126
126
  },
127
- facetSectionGeneticanalysis: {
128
- color: '#4555AB'
129
- },
130
- facetSectionGeneticanalysisBackground: {
131
- backgroundColor: '#4555AB30',
132
- border: '1px solid #646464'
133
- },
134
127
  facetSectionTreatment: {
135
- color: '#907642'
128
+ color: '#4555AB'
136
129
  },
137
130
  facetSectionTreatmentBackground: {
138
- backgroundColor: '#F0DFBD40',
131
+ backgroundColor: '#4555AB30',
139
132
  border: '1px solid #646464'
140
133
  },
141
134
  facetSectionTreatmentresponse: {
142
- color: '#A85348'
135
+ color: '#907642'
143
136
  },
144
137
  facetSectionTreatmentresponseBackground: {
145
- backgroundColor: '#F8D7D240',
138
+ backgroundColor: '#F0DFBD40',
146
139
  border: '1px solid #646464'
147
140
  },
148
141
  facetSectionSurvival: {
149
- color: '#1F6BBF'
142
+ color: '#A85348'
150
143
  },
151
144
  facetSectionSurvivalBackground: {
152
- backgroundColor: '#CEDEF040',
145
+ backgroundColor: '#F8D7D240',
153
146
  border: '1px solid #646464'
154
147
  },
155
148
  facetSectionSamples: {
156
- color: '#14A773'
149
+ color: '#1F6BBF'
157
150
  },
158
151
  facetSectionSamplesBackground: {
159
- backgroundColor: '#DDEAE540',
152
+ backgroundColor: '#CEDEF040',
160
153
  border: '1px solid #646464'
161
154
  },
162
155
  facetSectionDatacategory: {
163
- color: '#357288'
156
+ color: '#14A773'
164
157
  },
165
158
  facetSectionDatacategoryBackground: {
166
- backgroundColor: '#E4ECE9',
159
+ backgroundColor: '#DDEAE540',
167
160
  border: '1px solid #646464'
168
161
  },
169
162
  facetSectionStudy: {
@@ -179,6 +172,12 @@ var _default = () => ({
179
172
  facetSectionSequencinglibraryBackground: {
180
173
  backgroundColor: '#E1C9E140',
181
174
  border: '1px solid #646464'
175
+ },
176
+ localFindAssociatedIdsBackground: {
177
+ backgroundColor: '#F6A700'
178
+ },
179
+ localFindAssociatedIdsText: {
180
+ color: '#B36B00'
182
181
  }
183
182
  });
184
183
  exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bento-core/query-bar",
3
- "version": "1.0.1-ccdiintegrated.2",
3
+ "version": "1.0.1-ccdiintegrated.3",
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
  "homepage": "https://github.com/CBIIT/bento-frontend#readme",
6
6
  "bugs": {
@@ -121,70 +121,120 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
121
121
  {hasImportFrom && (mappedInputs.length || autocomplete.length || upload.length)
122
122
  ? <span className={classes.operators}> AND </span>
123
123
  : null}
124
- {(autocomplete.length || upload.length) ? (
124
+ {/* Section: Localfind Results */}
125
+ {(autocomplete.length || upload.length) > 0 && (
125
126
  <span>
126
- {/* Standalone case set button */}
127
- {(upload.length && !autocomplete.length)
128
- ? (
129
- <span
130
- className={clsx(classes.filterCheckboxes, classes.localFindBackground)}
131
- onClick={clearUpload}
132
- >
133
- INPUT PARTICIPANT SET
134
- </span>
135
- ) : null}
136
- {autocomplete.length
137
- ? (
138
- <span>
139
- {' '}
140
- <span
141
- className={clsx(classes.filterName, classes.localFindBackground)}
142
- onClick={clearAutocomplete}
143
- >
144
- Participant ID
145
- </span>
146
- {' '}
147
- {' '}
148
- <span className={classes.operators}>
149
- {(autocomplete.length === 1 && !upload.length) ? 'IS ' : 'IN '}
150
- </span>
151
- </span>
152
- ) : null}
153
- <span>
154
- {(((upload.length > 0 ? 1 : 0) + autocomplete.length) > 1)
155
- ? <span className={classes.bracketsOpen}>(</span>
156
- : null}
157
- {upload.length && autocomplete.length ? (
158
- <>
159
- {' '}
127
+ {/* Participant ID Section
128
+ * Treats any autocomplete item that is not explicitly an
129
+ * associated/synonym ID as a participant ID, so legacy items
130
+ * (e.g. type === 'subjectIds') keep working alongside the new
131
+ * synonym section. */}
132
+ {(() => {
133
+ const participantItems = autocomplete.filter((i) => i.type !== 'associatedIds');
134
+ const participantCount = upload.length + participantItems.length;
135
+
136
+ if (upload.length > 0 && participantItems.length === 0) {
137
+ return (
160
138
  <span
161
- className={clsx(classes.filterCheckboxes, classes.localFind)}
139
+ className={clsx(classes.filterCheckboxes, classes.localFindBackground)}
162
140
  onClick={clearUpload}
163
141
  >
164
142
  INPUT PARTICIPANT SET
165
143
  </span>
166
- {' '}
167
- </>
168
- ) : null}
169
- {autocomplete.slice(0, maxItems).map((d, idx) => (
144
+ );
145
+ }
146
+
147
+ if (participantCount > 0) {
148
+ const operator = participantCount === 1 ? 'IS' : 'IN';
149
+
150
+ return (
151
+ <>
152
+ <span
153
+ className={clsx(classes.filterName, classes.localFindBackground)}
154
+ onClick={clearAutocomplete}
155
+ >
156
+ Participant ID
157
+ </span>
158
+ <span className={classes.operators}>{operator}</span>
159
+
160
+ {operator === 'IN' && <span className={classes.bracketsOpen}>(</span>}
161
+
162
+ {upload.length > 0 && (
163
+ <span
164
+ className={clsx(classes.filterCheckboxes, classes.localFind)}
165
+ onClick={clearUpload}
166
+ >
167
+ INPUT PARTICIPANT SET
168
+ </span>
169
+ )}
170
+
171
+ {participantItems.slice(0, maxItems).map((d, idx, arr) => (
172
+ <React.Fragment key={`pid-${idx}`}>
173
+ <span
174
+ className={clsx(classes.filterCheckboxes, classes.facetSectionCases)}
175
+ onClick={() => deleteAutocompleteItem(d)}
176
+ >
177
+ {d.title}
178
+ </span>
179
+ {idx < arr.length - 1 && ' '}
180
+ </React.Fragment>
181
+ ))}
182
+ {participantItems.length > maxItems && '...'}
183
+ {operator === 'IN' && <span className={classes.bracketsClose}>)</span>}
184
+ </>
185
+ );
186
+ }
187
+
188
+ return null;
189
+ })()}
190
+
191
+ {/* OR connector between Participant IDs (or upload) and Synonyms */}
192
+ {(upload.length > 0 || autocomplete.some((i) => i.type !== 'associatedIds'))
193
+ && autocomplete.some((i) => i.type === 'associatedIds')
194
+ && (<span className={classes.operators}>OR</span>)}
195
+
196
+ {/* Associated ID (Synonym) Section */}
197
+ {(() => {
198
+ const associatedItems = autocomplete.filter((i) => i.type === 'associatedIds');
199
+ if (associatedItems.length === 0) return null;
200
+
201
+ const operator = associatedItems.length === 1 ? 'IS' : 'IN';
202
+
203
+ return (
170
204
  <>
171
205
  <span
172
- className={clsx(classes.filterCheckboxes, classes.facetSectionCases)}
173
- key={idx}
174
- onClick={() => deleteAutocompleteItem(d.title)}
206
+ className={clsx(
207
+ classes.filterName,
208
+ classes.localFindAssociatedIdsBackground,
209
+ )}
210
+ onClick={clearAutocomplete}
175
211
  >
176
- {d.title}
212
+ Synonym
177
213
  </span>
178
- {idx === (maxItems - 1) ? null : ' '}
214
+ <span className={classes.operators}>{operator}</span>
215
+ {operator === 'IN' && <span className={classes.bracketsOpen}>(</span>}
216
+
217
+ {associatedItems.slice(0, maxItems).map((d, idx, arr) => (
218
+ <React.Fragment key={`aid-${idx}`}>
219
+ <span
220
+ className={clsx(
221
+ classes.filterCheckboxes,
222
+ classes.localFindAssociatedIdsText,
223
+ )}
224
+ onClick={() => deleteAutocompleteItem(d)}
225
+ >
226
+ {d.synonym}
227
+ </span>
228
+ {idx < arr.length - 1 && ' '}
229
+ </React.Fragment>
230
+ ))}
231
+ {associatedItems.length > maxItems && '...'}
232
+ {operator === 'IN' && <span className={classes.bracketsClose}>)</span>}
179
233
  </>
180
- ))}
181
- {autocomplete.length > maxItems && '...'}
182
- {(((upload.length > 0 ? 1 : 0) + autocomplete.length) > 1)
183
- ? <span className={classes.bracketsClose}>)</span>
184
- : null}
185
- </span>
234
+ );
235
+ })()}
186
236
  </span>
187
- ) : null}
237
+ )}
188
238
 
189
239
  {/* Facet Sidebar Selections */}
190
240
  {((autocomplete.length || upload.length) && mappedInputs.length)
@@ -50,12 +50,20 @@ export default {
50
50
  clearAutocomplete: () => { },
51
51
 
52
52
  /**
53
- * Delete a specific Local Find searchbox filter (case)
53
+ * Delete a specific Local Find searchbox filter item.
54
+ * The full autocomplete item is passed (not just the title) so consumers
55
+ * can disambiguate between participant IDs and synonym/associated IDs that
56
+ * may share the same title.
54
57
  *
55
- * @param {string} title
58
+ * @param {object} item the autocomplete item to remove
59
+ * @param {string} item.title the participant identifier
60
+ * @param {string} [item.type] either 'associatedIds' for synonym entries
61
+ * or any other value (e.g. 'subjectIds', 'participantIds') for
62
+ * participant IDs
63
+ * @param {string} [item.synonym] the synonym value (associated-IDs only)
56
64
  * @returns {void}
57
65
  */
58
- deleteAutocompleteItem: (title) => { },
66
+ deleteAutocompleteItem: (item) => { },
59
67
 
60
68
  /**
61
69
  * Reset a specific facet section (e.g. Program)
@@ -118,46 +118,39 @@ export default () => ({
118
118
  backgroundColor: '#E1C9E140',
119
119
  border: '1px solid #646464',
120
120
  },
121
- facetSectionGeneticanalysis: {
122
- color: '#4555AB',
123
- },
124
- facetSectionGeneticanalysisBackground: {
125
- backgroundColor: '#4555AB30',
126
- border: '1px solid #646464',
127
- },
128
121
  facetSectionTreatment: {
129
- color: '#907642',
122
+ color: '#4555AB',
130
123
  },
131
124
  facetSectionTreatmentBackground: {
132
- backgroundColor: '#F0DFBD40',
125
+ backgroundColor: '#4555AB30',
133
126
  border: '1px solid #646464',
134
127
  },
135
128
  facetSectionTreatmentresponse: {
136
- color: '#A85348',
129
+ color: '#907642',
137
130
  },
138
131
  facetSectionTreatmentresponseBackground: {
139
- backgroundColor: '#F8D7D240',
132
+ backgroundColor: '#F0DFBD40',
140
133
  border: '1px solid #646464',
141
134
  },
142
135
  facetSectionSurvival: {
143
- color: '#1F6BBF',
136
+ color: '#A85348',
144
137
  },
145
138
  facetSectionSurvivalBackground: {
146
- backgroundColor: '#CEDEF040',
139
+ backgroundColor: '#F8D7D240',
147
140
  border: '1px solid #646464',
148
141
  },
149
142
  facetSectionSamples: {
150
- color: '#14A773',
143
+ color: '#1F6BBF',
151
144
  },
152
145
  facetSectionSamplesBackground: {
153
- backgroundColor: '#DDEAE540',
146
+ backgroundColor: '#CEDEF040',
154
147
  border: '1px solid #646464',
155
148
  },
156
149
  facetSectionDatacategory: {
157
- color: '#357288',
150
+ color: '#14A773',
158
151
  },
159
152
  facetSectionDatacategoryBackground: {
160
- backgroundColor: '#E4ECE9',
153
+ backgroundColor: '#DDEAE540',
161
154
  border: '1px solid #646464',
162
155
  },
163
156
  facetSectionStudy: {
@@ -174,4 +167,10 @@ export default () => ({
174
167
  backgroundColor: '#E1C9E140',
175
168
  border: '1px solid #646464',
176
169
  },
170
+ localFindAssociatedIdsBackground: {
171
+ backgroundColor: '#F6A700',
172
+ },
173
+ localFindAssociatedIdsText: {
174
+ color: '#B36B00',
175
+ },
177
176
  });