visual refactor
This commit is contained in:
@@ -2,75 +2,134 @@
|
||||
<html lang="en" data-bs-theme="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>PVE HA Panel</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='styles.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap & Icons -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet" />
|
||||
|
||||
<!-- App styles -->
|
||||
<link href="{{ url_for('static', filename='styles.css') }}" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container py-4">
|
||||
<!-- Top Navbar -->
|
||||
<nav class="navbar navbar-expand-lg sticky-top border-bottom bg-body">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand fw-semibold d-flex align-items-center gap-2" href="#">
|
||||
<i class="bi bi-hdd-network"></i> PVE HA Panel
|
||||
</a>
|
||||
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-center mb-3 gap-2">
|
||||
<h1 class="h4 m-0">PVE HA Panel</h1>
|
||||
<div class="d-flex flex-wrap align-items-center gap-2">
|
||||
<input class="form-control form-control-sm" id="node" value="{{ node }}" style="width: 180px" aria-label="Node">
|
||||
<button class="btn btn-outline-secondary btn-sm" id="btnToggleAll" aria-expanded="false">Collapse/Expand
|
||||
all</button>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#topNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="vr d-none d-md-block"></div>
|
||||
<div class="collapse navbar-collapse" id="topNav">
|
||||
<!-- Left: quick filters -->
|
||||
<form class="d-flex align-items-center gap-2 me-auto mt-3 mt-lg-0 flex-wrap" role="search">
|
||||
<div class="input-group input-group-sm" style="max-width: 220px;">
|
||||
<span class="input-group-text"><i class="bi bi-diagram-3"></i></span>
|
||||
<input class="form-control" id="node" value="{{ node }}" placeholder="Node" aria-label="Node" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<button class="btn btn-primary btn-sm" id="btnRefresh">Refresh now</button>
|
||||
<div class="input-group input-group-sm" style="width:220px">
|
||||
<span class="input-group-text">Auto-refresh</span>
|
||||
<select class="form-select" id="selInterval" disabled>
|
||||
<option value="10000">10 s</option>
|
||||
<option value="20000">20 s</option>
|
||||
<option value="30000" selected>30 s</option>
|
||||
<option value="45000">45 s</option>
|
||||
<option value="60000">60 s</option>
|
||||
<option value="120000">120 s</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-success" id="btnAuto">OFF</button>
|
||||
<!-- Right: global controls -->
|
||||
<div class="d-flex flex-wrap align-items-center gap-2 mt-3 mt-lg-0">
|
||||
<button class="btn btn-outline-secondary btn-sm" id="btnToggleAll" aria-expanded="false">
|
||||
<i class="bi bi-arrows-collapse"></i> Collapse/Expand all
|
||||
</button>
|
||||
|
||||
<div class="vr d-none d-lg-block"></div>
|
||||
|
||||
<button class="btn btn-primary btn-sm" id="btnRefresh">
|
||||
<i class="bi bi-arrow-clockwise"></i> Refresh now
|
||||
</button>
|
||||
|
||||
<div class="input-group input-group-sm" style="width: 240px;">
|
||||
<span class="input-group-text"><i class="bi bi-clock-history"></i> Auto</span>
|
||||
<select class="form-select" id="selInterval" disabled>
|
||||
<option value="10000">10 s</option>
|
||||
<option value="20000">20 s</option>
|
||||
<option value="30000" selected>30 s</option>
|
||||
<option value="45000">45 s</option>
|
||||
<option value="60000">60 s</option>
|
||||
<option value="120000">120 s</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-success" id="btnAuto">OFF</button>
|
||||
</div>
|
||||
|
||||
<div class="vr d-none d-lg-block"></div>
|
||||
|
||||
<button type="button" class="btn btn-success btn-sm" id="btnEnable">
|
||||
<i class="bi bi-hammer"></i> Enable maintenance
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger btn-sm" id="btnDisable">
|
||||
<i class="bi bi-exclamation-octagon"></i> Disable maintenance
|
||||
</button>
|
||||
|
||||
<div class="vr d-none d-lg-block"></div>
|
||||
|
||||
<!-- UI-only toggles (localStorage) -->
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" id="btnDensity" title="Toggle compact density">
|
||||
<i class="bi bi-distribute-vertical"></i> Density
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" id="btnTheme" title="Toggle dark / light">
|
||||
<i class="bi bi-moon-stars"></i> Theme
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="vr d-none d-md-block"></div>
|
||||
|
||||
<button type="button" class="btn btn-success btn-sm" id="btnEnable">Enable maintenance</button>
|
||||
<button type="button" class="btn btn-danger btn-sm" id="btnDisable">Disable maintenance</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Global loading -->
|
||||
<div id="global-loading" class="d-flex align-items-center gap-2 mb-3">
|
||||
<!-- Global loading -->
|
||||
<div id="global-loading" class="container-fluid py-2">
|
||||
<div class="d-flex align-items-center gap-2 small text-muted">
|
||||
<div class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></div>
|
||||
<span class="small text-muted">Loading data…</span>
|
||||
<span>Loading data…</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Health & Tabs -->
|
||||
<main class="container-fluid py-3">
|
||||
<!-- HEALTH -->
|
||||
<div class="card mb-3 border-0 shadow health-card">
|
||||
<section class="card border-0 shadow-sm mb-3 health-card">
|
||||
<div class="card-body d-flex flex-wrap align-items-center gap-3">
|
||||
<div class="health-dot" id="healthDot" aria-hidden="true"></div>
|
||||
<div>
|
||||
<div class="fw-bold" id="healthTitle">Loading…</div>
|
||||
<span class="health-dot" id="healthDot" aria-hidden="true"></span>
|
||||
<div class="me-auto">
|
||||
<div class="fw-semibold fs-6" id="healthTitle">Loading…</div>
|
||||
<div class="text-muted small" id="healthSub">—</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-tabs mb-3" id="mainTabs" role="tablist">
|
||||
<!-- Small inline metrics (space efficient) -->
|
||||
<div class="d-flex flex-wrap gap-3 small text-muted" id="inlineMetrics" aria-live="polite">
|
||||
<!-- You can fill from your JS if you wish; purely presentational -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Main tabs -->
|
||||
<ul class="nav nav-tabs nav-fill shadow-sm rounded overflow-auto mb-3" id="mainTabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tab-ha" type="button">HA</button>
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tab-ha" type="button">
|
||||
<i class="bi bi-shield-lock"></i> HA
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-nonha" type="button">VM/CT (non-HA)</button>
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-nonha" type="button">
|
||||
<i class="bi bi-cpu"></i> VM/CT (non-HA)
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-admin" type="button">VM Admin</button>
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-admin" type="button">
|
||||
<i class="bi bi-tools"></i> VM Admin
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-nodes" type="button">Nodes</button>
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-nodes" type="button">
|
||||
<i class="bi bi-diagram-3"></i> Nodes
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -80,7 +139,7 @@
|
||||
<div class="accordion" id="acc">
|
||||
|
||||
<!-- Cluster / Quorum -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-item rounded-3 overflow-hidden mb-2">
|
||||
<h2 class="accordion-header" id="h-q">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c-q">
|
||||
Cluster / Quorum
|
||||
@@ -96,8 +155,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Systemd -->
|
||||
<div class="accordion-item">
|
||||
<!-- Systemd (HA) -->
|
||||
<div class="accordion-item rounded-3 overflow-hidden mb-2">
|
||||
<h2 class="accordion-header" id="h-sd">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c-sd">
|
||||
Systemd (HA)
|
||||
@@ -105,13 +164,15 @@
|
||||
</h2>
|
||||
<div id="c-sd" class="accordion-collapse collapse" data-bs-parent="#acc">
|
||||
<div class="accordion-body">
|
||||
<div id="units" class="d-flex flex-wrap gap-2"><span class="text-muted small">Loading…</span></div>
|
||||
<div id="units" class="d-flex flex-wrap gap-2">
|
||||
<span class="text-muted small">Loading…</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Replication -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-item rounded-3 overflow-hidden mb-2">
|
||||
<h2 class="accordion-header" id="h-repl">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#c-repl">
|
||||
@@ -126,7 +187,7 @@
|
||||
</div>
|
||||
|
||||
<!-- HA resources -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-item rounded-3 overflow-hidden mb-2">
|
||||
<h2 class="accordion-header" id="h-res">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#c-res">
|
||||
@@ -136,7 +197,7 @@
|
||||
<div id="c-res" class="accordion-collapse collapse" data-bs-parent="#acc">
|
||||
<div class="accordion-body table-responsive">
|
||||
<table class="table table-sm table-striped align-middle table-nowrap" id="ha-res">
|
||||
<thead>
|
||||
<thead class="position-sticky top-0 bg-body">
|
||||
<tr>
|
||||
<th class="w-1"></th>
|
||||
<th>SID</th>
|
||||
@@ -148,13 +209,13 @@
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<div class="small text-muted">Click to expand VM/CT data.</div>
|
||||
<div class="small text-muted">Click a row to expand VM/CT details.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Raw -->
|
||||
<div class="accordion-item">
|
||||
<div class="accordion-item rounded-3 overflow-hidden">
|
||||
<h2 class="accordion-header" id="h-raw">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#c-raw">
|
||||
@@ -165,10 +226,10 @@
|
||||
<div class="accordion-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-6">
|
||||
<pre id="pvecm" class="mb-0 small"></pre>
|
||||
<pre id="pvecm" class="mb-0 small pre-scrollable"></pre>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<pre id="cfgtool" class="mb-0 small"></pre>
|
||||
<pre id="cfgtool" class="mb-0 small pre-scrollable"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -180,10 +241,10 @@
|
||||
|
||||
<!-- TAB: Non-HA -->
|
||||
<div class="tab-pane fade" id="tab-nonha">
|
||||
<div class="card border-0">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-sm table-striped align-middle table-nowrap" id="nonha">
|
||||
<thead>
|
||||
<thead class="position-sticky top-0 bg-body">
|
||||
<tr>
|
||||
<th class="w-1"></th>
|
||||
<th>SID</th>
|
||||
@@ -199,17 +260,17 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="small text-muted">Kliknij wiersz, aby rozwinąć szczegóły VM/CT.</div>
|
||||
<div class="small text-muted">Click a row to expand VM/CT details.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB: VM Admin -->
|
||||
<div class="tab-pane fade" id="tab-admin">
|
||||
<div class="card border-0">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-sm table-striped align-middle table-nowrap" id="vm-admin">
|
||||
<thead>
|
||||
<thead class="position-sticky top-0 bg-body">
|
||||
<tr>
|
||||
<th>SID</th>
|
||||
<th>Type</th>
|
||||
@@ -232,13 +293,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- TAB: Nodes (expandable) -->
|
||||
<!-- TAB: Nodes -->
|
||||
<div class="tab-pane fade" id="tab-nodes">
|
||||
<div class="card border-0">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-sm table-striped align-middle table-nowrap" id="nodes">
|
||||
<thead>
|
||||
<thead class="position-sticky top-0 bg-body">
|
||||
<tr>
|
||||
<th class="w-1"></th>
|
||||
<th>Node</th>
|
||||
@@ -264,8 +324,8 @@
|
||||
|
||||
<div class="text-muted small mt-3" id="footer">—</div>
|
||||
|
||||
<!-- SITE FOOTER -->
|
||||
<footer class="site-footer mt-4 pt-3 pb-4 text-muted small">
|
||||
<!-- Footer -->
|
||||
<footer class="site-footer mt-4 pt-3 pb-4 text-muted small border-top">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2">
|
||||
<div>© 2025 PVE HA Panel</div>
|
||||
<div>
|
||||
@@ -276,15 +336,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Toasts -->
|
||||
<div aria-live="polite" aria-atomic="true" class="position-fixed bottom-0 end-0" style="z-index: 1080">
|
||||
<div aria-live="polite" aria-atomic="true" class="position-fixed bottom-0 end-0 p-2" style="z-index:1080">
|
||||
<div id="toast-container" class="toast-container"></div>
|
||||
</div>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- UI-only enhancements (safe; no API changes) -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/ui.js') }}"></script>
|
||||
|
||||
<!-- Your logic (unchanged ids/contracts) -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
</body>
|
||||
|
||||
|
Reference in New Issue
Block a user