check / check (push) Successful in 3m11s
A database target's archive expiry was typed by hand as never or a raw duration such as 720h, and the target list showed it back raw. Adding or editing a database target now offers the new-webhook page's list of choices (never, 1h, 12h, 24h, 30d, 90d, 365d), defined once and shared by all three forms. The edit form starts on the stored expiry, or on the submitted one after a refused save; a stored value outside the choices is listed under its own value, so saving unchanged keeps it. The target list shows the expiry in plain units: "30 days", "12 hours", "never". Model: opus-5-5
69 lines
3.6 KiB
HTML
69 lines
3.6 KiB
HTML
{{template "base" .}}
|
|
|
|
{{define "title"}}New Webhook - Webhooker{{end}}
|
|
|
|
{{define "content"}}
|
|
<div class="max-w-2xl mx-auto px-6 py-8">
|
|
<div class="mb-6">
|
|
<a href="/hooks" class="btn-small">← Back to webhooks</a>
|
|
<h1 class="text-2xl font-medium text-gray-900 mt-2">Create Webhook</h1>
|
|
</div>
|
|
|
|
<div class="card p-6">
|
|
{{if .Error}}
|
|
<div class="alert-error">{{.Error}}</div>
|
|
{{end}}
|
|
|
|
<form method="POST" action="/hooks/new" class="space-y-6">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<div class="form-group">
|
|
<label for="name" class="label">Name</label>
|
|
<input type="text" id="name" name="name" value="{{.Form.Name}}" required autofocus placeholder="My Webhook" class="input">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="description" class="label">Description</label>
|
|
<textarea id="description" name="description" rows="3" placeholder="Optional description" class="input">{{.Form.Description}}</textarea>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="retention_days" class="label">Retention (days)</label>
|
|
<input type="number" id="retention_days" name="retention_days" value="{{.Form.RetentionDays}}" min="0" class="input">
|
|
<p class="text-xs text-gray-500 mt-1">A periodic cleanup permanently deletes events older than this, along with their delivery records. Enter 0 to retain events forever; leave blank to use the default of {{.DefaultRetentionDays}} days.</p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="http_url" class="label">HTTP target URL</label>
|
|
<input type="url" id="http_url" name="http_url" value="{{.Form.HTTPURL}}" placeholder="https://example.com/webhook" class="input">
|
|
<p class="text-xs text-gray-500 mt-1">Optional. When filled in, the webhook is created with an HTTP target that delivers each event to this URL.</p>
|
|
</div>
|
|
|
|
<!-- The checkbox shows the pruning choice while checked. With
|
|
autocomplete="off", going back to the page does not
|
|
check the box again with the choice hidden. -->
|
|
<div class="form-group" x-data="collapsible"{{if .Form.Archive}} data-open{{end}}>
|
|
<label class="flex items-center gap-2 text-sm font-medium text-gray-700">
|
|
<input type="checkbox" name="archive" value="on"{{if .Form.Archive}} checked{{end}} autocomplete="off" @change="toggle" class="h-4 w-4">
|
|
Archive
|
|
</label>
|
|
<p class="text-xs text-gray-500 mt-1">When checked, the webhook is created with a database target that keeps a copy of every event.</p>
|
|
<div x-show="open" x-cloak class="mt-3">
|
|
<label for="archive_expiry" class="label">Archive pruning</label>
|
|
<select id="archive_expiry" name="archive_expiry" class="input">
|
|
{{range .ArchiveExpiryChoices}}
|
|
<option value="{{.Value}}"{{if .Selected}} selected{{end}}>{{.Label}}</option>
|
|
{{end}}
|
|
</select>
|
|
<p class="text-xs text-gray-500 mt-1">Archived events older than this are deleted from the archive; never keeps them all.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-3">
|
|
<button type="submit" class="btn-primary">Create Webhook</button>
|
|
<a href="/hooks" class="btn-secondary">Cancel</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{{end}}
|