diff --git a/app/routers/library.py b/app/routers/library.py index 81b009c..5b270ae 100644 --- a/app/routers/library.py +++ b/app/routers/library.py @@ -70,6 +70,7 @@ def _build_item(db_row: dict, uid: int = 1) -> dict: "id": page_id, "title": title, "icon": icon, + "is_folder": bool(db_row.get("is_folder", 0)), "source_type": source_type, "source_label": _source_label(source_type, workspace), "workspace": workspace, @@ -254,6 +255,22 @@ async def library_private( return {"items": items} +@router.get("/children/{page_id:int}") +async def library_children(page_id: int, request: Request): + """Return child pages for a given parent page (for tree expansion in Library).""" + uid = _get_user_id(request) + with get_conn() as conn: + rows = conn.execute( + f"{BASE_SELECT}, p.is_folder, (SELECT COUNT(*) FROM pages c WHERE c.parent_id = p.id AND c.deleted_at IS NULL) as child_count " + f"FROM pages p WHERE p.parent_id = ? AND p.deleted_at IS NULL " + f"ORDER BY p.is_folder DESC, p.title COLLATE NOCASE", + [page_id], + ).fetchall() + items = _rows_to_items(rows, uid) + _enrich_children(items) + return {"items": items} + + @router.get("/workspace") async def library_workspace( request: Request, diff --git a/app/templates/library.html b/app/templates/library.html index 7abb2e2..5fc54e4 100644 --- a/app/templates/library.html +++ b/app/templates/library.html @@ -58,17 +58,17 @@ .lib-row .row-cell{display:flex;align-items:center;padding:0 8px;height:100%;overflow:hidden;} /* Hover-only elements */ -.lib-row .hover-only{opacity:0;transition:opacity 0.1s;} +.lib-row .hover-only{opacity:0.35;transition:opacity 0.15s;} .lib-row:hover .hover-only{opacity:1;} /* Drag handle — 6 dots */ -.drag-handle{display:flex;flex-wrap:wrap;width:14px;height:14px;cursor:grab;align-content:space-between;justify-content:space-between;flex-shrink:0;} -.drag-handle:hover{opacity:1!important;} +.drag-handle{display:flex;flex-wrap:wrap;width:16px;height:16px;cursor:grab;align-content:space-between;justify-content:space-between;flex-shrink:0;opacity:0.45;} +.lib-row:hover .drag-handle{opacity:1;} .drag-handle .dot{width:3px;height:3px;background:var(--text-tertiary);border-radius:50%;} /* Checkbox */ -.lib-checkbox{width:14px;height:14px;border:1.5px solid var(--text-tertiary);border-radius:3px;cursor:pointer;flex-shrink:0;display:flex;align-items:center;justify-content:center;transition:all 0.1s;} -.lib-checkbox:hover{border-color:var(--text-primary);} +.lib-checkbox{width:15px;height:15px;border:1.5px solid var(--text-tertiary);border-radius:3px;cursor:pointer;flex-shrink:0;display:flex;align-items:center;justify-content:center;transition:all 0.15s;} +.lib-row:hover .lib-checkbox{border-color:var(--text-secondary);} .lib-checkbox.checked{background:var(--accent);border-color:var(--accent);} .lib-checkbox.checked::after{content:'✓';color:#fff;font-size:10px;font-weight:700;} @@ -204,7 +204,7 @@ -