@blaze-cms/react-page-builder 0.124.0 → 0.124.1-alpha.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/CHANGELOG.md +33 -0
- package/lib/components/SearchFilter/SearchFilter/SearchFilter.js +2 -1
- package/lib/components/SearchFilter/SearchFilter/SearchFilter.js.map +1 -1
- package/lib/components/SearchFilter/SearchFilterContainer.js +22 -5
- package/lib/components/SearchFilter/SearchFilterContainer.js.map +1 -1
- package/lib/components/SearchFilter/components/Range.js +24 -8
- package/lib/components/SearchFilter/components/Range.js.map +1 -1
- package/lib/components/SearchFilter/helpers/build-filters-query.js +46 -5
- package/lib/components/SearchFilter/helpers/build-filters-query.js.map +1 -1
- package/lib/components/SearchFilter/helpers/build-raw-query-stringified.js +16 -10
- package/lib/components/SearchFilter/helpers/build-raw-query-stringified.js.map +1 -1
- package/lib/components/SearchFilter/helpers/get-initial-filter-values.js +6 -6
- package/lib/components/SearchFilter/helpers/get-initial-filter-values.js.map +1 -1
- package/lib/components/SearchFilter/helpers/get-range-value.js +4 -2
- package/lib/components/SearchFilter/helpers/get-range-value.js.map +1 -1
- package/lib-es/components/SearchFilter/SearchFilter/SearchFilter.js +2 -1
- package/lib-es/components/SearchFilter/SearchFilter/SearchFilter.js.map +1 -1
- package/lib-es/components/SearchFilter/SearchFilterContainer.js +17 -4
- package/lib-es/components/SearchFilter/SearchFilterContainer.js.map +1 -1
- package/lib-es/components/SearchFilter/components/Range.js +20 -8
- package/lib-es/components/SearchFilter/components/Range.js.map +1 -1
- package/lib-es/components/SearchFilter/helpers/build-filters-query.js +43 -5
- package/lib-es/components/SearchFilter/helpers/build-filters-query.js.map +1 -1
- package/lib-es/components/SearchFilter/helpers/build-raw-query-stringified.js +15 -10
- package/lib-es/components/SearchFilter/helpers/build-raw-query-stringified.js.map +1 -1
- package/lib-es/components/SearchFilter/helpers/get-initial-filter-values.js +5 -4
- package/lib-es/components/SearchFilter/helpers/get-initial-filter-values.js.map +1 -1
- package/lib-es/components/SearchFilter/helpers/get-range-value.js +2 -2
- package/lib-es/components/SearchFilter/helpers/get-range-value.js.map +1 -1
- package/package.json +2 -2
- package/src/components/SearchFilter/SearchFilter/SearchFilter.js +2 -1
- package/src/components/SearchFilter/SearchFilterContainer.js +21 -4
- package/src/components/SearchFilter/components/Range.js +19 -16
- package/src/components/SearchFilter/helpers/build-filters-query.js +26 -5
- package/src/components/SearchFilter/helpers/build-raw-query-stringified.js +17 -12
- package/src/components/SearchFilter/helpers/get-initial-filter-values.js +5 -2
- package/src/components/SearchFilter/helpers/get-range-value.js +2 -2
- package/tests/unit/src/components/SearchFilter/components/Range.test.js +24 -0
- package/tests/unit/src/components/SearchFilter/components/__snapshots__/Range.test.js.snap +3 -3
- package/tests/unit/src/components/SearchFilter/helpers/get-initial-filter-values.test.js +8 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useRef, useReducer } from 'react';
|
|
1
|
+
import React, { useState, useRef, useReducer, useEffect } from 'react';
|
|
2
2
|
import { useRouter } from 'next/router';
|
|
3
3
|
import { useQuery } from '@apollo/client';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
@@ -25,7 +25,7 @@ const reducer = (state, action) => {
|
|
|
25
25
|
case 'resetSearch':
|
|
26
26
|
return { ...state, shouldSearch: false };
|
|
27
27
|
case 'reset':
|
|
28
|
-
return { ...newValues, shouldSearch };
|
|
28
|
+
return { ...newValues, shouldSearch: false };
|
|
29
29
|
default:
|
|
30
30
|
throw new Error();
|
|
31
31
|
}
|
|
@@ -48,15 +48,24 @@ const SearchFilterContainer = ({
|
|
|
48
48
|
const searchFilterRef = useRef(null);
|
|
49
49
|
const [key, setKey] = useState(`filter-${name}`);
|
|
50
50
|
const [displaySearchFilter, setDisplaySearchFilter] = useState(false);
|
|
51
|
+
const [urlPath, setUrlPath] = useState(asPath); // used as asPath can take too long to update
|
|
51
52
|
const {
|
|
52
53
|
url: currentUrl,
|
|
53
54
|
query: { sort, sortby },
|
|
54
55
|
query
|
|
55
|
-
} = parseUrl(
|
|
56
|
+
} = parseUrl(urlPath);
|
|
56
57
|
const [filterValues, dispatch] = useReducer(
|
|
57
58
|
reducer,
|
|
58
59
|
getInitialFilterValues(null, filters, query)
|
|
59
60
|
);
|
|
61
|
+
|
|
62
|
+
useEffect(
|
|
63
|
+
() => {
|
|
64
|
+
if (asPath) setUrlPath(asPath);
|
|
65
|
+
},
|
|
66
|
+
[asPath]
|
|
67
|
+
);
|
|
68
|
+
|
|
60
69
|
const hasUrl = !!url;
|
|
61
70
|
|
|
62
71
|
const sortValues = sort && sortby ? stringify({ sort, sortby }) : '';
|
|
@@ -77,7 +86,13 @@ const SearchFilterContainer = ({
|
|
|
77
86
|
const { docType } = getEntityData(entity);
|
|
78
87
|
|
|
79
88
|
const filtersQuery = shouldAddFilters
|
|
80
|
-
? buildFiltersQuery(
|
|
89
|
+
? buildFiltersQuery({
|
|
90
|
+
query: filterValues,
|
|
91
|
+
filterBy,
|
|
92
|
+
filterByProperty,
|
|
93
|
+
rangeValues,
|
|
94
|
+
queryKeys: Object.keys(query)
|
|
95
|
+
})
|
|
81
96
|
: [];
|
|
82
97
|
|
|
83
98
|
const rawQueryStringified = buildRawQueryStringified(
|
|
@@ -108,12 +123,14 @@ const SearchFilterContainer = ({
|
|
|
108
123
|
|
|
109
124
|
if (!newQuery) {
|
|
110
125
|
scrollToFirstList();
|
|
126
|
+
setUrlPath(baseQuery);
|
|
111
127
|
return router.push('/Resolver', baseQuery, { shallow: !hasUrl, scroll: false }).then(() => {
|
|
112
128
|
setKey(`filter-${name}:${Date.now()}`); // remove after range component update
|
|
113
129
|
});
|
|
114
130
|
}
|
|
115
131
|
const newUrl = buildNewQuery(url, currentUrl, newQuery, sortValues);
|
|
116
132
|
scrollToFirstList();
|
|
133
|
+
setUrlPath(newUrl);
|
|
117
134
|
return router.push('/Resolver', newUrl, { shallow: !hasUrl, scroll: false });
|
|
118
135
|
};
|
|
119
136
|
|
|
@@ -7,7 +7,7 @@ import Select from '@blaze-react/select';
|
|
|
7
7
|
import { parseUrl } from 'query-string';
|
|
8
8
|
import { useGetSingleEntitySchema } from '../../../hooks';
|
|
9
9
|
import { withTitle } from '../../../HOC';
|
|
10
|
-
import { getSelectOptions, getIntersectedProp, getRangeValue } from '../helpers';
|
|
10
|
+
import { getSelectOptions, getIntersectedProp, getRangeValue, calculateMinMax } from '../helpers';
|
|
11
11
|
import { decodeValue } from '../helpers/decode-encode';
|
|
12
12
|
|
|
13
13
|
const Range = ({
|
|
@@ -15,6 +15,7 @@ const Range = ({
|
|
|
15
15
|
label,
|
|
16
16
|
entity,
|
|
17
17
|
propsToDisplay,
|
|
18
|
+
dataAggregations,
|
|
18
19
|
updateFilterValues,
|
|
19
20
|
filterValues,
|
|
20
21
|
shouldSearch
|
|
@@ -37,8 +38,11 @@ const Range = ({
|
|
|
37
38
|
if (loading || !rangeOption || !rangeValue) return '';
|
|
38
39
|
|
|
39
40
|
const options = getSelectOptions(getEntitySchema, propsToDisplay);
|
|
40
|
-
|
|
41
|
-
const
|
|
41
|
+
// get range from aggregations so it updates
|
|
42
|
+
const { min, max } = calculateMinMax(dataAggregations[rangeOption], rangeInterval);
|
|
43
|
+
const minValue = rangeValue.minValue < min ? min : rangeValue.minValue;
|
|
44
|
+
const maxValue = rangeValue.maxValue > max ? max : rangeValue.maxValue;
|
|
45
|
+
const valueToUse = { ...rangeValue, min, max, minValue, maxValue };
|
|
42
46
|
|
|
43
47
|
const handleChange = debounce((option, value) => {
|
|
44
48
|
updateFilterValues({ [option]: { ...value, selectedOption: rangeOption } }, shouldSearch);
|
|
@@ -67,18 +71,16 @@ const Range = ({
|
|
|
67
71
|
/>
|
|
68
72
|
</>
|
|
69
73
|
)}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
/>
|
|
81
|
-
)}
|
|
74
|
+
<RangeFilter
|
|
75
|
+
key={`${rangeOption}-${minValue}-${maxValue}`}
|
|
76
|
+
name={rangeOption}
|
|
77
|
+
label={hasMultipleOptions ? '' : label}
|
|
78
|
+
value={valueToUse}
|
|
79
|
+
id={rangeOption}
|
|
80
|
+
onChange={({ value }) => {
|
|
81
|
+
handleChange(rangeOption, value);
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
82
84
|
</>
|
|
83
85
|
);
|
|
84
86
|
};
|
|
@@ -90,7 +92,8 @@ Range.propTypes = {
|
|
|
90
92
|
updateFilterValues: PropTypes.func.isRequired,
|
|
91
93
|
shouldSearch: PropTypes.bool,
|
|
92
94
|
rangeInterval: PropTypes.number,
|
|
93
|
-
label: PropTypes.string
|
|
95
|
+
label: PropTypes.string,
|
|
96
|
+
dataAggregations: PropTypes.object.isRequired
|
|
94
97
|
};
|
|
95
98
|
|
|
96
99
|
Range.defaultProps = {
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
const
|
|
1
|
+
const QUERY_KEYS_TO_IGNORE = ['dataNotSet', 'shouldSearch', 'search_term'];
|
|
2
|
+
|
|
3
|
+
const builFilterObject = ({ queryKey, value, filters, isRange, isInQuery }) => {
|
|
4
|
+
if (isRange) {
|
|
5
|
+
// don't add to query if value matches range values
|
|
6
|
+
if (isInQuery || (value.min !== value.minValue && value.max !== value.maxValue)) {
|
|
7
|
+
filters.push({
|
|
8
|
+
range: {
|
|
9
|
+
[queryKey]: {
|
|
10
|
+
gte: Number(value.minValue),
|
|
11
|
+
lte: Number(value.maxValue)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const key = isRange ? queryKey : `${queryKey}.keyword`;
|
|
20
|
+
|
|
2
21
|
const isArray = Array.isArray(value);
|
|
3
22
|
if (!isArray) {
|
|
4
23
|
const singleFilterObj = { match: { [key]: value } };
|
|
@@ -10,14 +29,16 @@ const builFilterObject = (key, value, filters) => {
|
|
|
10
29
|
filters.push({ match: { [key]: filterValue } });
|
|
11
30
|
});
|
|
12
31
|
};
|
|
13
|
-
const buildFiltersQuery = (query, filterBy, filterByProperty) => {
|
|
32
|
+
const buildFiltersQuery = ({ query, filterBy, filterByProperty, rangeValues, queryKeys }) => {
|
|
14
33
|
const mustFilters = [];
|
|
15
34
|
Object.keys(query).forEach(queryKey => {
|
|
16
|
-
if (queryKey
|
|
35
|
+
if (QUERY_KEYS_TO_IGNORE.includes(queryKey)) return;
|
|
17
36
|
if (!queryKey || !query[queryKey]) return;
|
|
18
37
|
const queryValue = query[queryKey];
|
|
19
|
-
|
|
20
|
-
|
|
38
|
+
|
|
39
|
+
const isRange = rangeValues.includes(queryKey);
|
|
40
|
+
const isInQuery = queryKeys.includes(queryKey);
|
|
41
|
+
builFilterObject({ queryKey, value: queryValue, filters: mustFilters, isRange, isInQuery });
|
|
21
42
|
});
|
|
22
43
|
|
|
23
44
|
if (filterByProperty && filterByProperty.length) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { KEYWORD, SIZE } from '../constants';
|
|
2
2
|
|
|
3
|
-
const buildRawQueryStringified = (checkboxSelectValues, rangeValues, entity, mustFilters) => {
|
|
3
|
+
const buildRawQueryStringified = (checkboxSelectValues, rangeValues, entity, mustFilters = []) => {
|
|
4
4
|
if (!checkboxSelectValues.length && !rangeValues.length) return '';
|
|
5
5
|
|
|
6
6
|
const aggs = {};
|
|
@@ -22,23 +22,28 @@ const buildRawQueryStringified = (checkboxSelectValues, rangeValues, entity, mus
|
|
|
22
22
|
};
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
+
const boolFilter = {
|
|
26
|
+
should: [
|
|
27
|
+
{
|
|
28
|
+
match: {
|
|
29
|
+
docType: entity
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
minimum_should_match: 1
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
if (mustFilters.length) {
|
|
37
|
+
boolFilter.must = mustFilters;
|
|
38
|
+
}
|
|
39
|
+
|
|
25
40
|
return JSON.stringify({
|
|
26
41
|
aggs,
|
|
27
42
|
size: 0,
|
|
28
43
|
query: {
|
|
29
44
|
bool: {
|
|
30
45
|
filter: {
|
|
31
|
-
bool:
|
|
32
|
-
should: [
|
|
33
|
-
{
|
|
34
|
-
match: {
|
|
35
|
-
docType: entity
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
],
|
|
39
|
-
must: mustFilters,
|
|
40
|
-
minimum_should_match: 1
|
|
41
|
-
}
|
|
46
|
+
bool: boolFilter
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
}
|
|
@@ -6,8 +6,11 @@ const getInitialFilterValues = (filterData, filters, query) => {
|
|
|
6
6
|
filterValues[SEARCH_TERM] = query[SEARCH_TERM] || '';
|
|
7
7
|
|
|
8
8
|
if (!filterData) {
|
|
9
|
-
filters.forEach(
|
|
10
|
-
|
|
9
|
+
filters.forEach(filterProps => {
|
|
10
|
+
const {
|
|
11
|
+
propsToDisplay: [key]
|
|
12
|
+
} = filterProps;
|
|
13
|
+
filterValues[key] = query[key] ? getFilterValueFromQuery(key, filterProps, {}, query) : null;
|
|
11
14
|
});
|
|
12
15
|
filterValues.dataNotSet = true;
|
|
13
16
|
return filterValues;
|
|
@@ -11,8 +11,8 @@ const getRangeValue = (rawQueryProp, rangeInterval, _min, _max) => {
|
|
|
11
11
|
const updatedMaxValue = Number(queryParamMax);
|
|
12
12
|
|
|
13
13
|
return {
|
|
14
|
-
min,
|
|
15
|
-
max,
|
|
14
|
+
min: Number.isNaN(min) ? updatedMinValue : min,
|
|
15
|
+
max: Number.isNaN(max) ? updatedMaxValue : max,
|
|
16
16
|
step: rangeInterval,
|
|
17
17
|
maxValue: updatedMaxValue,
|
|
18
18
|
minValue: updatedMinValue
|
|
@@ -9,6 +9,12 @@ jest.mock('next/router', () => ({
|
|
|
9
9
|
const getMockedProps = overrides => ({
|
|
10
10
|
rangeInterval: 100,
|
|
11
11
|
label: 'GLabel',
|
|
12
|
+
dataAggregations: {
|
|
13
|
+
name: {
|
|
14
|
+
min: 0,
|
|
15
|
+
max: 6600
|
|
16
|
+
}
|
|
17
|
+
},
|
|
12
18
|
filterValues: {
|
|
13
19
|
name: {
|
|
14
20
|
max: 6600,
|
|
@@ -41,6 +47,12 @@ describe('Range component', () => {
|
|
|
41
47
|
|
|
42
48
|
it('should match snapshot large values formatted correctly', async () => {
|
|
43
49
|
const mockedProps = getMockedProps({
|
|
50
|
+
dataAggregations: {
|
|
51
|
+
name: {
|
|
52
|
+
min: 9995,
|
|
53
|
+
max: 10000
|
|
54
|
+
}
|
|
55
|
+
},
|
|
44
56
|
filterValues: {
|
|
45
57
|
name: {
|
|
46
58
|
min: 9999,
|
|
@@ -59,6 +71,12 @@ describe('Range component', () => {
|
|
|
59
71
|
|
|
60
72
|
it('should match snapshot with interval and rounded min & max values', async () => {
|
|
61
73
|
const mockedProps = getMockedProps({
|
|
74
|
+
dataAggregations: {
|
|
75
|
+
name: {
|
|
76
|
+
min: 15.5,
|
|
77
|
+
max: 49.5
|
|
78
|
+
}
|
|
79
|
+
},
|
|
62
80
|
filterValues: {
|
|
63
81
|
name: {
|
|
64
82
|
min: 15.5,
|
|
@@ -77,6 +95,12 @@ describe('Range component', () => {
|
|
|
77
95
|
|
|
78
96
|
it('should match snapshot with adjusted min & max values based on interval', async () => {
|
|
79
97
|
const mockedProps = getMockedProps({
|
|
98
|
+
dataAggregations: {
|
|
99
|
+
name: {
|
|
100
|
+
min: 6,
|
|
101
|
+
max: 8
|
|
102
|
+
}
|
|
103
|
+
},
|
|
80
104
|
filterValues: {
|
|
81
105
|
name: {
|
|
82
106
|
min: 6,
|
|
@@ -76,7 +76,7 @@ Array [
|
|
|
76
76
|
id="nameRange"
|
|
77
77
|
max={10000}
|
|
78
78
|
max-value={10000}
|
|
79
|
-
min={
|
|
79
|
+
min={9995}
|
|
80
80
|
min-value={9999}
|
|
81
81
|
step={1}
|
|
82
82
|
>
|
|
@@ -224,9 +224,9 @@ Array [
|
|
|
224
224
|
<div
|
|
225
225
|
className="range__filter name"
|
|
226
226
|
id="nameRange"
|
|
227
|
-
max={
|
|
227
|
+
max={50}
|
|
228
228
|
max-value={49.5}
|
|
229
|
-
min={15
|
|
229
|
+
min={15}
|
|
230
230
|
min-value={15.5}
|
|
231
231
|
step={1}
|
|
232
232
|
>
|
|
@@ -36,8 +36,14 @@ describe('getInitialFilterValues helper function', () => {
|
|
|
36
36
|
expect(withNoData).toEqual({
|
|
37
37
|
dataNotSet: true,
|
|
38
38
|
search_term: query[SEARCH_TERM],
|
|
39
|
-
rangeFilter:
|
|
40
|
-
|
|
39
|
+
rangeFilter: {
|
|
40
|
+
max: 8,
|
|
41
|
+
maxValue: 8,
|
|
42
|
+
min: 7,
|
|
43
|
+
minValue: 7,
|
|
44
|
+
step: 1
|
|
45
|
+
},
|
|
46
|
+
checkboxFilter: query.checkboxFilter,
|
|
41
47
|
emptySelect: null
|
|
42
48
|
});
|
|
43
49
|
});
|