diff --git a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.html b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.html
index 233425676..9acd1822d 100644
--- a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.html
+++ b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.html
@@ -1,17 +1,27 @@
+
+
+ {{ data.icon }}
+
+
+ {{ data.warning }}
+
+
+ close
+
+
{{ data.message }}
-
close
+
+ close
+
-
-
-
+
+
+
diff --git a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.scss b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.scss
index 98a0908bc..565cad324 100644
--- a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.scss
+++ b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.scss
@@ -8,6 +8,10 @@
cursor: pointer;
}
+ .warn-text {
+ color: #f44336;
+ }
+
.cancel {
background-color: #aaaaaa;
color: #ffffff;
diff --git a/dmp-frontend/src/app/library/deactivate/can-deactivate.guard.ts b/dmp-frontend/src/app/library/deactivate/can-deactivate.guard.ts
new file mode 100644
index 000000000..aac88736e
--- /dev/null
+++ b/dmp-frontend/src/app/library/deactivate/can-deactivate.guard.ts
@@ -0,0 +1,39 @@
+import { Injectable } from '@angular/core';
+import { MatDialog } from '@angular/material/dialog';
+import { CanDeactivate } from '@angular/router';
+import { Observable } from 'rxjs';
+import { TranslateService } from '@ngx-translate/core';
+import { map } from 'rxjs/operators';
+import { BaseComponent } from '../../core/common/base/base.component';
+import { CheckDeactivateBaseComponent } from './deactivate.component';
+import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
+
+@Injectable()
+export class CanDeactivateGuard extends BaseComponent implements CanDeactivate {
+
+ constructor(
+ private dialog: MatDialog,
+ public language: TranslateService
+ ) {
+ super();
+ }
+
+ canDeactivate(component: CheckDeactivateBaseComponent): boolean | Observable {
+
+ if (component.canDeactivate()) {
+ return true;
+ } else {
+ const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
+ maxWidth: '700px',
+ data: {
+ message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.LEAVE-PAGE'),
+ warning: this.language.instant('GENERAL.CONFIRMATION-DIALOG.LEAVE-WARNING'),
+ cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
+ confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.LEAVE'),
+ icon: 'error_outline'
+ }
+ });
+ return dialogRef.afterClosed().pipe(map(x => x ? true : false));
+ }
+ }
+}
diff --git a/dmp-frontend/src/app/library/deactivate/deactivate.component.ts b/dmp-frontend/src/app/library/deactivate/deactivate.component.ts
new file mode 100644
index 000000000..ce05a6632
--- /dev/null
+++ b/dmp-frontend/src/app/library/deactivate/deactivate.component.ts
@@ -0,0 +1,16 @@
+import { BaseComponent } from '../../core/common/base/base.component';
+import { HostListener } from '@angular/core';
+
+export abstract class CheckDeactivateBaseComponent extends BaseComponent {
+
+ protected constructor() { super(); }
+
+ abstract canDeactivate(): boolean;
+
+ @HostListener('window:beforeunload', ['$event'])
+ unloadNotification($event: any) {
+ if (!this.canDeactivate()) {
+ $event.returnValue = true;
+ }
+ }
+}
diff --git a/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.component.ts b/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.component.ts
index 573e0ef20..fb2d1dd29 100644
--- a/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.component.ts
+++ b/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.component.ts
@@ -1,5 +1,5 @@
-import {of as observableOf, Observable } from 'rxjs';
+import { of as observableOf, Observable } from 'rxjs';
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
@@ -16,17 +16,19 @@ import { TranslateService } from '@ngx-translate/core';
import { DatasetEditorWizardComponent } from '../quick-wizard/dataset-editor/dataset-editor-wizard.component';
import { DatasetStatus } from '../../core/common/enum/dataset-status';
import { ConfirmationDialogComponent } from '../../library/confirmation-dialog/confirmation-dialog.component';
+import { CheckDeactivateBaseComponent } from '../../library/deactivate/deactivate.component';
@Component({
selector: 'dataset-create-wizard.component',
templateUrl: 'dataset-create-wizard.component.html',
styleUrls: ['./dataset-create-wizard.component.scss'],
})
-export class DatasetCreateWizard extends BaseComponent implements OnInit, IBreadCrumbComponent {
+export class DatasetCreateWizard extends CheckDeactivateBaseComponent implements OnInit, IBreadCrumbComponent {
breadCrumbs: Observable;
@ViewChild(DatasetEditorWizardComponent, { static: false }) datasetEditorWizardComponent: DatasetEditorWizardComponent;
isLinear = false;
isNew = true;
+ isSubmitted = false;
formGroup: FormGroup;
@@ -70,7 +72,8 @@ export class DatasetCreateWizard extends BaseComponent implements OnInit, IBread
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCallbackSuccess(dmpId)
- )
+ );
+ this.isSubmitted = true;
} else {
return;
}
@@ -128,7 +131,8 @@ export class DatasetCreateWizard extends BaseComponent implements OnInit, IBread
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCallbackSuccess(dmpId)
- )
+ );
+ this.isSubmitted = true;
}
hasDatasets() {
@@ -156,4 +160,8 @@ export class DatasetCreateWizard extends BaseComponent implements OnInit, IBread
return this.stepper.selectedIndex == 1;
}
}
+
+ canDeactivate(): boolean {
+ return this.isSubmitted || !this.formGroup.dirty;
+ }
}
diff --git a/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.module.ts b/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.module.ts
index dbb004455..8c5d790ec 100644
--- a/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.module.ts
+++ b/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.module.ts
@@ -7,10 +7,11 @@ import { ConfirmationDialogModule } from '../../library/confirmation-dialog/conf
import { UrlListingModule } from '../../library/url-listing/url-listing.module';
import { DatasetDescriptionFormModule } from '../misc/dataset-description-form/dataset-description-form.module';
import { OuickWizardModule } from '../quick-wizard/quick-wizard.module';
-import { QuickWizardRoutingModule } from '../quick-wizard/quick-wizard.rooting';
import { DatasetCreateWizard } from './dataset-create-wizard.component';
import { DatasetCreateWizardRoutingModule } from './dataset-create-wizard.routing';
import { DatasetDmpSelector } from './dmp-selector/dataset-dmp-selector.component';
+import { QuickWizardRoutingModule } from '../quick-wizard/quick-wizard.routing';
+import { CanDeactivateGuard } from '../../library/deactivate/can-deactivate.guard';
@NgModule({
@@ -32,6 +33,9 @@ import { DatasetDmpSelector } from './dmp-selector/dataset-dmp-selector.componen
DatasetDmpSelector,
],
entryComponents: [
+ ],
+ providers: [
+ CanDeactivateGuard
]
})
export class DatasetCreateWizardModule { }
diff --git a/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.routing.ts b/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.routing.ts
index 63689111c..0eb34454b 100644
--- a/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.routing.ts
+++ b/dmp-frontend/src/app/ui/dataset-create-wizard/dataset-create-wizard.routing.ts
@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DatasetCreateWizard } from './dataset-create-wizard.component';
import { DatasetDmpSelector } from './dmp-selector/dataset-dmp-selector.component';
+import { CanDeactivateGuard } from '../../library/deactivate/can-deactivate.guard';
const routes: Routes = [
{
@@ -10,6 +11,7 @@ const routes: Routes = [
data: {
breadcrumb: true
},
+ canDeactivate: [CanDeactivateGuard]
},
{
path: '',
diff --git a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.component.ts b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.component.ts
index 2edef3209..4481729a3 100644
--- a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.component.ts
+++ b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.component.ts
@@ -1,6 +1,6 @@
-import {of as observableOf, Observable } from 'rxjs';
-import { Component, OnInit, ViewChild } from '@angular/core';
+import { of as observableOf, Observable } from 'rxjs';
+import { Component, OnInit, ViewChild, HostListener } from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
@@ -24,18 +24,20 @@ import { GrantEditorWizardModel } from '../grant-editor/grant-editor-wizard-mode
import { QuickWizardEditorWizardModel } from './quick-wizard-editor.model';
import { FunderFormModel } from '../../dmp/editor/grant-tab/funder-form-model';
import { ProjectFormModel } from '../../dmp/editor/grant-tab/project-form-model';
+import { CheckDeactivateBaseComponent } from '../../../library/deactivate/deactivate.component';
@Component({
selector: 'app-quick-wizard-editor-component',
templateUrl: 'quick-wizard-editor.component.html',
styleUrls: ['./quick-wizard-editor.component.scss']
})
-export class QuickWizardEditorComponent extends BaseComponent implements OnInit, IBreadCrumbComponent {
+export class QuickWizardEditorComponent extends CheckDeactivateBaseComponent implements OnInit, IBreadCrumbComponent {
breadCrumbs: Observable = observableOf([]);
@ViewChild('stepper', { static: true }) stepper: MatStepper;
@ViewChild(DatasetEditorWizardComponent, { static: false }) datasetEditorWizardComponent: DatasetEditorWizardComponent;
isNew = true;
+ isSubmitted = false;
quickWizard: QuickWizardEditorWizardModel;
allDatasets: DmpFinalizeDialogDataset[] = [];
formGroup: FormGroup = null;
@@ -155,6 +157,7 @@ export class QuickWizardEditorComponent extends BaseComponent implements OnInit,
complete => this.onCallbackSuccess(),
error => this.onCallbackError(error)
);
+ this.isSubmitted = true;
}
onSubmitSave(): void {
@@ -175,6 +178,7 @@ export class QuickWizardEditorComponent extends BaseComponent implements OnInit,
.subscribe(
complete => this.onCallbackSuccess()
)
+ this.isSubmitted = true;
}
});
}
@@ -217,4 +221,8 @@ export class QuickWizardEditorComponent extends BaseComponent implements OnInit,
return this.formGroup.get('grant').get('label').value;
}
}
+
+ canDeactivate(): boolean {
+ return this.isSubmitted || !this.formGroup.dirty;
+ }
}
diff --git a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.module.ts b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.module.ts
index e6925ddd6..d0f5980af 100644
--- a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.module.ts
+++ b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.module.ts
@@ -3,7 +3,7 @@ import { CommonFormsModule } from '../../common/forms/common-forms.module';
import { CommonUiModule } from '../../common/ui/common-ui.module';
import { ConfirmationDialogModule } from '../../library/confirmation-dialog/confirmation-dialog.module';
import { UrlListingModule } from '../../library/url-listing/url-listing.module';
-import { QuickWizardRoutingModule } from './quick-wizard.rooting';
+import { QuickWizardRoutingModule } from './quick-wizard.routing';
import { GrantEditorWizardComponent } from './grant-editor/grant-editor-wizard.component';
import { DmpEditorWizardComponent } from './dmp-editor/dmp-editor-wizard.component';
import { QuickWizardEditorComponent } from './quick-wizard-editor/quick-wizard-editor.component';
@@ -13,7 +13,7 @@ import { DatasetDescriptionFormModule } from '../misc/dataset-description-form/d
import { DmpModule } from '../dmp/dmp.module';
import { FunderEditorWizardComponent } from './funder-editor/funder-editor-wizard.component';
import { ProjectEditorWizardComponent } from './project-editor/project-editor-wizard.component';
-
+import { CanDeactivateGuard } from '../../library/deactivate/can-deactivate.guard';
@NgModule({
imports: [
@@ -36,6 +36,9 @@ import { ProjectEditorWizardComponent } from './project-editor/project-editor-wi
],
exports: [
DatasetEditorWizardComponent,
+ ],
+ providers: [
+ CanDeactivateGuard
]
})
export class OuickWizardModule { }
diff --git a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.rooting.ts b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.rooting.ts
deleted file mode 100644
index fd9248ede..000000000
--- a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.rooting.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { NgModule } from '@angular/core';
-import { RouterModule, Routes } from '@angular/router';
-import { DmpEditorWizardComponent } from './dmp-editor/dmp-editor-wizard.component';
-import { GrantEditorWizardComponent } from './grant-editor/grant-editor-wizard.component';
-import { QuickWizardEditorComponent } from './quick-wizard-editor/quick-wizard-editor.component';
-import { DatasetEditorWizardComponent } from './dataset-editor/dataset-editor-wizard.component';
-
-const routes: Routes = [
- {
- path: '',
- component: QuickWizardEditorComponent,
- data: {
- breadcrumb: true
- },
- },{
- path: 'grant',
- component: GrantEditorWizardComponent,
- data: {
- breadcrumb: true
- },
- },
- {
- path: 'dmp',
- component: DmpEditorWizardComponent,
- data: {
- breadcrumb: true
- },
- },
- {
- path: 'dataset',
- component: DatasetEditorWizardComponent,
- data: {
- breadcrumb: true
- },
- }
-];
-
-@NgModule({
- imports: [RouterModule.forChild(routes)],
- exports: [RouterModule]
-})
-export class QuickWizardRoutingModule { }
diff --git a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.routing.ts b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.routing.ts
new file mode 100644
index 000000000..31456ea00
--- /dev/null
+++ b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard.routing.ts
@@ -0,0 +1,42 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { QuickWizardEditorComponent } from './quick-wizard-editor/quick-wizard-editor.component';
+import { CanDeactivateGuard } from '../../library/deactivate/can-deactivate.guard';
+
+const routes: Routes = [
+ {
+ path: '',
+ component: QuickWizardEditorComponent,
+ data: {
+ breadcrumb: true
+ },
+ canDeactivate: [CanDeactivateGuard]
+ },
+ // {
+ // path: 'grant',
+ // component: GrantEditorWizardComponent,
+ // data: {
+ // breadcrumb: true
+ // },
+ // },
+ // {
+ // path: 'dmp',
+ // component: DmpEditorWizardComponent,
+ // data: {
+ // breadcrumb: true
+ // },
+ // },
+ // {
+ // path: 'dataset',
+ // component: DatasetEditorWizardComponent,
+ // data: {
+ // breadcrumb: true
+ // },
+ // }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class QuickWizardRoutingModule { }
diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json
index 4125c87d7..2836e9b1e 100644
--- a/dmp-frontend/src/assets/i18n/en.json
+++ b/dmp-frontend/src/assets/i18n/en.json
@@ -41,12 +41,15 @@
"PUBLISH-ITEM": "Publish this item?",
"ADD-DATASET": "Do you want to continue by adding a Dataset Description to your DMP? You can always add more Dataset Descriptions using \"Add Dataset Description (Wizard)\" menu.",
"ZENODO-DOI": "Would you like to create digital object identifier (DOI) for the DMP?",
+ "LEAVE-PAGE": "If you leave, your changes will be lost.",
+ "LEAVE-WARNING": "You have unsaved changes!",
"ACTIONS": {
"CONFIRM": "Yes",
"NO": "No",
"DELETE": "Delete",
"REMOVE": "Remove",
- "CANCEL": "Cancel"
+ "CANCEL": "Cancel",
+ "LEAVE": "Leave"
}
},
"ACTIONS": {