From 0593c588e9eb9ffba74544aa154387d9c7be6bcd Mon Sep 17 00:00:00 2001 From: bruno Date: Fri, 10 Jul 2026 15:46:10 -0400 Subject: [PATCH] fix: add workspace routes + RedirectResponse import to dashboard.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GET /workspace — unified workspace page - GET /api/workspace/projects — JSON API for built-in + Gitea projects - POST /api/workspace/projects — create built-in project - Added RedirectResponse to imports --- app/routers/dashboard.py | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/app/routers/dashboard.py b/app/routers/dashboard.py index 7961c76..9170a8c 100644 --- a/app/routers/dashboard.py +++ b/app/routers/dashboard.py @@ -303,3 +303,67 @@ async def dashboard( template = env.get_template("dashboard.html") return template.render(request=request, repos=repos, search=search, show_archived=show_archived, **sidebar) + + +# ═══════════ Workspace ═══════════ + +@router.get("/workspace", response_class=HTMLResponse) +async def workspace_page(request: Request): + """Unified workspace showing all projects.""" + from jinja2 import Environment, FileSystemLoader + env = Environment(loader=FileSystemLoader("app/templates")) + sidebar = _sidebar_data(request, []) + user = SessionManager.decode_session(request.cookies.get("flowdeck_session", "")) + if not user: + return RedirectResponse("/auth/login?provider=local", status_code=302) + ctx = {**sidebar, "user": user} + template = env.get_template("workspace.html") + return template.render(**ctx) + + +@router.get("/api/workspace/projects") +async def list_workspace_projects(request: Request): + """List all projects: built-in + Gitea + GitHub.""" + builtin = [] + with get_conn() as conn: + rows = conn.execute( + "SELECT id, title FROM pages WHERE parent_id IS NULL ORDER BY updated_at DESC LIMIT 20" + ).fetchall() + for r in rows: + count = conn.execute("SELECT COUNT(*) FROM pages WHERE parent_id=?", (r["id"],)).fetchone()[0] + builtin.append({"id": str(r["id"]), "name": r["title"] or "Untitled", "pageCount": count, "forge": "builtin"}) + + gitea_repos = [] + try: + repos = await gitea.get_user_repos(page=1, limit=50) + for repo in repos: + gitea_repos.append({ + "id": str(repo.get("id", "")), + "name": repo.get("name", ""), + "full_name": repo.get("full_name", ""), + "description": repo.get("description", ""), + "html_url": repo.get("html_url", ""), + "language": repo.get("language", ""), + "forge": "gitea", + }) + except Exception: + pass + + return {"builtin": builtin, "gitea": gitea_repos, "github": []} + + +@router.post("/api/workspace/projects") +async def create_workspace_project(request: Request): + import json + body = await request.json() + name = body.get("name", "").strip() + if not name: + return {"error": "Name required"} + with get_conn() as conn: + cursor = conn.execute( + "INSERT INTO pages (workspace, title, content, content_format, parent_section) VALUES ('', ?, '', 'blocks', 'Private')", + (name,), + ) + conn.commit() + pid = cursor.lastrowid + return {"id": pid, "name": name, "forge": "builtin"}