fix(editor): v4.8.1 bloc Tableau - +Row, +Colonne a droite, redim colonnes
- + 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:
@@ -1,5 +1,18 @@
|
||||
# Changelog — FlowDeck
|
||||
|
||||
## v4.8.1 (2026-09-03) — Fix bloc Tableau : boutons + Ligne / + Colonne, redimensionnement
|
||||
|
||||
### Fixed
|
||||
- **Bouton « + Row » (bas du tableau) inopérant** — le code passait la nouvelle ligne en argument `deleteCount` de `Array.splice` au lieu d'utiliser `splice(index, 0, ligne)` : aucune ligne n'était jamais insérée. Corrigé ; les insertions de lignes (menu contextuel aussi) fonctionnent.
|
||||
- Coloration/handles alignés sur l'en-tête.
|
||||
|
||||
### Added
|
||||
- **Bouton « + » à droite du tableau** (sur toute la hauteur) → ajoute une colonne à la droite (équivalent d'un « Add column » comme « Add Row »).
|
||||
- **Redimensionnement des colonnes à la souris** : au survol d'une bordure de colonne (en-tête) le curseur devient `col-resize` ; glisser ajuste la largeur. Les largeurs sont persistées dans le bloc (`colsW`) → conservées au rechargement, à l'ajout/suppression et dans l'auto-save.
|
||||
|
||||
### Infra
|
||||
- `VERSION` → 4.8.1 ; cache CSS `app.css?v=4.8.1`.
|
||||
|
||||
## v4.8.0 (2026-09-03) — Bloc Tableau simple (mode édition Notion)
|
||||
|
||||
> Insertion via `/table`, cellules éditables au clic, ajout/suppression/modification de lignes et colonnes comme dans Notion.
|
||||
|
||||
+6
-1
@@ -307,6 +307,11 @@ Détails livrés :
|
||||
- [x] **Colonnes** — poignée (⋮⋮) au-dessus de chaque colonne → Insérer à gauche/droite, Dupliquer, Effacer le contenu, Supprimer la colonne, Supprimer le tableau.
|
||||
- [x] **Import Markdown (GFM)** — `md2b` transforme les tableaux pipe en bloc `table` au lieu de les aplatir en paragraphes ; roundtrip Markdown (JS + export) et sortie MD/HTML/PDF correcte d'un bloc `table`.
|
||||
|
||||
### v4.8.1 — Fix bloc Tableau ✅ (2026-09-03)
|
||||
- [x] **« + Row » (bas) corrigé** — l'insertion de ligne utilisait `splice(index, ligne)` (mauvaise signature) → aucune ligne ajoutée ; désormais `splice(index, 0, ligne)`.
|
||||
- [x] **Bouton « + » à droite** — ajoute une colonne à droite (équivalent « Add column »).
|
||||
- [x] **Redimensionnement des colonnes** — curseur `col-resize` au survol des bordures d'en-tête, drag = largeur ; persisté via `colsW`.
|
||||
|
||||
### v4.9.0 — Collaboration
|
||||
- [ ] **Inline comments** — commentaires sur sélection de texte
|
||||
- [ ] **@mentions** — notifier un utilisateur → page/commentaire
|
||||
@@ -459,4 +464,4 @@ v4.0.2 ✅ v4.1.0 ✅ v4.2.0 ✅ v4.3.0 ✅ v4.4.0 ✅ v4.5.0 ✅
|
||||
Quality Data Sources Templates + 10 Views Tasks & Sprints & Content Export Bloc Table Collab + Pro + Agent
|
||||
& Tests & Linked DB Dashboards complets Dependencies My Tasks Blocks MD/PDF/HTML simple Agent IA (futur)
|
||||
|
||||
*Dernière mise à jour: 2026-09-03 — v4.8.0 Bloc Tableau simple (édition Notion) ✅*
|
||||
*Dernière mise à jour: 2026-09-03 — v4.8.1 Bloc Tableau : + Row / + Col / redimensionnement ✅*
|
||||
|
||||
+2
-2
@@ -39,13 +39,13 @@ async def lifespan(_app: FastAPI):
|
||||
(admin_hash,)
|
||||
)
|
||||
conn.commit()
|
||||
logger.info("FlowDeck v4.8.0 started on port %d", settings.app_port)
|
||||
logger.info("FlowDeck v4.8.1 started on port %d", settings.app_port)
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(
|
||||
title="FlowDeck",
|
||||
version="4.8.0",
|
||||
version="4.8.1",
|
||||
docs_url="/docs" if settings.log_level == "DEBUG" else None,
|
||||
redoc_url=None,
|
||||
lifespan=lifespan,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>FlowDeck — {% block title_prefix %}Home{% endblock %}</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||||
<link rel="stylesheet" href="/static/css/app.css?v=4.8.0">
|
||||
<link rel="stylesheet" href="/static/css/app.css?v=4.8.1">
|
||||
<link rel="stylesheet" href="/static/css/katex.min.css?v=0.16.11">
|
||||
<style>
|
||||
/* ── Mobile responsive (v4.0.2) ── */
|
||||
|
||||
+22
-1
@@ -4451,9 +4451,29 @@ button.breadcrumb-current { max-width: 260px; }
|
||||
font-size: 15px; line-height: 1.5; color: var(--text-primary);
|
||||
outline: none; text-align: left; word-break: break-word; overflow-wrap: break-word;
|
||||
}
|
||||
.ftable-edit th.ftable-cell { background: var(--bg-secondary); font-weight: 600; }
|
||||
.ftable-edit th.ftable-cell { background: var(--bg-secondary); font-weight: 600; position: relative; }
|
||||
.ftable-edit .ftable-cell:hover { background: var(--bg-hover); }
|
||||
.ftable-edit .ftable-cell:focus { background: var(--bg-hover); box-shadow: inset 0 0 0 1px var(--blue); }
|
||||
.ftable-edit .ftable-resize {
|
||||
position: absolute; top: 0; bottom: 0; right: -3px; width: 7px;
|
||||
cursor: col-resize; z-index: 3;
|
||||
}
|
||||
.ftable-edit .ftable-resize::after {
|
||||
content: ""; position: absolute; top: 0; bottom: 0; right: 3px; width: 1px;
|
||||
background: transparent; transition: background .12s ease;
|
||||
}
|
||||
.ftable-editor:hover .ftable-resize::after { background: var(--border); }
|
||||
.ftable-edit .ftable-resize:hover::after { background: var(--accent); }
|
||||
.ftable-editor .ftable-flex { display: flex; align-items: stretch; gap: 4px; }
|
||||
.ftable-editor .ftable-flex-main { flex: 1 1 auto; min-width: 0; }
|
||||
.ftable-editor .ftable-addcolwrap { flex: 0 0 auto; display: flex; align-items: center; }
|
||||
.ftable-editor .ftable-addcol {
|
||||
width: 26px; min-height: 64px; border: none; background: transparent;
|
||||
color: var(--text-dim); font-size: 18px; cursor: pointer; border-radius: 6px;
|
||||
opacity: 0; transition: opacity .12s ease;
|
||||
}
|
||||
.ftable-editor:hover .ftable-addcol { opacity: 1; }
|
||||
.ftable-editor .ftable-addcol:hover { background: var(--bg-hover); color: var(--accent); }
|
||||
.ftable-editor .ftable-colbar { display: flex; margin: 0 0 3px; }
|
||||
.ftable-editor .ftable-colcell { flex: 1 1 0; min-width: 0; display: flex; justify-content: flex-end; }
|
||||
.ftable-editor .ftable-colgrip {
|
||||
@@ -4485,4 +4505,5 @@ button.breadcrumb-current { max-width: 260px; }
|
||||
@media (max-width: 768px) {
|
||||
.ftable-editor .ftable-colgrip { opacity: 1; }
|
||||
.ftable-editor .ftable-rowbar { opacity: 1; }
|
||||
.ftable-editor .ftable-addcol { opacity: 1; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user