1 import {Component, OnInit, AfterViewInit, ViewChild} from '@angular/core';
2 import {Observable} from 'rxjs';
3 import {map, filter} from 'rxjs/operators';
4 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
5 import {Pager} from '@eg/share/util/pager';
6 import {IdlObject} from '@eg/core/idl.service';
7 import {EventService} from '@eg/core/event.service';
8 import {NetService} from '@eg/core/net.service';
9 import {AuthService} from '@eg/core/auth.service';
10 import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
11 import {ProgressDialogComponent} from '@eg/share/dialog/progress.component';
12 import {GridComponent} from '@eg/share/grid/grid.component';
13 import {GridDataSource, GridColumn} from '@eg/share/grid/grid';
14 import {VandelayService, VandelayImportSelection,
15 VANDELAY_EXPORT_PATH} from './vandelay.service';
18 templateUrl: 'queue.component.html'
20 export class QueueComponent implements OnInit, AfterViewInit {
23 queueType: string; // bib / authority
24 queueSource: GridDataSource;
25 queuedRecClass: string;
34 limitToMatches: (checked: boolean) => void;
35 limitToNonImported: (checked: boolean) => void;
36 limitToImportErrors: (checked: boolean) => void;
38 // keep a local copy for convenience
39 attrDefs: IdlObject[];
41 @ViewChild('queueGrid') queueGrid: GridComponent;
42 @ViewChild('confirmDelDlg') confirmDelDlg: ConfirmDialogComponent;
43 @ViewChild('progressDlg') progressDlg: ProgressDialogComponent;
46 private router: Router,
47 private route: ActivatedRoute,
48 private evt: EventService,
49 private net: NetService,
50 private auth: AuthService,
51 private vandelay: VandelayService) {
53 this.route.paramMap.subscribe((params: ParamMap) => {
54 this.queueType = params.get('qtype');
55 this.queueId = +params.get('id');
58 this.queueSource = new GridDataSource();
59 this.queueSource.getRows = (pager: Pager) => {
60 this.vandelay.queuePageOffset = pager.offset;
61 return this.loadQueueRecords(pager);
64 this.limitToMatches = (checked: boolean) => {
65 this.filters.matches = checked;
66 this.queueGrid.reload();
69 this.limitToNonImported = (checked: boolean) => {
70 this.filters.nonImported = checked;
71 this.queueGrid.reload();
74 this.limitToImportErrors = (checked: boolean) => {
75 this.filters.withErrors = checked;
76 this.queueGrid.reload();
83 queuePageOffset(): number {
84 return this.vandelay.queuePageOffset;
89 this.applyQueueType();
91 this.loadQueueSummary();
96 openRecord(row: any) {
97 if (this.queueType === 'auth') {
98 this.queueType = 'authority';
101 `/staff/cat/vandelay/queue/${this.queueType}/${this.queueId}/record/${row.id}/marc`;
102 this.router.navigate([url]);
106 this.queuedRecClass = this.queueType.match(/bib/) ? 'vqbr' : 'vqar';
107 this.vandelay.getAttrDefs(this.queueType).then(
109 this.attrDefs = attrs;
110 // Add grid columns for record attributes
111 attrs.forEach(attr => {
112 const col = new GridColumn();
113 col.name = attr.code(),
114 col.label = attr.description(),
115 col.datatype = 'string';
116 this.queueGrid.context.columnSet.add(col);
119 // Reapply the grid configuration now that we've
120 // dynamically added columns.
121 this.queueGrid.context.applyGridConfig();
126 qtypeShort(): string {
127 return this.queueType === 'bib' ? 'bib' : 'auth';
130 loadQueueSummary(): Promise<any> {
132 `open-ils.vandelay.${this.qtypeShort()}_queue.summary.retrieve`;
134 return this.net.request(
135 'open-ils.vandelay', method, this.auth.token(), this.queueId)
136 .toPromise().then(sum => this.queueSummary = sum);
139 loadQueueRecords(pager: Pager): Observable<any> {
143 offset: pager.offset,
145 flesh_import_items: true,
146 non_imported: this.filters.nonImported,
147 with_import_error: this.filters.withErrors
150 return this.vandelay.getQueuedRecords(
151 this.queueId, this.queueType, options, this.filters.matches).pipe(
153 // avoid sending mishapen data to the grid
154 // this happens (among other reasons) when the grid
156 const e = this.evt.parse(rec);
157 if (e) { console.error(e); return false; }
161 const recHash: any = {
163 import_error: rec.import_error(),
164 error_detail: rec.error_detail(),
165 import_time: rec.import_time(),
166 imported_as: rec.imported_as(),
169 matches: rec.matches()
172 if (this.queueType === 'bib') {
173 recHash.import_items = rec.import_items();
174 recHash.error_items = rec.import_items().filter(i => i.import_error());
177 // Link the record attribute values to the root record
178 // object so the grid can find them.
179 rec.attributes().forEach(attr => {
181 this.attrDefs.filter(d => d.id() === attr.field())[0];
182 recHash[def.code()] = attr.attr_value();
189 findOrCreateImportSelection() {
190 let selection = this.vandelay.importSelection;
192 selection = new VandelayImportSelection();
193 this.vandelay.importSelection = selection;
195 selection.queue = this.queueSummary.queue;
199 hasOverlayTarget(rid: number): boolean {
200 return this.vandelay.importSelection &&
201 Boolean(this.vandelay.importSelection.overlayMap[rid]);
205 const rows = this.queueGrid.context.getSelectedRows();
207 const selection = this.findOrCreateImportSelection();
208 selection.recordIds = rows.map(row => row.id);
209 console.log('importing: ', this.vandelay.importSelection);
210 this.router.navigate(['/staff/cat/vandelay/import']);
215 const selection = this.findOrCreateImportSelection();
216 selection.importQueue = true;
217 this.router.navigate(['/staff/cat/vandelay/import']);
221 this.confirmDelDlg.open().then(
223 this.progressDlg.open();
224 return this.net.request(
226 `open-ils.vandelay.${this.qtypeShort()}_queue.delete`,
227 this.auth.token(), this.queueId
231 this.progressDlg.close();
232 return Promise.reject('delete failed');
236 this.progressDlg.close();
237 const e = this.evt.parse(resp);
242 // Jump back to the main queue page.
243 this.router.navigate(['/staff/cat/vandelay/queue']);
247 this.progressDlg.close();
252 exportNonImported() {
253 this.vandelay.exportQueue(this.queueSummary.queue, true);