Files
gniza4linux/tui/screens/backup.py
shuki e2d94546bd Put back button and title on the same line
Wrap ← Back button and screen title in a Horizontal title-bar
container across all screens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 07:05:10 +02:00

108 lines
4.4 KiB
Python

from textual.app import ComposeResult
from textual.screen import Screen
from textual.widgets import Header, Footer, Static, Button, Select
from tui.widgets.header import GnizaHeader as Header # noqa: F811
from textual.containers import Vertical, Horizontal
from tui.config import list_conf_dir, has_targets, has_remotes
from tui.jobs import job_manager
from tui.widgets import ConfirmDialog, DocsPanel
class BackupScreen(Screen):
BINDINGS = [("escape", "go_back", "Back")]
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
targets = list_conf_dir("targets.d")
remotes = list_conf_dir("remotes.d")
with Horizontal(classes="screen-with-docs"):
with Vertical(id="backup-screen"):
with Horizontal(id="title-bar"):
yield Button("← Back", id="btn-back", classes="back-btn")
yield Static("Backup", id="screen-title")
if not targets:
yield Static("No sources configured. Add a source first.")
else:
yield Static("Source:")
yield Select(
[(t, t) for t in targets],
id="backup-target",
prompt="Select source",
)
yield Static("Destination:")
yield Select(
[("Default (all)", "")] + [(r, r) for r in remotes],
id="backup-remote",
prompt="Select destination",
value="",
)
with Horizontal(id="backup-buttons"):
yield Button("Run Backup", variant="primary", id="btn-backup")
yield Button("Backup All", variant="warning", id="btn-backup-all")
yield DocsPanel.for_screen("backup-screen")
yield Footer()
def on_screen_resume(self) -> None:
self._refresh_selects()
def _refresh_selects(self) -> None:
targets = list_conf_dir("targets.d")
remotes = list_conf_dir("remotes.d")
try:
ts = self.query_one("#backup-target", Select)
old_target = ts.value
ts.set_options([(t, t) for t in targets])
if old_target in targets:
ts.value = old_target
except Exception:
pass
try:
rs = self.query_one("#backup-remote", Select)
old_remote = rs.value
rs.set_options([("Default (all)", "")] + [(r, r) for r in remotes])
if old_remote == "" or old_remote in remotes:
rs.value = old_remote
except Exception:
pass
def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "btn-back":
self.app.pop_screen()
elif event.button.id == "btn-backup":
target_sel = self.query_one("#backup-target", Select)
if not isinstance(target_sel.value, str):
self.notify("Please select a source", severity="error")
return
target = str(target_sel.value)
remote_sel = self.query_one("#backup-remote", Select)
remote = str(remote_sel.value) if isinstance(remote_sel.value, str) else ""
msg = f"Run backup for source '{target}'?"
if remote:
msg += f"\nDestination: {remote}"
self.app.push_screen(
ConfirmDialog(msg, "Confirm Backup"),
callback=lambda ok: self._do_backup(target, remote) if ok else None,
)
elif event.button.id == "btn-backup-all":
self.app.push_screen(
ConfirmDialog("Backup ALL sources now?", "Confirm Backup"),
callback=lambda ok: self._do_backup_all() if ok else None,
)
def _do_backup(self, target: str, remote: str) -> None:
job = job_manager.create_job("backup", f"Backup: {target}")
args = ["backup", f"--source={target}"]
if remote:
args.append(f"--destination={remote}")
job_manager.start_job(self.app, job, *args)
self.app.switch_screen("running_tasks")
def _do_backup_all(self) -> None:
job = job_manager.create_job("backup", "Backup All Targets")
job_manager.start_job(self.app, job, "backup", "--all")
self.app.switch_screen("running_tasks")
def action_go_back(self) -> None:
self.app.pop_screen()