From 04acb4ac21b3d385a0f5ef458fc89fa9d5983788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Tue, 4 Nov 2025 08:59:16 +0100 Subject: [PATCH] fixes --- static/js/logs.js | 93 +++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 64 deletions(-) diff --git a/static/js/logs.js b/static/js/logs.js index 1ce6256..6babcaf 100644 --- a/static/js/logs.js +++ b/static/js/logs.js @@ -1,5 +1,6 @@ /** * HAProxy Logs Management with Security Alerts + * Fixed pagination */ document.addEventListener('DOMContentLoaded', function() { @@ -26,6 +27,7 @@ document.addEventListener('DOMContentLoaded', function() { // Event Listeners searchFilter.addEventListener('keyup', debounce(function() { + console.log('[Logs] Search changed'); currentPage = 1; loadLogsWithPage(); }, 300)); @@ -48,6 +50,7 @@ document.addEventListener('DOMContentLoaded', function() { }); clearFilterBtn.addEventListener('click', function() { + console.log('[Logs] Clear filters'); searchFilter.value = ''; excludePhrases = []; excludeFilter.value = ''; @@ -57,41 +60,45 @@ document.addEventListener('DOMContentLoaded', function() { }); perPageSelect.addEventListener('change', function() { + console.log(`[Logs] Per page changed to ${this.value}`); perPage = parseInt(this.value); currentPage = 1; - applyFilters(); + loadLogsWithPage(); }); refreshBtn.addEventListener('click', function() { + console.log('[Logs] Refresh clicked'); searchFilter.value = ''; excludePhrases = []; excludeFilter.value = ''; updateExcludeUI(); currentPage = 1; - loadLogs(); + loadLogsWithPage(); }); prevBtn.addEventListener('click', function() { if (currentPage > 1) { + console.log(`[Logs] Prev button: page ${currentPage} -> ${currentPage - 1}`); currentPage--; - applyFilters(); + loadLogsWithPage(); } }); nextBtn.addEventListener('click', function() { - const filtered = getFilteredLogs(); - const totalPages = Math.ceil(filtered.length / perPage); + const totalPages = parseInt(document.getElementById('total_pages').textContent); if (currentPage < totalPages) { + console.log(`[Logs] Next button: page ${currentPage} -> ${currentPage + 1}`); currentPage++; - applyFilters(); + loadLogsWithPage(); } }); loadAllBtn.addEventListener('click', function() { - perPage = totalLogs; + console.log('[Logs] Load all clicked'); + perPage = totalLogs > 500 ? 500 : totalLogs; currentPage = 1; - perPageSelect.value = totalLogs; - applyFilters(); + perPageSelect.value = perPage; + loadLogsWithPage(); }); /** @@ -105,19 +112,13 @@ document.addEventListener('DOMContentLoaded', function() { }; } - /** - * Load initial logs from API - */ - function loadLogs() { - logsContainer.innerHTML = 'Loading logs...'; - loadLogsWithPage(); - } - /** * Load logs with pagination from API */ function loadLogsWithPage() { - console.log(`[Logs] Loading page ${currentPage}, per_page ${perPage}`); + console.log(`[Logs] loadLogsWithPage: page=${currentPage}, per_page=${perPage}, search="${searchFilter.value.trim()}", exclude=${excludePhrases.length}`); + + logsContainer.innerHTML = 'Loading logs...'; fetch('/api/logs', { method: 'POST', @@ -131,6 +132,8 @@ document.addEventListener('DOMContentLoaded', function() { }) .then(r => r.json()) .then(data => { + console.log('[Logs] API Response:', data); + if (data.success) { allLoadedLogs = data.logs; loadedSpan.textContent = data.loaded_count; @@ -144,62 +147,21 @@ document.addEventListener('DOMContentLoaded', function() { renderLogs(data.logs); + // Update button states prevBtn.disabled = currentPage === 1; nextBtn.disabled = !data.has_more; - console.log(`[Logs] Page ${data.page}/${totalPages}, ${data.logs.length} logs`, flush=true); + console.log(`[Logs] Updated: page ${data.page}/${totalPages}, has_more=${data.has_more}, prev_disabled=${prevBtn.disabled}, next_disabled=${nextBtn.disabled}`); } else { showError(data.error); } }) .catch(e => { - console.error('Error:', e); - showError('Failed to load logs'); + console.error('[Logs] Error:', e); + showError('Failed to load logs: ' + e.message); }); } - /** - * Get filtered logs (for local filtering) - */ - function getFilteredLogs() { - let filtered = allLoadedLogs; - - // Apply search filter - if (searchFilter.value.trim()) { - const query = searchFilter.value.toLowerCase(); - filtered = filtered.filter(log => { - const text = `${log.timestamp} ${log.ip_address} ${log.http_method} ${log.requested_url} ${log.frontend} ${log.backend}`.toLowerCase(); - return text.includes(query); - }); - } - - // Apply exclude phrases - if (excludePhrases.length > 0) { - filtered = filtered.filter(log => { - const text = `${log.timestamp} ${log.ip_address} ${log.message}`; - return !excludePhrases.some(phrase => text.includes(phrase)); - }); - } - - return filtered; - } - - /** - * Apply local filters only - */ - function applyFilters() { - const filtered = getFilteredLogs(); - renderLogs(filtered); - - const totalPages = Math.ceil(filtered.length / perPage) || 1; - totalPagesSpan.textContent = totalPages; - currentPageSpan.textContent = currentPage; - matchSpan.textContent = filtered.length; - - prevBtn.disabled = currentPage === 1; - nextBtn.disabled = (currentPage * perPage) >= filtered.length; - } - /** * Render logs as table rows */ @@ -279,6 +241,7 @@ document.addEventListener('DOMContentLoaded', function() { * Remove exclude phrase */ window.removeExcludePhrase = function(idx) { + console.log(`[Logs] Remove exclude phrase at index ${idx}`); excludePhrases.splice(idx, 1); updateExcludeUI(); currentPage = 1; @@ -300,5 +263,7 @@ document.addEventListener('DOMContentLoaded', function() { return (text || '').replace(/[&<>"']/g, m => map[m]); } - loadLogs(); + // Initial load + console.log('[Logs] Initial load'); + loadLogsWithPage(); });