74e70f1f9e2e9d3e1c8d87ae0e65d1bb9ce913aa
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / cat / vandelay / queued-record-matches.component.ts
1 import {Component, Input, OnInit, ViewChild} from '@angular/core';
2 import {Router, ActivatedRoute, ParamMap} from '@angular/router';              
3 import {Observable} from 'rxjs/Observable';
4 import 'rxjs/add/observable/of';
5 import {map} from 'rxjs/operators/map';
6 import {Pager} from '@eg/share/util/pager';
7 import {GridComponent} from '@eg/share/grid/grid.component';
8 import {GridDataSource, GridColumn} from '@eg/share/grid/grid';
9 import {IdlObject} from '@eg/core/idl.service';
10 import {EventService} from '@eg/core/event.service';
11 import {NetService} from '@eg/core/net.service';
12 import {AuthService} from '@eg/core/auth.service';
13 import {PcrudService} from '@eg/core/pcrud.service';
14 import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.service';
15 import {VandelayService, VandelayImportSelection} from './vandelay.service';
16
17 @Component({
18   selector: 'eg-queued-record-matches',
19   templateUrl: 'queued-record-matches.component.html'
20 })
21 export class QueuedRecordMatchesComponent implements OnInit {
22
23     @Input() queueType: string;
24     @Input() recordId: number;
25     @ViewChild('bibGrid') bibGrid: GridComponent;
26     @ViewChild('authGrid') authGrid: GridComponent;
27
28     queuedRecord: IdlObject;
29     bibDataSource: GridDataSource;
30     authDataSource: GridDataSource;
31     markOverlayTarget: (rows: any[]) => any;
32     matchRowClick: (row: any) => void;
33     matchMap: {[id: number]: IdlObject};
34
35     constructor(
36         private router: Router,
37         private route: ActivatedRoute,
38         private evt: EventService,
39         private net: NetService,
40         private auth: AuthService,
41         private pcrud: PcrudService,
42         private bib: BibRecordService,
43         private vandelay: VandelayService) {
44
45         this.bibDataSource = new GridDataSource();
46         this.authDataSource = new GridDataSource();
47
48         this.bibDataSource.getRows = (pager: Pager) => {
49             return this.getBibMatchRows(pager);
50         }
51
52         /* TODO
53         this.authDataSource.getRows = (pager: Pager) => {
54         }
55         */
56
57         // Mark or un-mark as row as the merge target on row click
58         this.matchRowClick = (row: any) => {
59             this.toggleMergeTarget(row.id);
60         }
61     }
62
63     toggleMergeTarget(matchId: number) {
64
65         if (this.isOverlayTarget(matchId)) {
66
67             // clear selection on secondary click;
68             delete this.vandelay.importSelection.overlayMap[this.recordId];
69
70         } else {
71             // Add to selection.
72             // Start a new one if necessary, which will be adopted
73             // and completed by the queue UI before import.
74
75             let selection = this.vandelay.importSelection;
76             if (!selection) {
77                 selection = new VandelayImportSelection();
78                 this.vandelay.importSelection = selection;
79             }
80             const match = this.matchMap[matchId];
81             selection.overlayMap[this.recordId] = match.eg_record();
82         }
83     }
84
85     isOverlayTarget(matchId: number): boolean {
86         const selection = this.vandelay.importSelection;
87         if (selection) {
88             const match = this.matchMap[matchId];
89             return selection.overlayMap[this.recordId] === match.eg_record();
90         }
91         return false;
92     }
93
94     ngOnInit() {}
95
96     // This thing is a nesty beast -- clean it up
97     getBibMatchRows(pager: Pager): Observable<any> {
98
99         return new Observable(observer => {
100
101             this.getQueuedRecord().then(() => {
102
103                 const matches = this.queuedRecord.matches();
104                 const recIds = [];
105                 this.matchMap = {};
106                 matches.forEach(m => {
107                     this.matchMap[m.id()] = m;
108                     if (!recIds.includes(m.eg_record())) {
109                         recIds.push(m.eg_record());
110                     }
111                 });
112
113                 const bibSummaries: {[id: number]: BibRecordSummary} = {};
114                 this.bib.getBibSummary(recIds).subscribe(
115                     summary => bibSummaries[summary.id] = summary,
116                     err => {},
117                     ()  => {
118                         this.bib.fleshBibUsers(
119                             Object.values(bibSummaries).map(sum => sum.record)
120                         ).then(() => {
121                             matches.forEach(match => {
122                                 const row = {
123                                     id: match.id(),
124                                     eg_record: match.eg_record(),
125                                     bre_quality: match.quality(),
126                                     vqbr_quality: this.queuedRecord.quality(),
127                                     match_score: match.match_score(),
128                                     bib_summary: bibSummaries[match.eg_record()]
129                                 }
130
131                                 observer.next(row);
132                             });
133
134                             observer.complete();
135                         });
136                     }
137                 );
138             });
139         });
140     }
141
142     getQueuedRecord(): Promise<any> {
143         if (this.queuedRecord) {
144             return Promise.resolve('');
145         }
146         let idlClass = this.queueType === 'bib' ? 'vqbr' : 'vqar';
147         const flesh = {flesh: 1, flesh_fields: {}};
148         flesh.flesh_fields[idlClass] = ['matches'];
149         return this.pcrud.retrieve(idlClass, this.recordId, flesh)
150             .toPromise().then(rec => this.queuedRecord = rec);
151     }
152 }
153