Обновлен шаблон index.html

This commit is contained in:
Сергей Антропов 2025-08-17 16:02:18 +03:00
parent ee7eb3d163
commit ea94b8e3e0

View File

@ -2148,6 +2148,9 @@ async function setupMultiView() {
});
console.log(`setupMultiView: Multi-view setup completed for ${state.selectedContainers.length} containers`);
// Обновляем счетчики для multi view
await updateMultiViewCounters();
}
function createMultiViewPanel(service) {
@ -2181,6 +2184,8 @@ function createMultiViewPanel(service) {
function openMultiViewWs(service) {
const containerId = service.id;
console.log(`openMultiViewWs: Starting WebSocket setup for ${service.name} (${containerId})`);
console.log(`openMultiViewWs: Current multiViewMode: ${state.multiViewMode}`);
console.log(`openMultiViewWs: Selected containers: ${state.selectedContainers.join(', ')}`);
// Закрываем существующее соединение
closeWs(containerId);
@ -2379,6 +2384,9 @@ async function sendSnapshot(id){
function openWs(svc, panel){
const id = svc.id;
console.log(`openWs: Called for ${svc.name} (${id}) in multiViewMode: ${state.multiViewMode}`);
console.log(`openWs: Selected containers: ${state.selectedContainers.join(', ')}`);
const logEl = panel.querySelector('.log');
const wrapEl = panel.querySelector('.logwrap');
@ -2494,15 +2502,41 @@ function handleLine(id, line){
const multiViewLog = document.querySelector(`.multi-view-log[data-container-id="${id}"]`);
if (multiViewLog) {
if (shouldShow) {
// Применяем ограничение tail lines в multi view
const tailLines = parseInt(els.tail.value) || 50;
// Добавляем новую строку
multiViewLog.insertAdjacentHTML('beforeend', html);
// Ограничиваем количество отображаемых строк
const logLines = Array.from(multiViewLog.querySelectorAll('.line'));
if (logLines.length > tailLines) {
// Удаляем лишние строки с начала
const linesToRemove = logLines.length - tailLines;
console.log(`handleLine: Trimming ${linesToRemove} lines from container ${id} (tail: ${tailLines})`);
// Удаляем первые N строк
logLines.slice(0, linesToRemove).forEach(line => {
line.remove();
});
}
if (els.autoscroll && els.autoscroll.checked) {
multiViewLog.scrollTop = multiViewLog.scrollHeight;
}
console.log(`handleLine: Updated multi-view for container ${id}, log element found: true`);
console.log(`handleLine: Updated multi-view for container ${id}, log element found: true, tail lines: ${tailLines}`);
}
} else {
console.error(`handleLine: Multi-view log element not found for container ${id}`);
}
// Обновляем счетчики в multi view периодически (каждые 10 строк)
if (!state.multiViewCounterUpdateTimer) {
state.multiViewCounterUpdateTimer = setTimeout(() => {
updateMultiViewCounters();
state.multiViewCounterUpdateTimer = null;
}, 1000); // Обновляем каждую секунду
}
}
}
@ -2794,6 +2828,61 @@ async function updateCounters(containerId) {
}
}
// Функция для обновления счетчиков в multi view (суммирует статистику всех контейнеров)
async function updateMultiViewCounters() {
if (!state.multiViewMode || state.selectedContainers.length === 0) {
return;
}
try {
console.log('Updating multi-view counters for containers:', state.selectedContainers);
// Суммируем статистику всех выбранных контейнеров
let totalDebug = 0;
let totalInfo = 0;
let totalWarn = 0;
let totalError = 0;
// Получаем статистику для каждого контейнера
for (const containerId of state.selectedContainers) {
try {
const response = await fetch(`/api/logs/stats/${containerId}`);
if (response.ok) {
const stats = await response.json();
totalDebug += stats.debug || 0;
totalInfo += stats.info || 0;
totalWarn += stats.warn || 0;
totalError += stats.error || 0;
}
} catch (error) {
console.error(`Error fetching stats for container ${containerId}:`, error);
}
}
// Обновляем счетчики в интерфейсе
const cdbg = document.querySelector('.cdbg');
const cinfo = document.querySelector('.cinfo');
const cwarn = document.querySelector('.cwarn');
const cerr = document.querySelector('.cerr');
if (cdbg) cdbg.textContent = totalDebug;
if (cinfo) cinfo.textContent = totalInfo;
if (cwarn) cwarn.textContent = totalWarn;
if (cerr) cerr.textContent = totalError;
console.log('Multi-view counters updated:', { totalDebug, totalInfo, totalWarn, totalError });
// Обновляем видимость счетчиков
updateCounterVisibility();
// Добавляем обработчики для счетчиков
addCounterClickHandlers();
} catch (error) {
console.error('Error updating multi-view counters:', error);
}
}
// Функция для обновления видимости счетчиков
function updateCounterVisibility() {
const debugBtn = document.querySelector('.debug-btn');
@ -2821,10 +2910,8 @@ async function refreshLogsAndCounters() {
// Обновляем мультипросмотр
console.log('Refreshing multi-view for containers:', state.selectedContainers);
// Обновляем счетчики для всех выбранных контейнеров
for (const containerId of state.selectedContainers) {
await updateCounters(containerId);
}
// Обновляем счетчики для всех выбранных контейнеров (суммируем статистику)
await updateMultiViewCounters();
// Перезапускаем WebSocket соединения для всех выбранных контейнеров
state.selectedContainers.forEach(containerId => {
@ -3203,10 +3290,20 @@ if (els.tail) {
Object.keys(state.open).forEach(id=>{
const svc = state.services.find(s=> s.id===id);
if (!svc) return;
const panel = els.grid.querySelector(`.panel[data-cid="${id}"]`);
if (!panel) return;
state.open[id].logEl.textContent='';
closeWs(id); openWs(svc, panel);
// В multi view режиме используем openMultiViewWs
if (state.multiViewMode && state.selectedContainers.includes(id)) {
console.log(`Refresh: Using openMultiViewWs for ${svc.name} in multi view mode`);
closeWs(id);
openMultiViewWs(svc);
} else {
// В обычном режиме используем openWs
const panel = els.grid.querySelector(`.panel[data-cid="${id}"]`);
if (!panel) return;
state.open[id].logEl.textContent='';
closeWs(id);
openWs(svc, panel);
}
});
// Обновляем современный интерфейс
@ -3407,6 +3504,64 @@ window.addEventListener('keydown', async (e)=>{
const containerId = e.target.getAttribute('data-container-id');
toggleContainerSelection(containerId);
}
// Обработчик изменения tail lines
if (e.target.id === 'tail') {
console.log('Tail lines changed to:', e.target.value);
if (state.multiViewMode) {
// В multi view применяем новое ограничение к уже отображаемым логам
const tailLines = parseInt(e.target.value) || 50;
console.log(`Applying tail lines limit ${tailLines} to ${state.selectedContainers.length} containers:`, state.selectedContainers);
// Проверяем все элементы multi-view-log на странице
const allMultiViewLogs = document.querySelectorAll('.multi-view-log');
console.log(`Found ${allMultiViewLogs.length} multi-view-log elements on page:`, Array.from(allMultiViewLogs).map(el => el.getAttribute('data-container-id')));
state.selectedContainers.forEach(containerId => {
console.log(`Processing container ${containerId}...`);
// Ищем элемент несколькими способами
let multiViewLog = document.querySelector(`.multi-view-log[data-container-id="${containerId}"]`);
if (!multiViewLog) {
console.warn(`Container ${containerId} not found with data-container-id, trying alternative search...`);
// Попробуем найти по другому селектору
multiViewLog = document.querySelector(`[data-container-id="${containerId}"]`);
}
if (multiViewLog) {
console.log(`Found multi-view-log for container ${containerId}, current lines:`, multiViewLog.querySelectorAll('.line').length);
// Получаем все строки логов
const logLines = Array.from(multiViewLog.querySelectorAll('.line'));
console.log(`Container ${containerId}: ${logLines.length} log lines found`);
if (logLines.length > tailLines) {
// Удаляем лишние строки с начала
const linesToRemove = logLines.length - tailLines;
console.log(`Removing ${linesToRemove} lines from container ${containerId}`);
// Удаляем первые N строк
logLines.slice(0, linesToRemove).forEach(line => {
line.remove();
});
const remainingLines = multiViewLog.querySelectorAll('.line').length;
console.log(`Container ${containerId} now has ${remainingLines} lines after trimming`);
} else {
console.log(`Container ${containerId} has ${logLines.length} lines, no trimming needed (limit: ${tailLines})`);
}
} else {
console.error(`Multi-view log element not found for container ${containerId}`);
console.error(`Available multi-view-log elements:`, Array.from(document.querySelectorAll('.multi-view-log')).map(el => ({
containerId: el.getAttribute('data-container-id'),
className: el.className,
parent: el.parentElement?.className
})));
}
});
}
}
});
// Добавляем обработчики кликов на label чекбоксов