Skip to content

Commit

Permalink
editor: add can deactivate guard
Browse files Browse the repository at this point in the history
A confirmation message is displayed if the user leaves
the form without saving it.

* Closes rero/rero-ils#2104.

Co-Authored-by: Bertrand Zuchuat <bertrand.zuchuat@rero.ch>
  • Loading branch information
Garfield-fr committed Jun 21, 2023
1 parent e563c53 commit a43ea6a
Show file tree
Hide file tree
Showing 25 changed files with 164 additions and 125 deletions.
24 changes: 12 additions & 12 deletions projects/admin/src/app/acquisition/routes/accounts-route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* RERO ILS UI
* Copyright (C) 2022 RERO
* Copyright (C) 2022 UCLouvain
* Copyright (C) 2022-2023 RERO
* Copyright (C) 2022-2023 UCLouvain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand All @@ -16,17 +16,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { getCurrencySymbol } from '@angular/common';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { DetailComponent, EditorComponent, JSONSchema7, RouteInterface } from '@rero/ng-core';
import { BaseRoute } from '@app/admin/routes/base-route';
import { of } from 'rxjs';
import { CanAccessGuard, CAN_ACCESS_ACTIONS } from '@app/admin/guard/can-access.guard';
import { PermissionGuard } from '@app/admin/guard/permission.guard';
import { OrganisationService } from '@app/admin/service/organisation.service';
import { AccountDetailViewComponent } from '@app/admin/acquisition/components/account/account-detail-view/account-detail-view.component';
import { CanAddAccountGuard } from '@app/admin/acquisition/routes/guards/can-add-account.guard';
import { CAN_ACCESS_ACTIONS, CanAccessGuard } from '@app/admin/guard/can-access.guard';
import { PermissionGuard } from '@app/admin/guard/permission.guard';
import { BaseRoute } from '@app/admin/routes/base-route';
import { OrganisationService } from '@app/admin/service/organisation.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { ComponentCanDeactivateGuard, DetailComponent, EditorComponent, JSONSchema7, RouteInterface } from '@rero/ng-core';
import { PERMISSIONS } from '@rero/shared';
import { of } from 'rxjs';

/** Export formats configuration. */
export const exportFormats = [{
Expand All @@ -48,8 +48,8 @@ export class AccountsRoute extends BaseRoute implements RouteInterface {
matcher: (url: any) => this.routeMatcher(url, this.name),
children: [
{ path: 'detail/:pid', component: DetailComponent, canActivate: [ CanAccessGuard ], data: { action: CAN_ACCESS_ACTIONS.READ } },
{ path: 'edit/:pid', component: EditorComponent, canActivate: [ CanAccessGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE } },
{ path: 'new', component: EditorComponent, canActivate: [ PermissionGuard, CanAddAccountGuard ], data: { permissions: [ PERMISSIONS.ACAC_CREATE ] } }
{ path: 'edit/:pid', component: EditorComponent, canActivate: [ CanAccessGuard ], canDeactivate: [ ComponentCanDeactivateGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE } },
{ path: 'new', component: EditorComponent, canActivate: [ PermissionGuard, CanAddAccountGuard ], canDeactivate: [ ComponentCanDeactivateGuard ], data: { permissions: [ PERMISSIONS.ACAC_CREATE ] } }
],
data: {
types: [
Expand Down
12 changes: 6 additions & 6 deletions projects/admin/src/app/acquisition/routes/order-lines-route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* RERO ILS UI
* Copyright (C) 2021-2022 RERO
* Copyright (C) 2021-2022 UCLouvain
* Copyright (C) 2021-2023 RERO
* Copyright (C) 2021-2023 UCLouvain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand All @@ -18,11 +18,11 @@
import { getCurrencySymbol } from '@angular/common';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { EditorComponent, JSONSchema7, RouteInterface } from '@rero/ng-core';
import { ComponentCanDeactivateGuard, EditorComponent, JSONSchema7, RouteInterface } from '@rero/ng-core';
import { PERMISSIONS } from '@rero/shared';
import { of } from 'rxjs';
import { AcqOrderLineGuard } from '../../guard/acq-order-line.guard';
import { CanAccessGuard, CAN_ACCESS_ACTIONS } from '../../guard/can-access.guard';
import { CAN_ACCESS_ACTIONS, CanAccessGuard } from '../../guard/can-access.guard';
import { PermissionGuard } from '../../guard/permission.guard';
import { BaseRoute } from '../../routes/base-route';
import { OrganisationService } from '../../service/organisation.service';
Expand All @@ -41,8 +41,8 @@ export class OrderLinesRoute extends BaseRoute implements RouteInterface {
return {
matcher: (url: any) => this.routeMatcher(url, this.name),
children: [
{ path: 'edit/:pid', component: EditorComponent, canActivate: [ CanAccessGuard, IsBudgetActiveGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE } },
{ path: 'new', component: EditorComponent, canActivate: [ PermissionGuard, CanAddOrderLineGuard, AcqOrderLineGuard ], data: { permissions: [ PERMISSIONS.ACOL_CREATE ] } }
{ path: 'edit/:pid', component: EditorComponent, canActivate: [ CanAccessGuard, IsBudgetActiveGuard ], canDeactivate: [ ComponentCanDeactivateGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE } },
{ path: 'new', component: EditorComponent, canActivate: [ PermissionGuard, CanAddOrderLineGuard, AcqOrderLineGuard ], canDeactivate: [ ComponentCanDeactivateGuard ], data: { permissions: [ PERMISSIONS.ACOL_CREATE ] } }
],
data: {
types: [
Expand Down
12 changes: 6 additions & 6 deletions projects/admin/src/app/acquisition/routes/orders-route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* RERO ILS UI
* Copyright (C) 2021-2022 RERO
* Copyright (C) 2021-2022 UCLouvain
* Copyright (C) 2021-2023 RERO
* Copyright (C) 2021-2023 UCLouvain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand All @@ -16,11 +16,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DetailComponent, EditorComponent, RecordSearchPageComponent, RouteInterface } from '@rero/ng-core';
import { ComponentCanDeactivateGuard, DetailComponent, EditorComponent, RecordSearchPageComponent, RouteInterface } from '@rero/ng-core';
import { PERMISSIONS, PERMISSION_OPERATOR } from '@rero/shared';
import { of } from 'rxjs';
import { AcqOrderLineGuard } from '../../guard/acq-order-line.guard';
import { CanAccessGuard, CAN_ACCESS_ACTIONS } from '../../guard/can-access.guard';
import { CAN_ACCESS_ACTIONS, CanAccessGuard } from '../../guard/can-access.guard';
import { PermissionGuard } from '../../guard/permission.guard';
import { BaseRoute } from '../../routes/base-route';
import { OrderBriefViewComponent } from '../components/order/order-brief-view/order-brief-view.component';
Expand All @@ -40,8 +40,8 @@ export class OrdersRoute extends BaseRoute implements RouteInterface {
children: [
{ path: '', component: RecordSearchPageComponent, canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.ACOR_ACCESS, PERMISSIONS.ACOR_SEARCH ], operator: PERMISSION_OPERATOR.AND } },
{ path: 'detail/:pid', component: DetailComponent, canActivate: [ CanAccessGuard ], data: { action: CAN_ACCESS_ACTIONS.READ } },
{ path: 'edit/:pid', component: EditorComponent, canActivate: [CanAccessGuard, AcqOrderLineGuard], data: { action: CAN_ACCESS_ACTIONS.UPDATE, permissions: [ PERMISSIONS.ACOR_SEARCH ] } },
{ path: 'new', component: EditorComponent, canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.ACOR_CREATE ] } }
{ path: 'edit/:pid', component: EditorComponent, canActivate: [CanAccessGuard, AcqOrderLineGuard], canDeactivate: [ ComponentCanDeactivateGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE, permissions: [ PERMISSIONS.ACOR_SEARCH ] } },
{ path: 'new', component: EditorComponent, canActivate: [ PermissionGuard ], canDeactivate: [ ComponentCanDeactivateGuard ], data: { permissions: [ PERMISSIONS.ACOR_CREATE ] } }
],
data: {
types: [
Expand Down
10 changes: 5 additions & 5 deletions projects/admin/src/app/acquisition/routes/receipt-lines-route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* RERO ILS UI
* Copyright (C) 2021-2022 RERO
* Copyright (C) 2021-2022 UCLouvain
* Copyright (C) 2021-2023 RERO
* Copyright (C) 2021-2023 UCLouvain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand All @@ -18,10 +18,10 @@
import { getCurrencySymbol } from '@angular/common';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { EditorComponent, JSONSchema7, RouteInterface } from '@rero/ng-core';
import { ComponentCanDeactivateGuard, EditorComponent, JSONSchema7, RouteInterface } from '@rero/ng-core';
import { PERMISSIONS } from '@rero/shared';
import { of } from 'rxjs';
import { CanAccessGuard, CAN_ACCESS_ACTIONS } from '../../guard/can-access.guard';
import { CAN_ACCESS_ACTIONS, CanAccessGuard } from '../../guard/can-access.guard';
import { BaseRoute } from '../../routes/base-route';
import { OrganisationService } from '../../service/organisation.service';
import { IsBudgetActiveGuard } from './guards/is-budget-active.guard';
Expand All @@ -38,7 +38,7 @@ export class ReceiptLinesRoute extends BaseRoute implements RouteInterface {
return {
matcher: (url: any) => this.routeMatcher(url, this.name),
children: [
{ path: 'edit/:pid', component: EditorComponent, canActivate: [ CanAccessGuard, IsBudgetActiveGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE } }
{ path: 'edit/:pid', component: EditorComponent, canActivate: [ CanAccessGuard, IsBudgetActiveGuard ], canDeactivate: [ ComponentCanDeactivateGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE } }
],
data: {
types: [
Expand Down
10 changes: 5 additions & 5 deletions projects/admin/src/app/acquisition/routes/receipts-route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* RERO ILS UI
* Copyright (C) 2021-2022 RERO
* Copyright (C) 2021-2022 UCLouvain
* Copyright (C) 2021-2023 RERO
* Copyright (C) 2021-2023 UCLouvain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand All @@ -16,9 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DetailComponent, EditorComponent, RecordSearchPageComponent, RouteInterface } from '@rero/ng-core';
import { ComponentCanDeactivateGuard, DetailComponent, EditorComponent, RecordSearchPageComponent, RouteInterface } from '@rero/ng-core';
import { PERMISSIONS, PERMISSION_OPERATOR } from '@rero/shared';
import { CanAccessGuard, CAN_ACCESS_ACTIONS } from '../../guard/can-access.guard';
import { CAN_ACCESS_ACTIONS, CanAccessGuard } from '../../guard/can-access.guard';
import { PermissionGuard } from '../../guard/permission.guard';
import { BaseRoute } from '../../routes/base-route';
import { ReceiptDetailViewComponent } from '../components/receipt/receipt-detail-view/receipt-detail-view.component';
Expand All @@ -38,7 +38,7 @@ export class ReceiptsRoute extends BaseRoute implements RouteInterface {
children: [
{ path: '', component: RecordSearchPageComponent, canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.ACRE_ACCESS, PERMISSIONS.ACRE_SEARCH ], operator: PERMISSION_OPERATOR.AND } },
{ path: 'detail/:pid', component: DetailComponent, canActivate: [ CanAccessGuard, IsBudgetActiveGuard ], data: { action: CAN_ACCESS_ACTIONS.READ } },
{ path: 'edit/:pid', component: EditorComponent, canActivate: [ CanAccessGuard, IsBudgetActiveGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE } },
{ path: 'edit/:pid', component: EditorComponent, canActivate: [ CanAccessGuard, IsBudgetActiveGuard ], canDeactivate: [ ComponentCanDeactivateGuard ], data: { action: CAN_ACCESS_ACTIONS.UPDATE } },
],
data: {
types: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--
RERO ILS UI
Copyright (C) 2019 RERO
Copyright (C) 2019-2023 RERO
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
Expand All @@ -14,4 +14,8 @@
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<ng-core-editor (loadingChange)="loadingChanged($event)" [model]="model"></ng-core-editor>
<ng-core-editor
(loadingChange)="loadingChanged($event)"
(canDeactivateChange)="canDeactivateChanged($event)"
[model]="model"
></ng-core-editor>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* RERO ILS UI
* Copyright (C) 2019 RERO
* Copyright (C) 2019-2023 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand All @@ -18,7 +18,7 @@
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { RecordService } from '@rero/ng-core';
import { AbstractCanDeactivateComponent, RecordService } from '@rero/ng-core';
import { ToastrService } from 'ngx-toastr';
import { combineLatest } from 'rxjs';
import { EditorService } from '../../../service/editor.service';
Expand All @@ -31,7 +31,10 @@ import { EditorService } from '../../../service/editor.service';
/**
* Show Document Editor with a specific input: EAN import.
*/
export class DocumentEditorComponent {
export class DocumentEditorComponent extends AbstractCanDeactivateComponent {

/** Can deactivate from editor component */
canDeactivate: boolean = false;

// initial editor values
model = {};
Expand All @@ -50,7 +53,7 @@ export class DocumentEditorComponent {
private _translateService: TranslateService,
private _route: ActivatedRoute,
private _recordService: RecordService
) { }
) { super() }

/**
* Retrieve information about an item regarding its EAN code using EditorService
Expand Down Expand Up @@ -118,4 +121,12 @@ export class DocumentEditorComponent {
});
}
}

/**
* Can deactivate changed on editor
* @param activate - boolean
*/
canDeactivateChanged(activate: boolean): void {
this.canDeactivate = activate;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--
RERO ILS UI
Copyright (C) 2020 RERO
Copyright (C) 2020-2023 RERO
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
Expand All @@ -17,7 +17,7 @@

<div class="row">
<div [ngClass]="{'col-md-9 col-xl-8': serialPatternsTemplate != null, 'col-12': serialPatternsTemplate == null}" role="main">
<ng-core-editor [model]="model" (modelChange)="modelChanged($event)"></ng-core-editor>
<ng-core-editor [model]="model" (modelChange)="modelChanged($event)" (canDeactivateChange)="canDeactivateChanged($event)"></ng-core-editor>
</div>
<div *ngIf="serialPatternsTemplate != null" class="col-md-3 col-xl-4 bd-sidebar">
<div class="card">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* RERO ILS UI
* Copyright (C) 2020 RERO
* Copyright (C) 2020-2023 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand All @@ -16,7 +16,7 @@
*/

import { Component, OnDestroy, OnInit } from '@angular/core';
import { removeEmptyValues } from '@rero/ng-core';
import { AbstractCanDeactivateComponent, removeEmptyValues } from '@rero/ng-core';
import { BehaviorSubject, of, Subscription } from 'rxjs';
import { catchError, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
import { EditorService } from '../../../service/editor.service';
Expand All @@ -31,7 +31,10 @@ import { PredictionIssue } from '../../../service/holdings.service';
templateUrl: './holding-editor.component.html',
styleUrls: ['./holding-editor.component.scss']
})
export class HoldingEditorComponent implements OnInit, OnDestroy {
export class HoldingEditorComponent extends AbstractCanDeactivateComponent implements OnInit, OnDestroy {

/** Can deactivate from editor component */
canDeactivate: boolean = false;

/** Initial editor values */
model = {};
Expand Down Expand Up @@ -59,7 +62,9 @@ export class HoldingEditorComponent implements OnInit, OnDestroy {
* Constructor.
* @param _editorService - the local editor service
*/
constructor(private _editorService: EditorService) { }
constructor(private _editorService: EditorService) {
super();
}

/** Component initialization. */
ngOnInit() {
Expand Down Expand Up @@ -111,4 +116,12 @@ export class HoldingEditorComponent implements OnInit, OnDestroy {
this.serialPatternsTemplate = null;
}
}

/**
* Can deactivate changed on editor
* @param activate - boolean
*/
canDeactivateChanged(activate: boolean): void {
this.canDeactivate = activate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { CountryCodeTranslatePipe } from '@app/admin/pipe/country-code-translate.pipe';
import { TranslateService } from '@ngx-translate/core';
import { ApiService, cleanDictKeys, RecordService, removeEmptyValues, UniqueValidator } from '@rero/ng-core';
import { AbstractCanDeactivateComponent, ApiService, RecordService, UniqueValidator, cleanDictKeys, removeEmptyValues } from '@rero/ng-core';
import { UserService } from '@rero/shared';
import { ToastrService } from 'ngx-toastr';
import { Subscription } from 'rxjs';
Expand All @@ -35,7 +35,7 @@ import { LibraryFormService } from './library-form.service';
templateUrl: './library.component.html',
styleUrls: ['./library.component.scss']
})
export class LibraryComponent implements OnInit, OnDestroy {
export class LibraryComponent extends AbstractCanDeactivateComponent implements OnInit, OnDestroy {

// COMPONENT ATTRIBUTES =====================================================
/** The current library. */
Expand All @@ -52,6 +52,9 @@ export class LibraryComponent implements OnInit, OnDestroy {
availableCommunicationLanguagesOptions = [];
countryIsoCodesOptions = [];

/** Can deactivate guard */
public canDeactivate: boolean = false;

/** Form build event subscription to release the memory. */
private eventForm: Subscription;

Expand Down Expand Up @@ -102,7 +105,9 @@ export class LibraryComponent implements OnInit, OnDestroy {
private translateService: TranslateService,
private location: Location,
private countryCodeTranslatePipe: CountryCodeTranslatePipe
) { }
) {
super();
}

/** NgOnInit hook. */
ngOnInit() {
Expand Down Expand Up @@ -150,6 +155,7 @@ export class LibraryComponent implements OnInit, OnDestroy {

/** Form submission. */
onSubmit() {
this.canDeactivate = true;
this._cleanFormValues(this.libraryForm.getValues());
this.library.update(this.libraryForm.getValues());
if (this.library.pid) {
Expand Down Expand Up @@ -186,6 +192,7 @@ export class LibraryComponent implements OnInit, OnDestroy {

/** Cancel the edition. */
onCancel(event) {
this.canDeactivate = true;
event.preventDefault();
this.location.back();
this.libraryForm.build();
Expand Down
Loading

0 comments on commit a43ea6a

Please sign in to comment.