Targets section: one Add, then a type and Next, then its fields (closes #370)

The webhook page's targets section lists only its targets until Add is
clicked. Add shows a choice of target type with Next; Next shows only
that type's fields, with Save and Cancel. The `database` and `log`
types have no URL field, and the `slack` form gains max retries.

A refused target now shows the webhook page again with the form open on
its type, the values entered and the reason, instead of a bare text
page. Target validation returns that message rather than writing the
response; newTarget validates a whole new target for reuse by the
new-webhook page. The edit page still answers a refusal in plain text.

Model: opus-5-5
This commit is contained in:
2026-10-02 19:51:51 +00:00
parent faf7ca1a5e
commit 93f7a2b0f4
11 changed files with 612 additions and 391 deletions
+6 -5
View File
@@ -127,11 +127,12 @@ func (h *Handlers) applyTargetEdit(
return
}
configJSON, err := h.buildTargetConfig(
w, r, target.Type, targetFormInputFrom(r),
configJSON, errMsg := h.buildTargetConfig(
r.Context(), target.Type, targetFormInputFrom(r),
)
if err != nil {
// buildTargetConfig has already written the response.
if errMsg != "" {
http.Error(w, errMsg, http.StatusBadRequest)
return
}
@@ -161,7 +162,7 @@ func (h *Handlers) applyTargetEdit(
// A new name renames the archive file before it is saved (see
// delivery.Engine.Rename). If either step fails, it goes back to
// the name that is still stored.
err = h.renameTargetArchive(target, webhook.Name, oldName, name)
err := h.renameTargetArchive(target, webhook.Name, oldName, name)
if err == nil {
err = h.db.DB().Save(target).Error
}