// panes/demand.js — cxai-demand jobs.
import { registerPane } from '../app.js';
import { jget, jpost, escapeHtml, statusClass } from '../lib/api.js';
import { ok, err, fmtJSON } from '../lib/ui.js';
const TPL = `
Demand
Trend-driven design jobs.
`;
function num(v) { if (v === '' || v == null) return null; const n = +v; return Number.isFinite(n) ? n : null; }
async function loadJobs(host) {
try {
const r = await jget('/api/demand/runs');
host.querySelector('#demand-jobs').innerHTML = (r.jobs || []).map(j => {
const dur = j.finished_at && j.started_at ? `${(j.finished_at - j.started_at).toFixed(1)}s`
: (j.status === 'running' ? '…' : '—');
return `
${escapeHtml(j.id)}
${escapeHtml(j.status)}
${dur}
${escapeHtml(j.report_path || j.error || '')}
`;
}).join('') || 'no jobs yet
';
} catch (e) {
host.querySelector('#demand-jobs').innerHTML = `${escapeHtml(e.message)}
`;
}
}
async function loadReports(host) {
try {
const r = await jget('/api/demand/reports');
host.querySelector('#demand-reports').innerHTML = (r.reports || []).map(it =>
``
).join('') || 'no reports
';
host.querySelectorAll('.report-link').forEach(b => {
b.addEventListener('click', async (e) => {
e.preventDefault();
try { host.querySelector('#demand-report-body').textContent = fmtJSON(await jget('/api/demand/reports/' + b.dataset.name)); }
catch (e) { host.querySelector('#demand-report-body').textContent = e.message; }
});
});
} catch (e) {
host.querySelector('#demand-reports').innerHTML = `${escapeHtml(e.message)}
`;
}
}
async function refresh(host) {
try {
const platforms = (await jget('/api/demand/platforms')).platforms || [];
const sel = host.querySelector('#demand-platform');
if (sel && sel.children.length === 0) {
sel.innerHTML = `` + platforms.map(p => ``).join('');
}
await loadJobs(host); await loadReports(host);
} catch (e) {
host.querySelector('#demand-status').textContent = 'upstream unavailable: ' + e.message;
}
}
registerPane('demand', {
label: 'Demand',
init(host) {
host.innerHTML = TPL;
host.querySelector('#demand-refresh').addEventListener('click', () => refresh(host));
host.querySelector('#demand-form').addEventListener('submit', async (e) => {
e.preventDefault();
const body = {
designs_per_run: +host.querySelector('#demand-count').value || 0,
top_trends: num(host.querySelector('#demand-top').value),
variations_per_trend: num(host.querySelector('#demand-var').value),
min_score: num(host.querySelector('#demand-min').value),
platform: host.querySelector('#demand-platform').value || null,
dry_run: host.querySelector('#demand-dry').checked,
upload: host.querySelector('#demand-up').checked,
web_trends: host.querySelector('#demand-web').checked,
quantum: host.querySelector('#demand-q').checked,
};
try {
const r = await jpost('/api/demand/runs', body);
host.querySelector('#demand-status').textContent = `queued: ${r.job_id}`;
ok(`queued ${r.job_id}`);
await loadJobs(host);
} catch (e) { host.querySelector('#demand-status').textContent = 'error: ' + e.message; err(e.message); }
});
refresh(host);
},
refresh,
});