add signal generation feature; implement signals view in admin panel

This commit is contained in:
ImBenji 2026-04-23 22:08:46 +01:00
parent 9d89dc95e4
commit 4ffd31c2ab

View file

@ -799,6 +799,28 @@
}
/* ── view popover ── */
.view-opt {
display: block;
width: 100%;
text-align: left;
background: transparent;
border: none;
border-radius: 0;
color: var(--muted);
padding: 9px 14px;
font-size: 13px;
font-weight: 500;
border-bottom: 1px solid var(--border-light);
transition: background .1s, color .1s;
}
.view-opt:last-child { border-bottom: none; }
.view-opt:hover { background: var(--primary-bg); color: var(--foreground); }
.view-opt.active { color: var(--foreground); background: var(--primary-bg); }
/* ── signal cards ── */
#intel-signals-wrap {
@ -1050,12 +1072,18 @@
<select id="i-company"><option value="">All companies</option></select>
</label>
<label>View
<select id="i-view">
<option value="knowledge">Knowledge</option>
<option value="predictions">Predictions</option>
<option value="signals">Signals</option>
<option value="graph">Graph</option>
</select>
<div style="position:relative" id="i-view-wrap">
<button id="i-view-btn" onclick="toggleViewPopover(event)" style="display:flex; align-items:center; gap:6px; min-width:130px; justify-content:space-between">
<span id="i-view-label">Knowledge</span>
<svg width="10" height="6" viewBox="0 0 10 6" fill="none" style="opacity:.5;flex-shrink:0"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
<div id="i-view-popover" style="display:none; position:absolute; top:calc(100% + 5px); left:0; background:var(--bg-card); border:1px solid var(--border); border-radius:var(--radius-lg); box-shadow:0 8px 24px rgba(0,0,0,.4); z-index:50; min-width:160px; overflow:hidden">
<button class="view-opt active" data-view="knowledge" onclick="selectView('knowledge')">Knowledge</button>
<button class="view-opt" data-view="predictions" onclick="selectView('predictions')">Predictions</button>
<button class="view-opt" data-view="signals" onclick="selectView('signals')">Signals</button>
<button class="view-opt" data-view="graph" onclick="selectView('graph')">Graph</button>
</div>
</div>
</label>
<label>Type
<select id="i-type">
@ -1524,6 +1552,35 @@ document.getElementById('eDeleteBtn').onclick = async () => {
// ── intelligence ───────────────────────────────────────────────────────────
let intelOffset = 0;
let currentIntelView = 'knowledge';
function toggleViewPopover(ev) {
ev.stopPropagation();
const pop = document.getElementById('i-view-popover');
pop.style.display = pop.style.display === 'none' ? 'block' : 'none';
}
function selectView(view) {
currentIntelView = view;
const labels = { knowledge: 'Knowledge', predictions: 'Predictions', signals: 'Signals', graph: 'Graph' };
document.getElementById('i-view-label').textContent = labels[view] || view;
document.querySelectorAll('.view-opt').forEach(b => {
b.classList.toggle('active', b.dataset.view === view);
});
document.getElementById('i-view-popover').style.display = 'none';
intelOffset = 0;
loadIntelligence();
}
document.addEventListener('click', ev => {
const wrap = document.getElementById('i-view-wrap');
if (wrap && !wrap.contains(ev.target)) {
document.getElementById('i-view-popover').style.display = 'none';
}
});
async function loadIntelligenceStats() {
const data = await api('/admin/api/intelligence/stats');
@ -1570,7 +1627,7 @@ async function loadIntelligenceCompanies() {
}
async function loadIntelligence() {
const view = document.getElementById('i-view').value;
const view = currentIntelView;
if (view === 'graph') {
showSignalsView(false);
@ -1665,7 +1722,7 @@ async function loadIntelligence() {
document.getElementById('iPrevBtn').onclick = () => { intelOffset = Math.max(0, intelOffset - PAGE); loadIntelligence(); };
document.getElementById('iNextBtn').onclick = () => { intelOffset += PAGE; loadIntelligence(); };
document.getElementById('i-view').onchange = () => { intelOffset = 0; loadIntelligence(); };
// view switching is handled by selectView()
// ── intelligence graph ─────────────────────────────────────────────────────