Duriin-API/public/admin/assets/js/intel-knowledge.js

93 lines
3.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// intelligence → knowledge table
// filter/sort/pagination persisted via url query params
// depends on: app.js, intel-shared.js
let knowledgeOffset = 0;
function syncUrl() {
const companyId = document.getElementById("i-company").value;
const type = document.getElementById("i-type").value;
const sort = document.getElementById("i-sort").value;
queryWrite({
company_id: companyId,
type: type,
sort: sort && sort !== "id" ? sort : "",
offset: knowledgeOffset > 0 ? knowledgeOffset : "",
});
}
async function loadKnowledge() {
// fall back to url params when the company dropdown hasn't populated
// yet — lets init fire all api calls in parallel
const companyId = document.getElementById("i-company").value || queryGet("company_id");
const type = document.getElementById("i-type").value;
const sort = document.getElementById("i-sort").value;
const params = new URLSearchParams({ limit: PAGE, offset: knowledgeOffset });
if (companyId) params.set("company_id", companyId);
if (type) params.set("type", type);
if (sort) params.set("sort", sort);
const data = await api(`/admin/api/intelligence/knowledge?${params}`);
intelRows = data.rows;
document.getElementById("intel-thead").innerHTML = `
<tr><th>ID</th><th>Company</th><th>Event</th><th>Type</th><th>Data</th><th>Event date</th></tr>`;
document.getElementById("intel-tbody").innerHTML = data.rows.map(r => {
let parsed = {};
try { parsed = JSON.parse(r.data); } catch (_) {}
const summary = Object.values(parsed).filter(v => typeof v === "string").join(" · ").slice(0, 120);
return `<tr style="cursor:pointer" onclick="openIntelDetail(${r.id}, 'knowledge')">
<td style="color:var(--muted-dark); font-size:12px">${r.id}</td>
<td style="white-space:nowrap">${escapeHtml(r.company_name)}</td>
<td style="color:var(--muted-dark); font-size:12px">${r.event_id}</td>
<td><span class="badge null">${escapeHtml(r.type)}</span></td>
<td><span class="truncate" style="max-width:360px">${escapeHtml(summary)}</span></td>
<td style="color:var(--muted-dark); white-space:nowrap; font-size:12px">${r.event_date ? r.event_date.slice(0,10) : "—"}</td>
</tr>`;
}).join("");
const total = data.total;
document.getElementById("iPageInfo").textContent =
`${knowledgeOffset + 1}${Math.min(knowledgeOffset + PAGE, total)} of ${total.toLocaleString()}`;
document.getElementById("iPrevBtn").disabled = knowledgeOffset === 0;
document.getElementById("iNextBtn").disabled = knowledgeOffset + PAGE >= total;
}
document.addEventListener("DOMContentLoaded", async () => {
document.getElementById("iPrevBtn").onclick = () => {
knowledgeOffset = Math.max(0, knowledgeOffset - PAGE);
syncUrl();
loadKnowledge();
};
document.getElementById("iNextBtn").onclick = () => {
knowledgeOffset += PAGE;
syncUrl();
loadKnowledge();
};
document.getElementById("i-filter-btn").onclick = () => {
knowledgeOffset = 0;
syncUrl();
loadKnowledge();
};
// restore non-async inputs from url up-front (company_id is handled
// inside loadIntelCompanies once the dropdown has options)
queryApplyToInputs({
"i-type": "type",
"i-sort": "sort",
});
knowledgeOffset = parseInt(queryGet("offset"), 10) || 0;
// fire all three calls concurrently — loadKnowledge reads company_id
// from the url when the select isn't populated yet
await Promise.all([
loadIntelStatsRow(),
loadIntelCompanies(),
loadKnowledge(),
]);
});