diff --git a/src/cv4pve_tui/app.py b/src/cv4pve_tui/app.py index 173da82..8984d52 100644 --- a/src/cv4pve_tui/app.py +++ b/src/cv4pve_tui/app.py @@ -334,7 +334,15 @@ class InfoScreen(ModalScreen): ("n", "net", "Edit 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: super().__init__() @@ -349,12 +357,18 @@ class InfoScreen(ModalScreen): def compose(self) -> ComposeResult: with Vertical(): yield Static(f"{self.guest['name']} ({self.guest['vmid']})", markup=False) - yield Static("", id="jobs", markup=False) - yield DataTable(id="backups") - yield Static("", id="hidden", markup=False) - yield DataTable(id="nets") - yield Static("", id="unavailable", markup=False) - yield DataTable(id="addresses") + with Vertical(id="backup_section", classes="section") as backup: + backup.border_title = "Backups" + yield Static("", id="jobs", markup=False) + yield DataTable(id="backups") + yield Static("", id="hidden", markup=False) + 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() def on_mount(self) -> None: @@ -442,7 +456,9 @@ class InfoScreen(ModalScreen): ip.get("ip6", "-"), "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() for i in addresses: table.add_row( diff --git a/tests/test_app.py b/tests/test_app.py index 6f56ba0..9ca8dd5 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1864,3 +1864,22 @@ async def test_link_only_change_on_running_ct_does_not_mention_reboot(fake): await setv(app, pilot, tag="99") text = await apply_to_confirm(app, pilot) 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", + }