(ui) Rework dashboard around operator priorities

Move required actions, upcoming scheduled work, and recent run activity to the
top of the dashboard so the first screen answers what needs attention next.
Keep summary metrics, trends, and host cards as supporting drill-down content.

Refs #27
This commit is contained in:
2026-05-21 13:21:09 +02:00
parent 0fe2aa439f
commit 9412feaa58
4 changed files with 235 additions and 89 deletions

View File

@@ -120,20 +120,24 @@ class ViewTests(TestCase):
self.assertContains(response, "running 1")
self.assertContains(response, "warning 1")
self.assertContains(response, "failed 1")
self.assertContains(response, "Operational Status")
self.assertContains(response, "1 failed run needs review.")
self.assertContains(response, "1 run completed with warnings.")
self.assertContains(response, "Required Action")
self.assertContains(response, "Failed runs")
self.assertContains(response, "1 failed run(s) need review.")
self.assertContains(response, "1 run(s) completed with warnings.")
self.assertContains(response, "1 backup run in progress.")
self.assertContains(response, "1 backup run waiting for the worker.")
self.assertContains(response, "Review failed runs")
self.assertContains(response, "Review warnings")
self.assertContains(response, "View running runs")
self.assertContains(response, "View queued runs")
self.assertContains(response, "1 backup run waiting.")
self.assertContains(response, "Next Scheduled Work")
self.assertContains(response, "Recent Activity")
self.assertContains(response, f'href="{reverse("runs_list")}"', html=False)
self.assertContains(response, f'href="{reverse("runs_list")}?status=queued"', html=False)
self.assertContains(response, f'href="{reverse("runs_list")}?status=running"', html=False)
self.assertContains(response, f'href="{reverse("runs_list")}?status=warning&review=needed"', html=False)
self.assertContains(response, f'href="{reverse("runs_list")}?status=failed&review=needed"', html=False)
self.assertContains(
response,
f'href="{reverse("runs_list")}?host=web-01&status=failed&review=needed"',
html=False,
)
self.assertContains(response, f'href="{reverse("snapshots_list")}"', html=False)
self.assertContains(response, f'href="{reverse("schedules_list")}"', html=False)
@@ -208,8 +212,8 @@ class ViewTests(TestCase):
response = self.client.get(reverse("dashboard"))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Operational Status")
self.assertContains(response, "No queued, running, or unreviewed warning/failed runs.")
self.assertContains(response, "Required Action")
self.assertContains(response, "No queued, running, unreviewed warning/failed runs, or retention warnings.")
def test_runs_list_filters_by_status_and_review(self) -> None:
self.client.force_login(self.staff_user)
@@ -342,7 +346,7 @@ class ViewTests(TestCase):
response = self.client.get(reverse("dashboard"))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No queued, running, or unreviewed warning/failed runs.")
self.assertContains(response, "No queued, running, unreviewed warning/failed runs, or retention warnings.")
self.assertNotContains(response, "failed 1")
self.assertNotContains(response, "warning 1")