#988 Start Search On Click Autocomplete Result

This commit is contained in:
Sebastian
2020-10-06 17:11:05 +02:00
parent 7b8b3c10a6
commit 9a34cb0cff
6 changed files with 111 additions and 10 deletions

View File

@@ -3,6 +3,8 @@ import { AutocompleteResultsComponent } from './autocomplete-results.component';
import { ResultItemComponent } from './result-item';
import { ActiveDescendantKeyManager, Highlightable } from '@angular/cdk/a11y';
import { QueryList } from '@angular/core';
import { By } from '@angular/platform-browser';
import { AutocompleteDTO } from '@swagger/oms';
fdescribe('#AutocompleteResultsComponent', () => {
let fixture: ComponentFixture<AutocompleteResultsComponent>;
@@ -20,7 +22,9 @@ fdescribe('#AutocompleteResultsComponent', () => {
fixture = TestBed.createComponent(AutocompleteResultsComponent);
component = fixture.componentInstance;
items = new QueryList();
component['keyManager'] = new ActiveDescendantKeyManager<ResultItemComponent>(items).withWrap();
component['keyManager'] = new ActiveDescendantKeyManager<
ResultItemComponent
>(items).withWrap();
spyOn(component, 'ngAfterViewInit').and.callFake(() => {});
component.results = [];
@@ -39,7 +43,9 @@ fdescribe('#AutocompleteResultsComponent', () => {
} as unknown) as Highlightable & ResultItemComponent;
spyOn(component, 'onKeyDown').and.callThrough();
spyOn(component.selectItem, 'emit').and.callFake(() => {});
spyOnProperty(component['keyManager'], 'activeItem').and.returnValue(activeItemMock);
spyOnProperty(component['keyManager'], 'activeItem').and.returnValue(
activeItemMock
);
spyOn(component['keyManager'], 'setActiveItem').and.callFake(() => {});
});
@@ -67,8 +73,12 @@ fdescribe('#AutocompleteResultsComponent', () => {
fixture.detectChanges();
expect(component.onKeyDown).toHaveBeenCalled();
expect(component['keyManager'].setActiveItem).not.toHaveBeenCalledWith(null);
expect(component.selectItem.emit).toHaveBeenCalledWith(activeItemMock.result);
expect(component['keyManager'].setActiveItem).not.toHaveBeenCalledWith(
null
);
expect(component.selectItem.emit).toHaveBeenCalledWith(
activeItemMock.result
);
});
it('should not deselect if ArrowDown is pressed', () => {
@@ -77,8 +87,40 @@ fdescribe('#AutocompleteResultsComponent', () => {
fixture.detectChanges();
expect(component.onKeyDown).toHaveBeenCalled();
expect(component['keyManager'].setActiveItem).not.toHaveBeenCalledWith(null);
expect(component.selectItem.emit).toHaveBeenCalledWith(activeItemMock.result);
expect(component['keyManager'].setActiveItem).not.toHaveBeenCalledWith(
null
);
expect(component.selectItem.emit).toHaveBeenCalledWith(
activeItemMock.result
);
});
});
describe('onItemClicked', () => {
const results: AutocompleteDTO[] = [
{ id: 'test', display: 'display', query: 'Suchbegriff' },
];
beforeEach(() => {
spyOn(component.selectItem, 'emit').and.callFake((val) => val);
spyOn(component, 'onItemClicked').and.callThrough();
spyOn(component['keyManager'], 'setActiveItem').and.callFake(() => {});
spyOnProperty(component['keyManager'], 'activeItem').and.returnValue({
result: results[0],
});
component.results = results;
});
it('should set shouldStartSearch to true when emitting selectItem event', () => {
fixture.detectChanges();
component.onItemClicked(results[0]);
expect(component.selectItem.emit).toHaveBeenCalledWith({
...results[0],
shouldUpdateAutocomplete: false,
shouldStartSearch: true,
});
});
});
});

View File

@@ -24,7 +24,9 @@ export class AutocompleteResultsComponent implements AfterViewInit {
@ViewChildren(ResultItemComponent) items: QueryList<ResultItemComponent>;
@Input() results: AutocompleteDTO[];
@Output() selectItem = new EventEmitter<AutocompleteDTO & AutocompleteOptions>();
@Output() selectItem = new EventEmitter<
AutocompleteDTO & AutocompleteOptions
>();
private keyManager: ActiveDescendantKeyManager<ResultItemComponent>;
@@ -51,8 +53,8 @@ export class AutocompleteResultsComponent implements AfterViewInit {
this.keyManager.setActiveItem(this.getItemIndex(item));
this.selectItem.emit({
...this.keyManager.activeItem.result,
shouldNavigate: false,
shouldUpdateAutocomplete: false,
shouldStartSearch: true,
});
}

View File

@@ -9,6 +9,11 @@
padding-top: 16px;
padding-left: 28px;
padding-right: 28px;
cursor: pointer;
&:hover {
background-color: $isa-branch-bg;
}
}
:host.active {

View File

@@ -1,4 +1,4 @@
export interface AutocompleteOptions {
shouldNavigate?: boolean;
shouldUpdateAutocomplete?: boolean;
shouldStartSearch?: boolean;
}

View File

@@ -7,7 +7,7 @@ import {
} from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { SearchStateFacade } from '@shelf-store';
import { of, Subject } from 'rxjs';
import { BehaviorSubject, of, Subject } from 'rxjs';
import {
ShelfNavigationService,
ShelfSearchFacadeService,
@@ -17,6 +17,8 @@ import { ShelfFilterService } from '../../../services';
import { ShelfSearchbarComponent } from '../../../components';
import { By } from '@angular/platform-browser';
import { take } from 'rxjs/operators';
import { AutocompleteDTO } from '@swagger/oms';
import { AutocompleteOptions } from '../../../defs';
class MockSearchStateFacade {
constructor() {}
@@ -248,4 +250,49 @@ fdescribe('#SearchInputComponent', () => {
);
});
});
describe('handleAutocompleteAction', () => {
const mockAutocompleteDTO: AutocompleteDTO = {
type: 'Unit Test',
query: 'test query',
};
let mockSelectItem: AutocompleteDTO & AutocompleteOptions;
beforeEach(() => {
const selectedItem$ = new BehaviorSubject<
AutocompleteDTO & AutocompleteOptions
>({ ...mockAutocompleteDTO, query: 'overwritten query' });
component.selectedItem$ = selectedItem$;
spyOn(component, 'triggerSearch').and.callFake(() => {});
});
it('should start a search if startSearch is set to true', () => {
mockSelectItem = {
...mockAutocompleteDTO,
shouldStartSearch: true,
shouldUpdateAutocomplete: true,
};
component.handleAutocompleteAction(mockSelectItem);
expect(component.triggerSearch).toHaveBeenCalledWith({
value: mockAutocompleteDTO.query,
type: 'search',
});
});
it('should not start a search if startSearch is set to false', () => {
mockSelectItem = {
...mockAutocompleteDTO,
shouldStartSearch: false,
shouldUpdateAutocomplete: true,
};
component.handleAutocompleteAction(mockSelectItem);
expect(component.triggerSearch).not.toHaveBeenCalled();
});
});
});

View File

@@ -195,11 +195,16 @@ export class ShelfSearchInputComponent
const oldValue = this.selectedItem$.value && this.selectedItem$.value.query;
const newValue = selectItem.query;
if (selectItem.shouldStartSearch) {
this.triggerSearch({ value: newValue, type: 'search' });
}
if (this.isAutocompleteOverwritten(oldValue, newValue)) {
return this.setSelectedAutocompleteItem(null);
}
this.setSelectedAutocompleteItem(selectItem);
if (selectItem.query) {
this.updateSearchbarValue(selectItem.query);
this.updateSearchQuery(selectItem.query);