diff --git a/src/controllers/FacetQueryController.ts b/src/controllers/FacetQueryController.ts index b7d8623ea6..f9a51c1ae4 100644 --- a/src/controllers/FacetQueryController.ts +++ b/src/controllers/FacetQueryController.ts @@ -230,7 +230,7 @@ export class FacetQueryController { const additionalFilter = this.facet.options.additionalFilter ? this.facet.options.additionalFilter : ''; let queryOverrideObject: IQueryBuilderExpression = undefined; - if (this.facet.options.useAnd) { + if (this.facet.options.useAnd || (this.facet.options.isMultiValueField && this.facet.values.hasSelectedAndExcludedValues())) { if (Utils.isNonEmptyString(additionalFilter)) { queryOverrideObject = queryBuilder.computeCompleteExpressionParts(); if (Utils.isEmptyString(queryOverrideObject.basic)) { diff --git a/src/ui/Facet/Facet.ts b/src/ui/Facet/Facet.ts index 1490dd6371..1c5acea1bc 100644 --- a/src/ui/Facet/Facet.ts +++ b/src/ui/Facet/Facet.ts @@ -1219,9 +1219,15 @@ export class Facet extends Component { this.updateVisibilityBasedOnDependsOn(); const groupByResult = data.results.groupByResults[this.facetQueryController.lastGroupByRequestIndex]; this.facetQueryController.lastGroupByResult = groupByResult; + // Two corner case to handle regarding the "sticky" aspect of facets : + // 1) The group by is empty (so there is nothing to "sticky") + // 2) There is only one value displayed currently, so there is nothing to "sticky" either if (!groupByResult) { this.keepDisplayedValuesNextTime = false; } + if (this.values.getAll().length == 1) { + this.keepDisplayedValuesNextTime = false; + } this.processNewGroupByResults(groupByResult); } @@ -1378,7 +1384,7 @@ export class Facet extends Component { }) ); } else if (this.values.getSelected().length > 0 && !this.options.useAnd) { - this.values.updateDeltaWithFilteredFacetValues(new FacetValues()); + this.values.updateDeltaWithFilteredFacetValues(new FacetValues(), this.options.isMultiValueField); } if (!this.values.hasSelectedOrExcludedValues() || this.options.useAnd || !this.options.isMultiValueField) { this.rebuildValueElements(); @@ -1865,16 +1871,13 @@ export class Facet extends Component { this.triggerUpdateDeltaQuery( _.filter(this.values.getAll(), (facetValue: FacetValue) => !facetValue.selected && !facetValue.excluded) ); + } else if (this.values.hasSelectedOrExcludedValues() && !this.options.useAnd) { + this.values.updateDeltaWithFilteredFacetValues(new FacetValues(), this.options.isMultiValueField); + this.hideWaitingAnimation(); } else { - if (this.values.hasSelectedOrExcludedValues() && !this.options.useAnd) { - this.values.updateDeltaWithFilteredFacetValues(new FacetValues()); - this.hideWaitingAnimation(); - } else { - this.hideWaitingAnimation(); - } - - this.rebuildValueElements(); + this.hideWaitingAnimation(); } + this.rebuildValueElements(); }) .catch(() => this.hideWaitingAnimation()); } @@ -1890,7 +1893,8 @@ export class Facet extends Component { } }); }); - this.values.updateDeltaWithFilteredFacetValues(values); + this.values.updateDeltaWithFilteredFacetValues(values, this.options.isMultiValueField); + this.cleanupDeltaValuesForMultiValueField(); this.rebuildValueElements(); this.hideWaitingAnimation(); }); @@ -1928,6 +1932,19 @@ export class Facet extends Component { return Math.max(minValue, this.options.numberOfValues); } + private cleanupDeltaValuesForMultiValueField() { + // On a multi value field, it's possible to end up in a scenario where many of the current values are empty + // Crop those out, and adjust the nbAvailable values for the "search" and "show more"; + if (this.options.isMultiValueField) { + _.each(this.values.getAll(), v => { + if (v.occurrences == 0) { + this.values.remove(v.value); + } + }); + this.nbAvailableValues = this.values.getAll().length; + } + } + private updateVisibilityBasedOnDependsOn() { if (Utils.isNonEmptyString(this.options.dependsOn)) { $$(this.element).toggleClass( diff --git a/src/ui/Facet/FacetValues.ts b/src/ui/Facet/FacetValues.ts index 4e8bdcbc8f..6cb29e299f 100644 --- a/src/ui/Facet/FacetValues.ts +++ b/src/ui/Facet/FacetValues.ts @@ -184,6 +184,18 @@ export class FacetValues { return this.getSelected().length != 0 || this.getExcluded().length != 0; } + hasSelectedAndExcludedValues(): boolean { + return this.getSelected().length != 0 && this.getExcluded().length != 0; + } + + hasOnlyExcludedValues(): boolean { + return this.getSelected().length == 0 && this.getExcluded().length != 0; + } + + hasOnlySelectedValues(): boolean { + return this.getSelected().length != 0 && this.getExcluded().length == 0; + } + reset() { _.each(this.values, (elem: FacetValue) => elem.reset()); } @@ -196,8 +208,8 @@ export class FacetValues { if (Utils.exists(myValue)) { myValue.selected = true; } else { - if (otherValue.occurrences) { - this.values.push(otherValue.clone()) + if (otherValue.occurrences && !otherValue.excluded) { + this.values.push(otherValue.clone()); } else { this.values.push(otherValue.cloneWithZeroOccurrences()); } @@ -234,19 +246,31 @@ export class FacetValues { }); } - updateDeltaWithFilteredFacetValues(filtered: FacetValues) { + updateDeltaWithFilteredFacetValues(filtered: FacetValues, isMultiValueField: boolean) { Assert.exists(filtered); _.each(this.values, (unfilteredValue: FacetValue) => { var filteredValue = filtered.get(unfilteredValue.value); unfilteredValue.waitingForDelta = false; if (Utils.exists(filteredValue)) { if (unfilteredValue.occurrences - filteredValue.occurrences > 0) { - unfilteredValue.delta = unfilteredValue.occurrences - filteredValue.occurrences; + // When there are only exclusion in the facet, there should be no "delta" + // The number of value for each facet will be what is selected, no addition. + if (this.hasOnlyExcludedValues()) { + unfilteredValue.delta = null; + unfilteredValue.occurrences = filteredValue.occurrences; + } else { + unfilteredValue.delta = unfilteredValue.occurrences - filteredValue.occurrences; + } } else { unfilteredValue.delta = null; } } else if (!unfilteredValue.selected && !unfilteredValue.excluded) { - unfilteredValue.delta = unfilteredValue.occurrences; + if (isMultiValueField && filtered.values.length == 0) { + unfilteredValue.delta = null; + unfilteredValue.occurrences = 0; + } else { + unfilteredValue.delta = unfilteredValue.occurrences; + } } }); }