update
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import { Content } from '../../components/layout/Content';
|
||||
import { TPattern } from '../../components/common/TPattern';
|
||||
import { getSystemStats, getSystemConfig, type SystemStats, type SystemConfig } from '../../api/status';
|
||||
import { getDocumentList, type DocInfo } from '../../api/docs';
|
||||
|
||||
const StatsCard = ({ label, value, accent = false }: {
|
||||
label: string;
|
||||
value: number;
|
||||
accent?: boolean;
|
||||
}) => {
|
||||
const { theme, isDark } = useTheme();
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
padding: 20,
|
||||
background: theme.bgCard,
|
||||
borderRadius: 12,
|
||||
border: `1px solid ${accent ? theme.accent : theme.border}`,
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
boxShadow: !isDark ? '0 2px 8px rgba(226,0,116,0.06)' : 'none',
|
||||
}}>
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 3,
|
||||
background: theme.gradientAccent,
|
||||
}} />
|
||||
<div className="mono" style={{ fontSize: 11, color: theme.text3, marginBottom: 8, letterSpacing: '1px' }}>{label}</div>
|
||||
<div className="mono" style={{ fontSize: 32, fontWeight: 700, color: accent ? theme.accent : theme.text }}>{value}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const StatusPage: React.FC = () => {
|
||||
const { theme, isDark } = useTheme();
|
||||
const [stats, setStats] = useState<SystemStats>({ docs: 0, chunks: 0, vectors: 0, segments: 0 });
|
||||
const [config, setConfig] = useState<SystemConfig | null>(null);
|
||||
const [docs, setDocs] = useState<DocInfo[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const loadData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const [statsRes, configRes, docsRes] = await Promise.all([
|
||||
getSystemStats(),
|
||||
getSystemConfig(),
|
||||
getDocumentList(),
|
||||
]);
|
||||
setStats(statsRes);
|
||||
setConfig(configRes);
|
||||
setDocs(docsRes.docs);
|
||||
} catch (error) {
|
||||
console.error('Failed to load status data:', error);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
// 计算总chunks
|
||||
const totalChunks = docs.reduce((sum, d) => sum + d.chunks, 0);
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<TPattern />
|
||||
{/* System Stats */}
|
||||
<section style={{ marginBottom: 48 }}>
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(4, 1fr)',
|
||||
gap: 16,
|
||||
}}>
|
||||
<StatsCard label="DOCUMENTS" value={stats.docs} />
|
||||
<StatsCard label="CHUNKS" value={stats.chunks} />
|
||||
<StatsCard label="DIMENSIONS" value={config?.embedding.dimension || 1536} />
|
||||
<StatsCard label="CLAUSES" value={stats.vectors} accent />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Configuration */}
|
||||
<section style={{ marginBottom: 48 }}>
|
||||
<h2 style={{
|
||||
fontSize: 14,
|
||||
fontWeight: 600,
|
||||
color: theme.accent,
|
||||
marginBottom: 20,
|
||||
letterSpacing: '1px',
|
||||
}}>SYSTEM CONFIGURATION</h2>
|
||||
|
||||
{/* ChromaDB Config */}
|
||||
<div style={{ marginBottom: 20 }}>
|
||||
<div className="mono" style={{ fontSize: 11, color: theme.text3, marginBottom: 12, letterSpacing: '1px' }}>VECTOR DATABASE</div>
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr 1fr',
|
||||
gap: 12,
|
||||
}}>
|
||||
{[
|
||||
['Vector DB', 'Milvus'],
|
||||
['Host', config?.milvus.host || 'localhost'],
|
||||
['Port', String(config?.milvus.port || 19530)],
|
||||
].map(([k, v]) => (
|
||||
<div key={k} style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
background: theme.bgCard,
|
||||
borderRadius: 10,
|
||||
border: `1px solid ${theme.border}`,
|
||||
boxShadow: !isDark ? '0 2px 8px rgba(226,0,116,0.04)' : 'none',
|
||||
}}>
|
||||
<span className="mono" style={{ fontSize: 12, color: theme.text3 }}>{k}</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 500 }}>{v}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* LLM Config */}
|
||||
<div style={{ marginBottom: 20 }}>
|
||||
<div className="mono" style={{ fontSize: 11, color: theme.text3, marginBottom: 12, letterSpacing: '1px' }}>LLM CONFIGURATION</div>
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr',
|
||||
gap: 12,
|
||||
}}>
|
||||
{[
|
||||
['LLM Model', config?.llm.model || 'qwen-max'],
|
||||
['Embedding Model', config?.embedding.model || 'text-embedding-v3'],
|
||||
['Embedding Dim', String(config?.embedding.dimension || 1536)],
|
||||
['Temperature', '0.1'],
|
||||
].map(([k, v]) => (
|
||||
<div key={k} style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
background: theme.bgCard,
|
||||
borderRadius: 10,
|
||||
border: `1px solid ${theme.border}`,
|
||||
boxShadow: !isDark ? '0 2px 8px rgba(226,0,116,0.04)' : 'none',
|
||||
}}>
|
||||
<span className="mono" style={{ fontSize: 12, color: theme.text3 }}>{k}</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 500 }}>{v}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Retrieval Config */}
|
||||
<div style={{ marginBottom: 20 }}>
|
||||
<div className="mono" style={{ fontSize: 11, color: theme.text3, marginBottom: 12, letterSpacing: '1px' }}>RETRIEVAL CONFIGURATION (HYBRID)</div>
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr 1fr',
|
||||
gap: 12,
|
||||
}}>
|
||||
{[
|
||||
['Vector Top-K', String(config?.retrieval.vector_top_k || 10)],
|
||||
['BM25 Top-K', '10'],
|
||||
['Final Top-K', String(config?.retrieval.final_top_k || 5)],
|
||||
].map(([k, v]) => (
|
||||
<div key={k} style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
background: theme.bgCard,
|
||||
borderRadius: 10,
|
||||
border: `1px solid ${theme.border}`,
|
||||
boxShadow: !isDark ? '0 2px 8px rgba(226,0,116,0.04)' : 'none',
|
||||
}}>
|
||||
<span className="mono" style={{ fontSize: 12, color: theme.text3 }}>{k}</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 500 }}>{v}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Chunk Config */}
|
||||
<div>
|
||||
<div className="mono" style={{ fontSize: 11, color: theme.text3, marginBottom: 12, letterSpacing: '1px' }}>CHUNK CONFIGURATION</div>
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr',
|
||||
gap: 12,
|
||||
}}>
|
||||
{[
|
||||
['Chunk Size', '800'],
|
||||
['Chunk Overlap', '100'],
|
||||
].map(([k, v]) => (
|
||||
<div key={k} style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
background: theme.bgCard,
|
||||
borderRadius: 10,
|
||||
border: `1px solid ${theme.border}`,
|
||||
boxShadow: !isDark ? '0 2px 8px rgba(226,0,116,0.04)' : 'none',
|
||||
}}>
|
||||
<span className="mono" style={{ fontSize: 12, color: theme.text3 }}>{k}</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 500 }}>{v}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Indexed Docs Overview */}
|
||||
<section>
|
||||
<h2 style={{
|
||||
fontSize: 14,
|
||||
fontWeight: 600,
|
||||
color: theme.accent,
|
||||
marginBottom: 20,
|
||||
letterSpacing: '1px',
|
||||
}}>DOCUMENT INDEX</h2>
|
||||
{docs.map(d => (
|
||||
<div key={d.id} style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: 16,
|
||||
background: theme.bgCard,
|
||||
borderRadius: 10,
|
||||
marginBottom: 10,
|
||||
border: `1px solid ${theme.border}`,
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<span style={{ fontSize: 14 }}>{d.name}</span>
|
||||
<span className="mono" style={{ fontSize: 11, color: theme.text3 }}>{(d.chunks * 8 / 1024).toFixed(1)}MB</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
<span className="mono" style={{ fontSize: 12, color: theme.text2 }}>{d.chunks} chunks</span>
|
||||
<div style={{
|
||||
padding: '4px 12px',
|
||||
background: theme.green,
|
||||
borderRadius: 6,
|
||||
}}>
|
||||
<span className="mono" style={{ fontSize: 10, fontWeight: 600, color: '#fff' }}>INDEXED</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
</Content>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { StatusPage } from './StatusPage';
|
||||
Reference in New Issue
Block a user