P1: Einheitliche klassische Pagination (Neuheiten, Planung, Audit-Log)
- Infinite Scroll ersetzt durch Zurück/Weiter + Seitenzahlen-Fenster (funktioniert ohne JavaScript) - Gemeinsames Makro seitennavigation.html (aria-current auf aktiver Seite, deaktivierte Buttons als span) - Neuheiten: Pagination bleibt beim HTMX-Filter-Swap innerhalb von #neuheiten-liste konsistent; Filter/Sortierung/Jahr bleiben in den Seiten-URLs erhalten - Audit-Log: gleiche Optik statt reiner Text-Links
This commit is contained in:
@@ -27,7 +27,8 @@ import logging
|
||||
import os
|
||||
import threading
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from urllib.parse import quote
|
||||
from math import ceil
|
||||
from urllib.parse import quote, urlencode
|
||||
|
||||
from fastapi import Depends, Form, HTTPException, Request
|
||||
from fastapi.responses import RedirectResponse
|
||||
@@ -113,6 +114,7 @@ class NeuheitenPlugin(BasePlugin):
|
||||
abwaerts = richtung == "ab" if sort in SORTIERBAR else False
|
||||
spalte_sortiert = spalte.desc() if abwaerts else spalte.asc()
|
||||
pro_seite = 50
|
||||
seite_aktuell = max(seite_nr, 1)
|
||||
|
||||
with self.context.session_factory() as db:
|
||||
abfrage = select(Neuheit)
|
||||
@@ -148,9 +150,11 @@ class NeuheitenPlugin(BasePlugin):
|
||||
) if j is not None
|
||||
]
|
||||
gesamt = db.scalar(select(func.count()).select_from(abfrage.subquery())) or 0
|
||||
gesamt_seiten = max(1, ceil(gesamt / pro_seite))
|
||||
seite_aktuell = min(seite_aktuell, gesamt_seiten)
|
||||
eintraege = db.scalars(
|
||||
abfrage.order_by(spalte_sortiert, Neuheit.id.asc())
|
||||
.offset((max(seite_nr, 1) - 1) * pro_seite)
|
||||
.offset((seite_aktuell - 1) * pro_seite)
|
||||
.limit(pro_seite)
|
||||
).all()
|
||||
status_optionen = [
|
||||
@@ -160,7 +164,18 @@ class NeuheitenPlugin(BasePlugin):
|
||||
]
|
||||
|
||||
quellen_zeilen = self._quellen_uebersicht(db)
|
||||
hat_weitere = max(seite_nr, 1) * pro_seite < gesamt
|
||||
|
||||
def _seiten_url(nr: int) -> str:
|
||||
parameter = {
|
||||
"q": q,
|
||||
"status": status,
|
||||
"sort": sort if sort in SORTIERBAR else STANDARD_SORTIERUNG[0],
|
||||
"richtung": "ab" if abwaerts else "auf",
|
||||
"seite_nr": str(nr),
|
||||
}
|
||||
if jahr is not None:
|
||||
parameter["jahr"] = str(jahr)
|
||||
return f"/neuheiten?{urlencode(parameter)}"
|
||||
kontext = {
|
||||
"user": user,
|
||||
"titel": self.title,
|
||||
@@ -182,8 +197,9 @@ class NeuheitenPlugin(BasePlugin):
|
||||
"suchbegriffe": ", ".join(self._suchbegriffe) or "—",
|
||||
"sync_aktiv": self._scheduler is not None and self._scheduler.running,
|
||||
"anzahl": gesamt,
|
||||
"hat_weitere": hat_weitere,
|
||||
"naechste_seite": max(seite_nr, 1) + 1,
|
||||
"seite": seite_aktuell,
|
||||
"gesamt_seiten": gesamt_seiten,
|
||||
"seiten_url": _seiten_url,
|
||||
"quellen_zeilen": quellen_zeilen,
|
||||
"quellen_sync_aktiv": (
|
||||
os.environ.get("SPIELE_NEUHEITEN_QUELLEN_SYNC_AKTIV", "1").strip()
|
||||
|
||||
Reference in New Issue
Block a user