]> _ Git - fluidbook-toolbox.git/commitdiff
wip #7467 @2
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 22 May 2025 17:30:37 +0000 (19:30 +0200)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 22 May 2025 17:30:37 +0000 (19:30 +0200)
app/Http/Controllers/Admin/Operations/FluidbookPublication/LinksOperation.php
resources/linkeditor-stable/js/linkeditor.accessControl.js
resources/linkeditor-stable/js/linkeditor.links.js
resources/linkeditor-stable/js/linkeditor.panels.js
resources/views/fluidbook_publication/link_editor.blade.php

index 1125fe98b0dc90a31a54109ae06aa29fc6a1df1c..867ac489f66a3400f9f6ba6eb82b778846189b3e 100644 (file)
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin\Operations\FluidbookPublication;
 // __('!!Paramètres des fluidbooks')
 
 use App\Fluidbook\Link\LinksData;
+use App\Http\Middleware\VerifyCsrfToken;
 use App\Models\FluidbookPublication;
 use App\Models\User;
 use Cubist\Backpack\Http\Controllers\Base\XSendFileController;
@@ -27,7 +28,7 @@ trait LinksOperation
     {
         Route::match(['get'], $segment . '/{id}/edit/links-beta', $controller . '@linksBeta')->name('fluidbook_linkeditor_beta');
         Route::match(['get'], $segment . '/{id}/edit/links', $controller . '@links')->name('fluidbook_linkeditor');
-        Route::match(['post'], $segment . '/{id}/edit/links', $controller . '@broadcast')->name('fluidbook_linkeditor_post');
+        Route::match(['post'], $segment . '/{id}/edit/links', $controller . '@broadcast')->name('fluidbook_linkeditor_post')->withoutMiddleware(VerifyCsrfToken::class);
         Route::match(['get'], $segment . '/{id}/edit/links/versions', $controller . '@getLinkVersions');
         Route::match(['get'], $segment . '/{id}/edit/links/versions/export/{version}', $controller . '@exportLinks');
         Route::match(['post'], $segment . '/{id}/edit/links/import/merge', $controller . '@importLinksMerge');
@@ -378,7 +379,7 @@ trait LinksOperation
                 // si la connexion existe déjà, on remplace la date ainsi que le token pour là garder active
                 // sinon on ajoute la nouvelle connexion à la liste
                 // si la page est rechargée ou fermée la connexion est supprimée
-                if (null === $unload) {
+                if (!$unload) {
                     if ($key === null) {
                         $queueEditor[] = ["token" => $token, "date" => now(), "userid" => $userId];
                     } else {
index 10b15c6ab7b2cb18d723439ad0af494a543f0a8b..0ef8dc201ee441707a48667bfedf0ec16cba6a00 100644 (file)
@@ -5,35 +5,49 @@ function LinkeditorAccessControl(linkeditor) {
 
 LinkeditorAccessControl.prototype = {
     init: function () {
-        this.interval = null
-        this.token = $("[data-token]").data("token")
-        this.userID = $("#userID").data('id')
+        this.timeout = null
+        this.token = $("[data-token]").data("token");
+        this.userID = $("#userID").data('id');
+        this.unload = false;
         const $this = this
 
-        $(document).on("click", "#connectTo", function(e) {
-            e.preventDefault()
-            clearTimeout($this.interval)
-            $this.intervalConnection("1");
+        $(document).on("click", "#connectTo", function (e) {
+            clearTimeout($this.timeout);
+            $this.timeoutConnection(true);
+            e.preventDefault();
         })
 
-        $(window).on("unload",function(){
-            clearTimeout($this.interval)
-            sessionStorage.setItem('token', token);
-            localStorage.setItem('unload', '1');
+        $(window).on("beforeonunload unload", function () {
+            $this.unload = true;
+            clearTimeout($this.timeout);
+            navigator.sendBeacon($this.getBaseURL(), JSON.stringify($this.getDataToSend(false)));
         })
 
-        this.interval = setTimeout(() => { $this.intervalConnection() }, 10 )
+        this.timeout = setTimeout(() => {
+            $this.timeoutConnection()
+        }, 500)
     },
 
-    intervalConnection: function(clear = null) {
-        let unload = localStorage.getItem('unload')
-        let currentToken = sessionStorage.getItem('token')
+    getBaseURL: function () {
+        return '/fluidbook-publication/' + FLUIDBOOK_DATA.id + '/edit/links';
+    },
+
+    getDataToSend: function (clear = null) {
+        return {
+            id: FLUIDBOOK_DATA.id,
+            token: this.token,
+            unload: this.unload ? 1 : 0,
+            clear: clear ? 1 : 0,
+        };
+    },
+
+    timeoutConnection: function (clear = null) {
         const $this = this
 
         $.ajax({
             method: "POST",
-            url: '/fluidbook-publication/' + FLUIDBOOK_DATA.id + '/edit/links',
-            data: {id: FLUIDBOOK_DATA.id, token: currentToken ? currentToken : $this.token, unload: unload, clear: clear}
+            url: this.getBaseURL(),
+            data: this.getDataToSend(clear),
         }).done(function (msg) {
             let response = JSON.parse(msg)
             if (response.status === "unavailable") {
@@ -41,9 +55,10 @@ LinkeditorAccessControl.prototype = {
                     $("#popup-overlay").addClass("show")
 
                     let popupName = 'unavailable';
-                    if(response.infos_connection.id === $this.userID) popupName = 'unavailable-twin-connection';
+                    if (response.infos_connection.id === $this.userID) {
+                        popupName = 'unavailable-twin-connection';
+                    }
                     $this.linkeditor.popup.open(popupName);
-
                     $this.linkeditor.save.saveIfUnsavedChanges("Sauvegarde après avoir été déconnecté par un autre utilisateur", false, function () {
                     });
 
@@ -59,21 +74,17 @@ LinkeditorAccessControl.prototype = {
                     window.linkeditor.popup.close();
                 }
                 $this.linkeditor.controlKeyFilter(false)
-                window.key.filter = function(event) {
+                window.key.filter = function (event) {
                     let tagName = (event.target || event.srcElement).tagName;
-                    //let field=tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA';
                     if (tagName === 'TEXTAREA' && event.keyCode === 13) {
                         return false;
                     }
-
                     return true;
                 }
             }
-            sessionStorage.removeItem('token');
-            localStorage.removeItem('unload');
 
-            $this.interval = setTimeout(() => {
-                $this.intervalConnection()
+            $this.timeout = setTimeout(() => {
+                $this.timeoutConnection()
             }, 2000)
         });
     },
index 524023e06f6f509383c962541d9280c3eab55da1..172fa8df3794176f248ae83c5f42778819aace57 100644 (file)
@@ -21,6 +21,8 @@ var LinkeditorLinks = function (linkeditor) {
 
     this.locks = new LinkeditorLinksLock(linkeditor);
 
+    this.pageMaxOrderIndex = 0;
+
     this.init();
 }
 
@@ -221,7 +223,9 @@ LinkeditorLinks.prototype = {
                         }
                     }
                 },
-            }, build: function ($triggerElement, e) {
+            },
+
+            build: function ($triggerElement, e) {
                 var res = {
                     callback: function () {
 
@@ -309,8 +313,9 @@ LinkeditorLinks.prototype = {
                     }
                 }
                 if (hasSelection && !multiple) {
-                    res.items = $.extend(res.items, {
-                        'sep_extends': '---------', 'cover_1': {
+
+                    let cover_items = {
+                        'cover_1': {
                             isHtmlName: true, name: TRANSLATIONS.cover_page_1, callback: function () {
                                 $this.coverPage(1, false);
                             },
@@ -319,9 +324,10 @@ LinkeditorLinks.prototype = {
                                 $this.coverPage(0, false);
                             },
                         },
-                    });
+                    };
+
                     if (!$this.linkeditor.single) {
-                        res.items = $.extend(res.items, {
+                        cover_items = $.extend(cover_items, {
                             'cover_double_1': {
                                 isHtmlName: true, name: TRANSLATIONS.cover_doublepage_1, callback: function () {
                                     $this.coverPage(1, true);
@@ -333,6 +339,48 @@ LinkeditorLinks.prototype = {
                             },
                         });
                     }
+
+                    res.items = $.extend(res.items, {
+                        sep_extends: '---------',
+                        cover: {
+                            name: TRANSLATIONS.cover,
+                            items: cover_items,
+                        }
+                    });
+                }
+                if (hasSelection) {
+                    res.items = $.extend(res.items, {
+                        'sep_order': '---------',
+                        "order": {
+                            name: (TRANSLATIONS.edit_link_order) + '',
+                            items: {
+                                'move_order_start': {
+                                    name: TRANSLATIONS.move_beginning,
+                                    callback: function () {
+                                        $this.moveSelectionOrder('start');
+                                    }
+                                },
+                                'move_order_up': {
+                                    name: TRANSLATIONS.move_up,
+                                    callback: function () {
+                                        $this.moveSelectionOrder('up');
+                                    }
+                                },
+                                'move_order_down': {
+                                    name: TRANSLATIONS.move_down,
+                                    callback: function () {
+                                        $this.moveSelectionOrder('down');
+                                    }
+                                },
+                                'move_order_end': {
+                                    name: TRANSLATIONS.move_end,
+                                    callback: function () {
+                                        $this.moveSelectionOrder('end');
+                                    }
+                                }
+                            }
+                        },
+                    });
                 }
                 if (hasSelection) {
                     res.items = $.extend(res.items, {
@@ -344,6 +392,7 @@ LinkeditorLinks.prototype = {
                             }
                         },
                     });
+
                 }
                 return res;
             },
@@ -863,6 +912,7 @@ LinkeditorLinks.prototype = {
     },
 
     loadLinks: function (page, side) {
+        this.pageMaxOrderIndex = 0;
         let $this = this;
         this.normalizeLinksPage();
         $.each(LINKS, function (uid, link) {
@@ -905,6 +955,12 @@ LinkeditorLinks.prototype = {
             triggerChange = true;
         }
         let change = false;
+        if (link.order === undefined) {
+            link.order = ++this.pageMaxOrderIndex;
+        } else {
+            this.pageMaxOrderIndex = Math.max(this.pageMaxOrderIndex, link.order);
+        }
+        console.log(link.order);
         if (link.uid === undefined) {
             link.uid = this.linkeditor.utils.generateUID();
             change = true;
@@ -920,13 +976,16 @@ LinkeditorLinks.prototype = {
         let $this = this;
 
         let attrs = {};
+        let ignoreAttrs = ['_http_referrer'];
         $.each(link, function (k, v) {
+            if (ignoreAttrs.indexOf(k) >= 0) {
+                return;
+            }
             attrs['fb-' + k] = $this.linkeditor.form.normalizeFormValue(k, v);
         });
         attrs['fb-ref'] = "editor";
         attrs['fb-update'] = "1";
 
-
         let e = $('<div class="link" fb-ref="editor" fb-update="1"></div>');
         $(e).attr(attrs);
         if (this.dropTypes.indexOf(parseInt(link.type)) >= 0) {
index 0ca2ed66bcc669a5bfb18812741dbee4cf57ff65..cd98d309dc72f61d85f8096b404ce01ad16db1e0 100644 (file)
@@ -51,8 +51,6 @@ LinkeditorPanels.prototype = {
             $(this).addClass('dragging');
             return false;
         });
-
-
     },
 
     moveHandle: function () {
index fc6bed99d1eb09c919d6791cfd34151e5c91d663..51dc438e69744ed6ff9cb6f6d8fe7f8293767a0b 100644 (file)
         'delete_link'=>__('Supprimer le lien'),
         'edit_image_link'=>__('Editer les liens de l\'image'),
         'delete_selection'=>__('Supprimer la sélection'),
+        'edit_link_order'=>__('Modifier l\'ordre'),
+        'move_up'=>__('Avant'),
+        'move_down'=>__('Après'),
+        'move_beginning'=>__('Au début'),
+        'move_end'=>__('À la fin'),
         'select_all'=>__('Tout sélectionner'),
         'error_open_image_link'=>__('Impossible d\'ajouter des liens au contenu de ce lien'),
         'empty'=>__('Vide'),
         'paste_in_place'=>__('Coller en place'),
         'paste_on_left'=>__('Coller en décalant  vers la gauche'),
         'paste_on_right'=>__('Coller en décalant vers la droite'),
-        'cover_page_0'=>__('Recouvrir la page sans marge'),
-        'cover_doublepage_0'=>__('Recouvrir la double-page sans marge'),
-        'cover_page_1'=>__('Recouvrir la page avec une marge de :margin',['margin'=>'1px']),
-        'cover_doublepage_1'=>__('Recouvrir la double-page avec une marge de :margin',['margin'=>'1px']),
+        "cover"=>__('Recouvrir').' ...',
+        'cover_page_0'=>__('la page sans marge'),
+        'cover_doublepage_0'=>__('la double-page sans marge'),
+        'cover_page_1'=>__('la page avec une marge de :margin',['margin'=>'1px']),
+        'cover_doublepage_1'=>__('la double-page avec une marge de :margin',['margin'=>'1px']),
         'n_links_copied'=>__('%nb% liens copiés'),
         'n_links_cut'=>__('%nb% liens coupés'),
         'click_to_copy_id'=>__('Cliquer pour copier l\'identifiant du lien'),
         var DEPTH = @json($depths);
     </script>
     <script
-        src="/packages/linkeditor{{$scriptVersion}}/js/linkeditor.js?v={{filemtime(public_path('packages/linkeditor'.$scriptVersion.'/js/linkeditor.js'))}}"></script>
+            src="/packages/linkeditor{{$scriptVersion}}/js/linkeditor.js?v={{filemtime(public_path('packages/linkeditor'.$scriptVersion.'/js/linkeditor.js'))}}"></script>
 @endpush
 @push('linkeditor_styles')
     <script>window._skipAutoTriggers = true;</script>