]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.ts
LP1907115 MARC editor avoid ID collisions
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / share / marc-edit / authority-linking-dialog.component.ts
1 import {Component, ViewChild, Input, Output, OnInit, EventEmitter} from '@angular/core';
2 import {NetService} from '@eg/core/net.service';
3 import {OrgService} from '@eg/core/org.service';
4 import {AuthService} from '@eg/core/auth.service';
5 import {PcrudService} from '@eg/core/pcrud.service';
6 import {DialogComponent} from '@eg/share/dialog/dialog.component';
7 import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
8 import {MarcField} from './marcrecord';
9 import {MarcEditContext} from './editor-context';
10 import {Pager} from '@eg/share/util/pager';
11 import {MarcEditorDialogComponent} from './editor-dialog.component';
12
13 /**
14  * MARC Authority Linking Dialog
15  */
16
17 @Component({
18   selector: 'eg-authority-linking-dialog',
19   templateUrl: './authority-linking-dialog.component.html'
20 })
21
22 export class AuthorityLinkingDialogComponent
23     extends DialogComponent implements OnInit {
24
25     @Input() bibField: MarcField;
26     @Input() thesauri: string = null;
27     @Input() controlSet: number = null;
28     @Input() pager: Pager;
29     @Input() context: MarcEditContext;
30
31     browseData: any[] = [];
32
33     // If false, show the raw MARC field data.
34     showAs: 'heading' | 'marc' = 'heading';
35
36     authMeta: any;
37
38     selectedSubfields: string[] = [];
39
40     cni: string; // Control Number Identifier
41
42     @ViewChild('marcEditDialog', {static: false})
43         marcEditDialog: MarcEditorDialogComponent;
44
45     constructor(
46         private modal: NgbModal,
47         private auth: AuthService,
48         private org: OrgService,
49         private pcrud: PcrudService,
50         private net: NetService) {
51         super(modal);
52     }
53
54     ngOnInit() {
55         if (!this.pager) {
56             this.pager = new Pager();
57             this.pager.limit = 5;
58         }
59
60         this.onOpen$.subscribe(_ => this.initData());
61     }
62
63     fieldHash(field?: MarcField): any {
64         if (!field) { field = this.bibField; }
65
66         return {
67             tag: field.tag,
68             ind1: field.ind1,
69             ind2: field.ind2,
70             subfields: field.subfields.map(sf => [sf[0], sf[1]])
71         };
72     }
73
74     initData() {
75
76         this.pager.offset = 0;
77
78         this.org.settings(['cat.marc_control_number_identifier']).then(s => {
79             this.cni = s['cat.marc_control_number_identifier'] ||
80                 'Set cat.marc_control_number_identifier in Library Settings';
81         });
82
83         this.pcrud.search('acsbf',
84             {tag: this.bibField.tag},
85             {flesh: 1, flesh_fields: {acsbf: ['authority_field']}},
86             {atomic:  true, anonymous: true}
87
88         ).subscribe(bibMetas => {
89             if (bibMetas.length === 0) { return; }
90
91             let bibMeta;
92             if (this.controlSet) {
93                 bibMeta = bibMetas.filter(b =>
94                     this.controlSet === +b.authority_field().control_set());
95             } else {
96                 bibMeta = bibMetas[0];
97             }
98
99             if (bibMeta) {
100                 this.authMeta = bibMeta.authority_field();
101                 this.bibField.subfields.forEach(sf =>
102                     this.selectedSubfields[sf[0]] =
103                         this.isControlledBibSf(sf[0])
104                 );
105             }
106
107             this.getPage(0);
108         });
109     }
110
111     getPage(direction: number) {
112         this.browseData = [];
113
114         if (direction > 0) {
115             this.pager.offset++;
116         } else if (direction < 0) {
117             this.pager.offset--;
118         } else {
119             this.pager.offset = 0;
120         }
121
122         const hash = this.fieldHash();
123
124         // Only search the selected subfields
125         hash.subfields =
126             hash.subfields.filter(sf => this.selectedSubfields[sf[0]]);
127
128         if (hash.subfields.length === 0) { return; }
129
130         this.net.request(
131             'open-ils.cat',
132             'open-ils.cat.authority.bib_field.linking_browse',
133             hash, this.pager.limit,
134             this.pager.offset, this.thesauri
135         ).subscribe(entry => this.browseData.push(entry));
136     }
137
138     applyHeading(authField: MarcField, authId?: number) {
139         this.net.request(
140             'open-ils.cat',
141             'open-ils.cat.authority.bib_field.overlay_authority',
142             this.fieldHash(), this.fieldHash(authField), this.controlSet
143         ).subscribe(field => {
144             if (authId) {
145                 // If an authId is provided, it means we are using
146                 // a main entry heading and we should set the bib
147                 // field's subfield 0 to refer to the main entry record.
148                 this.setSubfieldZero(authId, field);
149             }
150             this.close(field);
151         });
152     }
153
154     isControlledBibSf(sf: string): boolean {
155         return this.authMeta ?
156             this.authMeta.sf_list().includes(sf) : false;
157     }
158
159     setSubfieldZero(authId: number, bibField?: MarcField) {
160
161         if (!bibField) { bibField = this.bibField; }
162
163         const sfZero = bibField.subfields.filter(sf => sf[0] === '0')[0];
164         if (sfZero) {
165             this.context.deleteSubfield(bibField, sfZero);
166         }
167         this.context.insertSubfield(bibField,
168             ['0', `(${this.cni})${authId}`, bibField.subfields.length]);
169
170         // Reset the validation state.
171         bibField.authChecked = null;
172         bibField.authValid = null;
173     }
174
175     createNewAuthority(editFirst?: boolean) {
176
177         const method = editFirst ?
178             'open-ils.cat.authority.record.create_from_bib.readonly' :
179             'open-ils.cat.authority.record.create_from_bib';
180
181         this.net.request(
182             'open-ils.cat', method,
183             this.fieldHash(), this.cni, this.auth.token()
184         ).subscribe(record => {
185             if (editFirst) {
186                 this.marcEditDialog.recordXml = record;
187                 this.marcEditDialog.open({size: 'xl'})
188                 .subscribe(saveEvent => {
189                     if (saveEvent && saveEvent.recordId) {
190                         this.setSubfieldZero(saveEvent.recordId);
191                     }
192                     this.close();
193                 });
194             } else {
195                 this.setSubfieldZero(record.id());
196                 this.close();
197             }
198         });
199     }
200 }
201
202