(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:
@@ -80,6 +80,23 @@
|
|||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
nav strong a:hover { background: transparent; }
|
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; }
|
nav .spacer { flex: 1; }
|
||||||
main {
|
main {
|
||||||
max-width: 1180px;
|
max-width: 1180px;
|
||||||
@@ -801,6 +818,12 @@
|
|||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
}
|
}
|
||||||
nav strong { flex-basis: 100%; margin-right: 0; }
|
nav strong { flex-basis: 100%; margin-right: 0; }
|
||||||
|
.nav-secondary {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
.nav-user {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
nav .spacer { display: none; }
|
nav .spacer { display: none; }
|
||||||
.page-header {
|
.page-header {
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
@@ -866,15 +889,20 @@
|
|||||||
<header>
|
<header>
|
||||||
<nav>
|
<nav>
|
||||||
<strong><a href="{% url 'dashboard' %}">pobsync</a></strong>
|
<strong><a href="{% url 'dashboard' %}">pobsync</a></strong>
|
||||||
<a href="{% url 'admin:index' %}">Admin</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 'ssh_credentials' %}">SSH Keys</a>
|
||||||
<a href="{% url 'self_check' %}">Self Check</a>
|
|
||||||
<a href="{% url 'logs' %}">Logs</a>
|
<a href="{% url 'logs' %}">Logs</a>
|
||||||
<a href="{% url 'purged_snapshots' %}">Purged</a>
|
<a href="{% url 'purged_snapshots' %}">Purged</a>
|
||||||
|
</span>
|
||||||
|
<span class="spacer"></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="{% url 'changelog' %}">Changelog</a>
|
||||||
<a href="/api/status/">Status API</a>
|
<a href="/api/status/">Status API</a>
|
||||||
<span class="spacer"></span>
|
<a href="{% url 'admin:index' %}">Admin</a>
|
||||||
<span class="muted">{{ request.user.username }}</span>
|
</span>
|
||||||
|
<span class="muted nav-user">{{ request.user.username }}</span>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
|
|||||||
@@ -39,6 +39,23 @@ class ViewTests(TestCase):
|
|||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertIn("/admin/login/", response["Location"])
|
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:
|
def test_changelog_requires_staff_login(self) -> None:
|
||||||
response = self.client.get(reverse("changelog"))
|
response = self.client.get(reverse("changelog"))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user