From cfb9a505e49a6b793c2d7692f4795f190b8cf23a Mon Sep 17 00:00:00 2001 From: Mykyta Maliarchuk <84377976+nikita-web-ua@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:18:56 +0100 Subject: [PATCH] [ACS-10847] Location filter breaks the page when user value used (#11667) * [ACS-10847] Location filter breaks the page when user value used * [ACS-10847] simplify the ternary --- ...ilter-autocomplete-chips.component.spec.ts | 36 ++++++++++++++++++- ...rch-filter-autocomplete-chips.component.ts | 11 ++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.spec.ts b/lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.spec.ts index 7a9aebb416..37310f7c8f 100644 --- a/lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.spec.ts +++ b/lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.spec.ts @@ -19,7 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { SearchFilterAutocompleteChipsComponent } from './search-filter-autocomplete-chips.component'; import { EMPTY, of, ReplaySubject } from 'rxjs'; -import { AutocompleteField } from '../../models/autocomplete-option.interface'; +import { AutocompleteField, AutocompleteOption } 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'; @@ -212,6 +212,18 @@ describe('SearchFilterAutocompleteChipsComponent', () => { }); }); + it('should use id if present, otherwise value, in LOCATION query fragment', () => { + component.settings.field = AutocompleteField.LOCATION; + component.settings.autocompleteOptions = []; + component.selectedOptions = [ + { id: 'site1', value: 'Marketing' }, + { value: 'custom' } + ]; + component.submitValues(); + expect(component.context.queryFragments[component.id]) + .toBe('SITE:"site1" OR SITE:"custom"'); + }); + 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( @@ -238,4 +250,26 @@ describe('SearchFilterAutocompleteChipsComponent', () => { expect(searchSpy).toHaveBeenCalledWith('', 0, 15); }); + + describe('optionComparator', () => { + it('should return false if either option is undefined', () => { + expect(component.optionComparator(undefined, { value: 'A' })).toBe(false); + expect(component.optionComparator({ value: 'A' }, undefined)).toBe(false); + }); + + it('should compare by id if both have id', () => { + expect(component.optionComparator({ id: 'abc', value: 'B' } , { id: 'ABC', value: 'B' })).toBe(true); + expect(component.optionComparator({ id: 'abc', value: 'B' }, { id: 'def', value: 'B' })).toBe(false); + }); + + it('should compare by value if both have value and one has no id', () => { + expect(component.optionComparator({ value: 'A', id: 'id1' }, { value: 'a' })).toBe(true); + expect(component.optionComparator({ value: 'A', id: 'id1' }, { value: 'B' })).toBe(false); + }); + + it('should return false if only one has id or value', () => { + expect(component.optionComparator({ id: 'abc' } as AutocompleteOption, { value: 'abc' })).toBe(false); + expect(component.optionComparator({ value: 'abc' }, { id: 'abc' } as AutocompleteOption)).toBe(false); + }); + }); }); diff --git a/lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.ts b/lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.ts index cdf6f70f05..3ef3f75ab5 100644 --- a/lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.ts +++ b/lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.ts @@ -130,7 +130,14 @@ export class SearchFilterAutocompleteChipsComponent implements SearchWidget, OnI } optionComparator(option1: AutocompleteOption, option2: AutocompleteOption): boolean { - return option1.id ? option1.id.toUpperCase() === option2.id.toUpperCase() : option1.value.toUpperCase() === option2.value.toUpperCase(); + if (!option1 || !option2) return false; + if (option1.id && option2.id) { + return option1.id.toUpperCase() === option2.id.toUpperCase(); + } + if (option1.value && option2.value) { + return option1.value.toUpperCase() === option2.value.toUpperCase(); + } + return false; } private updateQuery(updateContext = true) { @@ -143,7 +150,7 @@ export class SearchFilterAutocompleteChipsComponent implements SearchWidget, OnI queryFragments = this.selectedOptions.map((val) => `${this.settings.field}:"workspace://SpacesStore/${val.id}"`); break; case AutocompleteField.LOCATION: - queryFragments = this.selectedOptions.map((val) => val.query ?? `${this.settings.field}:"${val.id}"`); + queryFragments = this.selectedOptions.map((val) => val.query ?? `${this.settings.field}:"${val.id || val.value}"`); break; default: queryFragments = this.selectedOptions.map((val) => val.query ?? `${this.settings.field}:"${val.value}"`);