/** * Analytics Module JavaScript * Dashboard functionality, AI chat, time range, and chart controls */ // Time range management let currentTimeRange = "24h"; function updateTimeRange(range) { currentTimeRange = range; refreshDashboard(); } function refreshDashboard() { // Trigger all HTMX elements to refresh document.querySelectorAll("[hx-get]").forEach((el) => { htmx.trigger(el, "load"); }); } // Analytics chat functionality function askAnalytics(question) { document.getElementById("analyticsQuery").value = question; sendAnalyticsQuery(); } async function sendAnalyticsQuery() { const input = document.getElementById("analyticsQuery"); const query = input.value.trim(); if (!query) return; const messagesContainer = document.getElementById("analyticsChatMessages"); // Add user message const userMessage = document.createElement("div"); userMessage.className = "chat-message user"; userMessage.innerHTML = `
`; messagesContainer.appendChild(userMessage); // Clear input input.value = ""; // Scroll to bottom messagesContainer.scrollTop = messagesContainer.scrollHeight; // Add loading indicator const loadingMessage = document.createElement("div"); loadingMessage.className = "chat-message assistant"; loadingMessage.id = "loading-message"; loadingMessage.innerHTML = ` `; messagesContainer.appendChild(loadingMessage); messagesContainer.scrollTop = messagesContainer.scrollHeight; try { const response = await fetch("/api/analytics/query", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ query: query, timeRange: currentTimeRange, }), }); const data = await response.json(); // Remove loading message document.getElementById("loading-message")?.remove(); // Add assistant response const assistantMessage = document.createElement("div"); assistantMessage.className = "chat-message assistant"; assistantMessage.innerHTML = ` `; messagesContainer.appendChild(assistantMessage); messagesContainer.scrollTop = messagesContainer.scrollHeight; } catch (error) { document.getElementById("loading-message")?.remove(); const errorMessage = document.createElement("div"); errorMessage.className = "chat-message assistant"; errorMessage.innerHTML = ` `; messagesContainer.appendChild(errorMessage); } } function formatAnalyticsResponse(data) { if (data.error) { return `${escapeHtml(data.error)}
`; } let html = ""; if (data.answer) { html += `${escapeHtml(data.answer)}
`; } if (data.metrics && data.metrics.length > 0) { html += '${escapeHtml(data.insight)}
`; } return html || "No data available for that query.
"; } function escapeHtml(text) { const div = document.createElement("div"); div.textContent = text; return div.innerHTML; } // Chart type switching document.querySelectorAll(".chart-btn").forEach((btn) => { btn.addEventListener("click", function () { const chart = this.dataset.chart; const type = this.dataset.type; // Update active state this.parentElement .querySelectorAll(".chart-btn") .forEach((b) => b.classList.remove("active")); this.classList.add("active"); // Could trigger chart re-render here console.log(`Switching ${chart} chart to ${type}`); }); }); // Initialize document.addEventListener("DOMContentLoaded", () => { console.log("Analytics Dashboard initialized"); });