diff --git a/app/routers/board.py b/app/routers/board.py index db894b2..f12f303 100644 --- a/app/routers/board.py +++ b/app/routers/board.py @@ -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" diff --git a/app/routers/dashboard.py b/app/routers/dashboard.py index 4805a50..585b77e 100644 --- a/app/routers/dashboard.py +++ b/app/routers/dashboard.py @@ -581,6 +581,21 @@ async def delete_local_workspace_item(request: Request, item_id: int): return {"status": "ok"} +@router.put("/api/local-workspace/items/{item_id:int}/move") +async def move_local_workspace_item(request: Request, item_id: int): + """Move an item to a new parent (drag & drop).""" + import json + body = await request.json() + new_parent_id = body.get("parent_id") # None = move to root + with get_conn() as conn: + conn.execute( + "UPDATE pages SET parent_id=? WHERE id=?", + (new_parent_id, item_id), + ) + conn.commit() + return {"status": "ok"} + + # ═══════════ Workspaces CRUD ═══════════ WORKSPACE_COOKIE = "flowdeck_workspace" diff --git a/app/templates/base.html b/app/templates/base.html index 457ea6e..fd575a0 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -92,16 +92,38 @@ +{% macro render_workspace_tree(pages, depth=0) %} + {% for page in pages %} +