From 25386bc79f0ef26afdc62f684c72b0926abc1411 Mon Sep 17 00:00:00 2001 From: bruno Date: Fri, 17 Jul 2026 23:43:16 -0400 Subject: [PATCH] feat: breadcrumb hover Notion-style + nav_workspace_id sur toutes les pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _header.html: remplace click par hover (mouseenter/mouseleave) avec timer 200ms anti-flicker, cascade sous-menus au hover - dashboard.py: ajoute nav_workspace_id à trash, library, workspace, gitea-workspace, local-workspace, workspaces, settings, pages/{id} - La section du popover affiche 'Workspaces' pour Home, 'Private' pour le reste - Les clics dans les popovers ferment le menu + naviguent --- app/routers/dashboard.py | 23 +++++++++++ app/templates/_header.html | 78 ++++++++++++++++++++++++++++---------- 2 files changed, 80 insertions(+), 21 deletions(-) diff --git a/app/routers/dashboard.py b/app/routers/dashboard.py index 44f8a22..f39aa5c 100644 --- a/app/routers/dashboard.py +++ b/app/routers/dashboard.py @@ -192,6 +192,9 @@ async def trash_page(request: Request, owner: str = Query(default=""), repo: str "SELECT id, title, workspace FROM pages WHERE parent_section='Trash' ORDER BY updated_at DESC", ).fetchall() sidebar["trash_items"] = [{"id": r["id"], "name": r["title"] or "Untitled", "workspace": r["workspace"]} for r in rows] + # Pass active workspace for breadcrumb nav menu + ws = _get_active_workspace(request, user_id=_get_user_id(request)) + sidebar["nav_workspace_id"] = ws["id"] if ws else 0 template = env.get_template("trash.html") return template.render(**sidebar) @@ -206,6 +209,15 @@ async def library_page(request: Request, owner: str = Query(default=""), repo: s from app.routers.board import _sidebar_data as board_sidebar env = Environment(loader=FileSystemLoader("app/templates")) sidebar = board_sidebar(request, owner, repo) + # Pass active workspace for breadcrumb nav menu + ws_key_ws = f"{owner}/{repo}" if owner and repo else "" + if ws_key_ws: + with get_conn() as conn: + ws_row = conn.execute("SELECT id FROM workspaces WHERE name=? AND owner_id=?", (ws_key_ws, _get_user_id(request))).fetchone() + sidebar["nav_workspace_id"] = ws_row["id"] if ws_row else 0 + else: + ws = _get_active_workspace(request, user_id=_get_user_id(request)) + sidebar["nav_workspace_id"] = ws["id"] if ws else 0 template = env.get_template("library.html") return template.render(**sidebar) @@ -447,6 +459,9 @@ async def workspace_page(request: Request): if not user: return RedirectResponse("/auth/login?provider=local", status_code=302) ctx = {**sidebar, "user": user} + # Pass active workspace for breadcrumb nav menu + ws = _get_active_workspace(request, user_id=_get_user_id(request)) + ctx["nav_workspace_id"] = ws["id"] if ws else 0 template = env.get_template("workspace.html") return template.render(**ctx) @@ -498,6 +513,7 @@ async def gitea_workspace_page(request: Request): "workspace_initial": repo[0].upper() if repo else "G", "owner": owner, "repo": repo, + "nav_workspace_id": local_ws_id or 0, # for breadcrumb nav menu } template = env.get_template("gitea_workspace.html") resp = HTMLResponse(content=template.render(**ctx)) @@ -661,6 +677,7 @@ async def local_workspace_page(request: Request, folder: int = None): "workspace_name": sidebar.get("active_ws_name", "My Workspace"), "current_folder_id": current_folder_id or 0, "workspace_id": ws_id or 0, + "nav_workspace_id": ws_id or 0, "breadcrumb": breadcrumb, } template = env.get_template("local_workspace.html") @@ -1244,6 +1261,9 @@ async def workspaces_page(request: Request): if not user: return RedirectResponse("/auth/login?provider=local", status_code=302) ctx = {**sidebar, "user": user} + # Pass active workspace for breadcrumb nav menu (null on workspaces home) + ws = _get_active_workspace(request, user_id=_get_user_id(request)) + ctx["nav_workspace_id"] = ws["id"] if ws else 0 template = env.get_template("workspaces.html") return template.render(**ctx) @@ -1346,6 +1366,9 @@ async def app_settings_page(request: Request): if not user: return RedirectResponse("/auth/login?provider=local", status_code=302) ctx = {**sidebar, "user": user} + # Pass active workspace for breadcrumb nav menu + ws = _get_active_workspace(request, user_id=_get_user_id(request)) + ctx["nav_workspace_id"] = ws["id"] if ws else 0 template = env.get_template("settings.html") return template.render(**ctx) diff --git a/app/templates/_header.html b/app/templates/_header.html index b6eede6..f085e78 100644 --- a/app/templates/_header.html +++ b/app/templates/_header.html @@ -48,7 +48,8 @@ -
+
{% if page_icon %} {{ page_icon }} {% endif %} @@ -57,11 +58,15 @@ {# ── Collapsed "…" segment ── #}