feat(series): multi-field search, sort-direction toggle, apply placement
Toolbar feedback round: the series search box now matches whatever the main search matches for a group — series NAME, any book's AUTHOR, and any book's TITLE inside the series (WHERE EXISTS per group-row, so counts stay true); the separate author input is gone from the toolbar (the author= param stays live for the JSON API and deep links). The sort control becomes a base-key select (Date added/Name/Author/Books/ Progress/Last read) plus a chevron direction toggle that flips and resubmits; sort/dir compose through ResolveSeriesSort (full registry keys keep working for back-compat, unknown base keys fall to recent). The search/apply button moved next to the search box as requested, and default URLs stay clean (sort/dir only emitted once the user chooses).
This commit is contained in:
1 parent
14285ff314
commit
96c1228805
11 files changed
+504
-149
No files matched your search
@@ -151,17 +151,28 @@ func registerFrontendRoutes(cfg *Config) {
|
||||
|
||||
// Series-page state (URL is the source of truth — plain GET form,
|
||||
// no htmx on this page). Unknown values resolve to defaults in the
|
||||
// service's registries, so hand-edited URLs stay safe.
|
||||
// service's registries, so hand-edited URLs stay safe. The URL
|
||||
// carries the BASE sort key + direction; opts.Sort gets the
|
||||
// composed registry key (full keys win on re-resolve). With no
|
||||
// sort param at all, state stays empty so default URLs remain
|
||||
// clean (the toolbar treats empty as recent/desc).
|
||||
rawSort := c.QueryParam("sort")
|
||||
sortKey, sortDir := services.ResolveSeriesSort(rawSort, c.QueryParam("dir"))
|
||||
state := templates.SeriesPageState{
|
||||
Sort: c.QueryParam("sort"),
|
||||
Sort: services.SeriesSortBase(sortKey),
|
||||
Dir: sortDir,
|
||||
Query: c.QueryParam("q"),
|
||||
Author: c.QueryParam("author"),
|
||||
Status: c.QueryParam("status"),
|
||||
}
|
||||
if rawSort == "" {
|
||||
state.Sort = ""
|
||||
state.Dir = ""
|
||||
}
|
||||
opts := services.SeriesPageOptions{
|
||||
Sort: state.Sort,
|
||||
Sort: sortKey,
|
||||
Dir: sortDir,
|
||||
Query: state.Query,
|
||||
Author: state.Author,
|
||||
Author: c.QueryParam("author"), // API/deep-link back-compat; the toolbar's multi-field q covers authors
|
||||
Status: state.Status,
|
||||
}
|
||||
if viewerID, vidErr := uuid.Parse(user.ID); vidErr == nil {
|
||||
|
||||
Reference in new issue
Block a user