Merge pull request #4806 from tsiegleauq/smarter--back-button

Smarter back button
This commit is contained in:
Emanuel Schütze 2019-06-25 11:56:24 +02:00 committed by GitHub
commit ae618fce20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 7 deletions

View File

@ -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']);

View File

@ -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();
});
});

View 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);
});
}
}

View File

@ -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>

View File

@ -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 });
} }

View File

@ -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