diff --git a/hub/internal/web/configs.go b/hub/internal/web/configs.go index b3d3c82..07022f0 100644 --- a/hub/internal/web/configs.go +++ b/hub/internal/web/configs.go @@ -421,25 +421,43 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c } } +// configFormView is the render model of the customer config form — consumed by the standalone +// config_form.html chrome AND embedded in the customer page's Edit tab as .ConfigForm +// (v0.48.0 edit-a; the hostDetailData/host_detail_body pattern). +type configFormView struct { + IsNew bool + Config *store.CustomerConfig + Overrides map[string]interface{} + ActiveNav string + Error string + CSRFField template.HTML + PBSDR pbsDRView +} + +// configFormData assembles the config form's view model. overrides carries SUBMITTED form values +// for the validation-error re-render (typed values must survive — B3); pass nil to fall back to +// the STORED cfg.ConfigJSON (the normal read path). +func (s *Server) configFormData(r *http.Request, isNew bool, cfg *store.CustomerConfig, overrides map[string]interface{}, errMsg string) configFormView { + if overrides == nil { + json.Unmarshal([]byte(cfg.ConfigJSON), &overrides) + } + if overrides == nil { + overrides = make(map[string]interface{}) + } + return configFormView{ + IsNew: isNew, + Config: cfg, + Overrides: overrides, + ActiveNav: "configs", + Error: errMsg, + CSRFField: s.csrfField(r), + PBSDR: s.pbsDRViewFor(cfg.CustomerID), + } +} + // handleConfigNewForm shows the form to create a new customer config. func (s *Server) handleConfigNewForm(w http.ResponseWriter, r *http.Request) { - data := struct { - IsNew bool - Config *store.CustomerConfig - Overrides map[string]interface{} - ActiveNav string - Error string - CSRFField template.HTML - PBSDR pbsDRView - }{ - IsNew: true, - Config: &store.CustomerConfig{}, - Overrides: make(map[string]interface{}), - ActiveNav: "configs", - CSRFField: s.csrfField(r), - PBSDR: s.pbsDRViewFor(""), - } - s.templates.ExecuteTemplate(w, "config_form.html", data) + s.renderConfigForm(w, r, true, &store.CustomerConfig{}, nil, "") } // handleConfigCreate processes the form submission to create a new config. @@ -528,26 +546,7 @@ func (s *Server) handleConfigEditForm(w http.ResponseWriter, r *http.Request, cu return } - var overrides map[string]interface{} - json.Unmarshal([]byte(cfg.ConfigJSON), &overrides) - - data := struct { - IsNew bool - Config *store.CustomerConfig - Overrides map[string]interface{} - ActiveNav string - Error string - CSRFField template.HTML - PBSDR pbsDRView - }{ - IsNew: false, - Config: cfg, - Overrides: overrides, - ActiveNav: "configs", - CSRFField: s.csrfField(r), - PBSDR: s.pbsDRViewFor(customerID), - } - s.templates.ExecuteTemplate(w, "config_form.html", data) + s.renderConfigForm(w, r, false, cfg, nil, "") } // handleConfigUpdate processes the edit form submission. @@ -965,29 +964,11 @@ func (s *Server) handleCreateConfigFromReport(w http.ResponseWriter, r *http.Req http.Redirect(w, r, "/configs/"+customerID+"/edit", http.StatusSeeOther) } -// renderConfigForm is a helper to re-render the form with an error. +// renderConfigForm renders the STANDALONE config form page (chrome + config_form_body) — the +// create flow and the validation-error re-render. The customer page's Edit tab embeds the same +// body via configFormData directly. func (s *Server) renderConfigForm(w http.ResponseWriter, r *http.Request, isNew bool, cfg *store.CustomerConfig, overrides map[string]interface{}, errMsg string) { - if overrides == nil { - overrides = make(map[string]interface{}) - } - data := struct { - IsNew bool - Config *store.CustomerConfig - Overrides map[string]interface{} - ActiveNav string - Error string - CSRFField template.HTML - PBSDR pbsDRView - }{ - IsNew: isNew, - Config: cfg, - Overrides: overrides, - ActiveNav: "configs", - Error: errMsg, - CSRFField: s.csrfField(r), - PBSDR: s.pbsDRViewFor(cfg.CustomerID), - } - s.templates.ExecuteTemplate(w, "config_form.html", data) + s.templates.ExecuteTemplate(w, "config_form.html", s.configFormData(r, isNew, cfg, overrides, errMsg)) } // buildConfigJSON builds the config_json from optional form fields. diff --git a/hub/internal/web/templates/config_form.html b/hub/internal/web/templates/config_form.html index cd2a994..5afb244 100644 --- a/hub/internal/web/templates/config_form.html +++ b/hub/internal/web/templates/config_form.html @@ -4,7 +4,7 @@