From cadd965796b0c0a1e00bbed3e8d7f7c42feb3e80 Mon Sep 17 00:00:00 2001 From: anthrodjear Date: Fri, 8 May 2026 08:23:21 +0300 Subject: [PATCH] refactor(research): replace hardcoded data with TanStack Query API integration --- .../agent/research/research-page.tsx | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/web/frontend/src/components/agent/research/research-page.tsx b/web/frontend/src/components/agent/research/research-page.tsx index be90be90d..6441aaf39 100644 --- a/web/frontend/src/components/agent/research/research-page.tsx +++ b/web/frontend/src/components/agent/research/research-page.tsx @@ -1,74 +1,49 @@ "use client" import { useState } from "react" +import { useQuery } from "@tanstack/react-query" import { IconBook, IconDatabase, IconCircleCheck, IconSparkles, IconShield, IconActivity, IconCpu, IconFileText, IconSettings } from "@tabler/icons-react" import { ResearchAgents } from "./research-agents" import { ResearchGraph } from "./research-graph" import { ResearchConfig } from "./research-config" import { ResearchReports } from "./research-reports" import { Badge } from "@/components/ui/badge" +import { listResearchAgents, listResearchGraph, listResearchReports, ResearchAgent, ResearchNode, ResearchReport } from "@/api/research" -interface ResearchAgent { - id: string - name: string - icon: React.ComponentType<{ className?: string }> - active: boolean - progress: number - ram: string +const agentIcons: Record> = { + literature: IconBook, + extractor: IconDatabase, + validator: IconCircleCheck, + synthesizer: IconSparkles, } -interface ResearchReport { - id: string - title: string - status: "in-progress" | "complete" - timestamp: string - pages?: number - words?: number +function mapAgentIcon(type: string): React.ComponentType<{ className?: string }> { + return agentIcons[type] || IconBook } -interface ResearchNode { - name: string - abbr: string - x: number - y: number -} - -const defaultAgents: ResearchAgent[] = [ - { id: "literature", name: "Literature Analyzer", icon: IconBook, active: true, progress: 94, ram: "2.4GB" }, - { id: "extractor", name: "Data Extractor", icon: IconDatabase, active: true, progress: 87, ram: "1.8GB" }, - { id: "validator", name: "Fact Validator", icon: IconCircleCheck, active: true, progress: 76, ram: "1.2GB" }, - { id: "synthesizer", name: "Synthesizer", icon: IconSparkles, active: false, progress: 65, ram: "0.9GB" }, -] - -const defaultReports: ResearchReport[] = [ - { id: "1", title: "AI trends 2026", status: "in-progress", timestamp: "2 min ago", pages: 24, words: 7200 }, - { id: "2", title: "Quantum computing", status: "complete", timestamp: "1 hour ago", pages: 45, words: 13500 }, -] - -const defaultNodes: ResearchNode[] = [ - { name: "Neural Networks", abbr: "NN", x: 150, y: 80 }, - { name: "Transformers", abbr: "TR", x: 150, y: 120 }, - { name: "LLM Optimization", abbr: "LO", x: 150, y: 160 }, - { name: "Edge Computing", abbr: "EC", x: 150, y: 210 }, - { name: "Multi-Agent Systems", abbr: "MA", x: 150, y: 260 }, - { name: "Vision Models", abbr: "VM", x: 650, y: 100 }, - { name: "RAG Systems", abbr: "RA", x: 650, y: 200 }, - { name: "Knowledge Graphs", abbr: "KG", x: 400, y: 150 }, - { name: "Agent Architecture", abbr: "AA", x: 400, y: 180 }, - { name: "Fine-tuning Methods", abbr: "FT", x: 400, y: 250 }, -] - export function ResearchPage() { - const [agents, setAgents] = useState(defaultAgents) const [researchType, setResearchType] = useState("1.5") const [depth, setDepth] = useState("1.5") const [restrictToGraph, setRestrictToGraph] = useState(false) const [selectedNodes, setSelectedNodes] = useState>(new Set()) + const { data: agents = [], isLoading: agentsLoading, error: agentsError } = useQuery({ + queryKey: ["researchAgents"], + queryFn: listResearchAgents, + }) + + const { data: nodes = [], isLoading: nodesLoading, error: nodesError } = useQuery({ + queryKey: ["researchGraph"], + queryFn: listResearchGraph, + }) + + const { data: reports = [], isLoading: reportsLoading, error: reportsError } = useQuery({ + queryKey: ["researchReports"], + queryFn: listResearchReports, + }) + const handleToggleAgent = (id: string) => { - setAgents(agents.map(agent => - agent.id === id ? { ...agent, active: !agent.active } : agent - )) + console.log("Toggle agent:", id) } const activeAgents = agents.filter(a => a.active) @@ -76,6 +51,31 @@ export function ResearchPage() { ? Math.round(activeAgents.reduce((sum, a) => sum + a.progress, 0) / activeAgents.length) : 0 + const completedReports = reports.filter(r => r.status === "complete") + + const isLoading = agentsLoading || nodesLoading || reportsLoading + const hasError = agentsError || nodesError || reportsError + + if (isLoading) { + return ( +
+
+
Loading research data...
+
+
+ ) + } + + if (hasError) { + return ( +
+
+
Failed to load research data
+
+
+ ) + } + return (
{/* Ghost Background Typography */} @@ -116,7 +116,7 @@ export function ResearchPage() {
Reports: - {defaultReports.filter(r => r.status === "complete").length} + {completedReports.length}
@@ -135,7 +135,7 @@ export function ResearchPage() { {/* Center Column - Graph */}
{ setSelectedNodes(prev => { @@ -162,7 +162,7 @@ export function ResearchPage() { setRestrictToGraph={setRestrictToGraph} />
@@ -173,7 +173,7 @@ export function ResearchPage() {
PicoClaw Research Engine v2.4.1 | - Nodes: {defaultNodes.length} + Nodes: {nodes.length} | Agents: {activeAgents.length} active