@bento-core/facet-filter 1.0.1-popsci.3 → 1.0.1-popsci.4
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 +59 -3
- package/dist/FacetFilterController.js +23 -16
- package/dist/FacetFilterView.js +1 -6
- package/dist/components/inputs/checkbox/CheckboxView.js +13 -11
- package/dist/components/inputs/slider/InputMinMaxView.js +2 -1
- package/dist/components/inputs/slider/SliderView.js +16 -3
- package/dist/utils/Sort.js +8 -6
- package/package.json +2 -2
- package/src/FacetFilterController.js +18 -13
- package/src/FacetFilterView.js +1 -9
- package/src/components/inputs/checkbox/CheckboxView.js +20 -11
- package/src/components/inputs/slider/InputMinMaxView.js +1 -0
- package/src/components/inputs/slider/SliderView.js +28 -18
- package/src/utils/Sort.js +14 -8
package/README.md
CHANGED
|
@@ -95,6 +95,8 @@ export const facetsConfig = [{
|
|
|
95
95
|
minLowerBound: 0,
|
|
96
96
|
maxUpperBound: 100,
|
|
97
97
|
quantifier: 'Years',
|
|
98
|
+
CustomLowerUpperBound: CustomLowerUpperBound, // Custom component for displaying lower and upper bounds
|
|
99
|
+
CustomSliderValue: CustomSliderValue, // Custom component for displaying slider value
|
|
98
100
|
].
|
|
99
101
|
```
|
|
100
102
|
1. **apiForFiltering** refers to object key for retrieving name and subjects count from query response (DASHBOARD_QUERY)
|
|
@@ -244,12 +246,66 @@ className={clsx(classes.sectionSummaryText, classes[facetClasses])}
|
|
|
244
246
|
## 10 CLearAllFilterButton Component
|
|
245
247
|
Bento Core provides 1. function to clear all active filters, 2. disable flag (true incase of no active filters). Client is responsible for defining view (custom html).
|
|
246
248
|
```
|
|
247
|
-
import {
|
|
249
|
+
import { ClearAllFiltersBtn, FacetFilter } from '@bento-core/facet-filter';
|
|
250
|
+
import { getFilters } from '@bento-core/facet-filter';
|
|
248
251
|
|
|
249
252
|
const CustomClearAllFiltersBtn = ({ onClearAllFilters, disable }) => {
|
|
250
253
|
//...custom component 1. bind onClearFilters fn
|
|
251
254
|
// 2. disable flag to disable button
|
|
252
|
-
}
|
|
255
|
+
}
|
|
256
|
+
// get filter data
|
|
257
|
+
// filterState: state.statusReducer.filterState, (from reducer)
|
|
258
|
+
// const activeFilters = getFilters(filterState) // formating
|
|
259
|
+
|
|
260
|
+
<ClearAllFiltersBtn
|
|
261
|
+
Component={CustomClearAllFiltersBtn}
|
|
262
|
+
activeFilters={activeFilters}
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## 11 Facet Value Component
|
|
267
|
+
```
|
|
268
|
+
// response
|
|
269
|
+
// filterCaseCountByProgram: [{group: "COP", subjects: 301}]
|
|
270
|
+
const {
|
|
271
|
+
name,
|
|
272
|
+
customName,
|
|
273
|
+
subjects,
|
|
274
|
+
customSubjects,
|
|
275
|
+
tooltip,
|
|
276
|
+
} = checkboxItem;
|
|
277
|
+
|
|
278
|
+
// 1. by default facet value component display group ("COP")
|
|
279
|
+
// 2. set customName to display customize value
|
|
280
|
+
// 3. by default facet value component display subjects (301)
|
|
281
|
+
// 4. set customSubjects to display customize value or adjust correct field for subject count
|
|
282
|
+
// 5. tooltip - provide text value to tooltip text
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Add Bento frontend filter count/subjects
|
|
286
|
+
* Add tootip text
|
|
287
|
+
*/
|
|
288
|
+
const filterData = facetsConfig.reduce((acc, item) => {
|
|
289
|
+
const facetValues = searchData[item.apiPath];
|
|
290
|
+
if (!facetValues) {
|
|
291
|
+
return acc;
|
|
292
|
+
}
|
|
293
|
+
const subjectCounts = [...facetValues].map((checkbox) => {
|
|
294
|
+
const text = tooltipText[item.tooltipKey];
|
|
295
|
+
return {
|
|
296
|
+
...checkbox,
|
|
297
|
+
customSubjects: checkbox.count,
|
|
298
|
+
tooltip: text ? text[checkbox.group] : undefined,
|
|
299
|
+
};
|
|
300
|
+
});
|
|
301
|
+
return { ...acc, [item.apiPath]: [...subjectCounts] };
|
|
302
|
+
}, {});
|
|
253
303
|
|
|
254
|
-
|
|
304
|
+
<FacetFilter
|
|
305
|
+
data={filterData}
|
|
306
|
+
facetSectionConfig={facetSectionVariables}
|
|
307
|
+
facetsConfig={facetsConfig}
|
|
308
|
+
CustomFacetSection={CustomFacetSection}
|
|
309
|
+
CustomFacetView={CustomFacetView}
|
|
310
|
+
/>
|
|
255
311
|
```
|
|
@@ -12,13 +12,13 @@ var _FacetFilterView = _interopRequireDefault(require("./FacetFilterView"));
|
|
|
12
12
|
const _excluded = ["section"];
|
|
13
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
14
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
15
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
16
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
15
17
|
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
18
|
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; }
|
|
17
19
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
18
20
|
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
19
21
|
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
20
|
-
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
21
|
-
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
22
22
|
const FacetFilterController = props => {
|
|
23
23
|
/**
|
|
24
24
|
* update checkbox state
|
|
@@ -29,7 +29,8 @@ const FacetFilterController = props => {
|
|
|
29
29
|
filterState,
|
|
30
30
|
data,
|
|
31
31
|
facetsConfig,
|
|
32
|
-
facetSectionConfig
|
|
32
|
+
facetSectionConfig,
|
|
33
|
+
tooltipText = {}
|
|
33
34
|
} = props;
|
|
34
35
|
const updateFacetState = filterSections => {
|
|
35
36
|
const updateSections = [...filterSections];
|
|
@@ -37,9 +38,16 @@ const FacetFilterController = props => {
|
|
|
37
38
|
for (const [key, value] of Object.entries(filterState)) {
|
|
38
39
|
updateSections.forEach(sideBar => {
|
|
39
40
|
if (sideBar.type === _Types.InputTypes.CHECKBOX && sideBar.datafield === key) {
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
const {
|
|
42
|
+
facetValues = []
|
|
43
|
+
} = sideBar;
|
|
44
|
+
const updateFacetVals = facetValues.map(item => {
|
|
45
|
+
const facetVal = item[sideBar.field];
|
|
46
|
+
return _objectSpread(_objectSpread({}, item), {}, {
|
|
47
|
+
isChecked: value[facetVal] ? value[facetVal] : false
|
|
48
|
+
});
|
|
42
49
|
});
|
|
50
|
+
sideBar.facetValues = updateFacetVals;
|
|
43
51
|
}
|
|
44
52
|
if (sideBar.type === _Types.InputTypes.SLIDER && sideBar.datafield === key) {
|
|
45
53
|
sideBar.facetValues = value;
|
|
@@ -49,9 +57,13 @@ const FacetFilterController = props => {
|
|
|
49
57
|
} else {
|
|
50
58
|
updateSections.forEach(sideBar => {
|
|
51
59
|
if (sideBar.type === _Types.InputTypes.CHECKBOX) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
60
|
+
const {
|
|
61
|
+
facetValues = []
|
|
62
|
+
} = sideBar;
|
|
63
|
+
const updateFacetVals = facetValues.map(item => _objectSpread(_objectSpread({}, item), {}, {
|
|
64
|
+
isChecked: false
|
|
65
|
+
}));
|
|
66
|
+
sideBar.facetValues = updateFacetVals;
|
|
55
67
|
}
|
|
56
68
|
/**
|
|
57
69
|
* set default value for slider - on clear all filter
|
|
@@ -96,6 +108,7 @@ const FacetFilterController = props => {
|
|
|
96
108
|
* Construct filter object
|
|
97
109
|
* 1. add facet values to facets
|
|
98
110
|
* 2. add 'name' key to each facet value
|
|
111
|
+
* 3. add '
|
|
99
112
|
*/
|
|
100
113
|
const addFacetValues = facets => {
|
|
101
114
|
const updateFacets = [];
|
|
@@ -105,19 +118,13 @@ const FacetFilterController = props => {
|
|
|
105
118
|
facetValues: []
|
|
106
119
|
});
|
|
107
120
|
const {
|
|
108
|
-
field,
|
|
109
121
|
ApiLowerBoundName,
|
|
110
122
|
ApiUpperBoundName,
|
|
111
123
|
apiForFiltering
|
|
112
124
|
} = updateFacet;
|
|
113
125
|
if (data[apiForFiltering]) {
|
|
114
126
|
if (Array.isArray(data[apiForFiltering])) {
|
|
115
|
-
|
|
116
|
-
const addField = _objectSpread({}, item);
|
|
117
|
-
addField.name = item[field];
|
|
118
|
-
return addField;
|
|
119
|
-
});
|
|
120
|
-
updateFacet.facetValues = updateField;
|
|
127
|
+
updateFacet.facetValues = data[apiForFiltering];
|
|
121
128
|
}
|
|
122
129
|
/**
|
|
123
130
|
* add object to facet values
|
|
@@ -140,7 +147,7 @@ const FacetFilterController = props => {
|
|
|
140
147
|
* Generate facet sections state
|
|
141
148
|
*
|
|
142
149
|
*/
|
|
143
|
-
const displayFacets = facetsConfig.filter(facet => facet.show)
|
|
150
|
+
const displayFacets = facetsConfig.filter(facet => facet.show);
|
|
144
151
|
const facetStates = addFacetValues(displayFacets);
|
|
145
152
|
const updateState = updateFacetState(facetStates);
|
|
146
153
|
const facetSections = arrangeBySections(updateState);
|
package/dist/FacetFilterView.js
CHANGED
|
@@ -9,7 +9,6 @@ var _core = require("@material-ui/core");
|
|
|
9
9
|
var _FacetFilterStyle = _interopRequireDefault(require("./FacetFilterStyle"));
|
|
10
10
|
var _FacetSectionView = _interopRequireDefault(require("./components/section/FacetSectionView"));
|
|
11
11
|
var _ReduxFacetView = _interopRequireDefault(require("./components/facet/ReduxFacetView"));
|
|
12
|
-
var _FilterItems = _interopRequireDefault(require("./components/inputs/FilterItems"));
|
|
13
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
13
|
/* eslint-disable arrow-body-style */
|
|
15
14
|
/* eslint-disable padded-blocks */
|
|
@@ -29,11 +28,7 @@ const BentoFacetFilter = _ref => {
|
|
|
29
28
|
}, section.items.map(facet => /*#__PURE__*/_react.default.createElement(_ReduxFacetView.default, {
|
|
30
29
|
facet: facet,
|
|
31
30
|
CustomView: CustomFacetView
|
|
32
|
-
}
|
|
33
|
-
className: "List_".concat(facet.label)
|
|
34
|
-
}, /*#__PURE__*/_react.default.createElement(_FilterItems.default, {
|
|
35
|
-
facet: facet
|
|
36
|
-
}))))))));
|
|
31
|
+
}))))));
|
|
37
32
|
};
|
|
38
33
|
var _default = (0, _core.withStyles)(_FacetFilterStyle.default)(BentoFacetFilter);
|
|
39
34
|
exports.default = _default;
|
|
@@ -32,16 +32,20 @@ const CheckBoxView = _ref => {
|
|
|
32
32
|
facet
|
|
33
33
|
} = _ref;
|
|
34
34
|
const {
|
|
35
|
-
name,
|
|
36
|
-
subjects,
|
|
37
35
|
isChecked = false,
|
|
38
36
|
index,
|
|
39
37
|
section,
|
|
40
|
-
tooltip
|
|
41
|
-
label
|
|
38
|
+
tooltip
|
|
42
39
|
} = checkboxItem;
|
|
40
|
+
const {
|
|
41
|
+
field = 'group',
|
|
42
|
+
count = 'subjects',
|
|
43
|
+
customCount = text => "(".concat(text, ")"),
|
|
44
|
+
defaultValue = ''
|
|
45
|
+
} = facet;
|
|
43
46
|
const indexType = index % 2 === 0 ? 'Even' : 'Odd';
|
|
44
|
-
const checkedSection = "".concat(section).toLowerCase().replace(
|
|
47
|
+
const checkedSection = "".concat(section).toLowerCase().replace(/\ /g, '_');
|
|
48
|
+
const name = checkboxItem[field] || defaultValue || 'N/A';
|
|
45
49
|
const checkboxId = "checkbox_".concat(facet.label, "_").concat(name);
|
|
46
50
|
const rippleRef = (0, _react.useRef)(null);
|
|
47
51
|
const handleRippleStart = event => {
|
|
@@ -56,7 +60,7 @@ const CheckBoxView = _ref => {
|
|
|
56
60
|
};
|
|
57
61
|
const handleToggle = () => {
|
|
58
62
|
const toggleCheckBoxItem = {
|
|
59
|
-
name:
|
|
63
|
+
name: checkboxItem[field],
|
|
60
64
|
datafield: datafield,
|
|
61
65
|
isChecked: !isChecked
|
|
62
66
|
};
|
|
@@ -68,9 +72,7 @@ const CheckBoxView = _ref => {
|
|
|
68
72
|
["".concat(checkedSection, "NameUnChecked")]: !isChecked,
|
|
69
73
|
["".concat(checkedSection, "NameChecked")]: isChecked
|
|
70
74
|
})
|
|
71
|
-
},
|
|
72
|
-
className: classes.checkboxLabel
|
|
73
|
-
}, label) : /*#__PURE__*/_react.default.createElement(_core.Typography, {
|
|
75
|
+
}, /*#__PURE__*/_react.default.createElement(_core.Typography, {
|
|
74
76
|
className: classes.checkboxName
|
|
75
77
|
}, name));
|
|
76
78
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_core.ListItem, {
|
|
@@ -121,14 +123,14 @@ const CheckBoxView = _ref => {
|
|
|
121
123
|
title: tooltip
|
|
122
124
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
123
125
|
className: datafield
|
|
124
|
-
},
|
|
126
|
+
}, name)) : /*#__PURE__*/_react.default.createElement(LabelComponent, null), /*#__PURE__*/_react.default.createElement(_core.ListItemText, {
|
|
125
127
|
className: "".concat(checkedSection, "_md_space")
|
|
126
128
|
}), /*#__PURE__*/_react.default.createElement(_core.Typography, {
|
|
127
129
|
className: (0, _clsx.default)("".concat(checkedSection, "Subjects"), {
|
|
128
130
|
["".concat(checkedSection, "SubjectUnChecked")]: !isChecked,
|
|
129
131
|
["".concat(checkedSection, "SubjectChecked")]: isChecked
|
|
130
132
|
})
|
|
131
|
-
},
|
|
133
|
+
}, customCount(checkboxItem[count] || 0)), /*#__PURE__*/_react.default.createElement(_TouchRipple.default, {
|
|
132
134
|
ref: rippleRef,
|
|
133
135
|
center: true
|
|
134
136
|
})), /*#__PURE__*/_react.default.createElement(_core.Divider, {
|
|
@@ -29,7 +29,9 @@ const SliderView = _ref => {
|
|
|
29
29
|
maxUpperBound,
|
|
30
30
|
quantifier,
|
|
31
31
|
datafield,
|
|
32
|
-
facetValues
|
|
32
|
+
facetValues,
|
|
33
|
+
CustomLowerUpperBound,
|
|
34
|
+
CustomSliderValue
|
|
33
35
|
} = facet;
|
|
34
36
|
const lowerBoundValue = facetValues[0];
|
|
35
37
|
const upperBoundValue = facetValues[1];
|
|
@@ -102,13 +104,24 @@ const SliderView = _ref => {
|
|
|
102
104
|
thumb: isValid() ? classes.thumb : classes.invalidThumb,
|
|
103
105
|
track: isValid() ? classes.track : classes.invalidTrack
|
|
104
106
|
}
|
|
105
|
-
})),
|
|
107
|
+
})), typeof CustomLowerUpperBound === 'function' ? CustomLowerUpperBound({
|
|
108
|
+
minLowerBound,
|
|
109
|
+
maxUpperBound,
|
|
110
|
+
classes
|
|
111
|
+
}) : /*#__PURE__*/_react.default.createElement(_core.Box, {
|
|
106
112
|
className: classes.lowerUpperBound
|
|
107
113
|
}, /*#__PURE__*/_react.default.createElement(_core.Typography, {
|
|
108
114
|
className: classes.lowerBound
|
|
109
115
|
}, minLowerBound), /*#__PURE__*/_react.default.createElement(_core.Typography, {
|
|
110
116
|
className: classes.upperBound
|
|
111
|
-
}, maxUpperBound))),
|
|
117
|
+
}, maxUpperBound))), typeof CustomSliderValue === 'function' ? CustomSliderValue({
|
|
118
|
+
sliderValue,
|
|
119
|
+
minLowerBound,
|
|
120
|
+
maxUpperBound,
|
|
121
|
+
isValid,
|
|
122
|
+
quantifier,
|
|
123
|
+
classes
|
|
124
|
+
}) : (sliderValue[0] > minLowerBound || sliderValue[1] < maxUpperBound) && /*#__PURE__*/_react.default.createElement(_core.Typography, {
|
|
112
125
|
className: isValid() ? classes.sliderText : classes.invalidSliderText
|
|
113
126
|
}, sliderValue[0], ' - ', sliderValue[1], "\xA0", quantifier));
|
|
114
127
|
};
|
package/dist/utils/Sort.js
CHANGED
|
@@ -46,28 +46,30 @@ const sortBySection = _ref => {
|
|
|
46
46
|
let {
|
|
47
47
|
facetValues,
|
|
48
48
|
sort_type,
|
|
49
|
-
sortBy
|
|
49
|
+
sortBy,
|
|
50
|
+
field,
|
|
51
|
+
count = 'subjects'
|
|
50
52
|
} = _ref;
|
|
51
53
|
const sortfacetValues = [...facetValues];
|
|
52
54
|
if (!sortfacetValues) {
|
|
53
55
|
return facetValues;
|
|
54
56
|
}
|
|
55
57
|
if (sortBy === sortType.NUMERIC) {
|
|
56
|
-
sortfacetValues.sort((a, b) => b
|
|
58
|
+
sortfacetValues.sort((a, b) => b[count] - a[count]);
|
|
57
59
|
} else {
|
|
58
|
-
sortfacetValues.sort((a, b) => lowerCaseString(a
|
|
60
|
+
sortfacetValues.sort((a, b) => lowerCaseString(a[field]) > lowerCaseString(b[field]) || -(lowerCaseString(a[field]) < lowerCaseString(b[field])));
|
|
59
61
|
}
|
|
60
62
|
if (sort_type === sortType.CUSTOM_NUMBER && sortBy !== sortType.NUMERIC) {
|
|
61
63
|
sortfacetValues.sort((a, b) => {
|
|
62
|
-
const aNumbs = getNumberArray(a
|
|
63
|
-
const bNumbs = getNumberArray(b
|
|
64
|
+
const aNumbs = getNumberArray(a[field]);
|
|
65
|
+
const bNumbs = getNumberArray(b[field]);
|
|
64
66
|
const aNumb = Number(aNumbs[0]);
|
|
65
67
|
const bNumb = Number(bNumbs[0]);
|
|
66
68
|
return aNumbs.length === bNumbs.length ? aNumb > bNumb : -(aNumb <= bNumb);
|
|
67
69
|
});
|
|
68
70
|
}
|
|
69
71
|
if (sort_type === sortType.RANGE && sortBy !== sortType.NUMERIC) {
|
|
70
|
-
sortfacetValues.sort((a, b) => startIndex(a
|
|
72
|
+
sortfacetValues.sort((a, b) => startIndex(a[field]) > startIndex(b[field]) || -(startIndex(a[field]) < startIndex(b[field])));
|
|
71
73
|
}
|
|
72
74
|
/**
|
|
73
75
|
* Display checked item always on top
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bento-core/facet-filter",
|
|
3
|
-
"version": "1.0.1-popsci.
|
|
3
|
+
"version": "1.0.1-popsci.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -25,5 +25,5 @@
|
|
|
25
25
|
},
|
|
26
26
|
"author": "CTOS Bento Team",
|
|
27
27
|
"license": "ISC",
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "3b3ccdfd3f5870b13f64d3642c7d8ab1649cf632"
|
|
29
29
|
}
|
|
@@ -25,6 +25,7 @@ const FacetFilterController = (props) => {
|
|
|
25
25
|
data,
|
|
26
26
|
facetsConfig,
|
|
27
27
|
facetSectionConfig,
|
|
28
|
+
tooltipText = {},
|
|
28
29
|
} = props;
|
|
29
30
|
|
|
30
31
|
const updateFacetState = (filterSections) => {
|
|
@@ -33,9 +34,15 @@ const FacetFilterController = (props) => {
|
|
|
33
34
|
for (const [key, value] of Object.entries(filterState)) {
|
|
34
35
|
updateSections.forEach((sideBar) => {
|
|
35
36
|
if (sideBar.type === InputTypes.CHECKBOX && sideBar.datafield === key) {
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
const { facetValues = [] } = sideBar;
|
|
38
|
+
const updateFacetVals = facetValues.map((item) => {
|
|
39
|
+
const facetVal = item[sideBar.field];
|
|
40
|
+
return {
|
|
41
|
+
...item,
|
|
42
|
+
isChecked: value[facetVal] ? value[facetVal] : false,
|
|
43
|
+
};
|
|
38
44
|
});
|
|
45
|
+
sideBar.facetValues = updateFacetVals;
|
|
39
46
|
}
|
|
40
47
|
if (sideBar.type === InputTypes.SLIDER && sideBar.datafield === key) {
|
|
41
48
|
sideBar.facetValues = value;
|
|
@@ -45,9 +52,12 @@ const FacetFilterController = (props) => {
|
|
|
45
52
|
} else {
|
|
46
53
|
updateSections.forEach((sideBar) => {
|
|
47
54
|
if (sideBar.type === InputTypes.CHECKBOX) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
const { facetValues = [] } = sideBar;
|
|
56
|
+
const updateFacetVals = facetValues.map((item) => ({
|
|
57
|
+
...item,
|
|
58
|
+
isChecked: false,
|
|
59
|
+
}));
|
|
60
|
+
sideBar.facetValues = updateFacetVals;
|
|
51
61
|
}
|
|
52
62
|
/**
|
|
53
63
|
* set default value for slider - on clear all filter
|
|
@@ -83,6 +93,7 @@ const FacetFilterController = (props) => {
|
|
|
83
93
|
* Construct filter object
|
|
84
94
|
* 1. add facet values to facets
|
|
85
95
|
* 2. add 'name' key to each facet value
|
|
96
|
+
* 3. add '
|
|
86
97
|
*/
|
|
87
98
|
const addFacetValues = (facets) => {
|
|
88
99
|
const updateFacets = [];
|
|
@@ -90,19 +101,13 @@ const FacetFilterController = (props) => {
|
|
|
90
101
|
facets.forEach((facet) => {
|
|
91
102
|
const updateFacet = { ...facet, facetValues: [] };
|
|
92
103
|
const {
|
|
93
|
-
field,
|
|
94
104
|
ApiLowerBoundName,
|
|
95
105
|
ApiUpperBoundName,
|
|
96
106
|
apiForFiltering,
|
|
97
107
|
} = updateFacet;
|
|
98
108
|
if (data[apiForFiltering]) {
|
|
99
109
|
if (Array.isArray(data[apiForFiltering])) {
|
|
100
|
-
|
|
101
|
-
const addField = { ...item };
|
|
102
|
-
addField.name = item[field];
|
|
103
|
-
return addField;
|
|
104
|
-
});
|
|
105
|
-
updateFacet.facetValues = updateField;
|
|
110
|
+
updateFacet.facetValues = data[apiForFiltering];
|
|
106
111
|
}
|
|
107
112
|
/**
|
|
108
113
|
* add object to facet values
|
|
@@ -125,7 +130,7 @@ const FacetFilterController = (props) => {
|
|
|
125
130
|
* Generate facet sections state
|
|
126
131
|
*
|
|
127
132
|
*/
|
|
128
|
-
const displayFacets = facetsConfig.filter((facet) => facet.show)
|
|
133
|
+
const displayFacets = facetsConfig.filter((facet) => facet.show);
|
|
129
134
|
const facetStates = addFacetValues(displayFacets);
|
|
130
135
|
const updateState = updateFacetState(facetStates);
|
|
131
136
|
const facetSections = arrangeBySections(updateState);
|
package/src/FacetFilterView.js
CHANGED
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import {
|
|
5
5
|
Divider,
|
|
6
|
-
List,
|
|
7
6
|
withStyles,
|
|
8
7
|
} from '@material-ui/core';
|
|
9
8
|
import styles from './FacetFilterStyle';
|
|
10
9
|
import FacetSectionView from './components/section/FacetSectionView';
|
|
11
10
|
import FacetView from './components/facet/ReduxFacetView';
|
|
12
|
-
import FilterItems from './components/inputs/FilterItems';
|
|
13
11
|
|
|
14
12
|
const BentoFacetFilter = ({
|
|
15
13
|
sideBarSections,
|
|
@@ -33,13 +31,7 @@ const BentoFacetFilter = ({
|
|
|
33
31
|
<FacetView
|
|
34
32
|
facet={facet}
|
|
35
33
|
CustomView={CustomFacetView}
|
|
36
|
-
|
|
37
|
-
<List className={`List_${facet.label}`}>
|
|
38
|
-
<FilterItems
|
|
39
|
-
facet={facet}
|
|
40
|
-
/>
|
|
41
|
-
</List>
|
|
42
|
-
</FacetView>
|
|
34
|
+
/>
|
|
43
35
|
))}
|
|
44
36
|
</FacetSectionView>
|
|
45
37
|
</>
|
|
@@ -34,16 +34,21 @@ const CheckBoxView = ({
|
|
|
34
34
|
facet,
|
|
35
35
|
}) => {
|
|
36
36
|
const {
|
|
37
|
-
name,
|
|
38
|
-
subjects,
|
|
39
37
|
isChecked = false,
|
|
40
38
|
index,
|
|
41
39
|
section,
|
|
42
40
|
tooltip,
|
|
43
|
-
label,
|
|
44
41
|
} = checkboxItem;
|
|
42
|
+
const {
|
|
43
|
+
field = 'group',
|
|
44
|
+
count = 'subjects',
|
|
45
|
+
customCount = (text) => `(${text})`,
|
|
46
|
+
defaultValue = '',
|
|
47
|
+
} = facet;
|
|
48
|
+
|
|
45
49
|
const indexType = index % 2 === 0 ? 'Even' : 'Odd';
|
|
46
|
-
const checkedSection = `${section}`.toLowerCase().replace(
|
|
50
|
+
const checkedSection = `${section}`.toLowerCase().replace(/\ /g, '_');
|
|
51
|
+
const name = checkboxItem[field] || defaultValue || 'N/A';
|
|
47
52
|
const checkboxId = `checkbox_${facet.label}_${name}`;
|
|
48
53
|
const rippleRef = useRef(null);
|
|
49
54
|
|
|
@@ -61,7 +66,7 @@ const CheckBoxView = ({
|
|
|
61
66
|
|
|
62
67
|
const handleToggle = () => {
|
|
63
68
|
const toggleCheckBoxItem = {
|
|
64
|
-
name:
|
|
69
|
+
name: checkboxItem[field],
|
|
65
70
|
datafield: datafield,
|
|
66
71
|
isChecked: !isChecked,
|
|
67
72
|
};
|
|
@@ -76,9 +81,9 @@ const CheckBoxView = ({
|
|
|
76
81
|
[`${checkedSection}NameChecked`]: isChecked,
|
|
77
82
|
})}
|
|
78
83
|
>
|
|
79
|
-
{
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
<Typography className={classes.checkboxName}>
|
|
85
|
+
{name}
|
|
86
|
+
</Typography>
|
|
82
87
|
</Box>
|
|
83
88
|
);
|
|
84
89
|
|
|
@@ -97,7 +102,11 @@ const CheckBoxView = ({
|
|
|
97
102
|
>
|
|
98
103
|
<Checkbox
|
|
99
104
|
id={checkboxId}
|
|
100
|
-
icon={(
|
|
105
|
+
icon={(
|
|
106
|
+
<CheckBoxBlankIcon
|
|
107
|
+
style={{ fontSize: 18 }}
|
|
108
|
+
className={checkedSection}
|
|
109
|
+
/>
|
|
101
110
|
)}
|
|
102
111
|
inputProps={{ 'aria-label': 'checkbox', tabIndex: -1, 'aria-hidden': true }}
|
|
103
112
|
checked={isChecked}
|
|
@@ -117,7 +126,7 @@ const CheckBoxView = ({
|
|
|
117
126
|
{ tooltip ? (
|
|
118
127
|
<Tooltip id={datafield} title={tooltip}>
|
|
119
128
|
<div className={datafield}>
|
|
120
|
-
|
|
129
|
+
{name}
|
|
121
130
|
</div>
|
|
122
131
|
</Tooltip>
|
|
123
132
|
) : (
|
|
@@ -130,7 +139,7 @@ const CheckBoxView = ({
|
|
|
130
139
|
[`${checkedSection}SubjectChecked`]: isChecked,
|
|
131
140
|
})}
|
|
132
141
|
>
|
|
133
|
-
{
|
|
142
|
+
{customCount(checkboxItem[count] || 0)}
|
|
134
143
|
</Typography>
|
|
135
144
|
<TouchRipple ref={rippleRef} center />
|
|
136
145
|
</ListItem>
|
|
@@ -14,7 +14,15 @@ const SliderView = ({
|
|
|
14
14
|
onSliderToggle,
|
|
15
15
|
filterState,
|
|
16
16
|
}) => {
|
|
17
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
minLowerBound,
|
|
19
|
+
maxUpperBound,
|
|
20
|
+
quantifier,
|
|
21
|
+
datafield,
|
|
22
|
+
facetValues,
|
|
23
|
+
CustomLowerUpperBound,
|
|
24
|
+
CustomSliderValue,
|
|
25
|
+
} = facet;
|
|
18
26
|
const lowerBoundValue = facetValues[0];
|
|
19
27
|
const upperBoundValue = facetValues[1];
|
|
20
28
|
|
|
@@ -99,24 +107,26 @@ const SliderView = ({
|
|
|
99
107
|
}}
|
|
100
108
|
/>
|
|
101
109
|
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
{typeof CustomLowerUpperBound === 'function' ? (
|
|
111
|
+
CustomLowerUpperBound({ minLowerBound, maxUpperBound, classes })
|
|
112
|
+
) : (
|
|
113
|
+
<Box className={classes.lowerUpperBound}>
|
|
114
|
+
<Typography className={classes.lowerBound}>
|
|
115
|
+
{minLowerBound}
|
|
116
|
+
</Typography>
|
|
117
|
+
<Typography className={classes.upperBound}>
|
|
118
|
+
{maxUpperBound}
|
|
119
|
+
</Typography>
|
|
120
|
+
</Box>
|
|
121
|
+
)}
|
|
110
122
|
</div>
|
|
111
123
|
{/* Change to red if invalid range */}
|
|
112
|
-
{
|
|
113
|
-
(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
: classes.invalidSliderText}
|
|
119
|
-
>
|
|
124
|
+
{typeof CustomSliderValue === 'function' ? (
|
|
125
|
+
CustomSliderValue({
|
|
126
|
+
sliderValue, minLowerBound, maxUpperBound, isValid, quantifier, classes })
|
|
127
|
+
) : (
|
|
128
|
+
(sliderValue[0] > minLowerBound || sliderValue[1] < maxUpperBound) && (
|
|
129
|
+
<Typography className={isValid() ? classes.sliderText : classes.invalidSliderText}>
|
|
120
130
|
{sliderValue[0]}
|
|
121
131
|
{' - '}
|
|
122
132
|
{sliderValue[1]}
|
|
@@ -124,7 +134,7 @@ const SliderView = ({
|
|
|
124
134
|
{quantifier}
|
|
125
135
|
</Typography>
|
|
126
136
|
)
|
|
127
|
-
}
|
|
137
|
+
)}
|
|
128
138
|
</>
|
|
129
139
|
);
|
|
130
140
|
};
|
package/src/utils/Sort.js
CHANGED
|
@@ -37,22 +37,28 @@ export const getNumberArray = (range) => {
|
|
|
37
37
|
* @param {array} checkboxData
|
|
38
38
|
* @return {array}
|
|
39
39
|
*/
|
|
40
|
-
export const sortBySection = ({
|
|
40
|
+
export const sortBySection = ({
|
|
41
|
+
facetValues,
|
|
42
|
+
sort_type,
|
|
43
|
+
sortBy,
|
|
44
|
+
field,
|
|
45
|
+
count = 'subjects',
|
|
46
|
+
}) => {
|
|
41
47
|
const sortfacetValues = [...facetValues];
|
|
42
48
|
if (!sortfacetValues) {
|
|
43
49
|
return facetValues;
|
|
44
50
|
}
|
|
45
51
|
if (sortBy === sortType.NUMERIC) {
|
|
46
|
-
sortfacetValues.sort((a, b) => b
|
|
52
|
+
sortfacetValues.sort((a, b) => b[count] - a[count]);
|
|
47
53
|
} else {
|
|
48
|
-
sortfacetValues.sort(((a, b) => (lowerCaseString(a
|
|
49
|
-
|| -(lowerCaseString(a
|
|
54
|
+
sortfacetValues.sort(((a, b) => (lowerCaseString(a[field]) > lowerCaseString(b[field])
|
|
55
|
+
|| -(lowerCaseString(a[field]) < lowerCaseString(b[field])))));
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
if (sort_type === sortType.CUSTOM_NUMBER && sortBy !== sortType.NUMERIC) {
|
|
53
59
|
sortfacetValues.sort((a, b) => {
|
|
54
|
-
const aNumbs = getNumberArray(a
|
|
55
|
-
const bNumbs = getNumberArray(b
|
|
60
|
+
const aNumbs = getNumberArray(a[field]);
|
|
61
|
+
const bNumbs = getNumberArray(b[field]);
|
|
56
62
|
const aNumb = Number(aNumbs[0]);
|
|
57
63
|
const bNumb = Number(bNumbs[0]);
|
|
58
64
|
return (aNumbs.length === bNumbs.length) ? aNumb > bNumb : -(aNumb <= bNumb);
|
|
@@ -60,8 +66,8 @@ export const sortBySection = ({ facetValues, sort_type, sortBy }) => {
|
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
if (sort_type === sortType.RANGE && sortBy !== sortType.NUMERIC) {
|
|
63
|
-
sortfacetValues.sort(((a, b) => (startIndex(a
|
|
64
|
-
|| -(startIndex(a
|
|
69
|
+
sortfacetValues.sort(((a, b) => (startIndex(a[field]) > startIndex(b[field])
|
|
70
|
+
|| -(startIndex(a[field]) < startIndex(b[field])))));
|
|
65
71
|
}
|
|
66
72
|
/**
|
|
67
73
|
* Display checked item always on top
|