From 7f83d0319fe961edb9478d5f26a93f6683153ea1 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Thu, 19 Dec 2019 18:00:27 -0500 Subject: [PATCH] LP1852782 MARC edit inline authority record creation. Implement support for creating a new authority record from a bib field in "immediate" (non-editing) mode. Signed-off-by: Bill Erickson Signed-off-by: Jane Sandberg --- .../authority-linking-dialog.component.html | 17 +- .../authority-linking-dialog.component.ts | 59 ++++- .../marc-edit/editable-content.component.ts | 24 +- .../staff/share/marc-edit/editor-context.ts | 3 + .../marc-edit/editor-dialog.component.html | 14 ++ .../marc-edit/editor-dialog.component.ts | 44 ++++ .../share/marc-edit/editor.component.html | 16 +- .../staff/share/marc-edit/editor.component.ts | 97 ++++++-- .../share/marc-edit/fixed-field.component.ts | 5 +- .../staff/share/marc-edit/marc-edit.module.ts | 2 + .../marc-edit/rich-editor.component.html | 9 +- .../share/marc-edit/rich-editor.component.ts | 21 +- .../staff/share/marc-edit/tagtable.service.ts | 211 +++++++++++------- Open-ILS/src/eg2/src/styles.css | 5 + .../lib/OpenILS/Application/Cat/Authority.pm | 30 ++- 15 files changed, 402 insertions(+), 155 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-dialog.component.html create mode 100644 Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-dialog.component.ts diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.html index c0e9558433..df251677b3 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.html +++ b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.html @@ -7,9 +7,14 @@ + + + + - See From: {{field.heading}} @@ -54,12 +59,10 @@
Create new authority from this field
- - + +
diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.ts index 2015ec187c..1c7d3a5d1c 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/authority-linking-dialog.component.ts @@ -1,10 +1,14 @@ -import {Component, Input, Output, OnInit, EventEmitter} from '@angular/core'; +import {Component, ViewChild, Input, Output, OnInit, EventEmitter} from '@angular/core'; import {NetService} from '@eg/core/net.service'; +import {OrgService} from '@eg/core/org.service'; +import {AuthService} from '@eg/core/auth.service'; import {PcrudService} from '@eg/core/pcrud.service'; import {DialogComponent} from '@eg/share/dialog/dialog.component'; import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; import {MarcField} from './marcrecord'; +import {MarcEditContext} from './editor-context'; import {Pager} from '@eg/share/util/pager'; +import {MarcEditorDialogComponent} from './editor-dialog.component'; /** * MARC Authority Linking Dialog @@ -22,6 +26,7 @@ export class AuthorityLinkingDialogComponent @Input() thesauri: string = null; @Input() controlSet: number = null; @Input() pager: Pager; + @Input() context: MarcEditContext; browseData: any[] = []; @@ -32,8 +37,15 @@ export class AuthorityLinkingDialogComponent selectedSubfields: string[] = []; + cni: string; // Control Number Identifier + + @ViewChild('marcEditDialog', {static: false}) + marcEditDialog: MarcEditorDialogComponent; + constructor( private modal: NgbModal, + private auth: AuthService, + private org: OrgService, private pcrud: PcrudService, private net: NetService) { super(modal); @@ -61,9 +73,14 @@ export class AuthorityLinkingDialogComponent initData() { - this.pager.offset = 0; + this.pager.offset = 0; + + this.org.settings(['cat.marc_control_number_identifier']).then(s => { + this.cni = s['cat.marc_control_number_identifier'] || + 'Set cat.marc_control_number_identifier in Library Settings'; + }); - this.pcrud.search('acsbf', + this.pcrud.search('acsbf', {tag: this.bibField.tag}, {flesh: 1, flesh_fields: {acsbf: ['authority_field']}}, {atomic: true, anonymous: true} @@ -130,5 +147,41 @@ export class AuthorityLinkingDialogComponent return this.authMeta ? this.authMeta.sf_list().includes(sf) : false; } + + setSubfieldZero(authId: number) { + const sfZero = this.bibField.subfields.filter(sf => sf[0] === '0')[0]; + if (sfZero) { + this.context.deleteSubfield(this.bibField, sfZero); + } + this.context.insertSubfield(this.bibField, + ['0', `(${this.cni})${authId}`, this.bibField.subfields.length]); + } + + createNewAuthority(editFirst?: boolean) { + + const method = editFirst ? + 'open-ils.cat.authority.record.create_from_bib.readonly' : + 'open-ils.cat.authority.record.create_from_bib'; + + this.net.request( + 'open-ils.cat', method, + this.fieldHash(), this.cni, this.auth.token() + ).subscribe(record => { + if (editFirst) { + this.marcEditDialog.recordXml = record; + this.marcEditDialog.open({size: 'xl'}) + .subscribe(saveEvent => { + if (saveEvent && saveEvent.recordId) { + this.setSubfieldZero(saveEvent.recordId); + } + this.close(); + }); + } else { + this.setSubfieldZero(record.id()); + this.close(); + } + }); + } } + diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editable-content.component.ts b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editable-content.component.ts index 88be84c592..1bcc19dd65 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editable-content.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editable-content.component.ts @@ -6,8 +6,8 @@ import {MarcRecord, MarcField, MarcSubfield} from './marcrecord'; import {MarcEditContext, FieldFocusRequest, MARC_EDITABLE_FIELD_TYPE, TextUndoRedoAction} from './editor-context'; import {ContextMenuEntry} from '@eg/share/context-menu/context-menu.service'; -import {TagTableService} from './tagtable.service'; import {StringComponent} from '@eg/share/string/string.component'; +import {TagTable} from './tagtable.service'; /** * MARC Editable Content Component @@ -73,9 +73,11 @@ export class EditableContentComponent @ViewChild('insertAfter', {static: false}) insertAfterStr: StringComponent; @ViewChild('deleteField', {static: false}) deleteFieldStr: StringComponent; - constructor( - private renderer: Renderer2, - private tagTable: TagTableService) {} + constructor(private renderer: Renderer2) {} + + tt(): TagTable { // for brevity + return this.context.tagTable; + } ngOnInit() { this.setupFieldType(); @@ -197,8 +199,7 @@ export class EditableContentComponent } applyFFOptions() { - return this.tagTable.getFfFieldMeta( - this.fixedFieldCode, this.record.recordType()) + return this.tt().getFfFieldMeta(this.fixedFieldCode) .then(fieldMeta => { if (fieldMeta) { this.maxLength = fieldMeta.length || 1; @@ -216,20 +217,19 @@ export class EditableContentComponent return this.tagContextMenuEntries(); case 'sfc': - return this.tagTable.getSubfieldCodes(this.field.tag); + return this.tt().getSubfieldCodes(this.field.tag); case 'sfv': - return this.tagTable.getSubfieldValues( + return this.tt().getSubfieldValues( this.field.tag, this.subfield[0]); case 'ind1': case 'ind2': - return this.tagTable.getIndicatorValues( + return this.tt().getIndicatorValues( this.field.tag, this.fieldType); case 'ffld': - return this.tagTable.getFfValues( - this.fixedFieldCode, this.record.recordType()); + return this.tt().getFfValues(this.fixedFieldCode); } return null; @@ -261,7 +261,7 @@ export class EditableContentComponent {divider: true} ); - this.tagTable.getFieldTags().forEach(e => this.tagMenuEntries.push(e)); + this.tt().getFieldTags().forEach(e => this.tagMenuEntries.push(e)); return this.tagMenuEntries; } diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-context.ts b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-context.ts index 16a8caeecc..28335f81cb 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-context.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-context.ts @@ -1,6 +1,7 @@ import {EventEmitter} from '@angular/core'; import {MarcRecord, MarcField, MarcSubfield} from './marcrecord'; import {NgbPopover} from '@ng-bootstrap/ng-bootstrap'; +import {TagTable} from './tagtable.service'; /* Per-instance MARC editor context. */ @@ -65,6 +66,8 @@ export class MarcEditContext { undoStack: UndoRedoAction[] = []; redoStack: UndoRedoAction[] = []; + tagTable: TagTable; + // True if any changes have been made. // For the 'rich' editor, this is any un-do-able actions. // For the text edtior it's any text change. diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-dialog.component.html new file mode 100644 index 0000000000..1fc6efa694 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-dialog.component.html @@ -0,0 +1,14 @@ + + + + + diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-dialog.component.ts new file mode 100644 index 0000000000..67e836bb0c --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor-dialog.component.ts @@ -0,0 +1,44 @@ +import {Component, Input, Output, OnInit, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs'; +import {NetService} from '@eg/core/net.service'; +import {OrgService} from '@eg/core/org.service'; +import {AuthService} from '@eg/core/auth.service'; +import {PcrudService} from '@eg/core/pcrud.service'; +import {DialogComponent} from '@eg/share/dialog/dialog.component'; +import {NgbModal, NgbModalRef, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap'; +import {MarcEditContext} from './editor-context'; + + +/** + * Spawn a MARC editor within a dialog. + */ + +@Component({ + selector: 'eg-marc-editor-dialog', + templateUrl: './editor-dialog.component.html' +}) + +export class MarcEditorDialogComponent + extends DialogComponent implements OnInit { + + @Input() context: MarcEditContext; + @Input() recordXml: string; + @Input() recordType: 'biblio' | 'authority' = 'biblio'; + + constructor( + private modal: NgbModal, + private auth: AuthService, + private org: OrgService, + private pcrud: PcrudService, + private net: NetService) { + super(modal); + } + + ngOnInit() {} + + handleRecordSaved(saved) { + this.close(saved); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.component.html b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.component.html index 7daa2c89b2..f574604470 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.component.html +++ b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.component.html @@ -26,13 +26,15 @@ -
- - -
+ +
+ + +
+
-
+ +
+