Seitenleiste: Eintraege ausblendbar (Backend)
Zwei Ebenen in einer Tabelle, nach dem Vorbild von DashboardLayout: user_id NULL ist die Vorgabe des Administrators, eine Zeile mit user_id die zusaetzliche Auswahl eines Kontos. Beide Listen gelten zusammen - wer etwas versteckt, versteckt es zusaetzlich; einblenden, was der Administrator ausgeblendet hat, kann niemand. Das erspart einen dritten Zustand je Eintrag. Als Schluessel dient der Routenpfad; der ist ohnehin eindeutig, eine zweite Benennung waere nur eine weitere Stelle zum Auseinanderlaufen. Drei Routen: lesen (Vorgabe, eigene Auswahl und die fertige Vereinigung in einem Zug), eigene Auswahl setzen, Vorgabe setzen (nur Admin). Die Eindeutigkeit laeuft ueber einen Index auf coalesce(user_id, -1). Ein schlichtes UNIQUE(user_id) haette zwei Vorgabezeilen zugelassen, weil NULL in SQL nie gleich NULL ist - das war im Entwurf noch falsch. Versteckt wird nur der Eintrag, nicht die Seite: Lesezeichen, Dashboard-Karten und Lagerort-QR sollen weiter funktionieren. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8f5d679d9d
commit
be267e70a5
@@ -773,6 +773,49 @@ class DashboardLayout(Base):
|
||||
)
|
||||
|
||||
|
||||
class NavigationSichtbarkeit(Base):
|
||||
"""Welche Eintraege der Seitenleiste jemand ausgeblendet hat.
|
||||
|
||||
``user_id = NULL`` ist die Vorgabe des Administrators: Was dort steht,
|
||||
bekommt niemand zu sehen. Eine Zeile mit ``user_id`` ist die zusaetzliche
|
||||
Auswahl eines Kontos.
|
||||
|
||||
**Beide Listen gelten zusammen.** Wer etwas versteckt, versteckt es
|
||||
zusaetzlich; einblenden, was der Administrator ausgeblendet hat, kann
|
||||
niemand. Das erspart einen dritten Zustand je Eintrag ("erben / zeigen /
|
||||
verstecken") und laesst sich in einem Satz erklaeren.
|
||||
|
||||
Versteckt wird nur der EINTRAG, nicht die Seite: Lesezeichen,
|
||||
Dashboard-Karten und Lagerort-QR verweisen weiter auf Routen, die hier
|
||||
abgewaehlt sein koennen.
|
||||
|
||||
Vorbild ist :class:`DashboardLayout`: eigene Tabelle statt :class:`Setting`
|
||||
(dessen ``value`` fasst 255 Zeichen und haelt genau einen Wert je
|
||||
Schluessel), Nutzlast als JSON-Text. Als Schluessel dient der Routenpfad -
|
||||
der ist ohnehin schon eindeutig, eine zweite Benennung waere nur eine
|
||||
weitere Stelle, die auseinanderlaufen kann.
|
||||
"""
|
||||
|
||||
__tablename__ = "navigation_sichtbarkeit"
|
||||
__table_args__ = (
|
||||
# Eine Zeile je Konto UND genau eine Vorgabezeile - beides mit einem
|
||||
# Index. Ueber coalesce, weil NULL in SQL nie gleich NULL ist: ein
|
||||
# schlichtes UNIQUE(user_id) liesse beliebig viele Vorgabezeilen zu.
|
||||
Index("uq_navigation_zeile", text("coalesce(user_id, -1)"), unique=True),
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
user_id: Mapped[int | None] = mapped_column(
|
||||
ForeignKey("users.id", ondelete="CASCADE"), nullable=True
|
||||
)
|
||||
# JSON-Liste von Routenpfaden, z.B. ["/rezepte", "/shopping"].
|
||||
versteckt: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
|
||||
|
||||
# Loescht man ein Konto, geht seine Zeile mit (ON DELETE CASCADE oben).
|
||||
# In den Tests greift das nicht: SQLite erzwingt Fremdschluessel nur mit
|
||||
# PRAGMA foreign_keys=ON, und das setzt die Testumgebung nicht.
|
||||
|
||||
|
||||
class EtikettenVorlage(Base):
|
||||
"""Eine gespeicherte Zusammenstellung fuer den Etikettenexport.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user