docs nav: promote Devices and Administration out of User Guide

Follows the developer/api → API Reference carve-out: placement-only, no
file paths or URLs change. placeDoc routes user/devices/* to a new
top-level "Devices" section (icon: device) and user/admin-* to a new
top-level "Administration" section (icon: shield); User Guide keeps its
direct guides with no groups. Sidebar order: Getting Started, User
Guide, Devices, Administration, API Reference, Developer, Operations,
Contributing.

Verified live: on kobo-setup the Devices section opens with the three
device guides; on admin-guide Administration opens with both admin
guides; on user/dashboard User Guide opens as before. Tests
(TestPlaceDoc, TestBuildNavigation) updated to pin the new placement.
This commit is contained in:
John O'Keefe committed 2026-10-25 21:10:53 -04:00
1 parent fb95b6d400
commit 27f42bf703
2 files changed
+28 -24

No files matched your search

+20 -20
View File
@@ -4,8 +4,6 @@ import (
"os"
"path/filepath"
"testing"
"bookhoard/templates"
)
func TestPlaceDoc(t *testing.T) {
@@ -18,8 +16,8 @@ func TestPlaceDoc(t *testing.T) {
{"index.md", "Getting Started", "", true},
{"user/user-guide.md", "User Guide", "", true},
{"user/dashboard.md", "User Guide", "", false},
{"user/admin-guide.md", "User Guide", "Administration", false},
{"user/devices/kobo-setup.md", "User Guide", "Devices", false},
{"user/admin-guide.md", "Administration", "", false},
{"user/devices/kobo-setup.md", "Devices", "", false},
{"developer/api/api-reference.md", "API Reference", "", true},
{"developer/api/dashboard.md", "API Reference", "", false},
{"developer/api/authentication/login.md", "API Reference", "Authentication", false},
@@ -119,7 +117,7 @@ func TestBuildNavigation(t *testing.T) {
t.Fatal("no sections built")
}
wantOrder := []string{"Getting Started", "User Guide", "API Reference", "Developer", "Operations", "Contributing"}
wantOrder := []string{"Getting Started", "User Guide", "Devices", "Administration", "API Reference", "Developer", "Operations", "Contributing"}
for i, want := range wantOrder {
if nav.Sections[i].Title != want {
t.Fatalf("section %d = %q, want %q", i, nav.Sections[i].Title, want)
@@ -134,38 +132,40 @@ func TestBuildNavigation(t *testing.T) {
t.Errorf("Getting Started items = %+v, want single Overview → /docs", getting.Items)
}
// User Guide no longer contains the current page (device guides are
// their own section now): collapsed, no groups.
userGuide := nav.Sections[1]
if userGuide.Collapsed {
t.Error("User Guide should be expanded: it contains the current page")
if !userGuide.Collapsed {
t.Error("User Guide should be collapsed: it no longer contains the current page")
}
if len(userGuide.Groups) != 0 {
t.Errorf("User Guide groups = %+v, want none (Devices + Administration carved out)", userGuide.Groups)
}
if len(userGuide.Items) != 2 || userGuide.Items[0].Title != "User Guide" {
t.Errorf("User Guide direct items = %+v, want User Guide pinned first", userGuide.Items)
}
var devices *templates.NavGroup
for i := range userGuide.Groups {
if userGuide.Groups[i].Title == "Devices" {
devices = &userGuide.Groups[i]
}
}
if devices == nil {
t.Fatal("User Guide has no Devices group")
}
// Devices: own top-level section, expanded, no groups.
devices := nav.Sections[2]
if devices.Collapsed {
t.Error("Devices group should be expanded: it contains the current page")
t.Error("Devices section should be expanded: it contains the current page")
}
if len(devices.Groups) != 0 {
t.Errorf("Devices groups = %+v, want none", devices.Groups)
}
if len(devices.Items) != 2 || devices.Items[0].Title != "Kobo Setup" {
t.Errorf("Devices items = %+v, want Kobo Setup + KOReader Setup", devices.Items)
}
// Everything else starts collapsed.
for _, s := range nav.Sections[2:] {
for _, s := range nav.Sections[3:] {
if !s.Collapsed {
t.Errorf("section %q should be collapsed (current page is elsewhere)", s.Title)
}
}
// API Reference: subdirectory groups with the index page as Overview.
api := nav.Sections[2]
api := nav.Sections[4]
if len(api.Groups) != 2 {
t.Fatalf("API Reference groups = %d, want 2 (Authentication, Saved Filters)", len(api.Groups))
}
@@ -181,7 +181,7 @@ func TestBuildNavigation(t *testing.T) {
}
// Stray root files land in Developer → Reference.
dev := nav.Sections[3]
dev := nav.Sections[5]
if len(dev.Groups) != 1 || dev.Groups[0].Title != "Reference" {
t.Errorf("Developer groups = %+v, want Reference", dev.Groups)
}