Spaces:
Sleeping
Sleeping
File size: 4,885 Bytes
c2ea5ed |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
import { useState, useEffect, useCallback, useMemo } from "react";
import { useAgentGraph } from "@/context/AgentGraphContext";
interface DashboardStats {
totalTraces: number;
totalAgentGraphs: number;
totalEntities: number;
totalRelations: number;
completedProcessing: number;
processingProgress: number;
systemStatus: "healthy" | "warning" | "error";
}
interface ActivityItem {
id: string;
action: string;
trace: string;
timestamp: string;
status: "success" | "error" | "processing";
}
export function useDashboardData() {
const { state } = useAgentGraph();
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// Calculate stats using useMemo to avoid unnecessary recalculations
const stats = useMemo<DashboardStats>(() => {
const totalTraces = state.traces.length;
const totalAgentGraphs = state.traces.reduce((total, trace) => {
// Count only final knowledge graphs (consistent with sidebar and main content)
const finalKGs =
trace.knowledge_graphs?.filter(
(kg) =>
kg.is_final === true ||
(kg.window_index === null && kg.window_total !== null)
) || [];
return total + finalKGs.length;
}, 0);
const totalEntities = state.traces.reduce((total, trace) => {
const entityCount =
trace.knowledge_graphs?.reduce((kgTotal, kg) => {
return kgTotal + (kg.entity_count || 0);
}, 0) || 0;
return total + entityCount;
}, 0);
const totalRelations = state.traces.reduce((total, trace) => {
const relationCount =
trace.knowledge_graphs?.reduce((kgTotal, kg) => {
return kgTotal + (kg.relation_count || 0);
}, 0) || 0;
return total + relationCount;
}, 0);
const completedProcessing = state.traces.reduce((total, trace) => {
const completedKGs =
trace.knowledge_graphs?.filter((kg) => kg.status === "analyzed") || [];
return total + completedKGs.length;
}, 0);
const processingProgress =
totalAgentGraphs > 0 ? (completedProcessing / totalAgentGraphs) * 100 : 0;
return {
totalTraces,
totalAgentGraphs,
totalEntities,
totalRelations,
completedProcessing,
processingProgress,
systemStatus: "healthy",
};
}, [state.traces]);
// Calculate recent activity using useMemo
const recentActivity = useMemo<ActivityItem[]>(() => {
const activity: ActivityItem[] = [];
// Add recent trace uploads
state.traces.slice(0, 2).forEach((trace) => {
activity.push({
id: `trace-${trace.id}`,
action: "Trace Uploaded",
trace: trace.filename,
timestamp: getRelativeTime(
trace.update_timestamp || trace.upload_timestamp || ""
),
status: "success",
});
});
// Add recent graph generations from traces
const allKnowledgeGraphs = state.traces.flatMap(
(trace) => trace.knowledge_graphs || []
);
allKnowledgeGraphs
.sort((a, b) => {
const dateA = new Date(a.created_at || 0);
const dateB = new Date(b.created_at || 0);
return dateB.getTime() - dateA.getTime();
})
.slice(0, 2)
.forEach((kg, index) => {
activity.push({
id: `kg-${kg.kg_id || kg.id || index}`,
action: "Agent Graph Generated",
trace: kg.filename || "Unknown",
timestamp: getRelativeTime(kg.created_at),
status: kg.status === "analyzed" ? "success" : "processing",
});
});
return activity.slice(0, 5);
}, [state.traces]);
const fetchDashboardData = useCallback(async () => {
try {
setIsLoading(true);
setError(null);
// Data is now calculated via useMemo, so we just need to handle loading state
setIsLoading(false);
} catch (err) {
setError(
err instanceof Error ? err.message : "Failed to load dashboard data"
);
setIsLoading(false);
}
}, []);
useEffect(() => {
fetchDashboardData();
}, [fetchDashboardData]);
return {
stats,
recentActivity,
isLoading,
error,
refresh: fetchDashboardData,
};
}
function getRelativeTime(dateString: string): string {
const date = new Date(dateString);
const now = new Date();
const diffMs = now.getTime() - date.getTime();
// If the date is invalid, return a default
if (isNaN(diffMs)) return "Recently";
const diffMins = Math.floor(diffMs / 60000);
const diffHours = Math.floor(diffMs / 3600000);
const diffDays = Math.floor(diffMs / 86400000);
if (diffMins < 1) return "Just now";
if (diffMins < 60) return `${diffMins} minute${diffMins > 1 ? "s" : ""} ago`;
if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? "s" : ""} ago`;
return `${diffDays} day${diffDays > 1 ? "s" : ""} ago`;
}
|