LP1821382 Conjoined linking repairs
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / share / holdings / conjoined-items-dialog.component.ts
1 import {Component, OnInit, OnDestroy, Input, ViewChild, Renderer2} from '@angular/core';
2 import {Subscription} from 'rxjs';
3 import {IdlService} from '@eg/core/idl.service';
4 import {PcrudService} from '@eg/core/pcrud.service';
5 import {ToastService} from '@eg/share/toast/toast.service';
6 import {StoreService} from '@eg/core/store.service';
7 import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
8 import {DialogComponent} from '@eg/share/dialog/dialog.component';
9 import {StringComponent} from '@eg/share/string/string.component';
10 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
11
12
13 /**
14  * Dialog for linking conjoined items.
15  */
16
17 @Component({
18   selector: 'eg-conjoined-items-dialog',
19   templateUrl: 'conjoined-items-dialog.component.html'
20 })
21
22 export class ConjoinedItemsDialogComponent
23     extends DialogComponent implements OnInit, OnDestroy {
24
25     @Input() copyIds: number[];
26     ids: number[]; // copy of list so we can pop()
27
28     peerType: number;
29     numSucceeded: number;
30     numFailed: number;
31     peerTypes: ComboboxEntry[];
32     peerRecord: number;
33     existingMaps: any;
34
35     onOpenSub: Subscription;
36
37     @ViewChild('successMsg')
38         private successMsg: StringComponent;
39
40     @ViewChild('errorMsg')
41         private errorMsg: StringComponent;
42
43     constructor(
44         private modal: NgbModal, // required for passing to parent
45         private toast: ToastService,
46         private idl: IdlService,
47         private pcrud: PcrudService,
48         private localStore: StoreService) {
49         super(modal); // required for subclassing
50         this.peerTypes = [];
51     }
52
53     ngOnInit() {
54         this.onOpenSub = this.onOpen$.subscribe(() => {
55             this.ids = [].concat(this.copyIds);
56             this.numSucceeded = 0;
57             this.numFailed = 0;
58             this.peerRecord =
59                 this.localStore.getLocalItem('eg.cat.marked_conjoined_record');
60
61             if (!this.peerRecord) {
62                 this.close(false);
63             }
64
65             if (this.peerTypes.length === 0) {
66                 this.getPeerTypes();
67             }
68
69             this.fetchExisting();
70         });
71     }
72
73     ngOnDestroy() {
74         this.onOpenSub.unsubscribe();
75     }
76
77     fetchExisting() {
78         this.existingMaps = {};
79         this.pcrud.search('bpbcm',
80             {target_copy: this.copyIds, peer_record: this.peerRecord})
81         .subscribe(map => this.existingMaps[map.target_copy()] = map);
82     }
83
84     getPeerTypes(): Promise<any> {
85         return this.pcrud.retrieveAll('bpt', {}, {atomic: true}).toPromise()
86         .then(types =>
87             // Map types to ComboboxEntry's
88             this.peerTypes = types.map(t => ({id: t.id(), label: t.name()}))
89         );
90     }
91
92     peerTypeChanged(entry: ComboboxEntry) {
93         if (entry) {
94             this.peerType = entry.id;
95         } else {
96             this.peerType = null;
97         }
98     }
99
100     linkCopies(): Promise<any> {
101
102         if (this.ids.length === 0) {
103             this.close(this.numSucceeded > 0);
104             return Promise.resolve();
105         }
106
107         const id = this.ids.pop();
108         const map = this.existingMaps[id] || this.idl.create('bpbcm');
109         map.peer_record(this.peerRecord);
110         map.target_copy(id);
111         map.peer_type(this.peerType);
112
113         let promise: Promise<any>;
114         if (this.existingMaps[id]) {
115             promise = this.pcrud.update(map).toPromise();
116         } else {
117             promise = this.pcrud.create(map).toPromise();
118         }
119
120         return promise.then(
121             ok => {
122                 this.successMsg.current().then(msg => this.toast.success(msg));
123                 this.numSucceeded++;
124                 return this.linkCopies();
125             },
126             err => {
127                 this.numFailed++;
128                 console.error(err);
129                 this.errorMsg.current().then(msg => this.toast.warning(msg));
130                 return this.linkCopies();
131             }
132         );
133     }
134 }
135
136
137