201 lines
8.3 KiB
HTML
201 lines
8.3 KiB
HTML
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="color-scheme" content="dark">
|
||
<title>The Sentinel · Backup-Monitor</title>
|
||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><rect width='64' height='64' rx='10' fill='%23171917'/><path d='M18 20h28M18 32h28M18 44h18' stroke='%237abf8a' stroke-width='5' stroke-linecap='round'/></svg>">
|
||
<link rel="stylesheet" href="/static/css/style.css">
|
||
</head>
|
||
<body>
|
||
<header class="site-header">
|
||
<div class="topbar">
|
||
<a class="brand" href="#dashboard" onclick="showPage('dashboard'); return false;" aria-label="The Sentinel Startseite">
|
||
<span class="brand-mark" aria-hidden="true">S</span>
|
||
<span>
|
||
<strong>The Sentinel</strong>
|
||
<small>Backup-Monitor</small>
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="main-nav" aria-label="Hauptnavigation">
|
||
<a href="#dashboard" onclick="showPage('dashboard'); return false;" id="nav-dashboard" class="is-active" aria-current="page">Übersicht</a>
|
||
<a href="#alerts" onclick="showPage('alerts'); return false;" id="nav-alerts">Meldungen</a>
|
||
<a href="#hosts" onclick="showPage('hosts'); return false;" id="nav-hosts">Hosts</a>
|
||
<a href="#config" onclick="showPage('config'); return false;" id="nav-config">Einstellungen</a>
|
||
</nav>
|
||
|
||
<div class="topbar-actions">
|
||
<div id="sysStatus" class="system-state status--ok" aria-live="polite">
|
||
<span class="status-dot status--ok" aria-hidden="true"></span>
|
||
<span>Betriebsbereit</span>
|
||
</div>
|
||
<button type="button" class="icon-button" onclick="loadAll()" aria-label="Daten aktualisieren" title="Aktualisieren">↻</button>
|
||
<button type="button" class="icon-button" onclick="openAddHost()" aria-label="Host hinzufügen" title="Host hinzufügen">+</button>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="app-shell">
|
||
<section id="page-dashboard" class="page" aria-labelledby="dashboard-title">
|
||
<header class="page-header">
|
||
<div>
|
||
<p class="eyebrow">Borgmatic-Infrastruktur</p>
|
||
<h1 id="dashboard-title">Backup-Übersicht</h1>
|
||
<p class="lede">Der aktuelle Stand aller gemeldeten Sicherungen.</p>
|
||
</div>
|
||
<div class="scan-state">
|
||
<span>Letzte Aktualisierung</span>
|
||
<time id="lastScan">–</time>
|
||
</div>
|
||
</header>
|
||
|
||
<section class="metric-strip" id="metricCards" aria-label="Zusammenfassung">
|
||
<article class="metric">
|
||
<span class="metric-label">Hosts in Ordnung</span>
|
||
<strong id="mOk">–</strong>
|
||
</article>
|
||
<article class="metric">
|
||
<span class="metric-label">Heute gesichert</span>
|
||
<strong id="mSize">–</strong>
|
||
</article>
|
||
<article class="metric">
|
||
<span class="metric-label">Letzte Sicherung</span>
|
||
<strong id="mLatest">–</strong>
|
||
<small id="mLatestHost">–</small>
|
||
</article>
|
||
<article class="metric metric--issue" id="mWarnCard">
|
||
<span class="metric-label">Auffälligkeiten</span>
|
||
<strong id="mWarn">0</strong>
|
||
<button type="button" class="text-button" onclick="showPage('alerts')">Meldungen öffnen</button>
|
||
</article>
|
||
</section>
|
||
|
||
<div class="dashboard-grid">
|
||
<section class="panel panel--chart" aria-labelledby="volume-title">
|
||
<header class="panel-header">
|
||
<div>
|
||
<h2 id="volume-title">Gesichertes Datenvolumen</h2>
|
||
<p>Summe der letzten 30 Tage, über die zehn zuerst gemeldeten Hosts.</p>
|
||
</div>
|
||
</header>
|
||
<div class="chart" id="volumeChart">
|
||
<svg id="chartSvg" role="img" aria-label="Backup-Volumen der letzten 30 Tage" viewBox="0 0 100 100" preserveAspectRatio="none"></svg>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="panel panel--hosts" aria-labelledby="host-status-title">
|
||
<header class="panel-header">
|
||
<h2 id="host-status-title">Host-Status</h2>
|
||
</header>
|
||
<div id="clusterList" class="cluster-list"></div>
|
||
</section>
|
||
</div>
|
||
|
||
<section class="panel" aria-labelledby="stream-title">
|
||
<header class="panel-header panel-header--split">
|
||
<h2 id="stream-title">Letzte Meldungen</h2>
|
||
<span class="quiet-note">automatisch alle 30 Sekunden</span>
|
||
</header>
|
||
<div id="liveStream" class="event-list" aria-live="polite"></div>
|
||
</section>
|
||
</section>
|
||
|
||
<section id="page-alerts" class="page hidden" aria-labelledby="alerts-title">
|
||
<header class="page-header">
|
||
<div>
|
||
<p class="eyebrow">Prüfbedarf</p>
|
||
<h1 id="alerts-title">Meldungen</h1>
|
||
<p class="lede">Fehlgeschlagene oder überfällige Sicherungen.</p>
|
||
</div>
|
||
<dl class="inline-counts">
|
||
<div><dt>Fehler</dt><dd id="aCrit">0</dd></div>
|
||
<div><dt>Überfällig</dt><dd id="aStale">0</dd></div>
|
||
</dl>
|
||
</header>
|
||
<div id="alertList" class="alert-list">
|
||
<p class="empty-state">Keine offenen Meldungen.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="page-hosts" class="page hidden" aria-labelledby="hosts-title">
|
||
<header class="page-header">
|
||
<div>
|
||
<p class="eyebrow">Inventar</p>
|
||
<h1 id="hosts-title">Backup-Hosts</h1>
|
||
<p class="lede">Alle registrierten Endpunkte und ihre letzten Sicherungen.</p>
|
||
</div>
|
||
<button type="button" class="button button--primary" onclick="openAddHost()">Host hinzufügen</button>
|
||
</header>
|
||
<div id="hostGrid" class="host-grid"></div>
|
||
</section>
|
||
|
||
<section id="page-config" class="page hidden" aria-labelledby="config-title">
|
||
<header class="page-header">
|
||
<div>
|
||
<p class="eyebrow">Schnittstellen</p>
|
||
<h1 id="config-title">Einstellungen</h1>
|
||
<p class="lede">Die Endpunkte, über die Sentinel Daten annimmt und ausliefert.</p>
|
||
</div>
|
||
</header>
|
||
<dl class="settings-list">
|
||
<div>
|
||
<dt>Backup-Meldungen</dt>
|
||
<dd><code>POST /api/push</code></dd>
|
||
</div>
|
||
<div>
|
||
<dt>Prometheus</dt>
|
||
<dd><code>GET /metrics</code></dd>
|
||
</div>
|
||
<div>
|
||
<dt>API-Schlüssel</dt>
|
||
<dd>{{ 'Aktiviert (Umgebungsvariable API_KEY)' if api_key_required else 'Deaktiviert' }}</dd>
|
||
</div>
|
||
</dl>
|
||
</section>
|
||
</main>
|
||
|
||
<div id="drawerBg" class="backdrop is-hidden" onclick="closeDrawer()"></div>
|
||
<aside id="drawer" class="drawer is-closed" aria-labelledby="drawerTitle" aria-hidden="true">
|
||
<header class="overlay-header">
|
||
<div>
|
||
<span class="eyebrow">Host-Details</span>
|
||
<h2 id="drawerTitle">Host</h2>
|
||
</div>
|
||
<button type="button" class="icon-button" onclick="closeDrawer()" aria-label="Details schließen">×</button>
|
||
</header>
|
||
<div id="drawerBody" class="drawer-body"></div>
|
||
</aside>
|
||
|
||
<div id="modalBg" class="backdrop is-hidden" onclick="closeModal()"></div>
|
||
<section id="modal" class="modal is-closed" role="dialog" aria-modal="true" aria-labelledby="modalTitle" aria-hidden="true">
|
||
<header class="overlay-header">
|
||
<h2 id="modalTitle">Host hinzufügen</h2>
|
||
<button type="button" class="icon-button" onclick="closeModal()" aria-label="Dialog schließen">×</button>
|
||
</header>
|
||
<form id="hostForm" onsubmit="saveHost(event)" class="form-stack">
|
||
<input type="hidden" id="formMode" value="add">
|
||
<label>
|
||
<span>Hostname</span>
|
||
<input type="text" id="formName" required placeholder="zum Beispiel arrapps">
|
||
</label>
|
||
<label>
|
||
<span>Uptime-Kuma Push-URL</span>
|
||
<input type="url" id="formKumaUrl" placeholder="https://status.example.com/api/push/…">
|
||
</label>
|
||
<label class="checkbox-row">
|
||
<input type="checkbox" id="formEnabled" checked>
|
||
<span>Host überwachen</span>
|
||
</label>
|
||
<div class="form-actions">
|
||
<button type="button" class="button" onclick="closeModal()">Abbrechen</button>
|
||
<button type="submit" class="button button--primary">Speichern</button>
|
||
</div>
|
||
</form>
|
||
</section>
|
||
|
||
<div id="toasts" class="toast-stack" aria-live="polite"></div>
|
||
<script src="/static/js/app.js"></script>
|
||
</body>
|
||
</html>
|