From 8f623e1df693513cdc7218951d54568cb5dc5848 Mon Sep 17 00:00:00 2001 From: enzo Date: Wed, 13 May 2026 01:54:57 +0200 Subject: [PATCH] fix(ui): remove reactive vars in SummaryPanel, use direct widget update - Replace reactive attributes with direct widget updates in set_target - Delay _select_target by 0.1s after pop_screen to ensure DOM is stable - Remove summary.refresh() calls that interfere with direct updates --- full_updater/app.py | 3 +- full_updater/ui/summary.py | 73 ++++++++++++-------------------------- 2 files changed, 23 insertions(+), 53 deletions(-) diff --git a/full_updater/app.py b/full_updater/app.py index 969a526..0df0f6d 100644 --- a/full_updater/app.py +++ b/full_updater/app.py @@ -109,7 +109,7 @@ class FullUpdaterApp(App): ) sidebar.refresh() if self.targets: - self._select_target(self.targets[0].target_id) + self.set_timer(0.1, lambda: self._select_target(self.targets[0].target_id)) def _select_target(self, target_id: str): self.selected_target = target_id @@ -130,7 +130,6 @@ class FullUpdaterApp(App): skipped=not data and any(t.target_id == target_id and not t.is_host and not lxc_is_running(t.target_id) for t in self.targets), cache_time=get_cache_timestamp(cache_id) ) - summary.refresh() def on_sidebar_target_selected(self, event: Sidebar.TargetSelected): self._select_target(event.target_id) diff --git a/full_updater/ui/summary.py b/full_updater/ui/summary.py index b012b9f..fb93ca0 100644 --- a/full_updater/ui/summary.py +++ b/full_updater/ui/summary.py @@ -1,6 +1,5 @@ from textual.widgets import Static, Button from textual.containers import Vertical, Horizontal -from textual.reactive import reactive from textual.message import Message @@ -26,10 +25,6 @@ class SummaryPanel(Vertical): height: auto; margin: 1 0; } - .summary-count { - color: $primary; - text-style: bold; - } .summary-error { color: $error; text-style: bold; @@ -55,13 +50,8 @@ class SummaryPanel(Vertical): self.target_id = target_id super().__init__() - cache_time = reactive("") - apt_count = reactive(0) - cve_count = reactive(0) - target_id = reactive("") - target_name = reactive("") - error_msg = reactive("") - is_skipped = reactive(False) + _current_target_id: str = "" + _current_target_name: str = "" def compose(self): with Horizontal(id="summary-header"): @@ -75,31 +65,21 @@ class SummaryPanel(Vertical): yield Static("", id="summary-error", classes="summary-row summary-error") yield Button("📦 Mettre à jour", id="btn-upgrade", variant="primary") - def watch_cache_time(self, value: str): - self.query_one("#summary-cache", Static).update(f"Cache : {value}" if value else "") + def set_target(self, target_id: str, name: str, apt_count: int, cve_count: int, error: str, skipped: bool, cache_time: str): + self._current_target_id = target_id + self._current_target_name = name - def watch_apt_count(self, value: int): - self._update_display() - - def watch_cve_count(self, value: int): - self._update_display() - - def watch_error_msg(self, value: str): - self._update_display() - - def watch_is_skipped(self, value: bool): - self._update_display() - - def watch_target_name(self, value: str): - self.query_one("#summary-title", Static).update(value if value else "Sélectionnez une cible") - - def _update_display(self): + title = self.query_one("#summary-title", Static) apt_btn = self.query_one("#btn-apt", Button) cve_btn = self.query_one("#btn-cve", Button) err_label = self.query_one("#summary-error", Static) btn = self.query_one("#btn-upgrade", Button) + cache_label = self.query_one("#summary-cache", Static) - if self.is_skipped: + title.update(name if name else "Sélectionnez une cible") + cache_label.update(f"Cache : {cache_time}" if cache_time else "") + + if skipped: apt_btn.label = "Mises à jour : LXC éteint" cve_btn.label = "CVE : LXC éteint" err_label.update("") @@ -108,37 +88,28 @@ class SummaryPanel(Vertical): cve_btn.disabled = True return - if self.error_msg: - apt_btn.label = f"Mises à jour : {self.apt_count}" + if error: + apt_btn.label = f"Mises à jour : {apt_count}" cve_btn.label = "CVE : ERREUR" - err_label.update(self.error_msg) + err_label.update(error) btn.disabled = False - apt_btn.disabled = self.apt_count == 0 + apt_btn.disabled = apt_count == 0 cve_btn.disabled = True return - apt_btn.label = f"Mises à jour : {self.apt_count}" - cve_btn.label = f"CVE : {self.cve_count}" + apt_btn.label = f"Mises à jour : {apt_count}" + cve_btn.label = f"CVE : {cve_count}" err_label.update("") btn.disabled = False - apt_btn.disabled = self.apt_count == 0 - cve_btn.disabled = self.cve_count == 0 - - def set_target(self, target_id: str, name: str, apt_count: int, cve_count: int, error: str, skipped: bool, cache_time: str): - self.target_id = target_id - self.target_name = name - self.apt_count = apt_count - self.cve_count = cve_count - self.error_msg = error - self.is_skipped = skipped - self.cache_time = cache_time + apt_btn.disabled = apt_count == 0 + cve_btn.disabled = cve_count == 0 def on_button_pressed(self, event: Button.Pressed): if event.button.id == "btn-reload": self.post_message(self.ReloadPressed()) elif event.button.id == "btn-upgrade": - self.post_message(self.UpgradePressed(self.target_id, self.target_name)) + self.post_message(self.UpgradePressed(self._current_target_id, self._current_target_name)) elif event.button.id == "btn-apt": - self.post_message(self.AptClicked(self.target_id)) + self.post_message(self.AptClicked(self._current_target_id)) elif event.button.id == "btn-cve": - self.post_message(self.CveClicked(self.target_id)) + self.post_message(self.CveClicked(self._current_target_id))