diff --git a/app/main.py b/app/main.py index eff7ae4..2763f9d 100644 --- a/app/main.py +++ b/app/main.py @@ -75,6 +75,28 @@ def facets(db: Session, user: User) -> dict: } +# Auswahl für die Sortierung: Wert -> Beschriftung in der Oberfläche. +SORT_OPTIONS = { + "date_desc": "Neueste zuerst", + "date_asc": "Älteste zuerst", + "name_asc": "Name A–Z", + "name_desc": "Name Z–A", +} +DEFAULT_SORT = "date_desc" + + +def sort_links(links: list[Link], sort: str) -> list[Link]: + if sort == "date_asc": + return sorted(links, key=lambda link: link.created_at) + if sort == "name_asc": + return sorted(links, key=lambda link: (link.title or link.url).lower()) + if sort == "name_desc": + return sorted( + links, key=lambda link: (link.title or link.url).lower(), reverse=True + ) + return sorted(links, key=lambda link: link.created_at, reverse=True) + + def query_links( db: Session, user: User, @@ -82,6 +104,7 @@ def query_links( category: str = "", manufacturer: str = "", semantic: bool = False, + sort: str = DEFAULT_SORT, ) -> list[Link]: stmt = select(Link).where(Link.user_id == user.id) if category: @@ -92,18 +115,18 @@ def query_links( q = (q or "").strip() if not q: - return links + return sort_links(links, sort) if semantic and config.AI_ENABLED: query_vec = ai.embed(q) ranked = search.cosine_rank(query_vec, links) result = [link for link, score in ranked if score > 0.20][:50] if result: - return result + return sort_links(result, sort) # Fallback auf Textsuche, falls keine Embeddings vorhanden sind. ql = q.lower() - return [ + matches = [ link for link in links if ql @@ -111,6 +134,7 @@ def query_links( [link.title, link.summary, link.tags, link.category, link.manufacturer] ).lower() ] + return sort_links(matches, sort) # --------------------------------------------------------------------------- @@ -192,14 +216,17 @@ def index( category: str = "", manufacturer: str = "", semantic: str = "", + sort: str = DEFAULT_SORT, db: Session = Depends(get_db), ): user = current_user(request, db) if not user: return RedirectResponse("/login", status_code=303) + if sort not in SORT_OPTIONS: + sort = DEFAULT_SORT is_semantic = semantic in ("1", "on", "true") - links = query_links(db, user, q, category, manufacturer, is_semantic) + links = query_links(db, user, q, category, manufacturer, is_semantic, sort) return templates.TemplateResponse( "index.html", { @@ -212,6 +239,8 @@ def index( "active_manufacturer": manufacturer, "semantic": is_semantic, "ai_enabled": config.AI_ENABLED, + "sort": sort, + "sort_options": SORT_OPTIONS, }, ) @@ -223,14 +252,17 @@ def search_links( category: str = "", manufacturer: str = "", semantic: str = "", + sort: str = DEFAULT_SORT, db: Session = Depends(get_db), ): user = current_user(request, db) if not user: return Response(status_code=401, headers={"HX-Redirect": "/login"}) + if sort not in SORT_OPTIONS: + sort = DEFAULT_SORT is_semantic = semantic in ("1", "on", "true") - links = query_links(db, user, q, category, manufacturer, is_semantic) + links = query_links(db, user, q, category, manufacturer, is_semantic, sort) return templates.TemplateResponse( "_links_list.html", {"request": request, "links": links} ) diff --git a/app/templates/base.html b/app/templates/base.html index 8332275..2efb57a 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -38,7 +38,12 @@ background: var(--panel2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 10px 12px; font-size: .95rem; width: 100%; } - input:focus { outline: none; border-color: var(--accent); } + input:focus, select:focus { outline: none; border-color: var(--accent); } + select { + background: var(--panel2); border: 1px solid var(--border); color: var(--text); + border-radius: 8px; padding: 6px 10px; font-size: .85rem; font-family: inherit; + cursor: pointer; + } .layout { display: flex; gap: 24px; max-width: 1200px; margin: 24px auto; padding: 0 24px; } .sidebar { width: 240px; flex-shrink: 0; } .main { flex: 1; min-width: 0; } diff --git a/app/templates/index.html b/app/templates/index.html index de4efc7..c3cdaa0 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -19,14 +19,14 @@