Partnership page: one settings card instead of three, and a Data Transferred card

Windows with runs but no bytes say 'no data moved' rather than 0.00 GB, and rows before the byte-parser fix are excluded rather than summed into a false total.
This commit is contained in:
Gmer4Lfe
2026-08-17 14:36:21 -04:00
parent 49372996ac
commit bce3bf61e9
2 changed files with 160 additions and 20 deletions
+93 -20
View File
@@ -105,16 +105,6 @@ textarea.vv-pt-set-input { resize:vertical; white-space:pre; }
<div id="vv-pt-config-body" style="color:#444;font-size:12px;">Loading…</div>
</div>
<!-- Host Settings -->
<div class="vv-card" id="vv-pt-hosts-card" style="margin-bottom:12px;display:none;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;">
<h3 style="margin:0;">Host Settings</h3>
<button id="vv-pt-hosts-save" class="vv-pt-action-btn run"
onclick="vvPtSaveHosts(this)" style="display:none;">Save</button>
</div>
<div id="vv-pt-hosts-body"></div>
</div>
<!-- Offline countdown warning (shown only when partner has been unreachable) -->
<div id="vv-pt-offline-warn" style="display:none;margin-bottom:12px;"></div>
@@ -123,8 +113,11 @@ textarea.vv-pt-set-input { resize:vertical; white-space:pre; }
<div style="color:#444;font-size:12px;padding:16px 0;text-align:center;">Loading…</div>
</div>
<!-- Array settings (above sync/actions row) -->
<div id="vv-pt-arrays-wrap" style="margin-bottom:12px;display:none;"></div>
<!-- Data moved between the servers -->
<div class="vv-card" id="vv-pt-xfer-card" style="margin-bottom:12px;">
<h3>Data Transferred</h3>
<div id="vv-pt-xfer-body" style="color:#444;font-size:12px;">Loading…</div>
</div>
<!-- Mirror sync + Actions side by side -->
<div style="display:flex;gap:12px;margin-bottom:12px;align-items:stretch;flex-wrap:wrap;">
@@ -153,9 +146,28 @@ textarea.vv-pt-set-input { resize:vertical; white-space:pre; }
</div>
</div>
<div id="vv-pt-settings-hint" style="font-size:10px;color:#444;margin-top:4px;">
Partnership configuration for this server.
Partnership, host and array configuration for this server.
</div>
<!-- One card, three sections. These were three separate top-level cards — "Host Settings",
"Array Settings" and "Settings" — stacked down the page between the things people
actually come here to look at. They are all the same kind of thing: conf this host owns.
Collapsed together they cost one line until opened. -->
<div id="vv-pt-settings-body" style="display:none;margin-top:10px;">
<div id="vv-pt-hosts-section" style="display:none;margin-bottom:16px;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
<div class="vv-cl-title" style="margin:0;">Host settings</div>
<button id="vv-pt-hosts-save" class="vv-pt-action-btn run"
onclick="vvPtSaveHosts(this)" style="display:none;">Save</button>
</div>
<div id="vv-pt-hosts-body"></div>
</div>
<div id="vv-pt-arrays-wrap" style="display:none;margin-bottom:16px;"></div>
<div id="vv-pt-settings-conf"></div>
</div>
<div id="vv-pt-settings-body" style="display:none;margin-top:10px;"></div>
</div>
@@ -504,9 +516,9 @@ function _vvRenderArrayCards() {
if (!hasArrays) { wrap.style.display = 'none'; return; }
wrap.style.display = '';
wrap.innerHTML = `<div class="vv-card">
wrap.innerHTML = `<div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
<h3 style="margin:0;">Array Settings</h3>
<div class="vv-cl-title" style="margin:0;">Array settings</div>
<button id="vv-pt-arrays-save" class="vv-pt-action-btn run"
onclick="vvPtSaveArrays(this)" style="display:none;">Save Changes</button>
</div>
@@ -570,7 +582,9 @@ function vvPtToggleSettings() {
}
function vvPtLoadSettings() {
const body = document.getElementById('vv-pt-settings-body');
// The conf rows render into their own sub-node, not the whole collapsible body — the body now
// also holds the host and array sections, and writing over it would delete them.
const body = document.getElementById('vv-pt-settings-conf');
body.innerHTML = '<div style="color:#555;font-size:12px;padding:8px 0;">Loading…</div>';
fetch('/plugins/varaverk/api/partnership_settings.php?_=' + Date.now())
.then(r => r.json())
@@ -627,12 +641,12 @@ function vvPtSetChanged(el) {
const changed = el.value !== el.dataset.orig;
el.classList.toggle('changed', changed);
// Show Save button if any field is changed
const any = document.querySelector('#vv-pt-settings-body .vv-pt-set-input.changed');
const any = document.querySelector('#vv-pt-settings-conf .vv-pt-set-input.changed');
document.getElementById('vv-pt-settings-save').style.display = any ? '' : 'none';
}
async function vvPtSaveSettings(btn) {
const changedEls = document.querySelectorAll('#vv-pt-settings-body .vv-pt-set-input.changed');
const changedEls = document.querySelectorAll('#vv-pt-settings-conf .vv-pt-set-input.changed');
if (!changedEls.length) return;
const changes = [];
changedEls.forEach(el => changes.push({
@@ -723,6 +737,64 @@ function _syncToggle(gate, dimmed) {
title="${gate.var} — click to ${on ? 'disable' : 'enable'}">${on ? 'ON' : 'OFF'}</span>`;
}
// ── Data transferred ──────────────────────────────────────────────────────────
//
// A window with runs but no bytes says "no data moved", not "0.00 GB". They are different
// claims: rsync completing with nothing to send is the normal state for a mirror that is
// already in step, and printing a zero total invites the reading that the sync is broken.
// A window with no runs at all says so separately again.
function _renderXfer(x) {
const el = document.getElementById('vv-pt-xfer-body');
if (!el) return;
x = x || {};
const w = x.windows || {};
const fmt = (b) => {
if (b === null || b === undefined) return null;
const u = ['B','KB','MB','GB','TB'];
let i = 0, v = b;
while (v >= 1024 && i < u.length - 1) { v /= 1024; i++; }
return (i >= 3 ? v.toFixed(2) : Math.round(v)) + ' ' + u[i];
};
const row = (label, key) => {
const d = w[key] || {};
const bytes = fmt(d.bytes);
let val, col;
if (!d.runs) { val = 'no syncs ran'; col = '#333'; }
else if (bytes) { val = bytes; col = '#4caf50'; }
else { val = 'no data moved'; col = '#555'; }
const extra = d.runs
? `<span style="color:#333;font-size:9px;">${d.runs} run${d.runs===1?'':'s'}${d.failed?` · ${d.failed} failed`:''}</span>`
: '';
return `<div style="display:flex;justify-content:space-between;align-items:baseline;gap:10px;
padding:5px 0;border-bottom:1px solid #171717;">
<span style="color:#666;font-size:11px;">${label}</span>
<span style="display:flex;align-items:baseline;gap:8px;">
${extra}<span style="color:${col};font-size:12px;font-family:monospace;">${val}</span>
</span></div>`;
};
const live = x.live;
const liveHtml = live
? `<div style="display:flex;justify-content:space-between;align-items:baseline;gap:10px;
padding:5px 0;border-bottom:1px solid #171717;">
<span style="color:#666;font-size:11px;">Live</span>
<span style="color:#ff9800;font-size:12px;font-family:monospace;">⟳ ${live.running} transfer${live.running===1?'':'s'}${live.share?` · ${vvEscHtml(live.share)}`:''}</span>
</div>`
: `<div style="display:flex;justify-content:space-between;align-items:baseline;gap:10px;
padding:5px 0;border-bottom:1px solid #171717;">
<span style="color:#666;font-size:11px;">Live</span>
<span style="color:#333;font-size:12px;font-family:monospace;">idle</span>
</div>`;
el.innerHTML = liveHtml + row('Last 24 hours','24h') + row('Last 7 days','7d') + row('Last 30 days','30d')
+ `<div style="margin-top:7px;font-size:9px;color:#2e2e2e;line-height:1.5;">
Counted from ${vvEscHtml(x.epoch || '')} — before that rsync logged every transfer as
0 bytes, so those rows are excluded rather than summed into a false total.
</div>`;
}
function _renderSync(sync) {
const jobs = sync.jobs || {};
const gates = sync.gates || {};
@@ -1332,7 +1404,7 @@ function _render(data) {
document.getElementById('vv-pt-config-body').innerHTML = _renderConfig(cfg);
// Host settings — always shown upfront
const hostsCard = document.getElementById('vv-pt-hosts-card');
const hostsCard = document.getElementById("vv-pt-hosts-section");
hostsCard.style.display = nodes.length ? '' : 'none';
document.getElementById('vv-pt-hosts-body').innerHTML = _renderHostSettings(nodes, isOwner);
document.getElementById('vv-pt-hosts-save').style.display = 'none';
@@ -1341,6 +1413,7 @@ function _render(data) {
_renderOfflineWarn(cfg);
// Mirror sync health
_renderXfer(data.xfer || {});
document.getElementById('vv-pt-sync-body').innerHTML = _renderSync(data.sync || {});
// Node grid — columns based on count