mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACS-5347] New styles for facets and filters states (#8661)
* [ACS-5347] New styles for facets and filters states * [ACS-5347] Move ACA specific colors to ACA * [ACS-5347] CR fixes
This commit is contained in:
@@ -19,7 +19,7 @@
|
|||||||
{{ displayValue | translate }}
|
{{ displayValue | translate }}
|
||||||
</span>
|
</span>
|
||||||
<ng-template #showAny><span class="adf-search-filter-ellipsis adf-filter-value"> {{ 'SEARCH.FILTER.ANY' | translate }}</span></ng-template>
|
<ng-template #showAny><span class="adf-search-filter-ellipsis adf-filter-value"> {{ 'SEARCH.FILTER.ANY' | translate }}</span></ng-template>
|
||||||
<mat-icon *ngIf="isPopulated(); else disabledIcon">keyboard_arrow_down</mat-icon>
|
<mat-icon *ngIf="isPopulated(); else disabledIcon">{{ chipIcon }}</mat-icon>
|
||||||
<ng-template #disabledIcon>
|
<ng-template #disabledIcon>
|
||||||
<mat-icon>remove</mat-icon>
|
<mat-icon>remove</mat-icon>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@@ -38,8 +38,8 @@
|
|||||||
<adf-search-facet-field [field]="field" #facetField></adf-search-facet-field>
|
<adf-search-facet-field [field]="field" #facetField></adf-search-facet-field>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container ngProjectAs="filter-actions">
|
<ng-container ngProjectAs="filter-actions">
|
||||||
<button mat-flat-button class="adf-search-action-button" color="accent" (click)="onRemove()" id="cancel-filter-button">
|
<button mat-button class="adf-search-action-button" (click)="onRemove()" id="cancel-filter-button">
|
||||||
{{ 'SEARCH.FILTER.BUTTONS.REMOVE' | translate }}
|
{{ 'SEARCH.FILTER.BUTTONS.CLEAR' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button mat-flat-button class="adf-search-action-button" color="primary" (click)="onApply()" id="apply-filter-button">
|
<button mat-flat-button class="adf-search-action-button" color="primary" (click)="onApply()" id="apply-filter-button">
|
||||||
{{ 'SEARCH.FILTER.BUTTONS.APPLY' | translate }}
|
{{ 'SEARCH.FILTER.BUTTONS.APPLY' | translate }}
|
||||||
|
@@ -73,6 +73,14 @@ describe('SearchFacetChipComponent', () => {
|
|||||||
expect(icon).toEqual('keyboard_arrow_down');
|
expect(icon).toEqual('keyboard_arrow_down');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should display arrow up icon when menu is opened', () => {
|
||||||
|
component.field.buckets.items = [{ count: 1, label: 'test', filterQuery: '' }];
|
||||||
|
component.onMenuOpen();
|
||||||
|
fixture.detectChanges();
|
||||||
|
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
|
||||||
|
expect(icon).toEqual('keyboard_arrow_up');
|
||||||
|
});
|
||||||
|
|
||||||
it('should display remove icon and disable facet when no items are loaded', () => {
|
it('should display remove icon and disable facet when no items are loaded', () => {
|
||||||
const chip = fixture.debugElement.query(By.css('mat-chip'));
|
const chip = fixture.debugElement.query(By.css('mat-chip'));
|
||||||
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
|
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
|
||||||
|
@@ -41,6 +41,7 @@ export class SearchFacetChipComponent {
|
|||||||
facetFieldComponent: SearchFacetFieldComponent;
|
facetFieldComponent: SearchFacetFieldComponent;
|
||||||
|
|
||||||
focusTrap: ConfigurableFocusTrap;
|
focusTrap: ConfigurableFocusTrap;
|
||||||
|
chipIcon = 'keyboard_arrow_down';
|
||||||
|
|
||||||
constructor(private focusTrapFactory: ConfigurableFocusTrapFactory) {}
|
constructor(private focusTrapFactory: ConfigurableFocusTrapFactory) {}
|
||||||
|
|
||||||
@@ -48,11 +49,13 @@ export class SearchFacetChipComponent {
|
|||||||
if (this.menuContainer && !this.focusTrap) {
|
if (this.menuContainer && !this.focusTrap) {
|
||||||
this.focusTrap = this.focusTrapFactory.create(this.menuContainer.nativeElement);
|
this.focusTrap = this.focusTrapFactory.create(this.menuContainer.nativeElement);
|
||||||
}
|
}
|
||||||
|
this.chipIcon = 'keyboard_arrow_up';
|
||||||
}
|
}
|
||||||
|
|
||||||
onClosed() {
|
onClosed() {
|
||||||
this.focusTrap.destroy();
|
this.focusTrap.destroy();
|
||||||
this.focusTrap = null;
|
this.focusTrap = null;
|
||||||
|
this.chipIcon = 'keyboard_arrow_down';
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove() {
|
onRemove() {
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
&.adf-search-toggle-chip {
|
&.adf-search-toggle-chip {
|
||||||
background: var(--adf-theme-background-card-color);
|
background: var(--adf-theme-background-card-color);
|
||||||
border: 2px solid var(--theme-accent-color);
|
border: 2px solid var(--theme-primary-color);
|
||||||
|
|
||||||
&.mat-chip::after {
|
&.mat-chip::after {
|
||||||
background: unset;
|
background: unset;
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
{{ displayValue | translate }}
|
{{ displayValue | translate }}
|
||||||
</span>
|
</span>
|
||||||
<ng-template #showAny><span class="adf-search-filter-ellipsis adf-filter-value"> {{ 'SEARCH.FILTER.ANY' | translate }}</span></ng-template>
|
<ng-template #showAny><span class="adf-search-filter-ellipsis adf-filter-value"> {{ 'SEARCH.FILTER.ANY' | translate }}</span></ng-template>
|
||||||
<mat-icon>keyboard_arrow_down</mat-icon>
|
<mat-icon>{{ chipIcon }}</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
|
|
||||||
<mat-menu #menu="matMenu" backdropClass="adf-search-filter-chip-menu" (closed)="onClosed()">
|
<mat-menu #menu="matMenu" backdropClass="adf-search-filter-chip-menu" (closed)="onClosed()">
|
||||||
@@ -39,8 +39,8 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container ngProjectAs="filter-actions">
|
<ng-container ngProjectAs="filter-actions">
|
||||||
<button mat-flat-button class="adf-search-action-button" color="accent" (click)="onRemove()" id="cancel-filter-button">
|
<button mat-button class="adf-search-action-button" (click)="onRemove()" id="cancel-filter-button">
|
||||||
{{ 'SEARCH.FILTER.BUTTONS.REMOVE' | translate }}
|
{{ 'SEARCH.FILTER.BUTTONS.CLEAR' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button mat-flat-button class="adf-search-action-button" color="primary" (click)="onApply()" id="apply-filter-button">
|
<button mat-flat-button class="adf-search-action-button" color="primary" (click)="onApply()" id="apply-filter-button">
|
||||||
{{ 'SEARCH.FILTER.BUTTONS.APPLY' | translate }}
|
{{ 'SEARCH.FILTER.BUTTONS.APPLY' | translate }}
|
||||||
|
@@ -30,13 +30,13 @@ describe('SearchWidgetChipComponent', () => {
|
|||||||
let fixture: ComponentFixture<SearchWidgetChipComponent>;
|
let fixture: ComponentFixture<SearchWidgetChipComponent>;
|
||||||
let queryBuilder: SearchQueryBuilderService;
|
let queryBuilder: SearchQueryBuilderService;
|
||||||
|
|
||||||
setupTestBed( {
|
setupTestBed({
|
||||||
imports: [
|
imports: [
|
||||||
MatMenuModule,
|
MatMenuModule,
|
||||||
TranslateModule.forRoot(),
|
TranslateModule.forRoot(),
|
||||||
ContentTestingModule
|
ContentTestingModule
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
queryBuilder = TestBed.inject(SearchQueryBuilderService);
|
queryBuilder = TestBed.inject(SearchQueryBuilderService);
|
||||||
@@ -46,23 +46,35 @@ describe('SearchWidgetChipComponent', () => {
|
|||||||
|
|
||||||
component.category = simpleCategories[1];
|
component.category = simpleCategories[1];
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update search query on apply click', () => {
|
it('should update search query on apply click', () => {
|
||||||
const chip = fixture.debugElement.query(By.css('mat-chip'));
|
const chip = fixture.debugElement.query(By.css('mat-chip'));
|
||||||
chip.triggerEventHandler('click', { stopPropagation: () => null });
|
chip.triggerEventHandler('click', { stopPropagation: () => null });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const applyButton = fixture.debugElement.query(By.css('#apply-filter-button'));
|
const applyButton = fixture.debugElement.query(By.css('#apply-filter-button'));
|
||||||
applyButton.triggerEventHandler('click', {});
|
applyButton.triggerEventHandler('click', {});
|
||||||
expect(queryBuilder.update).toHaveBeenCalled();
|
expect(queryBuilder.update).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update search query on cancel click', () => {
|
it('should update search query on cancel click', () => {
|
||||||
const chip = fixture.debugElement.query(By.css('mat-chip'));
|
const chip = fixture.debugElement.query(By.css('mat-chip'));
|
||||||
chip.triggerEventHandler('click', { stopPropagation: () => null });
|
chip.triggerEventHandler('click', { stopPropagation: () => null });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const applyButton = fixture.debugElement.query(By.css('#cancel-filter-button'));
|
const applyButton = fixture.debugElement.query(By.css('#cancel-filter-button'));
|
||||||
applyButton.triggerEventHandler('click', {});
|
applyButton.triggerEventHandler('click', {});
|
||||||
expect(queryBuilder.update).toHaveBeenCalled();
|
expect(queryBuilder.update).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should display arrow down icon', () => {
|
||||||
|
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
|
||||||
|
expect(icon).toEqual('keyboard_arrow_down');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display arrow up icon when menu is opened', () => {
|
||||||
|
component.onMenuOpen();
|
||||||
|
fixture.detectChanges();
|
||||||
|
const icon = fixture.debugElement.query(By.css('mat-chip mat-icon')).nativeElement.innerText;
|
||||||
|
expect(icon).toEqual('keyboard_arrow_up');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -41,6 +41,7 @@ export class SearchWidgetChipComponent {
|
|||||||
widgetContainerComponent: SearchWidgetContainerComponent;
|
widgetContainerComponent: SearchWidgetContainerComponent;
|
||||||
|
|
||||||
focusTrap: ConfigurableFocusTrap;
|
focusTrap: ConfigurableFocusTrap;
|
||||||
|
chipIcon = 'keyboard_arrow_down';
|
||||||
|
|
||||||
constructor(private focusTrapFactory: ConfigurableFocusTrapFactory) {}
|
constructor(private focusTrapFactory: ConfigurableFocusTrapFactory) {}
|
||||||
|
|
||||||
@@ -48,11 +49,13 @@ export class SearchWidgetChipComponent {
|
|||||||
if (this.menuContainer && !this.focusTrap) {
|
if (this.menuContainer && !this.focusTrap) {
|
||||||
this.focusTrap = this.focusTrapFactory.create(this.menuContainer.nativeElement);
|
this.focusTrap = this.focusTrapFactory.create(this.menuContainer.nativeElement);
|
||||||
}
|
}
|
||||||
|
this.chipIcon = 'keyboard_arrow_up';
|
||||||
}
|
}
|
||||||
|
|
||||||
onClosed() {
|
onClosed() {
|
||||||
this.focusTrap.destroy();
|
this.focusTrap.destroy();
|
||||||
this.focusTrap = null;
|
this.focusTrap = null;
|
||||||
|
this.chipIcon = 'keyboard_arrow_down';
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove() {
|
onRemove() {
|
||||||
|
@@ -14,13 +14,4 @@
|
|||||||
[onReset]="resetObservable"
|
[onReset]="resetObservable"
|
||||||
(phrasesChanged)="onPhraseChange($event, LogicalSearchFields.EXCLUDE)">
|
(phrasesChanged)="onPhraseChange($event, LogicalSearchFields.EXCLUDE)">
|
||||||
</adf-search-chip-input>
|
</adf-search-chip-input>
|
||||||
|
|
||||||
<div class="adf-facet-buttons" *ngIf="!settings?.hideDefaultAction">
|
|
||||||
<button mat-button color="primary" data-automation-id="logical-filter-btn-clear" (click)="reset()">
|
|
||||||
{{ 'SEARCH.FILTER.ACTIONS.CLEAR' | translate }}
|
|
||||||
</button>
|
|
||||||
<button mat-button color="primary" data-automation-id="logical-filter-btn-apply" (click)="submitValues()">
|
|
||||||
{{ 'SEARCH.FILTER.ACTIONS.APPLY' | translate }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -64,12 +64,6 @@ describe('SearchLogicalFilterComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickApplyBtn() {
|
|
||||||
const applyBtn: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="logical-filter-btn-apply"]')).nativeElement;
|
|
||||||
applyBtn.click();
|
|
||||||
fixture.detectChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should update display value on init', () => {
|
it('should update display value on init', () => {
|
||||||
spyOn(component.displayValue$, 'next');
|
spyOn(component.displayValue$, 'next');
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
@@ -122,14 +116,13 @@ describe('SearchLogicalFilterComponent', () => {
|
|||||||
expect(component.displayValue$.next).toHaveBeenCalled();
|
expect(component.displayValue$.next).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reset value and display value when reset button is clicked', () => {
|
it('should reset value and display value when reset is called', () => {
|
||||||
const searchCondition: LogicalSearchCondition = { matchAll: ['test1'], matchAny: ['test2'], exclude: ['test3'] };
|
const searchCondition: LogicalSearchCondition = { matchAll: ['test1'], matchAny: ['test2'], exclude: ['test3'] };
|
||||||
component.setValue(searchCondition);
|
component.setValue(searchCondition);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
spyOn(component.context, 'update');
|
spyOn(component.context, 'update');
|
||||||
spyOn(component.displayValue$, 'next');
|
spyOn(component.displayValue$, 'next');
|
||||||
const resetBtn: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="logical-filter-btn-clear"]')).nativeElement;
|
component.reset();
|
||||||
resetBtn.click();
|
|
||||||
expect(component.context.queryFragments[component.id]).toBe('');
|
expect(component.context.queryFragments[component.id]).toBe('');
|
||||||
expect(component.context.update).toHaveBeenCalled();
|
expect(component.context.update).toHaveBeenCalled();
|
||||||
expect(component.getCurrentValue()).toEqual({ matchAll: [], matchAny: [], exclude: [] });
|
expect(component.getCurrentValue()).toEqual({ matchAll: [], matchAny: [], exclude: [] });
|
||||||
@@ -140,7 +133,7 @@ describe('SearchLogicalFilterComponent', () => {
|
|||||||
spyOn(component.context, 'update');
|
spyOn(component.context, 'update');
|
||||||
enterNewPhrase('test1', 0);
|
enterNewPhrase('test1', 0);
|
||||||
enterNewPhrase('test2', 0);
|
enterNewPhrase('test2', 0);
|
||||||
clickApplyBtn();
|
component.submitValues();
|
||||||
expect(component.context.update).toHaveBeenCalled();
|
expect(component.context.update).toHaveBeenCalled();
|
||||||
expect(component.context.queryFragments[component.id]).toBe('((field1:"test1" AND field1:"test2") OR (field2:"test1" AND field2:"test2"))');
|
expect(component.context.queryFragments[component.id]).toBe('((field1:"test1" AND field1:"test2") OR (field2:"test1" AND field2:"test2"))');
|
||||||
});
|
});
|
||||||
@@ -149,7 +142,7 @@ describe('SearchLogicalFilterComponent', () => {
|
|||||||
spyOn(component.context, 'update');
|
spyOn(component.context, 'update');
|
||||||
enterNewPhrase('test3', 1);
|
enterNewPhrase('test3', 1);
|
||||||
enterNewPhrase('test4', 1);
|
enterNewPhrase('test4', 1);
|
||||||
clickApplyBtn();
|
component.submitValues();
|
||||||
expect(component.context.update).toHaveBeenCalled();
|
expect(component.context.update).toHaveBeenCalled();
|
||||||
expect(component.context.queryFragments[component.id]).toBe('((field1:"test3" OR field1:"test4") OR (field2:"test3" OR field2:"test4"))');
|
expect(component.context.queryFragments[component.id]).toBe('((field1:"test3" OR field1:"test4") OR (field2:"test3" OR field2:"test4"))');
|
||||||
});
|
});
|
||||||
@@ -158,7 +151,7 @@ describe('SearchLogicalFilterComponent', () => {
|
|||||||
spyOn(component.context, 'update');
|
spyOn(component.context, 'update');
|
||||||
enterNewPhrase('test5', 2);
|
enterNewPhrase('test5', 2);
|
||||||
enterNewPhrase('test6', 2);
|
enterNewPhrase('test6', 2);
|
||||||
clickApplyBtn();
|
component.submitValues();
|
||||||
expect(component.context.update).toHaveBeenCalled();
|
expect(component.context.update).toHaveBeenCalled();
|
||||||
expect(component.context.queryFragments[component.id]).toBe('((NOT field1:"test5" AND NOT field1:"test6") AND (NOT field2:"test5" AND NOT field2:"test6"))');
|
expect(component.context.queryFragments[component.id]).toBe('((NOT field1:"test5" AND NOT field1:"test6") AND (NOT field2:"test5" AND NOT field2:"test6"))');
|
||||||
});
|
});
|
||||||
@@ -168,7 +161,7 @@ describe('SearchLogicalFilterComponent', () => {
|
|||||||
enterNewPhrase('test1', 0);
|
enterNewPhrase('test1', 0);
|
||||||
enterNewPhrase('test2', 1);
|
enterNewPhrase('test2', 1);
|
||||||
enterNewPhrase('test3', 2);
|
enterNewPhrase('test3', 2);
|
||||||
clickApplyBtn();
|
component.submitValues();
|
||||||
const subQuery1 = '((field1:"test1") OR (field2:"test1"))';
|
const subQuery1 = '((field1:"test1") OR (field2:"test1"))';
|
||||||
const subQuery2 = '((field1:"test2") OR (field2:"test2"))';
|
const subQuery2 = '((field1:"test2") OR (field2:"test2"))';
|
||||||
const subQuery3 = '((NOT field1:"test3") AND (NOT field2:"test3"))';
|
const subQuery3 = '((NOT field1:"test3") AND (NOT field2:"test3"))';
|
||||||
|
Reference in New Issue
Block a user