]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/cat/vandelay/queue.component.ts
e763130e55e812ee254758815dadb2b83490d134
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / cat / vandelay / queue.component.ts
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';
16
17 @Component({
18   templateUrl: 'queue.component.html'
19 })
20 export class QueueComponent implements OnInit, AfterViewInit {
21
22     queueId: number;
23     queueType: string; // bib / authority
24     queueSource: GridDataSource;
25     queuedRecClass: string;
26     queueSummary: any;
27
28     filters = {
29         matches: false,
30         nonImported: false,
31         withErrors: false
32     };
33
34     // keep a local copy for convenience
35     attrDefs: IdlObject[];
36
37     @ViewChild('queueGrid', { static: true }) queueGrid: GridComponent;
38     @ViewChild('confirmDelDlg', { static: false }) confirmDelDlg: ConfirmDialogComponent;
39     @ViewChild('progressDlg', { static: true }) progressDlg: ProgressDialogComponent;
40
41     cellPrintValues: (row: any, cell: GridColumn) => string;
42
43     constructor(
44         private router: Router,
45         private route: ActivatedRoute,
46         private evt: EventService,
47         private net: NetService,
48         private auth: AuthService,
49         private vandelay: VandelayService) {
50
51         this.route.paramMap.subscribe((params: ParamMap) => {
52             this.queueType = params.get('qtype');
53             this.queueId = +params.get('id');
54         });
55
56         this.queueSource = new GridDataSource();
57         this.queueSource.getRows = (pager: Pager) => {
58             this.vandelay.queuePageOffset = pager.offset;
59             return this.loadQueueRecords(pager);
60         };
61
62         // Text-ify function for cells that use display templates.
63         this.cellPrintValues = (row: any, cell: GridColumn): string => {
64             return ({
65                 '+matches': row.matches.length + '',
66                 'import_error': row.import_error,
67                 'imported_as': row.imported_as + ''
68             })[cell.name] || '';
69         };
70     }
71
72     ngOnInit() {
73     }
74
75     limitToMatches(checked: boolean) {
76         this.filters.matches = checked;
77         this.queueGrid.reload();
78     }
79
80     limitToNonImported(checked: boolean) {
81         this.filters.nonImported = checked;
82         this.queueGrid.reload();
83     }
84
85     limitToImportErrors(checked: boolean) {
86         this.filters.withErrors = checked;
87         this.queueGrid.reload();
88     }
89
90     queuePageOffset(): number {
91         return this.vandelay.queuePageOffset;
92     }
93
94     ngAfterViewInit() {
95         if (this.queueType) {
96             this.applyQueueType();
97             if (this.queueId) {
98                 this.loadQueueSummary();
99             }
100         }
101     }
102
103     openRecord(row: any) {
104         if (this.queueType === 'auth') {
105             this.queueType = 'authority';
106         }
107         const url =
108           `/staff/cat/vandelay/queue/${this.queueType}/${this.queueId}/record/${row.id}/marc`;
109         this.router.navigate([url]);
110     }
111
112     applyQueueType() {
113         this.queuedRecClass = this.queueType.match(/bib/) ? 'vqbr' : 'vqar';
114         this.vandelay.getAttrDefs(this.queueType).then(
115             attrs => {
116                 this.attrDefs = attrs;
117                 // Add grid columns for record attributes
118                 attrs.forEach(attr => {
119                     const col = new GridColumn();
120                     col.name = attr.code(),
121                     col.label = attr.description(),
122                     col.datatype = 'string';
123                     this.queueGrid.context.columnSet.add(col);
124                 });
125
126                 // Reapply the grid configuration now that we've
127                 // dynamically added columns.
128                 this.queueGrid.context.applyGridConfig();
129             }
130         );
131     }
132
133     qtypeShort(): string {
134         return this.queueType === 'bib' ? 'bib' : 'auth';
135     }
136
137     loadQueueSummary(): Promise<any> {
138         const method =
139             `open-ils.vandelay.${this.qtypeShort()}_queue.summary.retrieve`;
140
141         return this.net.request(
142             'open-ils.vandelay', method, this.auth.token(), this.queueId)
143         .toPromise().then(sum => this.queueSummary = sum);
144     }
145
146     loadQueueRecords(pager: Pager): Observable<any> {
147
148         const options = {
149             clear_marc: true,
150             offset: pager.offset,
151             limit: pager.limit,
152             flesh_import_items: true,
153             non_imported: this.filters.nonImported,
154             with_import_error: this.filters.withErrors
155         };
156
157         return this.vandelay.getQueuedRecords(
158             this.queueId, this.queueType, options, this.filters.matches).pipe(
159         filter(rec => {
160             // avoid sending mishapen data to the grid
161             // this happens (among other reasons) when the grid
162             // no longer exists
163             const e = this.evt.parse(rec);
164             if (e) { console.error(e); return false; }
165             return true;
166         }),
167         map(rec => {
168             const recHash: any = {
169                 id: rec.id(),
170                 import_error: rec.import_error(),
171                 error_detail: rec.error_detail(),
172                 import_time: rec.import_time(),
173                 imported_as: rec.imported_as(),
174                 import_items: [],
175                 error_items: [],
176                 matches: rec.matches()
177             };
178
179             if (this.queueType === 'bib') {
180                 recHash.import_items = rec.import_items();
181                 recHash.error_items = rec.import_items().filter(i => i.import_error());
182             }
183
184             // Link the record attribute values to the root record
185             // object so the grid can find them.
186             rec.attributes().forEach(attr => {
187                 const def =
188                     this.attrDefs.filter(d => d.id() === attr.field())[0];
189                 recHash[def.code()] = attr.attr_value();
190             });
191
192             return recHash;
193         }));
194     }
195
196     findOrCreateImportSelection() {
197         let selection = this.vandelay.importSelection;
198         if (!selection) {
199             selection = new VandelayImportSelection();
200             this.vandelay.importSelection = selection;
201         }
202         selection.queue = this.queueSummary.queue;
203         return selection;
204     }
205
206     hasOverlayTarget(rid: number): boolean {
207         return this.vandelay.importSelection &&
208             Boolean(this.vandelay.importSelection.overlayMap[rid]);
209     }
210
211     importSelected() {
212         const rows = this.queueGrid.context.getSelectedRows();
213         if (rows.length) {
214             const selection = this.findOrCreateImportSelection();
215             selection.recordIds = rows.map(row => row.id);
216             console.log('importing: ', this.vandelay.importSelection);
217             this.router.navigate(['/staff/cat/vandelay/import']);
218         }
219     }
220
221     importAll() {
222         const selection = this.findOrCreateImportSelection();
223         selection.importQueue = true;
224         this.router.navigate(['/staff/cat/vandelay/import']);
225     }
226
227     deleteQueue() {
228
229         this.confirmDelDlg.open().subscribe(confirmed => {
230             if (!confirmed) { return; }
231
232             this.progressDlg.open();
233             this.net.request(
234                 'open-ils.vandelay',
235                 `open-ils.vandelay.${this.qtypeShort()}_queue.delete`,
236                 this.auth.token(), this.queueId
237             ).toPromise().then(
238                 resp => {
239                     const e = this.evt.parse(resp);
240                     if (e) { return new Error(e.toString()); }
241
242                     // Jump back to the main queue page.
243                     this.router.navigate(['/staff/cat/vandelay/queue']);
244                 },
245                 err => console.error('queue deletion failed!', err)
246             ).finally(() => this.progressDlg.close());
247         });
248     }
249
250     exportNonImported() {
251         this.vandelay.exportQueue(this.queueSummary.queue, true);
252     }
253 }
254