Files
at-container-registry/pkg/appview/templates/partials/webhooks_list.html
2026-04-19 17:35:41 -05:00

108 lines
5.3 KiB
HTML

{{ define "webhooks_list" }}
<div class="space-y-6">
<!-- Add Webhook Form -->
<form hx-post="/api/webhooks"
hx-target="#{{ .ContainerID }}"
hx-swap="innerHTML"
class="space-y-4 bg-base-200 rounded-lg p-4">
<h3 class="font-semibold">Add Webhook</h3>
<fieldset class="fieldset">
<label class="label" for="webhook-url">
<span class="label-text">Webhook URL</span>
</label>
<input type="url" id="webhook-url" name="url" placeholder="https://example.com/webhook"
class="input input-bordered w-full" required aria-required="true">
</fieldset>
<fieldset class="fieldset">
<label class="label" for="webhook-secret">
<span class="label-text">Signing Secret <span class="text-base-content/70">(optional)</span></span>
</label>
<input type="password" id="webhook-secret" name="secret" placeholder="HMAC-SHA256 signing secret"
class="input input-bordered w-full" autocomplete="new-password"
aria-describedby="webhook-secret-hint">
<p id="webhook-secret-hint" class="text-xs text-base-content/60 mt-1">If set, payloads include an <code class="cmd">X-Webhook-Signature-256</code> header</p>
</fieldset>
<fieldset class="fieldset">
<legend class="label"><span class="label-text">Trigger Events</span></legend>
<div class="space-y-2 mt-1">
{{ range .TriggerInfo }}
<label class="flex items-start gap-3{{ if and (not .AlwaysAvailable) (not $.Limits.AllTriggers) }} opacity-50 cursor-not-allowed{{ else }} cursor-pointer{{ end }}">
<input type="checkbox" name="trigger_{{ if eq .Name "push" }}push{{ else if eq .Name "scan:first" }}first{{ else if eq .Name "scan:all" }}all{{ else }}changed{{ end }}"
class="checkbox checkbox-sm mt-0.5"
{{ if .DefaultChecked }}checked{{ end }}
{{ if and (not .AlwaysAvailable) (not $.Limits.AllTriggers) }}disabled{{ end }}>
<span>
<span class="text-sm font-medium">{{ .Label }}</span>
{{ if and (not .AlwaysAvailable) (not $.Limits.AllTriggers) }}<span class="badge badge-xs badge-outline ml-1">{{ if $.Limits.PaidTierName }}{{ $.Limits.PaidTierName }}{{ else }}Paid{{ end }}</span>{{ end }}
<br><span class="text-xs text-base-content/60">{{ .Description }}</span>
</span>
</label>
{{ end }}
</div>
</fieldset>
<div class="flex items-center justify-between">
<span class="text-sm text-base-content/60">
{{ len .Webhooks }} / {{ if eq .Limits.Max -1 }}unlimited{{ else }}{{ .Limits.Max }}{{ end }} webhooks configured
</span>
<button type="submit" class="btn btn-primary btn-sm"
{{ if and (ne .Limits.Max -1) (ge (len .Webhooks) .Limits.Max) }}disabled{{ end }}>
Add Webhook
</button>
</div>
</form>
<!-- Existing Webhooks -->
{{ if .Webhooks }}
<div class="space-y-3">
{{ range .Webhooks }}
<div class="card bg-base-200 border border-base-300 p-4">
<div class="flex items-start justify-between gap-4">
<div class="min-w-0 flex-1">
<code class="text-sm break-all">{{ .URL }}</code>
<div class="flex flex-wrap gap-1 mt-2">
{{ if .HasPush }}
<span class="badge badge-sm badge-info">push</span>
{{ end }}
{{ if .HasFirst }}
<span class="badge badge-sm badge-primary">scan:first</span>
{{ end }}
{{ if .HasAll }}
<span class="badge badge-sm badge-secondary">scan:all</span>
{{ end }}
{{ if .HasChanged }}
<span class="badge badge-sm badge-accent">scan:changed</span>
{{ end }}
{{ if .HasSecret }}
<span class="badge badge-sm badge-ghost">Signed</span>
{{ end }}
</div>
</div>
<div class="flex gap-2 shrink-0">
<button class="btn btn-xs btn-ghost"
data-action="test-webhook" data-webhook-id="{{ .ID }}"
title="Send test payload">
Test
</button>
<button class="btn btn-xs btn-error btn-ghost"
hx-delete="/api/webhooks/{{ .ID }}"
hx-target="#{{ $.ContainerID }}"
hx-swap="innerHTML"
hx-confirm="Delete this webhook?"
title="Delete webhook">
Delete
</button>
</div>
</div>
</div>
{{ end }}
</div>
{{ else }}
<p class="text-base-content/70 text-sm text-center py-4">No webhooks configured yet.</p>
{{ end }}
</div>
{{ end }}