Merge pull request #4806 from tsiegleauq/smarter--back-button
Smarter back button
This commit is contained in:
commit
ae618fce20
@ -17,6 +17,7 @@ import { PingService } from './core/core-services/ping.service';
|
||||
import { SpinnerService } from './core/ui-services/spinner.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { ViewUser } from './site/users/models/view-user';
|
||||
import { RoutingStateService } from './core/ui-services/routing-state.service';
|
||||
|
||||
/**
|
||||
* Enhance array with own functions
|
||||
@ -80,7 +81,8 @@ export class AppComponent {
|
||||
loadFontService: LoadFontService,
|
||||
dataStoreUpgradeService: DataStoreUpgradeService, // to start it.
|
||||
prioritizeService: PrioritizeService,
|
||||
pingService: PingService
|
||||
pingService: PingService,
|
||||
routingState: RoutingStateService
|
||||
) {
|
||||
// manually add the supported languages
|
||||
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">
|
||||
<div class="toolbar-left">
|
||||
<!-- 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>
|
||||
</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>
|
||||
</button>
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { ViewportService } from 'app/core/ui-services/viewport.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.
|
||||
@ -111,6 +111,10 @@ export class HeadBarComponent {
|
||||
@Output()
|
||||
public saveEvent = new EventEmitter<boolean>();
|
||||
|
||||
public get showBackButton(): boolean {
|
||||
return !this.nav && !this.editMode && !this.multiSelectMode && this.routingState.isSafePrevUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty constructor
|
||||
*/
|
||||
@ -119,7 +123,7 @@ export class HeadBarComponent {
|
||||
private menu: MainMenuService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private location: Location
|
||||
private routingState: RoutingStateService
|
||||
) {}
|
||||
|
||||
/**
|
||||
@ -149,7 +153,7 @@ export class HeadBarComponent {
|
||||
*/
|
||||
public onBackButton(): void {
|
||||
if (this.goBack) {
|
||||
this.location.back();
|
||||
this.router.navigateByUrl(this.routingState.previousUrl);
|
||||
} else {
|
||||
this.router.navigate([this.prevUrl], { relativeTo: this.route });
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ bleach>=1.5.0,<3.2
|
||||
channels>=2.1.2,<2.2
|
||||
daphne>=2.2,<2.3
|
||||
Django>=2.1,<2.3
|
||||
djangorestframework>=3.4,<3.10
|
||||
djangorestframework>=3.9.4,<3.10
|
||||
jsonfield2>=3.0,<3.1
|
||||
jsonschema>=3.0,<3.1
|
||||
lz4>=2.1.6
|
||||
|
Loading…
Reference in New Issue
Block a user