diff --git a/src/pobsync_backend/templates/pobsync_backend/dashboard.html b/src/pobsync_backend/templates/pobsync_backend/dashboard.html
index ab4c56f..ae585a4 100644
--- a/src/pobsync_backend/templates/pobsync_backend/dashboard.html
+++ b/src/pobsync_backend/templates/pobsync_backend/dashboard.html
@@ -46,6 +46,7 @@
Address |
Enabled |
Snapshots |
+ Latest Snapshot |
Runs |
Retention |
@@ -57,11 +58,19 @@
{{ host.address }} |
{{ host.enabled|yesno:"yes,no" }} |
{{ host.snapshot_count }} |
+
+ {% if host.latest_snapshot %}
+ {{ host.latest_snapshot.dirname }}
+ {{ host.latest_snapshot.kind }} {{ host.latest_snapshot.status }}
+ {% else %}
+ none
+ {% endif %}
+ |
{{ host.run_count }} |
d{{ host.retention_daily }} w{{ host.retention_weekly }} m{{ host.retention_monthly }} y{{ host.retention_yearly }} |
{% empty %}
- | No hosts configured yet. |
+ | No hosts configured yet. |
{% endfor %}
diff --git a/src/pobsync_backend/tests/test_views.py b/src/pobsync_backend/tests/test_views.py
index 3d7a3f7..31feeb0 100644
--- a/src/pobsync_backend/tests/test_views.py
+++ b/src/pobsync_backend/tests/test_views.py
@@ -47,6 +47,20 @@ class ViewTests(TestCase):
self.assertContains(response, "20260519-021500Z__ABCDEFGH")
self.assertContains(response, "success")
+ def test_dashboard_links_latest_snapshot_for_each_host(self) -> None:
+ self.client.force_login(self.staff_user)
+ host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
+ old_snapshot = self._snapshot(host, "20260518-021500Z__OLDSNAP")
+ latest_snapshot = self._snapshot(host, "20260519-021500Z__NEWSNAP")
+
+ response = self.client.get(reverse("dashboard"))
+
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, "Latest Snapshot")
+ self.assertContains(response, latest_snapshot.dirname)
+ self.assertContains(response, reverse("snapshot_detail", args=[latest_snapshot.id]))
+ self.assertNotContains(response, reverse("snapshot_detail", args=[old_snapshot.id]))
+
def test_dashboard_prompts_for_global_config_when_database_is_empty(self) -> None:
self.client.force_login(self.staff_user)
diff --git a/src/pobsync_backend/views.py b/src/pobsync_backend/views.py
index abcc24b..bde74bb 100644
--- a/src/pobsync_backend/views.py
+++ b/src/pobsync_backend/views.py
@@ -20,12 +20,18 @@ from .snapshot_discovery import discover_snapshots, inspect_snapshot_discovery
@staff_member_required
def dashboard(request):
- host_qs = (
+ hosts = list(
HostConfig.objects.annotate(snapshot_count=Count("snapshots", distinct=True), run_count=Count("runs", distinct=True))
.order_by("host")
)
+ for host_config in hosts:
+ host_config.latest_snapshot = (
+ host_config.snapshots.select_related("base")
+ .order_by("-started_at", "-discovered_at", "-id")
+ .first()
+ )
context = {
- "hosts": host_qs,
+ "hosts": hosts,
"global_config": GlobalConfig.objects.filter(name="default").first(),
"latest_runs": BackupRun.objects.select_related("host", "snapshot").order_by("-created_at")[:10],
"counts": {