mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
[MNT-25408]: ensure loader is not shown on nullish query (#4885)
* [MNT-25408]: ensure loader is not shown on nullish query * [MNT-25408]: moves config change processing to search inout component * [MNT-25408]: adds tests * [MNT-25408]: fixes logic; adds tests * [MNT-25408]: minor fix * [MNT-25408]: fixes build issue * [MNT-25408]: unit test fix
This commit is contained in:
+48
-2
@@ -29,7 +29,9 @@ import { AppStore } from '@alfresco/aca-shared/store';
|
||||
import { AppTestingModule } from '../../../testing/app-testing.module';
|
||||
import { SearchInputComponent } from './search-input.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { of } from 'rxjs';
|
||||
import { of, Subject } from 'rxjs';
|
||||
import { NavigationStart, Router, RouterEvent } from '@angular/router';
|
||||
import { SearchConfiguration, SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatMenuHarness } from '@angular/material/menu/testing';
|
||||
@@ -41,6 +43,9 @@ describe('SearchInputComponent', () => {
|
||||
let store: jasmine.SpyObj<Store<AppStore>>;
|
||||
let unitTestingUtils: UnitTestingUtils;
|
||||
let loader: HarnessLoader;
|
||||
let router: Router;
|
||||
const routerEventsSubject = new Subject<RouterEvent>();
|
||||
const configUpdatedSubject = new Subject<SearchConfiguration>();
|
||||
|
||||
function getFirstError(): string {
|
||||
const error = unitTestingUtils.getByDirective(MatError);
|
||||
@@ -77,18 +82,31 @@ describe('SearchInputComponent', () => {
|
||||
beforeEach(async () => {
|
||||
const storeSpy = jasmine.createSpyObj<Store<AppStore>>('Store', ['dispatch', 'pipe']);
|
||||
|
||||
const queryBuilderSpy = {
|
||||
configUpdated: configUpdatedSubject,
|
||||
removeFilterQuery: () => {}
|
||||
} as Partial<SearchQueryBuilderService>;
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AppTestingModule, SearchInputComponent],
|
||||
providers: [{ provide: Store, useValue: storeSpy }]
|
||||
providers: [
|
||||
{ provide: Store, useValue: storeSpy },
|
||||
{ provide: SearchQueryBuilderService, useValue: queryBuilderSpy }
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SearchInputComponent);
|
||||
component = fixture.componentInstance;
|
||||
store = TestBed.inject(Store) as jasmine.SpyObj<Store<AppStore>>;
|
||||
router = TestBed.inject(Router);
|
||||
store.pipe.and.returnValue(of([]));
|
||||
fixture.detectChanges();
|
||||
unitTestingUtils = new UnitTestingUtils(fixture.debugElement);
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
|
||||
Object.defineProperty(router, 'events', {
|
||||
get: () => routerEventsSubject.asObservable()
|
||||
});
|
||||
});
|
||||
|
||||
it('should show required error when field is empty and touched', async () => {
|
||||
@@ -147,4 +165,32 @@ describe('SearchInputComponent', () => {
|
||||
component.onSearchSubmit({ target: { value: '' } });
|
||||
expect(store.dispatch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('queryBuilder configUpdated handling', () => {
|
||||
it('should call searchByOption when searchedWord set and navigation has query params', () => {
|
||||
spyOn(component, 'searchByOption').and.stub();
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
component.searchedWord = 'term';
|
||||
|
||||
routerEventsSubject.next(new NavigationStart(1, '/path?q=term'));
|
||||
configUpdatedSubject.next({});
|
||||
|
||||
expect(component.searchByOption).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should NOT call searchByOption when searchedWord set and navigation has NO query params', () => {
|
||||
component.searchedWord = 'term';
|
||||
|
||||
routerEventsSubject.next(new NavigationStart(1, '/path'));
|
||||
|
||||
configUpdatedSubject.next({});
|
||||
spyOn(component, 'searchByOption').and.stub();
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(component.searchByOption).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+29
-2
@@ -28,7 +28,17 @@ import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { AppConfigService, NotificationService } from '@alfresco/adf-core';
|
||||
import { Component, DestroyRef, inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
|
||||
import { ActivatedRoute, NavigationSkipped, Params, PRIMARY_OUTLET, Router, UrlSegment, UrlSegmentGroup, UrlTree } from '@angular/router';
|
||||
import {
|
||||
ActivatedRoute,
|
||||
NavigationSkipped,
|
||||
NavigationStart,
|
||||
Params,
|
||||
PRIMARY_OUTLET,
|
||||
Router,
|
||||
UrlSegment,
|
||||
UrlSegmentGroup,
|
||||
UrlTree
|
||||
} from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { SearchInputControlComponent } from '../search-input-control/search-input-control.component';
|
||||
import { SearchNavigationService } from '../search-navigation.service';
|
||||
@@ -45,7 +55,7 @@ import { FormsModule } from '@angular/forms';
|
||||
import { extractSearchedWordFromEncodedQuery } from '../../../utils/aca-search-utils';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { merge } from 'rxjs/internal/observable/merge';
|
||||
import { filter, map, withLatestFrom } from 'rxjs';
|
||||
import { filter, map, startWith, withLatestFrom } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
imports: [
|
||||
@@ -140,6 +150,23 @@ export class SearchInputComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
|
||||
this.queryBuilder.configUpdated
|
||||
.pipe(
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
withLatestFrom(
|
||||
this.router.events.pipe(
|
||||
filter((event): event is NavigationStart => event instanceof NavigationStart),
|
||||
startWith(null)
|
||||
)
|
||||
)
|
||||
)
|
||||
.subscribe(([, navigationStartEvent]) => {
|
||||
const hasQueryParams = navigationStartEvent?.url.includes('?');
|
||||
if (this.searchedWord && hasQueryParams) {
|
||||
this.searchByOption();
|
||||
}
|
||||
});
|
||||
|
||||
this.appHookService.library400Error.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||
this.has400LibraryError = true;
|
||||
this.hasLibrariesConstraint = this.evaluateLibrariesConstraint();
|
||||
|
||||
+29
-19
@@ -1,8 +1,6 @@
|
||||
<aca-page-layout [class.aca-search-results-active-search-ai-input]="searchAiInputState.active">
|
||||
<div class="aca-page-layout-header">
|
||||
<aca-search-ai-input-container
|
||||
*ngIf="searchAiInputState.active"
|
||||
[agentId]="searchAiInputState.selectedAgentId" />
|
||||
<aca-search-ai-input-container *ngIf="searchAiInputState.active" [agentId]="searchAiInputState.selectedAgentId" />
|
||||
<div class="aca-header-container">
|
||||
<aca-search-input />
|
||||
<aca-bulk-actions-dropdown *ngIf="bulkActions && ('isBulkActionsAvailable' | isFeatureSupportedInCurrentAcs | async)" [items]="bulkActions" />
|
||||
@@ -26,23 +24,25 @@
|
||||
<div class="aca-content__advanced-filters--header">
|
||||
<p>{{ 'APP.BROWSE.SEARCH.ADVANCED_FILTERS' | translate }}</p>
|
||||
<div class="aca-content__advanced-filters--header--action-buttons">
|
||||
<button
|
||||
*ngIf="initialSavedSearch !== undefined else saveSearchButton"
|
||||
mat-button
|
||||
[disabled]="!encodedQuery"
|
||||
class="aca-content__save-search-action"
|
||||
title="{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate }}"
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate "
|
||||
[matMenuTriggerFor]="saveSearchOptionsMenu">
|
||||
{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate }}
|
||||
<mat-icon iconPositionEnd>keyboard_arrow_down</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="initialSavedSearch !== undefined; else saveSearchButton"
|
||||
mat-button
|
||||
[disabled]="!encodedQuery"
|
||||
class="aca-content__save-search-action"
|
||||
title="{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate }}"
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate"
|
||||
[matMenuTriggerFor]="saveSearchOptionsMenu"
|
||||
>
|
||||
{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate }}
|
||||
<mat-icon iconPositionEnd>keyboard_arrow_down</mat-icon>
|
||||
</button>
|
||||
<mat-menu #saveSearchOptionsMenu="matMenu">
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="editSavedSearch(initialSavedSearch)"
|
||||
title="{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_CHANGES' | translate }}"
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_CHANGES' | translate ">
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_CHANGES' | translate"
|
||||
>
|
||||
{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_CHANGES' | translate }}
|
||||
</button>
|
||||
<button
|
||||
@@ -50,7 +50,8 @@
|
||||
acaSaveSearch
|
||||
[acaSaveSearchQuery]="encodedQuery"
|
||||
title="{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_AS_NEW' | translate }}"
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_AS_NEW' | translate ">
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_AS_NEW' | translate"
|
||||
>
|
||||
{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_AS_NEW' | translate }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
@@ -62,16 +63,19 @@
|
||||
[disabled]="!encodedQuery"
|
||||
class="aca-content__save-search-action"
|
||||
title="{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate }}"
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate ">
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate"
|
||||
>
|
||||
{{ 'APP.BROWSE.SEARCH.SAVE_SEARCH.ACTION_BUTTON' | translate }}
|
||||
</button>
|
||||
</ng-template>
|
||||
<button
|
||||
[disabled]="!(areFiltersActive$ | async)"
|
||||
mat-button
|
||||
adf-reset-search
|
||||
class="aca-content__reset-action"
|
||||
title="{{ 'APP.BROWSE.SEARCH.RESET_ACTION' | translate }}"
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.RESET_ACTION' | translate ">
|
||||
[attr.aria-label]="'APP.BROWSE.SEARCH.RESET_ACTION' | translate"
|
||||
>
|
||||
{{ 'APP.BROWSE.SEARCH.RESET' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -97,7 +101,13 @@
|
||||
(node-dblclick)="handleNodeClick($event)"
|
||||
>
|
||||
<data-columns>
|
||||
<data-column id="app.search.thumbnail" key="$thumbnail" type="image" [sr-title]="'ADF-DOCUMENT-LIST.LAYOUT.THUMBNAIL'" [sortable]="false">
|
||||
<data-column
|
||||
id="app.search.thumbnail"
|
||||
key="$thumbnail"
|
||||
type="image"
|
||||
[sr-title]="'ADF-DOCUMENT-LIST.LAYOUT.THUMBNAIL'"
|
||||
[sortable]="false"
|
||||
>
|
||||
<ng-template let-context>
|
||||
<aca-custom-thumbnail-column [context]="context" />
|
||||
</ng-template>
|
||||
|
||||
+76
-11
@@ -22,13 +22,13 @@
|
||||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
|
||||
import { SearchResultsComponent } from './search-results.component';
|
||||
import { AppConfigService, NotificationService, TranslationService } from '@alfresco/adf-core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { NavigateToFolder } from '@alfresco/aca-shared/store';
|
||||
import { Pagination, SearchRequest } from '@alfresco/js-api';
|
||||
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { FacetFieldBucket, SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { ActivatedRoute, Event, NavigationStart, Params, Router } from '@angular/router';
|
||||
import { BehaviorSubject, Observable, of, Subject, throwError } from 'rxjs';
|
||||
import { AppTestingModule } from '../../../testing/app-testing.module';
|
||||
@@ -60,9 +60,11 @@ describe('SearchComponent', () => {
|
||||
let showErrorSpy: jasmine.Spy<(message: string, action?: string, interpolateArgs?: any, showAction?: boolean) => MatSnackBarRef<any>>;
|
||||
let showInfoSpy: jasmine.Spy<(message: string, action?: string, interpolateArgs?: any, showAction?: boolean) => MatSnackBarRef<any>>;
|
||||
let loader: HarnessLoader;
|
||||
let updatedSubjectMock: Subject<SearchRequest>;
|
||||
|
||||
const editSavedSearchesSpy = jasmine.createSpy('editSavedSearch');
|
||||
const getSavedSearchButton = (): HTMLButtonElement => fixture.nativeElement.querySelector('.aca-content__save-search-action');
|
||||
const getResetSearchButton = (): HTMLButtonElement => fixture.nativeElement.querySelector('.aca-content__reset-action');
|
||||
|
||||
const encodeQuery = (query: any): string => {
|
||||
return Buffer.from(JSON.stringify(query)).toString('base64');
|
||||
@@ -72,6 +74,7 @@ describe('SearchComponent', () => {
|
||||
params = new BehaviorSubject({ q: 'TYPE: "cm:folder" AND %28=cm: name: email OR cm: name: budget%29' });
|
||||
queryParams = new Subject();
|
||||
routerEvents = new Subject();
|
||||
updatedSubjectMock = new Subject();
|
||||
|
||||
const routerMock = jasmine.createSpyObj<Router>('Router', ['navigate'], {
|
||||
url: '/mock-search-url',
|
||||
@@ -92,9 +95,7 @@ describe('SearchComponent', () => {
|
||||
{
|
||||
provide: SavedSearchesContextService,
|
||||
useValue: {
|
||||
getSavedSearches: jasmine
|
||||
.createSpy('getSavedSearches')
|
||||
.and.returnValue(of([{ name: 'test', encodedUrl: encodeQuery({ name: 'test' }), order: 0 }])),
|
||||
savedSearches$: of([{ name: 'test', encodedUrl: encodeQuery({ name: 'test' }), order: 0 }]),
|
||||
editSavedSearch: editSavedSearchesSpy
|
||||
}
|
||||
},
|
||||
@@ -125,6 +126,8 @@ describe('SearchComponent', () => {
|
||||
router = TestBed.inject(Router);
|
||||
route = TestBed.inject(ActivatedRoute);
|
||||
|
||||
queryBuilder.updated = updatedSubjectMock;
|
||||
|
||||
const notificationService = TestBed.inject(NotificationService);
|
||||
showErrorSpy = spyOn(notificationService, 'showError');
|
||||
showInfoSpy = spyOn(notificationService, 'showInfo');
|
||||
@@ -257,12 +260,6 @@ describe('SearchComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should update the user query whenever configuration changed', () => {
|
||||
component.searchedWord = 'orange';
|
||||
queryBuilder.configUpdated.next({ 'app:fields': ['cm:tag'] } as any);
|
||||
expect(queryBuilder.userQuery).toBe(`((cm:tag:"orange*"))`);
|
||||
});
|
||||
|
||||
it('should get initial saved search when url matches', () => {
|
||||
route.queryParams = of({ q: encodeQuery({ name: 'test' }) });
|
||||
component.ngOnInit();
|
||||
@@ -372,5 +369,73 @@ describe('SearchComponent', () => {
|
||||
expect(queryBuilder.userQuery).toBe('(test)');
|
||||
});
|
||||
|
||||
it('should set loading to true in updated stream for non-nullish query', fakeAsync(() => {
|
||||
spyOn(queryBuilder, 'execute').and.stub();
|
||||
|
||||
expect(component.isLoading).toBeFalse();
|
||||
|
||||
updatedSubjectMock.next(null);
|
||||
|
||||
tick();
|
||||
|
||||
expect(component.isLoading).toBeFalse();
|
||||
|
||||
updatedSubjectMock.next({} as SearchRequest);
|
||||
|
||||
tick();
|
||||
|
||||
expect(component.isLoading).toBeTrue();
|
||||
|
||||
flush();
|
||||
}));
|
||||
|
||||
describe('reset button', () => {
|
||||
it('should enable the reset button when there are queryFragments', fakeAsync(() => {
|
||||
queryBuilder.queryFragmentsUpdate.next({ test: 'test-value' });
|
||||
|
||||
tick();
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const resetBtn = getResetSearchButton();
|
||||
|
||||
expect(resetBtn).toBeDefined();
|
||||
expect(resetBtn.getAttribute('disabled')).toBeFalsy();
|
||||
|
||||
flush();
|
||||
}));
|
||||
|
||||
it('should enable the reset button when there are userFacetBuckets', fakeAsync(() => {
|
||||
queryBuilder.userFacetBucketsUpdate.next({ test: [{ label: 'test-value' }] as FacetFieldBucket[] });
|
||||
|
||||
tick();
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const resetBtn = getResetSearchButton();
|
||||
|
||||
expect(resetBtn).toBeDefined();
|
||||
expect(resetBtn.getAttribute('disabled')).toBeFalsy();
|
||||
|
||||
flush();
|
||||
}));
|
||||
|
||||
it('should disable the reset button when there are no filters applied', fakeAsync(() => {
|
||||
queryBuilder.queryFragmentsUpdate.next({});
|
||||
queryBuilder.userFacetBucketsUpdate.next({});
|
||||
|
||||
tick();
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const resetBtn = getResetSearchButton();
|
||||
|
||||
expect(resetBtn).toBeDefined();
|
||||
expect(resetBtn.getAttribute('disabled')).toBeTruthy();
|
||||
|
||||
flush();
|
||||
}));
|
||||
});
|
||||
|
||||
testHeader(SearchResultsComponent, false);
|
||||
});
|
||||
|
||||
+19
-17
@@ -64,7 +64,7 @@ import {
|
||||
} from '@alfresco/aca-shared';
|
||||
import { SearchSortingDefinition } from '@alfresco/adf-content-services/lib/search/models/search-sorting-definition.interface';
|
||||
import { filter, first, map, startWith, switchMap, take, tap, toArray } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { AsyncPipe, CommonModule } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { SearchInputComponent } from '../search-input/search-input.component';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
@@ -84,7 +84,7 @@ import {
|
||||
formatSearchTerm
|
||||
} from '../../../utils/aca-search-utils';
|
||||
import { SaveSearchDirective } from '../search-save/directive/save-search.directive';
|
||||
import { combineLatest, of } from 'rxjs';
|
||||
import { combineLatest, merge, Observable, of } from 'rxjs';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { IsFeatureSupportedInCurrentAcsPipe } from '../../../pipes/is-feature-supported.pipe';
|
||||
@@ -123,7 +123,8 @@ import { SavedSearchesContextService } from '../../../services/saved-searches-co
|
||||
BulkActionsDropdownComponent,
|
||||
SearchAiInputContainerComponent,
|
||||
SaveSearchDirective,
|
||||
IsFeatureSupportedInCurrentAcsPipe
|
||||
IsFeatureSupportedInCurrentAcsPipe,
|
||||
AsyncPipe
|
||||
],
|
||||
selector: 'aca-search-results',
|
||||
templateUrl: './search-results.component.html',
|
||||
@@ -135,6 +136,8 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
|
||||
|
||||
infoDrawerPreview$ = this.store.select(infoDrawerPreview);
|
||||
|
||||
protected readonly areFiltersActive$: Observable<boolean>;
|
||||
|
||||
searchedWord: string;
|
||||
queryParamName = 'q';
|
||||
data: ResultSetPaging;
|
||||
@@ -168,8 +171,14 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
|
||||
|
||||
this.queryBuilder.configUpdated.pipe(takeUntilDestroyed()).subscribe((searchConfig) => {
|
||||
this.searchConfig = searchConfig;
|
||||
this.updateUserQuery();
|
||||
});
|
||||
|
||||
this.areFiltersActive$ = merge(this.queryBuilder.queryFragmentsUpdate, this.queryBuilder.userFacetBucketsUpdate).pipe(
|
||||
takeUntilDestroyed(),
|
||||
map((v) => {
|
||||
return Object.values(v).some((filterValue) => (Array.isArray(filterValue) ? filterValue.length > 0 : !!filterValue));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -179,12 +188,10 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
|
||||
this.sorting = this.getSorting();
|
||||
|
||||
this.subscriptions.push(
|
||||
this.queryBuilder.updated.subscribe((query) => {
|
||||
this.queryBuilder.updated.pipe(filter(Boolean)).subscribe(() => {
|
||||
this.isLoading = true;
|
||||
if (query) {
|
||||
this.sorting = this.getSorting();
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
this.sorting = this.getSorting();
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}),
|
||||
|
||||
this.queryBuilder.executed.subscribe((data) => {
|
||||
@@ -211,7 +218,7 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
|
||||
.pipe(
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
switchMap((params) =>
|
||||
this.savedSearchesService.getSavedSearches().pipe(
|
||||
this.savedSearchesService.savedSearches$.pipe(
|
||||
first(),
|
||||
map((savedSearches) => savedSearches.find((savedSearch) => savedSearch.encodedUrl === encodeURIComponent(params[this.queryParamName])))
|
||||
)
|
||||
@@ -224,18 +231,18 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
|
||||
combineLatest([
|
||||
this.route.queryParams,
|
||||
this.router.events.pipe(
|
||||
filter((e): e is NavigationStart => e instanceof NavigationStart),
|
||||
filter((event): event is NavigationStart => event instanceof NavigationStart),
|
||||
startWith(null)
|
||||
)
|
||||
])
|
||||
.pipe(
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
tap(([params]) => {
|
||||
this.queryBuilder.userQuery = '';
|
||||
this.encodedQuery = params[this.queryParamName];
|
||||
this.isLoading = !!this.encodedQuery;
|
||||
|
||||
this.searchedWord = extractSearchedWordFromEncodedQuery(this.encodedQuery);
|
||||
this.updateUserQuery();
|
||||
|
||||
const filtersFromEncodedQuery = extractFiltersFromEncodedQuery(this.encodedQuery);
|
||||
this.queryBuilder.populateFilters.next(filtersFromEncodedQuery || {});
|
||||
@@ -355,11 +362,6 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
private updateUserQuery(): void {
|
||||
const updatedUserQuery = formatSearchTerm(this.searchedWord, this.searchConfig['app:fields']);
|
||||
this.queryBuilder.userQuery = updatedUserQuery;
|
||||
}
|
||||
|
||||
private shouldExecuteQuery(navigationStartEvent: NavigationStart | null, query: string | undefined): boolean {
|
||||
const hasQueryChanged = query !== this.previousEncodedQuery;
|
||||
this.previousEncodedQuery = query;
|
||||
|
||||
Reference in New Issue
Block a user