feat(workspace,editor): creation dans le dossier courant + sync live du titre (sidebar/header)
FlowDeck CI / lint (push) Successful in 54s
FlowDeck CI / test (push) Successful in 5m50s
FlowDeck CI / docker (push) Successful in 47s

- 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:
2026-09-14 17:05:03 -04:00
parent 4038e9bdad
commit 41c1d315d3
8 changed files with 110 additions and 15 deletions
+22 -3
View File
@@ -897,6 +897,15 @@
return { wsId: 0, isGitea: false, workspaceKey: wk };
},
/** Folder currently open on the local-workspace page (0 when at root). */
_currentFolderId: function() {
var ws = window._wsData;
if (ws && typeof ws.currentFolder === 'number' && ws.currentFolder > 0) {
return ws.currentFolder;
}
return 0;
},
/** Return a toast function that works across pages. */
_toast: function(msg, type) {
if (window.appState && window.appState.toast) window.appState.toast(msg, type);
@@ -907,14 +916,19 @@
* Create a new page: opens the v5.12.0 template picker (built-in + the
* user's saved templates), then instantiates the chosen one.
*/
createPage: function() {
createPage: function(parentId) {
var self = this;
// Explicit folder (row/context-menu button) wins; otherwise create in the
// folder the user is currently browsing on the local-workspace page.
if (parentId == null || parentId === '') parentId = this._currentFolderId();
this._createParentId = parentId || 0;
// Direct creation path (fallback / no-template choice).
this._createPlainPage = function() {
var ctx = self._getContext();
if (ctx.wsId > 0) {
var body = { name: '', type: 'page' };
if (ctx.isGitea) body.workspace_id = ctx.wsId;
if (self._createParentId) body.parent_id = self._createParentId;
fetch('/api/local-workspace/items', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': self.getCsrfToken() },
@@ -986,6 +1000,7 @@
var ctx = self._getContext();
if (ctx.wsId > 0) { body.workspace_id = ctx.wsId; }
else if (ctx.workspaceKey) { body.workspace = ctx.workspaceKey; }
if (self._createParentId) { body.parent_id = self._createParentId; }
if (parts[0] === 'key') { body.key = parts.slice(1).join(':'); url = '/board/api/page-templates/0/use'; }
else { url = '/board/api/page-templates/' + parts[1] + '/use'; }
fetch(url, {
@@ -999,8 +1014,10 @@
.catch(function(){ self._createPlainPage(); });
},
/** Show the global New Folder modal. */
showCreateFolderModal: function() {
/** Show the global New Folder modal (parentId = target folder, optional). */
showCreateFolderModal: function(parentId) {
if (parentId == null || parentId === '') parentId = this._currentFolderId();
this._folderParentId = parentId || 0;
var modal = document.getElementById('fd-global-folder-modal');
if (!modal) return;
modal.style.display = 'flex';
@@ -1019,6 +1036,8 @@
var ctx = this._getContext();
var body = { name: name, type: 'folder' };
if (ctx.wsId > 0 && ctx.isGitea) body.workspace_id = ctx.wsId;
if (this._folderParentId) body.parent_id = this._folderParentId;
this._folderParentId = 0;
var self = this;
fetch('/api/local-workspace/items', {