From 6a2d56a7bd543624e44606705d62700950adfa9e Mon Sep 17 00:00:00 2001 From: bruno Date: Sat, 18 Jul 2026 11:10:55 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20Library=20page=20=E2=80=94=20hover=20eff?= =?UTF-8?q?ects,=20workspace=20filter,=20tree,=20rename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Hover effects fixed: converted table to div-based flexbox layout (tr/td don't support display:flex). .lib-row now properly shows drag handle, checkbox, and OPEN button on hover. 2. Recents filter by workspace: /api/library/recents now accepts workspace_id parameter. Template passes active_workspace_id from sidebar context to API calls. 3. Tree hierarchy: API now enriches items with has_children via _enrich_children() batch query — shows expand chevrons for pages with sub-pages. 4. Rename on click: single click on title starts inline rename (was opening page). OPEN button still opens side peek. 5. Code cleanup: extracted _enrich_children() helper to eliminate duplicate code across 6 endpoints. --- app/routers/dashboard.py | 1 + app/routers/library.py | 32 +++++++++++ app/templates/library.html | 114 +++++++++++++++++++------------------ 3 files changed, 93 insertions(+), 54 deletions(-) diff --git a/app/routers/dashboard.py b/app/routers/dashboard.py index 7fadb9a..d5208a2 100644 --- a/app/routers/dashboard.py +++ b/app/routers/dashboard.py @@ -220,6 +220,7 @@ async def library_page(request: Request, owner: str = Query(default=""), repo: s sidebar["nav_workspace_id"] = ws["id"] if ws else 0 template = env.get_template("library.html") + sidebar["active_workspace_id"] = sidebar.get("nav_workspace_id", 0) return template.render(**sidebar) diff --git a/app/routers/library.py b/app/routers/library.py index c54657f..81b009c 100644 --- a/app/routers/library.py +++ b/app/routers/library.py @@ -100,6 +100,25 @@ def _rows_to_items(rows, uid: int = 1) -> list: return [_build_item(dict(r), uid) for r in rows] +def _enrich_children(items: list) -> list: + """Add has_children info to items in a single batch query.""" + if not items: + return items + ids = [it["id"] for it in items] + placeholders = ",".join(["?" for _ in ids]) + with get_conn() as conn: + child_rows = conn.execute( + f"SELECT parent_id, COUNT(*) as cnt FROM pages " + f"WHERE parent_id IN ({placeholders}) AND deleted_at IS NULL " + f"GROUP BY parent_id", + ids, + ).fetchall() + child_counts = {r["parent_id"]: r["cnt"] for r in child_rows} + for it in items: + it["has_children"] = bool(child_counts.get(it["id"], 0)) + return items + + # ═══════════ Tab endpoints ═══════════ BASE_SELECT = ( @@ -113,6 +132,7 @@ async def library_recents( request: Request, source_type: str = Query(default="all"), tree: int = Query(default=0), + workspace_id: int = Query(default=0), ): if source_type not in SOURCE_TYPES: source_type = "all" @@ -120,6 +140,12 @@ async def library_recents( uid = _get_user_id(request) query = f"{BASE_SELECT} FROM pages p WHERE p.parent_section != 'Trash' AND p.deleted_at IS NULL" params: list = [] + + # Filter by active workspace + if workspace_id: + query += " AND p.workspace_id = ?" + params.append(workspace_id) + query, params = _apply_source_filter(query, params, source_type) query += " ORDER BY p.updated_at DESC LIMIT 50" @@ -127,6 +153,7 @@ async def library_recents( rows = conn.execute(query, params).fetchall() items = _rows_to_items(rows, uid) + _enrich_children(items) return {"items": items} @@ -154,6 +181,7 @@ async def library_favorites( rows = conn.execute(query, params).fetchall() items = _rows_to_items(rows, uid) + _enrich_children(items) return {"items": items} @@ -176,6 +204,7 @@ async def library_shared( rows = conn.execute(query, params).fetchall() items = _rows_to_items(rows, uid) + _enrich_children(items) return {"items": items} @@ -198,6 +227,7 @@ async def library_published( rows = conn.execute(query, params).fetchall() items = _rows_to_items(rows, uid) + _enrich_children(items) return {"items": items} @@ -220,6 +250,7 @@ async def library_private( rows = conn.execute(query, params).fetchall() items = _rows_to_items(rows, uid) + _enrich_children(items) return {"items": items} @@ -242,4 +273,5 @@ async def library_workspace( rows = conn.execute(query, params).fetchall() items = _rows_to_items(rows, uid) + _enrich_children(items) return {"items": items} diff --git a/app/templates/library.html b/app/templates/library.html index 0610bf7..7abb2e2 100644 --- a/app/templates/library.html +++ b/app/templates/library.html @@ -11,6 +11,7 @@ {% block content %}
+ @@ -201,36 +204,34 @@
- - - - - - - - - - - - - - +
+
+
+
+
+
+
Page name
+
Created by
+
Source
+
Last edited
+
Last visited
+
+
+
-
-
-
-
Page nameCreated bySourceLast editedLast visited
+ +