From 1d9d32c15f206ad22ae47a443ab6c8612d817bce Mon Sep 17 00:00:00 2001 From: shuki Date: Fri, 6 Mar 2026 03:08:41 +0200 Subject: [PATCH] Replace schedule targets/remotes inputs with selection lists Show checkable lists of existing targets and remotes instead of free-text comma-separated inputs. Selected items are joined with commas on save, empty selection means "all". Co-Authored-By: Claude Opus 4.6 --- tui/gniza.tcss | 6 ++++++ tui/screens/schedule.py | 26 +++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/tui/gniza.tcss b/tui/gniza.tcss index a5de427..c511c2d 100644 --- a/tui/gniza.tcss +++ b/tui/gniza.tcss @@ -63,6 +63,12 @@ Select { margin: 0 0 1 0; } +SelectionList { + height: auto; + max-height: 8; + margin: 0 0 1 0; +} + /* Browse row */ #restore-dest-row { height: auto; diff --git a/tui/screens/schedule.py b/tui/screens/schedule.py index e9be2c9..270a7bf 100644 --- a/tui/screens/schedule.py +++ b/tui/screens/schedule.py @@ -1,7 +1,7 @@ import re from textual.app import ComposeResult from textual.screen import Screen -from textual.widgets import Header, Footer, Static, Button, DataTable, Input, Select +from textual.widgets import Header, Footer, Static, Button, DataTable, Input, Select, SelectionList from textual.containers import Vertical, Horizontal from textual import work @@ -49,12 +49,24 @@ class ScheduleScreen(Screen): yield Input(id="sched-day", placeholder="Leave empty if not needed") yield Static("Custom cron (5 fields):") yield Input(id="sched-cron", placeholder="0 2 * * *") - yield Static("Targets (comma-separated, empty=all):") - yield Input(id="sched-targets", placeholder="") - yield Static("Remotes (comma-separated, empty=all):") - yield Input(id="sched-remotes", placeholder="") + yield Static("Targets (empty=all):") + yield SelectionList[str]( + *self._build_target_choices(), + id="sched-targets", + ) + yield Static("Remotes (empty=all):") + yield SelectionList[str]( + *self._build_remote_choices(), + id="sched-remotes", + ) yield Footer() + def _build_target_choices(self) -> list[tuple[str, str]]: + return [(name, name) for name in list_conf_dir("targets.d")] + + def _build_remote_choices(self) -> list[tuple[str, str]]: + return [(name, name) for name in list_conf_dir("remotes.d")] + def on_mount(self) -> None: self._refresh_table() @@ -115,8 +127,8 @@ class ScheduleScreen(Screen): time=self.query_one("#sched-time", Input).value.strip() or "02:00", day=self.query_one("#sched-day", Input).value.strip(), cron=self.query_one("#sched-cron", Input).value.strip(), - targets=self.query_one("#sched-targets", Input).value.strip(), - remotes=self.query_one("#sched-remotes", Input).value.strip(), + targets=",".join(self.query_one("#sched-targets", SelectionList).selected), + remotes=",".join(self.query_one("#sched-remotes", SelectionList).selected), ) write_conf(conf, sched.to_conf()) self.notify(f"Schedule '{name}' created.")