From e456b20b691cbd7cc29db4f67729a9e17d9cdf53 Mon Sep 17 00:00:00 2001 From: Timo Date: Tue, 20 Apr 2021 22:49:49 +0300 Subject: [PATCH] reworked route reuse --- apps/red-ui/src/app/app-routing.module.ts | 4 ++- apps/red-ui/src/app/app.module.ts | 3 +- .../file-actions/file-actions.component.html | 2 +- .../file-actions/file-actions.component.ts | 1 - .../projects/projects-routing.module.ts | 4 +-- .../file-preview-screen.component.html | 1 + .../file-preview-screen.component.ts | 18 +++++++++- .../shared/base/base-listing.component.ts | 7 ++-- .../app/utils/custom-route-reuse.strategy.ts | 34 ++++++++++++++++--- 9 files changed, 59 insertions(+), 15 deletions(-) diff --git a/apps/red-ui/src/app/app-routing.module.ts b/apps/red-ui/src/app/app-routing.module.ts index 1a7fc7bb3..d715b9b46 100644 --- a/apps/red-ui/src/app/app-routing.module.ts +++ b/apps/red-ui/src/app/app-routing.module.ts @@ -5,11 +5,12 @@ import { CompositeRouteGuard } from './guards/composite-route.guard'; import { RedRoleGuard } from './modules/auth/red-role.guard'; import { HtmlDebugScreenComponent } from './components/html-debug-screen/html-debug-screen.component'; import { BaseScreenComponent } from './components/base-screen/base-screen.component'; -import { RouterModule } from '@angular/router'; +import { RouteReuseStrategy, RouterModule } from '@angular/router'; import { NgModule } from '@angular/core'; import { DownloadsListScreenComponent } from './components/downloads-list-screen/downloads-list-screen.component'; import { AppStateGuard } from './state/app-state.guard'; import { UserProfileScreenComponent } from './components/user-profile/user-profile-screen.component'; +import { CustomRouteReuseStrategy } from './utils/custom-route-reuse.strategy'; const routes = [ { @@ -80,6 +81,7 @@ const routes = [ @NgModule({ imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })], + providers: [{ provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy }], exports: [RouterModule] }) export class AppRoutingModule {} diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index 0a0221504..1ce636680 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -93,8 +93,7 @@ const components = [AppComponent, LogoComponent, AuthErrorComponent, ToastCompon monthYearA11yLabel: 'YYYY' } } - }, - { provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy } + } ], bootstrap: [AppComponent] }) diff --git a/apps/red-ui/src/app/modules/projects/components/file-actions/file-actions.component.html b/apps/red-ui/src/app/modules/projects/components/file-actions/file-actions.component.html index 2baac9004..1fe34414c 100644 --- a/apps/red-ui/src/app/modules/projects/components/file-actions/file-actions.component.html +++ b/apps/red-ui/src/app/modules/projects/components/file-actions/file-actions.component.html @@ -141,7 +141,7 @@
; public viewMode: ViewMode = 'STANDARD'; public fullScreen = false; @@ -56,6 +57,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy { filesAutoUpdateTimer: Subscription; fileReanalysedSubscription: Subscription; hideSkipped = false; + displayPDFViewer = false; public viewDocumentInfo = false; private _instance: WebViewerInstance; @@ -165,7 +167,21 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy { this._updateCanPerformActions(); } + // TODO POC + onRouteReuse() { + // primitive route reuse mechanic to trigger code on reuse, in this case reload PDF Viewer, + // we would still need to first store some state-related data and the restore it to the new instance + // for example page + console.log('testing route reuse ... '); + this.displayPDFViewer = false; + setTimeout(() => { + this.displayPDFViewer = true; + }); + } + ngOnInit(): void { + this.displayPDFViewer = true; + document.documentElement.addEventListener('fullscreenchange', (event) => { if (!document.fullscreenElement) { this.fullScreen = false; diff --git a/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts b/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts index e2d99e543..80268ccdf 100644 --- a/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts +++ b/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts @@ -118,7 +118,7 @@ export class BaseListingComponent { } public resetFilters() { - for (const filterComponent of this.filterComponents) { + for (const filterComponent of this.filterComponents.filter((f) => !!f)) { filterComponent.deactivateAllFilters(); } this.filtersChanged(); @@ -126,7 +126,10 @@ export class BaseListingComponent { } public get hasActiveFilters() { - return this.filterComponents.reduce((prev, component) => prev || component?.hasActiveFilters, false) || this.searchForm.get('query').value; + return ( + this.filterComponents.filter((f) => !!f).reduce((prev, component) => prev || component?.hasActiveFilters, false) || + this.searchForm.get('query').value + ); } // Selection diff --git a/apps/red-ui/src/app/utils/custom-route-reuse.strategy.ts b/apps/red-ui/src/app/utils/custom-route-reuse.strategy.ts index a8836368d..d9177f68c 100644 --- a/apps/red-ui/src/app/utils/custom-route-reuse.strategy.ts +++ b/apps/red-ui/src/app/utils/custom-route-reuse.strategy.ts @@ -1,26 +1,50 @@ import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'; +import { debounce } from './debounce'; export class CustomRouteReuseStrategy implements RouteReuseStrategy { private _handlers: { [key: string]: DetachedRouteHandle } = {}; shouldDetach(route: ActivatedRouteSnapshot): boolean { - return !!route.routeConfig.data?.reuse; + return !!route.routeConfig.data?.reuse && !!this._getKey(route); } store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { if (handle === null) return; - this._handlers[route.toString()] = handle; + this._handlers[this._getKey(route)] = handle; } shouldAttach(route: ActivatedRouteSnapshot): boolean { - return !!this._handlers[route.toString()]; + return !!this._handlers[this._getKey(route)]; } retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { - return this._handlers[route.toString()] as DetachedRouteHandle; + const key = this._getKey(route); + const element: any = this._handlers[key]; + + if (element?.componentRef?.instance?.onRouteReuse) { + this._reuseRoute(element.componentRef?.instance); + } + + return element as DetachedRouteHandle; } shouldReuseRoute(future: ActivatedRouteSnapshot, current: ActivatedRouteSnapshot): boolean { - return future.routeConfig === current.routeConfig; + return this._getKey(future) === this._getKey(current); + } + + private _getKey(route: ActivatedRouteSnapshot): string { + return route.pathFromRoot + .map((el: ActivatedRouteSnapshot) => (el.routeConfig ? el.routeConfig.path + JSON.stringify(el.params) : '')) + .filter((str) => str.length > 0) + .join(''); + } + + @debounce() + private _reuseRoute(instance: any) { + instance.onRouteReuse(); } } + +export interface ReuseAwareRoute { + onRouteReuse(); +}