]> _ Git - fluidbook-toolbox.git/commitdiff
wait #5718 @1.5
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Fri, 17 Feb 2023 18:36:39 +0000 (19:36 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Fri, 17 Feb 2023 18:36:39 +0000 (19:36 +0100)
15 files changed:
app/Http/Controllers/Admin/Operations/Files/DownloadOperation.php
app/Http/Controllers/Admin/Operations/Files/UploadOperation.php
app/Http/Controllers/Admin/Operations/Files/UserListOperation.php [new file with mode: 0644]
app/Models/File.php
app/Slack/Slack.php
config/backpack/base.php
public/packages/fluidbook/toolbox/css/loader.css [new file with mode: 0644]
public/packages/fluidbook/toolbox/css/loader.css.map [new file with mode: 0644]
public/packages/fluidbook/toolbox/css/loader.less [new file with mode: 0644]
public/packages/fluidbook/toolbox/css/style.less
public/packages/fluidbook/toolbox/js/bundle.js
resources/views/fields/fluidbook_composition.blade.php
resources/views/vendor/backpack/crud/buttons/files/upload.blade.php
resources/views/vendor/backpack/crud/buttons/user/files.blade.php [new file with mode: 0644]
resources/views/vendor/backpack/crud/inc/datatables_logic.blade.php

index 8c6098015f1b837f8dadb848a31e29aaeabda833..27dbb4a1ae671180a820d726d7c727444cfdacfc 100644 (file)
@@ -18,7 +18,6 @@ trait DownloadOperation
     {
         Route::match(['get'], $segment . '/{hash}/install', $controller . '@manifestIpa')->withoutMiddleware([CheckIfAdmin::class]);
         Route::match(['get'], $segment . '/{hash}/{file}', $controller . '@download')->withoutMiddleware([CheckIfAdmin::class]);
-
     }
 
     protected function setupDownloadDefaults()
@@ -36,6 +35,8 @@ trait DownloadOperation
         return XSendFileController::sendfile($file->path);
     }
 
+
+
     /**
      * @throws IOException
      */
index 733cd84fc88e2bbdd8f9b593a0322f445758921d..296c4f0f25a6af2047d9308bed6dceedbcc3c6d0 100644 (file)
@@ -4,19 +4,20 @@ namespace App\Http\Controllers\Admin\Operations\Files;
 
 
 use App\Models\File;
-use App\Models\Quiz;
-use App\Models\QuizTranslation;
+use App\Models\User;
+use App\Slack\Slack;
 use Cubist\Util\Files\Files;
 use Illuminate\Http\UploadedFile;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Route;
 use Prologue\Alerts\Facades\Alert;
-use ZipArchive;
 
 trait UploadOperation
 {
     protected function setupImportRoutes($segment, $routeName, $controller)
     {
         Route::match(['post'], $segment . '/upload', $controller . '@upload');
+        Route::match(['post'], $segment . '/{user}/upload', $controller . '@upload');
     }
 
     protected function setupImportDefaults()
@@ -24,7 +25,8 @@ trait UploadOperation
         $this->crud->addButtonFromView('top', 'import', 'files.upload', 'end');
     }
 
-    protected function upload()
+
+    protected function upload($user = null)
     {
         /** @var UploadedFile[] $files */
         $files = request()->allFiles()['file'];
@@ -35,14 +37,36 @@ trait UploadOperation
         }
 
         $j = 0;
+        $paths = [];
         foreach ($files as $file) {
-            File::importUploadedFile($file);
+            $paths[] = File::importUploadedFile($file, $user, false);
             $j++;
         }
 
         if ($j === 0) {
             Alert::warning(__('Aucun fichier chargé'))->flash();
         } else {
+            Cache::forget(File::_cacheKeyUserFolder(backpack_user()->id));
+            if (null !== $user) {
+                Cache::forget(File::_cacheKeyUserFolder($user));
+            }
+            File::refreshDatabase();
+
+            if (null !== $user) {
+                /** @var User $destUser */
+                $destUser = User::withoutGlobalScopes()->find($user);
+                $subject = __(':nb fichiers chargés pour ' . $destUser->nameWithCompany, ['nb' => $j]);
+                $destChannel = backpack_user()->slack;
+            } else {
+                $subject = __(':nb fichiers chargés par ' . backpack_user()->nameWithCompany, ['nb' => $j]);
+                $destChannel = Slack::fluidbookFilesChannel;
+            }
+            $actions = [];
+            foreach ($paths as $path) {
+                $spl = new \SplFileInfo($path);
+                $actions[$spl->getFilename()] = backpack_url('/file/' . File::hash($path) . '/' . $spl->getFilename());
+            }
+            Slack::send($destChannel, $subject, '', $actions);
             Alert::success(__(':nb fichiers chargés', ['nb' => '<b>' . $j . '</b>']))->flash();
         }
         return redirect($this->crud->route);
diff --git a/app/Http/Controllers/Admin/Operations/Files/UserListOperation.php b/app/Http/Controllers/Admin/Operations/Files/UserListOperation.php
new file mode 100644 (file)
index 0000000..63e0b8c
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+namespace App\Http\Controllers\Admin\Operations\Files;
+
+use App\Models\User;
+use Illuminate\Support\Facades\Route;
+
+trait UserListOperation
+{
+    protected function setupUserListRoutes($segment, $routeName, $controller)
+    {
+        Route::get($segment . '/{user}', [
+            'as' => $routeName . '.userlist',
+            'uses' => $controller . '@userlist',
+            'operation' => 'list',
+        ]);
+
+        Route::post($segment . '/{user}/search', [
+            'as' => $routeName . '.usersearch',
+            'uses' => $controller . '@search',
+            'operation' => 'list',
+        ]);
+    }
+
+    public function setupUserListDefaults()
+    {
+        $this->crud->operation('list', function () {
+            $userid = request()->route('user');
+            if (null !== $userid) {
+                $user = User::withoutGlobalScopes()->find($userid);
+                $this->crud->searchURL = $userid . '/search';
+                $this->crud->addClause('whereIn', 'owner', $user->getManagedUsers());
+            }
+            $this->crud->disablePersistentTable();
+            $this->crud->orderBy('mtime', 'DESC');
+        });
+    }
+
+    public function userlist($id)
+    {
+        /** @var User $user */
+        $user = User::withoutGlobalScopes()->find($id);
+
+        $this->crud->hasAccessOrFail('list');
+        $this->crud->setHeading(__('Fichiers de :user', ['user' => $user->nameWithCompany]));
+
+        $this->data['crud'] = $this->crud;
+        $this->data['title'] = $this->crud->getHeading();
+        $this->crud->shareLabel = __('Partager des fichiers avec :user', ['user' => $user->firstname . ' ' . $user->lastname]);
+        $this->crud->shareURL = $id . '/upload';
+
+        // load the view from /resources/views/vendor/backpack/crud/ if it exists, otherwise load the one in the package
+        return view($this->crud->getListView(), $this->data);
+    }
+
+
+}
index 7176ea9981b73443c94849c0db02dd9523e17f0e..ee9fc2046ef2d2ebda91f79df61505a93fc0276c 100644 (file)
@@ -4,6 +4,7 @@ namespace App\Models;
 
 use App\Http\Controllers\Admin\Operations\Files\DownloadOperation;
 use App\Http\Controllers\Admin\Operations\Files\UploadOperation;
+use App\Http\Controllers\Admin\Operations\Files\UserListOperation;
 use App\Models\Base\ToolboxModel;
 use Cubist\Backpack\CubistBackpackServiceProvider;
 use Cubist\Backpack\Magic\Fields\Date;
@@ -37,7 +38,7 @@ class File extends ToolboxModel
     protected $keyType = 'string';
 
 
-    protected $_operations = [DownloadOperation::class, UploadOperation::class];
+    protected $_operations = [DownloadOperation::class, UploadOperation::class, UserListOperation::class];
 
     public static string $basePath = '/application/ftp/';
 
@@ -162,15 +163,27 @@ class File extends ToolboxModel
 
     /**
      * @param $file UploadedFile
-     * @return void
+     * @return string
      */
-    public static function importUploadedFile($file)
+    public static function importUploadedFile($file, $to = null, $refreshDatabase = true)
     {
-        $userId = backpack_user()->id;
-        $dest = Files::mkdir(self::$basePath . '/' . $userId) . Files::tidyName($file->getClientOriginalName());
+        $from = backpack_user()->id;
+        if (null === $to) {
+            /** @var User $toUser */
+            $dir = self::$basePath . '/' . $from;
+        } else {
+            $dir = self::$basePath . '/' . $to . '/.in/' . $from;
+        }
+        $dest = Files::mkdir($dir) . Files::tidyName($file->getClientOriginalName());
         move_uploaded_file($file->getPathname(), $dest);
-        Cache::forget(self::_cacheKeyUserFolder($userId));
-        static::refreshDatabase(true);
+        if ($refreshDatabase) {
+            Cache::forget(self::_cacheKeyUserFolder($from));
+            if (null !== $to) {
+                Cache::forget(self::_cacheKeyUserFolder($to));
+            }
+            static::refreshDatabase(true);
+        }
+        return $dest;
     }
 
     public static function hash($pathname)
index 8e02bbd7b038d4d38522a01abf70b2128cf9c226..57a1dd26c0ed3f568dc2b818374c7cbbae2cc8ed 100644 (file)
@@ -9,6 +9,7 @@ class Slack
 {
     const fluidbookQuoteChannel = 'C045CH0UB47';
     const fluidbookPreviewAlertsChannel = 'C04Q9LZNPT2';
+    const fluidbookFilesChannel='C04QJSY7CEM';
 
     /**
      * @var \JoliCode\Slack\Client|null
index bca61281b99d09151b9b433e1ebae930557bdfab..a606a65f274ee02cea0283e8c3cf4cb4415b6c44 100644 (file)
@@ -136,6 +136,7 @@ return [
         'https://cdnjs.cloudflare.com/ajax/libs/jquery.form/4.3.0/jquery.form.min.js',
         "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.2/jquery.contextMenu.min.js",
         "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.9.2/jquery.ui.position.min.js",
+        'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js',
 
         // examples (everything inside the bundle, loaded from CDN)
         // 'https://code.jquery.com/jquery-3.4.1.min.js',
diff --git a/public/packages/fluidbook/toolbox/css/loader.css b/public/packages/fluidbook/toolbox/css/loader.css
new file mode 100644 (file)
index 0000000..263101c
--- /dev/null
@@ -0,0 +1,57 @@
+#compositionProgress {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.25);
+}
+#compositionProgress div {
+  position: absolute;
+  top: calc(50% - 65px);
+  left: calc(50% - 200px);
+  width: 400px;
+  height: 130px;
+  padding: 20px;
+  background-color: #fff;
+  border-radius: 4px;
+}
+#compositionProgress span {
+  display: block;
+  text-align: center;
+  font-size: 17px;
+}
+#compositionProgress progress {
+  width: 100%;
+  margin: 10px auto;
+  height: 25px;
+  appearance: none;
+  border-radius: 2px;
+  border: 1px solid rgba(0, 40, 100, 0.12);
+}
+#compositionProgress progress::-moz-progress-bar,
+#compositionProgress progress::-webkit-progress-value {
+  border-radius: 2px;
+}
+#compositionProgress progress[data-step="0"] {
+  background-color: #fff;
+}
+#compositionProgress progress[data-step="0"]::-moz-progress-bar,
+#compositionProgress progress[data-step="0"]::-webkit-progress-value {
+  background-color: #3d86ee;
+}
+#compositionProgress progress[data-step="1"] {
+  background-color: #3d86ee;
+}
+#compositionProgress progress[data-step="1"]::-moz-progress-bar,
+#compositionProgress progress[data-step="1"]::-webkit-progress-value {
+  background-color: #3471c8;
+}
+#compositionProgress progress[data-step="2"] {
+  background-color: #3471c8;
+}
+#compositionProgress progress[data-step="2"]::-moz-progress-bar,
+#compositionProgress progress[data-step="2"]::-webkit-progress-value {
+  background-color: #20457b;
+}
+/*# sourceMappingURL=loader.css.map */
\ No newline at end of file
diff --git a/public/packages/fluidbook/toolbox/css/loader.css.map b/public/packages/fluidbook/toolbox/css/loader.css.map
new file mode 100644 (file)
index 0000000..4bdd4d5
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"sources":["loader.less"],"names":[],"mappings":"AAAA;EACI,eAAA;EACA,MAAA;EACA,OAAA;EACA,WAAA;EACA,YAAA;EACA,qCAAA;;AAGJ,oBAAqB;EACjB,kBAAA;EACA,KAAK,gBAAL;EACA,MAAM,iBAAN;EACA,YAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;EACA,kBAAA;;AAGJ,oBAAqB;EACjB,cAAA;EACA,kBAAA;EACA,eAAA;;AAGJ,oBAAqB;EACjB,WAAA;EACA,iBAAA;EACA,YAAA;EACA,gBAAA;EACA,kBAAA;EACA,wCAAA;;AAGJ,oBAAqB,SAAQ;AAAqB,oBAAqB,SAAQ;EAC3E,kBAAA;;AAGJ,oBAAqB,SAAQ;EACzB,sBAAA;;AAGJ,oBAAqB,SAAQ,eAAe;AAAqB,oBAAqB,SAAQ,eAAe;EACzG,yBAAA;;AAGJ,oBAAqB,SAAQ;EACzB,yBAAA;;AAGJ,oBAAqB,SAAQ,eAAe;AAAqB,oBAAqB,SAAQ,eAAe;EACzG,yBAAA;;AAGJ,oBAAqB,SAAQ;EACzB,yBAAA;;AAGJ,oBAAqB,SAAQ,eAAe;AAAqB,oBAAqB,SAAQ,eAAe;EACzG,yBAAA","file":"loader.css"}
\ No newline at end of file
diff --git a/public/packages/fluidbook/toolbox/css/loader.less b/public/packages/fluidbook/toolbox/css/loader.less
new file mode 100644 (file)
index 0000000..4028805
--- /dev/null
@@ -0,0 +1,66 @@
+#loader {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: rgba(0, 0, 0, 0.25);
+    cursor: wait;
+
+    div {
+        position: absolute;
+        top: calc(50% - 65px);
+        left: calc(50% - 200px);
+        width: 400px;
+        height: 130px;
+        padding: 20px;
+        background-color: #fff;
+        border-radius: 4px;
+        pointer-events: none;
+    }
+
+    span {
+        display: block;
+        text-align: center;
+        font-size: 17px;
+    }
+
+    progress {
+        width: 100%;
+        margin: 10px auto;
+        height: 25px;
+        appearance: none;
+        border-radius: 2px;
+        border: 1px solid rgba(0, 40, 100, .12);
+    }
+
+    progress::-moz-progress-bar, progress::-webkit-progress-value {
+        border-radius: 2px;
+    }
+
+    progress[data-step="0"] {
+        background-color: #fff;
+    }
+
+    progress[data-step="0"]::-moz-progress-bar, progress[data-step="0"]::-webkit-progress-value {
+        background-color: #3d86ee;
+    }
+
+    progress[data-step="1"] {
+        background-color: #3d86ee;
+    }
+
+    progress[data-step="1"]::-moz-progress-bar, progress[data-step="1"]::-webkit-progress-value {
+        background-color: #3471c8;
+    }
+
+    progress[data-step="2"] {
+        background-color: #3471c8;
+    }
+
+    progress[data-step="2"]::-moz-progress-bar, progress[data-step="2"]::-webkit-progress-value {
+        background-color: #20457b;
+    }
+
+}
+
index 33bd03e67449a5319affaa5a5d3353cbe6ffce89..c2bbd6013a69cd8b5241c6401299a796da55b95d 100644 (file)
@@ -448,4 +448,5 @@ body.embeded {
 }
 
 @import "context-menu";
+@import "loader";
 
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..95a5789d7ab63d43ef0ab36a0656496c0bc2e51b 100644 (file)
@@ -0,0 +1,70 @@
+$(function () {
+    $(document).on('submit', 'form.ajaxProgressForm', function () {
+        var progressMessage = $(this).data('progressmessage');
+        var errorMessage = $(this).data('errormessage');
+        var endMessage = $(this).data('endmessage');
+        var successMessage = $(this).data('successmessage');
+        var reloadOnSuccess = $(this).data('reloadonsuccess');
+        $(this).ajaxSubmit(
+            {
+                success: function (data) {
+                    if (reloadOnSuccess) {
+                        showLoader(successMessage, 1);
+                        setTimeout(function () {
+                            window.location.reload();
+                        }, 1000)
+                    } else {
+                        hideLoader();
+                    }
+                },
+                uploadProgress: function (event, position, total, percentComplete) {
+                    var progress = position / total;
+                    showLoader(progressMessage, progress);
+                    if (progress == 1) {
+                        showLoader(endMessage, progress)
+                    }
+                },
+                error: function (data) {
+                    new Noty({
+                        type: 'error',
+                        text: errorMessage,
+                    }).show();
+                }
+            }
+        );
+        return false;
+    });
+});
+
+function showLoader(message, progress) {
+    if ($("#loader").length === 0) {
+        $('body').append('<div id="loader"><div><span></span><progress data-progress="" data-step="0" value="0" max="100"></progress></div></div>');
+    }
+    if (message !== '' && progress > 0) {
+        var pb = $("#loader progress");
+        $("#loader span").html(message);
+        if (pb.attr('data-progress') == progress) {
+            return;
+        }
+        var dp = (progress % 1);
+        if (dp === 0 && progress > 0) {
+            dp = 1;
+        }
+        var p = Math.round(dp * 100);
+        var step = progress - dp;
+        var duration = 0.5;
+        if (p < pb.attr('value')) {
+            duration = 0;
+        }
+
+        gsap.to(pb, {
+            duration: duration, ease: 'none', attr: {'value': p}, onComplete: function () {
+                pb.attr('data-step', step);
+            }
+        });
+    }
+}
+
+function hideLoader() {
+    $("#loader").remove();
+}
index d1e18df57c04db2a9b01a56fbcd9b5a9c09b90a9..2a97cc0f5a35a8f893a31432e55e8aabf201651e 100644 (file)
                 }
 
                 function showProgressBar(message, progress, uploadID) {
-                    if ($("#compositionProgress").length === 0) {
-                        $('body').append('<div id="compositionProgress"><div><span></span><progress data-progress="" data-step="0" value="0" max="100"></progress></div></div>');
-                    }
-                    if (message !== '' && progress > 0) {
-                        $("#compositionProgress span").html(message);
-                        if ($("#compositionProgress progress").attr('data-progress') == progress) {
-                            return;
-                        }
-                        var dp = (progress % 1);
-                        if (dp === 0 && progress > 0) {
-                            dp = 1;
-                        }
-                        var p = Math.round(dp * 100);
-                        var step = progress - dp;
-                        var duration = 0.5;
-                        if (p < $("#compositionProgress progress").attr('value')) {
-                            duration = 0;
-                        }
-
-                        gsap.to($("#compositionProgress progress"), {
-                            duration: duration, ease: 'none', attr: {'value': p}, onComplete: function () {
-                                $("#compositionProgress progress").attr('data-step', step);
-                            }
-                        });
-                    }
+                    showLoader(message,progress)
 
                     if (progress >= 3) {
                         hideProgressBar();
 
                 function hideProgressBar() {
                     setTimeout(function () {
-                        $("#compositionProgress").remove();
+                      hideLoader();
                     }, 2000);
                 }
 
                 left: 12px;
             }
 
-            #compositionProgress {
-                position: fixed;
-                top: 0;
-                left: 0;
-                width: 100%;
-                height: 100%;
-                background-color: rgba(0, 0, 0, 0.25);
-            }
-
-            #compositionProgress div {
-                position: absolute;
-                top: calc(50% - 65px);
-                left: calc(50% - 200px);
-                width: 400px;
-                height: 130px;
-                padding: 20px;
-                background-color: #fff;
-                border-radius: 4px;
-            }
-
-            #compositionProgress span {
-                display: block;
-                text-align: center;
-                font-size: 17px;
-            }
-
-            #compositionProgress progress {
-                width: 100%;
-                margin: 10px auto;
-                height: 25px;
-                appearance: none;
-                border-radius: 2px;
-                border: 1px solid rgba(0, 40, 100, .12);
-            }
-
-            #compositionProgress progress::-moz-progress-bar, #compositionProgress progress::-webkit-progress-value {
-                border-radius: 2px;
-            }
-
-            #compositionProgress progress[data-step="0"] {
-                background-color: #fff;
-            }
-
-            #compositionProgress progress[data-step="0"]::-moz-progress-bar, #compositionProgress progress[data-step="0"]::-webkit-progress-value {
-                background-color: #3d86ee;
-            }
-
-            #compositionProgress progress[data-step="1"] {
-                background-color: #3d86ee;
-            }
-
-            #compositionProgress progress[data-step="1"]::-moz-progress-bar, #compositionProgress progress[data-step="1"]::-webkit-progress-value {
-                background-color: #3471c8;
-            }
-
-            #compositionProgress progress[data-step="2"] {
-                background-color: #3471c8;
-            }
-
-            #compositionProgress progress[data-step="2"]::-moz-progress-bar, #compositionProgress progress[data-step="2"]::-webkit-progress-value {
-                background-color: #20457b;
-            }
-
             .pace {
                 opacity: 0;
             }
index 668911228e37d203e28e5fdca2b2b2e31a5dda16..3fe5286e4279f2fe24cc7ace620f2f3eefc1246a 100644 (file)
@@ -1,10 +1,16 @@
-<form method="post" enctype="multipart/form-data" action="{{$crud->route}}/upload"
-      style="visibility:hidden;height:1px;position:absolute;top:0;" id="uploadfileform">
+<form method="post" enctype="multipart/form-data" action="{{$crud->route}}/{{$crud->shareURL??'upload'}}"
+      style="visibility:hidden;height:1px;position:absolute;top:0;" id="uploadfileform" class="ajaxProgressForm"
+      data-successmessage="{{__('Vos fichiers ont bien été envoyés')}}"
+      data-endmessage="{{__('Notification des destinataires')}} ..."
+      data-errormessage="{{__('Une erreur s\'est produite lors du chargement des fichiers')}}"
+      data-progressmessage="{{__('Chargement en cours').' ...'}}"
+      data-reloadonsuccess="true"
+>
     @csrf
     <input type="file" name="file[]" multiple="multiple" id="uploadfile" accept="*">
 </form>
 <a class="btn btn-primary" href="#" data-toggle="tooltip" title="Import" id="uploadfilebutton"><i
-        class="la la-upload"></i> {{__('Partager des fichiers')}}</a>
+        class="la la-upload"></i> {{$crud->shareLabel??__('Partager des fichiers')}}</a>
 
 
 @push('after_scripts')
diff --git a/resources/views/vendor/backpack/crud/buttons/user/files.blade.php b/resources/views/vendor/backpack/crud/buttons/user/files.blade.php
new file mode 100644 (file)
index 0000000..80f4d3f
--- /dev/null
@@ -0,0 +1,4 @@
+@if(backpack_user()->isOwner($entry))
+    <a class="btn btn-sm btn-link" href="{{backpack_url('file/'.$entry->id)}}" data-toggle="tooltip"
+       title="{{__('Partager des fichiers')}}"><i class="las la-cloud"></i> {{__('Partager des fichiers')}}</a>
+@endif
index 3d91ff8067e9de2a316fe859a0ad547fbe518697..25e55a02e5c9af6f4181e2c38fad73d6e6707ebb 100644 (file)
             serverSide: true,
             searching: @json($crud->getOperationSetting('searchableTable') ?? true),
             ajax: {
-                "url": "{!! url($crud->route.'/search').'?'.Request::getQueryString() !!}",
+                "url": "{!! url($crud->route.'/'.(isset($crud->searchURL) && $crud->searchURL?$crud->searchURL:'search')).'?'.Request::getQueryString() !!}",
                 "type": "POST"
             },
             dom: