/* # Documentation API ## Instanciation ex: `` var document = new DocumentApi('#ma-div',options); document.load(); `` ## Informations document.currentFolder : dossier visualisé document.currentView : vue en cours document.selected : item sélectionné ## Panels ex: ``document.showPanel('tree');`` ``document.hidePanel('detail');`` * tree : arborescence de gauche * files : liste des fichiers * search : moteur de recherche * breadcrumb : fil d'arianne * detail : panel de détail fichier de droite ## Events ex: ``document.on('moved',function(data){ ... });`` * loaded : html de l'interface chargé * searched : recherche de fichiers {request, response} * renamed : renommage d'un élement {path ,old_label, label} * moved : déplacement d'un élements {from, to, response} * uploaded : upload d'un ou plusieurs fichiers {data}; * folder-created : dossier créé {path, folder, response} * selected : sélection d'un élement {element, path, type, id} * deleted : suppression d'un élement {element, response, path} * executed : execution d'un fichier {element, path}; * opened : ouverture d'un dossier {element, path}; * downloaded : téléchargement d'un élement {element, path}; * properties-showed : affichage des propriétés d'un élement {modal, id ; * right-saved : ajout d'un droit {uid, read, edit, recursive}; * right-deleted : suppression d'un droit {id,element}; * view-loaded : chargement d'une vue {view:view} ## Ajouter des bouttons au panel de détail ### ajout d'un boutton classique : ex: `` var document = new DocumentApi('#ma-div',options); document.options.panels.detail.buttons.push({ label : 'Custom button', buttonClass : 'btn-custom', lineClass : 'li-class-custom', icon : 'fas fa-times', }); document.load(); `` ### ajout d'un boutton pour les dossiers uniquement : ex: `` var document = new DocumentApi('#ma-div',options); document.options.panels.detail.buttons.push({ label : 'Custom button', buttonClass : 'btn-custom', lineClass : 'li-class-custom', icon : 'fas fa-times', visibility : ['directory'] }); document.load(); `` ### custom html : `` var document = new DocumentApi('#ma-div',options); document.options.panels.detail.buttons.push({ html : '
Mon htl custom ici
', }); document.load(); `` ## Ajouter des boutons à la creation d'elements var document = new DocumentApi('#ma-div',options); document.options.panels.search.buttons.push({ lineClass : 'create-txt-button', buttonClass : '', icon : 'fas fa-pen text-secondary', label : 'Créer un fichier CUSTOM' }); document.load(); ## Vues ### Changer la vue des fichiers `` var document = new DocumentApi('#ma-div',options); document.view('list'); document.load(); `` ou après chargement `` var document = new DocumentApi('#ma-div',options); document.load(); document.view('list'); `` Les vues par défaut sont : * list : affichage en liste classique * grid : affichage en grille ### Créer une vue custom `` var doc = new DocumentApi('#document-container',urlOptions); html = ''; doc.addView({ uid : 'custom', label : 'Vue personnalisée', icon : 'fas fa-th', html : html }); doc.view('custom'); doc.load(); `` nb : Le html de la vue doit contenir un élement racine contenant un élement enfant qui servira de model pour l'affichage fichier, cet element doit contenir les attributs et classes comme dans l'example suivant : `` `` Une ligne fichier peut contenir les tags suivants : * childNumber: nombre d'enfants (pour les dossiers uniquement) * created: timestamp de création ex : 1564997272 * creator: login du créateur ex : "admin" * extension: extention si fichier ex : "jpg" * id: id en base de données ex : 68 * label: libellé du fichier ex : "09.jpg" * path: chemin relative du fichier à partir de la racine des documents ex : "./09.jpg" * size: taille en octet ex : 533172 * sizeReadable: taille au format human readable ex : "520.68 ko" * thumbnail: chemin vers l'image d'apercu ex : "plugin/document/img/file-types/image.svg" * type: type d'élément (file ou directory) ex : "file" * updatedReadable : Date de derniere modification au format human readable ex : "Vendredi 02 Aout 2019 à 18:02" * updatedRelative: Date de derniere modification au format relatif ex : Dat "Il y a 2 jours" * updated: timestamp de la derniere modification * updater: login du dernier modifieur ## Récuperation de la vue courante document.currentView (string) ## Récuperation de l'élement en cours de sélection document.selected : {element,id,path,type} ## Autres options `` var document = new DocumentApi('#ma-div',options); document.options.rootLabel = 'D:'; document.load(); `` * rootLabel : Libellé de la racine * rightEdit : Activer l'edition * rightDelete : Activer la suppression des élements * rightPermission : Activer la gestion des permissions */ class DocumentApi { constructor(element,options) { this.onEvents = {}; this.currentView = 'list'; this.currentFolder = '.'; this.views = []; this.selected = null; this.isProcessing = false; this.dom = { container : $(element), panels : { tree : null, detail : null, search : null, breadcrumb : null, files : null } } this.options = { rootLabel : 'C:', root : '', rightEdit : true, rightDelete : true, rightPermission : true, panels : { detail : { visible : true, buttons : [] }, view : { visible : true, buttons : [] }, tree : { visible : true }, search : { visible : true, buttons : [] }, breadcrumb : { visible : true } }, actions : { template : 'document_load_template', element_search : 'document_element_search', folder_create : 'document_folder_create', element_rename : 'document_element_rename', element_delete : 'document_element_delete', element_move : 'document_element_move', element_share_edit : 'document_element_share_edit', element_preview : 'document_element_preview', element_execute : 'document_element_execute', element_upload : 'document_element_upload', element_edit : 'document_element_edit', element_save : 'document_element_save', properties_show : 'document_properties_show', right_search : 'document_right_search', right_save : 'document_right_save', right_delete : 'document_right_delete', } }; if(options) this.options = $.extend(this.options,options); } load(){ this.dom.container.html('Chargement...'); var element = this.element; var object = this; object.options.panels.detail.buttons.push({ buttonClass : 'btn-primary btn-download', icon : 'fas fa-arrow-alt-circle-down', label : 'TÉLÉCHARGER', visibility : ['file','directory'] }); object.options.panels.detail.buttons.push({ lineClass : 'properties-button directory-button', buttonClass : 'btn', icon : 'fas fa-align-justify', label : 'PROPRIÉTÉS', visibility : ['file','directory'] }); object.options.panels.search.buttons.push({ lineClass : 'upload-button', buttonClass : '', icon : 'far fa-file-alt', label : 'Envoyer un fichier', afterHtml : '
' }); object.options.panels.search.buttons.push({ lineClass : '', buttonClass : 'add-new-folder', icon : 'far fa-folder', label : 'Créer un dossier', afterHtml : '' }); object.options.panels.search.buttons.push({ lineClass : 'create-txt-button', buttonClass : '', icon : 'fas fa-pen text-secondary', label : 'Créer un fichier' }); if(object.options.rightPermission){ object.options.panels.detail.buttons.push({ lineClass : 'share-button directory-button', buttonClass : 'btn', icon : 'fas fa-share', label : 'PERMISSIONS', visibility : ['file','directory'] }); object.options.panels.detail.buttons.push({ html : '', visibility : ['file','directory'] }); } if(object.options.rightDelete){ object.options.panels.detail.buttons.push({ buttonClass : 'btn text-danger btn-element-delete', icon : 'far fa-trash-alt', label : 'SUPPRIMER', visibility : ['file','directory'] }); } object.dom.container.load('action.php?action='+object.options.actions.template,function(){ object.dom.panels = { tree : $('.tree-panel',object.dom.container), detail : $('.detail-panel',object.dom.container), search : $('.search-module',object.dom.container), breadcrumb : $('.breadcrumb-module',object.dom.container), files : $('.file-module',object.dom.container) }; if(object.options.root) $('.document-container').attr('data-root',object.options.root); if(object.options.panels['tree'].visible === false) object.hidePanel('tree'); if(object.options.panels['detail'].visible === false) object.hidePanel('detail'); if(object.options.panels['search'].visible === false) object.hidePanel('search'); if(object.options.panels['breadcrumb'].visible === false) object.hidePanel('breadcrumb'); $('.root-folder span',object.dom.panels.tree).text(object.options.rootLabel); object.views.push({ uid : 'list', icon : 'fas fa-align-justify', label : 'Vue liste', html : $('.file-view[data-view="list"]').get(0).outerHTML }); object.views.push({ uid : 'grid', icon : 'fas fa-th-large', label : 'Vue grille', html : $('.file-view[data-view="grid"]').get(0).outerHTML }); //Chargement des vues disponibles object.loadViews(); //Rendu de la vue courante object.renderView(); //Chargement des fichiers object.element_search(); //Chargement des boutons ajouter (dossier, fichier..) $('.document-create-dropdown .dropdown-item:not(.hidden)').remove(); var tpl = $('.document-create-dropdown .dropdown-item.hidden').get(0).outerHTML; for(var k in object.options.panels.search.buttons){ var data = object.options.panels.search.buttons[k]; var button = $(Mustache.render(tpl,data)); button.removeClass('hidden'); $('.document-create-dropdown').append(button); } $('.root-folder',object.dom.container).addClass('folder-focused'); $(document).off('keyup').on('keyup', function(e){ switch(e.keyCode){ case 46: if(!object.options.rightDelete) break; object.element_delete(); break; case 113: if(!object.options.rightEdit) break; if ($('.file-view tr').hasClass('element-focused')) object.element_rename_edit($('.element-rename',object.selected.element)); break; case 13: if($('.label-search',object.dom.panels.search).is(":focus")) object.element_search(); break; } }); $('.file-view:visible').sortable_table({ onSort : function(){object.element_search();} }); //RESET KEYWORD $(".label-search").on('keyup',function(){ if ($(this).val() != ''){ $('.doc-search-container').addClass('typing'); }else{ $('.doc-search-container').removeClass('typing'); } }); $(".search-clear").click(function(){ $('.doc-search-container').removeClass('typing'); $(".label-search").val(''); $(".label-search").focus(); object.element_search(); }); $('div.file-panel').on('click',function(e){ if(e.target == (this)) { $('.file-view:visible tr').removeClass('element-focused'); object.reset_preview(); } }); // Mapping des events DOM / objet $('.root-folder',object.dom.panels.tree).click(function(event){object.element_search('.');}); $('.btn-search',object.dom.panels.search).click(function(){object.element_search();}); $('.add-new-folder',object.dom.panels.search).click(function(event){ object.new_folder(event); }); $('.new-folder-block .input-group-append',object.dom.panels.search).click(function(){object.folder_create()}); $('.detail-buttons',object.dom.panels.detail).on('click','.btn-download',function(){object.element_download(null,true)}); $('.detail-buttons',object.dom.panels.detail).on('click','.share-button',function(){object.right_toggle()}); $('.detail-buttons',object.dom.panels.detail).on('click','.properties-button',function(){object.properties_show()}); $('.detail-buttons',object.dom.panels.detail).on('click','.element-right-form .btn-add-share',function(){object.right_save()}); $('.detail-buttons',object.dom.panels.detail).on('click','.btn-delete-right',function(){object.right_delete(this)}); $('.detail-buttons',object.dom.panels.detail).on('click','.btn-element-delete',function(){object.element_delete();}); $('.tree-folders',object.dom.panels.tree).on('click','li',function(event){object.folder_toggle(this,event);}); //editeur $('.create-txt-button',object.dom.panels.search).click(function(){object.element_edit();}); $('.btn-editor-cancel',object.dom.panels.file).click(function(){ $('.file-editor',object.dom.panels.file).addClass('hidden'); }); $('.btn-editor-save',object.dom.panels.file).click(function(){object.element_edit_save();}); if(!object.options.rightEdit){ $('.document-add-element',object.dom.panels.file).addClass('hidden'); }else{ object.init_upload(); } object.triggerEvent('loaded'); }); } triggerEvent(event,options){ if(!this.onEvents[event]) return; for(var key in this.onEvents[event]){ this.onEvents[event][key](options); } } hidePanel(panel){ var object = this; object.options.panels[panel].visible = false; if(object.dom.panels[panel]!=null) object.dom.panels[panel].addClass('hidden'); } showPanel(panel){ var object = this; object.options.panels[panel].visible = true; if(object.dom.panels[panel]!=null) object.dom.panels[panel].removeClass('hidden'); } //Récuperation d'une liste de element dans le tableau elements element_search(folderPath){ var object = this; if(object.isProcessing) return; $('.file-preloader',object.dom.panels.files).removeClass('hidden'); var keyword = $('.label-search',object.dom.panels.search).val(); //tri var sort = {}; var sortElement = $('.file-view:visible th[data-sortable][data-sort]',object.dom.panels.files); if(sortElement.length!=0 && sortElement.attr('data-sort')!=""){ sort.column = sortElement.attr('data-sortable'); sort.sort = sortElement.attr('data-sort'); } var data = { /*async: false,*/ action: object.options.actions.element_search, keyword : keyword, sort : sort, root :object.options.root, folder : folderPath ? folderPath : object.currentFolder } data.folder = data.folder == '.' ? '': data.folder; object.isProcessing = true; $('.file-view:visible',object.dom.panels.files).fill(data,function(response){ object.currentFolder = data.folder; $('.file-preloader',object.dom.panels.files).addClass('hidden'); object.triggerEvent('searched',{data:data,response:response}); object.isProcessing = false; var breadcrumb = null; if(data.folder) breadcrumb = data.folder.split('/'); //gestion de l'arborescence de gauche (tree) var tree = $('ul.tree-folders',object.dom.panels.tree); var tpl = $('li:not(:visible)',tree).get(0).outerHTML; var recipient = data.folder=='' ? tree : $('> ul li[data-path="'+data.folder+'"] > ul',object.dom.panels.tree) ; recipient.find('li:visible').remove(); //On n'affiche l'arborcence que si on est pas en mode recherche if(!data.keyword || data.keyword ==''){ for(var k in response.rows){ var row = response.rows[k]; if(row.type!='directory') continue; var li = $(Mustache.render(tpl,row)); li.removeClass('hidden'); recipient.append(li); } if(data.folder){ $('li',object.dom.panels.tree).removeClass('folder-open folder-focused'); var crumb = ''; for(var k in breadcrumb){ if(k!=0) crumb += '/'; crumb += breadcrumb[k]; $('li[data-path="'+crumb+'"]',object.dom.panels.tree).addClass('folder-open'); } $('li[data-path="'+data.folder+'"]',object.dom.panels.tree).addClass('folder-focused'); } } // //Fil d'arianne object.breadcrumb_render(breadcrumb); //reset panel detail object.reset_preview(); //EVENTS //Prévisualisation $('.file-view:visible .file-element',object.dom.panels.files).click(function(event){ object.element_preview(this, event); }); //Ouverture fichier / dossier $('.file-view:visible .file-element',object.dom.panels.files).dblclick(function(event){ object.element_execute(this); }); //Renommage $('.file-view:visible .file-element .element-rename',object.dom.panels.files).click(function(event){ event.stopPropagation(); event.preventDefault(); object.element_rename_edit(this); }); //Validation du renommage $('.rename-input',object.dom.panels.files).bind('blur keyup', function(e){ var input = $(this); var text = input.next('span'); var label = text.text(); if(e.type === 'keyup'){ //adapte la largeur en temps réel de l'input à la largeur du texte avec un max de 320 px et un min de 45px var width = Math.min(Math.max( input.val().length *5.5 ,45),320); $(this).width(width+15); } if (e.type !== 'blur' && e.keyCode !== 13) return; var tr = input.closest('.file-element'); var button = tr.find('.element-rename'); var newLabel = input.val().replace(/\s+$/, ''); //Les dossiers ne peuvent finir par un . if(newLabel.slice(-1) == '.' && tr.attr('data-type') =='directory') newLabel = newLabel.slice(0,-1); //Check si le label a changé ou non if(newLabel == label){ text.text(label).removeClass('hidden'); input.addClass('hidden'); button.removeClass('hidden'); return; } //Attribution nouveau label text.text(newLabel).removeClass('hidden'); input.addClass('hidden'); $.action({ action : object.options.actions.element_rename, path : tr.attr('data-path'), label : newLabel }, function(r){ button.removeClass('hidden'); $('.tree-folders li[data-path="'+ tr.attr('data-path')+'"]').attr('data-path',r.element.path).find('span').text(newLabel); tr.attr('data-path', r.element.path); object.triggerEvent('renamed',{ path : tr.attr('data-path'), old_label : label, label : newLabel }); }, function(r){ text.text(label); button.removeClass('hidden'); }); }); //Maj du placeholder de la recherche $('.label-search').attr('placeholder','Rechercher'+(breadcrumb ? ' dans '+breadcrumb[breadcrumb.length-1]:'')); if(!object.options.rightEdit){ $('.element-rename',object.dom.panels.file).addClass('hidden'); }else{ //Drag & Drop fichiers var viewElement = $(".file-view:visible"); var droppableContainer = viewElement.get(0).tagName == 'TABLE' ? ' tbody': ''; $(".file-view:visible"+droppableContainer,object.dom.panels.files).sortable({ distance: 5, opacity: 0.75, start: function(e, ui) { var placeholder = ui.item.clone().addClass('original-placeholder').removeAttr('style'); ui.item.after(placeholder); }, stop: function(e, ui) { $('.original-placeholder').remove(); $(e.originalEvent.target).one('click', function(e){ e.stopImmediatePropagation(); }); } }).disableSelection(); $(".file-view:visible .file-element",object.dom.panels.files).droppable({ tolerance: "pointer", hoverClass: "folder-receive-element", drop: function(event, ui) { var from = $(ui.draggable["0"]); var to = $(this); if(to.attr('data-type') != 'directory') return; $.action({ action : object.options.actions.element_move, from : from.attr('data-path'), to : to.attr('data-path'), }, function(response){ if (response.element !== null && typeof response.element === 'object') { object.triggerEvent('moved',{from:from,to:to,response:response}); from.remove(); object.remove_treeline(from); object.reset_preview(); } else { alert('Action impossible, un élément existe déjà avec ce nom dans le dossier.'); } }); } }); //Drag & drop arborescence $("li",object.dom.panels.tree).droppable({ tolerance: "pointer", greedy: true, over: function(e, ui){ var to = $(this); var toPath = to.hasClass('root-folder') ? '.' : to.attr('data-path'); to.addClass( to.hasClass('root-folder') ?'folder-focused':'folder-hover'); }, out: function(e, ui){ var to = $(this); if( to.hasClass('root-folder') && to.hasClass('folder-focused')) to.removeClass('folder-focused'); if(to.hasClass('folder-hover')) to.removeClass('folder-hover'); }, drop: function(event, ui) { var from = $(ui.draggable["0"]); var fromPath = from.attr('data-path'); var to = $(this); var toPath = to.hasClass('root-folder') ? '.' : to.attr('data-path'); if( to.hasClass('root-folder') && to.hasClass('folder-focused')) to.removeClass('folder-focused'); if(to.hasClass('folder-hover')) to.removeClass('folder-hover'); $('.tree-panel li').removeClass('folder-hover'); if(fromPath == toPath) { $.message('error', 'Impossible de déplacer un dossier dans lui-même.'); return; } $.action({ action : object.options.actions.element_move, from : fromPath, to : toPath, }, function(response){ if (response.element !== null && typeof response.element === 'object') { object.triggerEvent('moved',{from:from,to:to,response:response}); // Suppression de la ligne dans le panneau arborescence object.remove_treeline(from); // Ajout d'une ligne dans le panneau de l'arborescence if(from.attr('data-type') == 'directory') { var fromLabel = $('span', from).text(); var tpl = $('.tree-folders li:not(:visible)',object.dom.panels.tree).get(0).outerHTML; var toContainer = toPath == '.' ? $('ul.tree-folders',object.dom.panels.tree) : $('>ul.folders-container', to); toContainer.parent().addClass('folder-open'); $('i.far.fa-folder',toContainer.parent()).removeClass('fa-folder').addClass('fa-folder-open'); var li = $(Mustache.render(tpl,{label:fromLabel,path:toPath+'/'+fromLabel})); li.removeClass('hidden'); toContainer.append(li); } // Suppression de la ligne dans le panneau d'élément from.remove(); // Reset de la preview object.reset_preview(); } else alert('Action impossible, un élément existe déjà avec ce nom dans le dossier.'); }); } }); } }); } //Draw du fil d'Ariane breadcrumb_render(breadcrumb){ var object = this; if(!object.dom.panels.breadcrumb) return; if(breadcrumb === null) breadcrumb = ['.']; if(breadcrumb[0]!='.') breadcrumb.unshift('.'); $('ul li:visible',object.dom.panels.breadcrumb).remove(); var tpl = $('li:not(:visible)',object.dom.panels.breadcrumb).get(0).outerHTML; for(var key in breadcrumb){ var label = breadcrumb[key]; if(label == '.') label = ''; var currentpath = breadcrumb.slice(0,key); currentpath.push(breadcrumb[key]); currentpath = currentpath.join('/'); var li = $(Mustache.render(tpl,{label:label,path:currentpath})); if(key == breadcrumb.length-1) li.attr('title', 'Dossier courant'); $('ul',object.dom.panels.breadcrumb).append(li); li.removeClass('hidden'); } $('ul > li',object.dom.panels.breadcrumb).click(function(){ object.element_search( $(this).attr('data-path')); }); } /** DOSSIER */ folder_toggle(element, event, force){ var object = this; $('.label-search').val('').blur(); var li = $(element).closest('li'); if (li.hasClass('folder-focused')){ var parent = li.parent().parent(); object.element_search(parent.attr('data-path')); }else{ object.element_search(li.attr('data-path')); } if(event) event.stopPropagation(); } // Reset du panneau de preview de la GED reset_preview(){ var object = this; $('.detail-thumbnail',object.dom.panels.detail).removeAttr('style'); $('> h1',object.dom.panels.detail).text('Aucun fichier sélectionné'); $('> small > span',object.dom.panels.detail).text('-'); $('.detail-buttons',object.dom.panels.detail).addClass('hidden'); } // Preloader affiché durant l'upload toggle_preloader_upload(){ var object = this; var preloader = $('.preloader-upload-container'); if(!preloader.is(':visible')) { preloader.removeClass('hidden'); preloader.find('.preloader-upload-close').unbind('click').click(function(){ object.toggle_preloader_upload(); }); $('body').css('overflow', 'hidden'); } else { $('body').css('overflow', ''); preloader.addClass('hidden'); } } // Init de l'upload init_upload(){ var object = this; var form = $('.upload-button form',object.dom.container); var input = form.find('input[type="file"]'); var zone = $('.file-panel'); var droppedFiles = null; var noBlink = null; var fileQueue = []; //Upload des images dans le presse papier window.addEventListener("paste", function(event){ var clipboardData = event.clipboardData || window.clipboardData; if(clipboardData.getData('Text').length) return; if(event.clipboardData == false || event.clipboardData.items == undefined) return; var items = event.clipboardData.items; if(items.length == 0) return; fileQueue = []; for (var i = 0; i < items.length; i++) { var f = items[i]; if (f.type.indexOf("image") == -1) return; var file = items[i].getAsFile(); fileQueue.push({ method : 'paste', file : file }); } form.trigger('submit'); }, false); input.addClass('hidden'); $('.upload-button > div',object.dom.container).click(function(e){ input.trigger('click'); e.preventDefault(); e.stopPropagation(); }); input.on('change', function (e) { fileQueue = []; for(var k in this.files){ if(this.files[k].name ==null) break; fileQueue.push({ method : 'browse', file : this.files[k] }); } form.trigger('submit'); }); zone.on('drag dragstart dragend dragover dragenter dragleave drop', function (e) { e.preventDefault(); e.stopPropagation(); }) .on('dragover dragenter', function (e) { clearTimeout(noBlink); $('.drag-overlay').css('display', 'block'); zone.addClass('drag-over'); e.preventDefault(); e.stopPropagation(); }) .on('dragleave dragend drop', function (e) { noBlink = setTimeout(function(){ $('.drag-overlay').css('display', 'none'); zone.removeClass('drag-over'); },500); e.preventDefault(); e.stopPropagation(); }) .on('drop', function (e) { fileQueue = []; if(!e.originalEvent.dataTransfer) return; droppedFiles = e.originalEvent.dataTransfer.files; for (var i=0, f; f=droppedFiles[i]; ++i) { if(f.name.indexOf(".")==-1 && f.size%4096 == 0) { $.message('error', 'Impossible d\'envoyer un dossier.'); return; } fileQueue.push({ method : 'drop', file : droppedFiles[i] }); } form.trigger('submit'); }); form.on('submit', function (e) { $('.drag-overlay').css('display', 'none'); e.preventDefault(); var tpl = $('.upload-files li.hidden').get(0).outerHTML; $('.upload-files li:not(.hidden)').remove(); var fileProcessed = []; object.toggle_preloader_upload(); for( var k in fileQueue){ var file = fileQueue[k].file; var line = $(Mustache.render(tpl,{ label : file.name, sort : k, size : readable_size(file.size) })); line.removeClass('hidden'); $('.upload-files').append(line); var ajaxData = new FormData(); ajaxData.append(input.attr('name'), file); ajaxData.append('method', fileQueue[k].method); ajaxData.append('path', object.currentFolder =='.' ? '' : object.currentFolder); ajaxData.append('sort', k); $.ajax({ url: form.attr('action'), type: form.attr('method'), data: ajaxData, dataType: 'json', cache: false, contentType: false, processData: false, complete: function (data) {}, success: function (response) { if(!response.error){ $('.upload-files li[data-sort="'+response.sort+'"] .upload-file-state').addClass('success').html(' Succès'); }else{ $('.upload-files li[data-sort="'+response.sort+'"] .upload-file-state').addClass('error').html(' Erreur :'+response.error); } fileProcessed.push(response); $('.preloader-upload-container .upload-state span').text(fileProcessed.length+'/'+fileQueue.length+' fichiers envoyés'); if(fileQueue.length==fileProcessed.length){ object.triggerEvent('uploaded',{data:fileProcessed}); $('.document-create-dropdown').removeClass('show'); object.element_search(); //On cache automatiquement le gestionnaire d'upload si aucune erreure. if($('.upload-file-state.error').length == 0){ setTimeout(function(){ var preloader = $('.preloader-upload-container'); $('body').css('overflow', ''); preloader.addClass('hidden'); },1500); } } }, error: function (data) { $('.document-create-dropdown').removeClass('show'); $.message('error',data); }, xhr: function() { var xhr = new window.XMLHttpRequest(); xhr.sort = k; xhr.upload.addEventListener("progress", function(evt){ if (evt.lengthComputable) { var percentComplete = (evt.loaded / evt.total) * 100; percentComplete = Math.round(percentComplete * 100) / 100; var progressBar = $('.upload-files li[data-sort="'+xhr.sort+'"] .progress-bar') .css('width',percentComplete+'%') .text(percentComplete+'%') .attr('aria-valuenow',percentComplete); } }, false); return xhr; } }); } }); } folder_create(){ var object = this; var path = object.currentFolder =='.' ? '' : object.currentFolder+'/'; path += $('.folder-name').val(); var data = { action : object.options.actions.folder_create, path : path, folder : $('.folder-name',object.dom.panels.search).val() } $.action(data,function(response){ object.triggerEvent('folder-created',{path:data.path,folder:data.folder,response:response}); $('.folder-name',object.dom.panels.search).val('').focus(); $('.new-folder-block',object.dom.panels.search).toggleClass('hidden'); $('.dropdown-menu',object.dom.panels.search).trigger('click'); object.element_search(); }); } new_folder(event){ var object = this; $('.new-folder-block',object.dom.panels.search).toggleClass('hidden'); $('.new-folder-block input',object.dom.panels.search).focus().enter(function(){object.folder_create()}); event.stopPropagation(); } /** ELEMENT **/ element_rename_edit(button){ var object = this; var button = $(button); var span = button.prev('span'); var text = span.find('span'); var tr = span.closest('.file-element'); var label = span.find('span').text(); var input = $('.rename-input',tr); //adapte la largeur de l'input à la largeur du texte avec un max de 320 px et un min de 45px var width = Math.min(Math.max(text.width(),45),320); button.addClass('hidden'); text.addClass('hidden'); input.removeClass('hidden') .focus() .val(label) .width(width+15) .click(function(event){ event.stopPropagation(); }); } // Met à jour l'arborescence (supprime la line dans l'arborescence sur move ou rename) remove_treeline(from){ var parent = $('.folder-focused ul'); if(parent.length == 0) parent = $('.tree-panel > ul'); $('li',parent).each(function(i,li){ var li = $(li); if(li.attr('data-path') == from.attr('data-path')) { li.remove(); } }); } //Récuperation d'une liste de element dans le tableau elements element_preview(element, event){ var object = this; var line = $(element); if(line.hasClass('element-focused')) return; object.selected = { element : line, path : line.attr('data-path'), type : line.attr('data-type'), id : line.attr('data-id') } $('.right-panel',object.dom.panels.detail).addClass('hidden'); $('.detail-buttons',object.dom.panels.detail).removeClass('hidden'); if(object.selected.type =='directory') { $('.detail-buttons > .directory-button',object.dom.panels.detail).removeClass('hidden'); }else{ $('.detail-buttons > .directory-button',object.dom.panels.detail).addClass('hidden'); } $('.detail-buttons > li:visible',object.dom.panels.detail).remove(); var buttonTemplate = $('.detail-buttons > li:eq(0).hidden').get(0).outerHTML; if(object.options.panels.detail.buttons){ for(var i in object.options.panels.detail.buttons){ var data = object.options.panels.detail.buttons[i]; if(data.visibility && data.visibility.indexOf(object.selected.type) == -1 ) continue; var button = $(Mustache.render(buttonTemplate,data)); button.removeClass('hidden'); $('.detail-buttons').append(button); } } //autoblur sur le rename d'un fichier en cours si existant var currentRename = $('.file-view:visible .file-element .rename-input:visible'); if(currentRename.length>0) currentRename.trigger('blur'); $('.file-view:visible .file-element',object.dom.panels.files).removeClass('element-focused'); line.addClass('element-focused'); $('.detail-thumbnail .thumbnail-preloader',object.dom.panels.detail).addClass('show'); $.action({ action : object.options.actions.element_preview, path : line.attr('data-path'), },function(response){ setTimeout(function(){ $('.detail-thumbnail .thumbnail-preloader',object.dom.panels.detail).removeClass('show'); },100); $('.detail-thumbnail',object.dom.panels.detail).css('background-image','url('+response.row.thumbnail+')'); var substrings = ['.jpg','.jpeg','.bmp','.gif','.png']; $('.detail-thumbnail',object.dom.panels.detail).css('background-size',''); if (new RegExp(substrings.join("|")).test(response.row.thumbnail)) $('.detail-thumbnail',object.dom.panels.detail).css('background-size','contain'); $('> h1',object.dom.panels.detail).html(response.row.label).text(); var size = response.row.sizeReadable; if(response.row.type == 'directory') size = response.row.childNumber+' élement'+(response.row.childNumber>1?'s':''); $('> small > span',object.dom.panels.detail).text(size+", "+response.row.updatedRelative); object.triggerEvent('selected',object.selected); }); } //Suppression d'un élément de la GED element_delete(){ var object = this; if($('span .rename-input:visible',object.selected.element).length) return; if(object.selected == null) { $.message('info', 'Sélectionnez d\'abord un élément à supprimer'); return; } if(!confirm('Êtes-vous sûr de vouloir supprimer cet élément ?')) return; $.action({ action : object.options.actions.element_delete, path : object.selected.path, },function(response){ object.triggerEvent('deleted',{ element : object.selected.element, response : response, path : object.selected.path, }); object.selected.element.remove(); object.reset_preview(); }); } element_share_edit(){ var object = this; if($('span .rename-input:visible',object.selected.element).length) return; if(object.selected == null) { $.message('info', 'Sélectionnez d\'abord un élément à partager'); return; } $.action({ action : object.options.actions.element_share_edit, path : object.selected.path, }); } //edition d'un fichier texte en ligne element_edit(path){ var object = this; $('.file-editor-name',object.dom.panels.file).val('Nouveau Fichier.txt'); $('.file-editor-input',object.dom.panels.file).val(''); if(path){ $('.file-editor-input',object.dom.panels.file).val('Chargement en cours...'); $.action({ action : object.options.actions.element_edit, path : path, },function(r){ $('.file-editor-name',object.dom.panels.file).val(r.label); $('.file-editor-input',object.dom.panels.file).val(r.content); }); } $('.file-editor',object.dom.panels.file).removeClass('hidden'); $('.file-editor-input',object.dom.panels.file).focus(); } //edition d'un fichier texte en ligne element_edit_save(){ var object = this; $.action({ action : object.options.actions.element_save, label : $('.file-editor-name',object.dom.panels.file).val(), content : $('.file-editor-input',object.dom.panels.file).val(), path : object.currentFolder, },function(r){ $('.file-editor',object.dom.panels.file).addClass('hidden'); object.element_search(); }); } //Récuperation d'une liste de element dans le tableau elements element_execute(element){ var object = this; var inputSearch = $('.label-search',object.dom.panels.search); if(inputSearch.val().length) { inputSearch.val('').blur(); $(".search-clear",object.dom.panels.search).removeAttr('style'); } var line = $(element); if(line.attr('data-type') == 'directory'){ object.element_search(line.attr('data-path')); object.triggerEvent('opened',{ element : line, path : line.attr('data-path') }); return; } object.triggerEvent('executed',{ element : line, path : line.attr('data-path') }); var ext = object.selected.path.split('.').pop(); switch(ext){ case 'txt': object.element_edit(object.selected.path); break; default: object.element_download(line); break; } } // Téléchargement d'un élément de la GED element_download(line,forceDownload){ var object = this; var line = line ? line : object.selected.element; if(line.length == 0) return $.message('info', 'Sélectionnez d\'abord un élément à télécharger'); object.triggerEvent('downloaded',{ element : line, path : line.attr('data-path') }); var url = 'action.php?action='+object.options.actions.element_execute+'&path='+encodeURIComponent(btoa(line.attr('data-path'))); if(forceDownload) url+= '&download'; window.open(url, '_blank'); } /** PROPERTIES **/ properties_show(){ var object = this; var modal = $('.document-properties-modal'); var tpl = $('.modal-body-template',modal).html(); modal.modal('show'); $('.modal-body',modal).html('Chargement...'); $.action({ action : object.options.actions.properties_show, id : object.selected.id },function(r){ $('.modal-body',modal).html(Mustache.render(tpl,r.row)); init_components(modal); object.triggerEvent('properties-showed',{ modal : modal, id : object.selected.id }); }); } /** ELEMENTRIGHT **/ //Récuperation d'une liste de elementright dans le tableau elementrights right_toggle(){ var object = this; $('.right-panel',object.dom.panels.detail).toggleClass('hidden'); init_components('.element-right-form'); this.right_search(); } //Récuperation d'une liste de elementright dans le tableau elementrights right_search(callback){ var object = this; if(object.selected == null) return; $('.element-rights').fill({ action:object.options.actions.right_search, id : object.selected.id },function(){ if(callback!=null) callback(); }); } //Ajout ou modification d'élément elementright right_save(){ var object = this; var data = { uid : $('.element-right-form input.uid').val(), read : $('.element-right-form .read').val(), edit : $('.element-right-form .edit').val(), recursive : $('.element-right-form .recursive').val() } data.action = object.options.actions.right_save; data.element = object.selected.id; $.action(data,function(r){ $.message('success','Enregistré'); $('.uid').val(''); $('.read,.edit,.recursive').prop('checked',false); init_components('.element-right-form'); object.right_search(); data.id = object.selected.id; data.element = object.selected.element; object.triggerEvent('right-saved',data); }); } //Suppression d'élement elementright right_delete(element){ var object = this; if(!confirm('Êtes-vous sûr de vouloir supprimer ce droit ?')) return; var line = $(element).closest('li'); $.action({ action : object.options.actions.right_delete, id : line.attr('data-id') },function(r){ object.triggerEvent('right-deleted',{id:line.attr('data-id'),element:line}); line.remove(); }); } //Ajoute un callback sur un evenement de la ged particulier on(event,callback){ if(!this.onEvents[event])this.onEvents[event] = []; this.onEvents[event].push(callback); } /* Gestion des vues */ //Change la vue courante view(view){ var object = this; object.currentView = view; object.renderView(); object.triggerEvent('view-loaded',{view:view}); } //Ajoute une vue custom addView(data){ var object = this; data.html = $(data.html); data.html.attr('data-view',data.uid); if(!data.html.hasClass('file-view')) data.html.addClass('file-view'); object.views.push(data); } //affiche le rendu de la vue courante (object.currentView) renderView(){ var object = this; if(!object.dom.panels.files) return; $('.file-view',object.dom.panels.files).addClass('hidden'); var viewElement = $('.file-view[data-view="'+object.currentView+'"]'); $(object.dom.panels.files).attr('data-view',object.currentView); $('.view-module > li',object.dom.panels.search).removeClass('selected'); $('.view-module > li[data-view="'+object.currentView+'"]',object.dom.panels.search).addClass('selected'); viewElement.removeClass('hidden'); object.element_search(); } //charge toutes les vues disponibles dans le dom loadViews(){ var object = this; //Chargement des bouttons de vue $('.view-module > li:visible',object.dom.panels.search).remove(); var tpl = $('.view-module > li.hidden',object.dom.panels.search).get(0).outerHTML; for(var key in object.views){ var view = object.views[key]; var button = $(Mustache.render(tpl, view)); button.removeClass('hidden'); $('.view-module',object.dom.panels.search).append(button); button.click(function(){ object.view($(this).attr('data-view')); }); if($('.file-view[data-view="'+view.uid+'"]',object.dom.panels.files).length==0) object.dom.panels.files.append(view.html); } } }