feat(workspace,editor): creation dans le dossier courant + sync live du titre (sidebar/header)
- creation fichier/dossier a la racine du dossier courant ou d'un dossier cible (context-menu, boutons de survol) via createPage/showCreateFolderModal(parentId)
- instances de modeles en tant qu'enfant d'un dossier (parent_id) ; nom vide -> 'Untitled'
- sidebar de la librairie rafraichi apres delete/move/duplicate/rename (_syncSidebar)
- editeur: le titre se synchronise en direct dans le sidebar, le breadcrumb et l'onglet (pages et fichiers) et persiste via PUT /board/api/pages/{id}
This commit is contained in:
@@ -2274,16 +2274,45 @@ applyAIBlocks(text){
|
||||
setTimeout(()=>{const fe=this.getEl(focusId);if(fe){fe.focus();ce(fe);}},60);
|
||||
},
|
||||
autoSave(){if(this.fileData)return;clearTimeout(this.st);this.st=setTimeout(()=>this.save(),1500);},
|
||||
// Reflect the page title in the left navigation, the header breadcrumb
|
||||
// and the browser tab as soon as it changes.
|
||||
_syncTitleUI(){
|
||||
const title=(this.pageTitle||'').trim()||'Untitled';
|
||||
document.querySelectorAll(`.sidebar-item[data-page-id="page/${this.pid}"]`).forEach(item=>{const n=item.querySelector('.page-name');if(n)n.textContent=title;});
|
||||
document.querySelectorAll(`.sidebar-item.ws-tree-item[data-id="${this.pid}"]`).forEach(item=>{item.setAttribute('data-name',title);const n=item.querySelector('.page-name');if(n)n.textContent=title;});
|
||||
document.title='FlowDeck — '+title;
|
||||
window.dispatchEvent(new CustomEvent('flowdeck:page-renamed',{detail:{id:this.pid,title:title}}));
|
||||
if(window.parent&&window.parent!==window){try{window.parent.postMessage({type:'fd-page-renamed',id:this.pid,title:title},window.location.origin);}catch(e){}}
|
||||
},
|
||||
save(cb){
|
||||
if(this.fileData)return;
|
||||
if(this.fileData){
|
||||
// File page: only the title is editable here. Sync the sidebar,
|
||||
// header breadcrumb and browser tab live, and persist the title
|
||||
// without rewriting the file's blocks.
|
||||
const t=document.getElementById('_titleEl');if(t)this.pageTitle=t.textContent?.trim()||'';
|
||||
this._syncTitleUI();
|
||||
if(this._fileTitleT)clearTimeout(this._fileTitleT);
|
||||
this._fileTitleT=setTimeout(()=>{
|
||||
this._fileTitleT=null;
|
||||
const title=(this.pageTitle||'').trim();
|
||||
if(!title)return;
|
||||
const csrf=document.cookie.match(/csrf_token=([^;]+)/);
|
||||
fetch(`/board/api/pages/${this.pid}?title=${encodeURIComponent(title)}`,{method:'PUT',headers:{'X-CSRF-Token':csrf?csrf[1]:''}})
|
||||
.then(()=>{this.dirty=false;})
|
||||
.catch(()=>{});
|
||||
},600);
|
||||
if(cb)cb();
|
||||
return;
|
||||
}
|
||||
const t=document.getElementById('_titleEl');if(t)this.pageTitle=t.textContent?.trim()||'';
|
||||
this._syncTitleUI();
|
||||
if(this.saving){ if(cb) cb(); return; }
|
||||
this.sync();
|
||||
const t=document.getElementById('_titleEl');if(t)this.pageTitle=t.textContent?.trim()||'';
|
||||
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','embed_src','embed_provider','alt','style','embed_type','collection_id','dbs','file_name','file_size','file_mime','children','rows','align','has_header','first_col_header','colsW','meeting','automation_id','automation_name'].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';});
|
||||
this._syncTitleUI();
|
||||
if(cb)cb();
|
||||
}).catch(()=>{this.saving=false;});
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user