auto-sync: 2026-05-17 06:15:50
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
// 全局监控页面
|
||||
|
||||
import React from 'react';
|
||||
import { useDaemonStatus } from '../hooks/useApi';
|
||||
import { useProjects } from '../hooks/useApi';
|
||||
|
||||
export function Monitor() {
|
||||
const { status, refresh: refreshStatus } = useDaemonStatus();
|
||||
const { projects, loading, refresh: refreshProjects } = useProjects();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
|
||||
<h2 className="page-title">全局监控</h2>
|
||||
<button className="btn" onClick={() => { refreshStatus(); refreshProjects(); }}>
|
||||
刷新
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Daemon 状态 */}
|
||||
<div className="stat-grid">
|
||||
<div className="stat-card">
|
||||
<div className="value">{status?.status === 'running' ? '🟢' : '🔴'}</div>
|
||||
<div className="label">Daemon 状态</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="value">{status?.tick_count ?? '-'}</div>
|
||||
<div className="label">Tick 计数</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="value">{status?.active_projects ?? '-'}</div>
|
||||
<div className="label">活跃项目</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="value">{status?.uptime_seconds ? Math.floor(status.uptime_seconds / 60) + 'm' : '-'}</div>
|
||||
<div className="label">运行时间</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 项目列表 */}
|
||||
<h3 style={{ fontSize: 15, fontWeight: 600, marginBottom: 12 }}>项目列表</h3>
|
||||
{loading ? (
|
||||
<div className="loading">加载中...</div>
|
||||
) : (
|
||||
<div className="card">
|
||||
<div className="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>名称</th>
|
||||
<th>状态</th>
|
||||
<th>创建时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{projects.map(p => (
|
||||
<tr key={p.id}>
|
||||
<td>{p.id.substring(0, 8)}</td>
|
||||
<td>{p.name}</td>
|
||||
<td>
|
||||
<span className={`badge badge-${p.status === 'active' ? 'done' : 'blocked'}`}>
|
||||
{p.status}
|
||||
</span>
|
||||
</td>
|
||||
<td>{p.created_at?.substring(0, 19) ?? '-'}</td>
|
||||
</tr>
|
||||
))}
|
||||
{projects.length === 0 && (
|
||||
<tr><td colSpan={4} style={{ color: 'var(--muted)' }}>暂无项目</td></tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 最近事件 */}
|
||||
<h3 style={{ fontSize: 15, fontWeight: 600, margin: '20px 0 12px' }}>最近事件</h3>
|
||||
<div className="card">
|
||||
<div className="event-log">
|
||||
<p style={{ color: 'var(--muted)' }}>通过 SSE 实时推送事件(连接后显示)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user