v0.36.9
This commit is contained in:
1 parent
358a4518d9
commit
2789991452
13 files changed
+215
-6
No files matched your search
@@ -53,6 +53,7 @@ function translate() {
|
||||
document.querySelectorAll("[data-i18n-placeholder]").forEach(e => e.placeholder = t(e.dataset.i18nPlaceholder));
|
||||
document.querySelectorAll("[data-i18n-aria]").forEach(e => e.setAttribute("aria-label", t(e.dataset.i18nAria)));
|
||||
document.querySelectorAll("[data-i18n-title]").forEach(e => { e.title = t(e.dataset.i18nTitle); });
|
||||
window.rustProxySidebar?.refresh?.();
|
||||
window.rustProxyAclProfiles?.refreshTranslations?.();
|
||||
$("language").value = languagePreference === "auto" ? "auto" : language; setPanel(currentPanel, false); syncAuthForm(); renderSession();
|
||||
window.rustProxyDrafts?.refresh();
|
||||
@@ -511,10 +512,13 @@ async function activate(info) {
|
||||
for (const id of ["password", "password-confirm", "setup-token"]) $(id).value = "";
|
||||
$("login").hidden = true; $("workspace").hidden = false; $("logout").hidden = false;
|
||||
renderSession();
|
||||
document.documentElement.classList.remove("app-loading");
|
||||
document.documentElement.classList.remove("app-startup-failed");
|
||||
rustProxyRefresh.start();
|
||||
const preferences = await loadAdminPreferences();
|
||||
// Keep the startup screen until the account preferences (menu, layout, density)
|
||||
// are applied, so the panel never appears first with defaults and then changes.
|
||||
let preferences;
|
||||
try { preferences = await loadAdminPreferences(); }
|
||||
finally { document.documentElement.classList.remove("app-loading"); }
|
||||
if (!authenticated || epoch !== authEpoch) return false;
|
||||
window.rustProxyLogs?.applyPreferences(preferences);
|
||||
window.rustProxyFileLogs?.applyPreferences(preferences);
|
||||
|
||||
@@ -168,7 +168,7 @@ function uiIconForTarget(target) {
|
||||
if (manual && UI_ICON_SHAPES[manual]) return manual;
|
||||
if (target.matches(".chart-style-choice")) return null;
|
||||
if (target.matches(".overview-inline-grip, .overview-inline-narrow, .overview-inline-widen, .overview-inline-up, .overview-inline-down, .overview-inline-hide, .overview-layout-narrow, .overview-layout-widen, .overview-layout-up, .overview-layout-down, .overview-layout-hide")) return null;
|
||||
if (target.matches("#tunnels-open, .vhost-backend-protocol-badge, .config-history-day, .draft-dock-toggle, .mobile-menu-toggle")) return null;
|
||||
if (target.matches("#tunnels-open, .vhost-backend-protocol-badge, .config-history-day, .draft-dock-toggle, .mobile-menu-toggle, .sidebar-collapse")) return null;
|
||||
if (UI_GLYPH_LABEL.test(String(target.textContent || "").trim())) return null;
|
||||
if (UI_ID_ICONS[target.id]) return UI_ID_ICONS[target.id];
|
||||
if (target.matches("#web-service-preset-apply, [data-cache-memory-preset], [data-cache-cold-preset], [data-transform-preset]")) return "wand";
|
||||
|
||||
@@ -14,7 +14,7 @@ const ADMIN_DEFAULT_HIDDEN_WIDGETS = Object.freeze([...new Set([
|
||||
const ADMIN_APPEARANCE_DEFAULTS = Object.freeze({
|
||||
theme: "dark", language: "auto", ui_scale: 100, time_format: "24h", chart_style: "default",
|
||||
chart_axes: false, interface_icons: false, logo_animation: false,
|
||||
button_style: "normal", corner_style: "default", table_density: "normal", dashboard_density: ADMIN_DASHBOARD_DEFAULTS.dashboard_density, dashboard_widgets: [...ADMIN_DASHBOARD_WIDGETS], dashboard_hidden_widgets: [...ADMIN_DEFAULT_HIDDEN_WIDGETS], dashboard_widget_sizes: null, dashboard_widget_heights: null, dashboard_auto_fit: true,
|
||||
button_style: "normal", corner_style: "default", table_density: "normal", dashboard_density: ADMIN_DASHBOARD_DEFAULTS.dashboard_density, dashboard_widgets: [...ADMIN_DASHBOARD_WIDGETS], dashboard_hidden_widgets: [...ADMIN_DEFAULT_HIDDEN_WIDGETS], dashboard_widget_sizes: null, dashboard_widget_heights: null, dashboard_auto_fit: true, sidebar_collapsed: false,
|
||||
});
|
||||
const CHART_STYLE_KEYS = Object.freeze({ default: "chartStyleDefault", soft: "chartStyleSoft", technical: "chartStyleTechnical", high_contrast: "chartStyleHighContrast", neon: "chartStyleNeon", monochrome: "chartStyleMonochrome", warm: "chartStyleWarm", cool: "chartStyleCool", sunset: "chartStyleSunset", aurora: "chartStyleAurora", ocean: "chartStyleOcean", forest: "chartStyleForest", pastel: "chartStylePastel", terminal: "chartStyleTerminal", blueprint: "chartStyleBlueprint", colorblind: "chartStyleColorblind" });
|
||||
let adminPreferences = null, adminPreferencesLoading = null, adminPreferencesWrite = Promise.resolve(), adminPreferencesUnavailable = false;
|
||||
@@ -316,6 +316,7 @@ function applyAdminPreferences(value, cache = true) {
|
||||
window.rustProxyStreams?.applyPreferences(normalized);
|
||||
if (languagePacks.size) translate();
|
||||
refreshAppearanceUi();
|
||||
window.rustProxySidebar?.applyPreference?.(normalized.sidebar_collapsed === true);
|
||||
window.rustProxyOverviewRows?.reveal?.();
|
||||
return normalized;
|
||||
}
|
||||
@@ -357,7 +358,7 @@ function updateAdminPreferences(patch) {
|
||||
next.refresh = normalizeRefreshPreferences(next.refresh);
|
||||
next.theme = normalizeAdminTheme(next.theme); next.language = normalizeAdminLanguage(next.language); next.ui_scale = normalizeAdminUiScale(next.ui_scale);
|
||||
next.time_format = normalizeAdminTimeFormat(next.time_format); next.chart_style = normalizeAdminChartStyle(next.chart_style); next.chart_axes = next.chart_axes === true; next.interface_icons = next.interface_icons === true; next.logo_animation = next.logo_animation === true; next.button_style = normalizeAdminButtonStyle(next.button_style); next.corner_style = normalizeAdminCornerStyle(next.corner_style); next.table_density = normalizeAdminDensity(next.table_density);
|
||||
next.dashboard_density = normalizeAdminDensity(next.dashboard_density, "compact"); next.dashboard_widgets = normalizeDashboardWidgets(next.dashboard_widgets); next.dashboard_hidden_widgets = normalizeHiddenDashboardWidgets(next.dashboard_hidden_widgets); next.dashboard_widget_sizes = normalizeDashboardWidgetSizes(next.dashboard_widget_sizes); next.dashboard_widget_heights = normalizeDashboardWidgetHeights(next.dashboard_widget_heights); next.dashboard_auto_fit = next.dashboard_auto_fit !== false;
|
||||
next.dashboard_density = normalizeAdminDensity(next.dashboard_density, "compact"); next.dashboard_widgets = normalizeDashboardWidgets(next.dashboard_widgets); next.dashboard_hidden_widgets = normalizeHiddenDashboardWidgets(next.dashboard_hidden_widgets); next.dashboard_widget_sizes = normalizeDashboardWidgetSizes(next.dashboard_widget_sizes); next.dashboard_widget_heights = normalizeDashboardWidgetHeights(next.dashboard_widget_heights); next.dashboard_auto_fit = next.dashboard_auto_fit !== false; next.sidebar_collapsed = next.sidebar_collapsed === true;
|
||||
const saved = await api("/api/preferences", { method: "PUT", body: JSON.stringify(next) });
|
||||
if (!authenticated || epoch !== authEpoch) return adminPreferences;
|
||||
return applyAdminPreferences(saved);
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Collapsible left menu. On wide screens (above 1300 px) the account preference
|
||||
// sidebar_collapsed shows the menu as a narrow rail (logo, section numbers or icons,
|
||||
// status dot). Between 851 and 1300 px the menu is always a rail and the toggle
|
||||
// opens it temporarily as an overlay (closed by choosing a section, clicking
|
||||
// outside or Esc). At 850 px and below the existing mobile menu is used.
|
||||
window.rustProxySidebar = (() => {
|
||||
const root = document.documentElement;
|
||||
const sidebar = document.querySelector(".sidebar");
|
||||
const toggle = document.getElementById("sidebar-collapse-toggle");
|
||||
if (!sidebar || !toggle) return { applyPreference() { }, refresh() { } };
|
||||
const desktop = window.matchMedia("(min-width: 851px)");
|
||||
const rail = window.matchMedia("(min-width: 851px) and (max-width: 1300px)");
|
||||
const label = key => (typeof t === "function" ? t(key) : key);
|
||||
let preferred = false, peek = false;
|
||||
|
||||
function render() {
|
||||
if (!desktop.matches || !rail.matches) peek = false;
|
||||
const collapsed = desktop.matches && (rail.matches ? !peek : preferred);
|
||||
root.classList.toggle("sidebar-collapsed", collapsed);
|
||||
root.classList.toggle("sidebar-peek", peek);
|
||||
const key = collapsed ? "sidebarExpand" : "sidebarCollapse";
|
||||
toggle.setAttribute("aria-expanded", String(!collapsed));
|
||||
toggle.setAttribute("aria-label", label(key));
|
||||
toggle.title = label(key);
|
||||
toggle.querySelector(".sidebar-collapse-label").textContent = label(key);
|
||||
toggle.querySelector(".sidebar-collapse-icon").textContent = collapsed ? "»" : "«";
|
||||
for (const nav of sidebar.querySelectorAll(".nav")) {
|
||||
if (collapsed) nav.title = nav.querySelector("b")?.textContent.replace(/\s+/g, " ").trim() || "";
|
||||
else nav.removeAttribute("title");
|
||||
}
|
||||
}
|
||||
function setPeek(open) {
|
||||
if (peek === open) return;
|
||||
peek = open;
|
||||
render();
|
||||
}
|
||||
toggle.addEventListener("click", event => {
|
||||
event.stopPropagation();
|
||||
if (rail.matches) { setPeek(!peek); return; }
|
||||
preferred = !preferred;
|
||||
render();
|
||||
window.rustProxyPreferences?.update?.({ sidebar_collapsed: preferred })?.catch?.(() => { });
|
||||
});
|
||||
sidebar.querySelectorAll(".nav, .brand").forEach(item => item.addEventListener("click", () => setPeek(false)));
|
||||
document.addEventListener("click", event => { if (peek && !sidebar.contains(event.target)) setPeek(false); });
|
||||
document.addEventListener("keydown", event => { if (event.key === "Escape" && peek) { setPeek(false); toggle.focus(); } });
|
||||
desktop.addEventListener?.("change", render);
|
||||
rail.addEventListener?.("change", render);
|
||||
render();
|
||||
return {
|
||||
applyPreference(value) { preferred = value === true; render(); },
|
||||
refresh: render,
|
||||
};
|
||||
})();
|
||||
Reference in new issue
Block a user