fix cn
All checks were successful
Build and Deploy Log Center / build-and-deploy (push) Successful in 1m20s
All checks were successful
Build and Deploy Log Center / build-and-deploy (push) Successful in 1m20s
This commit is contained in:
parent
61cbcfc4c4
commit
7ee724f8ac
@ -16,7 +16,7 @@ function App() {
|
||||
<div className="logo-icon">
|
||||
<Shield size={16} />
|
||||
</div>
|
||||
Log Center
|
||||
日志中台
|
||||
</div>
|
||||
<nav>
|
||||
<ul className="nav-menu">
|
||||
@ -27,7 +27,7 @@ function App() {
|
||||
end
|
||||
>
|
||||
<LayoutDashboard size={16} />
|
||||
Dashboard
|
||||
仪表盘
|
||||
</NavLink>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
@ -36,7 +36,7 @@ function App() {
|
||||
className={({ isActive }) => `nav-link ${isActive ? 'active' : ''}`}
|
||||
>
|
||||
<Bug size={16} />
|
||||
Bug List
|
||||
缺陷列表
|
||||
</NavLink>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
@ -45,7 +45,7 @@ function App() {
|
||||
className={({ isActive }) => `nav-link ${isActive ? 'active' : ''}`}
|
||||
>
|
||||
<Wrench size={16} />
|
||||
Repair Reports
|
||||
修复报告
|
||||
</NavLink>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@ -3,6 +3,18 @@ import { useParams, Link, useLocation } from 'react-router-dom';
|
||||
import { ArrowLeft, Play, Loader2, FileCode, GitCommit } from 'lucide-react';
|
||||
import { getBugDetail, triggerRepair, type ErrorLog } from '../api';
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
NEW: '新发现',
|
||||
VERIFYING: '验证中',
|
||||
CANNOT_REPRODUCE: '无法复现',
|
||||
PENDING_FIX: '待修复',
|
||||
FIXING: '修复中',
|
||||
FIXED: '已修复',
|
||||
VERIFIED: '已验证',
|
||||
DEPLOYED: '已部署',
|
||||
FIX_FAILED: '修复失败',
|
||||
};
|
||||
|
||||
export default function BugDetail() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const location = useLocation();
|
||||
@ -35,10 +47,10 @@ export default function BugDetail() {
|
||||
try {
|
||||
await triggerRepair(bug.id);
|
||||
setBug({ ...bug, status: 'PENDING_FIX' });
|
||||
setRepairMessage('Repair triggered successfully');
|
||||
setRepairMessage('已成功触发修复');
|
||||
} catch (error) {
|
||||
console.error('Failed to trigger repair:', error);
|
||||
setRepairMessage('Failed to trigger repair');
|
||||
setRepairMessage('触发修复失败');
|
||||
} finally {
|
||||
setRepairing(false);
|
||||
}
|
||||
@ -53,7 +65,7 @@ export default function BugDetail() {
|
||||
}
|
||||
|
||||
if (!bug) {
|
||||
return <div className="loading">Bug not found</div>;
|
||||
return <div className="loading">未找到该缺陷</div>;
|
||||
}
|
||||
|
||||
const canTriggerRepair = ['NEW', 'FIX_FAILED'].includes(bug.status);
|
||||
@ -62,7 +74,7 @@ export default function BugDetail() {
|
||||
<div>
|
||||
<Link to={`/bugs${backSearch ? `?${backSearch}` : ''}`} className="back-link">
|
||||
<ArrowLeft size={14} />
|
||||
Back to Bug List
|
||||
返回缺陷列表
|
||||
</Link>
|
||||
|
||||
<div className="detail-card">
|
||||
@ -72,25 +84,27 @@ export default function BugDetail() {
|
||||
{bug.error_type}: {bug.error_message}
|
||||
</h2>
|
||||
<div className="detail-meta">
|
||||
<span>Project: {bug.project_id}</span>
|
||||
<span>Env: {bug.environment}</span>
|
||||
<span>Level: {bug.level}</span>
|
||||
<span>项目:{bug.project_id}</span>
|
||||
<span>环境:{bug.environment}</span>
|
||||
<span>级别:{bug.level}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span className={`status-badge status-${bug.status}`}>{bug.status}</span>
|
||||
<span className={`status-badge status-${bug.status}`}>
|
||||
{STATUS_LABELS[bug.status] || bug.status}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="detail-section">
|
||||
<div className="detail-section-title">Location</div>
|
||||
<div className="detail-section-title">文件位置</div>
|
||||
<div className="detail-section-value">
|
||||
<FileCode size={14} style={{ display: 'inline', verticalAlign: 'middle', marginRight: '6px' }} />
|
||||
{bug.file_path} : Line {bug.line_number}
|
||||
{bug.file_path} : 第 {bug.line_number} 行
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{bug.commit_hash && (
|
||||
<div className="detail-section">
|
||||
<div className="detail-section-title">Git Info</div>
|
||||
<div className="detail-section-title">Git 信息</div>
|
||||
<div className="detail-section-value">
|
||||
<GitCommit size={14} style={{ display: 'inline', verticalAlign: 'middle', marginRight: '6px' }} />
|
||||
{bug.commit_hash}
|
||||
@ -100,7 +114,7 @@ export default function BugDetail() {
|
||||
)}
|
||||
|
||||
<div className="detail-section">
|
||||
<div className="detail-section-title">Stack Trace</div>
|
||||
<div className="detail-section-title">堆栈跟踪</div>
|
||||
<pre className="code-block error">
|
||||
{typeof bug.stack_trace === 'string'
|
||||
? bug.stack_trace
|
||||
@ -110,7 +124,7 @@ export default function BugDetail() {
|
||||
|
||||
{bug.context && Object.keys(bug.context).length > 0 && (
|
||||
<div className="detail-section">
|
||||
<div className="detail-section-title">Context</div>
|
||||
<div className="detail-section-title">上下文信息</div>
|
||||
<pre className="code-block accent">
|
||||
{JSON.stringify(bug.context, null, 2)}
|
||||
</pre>
|
||||
@ -128,42 +142,42 @@ export default function BugDetail() {
|
||||
) : (
|
||||
<Play size={14} />
|
||||
)}
|
||||
{repairing ? 'Triggering...' : 'Trigger Repair'}
|
||||
{repairing ? '触发中...' : '触发修复'}
|
||||
</button>
|
||||
{repairMessage && (
|
||||
<span style={{
|
||||
fontSize: '13px',
|
||||
color: repairMessage.includes('success') ? 'var(--success)' : 'var(--error)'
|
||||
color: repairMessage.includes('成功') ? 'var(--success)' : 'var(--error)'
|
||||
}}>
|
||||
{repairMessage}
|
||||
</span>
|
||||
)}
|
||||
{!canTriggerRepair && !repairing && (
|
||||
<span style={{ fontSize: '13px', color: 'var(--text-tertiary)' }}>
|
||||
Only NEW or FIX_FAILED bugs can be triggered
|
||||
仅"新发现"或"修复失败"状态的缺陷可触发修复
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="detail-card">
|
||||
<div className="detail-section-title" style={{ marginBottom: '12px' }}>Metadata</div>
|
||||
<div className="detail-section-title" style={{ marginBottom: '12px' }}>元数据</div>
|
||||
<table className="meta-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="meta-label">Bug ID</td>
|
||||
<td className="meta-label">缺陷编号</td>
|
||||
<td>{bug.id}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="meta-label">Fingerprint</td>
|
||||
<td className="meta-label">指纹</td>
|
||||
<td className="cell-mono">{bug.fingerprint}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="meta-label">Retry Count</td>
|
||||
<td className="meta-label">重试次数</td>
|
||||
<td>{bug.retry_count}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="meta-label">Reported At</td>
|
||||
<td className="meta-label">上报时间</td>
|
||||
<td>{new Date(bug.timestamp).toLocaleString()}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@ -7,6 +7,18 @@ const STATUSES = [
|
||||
'FIXING', 'FIXED', 'VERIFIED', 'DEPLOYED', 'FIX_FAILED'
|
||||
];
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
NEW: '新发现',
|
||||
VERIFYING: '验证中',
|
||||
CANNOT_REPRODUCE: '无法复现',
|
||||
PENDING_FIX: '待修复',
|
||||
FIXING: '修复中',
|
||||
FIXED: '已修复',
|
||||
VERIFIED: '已验证',
|
||||
DEPLOYED: '已部署',
|
||||
FIX_FAILED: '修复失败',
|
||||
};
|
||||
|
||||
export default function BugList() {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
@ -71,8 +83,8 @@ export default function BugList() {
|
||||
return (
|
||||
<div>
|
||||
<div className="page-header">
|
||||
<h1 className="page-title">Bug List</h1>
|
||||
<p className="page-subtitle">All reported errors and their current status</p>
|
||||
<h1 className="page-title">缺陷列表</h1>
|
||||
<p className="page-subtitle">所有上报的错误及其当前状态</p>
|
||||
</div>
|
||||
|
||||
<div className="project-tabs">
|
||||
@ -80,7 +92,7 @@ export default function BugList() {
|
||||
className={`project-tab ${currentProject === '' ? 'active' : ''}`}
|
||||
onClick={() => updateParams({ project: '' })}
|
||||
>
|
||||
All Projects
|
||||
全部项目
|
||||
</button>
|
||||
{projects.map(p => (
|
||||
<button
|
||||
@ -98,7 +110,7 @@ export default function BugList() {
|
||||
className={`status-tab ${currentStatus === '' ? 'active' : ''}`}
|
||||
onClick={() => updateParams({ status: '' })}
|
||||
>
|
||||
All Status
|
||||
全部状态
|
||||
</button>
|
||||
{STATUSES.map(s => (
|
||||
<button
|
||||
@ -106,7 +118,7 @@ export default function BugList() {
|
||||
className={`status-tab ${currentStatus === s ? 'active' : ''} status-color-${s}`}
|
||||
onClick={() => updateParams({ status: s })}
|
||||
>
|
||||
{s.replace('_', ' ')}
|
||||
{STATUS_LABELS[s] || s}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@ -118,21 +130,21 @@ export default function BugList() {
|
||||
</div>
|
||||
) : bugs.length === 0 ? (
|
||||
<div className="empty-state">
|
||||
No bugs found
|
||||
{currentProject && <span> in <strong>{currentProject}</strong></span>}
|
||||
{currentStatus && <span> with status <strong>{currentStatus}</strong></span>}
|
||||
未找到缺陷
|
||||
{currentProject && <span>,项目:<strong>{currentProject}</strong></span>}
|
||||
{currentStatus && <span>,状态:<strong>{STATUS_LABELS[currentStatus] || currentStatus}</strong></span>}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Project</th>
|
||||
<th>Error Type</th>
|
||||
<th>File</th>
|
||||
<th>Status</th>
|
||||
<th>Time</th>
|
||||
<th>编号</th>
|
||||
<th>项目</th>
|
||||
<th>错误类型</th>
|
||||
<th>文件</th>
|
||||
<th>状态</th>
|
||||
<th>时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -160,7 +172,7 @@ export default function BugList() {
|
||||
</td>
|
||||
<td>
|
||||
<span className={`status-badge status-${bug.status}`}>
|
||||
{bug.status}
|
||||
{STATUS_LABELS[bug.status] || bug.status}
|
||||
</span>
|
||||
</td>
|
||||
<td className="cell-secondary">
|
||||
@ -177,16 +189,16 @@ export default function BugList() {
|
||||
onClick={() => updateParams({ page: String(Math.max(1, currentPage - 1)) })}
|
||||
disabled={currentPage === 1}
|
||||
>
|
||||
Previous
|
||||
上一页
|
||||
</button>
|
||||
<span className="pagination-info">
|
||||
Page {currentPage} of {totalPages}
|
||||
第 {currentPage} 页,共 {totalPages} 页
|
||||
</span>
|
||||
<button
|
||||
onClick={() => updateParams({ page: String(Math.min(totalPages, currentPage + 1)) })}
|
||||
disabled={currentPage === totalPages}
|
||||
>
|
||||
Next
|
||||
下一页
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -2,6 +2,18 @@ import { useState, useEffect } from 'react';
|
||||
import { Bug, CalendarPlus, TrendingUp, AlertTriangle } from 'lucide-react';
|
||||
import { getStats, type DashboardStats } from '../api';
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
NEW: '新发现',
|
||||
VERIFYING: '验证中',
|
||||
CANNOT_REPRODUCE: '无法复现',
|
||||
PENDING_FIX: '待修复',
|
||||
FIXING: '修复中',
|
||||
FIXED: '已修复',
|
||||
VERIFIED: '已验证',
|
||||
DEPLOYED: '已部署',
|
||||
FIX_FAILED: '修复失败',
|
||||
};
|
||||
|
||||
export default function Dashboard() {
|
||||
const [stats, setStats] = useState<DashboardStats | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@ -29,14 +41,14 @@ export default function Dashboard() {
|
||||
}
|
||||
|
||||
if (!stats) {
|
||||
return <div className="loading">Failed to load statistics</div>;
|
||||
return <div className="loading">加载统计数据失败</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="page-header">
|
||||
<h1 className="page-title">Dashboard</h1>
|
||||
<p className="page-subtitle">Overview of your error tracking system</p>
|
||||
<h1 className="page-title">仪表盘</h1>
|
||||
<p className="page-subtitle">错误追踪系统概览</p>
|
||||
</div>
|
||||
|
||||
<div className="stats-grid">
|
||||
@ -44,28 +56,28 @@ export default function Dashboard() {
|
||||
<div className="stat-icon accent">
|
||||
<Bug size={18} />
|
||||
</div>
|
||||
<div className="stat-label">Total Bugs</div>
|
||||
<div className="stat-label">缺陷总数</div>
|
||||
<div className="stat-value accent">{stats.total_bugs}</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="stat-icon warning">
|
||||
<CalendarPlus size={18} />
|
||||
</div>
|
||||
<div className="stat-label">Today's New</div>
|
||||
<div className="stat-label">今日新增</div>
|
||||
<div className="stat-value warning">{stats.today_bugs}</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="stat-icon success">
|
||||
<TrendingUp size={18} />
|
||||
</div>
|
||||
<div className="stat-label">Fix Rate</div>
|
||||
<div className="stat-label">修复率</div>
|
||||
<div className="stat-value success">{stats.fix_rate}%</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="stat-icon error">
|
||||
<AlertTriangle size={18} />
|
||||
</div>
|
||||
<div className="stat-label">Pending Fix</div>
|
||||
<div className="stat-label">待修复</div>
|
||||
<div className="stat-value error">
|
||||
{(stats.status_distribution['NEW'] || 0) +
|
||||
(stats.status_distribution['PENDING_FIX'] || 0)}
|
||||
@ -75,20 +87,22 @@ export default function Dashboard() {
|
||||
|
||||
<div className="table-container">
|
||||
<div className="table-header">
|
||||
<h3 className="table-title">Status Distribution</h3>
|
||||
<h3 className="table-title">状态分布</h3>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<th>Count</th>
|
||||
<th>状态</th>
|
||||
<th>数量</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Object.entries(stats.status_distribution).map(([status, count]) => (
|
||||
<tr key={status}>
|
||||
<td>
|
||||
<span className={`status-badge status-${status}`}>{status}</span>
|
||||
<span className={`status-badge status-${status}`}>
|
||||
{STATUS_LABELS[status] || status}
|
||||
</span>
|
||||
</td>
|
||||
<td>{count}</td>
|
||||
</tr>
|
||||
|
||||
@ -3,6 +3,18 @@ import { useParams, Link } from 'react-router-dom';
|
||||
import { ArrowLeft, Bot, FileCode, FlaskConical } from 'lucide-react';
|
||||
import { getRepairReportDetail, type RepairReport } from '../api';
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
NEW: '新发现',
|
||||
VERIFYING: '验证中',
|
||||
CANNOT_REPRODUCE: '无法复现',
|
||||
PENDING_FIX: '待修复',
|
||||
FIXING: '修复中',
|
||||
FIXED: '已修复',
|
||||
VERIFIED: '已验证',
|
||||
DEPLOYED: '已部署',
|
||||
FIX_FAILED: '修复失败',
|
||||
};
|
||||
|
||||
export default function RepairDetail() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const [report, setReport] = useState<RepairReport | null>(null);
|
||||
@ -33,57 +45,59 @@ export default function RepairDetail() {
|
||||
}
|
||||
|
||||
if (!report) {
|
||||
return <div className="loading">Report not found</div>;
|
||||
return <div className="loading">未找到该修复报告</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Link to="/repairs" className="back-link">
|
||||
<ArrowLeft size={14} />
|
||||
Back to Repair Reports
|
||||
返回修复报告列表
|
||||
</Link>
|
||||
|
||||
<div style={{ marginBottom: '20px' }}>
|
||||
<div className="title-row">
|
||||
<h1 className="page-title">Repair Report #{report.id}</h1>
|
||||
<span className={`status-badge status-${report.status}`}>{report.status}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card">
|
||||
<h2>Basic Info</h2>
|
||||
<div className="info-row">
|
||||
<span>Project</span>
|
||||
<strong>{report.project_id}</strong>
|
||||
</div>
|
||||
<div className="info-row">
|
||||
<span>Bug ID</span>
|
||||
<Link to={`/bugs/${report.error_log_id}`}>#{report.error_log_id}</Link>
|
||||
</div>
|
||||
<div className="info-row">
|
||||
<span>Created At</span>
|
||||
<span>{new Date(report.created_at).toLocaleString()}</span>
|
||||
</div>
|
||||
<div className="info-row">
|
||||
<span>Test Result</span>
|
||||
<span className={report.test_passed ? 'test-pass' : 'test-fail'}>
|
||||
{report.test_passed ? 'PASS' : 'FAIL'}
|
||||
<h1 className="page-title">修复报告 #{report.id}</h1>
|
||||
<span className={`status-badge status-${report.status}`}>
|
||||
{STATUS_LABELS[report.status] || report.status}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card">
|
||||
<h2><Bot size={16} /> AI Analysis</h2>
|
||||
<h2>基本信息</h2>
|
||||
<div className="info-row">
|
||||
<span>项目</span>
|
||||
<strong>{report.project_id}</strong>
|
||||
</div>
|
||||
<div className="info-row">
|
||||
<span>缺陷编号</span>
|
||||
<Link to={`/bugs/${report.error_log_id}`}>#{report.error_log_id}</Link>
|
||||
</div>
|
||||
<div className="info-row">
|
||||
<span>创建时间</span>
|
||||
<span>{new Date(report.created_at).toLocaleString()}</span>
|
||||
</div>
|
||||
<div className="info-row">
|
||||
<span>测试结果</span>
|
||||
<span className={report.test_passed ? 'test-pass' : 'test-fail'}>
|
||||
{report.test_passed ? '通过' : '失败'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card">
|
||||
<h2><Bot size={16} /> AI 分析</h2>
|
||||
<pre className="code-block neutral">{report.ai_analysis}</pre>
|
||||
</div>
|
||||
|
||||
<div className="card">
|
||||
<h2><FileCode size={16} /> Code Changes</h2>
|
||||
<pre className="code-block neutral">{report.code_diff || 'No changes recorded'}</pre>
|
||||
<h2><FileCode size={16} /> 代码变更</h2>
|
||||
<pre className="code-block neutral">{report.code_diff || '无变更记录'}</pre>
|
||||
</div>
|
||||
|
||||
<div className="card">
|
||||
<h2><FlaskConical size={16} /> Test Output</h2>
|
||||
<h2><FlaskConical size={16} /> 测试输出</h2>
|
||||
<pre className="code-block neutral">{report.test_output}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -2,6 +2,18 @@ import { useState, useEffect } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getRepairReports, type RepairReport, getProjects } from '../api';
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
NEW: '新发现',
|
||||
VERIFYING: '验证中',
|
||||
CANNOT_REPRODUCE: '无法复现',
|
||||
PENDING_FIX: '待修复',
|
||||
FIXING: '修复中',
|
||||
FIXED: '已修复',
|
||||
VERIFIED: '已验证',
|
||||
DEPLOYED: '已部署',
|
||||
FIX_FAILED: '修复失败',
|
||||
};
|
||||
|
||||
export default function RepairList() {
|
||||
const [reports, setReports] = useState<RepairReport[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@ -52,8 +64,8 @@ export default function RepairList() {
|
||||
<div className="page-header">
|
||||
<div className="title-row">
|
||||
<div>
|
||||
<h1 className="page-title">Repair Reports</h1>
|
||||
<p className="page-subtitle">AI-powered bug repair attempts and their results</p>
|
||||
<h1 className="page-title">修复报告</h1>
|
||||
<p className="page-subtitle">AI 自动修复记录及结果</p>
|
||||
</div>
|
||||
<div className="filters">
|
||||
<select
|
||||
@ -61,7 +73,7 @@ export default function RepairList() {
|
||||
value={filters.project_id}
|
||||
onChange={(e) => handleFilterChange('project_id', e.target.value)}
|
||||
>
|
||||
<option value="">All Projects</option>
|
||||
<option value="">全部项目</option>
|
||||
{projects.map((p) => (
|
||||
<option key={p} value={p}>{p}</option>
|
||||
))}
|
||||
@ -76,19 +88,19 @@ export default function RepairList() {
|
||||
<div className="spinner"></div>
|
||||
</div>
|
||||
) : reports.length === 0 ? (
|
||||
<div className="empty-state">No reports found</div>
|
||||
<div className="empty-state">暂无修复报告</div>
|
||||
) : (
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Project</th>
|
||||
<th>Bug ID</th>
|
||||
<th>Modified Files</th>
|
||||
<th>Test Result</th>
|
||||
<th>Status</th>
|
||||
<th>Date</th>
|
||||
<th>Actions</th>
|
||||
<th>编号</th>
|
||||
<th>项目</th>
|
||||
<th>缺陷编号</th>
|
||||
<th>修改文件数</th>
|
||||
<th>测试结果</th>
|
||||
<th>状态</th>
|
||||
<th>日期</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -101,15 +113,15 @@ export default function RepairList() {
|
||||
#{report.error_log_id}
|
||||
</Link>
|
||||
</td>
|
||||
<td>{report.modified_files.length} files</td>
|
||||
<td>{report.modified_files.length} 个文件</td>
|
||||
<td>
|
||||
<span className={report.test_passed ? 'test-pass' : 'test-fail'}>
|
||||
{report.test_passed ? 'PASS' : 'FAIL'}
|
||||
{report.test_passed ? '通过' : '失败'}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span className={`status-badge status-${report.status}`}>
|
||||
{report.status}
|
||||
{STATUS_LABELS[report.status] || report.status}
|
||||
</span>
|
||||
</td>
|
||||
<td className="cell-secondary">
|
||||
@ -117,7 +129,7 @@ export default function RepairList() {
|
||||
</td>
|
||||
<td>
|
||||
<Link to={`/repairs/${report.id}`} className="btn-link">
|
||||
View
|
||||
查看
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
@ -133,16 +145,16 @@ export default function RepairList() {
|
||||
disabled={filters.page === 1}
|
||||
onClick={() => setFilters((prev) => ({ ...prev, page: prev.page - 1 }))}
|
||||
>
|
||||
Previous
|
||||
上一页
|
||||
</button>
|
||||
<span className="pagination-info">
|
||||
Page {filters.page} of {totalPages}
|
||||
第 {filters.page} 页,共 {totalPages} 页
|
||||
</span>
|
||||
<button
|
||||
disabled={filters.page === totalPages}
|
||||
onClick={() => setFilters((prev) => ({ ...prev, page: prev.page + 1 }))}
|
||||
>
|
||||
Next
|
||||
下一页
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user