Files
timmy-config/wizards/allegro-primus/dashboard/static/js/dashboard.js
2026-03-31 20:02:01 +00:00

258 lines
6.9 KiB
JavaScript

/**
* Allegro-Primus Dashboard JavaScript
* Handles real-time updates, charts, and interactivity
*/
// Auto-refresh configuration
const AUTO_REFRESH_INTERVAL = 30000; // 30 seconds
let refreshTimer = null;
// Initialize dashboard
document.addEventListener('DOMContentLoaded', function() {
initDashboard();
startAutoRefresh();
initCharts();
});
function initDashboard() {
// Add click handlers for table rows
document.querySelectorAll('.data-table tbody tr').forEach(row => {
row.style.cursor = 'pointer';
row.addEventListener('click', function() {
this.classList.toggle('selected');
});
});
// Initialize tooltips if needed
initTooltips();
}
function initTooltips() {
// Simple tooltip implementation
document.querySelectorAll('[title]').forEach(el => {
el.addEventListener('mouseenter', showTooltip);
el.addEventListener('mouseleave', hideTooltip);
});
}
function showTooltip(e) {
const tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.textContent = e.target.getAttribute('title');
document.body.appendChild(tooltip);
const rect = e.target.getBoundingClientRect();
tooltip.style.left = rect.left + 'px';
tooltip.style.top = (rect.bottom + 5) + 'px';
}
function hideTooltip() {
document.querySelectorAll('.tooltip').forEach(t => t.remove());
}
function initCharts() {
// Charts are initialized in individual templates
// This is for any global chart configuration
Chart.defaults.color = '#94a3b8';
Chart.defaults.borderColor = '#334155';
}
// Auto-refresh functionality
function startAutoRefresh() {
refreshTimer = setInterval(refreshData, AUTO_REFRESH_INTERVAL);
}
function stopAutoRefresh() {
if (refreshTimer) {
clearInterval(refreshTimer);
refreshTimer = null;
}
}
async function refreshData() {
try {
// Refresh metrics
const metricsResponse = await fetch('/api/metrics');
if (metricsResponse.ok) {
const data = await metricsResponse.json();
updateMetricsDisplay(data.current);
}
// Refresh status
const statusResponse = await fetch('/api/status');
if (statusResponse.ok) {
const status = await statusResponse.json();
updateStatusDisplay(status);
}
} catch (error) {
console.error('Error refreshing data:', error);
}
}
function updateMetricsDisplay(metrics) {
// Update metric cards if they exist
const successRateEl = document.querySelector('.metric-card.success .metric-value');
if (successRateEl) {
successRateEl.textContent = (metrics.success_rate * 100).toFixed(1) + '%';
}
}
function updateStatusDisplay(status) {
// Update status indicators
console.log('Status updated:', status);
}
// API helper functions
const API = {
async getStatus() {
const response = await fetch('/api/status');
return response.json();
},
async getMetrics() {
const response = await fetch('/api/metrics');
return response.json();
},
async getJournal(limit = 50, offset = 0) {
const response = await fetch(`/api/journal?limit=${limit}&offset=${offset}`);
return response.json();
},
async getIssues(state = 'all') {
const response = await fetch(`/api/issues?state=${state}`);
return response.json();
},
async getKnowledge() {
const response = await fetch('/api/knowledge');
return response.json();
},
async healthCheck() {
const response = await fetch('/api/health');
return response.json();
}
};
// Export data functionality
function exportData(format) {
window.location.href = `/export/${format}`;
}
// Search functionality for journal
function searchJournal(query) {
const rows = document.querySelectorAll('.journal-table tbody tr');
rows.forEach(row => {
const text = row.textContent.toLowerCase();
row.style.display = text.includes(query.toLowerCase()) ? '' : 'none';
});
}
// Filter functionality
function filterByStatus(status) {
const rows = document.querySelectorAll('.journal-table tbody tr');
rows.forEach(row => {
const rowStatus = row.querySelector('.badge');
if (status === 'all' || (rowStatus && rowStatus.classList.contains(status))) {
row.style.display = '';
} else {
row.style.display = 'none';
}
});
}
// Modal functionality
function showModal(content) {
const modal = document.getElementById('entryModal');
const modalContent = document.getElementById('modalContent');
if (modal && modalContent) {
modalContent.innerHTML = content;
modal.style.display = 'block';
}
}
function hideModal() {
const modal = document.getElementById('entryModal');
if (modal) {
modal.style.display = 'none';
}
}
// Close modal when clicking outside
document.addEventListener('click', function(e) {
const modal = document.getElementById('entryModal');
if (e.target === modal) {
hideModal();
}
});
// Keyboard shortcuts
document.addEventListener('keydown', function(e) {
// ESC to close modal
if (e.key === 'Escape') {
hideModal();
}
// R to refresh
if (e.key === 'r' && !e.ctrlKey && !e.metaKey) {
refreshData();
}
});
// Notification system
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.className = `notification notification-${type}`;
notification.innerHTML = `
<i class="fas fa-${type === 'success' ? 'check' : type === 'error' ? 'exclamation' : 'info'}-circle"></i>
<span>${message}</span>
`;
document.body.appendChild(notification);
setTimeout(() => {
notification.classList.add('show');
}, 10);
setTimeout(() => {
notification.classList.remove('show');
setTimeout(() => notification.remove(), 300);
}, 3000);
}
// Utility functions
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleString();
}
function formatDuration(ms) {
if (ms < 1000) return ms + 'ms';
if (ms < 60000) return (ms / 1000).toFixed(1) + 's';
return (ms / 60000).toFixed(1) + 'm';
}
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Performance monitoring
function measurePerformance() {
const perfData = performance.getEntriesByType('navigation')[0];
console.log('Page load time:', perfData.loadEventEnd - perfData.loadEventStart, 'ms');
}
// Log dashboard load
console.log('🚀 Allegro-Primus Dashboard loaded');
console.log('Press R to refresh data');