diff --git a/example_app/ui/index.html b/example_app/ui/index.html index 7a2d595..43b8198 100644 --- a/example_app/ui/index.html +++ b/example_app/ui/index.html @@ -542,6 +542,14 @@

AI Security Command Center

Admin JWT: + @@ -699,7 +707,9 @@

Evidence & ABOM

const activityEl = document.getElementById("activity"); const demoBannerEl = document.getElementById("demoBanner"); const topRisksEl = document.getElementById("topRisks"); + const dataSourceEl = document.getElementById("dataSource"); const tokenKey = "ocpa_admin_token"; + const dataSourceKey = "ocpa_data_source"; let demoMode = false; function setStatus(msg) { @@ -806,6 +816,17 @@

Evidence & ABOM

return localStorage.getItem(tokenKey) || ""; } + function getDataSource() { + return localStorage.getItem(dataSourceKey) || "auto"; + } + + function setDataSource(value) { + localStorage.setItem(dataSourceKey, value); + if (dataSourceEl) { + dataSourceEl.value = value; + } + } + function authHeaders() { const token = getToken(); if (!token) { @@ -1200,6 +1221,7 @@

Evidence & ABOM

let summaryFallback = false; let demoInjected = false; let demoEvents = null; + const dataMode = getDataSource(); try { const health = await fetchJson("/health"); renderOpaStatus(health.opa_status); @@ -1245,52 +1267,67 @@

Evidence & ABOM

errors.push(`inventory: ${err.message}`); } - try { - const summary = await fetchJson("/risk/summary?limit=500", true); - renderSummary(document.getElementById("summary"), summary); - } catch (err) { - summaryError = err; - summaryFallback = demoMode; - if (!demoMode) { - errors.push(`summary: ${err.message}`); - if (summaryMetaEl && /401|403/.test(err.message)) { - summaryMetaEl.textContent = "Admin JWT required to view counts."; - } - if (postureBadgeEl) { - postureBadgeEl.textContent = "Locked"; - postureBadgeEl.className = "posture-value posture-locked"; - } - if (postureSignalsEl) { - postureSignalsEl.textContent = "Signals in window: --"; + if (dataMode === "demo") { + demoInjected = true; + demoEvents = buildDemoEvents(); + renderSummary(document.getElementById("summary"), buildDemoSummary(demoEvents)); + } else { + try { + const summary = await fetchJson("/risk/summary?limit=500", true); + renderSummary(document.getElementById("summary"), summary); + } catch (err) { + summaryError = err; + summaryFallback = demoMode && dataMode === "auto"; + if (!(demoMode && dataMode === "auto")) { + errors.push(`summary: ${err.message}`); + if (summaryMetaEl && /401|403/.test(err.message)) { + summaryMetaEl.textContent = "Admin JWT required to view counts."; + } + if (postureBadgeEl) { + postureBadgeEl.textContent = "Locked"; + postureBadgeEl.className = "posture-value posture-locked"; + } + if (postureSignalsEl) { + postureSignalsEl.textContent = "Signals in window: --"; + } } } } - try { - const ledger = await fetchJson("/ui/ledger?limit=200", true); - if (demoMode && (!ledger.events || ledger.events.length === 0)) { - demoInjected = true; - demoEvents = buildDemoEvents(); - renderLedger(document.getElementById("ledger-body"), demoEvents); - renderRiskDrivers(demoEvents); - renderActivity(demoEvents); - renderTopRisks(demoEvents); - } else { - renderLedger(document.getElementById("ledger-body"), ledger.events); - renderRiskDrivers(ledger.events); - renderActivity(ledger.events); - renderTopRisks(ledger.events); - } - } catch (err) { - if (demoMode) { - demoInjected = true; - demoEvents = buildDemoEvents(); - renderLedger(document.getElementById("ledger-body"), demoEvents); - renderRiskDrivers(demoEvents); - renderActivity(demoEvents); - renderTopRisks(demoEvents); - } else { - errors.push(`ledger: ${err.message}`); + if (dataMode === "demo") { + demoInjected = true; + demoEvents = demoEvents || buildDemoEvents(); + renderLedger(document.getElementById("ledger-body"), demoEvents); + renderRiskDrivers(demoEvents); + renderActivity(demoEvents); + renderTopRisks(demoEvents); + } else { + try { + const ledger = await fetchJson("/ui/ledger?limit=200", true); + if (dataMode === "auto" && demoMode && (!ledger.events || ledger.events.length === 0)) { + demoInjected = true; + demoEvents = buildDemoEvents(); + renderLedger(document.getElementById("ledger-body"), demoEvents); + renderRiskDrivers(demoEvents); + renderActivity(demoEvents); + renderTopRisks(demoEvents); + } else { + renderLedger(document.getElementById("ledger-body"), ledger.events); + renderRiskDrivers(ledger.events); + renderActivity(ledger.events); + renderTopRisks(ledger.events); + } + } catch (err) { + if (demoMode && dataMode === "auto") { + demoInjected = true; + demoEvents = buildDemoEvents(); + renderLedger(document.getElementById("ledger-body"), demoEvents); + renderRiskDrivers(demoEvents); + renderActivity(demoEvents); + renderTopRisks(demoEvents); + } else { + errors.push(`ledger: ${err.message}`); + } } } @@ -1318,10 +1355,18 @@

Evidence & ABOM

errors.push(`summary: ${summaryError.message}`); } + const sourceLabel = + demoInjected || dataMode === "demo" + ? "demo" + : dataMode === "live" + ? "live" + : demoMode + ? "auto" + : "live"; if (errors.length) { - setStatus(`Updated with warnings: ${errors.join(" | ")}`); + setStatus(`Updated (${sourceLabel}) with warnings: ${errors.join(" | ")}`); } else { - setStatus(demoInjected ? "Updated (demo data active)." : "Updated."); + setStatus(`Updated (${sourceLabel}).`); } if (lastUpdatedEl) { lastUpdatedEl.textContent = `Last refresh: ${new Date().toLocaleTimeString()}`; @@ -1385,6 +1430,13 @@

Evidence & ABOM

document.getElementById("downloadOpenApi").addEventListener("click", () => downloadOpenApi("json")); tokenEl.value = getToken(); + if (dataSourceEl) { + dataSourceEl.value = getDataSource(); + dataSourceEl.addEventListener("change", (event) => { + setDataSource(event.target.value); + refreshAll(); + }); + } refreshAll();