feat: 流水线运行历史前后端联调 — 详情弹窗历史记录标签展示真实PipelineRun数据(构建号/状态/分支/Commit/触发者/时间)
This commit is contained in:
1 parent
1d98503f37
commit
6012418523
1 file changed
+71
-6
@@ -95,6 +95,8 @@ export function PipelineManager() {
|
||||
const [isDetailDialogOpen, setIsDetailDialogOpen] = useState(false);
|
||||
const [isRunDialogOpen, setIsRunDialogOpen] = useState(false);
|
||||
const [activeStage, setActiveStage] = useState<string | null>(null);
|
||||
const [pipelineRuns, setPipelineRuns] = useState<any[]>([]);
|
||||
const [loadingRuns, setLoadingRuns] = useState(false);
|
||||
const [newPipeline, setNewPipeline] = useState({
|
||||
name: '',
|
||||
description: '',
|
||||
@@ -119,6 +121,25 @@ export function PipelineManager() {
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const loadPipelineRuns = async (pipelineId: number | string) => {
|
||||
try {
|
||||
setLoadingRuns(true);
|
||||
const res = await pipelineApi.getRuns(pipelineId);
|
||||
setPipelineRuns((res as any)?.list || []);
|
||||
} catch (error) {
|
||||
console.error('Failed to load pipeline runs:', error);
|
||||
setPipelineRuns([]);
|
||||
} finally {
|
||||
setLoadingRuns(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleOpenDetail = (pipeline: any) => {
|
||||
setSelectedPipeline(pipeline);
|
||||
setIsDetailDialogOpen(true);
|
||||
loadPipelineRuns(pipeline.id);
|
||||
};
|
||||
|
||||
const filteredPipelines = pipelines.filter(
|
||||
(p) =>
|
||||
(p.name || '').toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
@@ -203,6 +224,9 @@ export function PipelineManager() {
|
||||
await pipelineApi.triggerPipeline(selectedPipeline.id);
|
||||
setIsRunDialogOpen(false);
|
||||
loadData();
|
||||
if (isDetailDialogOpen) {
|
||||
loadPipelineRuns(selectedPipeline.id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to trigger pipeline:', error);
|
||||
}
|
||||
@@ -382,10 +406,7 @@ export function PipelineManager() {
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-slate-400 hover:text-blue-400"
|
||||
onClick={() => {
|
||||
setSelectedPipeline(pipeline);
|
||||
setIsDetailDialogOpen(true);
|
||||
}}
|
||||
onClick={() => handleOpenDetail(pipeline)}
|
||||
>
|
||||
<Eye className="h-4 w-4" />
|
||||
</Button>
|
||||
@@ -509,7 +530,7 @@ export function PipelineManager() {
|
||||
配置
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="history" className="data-[state=active]:bg-slate-700">
|
||||
历史记录
|
||||
历史记录{pipelineRuns.length > 0 && ` (${pipelineRuns.length})`}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="stages" className="mt-4">
|
||||
@@ -569,7 +590,51 @@ export function PipelineManager() {
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent value="history" className="mt-4">
|
||||
<div className="text-slate-500 text-center py-8">历史执行记录将在这里显示</div>
|
||||
{loadingRuns ? (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 className="h-5 w-5 text-slate-500 animate-spin" />
|
||||
</div>
|
||||
) : pipelineRuns.length === 0 ? (
|
||||
<div className="text-slate-500 text-center py-8">暂无执行记录</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{pipelineRuns.map((run: any) => (
|
||||
<div
|
||||
key={run.id}
|
||||
className="flex items-center gap-3 p-3 rounded-lg border border-slate-700 bg-slate-800/50"
|
||||
>
|
||||
<div className="flex items-center gap-2 w-20 shrink-0">
|
||||
<span className="text-slate-500 text-sm font-mono">#{run.build_number}</span>
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
{getStatusBadge(run.status)}
|
||||
<Badge variant="outline" className="border-slate-700 text-slate-400 text-xs">
|
||||
<GitBranch className="h-3 w-3 mr-1" />
|
||||
{run.branch || 'main'}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 mt-1 text-xs text-slate-500">
|
||||
{run.commit_id && (
|
||||
<span className="flex items-center gap-1">
|
||||
<GitCommit className="h-3 w-3" />
|
||||
{run.commit_id.substring(0, 7)}
|
||||
</span>
|
||||
)}
|
||||
<span>{run.triggered_by || 'manual'}</span>
|
||||
{run.duration > 0 && (
|
||||
<span className="flex items-center gap-1">
|
||||
<Clock className="h-3 w-3" />
|
||||
{run.duration < 60 ? `${run.duration}s` : `${Math.floor(run.duration / 60)}m${run.duration % 60}s`}
|
||||
</span>
|
||||
)}
|
||||
<span>{run.created_at ? new Date(run.created_at).toLocaleString('zh-CN') : '--'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user