This commit is contained in:
@@ -16,6 +16,8 @@ export function CommonAppBuildPage() {
|
||||
const [selectedRepoId, setSelectedRepoId] = useState('');
|
||||
const [history, setHistory] = useState<CommonAppPipeline[]>([]);
|
||||
const [historyPage, setHistoryPage] = useState(1);
|
||||
const [historyTotal, setHistoryTotal] = useState<number | null>(null);
|
||||
const [historyTotalPages, setHistoryTotalPages] = useState<number | null>(null);
|
||||
const [hasNextHistoryPage, setHasNextHistoryPage] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [historyLoading, setHistoryLoading] = useState(false);
|
||||
@@ -64,6 +66,8 @@ export function CommonAppBuildPage() {
|
||||
let canceled = false;
|
||||
if (!selectedRepoId) {
|
||||
setHistory([]);
|
||||
setHistoryTotal(null);
|
||||
setHistoryTotalPages(null);
|
||||
setHasNextHistoryPage(false);
|
||||
return;
|
||||
}
|
||||
@@ -73,11 +77,15 @@ export function CommonAppBuildPage() {
|
||||
.then((result) => {
|
||||
if (canceled) return;
|
||||
setHistory(result.pipelines ?? []);
|
||||
setHistoryTotal(result.total ?? null);
|
||||
setHistoryTotalPages(result.totalPages ?? null);
|
||||
setHasNextHistoryPage(Boolean(result.hasNext));
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
if (canceled) return;
|
||||
setHistory([]);
|
||||
setHistoryTotal(null);
|
||||
setHistoryTotalPages(null);
|
||||
setHasNextHistoryPage(false);
|
||||
toast({ type: 'error', title: '파이프라인 이력 조회 실패', message: error.message });
|
||||
})
|
||||
@@ -139,7 +147,10 @@ export function CommonAppBuildPage() {
|
||||
<span className={cn('size-2.5 shrink-0 rounded-full', pipelineStatusDotClass(pipeline.status))} />
|
||||
<p className="truncate text-sm font-semibold">{formatRepositoryName(pipeline.repository)}</p>
|
||||
</div>
|
||||
<p className="mt-1 truncate text-sm text-muted-foreground">{pipeline.message || '-'}</p>
|
||||
<p className="mt-1 truncate text-sm text-muted-foreground">
|
||||
<span className="mr-1 font-mono text-xs">#{pipeline.number ?? '-'}</span>
|
||||
{pipeline.message || '-'}
|
||||
</p>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
@@ -158,31 +169,35 @@ export function CommonAppBuildPage() {
|
||||
<div className="flex min-h-40 items-center justify-center px-5 text-sm text-muted-foreground">표시할 파이프라인 이력이 없습니다.</div>
|
||||
) : null}
|
||||
{history.map((pipeline) => (
|
||||
<div key={pipeline.id} className="flex flex-col gap-3 px-5 py-3 transition-colors hover:bg-muted/20 md:flex-row md:items-center md:justify-between">
|
||||
<div className="min-w-0">
|
||||
<div key={pipeline.id} className="px-5 py-3 transition-colors hover:bg-muted/20">
|
||||
<div className="flex min-w-0 items-center justify-between gap-4">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
<span className={cn('size-2.5 shrink-0 rounded-full', pipelineStatusDotClass(pipeline.status))} />
|
||||
<span className="shrink-0 font-mono text-xs text-muted-foreground">#{pipeline.number ?? pipeline.id}</span>
|
||||
<p className="truncate text-sm font-semibold">{pipeline.message || '-'}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex shrink-0 flex-wrap items-center gap-2 text-xs text-muted-foreground md:justify-end">
|
||||
<Badge tone={pipelineStatusTone(pipeline.status)}>
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
{isActivePipelineStatus(pipeline.status) ? <Loader2 className="size-3 animate-spin" /> : null}
|
||||
{pipeline.status || '-'}
|
||||
</span>
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="mt-2 flex flex-wrap items-center gap-2 pl-5 text-xs text-muted-foreground">
|
||||
<span className="rounded-md bg-muted/50 px-2 py-1">{pipeline.branch || '-'}</span>
|
||||
<span className="rounded-md bg-muted/50 px-2 py-1 font-mono">SHA1 {formatShortSha(pipeline.commitSha)}</span>
|
||||
<span className="rounded-md bg-muted/50 px-2 py-1">소요 {formatDuration(pipeline.durationSeconds)}</span>
|
||||
<span className="min-w-16 text-right">{formatPipelineRelativeTime(pipeline.createdAt)}</span>
|
||||
<span className="rounded-md bg-muted/50 px-2 py-1">{formatPipelineRelativeTime(pipeline.createdAt)}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex items-center justify-between border-t border-border px-5 py-3 text-xs text-muted-foreground">
|
||||
<span>현재 {historyPage}페이지</span>
|
||||
<span>
|
||||
{historyTotal !== null && historyTotalPages !== null
|
||||
? `총 ${historyTotal}건 · ${historyPage} / ${historyTotalPages}`
|
||||
: `현재 ${historyPage}페이지`}
|
||||
</span>
|
||||
<div className="flex gap-2">
|
||||
<Button variant="outline" className="h-8 px-3 text-[13px]" disabled={historyLoading || historyPage <= 1} onClick={() => setHistoryPage((page) => Math.max(1, page - 1))}>
|
||||
이전
|
||||
|
||||
Reference in New Issue
Block a user