</eg-staff-banner>
</ng-container>
+<eg-confirm-dialog #pendingChangesDialog
+ i18n-dialogTitle dialogTitle="Unsaved Changes Confirmation"
+ i18n-dialogBoby dialogBody="Unsaved changes will be lost. Continue navigation?">
+</eg-confirm-dialog>
+
<ng-container *ngIf="context.summary">
<eg-staff-banner i18n-bannerText bannerText="Patron:
{{context.summary.patron.family_name()}},
<li ngbNavItem="edit" [disabled]="!context.summary">
<a ngbNavLink i18n>Edit</a>
<ng-template ngbNavContent>
- <eg-patron-edit [patronId]="patronId" [toolbar]="editorToolbar">
+ <eg-patron-edit #patronEditor [patronId]="patronId" [toolbar]="editorToolbar">
</eg-patron-edit>
</ng-template>
</li>
-import {Component, ViewChild, OnInit, AfterViewInit} from '@angular/core';
+import {Component, ViewChild, OnInit, AfterViewInit, HostListener} from '@angular/core';
import {Router, ActivatedRoute, ParamMap} from '@angular/router';
import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
import {NetService} from '@eg/core/net.service';
import {PatronSearch, PatronSearchComponent
} from '@eg/staff/share/patron/search.component';
import {EditToolbarComponent} from './edit-toolbar.component';
+import {EditComponent} from './edit.component';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
const MAIN_TABS =
['checkout', 'items_out', 'holds', 'bills', 'messages', 'edit', 'search'];
/* eg-patron-edit is unable to find #editorToolbar directly
* within the template. Adding a ref here allows it to
* successfully transfer to the editor */
- @ViewChild('editorToolbar') editorToolbar: EditToolbarComponent;
+ @ViewChild('editorToolbar') private editorToolbar: EditToolbarComponent;
+
+ @ViewChild('patronEditor') private patronEditor: EditComponent;
+
+ @ViewChild('pendingChangesDialog')
+ private pendingChangesDialog: ConfirmDialogComponent;
constructor(
private router: Router,
this.load();
}
+ @HostListener('window:beforeunload', ['$event'])
+ canDeactivate($event?: Event): Promise<boolean> {
+
+ if (this.patronEditor && this.patronEditor.changesPending) {
+
+ // 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.patronEditor.changesPending = false;
+
+ if ($event) { // window.onbeforeunload
+ $event.preventDefault();
+ $event.returnValue = true;
+
+ } else { // tab OR route change.
+ return this.pendingChangesDialog.open().toPromise();
+ }
+
+ } else {
+ return Promise.resolve(true);
+ }
+ }
+
load() {
this.loading = true;
this.fetchSettings()
// tab will change with route navigation.
evt.preventDefault();
- this.patronTab = evt.nextId;
- this.routeToTab();
+ // Protect against tab changes with dirty data.
+ this.canDeactivate().then(ok => {
+ if (ok) {
+ this.patronTab = evt.nextId;
+ this.routeToTab();
+ }
+ });
}
// The bills tab has various sub-interfaces. If the user is already
import {PatronResolver} from './resolver.service';
import {TestPatronPasswordComponent} from './test-password.component';
import {RegisterPatronComponent} from './register.component';
+import {CanDeactivateGuard} from '@eg/share/util/can-deactivate.guard';
const routes: Routes = [{
path: '',
}, {
path: ':id/:tab',
component: PatronComponent,
- resolve: {resolver : PatronResolver}
+ resolve: {resolver : PatronResolver},
+ canDeactivate: [CanDeactivateGuard]
}];
@NgModule({