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