hub: extract config_form_body sub-template + configFormData builder (v0.48.0 part 1)

Behavior-neutral extraction (the host_detail_body pattern): the config form's
<form> + in-flight script move to a {{define}} sub-template; config_form.html
keeps the chrome. renderConfigForm/handleConfigNewForm/handleConfigEditForm
now go through the one configFormData builder (nil overrides = parse stored
ConfigJSON). Prepares the customer page Edit tab embed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TZc5w5jDhFLv6qDC32KN5v
This commit is contained in:
2026-07-12 17:24:59 +02:00
parent 3e949bc513
commit e74014730a
3 changed files with 240 additions and 254 deletions
+40 -59
View File
@@ -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.