Bug 17268: Use API to store/retrieve values
authorNick Clemens <nick@bywatersolutions.com>
Tue, 3 Mar 2020 13:14:03 +0000 (13:14 +0000)
committerMartin Renvoize <martin.renvoize@ptfs-europe.com>
Mon, 4 May 2020 07:25:41 +0000 (08:25 +0100)
To test:
 1  - Enable AdvancedCatalogingEditor
 2  - Add some macros (they don't need to be valid, just have content)
 3  - Apply patches
 4  - updatedatabase
 5  - Set user to have 'create_shared_macros' and 'delete_shared_macros'
 6  - Load the advanced editor (Cataloging->Advanced editor)
 7  - Click on 'Macros'
 8  - Previous macros should not show, but you should have a 'Convert' button
 9  - Convert old macros and confirm they show
10  - Edit the macros, changing content and the public checkbox, confirm 'Saved' shows in the top right of editor when updating
11  - Have at least on valid macro and run it, e.g.:
    new 100=Testing this out
12  - Run the macro, confirm it runs
13  - Try a macro with gibberish, confirm there is an error when running
14  - Ensure you have a few macros marked public
15  - In a private browser window sign in as a patron with neither shared macro permission
16  - Confirm the public macros load, but cannot be edited
17  - Grant create_shared_macros permission to this patron
18  - Reload editor, they should now be able to edit shared macros
19  - Confirm they cannot delete shared macros
20  - Grant delete_shared_macros permission
21  - Reload editor
22  - Confirm they can now delete shared macros

Signed-off-by: Andrew Fuerste-Henry <andrew@bywatersolutions.com>
Signed-off-by: Heather Hernandez <Heather_Hernandez@nps.gov>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Koha/REST/V1/AdvancedEditorMacro.pm
koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/editor.tt

index 92f6730..6e0f04d 100644 (file)
@@ -150,7 +150,6 @@ sub add_shared {
         return $c->render( status  => 403,
                            openapi => { error => "To create private macros you must use advancededitor" } );
     }
-
     return try {
         my $macro = Koha::AdvancedEditorMacro->new( _to_model( $c->validation->param('body') ) );
         $macro->store;
index 8e231e3..9b0c857 100644 (file)
@@ -694,80 +694,221 @@ 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/advancededitormacros/";
+        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) {
+                humanMsg.displayAlert( _("Failed to delete macro:") + err.responseText, { 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/advancededitormacros/";
+        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) {
+                humanMsg.displayAlert( _("Failed to load macros:") + err.responseText, { className: 'humanError' } );
+            });
 
-        $( '#macro-list li[data-name="' + name + '"]' ).addClass( 'active' );
-        var macro = Preferences.user.macros[name];
-        macroEditor.setValue( macro.contents );
-        macroEditor.setOption( 'readOnly', false );
-        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/advancededitormacros/",
+                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) {
+                    humanMsg.displayAlert( _("Failed to create macro:") + err.responseText, { 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"></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/advancededitormacros/",
+            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.macro_id + ' - ' + 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) {
+                humanMsg.displayAlert( _("Failed to load macros:") + err.responseText, { 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/advancededitormacros/",
+                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(undef, result) {
+                    showSavedMacros();
+                    loadMacro( result.name, result.macro_id );
+                })
+                .fail(function(err) {
+                    humanMsg.displayAlert( _("Failed to create macro:") + err.responseText, { 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() } );
-        $('#macro-save-message').text(_("Saved"));
-        showSavedMacros();
+        api_url = "/api/v1/advancededitormacros/";
+        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) {
+                humanMsg.displayAlert( _("Failed to save macro:") + err.responseText, { 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( {
@@ -844,7 +985,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 );
@@ -995,9 +1136,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;
index a4a2b4d..d288226 100644 (file)
         <div id="macro-toolbar" class="btn-toolbar">
             <button class="btn btn-default" id="run-macro" title="Run and edit macros"><i class="fa fa-play"></i> Run macro</button>
             <button class="btn btn-default" id="delete-macro" title="Delete macro"><i class="fa fa-trash"></i> Delete macro</button>
+            <label class="macro_shared" for="public" style="display:none;">Public macro:</label>
+            [% IF CAN_user_editcatalogue_create_shared_macros %]
+                <input class="macro_shared" type="checkbox" name="public" style="display:none;"/>
+            [% ELSE %]
+                <input class="macro_shared" type="checkbox" name="public" style="display:none;" disabled/>
+            [% END %]
             <div id="macro-save-message"></div>
         </div>
     </div>