Diff -- /var/www/vhosts/3dshawn.com/site1/TEMPLATES/alerts.html

O Operator
Diff

/var/www/vhosts/3dshawn.com/site1/TEMPLATES/alerts.html

added on local at 2026-07-11 18:27:46

Added
+184
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to e8e28508e1fc
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1<div class="page-head">
2 <span class="page-eyebrow"><span class="dot"></span> Notify</span>
3 <h1 class="page-title">Alert rules</h1>
4 <p class="page-subtitle">Route file + schema changes to Slack, Discord, or any HTTP webhook. Rules fire in near-real-time (as the cron dispatcher runs every minute). Every attempt is logged.</p>
5</div>
6
7<div class="dash-grid" style="grid-template-columns:1fr 1fr;margin-bottom:20px">
8
9 <!-- Rule form -->
10 <div class="module glow-teal">
11 <div class="module-head"><div class="left">
12 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg></div>
13 <div class="module-title">[if:$is_edit]Edit rule #$edit_id[/if][if:!$is_edit]New rule[/if]</div>
14 <span class="module-subtitle">Combine a matcher (kind + path glob) with a delivery target. Save, then wait for the next capture tick.</span>
15 </div></div>
16 <div class="module-body">
17 <form method="post" action="/alerts.cgi" style="display:flex;flex-direction:column;gap:12px">
18 <input type="hidden" name="op" value="$form_op">
19 [if:$is_edit]<input type="hidden" name="alert_rule_id" value="$edit_id">[/if]
20
21 <label style="display:flex;flex-direction:column;gap:4px">
22 <span class="rb-label">Name</span>
23 <input type="text" name="rule_name" value="$rule_name" placeholder="e.g. Prod nginx config changes" required
24 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:inherit">
25 </label>
26
27 <div style="display:flex;gap:12px">
28 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
29 <span class="rb-label">Match kind</span>
30 <select name="match_kind" style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
31 <option value="either" $mk_either_sel>Either (file + schema)</option>
32 <option value="file" $mk_file_sel>File changes only</option>
33 <option value="schema" $mk_schema_sel>Schema DDL only</option>
34 </select>
35 </label>
36 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
37 <span class="rb-label">Path glob</span>
38 <input type="text" name="match_path_glob" value="$match_path_glob" placeholder="e.g. /etc/nginx/** or drift_sense.**"
39 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:var(--mono);font-size:12px">
40 </label>
41 </div>
42
43 <div style="display:flex;gap:12px">
44 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
45 <span class="rb-label">Status filter <span class="dim" style="text-transform:none;letter-spacing:0;font-size:10.5px">(files only)</span></span>
46 <input type="text" name="match_status_list" value="$match_status_list" placeholder="added,modified,deleted"
47 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:var(--mono);font-size:12px">
48 </label>
49 <label style="flex:1;display:flex;align-items:center;gap:8px;margin-top:16px">
50 <input type="checkbox" name="exclude_ts_only" value="1" $exclude_ts_only_checked>
51 <span style="font-size:12.5px;color:var(--text-dim)">Exclude timestamp-only changes</span>
52 </label>
53 </div>
54
55 <hr style="border:none;border-top:1px solid var(--border);margin:4px 0">
56
57 <div style="display:flex;gap:12px">
58 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
59 <span class="rb-label">Delivery</span>
60 <select name="delivery_kind" style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
61 <option value="generic_webhook" $dk_generic_webhook_sel>Generic HTTP webhook</option>
62 <option value="slack" $dk_slack_sel>Slack incoming webhook</option>
63 <option value="discord" $dk_discord_sel>Discord webhook</option>
64 <option value="email" $dk_email_sel>Email (not yet implemented)</option>
65 </select>
66 </label>
67 <label style="flex:2;display:flex;flex-direction:column;gap:4px">
68 <span class="rb-label">Webhook URL</span>
69 <input type="text" name="delivery_url" value="$delivery_url" placeholder="https://hooks.slack.com/..."
70 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:var(--mono);font-size:11.5px">
71 </label>
72 </div>
73
74 <div style="display:flex;gap:12px">
75 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
76 <span class="rb-label">Rate limit / min</span>
77 <input type="number" name="rate_limit_per_min" value="$rate_limit_per_min" min="0"
78 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
79 </label>
80 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
81 <span class="rb-label">Coalesce window (s)</span>
82 <input type="number" name="coalesce_window_s" value="$coalesce_window_s" min="0"
83 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
84 </label>
85 <label style="flex:1;display:flex;align-items:center;gap:8px;margin-top:16px">
86 <input type="checkbox" name="is_active" value="1" $is_active_checked>
87 <span style="font-size:12.5px;color:var(--text-dim)">Rule is active</span>
88 </label>
89 </div>
90
91 <div style="display:flex;gap:8px;justify-content:flex-end;margin-top:8px">
92 [if:$is_edit]<a href="/alerts.cgi" class="tr-chip">Cancel</a>[/if]
93 <button type="submit" class="tr-chip is-active" style="border:none">[if:$is_edit]Save changes[/if][if:!$is_edit]Create rule[/if]</button>
94 </div>
95 </form>
96 </div>
97 </div>
98
99 <!-- Delivery history -->
100 <div class="module glow-emerald">
101 <div class="module-head"><div class="left">
102 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg></div>
103 <div class="module-title">Recent deliveries</div>
104 <span class="module-subtitle">Last 30 fire attempts across every rule. Audit trail for compliance / debugging.</span>
105 </div></div>
106 <div class="module-body tight" style="max-height:520px;overflow:auto">
107 [if:$has_deliveries]
108 <table class="tbl">
109 <thead><tr>
110 <th style="width:80px">Status</th>
111 <th>Rule / target</th>
112 <th style="width:120px">Result</th>
113 <th style="width:150px">When</th>
114 </tr></thead>
115 <tbody>
116 [loop:@deliveries]
117 <tr>
118 <td><span class="pill $delivery_pill">$delivery_status</span></td>
119 <td class="mono" style="font-size:11.5px"><a href="$source_url" style="color:var(--accent-hi);text-decoration:none">$summary_h</a></td>
120 <td class="dim mono" style="font-size:11px">$err_h</td>
121 <td class="mono dim"><span class="ts" data-ts="$fired_epoch" data-fmt="relative">$fired_at</span></td>
122 </tr>
123 [/loop]
124 </tbody>
125 </table>
126 [/if]
127 [if:!$has_deliveries]
128 <div style="padding:36px 14px;text-align:center;color:var(--text-dim);font-size:13.5px">
129 No deliveries yet. Create a rule and wait for a change to fire it.
130 </div>
131 [/if]
132 </div>
133 </div>
134</div>
135
136<!-- Rule list -->
137<div class="module glow-sky">
138 <div class="module-head"><div class="left">
139 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg></div>
140 <div class="module-title">Rules</div>
141 <span class="module-subtitle">Click a row to edit. Deactivating a rule stops it firing but keeps its history.</span>
142 </div></div>
143 <div class="module-body tight">
144 [if:$has_rules]
145 <table class="tbl">
146 <thead><tr>
147 <th style="width:80px">Status</th>
148 <th>Name</th>
149 <th>Matches</th>
150 <th style="width:110px">Delivery</th>
151 <th>Target</th>
152 <th style="width:70px">Fires</th>
153 <th style="width:150px">Last fired</th>
154 <th style="width:60px">Actions</th>
155 </tr></thead>
156 <tbody>
157 [loop:@rules]
158 <tr>
159 <td><span class="pill $status_pill">$status_label</span></td>
160 <td><a href="$edit_url" style="color:var(--accent-hi);text-decoration:none">$rule_name</a></td>
161 <td class="mono dim" style="font-size:11.5px">$match_kind &middot; $match_glob_h</td>
162 <td><span class="pill $kind_pill">$delivery_kind</span></td>
163 <td class="mono dim" style="font-size:11px">$url_h</td>
164 <td class="mono">$fire_count</td>
165 <td class="mono dim"><span class="ts" data-ts="$last_fired_epoch" data-fmt="relative">$last_fired_h</span></td>
166 <td>
167 <form method="post" action="/alerts.cgi" style="display:inline">
168 <input type="hidden" name="op" value="toggle">
169 <input type="hidden" name="alert_rule_id" value="$alert_rule_id">
170 <button type="submit" class="tr-chip" title="Toggle active" style="padding:3px 8px;font-size:11px">⏻</button>
171 </form>
172 </td>
173 </tr>
174 [/loop]
175 </tbody>
176 </table>
177 [/if]
178 [if:!$has_rules]
179 <div style="padding:36px 14px;text-align:center;color:var(--text-dim);font-size:13.5px">
180 No rules yet. Use the form above to create your first.
181 </div>
182 [/if]
183 </div>
184</div>