Give each event its own page and show bodies the same everywhere (closes #369)
check / check (push) Successful in 3m20s

Each row of the recent events on the webhook page links to the
event's own page, /hook/{id}/events/{eventID}, and expands to show its
body; only the newest starts expanded. The event's page shows its
details, its whole body and every delivery with its attempts.

One renderer, newBodyView with templates/event_body.html, shows a body
in all three places: whole up to 32 KiB, cut there in the lists with a
link to the event's page, JSON pretty-printed, a body of more than 200
lines or 32 KiB in a scrolling box, and a body that is not text left
out beside its download link. A resubmitted copy links to its
original's page.

Model: opus-5-5
This commit is contained in:
clawbot
2026-10-02 18:33:27 +00:00
parent 9526e961b5
commit f01e5c45ad
23 changed files with 1009 additions and 172 deletions
+18 -11
View File
@@ -150,16 +150,23 @@ func New(
// Parse all page templates once at startup
s.templates = map[string]*template.Template{
"login.html": parsePageTemplate("login.html"),
"profile.html": parsePageTemplate("profile.html"),
"settings.html": parsePageTemplate("settings.html"),
"sources_list.html": parsePageTemplate("sources_list.html"),
"sources_new.html": parsePageTemplate("sources_new.html"),
"source_detail.html": parsePageTemplate("source_detail.html", "webhook_stats.html"),
"source_edit.html": parsePageTemplate("source_edit.html"),
"source_logs.html": parsePageTemplate("source_logs.html"),
"target_edit.html": parsePageTemplate("target_edit.html"),
"error.html": parsePageTemplate("error.html"),
"login.html": parsePageTemplate("login.html"),
"profile.html": parsePageTemplate("profile.html"),
"settings.html": parsePageTemplate("settings.html"),
"sources_list.html": parsePageTemplate("sources_list.html"),
"sources_new.html": parsePageTemplate("sources_new.html"),
"source_detail.html": parsePageTemplate(
"source_detail.html", "webhook_stats.html", "event_body.html",
),
"source_edit.html": parsePageTemplate("source_edit.html"),
"source_logs.html": parsePageTemplate(
"source_logs.html", "event_body.html", "delivery_attempts.html",
),
"event_detail.html": parsePageTemplate(
"event_detail.html", "event_body.html", "delivery_attempts.html",
),
"target_edit.html": parsePageTemplate("target_edit.html"),
"error.html": parsePageTemplate("error.html"),
}
lc.Append(fx.Hook{
@@ -386,7 +393,7 @@ func (s *Handlers) pageData(
// partial body and the status before a mid-render error can be
// reported, leaving no way to serve a 500. Buffering makes a page's
// rendered size resident memory per concurrent viewer, so every page
// owes it a bound: the event log caps each stored body at
// owes it a bound: the lists of events cap each stored body at
// maxRenderedBodyBytes for exactly this reason.
func (s *Handlers) executeTemplate(
w http.ResponseWriter,