mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-07-01 03:04:52 +02:00
feat: show housekeeper task details
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
"Regelskripte im Mitglieder-Store können eingebaute Regeln anhand ihres Dateinamens gezielt ersetzen.",
|
||||
"Beschädigte Beitragsdateien blockieren die Mitgliederansicht nicht mehr und werden vom Hausmeister ohne automatisches Überschreiben gemeldet.",
|
||||
"Ein Akten-Preflight sperrt bei beschädigten Mitglieder-, Beitrags- oder Eventdateien alle Regeln für die betroffene Akte.",
|
||||
"Der Hausmeister-Tab zeigt den vollständigen Inhalt eines markierten Vorgangs in einem mehrzeiligen Detailbereich.",
|
||||
"Hausmeister um konfigurierbare Geburtstags- und Mitgliedsjubiläumsmeldungen erweitert.",
|
||||
"Statusänderungen werden mit altem und neuem Klartextwert in der Mitgliederchronik protokolliert.",
|
||||
"Fensterposition, normaler Fensterzustand und Maximierung werden gespeichert; der Splash startet auf dem zuletzt verwendeten Monitor.",
|
||||
|
||||
@@ -227,6 +227,24 @@ class HousekeeperTab(ttk.Frame):
|
||||
self.tree.column(key, width=width, anchor="w")
|
||||
self.tree.grid(row=1, column=0, sticky="nsew")
|
||||
self.tree.bind("<Double-1>", lambda _event: self._open_selected())
|
||||
self.tree.bind("<<TreeviewSelect>>", lambda _event: self._show_selected_details())
|
||||
details = ttk.LabelFrame(self, text="Details", padding=12)
|
||||
details.grid(row=2, column=0, sticky="ew", pady=(10, 0))
|
||||
details.columnconfigure(0, weight=1)
|
||||
self.detail_var = tk.StringVar(value="Eintrag auswählen, um Details anzuzeigen.")
|
||||
self.detail_label = ttk.Label(
|
||||
details,
|
||||
textvariable=self.detail_var,
|
||||
anchor="nw",
|
||||
justify="left",
|
||||
wraplength=800,
|
||||
style="Status.TLabel",
|
||||
)
|
||||
self.detail_label.grid(row=0, column=0, sticky="ew")
|
||||
details.bind(
|
||||
"<Configure>",
|
||||
lambda event: self.detail_label.configure(wraplength=max(300, event.width - 32)),
|
||||
)
|
||||
self._render()
|
||||
|
||||
def refresh(self) -> None:
|
||||
@@ -235,6 +253,7 @@ class HousekeeperTab(ttk.Frame):
|
||||
|
||||
def _render(self) -> None:
|
||||
self.tree.delete(*self.tree.get_children())
|
||||
self.detail_var.set("Eintrag auswählen, um Details anzuzeigen.")
|
||||
self.title_var.set(f"HAUSMEISTER · {len(self.findings)} Vorgänge")
|
||||
for index, finding in enumerate(self.findings):
|
||||
self.tree.insert(
|
||||
@@ -244,7 +263,26 @@ class HousekeeperTab(ttk.Frame):
|
||||
values=(finding.severity.upper(), finding.title, finding.detail, finding.due_date or ""),
|
||||
)
|
||||
|
||||
def _show_selected_details(self) -> None:
|
||||
selected = self.tree.selection()
|
||||
if not selected:
|
||||
self.detail_var.set("Eintrag auswählen, um Details anzuzeigen.")
|
||||
return
|
||||
index = int(selected[0])
|
||||
if index >= len(self.findings):
|
||||
return
|
||||
self.detail_var.set(_finding_details(self.findings[index]))
|
||||
|
||||
def _open_selected(self) -> None:
|
||||
selected = self.tree.selection()
|
||||
if selected:
|
||||
self.on_open_member(self.findings[int(selected[0])].member_id)
|
||||
|
||||
|
||||
def _finding_details(finding: HousekeeperFinding) -> str:
|
||||
lines = [f"{finding.severity.upper()} · {finding.code}", finding.title]
|
||||
if finding.due_date:
|
||||
lines.append(f"Fällig: {format_date_for_display(finding.due_date.isoformat())}")
|
||||
if finding.detail:
|
||||
lines.extend(("", finding.detail))
|
||||
return "\n".join(lines)
|
||||
|
||||
@@ -38,3 +38,24 @@ def test_event_labels_hide_board_actor_but_keep_automatic_marker() -> None:
|
||||
system_event = Event("2", "2026-01-01T00:00:00+01:00", "automatic", "Automatisch")
|
||||
assert _event_label(user_event) == "Kommentar"
|
||||
assert _event_label(system_event) == "[AUTO] Automatisch"
|
||||
|
||||
|
||||
def test_housekeeper_details_are_multiline() -> None:
|
||||
from datetime import date
|
||||
|
||||
from ccma.domain.models import HousekeeperFinding
|
||||
from ccma.ui.work_tabs import _finding_details
|
||||
|
||||
finding = HousekeeperFinding(
|
||||
severity="error",
|
||||
member_id="member-1",
|
||||
code="invalid_member_record",
|
||||
title="Mitgliederakte beschädigt",
|
||||
detail="Die JSON-Datei ist leer und wird nicht automatisch überschrieben.",
|
||||
due_date=date(2026, 7, 31),
|
||||
)
|
||||
|
||||
rendered = _finding_details(finding)
|
||||
assert rendered.splitlines()[0] == "ERROR · invalid_member_record"
|
||||
assert "Mitgliederakte beschädigt\nFällig:" in rendered
|
||||
assert rendered.endswith("nicht automatisch überschrieben.")
|
||||
|
||||
Reference in New Issue
Block a user