{{define "title"}}{{.Title}}{{end}} {{define "content"}} {{$page := .Page}}
{{/* ---------- breadcrumbs ---------- */}}
Dashboard/ {{if $page.Form}} Settings/ notifications/ {{if $page.Form.ID}} {{$page.Form.Name}} {{else}} new channel {{end}} {{else}} Settings/ notifications {{end}}
{{/* ---------- page header ---------- */}}
{{if $page.Form}}

{{if $page.Form.ID}}Edit channel · {{$page.Form.Name}}{{else}}Add channel{{end}}

{{else}}

Settings

+ Add channel {{end}}
{{/* ---------- sub-tab nav ---------- */}}
Notifications {{if not $page.Form}}{{len $page.Channels}}{{end}} Users Authentication
{{/* ---------- sub-tab body ---------- */}}
{{if $page.Form}} {{template "notification_edit_form" $page}} {{else}} {{template "notification_list_body" $page}} {{end}}
{{end}} {{/* ================================================================ notification_list_body — channel list (embedded in settings.html) Receives $page (settingsPage). ================================================================ */}} {{define "notification_list_body"}}

Notification channels fire when the alert engine raises an alert. All channels apply globally — every alert that meets the engine's thresholds is sent to every enabled channel.

{{if not .Channels}}

No channels configured.

Alerts are still raised in the dashboard, but nothing is pushed to chat / phone / email. Add a channel to get notified.

+ Add your first channel
{{else}}
Name
Endpoint
Enabled
Last fired
{{range .Channels}} {{$ch := .}}
edit {{$ch.Name}}
{{if eq $ch.Kind "webhook"}}WH {{else if eq $ch.Kind "ntfy"}}NT {{else}}@{{end}}
{{$ch.Name}}
{{if eq $ch.Kind "webhook"}}webhook · click to edit{{else if eq $ch.Kind "ntfy"}}ntfy · click to edit{{else}}smtp · click to edit{{end}}
{{if $ch.Enabled}} {{else}} {{end}}
{{if $ch.LastFiredAt}}{{relTime $ch.LastFiredAt}}{{else}}never{{end}}
{{end}}
{{end}} {{end}} {{/* ================================================================ notification_edit_form — create/edit form (embedded in settings.html) Receives $page (settingsPage). ================================================================ */}} {{define "notification_edit_form"}} {{$f := .Form}} {{$isEdit := ne $f.ID ""}} {{if .FormError}}
{{.FormError}}
{{end}} {{if .DeleteError}}
{{.DeleteError}}
{{end}}
{{/* ---------- kind picker ---------- */}}
Channel kind
{{/* Webhook card */}} {{/* Ntfy card */}} {{/* SMTP card */}}
{{/* ---------- per-kind fields ---------- */}} {{if $isEdit}}
{{else}} {{end}} {{/* hidden kind field updated by JS */}} {{/* Webhook fields */}}
Operator-friendly label shown in the channel list and audit log.
We POST the JSON envelope shown on the right. 5s timeout; failures are logged but not retried.
If set, sent as Authorization: Bearer … on every POST.
Single extra header in v1.
{{/* Ntfy fields */}}
Default https://ntfy.sh; change for self-hosted.
Subscribe to this topic in the ntfy app.
Use this OR username+password below. Token wins when both are set.
Sent as HTTP Basic auth when no token is set.
Per-alert severity overrides this — critical alerts always go out at urgent regardless of the default.
{{/* SMTP fields */}}
One channel = one recipient — add another channel for a second mailbox.
App password recommended for Gmail / M365.
Single address or distribution list.
{{/* ---------- enabled + test ---------- */}}
Enabled
When off, this channel is skipped on alert dispatch.
{{if $isEdit}}
Sends severity=info, kind=test_notification, message="Test from restic-manager".
{{end}}
{{/* ---------- action row ---------- */}}
Cancel
{{if $isEdit}} {{end}}
{{/* ---------- typed-confirm delete ---------- */}}
{{/* close ch-form — delete panel must live OUTSIDE because HTML forbids nested forms */}} {{if $isEdit}} {{end}}
{{/* ---------- right rail — payload preview ---------- All three are rendered; the kind-switcher JS toggles which is visible. Server-side {{if}} would freeze the panel at whichever kind was loaded, so flipping the picker leaves it stale. */}}
{{/* JS: kind-picker interactivity + enabled toggle + HTMX test-result rendering */}} {{end}}