agentic-os/dashboard/pages/dashboard.js

130 lines
5.1 KiB
JavaScript

let healthChart = null;
async function renderDashboard() {
const content = document.getElementById('pageContent');
let status;
try {
status = await api.getStatus();
} catch {
content.innerHTML = '<div class="empty-state"><div class="icon">⚠</div><h3>Cannot connect to server</h3><p>Make sure server.py is running</p></div>';
return;
}
content.innerHTML = `
<div class="page-header">
<div>
<h1 class="page-title">Dashboard</h1>
<p class="page-subtitle">System overview and quick actions</p>
</div>
<button class="btn btn-primary" onclick="refreshDashboard()">⟳ Refresh</button>
</div>
<div class="grid grid-4" id="statCards">
<div class="card"><div class="card-value" id="agentsOnline">-</div><div class="card-label">Agents Online</div></div>
<div class="card"><div class="card-value" id="skillsCount">-</div><div class="card-label">Skills Available</div></div>
<div class="card"><div class="card-value" id="systemUptime">-</div><div class="card-label">System Uptime</div></div>
<div class="card"><div class="card-value" id="healthStatus">-</div><div class="card-label">Health Status</div></div>
</div>
<div class="grid grid-2">
<div class="card">
<div class="card-header">
<span class="card-title">Agent Status</span>
</div>
<div id="agentList"></div>
</div>
<div class="card">
<div class="card-header">
<span class="card-title">Quick Run</span>
</div>
<div class="form-group">
<label class="form-label">Select Skill</label>
<select id="quickSkillSelect"></select>
</div>
<div class="form-group">
<label class="form-label">Input (optional)</label>
<textarea id="quickSkillInput" rows="2" placeholder="Optional input for the skill..."></textarea>
</div>
<button class="btn btn-primary" onclick="quickRunSkill()">▶ Run Skill</button>
<div id="quickRunResult" style="margin-top:12px"></div>
</div>
</div>
<div class="card">
<div class="card-header">
<span class="card-title">Recent Activity</span>
</div>
<div id="recentActivity"><div class="loading">Loading...</div></div>
</div>
`;
// Fill stat cards
const agents = status.agents || [];
document.getElementById('agentsOnline').textContent = `${agents.filter(a => a.status === 'online').length}/${agents.length}`;
document.getElementById('skillsCount').textContent = status.skills_count || 0;
document.getElementById('systemUptime').textContent = status.uptime ? Math.floor((Date.now()/1000 - status.uptime) / 60) + ' min' : '-';
document.getElementById('healthStatus').textContent = status.status === 'healthy' ? 'Healthy' : 'Degraded';
document.getElementById('healthStatus').style.color = status.status === 'healthy' ? 'var(--green)' : 'var(--red)';
// Agent list
const agentList = document.getElementById('agentList');
agents.forEach(a => {
agentList.innerHTML += `
<div style="display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--border)">
<div class="status-dot ${a.status}"></div>
<strong>${a.name}</strong>
<span style="color:var(--text2);font-size:12px">${a.status}</span>
</div>
`;
});
// Skill select
try {
const skills = await api.getSkills();
const select = document.getElementById('quickSkillSelect');
skills.forEach(s => {
const opt = document.createElement('option');
opt.value = s.name;
opt.textContent = s.name;
select.appendChild(opt);
});
} catch {}
// Recent activity
try {
const audit = await api.getAudit(10);
const activity = document.getElementById('recentActivity');
if (audit.entries && audit.entries.length > 0) {
activity.innerHTML = audit.entries.reverse().map(e => `
<div style="display:flex;align-items:center;gap:8px;padding:6px 0;font-size:13px;border-bottom:1px solid var(--border)">
<span style="color:var(--text2);font-size:11px">${formatDate(e.timestamp)}</span>
<span class="badge badge-info">${e.action}</span>
<span>${e.skill || e.file || ''}</span>
</div>
`).join('');
} else {
activity.innerHTML = '<div class="empty-state" style="padding:20px"><span>No activity yet</span></div>';
}
} catch {}
}
async function quickRunSkill() {
const select = document.getElementById('quickSkillSelect');
const input = document.getElementById('quickSkillInput');
const result = document.getElementById('quickRunResult');
if (!select.value) { showToast('Select a skill first', 'error'); return; }
result.innerHTML = '<span style="color:var(--text2)">Running...</span>';
try {
const r = await api.runSkill(select.value, input.value);
result.innerHTML = `<span style="color:var(--green)">✓ ${r.message}</span>`;
showToast(`Skill '${select.value}' dispatched to ${r.agent}`, 'success');
} catch (err) {
result.innerHTML = `<span style="color:var(--red)">✗ ${err.message}</span>`;
}
}
async function refreshDashboard() {
showToast('Refreshing dashboard...', 'info');
renderDashboard();
}