[ACS-10332] Search: Editable Combobox Without Autocomplete Does Not D… (#11310)

This commit is contained in:
dominikiwanekhyland
2025-10-30 14:29:05 +01:00
committed by GitHub
parent a4f5cfc964
commit 4feba2f304
5 changed files with 48 additions and 12 deletions
@@ -33,7 +33,6 @@
</mat-chip-grid>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)" id="adf-search-chip-autocomplete"
(optionActivated)="activeAnyOption = true" (closed)="activeAnyOption = false">
<ng-container *ngIf="optionInput.value.length > 0">
<mat-option
*ngFor="let option of filteredOptions"
[value]="option"
@@ -46,6 +45,5 @@
>
{{ option.fullPath || option.value }}
</mat-option>
</ng-container>
</mat-autocomplete>
</mat-form-field>
@@ -340,5 +340,17 @@ describe('SearchChipAutocompleteInputComponent', () => {
component.selectedOptions = [option];
expect(component.isOptionSelected(option)).toBeTrue();
});
it('should clear filteredOptions after input is cleared', async () => {
enterNewInputValue('option');
await fixture.whenStable();
fixture.detectChanges();
expect(component.filteredOptions.length).toBe(component.autocompleteOptions.length);
enterNewInputValue('');
await fixture.whenStable();
fixture.detectChanges();
expect(component.filteredOptions.length).toBe(component.autocompleteOptions.length);
});
});
});
@@ -33,7 +33,7 @@ import { ENTER } from '@angular/cdk/keycodes';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
import { MatChipInputEvent, MatChipsModule } from '@angular/material/chips';
import { EMPTY, Observable, timer } from 'rxjs';
import { Observable, timer } from 'rxjs';
import { debounce, startWith, tap } from 'rxjs/operators';
import { AutocompleteOption } from '../../models/autocomplete-option.interface';
import { CommonModule } from '@angular/common';
@@ -77,7 +77,7 @@ export class SearchChipAutocompleteInputComponent implements OnInit, OnChanges {
@Input()
filter = (options: AutocompleteOption[], value: string): AutocompleteOption[] => {
const filterValue = value.toLowerCase();
return options.filter((option) => option.value.toLowerCase().includes(filterValue)).slice(0, 15);
return options?.filter((option) => option.value.toLowerCase().includes(filterValue)).slice(0, 15) ?? [];
};
@Output()
@@ -104,11 +104,11 @@ export class SearchChipAutocompleteInputComponent implements OnInit, OnChanges {
.pipe(
startWith(''),
tap(() => (this.activeAnyOption = false)),
debounce((value: string) => (value ? timer(300) : EMPTY)),
debounce(() => timer(300)),
takeUntilDestroyed(this.destroyRef)
)
.subscribe((value: string) => {
this.filteredOptions = value ? this.filter(this.autocompleteOptions, value) : [];
this.filteredOptions = this.filter(this.autocompleteOptions, value);
this.inputChanged.emit(value);
});
this.onReset$?.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.reset());
@@ -24,6 +24,7 @@ import { AutocompleteField } from '../../models/autocomplete-option.interface';
import { TagService } from '../../../tag/services/tag.service';
import { SitesService } from '../../../common/services/sites.service';
import { SitePaging } from '@alfresco/js-api';
import { CategoryService } from '../../../category';
describe('SearchFilterAutocompleteChipsComponent', () => {
let component: SearchFilterAutocompleteChipsComponent;
@@ -211,4 +212,31 @@ describe('SearchFilterAutocompleteChipsComponent', () => {
done();
});
});
it('should still call sitesService.getSites when input is empty for LOCATION field', () => {
component.settings.field = AutocompleteField.LOCATION;
const getSitesSpy = spyOn(sitesService, 'getSites').and.returnValue(
of({
list: { entries: [], pagination: {} }
})
);
component.onInputChange('');
expect(getSitesSpy).toHaveBeenCalled();
});
it('should still call categoryService.searchCategories when input is empty for CATEGORIES field', () => {
component.settings.field = AutocompleteField.CATEGORIES;
const categoryService = TestBed.inject(CategoryService);
const searchSpy = spyOn(categoryService, 'searchCategories').and.returnValue(
of({
list: { entries: [], pagination: {} }
})
);
component.onInputChange('');
expect(searchSpy).toHaveBeenCalledWith('', 0, 15);
});
});
@@ -122,12 +122,10 @@ export class SearchFilterAutocompleteChipsComponent implements SearchWidget, OnI
}
onInputChange(value: string) {
if (value) {
if (this.settings.field === AutocompleteField.CATEGORIES) {
this.searchForExistingCategories(value);
} else if (this.settings.field === AutocompleteField.LOCATION) {
this.populateSitesOptions();
}
if (this.settings.field === AutocompleteField.CATEGORIES) {
this.searchForExistingCategories(value);
} else if (this.settings.field === AutocompleteField.LOCATION) {
this.populateSitesOptions();
}
}