선택된 컬럼 섹션 위치 변경

This commit is contained in:
hyeonsu 2025-09-10 18:35:55 +09:00
parent f97e414df9
commit fe6c0af5a8
1 changed files with 93 additions and 67 deletions

View File

@ -1089,73 +1089,6 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
</div>
{/* 선택된 컬럼 정보 */}
{Object.keys(selectedColumns).length > 0 && (
<div className="mt-6 space-y-4">
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4">
<div className="mb-3 text-sm font-semibold text-blue-800"> </div>
<div className="space-y-3">
{[...new Set(selectionOrder)]
.filter((tableName) => selectedColumns[tableName] && selectedColumns[tableName].length > 0)
.map((tableName, index, filteredOrder) => {
const columns = selectedColumns[tableName];
const node = nodes.find((n) => n.data.table.tableName === tableName);
const displayName = node?.data.table.displayName || tableName;
return (
<div key={`selected-${tableName}-${index}`}>
<div className="w-full min-w-0 rounded-lg border border-blue-300 bg-white p-3">
<div className="mb-2 flex flex-wrap items-center gap-2">
<div className="flex-shrink-0 rounded px-2 py-1 text-xs font-medium text-blue-600">
{displayName}
</div>
</div>
<div className="flex w-full min-w-0 flex-wrap gap-1">
{columns.map((column, columnIndex) => (
<div
key={`${tableName}-${column}-${columnIndex}`}
className="max-w-full truncate rounded-full border border-blue-200 bg-blue-100 px-2 py-1 text-xs text-blue-800"
title={column}
>
{column}
</div>
))}
</div>
</div>
{/* 첫 번째 테이블 다음에 화살표 표시 */}
{index === 0 && filteredOrder.length > 1 && (
<div className="flex justify-center py-2">
<div className="text-gray-400"></div>
</div>
)}
</div>
);
})}
</div>
<div className="mt-3 flex gap-2">
<button
onClick={openConnectionModal}
disabled={!canCreateConnection()}
className={`w-full rounded px-3 py-1 text-xs font-medium transition-colors ${
canCreateConnection()
? "cursor-pointer bg-blue-600 text-white hover:bg-blue-700"
: "cursor-not-allowed bg-gray-300 text-gray-500"
}`}
>
</button>
<button
onClick={() => {
setSelectedColumns({});
setSelectionOrder([]);
}}
className="w-full cursor-pointer rounded bg-gray-200 px-3 py-1 text-xs font-medium text-gray-600 hover:bg-gray-300"
>
</button>
</div>
</div>
</div>
)}
</div>
</div>
@ -1190,6 +1123,99 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
<Background variant={BackgroundVariant.Dots} gap={20} size={1} color="#E5E7EB" />
</ReactFlow>
{/* 선택된 컬럼 팝업 - 캔버스 좌측 상단 고정 (엣지 정보 팝업이 없을 때만 표시) */}
{Object.keys(selectedColumns).length > 0 && !showEdgeActions && (
<div className="pointer-events-auto absolute top-4 left-4 z-40 w-80 rounded-xl border border-blue-200 bg-white shadow-lg">
{/* 헤더 */}
<div className="flex items-center justify-between rounded-t-xl border-b border-blue-100 bg-gradient-to-r from-blue-50 to-indigo-50 p-3">
<div className="flex items-center gap-2">
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-blue-100">
<span className="text-sm text-blue-600">📋</span>
</div>
<div>
<div className="text-sm font-semibold text-gray-800"> </div>
<div className="text-xs text-gray-500">{Object.keys(selectedColumns).length} </div>
</div>
</div>
<button
onClick={() => {
setSelectedColumns({});
setSelectionOrder([]);
}}
className="flex h-5 w-5 items-center justify-center rounded-full text-gray-400 hover:bg-gray-100 hover:text-gray-600"
>
</button>
</div>
{/* 컨텐츠 */}
<div className="max-h-80 overflow-y-auto p-3">
<div className="space-y-3">
{[...new Set(selectionOrder)]
.filter((tableName) => selectedColumns[tableName] && selectedColumns[tableName].length > 0)
.map((tableName, index, filteredOrder) => {
const columns = selectedColumns[tableName];
const node = nodes.find((n) => n.data.table.tableName === tableName);
const displayName = node?.data.table.displayName || tableName;
return (
<div key={`selected-${tableName}-${index}`}>
{/* 테이블 정보 */}
<div className="rounded-lg bg-blue-50 p-2">
<div className="mb-1 text-xs font-medium text-blue-700">{displayName}</div>
<div className="flex flex-wrap gap-1">
{columns.map((column, columnIndex) => (
<span
key={`${tableName}-${column}-${columnIndex}`}
className="rounded bg-blue-100 px-2 py-1 text-xs text-blue-800"
title={column}
>
{column}
</span>
))}
</div>
</div>
{/* 화살표 */}
{index === 0 && filteredOrder.length > 1 && (
<div className="flex justify-center py-1">
<div className="text-sm text-gray-400"></div>
</div>
)}
</div>
);
})}
</div>
</div>
{/* 액션 버튼 */}
<div className="flex gap-2 border-t border-blue-100 p-3">
<button
onClick={openConnectionModal}
disabled={!canCreateConnection()}
className={`flex flex-1 items-center justify-center gap-1 rounded-lg px-3 py-2 text-xs font-medium transition-colors ${
canCreateConnection()
? "bg-blue-500 text-white hover:bg-blue-600"
: "cursor-not-allowed bg-gray-300 text-gray-500"
}`}
>
<span>🔗</span>
<span> </span>
</button>
<button
onClick={() => {
setSelectedColumns({});
setSelectionOrder([]);
}}
className="flex flex-1 items-center justify-center gap-1 rounded-lg bg-gray-200 px-3 py-2 text-xs font-medium text-gray-600 hover:bg-gray-300"
>
<span>🗑</span>
<span></span>
</button>
</div>
</div>
)}
{/* 안내 메시지 */}
{nodes.length === 0 && (
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">