[agent-pipeline] pipe-20260315080636-1tpd round-4

This commit is contained in:
DDD1542 2026-03-15 17:22:24 +09:00
parent 4c19d3a6eb
commit 27ce039fc8
1 changed files with 15 additions and 62 deletions

View File

@ -11,7 +11,6 @@ import {
MousePointer2, MousePointer2,
Key, Key,
Link2, Link2,
Columns3,
} from "lucide-react"; } from "lucide-react";
import { ScreenLayoutSummary } from "@/lib/api/screenGroup"; import { ScreenLayoutSummary } from "@/lib/api/screenGroup";
@ -180,7 +179,7 @@ export const ScreenNode: React.FC<{ data: ScreenNodeData }> = ({ data }) => {
return ( return (
<div <div
className={`group relative flex h-[320px] w-[260px] flex-col overflow-hidden rounded-xl border border-border/50 bg-card/80 backdrop-blur-sm shadow-lg transition-all cursor-pointer ${ className={`group relative flex h-[240px] w-[240px] flex-col overflow-hidden rounded-xl border border-border/50 bg-card/80 backdrop-blur-sm shadow-lg transition-all cursor-pointer ${
isFocused isFocused
? "border-2 border-primary ring-4 ring-primary/30 shadow-[0_0_30px_-5px_hsl(var(--primary)/0.4)] scale-[1.03]" ? "border-2 border-primary ring-4 ring-primary/30 shadow-[0_0_30px_-5px_hsl(var(--primary)/0.4)] scale-[1.03]"
: isFaded : isFaded
@ -213,14 +212,19 @@ export const ScreenNode: React.FC<{ data: ScreenNodeData }> = ({ data }) => {
/> />
{/* 헤더 (컬러) */} {/* 헤더 (컬러) */}
<div className={`flex items-center gap-2 px-3.5 py-2.5 text-primary-foreground ${headerColor} transition-colors duration-300`}> <div className={`flex items-center gap-2 px-3 py-2 text-primary-foreground ${headerColor} transition-colors duration-300`}>
<Monitor className="h-4 w-4" /> <div className="flex h-6 w-6 items-center justify-center rounded bg-primary-foreground/20">
<span className="flex-1 truncate text-[13px] font-bold tracking-tight">{label}</span> <Monitor className="h-3.5 w-3.5" />
</div>
<div className="flex-1 min-w-0">
<div className="truncate text-xs font-bold text-primary-foreground">{label}</div>
{tableName && <div className="truncate text-[9px] text-primary-foreground/70 font-mono">{tableName}</div>}
</div>
{(isMain || isFocused) && <span className="flex h-2 w-2 rounded-full bg-primary-foreground/80 animate-pulse" />} {(isMain || isFocused) && <span className="flex h-2 w-2 rounded-full bg-primary-foreground/80 animate-pulse" />}
</div> </div>
{/* 화면 미리보기 영역 (컴팩트) */} {/* 화면 미리보기 영역 (컴팩트) */}
<div className="h-[140px] overflow-hidden bg-gradient-to-b from-muted/30 to-muted/60 p-2.5"> <div className="h-[110px] overflow-hidden bg-gradient-to-b from-muted/30 to-muted/60 p-2.5">
{layoutSummary ? ( {layoutSummary ? (
<ScreenPreview layoutSummary={layoutSummary} screenType={screenType} /> <ScreenPreview layoutSummary={layoutSummary} screenType={screenType} />
) : ( ) : (
@ -231,44 +235,10 @@ export const ScreenNode: React.FC<{ data: ScreenNodeData }> = ({ data }) => {
)} )}
</div> </div>
{/* 필드 매핑 영역 */} {/* 푸터 (타입 + 컴포넌트 수) */}
<div className="flex-1 overflow-hidden border-t border-border bg-card px-2 py-1.5"> <div className="flex items-center justify-between border-t border-border bg-muted/20 px-3 py-1.5">
<div className="mb-1 flex items-center gap-1 text-[9px] font-medium text-muted-foreground"> <span className="text-[9px] font-medium text-muted-foreground">{getScreenTypeLabel(screenType)}</span>
<Columns3 className="h-3 w-3" /> <span className="text-[9px] text-muted-foreground">{layoutSummary?.totalComponents ?? 0} </span>
<span> </span>
<span className="ml-auto text-[8px] text-muted-foreground/70">
{layoutSummary?.layoutItems?.filter(i => i.label && !i.componentKind?.includes('button')).length || 0}
</span>
</div>
<div className="flex flex-col gap-0.5 overflow-y-auto" style={{ maxHeight: '80px' }}>
{layoutSummary?.layoutItems
?.filter(item => item.label && !item.componentKind?.includes('button'))
?.slice(0, 6)
?.map((item, idx) => (
<div key={idx} className="flex items-center gap-1 rounded bg-muted/50 px-1.5 py-0.5">
<div className={`h-1.5 w-1.5 rounded-full ${
item.componentKind === 'table-list' ? 'bg-primary' :
item.componentKind?.includes('select') ? 'bg-warning' :
'bg-muted-foreground'
}`} />
<span className="flex-1 truncate text-[9px] text-muted-foreground">{item.label}</span>
<span className="text-[8px] text-muted-foreground/70">{item.componentKind?.split('-')[0] || 'field'}</span>
</div>
)) || (
<div className="text-center text-[9px] text-muted-foreground py-2"> </div>
)}
</div>
</div>
{/* 푸터 (테이블 정보) */}
<div className="flex items-center justify-between border-t border-border bg-muted/20 px-3 py-2 backdrop-blur-sm">
<div className="flex items-center gap-1 text-[10px] text-muted-foreground">
<Database className="h-3 w-3" />
<span className="max-w-[120px] truncate font-mono">{tableName || "No Table"}</span>
</div>
<span className="rounded bg-muted px-1.5 py-0.5 text-[9px] font-medium text-muted-foreground">
{getScreenTypeLabel(screenType)}
</span>
</div> </div>
</div> </div>
); );
@ -350,10 +320,6 @@ const ScreenPreview: React.FC<{ layoutSummary: ScreenLayoutSummary; screenType:
<div className="h-2.5 w-4 rounded bg-muted-foreground/40" /> <div className="h-2.5 w-4 rounded bg-muted-foreground/40" />
<div className="h-2.5 w-4 rounded bg-muted-foreground/40" /> <div className="h-2.5 w-4 rounded bg-muted-foreground/40" />
</div> </div>
{/* 컴포넌트 수 */}
<div className="absolute bottom-2 right-2 rounded-md bg-foreground/80 px-2 py-1 text-[10px] font-medium text-primary-foreground shadow-sm">
{totalComponents}
</div>
</div> </div>
); );
} }
@ -374,10 +340,6 @@ const ScreenPreview: React.FC<{ layoutSummary: ScreenLayoutSummary; screenType:
<div className="h-5 w-14 rounded-md bg-muted-foreground/40 shadow-sm" /> <div className="h-5 w-14 rounded-md bg-muted-foreground/40 shadow-sm" />
<div className="h-5 w-14 rounded-md bg-primary shadow-sm" /> <div className="h-5 w-14 rounded-md bg-primary shadow-sm" />
</div> </div>
{/* 컴포넌트 수 */}
<div className="absolute bottom-2 right-2 rounded-md bg-foreground/80 px-2 py-1 text-[10px] font-medium text-primary-foreground shadow-sm">
{totalComponents}
</div>
</div> </div>
); );
} }
@ -406,10 +368,6 @@ const ScreenPreview: React.FC<{ layoutSummary: ScreenLayoutSummary; screenType:
/> />
))} ))}
</div> </div>
</div>
{/* 컴포넌트 수 */}
<div className="absolute bottom-2 right-2 rounded-md bg-foreground/80 px-2 py-1 text-[10px] font-medium text-primary-foreground shadow-sm">
{totalComponents}
</div> </div>
</div> </div>
); );
@ -427,10 +385,6 @@ const ScreenPreview: React.FC<{ layoutSummary: ScreenLayoutSummary; screenType:
<div className="h-7 w-16 rounded-md bg-muted-foreground/40 shadow-sm" /> <div className="h-7 w-16 rounded-md bg-muted-foreground/40 shadow-sm" />
</div> </div>
<div className="text-xs font-medium text-muted-foreground"> </div> <div className="text-xs font-medium text-muted-foreground"> </div>
{/* 컴포넌트 수 */}
<div className="absolute bottom-2 right-2 rounded-md bg-foreground/80 px-2 py-1 text-[10px] font-medium text-primary-foreground shadow-sm">
{totalComponents}
</div>
</div> </div>
); );
} }
@ -836,8 +790,7 @@ export const TableNode: React.FC<{ data: TableNodeData }> = ({ data }) => {
</div> </div>
{/* 푸터 (컴팩트) */} {/* 푸터 (컴팩트) */}
<div className="flex items-center justify-between border-t border-border bg-muted/30 px-2 py-1"> <div className="flex items-center justify-end border-t border-border bg-muted/30 px-2 py-1">
<span className="text-[9px] text-muted-foreground">PostgreSQL</span>
{columns && ( {columns && (
<span className="text-[9px] text-muted-foreground"> <span className="text-[9px] text-muted-foreground">
{hasActiveColumns ? `${displayColumns.length}/${totalCount}` : totalCount} {hasActiveColumns ? `${displayColumns.length}/${totalCount}` : totalCount}