// n8n-Agent Dashboard JavaScript
// Initialize dashboard when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
initializeDashboard();
});
function initializeDashboard() {
// Initialize navigation
initializeNavigation();
// Initialize chat interface
initializeChat();
// Initialize real-time updates
initializeRealTimeUpdates();
// Initialize workflow management
initializeWorkflows();
// Initialize agent controls
initializeAgents();
// Load initial data
loadDashboardData();
}
// Navigation functionality
function initializeNavigation() {
const navItems = document.querySelectorAll('.nav-item');
const sectionTitle = document.getElementById('section-title');
const sectionSubtitle = document.getElementById('section-subtitle');
const sectionInfo = {
overview: {
title: 'Overview Dashboard',
subtitle: 'Monitor your automation platform'
},
automation: {
title: 'Automation Management',
subtitle: 'Create and manage automated workflows'
},
research: {
title: 'Research Tools',
subtitle: 'AI-powered research and analysis tools'
},
agents: {
title: 'Agent Management',
subtitle: 'Monitor and control your AI agents'
},
workflows: {
title: 'Workflow Management',
subtitle: 'Advanced workflow builder and management'
},
integrations: {
title: 'Integrations',
subtitle: 'Connect with external services and APIs'
}
};
navItems.forEach(item => {
item.addEventListener('click', function(e) {
e.preventDefault();
// Remove active class from all nav items
navItems.forEach(nav => nav.classList.remove('active'));
// Add active class to clicked item
this.classList.add('active');
// Get section to show
const section = this.dataset.section;
// Hide all sections
const sections = document.querySelectorAll('.section-content');
sections.forEach(sec => sec.classList.add('hidden'));
// Show selected section
const targetSection = document.getElementById(section);
if (targetSection) {
targetSection.classList.remove('hidden');
}
// Update header
if (sectionInfo[section]) {
sectionTitle.textContent = sectionInfo[section].title;
sectionSubtitle.textContent = sectionInfo[section].subtitle;
}
});
});
}
// Chat interface functionality
function initializeChat() {
const chatInput = document.querySelector('input[placeholder="Type your message..."]');
const sendButton = document.querySelector('button[aria-label="send"]');
const chatContainer = document.querySelector('.flex-1.overflow-y-auto.p-4.space-y-4');
function sendMessage() {
const message = chatInput.value.trim();
if (message) {
addChatMessage(message, 'user');
chatInput.value = '';
// Simulate agent response
setTimeout(() => {
addChatMessage("Request received and processing...", 'agent');
}, 1000 + Math.random() * 2000);
}
}
function addChatMessage(message, sender) {
const messageDiv = document.createElement('div');
messageDiv.className = 'flex items-start space-x-3 chat-message';
const isUser = sender === 'user';
const avatarBg = isUser ? 'bg-primary-600' : 'bg-green-600';
const avatarIcon = isUser ? 'user' : 'search';
messageDiv.innerHTML = `
${isUser ? 'You' : 'Agent'} ยท now
`;
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
// Re-initialize feather icons
feather.replace();
}
// Event listeners
if (sendButton) {
sendButton.addEventListener('click', sendMessage);
}
if (chatInput) {
chatInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage();
}
});
}
}
// Real-time updates simulation
function initializeRealTimeUpdates() {
// Simulate real-time activity updates
setInterval(() => {
updateActivityFeed();
updateAgentStatus();
}, 30000); // Every 30 seconds
// Simulate progress updates
setInterval(() => {
updateWorkflowProgress();
}, 5000); // Every 5 seconds
}
function updateActivityFeed() {
const timestamp = new Date().toLocaleTimeString();
addChatMessage(`Task completed at ${timestamp}`, 'agent');
// Add to activity feed if it exists
const feedContainer = document.querySelector('.space-y-3');
if (feedContainer && document.getElementById('overview').classList.contains('hidden') === false) {
const activityDiv = document.createElement('div');
activityDiv.className = 'flex items-start space-x-3';
activityDiv.innerHTML = `
${randomActivity}
Just now
`;
// Add to top of feed
feedContainer.insertBefore(activityDiv, feedContainer.firstChild);
// Remove old activities (keep only last 5)
const activities_list = feedContainer.querySelectorAll('.flex.items-start.space-x-3');
if (activities_list.length > 5) {
activities_list[activities_list.length - 1].remove();
}
}
}
function updateAgentStatus() {
const agentCards = document.querySelectorAll('.bg-secondary-900');
agentCards.forEach(card => {
const statusElement = card.querySelector('.text-green-400, .text-yellow-400, .text-secondary-400');
if (statusElement && card.querySelector('h4')?.textContent?.includes('Agent')) {
// Simulate status changes
const statuses = ['Active', 'Processing', 'Idle'];
const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
statusElement.textContent = randomStatus;
// Update status indicator
const indicator = card.querySelector('.w-2.h-2.rounded-full');
if (indicator) {
indicator.className = `w-2 h-2 rounded-full ${
randomStatus === 'Active' ? 'bg-green-500' :
randomStatus === 'Processing' ? 'bg-yellow-500' : 'bg-secondary-500'
}`;
}
}
});
}
function updateWorkflowProgress() {
const progressBars = document.querySelectorAll('[style*="width:"]');
progressBars.forEach(bar => {
const currentWidth = parseInt(bar.style.width);
if (currentWidth < 100 && Math.random() > 0.7) {
const newWidth = Math.min(currentWidth + Math.floor(Math.random() * 5), 100);
bar.style.width = newWidth + '%';
// Update percentage text
const percentageText = bar.parentElement.parentElement.querySelector('.text-xs');
if (percentageText) {
percentageText.textContent = newWidth + '%';
}
}
});
}
// Workflow management
function initializeWorkflows() {
// Add workflow controls
const workflowButtons = document.querySelectorAll('button');
workflowButtons.forEach(button => {
button.addEventListener('click', function() {
const buttonText = this.textContent.trim().toLowerCase();
if (buttonText === 'start') {
this.textContent = 'Pause';
this.className = this.className.replace('bg-primary-600 hover:bg-primary-700', 'bg-yellow-600 hover:bg-yellow-700');
showNotification('Workflow started successfully');
} else if (buttonText === 'pause') {
this.textContent = 'Start';
this.className = this.className.replace('bg-yellow-600 hover:bg-yellow-700', 'bg-primary-600 hover:bg-primary-700');
showNotification('Workflow paused');
} else if (buttonText === 'view') {
showNotification('Opening workflow details...');
}
});
});
}
// Agent controls
function initializeAgents() {
// Agent control buttons
const agentButtons = document.querySelectorAll('button');
agentButtons.forEach(button => {
button.addEventListener('click', function() {
const buttonText = this.textContent.trim().toLowerCase();
if (buttonText === 'start') {
this.textContent = 'Pause';
this.className = this.className.replace('bg-primary-600 hover:bg-primary-700', 'bg-yellow-600 hover:bg-yellow-700');
showNotification('Agent started successfully');
} else if (buttonText === 'pause') {
this.textContent = 'Start';
this.className = this.className.replace('bg-yellow-600 hover:bg-yellow-700', 'bg-primary-600 hover:bg-primary-700');
showNotification('Agent paused');
} else if (buttonText === 'configure') {
showNotification('Opening agent configuration...');
}
});
});
}
// Load dashboard data
function loadDashboardData() {
// Simulate loading data
console.log('Loading dashboard data...');
// You could fetch real data here
// fetch('/api/dashboard/data')
// .then(response => response.json())
// .then(data => updateDashboard(data));
}
// Notification system
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.className = `notification ${type}`;
const iconMap = {
success: 'check-circle',
error: 'x-circle',
warning: 'alert-triangle',
info: 'info'
};
const colorMap = {
success: 'text-green-400',
error: 'text-red-400',
warning: 'text-yellow-400',
info: 'text-blue-400'
};
notification.innerHTML = `
`;
document.body.appendChild(notification);
// Auto remove after 5 seconds
setTimeout(() => {
if (notification.parentElement) {
notification.remove();
}
}, 5000);
// Re-initialize feather icons
feather.replace();
}
// Keyboard shortcuts
document.addEventListener('keydown', function(e) {
// Ctrl/Cmd + K for search
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
const searchInput = document.querySelector('input[placeholder*="research" i]');
if (searchInput) {
searchInput.focus();
}
}
// Escape to close notifications
if (e.key === 'Escape') {
const notifications = document.querySelectorAll('.notification');
notifications.forEach(notification => notification.remove());
}
});
// Export functions for testing
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
initializeDashboard,
showNotification,
updateActivityFeed,
updateAgentStatus,
updateWorkflowProgress
};
}