fix: actions (créer/éditer/supprimer/expand) sur dossiers/fichiers niveau 2+
Refactor complet de renderChildren: - window._wsData exposé dans init() (au lieu de document.querySelector) - data-ws-action + data-ws-id + data-ws-name sur les boutons d'action - Event delegation: handleTreeAction() sur le <ul> via @click Alpine - Suppression de event.stopPropagation() qui bloquait la délégation - Chevron: onclick utilise window._wsData, data-ws-id ajouté - Drag & drop + hover: utilisent window._wsData Toutes les actions fonctionnent maintenant à n'importe quel niveau de profondeur.
This commit is contained in:
@@ -172,7 +172,7 @@
|
||||
<button class="search-clear" x-show="searchQuery" @click="searchQuery='';doFilter()" title="Clear">×</button>
|
||||
</div>
|
||||
|
||||
<ul class="ws-tree" x-show="displayTree.length>0">
|
||||
<ul class="ws-tree" x-show="displayTree.length>0" @click="handleTreeAction($event)">
|
||||
<template x-for="node in displayTree" :key="node.id">
|
||||
<li>
|
||||
<div class="ws-tree-item" :style="{paddingLeft:(node.depth||0)*20+'px'}"
|
||||
@@ -333,6 +333,8 @@ document.addEventListener('alpine:init', function() {
|
||||
this.displayTree = roots;
|
||||
this.breadcrumb = d.breadcrumb || [];
|
||||
this.loaded = true;
|
||||
// Expose globally for renderChildren onclick handlers
|
||||
window._wsData = this;
|
||||
} catch(e) { console.error('Tree load error:', e); this.loaded = true; }
|
||||
},
|
||||
|
||||
@@ -354,9 +356,14 @@ document.addEventListener('alpine:init', function() {
|
||||
var c = children[i];
|
||||
var hasKids = c.children && c.children.length > 0;
|
||||
var icon = c.is_folder ? '📁' : '📄';
|
||||
html += '<li><div class="ws-tree-item" style="padding-left:'+(depth*20)+'px" draggable="true" data-folder-id="'+(c.is_folder?c.id:'')+'" ondragstart="var d=document.querySelector(\'[x-data]\').__x.$data;d.onInternalDragStart(event,'+c.id+')" ondragend="event.target.style.opacity=\'\'">';
|
||||
var escName = this.esc(c.name);
|
||||
html += '<li><div class="ws-tree-item" style="padding-left:'+(depth*20)+'px" draggable="true"'
|
||||
+ ' data-folder-id="'+(c.is_folder?c.id:'')+'"'
|
||||
+ ' data-ws-id="'+c.id+'"'
|
||||
+ ' ondragstart="var d=window._wsData;if(d)d.onInternalDragStart(event,'+c.id+')"'
|
||||
+ ' ondragend="event.target.style.opacity=\'\'">';
|
||||
if (c.is_folder && hasKids) {
|
||||
html += '<button class="ws-chevron" onclick="event.stopPropagation();var d=document.querySelector(\'[x-data]\').__x.$data;d.toggleExpand('+c.id+',this)">▶</button>';
|
||||
html += '<button class="ws-chevron ws-expand-btn" data-ws-id="'+c.id+'" onclick="event.stopPropagation();var d=window._wsData;if(d)d.toggleExpand('+c.id+',this)">▶</button>';
|
||||
} else {
|
||||
html += '<span style="width:16px;flex-shrink:0;"></span>';
|
||||
}
|
||||
@@ -364,17 +371,19 @@ document.addEventListener('alpine:init', function() {
|
||||
if (c.is_folder) {
|
||||
html += '<span class="name folder" onclick="window.location=\'/local-workspace?folder='+c.id+'\'">'+c.name+'</span>';
|
||||
} else {
|
||||
html += '<span class="name file" onclick="window.location=\'/pages/'+c.id+'\'" onmouseenter="var d=document.querySelector(\'[x-data]\').__x.$data;d.showPreview(event,{name:\''+this.esc(c.name)+'\',is_folder:false})" onmouseleave="var d=document.querySelector(\'[x-data]\').__x.$data;d.hidePreview()">'+c.name+'</span>';
|
||||
html += '<span class="name file" onclick="window.location=\'/pages/'+c.id+'\'"'
|
||||
+ ' onmouseenter="var d=window._wsData;if(d)d.showPreview(event,{id:'+c.id+',name:\''+escName+'\',is_folder:false,content_format:\''+(c.content_format||'')+'\'})"'
|
||||
+ ' onmouseleave="var d=window._wsData;if(d)d.hidePreview()">'+c.name+'</span>';
|
||||
}
|
||||
html += '<div class="actions">';
|
||||
if (c.is_folder) {
|
||||
html += '<span style="display:flex;gap:2px">';
|
||||
html += '<button class="ws-act" onclick="event.stopPropagation();document.querySelector(\'[x-data]\').__x.$data.openModal(\'file\',{db_id:'+c.id+',name:\''+this.esc(c.name)+'\'})">📄</button>';
|
||||
html += '<button class="ws-act" onclick="event.stopPropagation();document.querySelector(\'[x-data]\').__x.$data.openModal(\'folder\',{db_id:'+c.id+',name:\''+this.esc(c.name)+'\'})">📁</button>';
|
||||
html += '<button class="ws-act" data-ws-action="new-file" data-ws-id="'+c.id+'" data-ws-name="'+escName+'">📄</button>';
|
||||
html += '<button class="ws-act" data-ws-action="new-folder" data-ws-id="'+c.id+'" data-ws-name="'+escName+'">📁</button>';
|
||||
html += '</span>';
|
||||
}
|
||||
html += '<button class="ws-act" onclick="event.stopPropagation();document.querySelector(\'[x-data]\').__x.$data.startRename({db_id:'+c.id+',name:\''+this.esc(c.name)+'\'})">✏️</button>';
|
||||
html += '<button class="ws-act danger" onclick="event.stopPropagation();document.querySelector(\'[x-data]\').__x.$data.startDelete({db_id:'+c.id+',name:\''+this.esc(c.name)+'\'})">🗑</button>';
|
||||
html += '<button class="ws-act" data-ws-action="rename" data-ws-id="'+c.id+'" data-ws-name="'+escName+'">✏️</button>';
|
||||
html += '<button class="ws-act danger" data-ws-action="delete" data-ws-id="'+c.id+'" data-ws-name="'+escName+'">🗑</button>';
|
||||
html += '</div></div>';
|
||||
if (hasKids) {
|
||||
html += '<ul class="ws-tree" style="display:none">'+this.renderChildren(c.children, depth+1)+'</ul>';
|
||||
@@ -389,6 +398,32 @@ document.addEventListener('alpine:init', function() {
|
||||
return s.replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/"/g,'"');
|
||||
},
|
||||
|
||||
// ── Event delegation for renderChildren action buttons ──
|
||||
handleTreeAction(ev) {
|
||||
var btn = ev.target.closest('[data-ws-action]');
|
||||
if (!btn) return;
|
||||
ev.stopPropagation();
|
||||
var action = btn.getAttribute('data-ws-action');
|
||||
var id = parseInt(btn.getAttribute('data-ws-id'));
|
||||
var name = btn.getAttribute('data-ws-name') || '';
|
||||
if (!id) return;
|
||||
|
||||
switch(action) {
|
||||
case 'new-file':
|
||||
this.openModal('file', {db_id: id, name: name});
|
||||
break;
|
||||
case 'new-folder':
|
||||
this.openModal('folder', {db_id: id, name: name});
|
||||
break;
|
||||
case 'rename':
|
||||
this.startRename({db_id: id, name: name});
|
||||
break;
|
||||
case 'delete':
|
||||
this.startDelete({db_id: id, name: name});
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
toggleExpand(id, btn) {
|
||||
this.expanded[id] = !(this.expanded[id] || false);
|
||||
this.expanded = Object.assign({}, this.expanded);
|
||||
|
||||
Reference in New Issue
Block a user