1 import {Component, Input, Output, OnInit, AfterViewInit, EventEmitter,
2 ViewChild, OnDestroy} from '@angular/core';
3 import {filter} from 'rxjs/operators';
4 import {IdlService} from '@eg/core/idl.service';
5 import {NetService} from '@eg/core/net.service';
6 import {OrgService} from '@eg/core/org.service';
7 import {ServerStoreService} from '@eg/core/server-store.service';
8 import {TagTableService} from './tagtable.service';
9 import {MarcRecord, MarcField} from './marcrecord';
10 import {MarcEditContext} from './editor-context';
11 import {AuthorityLinkingDialogComponent} from './authority-linking-dialog.component';
15 * MARC Record rich editor interface.
19 selector: 'eg-marc-rich-editor',
20 templateUrl: './rich-editor.component.html',
21 styleUrls: ['rich-editor.component.css']
24 export class MarcRichEditorComponent implements OnInit {
26 @Input() context: MarcEditContext;
27 get record(): MarcRecord { return this.context.record; }
31 randId = Math.floor(Math.random() * 100000);
32 stackSubfields: boolean;
33 controlledBibTags: string[] = [];
35 @ViewChild('authLinker', {static: false})
36 authLinker: AuthorityLinkingDialogComponent;
39 private idl: IdlService,
40 private net: NetService,
41 private org: OrgService,
42 private store: ServerStoreService,
43 private tagTable: TagTableService
48 this.store.getItem('cat.marcedit.stack_subfields')
49 .then(stack => this.stackSubfields = stack);
52 this.context.recordChange.subscribe(__ => this.init()));
54 // Changing the Type fixed field means loading new meta-metadata.
55 this.record.fixedFieldChange.pipe(filter(code => code === 'Type'))
56 .subscribe(_ => this.init());
59 init(): Promise<any> {
60 this.dataLoaded = false;
62 if (!this.record) { return Promise.resolve(); }
65 this.tagTable.loadTags({
66 marcRecordType: this.context.recordType,
67 ffType: this.record.recordType()
68 }).then(table => this.context.tagTable = table),
69 this.tagTable.getControlledBibTags().then(
70 tags => this.controlledBibTags = tags),
73 // setTimeout forces all of our sub-components to rerender
74 // themselves each time init() is called. Without this,
75 // changing the record Type would only re-render the fixed
76 // fields editor when data had to be fetched from the
77 // network. (Sometimes the data is cached).
78 setTimeout(() => this.dataLoaded = true)
82 fetchSettings(): Promise<any> {
83 // Fetch at rich editor load time to cache.
84 return this.org.settings(['cat.marc_control_number_identifier']);
87 stackSubfieldsChange() {
88 if (this.stackSubfields) {
89 this.store.setItem('cat.marcedit.stack_subfields', true);
91 this.store.removeItem('cat.marcedit.stack_subfields');
96 return this.context.undoCount();
100 return this.context.redoCount();
104 this.context.requestUndo();
108 this.context.requestRedo();
111 controlFields(): MarcField[] {
112 return this.record.fields.filter(f => f.isCtrlField);
115 dataFields(): MarcField[] {
116 return this.record.fields.filter(f => !f.isCtrlField);
122 this.record.fields.filter(f => this.isControlledBibTag(f.tag))
126 id: f.fieldId, // ignored and echoed by server
130 subfields: f.subfields.map(sf => [sf[0], sf[1]])
134 this.net.request('open-ils.cat',
135 'open-ils.cat.authority.validate.bib_field', fields)
136 .subscribe(checkedField => {
137 const bibField = this.record.fields
138 .filter(f => f.fieldId === +checkedField.id)[0];
140 bibField.authChecked = true;
141 bibField.authValid = checkedField.valid;
145 isControlledBibTag(tag: string): boolean {
146 return this.controlledBibTags && this.controlledBibTags.includes(tag);
149 openLinkerDialog(field: MarcField) {
150 this.authLinker.bibField = field;
151 this.authLinker.open({size: 'xl'}).subscribe(newField => {
152 if (!newField) { return; }
154 // Performs an insert followed by a delete, so the two
155 // fields can be tracked separately for undo/redo actions.
156 const marcField = this.record.newField(newField);
157 this.context.insertField(field, marcField);
158 this.context.deleteField(field);
160 // Mark the insert and delete as an atomic undo/redo action.
161 this.context.setUndoGroupSize(2);