(ui) Split primary and system navigation

Move operator routes into a primary navigation group and demote admin,
self-check, changelog, and status API links into a secondary system group
so the header reflects the control panel workflow more clearly.

Refs #37
This commit is contained in:
2026-05-21 14:56:30 +02:00
parent a3a8fea071
commit 6035c547ae
2 changed files with 53 additions and 8 deletions

View File

@@ -80,6 +80,23 @@
padding-left: 0;
}
nav strong a:hover { background: transparent; }
.nav-primary,
.nav-secondary {
align-items: center;
display: flex;
flex-wrap: wrap;
gap: 4px;
}
.nav-secondary {
justify-content: flex-end;
}
.nav-secondary a {
font-size: 13px;
}
.nav-user {
margin-left: 6px;
white-space: nowrap;
}
nav .spacer { flex: 1; }
main {
max-width: 1180px;
@@ -801,6 +818,12 @@
padding: 8px 0;
}
nav strong { flex-basis: 100%; margin-right: 0; }
.nav-secondary {
justify-content: flex-start;
}
.nav-user {
margin-left: 0;
}
nav .spacer { display: none; }
.page-header {
align-items: stretch;
@@ -866,15 +889,20 @@
<header>
<nav>
<strong><a href="{% url 'dashboard' %}">pobsync</a></strong>
<a href="{% url 'admin:index' %}">Admin</a>
<a href="{% url 'ssh_credentials' %}">SSH Keys</a>
<a href="{% url 'self_check' %}">Self Check</a>
<a href="{% url 'logs' %}">Logs</a>
<a href="{% url 'purged_snapshots' %}">Purged</a>
<a href="{% url 'changelog' %}">Changelog</a>
<a href="/api/status/">Status API</a>
<span class="nav-primary" aria-label="Primary navigation">
<a href="{% url 'dashboard' %}">Dashboard</a>
<a href="{% url 'ssh_credentials' %}">SSH Keys</a>
<a href="{% url 'logs' %}">Logs</a>
<a href="{% url 'purged_snapshots' %}">Purged</a>
</span>
<span class="spacer"></span>
<span class="muted">{{ request.user.username }}</span>
<span class="nav-secondary" aria-label="System navigation">
<a href="{% url 'self_check' %}">Self Check</a>
<a href="{% url 'changelog' %}">Changelog</a>
<a href="/api/status/">Status API</a>
<a href="{% url 'admin:index' %}">Admin</a>
</span>
<span class="muted nav-user">{{ request.user.username }}</span>
</nav>
</header>
<main>

View File

@@ -39,6 +39,23 @@ class ViewTests(TestCase):
self.assertEqual(response.status_code, 302)
self.assertIn("/admin/login/", response["Location"])
def test_base_navigation_groups_primary_and_system_links(self) -> None:
self.client.force_login(self.staff_user)
response = self.client.get(reverse("dashboard"))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'aria-label="Primary navigation"', html=False)
self.assertContains(response, 'aria-label="System navigation"', html=False)
self.assertContains(response, reverse("dashboard"))
self.assertContains(response, reverse("ssh_credentials"))
self.assertContains(response, reverse("logs"))
self.assertContains(response, reverse("purged_snapshots"))
self.assertContains(response, reverse("self_check"))
self.assertContains(response, reverse("changelog"))
self.assertContains(response, "/api/status/")
self.assertContains(response, reverse("admin:index"))
def test_changelog_requires_staff_login(self) -> None:
response = self.client.get(reverse("changelog"))