fix(ui): derive Library Type dropdowns from library_types — audiobooks was missing
The audiobook library type shipped backend-complete (LibraryTypeAudiobooks constant, allowed extensions, MIME map, schema seed row, GET /api/libraries/types) but neither create-library form offered it: the admin Create Library modal and the setup wizard's add-library step both hardcoded their <option> lists to the original three types (ebooks/comics/manga), so an audiobook library could not be created from the UI. Both dropdowns now render from the same DB-backed library_types table the create API resolves types against — a future type appears without template edits (the exact drift the rendering-ownership rule warns about): - templates/utils.go: OrderedLibraryTypes pins the historical dropdown order (ebooks, comics, manga, audiobooks) and appends unknown future types by name; LibraryTypeDisplayName renders labels with a capitalize-the-name fallback for types added without a label - templates/admin_library.templ: new LibraryTypeOptions fragment used by the modal's select; AdminLibrary takes the types list - templates/setup.templ: Setup takes the types list, same fragment - internal/router/helpers.go: libraryTypeOptionsFor fetches via LibraryService.GetLibraryTypes, falling back to the built-in type names on DB failure so the forms stay usable (CreateLibrary still resolves the name against the DB, so the fallback is never authoritative) - internal/router/frontend.go, internal/router/setup.go: pass the list into the two pages Tests: - templates/utils_test.go: pure unit tests for ordering + labels - cmd/server/tests/admin_library_page_test.go: SSR regression — /admin/library must offer all four library types, audiobooks exactly once (options come from the DB loop, not a hardcode)
This commit is contained in:
1 parent
327fc2c0f9
commit
9e831085ef
10 files changed
+593
-346
No files matched your search
@@ -1143,7 +1143,8 @@ func registerFrontendRoutes(cfg *Config) {
|
||||
|
||||
var buf bytes.Buffer
|
||||
archivedCount, _ := cfg.Queries.CountArchivedMediaItems(c.Request().Context())
|
||||
err = templates.AdminLibrary(user, libData, userData, archivedCount).Render(c.Request().Context(), &buf)
|
||||
libraryTypes := libraryTypeOptionsFor(c.Request().Context(), cfg)
|
||||
err = templates.AdminLibrary(user, libData, userData, archivedCount, libraryTypes).Render(c.Request().Context(), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -405,3 +405,24 @@ func (cfg *Config) loadCollectionBooksLite(c *echo.Context, userUUID uuid.UUID,
|
||||
return cfg.collectionBooksForScope(c, userUUID, pgtype.UUID{Bytes: collUUID, Valid: true}, collection, collectionID,
|
||||
libUUID, libUUID, libraryID != "", visibleIDs)
|
||||
}
|
||||
|
||||
// libraryTypeOptionsFor loads the library_types rows for the create-library
|
||||
// dropdowns (admin page + setup wizard), ordered for display. On DB failure
|
||||
// it falls back to the built-in type names so the form stays usable —
|
||||
// CreateLibrary resolves the name against the DB, so this is never
|
||||
// authoritative.
|
||||
func libraryTypeOptionsFor(ctx context.Context, cfg *Config) []database.LibraryTypes {
|
||||
types, err := cfg.LibraryService.GetLibraryTypes(ctx)
|
||||
if err != nil {
|
||||
log.Printf("libraryTypeOptionsFor: GetLibraryTypes failed, using built-in type names: %v", err)
|
||||
for _, name := range []string{
|
||||
services.LibraryTypeEbooks,
|
||||
services.LibraryTypeComics,
|
||||
services.LibraryTypeManga,
|
||||
services.LibraryTypeAudiobooks,
|
||||
} {
|
||||
types = append(types, database.LibraryTypes{Name: name})
|
||||
}
|
||||
}
|
||||
return templates.OrderedLibraryTypes(types)
|
||||
}
|
||||
@@ -81,7 +81,8 @@ func registerSetupRoutes(cfg *Config) {
|
||||
return c.Redirect(http.StatusFound, "/")
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := templates.Setup().Render(c.Request().Context(), &buf); err != nil {
|
||||
libraryTypes := libraryTypeOptionsFor(c.Request().Context(), cfg)
|
||||
if err := templates.Setup(libraryTypes).Render(c.Request().Context(), &buf); err != nil {
|
||||
log.Printf("Failed to render setup template: %v", err)
|
||||
return c.HTML(http.StatusInternalServerError, "Failed to render setup page")
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user