diff --git a/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters/process-filters-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters/process-filters-cloud.component.spec.ts index 5a6cd7a1be..8c90e5f42a 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters/process-filters-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters/process-filters-cloud.component.spec.ts @@ -95,6 +95,12 @@ describe('ProcessFiltersCloudComponent', () => { getProcessNotificationSubscriptionSpy = spyOn(processFilterService, 'getProcessNotificationSubscription').and.returnValue(of([])); }; + const bindAppName = async (appName = 'my-app-1') => { + fixture.componentRef.setInput('appName', appName); + fixture.detectChanges(); + await fixture.whenStable(); + }; + afterEach(() => { fixture.destroy(); }); @@ -191,8 +197,7 @@ describe('ProcessFiltersCloudComponent', () => { const change = new SimpleChange(null, appName, true); component.ngOnChanges({ appName: change }); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); const filterButton = fixture.debugElement.nativeElement.querySelector(`[data-automation-id="${mockProcessFilters[0].key}_filter"]`); filterButton.click(); @@ -210,11 +215,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should apply active CSS class on filter click', async () => { component.enableNotifications = true; - component.appName = 'mock-app-name'; - const appNameChange = new SimpleChange(null, 'mock-app-name', true); - component.ngOnChanges({ appName: appNameChange }); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName('mock-app-name'); let link = fixture.debugElement.query(By.css(`[data-automation-id="${allProcessesFilterKey}_filter"]`)).nativeElement; expect(link.getAttribute('href')).toBe(`/process-list-cloud?filterId=${allProcessesFilterId}`); @@ -230,12 +231,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should add aria-current attribute with value "page" to the active filter', async () => { component.enableNotifications = true; - component.appName = 'mock-app-name'; - const appNameChange = new SimpleChange(null, 'mock-app-name', true); - - component.ngOnChanges({ appName: appNameChange }); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName('mock-app-name'); const link = fixture.debugElement.query(By.css(`[data-automation-id="${allProcessesFilterKey}_filter"]`)).nativeElement; expect(link.getAttribute('aria-current')).toBe('page'); @@ -243,12 +239,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should not have aria-current attribute when filter is not active', async () => { component.enableNotifications = true; - component.appName = 'mock-app-name'; - const appNameChange = new SimpleChange(null, 'mock-app-name', true); - - component.ngOnChanges({ appName: appNameChange }); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName('mock-app-name'); const link = fixture.debugElement.query(By.css(`[data-automation-id="${mockProcessFilters[1].key}_filter"]`)).nativeElement; expect(link.getAttribute('aria-current')).toBeNull(); @@ -262,11 +253,7 @@ describe('ProcessFiltersCloudComponent', () => { }); it('should attach specific icon for each filter if hasIcon is true', async () => { - const change = new SimpleChange(undefined, 'my-app-1', true); - component.ngOnChanges({ appName: change }); - - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.showIcons = true; @@ -283,22 +270,14 @@ describe('ProcessFiltersCloudComponent', () => { it('should not attach icons for each filter if hasIcon is false', async () => { component.showIcons = false; - const change = new SimpleChange(undefined, 'my-app-1', true); - component.ngOnChanges({ appName: change }); - - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); const filterIcons = await loader.getAllHarnesses(MatIconHarness.with({ selector: '[data-automation-id="adf-filter-icon"]' })); expect(filterIcons.length).toBe(0); }); it('should display the filters', async () => { - const change = new SimpleChange(undefined, 'my-app-1', true); - component.ngOnChanges({ appName: change }); - - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.showIcons = true; @@ -316,12 +295,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should emit success with the filters when filters are loaded', async () => { const successSpy = spyOn(component.success, 'emit'); - const appName = 'my-app-1'; - const change = new SimpleChange(null, appName, true); - - component.ngOnChanges({ appName: change }); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); expect(successSpy).toHaveBeenCalledWith(mockProcessFilters); expect(component.filters).toBeDefined(); @@ -332,24 +306,14 @@ describe('ProcessFiltersCloudComponent', () => { }); it('should not select any filter as default', async () => { - const appName = 'my-app-1'; - const change = new SimpleChange(null, appName, true); - - component.ngOnChanges({ appName: change }); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); expect(component.currentFilter).toBeUndefined(); }); it('should filterClicked emit when a filter is clicked from the UI', async () => { const filterClickedSpy = spyOn(component.filterClicked, 'emit'); - const appName = 'my-app-1'; - const change = new SimpleChange(null, appName, true); - component.ngOnChanges({ appName: change }); - - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); const filterButton = fixture.debugElement.nativeElement.querySelector(`[data-automation-id="${mockProcessFilters[0].key}_filter"]`); filterButton.click(); @@ -367,17 +331,13 @@ describe('ProcessFiltersCloudComponent', () => { await configureTestingModule('GET'); }); - it('should emit an error with a bad response', () => { + it('should emit an error with a bad response', async () => { getProcessFiltersSpy.and.returnValue(throwError('wrong request')); - - const appName = 'my-app-1'; - const change = new SimpleChange(null, appName, true); - let lastValue: any; component.error.subscribe((err) => (lastValue = err)); - component.ngOnChanges({ appName: change }); - fixture.detectChanges(); + await bindAppName(); + expect(lastValue).toBeDefined(); }); @@ -394,8 +354,7 @@ describe('ProcessFiltersCloudComponent', () => { const filterSelectedSpy = spyOn(component.filterSelected, 'emit'); const change = new SimpleChange(null, { name: 'FakeRunningProcesses' }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toEqual(mockProcessFilters[1]); @@ -406,8 +365,7 @@ describe('ProcessFiltersCloudComponent', () => { const filterSelectedSpy = spyOn(component.filterSelected, 'emit'); const change = new SimpleChange(null, { key: 'completed-processes' }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toEqual(mockProcessFilters[2]); @@ -418,8 +376,7 @@ describe('ProcessFiltersCloudComponent', () => { const filterSelectedSpy = spyOn(component.filterSelected, 'emit'); const change = new SimpleChange(null, { index: 2 }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toEqual(mockProcessFilters[2]); @@ -430,8 +387,7 @@ describe('ProcessFiltersCloudComponent', () => { const filterSelectedSpy = spyOn(component.filterSelected, 'emit'); const change = new SimpleChange(null, { id: '12' }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toEqual(mockProcessFilters[2]); @@ -450,8 +406,7 @@ describe('ProcessFiltersCloudComponent', () => { const filterClickedSpy = spyOn(component.filterClicked, 'emit'); const change = new SimpleChange(null, { id: '10' }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toBe(mockProcessFilters[0]); @@ -573,21 +528,16 @@ describe('ProcessFiltersCloudComponent', () => { }); describe('Highlight Selected Filter', () => { - it('should make subscription', () => { + it('should make subscription', async () => { component.enableNotifications = true; - component.appName = 'mock-app-name'; - const appNameChange = new SimpleChange(null, 'mock-app-name', true); - component.ngOnChanges({ appName: appNameChange }); - fixture.detectChanges(); + await bindAppName('mock-app-name'); expect(getProcessNotificationSubscriptionSpy).toHaveBeenCalled(); }); - it('should not make subscription when notifications are disabled', () => { + it('should not make subscription when notifications are disabled', async () => { const appConfigService = TestBed.inject(AppConfigService); spyOn(appConfigService, 'get').and.callFake((key: string, defaultValue: any) => (key === 'notifications' ? false : defaultValue)); - component.appName = 'mock-app-name'; - - fixture.detectChanges(); + await bindAppName('mock-app-name'); expect(getProcessNotificationSubscriptionSpy).not.toHaveBeenCalled(); }); diff --git a/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters/process-filters-cloud.component.ts b/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters/process-filters-cloud.component.ts index 70611d4139..9e7fc7ba5f 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters/process-filters-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters/process-filters-cloud.component.ts @@ -16,12 +16,12 @@ */ import { Component, DestroyRef, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; -import { Observable } from 'rxjs'; +import { EMPTY, Observable } from 'rxjs'; import { ProcessFilterCloudService } from '../../services/process-filter-cloud.service'; import { ProcessFilterCloudModel } from '../../models/process-filter-cloud.model'; import { AppConfigService, IconModule, TranslationService } from '@alfresco/adf-core'; import { FilterParamsModel } from '../../../../task/task-filters/models/filter-cloud.model'; -import { debounceTime, map, tap } from 'rxjs/operators'; +import { catchError, debounceTime, map, shareReplay, tap } from 'rxjs/operators'; import { ProcessListCloudService } from '../../../process-list/services/process-list-cloud.service'; import { ProcessFilterCloudAdapter } from '../../../process-list/models/process-cloud-query-request.model'; import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop'; @@ -83,6 +83,7 @@ export class ProcessFiltersCloudComponent implements OnInit, OnChanges { notificationDebounceTime = 3000; currentFiltersValues: { [key: string]: number } = {}; updatedFiltersSet = new Set(); + private filtersLoadedFor?: string; private readonly destroyRef = inject(DestroyRef); private readonly processFilterCloudService = inject(ProcessFilterCloudService); @@ -95,7 +96,7 @@ export class ProcessFiltersCloudComponent implements OnInit, OnChanges { ngOnInit() { this.enableNotifications = this.appConfigService.get('notifications', true); this.notificationDebounceTime = this.appConfigService.get('notificationDebounceTime', 3000); - if (this.appName === '') { + if (!this.filtersLoadedFor) { this.getFilters(this.appName); } this.initProcessNotification(); @@ -118,9 +119,11 @@ export class ProcessFiltersCloudComponent implements OnInit, OnChanges { * @param appName application name */ getFilters(appName: string): void { - this.filters$ = this.processFilterCloudService.getProcessFilters(appName); + this.filtersLoadedFor = appName; + const filters$ = this.processFilterCloudService.getProcessFilters(appName).pipe(shareReplay({ bufferSize: 1, refCount: true })); + this.filters$ = filters$.pipe(catchError(() => EMPTY)); - this.filters$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ + filters$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ next: (res) => { this.resetFilter(); this.filters = res || []; diff --git a/lib/process-services-cloud/src/lib/task/task-filters/components/service-task-filters/service-task-filters-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-filters/components/service-task-filters/service-task-filters-cloud.component.ts index e88bd4d656..5f9f2a7268 100644 --- a/lib/process-services-cloud/src/lib/task/task-filters/components/service-task-filters/service-task-filters-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/task/task-filters/components/service-task-filters/service-task-filters-cloud.component.ts @@ -16,7 +16,8 @@ */ import { Component, EventEmitter, inject, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core'; -import { Observable } from 'rxjs'; +import { EMPTY, Observable } from 'rxjs'; +import { catchError, shareReplay } from 'rxjs/operators'; import { FilterParamsModel, ServiceTaskFilterCloudModel } from '../../models/filter-cloud.model'; import { BaseTaskFiltersCloudComponent } from '../base-task-filters-cloud.component'; import { ServiceTaskFilterCloudService } from '../../services/service-task-filter-cloud.service'; @@ -46,12 +47,15 @@ export class ServiceTaskFiltersCloudComponent extends BaseTaskFiltersCloudCompon filters$: Observable; filters: ServiceTaskFilterCloudModel[] = []; currentFilter: ServiceTaskFilterCloudModel; + private filtersLoadedFor?: string; private readonly serviceTaskFilterCloudService = inject(ServiceTaskFilterCloudService); private readonly translationService = inject(TranslationService); ngOnInit() { - this.getFilters(this.appName); + if (!this.filtersLoadedFor) { + this.getFilters(this.appName); + } } ngOnChanges(changes: SimpleChanges) { @@ -70,9 +74,11 @@ export class ServiceTaskFiltersCloudComponent extends BaseTaskFiltersCloudCompon * @param appName application name */ getFilters(appName: string): void { - this.filters$ = this.serviceTaskFilterCloudService.getTaskListFilters(appName); + this.filtersLoadedFor = appName; + const filters$ = this.serviceTaskFilterCloudService.getTaskListFilters(appName).pipe(shareReplay({ bufferSize: 1, refCount: true })); + this.filters$ = filters$.pipe(catchError(() => EMPTY)); - this.filters$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe( + filters$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe( (res: ServiceTaskFilterCloudModel[]) => { this.resetFilter(); this.filters = res || []; diff --git a/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters/task-filters-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters/task-filters-cloud.component.spec.ts index 4ec74ee071..5fb1f21daf 100644 --- a/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters/task-filters-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters/task-filters-cloud.component.spec.ts @@ -93,6 +93,12 @@ describe('TaskFiltersCloudComponent', () => { await RouterTestingHarness.create(); }; + const bindAppName = async (appName = 'my-app-1') => { + fixture.componentRef.setInput('appName', appName); + fixture.detectChanges(); + await fixture.whenStable(); + }; + afterEach(() => { fixture.destroy(); }); @@ -187,8 +193,7 @@ describe('TaskFiltersCloudComponent', () => { it('should filterClicked emit when a filter is clicked from the UI', async () => { spyOn(component.filterClicked, 'emit'); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); const filterButton = fixture.debugElement.nativeElement.querySelector(`[data-automation-id="${fakeGlobalFilter[0].key}_filter"]`); filterButton.click(); @@ -217,10 +222,9 @@ describe('TaskFiltersCloudComponent', () => { expect(filterCounters[0].nativeElement.innerText).toContain('11'); }); - it('should update filter counter when notification received', () => { - component.appName = 'my-app-1'; + it('should update filter counter when notification received', async () => { component.showIcons = true; - fixture.detectChanges(); + await bindAppName(); const updatedFilterCounters = fixture.debugElement.queryAll(By.css('span.adf-active')); expect(updatedFilterCounters.length).toBe(1); @@ -238,12 +242,11 @@ describe('TaskFiltersCloudComponent', () => { expect(updatedFilterCounters.length).toBe(0); })); - it('should reset filter counter notification when filter is selected', () => { + it('should reset filter counter notification when filter is selected', async () => { spyOn(appConfigService, 'get').and.returnValue(true); const change = new SimpleChange(null, { key: fakeGlobalFilter[0].key }, true); - component.appName = 'my-app-1'; component.showIcons = true; - fixture.detectChanges(); + await bindAppName(); let updatedFilterCounters = fixture.debugElement.queryAll(By.css('span.adf-active')); expect(updatedFilterCounters.length).toBe(1); @@ -258,10 +261,9 @@ describe('TaskFiltersCloudComponent', () => { expect(updatedFilterCounters.length).toBe(0); }); - it('should update filter counter when filter is selected', () => { - component.appName = 'my-app-1'; + it('should update filter counter when filter is selected', async () => { component.showIcons = true; - fixture.detectChanges(); + await bindAppName(); const filterButton = fixture.debugElement.nativeElement.querySelector(`[data-automation-id="${fakeGlobalFilter[0].key}_filter"]`); filterButton.click(); @@ -334,14 +336,13 @@ describe('TaskFiltersCloudComponent', () => { }); describe('searchApiMethod set to POST', () => { - beforeEach(() => { - configureTestingModule('POST'); + beforeEach(async () => { + await configureTestingModule('POST'); component.showIcons = true; - component.appName = 'my-app-1'; }); it('should attach specific icon for each filter if hasIcon is true', async () => { - fixture.detectChanges(); + await bindAppName(); const filterIcons = await loader.getAllHarnesses(MatIconHarness.with({ selector: '[data-automation-id="adf-filter-icon"]' })); @@ -354,14 +355,14 @@ describe('TaskFiltersCloudComponent', () => { it('should not attach icons for each filter if showIcons is false', async () => { component.showIcons = false; - fixture.detectChanges(); + await bindAppName(); const filterIcons = await loader.getAllHarnesses(MatIconHarness.with({ selector: '[data-automation-id="adf-filter-icon"]' })); expect(filterIcons.length).toBe(0); }); - it('should display the filters', () => { - fixture.detectChanges(); + it('should display the filters', async () => { + await bindAppName(); const filters = fixture.debugElement.queryAll(By.css('.adf-task-filters__entry')); @@ -372,14 +373,14 @@ describe('TaskFiltersCloudComponent', () => { expect(filters[2].nativeElement.innerText).toContain('FakeMyTasks2'); }); - it('should not select any filter as default', () => { - fixture.detectChanges(); + it('should not select any filter as default', async () => { + await bindAppName(); expect(component.currentFilter).toBeUndefined(); }); it('should emit filterClicked when a filter is clicked from the UI', async () => { - fixture.detectChanges(); + await bindAppName(); const spy = spyOn(component.filterClicked, 'emit'); const filterButton = await loader.getHarness( @@ -390,8 +391,8 @@ describe('TaskFiltersCloudComponent', () => { expect(spy).toHaveBeenCalledWith(fakeGlobalFilter[0]); }); - it('should display filter counter if property set to true', () => { - fixture.detectChanges(); + it('should display filter counter if property set to true', async () => { + await bindAppName(); const filterCounters = fixture.debugElement.queryAll(By.css('.adf-task-filters__entry-counter')); @@ -400,8 +401,8 @@ describe('TaskFiltersCloudComponent', () => { expect(filterCounters[0].nativeElement.innerText).toContain('11'); }); - it('should update filter counter when notification received', () => { - fixture.detectChanges(); + it('should update filter counter when notification received', async () => { + await bindAppName(); const updatedFilterCounters = fixture.debugElement.queryAll(By.css('span.adf-active')); @@ -410,17 +411,17 @@ describe('TaskFiltersCloudComponent', () => { expect(component.counters['fake-involved-tasks']).toBeDefined(); }); - it('should not update filter counter when notifications are disabled from app.config.json', () => { + it('should not update filter counter when notifications are disabled from app.config.json', async () => { spyOn(appConfigService, 'get').and.returnValue(false); - fixture.detectChanges(); + await bindAppName(); expect(fixture.componentInstance.counters).toBeDefined(); const updatedFilterCounters = fixture.debugElement.queryAll(By.css('span.adf-active')); expect(updatedFilterCounters.length).toBe(0); }); - it('should reset filter counter notification when filter is selected', () => { - fixture.detectChanges(); + it('should reset filter counter notification when filter is selected', async () => { + await bindAppName(); spyOn(appConfigService, 'get').and.returnValue(true); const change = new SimpleChange(null, { key: fakeGlobalFilter[0].key }, true); @@ -438,7 +439,7 @@ describe('TaskFiltersCloudComponent', () => { }); it('should update filter counter when filter is selected', async () => { - fixture.detectChanges(); + await bindAppName(); const filterButton = await loader.getHarness( MatNavListItemHarness.with({ selector: `[data-automation-id="${fakeGlobalFilter[0].key}_filter"]` }) @@ -450,8 +451,8 @@ describe('TaskFiltersCloudComponent', () => { }); describe('API agnostic', () => { - beforeEach(() => { - configureTestingModule('GET'); + beforeEach(async () => { + await configureTestingModule('GET'); }); it('should emit an error with a bad response', (done) => { @@ -475,8 +476,7 @@ describe('TaskFiltersCloudComponent', () => { const filterSelectedSpy = spyOn(component.filterSelected, 'emit'); const change = new SimpleChange(null, { name: 'FakeMyTasks2' }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toEqual(fakeGlobalFilter[2]); @@ -496,8 +496,7 @@ describe('TaskFiltersCloudComponent', () => { const filterSelectedSpy = spyOn(component.filterSelected, 'emit'); const change = new SimpleChange(null, { index: 2 }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toEqual(fakeGlobalFilter[2]); @@ -508,8 +507,7 @@ describe('TaskFiltersCloudComponent', () => { const filterSelectedSpy = spyOn(component.filterSelected, 'emit'); const change = new SimpleChange(null, { id: '12' }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toEqual(fakeGlobalFilter[2]); @@ -520,8 +518,7 @@ describe('TaskFiltersCloudComponent', () => { const filterSelectedSpy = spyOn(component.filterSelected, 'emit'); const change = new SimpleChange(null, { key: 'fake-my-task2' }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toEqual(fakeGlobalFilter[2]); @@ -532,8 +529,7 @@ describe('TaskFiltersCloudComponent', () => { const filterClickedSpy = spyOn(component.filterClicked, 'emit'); const change = new SimpleChange(null, { id: '10' }, true); - fixture.detectChanges(); - await fixture.whenStable(); + await bindAppName(); component.ngOnChanges({ filterParam: change }); expect(component.currentFilter).toBe(fakeGlobalFilter[0]); @@ -558,6 +554,18 @@ describe('TaskFiltersCloudComponent', () => { expect(component.getFilters).toHaveBeenCalledWith(appName); }); + it('should load filters only once when appName is bound', async () => { + await bindAppName(); + + expect(getTaskListFiltersSpy).toHaveBeenCalledTimes(1); + }); + + it('should load filters on init when appName is not bound', () => { + fixture.detectChanges(); + + expect(getTaskListFiltersSpy).toHaveBeenCalledTimes(1); + }); + it('should emit filter key when filter counter is set for first time', () => { component.currentFiltersValues = {}; const fakeFilterKey = 'testKey'; diff --git a/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters/task-filters-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters/task-filters-cloud.component.ts index cf09f583d6..3c553aa7c2 100644 --- a/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters/task-filters-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/task/task-filters/components/task-filters/task-filters-cloud.component.ts @@ -16,11 +16,11 @@ */ import { Component, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; -import { Observable } from 'rxjs'; +import { EMPTY, Observable } from 'rxjs'; import { TaskFilterCloudService } from '../../services/task-filter-cloud.service'; import { FilterParamsModel, TaskFilterCloudModel } from '../../models/filter-cloud.model'; import { AppConfigService, IconModule, TranslationService } from '@alfresco/adf-core'; -import { debounceTime, map, tap } from 'rxjs/operators'; +import { catchError, debounceTime, map, shareReplay, tap } from 'rxjs/operators'; import { BaseTaskFiltersCloudComponent } from '../base-task-filters-cloud.component'; import { TaskDetailsCloudModel } from '../../../models/task-details-cloud.model'; import { TaskCloudEngineEvent } from '../../../../models/engine-event-cloud.model'; @@ -68,6 +68,7 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp enableNotifications = true; notificationDebounceTime = 3000; currentFiltersValues: { [key: string]: number } = {}; + private filtersLoadedFor?: string; private readonly taskFilterCloudService = inject(TaskFilterCloudService); private readonly taskListCloudService = inject(TaskListCloudService); @@ -79,7 +80,9 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp ngOnInit() { this.enableNotifications = this.appConfigService.get('notifications', true); this.notificationDebounceTime = this.appConfigService.get('notificationDebounceTime', 3000); - this.getFilters(this.appName); + if (!this.filtersLoadedFor) { + this.getFilters(this.appName); + } this.initFilterCounterNotifications(); this.getFilterKeysAfterExternalRefreshing(); } @@ -100,9 +103,11 @@ export class TaskFiltersCloudComponent extends BaseTaskFiltersCloudComponent imp * @param appName application name */ getFilters(appName: string): void { - this.filters$ = this.taskFilterCloudService.getTaskListFilters(appName); + this.filtersLoadedFor = appName; + const filters$ = this.taskFilterCloudService.getTaskListFilters(appName).pipe(shareReplay({ bufferSize: 1, refCount: true })); + this.filters$ = filters$.pipe(catchError(() => EMPTY)); - this.filters$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ + filters$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ next: (res) => { this.resetFilter(); this.filters = res || [];