fix: Library preserves sidebar tree and categorizes by parent_section
- Sidebar data (board._sidebar_data()) no longer overwritten by library content - New variables: lib_recent, lib_favorites, lib_shared, lib_private - Pages categorized by parent_section column: Private/Favorites/Shared - Recents tab shows all non-trashed pages ordered by updated_at - library.html updated to use lib_* variables instead of sidebar data - Favorites/Shared tabs hidden when empty (lib_has_favorites/lib_has_shared)
This commit is contained in:
+38
-28
@@ -71,42 +71,52 @@ async def trash_page(request: Request, owner: str = Query(default=""), repo: str
|
|||||||
|
|
||||||
@router.get("/library", response_class=HTMLResponse)
|
@router.get("/library", response_class=HTMLResponse)
|
||||||
async def library_page(request: Request, owner: str = Query(default=""), repo: str = Query(default="")):
|
async def library_page(request: Request, owner: str = Query(default=""), repo: str = Query(default="")):
|
||||||
"""Library page avec onglets Recents, Favorites, Shared, Private — scopé au workspace."""
|
"""Library page avec onglets Recents, Favorites, Shared, Private — scopé au workspace.
|
||||||
|
|
||||||
|
La sidebar garde exactement la même arborescence que dans le workspace.
|
||||||
|
Seul le contenu principal change pour afficher les pages triées par catégorie.
|
||||||
|
"""
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
from app.routers.board import _sidebar_data as board_sidebar
|
from app.routers.board import _sidebar_data as board_sidebar
|
||||||
env = Environment(loader=FileSystemLoader("app/templates"))
|
env = Environment(loader=FileSystemLoader("app/templates"))
|
||||||
sidebar = board_sidebar(request, owner, repo)
|
sidebar = board_sidebar(request, owner, repo) # Sidebar intacte, inchangée
|
||||||
# Load all pages for the workspace from DB
|
|
||||||
ws_key = f"{owner}/{repo}" if owner and repo else ""
|
ws_key = f"{owner}/{repo}" if owner and repo else ""
|
||||||
with get_conn() as conn:
|
with get_conn() as conn:
|
||||||
|
base_query = (
|
||||||
|
"SELECT id, title, workspace, parent_section, updated_at FROM pages "
|
||||||
|
"WHERE parent_section != 'Trash'"
|
||||||
|
)
|
||||||
|
params = []
|
||||||
if ws_key:
|
if ws_key:
|
||||||
rows = conn.execute(
|
base_query += " AND workspace=?"
|
||||||
"SELECT id, title, workspace, updated_at FROM pages "
|
params.append(ws_key)
|
||||||
"WHERE workspace=? ORDER BY updated_at DESC",
|
base_query += " ORDER BY updated_at DESC"
|
||||||
(ws_key,),
|
rows = conn.execute(base_query, params).fetchall()
|
||||||
).fetchall()
|
|
||||||
else:
|
def to_page(r):
|
||||||
rows = conn.execute(
|
r = dict(r)
|
||||||
"SELECT id, title, workspace, updated_at FROM pages "
|
return {
|
||||||
"ORDER BY updated_at DESC",
|
"id": f"page/{r['id']}",
|
||||||
).fetchall()
|
"name": r["title"] or "Untitled",
|
||||||
all_pages = []
|
|
||||||
for r in rows:
|
|
||||||
page = dict(r)
|
|
||||||
all_pages.append({
|
|
||||||
"id": f"page/{page['id']}",
|
|
||||||
"name": page["title"] or "Untitled",
|
|
||||||
"icon": "📄",
|
"icon": "📄",
|
||||||
"url": f"/pages/{page['id']}",
|
"url": f"/pages/{r['id']}",
|
||||||
"created_by": "You",
|
"created_by": "You",
|
||||||
"source": page.get("workspace") or "🔒 Private",
|
"source": r.get("workspace") or "🔒 Private",
|
||||||
"last_edited": page.get("updated_at", "now"),
|
"last_edited": r.get("updated_at", "now"),
|
||||||
"last_visited": page.get("updated_at", "now"),
|
"last_visited": r.get("updated_at", "now"),
|
||||||
})
|
}
|
||||||
sidebar["recent_pages"] = all_pages
|
|
||||||
sidebar["favorite_pages"] = []
|
all_pages = [to_page(r) for r in rows]
|
||||||
sidebar["private_pages"] = [p for p in all_pages if p.get("source") == "🔒 Private"]
|
|
||||||
sidebar["shared_pages"] = []
|
# Catégoriser par parent_section — sidebar data intacte
|
||||||
|
sidebar["lib_recent"] = all_pages
|
||||||
|
sidebar["lib_favorites"] = [p for p, r in zip(all_pages, rows) if (r["parent_section"] or "") == "Favorites"]
|
||||||
|
sidebar["lib_shared"] = [p for p, r in zip(all_pages, rows) if (r["parent_section"] or "") == "Shared"]
|
||||||
|
sidebar["lib_private"] = [p for p, r in zip(all_pages, rows) if (r["parent_section"] or "Private") == "Private"]
|
||||||
|
sidebar["lib_has_favorites"] = len(sidebar["lib_favorites"]) > 0
|
||||||
|
sidebar["lib_has_shared"] = len(sidebar["lib_shared"]) > 0
|
||||||
|
|
||||||
template = env.get_template("library.html")
|
template = env.get_template("library.html")
|
||||||
return template.render(**sidebar)
|
return template.render(**sidebar)
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,16 @@
|
|||||||
<button class="view-tab" :class="{ active: tab === 'recents' }" @click="tab = 'recents'">
|
<button class="view-tab" :class="{ active: tab === 'recents' }" @click="tab = 'recents'">
|
||||||
<span class="tab-icon">🕒</span> Recents
|
<span class="tab-icon">🕒</span> Recents
|
||||||
</button>
|
</button>
|
||||||
|
{% if lib_has_favorites %}
|
||||||
<button class="view-tab" :class="{ active: tab === 'favorites' }" @click="tab = 'favorites'">
|
<button class="view-tab" :class="{ active: tab === 'favorites' }" @click="tab = 'favorites'">
|
||||||
<span class="tab-icon">⭐</span> Favorites
|
<span class="tab-icon">⭐</span> Favorites
|
||||||
</button>
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
{% if lib_has_shared %}
|
||||||
<button class="view-tab" :class="{ active: tab === 'shared' }" @click="tab = 'shared'">
|
<button class="view-tab" :class="{ active: tab === 'shared' }" @click="tab = 'shared'">
|
||||||
<span class="tab-icon">👥</span> Shared
|
<span class="tab-icon">👥</span> Shared
|
||||||
</button>
|
</button>
|
||||||
|
{% endif %}
|
||||||
<button class="view-tab" :class="{ active: tab === 'private' }" @click="tab = 'private'">
|
<button class="view-tab" :class="{ active: tab === 'private' }" @click="tab = 'private'">
|
||||||
<span class="tab-icon">🔒</span> Private
|
<span class="tab-icon">🔒</span> Private
|
||||||
</button>
|
</button>
|
||||||
@@ -61,8 +65,8 @@
|
|||||||
|
|
||||||
<!-- Recents -->
|
<!-- Recents -->
|
||||||
<div x-show="tab === 'recents'">
|
<div x-show="tab === 'recents'">
|
||||||
{% for page in recent_pages %}{{ page_row(page) }}{% endfor %}
|
{% for page in lib_recent %}{{ page_row(page) }}{% endfor %}
|
||||||
{% if not recent_pages %}
|
{% if not lib_recent %}
|
||||||
<div class="lib-empty">
|
<div class="lib-empty">
|
||||||
<div style="font-size:48px;margin-bottom:16px;">🕒</div>
|
<div style="font-size:48px;margin-bottom:16px;">🕒</div>
|
||||||
<h3>No recent pages</h3>
|
<h3>No recent pages</h3>
|
||||||
@@ -72,8 +76,8 @@
|
|||||||
|
|
||||||
<!-- Favorites -->
|
<!-- Favorites -->
|
||||||
<div x-show="tab === 'favorites'">
|
<div x-show="tab === 'favorites'">
|
||||||
{% for page in favorite_pages %}{{ page_row(page) }}{% endfor %}
|
{% for page in lib_favorites %}{{ page_row(page) }}{% endfor %}
|
||||||
{% if not favorite_pages %}
|
{% if not lib_favorites %}
|
||||||
<div class="lib-empty">
|
<div class="lib-empty">
|
||||||
<div style="font-size:48px;margin-bottom:16px;">⭐</div>
|
<div style="font-size:48px;margin-bottom:16px;">⭐</div>
|
||||||
<h3>No favorites</h3>
|
<h3>No favorites</h3>
|
||||||
@@ -84,17 +88,20 @@
|
|||||||
|
|
||||||
<!-- Shared -->
|
<!-- Shared -->
|
||||||
<div x-show="tab === 'shared'">
|
<div x-show="tab === 'shared'">
|
||||||
|
{% for page in lib_shared %}{{ page_row(page) }}{% endfor %}
|
||||||
|
{% if not lib_shared %}
|
||||||
<div class="lib-empty">
|
<div class="lib-empty">
|
||||||
<div style="font-size:48px;margin-bottom:16px;">👥</div>
|
<div style="font-size:48px;margin-bottom:16px;">👥</div>
|
||||||
<h3>No shared pages</h3>
|
<h3>No shared pages</h3>
|
||||||
<p>Shared pages from your team will appear here.</p>
|
<p>Shared pages from your team will appear here.</p>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Private -->
|
<!-- Private -->
|
||||||
<div x-show="tab === 'private'">
|
<div x-show="tab === 'private'">
|
||||||
{% for page in private_pages %}{{ page_row(page) }}{% endfor %}
|
{% for page in lib_private %}{{ page_row(page) }}{% endfor %}
|
||||||
{% if not private_pages %}
|
{% if not lib_private %}
|
||||||
<div class="lib-empty">
|
<div class="lib-empty">
|
||||||
<div style="font-size:48px;margin-bottom:16px;">🔒</div>
|
<div style="font-size:48px;margin-bottom:16px;">🔒</div>
|
||||||
<h3>No private pages</h3>
|
<h3>No private pages</h3>
|
||||||
|
|||||||
Reference in New Issue
Block a user