feat: bring over api features to dash

This commit is contained in:
nate 2026-04-10 00:50:05 +04:00
parent 52434d6529
commit efa90cac6a
5 changed files with 47 additions and 1 deletions

View File

@ -594,6 +594,7 @@ export const dashboard = new Elysia()
retry_interval_s: Number(b.retry_interval_s) || undefined,
resend_interval: Number(b.resend_interval) || 0,
cert_alert_days: b.cert_alert_days != null ? Number(b.cert_alert_days) : 0,
max_redirects: b.max_redirects != null ? Number(b.max_redirects) : 1,
channel_ids: Array.isArray(b.channel_ids) ? b.channel_ids : (b.channel_ids ? [b.channel_ids] : []),
regions,
request_headers: Object.keys(requestHeaders).length ? requestHeaders : null,
@ -636,6 +637,7 @@ export const dashboard = new Elysia()
retry_interval_s: Number(b.retry_interval_s) || undefined,
resend_interval: Number(b.resend_interval) || 0,
cert_alert_days: b.cert_alert_days != null ? Number(b.cert_alert_days) : 0,
max_redirects: b.max_redirects != null ? Number(b.max_redirects) : 1,
channel_ids: Array.isArray(b.channel_ids) ? b.channel_ids : (b.channel_ids ? [b.channel_ids] : []),
regions,
request_headers: Object.keys(requestHeaders).length ? requestHeaders : null,
@ -737,8 +739,11 @@ export const dashboard = new Elysia()
bar_frequency: b.bar_frequency || "daily",
bar_count: Number(b.bar_count) || 90,
show_response_time: !!b.show_response_time,
show_cert_expiry: !!b.show_cert_expiry,
show_powered_by: !!b.show_powered_by,
index_search: !!b.index_search,
auto_refresh_s: Number(b.auto_refresh_s) || 60,
og_image_url: b.og_image_url || null,
password: b.password || undefined,
custom_css: b.custom_css || null,
footer_text: b.footer_text || null,
@ -767,8 +772,11 @@ export const dashboard = new Elysia()
bar_frequency: b.bar_frequency || "daily",
bar_count: Number(b.bar_count) || 90,
show_response_time: !!b.show_response_time,
show_cert_expiry: !!b.show_cert_expiry,
show_powered_by: !!b.show_powered_by,
index_search: !!b.index_search,
auto_refresh_s: Number(b.auto_refresh_s) || 60,
og_image_url: b.og_image_url || null,
custom_css: b.custom_css || null,
footer_text: b.footer_text || null,
monitors: monitorsForApi,
@ -858,6 +866,7 @@ export const dashboard = new Elysia()
title: b.title,
status: b.status || "investigating",
severity: b.severity || "minor",
pinned: !!b.pinned,
monitor_ids: monitorIds,
status_page_ids: pageIds,
initial_update: { body: b.initial_update_body || "Investigating." },
@ -883,6 +892,7 @@ export const dashboard = new Elysia()
title: b.title,
status: b.status,
severity: b.severity,
pinned: !!b.pinned,
monitor_ids: monitorIds,
status_page_ids: pageIds,
}),

View File

@ -25,6 +25,11 @@
class="w-full bg-gray-900 border border-gray-800 rounded-lg px-4 py-2.5 text-gray-100 placeholder-gray-600 focus:outline-none focus:border-blue-500">
</div>
<label class="flex items-center gap-2 text-sm text-gray-400">
<input type="checkbox" name="pinned" value="1" <%= (i.pinned !== false) ? 'checked' : '' %> class="accent-blue-500">
Pinned (show in active incidents on status pages)
</label>
<div class="flex gap-4">
<div class="flex-1">
<label class="block text-sm text-gray-400 mb-1.5">Status</label>

View File

@ -47,6 +47,7 @@
retry_interval_s: Number(document.getElementById(prefix + 'retry-interval').value),
resend_interval: Number(document.getElementById(prefix + 'resend-interval').value),
cert_alert_days: Number(document.getElementById(prefix + 'cert-alert-days').value),
max_redirects: Number(document.getElementById(prefix + 'max-redirects-follow').value),
};
body.channel_ids = [...document.querySelectorAll('.' + prefix + 'channel-check:checked')].map(el => el.value);
if (Object.keys(headers).length) body.request_headers = headers;

View File

@ -121,6 +121,16 @@
</div>
</div>
<div>
<label class="block text-sm text-gray-400 mb-1.5">Max redirects</label>
<select id="<%= prefix %>max-redirects-follow" name="max_redirects"
class="w-full <%= bg %> border <%= border %> rounded-lg px-4 py-2.5 text-gray-100 focus:outline-none focus:border-blue-500">
<% [['0','None'],['1','1'],['2','2'],['3','3'],['4','4']].forEach(function([val, label]) { %>
<option value="<%= val %>" <%= String(monitor.max_redirects ?? '1') === val ? 'selected' : '' %>><%= label %></option>
<% }) %>
</select>
</div>
<%
const certDaysRaw = Number(monitor.cert_alert_days);
const certDaysSel = (certDaysRaw >= 1 && certDaysRaw <= 9) ? String(certDaysRaw) : '0';

View File

@ -160,11 +160,15 @@
<% } %>
</div>
<div class="flex gap-6">
<div class="flex flex-wrap gap-x-6 gap-y-2">
<label class="flex items-center gap-2 text-sm text-gray-400">
<input type="checkbox" name="show_response_time" value="1" <%= (p.show_response_time !== false) ? 'checked' : '' %> class="accent-blue-500">
Show response time
</label>
<label class="flex items-center gap-2 text-sm text-gray-400">
<input type="checkbox" name="show_cert_expiry" value="1" <%= p.show_cert_expiry ? 'checked' : '' %> class="accent-blue-500">
Show cert expiry
</label>
<label class="flex items-center gap-2 text-sm text-gray-400">
<input type="checkbox" name="show_powered_by" value="1" <%= (p.show_powered_by !== false) ? 'checked' : '' %> class="accent-blue-500">
Show "Powered by PingQL"
@ -175,6 +179,22 @@
</label>
</div>
<div class="flex gap-4">
<div class="flex-1">
<label class="block text-sm text-gray-400 mb-1.5">Auto-refresh</label>
<select name="auto_refresh_s" class="w-full bg-surface-solid border border-border-subtle rounded-lg px-4 py-2.5 text-gray-100 focus:outline-none focus:border-blue-500">
<% [['10','10 seconds'],['30','30 seconds'],['60','1 minute'],['120','2 minutes'],['300','5 minutes'],['600','10 minutes'],['3600','1 hour']].forEach(function([v, label]) { %>
<option value="<%= v %>" <%= String(p.auto_refresh_s || 60) === v ? 'selected' : '' %>><%= label %></option>
<% }) %>
</select>
</div>
<div class="flex-1">
<label class="block text-sm text-gray-400 mb-1.5">OG image URL <span class="text-gray-600">(optional)</span></label>
<input name="og_image_url" type="url" value="<%= p.og_image_url || '' %>" placeholder="https://example.com/og.png"
class="w-full bg-surface-solid border border-border-subtle rounded-lg px-4 py-2.5 text-gray-100 placeholder-gray-600 focus:outline-none focus:border-blue-500 text-sm">
</div>
</div>
<% const hasPassword = !it.isNew && p.password_hash; %>
<div data-password-section>
<label class="block text-sm text-gray-400 mb-1.5">Password <span class="text-gray-600">(optional)</span></label>