overview updates and removal of duplicate title headers
CI / Build & Test (push) Successful in 4m55s

This commit is contained in:
Raven Scott
2026-02-28 22:10:48 -05:00
parent 4a7399dab8
commit 8cc76e580a
+43 -45
View File
@@ -184,14 +184,20 @@
.topbar-title { font-size: 15px; font-weight: 600; color: var(--text); } .topbar-title { font-size: 15px; font-weight: 600; color: var(--text); }
.topbar-actions { display: flex; align-items: center; gap: 8px; } .topbar-actions { display: flex; align-items: center; gap: 8px; }
.content { padding: 24px 28px; flex: 1; } .content { padding: 24px 28px; flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* ── Page visibility ───────────────────────────── */ /* ── Page visibility ───────────────────────────── */
.page { display: none; } .page { display: none; }
.page.active { display: block; } .page.active { display: block; }
/* Overview page: content is fixed-height (capped list cards) so the /* Overview page fills the content area as a flex column so Quick Actions
outer scroll area must not scroll — Quick Actions stays visible. */ sticks to the bottom and the list cards share all remaining space. */
#page-dashboard.active { overflow: hidden; } #page-dashboard.active {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
overflow: hidden;
}
/* ── Cards ─────────────────────────────────────── */ /* ── Cards ─────────────────────────────────────── */
.card { .card {
@@ -324,13 +330,17 @@
.ov-list-card { .ov-list-card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 0;
/* Cards fill the grid cell height set by the flex grid rows */
height: 100%;
} }
/* Fixed height: thead (~34px) + exactly 2 data rows (~36px each) = ~106px. /* The scroll area grows to fill whatever height the card has after the
Items 3+ scroll inside the card; the page itself never scrolls. */ header and search input. No max-height — the grid rows control height. */
.ov-scroll-area { .ov-scroll-area {
flex: 1;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
max-height: 106px; min-height: 0;
} }
.ov-table thead th { .ov-table thead th {
position: sticky; position: sticky;
@@ -634,15 +644,6 @@
.copy-btn.copied .copy-tooltip { opacity: 1; } .copy-btn.copied .copy-tooltip { opacity: 1; }
/* ── Page headers ──────────────────────────────── */ /* ── Page headers ──────────────────────────────── */
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
gap: 12px;
}
.page-header h2 { font-size: 18px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
/* ── Inline row layout ─────────────────────────── */ /* ── Inline row layout ─────────────────────────── */
.row { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; } .row { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.row .form-group { flex: 1; min-width: 120px; } .row .form-group { flex: 1; min-width: 120px; }
@@ -1017,13 +1018,12 @@
<!-- ── Overview page ──────────────────────────── --> <!-- ── Overview page ──────────────────────────── -->
<div class="page active" id="page-dashboard"> <div class="page active" id="page-dashboard">
<div class="page-header" style="margin-bottom:16px;"> <div style="margin-bottom:16px;flex-shrink:0;display:flex;align-items:center;justify-content:flex-end;">
<h2>Overview</h2> <div id="overviewLastUpdated" style="font-size:11px;color:var(--text4);"></div>
<div id="overviewLastUpdated" style="font-size:11px;color:var(--text4);align-self:center;"></div>
</div> </div>
<!-- System status bar --> <!-- System status bar -->
<div id="overviewStatusBar" style="display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--card);border:1px solid var(--border);border-radius:var(--radius-lg);margin-bottom:14px;flex-wrap:wrap;"> <div id="overviewStatusBar" style="display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--card);border:1px solid var(--border);border-radius:var(--radius-lg);margin-bottom:14px;flex-wrap:wrap;flex-shrink:0;">
<div style="display:flex;align-items:center;gap:7px;flex:1;min-width:160px;"> <div style="display:flex;align-items:center;gap:7px;flex:1;min-width:160px;">
<div class="status-dot" id="ovHostDot"></div> <div class="status-dot" id="ovHostDot"></div>
<span style="font-size:12.5px;font-weight:500;color:var(--text2);">Native Host</span> <span style="font-size:12.5px;font-weight:500;color:var(--text2);">Native Host</span>
@@ -1050,7 +1050,7 @@
</div> </div>
<!-- Stat cards — 6 across --> <!-- Stat cards — 6 across -->
<div class="stats-grid" style="grid-template-columns:repeat(6,1fr);margin-bottom:14px;"> <div class="stats-grid" style="grid-template-columns:repeat(6,1fr);margin-bottom:14px;flex-shrink:0;">
<div class="stat-card"> <div class="stat-card">
<div class="stat-icon cyan"> <div class="stat-icon cyan">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="2"/><circle cx="4" cy="6" r="2"/><circle cx="20" cy="6" r="2"/><line x1="6" y1="6" x2="10" y2="11"/><line x1="18" y1="6" x2="14" y2="11"/></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="2"/><circle cx="4" cy="6" r="2"/><circle cx="20" cy="6" r="2"/><line x1="6" y1="6" x2="10" y2="11"/><line x1="18" y1="6" x2="14" y2="11"/></svg>
@@ -1095,8 +1095,12 @@
</div> </div>
</div> </div>
<!-- Lists: 2-col top row, 3-col bottom row — each card has fixed height + scroll --> <!-- Lists: flex column that fills all remaining space between stat cards
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:10px;"> and Quick Actions. Each grid row gets equal share via flex:1. -->
<div id="ovListsWrapper" style="flex:1;min-height:0;display:flex;flex-direction:column;gap:10px;margin-bottom:10px;">
<!-- Row 1: Virtual Hosts + Server Tunnels -->
<div style="flex:1;min-height:0;display:grid;grid-template-columns:1fr 1fr;gap:10px;">
<!-- Virtual Hosts --> <!-- Virtual Hosts -->
<div class="card ov-list-card"> <div class="card ov-list-card">
@@ -1106,7 +1110,7 @@
<div class="card-subtitle" id="ovVhostSubtitle"></div> <div class="card-subtitle" id="ovVhostSubtitle"></div>
</div> </div>
</div> </div>
<div style="padding:0 12px 8px;"> <div style="padding:0 12px 8px;flex-shrink:0;">
<input class="input ov-search" id="ovVhostSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;"> <input class="input ov-search" id="ovVhostSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;">
</div> </div>
<div class="ov-scroll-area"> <div class="ov-scroll-area">
@@ -1126,7 +1130,7 @@
<div class="card-subtitle" id="ovServersSubtitle"></div> <div class="card-subtitle" id="ovServersSubtitle"></div>
</div> </div>
</div> </div>
<div style="padding:0 12px 8px;"> <div style="padding:0 12px 8px;flex-shrink:0;">
<input class="input ov-search" id="ovServersSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;"> <input class="input ov-search" id="ovServersSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;">
</div> </div>
<div class="ov-scroll-area"> <div class="ov-scroll-area">
@@ -1139,7 +1143,8 @@
</div> </div>
</div> </div>
<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:10px;"> <!-- Row 2: Service Tunnels + SSH + Remote Desktops -->
<div style="flex:1;min-height:0;display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;">
<!-- Service Tunnels --> <!-- Service Tunnels -->
<div class="card ov-list-card"> <div class="card ov-list-card">
@@ -1149,7 +1154,7 @@
<div class="card-subtitle" id="ovSvcSubtitle"></div> <div class="card-subtitle" id="ovSvcSubtitle"></div>
</div> </div>
</div> </div>
<div style="padding:0 12px 8px;"> <div style="padding:0 12px 8px;flex-shrink:0;">
<input class="input ov-search" id="ovSvcSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;"> <input class="input ov-search" id="ovSvcSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;">
</div> </div>
<div class="ov-scroll-area"> <div class="ov-scroll-area">
@@ -1169,7 +1174,7 @@
<div class="card-subtitle" id="ovSshSubtitle"></div> <div class="card-subtitle" id="ovSshSubtitle"></div>
</div> </div>
</div> </div>
<div style="padding:0 12px 8px;"> <div style="padding:0 12px 8px;flex-shrink:0;">
<input class="input ov-search" id="ovSshSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;"> <input class="input ov-search" id="ovSshSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;">
</div> </div>
<div class="ov-scroll-area"> <div class="ov-scroll-area">
@@ -1189,7 +1194,7 @@
<div class="card-subtitle" id="ovRdpSubtitle"></div> <div class="card-subtitle" id="ovRdpSubtitle"></div>
</div> </div>
</div> </div>
<div style="padding:0 12px 8px;"> <div style="padding:0 12px 8px;flex-shrink:0;">
<input class="input ov-search" id="ovRdpSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;"> <input class="input ov-search" id="ovRdpSearch" placeholder="Filter…" autocomplete="off" style="height:28px;font-size:12px;">
</div> </div>
<div class="ov-scroll-area"> <div class="ov-scroll-area">
@@ -1202,7 +1207,9 @@
</div> </div>
</div> </div>
<!-- Quick actions --> </div><!-- /ovListsWrapper -->
<!-- Quick Actions — sticky at the bottom, never pushed off screen -->
<div class="card" style="flex-shrink:0;"> <div class="card" style="flex-shrink:0;">
<div class="card-header"><div class="card-title">Quick Actions</div></div> <div class="card-header"><div class="card-title">Quick Actions</div></div>
<div class="card-body" style="display:flex;gap:8px;flex-wrap:wrap;padding-top:10px;padding-bottom:10px;"> <div class="card-body" style="display:flex;gap:8px;flex-wrap:wrap;padding-top:10px;padding-bottom:10px;">
@@ -1236,8 +1243,7 @@
<!-- ── Virtual Hosts page ──────────────────────── --> <!-- ── Virtual Hosts page ──────────────────────── -->
<div class="page" id="page-connections"> <div class="page" id="page-connections">
<div class="page-header"> <div style="margin-bottom:16px;display:flex;justify-content:flex-end;">
<h2>Virtual Hosts</h2>
<button class="btn btn-primary" id="addVhostBtn"> <button class="btn btn-primary" id="addVhostBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
Add Host Add Host
@@ -1265,8 +1271,7 @@
<!-- ── Servers page ────────────────────────────── --> <!-- ── Servers page ────────────────────────────── -->
<div class="page" id="page-swarms"> <div class="page" id="page-swarms">
<div class="page-header"> <div style="margin-bottom:16px;display:flex;justify-content:flex-end;">
<h2>Server Tunnels</h2>
<button class="btn btn-primary" id="startServerBtn"> <button class="btn btn-primary" id="startServerBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
New Server New Server
@@ -1294,7 +1299,6 @@
<!-- ── Proxy & CA page ────────────────────────── --> <!-- ── Proxy & CA page ────────────────────────── -->
<div class="page" id="page-tabs"> <div class="page" id="page-tabs">
<div class="page-header"><h2>Proxy &amp; CA</h2></div>
<div class="info-grid" id="proxyInfoGrid" style="margin-bottom:16px;"> <div class="info-grid" id="proxyInfoGrid" style="margin-bottom:16px;">
<div class="info-item"> <div class="info-item">
<div class="info-item-label">Proxy Port</div> <div class="info-item-label">Proxy Port</div>
@@ -1356,8 +1360,7 @@
<!-- ── Remote Desktop page ───────────────────── --> <!-- ── Remote Desktop page ───────────────────── -->
<div class="page" id="page-rdp"> <div class="page" id="page-rdp">
<div class="page-header"> <div style="margin-bottom:16px;display:flex;justify-content:flex-end;">
<h2>Remote Desktop</h2>
<button class="btn btn-primary" id="addRdpBtn"> <button class="btn btn-primary" id="addRdpBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
Add Connection Add Connection
@@ -1374,8 +1377,7 @@
<!-- ── Backups page ───────────────────────────── --> <!-- ── Backups page ───────────────────────────── -->
<div class="page" id="page-backups"> <div class="page" id="page-backups">
<div class="page-header"> <div style="margin-bottom:16px;display:flex;justify-content:flex-end;">
<h2>Backups</h2>
<button class="btn btn-primary" id="btnTakeBackup"> <button class="btn btn-primary" id="btnTakeBackup">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17,8 12,3 7,8"/><line x1="12" y1="3" x2="12" y2="15"/></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17,8 12,3 7,8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
Take Backup Take Backup
@@ -1406,7 +1408,6 @@
<!-- ── Settings page ──────────────────────────── --> <!-- ── Settings page ──────────────────────────── -->
<div class="page" id="page-settings"> <div class="page" id="page-settings">
<div class="page-header"><h2>Settings</h2></div>
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<div class="section-heading">Notifications</div> <div class="section-heading">Notifications</div>
@@ -1480,8 +1481,7 @@
<!-- ── Service Tunnels page ──────────────────────── --> <!-- ── Service Tunnels page ──────────────────────── -->
<div class="page" id="page-service-tunnels"> <div class="page" id="page-service-tunnels">
<div class="page-header"> <div style="margin-bottom:16px;display:flex;justify-content:flex-end;">
<h2>Service Tunnels</h2>
<button class="btn btn-primary" id="addServiceTunnelBtn"> <button class="btn btn-primary" id="addServiceTunnelBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
Add Tunnel Add Tunnel
@@ -1509,8 +1509,7 @@
<!-- ── SSH page ────────────────────────────────── --> <!-- ── SSH page ────────────────────────────────── -->
<div class="page" id="page-ssh"> <div class="page" id="page-ssh">
<div class="page-header"> <div style="margin-bottom:16px;display:flex;justify-content:flex-end;">
<h2>SSH Connections</h2>
<button class="btn btn-primary" id="addSshBtn"> <button class="btn btn-primary" id="addSshBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
Add Connection Add Connection
@@ -1527,7 +1526,6 @@
<!-- ── Logs page ───────────────────────────────── --> <!-- ── Logs page ───────────────────────────────── -->
<div class="page" id="page-logs"> <div class="page" id="page-logs">
<div class="page-header"><h2>System Logs</h2></div>
<div class="logs-toolbar"> <div class="logs-toolbar">
<input type="text" class="input logs-filter" id="logsFilter" placeholder="Filter logs…"> <input type="text" class="input logs-filter" id="logsFilter" placeholder="Filter logs…">
<button class="btn btn-secondary" id="btnAutoScroll"> <button class="btn btn-secondary" id="btnAutoScroll">