Merge pull request #5120 from tsiegleauq/nav-from-motion-blocks

Add navigation flag to return to custom oriring
This commit is contained in:
Emanuel Schütze 2019-12-02 15:35:01 +01:00 committed by GitHub
commit ed8d666fce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 46 deletions

View File

@ -17,6 +17,11 @@ export class RoutingStateService {
*/
private _previousUrl: string;
/**
* Stores the routing state
*/
private _customOrigin: string;
/**
* Unsafe paths that the user should not go "back" to
* TODO: Might also work using Routing parameters
@ -39,6 +44,10 @@ export class RoutingStateService {
return this._previousUrl;
}
public get customOrigin(): string {
return this._customOrigin;
}
/**
* Watch routing changes and save the last visited URL
*
@ -52,10 +61,33 @@ export class RoutingStateService {
)
.subscribe((event: any[]) => {
this._previousUrl = event[0].urlAfterRedirects;
if (
this.router.getCurrentNavigation().extras &&
this.router.getCurrentNavigation().extras.state &&
this.router.getCurrentNavigation().extras.state.back
) {
this._customOrigin = this._previousUrl;
} else if (
this._customOrigin &&
!this.isSameComponent(event[0].urlAfterRedirects, event[1].urlAfterRedirects)
) {
this._customOrigin = null;
}
});
}
public goBack(): void {
this.location.back();
}
/**
* Analyse the URL to check if you were navigating using the same components
*/
private isSameComponent(urlA: string, urlB: string): boolean {
const pathA = urlA.slice(0, urlA.lastIndexOf('/'));
const pathB = urlB.slice(0, urlB.lastIndexOf('/'));
const paramA = urlA.slice(urlA.lastIndexOf('/') + 1);
const paramB = urlB.slice(urlA.lastIndexOf('/') + 1);
return pathA === pathB && !isNaN(+paramA) && !isNaN(+paramB);
}
}

View File

@ -222,6 +222,8 @@ export class HeadBarComponent implements OnInit {
public onBackButton(): void {
if (this.goBack) {
this.routingState.goBack();
} else if (this.routingState.customOrigin && this.routingState.customOrigin !== this.router.url) {
this.router.navigate([this.routingState.customOrigin], { relativeTo: this.route });
} else {
this.router.navigate([this.prevUrl], { relativeTo: this.route });
}

View File

@ -1,4 +1,4 @@
<os-head-bar [nav]="false" [multiSelectMode]="isMultiSelect" goBack="true">
<os-head-bar prevUrl="../.." [nav]="false" [multiSelectMode]="isMultiSelect">
<!-- Title -->
<div class="title-slot" *ngIf="!parentMotion"><h2 translate>Amendments</h2></div>
@ -38,7 +38,7 @@
>
<!-- Meta -->
<div *pblNgridCellDef="'meta'; row as motion" class="cell-slot fill">
<a class="detail-link" [routerLink]="motion.getDetailStateURL()"></a>
<a class="detail-link" [routerLink]="motion.getDetailStateURL()" [state]="{ back: 'true' }"></a>
<div class="innerTable">
<!-- Identifier and line -->
<div class="title-line one-line">

View File

@ -55,7 +55,7 @@
<ng-container matColumnDef="anchor">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let motion">
<a [routerLink]="motion.getDetailStateURL()"></a>
<a [routerLink]="motion.getDetailStateURL()" [state]="{ back: 'true' }"></a>
</mat-cell>
</ng-container>

View File

@ -40,7 +40,12 @@
>
<!-- Title column -->
<div *pblNgridCellDef="'title'; row as motion; rowContext as rowContext" class="cell-slot fill">
<a class="detail-link" [routerLink]="motion.getDetailStateURL()" *ngIf="!isMultiSelect"></a>
<a
class="detail-link"
[routerLink]="motion.getDetailStateURL()"
[state]="{ back: 'true' }"
*ngIf="!isMultiSelect"
></a>
<div class="column-title innerTable">
<div class="title-line ellipsis-overflow">
<!-- Is Favorite -->

View File

@ -1,7 +1,7 @@
<os-head-bar
[hasMainButton]="perms.isAllowed('can_create_amendments', motion)"
mainActionTooltip="New amendment"
[prevUrl]="getPrevUrl()"
prevUrl="../.."
[nav]="false"
[editMode]="editMotion"
[isSaveButtonEnabled]="contentForm.valid"
@ -144,9 +144,12 @@
<span *ngIf="showSequential && motion.parent_id">&#xb7;&nbsp;</span>
<span *ngIf="motion.parent_id">
<span>
<span translate>Amendment to</span>&nbsp;<a [routerLink]="motion.parent.getDetailStateURL()">{{
motion.parent.identifier || motion.parent.title
}}</a>
<span translate>Amendment to</span>&nbsp;<a
[routerLink]="motion.parent.getDetailStateURL()"
[state]="{ back: 'true' }"
>
{{ motion.parent.identifier || motion.parent.title }}
</a>
</span>
</span>
</span>
@ -440,7 +443,7 @@
<!-- Ammendments -->
<div *ngIf="!editMotion && amendments && amendments.length > 0">
<h4 translate>Amendments</h4>
<a [routerLink]="['/motions/amendments', motion.id]">
<a [routerLink]="['/motions/amendments', motion.id]" [state]="{ back: 'true' }">
{{ amendments.length }}
<span *ngIf="amendments.length === 1" translate>Amendment</span>
<span *ngIf="amendments.length > 1" translate>Amendments</span>
@ -621,12 +624,7 @@
<!-- Title -->
<div *ngIf="editMotion" class="content-field form-title">
<mat-form-field *ngIf="editMotion">
<input
matInput
placeholder="{{ 'Title' | translate }}"
formControlName="title"
required
/>
<input matInput placeholder="{{ 'Title' | translate }}" formControlName="title" required />
<mat-error>{{ 'The title is required' | translate }}</mat-error>
</mat-form-field>
</div>
@ -839,11 +837,7 @@
<div class="content-field" *ngIf="editMotion">
<div *ngIf="perms.isAllowed('change_metadata', motion)">
<mat-form-field>
<input
matInput
placeholder="{{ 'Origin' | translate }}"
formControlName="origin"
/>
<input matInput placeholder="{{ 'Origin' | translate }}" formControlName="origin" />
</mat-form-field>
</div>
</div>

View File

@ -35,7 +35,6 @@ import { DiffLinesInParagraph, LineRange } from 'app/core/ui-services/diff.servi
import { LinenumberingService } from 'app/core/ui-services/linenumbering.service';
import { PersonalNoteService } from 'app/core/ui-services/personal-note.service';
import { PromptService } from 'app/core/ui-services/prompt.service';
import { RoutingStateService } from 'app/core/ui-services/routing-state.service';
import { ViewportService } from 'app/core/ui-services/viewport.service';
import { Mediafile } from 'app/shared/models/mediafiles/mediafile';
import { Motion } from 'app/shared/models/motions/motion';
@ -451,7 +450,6 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
private itemRepo: ItemRepositoryService,
private motionSortService: MotionSortListService,
private motionFilterService: MotionFilterListService,
private routingStateService: RoutingStateService,
private cd: ChangeDetectorRef
) {
super(title, translate, matSnackBar);
@ -1538,30 +1536,6 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
this.raiseError(error);
}
/**
* Tries to determine the previous URL if it's considered unsafe
*
* @returns the target to navigate to
*/
public getPrevUrl(): string {
if (this.motion && this.motion.parent_id) {
if (this.routingStateService.previousUrl && this.routingStateService.isSafePrevUrl) {
if (
(this.previousMotion &&
this.routingStateService.previousUrl === this.previousMotion.getDetailStateURL()) ||
(this.nextMotion && this.routingStateService.previousUrl === this.nextMotion.getDetailStateURL())
) {
return '../..';
} else {
return this.routingStateService.previousUrl;
}
} else {
return this.motion.parent.getDetailStateURL();
}
}
return '../..';
}
/**
* Function to prevent automatically closing the window/tab,
* if the user is editing a motion.