feat: recursive tree, drag & drop, sub-folders in sidebar workspace
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped

- _load_workspace_pages now recursively loads children via _load_children()
- Sidebar: recursive Jinja2 macro render_workspace_tree()
- Drag & drop: HTML5 DnD — drag files into folders or reorder
- move API: PUT /api/local-workspace/items/{id}/move
- Folder hover shows 📄 (new file) + 📁 (sub-folder) buttons
- newPageInFolder/newFolderInFolder with parent_id for nesting
- Visual: dragging opacity + drop target highlight
- Items indented by depth (16px per level)
This commit is contained in:
2026-07-10 21:22:11 -04:00
parent 373153de69
commit 1ab5b1271f
3 changed files with 132 additions and 11 deletions
+30 -3
View File
@@ -141,7 +141,7 @@ def _build_page_tree(conn, parent_id: int | None, ws_key: str, depth: int = 0, m
def _load_workspace_pages(ws_cookie: str) -> list:
"""Load top-level pages for the active workspace."""
"""Load top-level pages with children for the active workspace."""
if not ws_cookie:
return []
try:
@@ -151,12 +151,39 @@ def _load_workspace_pages(ws_cookie: str) -> list:
"SELECT id, title, parent_section FROM pages WHERE workspace_id=? AND parent_id IS NULL ORDER BY created_at DESC",
(ws_id,),
).fetchall()
return [{"db_id": r["id"], "name": r["title"] or "Untitled", "id": f"page/{r['id']}",
"icon": "📁" if r["parent_section"] == "Workspace" else "📄"} for r in rows]
items = []
for r in rows:
items.append({
"db_id": r["id"], "name": r["title"] or "Untitled",
"id": f"page/{r['id']}",
"icon": "📁" if r["parent_section"] == "Workspace" else "📄",
"is_folder": r["parent_section"] == "Workspace",
"children": _load_children(r["id"]),
})
return items
except (ValueError, Exception):
return []
def _load_children(parent_id: int) -> list:
"""Recursively load children of a page."""
with get_conn() as conn:
rows = conn.execute(
"SELECT id, title, parent_section FROM pages WHERE parent_id=? ORDER BY created_at",
(parent_id,),
).fetchall()
children = []
for r in rows:
children.append({
"db_id": r["id"], "name": r["title"] or "Untitled",
"id": f"page/{r['id']}",
"icon": "📁" if r["parent_section"] == "Workspace" else "📄",
"is_folder": r["parent_section"] == "Workspace",
"children": _load_children(r["id"]),
})
return children
def _sidebar_data(request: Request, owner: str = "", repo: str = "") -> dict:
user = SessionManager.decode_session(request.cookies.get("flowdeck_session", ""))
ws_name = user.get("login", "Bruno") if user else "Bruno"