From 12beab01c9aa4888c7462d9e9a87e0d5ed41d925 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Sat, 10 Oct 2026 20:49:45 -0400 Subject: [PATCH] =?UTF-8?q?fix(editor+sidebar):=20bouton=20=E2=8B=AF=20ret?= =?UTF-8?q?ir=C3=A9,=20Form=20via=20modale=20app,=20doublon=20du=20dernier?= =?UTF-8?q?=20fichier=20du=20tree?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "Get started with" : suppression du bouton "⋯" et de son menu mort (Table/Board/List/Timeline/Calendar/Gallery/Import — aucun handler). - Pilule Form : createForm() plantait sur page vide ("Cannot read properties of undefined (reading 'push')") car this.inlineDBs n'était jamais initialisé dans editorState() (seulement via loadInlineDBs si un bloc inline_dbs existait déjà). Corrigé : inlineDBs:[] initialisé. Le nom du form est demandé via une modale Alpine personnalisée (flowdeck-modal*) au lieu du prompt() natif. - Sidebar tree après drag&drop : refreshSidebarTree() préservait le lien "Manage Workspaces" via ul.querySelector('li:last-child') — non scopé, il attrapait le dernier fichier d'une sous-liste de dossier imbriquée (premier li:last-child du document) et le ré-insérait → doublon du dernier fichier. Corrigé : ':scope > li:last-child' (enfant direct). --- app/templates/_page_editor_content.html | 61 ++++++++++--------------- app/templates/base.html | 6 ++- static/js/page_editor_scripts.js | 16 +++++-- 3 files changed, 41 insertions(+), 42 deletions(-) diff --git a/app/templates/_page_editor_content.html b/app/templates/_page_editor_content.html index 54d25d9..045b764 100644 --- a/app/templates/_page_editor_content.html +++ b/app/templates/_page_editor_content.html @@ -743,7 +743,7 @@ @@ -753,41 +753,7 @@ > {{ fd_icon("file",14) }} Templates -
- -
-
- {{ fd_icon("bar-chart",14) }} Table -
-
- {{ fd_icon("copy",14) }} Board -
-
- {{ fd_icon('list',14) }} List -
-
- {{ fd_icon("calendar",14) }} Timeline -
-
- {{ fd_icon("calendar",14) }} Calendar -
-
- {{ fd_icon("image",14) }} Gallery -
-
-
- {{ fd_icon("download",14) }} Import -
-
-
Saving... @@ -1010,4 +976,27 @@
- + +
+
+
+

{{ fd_icon("copy",16) }} Create form

+ +
+
+

Enter a name for the new form.

+ +
+ +
+
+ + diff --git a/app/templates/base.html b/app/templates/base.html index f735648..70e9b8f 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -2613,8 +2613,10 @@ .then(html => { const ul = document.getElementById('sidebar-workspace-items'); if (!ul) return; - // Preserve the "Manage Workspaces" link (last
  • ) - const manageLink = ul.querySelector('li:last-child'); + // Preserve the "Manage Workspaces" link (direct last
  • child only — + // plain 'li:last-child' grabs the last file of a nested folder sublist + // when the tree has folders, splicing it back in → duplicated entry) + const manageLink = ul.querySelector(':scope > li:last-child'); ul.innerHTML = html; if (manageLink) ul.appendChild(manageLink); // Le HTML injecté porte des directives Alpine (@contextmenu, diff --git a/static/js/page_editor_scripts.js b/static/js/page_editor_scripts.js index 8b61da4..72caa94 100644 --- a/static/js/page_editor_scripts.js +++ b/static/js/page_editor_scripts.js @@ -1480,6 +1480,7 @@ const PD=(()=>{try{const el=document.getElementById('page-data');return el?JSON. _commentSel:{range:null,bid:null,start:0,end:0}, _notifiedMentions:{}, undoStack:[],redoStack:[],_histCap:100,_histLock:false, + inlineDBs: [], formOpen: false, formName: '', // ── Cover & icon (v5.10+) ── coverUrl:'', coverOpen:false, @@ -2727,14 +2728,21 @@ applyAIBlocks(text){ }catch(e){} return this.blocks.length; }, - async createForm(){ - const name=prompt('Form name:','New Form'); - if(!name||!name.trim())return; + openFormModal(){ + this.formName='New Form'; + this.formOpen=true; + this.$nextTick(()=>{ const el=this.$refs.formNameInput; if(el) el.focus(); }); + }, + closeFormModal(){ this.formOpen=false; }, + async confirmCreateForm(){ + const name=this.formName.trim(); + if(!name){ this.showToast('Form name required','error'); return; } + this.formOpen=false; const csrf = getCsrf();; try{ const r=await fetch('/db/inline/api',{ method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':csrf}, - body:JSON.stringify({name:name.trim(),parent_page_id:this.pid}) + body:JSON.stringify({name:name,parent_page_id:this.pid}) }); const d=await r.json(); if(d.id){