From 14a779ce01e1ef1a355137e79617e740a4e9e8e3 Mon Sep 17 00:00:00 2001 From: chyoo Date: Thu, 9 Jul 2026 10:22:11 +0900 Subject: [PATCH] show common app pipeline sha and duration --- src/App.tsx | 2 ++ src/pages/common-apps/CommonAppBuildPage.tsx | 38 ++++++++++---------- src/pages/common-apps/common-app-api.ts | 2 ++ src/pages/common-apps/common-app-utils.ts | 16 +++++++++ 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 18b2d99..2f41e8b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -248,6 +248,8 @@ type CommonAppPipeline = { repository: string; message: string; branch: string; + commitSha?: string | null; + durationSeconds?: number | null; status: string; createdAt: number; url?: string | null; diff --git a/src/pages/common-apps/CommonAppBuildPage.tsx b/src/pages/common-apps/CommonAppBuildPage.tsx index d82ee87..e6afb7b 100644 --- a/src/pages/common-apps/CommonAppBuildPage.tsx +++ b/src/pages/common-apps/CommonAppBuildPage.tsx @@ -6,7 +6,7 @@ import { PageTitle } from '../../layout/AppLayout'; import { cn } from '../../lib/utils'; import { LoadingModal, useMinimumLoading } from '../operations/operation-utils'; import { listCommonAppPipelines, type CommonAppPipeline } from './common-app-api'; -import { formatPipelineRelativeTime, formatRepositoryName, isActivePipelineStatus, pipelineStatusDotClass, pipelineStatusTone } from './common-app-utils'; +import { formatDuration, formatPipelineRelativeTime, formatRepositoryName, formatShortSha, isActivePipelineStatus, pipelineStatusDotClass, pipelineStatusTone } from './common-app-utils'; export function CommonAppBuildPage() { const { toast } = useToast(); @@ -77,25 +77,25 @@ export function CommonAppBuildPage() { ) : null}
{pipelines.map((pipeline) => ( -
-
-
-
- -

{formatRepositoryName(pipeline.repository)}

-
-

{pipeline.message || '-'}

-
- - - {isActivePipelineStatus(pipeline.status) ? : null} - {pipeline.status || '-'} - - - {pipeline.branch || '-'} - {formatPipelineRelativeTime(pipeline.createdAt)} -
+
+
+
+ +

{formatRepositoryName(pipeline.repository)}

+

{pipeline.message || '-'}

+
+
+ + + {isActivePipelineStatus(pipeline.status) ? : null} + {pipeline.status || '-'} + + + {pipeline.branch || '-'} + SHA1 {formatShortSha(pipeline.commitSha)} + 소요 {formatDuration(pipeline.durationSeconds)} + {formatPipelineRelativeTime(pipeline.createdAt)}
))} diff --git a/src/pages/common-apps/common-app-api.ts b/src/pages/common-apps/common-app-api.ts index dd0a135..1def70a 100644 --- a/src/pages/common-apps/common-app-api.ts +++ b/src/pages/common-apps/common-app-api.ts @@ -5,6 +5,8 @@ export type CommonAppPipeline = { repository: string; message: string; branch: string; + commitSha?: string | null; + durationSeconds?: number | null; status: string; createdAt: number; ciUrl?: string | null; diff --git a/src/pages/common-apps/common-app-utils.ts b/src/pages/common-apps/common-app-utils.ts index 264a2ea..d844ffb 100644 --- a/src/pages/common-apps/common-app-utils.ts +++ b/src/pages/common-apps/common-app-utils.ts @@ -75,6 +75,22 @@ export function formatRepositoryName(repository: string) { return repository.replace('/', ' / '); } +export function formatShortSha(value?: string | null) { + if (!value) return '-'; + return value.length > 8 ? value.slice(0, 8) : value; +} + +export function formatDuration(seconds?: number | null) { + if (seconds === null || seconds === undefined || !Number.isFinite(seconds)) return '-'; + if (seconds < 60) return `${seconds}초`; + const minutes = Math.floor(seconds / 60); + const remainingSeconds = seconds % 60; + if (minutes < 60) return remainingSeconds ? `${minutes}분 ${remainingSeconds}초` : `${minutes}분`; + const hours = Math.floor(minutes / 60); + const remainingMinutes = minutes % 60; + return remainingMinutes ? `${hours}시간 ${remainingMinutes}분` : `${hours}시간`; +} + export function pipelineStatusTone(status?: string | null): 'green' | 'amber' | 'red' | 'blue' | 'neutral' { const value = (status ?? '').toLowerCase(); if (['success', 'succeeded', 'passed'].includes(value)) return 'green';