This commit is contained in:
Mateusz Gruszczyński committed 2026-10-15 14:42:56 +02:00
1 parent de090d20fa
commit c6486bfe85
16 files changed
+254 -104

No files matched your search

+6 -46
View File
@@ -11588,62 +11588,22 @@ html:is([data-corner-style=square], [data-corner-style=subtle], [data-corner-sty
color: var(--text);
}
/* Web Services reuse the same full-width live tiles and chart as Vhosts. */
#panel-web-server .www-service-panel {
border-top: 1px solid var(--line);
margin-top: 10px;
padding-top: 8px;
}
#panel-web-server .www-service-panel summary {
cursor: pointer;
color: var(--chart-accent);
font-size: 12px;
}
#panel-web-server .www-service-live {
padding: 12px 0 3px;
}
#panel-web-server .www-service-values {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
gap: 10px;
}
#panel-web-server .www-service-values>div {
display: grid;
gap: 5px;
min-width: 0;
margin-top: 10px;
}
#panel-web-server .www-service-values small {
color: var(--muted);
font: 10px var(--mono);
}
#panel-web-server .www-service-values strong {
font: 500 14px var(--mono);
overflow-wrap: anywhere;
}
#panel-web-server .www-service-live svg {
display: block;
width: 100%;
max-height: 86px;
margin: 10px 0 0;
}
#panel-web-server .www-service-live polyline {
fill: none;
stroke: var(--chart-accent);
stroke-width: 2;
#panel-web-server .www-service-heading {
margin: 0;
font-size: 11px;
}
#panel-web-server .www-service-split {
color: var(--muted);
font: 11px var(--mono);
overflow-wrap: anywhere;
margin-top: 4px;
margin: 4px 10px 8px;
}
@media(prefers-reduced-motion:reduce) {
+19 -20
View File
@@ -286,7 +286,6 @@
try {
const preset = presetConfig($("web-service-preset").value);
if (!preset) { toast(t("webServicePresetChoose"), true); return; }
// Keep deployment-specific FastCGI endpoint/tuning while replacing application policy.
preset.php.endpoint = $("web-service-php-endpoint").value.trim() || preset.php.endpoint;
preset.php.connect_timeout_ms = Number($("web-service-php-connect-timeout").value || preset.php.connect_timeout_ms);
preset.php.request_timeout_ms = Number($("web-service-php-request-timeout").value || preset.php.request_timeout_ms);
@@ -312,9 +311,6 @@
function presetChanged() {
updatePresetSummary();
// Presets are one-shot form generators. Selecting one must immediately
// materialize its normal Web Service fields; otherwise a user can select a
// CMS, save the form and unknowingly persist the previous/custom values.
if ($("web-service-preset").value !== "custom") applyPreset();
}
@@ -392,31 +388,34 @@
item.append(el("span", t(key), "small-label"), el("b", value));
details.append(item);
}
const live = el("details", undefined, "www-service-panel");
const summary = el("summary", t("webLiveMetrics")); live.append(summary);
const live = el("section", undefined, "www-service-panel");
const panel = el("div", undefined, "www-service-live"); panel.dataset.webLiveId = service.id;
const figures = el("div", undefined, "www-service-values");
const figures = el("div", undefined, "vhost-live-grid");
for (const [field, key] of [
["requests", "webLiveRequests"], ["rate", "webLiveRate"],
["errors", "webLiveErrors"], ["latency", "webLiveLatency"],
["php", "webLivePhpCapacity"], ["bytes", "webLiveBytes"]]) {
const item = el("div");
const name = el("small", t(key));
name.dataset.i18n = key;
const item = el("div", undefined, "vhost-live-metric");
const name = el("span", t(key)); name.dataset.i18n = key;
const value = el("strong", "-"); value.dataset.webLiveField = field;
item.append(name, value); figures.append(item);
}
const chart = document.createElementNS("http://www.w3.org/2000/svg", "svg");
chart.setAttribute("viewBox", "0 0 300 60"); chart.setAttribute("role", "img");
chart.setAttribute("aria-label", t("webLiveRate"));
const chart = el("div", undefined, "vhost-chart");
const chartHead = el("div", undefined, "vhost-chart-head");
chartHead.append(el("span", t("webLiveRateHistory"), "small-label")); chart.append(chartHead);
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("viewBox", "0 0 320 54"); svg.setAttribute("preserveAspectRatio", "none");
svg.setAttribute("role", "img"); svg.setAttribute("aria-label", t("webLiveRate"));
const line = document.createElementNS("http://www.w3.org/2000/svg", "polyline");
line.setAttribute("points", "0,55 300,55"); chart.append(line);
line.setAttribute("class", "vhost-chart-line");
line.setAttribute("points", "0,50 320,50"); svg.append(line); chart.append(svg);
const split = el("p", "-", "www-service-split"); split.dataset.webLiveField = "split";
panel.append(figures, chart, split); live.append(panel);
live.addEventListener("toggle", () => { if (live.open && latestStatus) renderLive(latestStatus, false); });
chart.append(split); panel.append(figures, chart); live.append(panel);
box.append(details, live); return box;
});
$("web-service-list").replaceChildren(...(cards.length ? cards : [el("p", t(query ? "webServiceSearchEmpty" : "webServiceEmpty"), "fine")]));
if (latestStatus && currentPanel === "web-server") renderLive(latestStatus, false);
}
const serviceHistory = new Map();
@@ -425,7 +424,6 @@
if (currentPanel !== "web-server") return;
const services = status?.web_server_metrics || {};
for (const panel of document.querySelectorAll("#web-service-list [data-web-live-id]")) {
if (!panel.closest("details")?.open) continue;
const id = panel.dataset.webLiveId, values = services[id], web = values?.web;
const lookup = key => panel.querySelector(`[data-web-live-field="${key}"]`);
const set = (key, value) => { const node = lookup(key); if (node) node.textContent = value; };
@@ -439,11 +437,12 @@
const deltas = record ? sample.deltas : null;
const rate = deltas ? deltas[0] / sample.seconds : null;
const previous = serviceHistory.get(id) || [];
// An unavailable counter delta is not a 0/s measurement; do not plot it.
if (record && rate !== null) { previous.push(rate); window.rustProxyOverviewSamples.trim(previous); serviceHistory.set(id, previous); }
const peak = Math.max(1, ...previous.filter(x => x != null));
const points = previous.map((value, i) => `${300 * i / Math.max(1, previous.length - 1)},${55 - (value || 0) / peak * 50}`).join(" ");
panel.querySelector("polyline")?.setAttribute("points", points || "0,55 300,55");
const y = value => 50 - (value || 0) / peak * 46;
const points = previous.length === 1 ? `0,${y(previous[0])} 320,${y(previous[0])}` :
previous.map((value, i) => `${320 * i / Math.max(1, previous.length - 1)},${y(value)}`).join(" ");
panel.querySelector("polyline")?.setAttribute("points", points || "0,50 320,50");
set("requests", fmt(total)); set("rate", rate == null ? "-" : `${fmt(rate, 1)}/s`);
set("errors", fmt(n(web.status_5xx)));
set("latency", deltas?.[0] > 0 ? `${fmt(deltas[1] / deltas[0] / 1000, 1)} ms` : "-");