import React, { useState, useRef, useEffect } from 'react'; import { useNavigate } from 'react-router'; import { Menu, Search, X } from 'lucide-react'; import { useAppState, type KGNode } from '../../store'; import { api } from '../../api'; import { TYPE_COLORS } from '../../mock-data'; export function Header() { const { sidebarCollapsed, setSidebarCollapsed, health } = useAppState(); const [query, setQuery] = useState(''); const [showSuggestions, setShowSuggestions] = useState(false); const [suggestions, setSuggestions] = useState([]); const navigate = useNavigate(); const inputRef = useRef(null); const timerRef = useRef>(); useEffect(() => { if (query.length >= 2) { clearTimeout(timerRef.current); timerRef.current = setTimeout(async () => { try { const res = await api.searchEntities(query, undefined, 5); setSuggestions(res.items.map(n => ({ id: n.id, name: n.name, type: n.type as KGNode['type'], page: n.page, confidence: n.confidence as KGNode['confidence'], degree: n.degree, centrality: 0, doc_id: n.doc_id, }))); setShowSuggestions(true); } catch { setSuggestions([]); } }, 300); } else { setSuggestions([]); setShowSuggestions(false); } return () => clearTimeout(timerRef.current); }, [query]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (query.trim()) { setShowSuggestions(false); navigate(`/search?q=${encodeURIComponent(query)}`); } }; const allOk = Object.values(health).every(v => v === 'ok'); return (
{/* Left */} GraphRAG Studio {/* Center - Search */}
setQuery(e.target.value)} onFocus={() => query.length >= 3 && setShowSuggestions(true)} onBlur={() => setTimeout(() => setShowSuggestions(false), 200)} placeholder="搜索实体..." className="w-full pl-9 pr-8 py-1.5 rounded-md outline-none" style={{ background: 'var(--bg-s2)', border: '1px solid var(--border-main)', color: 'var(--text-1)', fontSize: 13, }} /> {query && ( )}
{showSuggestions && suggestions.length > 0 && (
{suggestions.map(s => ( ))}
)}
{/* Right */}
API: localhost:8000
); }