From 4a7988567c96c1669fe0eb648ffb4b65974b3df4 Mon Sep 17 00:00:00 2001 From: Yann Gonidec Date: Wed, 22 May 2019 17:10:16 +0200 Subject: [PATCH] =?UTF-8?q?front=20:=20gestion=20des=20r=C3=A9pertoires?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Dossier.php | 44 ++ app/Http/Controllers/CommunController.php | 17 +- app/Http/Controllers/DossierController.php | 148 ++++++ app/Http/Controllers/MediaController.php | 26 + app/Http/Controllers/UserController.php | 22 + app/Media.php | 26 + app/Sujet.php | 8 + app/User.php | 15 +- public/css/app.css | 589 ++++++++++++++++++++- public/js/app.js | 586 +++++++++++++++++++- public/js/jquery.nestable.min.js | 1 + resources/js/app.js | 25 +- resources/js/media.js | 505 ++++++++++++++++++ resources/sass/app.scss | 1 + resources/sass/partials/common.scss | 139 ++++- resources/sass/partials/media.scss | 151 +++++- resources/sass/partials/nestable.scss | 258 +++++++++ resources/views/dossiers/create.blade.php | 2 +- resources/views/dossiers/edit.blade.php | 2 +- resources/views/home.blade.php | 7 +- resources/views/layouts/app.blade.php | 2 +- resources/views/media_manager.blade.php | 47 +- routes/web.php | 13 +- webpack.mix.js | 3 +- 24 files changed, 2584 insertions(+), 53 deletions(-) create mode 100644 app/Http/Controllers/MediaController.php create mode 100644 app/Media.php create mode 100644 public/js/jquery.nestable.min.js create mode 100644 resources/js/media.js create mode 100644 resources/sass/partials/nestable.scss diff --git a/app/Dossier.php b/app/Dossier.php index 385d022..3845518 100644 --- a/app/Dossier.php +++ b/app/Dossier.php @@ -3,9 +3,33 @@ namespace App; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Auth; class Dossier extends Model { + protected $with = "sousdossiers"; + protected $appends = array('favoris', 'mediacount'); + + /** + * Get user favoris + */ + public function getFavorisAttribute() + { + $userId = Auth::user()->id; + if($this->users()->where('id', $userId)->first()){ + return true; + }else{ + return false; + } + } + + /** + * Get media linked + */ + public function getMediacountAttribute() + { + return $this->medias()->count(); + } /** * The marques that belong to the dossier. @@ -23,6 +47,14 @@ class Dossier extends Model return $this->belongsTo('App\Sujet', 'sujet_id'); } + /** + * Get the dossier for the sujet. + */ + public function medias() + { + return $this->hasMany('App\Media', 'dossier_id', 'id'); + } + /** * Get the dossiers for the parent. */ @@ -40,4 +72,16 @@ class Dossier extends Model } + /** + * The users that belong to the dossier. + */ + public function users() + { + return $this->belongsToMany('App\User', 'dossiers_users', 'dossier_id', 'user_id'); + } + + public static function getDossierBySujetid($sujetId) + { + return Dossier::where('sujet_id', $sujetId)->whereNull('parent_id')->get(); + } } diff --git a/app/Http/Controllers/CommunController.php b/app/Http/Controllers/CommunController.php index 20075c1..014ee72 100644 --- a/app/Http/Controllers/CommunController.php +++ b/app/Http/Controllers/CommunController.php @@ -4,8 +4,9 @@ namespace App\Http\Controllers; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Mail; -use App\Mail\contact; use App\Sujet; +use App\User; +use App\Mail\contact; use Illuminate\Http\Request; class CommunController extends Controller @@ -17,7 +18,8 @@ class CommunController extends Controller */ public function index() { - return view('home'); + $sujets = Auth::user()->sujets; + return view('home')->with(['sujets'=> $sujets]); } /** @@ -38,15 +40,4 @@ class CommunController extends Controller } return ""; } - - /** - * page gestion des médias - * - * @return \Illuminate\Contracts\Support\Renderable - */ - public function media_manager() - { - $sujets = Sujet::all(); - return view('media_manager')->with(['sujets'=> $sujets]); - } } diff --git a/app/Http/Controllers/DossierController.php b/app/Http/Controllers/DossierController.php index 0ddebcf..b8d816c 100644 --- a/app/Http/Controllers/DossierController.php +++ b/app/Http/Controllers/DossierController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Dossier; use App\Sujet; use App\Marque; +use App\Media; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -172,4 +173,151 @@ class DossierController extends Controller return redirect()->route('dossier.edit', ['user' => $dossier]); } } + + /** + * Chargement des dossiers + * + */ + public function loadFolder(Request $request) + { + $response = array(); + $sujetId = $request->input('sujetId'); + $marques = Auth::user()->marques()->pluck("marque_id"); + $response['data'] = Dossier::where('sujet_id', $sujetId) + ->whereNull('parent_id') + ->whereHas("marques", function($query) use ($marques){ + $query->whereIn("marque_id", $marques); + })->get(); + $response['count'] = Media::where('sujet_id', $sujetId)->whereNull('dossier_id')->count(); + + if(Auth::user()->hasRole([config('roles.const.ADMIN'), config('roles.const.REDACTEUR')] )){ + $response['draggable'] = true; + }else{ + $response['draggable'] = false; + } + + return json_encode($response); + } + + /** + * Ajouter un dossier + * + */ + public function addFolder(Request $request) + { + $response = array(); + Auth::user()->authorizeRoles([config('roles.const.ADMIN'), config('roles.const.REDACTEUR')]); + $parent_id = $request->input('parent_id'); + $libelle = $request->input('libelle'); + + // ---- Le dossier + $dossier = new Dossier(); + $dossier->libelle = $libelle; + $dossier->parent_id = $parent_id; + $dossier->save(); + + $response['folder_id'] = $dossier->id; + return json_encode($response); + } + + /** + * supprimer un dossier + * + */ + public function removeFolder(Request $request) + { + Auth::user()->authorizeRoles([config('roles.const.ADMIN'), config('roles.const.REDACTEUR')]); + $dossier_id = $request->input('dossier_id'); + + // ---- Le dossier + $dossier = Dossier::where('id', $dossier_id)->first(); + if($dossier && !is_null($dossier->parent_id)){ + if ($dossier->delete()) { + return json_encode(true); + } + } + + return json_encode(false); + } + + /** + * déplacer un dossier + * + */ + public function moveFolder(Request $request) + { + Auth::user()->authorizeRoles([config('roles.const.ADMIN'), config('roles.const.REDACTEUR')]); + $dossier_id = $request->input('dossier_id'); + $parent_id = $request->input('parent_id'); + + // ---- Le dossier + $dossier = Dossier::where('id', $dossier_id)->first(); + if($dossier && !is_null($dossier->parent_id)){ + $dossier->parent_id = $parent_id; + if ($dossier->save()) { + return json_encode(true); + } + } + + return json_encode(false); + } + + /** + * renommer un dossier + * + */ + public function renameFolder(Request $request) + { + Auth::user()->authorizeRoles([config('roles.const.ADMIN'), config('roles.const.REDACTEUR')]); + $dossier_id = $request->input('dossier_id'); + $libelle = $request->input('libelle'); + + // ---- Le dossier + $dossier = Dossier::where('id', $dossier_id)->first(); + if($dossier && !is_null($dossier->parent_id)){ + $dossier->libelle = $libelle; + if ($dossier->save()) { + return json_encode(true); + } + } + return json_encode(false); + } + + /** + * get propriétés d'un dossier + * + */ + public function getFolderProperty(Request $request) + { + $response = array(); + $dossier_id = $request->input('dossier_id'); + + // ---- Le dossier + $dossier = Dossier::where('id', $dossier_id)->first(); + if($dossier){ + $response["data"] = $dossier; + } + return json_encode($response); + } + + /** + * enregistre les propriétés d'un dossier + * + */ + public function saveFolderProperty(Request $request) + { + $dossier_id = $request->input('dossier_id'); + $libelle = $request->input('libelle'); + $description = $request->input('description'); + + // ---- Le dossier + $dossier = Dossier::where('id', $dossier_id)->first(); + if($dossier && !is_null($dossier->parent_id) && strlen ($libelle)>3 ){ + $dossier->libelle = $libelle; + $dossier->description = $description; + $dossier->save(); + } + return json_encode(true); + } + } diff --git a/app/Http/Controllers/MediaController.php b/app/Http/Controllers/MediaController.php new file mode 100644 index 0000000..2b24f08 --- /dev/null +++ b/app/Http/Controllers/MediaController.php @@ -0,0 +1,26 @@ +with(['sujets'=> $sujets]); + } + + +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 6261f75..3639e15 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\User; use App\Marque; use App\Sujet; +use App\Dossier; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Adldap\Laravel\Facades\Adldap; @@ -227,4 +228,25 @@ class UserController extends Controller return redirect()->route('user.edit', ['user' => $user]); } } + + /** + * ajouter un dossier en favoris + * + */ + public function favorisFolder(Request $request) + { + Auth::user()->authorizeRoles([config('roles.const.ADMIN'), config('roles.const.REDACTEUR')]); + $dossier_id = $request->input('dossier_id'); + $favoris = (bool) $request->input('favoris'); + + $dossierFav = Auth::user()->dossiers()->where('id', $dossier_id)->first(); + + if($favoris == false && $dossierFav){ + + Auth::user()->dossiers()->detach($dossier_id); + }elseif ($favoris == true && !$dossierFav) { + Auth::user()->dossiers()->attach($dossier_id); + } + return json_encode(true); + } } diff --git a/app/Media.php b/app/Media.php new file mode 100644 index 0000000..7cdc749 --- /dev/null +++ b/app/Media.php @@ -0,0 +1,26 @@ +belongsTo('App\Dossier', 'dossier_id'); + } + + /** + * Get the sujet that owns the media. + */ + public function sujet() + { + return $this->belongsTo('App\Sujet', 'sujet_id'); + } +} diff --git a/app/Sujet.php b/app/Sujet.php index 715a58a..ee05d1a 100644 --- a/app/Sujet.php +++ b/app/Sujet.php @@ -30,4 +30,12 @@ class Sujet extends Model { return $this->hasMany('App\Dossier'); } + + /** + * Get the medias for the sujet. + */ + public function medias() + { + return $this->hasMany('App\Media'); + } } diff --git a/app/User.php b/app/User.php index 0f061a4..fa38dcd 100644 --- a/app/User.php +++ b/app/User.php @@ -53,8 +53,11 @@ class User extends Authenticatable * Check one role * @param string $role */ - public function hasRole($role) { - return $this->role == $role; + public function hasRole($roles) { + if (is_array($roles)) { + return in_array($this->role, $roles); + } + return $this->role == $roles; } /** @@ -73,6 +76,14 @@ class User extends Authenticatable return $this->belongsToMany('App\Marque', 'marques_users', 'user_id', 'marque_id'); } + /** + * The dossiers that belong to the user. + */ + public function dossiers() + { + return $this->belongsToMany('App\Dossier', 'dossiers_users', 'user_id', 'dossier_id'); + } + /** * The sujet that belong to the user. */ diff --git a/public/css/app.css b/public/css/app.css index d1c782f..0edfa1f 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -3659,6 +3659,266 @@ table { } } +.dd { + position: relative; + display: block; + margin: 0; + padding: 0; + max-width: 600px; + list-style: none; + font-size: 13px; + line-height: 20px; +} + +.dd-list { + display: block; + position: relative; + margin: 0; + padding: 0; + list-style: none; +} + +.dd-list .dd-list { + padding-left: 30px; +} + +.dd-empty, +.dd-item, +.dd-placeholder { + display: block; + position: relative; + margin: 0; + padding: 0; + min-height: 20px; + font-size: 12px; + line-height: 20px; +} + +.dd-handle { + display: block; + height: 30px; + margin: 5px 0; + padding: 5px 10px; + color: #ffffff; + text-decoration: none; + font-weight: 700; + border-radius: 3px; + box-sizing: border-box; +} + +.dd-handle:hover { + color: #2ea8e5; +} + +.dd-item > button { + position: relative; + cursor: pointer; + float: left; + width: 11px; + height: 20px; + margin: 5px 0; + padding: 0; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + border: 0; + background: 0 0; + font-size: 12px; + line-height: 1; + text-align: center; + font-weight: 700; +} + +.dd-item > button:before { + display: block; + position: absolute; + width: 100%; + text-align: center; + text-indent: 0; + color: white; + font-family: "Font Awesome 5 Pro"; + font-weight: 900; + top: 3px; +} + +.dd-item > button.dd-expand:before { + content: "\F0DA"; +} + +.dd-item > button.dd-collapse:before { + content: "\F0D7"; +} + +.dd-expand { + display: none; +} + +.dd-collapsed .dd-collapse, +.dd-collapsed .dd-list { + display: none; +} + +.dd-collapsed .dd-expand { + display: block; +} + +.dd-empty, +.dd-placeholder { + margin: 0px 0; + padding: 0; + min-height: 30px; + background: #3b3b3b; + border: 1px dashed #b6bcbf; + box-sizing: border-box; + -moz-box-sizing: border-box; +} + +.dd-empty { + border: 1px dashed #bbb; + min-height: 100px; + background-size: 60px 60px; + background-position: 0 0, 30px 30px; +} + +.dd-dragel { + position: absolute; + pointer-events: none; + z-index: 9999; +} + +.dd-dragel > .dd-item .dd-handle { + margin-top: 0; +} + +.dd-dragel .dd-handle { + box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1); +} + +.dd-nochildren .dd-placeholder { + display: none; +} + +/** +* Nestable Draggable Handles +*/ + +.dd3-content { + display: block; + height: 30px; + margin: 0; + padding: 5px 10px 5px 33px; + text-decoration: none; + color: #ffffff; + border-radius: 3px; + box-sizing: border-box; + -moz-box-sizing: border-box; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.dd3-content .count { + float: right; + display: inline; + background-color: #1a1a1a; + color: #aaaaaa; + border-radius: 11px; + padding: 0px 8px; + margin-left: 5px; +} + +.dd3-content i { + color: #ffed4a; + float: right; + padding: 3px; +} + +.dd3-content i.fas { + display: inline-block; +} + +.dd3-content i.fal { + display: none; +} + +.dd3-content:hover { + background-color: rgba(46, 168, 229, 0.2); +} + +.dd3-content:hover i.fal { + display: inline-block; +} + +.dd3-content.selected, +.dd3-content.dragged { + color: #ffffff; + background-color: #2ea8e5; +} + +.dd3-content.selected:hover, +.dd3-content.dragged:hover { + color: #ffffff; +} + +.dd3-content .input_rename { + display: none; + width: 91%; + padding: 2px 1%; + border-radius: 1px; +} + +.dd-dragel > .dd3-item > .dd3-content { + margin: 0; +} + +.dd3-content.renaming .input_rename { + display: inline-block; +} + +.dd3-content.renaming span { + display: none; +} + +.dd3-item > button { + margin-left: 27px; + margin-right: 3px; +} + +.dd3-handle { + position: absolute; + margin: 0; + left: 0; + top: 0; + cursor: move; + width: 30px; + text-indent: 30px; + white-space: nowrap; + overflow: hidden; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.dd3-handle.no-handle { + cursor: default; +} + +.dd3-handle:before { + content: "\F07B"; + font-family: "Font Awesome 5 Pro"; + font-weight: 900; + display: block; + position: absolute; + left: 0; + top: 3px; + width: 100%; + text-align: center; + text-indent: 0; + color: #ffffff; + font-size: 13px; +} + /*! * Font Awesome Pro 5.8.1 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license (Commercial License) @@ -12177,6 +12437,56 @@ readers do not read off random characters that represent icons */ vertical-align: middle; } +#form_folder_property { + padding: 30px; + min-width: 550px; +} + +#form_folder_property h3 { + font-size: 14px; + margin-bottom: 12px; + font-weight: bold; + color: #ffffff; +} + +#form_folder_property hr { + color: #24272e; + border-bottom: 1px solid #2c2f36; + margin-bottom: 20px; +} + +#form_folder_property p.button_bar { + text-align: right; + margin: 0; +} + +#form_folder_property select, +#form_folder_property input, +#form_folder_property textarea { + width: 100%; +} + +#form_folder_property textarea { + margin-bottom: 20px; + min-height: 200px; +} + +#form_folder_property .btn { + margin-right: 10px; +} + +#form_folder_property .form_folder_save .fa-spinner-third { + display: none; +} + +#form_folder_property .form_folder_save.loading .fa-spinner-third { + display: inline-block; +} + +#form_folder_property .form_folder_save.loading .fa-share { + display: none; +} + /****************************************** TEMPLATE ******************************************/ @@ -12247,7 +12557,7 @@ readers do not read off random characters that represent icons */ transform: translate(-50%, -50%); position: absolute; text-align: center; - width: 560px; + width: 700px; } .home .search .container h1 { @@ -12257,24 +12567,123 @@ readers do not read off random characters that represent icons */ .home .search .container .input_search { margin-top: 20px; + display: flex; + flex-direction: row; position: relative; } -.home .search .container .input_search input { +.home .search .container .input_search::before { + position: absolute; + top: 0; + left: 0; width: 100%; + height: 100%; + pointer-events: none; + border-radius: 3px; + box-shadow: inset 0 0 0 1px #dfdfdf; + content: ""; + z-index: 2; +} + +.home .search .container .input_search input { + width: 66%; font-size: 17px; - padding: 12px 48px 12px 14px; + padding: 12px; + border-radius: 0; + color: #4a4a4a; +} + +.home .search .container .input_search input::-webkit-input-placeholder { + color: rgba(74, 74, 74, 0.4); +} + +.home .search .container .input_search input::-moz-placeholder { + color: rgba(74, 74, 74, 0.4); +} + +.home .search .container .input_search input:-ms-input-placeholder { + color: rgba(74, 74, 74, 0.4); +} + +.home .search .container .input_search input::-ms-input-placeholder { + color: rgba(74, 74, 74, 0.4); +} + +.home .search .container .input_search input::placeholder { + color: rgba(74, 74, 74, 0.4); } .home .search .container .input_search button { border: none; - position: absolute; - right: 0; - background-color: transparent; - color: #aaaaaa; + width: 8%; + background-color: #ffffff; + border-radius: 0 3px 3px 0; + color: #374957; font-size: 25px; - padding: 8px 15px 8px 8px; + padding: 8px; cursor: pointer; + box-shadow: inset 0 0 0 1px #e3e3e3; +} + +.home .search .container .input_search button:hover { + background-color: #0a6fb7; + color: #ffffff; +} + +.home .search .container .input_search .select_container { + width: 26%; + position: relative; + overflow: hidden; +} + +.home .search .container .input_search .select_container::after { + /* Le pointeur du select */ + content: ""; + position: absolute; + top: 50%; + margin-top: -3px; + right: 0.75em; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-top-color: #444; + border-width: 5px; + border-style: solid; + pointer-events: none; +} + +.home .search .container .input_search .select_container::before { + position: absolute; + top: 50%; + width: 1px; + height: 60%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + background-color: #dfdfdf; + content: ""; + right: 0; + z-index: 10; +} + +.home .search .container .input_search .select_container select { + position: relative; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 110%; + height: auto; + color: #4a4a4a; + border: 0; + margin: 0; + padding: 14px 48px 14px 14px; + border-radius: 0; + overflow: hidden; + text-overflow: ellipsis; + /* + + border-radius: 3px 0 0 3px; + border-left: 1px solid #E1E1E1;*/ } /****************************************** @@ -12605,10 +13014,74 @@ table tfoot tr { margin-top: 25px; } +.media_manager { + height: calc(100% - 48px); +} + +.media_manager .main_content { + height: 100%; + padding: 0; +} + +.media_manager .main_content .media_container { + overflow-y: auto; + overflow-x: hidden; + position: relative; + height: 100%; +} + +.media_manager .main_content .media_container .loader { + position: -webkit-sticky; + position: sticky; + font-size: 20px; + color: #ffffff; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 50; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + top: 0; +} + +.media_manager .main_content .media_container .imageItem { + padding: 51px 20px; + margin: 30px 10px; + display: inline-block; + border: 1px solid grey; +} + +.media_manager .main_content .media_container .imageItem[aria-grabbed=true] { + background: #8ad; + color: #fff; +} + +.media_manager .main_content .media_container .imageItem:focus { + outline: none; + box-shadow: 0 0 0 2px #68b, inset 0 0 0 1px #ddd; +} + +.media_manager [draggable] { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + .media_manager .side_menu { background-color: #3b3b3b; position: relative; width: 340px; + height: 100%; + transition: 0.3s ease-in-out; +} + +.media_manager .side_menu.collapse { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + position: absolute; } .media_manager .side_menu::before { @@ -12621,7 +13094,8 @@ table tfoot tr { } .media_manager .side_menu header { - padding-left: 12px; + padding: 12px; + position: relative; } .media_manager .side_menu header h1 { @@ -12635,10 +13109,103 @@ table tfoot tr { border-radius: 50%; } +.media_manager .side_menu header .close_side_menu { + background-color: #3b3b3b; + position: absolute; + right: -17px; + top: 40px; + width: 17px; + height: 40px; + z-index: 2; + border-radius: 0 3px 3px 0; + border-top: 1px solid #505050; + border-right: 1px solid #505050; + border-bottom: 1px solid #505050; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} + .media_manager .side_menu .folder_container { background-color: #333333; - min-height: calc(100% - 77px); - overflow: auto; + height: calc(100% - 129px); + overflow-y: auto; + position: relative; +} + +.media_manager .side_menu .folder_container .loader { + position: absolute; + font-size: 20px; + color: #ffffff; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 50; + text-align: center; +} + +.media_manager .side_menu .folder_container .loader i { + margin-top: 232px; +} + +.media_manager .side_menu .folder_container .root_folder { + color: white; + font-weight: bold; + padding: 9px 11px; + margin-top: 13px; + font-size: 12px; +} + +.media_manager .side_menu .folder_container .root_folder:hover { + color: #2ea8e5; +} + +.media_manager .side_menu .folder_container .root_folder.selected, +.media_manager .side_menu .folder_container .root_folder.dragged { + color: #ffffff; + background-color: #2ea8e5; +} + +.media_manager .side_menu .folder_container .root_folder.selected:hover, +.media_manager .side_menu .folder_container .root_folder.dragged:hover { + color: #ffffff; +} + +.media_manager .side_menu .folder_container .root_folder .count { + float: right; + display: inline; + background-color: #1a1a1a; + color: #aaaaaa; + border-radius: 11px; + padding: 5px 8px; + position: relative; + top: -5px; +} + +.media_manager .side_menu .folder_container .folder_menu { + width: 140px; + box-shadow: 0 4px 5px 3px rgba(0, 0, 0, 0.2); + position: absolute; + display: none; + background-color: #333333; + z-index: 1; +} + +.media_manager .side_menu .folder_container .folder_menu .menu-options { + list-style: none; + padding: 10px 0; +} + +.media_manager .side_menu .folder_container .folder_menu .menu-options .menu-option { + font-weight: 500; + font-size: 13px; + padding: 10px; + cursor: pointer; +} + +.media_manager .side_menu .folder_container .folder_menu .menu-options .menu-option:hover { + background: rgba(0, 0, 0, 0.2); } /****************************************** diff --git a/public/js/app.js b/public/js/app.js index 4b6112f..61aed35 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -10911,7 +10911,24 @@ function tableGlobalSearch(field, search, cols) { try { window.$ = window.jQuery = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); -} catch (e) {} //confirm popup +} catch (e) {} + +jQuery.fn.scrollParent = function () { + var overflowRegex = /(auto|scroll)/, + position = this.css("position"), + excludeStaticParent = position === "absolute", + scrollParent = this.parents().filter(function () { + var parent = $(this); + + if (excludeStaticParent && parent.css("position") === "static") { + return false; + } + + var overflowState = parent.css(["overflow", "overflowX", "overflowY"]); + return overflowRegex.test(overflowState.overflow + overflowState.overflowX + overflowState.overflowY); + }).eq(0); + return position === "fixed" || !scrollParent.length ? $(this[0].ownerDocument || document) : scrollParent; +}; //confirm popup $.fancyConfirm = function (opts) { @@ -10964,10 +10981,15 @@ $(".userbar").on('click', function (event) { }); $(document).mouseup(function (e) { var container = $(".userbar"); + var menuContextuel = $(".folder_container .folder_menu"); if (!container.is(e.target) && container.has(e.target).length === 0) { $(".submenu").hide(); } + + if (!menuContextuel.is(e.target) && menuContextuel.has(e.target).length === 0) { + menuContextuel.hide(); + } }); // ---- Header : Ouverture formulaire de contact $(".contact_btn").on('click', function (event) { @@ -10988,9 +11010,9 @@ $(".contact_btn").on('click', function (event) { } } }); -}); // ---- Header : fermeture formulaire de contact +}); // ---- Header : fermeture de la popup -$(".form_contact_close").on('click', function (event) { +$(".close_popup").on('click', function (event) { event.preventDefault(); $.fancybox.getInstance().close(); }); // ---- Header : envoi formulaire de contact @@ -11036,6 +11058,557 @@ $(".form_contact_send").on('click', function (event) { /***/ }), +/***/ "./resources/js/media.js": +/*!*******************************!*\ + !*** ./resources/js/media.js ***! + \*******************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +$(document).ready(function () { + // ---- Gestion des média : init des dossiers + if ($(".media_manager").length) { + var sujetId = $("#sujet_selector").val(); + if (sujetId != "") initFolderManager(sujetId); + } // ---- Gestion des média : collapse/expand side menu + + + $(".close_side_menu").on('click', function (event) { + event.preventDefault(); + + if ($(".side_menu ").hasClass('collapse')) { + $(".side_menu ").removeClass('collapse'); + $(".close_side_menu i").removeClass('fa-chevron-right'); + $(".close_side_menu i").addClass('fa-chevron-left'); + } else { + $(".side_menu ").addClass('collapse'); + $(".close_side_menu i").removeClass('fa-chevron-left'); + $(".close_side_menu i").addClass('fa-chevron-right'); + } + }); // ---- Gestion des média : init des dossiers lorsqu'on change de sujet + + $("#sujet_selector").on('change', function (event) { + var sujetId = $("#sujet_selector").val(); + if (sujetId != "") $('.dd').nestable('destroy'); + initFolderManager(sujetId); + }); // ---- Gestion des média : sélectionner un dossier et favoris + + $(".folder_container").on('click', '.dd3-content', function (e) { + event.preventDefault(); + var target = e.target, + $target = $(target); + + if ($target.hasClass('fa-star')) { + // Gestion des favoris + var dossier_id = $target.parents(".dd3-item").attr("data-id"); + var favoris = false; + + if ($target.hasClass("fas")) { + $target.removeClass("fas").addClass("fal"); + } else { + $target.removeClass("fal").addClass("fas"); + favoris = true; + } + + $.ajax({ + url: '/ajax/favoris-folder', + method: 'POST', + dataType: 'json', + data: { + dossier_id: dossier_id, + favoris: favoris + } + }); + } else { + // simple sélection de dossier + $(".folder_container .dd3-content").removeClass('selected'); + $(".folder_container .root_folder").removeClass('selected'); + $(this).addClass('selected'); + } + }); // ---- Gestion des média : sélectionner la racine + + $(".folder_container").on('click', '.root_folder', function (event) { + event.preventDefault(); + $(".folder_container .dd3-content").removeClass('selected'); + $(this).addClass('selected'); + }); // ---- Gestion des média : menu contextuel des dossiers + + $(".folder_container").on('contextmenu', '.dd3-content', function (event) { + event.preventDefault(); // placement du menu + + $(".folder_container .folder_menu").css({ + left: event.pageX, + top: event.pageY - 180 + }); // memo l'id du dossier cible + + var id = $(this).parent("li").attr("data-id"); + $(".folder_container .folder_menu").attr('data-id', id); // si c'est un dossier parent, on cache certaines options + + if ($(this).parent("li").hasClass("parent")) { + $(".folder_menu .renameItem, .folder_menu .removeItem").hide(); + } else { + $(".folder_menu .renameItem, .folder_menu .removeItem").show(); + } + + $(".folder_container .folder_menu").show(); + }); // ---- Gestion des média : ajouter un dossier + + $(".folder_menu").on('click', '.addItem', function (event) { + event.preventDefault(); + var parent_id = $(this).parents(".folder_menu").attr("data-id"); + $(".folder_container .folder_menu").hide(); + $(".folder_container .loader").show(); + var folder = $('.dd .dd-item[data-id="' + parent_id + '"]'); + + if (folder.parents('.dd-item').length + 1 >= 5) { + $.fancyMessage({ + title: "Attention", + message: "Vous ne pouvez pas créer plus de 5 niveaux de sous-dossiers.", + type: "info" + }); + $(".folder_container .loader").hide(); + return false; + } + + $.ajax({ + url: '/ajax/add-folder', + method: 'POST', + dataType: 'json', + data: { + parent_id: parent_id, + libelle: 'Nouveau dossier' + }, + success: function success(result) { + addItem(parent_id, result.folder_id, 'Nouveau dossier'); + $(".folder_container .loader").hide(); + }, + error: function error(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({ + title: "Attention", + message: "Erreur lors de l'ajout du dossier. Merci d'actualiser la page.", + type: "error" + }); + } + }); + }); // ---- Gestion des média : supprimer un dossier + + $(".folder_menu").on('click', '.removeItem', function (event) { + event.preventDefault(); + var dossier_id = $(this).parents(".folder_menu").attr("data-id"); + $(".folder_container .folder_menu").hide(); + $(".folder_container .loader").show(); + + if (!$('.dd .dd-item[data-id="' + dossier_id + '"] > ol').length) { + $.ajax({ + url: '/ajax/remove-folder', + method: 'POST', + dataType: 'json', + data: { + dossier_id: dossier_id + }, + success: function success(result) { + // supprimer dossier + if (result == true) { + $('.dd').nestable('remove', dossier_id); + } else { + $.fancyMessage({ + title: "Attention", + message: "Erreur lors de la suppression du dossier. Merci d'actualiser la page.", + type: "error" + }); + } + + $(".folder_container .loader").hide(); + }, + error: function error(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({ + title: "Attention", + message: "Erreur lors de la suppression du dossier. Merci d'actualiser la page.", + type: "error" + }); + } + }); + } else { + $(".folder_container .loader").hide(); + $.fancyMessage({ + title: "Suppresion impossible", + message: "Pour supprimer un dossier, vous devez d'abord vider son contenu (médias et sous-dossiers).", + type: "error" + }); + } + }); // ---- Gestion des média : renommer un dossier + + $(".folder_menu").on('click', '.renameItem', function (event) { + event.preventDefault(); + $(".folder_container .folder_menu").hide(); + var dossier_id = $(this).parents(".folder_menu").attr("data-id"); + $('.dd .dd-item[data-id="' + dossier_id + '"] > .dd3-content').addClass('renaming'); + $('.renaming .input_rename').val($('.renaming span').html()); + $('.renaming .input_rename').select(); + }); + $('.folder_container').on('focusout keyup', '.renaming .input_rename', function (e) { + if (e.type == "focusout" || e.type == "keyup" && e.keyCode == 13) { + var libelle = $(this).val(); + var dossier_id = $(this).parents(".dd3-item").attr("data-id"); + var span = $(this).next(); + var input = $(this); + $.ajax({ + url: '/ajax/rename-folder', + method: 'POST', + dataType: 'json', + data: { + dossier_id: dossier_id, + libelle: libelle + }, + success: function success(result) { + if (result == true) { + span.html(input.val()); + } else { + $.fancyMessage({ + title: "Attention", + message: "Le dossier n'a pas été renommé. Merci d'actualiser la page.", + type: "error" + }); + } + + $(".renaming").removeClass('renaming'); + }, + error: function error(jqXHR, textStatus, errorThrown) { + $(".renaming").removeClass('renaming'); + $.fancyMessage({ + title: "Attention", + message: "Le dossier n'a pas été renommé. Merci d'actualiser la page.", + type: "error" + }); + } + }); + } + }); // ---- Gestion des média : propriétés d'un dossier + + $(".folder_menu").on('click', '.propertyItem', function (event) { + event.preventDefault(); + $(".folder_container .folder_menu").hide(); + var dossier_id = $(this).parents(".folder_menu").attr("data-id"); + $.ajax({ + url: '/ajax/get-folder-property', + method: 'POST', + dataType: 'json', + data: { + dossier_id: dossier_id + }, + success: function success(result) { + var dossier = result.data; + $.fancybox.open({ + src: '#form_folder_property', + type: 'inline', + opts: { + animationDuration: 350, + animationEffect: 'material', + beforeShow: function beforeShow(instance, current) { + if (dossier.parent_id === null) { + $(".form_folder_save").hide(); + } else { + $(".form_folder_save").show(); + } + + var date = new Date(dossier.created_at); + $(".form_folder_datecreate").html(date.toLocaleDateString('fr-FR', { + 'hour': '2-digit', + 'minute': '2-digit' + })); + $("#form_folder_property").attr("data-id", dossier_id); + $(".form_folder_libelle").val(dossier.libelle); + $(".form_folder_description").val(dossier.description); + } + } + }); + } + }); + }); // ---- Gestion des média : enregistre les propriétés d'un dossier + + $("html").on('click', '.form_folder_save', function (event) { + event.preventDefault(); + var dossier_id = $("#form_folder_property").attr("data-id"); + var libelle = $(".form_folder_libelle").val(); + var description = $(".form_folder_description").val(); + $.ajax({ + url: '/ajax/save-folder-property', + method: 'POST', + dataType: 'json', + data: { + dossier_id: dossier_id, + libelle: libelle, + description: description + } + }); + }); // ---- Gestion des média : au début du drag, set les valeurs des éléments draggés + + $("html").on("dragstart", ".imageItem", function (event) { + var datavalue = []; + + if ($(this).attr("aria-grabbed") == "true") { + $(".imageItem").each(function (index, el) { + if ($(this).attr("aria-grabbed") == "true") { + datavalue.push($(this).attr("data-id")); + } + }); + event.originalEvent.dataTransfer.setData('Text', datavalue); + } else { + $(".imageItem").attr("aria-grabbed", "false"); + $(this).attr("aria-grabbed", "true"); + event.originalEvent.dataTransfer.setData('Text', $(this).attr("data-id")); + } + }); // ---- Gestion des média : déselectionne les éléments si on clique en dehors + + $(".main_content").on("click", function (event) { + if (event.target !== this) return; + $(".imageItem").attr("aria-grabbed", "false"); + }); // ---- Gestion des média : gère la sélection des éléments + + var lastSelected; + $("html").on("click", ".imageItem", function (event) { + event.preventDefault(); + + if (event.ctrlKey) { + if ($(this).attr("aria-grabbed") == "true") { + $(this).attr("aria-grabbed", "false"); + } else { + $(this).attr("aria-grabbed", "true"); + } + + lastSelected = $(this); + } else if (event.shiftKey) { + var select; + + if (lastSelected == null) { + lastSelected = $(this); + select = true; + } else { + select = lastSelected.attr("aria-grabbed"); + } + + $(".imageItem").attr("aria-grabbed", "false"); + var imageItem = $(".imageItem"); + var last = imageItem.index(lastSelected); + var first = imageItem.index($(this)); + var start = Math.min(first, last); + var end = Math.max(first, last); + + for (var i = start; i <= end; i++) { + imageItem.eq(i).attr("aria-grabbed", select); + } + } else { + $(".imageItem").attr("aria-grabbed", "false"); + + if ($(this).attr("aria-grabbed") == "true") { + $(this).attr("aria-grabbed", "false"); + } else { + $(this).attr("aria-grabbed", "true"); + } + + lastSelected = $(this); + } + }); // ---- Gestion des média : affichage des dossiers on draghover + + $(".folder_container").on("dragover", ".dd3-content, .root_folder", function (event) { + event.preventDefault(); + event.stopPropagation(); + $(".folder_container .dd3-content").removeClass('dragged'); + $(".folder_container .root_folder").removeClass('dragged'); + $(this).addClass('dragged'); + }); // ---- Gestion des média : affichage des dossiers on dragleave + + $(".folder_container").on("dragleave", ".dd3-content, .root_folder", function (event) { + event.preventDefault(); + event.stopPropagation(); + $(".folder_container .dd3-content").removeClass('dragged'); + $(".folder_container .root_folder").removeClass('dragged'); + }); // ---- Gestion des média : evt lorsque l'on drop des élements dans un dossier + + $(".folder_container").on("drop", ".dd3-content, .root_folder", function (event) { + event.preventDefault(); + event.stopPropagation(); + $(".folder_container .dd3-content").removeClass('dragged'); + $(".folder_container .root_folder").removeClass('dragged'); // ---- Cible + + if ($(this).hasClass("root_folder")) { + var id = $(this).attr("data-id"); + } else { + var id = $(this).parent("li").attr("data-id"); + } + + console.log("Dossier cible id n°" + id); // ---- source + + var data = event.originalEvent.dataTransfer.getData("Text"); + console.log("Id des éléments sources " + data); + }); +}); // ---- Gestion des média : init des dossiers + +function initFolderManager(sujetId) { + $(".folder_container .loader").show(); + $.ajaxSetup({ + headers: { + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') + } + }); + $.ajax({ + url: '/ajax/load-folder', + method: 'POST', + dataType: 'json', + data: { + sujetId: sujetId + }, + success: function success(result) { + var output = ''; + var draggable = result.draggable; + var data = result.data; + var total = result.count; + $(".root_folder .count").html(total); + $.each(data, function (index, item) { + output += buildItem(item); + }); + $('.folder_container .dd .dd-list').html(output); + $('.dd').nestable({ + scroll: true, + onDragStart: function onDragStart(l, e) { + if ($(e).hasClass("parent")) { + // pour empêcher le déplacement des dossiers parents + return false; + } + + return draggable; + }, + beforeDragStop: function beforeDragStop(l, e, p) { + // l is the main container, e is the element that was moved, p is the place where element was moved. + if ($(p).hasClass('root')) { + $.fancyMessage({ + title: "Attention", + message: "Vous ne pouvez pas déplacer un dossier à la racine.", + type: "error" + }); + return false; + } + + var r = confirm("Etes-vous sûr d'appliquer ce déplacement ?"); + + if (r == true) { + var dossier_id = $(e).attr("data-id"); + var parent_id = $(p).parent("li").attr("data-id"); + $(".folder_container .loader").show(); + $.ajax({ + url: '/ajax/move-folder', + method: 'POST', + dataType: 'json', + data: { + parent_id: parent_id, + dossier_id: dossier_id + }, + success: function success(result) { + $(".folder_container .loader").hide(); + }, + error: function error(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({ + title: "Attention", + message: "Erreur lors du déplacement du dossier. Merci d'actualiser la page.", + type: "error" + }); + } + }); + } else { + return false; + } + } + }); + $('.dd').nestable('collapseAll'); + $(".folder_container .dd-empty").remove(); + $(".folder_container .loader").hide(); //---- Chargement des médias + + var currentFolder = $(".currentFolder").val(); + loadMedia(currentFolder); + }, + error: function error(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({ + title: "Attention", + message: "Erreur lors du chargement des dossiers. Merci d'actualiser la page.", + type: "error" + }); + } + }); +} + +function loadMedia(dossier_id) { + $(".media_container .loader").show(); + $.ajax({ + url: '/ajax/load-media', + method: 'POST', + dataType: 'json', + data: { + dossier_id: dossier_id + }, + success: function success(result) { + $(".folder_container .loader").hide(); + }, + error: function error(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({ + title: "Attention", + message: "Erreur lors du déplacement du dossier. Merci d'actualiser la page.", + type: "error" + }); + } + }); +} // ---- Gestion des média : contruction de l'arborescence des dossiers + + +function buildItem(item) { + var parentClass = ""; + var handleClass = ""; + var favClass = "fal"; + + if (item.parent_id === null) { + parentClass = "parent"; + handleClass = "no-handle"; + } + + if (item.favoris == true) { + favClass = "fas"; + } + + var html = "
  • "; + html += "
    "; + html += "
    " + item.libelle + "
    " + item.mediacount + "
    "; + + if (item.sousdossiers.length) { + html += "
      "; + $.each(item.sousdossiers, function (index, sub) { + html += buildItem(sub); + }); + html += "
    "; + } + + html += "
  • "; + return html; +} // ---- Gestion des média : ajouter un dossier + + +function addItem(parent_id, item_id, content) { + if (!$('.dd .dd-item[data-id="' + parent_id + '"] > ol').length) { + $('.dd .dd-item[data-id="' + parent_id + '"]').append("
      "); + $('.dd .dd-item[data-id="' + parent_id + '"]').prepend(""); + } + + var html = "
    1. "; + html += "
      "; + html += "
      " + content + "
      0
    2. "; + $('.dd .dd-item[data-id="' + parent_id + '"] > ol').append(html); +} + +/***/ }), + /***/ "./resources/sass/app.scss": /*!*********************************!*\ !*** ./resources/sass/app.scss ***! @@ -11048,14 +11621,15 @@ $(".form_contact_send").on('click', function (event) { /***/ }), /***/ 0: -/*!*************************************************************************************!*\ - !*** multi ./resources/js/app.js ./resources/js/admin.js ./resources/sass/app.scss ***! - \*************************************************************************************/ +/*!*************************************************************************************************************!*\ + !*** multi ./resources/js/app.js ./resources/js/admin.js ./resources/js/media.js ./resources/sass/app.scss ***! + \*************************************************************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(/*! D:\sources\www\ldc-dam\resources\js\app.js */"./resources/js/app.js"); __webpack_require__(/*! D:\sources\www\ldc-dam\resources\js\admin.js */"./resources/js/admin.js"); +__webpack_require__(/*! D:\sources\www\ldc-dam\resources\js\media.js */"./resources/js/media.js"); module.exports = __webpack_require__(/*! D:\sources\www\ldc-dam\resources\sass\app.scss */"./resources/sass/app.scss"); diff --git a/public/js/jquery.nestable.min.js b/public/js/jquery.nestable.min.js new file mode 100644 index 0000000..0bc32ca --- /dev/null +++ b/public/js/jquery.nestable.min.js @@ -0,0 +1 @@ +!function(t,e,s,i){function o(e,o){this.w=t(s),this.el=t(e),(o=o||a).rootClass!==i&&"dd"!==o.rootClass&&(o.listClass=o.listClass?o.listClass:o.rootClass+"-list",o.itemClass=o.itemClass?o.itemClass:o.rootClass+"-item",o.dragClass=o.dragClass?o.dragClass:o.rootClass+"-dragel",o.handleClass=o.handleClass?o.handleClass:o.rootClass+"-handle",o.collapsedClass=o.collapsedClass?o.collapsedClass:o.rootClass+"-collapsed",o.placeClass=o.placeClass?o.placeClass:o.rootClass+"-placeholder",o.noDragClass=o.noDragClass?o.noDragClass:o.rootClass+"-nodrag",o.noChildrenClass=o.noChildrenClass?o.noChildrenClass:o.rootClass+"-nochildren",o.emptyClass=o.emptyClass?o.emptyClass:o.rootClass+"-empty"),this.options=t.extend({},a,o),this.options.json!==i&&this._build(),this.init()}var n="ontouchstart"in s,l=function(){var t=s.createElement("div"),i=s.documentElement;if(!("pointerEvents"in t.style))return!1;t.style.pointerEvents="auto",t.style.pointerEvents="x",i.appendChild(t);var o=e.getComputedStyle&&"auto"===e.getComputedStyle(t,"").pointerEvents;return i.removeChild(t),!!o}(),a={contentCallback:function(t){return t.content?t.content:t.id},listNodeName:"ol",itemNodeName:"li",handleNodeName:"div",contentNodeName:"span",rootClass:"dd",listClass:"dd-list",itemClass:"dd-item",dragClass:"dd-dragel",handleClass:"dd-handle",contentClass:"dd-content",collapsedClass:"dd-collapsed",placeClass:"dd-placeholder",noDragClass:"dd-nodrag",noChildrenClass:"dd-nochildren",emptyClass:"dd-empty",expandBtnHTML:'',collapseBtnHTML:'',group:0,maxDepth:5,threshold:20,fixedDepth:!1,fixed:!1,includeContent:!1,scroll:!1,scrollSensitivity:1,scrollSpeed:5,scrollTriggers:{top:40,left:40,right:-40,bottom:-40},effect:{animation:"none",time:"slow"},callback:function(t,e,s){},onDragStart:function(t,e,s){},beforeDragStop:function(t,e,s){},listRenderer:function(t,e){var s="<"+e.listNodeName+' class="'+e.listClass+'">';return s+=t,s+=""},itemRenderer:function(e,s,i,o,n){var l=t.map(e,function(t,e){return" "+e+'="'+t+'"'}).join(" "),a="<"+o.itemNodeName+l+">";return a+="<"+o.handleNodeName+' class="'+o.handleClass+'">',a+="<"+o.contentNodeName+' class="'+o.contentClass+'">',a+=s,a+="",a+="",a+=i,a+=""}};o.prototype={init:function(){var s=this;s.reset(),s.el.data("nestable-group",this.options.group),s.placeEl=t('
      ');var i=this.el.find(s.options.itemNodeName);t.each(i,function(e,i){var o=t(i),n=o.parent();s.setParent(o),n.hasClass(s.options.collapsedClass)&&s.collapseItem(n.parent())}),i.length||this.appendEmptyElement(this.el),s.el.on("click","button",function(e){if(!s.dragEl){var i=t(e.currentTarget),o=i.data("action"),n=i.parents(s.options.itemNodeName).eq(0);"collapse"===o&&s.collapseItem(n),"expand"===o&&s.expandItem(n)}});var o=function(e){var i=t(e.target);if(!i.hasClass(s.options.handleClass)){if(i.closest("."+s.options.noDragClass).length)return;i=i.closest("."+s.options.handleClass)}i.length&&!s.dragEl&&(s.isTouch=/^touch/.test(e.type),s.isTouch&&1!==e.touches.length||(e.preventDefault(),s.dragStart(e.touches?e.touches[0]:e)))},l=function(t){s.dragEl&&(t.preventDefault(),s.dragMove(t.touches?t.touches[0]:t))},a=function(t){s.dragEl&&(t.preventDefault(),s.dragStop(t.touches?t.changedTouches[0]:t))};n&&(s.el[0].addEventListener("touchstart",o,!1),e.addEventListener("touchmove",l,!1),e.addEventListener("touchend",a,!1),e.addEventListener("touchcancel",a,!1)),s.el.on("mousedown",o),s.w.on("mousemove",l),s.w.on("mouseup",a);s.el.bind("destroy-nestable",function(){n&&(s.el[0].removeEventListener("touchstart",o,!1),e.removeEventListener("touchmove",l,!1),e.removeEventListener("touchend",a,!1),e.removeEventListener("touchcancel",a,!1)),s.el.off("mousedown",o),s.w.off("mousemove",l),s.w.off("mouseup",a),s.el.off("click"),s.el.unbind("destroy-nestable"),s.el.data("nestable",null)})},destroy:function(){this.el.trigger("destroy-nestable")},add:function(e){var s="."+this.options.listClass,o=t(this.el).children(s);e.parent_id!==i&&(o=o.find('[data-id="'+e.parent_id+'"]'),delete e.parent_id,0===o.children(s).length&&(o=o.append(this.options.listRenderer("",this.options))),o=o.find(s+":first"),this.setParent(o.parent())),o.append(this._buildItem(e,this.options))},replace:function(t){var e=this._buildItem(t,this.options);this._getItemById(t.id).replaceWith(e)},removeItem:function(e){var s=this.options,i=this.el;(e=e||this).remove();var o="."+s.listClass+" ."+s.listClass+":not(:has(*))";t(i).find(o).remove();t(i).find('[data-action="expand"], [data-action="collapse"]').each(function(){0===t(this).siblings("."+s.listClass).length&&t(this).remove()})},remove:function(t,e){var s=this.options,i=this,o=this._getItemById(t),n=s.effect.animation||"fade",l=s.effect.time||"slow";"fade"===n?o.fadeOut(l,function(){i.removeItem(o)}):this.removeItem(o),e&&e()},removeAll:function(e){function s(){l.each(function(){i.removeItem(t(this))}),n.show(),e&&e()}var i=this,o=this.options,n=i.el.find(o.listNodeName).first(),l=n.children(o.itemNodeName),a=o.effect.animation||"fade",r=o.effect.time||"slow";"fade"===a?n.fadeOut(r,s):s()},_getItemById:function(e){return t(this.el).children("."+this.options.listClass).find('[data-id="'+e+'"]')},_build:function(){var e=this.options.json;"string"==typeof e&&(e=JSON.parse(e)),t(this.el).html(this._buildList(e,this.options))},_buildList:function(e,s){if(!e)return"";var i="",o=this;return t.each(e,function(t,e){i+=o._buildItem(e,s)}),s.listRenderer(i,s)},_buildItem:function(e,s){function i(t){var e={"&":"&","<":"<",">":">",'"':""","'":"'"};return t+"".replace(/[&<>"']/g,function(t){return e[t]})}function o(t){var e={};for(var s in t)e[t[s]]=t[s];return e}var n=function(e){delete(e=t.extend({},e)).children,delete e.classes,delete e.content;var s={};return t.each(e,function(t,e){"object"==typeof e&&(e=JSON.stringify(e)),s["data-"+t]=i(e)}),s}(e);n.class=function(e,s){var i=e.classes||{};"string"==typeof i&&(i=[i]);var n=o(i);return n[s.itemClass]=s.itemClass,t.map(n,function(t){return t}).join(" ")}(e,s);var l=s.contentCallback(e),a=this._buildList(e.children,s),r=t(s.itemRenderer(n,l,a,s,e));return this.setParent(r),r[0].outerHTML},serialize:function(){var e=this,s=function(i){var o=[];return i.children(e.options.itemNodeName).each(function(){var i=t(this),n=t.extend({},i.data()),l=i.children(e.options.listNodeName);if(e.options.includeContent){var a=i.find("."+e.options.contentClass).html();a&&(n.content=a)}l.length&&(n.children=s(l)),o.push(n)}),o};return s(e.el.find(e.options.listNodeName).first())},asNestedSet:function(){function e(i,l,a){var r,d,h=a+1;return t(i).children(o.listNodeName).children(o.itemNodeName).length>0&&(l++,t(i).children(o.listNodeName).children(o.itemNodeName).each(function(){h=e(t(this),l,h)}),l--),r=t(i).attr("data-id"),s(r)&&(r=parseInt(r)),d=t(i).parent(o.listNodeName).parent(o.itemNodeName).attr("data-id")||"",s(d)&&(r=parseInt(d)),r&&n.push({id:r,parent_id:d,depth:l,lft:a,rgt:h}),a=h+1}function s(e){return t.isNumeric(e)&&Math.floor(e)==e}var i=this,o=i.options,n=[],l=1;return i.el.find(o.listNodeName).first().children(o.itemNodeName).each(function(){l=e(this,0,l)}),n=n.sort(function(t,e){return t.lft-e.lft})},returnOptions:function(){return this.options},serialise:function(){return this.serialize()},toHierarchy:function(e){function s(e){var o=(t(e).attr(i.attribute||"id")||"").match(i.expression||/(.+)[-=_](.+)/);if(o){var n={id:o[2]};return t(e).children(i.listType).children(i.items).length>0&&(n.children=[],t(e).children(i.listType).children(i.items).each(function(){var t=s(this);n.children.push(t)})),n}}var i=t.extend({},this.options,e),o=[];return t(this.element).children(i.items).each(function(){var t=s(this);o.push(t)}),o},toArray:function(){function e(n,l,a){var r,d,h=a+1;return n.children(s.options.listNodeName).children(s.options.itemNodeName).length>0&&(l++,n.children(s.options.listNodeName).children(s.options.itemNodeName).each(function(){h=e(t(this),l,h)}),l--),r=n.data().id,d=l===i+1?s.rootID:n.parent(s.options.listNodeName).parent(s.options.itemNodeName).data().id,r&&o.push({id:r,parent_id:d,depth:l,left:a,right:h}),a=h+1}var s=t.extend({},this.options,this),i=s.startDepthCount||0,o=[],n=2,l=this;return l.el.find(l.options.listNodeName).first().children(l.options.itemNodeName).each(function(){n=e(t(this),i+1,n)}),o=o.sort(function(t,e){return t.left-e.left})},reset:function(){this.mouse={offsetX:0,offsetY:0,startX:0,startY:0,lastX:0,lastY:0,nowX:0,nowY:0,distX:0,distY:0,dirAx:0,dirX:0,dirY:0,lastDirX:0,lastDirY:0,distAxX:0,distAxY:0},this.isTouch=!1,this.moving=!1,this.dragEl=null,this.dragRootEl=null,this.dragDepth=0,this.hasNewRoot=!1,this.pointEl=null},expandItem:function(t){t.removeClass(this.options.collapsedClass)},collapseItem:function(t){t.children(this.options.listNodeName).length&&t.addClass(this.options.collapsedClass)},expandAll:function(){var e=this;e.el.find(e.options.itemNodeName).each(function(){e.expandItem(t(this))})},collapseAll:function(){var e=this;e.el.find(e.options.itemNodeName).each(function(){e.collapseItem(t(this))})},setParent:function(e){e.is(this.options.itemNodeName)&&e.children(this.options.listNodeName).length&&(e.children("[data-action]").remove(),e.prepend(t(this.options.expandBtnHTML)),e.prepend(t(this.options.collapseBtnHTML)))},unsetParent:function(t){t.removeClass(this.options.collapsedClass),t.children("[data-action]").remove(),t.children(this.options.listNodeName).remove()},dragStart:function(e){var i=this.mouse,o=t(e.target).closest(this.options.itemNodeName),n={top:e.pageY,left:e.pageX},l=this.options.onDragStart.call(this,this.el,o,n);if(void 0===l||!1!==l){this.placeEl.css("height",o.height()),i.offsetX=e.pageX-o.offset().left,i.offsetY=e.pageY-o.offset().top,i.startX=i.lastX=e.pageX,i.startY=i.lastY=e.pageY,this.dragRootEl=this.el,this.dragEl=t(s.createElement(this.options.listNodeName)).addClass(this.options.listClass+" "+this.options.dragClass),this.dragEl.css("width",o.outerWidth()),this.setIndexOfItem(o),o.after(this.placeEl),o[0].parentNode.removeChild(o[0]),o.appendTo(this.dragEl),t(s.body).append(this.dragEl),this.dragEl.css({left:e.pageX-i.offsetX,top:e.pageY-i.offsetY});var a,r,d=this.dragEl.find(this.options.itemNodeName);for(a=0;athis.dragDepth&&(this.dragDepth=r)}},createSubLevel:function(e,s){var i=t("<"+this.options.listNodeName+"/>").addClass(this.options.listClass);return s&&i.append(s),e.append(i),this.setParent(e),i},setIndexOfItem:function(e,s){(s=s||[]).unshift(e.index()),t(e[0].parentNode)[0]!==this.dragRootEl[0]?this.setIndexOfItem(t(e[0].parentNode),s):this.dragEl.data("indexOfItem",s)},restoreItemAtIndex:function(e,s){for(var i=this.el,o=s.length-1,n=0;n0?1:-1,d.dirY=0===d.distY?0:d.distY>0?1:-1;var h=Math.abs(d.distX)>Math.abs(d.distY)?1:0;if(!d.moving)return d.dirAx=h,void(d.moving=!0);if(r.scroll)if(void 0!==e.jQuery.fn.scrollParent){var c=!1,p=this.el.scrollParent()[0];p!==s&&"HTML"!==p.tagName?(r.scrollTriggers.bottom+p.offsetHeight-i.pageY=r.threshold&&(d.distAxX=0,a=this.placeEl.prev(r.itemNodeName),d.distX>0&&a.length&&!a.hasClass(r.collapsedClass)&&!a.hasClass(r.noChildrenClass)&&(o=a.find(r.listNodeName).last(),this.placeEl.parents(r.listNodeName).length+this.dragDepth<=r.maxDepth&&(o.length?(o=a.children(r.listNodeName).last()).append(this.placeEl):this.createSubLevel(a,this.placeEl))),d.distX<0&&(this.placeEl.next(r.itemNodeName).length||(n=this.placeEl.parent(),this.placeEl.closest(r.itemNodeName).after(this.placeEl),n.children().length||this.unsetParent(n.parent()))));var f=!1;if(l||(this.dragEl[0].style.visibility="hidden"),this.pointEl=t(s.elementFromPoint(i.pageX-s.body.scrollLeft,i.pageY-(e.pageYOffset||s.documentElement.scrollTop))),l||(this.dragEl[0].style.visibility="visible"),this.pointEl.hasClass(r.handleClass)&&(this.pointEl=this.pointEl.closest(r.itemNodeName)),this.pointEl.hasClass(r.emptyClass))f=!0;else if(!this.pointEl.length||!this.pointEl.hasClass(r.itemClass))return;var u=this.pointEl.closest("."+r.rootClass),m=this.dragRootEl.data("nestable-id")!==u.data("nestable-id");if(!d.dirAx||m||f){if(m&&r.group!==u.data("nestable-group"))return;if(this.options.fixedDepth&&this.dragDepth+1!==this.pointEl.parents(r.listNodeName).length)return;if(this.dragDepth-1+this.pointEl.parents(r.listNodeName).length>r.maxDepth)return;var g=i.pageY')}},t.fn.nestable=function(s){var i=this,n=this,l=arguments;return"Nestable"in e||(e.Nestable={},Nestable.counter=0),i.each(function(){var e=t(this).data("nestable");if(e){if("string"==typeof s&&"function"==typeof e[s])if(l.length>1){for(var i=[],a=1;a= 5){ + $.fancyMessage({title : "Attention", message : "Vous ne pouvez pas créer plus de 5 niveaux de sous-dossiers.", type : "info"}); + $(".folder_container .loader").hide(); + return false; + } + + + $.ajax({ + url: '/ajax/add-folder', + method: 'POST', + dataType : 'json', + data: { + parent_id: parent_id, + libelle: 'Nouveau dossier', + }, + success: function(result){ + addItem(parent_id, result.folder_id, 'Nouveau dossier'); + $(".folder_container .loader").hide(); + }, + error: function(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({title : "Attention", message : "Erreur lors de l'ajout du dossier. Merci d'actualiser la page.", type : "error"}); + } + }); + }); + + // ---- Gestion des média : supprimer un dossier + $(".folder_menu").on('click', '.removeItem', function(event) { + event.preventDefault(); + var dossier_id = $(this).parents(".folder_menu").attr("data-id"); + $(".folder_container .folder_menu").hide(); + $(".folder_container .loader").show(); + + if(!$('.dd .dd-item[data-id="'+dossier_id+'"] > ol').length){ + $.ajax({ + url: '/ajax/remove-folder', + method: 'POST', + dataType : 'json', + data: { + dossier_id: dossier_id, + }, + success: function(result){ + // supprimer dossier + if(result == true){ + $('.dd').nestable('remove', dossier_id); + }else{ + $.fancyMessage({title : "Attention", message : "Erreur lors de la suppression du dossier. Merci d'actualiser la page.", type : "error"}); + } + $(".folder_container .loader").hide(); + }, + error: function(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({title : "Attention", message : "Erreur lors de la suppression du dossier. Merci d'actualiser la page.", type : "error"}); + } + }); + }else{ + $(".folder_container .loader").hide(); + $.fancyMessage({title : "Suppresion impossible", message : "Pour supprimer un dossier, vous devez d'abord vider son contenu (médias et sous-dossiers).", type : "error"}); + } + }); + + // ---- Gestion des média : renommer un dossier + $(".folder_menu").on('click', '.renameItem', function(event) { + event.preventDefault(); + $(".folder_container .folder_menu").hide(); + var dossier_id = $(this).parents(".folder_menu").attr("data-id"); + $('.dd .dd-item[data-id="'+dossier_id+'"] > .dd3-content').addClass('renaming'); + $('.renaming .input_rename').val($('.renaming span').html()); + $('.renaming .input_rename').select(); + }); + + $('.folder_container').on('focusout keyup', '.renaming .input_rename', function (e) { + if(e.type == "focusout" || (e.type == "keyup" && e.keyCode == 13)){ + + var libelle = $(this).val(); + var dossier_id = $(this).parents(".dd3-item").attr("data-id"); + var span = $(this).next(); + var input = $(this); + $.ajax({ + url: '/ajax/rename-folder', + method: 'POST', + dataType : 'json', + data: { + dossier_id: dossier_id, + libelle: libelle, + }, + success: function(result){ + if(result == true){ + span.html(input.val()); + }else{ + $.fancyMessage({title : "Attention", message : "Le dossier n'a pas été renommé. Merci d'actualiser la page.", type : "error"}); + } + $(".renaming").removeClass('renaming'); + }, + error: function(jqXHR, textStatus, errorThrown) { + $(".renaming").removeClass('renaming'); + $.fancyMessage({title : "Attention", message : "Le dossier n'a pas été renommé. Merci d'actualiser la page.", type : "error"}); + } + }); + } + }); + + // ---- Gestion des média : propriétés d'un dossier + $(".folder_menu").on('click', '.propertyItem', function(event) { + event.preventDefault(); + $(".folder_container .folder_menu").hide(); + var dossier_id = $(this).parents(".folder_menu").attr("data-id"); + + $.ajax({ + url: '/ajax/get-folder-property', + method: 'POST', + dataType : 'json', + data: { + dossier_id: dossier_id, + }, + success: function(result){ + var dossier = result.data; + $.fancybox.open({ + src : '#form_folder_property', + type : 'inline', + opts : { + animationDuration : 350, + animationEffect : 'material', + beforeShow : function( instance, current ) { + if(dossier.parent_id=== null){ + $(".form_folder_save").hide(); + }else{ + $(".form_folder_save").show(); + } + var date = new Date(dossier.created_at); + $(".form_folder_datecreate").html(date.toLocaleDateString('fr-FR', {'hour': '2-digit', 'minute': '2-digit'} )); + $("#form_folder_property").attr("data-id", dossier_id); + $(".form_folder_libelle").val(dossier.libelle); + $(".form_folder_description").val(dossier.description); + } + } + }); + } + }); + }); + + // ---- Gestion des média : enregistre les propriétés d'un dossier + $("html").on('click', '.form_folder_save', function(event) { + event.preventDefault(); + + var dossier_id = $("#form_folder_property").attr("data-id"); + var libelle = $(".form_folder_libelle").val(); + var description = $(".form_folder_description").val(); + + $.ajax({ + url: '/ajax/save-folder-property', + method: 'POST', + dataType : 'json', + data: { + dossier_id: dossier_id, + libelle: libelle, + description: description, + } + }); + }); + + + // ---- Gestion des média : au début du drag, set les valeurs des éléments draggés + $("html").on("dragstart", ".imageItem", function(event) { + var datavalue = []; + if($(this).attr("aria-grabbed") == "true"){ + $(".imageItem").each(function(index, el) { + if($(this).attr("aria-grabbed") == "true"){ + datavalue.push($(this).attr("data-id")); + } + }); + event.originalEvent.dataTransfer.setData('Text', datavalue); + }else{ + $(".imageItem").attr("aria-grabbed", "false"); + $(this).attr("aria-grabbed", "true"); + event.originalEvent.dataTransfer.setData('Text', $(this).attr("data-id")); + } + }); + + // ---- Gestion des média : déselectionne les éléments si on clique en dehors + $(".main_content").on("click", function(event) { + if (event.target !== this) return; + $(".imageItem").attr("aria-grabbed", "false"); + }); + + // ---- Gestion des média : gère la sélection des éléments + var lastSelected ; + $("html").on("click", ".imageItem", function(event) { + event.preventDefault(); + if(event.ctrlKey){ + if($(this).attr("aria-grabbed") == "true"){ + $(this).attr("aria-grabbed", "false"); + }else{ + $(this).attr("aria-grabbed", "true"); + } + lastSelected = $(this); + }else if(event.shiftKey){ + var select; + if(lastSelected == null){ + lastSelected = $(this); + select = true + }else{ + select = lastSelected.attr("aria-grabbed"); + } + + $(".imageItem").attr("aria-grabbed", "false"); + var imageItem = $(".imageItem"); + var last = imageItem.index(lastSelected); + var first = imageItem.index( $(this)); + var start = Math.min(first, last); + var end = Math.max(first, last); + for (var i = start; i <= end; i++) { + imageItem.eq(i).attr("aria-grabbed", select); + } + }else{ + $(".imageItem").attr("aria-grabbed", "false"); + if($(this).attr("aria-grabbed") == "true"){ + $(this).attr("aria-grabbed", "false"); + }else{ + $(this).attr("aria-grabbed", "true"); + } + lastSelected = $(this); + } + + + }); + + // ---- Gestion des média : affichage des dossiers on draghover + $(".folder_container").on("dragover", ".dd3-content, .root_folder", function(event) { + event.preventDefault(); + event.stopPropagation(); + $(".folder_container .dd3-content").removeClass('dragged'); + $(".folder_container .root_folder").removeClass('dragged'); + $(this).addClass('dragged'); + }); + + // ---- Gestion des média : affichage des dossiers on dragleave + $(".folder_container").on("dragleave", ".dd3-content, .root_folder", function(event) { + event.preventDefault(); + event.stopPropagation(); + $(".folder_container .dd3-content").removeClass('dragged'); + $(".folder_container .root_folder").removeClass('dragged'); + }); + + // ---- Gestion des média : evt lorsque l'on drop des élements dans un dossier + $(".folder_container").on("drop", ".dd3-content, .root_folder", function(event) { + event.preventDefault(); + event.stopPropagation(); + $(".folder_container .dd3-content").removeClass('dragged'); + $(".folder_container .root_folder").removeClass('dragged'); + // ---- Cible + if($(this).hasClass("root_folder")){ + var id = $(this).attr("data-id"); + }else{ + var id = $(this).parent("li").attr("data-id"); + } + console.log("Dossier cible id n°"+id); + // ---- source + var data = event.originalEvent.dataTransfer.getData("Text"); + console.log("Id des éléments sources "+data); + }); + +}); + +// ---- Gestion des média : init des dossiers +function initFolderManager(sujetId){ + $(".folder_container .loader").show(); + $.ajaxSetup({ + headers: { + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') + } + }); + $.ajax({ + url: '/ajax/load-folder', + method: 'POST', + dataType : 'json', + data: { + sujetId: sujetId, + }, + success: function(result){ + var output = ''; + var draggable = result.draggable; + var data = result.data; + var total = result.count; + $(".root_folder .count").html(total); + + $.each(data, function (index, item) { + output += buildItem(item); + }); + $('.folder_container .dd .dd-list').html(output); + $('.dd').nestable({ + scroll: true, + onDragStart: function(l,e){ + if($(e).hasClass("parent")){ // pour empêcher le déplacement des dossiers parents + return false; + } + return draggable; + }, + beforeDragStop: function(l,e, p){ + // l is the main container, e is the element that was moved, p is the place where element was moved. + if($(p).hasClass('root')){ + $.fancyMessage({title : "Attention", message : "Vous ne pouvez pas déplacer un dossier à la racine.", type : "error"}); + return false; + } + var r = confirm("Etes-vous sûr d'appliquer ce déplacement ?"); + if (r == true) { + var dossier_id = $(e).attr("data-id"); + var parent_id = $(p).parent("li").attr("data-id"); + $(".folder_container .loader").show(); + $.ajax({ + url: '/ajax/move-folder', + method: 'POST', + dataType : 'json', + data: { + parent_id : parent_id, + dossier_id : dossier_id, + }, + success: function(result){ + $(".folder_container .loader").hide(); + }, + error: function(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({title : "Attention", message : "Erreur lors du déplacement du dossier. Merci d'actualiser la page.", type : "error"}); + } + }); + } else { + return false; + } + } + }); + $('.dd').nestable('collapseAll'); + $(".folder_container .dd-empty").remove(); + $(".folder_container .loader").hide(); + //---- Chargement des médias + var currentFolder = $(".currentFolder").val(); + loadMedia(currentFolder); + }, + error: function(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({title : "Attention", message : "Erreur lors du chargement des dossiers. Merci d'actualiser la page.", type : "error"}); + } + }); +} + +function loadMedia(dossier_id){ + $(".media_container .loader").show(); + $.ajax({ + url: '/ajax/load-media', + method: 'POST', + dataType : 'json', + data: { + dossier_id : dossier_id, + }, + success: function(result){ + $(".folder_container .loader").hide(); + }, + error: function(jqXHR, textStatus, errorThrown) { + $(".folder_container .loader").hide(); + $.fancyMessage({title : "Attention", message : "Erreur lors du déplacement du dossier. Merci d'actualiser la page.", type : "error"}); + } + }); +} + +// ---- Gestion des média : contruction de l'arborescence des dossiers +function buildItem(item) { + var parentClass = ""; + var handleClass = ""; + var favClass="fal"; + if(item.parent_id === null){ + parentClass="parent"; + handleClass= "no-handle"; + } + if(item.favoris == true){ + favClass="fas"; + } + + var html = "
    3. "; + html += "
      "; + html += "
      " + item.libelle + "
      " + item.mediacount + "
      "; + + if (item.sousdossiers.length) { + html += "
        "; + $.each(item.sousdossiers, function (index, sub) { + html += buildItem(sub); + }); + html += "
      "; + + } + html += "
    4. "; + return html; +} + +// ---- Gestion des média : ajouter un dossier +function addItem(parent_id, item_id, content){ + if(!$('.dd .dd-item[data-id="'+parent_id+'"] > ol').length){ + $('.dd .dd-item[data-id="'+parent_id+'"]').append("
        "); + $('.dd .dd-item[data-id="'+parent_id+'"]').prepend(""); + } + + var html = "
      1. "; + html += "
        "; + html += "
        " + content + "
        0
      2. "; + $('.dd .dd-item[data-id="'+parent_id+'"] > ol').append(html); +} diff --git a/resources/sass/app.scss b/resources/sass/app.scss index 7234022..40932fc 100644 --- a/resources/sass/app.scss +++ b/resources/sass/app.scss @@ -3,6 +3,7 @@ @import 'partials/app_variables.scss', 'partials/reset.scss', 'partials/animate.scss', +'partials/nestable.scss', 'partials/fontawesome/fontawesome.scss', 'partials/fontawesome/solid.scss', 'partials/fontawesome/regular.scss', diff --git a/resources/sass/partials/common.scss b/resources/sass/partials/common.scss index de500f0..29558aa 100644 --- a/resources/sass/partials/common.scss +++ b/resources/sass/partials/common.scss @@ -224,6 +224,50 @@ } } +#form_folder_property{ + padding: 30px; + min-width: 550px; + + h3{ + font-size: 14px; + margin-bottom: 12px; + font-weight: bold; + color: $white; + } + hr{ + color: #24272e; + border-bottom: 1px solid #2c2f36; + margin-bottom: 20px; + } + p.button_bar{ + text-align: right; + margin: 0; + } + select, input, textarea{ + width: 100%; + } + textarea{ + margin-bottom: 20px; + min-height: 200px; + } + .btn{ + margin-right: 10px; + } + .form_folder_save { + .fa-spinner-third{ + display: none; + } + &.loading{ + .fa-spinner-third{ + display: inline-block; + } + .fa-share{ + display: none; + } + } + } +} + /****************************************** TEMPLATE ******************************************/ @@ -290,7 +334,7 @@ transform: translate(-50%, -50%); position: absolute; text-align: center; - width: 560px; + width: 700px; h1{ color: $white; @@ -301,23 +345,102 @@ } .input_search{ margin-top: 20px; + display: flex; + flex-direction: row; position: relative; + &::before { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + border-radius: 3px; + box-shadow: inset 0 0 0 1px #dfdfdf; + content: ""; + z-index: 2; + } + input{ - width: 100%; + width: 66%; font-size: 17px; - padding: 12px 48px 12px 14px; + padding: 12px; + border-radius: 0; + color: #4a4a4a; + + &::placeholder{ + color: rgba(74,74,74,.4); + } } button{ border: none; - position: absolute; - right: 0; - background-color: transparent; - color: $grey2; + width: 8%; + background-color: $white; + border-radius: 0 3px 3px 0; + color: #374957; font-size: 25px; - padding: 8px 15px 8px 8px; + padding: 8px; cursor: pointer; + box-shadow: inset 0 0 0 1px #e3e3e3; + + &:hover{ + background-color: $blue; + color:$white; + } } + .select_container{ + width: 26%; + position: relative; + overflow: hidden; + + &::after { + /* Le pointeur du select */ + content: ''; + position: absolute; + top: 50%; + margin-top: -3px; + right: .75em; + display: block; + width: 0; height: 0; + border-color: transparent; + border-top-color: #444; + border-width: 5px; + border-style: solid; + pointer-events: none; + } + + &::before { + position: absolute; + top: 50%; + width: 1px; + height: 60%; + transform: translateY(-50%); + background-color: #dfdfdf; + content: ""; + right:0; + z-index: 10; + } + + select{ + position: relative; + appearance: none; + width: 110%; + height: auto; + color: #4a4a4a; + border: 0; + margin: 0; + padding: 14px 48px 14px 14px; + border-radius: 0; + overflow: hidden; + text-overflow: ellipsis; + /* + + border-radius: 3px 0 0 3px; + border-left: 1px solid #E1E1E1;*/ + } + } + } } diff --git a/resources/sass/partials/media.scss b/resources/sass/partials/media.scss index 2f7033c..a5f0546 100644 --- a/resources/sass/partials/media.scss +++ b/resources/sass/partials/media.scss @@ -1,11 +1,67 @@ .media_manager{ + height: calc(100% - 48px); + .main_content{ + height: 100%; + padding: 0; + + .media_container{ + overflow-y: auto; + overflow-x: hidden; + position: relative; + height: 100%; + + + .loader{ + position: sticky; + font-size: 20px; + color: $white; + width: 100%; + height: 100%; + background-color: rgba(0,0,0,0.5); + z-index: 50; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + top: 0; + } + + .imageItem{ + padding: 51px 20px; + margin: 30px 10px; + display: inline-block; + border: 1px solid grey; + + &[aria-grabbed="true"] { + background: #8ad; + color: #fff; + } + &:focus { + outline: none; + box-shadow: 0 0 0 2px #68b, inset 0 0 0 1px #ddd; + } + } + } + } + + + [draggable] { + user-select: none; + } .side_menu{ background-color: $grey; position: relative; width: 340px; + height: 100%; + transition: 0.3s ease-in-out; + + &.collapse{ + transform: translateX(-100%); + position: absolute; + } &::before{ content: ''; @@ -17,7 +73,8 @@ } header{ - padding-left: 12px; + padding: 12px; + position: relative; h1{ font-size: 19px; @@ -29,11 +86,99 @@ border-radius: 50%; } } + .close_side_menu{ + background-color: $grey; + position: absolute; + right: -17px; + top: 40px; + width: 17px; + height: 40px; + z-index: 2; + border-radius : 0 3px 3px 0; + border-top: 1px solid #505050; + border-right: 1px solid #505050; + border-bottom: 1px solid #505050; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + + } } .folder_container{ background-color: $grey3; - min-height: calc(100% - 77px); - overflow: auto; + height: calc(100% - 129px); + overflow-y: auto; + position: relative; + + .loader{ + position: absolute; + font-size: 20px; + color: $white; + width: 100%; + height: 100%; + background-color: rgba(0,0,0,0.5); + z-index: 50; + text-align: center; + i{ + margin-top: 232px; + } + } + .root_folder{ + color: white; + font-weight: bold; + padding: 9px 11px; + margin-top: 13px; + font-size: 12px; + + &:hover { + color: #2ea8e5; + } + + &.selected, &.dragged{ + color:$white; + background-color: #2ea8e5; + + &:hover { + color:$white; + } + } + .count{ + float: right; + display: inline; + background-color: $dark; + color: $grey2; + border-radius: 11px; + padding: 5px 8px; + position: relative; + top: -5px; + } + } + .folder_menu { + width: 140px; + box-shadow: 0 4px 5px 3px rgba(0, 0, 0, 0.2); + position: absolute; + display: none; + background-color: $grey3; + z-index: 1; + + .menu-options { + list-style: none; + padding: 10px 0; + + .menu-option { + font-weight: 500; + font-size: 13px; + padding: 10px; + cursor: pointer; + + &:hover { + background: rgba(0, 0, 0, 0.2); + } + } + } + } + } } diff --git a/resources/sass/partials/nestable.scss b/resources/sass/partials/nestable.scss new file mode 100644 index 0000000..d11a481 --- /dev/null +++ b/resources/sass/partials/nestable.scss @@ -0,0 +1,258 @@ +.dd { + position: relative; + display: block; + margin: 0; + padding: 0; + max-width: 600px; + list-style: none; + font-size: 13px; + line-height: 20px +} + +.dd-list { + display: block; + position: relative; + margin: 0; + padding: 0; + list-style: none +} + +.dd-list .dd-list { + padding-left: 30px +} + +.dd-empty, +.dd-item, +.dd-placeholder { + display: block; + position: relative; + margin: 0; + padding: 0; + min-height: 20px; + font-size: 12px; + line-height: 20px +} + +.dd-handle { + display: block; + height: 30px; + margin: 5px 0; + padding: 5px 10px; + color: $white; + text-decoration: none; + font-weight: 700; + border-radius: 3px; + box-sizing: border-box +} + +.dd-handle:hover { + color: #2ea8e5; +} + +.dd-item>button { + position: relative; + cursor: pointer; + float: left; + width: 11px; + height: 20px; + margin: 5px 0; + padding: 0; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + border: 0; + background: 0 0; + font-size: 12px; + line-height: 1; + text-align: center; + font-weight: 700 +} + +.dd-item>button:before { + display: block; + position: absolute; + width: 100%; + text-align: center; + text-indent: 0; + color: white; + font-family: "Font Awesome 5 Pro"; + font-weight: 900; + top: 3px; +} + +.dd-item>button.dd-expand:before { + content: '\f0da' +} + +.dd-item>button.dd-collapse:before { + content: '\f0d7' +} + +.dd-expand { + display: none +} + +.dd-collapsed .dd-collapse, +.dd-collapsed .dd-list { + display: none +} + +.dd-collapsed .dd-expand { + display: block +} + +.dd-empty, +.dd-placeholder { + margin: 0px 0; + padding: 0; + min-height: 30px; + background: $grey; + border: 1px dashed #b6bcbf; + box-sizing: border-box; + -moz-box-sizing: border-box +} + +.dd-empty { + border: 1px dashed #bbb; + min-height: 100px; + background-size: 60px 60px; + background-position: 0 0, 30px 30px +} + +.dd-dragel { + position: absolute; + pointer-events: none; + z-index: 9999 +} + +.dd-dragel>.dd-item .dd-handle { + margin-top: 0 +} + +.dd-dragel .dd-handle { + box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, .1) +} + +.dd-nochildren .dd-placeholder { + display: none +} + + + + + +/** +* Nestable Draggable Handles +*/ + +.dd3-content { + display: block; + height: 30px; + margin: 0; + padding: 5px 10px 5px 33px; + text-decoration: none; + color: $white; + -webkit-border-radius: 3px; + border-radius: 3px; + box-sizing: border-box; + -moz-box-sizing: border-box; + cursor: pointer; + user-select: none; + + .count{ + float: right; + display: inline; + background-color: $dark; + color: $grey2; + border-radius: 11px; + padding: 0px 8px; + margin-left: 5px; + } + i{ + color: $yellow; + float: right; + padding: 3px; + + &.fas{ + display: inline-block; + } + &.fal{ + display: none; + } + } + + &:hover { + background-color: rgba(46, 168, 229,0.2); + + i.fal{ + display: inline-block; + } + + } + &.selected, &.dragged{ + color:$white; + background-color: #2ea8e5; + + &:hover { + color:$white; + } + } + .input_rename{ + display: none; + width: 91%; + padding: 2px 1%; + border-radius: 1px; + } + +} + +.dd-dragel > .dd3-item > .dd3-content { + margin: 0; +} + +.dd3-content.renaming{ + .input_rename{ + display: inline-block; + } + span{ + display: none; + } +} + +.dd3-item > button { + margin-left: 27px; + margin-right: 3px; +} + +.dd3-handle { + position: absolute; + margin: 0; + left: 0; + top: 0; + cursor: move; + width: 30px; + text-indent: 30px; + white-space: nowrap; + overflow: hidden; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + + &.no-handle{ + cursor: default; + } +} + +.dd3-handle:before { + content: '\f07b'; + font-family: "Font Awesome 5 Pro"; + font-weight: 900; + display: block; + position: absolute; + left: 0; + top: 3px; + width: 100%; + text-align: center; + text-indent: 0; + color: $white; + font-size: 13px; +} diff --git a/resources/views/dossiers/create.blade.php b/resources/views/dossiers/create.blade.php index 3a17c3f..8f24f1a 100644 --- a/resources/views/dossiers/create.blade.php +++ b/resources/views/dossiers/create.blade.php @@ -40,7 +40,7 @@ @method('POST')
        {!! Form::label('libelle', 'Libellé') !!} - {!! Form::text('libelle', null, ['required']) !!} + {!! Form::text('libelle', null, ['required', 'maxlength' => '100' , 'minlength' => '4']) !!}
        {!! Form::label('description', 'Description') !!} diff --git a/resources/views/dossiers/edit.blade.php b/resources/views/dossiers/edit.blade.php index cb38e6f..eb2cb57 100644 --- a/resources/views/dossiers/edit.blade.php +++ b/resources/views/dossiers/edit.blade.php @@ -40,7 +40,7 @@ @method('PUT')
        {!! Form::label('libelle', 'Libellé') !!} - {!! Form::text('libelle', $dossier->libelle, ['required']) !!} + {!! Form::text('libelle', $dossier->libelle, ['required' , 'maxlength' => '100' , 'minlength' => '4']) !!}
        {!! Form::label('description', 'Description') !!} diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index 8826bb6..3129bf1 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -6,7 +6,12 @@

        Bienvenue

        diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 4b09925..7668400 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -34,7 +34,7 @@


        - EnvoyerAnnuler + EnvoyerAnnuler

        diff --git a/resources/views/media_manager.blade.php b/resources/views/media_manager.blade.php index d07cd16..4fd824e 100644 --- a/resources/views/media_manager.blade.php +++ b/resources/views/media_manager.blade.php @@ -5,12 +5,55 @@

        Gestion des médias

        + + +
        - + +
        + +
        + /racine +
        +
          +
        +
        -
        +
        + + Mon image + +
        + + +@endsection +@section('scripts') + @endsection diff --git a/routes/web.php b/routes/web.php index 0b8ad74..afaa23e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,7 +14,18 @@ Route::group(['middleware' => ['auth']], function(){ Route::get('/', 'CommunController@index')->name('home'); Route::post('/send-message', 'CommunController@sendMessage'); - Route::get('/gestion-des-medias', 'CommunController@media_manager')->name('media_manager'); + + Route::get('/gestion-des-medias', 'MediaController@index')->name('media_manager'); + Route::post('/ajax/load-folder', 'DossierController@loadFolder'); + Route::post('/ajax/add-folder', 'DossierController@addFolder'); + Route::post('/ajax/remove-folder', 'DossierController@removeFolder'); + Route::post('/ajax/move-folder', 'DossierController@moveFolder'); + Route::post('/ajax/rename-folder', 'DossierController@renameFolder'); + Route::post('/ajax/favoris-folder', 'UserController@favorisFolder'); + Route::post('/ajax/get-folder-property', 'DossierController@getFolderProperty'); + Route::post('/ajax/save-folder-property', 'DossierController@saveFolderProperty'); + Route::post('/ajax/load-media', 'MediaController@loadMedia'); + Route::resource('user', 'UserController'); Route::post('/check-matricule', 'UserController@checkMatricule'); Route::resource('dossier', 'DossierController'); diff --git a/webpack.mix.js b/webpack.mix.js index 4b8a101..150a773 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -13,6 +13,7 @@ const mix = require('laravel-mix'); mix.js([ 'resources/js/app.js', - 'resources/js/admin.js' + 'resources/js/admin.js', + 'resources/js/media.js' ], 'public/js/app.js') .sass('resources/sass/app.scss', 'public/css');