Make createPage() and createFolder() context-aware
FlowDeck CI / test (push) Failing after 3s
FlowDeck CI / docker (push) Has been skipped

- createPage() now detects active workspace context (library, local-workspace page, sidebar)
- In a local/Gitea workspace: creates workspace item via /api/local-workspace/items with prompt
- No workspace: creates general Notion page via /board/api/pages (no prompt)
- Added hidden #fd-local-ws-id in local_workspace.html to expose workspace_id
- _confirmCreateFolder() passes workspace_id for Gitea workspaces
- Added _getContext() helper that checks multiple context sources in priority order
- Added _toast() helper for cross-component notifications
This commit is contained in:
2026-07-19 21:56:46 -04:00
parent 9100da74f3
commit 98bda37484
2 changed files with 88 additions and 10 deletions
+87 -10
View File
@@ -497,9 +497,84 @@
return m ? m[1] : '';
},
/** Create a new Notion-style page (same as sidebar bottom-right button). */
/** Detect the active workspace context from multiple sources.
* Returns { wsId: number, isGitea: boolean, workspaceKey: string } */
_getContext: function() {
// 1) Library page context (most specific)
if (window._libData && window._libData.workspaceId) {
return {
wsId: window._libData.workspaceId,
isGitea: !!window._libData.isGiteaActive,
workspaceKey: (window.appState && window.appState.workspaceKey) || ''
};
}
// 2) local-workspace page (hidden element)
var wsEl = document.getElementById('fd-local-ws-id');
if (wsEl) {
var wid = parseInt(wsEl.textContent) || 0;
if (wid > 0) {
return {
wsId: wid,
isGitea: false,
workspaceKey: (window.appState && window.appState.workspaceKey) || ''
};
}
}
// 3) Sidebar Gitea workspace (localWsId is set)
if (window.appState && window.appState.localWsId) {
return {
wsId: window.appState.localWsId,
isGitea: true,
workspaceKey: window.appState.workspaceKey || ''
};
}
// 4) Sidebar has workspaceKey but no localWsId (possibly a named local ws?)
var wk = (window.appState && window.appState.workspaceKey) || '';
if (wk && wk.includes('/')) {
return { wsId: 0, isGitea: true, workspaceKey: wk };
}
// 5) No workspace context
return { wsId: 0, isGitea: false, workspaceKey: wk };
},
/** Return a toast function that works across pages. */
_toast: function(msg, type) {
if (window.appState && window.appState.toast) window.appState.toast(msg, type);
else console.log('[FlowDeck]', type, msg);
},
/**
* Create a new page/file in the correct workspace context.
* - Local workspace active → workspace item (prompts for name)
* - Gitea workspace active → workspace item with workspace_id (prompts for name)
* - No workspace → general Notion page (no prompt, title "New page")
*/
createPage: function() {
var project = (window.appState && window.appState.workspaceKey) || '';
var ctx = this._getContext();
var self = this;
// ── Workspace context → create workspace item ──
if (ctx.wsId > 0) {
var name = prompt('File name:');
if (!name || !name.trim()) return;
var body = { name: name.trim(), type: 'page' };
if (ctx.isGitea) body.workspace_id = ctx.wsId;
fetch('/api/local-workspace/items', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': this.getCsrfToken() },
body: JSON.stringify(body)
})
.then(function(r) { if (!r.ok) throw new Error('Failed'); return r.json(); })
.then(function(data) {
window.location.href = '/pages/' + data.id;
})
.catch(function(err) { self._toast('Failed: ' + err.message, 'error'); });
return;
}
// ── No workspace → general Notion page ──
var project = ctx.workspaceKey;
var url = '/board/api/pages?section=Private&project=' + encodeURIComponent(project);
fetch(url, {
method: 'POST',
@@ -507,10 +582,7 @@
})
.then(function(r) { if (!r.ok) throw new Error('CSRF or API error'); return r.json(); })
.then(function(data) { window.location.href = '/pages/' + data.id; })
.catch(function(err) {
if (window.appState && window.appState.toast) window.appState.toast('Failed to create page: ' + err.message, 'error');
else alert('Failed to create page: ' + err.message);
});
.catch(function(err) { self._toast('Failed to create page: ' + err.message, 'error'); });
},
/** Show the global New Folder modal. */
@@ -529,11 +601,16 @@
if (!name) return;
var modal = document.getElementById('fd-global-folder-modal');
if (modal) modal.style.display = 'none';
var ctx = this._getContext();
var body = { name: name, type: 'folder' };
if (ctx.wsId > 0 && ctx.isGitea) body.workspace_id = ctx.wsId;
var self = this;
fetch('/api/local-workspace/items', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': this.getCsrfToken() },
body: JSON.stringify({ name: name, type: 'folder' })
body: JSON.stringify(body)
})
.then(function(r) { if (!r.ok) throw new Error('Failed'); return r.json(); })
.then(function() {
@@ -543,11 +620,11 @@
document.dispatchEvent(new CustomEvent('flowdeck:workspace-changed'));
if (window._wsData && window._wsData._reloadAfterAction) window._wsData._reloadAfterAction();
// Show toast
if (window.appState && window.appState.toast) window.appState.toast('Folder created', 'success');
self._toast('Folder created', 'success');
})
.catch(function(err) {
if (window.appState && window.appState.toast) window.appState.toast('Failed: ' + err.message, 'error');
else alert('Failed to create folder: ' + err.message);
self._toast('Failed: ' + err.message, 'error');
alert('Failed to create folder: ' + err.message);
});
}
};
+1
View File
@@ -10,6 +10,7 @@
{% endblock %}
{% block content %}
<span id="fd-local-ws-id" hidden>{{ workspace_id }}</span>
<div x-data="_wsInitData"
@dragover.prevent="onDragOver($event)"
@dragleave="onDragLeave($event)"