Separate backups and network on the info screen #5

Merged
Duckboot merged 1 commits from feat/info-sections into main 2026-11-02 21:53:54 +01:00
2 changed files with 43 additions and 8 deletions
Showing only changes of commit 62490af913 - Show all commits

No files matched your search

+24 -8
View File
@@ -334,7 +334,15 @@ class InfoScreen(ModalScreen):
("n", "net", "Edit network"), ("n", "net", "Edit network"),
("u", "undo", "Undo network"), ("u", "undo", "Undo network"),
] ]
DEFAULT_CSS = "InfoScreen DataTable { height: auto; max-height: 12; }" DEFAULT_CSS = """
InfoScreen DataTable { height: auto; max-height: 12; }
InfoScreen .section {
height: auto; border: round $accent; border-title-style: bold;
padding: 0 1; margin-bottom: 1;
}
InfoScreen .label { text-style: bold; margin-top: 1; }
InfoScreen .label.first { margin-top: 0; }
"""
def __init__(self, guest: dict) -> None: def __init__(self, guest: dict) -> None:
super().__init__() super().__init__()
@@ -349,12 +357,18 @@ class InfoScreen(ModalScreen):
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
with Vertical(): with Vertical():
yield Static(f"{self.guest['name']} ({self.guest['vmid']})", markup=False) yield Static(f"{self.guest['name']} ({self.guest['vmid']})", markup=False)
yield Static("", id="jobs", markup=False) with Vertical(id="backup_section", classes="section") as backup:
yield DataTable(id="backups") backup.border_title = "Backups"
yield Static("", id="hidden", markup=False) yield Static("", id="jobs", markup=False)
yield DataTable(id="nets") yield DataTable(id="backups")
yield Static("", id="unavailable", markup=False) yield Static("", id="hidden", markup=False)
yield DataTable(id="addresses") with Vertical(id="network_section", classes="section") as network:
network.border_title = "Network"
yield Static("Configured", classes="label first")
yield DataTable(id="nets")
yield Static("In use", classes="label")
yield Static("", id="unavailable", markup=False)
yield DataTable(id="addresses")
yield Footer() yield Footer()
def on_mount(self) -> None: def on_mount(self) -> None:
@@ -442,7 +456,9 @@ class InfoScreen(ModalScreen):
ip.get("ip6", "-"), ip.get("ip6", "-"),
"yes" if net.get("firewall") == "1" else "no", "yes" if net.get("firewall") == "1" else "no",
) )
self.query_one("#unavailable", Static).update(unavailable) note = self.query_one("#unavailable", Static)
note.update(unavailable)
note.display = bool(unavailable) # no empty line when the addresses are known
table = self.query_one("#addresses", DataTable).clear() table = self.query_one("#addresses", DataTable).clear()
for i in addresses: for i in addresses:
table.add_row( table.add_row(
+19
View File
@@ -1864,3 +1864,22 @@ async def test_link_only_change_on_running_ct_does_not_mention_reboot(fake):
await setv(app, pilot, tag="99") await setv(app, pilot, tag="99")
text = await apply_to_confirm(app, pilot) text = await apply_to_confirm(app, pilot)
assert "reboot" not in text.lower() assert "reboot" not in text.lower()
# --- info screen layout: backups and network clearly separated --------------------
async def test_info_has_separate_titled_backup_and_network_sections(fake):
app = make_app()
async with app.run_test() as pilot:
await open_info(app, pilot)
backup = app.screen.query_one("#backup_section")
network = app.screen.query_one("#network_section")
assert "Backups" in str(backup.border_title)
assert "Network" in str(network.border_title)
assert {w.id for w in backup.query("*")} >= {"jobs", "backups", "hidden"}
assert {w.id for w in network.query("*")} >= {
"nets",
"unavailable",
"addresses",
}