192 lines
7.9 KiB
HTML
192 lines
7.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Visor de Log Completo - Script Parameter Manager</title>
|
|
<link rel="icon" type="image/png" href="{{ url_for('static', filename='icon.png') }}">
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<style>
|
|
.log-content {
|
|
font-family: 'Courier New', monospace;
|
|
white-space: pre-wrap;
|
|
word-break: break-all;
|
|
}
|
|
.search-highlight {
|
|
background-color: yellow;
|
|
padding: 1px 2px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-100">
|
|
<div class="container mx-auto p-6">
|
|
<!-- Header -->
|
|
<div class="bg-white rounded-lg shadow mb-6 p-6">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h1 class="text-2xl font-bold text-gray-800">Visor de Log Completo</h1>
|
|
<div class="flex gap-3">
|
|
<button onclick="downloadLog()"
|
|
class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600">
|
|
📥 Descargar
|
|
</button>
|
|
<button onclick="refreshLog()"
|
|
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
|
|
🔄 Actualizar
|
|
</button>
|
|
<button onclick="window.close()"
|
|
class="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600">
|
|
✖️ Cerrar
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Search -->
|
|
<div class="mb-4">
|
|
<div class="flex gap-2">
|
|
<input type="text" id="searchInput" placeholder="Buscar en el log..."
|
|
class="flex-1 p-2 border border-gray-300 rounded focus:border-blue-500 focus:outline-none">
|
|
<button onclick="searchInLog()"
|
|
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
|
|
🔍 Buscar
|
|
</button>
|
|
<button onclick="clearSearch()"
|
|
class="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600">
|
|
Limpiar
|
|
</button>
|
|
</div>
|
|
<div id="searchStats" class="text-sm text-gray-600 mt-2"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Log Content -->
|
|
<div class="bg-white rounded-lg shadow">
|
|
<div class="p-4 border-b bg-gray-50">
|
|
<div class="flex justify-between items-center">
|
|
<h2 class="text-lg font-semibold">Contenido del Log</h2>
|
|
<div class="text-sm text-gray-600">
|
|
<span id="lineCount">Calculando líneas...</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="p-6">
|
|
<div id="logContent" class="log-content bg-gray-100 p-4 rounded border max-h-[70vh] overflow-auto text-sm">
|
|
{{ log_content }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
let originalLogContent = '';
|
|
|
|
// Inicializar al cargar la página
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const logContentElement = document.getElementById('logContent');
|
|
originalLogContent = logContentElement.textContent;
|
|
updateLineCount();
|
|
|
|
// Scroll al final del log
|
|
logContentElement.scrollTop = logContentElement.scrollHeight;
|
|
|
|
// Configurar búsqueda con Enter
|
|
document.getElementById('searchInput').addEventListener('keypress', function(e) {
|
|
if (e.key === 'Enter') {
|
|
searchInLog();
|
|
}
|
|
});
|
|
});
|
|
|
|
function updateLineCount() {
|
|
const lines = originalLogContent.split('\n').length;
|
|
document.getElementById('lineCount').textContent = `${lines.toLocaleString()} líneas`;
|
|
}
|
|
|
|
function searchInLog() {
|
|
const searchTerm = document.getElementById('searchInput').value.trim();
|
|
const logContentElement = document.getElementById('logContent');
|
|
const searchStatsElement = document.getElementById('searchStats');
|
|
|
|
if (!searchTerm) {
|
|
clearSearch();
|
|
return;
|
|
}
|
|
|
|
// Escapar caracteres especiales para regex
|
|
const escapedTerm = searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
const regex = new RegExp(escapedTerm, 'gi');
|
|
|
|
// Contar coincidencias
|
|
const matches = (originalLogContent.match(regex) || []).length;
|
|
|
|
if (matches > 0) {
|
|
// Resaltar coincidencias
|
|
const highlightedContent = originalLogContent.replace(regex,
|
|
'<span class="search-highlight">$&</span>');
|
|
logContentElement.innerHTML = highlightedContent;
|
|
|
|
searchStatsElement.textContent = `Encontradas ${matches} coincidencias de "${searchTerm}"`;
|
|
searchStatsElement.className = 'text-sm text-green-600 mt-2';
|
|
|
|
// Scroll a la primera coincidencia
|
|
const firstHighlight = logContentElement.querySelector('.search-highlight');
|
|
if (firstHighlight) {
|
|
firstHighlight.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
}
|
|
} else {
|
|
searchStatsElement.textContent = `No se encontraron coincidencias de "${searchTerm}"`;
|
|
searchStatsElement.className = 'text-sm text-red-600 mt-2';
|
|
}
|
|
}
|
|
|
|
function clearSearch() {
|
|
const logContentElement = document.getElementById('logContent');
|
|
const searchStatsElement = document.getElementById('searchStats');
|
|
|
|
// Restaurar contenido original
|
|
logContentElement.textContent = originalLogContent;
|
|
document.getElementById('searchInput').value = '';
|
|
searchStatsElement.textContent = '';
|
|
}
|
|
|
|
async function refreshLog() {
|
|
try {
|
|
const response = await fetch('/api/full-log');
|
|
const result = await response.json();
|
|
|
|
if (result.logs !== undefined) {
|
|
originalLogContent = result.logs;
|
|
document.getElementById('logContent').textContent = originalLogContent;
|
|
updateLineCount();
|
|
clearSearch();
|
|
|
|
// Scroll al final
|
|
const logContentElement = document.getElementById('logContent');
|
|
logContentElement.scrollTop = logContentElement.scrollHeight;
|
|
} else {
|
|
alert('Error al actualizar el log: ' + (result.error || 'Error desconocido'));
|
|
}
|
|
} catch (error) {
|
|
console.error('Error refreshing log:', error);
|
|
alert('Error de red al actualizar el log');
|
|
}
|
|
}
|
|
|
|
function downloadLog() {
|
|
const blob = new Blob([originalLogContent], { type: 'text/plain' });
|
|
const url = window.URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
|
|
const now = new Date();
|
|
const timestamp = now.toISOString().replace(/[:.]/g, '-').slice(0, -5);
|
|
|
|
a.href = url;
|
|
a.download = `log_${timestamp}.txt`;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
window.URL.revokeObjectURL(url);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|