// K8s Agent Dashboard - Frontend JavaScript const API_BASE = '/api'; // State let currentView = 'status'; // Initialize document.addEventListener('DOMContentLoaded', () => { setupNavigation(); loadAllData(); // Refresh data every 30 seconds setInterval(loadAllData, 30000); }); // Navigation function setupNavigation() { document.querySelectorAll('.nav-btn').forEach(btn => { btn.addEventListener('click', () => { const view = btn.dataset.view; switchView(view); }); }); } function switchView(view) { currentView = view; // Update nav buttons document.querySelectorAll('.nav-btn').forEach(btn => { btn.classList.toggle('active', btn.dataset.view === view); }); // Update views document.querySelectorAll('.view').forEach(v => { v.classList.toggle('active', v.id === `${view}-view`); }); } // Data Loading async function loadAllData() { try { await Promise.all([ loadClusterStatus(), loadPendingActions(), loadHistory(), loadWorkflows() ]); updateLastUpdate(); } catch (error) { console.error('Error loading data:', error); } } async function loadClusterStatus() { try { const response = await fetch(`${API_BASE}/status`); const data = await response.json(); renderClusterStatus(data); } catch (error) { console.error('Error loading status:', error); } } async function loadPendingActions() { try { const response = await fetch(`${API_BASE}/pending`); const data = await response.json(); renderPendingActions(data.actions || []); document.getElementById('pending-count').textContent = data.count || 0; } catch (error) { console.error('Error loading pending:', error); } } async function loadHistory() { try { const response = await fetch(`${API_BASE}/history?limit=20`); const data = await response.json(); renderHistory(data.history || []); } catch (error) { console.error('Error loading history:', error); } } async function loadWorkflows() { try { const response = await fetch(`${API_BASE}/workflows`); const data = await response.json(); renderWorkflows(data.workflows || []); } catch (error) { console.error('Error loading workflows:', error); } } // Rendering function renderClusterStatus(status) { // Update health indicator const healthEl = document.getElementById('cluster-health'); const indicator = healthEl.querySelector('.health-indicator'); const text = healthEl.querySelector('.health-text'); const health = (status.health || 'Unknown').toLowerCase(); indicator.className = `health-indicator ${health}`; text.textContent = status.health || 'Unknown'; // Render nodes const nodesBody = document.querySelector('#nodes-table tbody'); if (status.nodes && status.nodes.length > 0) { nodesBody.innerHTML = status.nodes.map(node => `
No active alerts
'; } // Render apps const appsBody = document.querySelector('#apps-table tbody'); if (status.apps && status.apps.length > 0) { appsBody.innerHTML = status.apps.map(app => `${app.revision.substring(0, 7)}No pending actions
'; return; } list.innerHTML = actions.map(action => `No workflows defined
'; return; } list.innerHTML = workflows.map(wf => `${wf.description}