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 = `
${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
${icons.pause(12)} Pause
${icons.download(12)} Download
`;
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,'>'); }