import { useState, useCallback, useRef, useEffect } from 'react'; import { useSearchParams } from 'react-router-dom'; import { IoMdArrowDropdown } from 'react-icons/io'; import { useLanguage } from '../../contexts/LanguageContext'; import { useWorkflows } from '../../hooks/useWorkflows'; import { Workflow } from '../../components/Dashboard/DashboardChat/dashboardChatAreaTypes'; import { useWorkflowManager } from '../../components/Dashboard/DashboardChat/useWorkflowManager'; import styles from './HomeStyles/Dashboard.module.css' import sharedStyles from '../../core/PageManager/pages.module.css'; import DashboardChat from '../../components/Dashboard/DashboardChat/DashboardChat'; import { IoMdClose } from 'react-icons/io'; function Dashboard() { const { t } = useLanguage(); const [searchParams, setSearchParams] = useSearchParams(); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const dropdownRef = useRef(null); // Get workflow ID from URL parameters const workflowIdFromUrl = searchParams.get('workflowId'); const [workflowState, workflowActions] = useWorkflowManager(workflowIdFromUrl); const { workflows, loading: workflowsLoading, error: workflowsError, refetch: refetchWorkflows } = useWorkflows(); const handleWorkflowSelect = useCallback((workflowId: string) => { workflowActions.loadWorkflow(workflowId); setIsDropdownOpen(false); // Clear the URL parameter once workflow is loaded setSearchParams({}); }, [workflowActions, setSearchParams]); const handleResetWorkflow = useCallback(() => { workflowActions.clearWorkflow(); // Clear the URL parameter when resetting setSearchParams({}); }, [workflowActions, setSearchParams]); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setIsDropdownOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); // Listen for workflow updates from other components (like WorkflowsTable) useEffect(() => { const handleWorkflowUpdated = (event: CustomEvent) => { console.log('Dashboard received workflow update event:', event.detail); // Refetch workflows to update the dropdown refetchWorkflows(); }; window.addEventListener('workflowUpdated', handleWorkflowUpdated as EventListener); return () => window.removeEventListener('workflowUpdated', handleWorkflowUpdated as EventListener); }, [refetchWorkflows]); const getWorkflowDisplayName = (workflow: Workflow) => workflow.name || `${workflow.id.substring(0, 8)}...`; const formatWorkflowId = (id: string) => `${id.substring(0, 8)}...`; const displayWorkflowId = workflowState.currentWorkflowId ? `${workflowState.currentWorkflowId.substring(0, 8)}...` : t('dashboard.log.no_workflow'); const getWorkflowStats = () => { if (!workflowState.workflow) return null; const { workflow, messages } = workflowState; const messageCount = messages?.length || 0; const fileCount = messages?.reduce((count, msg) => count + (msg.documents?.length || msg.fileIds?.length || 0), 0) || 0; const totalTokens = (workflow.stats?.tokenCount || 0) + (messages?.reduce((sum, msg) => sum + (msg.stats?.tokenCount || 0), 0) || 0); const totalBytesSent = (workflow.stats?.bytesSent || 0) + (messages?.reduce((sum, msg) => sum + (msg.stats?.bytesSent || 0), 0) || 0); const totalBytesReceived = (workflow.stats?.bytesReceived || 0) + (messages?.reduce((sum, msg) => sum + (msg.stats?.bytesReceived || 0), 0) || 0); const totalErrors = (workflow.stats?.errorCount || 0) + (messages?.reduce((sum, msg) => sum + (msg.stats?.errorCount || 0), 0) || 0); const successfulMessages = messages?.filter(msg => msg.success)?.length || 0; const successRate = messageCount > 0 ? (successfulMessages / messageCount) * 100 : 100; return { status: workflow.status, rounds: workflow.currentRound, startedAt: workflow.startedAt, messageCount, fileCount, tokenCount: totalTokens, bytesSent: totalBytesSent, bytesReceived: totalBytesReceived, successRate: Math.round(successRate), errorCount: totalErrors }; }; const formatBytes = (bytes: number) => { if (bytes === 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; }; const formatDate = (dateValue: string | number) => { if (typeof dateValue === 'number') { // Convert from seconds to milliseconds for Date constructor return new Date(dateValue * 1000).toLocaleString(); } return new Date(dateValue).toLocaleString(); }; const getStatusColor = (status: string) => { switch (status.toLowerCase()) { case 'completed': case 'success': case 'finished': return 'var(--color-success)'; case 'running': case 'processing': case 'started': case 'in_progress': return 'var(--color-warning)'; case 'failed': case 'error': case 'cancelled': return 'var(--color-error)'; case 'pending': case 'queued': case 'waiting': return 'var(--color-text-secondary)'; default: return 'var(--color-text)'; } }; const formatStatus = (status: string) => status.charAt(0).toUpperCase() + status.slice(1).toLowerCase(); const stats = getWorkflowStats(); return (

{t('nav.dashboard')}

{workflowState.currentWorkflowId ? ( <>
{t('dashboard.stats.workflow')} {displayWorkflowId}
{stats && ( <>
{t('dashboard.stats.status')} {formatStatus(stats.status)}
{t('dashboard.stats.rounds')} {stats.rounds}
{t('dashboard.stats.messages')} {stats.messageCount}
{t('dashboard.stats.files')} {stats.fileCount}
{t('dashboard.stats.tokens')} {stats.tokenCount.toLocaleString()}
{t('dashboard.stats.data_sent')} {formatBytes(stats.bytesSent)}
{t('dashboard.stats.data_received')} {formatBytes(stats.bytesReceived)}
{t('dashboard.stats.success_rate')} = 90 ? 'var(--color-success)' : stats.successRate >= 70 ? 'var(--color-warning)' : 'var(--color-error)' }}>{stats.successRate}%
{t('dashboard.stats.errors')} 0 ? styles.statValueError : ''}`}> {stats.errorCount}
{t('dashboard.stats.started')} {formatDate(stats.startedAt)}
)}
) : (
{isDropdownOpen && !workflowsLoading && !workflowsError && (
{t('dashboard.workflow_dropdown.available_workflows')}
{workflows.length === 0 ? (
{t('dashboard.workflow_dropdown.no_workflows')}
) : ( workflows.map((workflow) => ( )) )}
)}
)}
); } export default Dashboard;