Let the uptime history card be folded away, and remember that per browser

This commit is contained in:
Gmer4Lfe
2026-08-16 12:06:52 -04:00
parent b90fd59544
commit 7b65b64864
+53 -5
View File
@@ -352,6 +352,17 @@ require_once dirname(__DIR__) . '/include/ai_chat.php';
served any more. Sorted below the live ones, so it never leads the card at 0%. */
.vv-au-hb-dom.vv-au-hb-stale { color:#4a4a4a; }
/* Collapse. The open class is namespaced like the rest of this card rather than the bare `open`
the AI tab uses — same reasoning as the state modifiers above. */
.vv-au-hb-t { cursor:pointer; user-select:none; }
.vv-au-hb-t:hover .vv-au-card-title { color:#8a8a8a; }
.vv-au-hb-c { color:#333; font-size:9px; transition:transform .12s; flex-shrink:0; }
.vv-au-hb-t.vv-au-hb-open .vv-au-hb-c { transform:rotate(90deg); }
/* Collapsed, the header is the whole card, and a divider under it would be a line to nowhere. */
.vv-au-hb-t:not(.vv-au-hb-open) { border-bottom:none; }
.vv-au-hb-body { display:none; }
.vv-au-hb-body.vv-au-hb-open { display:block; }
/* ── Why ─────────────────────────────────────────────────────────────────── */
/* On the figure's own line, not under the strip: the strip is 179px of fixed-width bars and is what
sets this column's width, so anything below it would widen every row for the four that need it. */
@@ -527,15 +538,24 @@ $tabs = ['proxies' => 'Proxies', 'users' => 'Users & Groups',
is the finding. A toggle would make "fine this week, bad this month" something you have to
remember across two clicks. -->
<div class="vv-au-card vv-au-hist-card" style="margin-top:12px">
<div class="vv-au-card-h">
<!-- Expanded in the markup, not by JS. The card is open because the class is written here, so
a slow load or a script that throws leaves it showing its contents rather than collapsed
with no way to open it. JS only ever closes it, and only when storage says to. -->
<div class="vv-au-card-h vv-au-hb-t vv-au-hb-open" id="vv-au-up-t"
title="Click to collapse — remembered on this browser">
<span class="vv-au-hb-c">&#9654;</span>
<span class="vv-au-card-title">Uptime history</span>
<!-- Stays visible while collapsed: a header that says nothing when shut is a header you have
to open to know whether opening it was worth it. -->
<span class="vv-au-hist-note" id="vv-au-up-note"></span>
</div>
<div class="vv-au-hb-head">
<span></span>
<span>24 hours</span><span>7 days</span><span>30 days</span><span>12 months</span>
<div class="vv-au-hb-body vv-au-hb-open" id="vv-au-up-body">
<div class="vv-au-hb-head">
<span></span>
<span>24 hours</span><span>7 days</span><span>30 days</span><span>12 months</span>
</div>
<div id="vv-au-up-hist"><div class="vv-au-loading">Loading…</div></div>
</div>
<div id="vv-au-up-hist"><div class="vv-au-loading">Loading…</div></div>
</div>
</div>
<?php endif; ?>
@@ -822,6 +842,34 @@ document.querySelectorAll('.vv-au-tab').forEach(btn => {
_on('vv-au-refresh', 'click', () => _loadTab(_activeTab));
// ── Uptime history collapse ───────────────────────────────────────────────────
// Open on a browser that has never been told otherwise, and whatever it was last set to after
// that — `!== '0'` rather than `=== '1'`, so an absent key reads as open rather than as closed.
//
// The markup ships open, so this only ever has to close it. That ordering matters: localStorage
// throws outright in a few configurations, and if the default lived here instead of in the HTML a
// failed read would leave the card collapsed with its own toggle the only way back.
const UP_OPEN_KEY = 'vv-au-uptime-open';
function _upSetOpen(open, remember) {
['vv-au-up-t', 'vv-au-up-body'].forEach(id => {
const el = document.getElementById(id);
if (el) el.classList.toggle('vv-au-hb-open', open);
});
const t = document.getElementById('vv-au-up-t');
if (t) t.title = (open ? 'Click to collapse' : 'Click to expand') + ' — remembered on this browser';
// Not remembered when restoring, only when the operator actually chooses. Writing on restore
// would turn a browser that cannot read storage into one that rewrites it on every load.
if (remember) { try { localStorage.setItem(UP_OPEN_KEY, open ? '1' : '0'); } catch (_) {} }
}
if (_on('vv-au-up-t', 'click', () => {
const body = document.getElementById('vv-au-up-body');
_upSetOpen(!body.classList.contains('vv-au-hb-open'), true);
})) {
try { if (localStorage.getItem(UP_OPEN_KEY) === '0') _upSetOpen(false, false); } catch (_) {}
}
function _loadTab(tab) {
if (tab === 'proxies') _loadProxies();
if (tab === 'users') { _loadUsers(); _loadGroups(); }