// ========================================== // HOME VIEW - Dashboard Homepage // ========================================== function renderDashboard() { // Show stats grid and search (may be hidden by MCP view) showStatsAndSearch(); updateStats(); updateBadges(); updateCarousel(); renderSessions(); document.getElementById('generatedAt').textContent = workflowData.generatedAt || new Date().toISOString(); } function showStatsAndSearch() { const statsGrid = document.getElementById('statsGrid'); const searchInput = document.getElementById('searchInput'); if (statsGrid) statsGrid.style.display = ''; if (searchInput) searchInput.parentElement.style.display = ''; } function hideStatsAndCarousel() { const statsGrid = document.getElementById('statsGrid'); const searchInput = document.getElementById('searchInput'); if (statsGrid) statsGrid.style.display = 'none'; if (searchInput) searchInput.parentElement.style.display = 'none'; } function updateStats() { const stats = workflowData.statistics || {}; document.getElementById('statTotalSessions').textContent = stats.totalSessions || 0; document.getElementById('statActiveSessions').textContent = stats.activeSessions || 0; document.getElementById('statTotalTasks').textContent = stats.totalTasks || 0; document.getElementById('statCompletedTasks').textContent = stats.completedTasks || 0; } function updateBadges() { const active = workflowData.activeSessions || []; const archived = workflowData.archivedSessions || []; document.getElementById('badgeAll').textContent = active.length + archived.length; document.getElementById('badgeActive').textContent = active.length; document.getElementById('badgeArchived').textContent = archived.length; // Lite Tasks badges const liteTasks = workflowData.liteTasks || {}; document.getElementById('badgeLitePlan').textContent = liteTasks.litePlan?.length || 0; document.getElementById('badgeLiteFix').textContent = liteTasks.liteFix?.length || 0; // MCP badge - load async if needed if (typeof loadMcpConfig === 'function') { loadMcpConfig().then(() => { if (typeof updateMcpBadge === 'function') { updateMcpBadge(); } }).catch(e => console.error('MCP badge update failed:', e)); } } function renderSessions() { const container = document.getElementById('mainContent'); let sessions = []; if (currentFilter === 'all' || currentFilter === 'active') { sessions = sessions.concat((workflowData.activeSessions || []).map(s => ({ ...s, _isActive: true }))); } if (currentFilter === 'all' || currentFilter === 'archived') { sessions = sessions.concat((workflowData.archivedSessions || []).map(s => ({ ...s, _isActive: false }))); } if (sessions.length === 0) { container.innerHTML = `
No Sessions Found
No workflow sessions match your current filter.
`; if (typeof lucide !== 'undefined') lucide.createIcons(); return; } container.innerHTML = `
${sessions.map(session => renderSessionCard(session)).join('')}
`; // Initialize Lucide icons after rendering if (typeof lucide !== 'undefined') lucide.createIcons(); } function renderSessionCard(session) { const tasks = session.tasks || []; const taskCount = session.taskCount || tasks.length; const completed = tasks.filter(t => t.status === 'completed').length; const progress = taskCount > 0 ? Math.round((completed / taskCount) * 100) : 0; // Use _isActive flag set during rendering, default to true const isActive = session._isActive !== false; const date = session.created_at; // Get session type badge const sessionType = session.type || 'workflow'; const typeBadge = sessionType !== 'workflow' ? `${sessionType}` : ''; // Store session data for modal const sessionKey = `session-${session.session_id}`.replace(/[^a-zA-Z0-9-]/g, '-'); sessionDataStore[sessionKey] = session; // Special rendering for review sessions if (sessionType === 'review') { return renderReviewSessionCard(session, sessionKey, typeBadge, isActive, date); } return `
${escapeHtml(session.session_id || 'Unknown')}
${typeBadge} ${isActive ? 'ACTIVE' : 'ARCHIVED'}
${formatDate(date)} ${taskCount} tasks
${taskCount > 0 ? `
Progress
${completed}/${taskCount} (${progress}%)
` : ''}
`; } // Special card rendering for review sessions function renderReviewSessionCard(session, sessionKey, typeBadge, isActive, date) { // Calculate findings stats from reviewDimensions const dimensions = session.reviewDimensions || []; let totalFindings = 0; let criticalCount = 0; let highCount = 0; let mediumCount = 0; let lowCount = 0; dimensions.forEach(dim => { const findings = dim.findings || []; totalFindings += findings.length; criticalCount += findings.filter(f => f.severity === 'critical').length; highCount += findings.filter(f => f.severity === 'high').length; mediumCount += findings.filter(f => f.severity === 'medium').length; lowCount += findings.filter(f => f.severity === 'low').length; }); return `
${escapeHtml(session.session_id || 'Unknown')}
${typeBadge} ${isActive ? 'ACTIVE' : 'ARCHIVED'}
${formatDate(date)} ${totalFindings} findings
${totalFindings > 0 ? `
${criticalCount > 0 ? ` ${criticalCount}` : ''} ${highCount > 0 ? ` ${highCount}` : ''} ${mediumCount > 0 ? ` ${mediumCount}` : ''} ${lowCount > 0 ? ` ${lowCount}` : ''}
${dimensions.length} dimensions
` : ''}
`; }