fix(views): edit UI + URL chip overlay on saved-view pages
m's bug (verbatim from /views): "we cant edit views yet. and the filters on custom views dont seem to work. No apply button and no instant apply" Two distinct gaps, both surgically fixed. ## Gap 1 — edit UI missing Slice D shipped POST /views/<id> (update) but no GET form to drive it. The index page had delete + redirect-open links only. Fix: - New handleViewEdit serves GET /views/<id>/edit with the form pre-filled from the persisted row. - New templates/view_edit.tmpl mirrors the create form, selecting the current values on each <select>, populating each <input value="">. - filterJSONToQuery rebuilds the URL-query representation of filter_json so the `filter_query` text input round-trips on edit. - /views index row gets an "edit" link next to delete. - Route registered before the catch-all GET /views/ so the more specific pattern wins. handleViewRedirect also defensively forwards /edit suffix in case routing falls through. ## Gap 2 — URL chips clobbered by saved-view filter applySavedView did `*filter = filterFromJSONPayload(payload)` — wholesale replace. URL chip params parsed earlier in handleTree were thrown away. Compounded by chip URLs not preserving `?view=<id>`, so even if the overlay had worked, chip clicks would have stripped the saved view. Fix: - TreeFilter grows a `ViewID` field that round-trips through ParseTreeFilter + QueryString. Not a "filter dimension" in the matching sense (Matches ignores it); just a URL anchor that every chip URL emits forward. - applySavedView builds the saved filter, then overlayURLFields() selectively replaces any dimension the user set via URL chip on top (q/tag/mgmt/status/has/show-archived/public/project/project_descendants). - view_type: URL wins when explicitly set, saved value otherwise. - Drift is transient — URL bookmarkable as a "narrowed saved view" without auto-saving back to the row. To persist, user opens /edit. ## Tests - TestViewEditFlow — GET /<id>/edit pre-fills name + filter_query; POST /<id> updates name + view_type + filter_json round-trip in DB. - TestSavedViewPageFilterApply — seed two items + an empty saved view; /?view=<id> shows both; /?view=<id>&tag=work shows only the work one. Also asserts chip URLs contain view=<id> so navigation stays in the saved view. Out of scope (per brief): - No schema changes. - No view sharing / multi-user. - HTMX modal save UI deferred — the existing inline edit page is the surgical fix m's bug actually needs.
This commit is contained in:
@@ -151,7 +151,7 @@ func New(s *store.Store, logger *slog.Logger) (*Server, error) {
|
||||
},
|
||||
}
|
||||
pages := map[string]*template.Template{}
|
||||
for _, name := range []string{"new", "classify", "caldav_admin", "caldav_disabled", "error", "views"} {
|
||||
for _, name := range []string{"new", "classify", "caldav_admin", "caldav_disabled", "error", "views", "view_edit"} {
|
||||
t, err := template.New(name).Funcs(funcs).ParseFS(templatesFS,
|
||||
"templates/layout.tmpl",
|
||||
"templates/"+name+".tmpl",
|
||||
@@ -384,6 +384,7 @@ func (s *Server) Routes() http.Handler {
|
||||
mux.HandleFunc("POST /admin/caldav/unlink", s.handleCalDAVUnlink)
|
||||
mux.HandleFunc("GET /views", s.handleViewsIndex)
|
||||
mux.HandleFunc("POST /views", s.handleViewCreate)
|
||||
mux.HandleFunc("GET /views/{id}/edit", s.handleViewEdit)
|
||||
mux.HandleFunc("GET /views/", s.handleViewRedirect)
|
||||
mux.HandleFunc("POST /views/", s.handleViewWrite)
|
||||
mux.HandleFunc("GET /login", s.handleLoginForm)
|
||||
|
||||
Reference in New Issue
Block a user