(deleteRequested)="deleteCopy($event)"
(cancelRequested)="cancelCopy($event)"
[showReceiver]="!hasEditableCopies()"
+ (becameDirty)="becameDirty.emit(true)"
[rowIndex]="idx + 1" [lineitem]="lineitem" [copy]="copy">
</eg-lineitem-copy-attrs>
</div>
@Input() lineitem: IdlObject;
@Input() batchAdd = false;
+ @Output() becameDirty = new EventEmitter<Boolean>();
+
@ViewChild('confirmAlertsDialog') confirmAlertsDialog: LineitemAlertDialogComponent;
@ViewChild('cancelDialog') cancelDialog: CancelDialogComponent;
this.lineitem.lineitem_details().forEach(copy => {
copy[field](val);
copy.ischanged(true); // isnew() takes precedence
+ this.becameDirty.emit(true);
});
});
}
} else {
// Requires a Save Changes action.
copy.isdeleted(true);
+ this.becameDirty.emit(true);
}
}
<h3 *ngIf="mode !== 'multiAdd'" class="mt-3" i18n>Items for Line Item {{lineitem.id()}} ({{getTitle(lineitem)}})</h3>
+
+<eg-confirm-dialog #leaveConfirm
+ i18n-dialogTitle i18n-dialogBody
+ dialogTitle="Unsaved Changes Warning"
+ dialogBody="There are unsaved changes. Are you sure you want to leave?">
+</eg-confirm-dialog>
+
<div class="row mt-3 mb-1">
<div class="col-lg-12 form-inline">
</div>
</div>
- <eg-lineitem-batch-copies [lineitem]="lineitem" [batchAdd]="mode === 'multiAdd'"></eg-lineitem-batch-copies>
+ <eg-lineitem-batch-copies
+ [lineitem]="lineitem" [batchAdd]="mode === 'multiAdd'"
+ (becameDirty)="dirty = true"
+ ></eg-lineitem-batch-copies>
</ng-container>
import {Component, OnInit, AfterViewInit, Input, Output, EventEmitter,
ViewChild} from '@angular/core';
import {Router, ActivatedRoute, ParamMap} from '@angular/router';
+import {Observable, of} from 'rxjs';
import {tap} from 'rxjs/operators';
import {Pager} from '@eg/share/util/pager';
import {IdlService, IdlObject} from '@eg/core/idl.service';
import {LineitemService, FleshCacheParams} from './lineitem.service';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {ItemLocationService} from '@eg/share/item-location-select/item-location-select.service';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
const FORMULA_FIELDS = [
'owning_lib',
batchOwningLib: IdlObject;
batchFund: ComboboxEntry;
batchCopyLocId: number;
+ dirty = false;
saving = false;
progressMax = 0;
progressValue = 0;
// Can any changes be applied?
liLocked = false;
+ @ViewChild('leaveConfirm', { static: true }) leaveConfirm: ConfirmDialogComponent;
+
constructor(
private route: ActivatedRoute,
private idl: IdlService,
copy.isnew(true);
copy.lineitem(this.lineitem.id());
copies.push(copy);
+ this.dirty = true;
}
if (copies.length > this.copyCount) {
if (this.mode === 'multiAdd') {
app.isnew(true);
this.lineitem.distribution_formulas().push(app);
+ this.dirty = true;
} else {
this.pcrud.create(app).toPromise().then(a => {
a.creator(this.auth.user());
} else {
copy[field](val);
+ this.dirty = true;
}
});
() => this.load({toCache: true}).then(_ => {
this.liService.activateStateChange.emit(this.lineitem.id());
this.saving = false;
+ this.dirty = false;
})
);
}
getTitle(li: IdlObject): string {
return this.liService.getFirstAttributeValue(li, 'title');
}
+
+ canDeactivate(): Observable<boolean> {
+ if (this.dirty) {
+ return this.leaveConfirm.open();
+ } else {
+ return of(true);
+ }
+ }
}
@Input() rowIndex: number;
@Input() batchAdd = false;
+ @Output() becameDirty = new EventEmitter<Boolean>();
+
fundEntries: ComboboxEntry[];
circModEntries: ComboboxEntry[];
const announce: any = {};
this.copy.ischanged(true);
+ if (!this.batchMode) {
+ if (field !== 'owning_lib') {
+ this.becameDirty.emit(true);
+ } else {
+ // FIXME eg-org-select current send needless change
+ // events, so we need to check
+ if (entry && this.copy[field]() !== entry.id()) {
+ this.becameDirty.emit(true);
+ }
+ }
+ }
switch (field) {
-import {NgModule} from '@angular/core';
+import {NgModule, Injectable} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
+import {Router, Resolve, RouterStateSnapshot,
+ ActivatedRouteSnapshot, CanDeactivate} from '@angular/router';
+import {Observable} from 'rxjs';
import {PoComponent} from './po.component';
import {PrintComponent} from './print.component';
import {PoSummaryComponent} from './summary.component';
import {PoEdiMessagesComponent} from './edi.component';
import {PoCreateComponent} from './create.component';
+// following example of https://www.concretepage.com/angular-2/angular-candeactivate-guard-example
+export interface PoChildDeactivationGuarded {
+ canDeactivate(): Observable<boolean> | Promise<boolean> | boolean;
+}
+
+@Injectable()
+export class CanLeavePoChildGuard implements CanDeactivate<PoChildDeactivationGuarded> {
+ canDeactivate(component: PoChildDeactivationGuarded): Observable<boolean> | Promise<boolean> | boolean {
+ return component.canDeactivate ? component.canDeactivate() : true;
+ }
+}
+
const routes: Routes = [{
path: 'create',
component: PoCreateComponent
component: LineitemHistoryComponent
}, {
path: 'lineitem/:lineitemId/items',
- component: LineitemCopiesComponent
+ component: LineitemCopiesComponent,
+ canDeactivate: [CanLeavePoChildGuard]
}, {
path: 'lineitem/:lineitemId/worksheet',
component: LineitemWorksheetComponent
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
- providers: []
+ providers: [CanLeavePoChildGuard]
})
export class PoRoutingModule {}