Harden diagnostics UI (busy states, retry refresh)
This commit is contained in:
@@ -8,6 +8,7 @@ const uiBuffer = [];
|
|||||||
let uiEnabled = false;
|
let uiEnabled = false;
|
||||||
let uiLevel = "normal";
|
let uiLevel = "normal";
|
||||||
let clickListenerAttached = false;
|
let clickListenerAttached = false;
|
||||||
|
let loading = false;
|
||||||
|
|
||||||
function appendUi(level, msg, meta = null) {
|
function appendUi(level, msg, meta = null) {
|
||||||
if (!uiEnabled) return;
|
if (!uiEnabled) return;
|
||||||
@@ -50,6 +51,13 @@ export async function initDiagUI({ elements, toast }) {
|
|||||||
const { enableToggle, debugToggle, refreshBtn, clearBtn, copyBtn, downloadBtn, logBox, statusEl } =
|
const { enableToggle, debugToggle, refreshBtn, clearBtn, copyBtn, downloadBtn, logBox, statusEl } =
|
||||||
elements;
|
elements;
|
||||||
|
|
||||||
|
const setBusy = (on) => {
|
||||||
|
loading = on;
|
||||||
|
[refreshBtn, clearBtn, copyBtn, downloadBtn, enableToggle, debugToggle].forEach((el) => {
|
||||||
|
if (el) el.disabled = !!on;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
async function syncState() {
|
async function syncState() {
|
||||||
const data = await getDiagLog();
|
const data = await getDiagLog();
|
||||||
const state = data.state || {};
|
const state = data.state || {};
|
||||||
@@ -73,17 +81,30 @@ export async function initDiagUI({ elements, toast }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function refresh() {
|
async function refresh() {
|
||||||
|
if (loading) return;
|
||||||
|
setBusy(true);
|
||||||
try {
|
try {
|
||||||
const entries = await syncState();
|
const entries = await syncState();
|
||||||
render(entries);
|
render(entries);
|
||||||
toast?.("Diagnostics refreshed", "success");
|
toast?.("Diagnostics refreshed", "success");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast?.(e.error || "Failed to load diagnostics", "error");
|
toast?.(e.error || "Failed to load diagnostics", "error");
|
||||||
|
// retry once if failed
|
||||||
|
try {
|
||||||
|
const entries = await syncState();
|
||||||
|
render(entries);
|
||||||
|
toast?.("Diagnostics refreshed (after retry)", "success");
|
||||||
|
} catch {
|
||||||
|
// swallow
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enableToggle?.addEventListener("change", async () => {
|
enableToggle?.addEventListener("change", async () => {
|
||||||
try {
|
try {
|
||||||
|
setBusy(true);
|
||||||
uiEnabled = enableToggle.checked;
|
uiEnabled = enableToggle.checked;
|
||||||
await setDiagLevel({ enabled: uiEnabled, level: uiLevel });
|
await setDiagLevel({ enabled: uiEnabled, level: uiLevel });
|
||||||
appendUi("info", `Diagnostics ${uiEnabled ? "enabled" : "disabled"}`);
|
appendUi("info", `Diagnostics ${uiEnabled ? "enabled" : "disabled"}`);
|
||||||
@@ -92,11 +113,14 @@ export async function initDiagUI({ elements, toast }) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast?.(e.error || "Failed to save diagnostics setting", "error");
|
toast?.(e.error || "Failed to save diagnostics setting", "error");
|
||||||
enableToggle.checked = !enableToggle.checked;
|
enableToggle.checked = !enableToggle.checked;
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
debugToggle?.addEventListener("change", async () => {
|
debugToggle?.addEventListener("change", async () => {
|
||||||
try {
|
try {
|
||||||
|
setBusy(true);
|
||||||
uiLevel = debugToggle.checked ? "debug" : "normal";
|
uiLevel = debugToggle.checked ? "debug" : "normal";
|
||||||
await setDiagLevel({ enabled: uiEnabled, level: uiLevel });
|
await setDiagLevel({ enabled: uiEnabled, level: uiLevel });
|
||||||
appendUi("info", `Diagnostics level set to ${uiLevel}`);
|
appendUi("info", `Diagnostics level set to ${uiLevel}`);
|
||||||
@@ -105,6 +129,8 @@ export async function initDiagUI({ elements, toast }) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast?.(e.error || "Failed to save level", "error");
|
toast?.(e.error || "Failed to save level", "error");
|
||||||
debugToggle.checked = uiLevel === "debug";
|
debugToggle.checked = uiLevel === "debug";
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -112,12 +138,15 @@ export async function initDiagUI({ elements, toast }) {
|
|||||||
|
|
||||||
clearBtn?.addEventListener("click", async () => {
|
clearBtn?.addEventListener("click", async () => {
|
||||||
try {
|
try {
|
||||||
|
setBusy(true);
|
||||||
await clearDiagLog();
|
await clearDiagLog();
|
||||||
uiBuffer.length = 0;
|
uiBuffer.length = 0;
|
||||||
appendUi("info", "Cleared diagnostics");
|
appendUi("info", "Cleared diagnostics");
|
||||||
await refresh();
|
await refresh();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast?.(e.error || "Failed to clear log", "error");
|
toast?.(e.error || "Failed to clear log", "error");
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user