import { deploys as deploysApi, createLogSocket } from '../api.js'; import { icons } from '../icons.js'; export function renderLogs(container) { let deploysList = []; let selectedDeploy = null; let logWs = null; container.innerHTML = `

${icons.scrollText(16)} Deploy Recenti

Caricamento...

${icons.scrollText(32)}

Seleziona un deploy

Clicca su un deploy nella lista per visualizzarne i log

`; async function load() { try { deploysList = await deploysApi.list(); renderList(); } catch (err) { document.getElementById('deploy-list').innerHTML = `

Errore: ${err.message}

`; } } function renderList() { const el = document.getElementById('deploy-list'); el.innerHTML = `

${icons.scrollText(16)} Deploy Recenti

` + (deploysList.length === 0 ? '

Nessun deploy trovato

' : `
${deploysList.map(d => `
${d.service_name} ${d.status}
${d.commit_sha ? `${icons.gitCommit(10)} ${d.commit_sha}` : ''} ${icons.clock(10)} ${new Date(d.created_at).toLocaleString('it-IT')}
${d.commit_message ? `

${esc(d.commit_message)}

` : ''}
`).join('')}
`); el.querySelectorAll('.deploy-item').forEach(item => { item.onclick = () => { const did = parseInt(item.dataset.id); selectedDeploy = deploysList.find(d => d.id === did); renderList(); renderLogPanel(); }; }); } function renderLogPanel() { const panel = document.getElementById('log-panel'); if (!selectedDeploy) { panel.innerHTML = `
${icons.scrollText(32)}

Seleziona un deploy

Clicca su un deploy nella lista per visualizzarne i log

`; return; } if (logWs) { logWs.close(); logWs = null; } const d = selectedDeploy; panel.innerHTML = `

Log: ${d.service_name}

${d.status}
${icons.user(10)} ${d.commit_author || d.trigger} ${icons.gitCommit(10)} ${d.commit_sha || '–'} ${d.duration_ms > 0 ? `${icons.clock(10)} ${(d.duration_ms / 1000).toFixed(1)}s` : ''}
0 righe
In attesa di log...
`; let lines = []; let paused = false; const lv = panel.querySelector('#lv-container'); logWs = createLogSocket(`deploy:${d.id}`); logWs.onmessage = (event) => { try { const msg = JSON.parse(event.data); if (msg.type === 'log' || msg.type === 'info' || msg.type === 'error') { lines.push(msg); if (lines.length > 2000) lines = lines.slice(-1500); if (lv.firstChild?.classList?.contains('info') && lines.length === 1) lv.innerHTML = ''; const div = document.createElement('div'); div.className = `log-line ${msg.type}`; div.textContent = msg.data; lv.appendChild(div); panel.querySelector('#lv-count').textContent = `${lines.length} righe`; if (!paused) lv.scrollTop = lv.scrollHeight; } } catch {} }; logWs.onerror = () => appendLine('error', 'WebSocket connection error'); logWs.onclose = () => appendLine('info', '— Stream ended —'); function appendLine(type, text) { lines.push({ type, data: text }); const div = document.createElement('div'); div.className = `log-line ${type}`; div.textContent = text; lv.appendChild(div); if (!paused) lv.scrollTop = lv.scrollHeight; } panel.querySelector('#lv-pause').onclick = () => { paused = !paused; panel.querySelector('#lv-pause').innerHTML = paused ? `${icons.play(12)} Resume` : `${icons.pause(12)} Pause`; }; panel.querySelector('#lv-download').onclick = () => { const blob = new Blob([lines.map(l => l.data).join('\n')], { type: 'text/plain' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = `logs-deploy-${d.id}-${Date.now()}.txt`; a.click(); URL.revokeObjectURL(a.href); }; } load(); return () => { if (logWs) logWs.close(); }; } function esc(s) { return String(s).replace(/&/g,'&').replace(//g,'>'); }