feat: auto-create local workspace mirror for Gitea projects
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped

- Opening /gitea-workspace auto-creates a local workspace with same name
- New Page/New Folder in remote context → saves to local mirror workspace
- Sidebar stays focused on remote workspace (🔗 icon, remote tree)
- local_ws_id passed to Alpine for API calls
- /api/local-workspace/items accepts workspace_id in body
This commit is contained in:
2026-07-14 15:24:43 -04:00
parent 7c3f62d094
commit e8f4cfb631
2 changed files with 60 additions and 12 deletions
+42 -3
View File
@@ -113,10 +113,25 @@ def _sidebar_data(request: Request, repos: list[dict]) -> dict:
except Exception:
pass
# Get local workspace ID for Gitea workspace mirror
local_ws_id = 0
if gitea_workspace and gitea_owner and gitea_repo:
try:
with get_conn() as conn:
row = conn.execute(
"SELECT id FROM workspaces WHERE owner_id=? AND name=? AND settings_json LIKE ?",
(user["id"], f"{gitea_owner}/{gitea_repo}", "%gitea_repo%")
).fetchone()
if row:
local_ws_id = row["id"]
except Exception:
pass
return {
"workspace_name": ws, "workspace_initial": initial,
"active_ws_name": active_ws_name,
"workspace_key": f"{gitea_owner}/{gitea_repo}" if gitea_workspace else "",
"local_ws_id": local_ws_id,
"workspace_pages": workspace_pages,
"gitea_workspace": gitea_workspace,
"current_page": "Dashboard", "last_edited": "now",
@@ -385,6 +400,27 @@ async def gitea_workspace_page(request: Request):
repo = request.query_params.get("repo", "")
ws_key = f"{owner}/{repo}" if owner and repo else ""
ws_name = ws_key or "Gitea Workspace"
# Auto-create local workspace mirror for storing local files
local_ws_id = None
if ws_key:
with get_conn() as conn:
existing = conn.execute(
"SELECT id, owner_id FROM workspaces WHERE owner_id=? AND name=? AND settings_json LIKE ?",
(user["id"], ws_key, "%gitea_repo%")
).fetchone()
if existing:
local_ws_id = existing["id"]
else:
c = conn.execute(
"INSERT INTO workspaces (name, owner_id, settings_json) VALUES (?, ?, ?)",
(ws_key, user["id"], json.dumps({"gitea_repo": ws_key, "gitea_owner": owner}))
)
local_ws_id = c.lastrowid
conn.execute(
"INSERT INTO workspace_members (workspace_id, user_id, role) VALUES (?, ?, ?)",
(local_ws_id, user["id"], "admin")
)
conn.commit()
ctx = {
**sidebar,
"user": user,
@@ -394,6 +430,7 @@ async def gitea_workspace_page(request: Request):
"workspace_initial": repo[0].upper() if repo else "G",
"owner": owner,
"repo": repo,
"local_ws_id": local_ws_id or 0,
}
template = env.get_template("gitea_workspace.html")
resp = HTMLResponse(content=template.render(**ctx))
@@ -726,14 +763,16 @@ async def create_local_workspace_item(request: Request):
name = body.get("name", "Untitled").strip()
item_type = body.get("type", "page")
parent_id = body.get("parent_id")
explicit_ws_id = body.get("workspace_id")
ws = _get_active_workspace(request)
ws_id = ws["id"] if ws else None
ws_id = explicit_ws_id or (ws["id"] if ws else None)
ws_key = ws["workspace_key"] if ws and not explicit_ws_id else ""
section = 'Workspace' if item_type == 'folder' else 'Private'
with get_conn() as conn:
cursor = conn.execute(
"INSERT INTO pages (workspace, workspace_id, title, content, content_format, parent_section, parent_id) "
"VALUES ('', ?, ?, '', 'blocks', ?, ?)",
(ws_id, name, section, parent_id),
"VALUES (?, ?, ?, '', 'blocks', ?, ?)",
(ws_key, ws_id, name, section, parent_id)
)
conn.commit()
pid = cursor.lastrowid