diff --git a/lib/content-services/search/components/search-filter/search-filter.component.html b/lib/content-services/search/components/search-filter/search-filter.component.html index 750b100038..89f3c98083 100644 --- a/lib/content-services/search/components/search-filter/search-filter.component.html +++ b/lib/content-services/search/components/search-filter/search-filter.component.html @@ -95,7 +95,7 @@ [checked]="bucket.checked" [attr.data-automation-id]="'checkbox-'+field.label+'-'++(bucket.display || bucket.label)" (change)="onToggleBucket($event, field, bucket)"> - {{ bucket.display || bucket.label }} ({{ bucket.count }}) + {{ bucket.display || bucket.label }} ({{ bucket.count }}) diff --git a/lib/content-services/search/components/search-filter/search-filter.component.spec.ts b/lib/content-services/search/components/search-filter/search-filter.component.spec.ts index f14dd03c74..d17dacbb52 100644 --- a/lib/content-services/search/components/search-filter/search-filter.component.spec.ts +++ b/lib/content-services/search/components/search-filter/search-filter.component.spec.ts @@ -216,6 +216,192 @@ describe('SearchFilterComponent', () => { expect(component.responseFacetFields.length).toEqual(2); }); + it('should fetch facet fields from response payload and show the bucket values', () => { + component.responseFacetFields = null; + + queryBuilder.config = { + categories: [], + facetFields: [ + { label: 'f1', field: 'f1' }, + { label: 'f2', field: 'f2' } + ], + facetQueries: { + queries: [] + } + }; + + const serverResponseFields: any = [ + { + label: 'f1', + buckets: [ + { label: 'b1', count: 10 }, + { label: 'b2', count: 1 } + ] + }, + { label: 'f2', buckets: [] } + ]; + const data = { + list: { + context: { + facetsFields: serverResponseFields + } + } + }; + + component.onDataLoaded(data); + + expect(component.responseFacetFields[0].buckets.items[0].count).toEqual(10); + expect(component.responseFacetFields[0].buckets.items[1].count).toEqual(1); + }); + + it('should fetch facet fields from response payload and update the existing bucket values', () => { + queryBuilder.config = { + categories: [], + facetFields: [ + { label: 'f1', field: 'f1' }, + { label: 'f2', field: 'f2' } + ], + facetQueries: { + queries: [] + } + }; + + const initialFields: any = [ + { label: 'f1', buckets: { items: [{ label: 'b1', count: 10, filterQuery: 'filter' }, { label: 'b2', count: 1 }]} }, + { label: 'f2', buckets: [] } + ]; + component.responseFacetFields = initialFields; + + expect(component.responseFacetFields[0].buckets.items[0].count).toEqual(10); + expect(component.responseFacetFields[0].buckets.items[1].count).toEqual(1); + + const serverResponseFields: any = [ + { label: 'f1', buckets: [{ label: 'b1', count: 6, filterQuery: 'filter' }, { label: 'b2', count: 0 }] }, + { label: 'f2', buckets: [] } + ]; + const data = { + list: { + context: { + facetsFields: serverResponseFields + } + } + }; + + component.onDataLoaded(data); + + expect(component.responseFacetFields[0].buckets.items[0].count).toEqual(6); + expect(component.responseFacetFields[0].buckets.items[1].count).toEqual(0); + }); + + it('should fetch facet fields from response payload and show the already checked items', () => { + spyOn(queryBuilder, 'execute').and.stub(); + queryBuilder.config = { + categories: [], + facetFields: [ + { label: 'f1', field: 'f1' }, + { label: 'f2', field: 'f2' } + ], + facetQueries: { + queries: [] + } + }; + + component.responseFacetFields = [ + { label: 'f1', field: 'f1', buckets: {items: [ + { label: 'b1', count: 10, filterQuery: 'filter', checked: true }, + { label: 'b2', count: 1, filterQuery: 'filter2' }] }}, + { label: 'f2', field: 'f2', buckets: {items: [] }} + ]; + + const serverResponseFields: any = [ + { label: 'f1', field: 'f1', buckets: [ + { label: 'b1', count: 6, filterQuery: 'filter' }, + { label: 'b2', count: 1, filterQuery: 'filter2' }] }, + { label: 'f2', field: 'f2', buckets: [] } + ]; + const data = { + list: { + context: { + facetsFields: serverResponseFields + } + } + }; + component.selectFacetBucket({ field: 'f1', label: 'f1' }, component.responseFacetFields[0].buckets.items[1]); + component.onDataLoaded(data); + expect(component.responseFacetFields.length).toEqual(2); + expect(component.responseFacetFields[0].buckets.items[0].checked).toEqual(true, 'should show the already checked item'); + }); + + it('should fetch facet fields from response payload and show the newly checked items', () => { + spyOn(queryBuilder, 'execute').and.stub(); + queryBuilder.config = { + categories: [], + facetFields: [ + { label: 'f1', field: 'f1' }, + { label: 'f2', field: 'f2' } + ], + facetQueries: { + queries: [] + } + }; + + component.responseFacetFields = [ + { label: 'f1', field: 'f1', buckets: {items: [ + { label: 'b1', count: 10, filterQuery: 'filter', checked: true }, + { label: 'b2', count: 1, filterQuery: 'filter2' }] }}, + { label: 'f2', field: 'f2', buckets: {items: [] }} + ]; + + const serverResponseFields: any = [ + { label: 'f1', field: 'f1', buckets: [ + { label: 'b1', count: 6, filterQuery: 'filter' }, + { label: 'b2', count: 1, filterQuery: 'filter2' }] }, + { label: 'f2', field: 'f2', buckets: [] } + ]; + const data = { + list: { + context: { + facetsFields: serverResponseFields + } + } + }; + component.selectFacetBucket({ label: 'f1', field: 'f1' }, component.responseFacetFields[0].buckets.items[1]); + component.onDataLoaded(data); + expect(component.responseFacetFields.length).toEqual(2); + expect(component.responseFacetFields[0].buckets.items[1].checked).toEqual(true, 'should show the newly checked item'); + }); + + it('should show buckets with 0 values when there are no facet fields on the response payload', () => { + spyOn(queryBuilder, 'execute').and.stub(); + queryBuilder.config = { + categories: [], + facetFields: [ + { label: 'f1', field: 'f1' }, + { label: 'f2', field: 'f2' } + ], + facetQueries: { + queries: [] + } + }; + + component.responseFacetFields = [ + { label: 'f1', field: 'f1', buckets: {items: [ + { label: 'b1', count: 10, filterQuery: 'filter', checked: true }, + { label: 'b2', count: 1, filterQuery: 'filter2' }] }}, + { label: 'f2', field: 'f2', buckets: {items: [] }} + ]; + const data = { + list: { + context: {} + } + }; + component.selectFacetBucket({ label: 'f1', field: 'f1' }, component.responseFacetFields[0].buckets.items[1]); + component.onDataLoaded(data); + + expect(component.responseFacetFields[0].buckets.items[0].count).toEqual(0); + expect(component.responseFacetFields[0].buckets.items[1].count).toEqual(0); + }); + it('should update query builder only when has bucket to unselect', () => { spyOn(queryBuilder, 'update').and.stub(); @@ -256,6 +442,7 @@ describe('SearchFilterComponent', () => { }); it('should reset selected buckets', () => { + spyOn(queryBuilder, 'execute').and.stub(); const buckets: FacetFieldBucket[] = [ { label: 'bucket1', checked: false, count: 1, filterQuery: 'q1' }, { label: 'bucket2', checked: true, count: 1, filterQuery: 'q2' } diff --git a/lib/content-services/search/components/search-filter/search-filter.component.ts b/lib/content-services/search/components/search-filter/search-filter.component.ts index a01e343c48..b2c303c88e 100644 --- a/lib/content-services/search/components/search-filter/search-filter.component.ts +++ b/lib/content-services/search/components/search-filter/search-filter.component.ts @@ -208,14 +208,45 @@ export class SearchFilterComponent implements OnInit, OnDestroy { } private parseFacetFields(context: any) { - if (!this.responseFacetFields) { - const configFacetFields = this.queryBuilder.config.facetFields || []; - this.responseFacetFields = configFacetFields.map(field => { - const responseField = (context.facetsFields || []).find(response => response.label === field.label); - const buckets: FacetFieldBucket[] = (responseField.buckets || []).map(bucket => { + const configFacetFields = this.queryBuilder.config.facetFields || []; + + const bkpResponseFacetFields = [...this.responseFacetFields || []]; + this.responseFacetFields = configFacetFields + .map(field => { + + const bkpField = bkpResponseFacetFields.find(item => item.field === field.field); + + let bkpBuckets = (bkpField && bkpField.buckets.items || []) + .map(bucket => { + const currentlySelected = this.selectedBuckets.find(facetBucket => facetBucket.bucket.label === bucket.label); + bucket.count = (currentlySelected ? 0 : null); + + return bucket; + }); + + let responseField = (context.facetsFields || []).find(response => response.label === field.label); + + if (!responseField && bkpBuckets.length) { + responseField = { buckets: [...bkpBuckets] }; + } + + if (responseField && this.selectedBuckets.length) { + responseField.buckets = bkpBuckets.map(bkpBucket => { + const responseBucket = responseField.buckets.find(respBucket => respBucket.label === bkpBucket.label); + + if (responseBucket) { + bkpBucket.count = responseBucket.count; + } + return bkpBucket; + }); + } + + const buckets: FacetFieldBucket[] = ((responseField && responseField.buckets) || []).map(bucket => { + const selectedBucket = this.selectedBuckets.find(facetBucket => facetBucket.bucket.label === bucket.label); + return { ...bucket, - checked: false, + checked: !!selectedBucket, display: this.translationService.instant(bucket.display), label: this.translationService.instant(bucket.label) }; @@ -237,15 +268,22 @@ export class SearchFilterComponent implements OnInit, OnDestroy { buckets: bucketList }; }); - } } private parseFacetQueries(context: any) { const responseQueries = this.getFacetQueryMap(context); - if (!this.responseFacetQueries && this.queryBuilder.config.facetQueries) { + if (this.queryBuilder.config.facetQueries) { + const bkpResponseFacetQueries = Object.assign({}, this.responseFacetQueries); const facetQueries = (this.queryBuilder.config.facetQueries.queries || []) .map(query => { + const queryResult = responseQueries[query.label]; + const bkpQuery = (bkpResponseFacetQueries.items || []).find(item => item.label === query.label); + + if (bkpQuery) { + bkpQuery.count = queryResult.count; + return bkpQuery; + } return { ...query, label: this.translationService.instant(query.label), @@ -254,7 +292,13 @@ export class SearchFilterComponent implements OnInit, OnDestroy { }); if (facetQueries.length > 0) { - this.responseFacetQueries = new ResponseFacetQueryList(facetQueries, this.facetQueriesPageSize); + if (this.responseFacetQueries) { + this.responseFacetQueries.items = facetQueries; + + } else { + this.responseFacetQueries = new ResponseFacetQueryList(facetQueries, this.facetQueriesPageSize); + } + } else { this.responseFacetQueries = null; }