From 75b5ce2a317dad5307d2490c2d2f16e3e3bc3e29 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Sun, 16 Sep 2018 21:37:06 +0300 Subject: [PATCH] Bug 16424: Add framework support to advanced MARC editor Keeps the selected framework, allows selecting another and validates the record using the correct framework. Contains additional minor tweaks to display proper error messages. To test: 1. Add a record with a non-default framework in the basic editor. 2. Switch to advanced editor and make sure the settings menu displays the correct framework. 3. Save the record and confirm that the framework code did not change. 4. Change the framework and save the record again. 5. Verify that the framework code changed. 6. Change one framework to make an extra field mandatory. 7. Make sure that the field is required in the editor when the framework above is selected but not when another framework is selected. Signed-off-by: Michal Denar Signed-off-by: Katrin Fischer Signed-off-by: Nick Clemens --- cataloguing/editor.pl | 4 ++ .../lib/koha/cateditor/koha-backend.js | 59 +++++++++++++---- .../lib/koha/cateditor/marc-editor.js | 26 ++++++++ .../intranet-tmpl/prog/css/cateditor.css | 14 ++-- .../prog/en/includes/cateditor-ui.inc | 21 +++++- .../prog/en/modules/cataloguing/editor.tt | 17 +++++ svc/bib | 3 +- svc/bib_framework | 64 +++++++++++++++++++ 8 files changed, 184 insertions(+), 24 deletions(-) create mode 100755 svc/bib_framework diff --git a/cataloguing/editor.pl b/cataloguing/editor.pl index 0806233fa0..42f35b3f47 100755 --- a/cataloguing/editor.pl +++ b/cataloguing/editor.pl @@ -30,6 +30,7 @@ use C4::Output; use DBIx::Class::ResultClass::HashRefInflator; use Koha::Database; use Koha::MarcSubfieldStructures; +use Koha::BiblioFrameworks; my $input = CGI->new; @@ -60,6 +61,9 @@ $template->{VARS}->{DefaultLanguageField008} = pack( 'A3', C4::Context->preferen my $authtags = Koha::MarcSubfieldStructures->search({ authtypecode => { '!=' => '' }, 'frameworkcode' => '' }); $template->{VARS}->{authtags} = $authtags; +my $frameworks = Koha::BiblioFrameworks->search({}, { order_by => ['frameworktext'] }); +$template->{VARS}->{frameworks} = $frameworks; + # Z39.50 servers my $dbh = C4::Context->dbh; $template->{VARS}->{z3950_servers} = $dbh->selectall_arrayref( q{ diff --git a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/koha-backend.js b/koha-tmpl/intranet-tmpl/lib/koha/cateditor/koha-backend.js index 9e393d3033..49bf3838c3 100644 --- a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/koha-backend.js +++ b/koha-tmpl/intranet-tmpl/lib/koha/cateditor/koha-backend.js @@ -66,9 +66,26 @@ define( [ '/cgi-bin/koha/svc/cataloguing/framework?frameworkcode=&callback=defin while ( record.removeField(bibnumTag) ); } + function initFramework( frameworkcode, callback ) { + if ( typeof _frameworks[frameworkcode] === 'undefined' ) { + $.get( + '/cgi-bin/koha/svc/cataloguing/framework?frameworkcode=' + frameworkcode + ).done( function( framework ) { + _importFramework( frameworkcode, framework.framework ); + callback(); + } ).fail( function( data ) { + callback( 'Could not fetch framework settings' ); + } ); + } else { + callback(); + } + } + var KohaBackend = { NOT_EMPTY: {}, // Sentinel value + InitFramework: initFramework, + GetAllTagsInfo: function( frameworkcode, tagnumber ) { return _framework_mappings[frameworkcode]; }, @@ -89,12 +106,23 @@ define( [ '/cgi-bin/koha/svc/cataloguing/framework?frameworkcode=&callback=defin GetRecord: function( id, callback ) { $.get( '/cgi-bin/koha/svc/bib/' + id - ).done( function( data ) { - var record = new MARC.Record(); - record.loadMARCXML(data); - callback(record); - } ).fail( function( data ) { - callback( { error: data } ); + ).done( function( metadata ) { + $.get( + '/cgi-bin/koha/svc/bib_framework/' + id + ).done( function( frameworkcode ) { + var record = new MARC.Record(); + record.loadMARCXML(metadata); + record.frameworkcode = $(frameworkcode).find('frameworkcode').text(); + initFramework( record.frameworkcode, function( error ) { + if ( typeof error === 'undefined' ) { + callback( record ); + } else { + callback( { error: error } ); + } + }); + } ).fail( function( data ) { + callback( { error: _('Could not fetch frameworkcode for record') } ); + } ); } ); }, @@ -110,21 +138,26 @@ define( [ '/cgi-bin/koha/svc/cataloguing/framework?frameworkcode=&callback=defin } ).done( function( data ) { callback( _fromXMLStruct( data ) ); } ).fail( function( data ) { - callback( { error: data } ); + callback( { error: _('Could not save record') } ); } ); }, SaveRecord: function( id, record, callback ) { + var frameworkcode = record.frameworkcode; record = record.clone(); _removeBiblionumberFields( record ); $.ajax( { type: 'POST', - url: '/cgi-bin/koha/svc/bib/' + id, + url: '/cgi-bin/koha/svc/bib/' + id + '?frameworkcode=' + encodeURIComponent(frameworkcode), data: record.toXML(), contentType: 'text/xml' } ).done( function( data ) { - callback( _fromXMLStruct( data ) ); + var record = _fromXMLStruct( data ); + if ( record.marcxml ) { + record.marcxml[0].frameworkcode = frameworkcode; + } + callback( record ); } ).fail( function( data ) { callback( { data: { error: data } } ); } ); @@ -196,10 +229,10 @@ define( [ '/cgi-bin/koha/svc/cataloguing/framework?frameworkcode=&callback=defin ValidateRecord: function( frameworkcode, record ) { var errors = []; - var mandatoryTags = KohaBackend.GetTagsBy( '', 'mandatory', '1' ); - var mandatorySubfields = KohaBackend.GetSubfieldsBy( '', 'mandatory', '1' ); - var nonRepeatableTags = KohaBackend.GetTagsBy( '', 'repeatable', '0' ); - var nonRepeatableSubfields = KohaBackend.GetSubfieldsBy( '', 'repeatable', '0' ); + var mandatoryTags = KohaBackend.GetTagsBy( record.frameworkcode, 'mandatory', '1' ); + var mandatorySubfields = KohaBackend.GetSubfieldsBy( record.frameworkcode, 'mandatory', '1' ); + var nonRepeatableTags = KohaBackend.GetTagsBy( record.frameworkcode, 'repeatable', '0' ); + var nonRepeatableSubfields = KohaBackend.GetSubfieldsBy( record.frameworkcode, 'repeatable', '0' ); $.each( mandatoryTags, function( tag ) { if ( !record.hasField( tag ) ) errors.push( { type: 'missingTag', tag: tag } ); diff --git a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/marc-editor.js b/koha-tmpl/intranet-tmpl/lib/koha/cateditor/marc-editor.js index 1caf75d83b..046ff71da5 100644 --- a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/marc-editor.js +++ b/koha-tmpl/intranet-tmpl/lib/koha/cateditor/marc-editor.js @@ -478,6 +478,8 @@ define( [ 'marc-record', 'koha-backend', 'preferences', 'text-marc', 'widget' ], } ); function MARCEditor( options ) { + this.frameworkcode = ''; + this.cm = CodeMirror( options.position, { @@ -535,9 +537,32 @@ define( [ 'marc-record', 'koha-backend', 'preferences', 'text-marc', 'widget' ], this.cm.refresh(); }, + setFrameworkCode: function( code, callback ) { + this.frameworkcode = code; + $( 'a.change-framework i.selected' ).addClass( 'hidden' ); + $( 'a.change-framework i.unselected' ).removeClass( 'hidden' ); + $( 'a.change-framework[data-frameworkcode="' + code + '"] i.unselected' ).addClass( 'hidden' ); + $( 'a.change-framework[data-frameworkcode="' + code + '"] i.selected' ).removeClass( 'hidden '); + KohaBackend.InitFramework( code, callback ); + }, + displayRecord: function( record ) { this.cm.setValue( TextMARC.RecordToText(record) ); this.modified = false; + var cm = this.cm; + this.setFrameworkCode( + typeof record.frameworkcode !== 'undefined' ? record.frameworkcode : '', + function ( error ) { + if ( typeof error !== 'undefined' ) { + humanMsg.displayAlert( _(error), { className: 'humanError' } ); + } + cm.setOption( 'mode', { + name: 'marc', + nonRepeatableTags: KohaBackend.GetTagsBy( this.frameworkcode, 'repeatable', '0' ), + nonRepeatableSubfields: KohaBackend.GetSubfieldsBy( this.frameworkcode, 'repeatable', '0' ) + }); + } + ); }, getRecord: function() { @@ -553,6 +578,7 @@ define( [ 'marc-record', 'koha-backend', 'preferences', 'text-marc', 'widget' ], this.textMode = false; + record.frameworkcode = this.frameworkcode; return record; }, diff --git a/koha-tmpl/intranet-tmpl/prog/css/cateditor.css b/koha-tmpl/intranet-tmpl/prog/css/cateditor.css index 6840d0c6a1..b134b66438 100644 --- a/koha-tmpl/intranet-tmpl/prog/css/cateditor.css +++ b/koha-tmpl/intranet-tmpl/prog/css/cateditor.css @@ -55,6 +55,12 @@ body { padding-bottom: 0; } +.humanMsg.humanSuccess { + left: 75%; + width: 20%; + top: 160px; +} + #shortcuts-container { font-size: 12px; } @@ -283,14 +289,6 @@ body { width: 14em; } -.fa.fa-spinner { - display: inline-block; - height: 16px; - width: 16px; - background: transparent url("../img/spinner-small.gif") top left no-repeat; - padding: -1px; - vertical-align: text-top; -} /*> Search results */ diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc index 7dd6f9d61d..a20bbe6eed 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc @@ -329,6 +329,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr if (data.newRecord) { var record = new MARC.Record(); record.loadMARCXML(data.newRecord); + record.frameworkcode = data.newRecord.frameworkcode; editor.displayRecord( record ); } @@ -841,7 +842,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr // Click bindings $( '#save-record, #save-dropdown a' ).click( function() { - $( '#save-record' ).find('i').attr( 'class', 'fa fa-spinner' ).siblings( 'span' ).text( _("Saving...") ); + $( '#save-record' ).find('i').attr( 'class', 'fa fa-spinner fa-spin' ).siblings( 'span' ).text( _("Saving...") ); function finishCb(result) { if ( result.error == 'syntax' ) { @@ -1093,6 +1094,19 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr { return undefined; } }; + $('a.change-framework').click( function() { + $("#loading").show(); + editor.setFrameworkCode( + $(this).data( 'frameworkcode' ), + function ( error ) { + if ( typeof error !== 'undefined' ) { + humanMsg.displayAlert( _("Failed to change framework"), { className: 'humanError' } ); + } + $('#loading').hide(); + } + ); + } ); + // Start editor Preferences.Load( [% logged_in_user.borrowernumber || 0 | html %] ); displayPreferences(editor); @@ -1104,7 +1118,10 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr } ); function finishCb( data ) { - if ( data.error ) openRecord( 'new/', editor, finishCb ); + if ( data.error ) { + humanMsg.displayAlert( data.error ); + openRecord( 'new/', editor, finishCb ); + } Resources.GetAll().done( function() { $("#loading").hide(); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/editor.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/editor.tt index b282489e27..503552fa0f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/editor.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/editor.tt @@ -49,6 +49,23 @@