Bug 26019: Koha should set SameSite attribute on cookies
[srvgit] / koha-tmpl / intranet-tmpl / prog / en / includes / cateditor-ui.inc
index a20bbe6..9fd3364 100644 (file)
@@ -1,9 +1,18 @@
 [% 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 %]: {
@@ -32,25 +41,28 @@ require.config( {
 
 <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") ],
@@ -58,6 +70,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
         [ "issn", _("ISSN") ],
         [ "medium", _("Medium") ],
         [ "edition", _("Edition") ],
+        [ "date", _("Published") ],
         [ "notes", _("Notes") ],
     ];
 
@@ -178,7 +191,13 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
     }
 
     function getFieldHelpURL( tag ) {
-        [% IF ( marcflavour == 'MARC21' ) %]
+        [% IF Koha.Preference('marcfielddocurl') %]
+            var docurl = "[% Koha.Preference('marcfielddocurl').replace('"','&quot;') | 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' ) {
@@ -227,6 +246,22 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
                 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: [
@@ -252,9 +287,20 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
             }
         },
         '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( {} );
             }
@@ -262,7 +308,18 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
         '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( {} );
             }
@@ -372,8 +429,8 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
     // 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');
     }
@@ -424,18 +481,18 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
         $('#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 = {};
@@ -478,7 +535,8 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
             }
 
             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;
@@ -608,8 +666,8 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
                 // 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;
                 } );
@@ -661,81 +719,258 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
     }
 
     //> 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( {
@@ -778,7 +1013,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
             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() {
@@ -812,7 +1047,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
 
                 if ( saveTimeout ) clearTimeout( saveTimeout );
                 saveTimeout = setTimeout( function() {
-                    saveMacro();
+                    saveMacro(macroEditor.activeMacroShared);
 
                     saveTimeout = null;
                 }, 500 );
@@ -830,16 +1065,6 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
             $( '#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...") );
@@ -849,6 +1074,8 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
                     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' } );
                 }
@@ -944,7 +1171,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
         } );
 
         $('#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');
@@ -954,7 +1181,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
 
             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;
@@ -971,9 +1198,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
 
         $('#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;
@@ -982,7 +1207,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
         $( '#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;
@@ -1098,6 +1323,7 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
             $("#loading").show();
             editor.setFrameworkCode(
                 $(this).data( 'frameworkcode' ),
+                true,
                 function ( error ) {
                     if ( typeof error !== 'undefined' ) {
                         humanMsg.displayAlert( _("Failed to change framework"), { className: 'humanError' } );
@@ -1141,3 +1367,4 @@ require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr
 } )();
 
 </script>
+<!-- / cateditor-ui.inc -->