X-Git-Url: https://git.evergreen-ils.org/?p=working%2FEvergreen.git;a=blobdiff_plain;f=Open-ILS%2Fsrc%2Feg2%2Fsrc%2Fapp%2Fstaff%2Fcatalog%2Frecord%2Frecord.component.ts;h=b900ea87340d623d85a2d973ac7bf45f5bec49f5;hp=e6832f1ab960ab0fc4daf6bb1a86a3433ae06179;hb=0df5d1f8f7e0d907489feaa0156b966440310fb3;hpb=582bb8924e1801aaee40e73e79c3ebd312dc8a2e diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts index e6832f1ab9..b900ea8734 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit, Input, ViewChild} from '@angular/core'; +import {Component, OnInit, Input, ViewChild, HostListener} from '@angular/core'; import {NgbTabset, NgbTabChangeEvent} from '@ng-bootstrap/ng-bootstrap'; import {Router, ActivatedRoute, ParamMap} from '@angular/router'; import {PcrudService} from '@eg/core/pcrud.service'; @@ -9,13 +9,8 @@ import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.s import {StaffCatalogService} from '../catalog.service'; import {BibSummaryComponent} from '@eg/staff/share/bib-summary/bib-summary.component'; import {StoreService} from '@eg/core/store.service'; - -const ANGJS_TABS: any = { - marc_edit: true, - holds: true, - holdings: true, - conjoined: true -}; +import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; +import {MarcEditorComponent} from '@eg/staff/share/marc-edit/editor.component'; @Component({ selector: 'eg-catalog-record', @@ -27,9 +22,13 @@ export class RecordComponent implements OnInit { recordTab: string; summary: BibRecordSummary; searchContext: CatalogSearchContext; - @ViewChild('recordTabs') recordTabs: NgbTabset; + @ViewChild('recordTabs', { static: true }) recordTabs: NgbTabset; + @ViewChild('marcEditor', {static: false}) marcEditor: MarcEditorComponent; defaultTab: string; // eg.cat.default_record_tab + @ViewChild('pendingChangesDialog', {static: false}) + pendingChangesDialog: ConfirmDialogComponent; + constructor( private router: Router, private route: ActivatedRoute, @@ -45,10 +44,7 @@ export class RecordComponent implements OnInit { this.defaultTab = this.store.getLocalItem('eg.cat.default_record_tab') - || 'catalog'; - - // TODO: Implement default tab handling for tabs that require - // and AngJS redirect. + || 'item_table'; // Watch for URL record ID changes // This includes the initial route. @@ -62,12 +58,7 @@ export class RecordComponent implements OnInit { this.searchContext = this.staffCat.searchContext; if (!this.recordTab) { - this.recordTab = this.defaultTab || 'catalog'; - // On initial load, if the default tab is set to one of - // the AngularJS tabs, redirect the user there. - if (this.recordTab in ANGJS_TABS) { - return this.routeToTab(); - } + this.recordTab = this.defaultTab || 'item_table'; } this.loadRecord(); @@ -81,26 +72,57 @@ export class RecordComponent implements OnInit { // Changing a tab in the UI means changing the route. // Changing the route ultimately results in changing the tab. - onTabChange(evt: NgbTabChangeEvent) { - this.recordTab = evt.nextId; + beforeTabChange(evt: NgbTabChangeEvent) { // prevent tab changing until after route navigation evt.preventDefault(); - this.routeToTab(); + // Protect against tab changes with dirty data. + this.canDeactivate().then(ok => { + if (ok) { + this.recordTab = evt.nextId; + this.routeToTab(); + } + }); } - routeToTab() { - - // Route to the AngularJS catalog tab - if (this.recordTab in ANGJS_TABS) { - const angjsBase = '/eg/staff/cat/catalog/record'; + /* + * Handle 3 types of navigation which can cause loss of data. + * 1. Record detail tab navigation (see also beforeTabChange()) + * 2. Intra-Angular route navigation away from the record detail page + * 3. Browser page unload/reload + * + * For the #1, and #2, display a eg confirmation dialog. + * For #3 use the stock browser onbeforeunload dialog. + * + * Note in this case a tab change is a route change, but it's one + * which does not cause RecordComponent to unload, so it has to be + * manually tracked in beforeTabChange(). + */ + @HostListener('window:beforeunload', ['$event']) + canDeactivate($event?: Event): Promise { + + if (this.marcEditor && this.marcEditor.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.marcEditor.clearPendingChanges(); + + if ($event) { // window.onbeforeunload + $event.preventDefault(); + $event.returnValue = true; + + } else { // tab OR route change. + return this.pendingChangesDialog.open().toPromise(); + } - window.location.href = - `${angjsBase}/${this.recordId}/${this.recordTab}`; - return; + } else { + return Promise.resolve(true); } + } + routeToTab() { const url = `/staff/catalog/record/${this.recordId}/${this.recordTab}`; @@ -128,6 +150,35 @@ export class RecordComponent implements OnInit { this.bib.fleshBibUsers([summary.record]); }); } + + // Lets us intercept the summary object and augment it with + // search highlight data if/when it becomes available from + // an externally executed search. + summaryForDisplay(): BibRecordSummary { + if (!this.summary) { return null; } + const sum = this.summary; + const ctx = this.searchContext; + + if (Object.keys(sum.displayHighlights).length === 0) { + if (ctx.highlightData[sum.id]) { + sum.displayHighlights = ctx.highlightData[sum.id]; + } + } + + return this.summary; + } + + currentSearchOrg(): IdlObject { + if (this.staffCat && this.staffCat.searchContext) { + return this.staffCat.searchContext.searchOrg; + } + return null; + } + + handleMarcRecordSaved() { + this.staffCat.currentDetailRecordSummary = null; + this.loadRecord(); + } }