v0.31.5
This commit is contained in:
1 parent
75104f87ba
commit
4cc994b3bc
86 files changed
+942
-223
No files matched your search
@@ -244,6 +244,7 @@ pub(super) static READER_DOCUMENTS: &[(&str, &str, &str)] = &[
|
||||
"guides",
|
||||
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/docs/STREAMS.md")),
|
||||
),
|
||||
reader_doc!("docs/IMPLEMENTATION_0.31.6.md", "technical"),
|
||||
reader_doc!("docs/IMPLEMENTATION_0.31.5.md", "technical"),
|
||||
reader_doc!("docs/IMPLEMENTATION_0.31.4.md", "technical"),
|
||||
reader_doc!("docs/IMPLEMENTATION_0.31.3.md", "technical"),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "RustProxy Administration API",
|
||||
"version": "0.31.5",
|
||||
"version": "0.31.6",
|
||||
"description": "Administration API for the active panel origin. Sign in through the panel; the same-origin HttpOnly cookie authenticates all private operations. Mutations also require the exact Origin, X-RustProxy-Request: 1 and a session-bound X-CSRF-Token. Loopback HTTP is the default; Settings can enable HTTPS before using a non-loopback administration bind. This document contains no live configuration or credentials. Object schemas marked extensible are summaries: full configuration validation is authoritative in Rust."
|
||||
},
|
||||
"servers": [
|
||||
|
||||
@@ -463,6 +463,15 @@ function setMobileMenu(open) {
|
||||
}
|
||||
mobileMenuToggle?.addEventListener("click", event => { event.stopPropagation(); setMobileMenu(!dashboardSidebar.classList.contains("mobile-nav-open")); });
|
||||
document.querySelectorAll(".nav").forEach(button => button.addEventListener("click", () => { setPanel(button.dataset.panel); setMobileMenu(false); }));
|
||||
// The brand is a Home navigation action, not a hard reload of the HTTP/3
|
||||
// document. Preserve href="/" as the no-JS and modified-click fallback.
|
||||
document.querySelector('.brand[href="/"]')?.addEventListener("click", event => {
|
||||
if (!authenticated || event.defaultPrevented || event.button !== 0 ||
|
||||
event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return;
|
||||
event.preventDefault();
|
||||
setPanel("overview");
|
||||
setMobileMenu(false);
|
||||
});
|
||||
document.addEventListener("click", event => { if (dashboardSidebar?.classList.contains("mobile-nav-open") && !dashboardSidebar.contains(event.target)) setMobileMenu(false); });
|
||||
document.addEventListener("keydown", event => { if (event.key === "Escape" && dashboardSidebar?.classList.contains("mobile-nav-open")) { setMobileMenu(false); mobileMenuToggle?.focus(); } });
|
||||
window.addEventListener("popstate", () => { setPanel(panelFromLocation(), false); setMobileMenu(false); });
|
||||
|
||||
@@ -238,8 +238,15 @@
|
||||
entries.forEach((entry, index) => {
|
||||
const row = el("tr"); row.tabIndex = 0; row.classList.toggle("selected", selectedIndex === index);
|
||||
row.setAttribute("aria-expanded", selectedIndex === index ? "true" : "false");
|
||||
row.setAttribute("aria-label", entrySummary(entry));
|
||||
for (const id of ids) {
|
||||
const value = columnValue(entry, id), cell = el("td", value); cell.title = value; row.append(cell);
|
||||
const value = columnValue(entry, id), cell = el("td", value); cell.title = value;
|
||||
// Mobile uses compact, expandable cards instead of a width-growing
|
||||
// table. All parsed fields remain accessible in the detail row.
|
||||
cell.dataset.mobileColumn = id;
|
||||
const label = columnLabel(id);
|
||||
cell.dataset.mobileLabel = label;
|
||||
row.append(cell);
|
||||
}
|
||||
const select = () => { selectedIndex = selectedIndex === index ? null : index; renderRows(); };
|
||||
row.addEventListener("click", select);
|
||||
|
||||
@@ -2758,7 +2758,7 @@
|
||||
<label><span data-i18n="administrationPublicOrigin">Public panel HTTPS origin (optional)</span><input
|
||||
id="admin-public-origin" maxlength="255" placeholder="https://panel.example.com"
|
||||
type="url" spellcheck="false" autocomplete="off" /></label>
|
||||
<p class="fine" data-i18n="administrationPublicOriginHelp">When behind a trusted reverse proxy, enter the panel's external HTTPS address once. Its DNS name is automatically allowed. A restart is required.</p>
|
||||
<p class="fine" data-i18n="administrationPublicOriginHelp">Pins the browser-facing HTTPS scheme, hostname and optional port for Origin/CSRF checks behind a trusted reverse proxy; it is not only a DNS allowlist. The hostname is automatically allowed. Restart required.</p>
|
||||
<details id="admin-extra-hosts-details">
|
||||
<summary data-i18n="administrationHostsAdvanced">Advanced: additional allowed DNS hostnames</summary>
|
||||
<label><span data-i18n="administrationHosts">Additional allowed DNS hostnames</span><textarea
|
||||
|
||||
@@ -10265,3 +10265,201 @@ html[data-chart-style] :is(#workspace, dialog) svg polyline {
|
||||
@media (max-width: 800px) {
|
||||
.file-log-aggregate-form { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
|
||||
/* Stored Logs on narrow screens: bounded container and a compact record list.
|
||||
The complete parsed JSON is available by opening any row, while the desktop
|
||||
table and the persisted column picker keep their original behavior. */
|
||||
@media (max-width: 700px) {
|
||||
#panel-filelogs,
|
||||
#panel-filelogs .file-logs-workspace,
|
||||
#file-log-view-entries,
|
||||
#file-log-view-counts,
|
||||
#panel-filelogs .file-logs-table,
|
||||
#panel-filelogs .file-logs-table-toolbar,
|
||||
#panel-filelogs .file-log-field-grid {
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
#panel-filelogs .file-logs-workspace {
|
||||
gap: 10px;
|
||||
padding: 12px;
|
||||
overflow: visible;
|
||||
}
|
||||
#panel-filelogs .card-heading {
|
||||
min-width: 0;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
#panel-filelogs .file-logs-heading-actions {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
gap: 4px;
|
||||
}
|
||||
#panel-filelogs .file-logs-heading-actions .file-log-consolidate {
|
||||
margin-inline-end: auto;
|
||||
white-space: normal;
|
||||
}
|
||||
#panel-filelogs .file-log-search-help-popover {
|
||||
width: min(320px, calc(100vw - 54px));
|
||||
}
|
||||
#panel-filelogs .file-logs-filter,
|
||||
#panel-filelogs .file-log-aggregate-form {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
#panel-filelogs .file-log-limit { max-width: none; }
|
||||
#panel-filelogs .file-logs-filter label,
|
||||
#panel-filelogs .file-logs-filter input,
|
||||
#panel-filelogs .file-logs-filter select,
|
||||
#panel-filelogs .file-log-aggregate-form label,
|
||||
#panel-filelogs .file-log-aggregate-form input,
|
||||
#panel-filelogs .file-log-aggregate-form select {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
#panel-filelogs .file-log-tabs { min-width: 0; }
|
||||
#panel-filelogs .file-log-tab {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
#panel-filelogs .file-logs-table-toolbar {
|
||||
align-items: flex-start;
|
||||
gap: 5px;
|
||||
}
|
||||
#panel-filelogs .file-log-column-picker { align-self: flex-end; }
|
||||
#panel-filelogs .file-logs-table {
|
||||
max-height: none;
|
||||
overflow: visible;
|
||||
}
|
||||
#panel-filelogs .file-logs-table table,
|
||||
#panel-filelogs .file-logs-table tbody {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
#panel-filelogs .file-logs-table thead { display: none; }
|
||||
#panel-filelogs .file-logs-table tbody tr:not(.file-log-detail-row) {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||
gap: 5px 10px;
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
padding: 10px 12px;
|
||||
margin-bottom: 8px;
|
||||
border: 1px solid var(--line);
|
||||
background: var(--panel);
|
||||
}
|
||||
#panel-filelogs .file-logs-table tbody tr:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
#panel-filelogs .file-logs-table tbody tr.selected { border-color: var(--accent); }
|
||||
#panel-filelogs .file-logs-table tbody tr:not(.file-log-detail-row) > td {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: unset;
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
/* Every user-selected column is available even when the administrator
|
||||
replaces all default columns with custom parsed fields. */
|
||||
#panel-filelogs .file-logs-table td[data-mobile-column="record"] {
|
||||
grid-column: 1 / -1;
|
||||
font-weight: 600;
|
||||
line-height: 1.45;
|
||||
padding-inline-end: 16px;
|
||||
}
|
||||
#panel-filelogs .file-logs-table td[data-mobile-column="time"],
|
||||
#panel-filelogs .file-logs-table td[data-mobile-column="event"],
|
||||
#panel-filelogs .file-logs-table td[data-mobile-column="status"],
|
||||
#panel-filelogs .file-logs-table td[data-mobile-column="vhost"] {
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
#panel-filelogs .file-logs-table tbody tr:not(.file-log-detail-row) > td::before {
|
||||
content: attr(data-mobile-label) ": ";
|
||||
color: var(--text-subtle);
|
||||
font-weight: 400;
|
||||
}
|
||||
#panel-filelogs .file-logs-table tbody tr:not(.file-log-detail-row) > td[data-mobile-column="record"]::before {
|
||||
content: "";
|
||||
}
|
||||
#panel-filelogs .file-logs-table tbody tr:not(.file-log-detail-row)::after {
|
||||
content: "+";
|
||||
position: absolute;
|
||||
inset-block-end: 4px;
|
||||
inset-inline-end: 8px;
|
||||
color: var(--muted);
|
||||
font-size: 15px;
|
||||
pointer-events: none;
|
||||
}
|
||||
#panel-filelogs .file-logs-table tbody tr.selected::after { content: "-"; }
|
||||
#panel-filelogs .file-logs-table .file-log-detail-row {
|
||||
display: block;
|
||||
margin: -8px 0 8px;
|
||||
border: 1px solid var(--accent);
|
||||
border-top: 0;
|
||||
background: var(--panel2);
|
||||
}
|
||||
#panel-filelogs .file-logs-table .file-log-detail-row td {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
}
|
||||
#panel-filelogs .file-log-field { grid-template-columns: minmax(0, 1fr); }
|
||||
#panel-filelogs .file-log-inline-detail { min-width: 0; padding: 8px; }
|
||||
#panel-filelogs .file-log-inline-detail pre { max-width: 100%; overflow-x: auto; }
|
||||
#panel-filelogs .file-log-aggregate-table {
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
#panel-filelogs .file-log-aggregate-table table { table-layout: fixed; }
|
||||
#panel-filelogs .file-log-aggregate-table td:first-child {
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
#panel-filelogs .file-logs-pager { justify-content: space-between; }
|
||||
}
|
||||
|
||||
/* Tablet/narrow-desktop log tables scroll locally instead of expanding <main>. */
|
||||
#panel-filelogs,
|
||||
#panel-filelogs .file-logs-workspace,
|
||||
#file-log-view-entries,
|
||||
#file-log-view-counts {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
#panel-filelogs .file-logs-workspace { grid-template-columns: minmax(0, 1fr); }
|
||||
#panel-filelogs .file-logs-table,
|
||||
#panel-filelogs .file-log-aggregate-table {
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
#panel-filelogs .file-logs-table { overflow: visible; }
|
||||
#panel-filelogs .file-logs-table td[data-mobile-column="time"],
|
||||
#panel-filelogs .file-logs-table td[data-mobile-column="vhost"] { grid-column: 1 / -1; }
|
||||
#panel-filelogs .file-logs-table td[data-mobile-column="record"] {
|
||||
max-height: 4.4em;
|
||||
overflow: hidden;
|
||||
}
|
||||
#panel-filelogs .file-logs-table tr.selected td[data-mobile-column="record"] {
|
||||
max-height: none;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user