Makes navigation from Legal notice and pp always possible.
Tracks the last history and evaluates if the last visited URL is safe to navigate to also increases the version of djangorestframework. fixes #4705
This commit is contained in:
parent
19a389cae6
commit
9d37989ec7
@ -17,6 +17,7 @@ import { PingService } from './core/core-services/ping.service';
|
|||||||
import { SpinnerService } from './core/ui-services/spinner.service';
|
import { SpinnerService } from './core/ui-services/spinner.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { ViewUser } from './site/users/models/view-user';
|
import { ViewUser } from './site/users/models/view-user';
|
||||||
|
import { RoutingStateService } from './core/ui-services/routing-state.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enhance array with own functions
|
* Enhance array with own functions
|
||||||
@ -80,7 +81,8 @@ export class AppComponent {
|
|||||||
loadFontService: LoadFontService,
|
loadFontService: LoadFontService,
|
||||||
dataStoreUpgradeService: DataStoreUpgradeService, // to start it.
|
dataStoreUpgradeService: DataStoreUpgradeService, // to start it.
|
||||||
prioritizeService: PrioritizeService,
|
prioritizeService: PrioritizeService,
|
||||||
pingService: PingService
|
pingService: PingService,
|
||||||
|
routingState: RoutingStateService
|
||||||
) {
|
) {
|
||||||
// manually add the supported languages
|
// manually add the supported languages
|
||||||
translate.addLangs(['en', 'de', 'cs']);
|
translate.addLangs(['en', 'de', 'cs']);
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RoutingStateService } from './routing-state.service';
|
||||||
|
import { E2EImportsModule } from 'e2e-imports.module';
|
||||||
|
|
||||||
|
describe('RoutingStateService', () => {
|
||||||
|
beforeEach(() =>
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [E2EImportsModule]
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: RoutingStateService = TestBed.get(RoutingStateService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
51
client/src/app/core/ui-services/routing-state.service.ts
Normal file
51
client/src/app/core/ui-services/routing-state.service.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Router, RoutesRecognized } from '@angular/router';
|
||||||
|
import { filter, pairwise } from 'rxjs/operators';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watches URL changes.
|
||||||
|
* Can be enhanced using locale storage to support back-navigation even after reload
|
||||||
|
*/
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class RoutingStateService {
|
||||||
|
/**
|
||||||
|
* Hold the previous URL
|
||||||
|
*/
|
||||||
|
private _previousUrl: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsafe paths that the user should not go "back" to
|
||||||
|
* TODO: Might also work using Routing parameters
|
||||||
|
*/
|
||||||
|
private unsafeUrls: string[] = ['/login', '/privacypolicy', '/legalnotice'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Get the previous URL
|
||||||
|
*/
|
||||||
|
public get previousUrl(): string {
|
||||||
|
return this._previousUrl ? this._previousUrl : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isSafePrevUrl(): boolean {
|
||||||
|
return !!this.previousUrl && !this.unsafeUrls.includes(this.previousUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watch routing changes and save the last visited URL
|
||||||
|
*
|
||||||
|
* @param router Angular Router
|
||||||
|
*/
|
||||||
|
public constructor(private router: Router) {
|
||||||
|
this.router.events
|
||||||
|
.pipe(
|
||||||
|
filter(e => e instanceof RoutesRecognized),
|
||||||
|
pairwise()
|
||||||
|
)
|
||||||
|
.subscribe((event: any[]) => {
|
||||||
|
this._previousUrl = event[0].urlAfterRedirects;
|
||||||
|
console.log('prev URL: ', this._previousUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,12 @@
|
|||||||
<mat-toolbar color="primary" [ngClass]="multiSelectMode ? 'multi-select' : ''" class="sticky-toolbar">
|
<mat-toolbar color="primary" [ngClass]="multiSelectMode ? 'multi-select' : ''" class="sticky-toolbar">
|
||||||
<div class="toolbar-left">
|
<div class="toolbar-left">
|
||||||
<!-- Nav menu -->
|
<!-- Nav menu -->
|
||||||
<button mat-icon-button *ngIf="vp.isMobile && nav && !multiSelectMode" (click)="clickHamburgerMenu()">
|
<button mat-icon-button *ngIf="vp.isMobile && !showBackButton" (click)="clickHamburgerMenu()">
|
||||||
<mat-icon>menu</mat-icon>
|
<mat-icon>menu</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Exit / Back button -->
|
<!-- Exit / Back button -->
|
||||||
<button mat-icon-button *ngIf="!nav && !editMode && !multiSelectMode" (click)="onBackButton()">
|
<button mat-icon-button *ngIf="showBackButton" (click)="onBackButton()">
|
||||||
<mat-icon>arrow_back</mat-icon>
|
<mat-icon>arrow_back</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||||
import { Location } from '@angular/common';
|
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
import { ViewportService } from 'app/core/ui-services/viewport.service';
|
import { ViewportService } from 'app/core/ui-services/viewport.service';
|
||||||
import { MainMenuService } from 'app/core/core-services/main-menu.service';
|
import { MainMenuService } from 'app/core/core-services/main-menu.service';
|
||||||
|
import { RoutingStateService } from 'app/core/ui-services/routing-state.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reusable head bar component for Apps.
|
* Reusable head bar component for Apps.
|
||||||
@ -111,6 +111,10 @@ export class HeadBarComponent {
|
|||||||
@Output()
|
@Output()
|
||||||
public saveEvent = new EventEmitter<boolean>();
|
public saveEvent = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
public get showBackButton(): boolean {
|
||||||
|
return !this.nav && !this.editMode && !this.multiSelectMode && this.routingState.isSafePrevUrl;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty constructor
|
* Empty constructor
|
||||||
*/
|
*/
|
||||||
@ -119,7 +123,7 @@ export class HeadBarComponent {
|
|||||||
private menu: MainMenuService,
|
private menu: MainMenuService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private location: Location
|
private routingState: RoutingStateService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,7 +153,7 @@ export class HeadBarComponent {
|
|||||||
*/
|
*/
|
||||||
public onBackButton(): void {
|
public onBackButton(): void {
|
||||||
if (this.goBack) {
|
if (this.goBack) {
|
||||||
this.location.back();
|
this.router.navigateByUrl(this.routingState.previousUrl);
|
||||||
} else {
|
} else {
|
||||||
this.router.navigate([this.prevUrl], { relativeTo: this.route });
|
this.router.navigate([this.prevUrl], { relativeTo: this.route });
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ bleach>=1.5.0,<3.2
|
|||||||
channels>=2.1.2,<2.2
|
channels>=2.1.2,<2.2
|
||||||
daphne>=2.2,<2.3
|
daphne>=2.2,<2.3
|
||||||
Django>=2.1,<2.3
|
Django>=2.1,<2.3
|
||||||
djangorestframework>=3.4,<3.10
|
djangorestframework>=3.9.4,<3.10
|
||||||
jsonfield2>=3.0,<3.1
|
jsonfield2>=3.0,<3.1
|
||||||
jsonschema>=3.0,<3.1
|
jsonschema>=3.0,<3.1
|
||||||
lz4>=2.1.6
|
lz4>=2.1.6
|
||||||
|
Loading…
Reference in New Issue
Block a user