fix(editor): v4.8.1 bloc Tableau - +Row, +Colonne a droite, redim colonnes
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Skipped

- + Row (bas) ne fonctionnait pas: splice(index,ligne) -> splice(index,0,ligne)
- bouton + a droite du tableau = ajoute une colonne a droite
- redimensionnement colonnes a la souris (curseur col-resize) + persistance colsW
- VERSION/CHANGELOG/ROADMAP/css?v bump 4.8.1
This commit is contained in:
2026-09-04 12:10:22 -04:00
parent c809a864e6
commit 23df10732b
7 changed files with 84 additions and 10 deletions
+39 -4
View File
@@ -27,7 +27,7 @@
function _tblNew(rows,cols){var out=[];for(var i=0;i<rows;i++){var r=new Array(cols);for(var j=0;j<cols;j++)r[j]='';out.push(r);}return out;}
function _tblClone(b){b.rows=(b.rows||[]).map(function(r){return (r||[]).slice();});return b;}
function _tblAddCol(b,index){_tblClone(b);var w=b.rows.length?b.rows[0].length:1;if(index<0)index=0;if(index>w)index=w;b.rows.forEach(function(r){r.splice(index,0,'');});}
function _tblAddRow(b,index){_tblClone(b);var w=b.rows.length&&b.rows[0]?b.rows[0].length:1;if(index<0)index=0;if(index>b.rows.length)index=b.rows.length;b.rows.splice(index,_tblNew(1,w)[0]);}
function _tblAddRow(b,index){_tblClone(b);var w=b.rows.length&&b.rows[0]?b.rows[0].length:1;if(index<0)index=0;if(index>b.rows.length)index=b.rows.length;b.rows.splice(index,0,_tblNew(1,w)[0]);}
function _tblDupCol(b,index){_tblClone(b);b.rows.forEach(function(r){var v=(index<r.length)?r[index]:'';var at=index+1>r.length?r.length:index+1;r.splice(at,0,v);});}
function _tblDupRow(b,index){_tblClone(b);if(index<0||index>b.rows.length)return;b.rows.splice(index+1,0,(b.rows[index]||[]).slice());}
function _tblClearCol(b,index){_tblClone(b);b.rows.forEach(function(r){if(r&&index<r.length)r[index]='';});}
@@ -40,8 +40,10 @@
function renderTableBlock(b,idx){
var rows=(b&&Array.isArray(b.rows)&&b.rows.length)?b.rows:_tblNew(2,2);
var w=0;rows.forEach(function(r){if(r&&r.length>w)w=r.length;});if(w<1)w=2;
var widths=(b&&Array.isArray(b.colsW))?b.colsW:[];
var bid=b.id;var h='';
h+='<div class="block-wrapper"><div class="block-content ftable-editor" data-bid="'+bid+'">';
h+='<div class="ftable-flex"><div class="ftable-flex-main">';
h+='<div class="ftable-colbar">';
for(var c=0;c<w;c++){
h+='<div class="ftable-colcell"><button type="button" class="ftable-colgrip" data-tbl="colmenu" data-bid="'+bid+'" data-col="'+c+'" title="Column options">'+_tblGrip()+'</button></div>';
@@ -53,12 +55,18 @@
h+='<tr class="ftable-row">';
for(var ci=0;ci<w;ci++){
var v=rows[ri]&&ci<rows[ri].length?rows[ri][ci]:'';
h+='<'+tag+' class="ftable-cell'+(isHead?' head':'')+'" contenteditable="true" data-r="'+ri+'" data-c="'+ci+'" spellcheck="false">'+esc(v)+'</'+tag+'>';
var wpx=(widths[ci]&&widths[ci]>0)?(' style="width:'+widths[ci]+'px"'):'';
h+='<'+tag+' class="ftable-cell'+(isHead?' head':'')+'" contenteditable="true" data-r="'+ri+'" data-c="'+ci+'"'+wpx+' spellcheck="false">'+esc(v);
if(isHead)h+='<span class="ftable-resize" data-col="'+ci+'" title="Drag to resize column"></span>';
h+='</'+tag+'>';
}
h+='</tr>';
}
h+='</tbody></table>';
h+='<div class="ftable-rowbar"><button type="button" class="ftable-addrow" data-tbl="rowadd" data-bid="'+bid+'" title="Click to add a row">+ Row</button></div>';
h+='</div>';
h+='<div class="ftable-addcolwrap"><button type="button" class="ftable-addcol" data-tbl="coladdright" data-bid="'+bid+'" title="Add column on the right">+</button></div>';
h+='</div>';
h+='</div></div>';
return h;
}
@@ -108,6 +116,29 @@
e.render();e.dirty=true;e.autoSave();
_tblFocus(bid,focusR,focusC);
}
function _tblResizeStart(ev){
var sp=ev.target&&ev.target.closest?ev.target.closest('.ftable-resize'):null;if(!sp)return;
var th=sp.parentElement;if(!th)return;
var wrap=th.closest('.ftable-editor');if(!wrap)return;
var bid=wrap.getAttribute('data-bid');var col=parseInt(sp.getAttribute('data-col')||'0',10);
var b=_tblBlockById(bid);if(!b)return;
ev.preventDefault();ev.stopPropagation();
var E=window.E;if(E&&E.sync)E.sync();
var widths=(b.colsW&&Array.isArray(b.colsW))?b.colsW.slice():[];
while(widths.length<=col)widths.push(null);
var startX=ev.clientX;var base=widths[col]||th.getBoundingClientRect().width;
document.body.style.cursor='col-resize';document.body.style.userSelect='none';
function move(me){var dx=me.clientX-startX;var nw=Math.max(48,Math.min(760,base+dx));th.style.width=Math.round(nw)+'px';widths[col]=Math.round(nw);}
function up(me){
document.removeEventListener('mousemove',move);document.removeEventListener('mouseup',up);
document.body.style.cursor='';document.body.style.userSelect='';
move(me);
b.colsW=widths;
if(E){E.dirty=true;E.autoSave();}
}
document.addEventListener('mousemove',move);
document.addEventListener('mouseup',up);
}
function _tblInitDelegate(){
if(window._tblDelegate)return;window._tblDelegate=true;
document.addEventListener('click',function(ev){
@@ -118,6 +149,7 @@
if(act==='colmenu'){_tblMenuOpen(gr?gr.left:ev.clientX,(gr?gr.bottom:ev.clientY)+4,bid,'col',col);ev.preventDefault();}
else if(act==='colplus'){var b=_tblBlockById(bid);if(b){window.E.sync();_tblAddCol(b,col+1);window.E.render();window.E.dirty=true;window.E.autoSave();_tblFocus(bid,1,col+1);}}
else if(act==='rowadd'){var b2=_tblBlockById(bid);if(b2){window.E.sync();var n=b2.rows.length;_tblAddRow(b2,n);window.E.render();window.E.dirty=true;window.E.autoSave();_tblFocus(bid,n,0);}}
else if(act==='coladdright'){var b4=_tblBlockById(bid);if(b4){window.E.sync();var cw=(b4.rows&&b4.rows[0])?b4.rows[0].length:1;_tblAddCol(b4,cw);window.E.render();window.E.dirty=true;window.E.autoSave();_tblFocus(bid,1,cw);}}
return;
}
if(document.getElementById('_tblMenu')&&!(ev.target.closest&&ev.target.closest('[data-tbl]')))_tblMenuClose();
@@ -131,7 +163,10 @@
if(r===0)_tblMenuOpen(ev.clientX,ev.clientY,bid,'col',c);
else _tblMenuOpen(ev.clientX,ev.clientY,bid,'row',r);
});
document.addEventListener('mousedown',function(ev){if(document.getElementById('_tblMenu')&&!ev.target.closest('#_tblMenu'))_tblMenuClose();});
document.addEventListener('mousedown',function(ev){
if(ev.target&&ev.target.closest&&ev.target.closest('.ftable-resize')){_tblResizeStart(ev);return;}
if(document.getElementById('_tblMenu')&&!(ev.target.closest&&ev.target.closest('#_tblMenu')))_tblMenuClose();
});
}
const SM={_o:false,_i:-1,_s:0,_q:'',_it:[],
@@ -653,7 +688,7 @@
const t=document.getElementById('_titleEl');if(t)this.pageTitle=t.textContent?.trim()||'New page';
this.saving=true;
const csrf=document.cookie.match(/csrf_token=([^;]+)/);
fetch(`/board/api/pages/${this.pid}/blocks`,{method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':csrf?csrf[1]:''},body:JSON.stringify({title:this.pageTitle,blocks:this.blocks.map(b=>{const c={id:b.id,type:b.type,content:b.content};['checked','expanded','language','icon','src','alt','style','embed_type','collection_id','dbs','file_name','file_size','file_mime','children','rows','align','has_header'].forEach(k=>{if(b[k]!=null)c[k]=b[k];});return c;})})})
fetch(`/board/api/pages/${this.pid}/blocks`,{method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':csrf?csrf[1]:''},body:JSON.stringify({title:this.pageTitle,blocks:this.blocks.map(b=>{const c={id:b.id,type:b.type,content:b.content};['checked','expanded','language','icon','src','alt','style','embed_type','collection_id','dbs','file_name','file_size','file_mime','children','rows','align','has_header','colsW'].forEach(k=>{if(b[k]!=null)c[k]=b[k];});return c;})})})
.then(r=>r.json()).then(()=>{this.saving=false;this.dirty=false;this.lastSaved=new Date().toLocaleTimeString();
document.querySelectorAll(`.sidebar-item[data-page-id="page/${this.pid}"]`).forEach(item=>{const n=item.querySelector('.page-name');if(n)n.textContent=this.pageTitle||'New page';});
if(cb)cb();