refactor admin navigation; update links to ingest pages and improve loading of data in parallel

This commit is contained in:
ImBenji
2026-04-24 00:08:52 +01:00
parent 16cd61fdf5
commit fc7ea464b3
17 changed files with 292 additions and 67 deletions
+77 -7
View File
@@ -22,7 +22,7 @@ async function loadSignals() {
grid.innerHTML = data.map(s => {
const firstSentence = (s.summary || "").split(/\.\s+/)[0].replace(/\.$/, "") + ".";
const ts = s.generated_at ? s.generated_at.slice(0, 16).replace("T", " ") : "—";
const eventTs = s.latest_event_date ? s.latest_event_date.slice(0, 10) : null;
let drivers = [];
let risks = [];
@@ -50,7 +50,7 @@ async function loadSignals() {
<span class="signal-tag">${escapeHtml(s.timeframe)}</span>
</div>
<div class="signal-summary">${escapeHtml(firstSentence)}</div>
<div class="signal-ts">Generated ${ts}</div>
<div class="signal-ts">${eventTs ? `Latest event ${eventTs}` : "No dated event"}</div>
</div>
<div class="signal-card-detail">
<div class="signal-detail-section">
@@ -63,6 +63,10 @@ async function loadSignals() {
<div class="signal-detail-label">Data used</div>
<p style="color:var(--muted-dark)">${predIds.length} predictions &nbsp;·&nbsp; window: 90 days</p>
</div>
<div class="signal-detail-section" id="signal-refs-${s.company_id}" data-loaded="0">
<div class="signal-detail-label">References</div>
<p style="color:var(--muted-dark)">Loading…</p>
</div>
<button class="signal-regen-btn" onclick="regenerateSignal(event, ${s.company_id})">Regenerate</button>
</div>
</div>
@@ -73,7 +77,73 @@ async function loadSignals() {
function toggleSignalCard(companyId) {
const card = document.getElementById(`signal-card-${companyId}`);
if (card) card.classList.toggle("expanded");
if (!card) return;
card.classList.toggle("expanded");
if (card.classList.contains("expanded")) {
loadSignalReferences(companyId);
}
}
async function loadSignalReferences(companyId) {
const container = document.getElementById(`signal-refs-${companyId}`);
if (!container || container.dataset.loaded === "1") return;
container.dataset.loaded = "1";
let data;
try {
data = await api(`/admin/api/intelligence/signals/${companyId}/references`);
} catch (_) {
container.innerHTML = `
<div class="signal-detail-label">References</div>
<p style="color:var(--muted-dark)">Failed to load references</p>
`;
container.dataset.loaded = "0";
return;
}
const events = data?.events || [];
if (!events.length) {
container.innerHTML = `
<div class="signal-detail-label">References</div>
<p style="color:var(--muted-dark)">No linked events</p>
`;
return;
}
const blocks = events.map(ev => {
const dateStr = (ev.event_date || ev.created_at || "").slice(0, 10);
const articles = (ev.articles || []).map(a => {
const src = a.source ? `<span class="signal-ref-source">${escapeHtml(a.source)}</span>` : "";
const pd = a.pub_date ? `<span class="signal-ref-date">${escapeHtml(a.pub_date.slice(0, 10))}</span>` : "";
return `
<li>
<a href="${escapeHtml(a.url)}" target="_blank" rel="noopener">${escapeHtml(a.title || a.url)}</a>
${src}${pd}
</li>
`;
}).join("");
return `
<div class="signal-ref-event">
<div class="signal-ref-event-title">
${escapeHtml(ev.title || `Event #${ev.id}`)}
${dateStr ? `<span class="signal-ref-date">${dateStr}</span>` : ""}
</div>
${articles ? `<ul class="signal-ref-articles">${articles}</ul>` : `<p style="color:var(--muted-dark);margin:4px 0 0">No articles linked</p>`}
</div>
`;
}).join("");
container.innerHTML = `
<div class="signal-detail-label">References</div>
${blocks}
`;
}
@@ -96,8 +166,8 @@ async function regenerateSignal(ev, companyId) {
}
document.addEventListener("DOMContentLoaded", async () => {
const ok = await loadIntelStatsRow();
if (!ok) return;
loadSignals();
document.addEventListener("DOMContentLoaded", () => {
// fire both in parallel — signals api returns [] when intelligence
// db is unavailable, so no need to gate on the stats call
Promise.all([loadIntelStatsRow(), loadSignals()]);
});