diff options
Diffstat (limited to 'static/js/main.js')
-rw-r--r-- | static/js/main.js | 164 |
1 files changed, 138 insertions, 26 deletions
diff --git a/static/js/main.js b/static/js/main.js index 74cd9c7..5460247 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -254,7 +254,7 @@ const chartColors = { memory: '#FDCFF3', system: '#88B7B5', generic: '#88B7B5', - // New colors for application performance metrics + // Colors for application performance metrics appResponse: '#4CAF50', // Green for response time appError: '#F44336', // Red for error rate appRequests: '#2196F3', // Blue for request count @@ -369,8 +369,20 @@ function createMetricCard(container, metricName, definition) { const displayName = definition.label || metricName; const metricCard = document.createElement('div'); metricCard.className = 'metric-card'; - metricCard.innerHTML = `<h5>${displayName}</h5><div class="chart-container"><canvas id="${metricName}Chart"></canvas></div>`; + metricCard.innerHTML = `<h5>${displayName}</h5><div class="chart-container" data-metric="${metricName}" data-label="${displayName}"><canvas id="${metricName}Chart"></canvas></div>`; container.appendChild(metricCard); + + // Add click event for chart expansion + const chartContainer = metricCard.querySelector('.chart-container'); + if (chartContainer && typeof expandChart === 'function') { + chartContainer.addEventListener('click', function() { + const metricAttr = this.getAttribute('data-metric'); + const labelAttr = this.getAttribute('data-label'); + if (metricAttr && labelAttr) { + expandChart(metricAttr, labelAttr); + } + }); + } } function startDataUpdates() { @@ -702,49 +714,149 @@ function initializeMetricsUI() { }); } -// --- Initial Load Logic --- +// --- Initialize everything when DOM is loaded --- document.addEventListener('DOMContentLoaded', function() { - // Start server stats check immediately and then interval + // Start server stats check getServerStats(); setInterval(getServerStats, 30000); - // Style the submit button + // Apply styles to submit button if (submitPasswordBtn) submitPasswordBtn.classList.add('submit-button'); - // Event listeners for authentication + // Set up password input event listener + if (passwordInput) { + passwordInput.addEventListener('keyup', function(event) { + if (event.key === 'Enter') { + submitPasswordBtn.click(); + } + }); + } + + // Set up view metrics button if (viewMetricsBtn) { - viewMetricsBtn.addEventListener('click', () => { - // Authenticate and show metrics - const token = getToken(); - if (token) { - // Try to initialize/show metrics, fetchWithAuth will handle invalid tokens - showMetrics(); + viewMetricsBtn.addEventListener('click', function() { + if (getToken()) { + showMetrics(); } else { openPasswordModal(); } }); } + + // Set up password modal submit button if (submitPasswordBtn) { submitPasswordBtn.addEventListener('click', login); } - if (passwordInput) { - passwordInput.addEventListener('keyup', (event) => { - if (event.key === 'Enter') login(); - }); - } + + // Set up password modal close button if (closeModalBtn) { closeModalBtn.addEventListener('click', closePasswordModal); } - window.addEventListener('click', (event) => { - if (event.target === passwordModal) closePasswordModal(); + + // Close password modal when clicking outside + if (passwordModal) { + passwordModal.addEventListener('click', function(event) { + if (event.target === passwordModal) { + closePasswordModal(); + } + }); + } + + // Check if already authenticated and show metrics if so + if (getToken()) showMetrics(); + + // Observer for metrics section visibility + if (metricsSection) { + const observer = new MutationObserver(handleMetricsVisibilityChange); + observer.observe(metricsSection, { attributes: true, attributeFilter: ['style'] }); + } +}); + +// Chart expansion functionality +const chartModal = document.getElementById('chart-modal'); +const chartModalTitle = document.getElementById('chart-modal-title'); +const closeChartModalBtn = document.querySelector('#chart-modal .close-button'); +const closeChartBtn = document.getElementById('close-chart-modal'); +let expandedChart = null; + +function expandChart(metricName, displayName) { + // Set the modal title + chartModalTitle.textContent = displayName; + + // Show the modal + chartModal.style.display = 'block'; + setTimeout(() => chartModal.classList.add('show'), 10); + + // Create an expanded version of the chart + const expandedChartCanvas = document.getElementById('expandedChart'); + const ctx = expandedChartCanvas.getContext('2d'); + + // If there's already an expanded chart, destroy it first + if (expandedChart) { + expandedChart.destroy(); + } + + // Clone the options and data from the original chart + const originalChart = charts[metricName]; + if (!originalChart) return; + + const chartOptions = JSON.parse(JSON.stringify(originalChart.options)); + // Adjust options for the expanded view + chartOptions.maintainAspectRatio = false; + if (chartOptions.scales && chartOptions.scales.y) { + chartOptions.scales.y.ticks.maxTicksLimit = 10; // More ticks for expanded view + } + + // Create the expanded chart with cloned data + const chartData = { + datasets: originalChart.data.datasets.map(dataset => ({ + ...dataset, + data: [...dataset.data], + pointRadius: 3 // Show points in expanded view + })) + }; + + expandedChart = new Chart(ctx, { + type: 'line', + data: chartData, + options: chartOptions }); +} - // Check token on load - attempt to show metrics if token exists - // initializeMetricsUI() will handle token validation via fetchWithAuth - if (getToken()) { - showMetrics(); - } else { - // Ensure metrics are hidden if no token - hideMetrics(); +// Close modal events +function closeChartModal() { + chartModal.classList.remove('show'); + setTimeout(() => chartModal.style.display = 'none', 300); +} + +// Initialize event listeners when DOM is loaded +document.addEventListener('DOMContentLoaded', function() { + // Chart modal close buttons + if (closeChartModalBtn) { + closeChartModalBtn.addEventListener('click', closeChartModal); + } + + if (closeChartBtn) { + closeChartBtn.addEventListener('click', closeChartModal); + } + + // Close modal when clicking outside of it + if (chartModal) { + chartModal.addEventListener('click', (event) => { + if (event.target === chartModal) { + closeChartModal(); + } + }); } + + // Close modal with Escape key + document.addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + if (chartModal && chartModal.classList.contains('show')) { + closeChartModal(); + } else if (passwordModal && passwordModal.style.display === 'block') { + closePasswordModal(); + } + } + }); });
\ No newline at end of file |