diff --git a/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.spec.ts b/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.spec.ts index bcfb4c64d..dde7569eb 100644 --- a/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.spec.ts +++ b/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.spec.ts @@ -126,13 +126,15 @@ describe('ExtensionsDataLoaderGuard', () => { return subject1.asObservable(); } }; - const extensionLoaderSpy = spyOn(extensionLoaders, 'fct1'); + const extensionLoaderSpy = spyOn(extensionLoaders, 'fct1').and.callThrough(); const guard = new ExtensionsDataLoaderGuard([extensionLoaders.fct1]); guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy); expect(extensionLoaderSpy).toHaveBeenCalled(); extensionLoaderSpy.calls.reset(); + subject1.next(true); + subject1.complete(); guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy); expect(extensionLoaderSpy).not.toHaveBeenCalled(); }); diff --git a/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.ts b/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.ts index cf842aae8..3b6f828e0 100644 --- a/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.ts +++ b/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.ts @@ -26,7 +26,7 @@ import { Injectable, InjectionToken, Inject } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot } from '@angular/router'; import { Observable, forkJoin, of } from 'rxjs'; -import { map, catchError } from 'rxjs/operators'; +import { tap, map, catchError } from 'rxjs/operators'; export type ExtensionLoaderCallback = (route: ActivatedRouteSnapshot) => Observable; @@ -50,9 +50,8 @@ export class ExtensionsDataLoaderGuard implements CanActivate { canActivate(route: ActivatedRouteSnapshot): Observable { if (!this.invoked) { - this.invoked = true; - if (!this.extensionDataLoaders.length) { + this.invoked = true; return of(true); } @@ -63,6 +62,7 @@ export class ExtensionsDataLoaderGuard implements CanActivate { // So all callbacks need to emit before completion, otherwise forkJoin will short circuit return forkJoin(...dataLoaderCallbacks).pipe( map(() => true), + tap(() => (this.invoked = true)), catchError((e) => { // tslint:disable-next-line console.error('Some of the extension data loader guards has been errored.'); diff --git a/projects/aca-shared/src/lib/routing/app.routes.strategy.spec.ts b/projects/aca-shared/src/lib/routing/app.routes.strategy.spec.ts deleted file mode 100644 index 5498a1e69..000000000 --- a/projects/aca-shared/src/lib/routing/app.routes.strategy.spec.ts +++ /dev/null @@ -1,86 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2020 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { AppRouteReuseStrategy } from './app.routes.strategy'; -import { TestBed } from '@angular/core/testing'; - -describe('AppRouteReuseStrategy', () => { - let appRouteReuse: AppRouteReuseStrategy; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [AppRouteReuseStrategy] - }); - - appRouteReuse = TestBed.inject(AppRouteReuseStrategy); - }); - - it('should allow detach if route is configured to be reused', () => { - const route: any = { - routeConfig: { - data: { - reuse: true - }, - path: 'tested-path' - } - }; - expect(appRouteReuse.shouldDetach(route)).toBe(true); - }); - - it('should store on routeCache', () => { - const route: any = { - url: [], - routeConfig: { - data: { - reuse: true - }, - path: 'tested-path', - component: {} - }, - firstChild: null, - children: [] - }; - appRouteReuse.store(route, { route: {} }); - expect(appRouteReuse.shouldAttach(route)).toBe(true); - }); - - it('should clear routeCache on resetCache', () => { - const route: any = { - url: [], - routeConfig: { - data: { - reuse: true - }, - path: 'tested-path', - component: {} - }, - firstChild: null, - children: [] - }; - appRouteReuse.store(route, { route: {} }); - appRouteReuse.resetCache(); - expect(appRouteReuse.shouldAttach(route)).toBe(false); - }); -}); diff --git a/projects/aca-shared/src/lib/routing/app.routes.strategy.ts b/projects/aca-shared/src/lib/routing/app.routes.strategy.ts deleted file mode 100644 index eca5e4172..000000000 --- a/projects/aca-shared/src/lib/routing/app.routes.strategy.ts +++ /dev/null @@ -1,124 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2020 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router'; -import { ComponentRef, Injectable } from '@angular/core'; - -interface RouteData { - reuse: boolean; -} - -interface RouteInfo { - handle: DetachedRouteHandle; - data: RouteData; -} - -@Injectable() -export class AppRouteReuseStrategy implements RouteReuseStrategy { - private routeCache = new Map(); - - resetCache() { - this.routeCache.forEach((value) => { - this.deactivateComponent(value.handle); - }); - this.routeCache.clear(); - } - - private deactivateComponent(handle: DetachedRouteHandle): void { - if (!handle) { - return; - } - const componentRef: ComponentRef = handle['componentRef']; - if (componentRef) { - componentRef.destroy(); - } - } - - shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { - const ret = future.routeConfig === curr.routeConfig; - if (ret) { - this.addRedirectsRecursively(future); // update redirects - } - return ret; - } - - shouldDetach(route: ActivatedRouteSnapshot): boolean { - const data = this.getRouteData(route); - return data && data.reuse; - } - - store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { - const url = this.getFullRouteUrl(route); - const data = this.getRouteData(route); - this.routeCache.set(url, { handle, data }); - this.addRedirectsRecursively(route); - } - - shouldAttach(route: ActivatedRouteSnapshot): boolean { - const url = this.getFullRouteUrl(route); - return this.routeCache.has(url); - } - - retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { - const url = this.getFullRouteUrl(route); - const data = this.getRouteData(route); - return data && data.reuse && this.routeCache.has(url) ? this.routeCache.get(url).handle : null; - } - - private addRedirectsRecursively(route: ActivatedRouteSnapshot): void { - const config = route.routeConfig; - if (config) { - if (!config.loadChildren) { - const routeFirstChild = route.firstChild; - const routeFirstChildUrl = routeFirstChild ? this.getRouteUrlPaths(routeFirstChild).join('/') : ''; - const childConfigs = config.children; - if (childConfigs) { - const childConfigWithRedirect = childConfigs.find((c) => c.path === '' && !!c.redirectTo); - if (childConfigWithRedirect) { - childConfigWithRedirect.redirectTo = routeFirstChildUrl; - } - } - } - route.children.forEach((childRoute) => this.addRedirectsRecursively(childRoute)); - } - } - - private getFullRouteUrl(route: ActivatedRouteSnapshot): string { - return this.getFullRouteUrlPaths(route).filter(Boolean).join('/'); - } - - private getFullRouteUrlPaths(route: ActivatedRouteSnapshot): string[] { - const paths = this.getRouteUrlPaths(route); - return route.parent ? [...this.getFullRouteUrlPaths(route.parent), ...paths] : paths; - } - - private getRouteUrlPaths(route: ActivatedRouteSnapshot): string[] { - return route.url.map((urlSegment) => urlSegment.path); - } - - private getRouteData(route: ActivatedRouteSnapshot): RouteData { - return route.routeConfig && (route.routeConfig.data as RouteData); - } -} diff --git a/projects/aca-shared/src/lib/services/app.service.spec.ts b/projects/aca-shared/src/lib/services/app.service.spec.ts index 405107212..0e51a3641 100644 --- a/projects/aca-shared/src/lib/services/app.service.spec.ts +++ b/projects/aca-shared/src/lib/services/app.service.spec.ts @@ -28,13 +28,11 @@ import { TestBed } from '@angular/core/testing'; import { AuthenticationService, AppConfigService } from '@alfresco/adf-core'; import { Subject } from 'rxjs'; import { HttpClientModule } from '@angular/common/http'; -import { AppRouteReuseStrategy } from '../routing/app.routes.strategy'; import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; describe('AppService', () => { let service: AppService; let auth: AuthenticationService; - let routeReuse: AppRouteReuseStrategy; let appConfig: AppConfigService; let searchQueryBuilderService: SearchQueryBuilderService; @@ -42,7 +40,6 @@ describe('AppService', () => { TestBed.configureTestingModule({ imports: [HttpClientModule], providers: [ - AppRouteReuseStrategy, SearchQueryBuilderService, { provide: AuthenticationService, @@ -55,14 +52,11 @@ describe('AppService', () => { ] }); - routeReuse = TestBed.inject(AppRouteReuseStrategy); auth = TestBed.inject(AuthenticationService); appConfig = TestBed.inject(AppConfigService); searchQueryBuilderService = TestBed.inject(SearchQueryBuilderService); - spyOn(routeReuse, 'resetCache').and.stub(); - - service = new AppService(auth, appConfig, searchQueryBuilderService, routeReuse); + service = new AppService(auth, appConfig, searchQueryBuilderService); }); it('should be ready if [withCredentials] mode is used', (done) => { @@ -72,7 +66,7 @@ describe('AppService', () => { } }; - const instance = new AppService(auth, appConfig, searchQueryBuilderService, routeReuse); + const instance = new AppService(auth, appConfig, searchQueryBuilderService); expect(instance.withCredentials).toBeTruthy(); instance.ready$.subscribe(() => { @@ -80,16 +74,6 @@ describe('AppService', () => { }); }); - it('should reset route cache on login', async () => { - auth.onLogin.next(); - await expect(routeReuse.resetCache).toHaveBeenCalled(); - }); - - it('should reset route cache on logout', async () => { - auth.onLogout.next(); - await expect(routeReuse.resetCache).toHaveBeenCalled(); - }); - it('should be ready after login', async () => { let isReady = false; service.ready$.subscribe((value) => { diff --git a/projects/aca-shared/src/lib/services/app.service.ts b/projects/aca-shared/src/lib/services/app.service.ts index aa1c773aa..f0497bb26 100644 --- a/projects/aca-shared/src/lib/services/app.service.ts +++ b/projects/aca-shared/src/lib/services/app.service.ts @@ -23,11 +23,9 @@ * along with Alfresco. If not, see . */ -import { Injectable, Inject } from '@angular/core'; +import { Injectable } from '@angular/core'; import { AuthenticationService, AppConfigService } from '@alfresco/adf-core'; import { Observable, BehaviorSubject } from 'rxjs'; -import { RouteReuseStrategy } from '@angular/router'; -import { AppRouteReuseStrategy } from '../routing/app.routes.strategy'; import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; @Injectable({ @@ -45,23 +43,16 @@ export class AppService { return this.config.get('auth.withCredentials', false); } - constructor( - auth: AuthenticationService, - private config: AppConfigService, - searchQueryBuilderService: SearchQueryBuilderService, - @Inject(RouteReuseStrategy) routeStrategy: AppRouteReuseStrategy - ) { + constructor(auth: AuthenticationService, private config: AppConfigService, searchQueryBuilderService: SearchQueryBuilderService) { this.ready = new BehaviorSubject(auth.isLoggedIn() || this.withCredentials); this.ready$ = this.ready.asObservable(); auth.onLogin.subscribe(() => { - routeStrategy.resetCache(); this.ready.next(true); }); auth.onLogout.subscribe(() => { searchQueryBuilderService.resetToDefaults(); - routeStrategy.resetCache(); }); } } diff --git a/projects/aca-shared/src/public-api.ts b/projects/aca-shared/src/public-api.ts index 25a352deb..87613c1c9 100644 --- a/projects/aca-shared/src/public-api.ts +++ b/projects/aca-shared/src/public-api.ts @@ -49,7 +49,6 @@ export * from './lib/directives/shared.directives.module'; export * from './lib/models/types'; export * from './lib/models/viewer.rules'; -export * from './lib/routing/app.routes.strategy'; export * from './lib/routing/shared.guard'; export * from './lib/services/app.service'; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 1137548d3..7d779c930 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -25,12 +25,12 @@ import { BrowserModule, HammerModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; -import { RouterModule, RouteReuseStrategy } from '@angular/router'; +import { RouterModule } from '@angular/router'; import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { TRANSLATION_PROVIDER, CoreModule, AppConfigService, DebugAppConfigService } from '@alfresco/adf-core'; import { ContentModule } from '@alfresco/adf-content-services'; -import { AppRouteReuseStrategy, SharedModule } from '@alfresco/aca-shared'; +import { SharedModule } from '@alfresco/aca-shared'; import { AppComponent } from './app.component'; import { APP_ROUTES } from './app.routes'; @@ -152,7 +152,6 @@ registerLocaleData(localeSv); BlankPageComponent ], providers: [ - { provide: RouteReuseStrategy, useClass: AppRouteReuseStrategy }, { provide: AppConfigService, useClass: DebugAppConfigService }, { provide: TRANSLATION_PROVIDER,