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