diff --git a/packages/reactivecore b/packages/reactivecore index 484b67bcd4..14ad31d77f 160000 --- a/packages/reactivecore +++ b/packages/reactivecore @@ -1 +1 @@ -Subproject commit 484b67bcd4b1befdc3cfc9cbecfa336f2d2d5e6c +Subproject commit 14ad31d77faf290cbdabf7dcf725c6085b1f7246 diff --git a/packages/web/src/components/range/RatingsFilter.js b/packages/web/src/components/range/RatingsFilter.js index b19ac55994..a0360b4db3 100644 --- a/packages/web/src/components/range/RatingsFilter.js +++ b/packages/web/src/components/range/RatingsFilter.js @@ -55,7 +55,12 @@ class RatingsFilter extends Component { const hasMounted = false; if (currentValue) { - this.setValue(currentValue, props, hasMounted); + this.setValue({ + value: currentValue, + props, + hasMounted, + includeUnrated: this.getIncludeUnratedFromData(currentValue), + }); } } @@ -70,18 +75,24 @@ class RatingsFilter extends Component { }); if (!isEqual(this.props.value, prevProps.value)) { - this.setValue(this.props.value); + this.setValue({ value: this.props.value }); } else if ( !isEqual(this.state.currentValue, this.props.selectedValue) && !isEqual(this.props.selectedValue, prevProps.selectedValue) ) { const { value, onChange } = this.props; if (value === undefined) { - this.setValue(this.props.selectedValue || null); + this.setValue({ + value: this.props.selectedValue || null, + includeUnrated: this.getIncludeUnratedFromData(this.props.selectedValue), + }); } else if (onChange) { onChange(this.props.selectedValue || null); } else { - this.setValue(this.state.currentValue); + this.setValue({ + value: this.state.currentValue, + includeUnrated: this.getIncludeUnratedFromData(this.state.currentValue), + }); } } } @@ -96,16 +107,24 @@ class RatingsFilter extends Component { } } + getIncludeUnratedFromData = (range) => { + if (!this.props.data || !range) return false; + const dataObj = this.props.data.find( + data => data.start === range[0] && data.end === range[1], + ); + return dataObj && dataObj.includeUnrated; + }; + // parses range label to get start and end static parseValue = (value) => { if (Array.isArray(value)) return value; return value ? [value.start, value.end] : null; }; - static defaultQuery = (value, props) => { + static defaultQuery = (value, props, includeNullValues = false) => { let query = null; if (value) { - query = { + const rangeQuery = { range: { [props.dataField]: { gte: value[0], @@ -114,6 +133,14 @@ class RatingsFilter extends Component { }, }, }; + if (includeNullValues) { + const nullQuery = RatingsFilter.getNullValuesQuery(props.dataField); + query = { + bool: { + should: [rangeQuery, nullQuery], + }, + }; + } else query = rangeQuery; } if (query && props.nestedField) { @@ -130,7 +157,19 @@ class RatingsFilter extends Component { return query; }; - setValue = (value, props = this.props, hasMounted = true) => { + static getNullValuesQuery = fieldName => ({ + bool: { + must_not: { + exists: { + field: fieldName, + }, + }, + }, + }); + + setValue = ({ + value, props = this.props, hasMounted = true, includeUnrated = false, + }) => { // ignore state updates when component is locked if (props.beforeValueChange && this.locked) { return; @@ -139,7 +178,7 @@ class RatingsFilter extends Component { this.locked = true; const performUpdate = () => { const handleUpdates = () => { - this.updateQuery(value, props); + this.updateQuery(value, props, includeUnrated); this.locked = false; if (props.onValueChange) props.onValueChange(value); }; @@ -158,9 +197,9 @@ class RatingsFilter extends Component { checkValueChange(props.componentId, value, props.beforeValueChange, performUpdate); }; - updateQuery = (value, props) => { + updateQuery = (value, props, includeNullValues) => { const { customQuery } = props; - let query = RatingsFilter.defaultQuery(value, props); + let query = RatingsFilter.defaultQuery(value, props, includeNullValues); let customQueryOptions; if (customQuery) { ({ query } = customQuery(value, props) || {}); @@ -179,11 +218,10 @@ class RatingsFilter extends Component { }); }; - handleClick = (selectedItem) => { + handleClick = (selectedItem, params) => { const { value, onChange } = this.props; - if (value === undefined) { - this.setValue(selectedItem); + this.setValue({ value: selectedItem, includeUnrated: params.includeUnrated }); } else if (onChange) { onChange(selectedItem); } @@ -198,29 +236,34 @@ class RatingsFilter extends Component { )} );