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 // keep a local copy for convenience
35 attrDefs: IdlObject[];
37 @ViewChild('queueGrid') queueGrid: GridComponent;
38 @ViewChild('confirmDelDlg') confirmDelDlg: ConfirmDialogComponent;
39 @ViewChild('progressDlg') progressDlg: ProgressDialogComponent;
42 private router: Router,
43 private route: ActivatedRoute,
44 private evt: EventService,
45 private net: NetService,
46 private auth: AuthService,
47 private vandelay: VandelayService) {
49 this.route.paramMap.subscribe((params: ParamMap) => {
50 this.queueType = params.get('qtype');
51 this.queueId = +params.get('id');
54 this.queueSource = new GridDataSource();
55 this.queueSource.getRows = (pager: Pager) => {
56 this.vandelay.queuePageOffset = pager.offset;
57 return this.loadQueueRecords(pager);
65 limitToMatches(checked: boolean) {
66 this.filters.matches = checked;
67 this.queueGrid.reload();
70 limitToNonImported(checked: boolean) {
71 this.filters.nonImported = checked;
72 this.queueGrid.reload();
75 limitToImportErrors(checked: boolean) {
76 this.filters.withErrors = checked;
77 this.queueGrid.reload();
80 queuePageOffset(): number {
81 return this.vandelay.queuePageOffset;
86 this.applyQueueType();
88 this.loadQueueSummary();
93 openRecord(row: any) {
94 if (this.queueType === 'auth') {
95 this.queueType = 'authority';
98 `/staff/cat/vandelay/queue/${this.queueType}/${this.queueId}/record/${row.id}/marc`;
99 this.router.navigate([url]);
103 this.queuedRecClass = this.queueType.match(/bib/) ? 'vqbr' : 'vqar';
104 this.vandelay.getAttrDefs(this.queueType).then(
106 this.attrDefs = attrs;
107 // Add grid columns for record attributes
108 attrs.forEach(attr => {
109 const col = new GridColumn();
110 col.name = attr.code(),
111 col.label = attr.description(),
112 col.datatype = 'string';
113 this.queueGrid.context.columnSet.add(col);
116 // Reapply the grid configuration now that we've
117 // dynamically added columns.
118 this.queueGrid.context.applyGridConfig();
123 qtypeShort(): string {
124 return this.queueType === 'bib' ? 'bib' : 'auth';
127 loadQueueSummary(): Promise<any> {
129 `open-ils.vandelay.${this.qtypeShort()}_queue.summary.retrieve`;
131 return this.net.request(
132 'open-ils.vandelay', method, this.auth.token(), this.queueId)
133 .toPromise().then(sum => this.queueSummary = sum);
136 loadQueueRecords(pager: Pager): Observable<any> {
140 offset: pager.offset,
142 flesh_import_items: true,
143 non_imported: this.filters.nonImported,
144 with_import_error: this.filters.withErrors
147 return this.vandelay.getQueuedRecords(
148 this.queueId, this.queueType, options, this.filters.matches).pipe(
150 // avoid sending mishapen data to the grid
151 // this happens (among other reasons) when the grid
153 const e = this.evt.parse(rec);
154 if (e) { console.error(e); return false; }
158 const recHash: any = {
160 import_error: rec.import_error(),
161 error_detail: rec.error_detail(),
162 import_time: rec.import_time(),
163 imported_as: rec.imported_as(),
166 matches: rec.matches()
169 if (this.queueType === 'bib') {
170 recHash.import_items = rec.import_items();
171 recHash.error_items = rec.import_items().filter(i => i.import_error());
174 // Link the record attribute values to the root record
175 // object so the grid can find them.
176 rec.attributes().forEach(attr => {
178 this.attrDefs.filter(d => d.id() === attr.field())[0];
179 recHash[def.code()] = attr.attr_value();
186 findOrCreateImportSelection() {
187 let selection = this.vandelay.importSelection;
189 selection = new VandelayImportSelection();
190 this.vandelay.importSelection = selection;
192 selection.queue = this.queueSummary.queue;
196 hasOverlayTarget(rid: number): boolean {
197 return this.vandelay.importSelection &&
198 Boolean(this.vandelay.importSelection.overlayMap[rid]);
202 const rows = this.queueGrid.context.getSelectedRows();
204 const selection = this.findOrCreateImportSelection();
205 selection.recordIds = rows.map(row => row.id);
206 console.log('importing: ', this.vandelay.importSelection);
207 this.router.navigate(['/staff/cat/vandelay/import']);
212 const selection = this.findOrCreateImportSelection();
213 selection.importQueue = true;
214 this.router.navigate(['/staff/cat/vandelay/import']);
219 this.confirmDelDlg.open().subscribe(confirmed => {
220 if (!confirmed) { return; }
222 this.progressDlg.open();
225 `open-ils.vandelay.${this.qtypeShort()}_queue.delete`,
226 this.auth.token(), this.queueId
229 const e = this.evt.parse(resp);
230 if (e) { return new Error(e.toString()); }
232 // Jump back to the main queue page.
233 this.router.navigate(['/staff/cat/vandelay/queue']);
235 err => console.error('queue deletion failed!', err)
236 ).finally(() => this.progressDlg.close());
240 exportNonImported() {
241 this.vandelay.exportQueue(this.queueSummary.queue, true);