View | Details | Raw Unified | Return to bug 17268
Collapse All | Expand All

(-)a/Koha/REST/V1/AdvancedEditorMacro.pm (-1 lines)
Lines 150-156 sub add_shared { Link Here
150
        return $c->render( status  => 403,
150
        return $c->render( status  => 403,
151
                           openapi => { error => "To create private macros you must use advancededitor" } );
151
                           openapi => { error => "To create private macros you must use advancededitor" } );
152
    }
152
    }
153
154
    return try {
153
    return try {
155
        my $macro = Koha::AdvancedEditorMacro->new( _to_model( $c->validation->param('body') ) );
154
        my $macro = Koha::AdvancedEditorMacro->new( _to_model( $c->validation->param('body') ) );
156
        $macro->store;
155
        $macro->store;
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc (-44 / +183 lines)
Lines 694-773 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
694
    }
694
    }
695
695
696
    //> Macro functions
696
    //> Macro functions
697
    function loadMacro( name ) {
697
    var canCreatePublic = "[% CAN_user_editcatalogue_create_shared_macros | html %]";
698
    var canDeletePublic = "[% CAN_user_editcatalogue_delete_shared_macros | html %]";
699
700
    function deleteMacro( id ){
701
        $( '#macro-list' ).empty();
702
        var shared = macroEditor.activeMacroShared;
703
        var id = macroEditor.activeMacroId;
704
        macroEditor.activeMacroId = null;
705
        api_url = "/api/v1/advancededitormacros/";
706
        if( shared ) { api_url += "shared/" }
707
        let options = {
708
            url: api_url + id,
709
            method: "DELETE",
710
            contentType: "application/json",
711
        };
712
        $.ajax(options)
713
            .then(function(result) {
714
                humanMsg.displayAlert( _("Macro successfully deleted") );
715
                showSavedMacros();
716
            })
717
            .fail(function(err) {
718
                humanMsg.displayAlert( _("Failed to delete macro:") + err.responseText, { className: 'humanError' } );
719
            });
720
    }
721
722
723
    function loadMacro( name, id, shared ) {
698
        $( '#macro-list li' ).removeClass( 'active' );
724
        $( '#macro-list li' ).removeClass( 'active' );
725
        $(".macro_shared").prop("checked",false).hide();
726
        $("#delete-macro").prop("disabled",true);
727
        macroEditor.setOption( 'readOnly', false );
699
        macroEditor.activeMacro = name;
728
        macroEditor.activeMacro = name;
729
        macroEditor.activeMacroId = id;
700
730
701
        if ( !name ) {
731
        if ( !name ) {
702
            macroEditor.setValue( '' );
732
            macroEditor.setValue( '' );
703
            return;
733
            return;
704
        }
734
        }
735
        $( '#macro-list li[data-name="' + name + '"][data-id="' + id + '"]' ).addClass( 'active' );
736
        api_url = "/api/v1/advancededitormacros/";
737
        if( shared ) { api_url += "shared/" }
738
        let options = {
739
            url: api_url + id,
740
            method: "GET",
741
            contentType: "application/json",
742
        };
743
        $.ajax(options)
744
            .then(function(result) {
745
                macroEditor.setValue( result.macro_text );
746
                $(".macro_shared").show();
747
                if( result.shared ){
748
                    $(".macro_shared").prop("checked",true);
749
                    if( canCreatePublic ){
750
                        macroEditor.setOption( 'readOnly', false );
751
                    } else {
752
                        macroEditor.setOption( 'readOnly', true );
753
                    }
754
                    if( canDeletePublic ){
755
                        $("#delete-macro").prop("disabled",false);
756
                    }
757
                } else {
758
                    macroEditor.setOption( 'readOnly', false );
759
                    $("#delete-macro").prop("disabled",false);
760
                }
761
                macroEditor.activeMacroShared = result.shared;
762
            })
763
            .fail(function(err) {
764
                humanMsg.displayAlert( _("Failed to load macros:") + err.responseText, { className: 'humanError' } );
765
            });
705
766
706
        $( '#macro-list li[data-name="' + name + '"]' ).addClass( 'active' );
707
        var macro = Preferences.user.macros[name];
708
        macroEditor.setValue( macro.contents );
709
        macroEditor.setOption( 'readOnly', false );
710
        if ( macro.history ) macroEditor.setHistory( macro.history );
711
    }
712
713
    function storeMacro( name, macro ) {
714
        if ( macro ) {
715
            Preferences.user.macros[name] = macro;
716
        } else {
717
            delete Preferences.user.macros[name];
718
        }
719
720
        Preferences.Save( [% logged_in_user.borrowernumber | html %] );
721
    }
767
    }
722
768
723
    function showSavedMacros( macros ) {
769
    function convertOldMacros(){
724
        var scrollTop = $('#macro-list').scrollTop();
770
        $("#convert-macros").remove();
725
        $( '#macro-list' ).empty();
726
        var macro_list = $.map( Preferences.user.macros, function( macro, name ) {
771
        var macro_list = $.map( Preferences.user.macros, function( macro, name ) {
727
            return $.extend( { name: name }, macro );
772
            return $.extend( { name: name }, macro );
728
        } );
773
        } );
729
        macro_list.sort( function( a, b ) {
774
        macro_list.sort( function( a, b ) {
730
            return a.name.localeCompare(b.name);
775
            return a.name.localeCompare(b.name);
731
        } );
776
        } );
732
        $.each( macro_list, function( undef, macro ) {
777
        $.each( macro_list, function( index, macro ) {
733
            var $li = $( '<li data-name="' + macro.name + '"><a href="#">' + macro.name + '</a><ol class="macro-info"></ol></li>' );
778
            let options = {
734
            $li.click( function() {
779
                url: "/api/v1/advancededitormacros/",
735
                loadMacro(macro.name);
780
                method: "POST",
736
                return false;
781
                contentType: "application/json",
737
            } );
782
                data: JSON.stringify({
738
            if ( macro.name == macroEditor.activeMacro ) $li.addClass( 'active' );
783
                    name: macro.name,
739
            var modified = macro.modified && new Date(macro.modified);
784
                    patron_id: [% logged_in_user.borrowernumber | html %],
740
            $li.find( '.macro-info' ).append(
785
                    macro_text: macro.contents,
741
                '<li><span class="label">' + _("Last changed:") + '</span>' +
786
                    shared: false
742
                ( modified ? ( modified.toLocaleDateString() + ', ' + modified.toLocaleTimeString() ) : _("never") ) + '</li>'
787
                })
743
            );
788
            };
744
            $('#macro-list').append($li);
789
            $.ajax(options)
790
                .then(function(undef, result) {
791
                    delete Preferences.user.macros[macro.name];
792
                    Preferences.Save( [% logged_in_user.borrowernumber | html %] );
793
                    if( index == macro_list.length -1 ){
794
                        showSavedMacros();
795
                    }
796
797
                })
798
                .fail(function(err) {
799
                    humanMsg.displayAlert( _("Failed to create macro:") + err.responseText, { className: 'humanError' } );
800
                });
745
        } );
801
        } );
802
    }
803
804
    function showSavedMacros( macros ) {
805
        var scrollTop = $('#macro-list').scrollTop();
806
        $( '#macro-list' ).empty();
807
        $("#convert-macros").remove();
808
        if( Object.keys(Preferences.user.macros).length ){
809
            $convert = $( '<button class="btn btn-default" id="convert-macros" title="Convert browser storage macros"><i class="fa fa-adjust"></i> Convert old macros</button>' );
810
            $convert.click( function(){
811
                if( !confirm( _("This will retrieve macros stored in the brower, save them in the database, and delete them from the browser. Proceed?") ) ){
812
                    return;
813
                }
814
                convertOldMacros();
815
            });
816
            $("#macro-toolbar").prepend($convert);
817
        }
818
        let options = {
819
            url: "/api/v1/advancededitormacros/",
820
            method: "GET",
821
            contentType: "application/json",
822
        };
823
        $.ajax(options)
824
            .then(function(result) {
825
                    $.each(result,function( undef, macro ){
826
                        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>' );
827
                        if ( macro.macro_id == macroEditor.activeMacroId ) $li.addClass( 'active' );
828
                        $li.click( function() {
829
                            loadMacro(macro.name, macro.macro_id, macro.shared);
830
                            return false;
831
                        } );
832
                        $('#macro-list').append($li);
833
                    });
834
            })
835
            .fail(function(err) {
836
                humanMsg.displayAlert( _("Failed to load macros:") + err.responseText, { className: 'humanError' } );
837
            });
746
        var $new_li = $( '<li class="new-macro"><a href="#">' + _("New macro...") + '</a></li>' );
838
        var $new_li = $( '<li class="new-macro"><a href="#">' + _("New macro...") + '</a></li>' );
747
        $new_li.click( function() {
839
        $new_li.click( function() {
748
            // TODO: make this a bit less retro
840
            // TODO: make this a bit less retro
749
            var name = prompt(_("Please enter the name for the new macro:"));
841
            var name = prompt(_("Please enter the name for the new macro:"));
750
            if (!name) return;
842
            if (!name) return;
751
843
752
            if ( !Preferences.user.macros[name] ) storeMacro( name, { format: "rancor", contents: "" } );
844
//            if ( !Preferences.user.macros[name] ) storeMacro( name, { format: "rancor", contents: "" } );
753
            showSavedMacros();
845
            let options = {
754
            loadMacro( name );
846
                url: "/api/v1/advancededitormacros/",
847
                method: "POST",
848
                contentType: "application/json",
849
                data: JSON.stringify({
850
                    name: name,
851
                    patron_id: [% logged_in_user.borrowernumber | html %],
852
                    macro_text: "",
853
                    shared: false
854
                })
855
            };
856
            $.ajax(options)
857
                .then(function(undef, result) {
858
                    showSavedMacros();
859
                    loadMacro( result.name, result.macro_id );
860
                })
861
                .fail(function(err) {
862
                    humanMsg.displayAlert( _("Failed to create macro:") + err.responseText, { className: 'humanError' } );
863
                });
755
        } );
864
        } );
756
        $('#macro-list').append($new_li);
865
        $('#macro-list').append($new_li);
757
        $('#macro-list').scrollTop(scrollTop);
866
        $('#macro-list').scrollTop(scrollTop);
758
    }
867
    }
759
868
760
    function saveMacro() {
869
    function saveMacro(shared) {
761
        var name = macroEditor.activeMacro;
870
        var name = macroEditor.activeMacro;
871
        var macro_id = macroEditor.activeMacroId;
872
        var was_shared = macroEditor.activeMacroShared;
762
873
763
        if ( !name || macroEditor.savedGeneration == macroEditor.changeGeneration() ) return;
874
        if ( !name || macroEditor.savedGeneration == macroEditor.changeGeneration() && was_shared == shared ) return;
764
875
765
        macroEditor.savedGeneration = macroEditor.changeGeneration();
876
        macroEditor.savedGeneration = macroEditor.changeGeneration();
766
        storeMacro( name, { contents: macroEditor.getValue(), modified: (new Date()).valueOf(), history: macroEditor.getHistory() } );
877
        api_url = "/api/v1/advancededitormacros/";
767
        $('#macro-save-message').text(_("Saved"));
878
        if( shared || was_shared ) { api_url += "shared/" }
768
        showSavedMacros();
879
880
        let options = {
881
            url: api_url + macro_id,
882
            method: "PUT",
883
            contentType: "application/json",
884
            data: JSON.stringify({
885
                name: name,
886
                patron_id: [% logged_in_user.borrowernumber | html %],
887
                macro_text: macroEditor.getValue(),
888
                shared: shared
889
            })
890
        };
891
        $.ajax(options)
892
            .then(function(result) {
893
                $('#macro-save-message').text(_("Saved"));
894
                macroEditor.activeMacroShared = shared;
895
                showSavedMacros();
896
            })
897
            .fail(function(err) {
898
                humanMsg.displayAlert( _("Failed to save macro:") + err.responseText, { className: 'humanError' } );
899
            });
769
    }
900
    }
770
901
902
    $(".macro_shared").change(function(){
903
        if(this.checked){
904
            saveMacro(true);
905
        } else {
906
            saveMacro(false);
907
        }
908
    });
909
910
    // END Macro functions
911
771
    $(document).ready( function() {
912
    $(document).ready( function() {
772
        // Editor setup
913
        // Editor setup
773
        editor = new MARCEditor( {
914
        editor = new MARCEditor( {
Lines 844-850 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
844
985
845
                if ( saveTimeout ) clearTimeout( saveTimeout );
986
                if ( saveTimeout ) clearTimeout( saveTimeout );
846
                saveTimeout = setTimeout( function() {
987
                saveTimeout = setTimeout( function() {
847
                    saveMacro();
988
                    saveMacro(macroEditor.activeMacroShared);
848
989
849
                    saveTimeout = null;
990
                    saveTimeout = null;
850
                }, 500 );
991
                }, 500 );
Lines 995-1003 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
995
1136
996
        $('#delete-macro').click( function() {
1137
        $('#delete-macro').click( function() {
997
            if ( !macroEditor.activeMacro || !confirm( _("Are you sure you want to delete this macro?") ) ) return;
1138
            if ( !macroEditor.activeMacro || !confirm( _("Are you sure you want to delete this macro?") ) ) return;
998
1139
            deleteMacro();
999
            storeMacro( macroEditor.activeMacro, undefined );
1000
            showSavedMacros();
1001
            loadMacro( undefined );
1140
            loadMacro( undefined );
1002
1141
1003
            return false;
1142
            return false;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/editor.tt (-1 / +6 lines)
Lines 264-269 Link Here
264
        <div id="macro-toolbar" class="btn-toolbar">
264
        <div id="macro-toolbar" class="btn-toolbar">
265
            <button class="btn btn-default" id="run-macro" title="Run and edit macros"><i class="fa fa-play"></i> Run macro</button>
265
            <button class="btn btn-default" id="run-macro" title="Run and edit macros"><i class="fa fa-play"></i> Run macro</button>
266
            <button class="btn btn-default" id="delete-macro" title="Delete macro"><i class="fa fa-trash"></i> Delete macro</button>
266
            <button class="btn btn-default" id="delete-macro" title="Delete macro"><i class="fa fa-trash"></i> Delete macro</button>
267
            <label class="macro_shared" for="public" style="display:none;">Public macro:</label>
268
            [% IF CAN_user_editcatalogue_create_shared_macros %]
269
                <input class="macro_shared" type="checkbox" name="public" style="display:none;"/>
270
            [% ELSE %]
271
                <input class="macro_shared" type="checkbox" name="public" style="display:none;" disabled/>
272
            [% END %]
267
            <div id="macro-save-message"></div>
273
            <div id="macro-save-message"></div>
268
        </div>
274
        </div>
269
    </div>
275
    </div>
270
- 

Return to bug 17268