Files
crowdsec-admin/app/templates/_alerts.html
domverse 708f6373f1
All checks were successful
Deploy / deploy (push) Successful in 22s
feat: alerts view + created-at timestamps on decisions
Mirror cscli alerts list: new /alerts endpoint hits LAPI machine auth
with since/ip/scenario/origin filters, renders ID, scope:value, reason,
country, AS, events, decisions, created_at.

Decisions table gains a Created column derived from until - duration
(LAPI does not expose created_at on /v1/decisions). Both views format
timestamps locally and append a relative "x ago" via Intl.RelativeTimeFormat,
refreshed every 30s on the decisions view.
2026-06-21 15:13:14 +02:00

85 lines
3.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% if error %}
<p class="err">{{ error }}</p>
{% endif %}
{% if alerts %}
<p style="font-size:.8rem;color:#888;margin:.4rem 0;">
Showing <strong>{{ total }}</strong> alert{{ '' if total == 1 else 's' }}
since <code>{{ since }}</code>
(server limit {{ limit }}{% if total == limit %} — at cap, raise limit if more expected{% endif %}).
</p>
<table>
<thead>
<tr>
<th>ID</th>
<th>Scope:Value</th>
<th>Reason</th>
<th>Country</th>
<th>AS</th>
<th>Events</th>
<th>Decisions</th>
<th>Created</th>
</tr>
</thead>
<tbody>
{% for a in alerts %}
{% set src = a.source or {} %}
<tr>
<td><code>{{ a.id }}</code></td>
<td><code>{{ src.scope or a.scope or '?' }}:{{ src.value or a.value or '?' }}</code></td>
<td>
{{ a.scenario }}
{% if a.events_count and a.events_count > 1 %}<span class="pill">×{{ a.events_count }}</span>{% endif %}
</td>
<td>{{ src.cn or '—' }}</td>
<td>{% if src.as_number %}{{ src.as_number }}{% if src.as_name %} {{ src.as_name }}{% endif %}{% else %}—{% endif %}</td>
<td>{{ a.events_count or 0 }}</td>
<td>
{% if a.decisions %}
{% for dec in a.decisions %}
<span class="pill" title="origin={{ dec.origin }} until={{ dec.until }}">{{ dec.type }} {{ dec.duration }}{% if dec.simulated %} sim{% endif %}</span>
{% endfor %}
{% else %}
{% endif %}
</td>
<td><time class="ts" datetime="{{ a.created_at }}">{{ a.created_at }}</time></td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
(function(){
const RTF = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' });
const FMT = new Intl.DateTimeFormat(undefined, {
year: 'numeric', month: 'short', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false
});
const UNITS = [['year',31536000],['month',2592000],['day',86400],['hour',3600],['minute',60],['second',1]];
function relative(target, now){
const diff = (target - now) / 1000;
const abs = Math.abs(diff);
for (const [u, s] of UNITS) {
if (abs >= s || u === 'second') return RTF.format(Math.round(diff / s), u);
}
}
const now = new Date();
document.querySelectorAll('#alerts time.ts').forEach(t => {
const iso = t.getAttribute('datetime');
if (!iso) return;
const d = new Date(iso);
if (isNaN(d)) return;
t.textContent = FMT.format(d);
t.title = iso + ' (' + relative(d, now) + ')';
const small = document.createElement('small');
small.style.color = '#888';
small.style.marginLeft = '.35rem';
small.textContent = relative(d, now);
t.appendChild(small);
});
})();
</script>
{% else %}
{% if not error %}<p>No alerts in window.</p>{% endif %}
{% endif %}