]> _ Git - fluidbook-toolbox.git/commitdiff
wip #5631 @2
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 8 Dec 2022 15:30:52 +0000 (16:30 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 8 Dec 2022 15:30:52 +0000 (16:30 +0100)
app/Http/Controllers/Admin/Operations/FluidbookPublication/EditOperation.php
app/Util/FluidbookLinks.php
resources/linkeditor/js/linkeditor.js
resources/linkeditor/js/linkeditor.save.js
resources/linkeditor/js/linkeditor.toolbar.js
resources/linkeditor/js/linkeditor.versions.js
resources/linkeditor/style/inc/_versions.sass
resources/views/fluidbook_publication/link_editor.blade.php

index 6c489671d4534facee6e4f166c105c692a8da3bf..609de163447db2e996c64da8346d66088d84d032 100644 (file)
@@ -6,7 +6,9 @@ use App\Models\FluidbookDocument;
 use App\Models\FluidbookPublication;
 use App\Util\FluidbookLinks;
 use Cubist\Backpack\Http\Controllers\Base\XSendFileController;
+use Cubist\Util\Files\Files;
 use Illuminate\Support\Facades\Route;
+use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
 
 trait EditOperation
 {
@@ -15,6 +17,8 @@ trait EditOperation
     {
         Route::match(['get'], $segment . '/{id}/edit/links', $controller . '@links');
         Route::match(['get'], $segment . '/{id}/edit/links/versions', $controller . '@getLinkVersions');
+        Route::match(['get'], $segment . '/{id}/edit/links/versions/export/{version}', $controller . '@exportLinks');
+        Route::match(['get'], $segment . '/{id}/edit/links/versions/restore/{version}', $controller . '@restoreLinks');
         Route::put($segment . '/{id}/save/links', $controller . '@saveLinks');
         Route::get($segment . '/{id}/edit/{type}_{page}.{format}', $controller . '@getLinkPage')
             // ->whereIn('type', ['raster', 'images', 'texts', 'vector'])
@@ -71,6 +75,31 @@ trait EditOperation
         return response()->json($links);
     }
 
+    protected function exportLinks($fluidbook_id, $version)
+    {
+        if (!FluidbookPublication::hasPermission($fluidbook_id)) {
+            abort(401);
+        }
+        FluidbookLinks::getLinksAndRulers($fluidbook_id, $links, $rulers, $version);
+        $xlsx = FluidbookLinks::linksToExcel($links, $rulers);
+        $tmpfile = Files::tempnam() . '.xlsx';
+        $writer = new Xlsx($xlsx);
+        $writer->save($tmpfile);
+        return response()->file($tmpfile)->deleteFileAfterSend();
+    }
+
+    protected function restoreLinks($fluidbook_id, $version)
+    {
+        if (!FluidbookPublication::hasPermission($fluidbook_id)) {
+            abort(401);
+        }
+        $comments = 'Restore links from ' . date('Y-m-d H:i:s', $version);
+
+        // New way
+        FluidbookLinks::getLinksAndRulers($fluidbook_id, $links, $rulers, $version);
+        FluidbookLinks::saveLinksInFile($fluidbook_id, backpack_user()->id, $comments, $links, $rulers, [], []);
+    }
+
 //    protected function getThumb($doc_id, $doc_page)
 //    {
 //
index b9b4c6ff7d9e9e34599c561589255483e5e0216c..01ad6a19afed40212ed5ce214e56d7e7e6f3c1c0 100644 (file)
@@ -52,7 +52,7 @@ class FluidbookLinks
         $s->setTitle('Links');
 
         // Labels
-        $i = 0;
+        $i = 1;
         foreach ($cols as $id => $label) {
             $s->setCellValueByColumnAndRow($i, 1, $id);
             $s->getColumnDimensionByColumn($i)->setAutoSize(true);
@@ -64,7 +64,7 @@ class FluidbookLinks
         self::_correctImageSpecialLinks($links);
         $j = 2;
         foreach ($links as $l) {
-            $i = 0;
+            $i = 1;
             foreach ($cols as $id => $label) {
                 if (($id == 'document_id' || $id == 'document_page')) {
                     if (!is_null($pages)) {
@@ -103,7 +103,7 @@ class FluidbookLinks
         $s->setTitle('Rulers');
 
         $rcols = array('page', 'type', 'pos');
-        $i = 0;
+        $i = 1;
         // Labels
         foreach ($rcols as $id) {
             $s->setCellValueByColumnAndRow($i, 1, $id);
@@ -114,7 +114,7 @@ class FluidbookLinks
         // Contents
         $j = 2;
         foreach ($rulers as $r) {
-            $i = 0;
+            $i = 1;
             foreach ($rcols as $id) {
                 if (!is_null($pages) && ($id == 'document_id' || $id == 'document_page')) {
                     $infos = $pages[$r['page']];
@@ -328,7 +328,7 @@ class FluidbookLinks
                 continue;
             }
             $link->$attr = trim($link->$attr);
-            if (strpos($link->$attr, '///') === 0 || $link->$attr == '') {
+            if (str_starts_with($link->$attr, '///') || $link->$attr == '') {
                 continue;
             }
             $link->$attr = '///' . Crypt::safeEncrypt($link->uid . '|||' . $link->$attr, self::_getLinkKey());
@@ -348,7 +348,7 @@ class FluidbookLinks
         }
 
         foreach ($link as $attr => $item) {
-            if (strpos($item, '///') !== 0) {
+            if (!str_starts_with($item, '///')) {
                 continue;
             }
             $v = Crypt::safeDecrypt(substr($item, 3), self::_getLinkKey());
@@ -417,7 +417,11 @@ class FluidbookLinks
 
         $res = [];
         foreach ($updates as $timestamp => $u) {
-            $u['name'] = User::find($u['user'])->name;
+            try {
+                $u['name'] = User::find($u['user'])->name;
+            } catch (\Exception $e) {
+                $u['name'] = '-';
+            }
             $u['date'] = date('Y-m-d H:i:s', $timestamp);
             $u['timestamp'] = $timestamp;
             $res[] = $u;
index 74b1d9d5795de81a59d62515bb79c8e5279b7886..d28d242c6211c14fd53ebfbdfe1e1041fa436401 100644 (file)
@@ -95,6 +95,13 @@ LinkEditor.prototype = {
         });
     },
 
+    initTooltips: function () {
+        $('[data-tooltip]:not(.init-tooltip)').each(function () {
+            tippy($(this).get(0), {content: $(this).data('tooltip')});
+        });
+        $(this).addClass('init-tooltip');
+    },
+
     initEvents: function () {
         var $this = this;
         $(window).on('hashchange', function () {
@@ -181,7 +188,10 @@ LinkEditor.prototype = {
         this.changePage();
     },
 
-    runAction: function (act) {
+    runAction: function (act, args) {
+        if (arguments === undefined) {
+            args = [];
+        }
         var a = act.split('.');
         var o = this;
         let po = this;
@@ -189,7 +199,12 @@ LinkEditor.prototype = {
             po = o;
             o = o[a[i]];
         }
-        return o.call(po);
+        try {
+            return o.apply(po, args);
+        } catch (e) {
+            console.log(e);
+            console.error('Error while calling ' + act, args);
+        }
     },
 
     firstPage: function () {
index 072301e20b89eda6f5153a79f92f7d3cc7f6dad1..0f0353b99d12d3359a21babe597462f8edc3e6ba 100644 (file)
@@ -30,25 +30,38 @@ LinkeditorSave.prototype = {
         }
     },
 
-    save: function (message) {
+    save: function (message, notify, callback) {
+        if (notify === undefined) {
+            notify = true;
+        }
+        if (callback === undefined) {
+            callback = function () {
+
+            };
+        }
         var $this = this;
         if (message === undefined) {
             message = TRANSLATIONS.manual_save_message;
         }
-        var notificationTimeout=5000;
+        var notificationTimeout = 5000;
         $.ajax({
             url: '/fluidbook-publication/' + FLUIDBOOK_DATA.id + '/save/links', method: 'post', data: {
                 _method: 'put', 'message': message, rulers: window.RULERS, links: window.LINKS,
             },
             success: function (data) {
-                new Noty({
-                    type: "success",
-                    text: TRANSLATIONS.success_save,
-                    timeout: notificationTimeout,
-                }).show();
+                if (notify) {
+                    new Noty({
+                        type: "success",
+                        text: TRANSLATIONS.success_save,
+                        timeout: notificationTimeout,
+                    }).show();
+                }
                 clearTimeout($this.automaticSaveTimeout);
                 $this.unsavedChanges = false;
                 $this.runningAutomaticSaveTimeout = false;
+
+                $this.linkeditor.versions.refresh();
+                callback();
             },
             error: function (jqXHR, status, error) {
                 $this.linkeditor.hasChanged();
index 3c7dac2deac19e43c3f65f2d084d006cd73f8d3a..b85291a51c12c1201f68c54023400f4084bc8006 100644 (file)
@@ -5,7 +5,7 @@ function LinkeditorToolbar(linkeditor) {
 
 LinkeditorToolbar.prototype = {
     init: function () {
-        var $this=this;
+        var $this = this;
         $("#linkeditor-page-field input").on('change', function () {
             $this.linkeditor.changePage($(this).val());
             $(this).blur();
@@ -24,14 +24,12 @@ LinkeditorToolbar.prototype = {
             });
         });
 
-        $('[data-action]').click(function () {
-            $this.linkeditor.runAction($(this).data('action'));
+        $(document).on('click', '[data-action]', function () {
+            $this.linkeditor.runAction($(this).data('action'), $(this).is('[data-action-args]') ? $(this).data('action-args') : []);
             return false;
         });
 
-        $('[data-tooltip]').each(function () {
-            tippy($(this).get(0), {content: $(this).data('tooltip')});
-        });
+        this.linkeditor.initTooltips();
     },
 };
 module.exports = LinkeditorToolbar;
index 4cf8d1af348a20be23ddd045c1e3cf9728b2ab34..9804e060da1898a4940cf806753a9ea46d74a7d0 100644 (file)
@@ -21,7 +21,8 @@ LinkeditorVersions.prototype = {
     setVersions: function (data) {
         var list = $("#linkeditor-panel-versions-list");
         list.html('');
-        $.each(data, function (timestamp, version) {
+        $.each(data, function (k, version) {
+            let actionArgs = JSON.stringify([version.timestamp]);
             var item = '<div class="row">';
             item += '<div class="col1">';
             item += '<div class="date">' + version.date + '</div>';
@@ -33,25 +34,57 @@ LinkeditorVersions.prototype = {
             item += '<div class="rulers"><b>' + version.rulers + '</b> rulers</div>';
             item += '</div>'
             item += '<div class="col3">';
-            item += '<div class="actions"><a href="#" data-icon="wayback-machine" data-tooltip="Restaurer cette version"></a></td><td><a href="#" data-icon="export-links" data-tooltip="Exporter les liens au format xlsx"></a></div>';
+            item += '<div class="actions"><a nohref data-action="versions.restoreVersion" data-action-args="' + actionArgs + '" data-icon="wayback-machine" data-tooltip="Restaurer cette version"></a>' +
+                '<a download="links_' + FLUIDBOOK_DATA.id + '_' + version.timestamp + '.xlsx" href="/fluidbook-publication/' + FLUIDBOOK_DATA.id + '/edit/links/versions/export/' + version.timestamp + '" data-icon="export-links" data-tooltip="Exporter les liens au format xlsx"></a></div>';
             item += '</div>'
             item += '</div>'
             list.append(item);
         });
         this.linkeditor.initIcons();
+        this.linkeditor.initTooltips();
         this.resize();
     },
 
+    restoreVersion: function (timestamp) {
+        var $this = this;
+        var callback = function () {
+            $this._restoreVersion(timestamp);
+        }
+
+        //Restore links from 2022-12-07 13:37:15
+        if (this.linkeditor.save.unsavedChanges) {
+            console.log('save save save');
+            this.linkeditor.save.save('Save before restoring links', false, function () {
+                setTimeout(function () {
+                    callback();
+                }, 1000);
+            });
+        } else {
+            callback();
+        }
+    },
+
+    _restoreVersion(timestamp) {
+        $.ajax({
+            url: '/fluidbook-publication/' + FLUIDBOOK_DATA.id + '/edit/links/versions/restore/' + timestamp + '',
+            success: function (data) {
+                window.location.reload();
+            },
+        });
+    },
+
     resize: function () {
-        var w=$("#linkeditor-panel-versions-list").outerWidth();
-        if(w<=0){
+        var w = $("#linkeditor-panel-versions-list").outerWidth();
+        if (w <= 0) {
             return;
         }
-        if(w<300){
+        if (w < 300) {
             $("#linkeditor-panel-versions-list").addClass('small');
-        }else{
+        } else {
             $("#linkeditor-panel-versions-list").removeClass('small');
         }
     },
+
+
 };
 module.exports = LinkeditorVersions;
index 03ec50f10216fb57e5cea4e569ae439d1eb8322a..8ca744134a2fb8248a951ee7f61ef5261a1fc4ca 100644 (file)
@@ -1,5 +1,6 @@
 #linkeditor-panel-versions
     padding: 5px 10px
+    user-select: none
 
 #linkeditor-panel-versions-list
     font-size: 12px
@@ -42,6 +43,7 @@
                 height: $icon-size
                 margin-left: 7px
                 color: currentColor
+                cursor: pointer
 
                 svg
                     width: $icon-size
index 16a00ce270421b3b030979e1a0717e90d6605567..7fc382f3345e6e8df2dc9b0f0f36ff6cfc6c0b47 100644 (file)
@@ -75,8 +75,9 @@
                        data-tooltip="{{__('Importer les liens (Remplacer)')}}"></a>
                     <a href="#" data-action="mergeExcel" data-icon="merge-links"
                        data-tooltip="{{__('Importer les liens (Ajouter)')}}"></a>
-                    <a href="#" data-action="export" data-icon="export-links"
-                       data-tooltip="{{__('Exporter les liens')}}"></a>
+                    <a download="links_{{$fbdata['id']}}.xlsx"
+                       href="/fluidbook-publication/{{$fbdata['id']}}/edit/links/versions/export/latest"
+                       data-icon="export-links" data-tooltip="Exporter les liens"></a>
                     <a href="#" data-action="moveLinks" data-icon="move-links"
                        data-tooltip="{{__('Déplacer les liens')}}"></a>
                 </nav>