connect tailscale node status through platform gateway
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import { ExternalLink, RotateCcw } from 'lucide-react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Badge, Button, Card, CardHeader } from '../../components/ui';
|
||||
import { useToast } from '../../components/toast';
|
||||
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 { commonAppComponents, formatPipelineTime, pipelineStatusTone } from './common-app-utils';
|
||||
|
||||
export function CommonAppSourcePage() {
|
||||
const { toast } = useToast();
|
||||
const [pipelines, setPipelines] = useState<CommonAppPipeline[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const loadingVisible = useMinimumLoading(loading);
|
||||
|
||||
const pipelineByRepo = useMemo(() => new Map(pipelines.map((pipeline) => [pipeline.repository, pipeline])), [pipelines]);
|
||||
|
||||
const refresh = () => {
|
||||
setLoading(true);
|
||||
listCommonAppPipelines()
|
||||
.then(setPipelines)
|
||||
.catch((error: Error) => {
|
||||
toast({ type: 'error', title: '공통앱 소스 조회 실패', message: error.message });
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
refresh();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageTitle
|
||||
eyebrow="공통앱"
|
||||
title="소스 관리"
|
||||
description="플랫폼 공통앱 저장소와 최근 파이프라인 기준 상태입니다."
|
||||
actions={
|
||||
<Button variant="outline" className="h-8 px-3 text-[13px]" onClick={refresh} disabled={loading}>
|
||||
<RotateCcw className={cn('size-4', loading && 'animate-spin')} />
|
||||
새로고침
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<Card>
|
||||
<CardHeader title="저장소" description="Woodpecker에 연결된 공통앱 저장소입니다." />
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full min-w-[920px] whitespace-nowrap text-left text-sm">
|
||||
<thead className="border-b border-border bg-muted/30 text-xs text-muted-foreground">
|
||||
<tr>
|
||||
<th className="px-5 py-3 font-medium">저장소</th>
|
||||
<th className="px-5 py-3 font-medium">구성요소</th>
|
||||
<th className="px-5 py-3 font-medium">브랜치</th>
|
||||
<th className="px-5 py-3 font-medium">최근 파이프라인</th>
|
||||
<th className="px-5 py-3 font-medium">상태</th>
|
||||
<th className="px-5 py-3 font-medium">생성시각</th>
|
||||
<th className="px-5 py-3 font-medium">관리</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-border">
|
||||
{commonAppComponents.map((component) => {
|
||||
const pipeline = pipelineByRepo.get(component.repository);
|
||||
return (
|
||||
<tr key={component.key} className="hover:bg-muted/20">
|
||||
<td className="px-5 py-4 font-medium">{component.repository}</td>
|
||||
<td className="px-5 py-4 text-muted-foreground">{component.name}</td>
|
||||
<td className="px-5 py-4">{pipeline?.branch || '-'}</td>
|
||||
<td className="max-w-[340px] truncate px-5 py-4">{pipeline?.message || '-'}</td>
|
||||
<td className="px-5 py-4">
|
||||
<Badge tone={pipelineStatusTone(pipeline?.status)}>{pipeline?.status || '-'}</Badge>
|
||||
</td>
|
||||
<td className="px-5 py-4 text-muted-foreground">{formatPipelineTime(pipeline?.createdAt)}</td>
|
||||
<td className="px-5 py-4">
|
||||
{pipeline?.url ? (
|
||||
<Button variant="outline" className="size-8 px-0" aria-label="저장소 열기" onClick={() => window.open(pipeline.url ?? undefined, '_blank', 'noopener,noreferrer')}>
|
||||
<ExternalLink className="size-4" />
|
||||
</Button>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<LoadingModal open={loadingVisible} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user