reworked route reuse

This commit is contained in:
Timo 2021-04-20 22:49:49 +03:00
parent 11a3f79c3f
commit e456b20b69
9 changed files with 59 additions and 15 deletions

View File

@ -5,11 +5,12 @@ import { CompositeRouteGuard } from './guards/composite-route.guard';
import { RedRoleGuard } from './modules/auth/red-role.guard'; import { RedRoleGuard } from './modules/auth/red-role.guard';
import { HtmlDebugScreenComponent } from './components/html-debug-screen/html-debug-screen.component'; import { HtmlDebugScreenComponent } from './components/html-debug-screen/html-debug-screen.component';
import { BaseScreenComponent } from './components/base-screen/base-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 { NgModule } from '@angular/core';
import { DownloadsListScreenComponent } from './components/downloads-list-screen/downloads-list-screen.component'; import { DownloadsListScreenComponent } from './components/downloads-list-screen/downloads-list-screen.component';
import { AppStateGuard } from './state/app-state.guard'; import { AppStateGuard } from './state/app-state.guard';
import { UserProfileScreenComponent } from './components/user-profile/user-profile-screen.component'; import { UserProfileScreenComponent } from './components/user-profile/user-profile-screen.component';
import { CustomRouteReuseStrategy } from './utils/custom-route-reuse.strategy';
const routes = [ const routes = [
{ {
@ -80,6 +81,7 @@ const routes = [
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })], imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
providers: [{ provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy }],
exports: [RouterModule] exports: [RouterModule]
}) })
export class AppRoutingModule {} export class AppRoutingModule {}

View File

@ -93,8 +93,7 @@ const components = [AppComponent, LogoComponent, AuthErrorComponent, ToastCompon
monthYearA11yLabel: 'YYYY' monthYearA11yLabel: 'YYYY'
} }
} }
}, }
{ provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy }
], ],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })

View File

@ -141,7 +141,7 @@
<mat-slide-toggle <mat-slide-toggle
(click)="toggleAnalysis($event)" (click)="toggleAnalysis($event)"
[disabled]="!permissionsService.isManager()" [disabled]="!permissionsService.isManager()"
[checked]="!fileStatus.isExcluded" [checked]="!fileStatus?.isExcluded"
[matTooltip]="toggleTooltip | translate" [matTooltip]="toggleTooltip | translate"
[matTooltipPosition]="tooltipPosition" [matTooltipPosition]="tooltipPosition"
[class.mr-24]="screen === 'project-overview'" [class.mr-24]="screen === 'project-overview'"

View File

@ -4,7 +4,6 @@ import { FileStatusWrapper } from '../../../../models/file/file-status.wrapper';
import { AppStateService } from '../../../../state/app-state.service'; import { AppStateService } from '../../../../state/app-state.service';
import { FileActionService } from '../../services/file-action.service'; import { FileActionService } from '../../services/file-action.service';
import { ProjectsDialogService } from '../../services/projects-dialog.service'; import { ProjectsDialogService } from '../../services/projects-dialog.service';
import { TooltipPosition } from '@angular/material/tooltip';
@Component({ @Component({
selector: 'redaction-file-actions', selector: 'redaction-file-actions',

View File

@ -32,8 +32,8 @@ const routes = [
component: FilePreviewScreenComponent, component: FilePreviewScreenComponent,
canActivate: [CompositeRouteGuard], canActivate: [CompositeRouteGuard],
data: { data: {
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard] routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
// reuse: true reuse: false // TODO ROUTE REUSE FOR file
} }
} }
]; ];

View File

@ -194,6 +194,7 @@
<div class="content-container"> <div class="content-container">
<div class="overlay-shadow"></div> <div class="overlay-shadow"></div>
<redaction-pdf-viewer <redaction-pdf-viewer
*ngIf="displayPDFViewer"
(keyUp)="handleKeyEvent($event)" (keyUp)="handleKeyEvent($event)"
(annotationSelected)="handleAnnotationSelected($event)" (annotationSelected)="handleAnnotationSelected($event)"
(manualAnnotationRequested)="openManualAnnotationDialog($event)" (manualAnnotationRequested)="openManualAnnotationDialog($event)"

View File

@ -28,6 +28,7 @@ import { download } from '../../../../utils/file-download-utils';
import { ViewMode } from '../../../../models/file/view-mode'; import { ViewMode } from '../../../../models/file/view-mode';
import { FileWorkloadComponent } from '../../components/file-workload/file-workload.component'; import { FileWorkloadComponent } from '../../components/file-workload/file-workload.component';
import { ProjectsDialogService } from '../../services/projects-dialog.service'; import { ProjectsDialogService } from '../../services/projects-dialog.service';
import { ReuseAwareRoute } from '../../../../utils/custom-route-reuse.strategy';
const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f']; const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
@ -36,7 +37,7 @@ const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
templateUrl: './file-preview-screen.component.html', templateUrl: './file-preview-screen.component.html',
styleUrls: ['./file-preview-screen.component.scss'] styleUrls: ['./file-preview-screen.component.scss']
}) })
export class FilePreviewScreenComponent implements OnInit, OnDestroy { export class FilePreviewScreenComponent implements OnInit, OnDestroy, ReuseAwareRoute {
public dialogRef: MatDialogRef<any>; public dialogRef: MatDialogRef<any>;
public viewMode: ViewMode = 'STANDARD'; public viewMode: ViewMode = 'STANDARD';
public fullScreen = false; public fullScreen = false;
@ -56,6 +57,7 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
filesAutoUpdateTimer: Subscription; filesAutoUpdateTimer: Subscription;
fileReanalysedSubscription: Subscription; fileReanalysedSubscription: Subscription;
hideSkipped = false; hideSkipped = false;
displayPDFViewer = false;
public viewDocumentInfo = false; public viewDocumentInfo = false;
private _instance: WebViewerInstance; private _instance: WebViewerInstance;
@ -165,7 +167,21 @@ export class FilePreviewScreenComponent implements OnInit, OnDestroy {
this._updateCanPerformActions(); 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 { ngOnInit(): void {
this.displayPDFViewer = true;
document.documentElement.addEventListener('fullscreenchange', (event) => { document.documentElement.addEventListener('fullscreenchange', (event) => {
if (!document.fullscreenElement) { if (!document.fullscreenElement) {
this.fullScreen = false; this.fullScreen = false;

View File

@ -118,7 +118,7 @@ export class BaseListingComponent<T = any> {
} }
public resetFilters() { public resetFilters() {
for (const filterComponent of this.filterComponents) { for (const filterComponent of this.filterComponents.filter((f) => !!f)) {
filterComponent.deactivateAllFilters(); filterComponent.deactivateAllFilters();
} }
this.filtersChanged(); this.filtersChanged();
@ -126,7 +126,10 @@ export class BaseListingComponent<T = any> {
} }
public get hasActiveFilters() { 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 // Selection

View File

@ -1,26 +1,50 @@
import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'; import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';
import { debounce } from './debounce';
export class CustomRouteReuseStrategy implements RouteReuseStrategy { export class CustomRouteReuseStrategy implements RouteReuseStrategy {
private _handlers: { [key: string]: DetachedRouteHandle } = {}; private _handlers: { [key: string]: DetachedRouteHandle } = {};
shouldDetach(route: ActivatedRouteSnapshot): boolean { shouldDetach(route: ActivatedRouteSnapshot): boolean {
return !!route.routeConfig.data?.reuse; return !!route.routeConfig.data?.reuse && !!this._getKey(route);
} }
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
if (handle === null) return; if (handle === null) return;
this._handlers[route.toString()] = handle; this._handlers[this._getKey(route)] = handle;
} }
shouldAttach(route: ActivatedRouteSnapshot): boolean { shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!this._handlers[route.toString()]; return !!this._handlers[this._getKey(route)];
} }
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { 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 { 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();
}