import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {VolCopyComponent} from './volcopy.component';
+import {CanDeactivateGuard} from '@eg/share/util/can-deactivate.guard';
const routes: Routes = [{
path: ':tab/:target/:target_id',
- component: VolCopyComponent
- /*
- }, {
- path: 'templates'
- component: VolCopyComponent
- }, {
- path: 'configure'
- component: VolCopyComponent
- */
+ component: VolCopyComponent,
+ canDeactivate: [CanDeactivateGuard]
}];
@NgModule({
<eg-staff-banner bannerText="Holdings Editor" i18n-bannerText></eg-staff-banner>
+<eg-confirm-dialog #pendingChangesDialog
+ i18n-dialogTitle dialogTitle="Unsaved Changes Confirmation"
+ i18n-dialogBoby dialogBody="Unsaved changes will be lost. Continue navigation?">
+</eg-confirm-dialog>
+
<div class="row" *ngIf="sessionExpired">
<div class="col-lg-6 mt-4 offset-lg-3 alert alert-danger d-flex justify-content-center" i18n>
Holdings Editor Session Expired
<ng-template ngbNavContent>
<div class="mt-2">
<eg-vol-edit [context]="context"
- (canSaveChange)="volsCanSave = $event"></eg-vol-edit>
+ (canSaveChange)="volsCanSaveChange($event)"></eg-vol-edit>
</div>
<ng-container *ngIf="volcopy.defaults.values.unified_display">
<div class="mt-2">
<eg-copy-attrs [context]="context"
- (canSaveChange)="attrsCanSave = $event"></eg-copy-attrs>
+ (canSaveChange)="attrsCanSaveChange($event)"></eg-copy-attrs>
</div>
</ng-container>
</ng-template>
<ng-template ngbNavContent>
<div class="mt-2">
<eg-copy-attrs [context]="context"
- (canSaveChange)="attrsCanSave = $event"></eg-copy-attrs>
+ (canSaveChange)="attrsCanSaveChange($event)"></eg-copy-attrs>
</div>
</ng-template>
</li>
-import {Component, OnInit, AfterViewInit, ViewChild, Renderer2} from '@angular/core';
+import {Component, OnInit, AfterViewInit, ViewChild, HostListener} from '@angular/core';
import {Router, ActivatedRoute, ParamMap} from '@angular/router';
import {tap} from 'rxjs/operators';
import {IdlObject, IdlService} from '@eg/core/idl.service';
import {HoldingsService, CallNumData} from '@eg/staff/share/holdings/holdings.service';
import {VolCopyContext} from './volcopy';
import {ProgressInlineComponent} from '@eg/share/dialog/progress-inline.component';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
import {AnonCacheService} from '@eg/share/util/anon-cache.service';
import {VolCopyService} from './volcopy.service';
import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
volsCanSave = true;
attrsCanSave = true;
+ changesPending = false;
+
+ @ViewChild('pendingChangesDialog', {static: false})
+ pendingChangesDialog: ConfirmDialogComponent;
constructor(
private router: Router,
private route: ActivatedRoute,
- private renderer: Renderer2,
private evt: EventService,
private idl: IdlService,
private org: OrgService,
return this.load(Object.keys(ids).map(id => Number(id)));
- }).then(_ => this.loading = false);
+ }).then(_ => {
+ this.loading = false;
+ this.changesPending = false;
+ });
}
broadcastChanges(volumes: IdlObject[]) {
isNotSaveable(): boolean {
return !(this.volsCanSave && this.attrsCanSave);
}
+
+ volsCanSaveChange(can: boolean) {
+ this.volsCanSave = can;
+ this.changesPending = true;
+ }
+
+ attrsCanSaveChange(can: boolean) {
+ this.attrsCanSave = can;
+ this.changesPending = true;
+ }
+
+ @HostListener('window:beforeunload', ['$event'])
+ canDeactivate($event?: Event): Promise<boolean> {
+
+ if (!this.changesPending) { return Promise.resolve(true); }
+
+ // Each warning dialog clears the current "changes are pending"
+ // flag so the user is not presented with the dialog again
+ // unless new changes are made.
+ this.changesPending = false;
+
+ if ($event) { // window.onbeforeunload
+ $event.preventDefault();
+ $event.returnValue = true;
+
+ } else { // tab OR route change.
+ return this.pendingChangesDialog.open().toPromise();
+ }
+ }
}