All checks were successful
Check / check (push) Successful in 4s
## Summary
Adds a per-app webhook event history page at `/apps/{id}/webhooks` showing received webhook events with match/no-match status.
## Changes
- **New template** `webhook_events.html` — displays webhook events in a table with time, event type, branch, commit SHA (linked when URL available), and match status badges
- **New handler** `HandleAppWebhookEvents()` in `webhook_events.go` — fetches app and its webhook events (limit 100)
- **New route** `GET /apps/{id}/webhooks` — registered in protected routes group
- **Template registration** — added `webhook_events.html` to the template cache in `templates.go`
- **Model enhancement** — added `ShortCommit()` method to `WebhookEvent` for truncated SHA display
- **App detail link** — added "Event History" link in the Webhook URL card on the app detail page
## UI
Follows the existing UI patterns (Tailwind CSS classes, Alpine.js `relativeTime`, badge styles, empty state, back-navigation). The page mirrors the deployments history page layout.
closes [#85](#85)
Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Reviewed-on: #164
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
80 lines
3.2 KiB
HTML
80 lines
3.2 KiB
HTML
{{template "base" .}}
|
|
|
|
{{define "title"}}Webhook Events - {{.App.Name}} - µPaaS{{end}}
|
|
|
|
{{define "content"}}
|
|
{{template "nav" .}}
|
|
|
|
<main class="max-w-4xl mx-auto px-4 py-8">
|
|
<div class="mb-6">
|
|
<a href="/apps/{{.App.ID}}" class="text-primary-600 hover:text-primary-800 inline-flex items-center">
|
|
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
|
|
</svg>
|
|
Back to {{.App.Name}}
|
|
</a>
|
|
</div>
|
|
|
|
<div class="section-header">
|
|
<h1 class="text-2xl font-medium text-gray-900">Webhook Events</h1>
|
|
</div>
|
|
|
|
{{if .Events}}
|
|
<div class="card overflow-hidden">
|
|
<table class="table">
|
|
<thead class="table-header">
|
|
<tr>
|
|
<th>Time</th>
|
|
<th>Event</th>
|
|
<th>Branch</th>
|
|
<th>Commit</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="table-body">
|
|
{{range .Events}}
|
|
<tr>
|
|
<td class="text-gray-500 text-sm whitespace-nowrap">
|
|
<span x-data="relativeTime('{{.CreatedAt.Format `2006-01-02T15:04:05Z07:00`}}')" x-text="display" class="cursor-default" title="{{.CreatedAt.Format `2006-01-02 15:04:05`}}"></span>
|
|
</td>
|
|
<td class="text-gray-700 text-sm">{{.EventType}}</td>
|
|
<td class="font-mono text-gray-500 text-sm">{{.Branch}}</td>
|
|
<td class="font-mono text-gray-500 text-xs">
|
|
{{if and .CommitSHA.Valid .CommitURL.Valid}}
|
|
<a href="{{.CommitURL.String}}" target="_blank" rel="noopener noreferrer" class="text-primary-600 hover:text-primary-800">{{.ShortCommit}}</a>
|
|
{{else if .CommitSHA.Valid}}
|
|
{{.ShortCommit}}
|
|
{{else}}
|
|
<span class="text-gray-400">-</span>
|
|
{{end}}
|
|
</td>
|
|
<td>
|
|
{{if .Matched}}
|
|
{{if .Processed}}
|
|
<span class="badge-success">Matched</span>
|
|
{{else}}
|
|
<span class="badge-warning">Matched (pending)</span>
|
|
{{end}}
|
|
{{else}}
|
|
<span class="badge-neutral">No match</span>
|
|
{{end}}
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{else}}
|
|
<div class="card">
|
|
<div class="empty-state">
|
|
<svg class="empty-state-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
|
</svg>
|
|
<h3 class="empty-state-title">No webhook events yet</h3>
|
|
<p class="empty-state-description">Webhook events will appear here once your repository sends push notifications.</p>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</main>
|
|
{{end}}
|