[% USE raw %]
-[% Asset.js("lib/codemirror/codemirror-compressed.js") | $raw %]
+[% USE Koha %]
+[% Asset.js("lib/codemirror/codemirror.min.js") | $raw %]
[% Asset.js("lib/filesaver.js") | $raw %]
+[% Asset.css("lib/keyboard/css/keyboard.min.css") | $raw %]
+[% Asset.js("lib/keyboard/js/jquery.keyboard.js") | $raw %]
+[% Asset.js("lib/keyboard/languages/all.min.js") | $raw %]
+[% Asset.js("lib/keyboard/layouts/all.min.js") | $raw %]
[% Asset.js("lib/koha/cateditor/marc-mode.js") | $raw %]
[% Asset.js("lib/require.js") | $raw %]
+<!-- cateditor-ui.inc -->
<script>
+[% FOREACH shortcut IN shortcuts -%]
+ var [% shortcut.shortcut_name | html %] = "[% shortcut.shortcut_keys | html %]";
+[% END %]
var authInfo = {
[%- FOREACH authtag = authtags -%]
[% authtag.tagfield | html %]: {
<script>
require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'preferences', 'resources', 'text-marc', 'widget' ], function( KohaBackend, Search, Macros, MARCEditor, MARC, Preferences, Resources, TextMARC, Widget ) {
- var z3950Servers = {
- 'koha:biblioserver': {
+ var z3950Servers = [
+ {
+ server_id: 'koha:biblioserver',
name: _("Local catalog"),
recordtype: 'biblio',
checked: false,
},
[%- FOREACH server = z3950_servers -%]
- [% server.id | html %]: {
- name: '[% server.servername | html %]',
+ {
+ server_id: [% server.id | html %],
+ name: '[% server.servername | html_entity %]',
recordtype: '[% server.recordtype | html %]',
checked: [% server.checked ? 'true' : 'false' | html %],
},
[%- END -%]
- };
+ ];
// The columns that should show up in a search, in order, and keyed by the corresponding <metadata> tag in the XSL and Pazpar2 config
var z3950Labels = [
[ "local_number", _("Local number") ],
[ "title", _("Title") ],
+ [ "subtitle",_("Subtitle") ],
[ "series", _("Series title") ],
[ "author", _("Author") ],
[ "lccn", _("LCCN") ],
[ "issn", _("ISSN") ],
[ "medium", _("Medium") ],
[ "edition", _("Edition") ],
+ [ "date", _("Published") ],
[ "notes", _("Notes") ],
];
}
function getFieldHelpURL( tag ) {
- [% IF ( marcflavour == 'MARC21' ) %]
+ [% IF Koha.Preference('marcfielddocurl') %]
+ var docurl = "[% Koha.Preference('marcfielddocurl').replace('"','"') | html %]";
+ docurl = docurl.replace("{MARC}", "[% marcflavour | html %]");
+ docurl = docurl.replace("{FIELD}", ""+tag);
+ docurl = docurl.replace("{LANG}", "[% lang | html %]");
+ return docurl;
+ [% ELSIF ( marcflavour == 'MARC21' ) %]
if ( tag == '000' ) {
return "http://www.loc.gov/marc/bibliographic/bdleader.html";
} else if ( tag >= '090' && tag < '100' ) {
callback( record );
},
},
+ 'duplicate': {
+ titleForRecord: _("Editing duplicate record of #{ID}"),
+ saveLabel: _("Duplicate"),
+ get: function( id, callback ) {
+ if ( !id ) return false;
+
+ KohaBackend.GetRecord( id, callback );
+ },
+ save: function( id, record, done ) {
+ function finishCb( data ) {
+ done( { error: data.error, newRecord: data.marcxml && data.marcxml[0], newId: data.biblionumber && [ 'catalog', data.biblionumber ] } );
+ }
+
+ KohaBackend.CreateRecord( record, finishCb );
+ }
+ },
'catalog': {
titleForRecord: _("Editing catalog record #{ID}"),
links: [
}
},
'iso2709': {
- saveLabel: _("Save as ISO2709 (.mrc) file"),
+ saveLabel: _("Save as MARC (.mrc) file"),
save: function( id, record, done ) {
- saveAs( new Blob( [record.toISO2709()], { 'type': 'application/octet-stream;charset=utf-8' } ), 'record.mrc' );
+ var recname = 'record.mrc';
+ if(state.recordID) {
+ recname = 'bib-'+state.recordID+'.mrc';
+ }
+
+ [% IF (Koha.Preference('DefaultSaveRecordFileID') == 'controlnumber') %]
+ var controlnumfield = record.field('001');
+ if(controlnumfield) {
+ recname = 'record-'+controlnumfield.subfield('@')+'.mrc';
+ }
+ [% END %]
+ saveAs( new Blob( [record.toISO2709()], { 'type': 'application/octet-stream;charset=utf-8' } ), recname );
done( {} );
}
'marcxml': {
saveLabel: _("Save as MARCXML (.xml) file"),
save: function( id, record, done ) {
- saveAs( new Blob( [record.toXML()], { 'type': 'application/octet-stream;charset=utf-8' } ), 'record.xml' );
+ var recname = 'record.xml';
+ if(state.recordID) {
+ recname = 'bib-'+state.recordID+'.xml';
+ }
+
+ [% IF (Koha.Preference('DefaultSaveRecordFileID') == 'controlnumber') %]
+ var controlnumfield = record.field('001');
+ if(controlnumfield) {
+ recname = 'record-'+controlnumfield.subfield('@')+'.xml';
+ }
+ [% END %]
+ saveAs( new Blob( [record.toXML()], { 'type': 'application/octet-stream;charset=utf-8' } ), recname );
done( {} );
}
// Search functions
function showAdvancedSearch() {
$('#advanced-search-servers').empty();
- $.each( z3950Servers, function( server_id, server ) {
- $('#advanced-search-servers').append( '<li data-server-id="' + server_id + '"><label><input class="search-toggle-server" type="checkbox"' + ( server.checked ? ' checked="checked">' : '>' ) + server.name + '</label></li>' );
+ $.each( z3950Servers, function( index, server ) {
+ $('#advanced-search-servers').append( '<li data-server-id="' + index + '"><label><input class="search-toggle-server" type="checkbox"' + ( server.checked ? ' checked="checked">' : '>' ) + server.name + '</label></li>' );
} );
$('#advanced-search-ui').modal('show');
}
$('#searchresults tbody').empty();
$('#search-serversinfo').empty();
- $.each( z3950Servers, function( server_id, server ) {
- var num_fetched = data.num_fetched[server_id];
+ $.each( z3950Servers, function( index, server ) {
+ var num_fetched = data.num_fetched[server.server_id];
- if ( data.errors[server_id] ) {
- num_fetched = data.errors[server_id];
+ if ( data.errors[server.server_id] ) {
+ num_fetched = data.errors[server.server_id];
} else if ( num_fetched == null ) {
num_fetched = '-';
- } else if ( num_fetched < data.num_hits[server_id] ) {
+ } else if ( num_fetched < data.num_hits[server.server_id] ) {
num_fetched += '+';
}
- $('#search-serversinfo').append( '<li data-server-id="' + server_id + '"><label><input class="search-toggle-server" type="checkbox"' + ( server.checked ? ' checked="checked">' : '>' ) + server.name + ' (' + num_fetched + ')' + '</label></li>' );
+ $('#search-serversinfo').append( '<li data-server-id="' + index + '"><label><input class="search-toggle-server" type="checkbox"' + ( server.checked ? ' checked="checked">' : '>' ) + server.name + ' (' + num_fetched + ')' + '</label></li>' );
} );
var seenColumns = {};
}
var result = '<tr>';
- result += '<td class="sourcecol">' + z3950Servers[ hit.server ].name + '</td>';
+ var server_name = hit.servername == 'koha:biblioserver' ? _("Local catalog") : hit.servername;
+ result += '<td class="sourcecol">' + server_name + '</td>';
$.each( z3950Labels, function( undef, label ) {
if ( !seenColumns[ label[0] ] ) return;
// Macros loaded on first show of modal
break;
case 'selected_search_targets':
- $.each( z3950Servers, function( server_id, server ) {
- var saved_val = Preferences.user.selected_search_targets[server_id];
+ $.each( z3950Servers, function( index, server ) {
+ var saved_val = Preferences.user.selected_search_targets[server.server_id];
if ( saved_val != null ) server.checked = saved_val;
} );
}
//> Macro functions
- function loadMacro( name ) {
+ var canCreatePublic = "[% CAN_user_editcatalogue_create_shared_macros | html %]";
+ var canDeletePublic = "[% CAN_user_editcatalogue_delete_shared_macros | html %]";
+
+ function deleteMacro( id ){
+ $( '#macro-list' ).empty();
+ var shared = macroEditor.activeMacroShared;
+ var id = macroEditor.activeMacroId;
+ macroEditor.activeMacroId = null;
+ api_url = "/api/v1/advanced_editor/macros/";
+ if( shared ) { api_url += "shared/" }
+ let options = {
+ url: api_url + id,
+ method: "DELETE",
+ contentType: "application/json",
+ };
+ $.ajax(options)
+ .then(function(result) {
+ humanMsg.displayAlert( _("Macro successfully deleted") );
+ showSavedMacros();
+ })
+ .fail(function(err) {
+ var err_message;
+ if( err.status == "404" ){
+ err_message = "Macro not found";
+ } else if ( err.status == "403" ){
+ err_message = _("You do not have permission to delete this macro");
+ } else {
+ err_message = _("There was a problem, please check the logs");
+ }
+ humanMsg.displayAlert( _("Failed to delete macro: " + err_message), { className: 'humanError' } );
+ });
+ }
+
+
+ function loadMacro( name, id, shared ) {
$( '#macro-list li' ).removeClass( 'active' );
+ $(".macro_shared").prop("checked",false).hide();
+ $("#delete-macro").prop("disabled",true);
+ macroEditor.setOption( 'readOnly', false );
macroEditor.activeMacro = name;
+ macroEditor.activeMacroId = id;
if ( !name ) {
macroEditor.setValue( '' );
return;
}
+ $( '#macro-list li[data-name="' + name + '"][data-id="' + id + '"]' ).addClass( 'active' );
+ api_url = "/api/v1/advanced_editor/macros/";
+ if( shared ) { api_url += "shared/" }
+ let options = {
+ url: api_url + id,
+ method: "GET",
+ contentType: "application/json",
+ };
+ $.ajax(options)
+ .then(function(result) {
+ macroEditor.setValue( result.macro_text );
+ $(".macro_shared").show();
+ if( result.shared ){
+ $(".macro_shared").prop("checked",true);
+ if( canCreatePublic ){
+ macroEditor.setOption( 'readOnly', false );
+ } else {
+ macroEditor.setOption( 'readOnly', true );
+ }
+ if( canDeletePublic ){
+ $("#delete-macro").prop("disabled",false);
+ }
+ } else {
+ macroEditor.setOption( 'readOnly', false );
+ $("#delete-macro").prop("disabled",false);
+ }
+ macroEditor.activeMacroShared = result.shared;
+ })
+ .fail(function(err) {
+ var err_message;
+ if( err.status == "404" ){
+ err_message = "Macro not found";
+ } else if ( err.status == "403" ){
+ err_message = _("You do not have permission to access this macro");
+ } else {
+ err_message = _("There was a problem, please check the logs");
+ }
+ humanMsg.displayAlert( _("Failed to load macros: ") + err_message, { className: 'humanError' } );
+ });
- $( '#macro-list li[data-name="' + name + '"]' ).addClass( 'active' );
- var macro = Preferences.user.macros[name];
- macroEditor.setValue( macro.contents );
- macroEditor.setOption( 'readOnly', false );
- $( '#macro-format' ).val( macro.format || 'its' );
- if ( macro.history ) macroEditor.setHistory( macro.history );
- }
-
- function storeMacro( name, macro ) {
- if ( macro ) {
- Preferences.user.macros[name] = macro;
- } else {
- delete Preferences.user.macros[name];
- }
-
- Preferences.Save( [% logged_in_user.borrowernumber | html %] );
}
- function showSavedMacros( macros ) {
- var scrollTop = $('#macro-list').scrollTop();
- $( '#macro-list' ).empty();
+ function convertOldMacros(){
+ $("#convert-macros").remove();
var macro_list = $.map( Preferences.user.macros, function( macro, name ) {
return $.extend( { name: name }, macro );
} );
macro_list.sort( function( a, b ) {
return a.name.localeCompare(b.name);
} );
- $.each( macro_list, function( undef, macro ) {
- var $li = $( '<li data-name="' + macro.name + '"><a href="#">' + macro.name + '</a><ol class="macro-info"></ol></li>' );
- $li.click( function() {
- loadMacro(macro.name);
- return false;
- } );
- if ( macro.name == macroEditor.activeMacro ) $li.addClass( 'active' );
- var modified = macro.modified && new Date(macro.modified);
- $li.find( '.macro-info' ).append(
- '<li><span class="label">' + _("Last changed:") + '</span>' +
- ( modified ? ( modified.toLocaleDateString() + ', ' + modified.toLocaleTimeString() ) : _("never") ) + '</li>'
- );
- $('#macro-list').append($li);
+ $.each( macro_list, function( index, macro ) {
+ let options = {
+ url: "/api/v1/advanced_editor/macros/",
+ method: "POST",
+ contentType: "application/json",
+ data: JSON.stringify({
+ name: macro.name,
+ patron_id: [% logged_in_user.borrowernumber | html %],
+ macro_text: macro.contents,
+ shared: false
+ })
+ };
+ $.ajax(options)
+ .then(function(undef, result) {
+ delete Preferences.user.macros[macro.name];
+ Preferences.Save( [% logged_in_user.borrowernumber | html %] );
+ if( index == macro_list.length -1 ){
+ showSavedMacros();
+ }
+
+ })
+ .fail(function(err) {
+ var err_message;
+ if( err.status == "403" ){
+ err_message = _("You do not have permission to create this macro");
+ } else {
+ err_message = _("There was a problem, please check the logs");
+ }
+ humanMsg.displayAlert( _("Failed to create macro: ") + err_message, { className: 'humanError' } );
+ });
} );
+ }
+
+ function showSavedMacros( macros ) {
+ var scrollTop = $('#macro-list').scrollTop();
+ $( '#macro-list' ).empty();
+ $("#convert-macros").remove();
+ if( Object.keys(Preferences.user.macros).length ){
+ $convert = $( '<button class="btn btn-default" id="convert-macros" title="'+_("Convert browser storage macros")+'><i class="fa fa-adjust" aria-hidden="true"></i> Convert old macros</button>' );
+ $convert.click( function(){
+ if( !confirm( _("This will retrieve macros stored in the brower, save them in the database, and delete them from the browser. Proceed?") ) ){
+ return;
+ }
+ convertOldMacros();
+ });
+ $("#macro-toolbar").prepend($convert);
+ }
+ let options = {
+ url: "/api/v1/advanced_editor/macros/",
+ method: "GET",
+ contentType: "application/json",
+ };
+ $.ajax(options)
+ .then(function(result) {
+ $.each(result,function( undef, macro ){
+ var $li = $( '<li data-name="' + macro.name + '" data-id="' + macro.macro_id + '"><a href="#">' + macro.name + '</a><ol class="macro-info"></ol></li>' );
+ if ( macro.macro_id == macroEditor.activeMacroId ) $li.addClass( 'active' );
+ $li.click( function() {
+ loadMacro(macro.name, macro.macro_id, macro.shared);
+ return false;
+ } );
+ $('#macro-list').append($li);
+ });
+ })
+ .fail(function(err) {
+ var err_message = _("There was a problem, please check the logs");
+ humanMsg.displayAlert( _("Failed to load macros: ") + err_message, { className: 'humanError' } );
+ });
var $new_li = $( '<li class="new-macro"><a href="#">' + _("New macro...") + '</a></li>' );
$new_li.click( function() {
// TODO: make this a bit less retro
var name = prompt(_("Please enter the name for the new macro:"));
if (!name) return;
- if ( !Preferences.user.macros[name] ) storeMacro( name, { format: "rancor", contents: "" } );
- showSavedMacros();
- loadMacro( name );
+// if ( !Preferences.user.macros[name] ) storeMacro( name, { format: "rancor", contents: "" } );
+ let options = {
+ url: "/api/v1/advanced_editor/macros/",
+ method: "POST",
+ contentType: "application/json",
+ data: JSON.stringify({
+ name: name,
+ patron_id: [% logged_in_user.borrowernumber | html %],
+ macro_text: "",
+ shared: false
+ })
+ };
+ $.ajax(options)
+ .then(function(result) {
+ showSavedMacros();
+ loadMacro( result.name, result.macro_id );
+ })
+ .fail(function(err) {
+ var err_message;
+ if( err.status == "403" ){
+ err_message = _("You do not have permission to access this macro");
+ } else {
+ err_message = _("There was a problem, please check the logs");
+ }
+ humanMsg.displayAlert( _("Failed to create macro: ") + err_message, { className: 'humanError' } );
+ });
} );
$('#macro-list').append($new_li);
$('#macro-list').scrollTop(scrollTop);
}
- function saveMacro() {
+ function saveMacro(shared) {
var name = macroEditor.activeMacro;
+ var macro_id = macroEditor.activeMacroId;
+ var was_shared = macroEditor.activeMacroShared;
- if ( !name || macroEditor.savedGeneration == macroEditor.changeGeneration() ) return;
+ if ( !name || macroEditor.savedGeneration == macroEditor.changeGeneration() && was_shared == shared ) return;
macroEditor.savedGeneration = macroEditor.changeGeneration();
- storeMacro( name, { contents: macroEditor.getValue(), modified: (new Date()).valueOf(), history: macroEditor.getHistory(), format: $('#macro-format').val() } );
- $('#macro-save-message').text(_("Saved"));
- showSavedMacros();
+ api_url = "/api/v1/advanced_editor/macros/";
+ if( shared || was_shared ) { api_url += "shared/" }
+
+ let options = {
+ url: api_url + macro_id,
+ method: "PUT",
+ contentType: "application/json",
+ data: JSON.stringify({
+ name: name,
+ patron_id: [% logged_in_user.borrowernumber | html %],
+ macro_text: macroEditor.getValue(),
+ shared: shared
+ })
+ };
+ $.ajax(options)
+ .then(function(result) {
+ $('#macro-save-message').text(_("Saved"));
+ macroEditor.activeMacroShared = shared;
+ showSavedMacros();
+ })
+ .fail(function(err) {
+ var err_message;
+ if( err.status == "404" ){
+ err_message = _("Macro not found");
+ } else if ( err.status ="403" ){
+ err_message = _("You do not have permission to access this macro");
+ } else {
+ err_message = _("There was a problem, please check the logs");
+ }
+ humanMsg.displayAlert( _("Failed to save macro: ") + err_message, { className: 'humanError' } );
+ });
}
+ $(".macro_shared").change(function(){
+ if(this.checked){
+ saveMacro(true);
+ } else {
+ saveMacro(false);
+ }
+ });
+
+ // END Macro functions
+
$(document).ready( function() {
// Editor setup
editor = new MARCEditor( {
if ( resizeTimer == null ) resizeTimer = setTimeout( function() {
resizeTimer = null;
- var pos = $('#editor .CodeMirror').position();
+ var pos = $('#editor .CodeMirror').offset();
$('#editor .CodeMirror').height( $(window).height() - pos.top - 24 - $('#changelanguage').height() ); // 24 is hardcoded value but works well
$('.modal-body').each( function() {
if ( saveTimeout ) clearTimeout( saveTimeout );
saveTimeout = setTimeout( function() {
- saveMacro();
+ saveMacro(macroEditor.activeMacroShared);
saveTimeout = null;
}, 500 );
$( '#save-dropdown' ).append( '<li><a href="#" data-backend="' + backend[1] + '">' + backend[0] + '</a></li>' );
} );
- var macro_format_list = $.map( Macros.formats, function( format, name ) {
- return $.extend( { name: name }, format );
- } );
- macro_format_list.sort( function( a, b ) {
- return a.description.localeCompare(b.description);
- } );
- $.each( macro_format_list, function() {
- $('#macro-format').append( '<option value="' + this.name + '">' + this.description + '</option>' );
- } );
-
// Click bindings
$( '#save-record, #save-dropdown a' ).click( function() {
$( '#save-record' ).find('i').attr( 'class', 'fa fa-spinner fa-spin' ).siblings( 'span' ).text( _("Saving...") );
humanMsg.displayAlert( _("Incorrect syntax, cannot save"), { className: 'humanError' } );
} else if ( result.error == 'invalid' ) {
humanMsg.displayAlert( _("Record structure invalid, cannot save"), { className: 'humanError' } );
+ } else if ( result.error ) {
+ humanMsg.displayAlert( _("Something went wrong, cannot save"), { className: 'humanError' } );
} else if ( !result.error ) {
humanMsg.displayAlert( _("Record saved "), { className: 'humanSuccess' } );
}
} );
$('#run-macro').click( function() {
- var result = Macros.Run( editor, $('#macro-format').val(), macroEditor.getValue() );
+ var result = Macros.Run( editor, 'rancor', macroEditor.getValue() );
if ( !result.errors.length ) {
$('#macro-ui').modal('hide');
var errors = [];
$.each( result.errors, function() {
- var error = '<b>' + _("Line ") + (this.line + 1) + ':</b> ';
+ var error = '<strong>' + _("Line ") + (this.line + 1) + ':</strong> ';
switch ( this.error ) {
case 'failed': error += _("failed to run"); break;
$('#delete-macro').click( function() {
if ( !macroEditor.activeMacro || !confirm( _("Are you sure you want to delete this macro?") ) ) return;
-
- storeMacro( macroEditor.activeMacro, undefined );
- showSavedMacros();
+ deleteMacro();
loadMacro( undefined );
return false;
$( '#switch-editor' ).click( function() {
if ( !confirm( _("Any changes will not be saved. Continue?") ) ) return;
- $.cookie( 'catalogue_editor_[% logged_in_user.borrowernumber | html %]', 'basic', { expires: 365, path: '/' } );
+ Cookies.set( "catalogue_editor_[% logged_in_user.borrowernumber | html %]", "basic", { expires: 365, path: '/', sameSite: 'Lax'} );
if ( state.backend == 'catalog' ) {
window.location = '/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=' + state.recordID;
$("#loading").show();
editor.setFrameworkCode(
$(this).data( 'frameworkcode' ),
+ true,
function ( error ) {
if ( typeof error !== 'undefined' ) {
humanMsg.displayAlert( _("Failed to change framework"), { className: 'humanError' } );
} )();
</script>
+<!-- / cateditor-ui.inc -->