import { monitoring as monitoringApi, services as servicesApi } from '../api.js'; import { icons } from '../icons.js'; const RANGES = [ { value: '-1h', label: '1 ora' }, { value: '-6h', label: '6 ore' }, { value: '-24h', label: '24 ore' }, { value: '-7d', label: '7 giorni' }, ]; const METRICS = [ { value: 'cpu_percent', label: 'CPU %', color: '#6366f1' }, { value: 'memory_percent', label: 'RAM %', color: '#8b5cf6' }, { value: 'network_rx', label: 'Network RX', color: '#10b981' }, { value: 'network_tx', label: 'Network TX', color: '#f59e0b' }, ]; export function renderMonitoring(container) { let stats = {}; let selectedService = null; let chartRange = '-1h'; let chartMetric = 'cpu_percent'; let chart = null; let interval; container.innerHTML = `
`; async function loadInitial() { try { const st = await monitoringApi.realtime(); stats = st; renderStats(); } catch {} } async function pollStats() { try { stats = await monitoringApi.realtime(); renderStats(); } catch {} } function formatBytes(bytes) { if (!bytes) return '0 B'; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(1024)); return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`; } function renderStats() { const grid = document.getElementById('stats-grid'); const entries = Object.entries(stats); if (entries.length === 0) { grid.innerHTML = ''; document.getElementById('empty-msg').innerHTML = `
${icons.activity(48)}

Nessun servizio attivo

I dati di monitoring saranno visibili quando almeno un servizio sarà in esecuzione

`; document.getElementById('empty-msg').classList.remove('hidden'); return; } document.getElementById('empty-msg').classList.add('hidden'); grid.innerHTML = entries.map(([name, s]) => `
${name} running
${icons.cpu(12)} CPU
${s?.cpu_percent?.toFixed(1) || '0'}%
${icons.hardDrive(12)} RAM
${formatBytes(s?.memory_usage)}
/ ${formatBytes(s?.memory_limit)}
${icons.wifi(12)} Net RX
${formatBytes(s?.network_rx)}
${icons.wifi(12)} Net TX
${formatBytes(s?.network_tx)}
`).join(''); grid.querySelectorAll('.metric-card').forEach(card => { card.onclick = () => { selectedService = card.dataset.svc; renderStats(); renderChart(); }; }); } async function renderChart() { if (!selectedService) { document.getElementById('chart-section').classList.add('hidden'); return; } const section = document.getElementById('chart-section'); section.classList.remove('hidden'); section.innerHTML = `

📊 ${selectedService} — Storico

${RANGES.map(r => ``).join('')}
${METRICS.map(m => ``).join('')}
`; section.querySelectorAll('[data-range]').forEach(b => { b.onclick = () => { chartRange = b.dataset.range; renderChart(); }; }); section.querySelectorAll('[data-metric]').forEach(b => { b.onclick = () => { chartMetric = b.dataset.metric; renderChart(); }; }); await loadChartData(); } async function loadChartData() { try { const result = await monitoringApi.history(selectedService, chartRange, chartMetric); const labels = result.map(d => new Date(d.time).toLocaleTimeString('it-IT', { hour: '2-digit', minute: '2-digit' })); const values = result.map(d => Math.round(d.value * 100) / 100); const currentMetric = METRICS.find(m => m.value === chartMetric); if (chart) chart.destroy(); const canvas = document.getElementById('monitoring-canvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); // Use Chart.js if available if (typeof Chart !== 'undefined') { chart = new Chart(ctx, { type: 'line', data: { labels, datasets: [{ data: values, borderColor: currentMetric.color, backgroundColor: currentMetric.color + '30', fill: true, tension: 0.3, pointRadius: 0, pointHitRadius: 10, borderWidth: 2, }], }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { x: { ticks: { color: '#6b7280', font: { size: 11 } }, grid: { color: 'rgba(255,255,255,0.05)' } }, y: { min: chartMetric.includes('percent') ? 0 : undefined, max: chartMetric.includes('percent') ? 100 : undefined, ticks: { color: '#6b7280', font: { size: 11 } }, grid: { color: 'rgba(255,255,255,0.05)' }, }, }, }, }); } else { document.getElementById('chart-area').innerHTML = `

Chart.js non caricato. Aggiungi chart.min.js nella cartella lib/

`; } } catch (err) { document.getElementById('chart-area').innerHTML = `

Nessun dato disponibile

`; } } loadInitial(); interval = setInterval(pollStats, 5000); return () => { clearInterval(interval); if (chart) chart.destroy(); }; }