# -*- coding: utf-8 -*- """ Trainer-View: Tabellarische Liste aller verfuegbaren Trainer. Zeigt Trainer in einer DataTable mit Name, Typ, Modell, Version. Enter/Klick auf eine Zeile oeffnet die Trainer-Detailansicht. """ from __future__ import annotations from textual.app import ComposeResult from textual.widgets import Static, DataTable from trixy_core.tui.views.base import MainView class TrainerView(MainView): """ F7: Trainer-Ansicht. Zeigt alle verfuegbaren ML-Trainer tabellarisch. Zeilen-Auswahl oeffnet Detail-Sub-Navigation. """ TITLE = "Trainer" VIEW_ID = "trainer" def __init__(self, **kwargs) -> None: super().__init__(**kwargs) self._trainers: list[dict] = [] self._refresh_counter: int = 0 def compose(self) -> ComposeResult: yield Static("", id="trainer-header") yield DataTable(id="trainer-table", cursor_type="row") yield Static("", id="trainer-status") async def on_activate(self) -> None: """Laedt die Trainer-Liste.""" table = self.query_one("#trainer-table", DataTable) if not table.columns: table.add_columns("Name", "Typ", "Modell-Typ", "Version", "Autor") await self._load_trainers() async def refresh_data(self) -> None: """Periodisches Update (alle 20 Sekunden).""" self._refresh_counter += 1 if self._refresh_counter % 10 == 0: await self._load_trainers() async def _load_trainers(self) -> None: """Laedt die Trainer-Liste vom Server.""" if not self.connection: return try: response = await self.connection.request_trainers() except Exception: self._set_status("Fehler beim Laden der Trainer", error=True) return if response is None: return self._trainers = response.trainers self._update_header() self._update_table() def _update_header(self) -> None: """Aktualisiert die Kopfzeile.""" header = self.query_one("#trainer-header", Static) total = len(self._trainers) core = sum(1 for t in self._trainers if t.get("trainer_type") == "core") plugin = total - core header.update(f"[bold]Trainer:[/bold] {total} verfuegbar ({core} Core, {plugin} Plugin)") def _update_table(self) -> None: """Aktualisiert die Trainer-Tabelle.""" table = self.query_one("#trainer-table", DataTable) table.clear() for trainer in sorted(self._trainers, key=lambda t: t.get("name", "")): name = trainer.get("name", "") trainer_type = trainer.get("trainer_type", "") model_type = trainer.get("model_type", "") version = trainer.get("version", "") author = trainer.get("author", "") type_label = "[cyan]Core[/cyan]" if trainer_type == "core" else "[green]Plugin[/green]" table.add_row( name, type_label, model_type, version, author, key=trainer.get("trainer_id", name), ) async def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None: """Enter auf einer Zeile: Oeffnet die Detail-Ansicht.""" row_key = str(event.row_key.value) if event.row_key else "" trainer_data = None for t in self._trainers: if t.get("trainer_id") == row_key: trainer_data = t break if not trainer_data: return try: app = self.app if hasattr(app, "open_trainer_detail"): await app.open_trainer_detail(trainer_data) except Exception: pass def _set_status(self, text: str, error: bool = False) -> None: """Setzt die Statuszeile.""" status = self.query_one("#trainer-status", Static) if error: status.update(f"[red]{text}[/red]") else: status.update(f"[green]{text}[/green]")