check / check (push) Waiting to run
Each event now has its own page at /hook/ID/events/EVENTID, behind the login, showing its details, its whole body and every delivery; a resubmitted copy links to its original's page. The recent events on the webhook page link there and expand to show their bodies, only the newest expanded on load. One renderer and one template show a body the same way in the recent events, the event log and the event's page: whole up to 32 KiB, cut there in the two lists with links to the event's page and the download; JSON pretty-printed unless that would grow it past four times plus 1 KiB; over 200 lines in a scrolling box; a body holding NUL or control characters treated as binary and never dumped raw. Model: opus-5-5
88 lines
3.8 KiB
HTML
88 lines
3.8 KiB
HTML
{{template "base" .}}
|
|
|
|
{{define "title"}}Event - {{.Webhook.Name}} - Webhooker{{end}}
|
|
|
|
{{define "content"}}
|
|
<div class="max-w-6xl mx-auto px-6 py-8">
|
|
<div class="mb-6">
|
|
<div class="flex flex-wrap gap-2">
|
|
<a href="/hook/{{.Webhook.ID}}" class="btn-small">← Back to {{.Webhook.Name}}</a>
|
|
<a href="/hook/{{.Webhook.ID}}/events" class="btn-small">Full Event Log</a>
|
|
</div>
|
|
<h1 class="text-2xl font-medium text-gray-900 mt-2">Event</h1>
|
|
</div>
|
|
|
|
{{with .Event}}
|
|
<div class="card p-4">
|
|
<dl class="space-y-2 text-sm">
|
|
<div class="flex flex-wrap gap-2">
|
|
<dt class="w-32 flex-shrink-0 text-gray-500">ID</dt>
|
|
<dd class="font-mono text-gray-900 break-all">{{.ID}}</dd>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2">
|
|
<dt class="w-32 flex-shrink-0 text-gray-500">Received</dt>
|
|
<dd class="text-gray-900">{{.CreatedAt.UTC.Format "2006-01-02 15:04:05"}} UTC</dd>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2">
|
|
<dt class="w-32 flex-shrink-0 text-gray-500">Method</dt>
|
|
<dd><span class="badge-info">{{.Method}}</span></dd>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2">
|
|
<dt class="w-32 flex-shrink-0 text-gray-500">Content type</dt>
|
|
<dd class="text-gray-900 break-all">{{.ContentType}}</dd>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2">
|
|
<dt class="w-32 flex-shrink-0 text-gray-500">Body size</dt>
|
|
<dd class="text-gray-900">{{.Body.Size}} bytes</dd>
|
|
</div>
|
|
{{if .ResubmittedFrom}}
|
|
<div class="flex flex-wrap gap-2">
|
|
<dt class="w-32 flex-shrink-0 text-gray-500">Resubmitted from</dt>
|
|
<dd><a href="/hook/{{$.Webhook.ID}}/events/{{.ResubmittedFromID}}" class="btn-small font-mono">{{.ResubmittedFromID}}</a></dd>
|
|
</div>
|
|
{{end}}
|
|
{{if .ResubmitCount}}
|
|
<div class="flex flex-wrap gap-2">
|
|
<dt class="w-32 flex-shrink-0 text-gray-500">Resubmitted</dt>
|
|
<dd class="text-gray-900">as {{.ResubmitCount}} new event{{if ne .ResubmitCount 1}}s{{end}}</dd>
|
|
</div>
|
|
{{end}}
|
|
</dl>
|
|
</div>
|
|
|
|
<div class="card mt-6">
|
|
<div class="p-4 border-b border-gray-200">
|
|
<h2 class="text-lg font-medium text-gray-900">Body</h2>
|
|
</div>
|
|
<div class="p-4">
|
|
{{template "event_body" .Body}}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card mt-6">
|
|
<div class="p-4 border-b border-gray-200">
|
|
<h2 class="text-lg font-medium text-gray-900">Deliveries</h2>
|
|
</div>
|
|
<div class="divide-y divide-gray-100">
|
|
{{range .Deliveries}}
|
|
<div class="p-4">
|
|
<div class="flex flex-wrap items-center justify-between gap-3">
|
|
<span class="text-sm text-gray-700">{{.Target.DisplayName}}</span>
|
|
<span class="flex flex-wrap items-center gap-3">
|
|
<span class="text-xs {{if eq .Status "delivered"}}text-green-600{{else if eq .Status "failed"}}text-red-600{{else if eq .Status "retrying"}}text-yellow-600{{else}}text-gray-400{{end}}">{{.Status}}</span>
|
|
<span class="text-xs text-gray-400">{{.AttemptCount}} attempt{{if ne .AttemptCount 1}}s{{end}}</span>
|
|
</span>
|
|
</div>
|
|
<div class="mt-2 space-y-2">
|
|
{{template "delivery_attempts" .}}
|
|
</div>
|
|
</div>
|
|
{{else}}
|
|
<div class="p-4 text-sm text-gray-500">No deliveries.</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|