aboutsummaryrefslogtreecommitdiffstats
path: root/static/js/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/js/main.js')
-rw-r--r--static/js/main.js164
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