Files
weircon-front/templates/admin_ops.html
T

66 lines
3.5 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.
{% extends "base.html" %}
{% block title %}Admin — drift{% endblock %}
{% block body %}
<h1>Drift / egress</h1>
<p class="lead">Live driftsoverblik. Genindlæser automatisk hvert 20. sekund.</p>
<h2>Static-assets</h2>
<div class="stat" style="max-width:18rem">
<div class="n">{{ version if version else '—' }}</div>
<div class="muted">deployet version (assets.weircon.dk)</div>
</div>
<h2 style="display:flex;align-items:baseline;gap:.8rem">Random-proxy egress
{% if rp and not rp.error %}<span class="muted" style="font-size:.8rem;letter-spacing:0;text-transform:none">
{{ rp.available }}/{{ rp.proxies_total }} live · {{ rp.inflight_total }} inflight i alt</span>{% endif %}
</h2>
{% if rp.error %}
<div class="err">Kunne ikke nå random-proxy: {{ rp.error }}</div>
{% else %}
{% set rot = rp.rotation %}
{% if rot %}
<div class="stat" style="margin-bottom:1rem">
<div class="muted">Næste rollover</div>
<div style="margin-top:.3rem">
<strong>slot {{ rot.next_slot }}</strong>
— <span class="font-mono">{{ rot.next_egress_ip }}</span>
{% if rot.geo and rot.geo.flag %}<span title="{{ rot.geo.name }}">{{ rot.geo.flag }} {{ rot.geo.iso }}</span>{% endif %}
ruller af om <strong>{{ '%d:%02d'|format(rot.eta_sec//60, rot.eta_sec%60) }}</strong>
<span class="muted">(interval {{ rot.interval_sec }}s · sidst: slot {{ rot.last_slot }} for {{ rot.last_rotated_age_sec }}s siden)</span>
</div>
</div>
{% endif %}
<div class="grid" style="grid-template-columns:repeat(auto-fill,minmax(190px,1fr))">
{% for p in rp.proxies %}
<div class="slot{% if rot and p.id == rot.next_slot %} next{% endif %}">
<div class="slot-top">
<span class="slot-id">#{{ p.id }}</span>
<span class="slot-state {{ 'down' if not p.reachable else ('busy' if p.inflight else 'live') }}">
{{ '⚠ down' if not p.reachable else (p.state or 'live') }}</span>
</div>
<div class="font-mono" style="font-size:.92rem;overflow:hidden;text-overflow:ellipsis">{{ p.egress_ip or '–' }}</div>
<div class="muted" style="font-size:.84rem;margin-top:.2rem">
{% if p.geo and p.geo.flag %}{{ p.geo.flag }} {{ p.geo.iso }} · {% endif %}{{ p.inflight or 0 }} inflight
{% if p.latency_ms %}· {{ p.latency_ms }}ms{% endif %}
</div>
{% if rot and p.id == rot.next_slot %}<div class="slot-next">↻ ruller af næst</div>{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
<style>
.font-mono { font-family: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace; }
.slot { background:color-mix(in srgb, var(--surface) 70%, transparent); border:1px solid var(--border); border-radius:.9rem; padding:.8rem .9rem; }
.slot.next { border-color:#f5a623; box-shadow:0 0 0 1px color-mix(in srgb,#f5a623 40%,transparent); }
.slot-top { display:flex; justify-content:space-between; align-items:center; margin-bottom:.35rem; }
.slot-id { font-weight:700; color:var(--muted); font-size:.85rem; }
.slot-state { font-size:.72rem; border-radius:999px; padding:.05rem .5rem; border:1px solid var(--border); color:var(--muted); }
.slot-state.live { color:var(--ok, #3ecf8e); border-color:color-mix(in srgb,#3ecf8e 40%,transparent); }
.slot-state.busy { color:#f5a623; border-color:color-mix(in srgb,#f5a623 40%,transparent); }
.slot-state.down { color:#f87171; border-color:color-mix(in srgb,#f87171 40%,transparent); }
.slot-next { color:#f5a623; font-size:.74rem; margin-top:.35rem; }
</style>
<script>setTimeout(function(){ location.reload(); }, 20000);</script>
{% endblock %}