[ADF-2927] search filter enhancements (#3365)

* search filter enhancements

* reset button for facet queries

* update code and tests

* remove unused type

* restore code missing after rebase
This commit is contained in:
Denys Vuika
2018-05-23 00:36:20 +01:00
committed by Eugenio Romano
parent ca12233580
commit f69bad3732
4 changed files with 187 additions and 21 deletions

View File

@@ -44,16 +44,22 @@
</ng-container>
</div>
<div class="facet-buttons">
<button mat-button
<button mat-icon-button
*ngIf="canResetSelectedQueries()"
title="{{ 'SEARCH.FILTER.ACTIONS.CLEAR-ALL' | translate }}"
(click)="resetSelectedQueries()">
<mat-icon>clear</mat-icon>
</button>
<button mat-icon-button
*ngIf="responseFacetQueries.canShowLessItems"
title="{{ 'SEARCH.FILTER.ACTIONS.SHOW-LESS' | translate }}"
(click)="responseFacetQueries.showLessItems()">
{{ 'SEARCH.FILTER.ACTIONS.SHOW-LESS' | translate }}
<mat-icon>keyboard_arrow_up</mat-icon>
</button>
<button mat-button
<button mat-icon-button
*ngIf="responseFacetQueries.canShowMoreItems"
title="{{ 'SEARCH.FILTER.ACTIONS.SHOW-MORE' | translate }}"
(click)="responseFacetQueries.showMoreItems()">
{{ 'SEARCH.FILTER.ACTIONS.SHOW-MORE' | translate }}
<mat-icon>keyboard_arrow_down</mat-icon>
</button>
</div>
@@ -91,17 +97,32 @@
</mat-checkbox>
</div>
<div class="facet-buttons" *ngIf="field.buckets.fitsPage">
<button *ngIf="canResetSelectedBuckets(field)"
mat-button
color="primary"
(click)="resetSelectedBuckets(field)">
{{ 'SEARCH.FILTER.ACTIONS.CLEAR-ALL' | translate }}
</button>
</div>
<div class="facet-buttons" *ngIf="!field.buckets.fitsPage">
<button mat-button
<button mat-icon-button
*ngIf="canResetSelectedBuckets(field)"
title="{{ 'SEARCH.FILTER.ACTIONS.CLEAR-ALL' | translate }}"
(click)="resetSelectedBuckets(field)">
<mat-icon>clear</mat-icon>
</button>
<button mat-icon-button
*ngIf="field.buckets.canShowLessItems"
(click)="field.buckets.showLessItems()">
{{ 'SEARCH.FILTER.ACTIONS.SHOW-LESS' | translate }}
(click)="field.buckets.showLessItems()"
title="{{ 'SEARCH.FILTER.ACTIONS.SHOW-LESS' | translate }}">
<mat-icon>keyboard_arrow_up</mat-icon>
</button>
<button mat-button
<button mat-icon-button
*ngIf="field.buckets.canShowMoreItems"
(click)="field.buckets.showMoreItems()">
{{ 'SEARCH.FILTER.ACTIONS.SHOW-MORE' | translate }}
(click)="field.buckets.showMoreItems()"
title="{{ 'SEARCH.FILTER.ACTIONS.SHOW-MORE' | translate }}">
<mat-icon>keyboard_arrow_down</mat-icon>
</button>
</div>

View File

@@ -21,6 +21,9 @@ import { SearchConfiguration } from '../../search-configuration.interface';
import { AppConfigService, TranslationMock } from '@alfresco/adf-core';
import { Subject } from 'rxjs/Subject';
import { ResponseFacetQueryList } from './models/response-facet-query-list.model';
import { ResponseFacetField } from '../../response-facet-field.interface';
import { SearchFilterList } from './models/search-filter-list.model';
import { FacetFieldBucket } from '../../facet-field-bucket.interface';
describe('SearchSettingsComponent', () => {
@@ -340,4 +343,100 @@ describe('SearchSettingsComponent', () => {
expect(queryBuilder.update).not.toHaveBeenCalled();
});
it('should allow to to reset selected buckets', () => {
const buckets: FacetFieldBucket[] = [
{ label: 'bucket1', $checked: true, count: 1, filterQuery: 'q1' },
{ label: 'bucket2', $checked: false, count: 1, filterQuery: 'q2' }
];
const field: ResponseFacetField = {
label: 'field1',
buckets: new SearchFilterList<FacetFieldBucket>(buckets)
};
expect(component.canResetSelectedBuckets(field)).toBeTruthy();
});
it('should not allow to reset selected buckets', () => {
const buckets: FacetFieldBucket[] = [
{ label: 'bucket1', $checked: false, count: 1, filterQuery: 'q1' },
{ label: 'bucket2', $checked: false, count: 1, filterQuery: 'q2' }
];
const field: ResponseFacetField = {
label: 'field1',
buckets: new SearchFilterList<FacetFieldBucket>(buckets)
};
expect(component.canResetSelectedBuckets(field)).toBeFalsy();
});
it('should reset selected buckets', () => {
const buckets: FacetFieldBucket[] = [
{ label: 'bucket1', $checked: false, count: 1, filterQuery: 'q1', $field: 'field1' },
{ label: 'bucket2', $checked: true, count: 1, filterQuery: 'q2', $field: 'field1' }
];
const field: ResponseFacetField = {
label: 'field1',
buckets: new SearchFilterList<FacetFieldBucket>(buckets)
};
component.selectedBuckets = [buckets[1]];
component.resetSelectedBuckets(field);
expect(buckets[0].$checked).toBeFalsy();
expect(buckets[1].$checked).toBeFalsy();
expect(component.selectedBuckets.length).toBe(0);
});
it('should update query builder upon resetting buckets', () => {
spyOn(queryBuilder, 'update').and.stub();
const buckets: FacetFieldBucket[] = [
{ label: 'bucket1', $checked: false, count: 1, filterQuery: 'q1', $field: 'field1' },
{ label: 'bucket2', $checked: true, count: 1, filterQuery: 'q2', $field: 'field1' }
];
const field: ResponseFacetField = {
label: 'field1',
buckets: new SearchFilterList<FacetFieldBucket>(buckets)
};
component.selectedBuckets = [buckets[1]];
component.resetSelectedBuckets(field);
expect(queryBuilder.update).toHaveBeenCalled();
});
it('should allow to reset selected queries', () => {
component.selectedFacetQueries = ['q1', 'q2'];
expect(component.canResetSelectedQueries()).toBeTruthy();
});
it('should not allow to reset selected queries when nothing selected', () => {
component.selectedFacetQueries = [];
expect(component.canResetSelectedQueries()).toBeFalsy();
});
it('should reset selected queries', () => {
const methodSpy = spyOn(component, 'unselectFacetQuery').and.stub();
component.selectedFacetQueries = ['q1', 'q2'];
component.resetSelectedQueries();
expect(methodSpy.calls.count()).toBe(2);
expect(methodSpy.calls.argsFor(0)).toEqual(['q1', false]);
expect(methodSpy.calls.argsFor(1)).toEqual(['q2', false]);
});
it('should update query builder upon resetting selected queries', () => {
spyOn(queryBuilder, 'update').and.stub();
component.selectedFacetQueries = ['q1', 'q2'];
component.resetSelectedQueries();
expect(queryBuilder.update).toHaveBeenCalled();
});
});

View File

@@ -129,15 +129,20 @@ export class SearchFilterComponent implements OnInit {
this.queryBuilder.update();
}
unselectFacetQuery(label: string) {
unselectFacetQuery(label: string, reloadQuery: boolean = true) {
const facetQuery = this.queryBuilder.getFacetQuery(label);
if (facetQuery) {
this.queryBuilder.removeFilterQuery(facetQuery.query);
}
this.selectedFacetQueries = this.selectedFacetQueries.filter(selectedQuery => selectedQuery !== label);
this.queryBuilder.removeFilterQuery(facetQuery.query);
this.queryBuilder.update();
if (reloadQuery) {
this.queryBuilder.update();
}
}
unselectFacetBucket(bucket: FacetFieldBucket) {
unselectFacetBucket(bucket: FacetFieldBucket, reloadQuery: boolean = true) {
if (bucket) {
const idx = this.selectedBuckets.findIndex(
selectedBucket => selectedBucket.$field === bucket.$field && selectedBucket.label === bucket.label
@@ -147,6 +152,40 @@ export class SearchFilterComponent implements OnInit {
this.selectedBuckets.splice(idx, 1);
}
this.queryBuilder.removeFilterQuery(bucket.filterQuery);
bucket.$checked = false;
if (reloadQuery) {
this.queryBuilder.update();
}
}
}
canResetSelectedQueries(): boolean {
return this.selectedFacetQueries && this.selectedFacetQueries.length > 0;
}
resetSelectedQueries() {
if (this.canResetSelectedQueries()) {
this.selectedFacetQueries.forEach(query => {
this.unselectFacetQuery(query, false);
});
this.queryBuilder.update();
}
}
canResetSelectedBuckets(field: ResponseFacetField): boolean {
if (field && field.buckets) {
return field.buckets.items.some(bucket => bucket.$checked);
}
return false;
}
resetSelectedBuckets(field: ResponseFacetField) {
if (field && field.buckets) {
field.buckets.items.forEach(bucket => {
this.unselectFacetBucket(bucket, false);
});
this.queryBuilder.update();
}
}

View File

@@ -74,9 +74,8 @@ export class SearchQueryBuilderService {
}
getFacetQuery(label: string): FacetQuery {
if (label) {
const queries = this.config.facetQueries.queries || [];
return queries.find(query => query.label === label);
if (label && this.hasFacetQueries) {
return this.config.facetQueries.queries.find(query => query.label === label);
}
return null;
}
@@ -171,10 +170,8 @@ export class SearchQueryBuilderService {
}
private get facetQueries(): FacetQuery[] {
const config = this.config.facetQueries;
if (config && config.queries && config.queries.length > 0) {
return config.queries.map(query => {
if (this.hasFacetQueries) {
return this.config.facetQueries.queries.map(query => {
return <FacetQuery> { ...query };
});
}
@@ -200,4 +197,14 @@ export class SearchQueryBuilderService {
return null;
}
private get hasFacetQueries(): boolean {
if (this.config
&& this.config.facetQueries
&& this.config.facetQueries.queries
&& this.config.facetQueries.queries.length > 0) {
return true;
}
return false;
}
}