70 lines
2.3 KiB
Python
70 lines
2.3 KiB
Python
"""Hilfsfunktionen des Projekte-Moduls.
|
|
|
|
Enthält die feste Farbpalette (zyklisch zugewiesen), die Fälligkeits-Badge-Logik
|
|
(portiert aus dem Prototyp `dueBadge`), die Aufgaben-Sortierung und ein
|
|
locale-unabhängiges deutsches Datumslabel.
|
|
"""
|
|
|
|
from datetime import date
|
|
|
|
# Feste Palette wie im Prototyp — neue Projekte bekommen zyklisch die nächste Farbe.
|
|
PROJECT_COLORS = [
|
|
"#e94560", "#f5a623", "#4ecca3", "#a78bfa", "#60a5fa",
|
|
"#f472b6", "#34d399", "#fb923c", "#818cf8", "#38bdf8",
|
|
]
|
|
|
|
_WEEKDAYS_DE = [
|
|
"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag",
|
|
]
|
|
_MONTHS_DE = [
|
|
"Januar", "Februar", "März", "April", "Mai", "Juni",
|
|
"Juli", "August", "September", "Oktober", "November", "Dezember",
|
|
]
|
|
|
|
|
|
def next_color(existing_count: int) -> str:
|
|
"""Nächste Farbe aus der Palette (zyklisch nach Anzahl vorhandener Projekte)."""
|
|
return PROJECT_COLORS[existing_count % len(PROJECT_COLORS)]
|
|
|
|
|
|
def _fmt(d: date) -> str:
|
|
"""Datum als dd.mm.yy (wie im Prototyp)."""
|
|
return f"{d.day:02d}.{d.month:02d}.{str(d.year)[2:]}"
|
|
|
|
|
|
def due_badge(due: date | None, done: bool) -> dict:
|
|
"""Fälligkeits-Badge: CSS-Klasse + Text. Portiert aus dem Prototyp.
|
|
|
|
- kein Datum -> 'kein Datum' (neutral)
|
|
- erledigt -> Datum neutral
|
|
- überfällig -> rot, mit Tagen drüber
|
|
- <= 7 Tage -> orange, mit Resttagen
|
|
- sonst -> grün
|
|
"""
|
|
if due is None:
|
|
return {"cls": "due-none", "text": "kein Datum"}
|
|
|
|
label = _fmt(due)
|
|
if done:
|
|
return {"cls": "due-none", "text": label}
|
|
|
|
diff = (due - date.today()).days
|
|
if diff < 0:
|
|
return {"cls": "due-overdue", "text": f"⚠ {label} ({abs(diff)}d über)"}
|
|
if diff <= 7:
|
|
return {"cls": "due-soon", "text": f"⏳ {label} ({diff}d)"}
|
|
return {"cls": "due-ok", "text": f"📅 {label}"}
|
|
|
|
|
|
def sort_tasks(tasks: list) -> list:
|
|
"""Sortierung wie im Prototyp: offen vor erledigt, dann nach Datum (ohne zuletzt)."""
|
|
return sorted(
|
|
tasks,
|
|
key=lambda t: (t.done, t.due_date is None, t.due_date or date.max),
|
|
)
|
|
|
|
|
|
def today_label() -> str:
|
|
"""Deutsches Datumslabel ohne Locale-Abhängigkeit (z.B. 'Donnerstag, 11. Juni 2026')."""
|
|
d = date.today()
|
|
return f"{_WEEKDAYS_DE[d.weekday()]}, {d.day}. {_MONTHS_DE[d.month - 1]} {d.year}"
|