연결 이름 수정 로직 수정
This commit is contained in:
parent
f715b5fa8c
commit
104faf487c
|
|
@ -13,11 +13,17 @@ import { RelationshipListModal } from "./RelationshipListModal";
|
|||
import { EdgeInfoPanel } from "./EdgeInfoPanel";
|
||||
import SaveDiagramModal from "./SaveDiagramModal";
|
||||
|
||||
import { TableDefinition, DataFlowAPI, JsonRelationship } from "@/lib/api/dataflow";
|
||||
import {
|
||||
TableDefinition,
|
||||
DataFlowAPI,
|
||||
JsonRelationship,
|
||||
TableRelationship,
|
||||
CreateDiagramRequest,
|
||||
} from "@/lib/api/dataflow";
|
||||
import { useAuth } from "@/hooks/useAuth";
|
||||
import { useDataFlowDesigner } from "@/hooks/useDataFlowDesigner";
|
||||
import { DataFlowDesignerProps, TableNodeData } from "@/types/dataflowTypes";
|
||||
import { extractTableNames } from "@/utils/dataflowUtils";
|
||||
import { extractTableNames, extractNodePositions } from "@/utils/dataflowUtils";
|
||||
|
||||
// 노드 및 엣지 타입 정의
|
||||
const nodeTypes = {
|
||||
|
|
@ -30,10 +36,10 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
companyCode: propCompanyCode = "*",
|
||||
diagramId,
|
||||
}) => {
|
||||
const { user } = useAuth();
|
||||
const { user: authUser } = useAuth();
|
||||
|
||||
// 실제 사용자 회사 코드 사용 (prop보다 사용자 정보 우선)
|
||||
const companyCode = user?.company_code || user?.companyCode || propCompanyCode;
|
||||
const companyCode = authUser?.company_code || authUser?.companyCode || propCompanyCode;
|
||||
|
||||
// 커스텀 훅 사용
|
||||
const {
|
||||
|
|
@ -196,11 +202,6 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
}));
|
||||
|
||||
setEdges(loadedEdges);
|
||||
|
||||
console.log("✅ 관계도 데이터 로드 완료:", {
|
||||
relationships: jsonDiagram.relationships?.relationships?.length || 0,
|
||||
tables: Array.from(new Set(loadedRelationships.flatMap((rel) => [rel.fromTable, rel.toTable]))).length,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
@ -386,8 +387,6 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
(rel.fromTable === toTable && rel.toTable === fromTable),
|
||||
);
|
||||
|
||||
console.log(`🔗 ${fromTable} ↔ ${toTable} 간의 관계:`, tablePairRelationships);
|
||||
|
||||
// 관계가 1개든 여러 개든 항상 관계 목록 모달 표시
|
||||
setSelectedTablePairRelationships(tablePairRelationships);
|
||||
setShowRelationshipListModal(true);
|
||||
|
|
@ -468,15 +467,102 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
};
|
||||
|
||||
// 연결 설정 확인
|
||||
const handleConfirmConnection = useCallback(() => {
|
||||
if (!pendingConnection) return;
|
||||
const handleConfirmConnection = useCallback(
|
||||
(relationshipData: TableRelationship) => {
|
||||
if (!pendingConnection || !relationshipData) return;
|
||||
|
||||
// 관계 생성 로직은 여기서 구현...
|
||||
// 현재는 간단히 성공 메시지만 표시
|
||||
toast.success("관계가 생성되었습니다.");
|
||||
setPendingConnection(null);
|
||||
setHasUnsavedChanges(true);
|
||||
}, [pendingConnection, setPendingConnection, setHasUnsavedChanges]);
|
||||
if (editingRelationshipId) {
|
||||
// 편집 모드: 기존 관계 업데이트
|
||||
const updatedRelationship = {
|
||||
id: editingRelationshipId,
|
||||
fromTable: relationshipData.from_table_name,
|
||||
toTable: relationshipData.to_table_name,
|
||||
fromColumns: relationshipData.from_column_name ? relationshipData.from_column_name.split(",") : [],
|
||||
toColumns: relationshipData.to_column_name ? relationshipData.to_column_name.split(",") : [],
|
||||
connectionType: relationshipData.connection_type as "simple-key" | "data-save" | "external-call",
|
||||
relationshipName: relationshipData.relationship_name,
|
||||
settings: relationshipData.settings || {},
|
||||
};
|
||||
|
||||
// tempRelationships에서 기존 관계 업데이트
|
||||
setTempRelationships((prev) =>
|
||||
prev.map((rel) => (rel.id === editingRelationshipId ? updatedRelationship : rel)),
|
||||
);
|
||||
|
||||
// 기존 엣지 업데이트
|
||||
setEdges((prevEdges) =>
|
||||
prevEdges.map((edge) =>
|
||||
edge.data?.relationshipId === editingRelationshipId
|
||||
? {
|
||||
...edge,
|
||||
data: {
|
||||
...edge.data,
|
||||
relationshipId: editingRelationshipId,
|
||||
fromTable: relationshipData.from_table_name,
|
||||
toTable: relationshipData.to_table_name,
|
||||
connectionType: relationshipData.connection_type,
|
||||
relationshipName: relationshipData.relationship_name,
|
||||
},
|
||||
}
|
||||
: edge,
|
||||
),
|
||||
);
|
||||
|
||||
// 편집 모드 종료
|
||||
setEditingRelationshipId(null);
|
||||
} else {
|
||||
// 새로 생성 모드: 새로운 관계 추가
|
||||
const newRelationship = {
|
||||
id: `rel-${Date.now()}`,
|
||||
fromTable: relationshipData.from_table_name,
|
||||
toTable: relationshipData.to_table_name,
|
||||
fromColumns: relationshipData.from_column_name ? relationshipData.from_column_name.split(",") : [],
|
||||
toColumns: relationshipData.to_column_name ? relationshipData.to_column_name.split(",") : [],
|
||||
connectionType: relationshipData.connection_type as "simple-key" | "data-save" | "external-call",
|
||||
relationshipName: relationshipData.relationship_name,
|
||||
settings: relationshipData.settings || {},
|
||||
};
|
||||
|
||||
// tempRelationships 상태 업데이트
|
||||
setTempRelationships((prev) => [...prev, newRelationship]);
|
||||
|
||||
// 새로운 엣지 생성
|
||||
const newEdge = {
|
||||
id: `edge-${relationshipData.from_table_name}-${relationshipData.to_table_name}-${Date.now()}`,
|
||||
source: `table-${relationshipData.from_table_name}`,
|
||||
target: `table-${relationshipData.to_table_name}`,
|
||||
type: "step",
|
||||
data: {
|
||||
relationshipId: newRelationship.id,
|
||||
fromTable: relationshipData.from_table_name,
|
||||
toTable: relationshipData.to_table_name,
|
||||
connectionType: relationshipData.connection_type,
|
||||
relationshipName: relationshipData.relationship_name,
|
||||
},
|
||||
style: {
|
||||
stroke: "#3b82f6",
|
||||
strokeWidth: 2,
|
||||
},
|
||||
animated: false,
|
||||
};
|
||||
|
||||
// 엣지 추가
|
||||
setEdges((prevEdges) => [...prevEdges, newEdge]);
|
||||
}
|
||||
|
||||
setPendingConnection(null);
|
||||
setHasUnsavedChanges(true);
|
||||
},
|
||||
[
|
||||
pendingConnection,
|
||||
setPendingConnection,
|
||||
setHasUnsavedChanges,
|
||||
setTempRelationships,
|
||||
setEdges,
|
||||
editingRelationshipId,
|
||||
setEditingRelationshipId,
|
||||
],
|
||||
);
|
||||
|
||||
// 연결 설정 취소
|
||||
const handleCancelConnection = useCallback(() => {
|
||||
|
|
@ -499,7 +585,7 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
}
|
||||
}, [isSaving, setShowSaveModal]);
|
||||
|
||||
// 관계도 저장 함수 (간단한 구현)
|
||||
// 관계도 저장 함수
|
||||
const handleSaveDiagram = useCallback(
|
||||
async (diagramName: string) => {
|
||||
if (nodes.length === 0) {
|
||||
|
|
@ -509,7 +595,74 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
|
||||
setIsSaving(true);
|
||||
try {
|
||||
// 여기서 실제 저장 로직 구현
|
||||
// 노드 위치 정보 추출
|
||||
const nodePositions = extractNodePositions(nodes);
|
||||
|
||||
// 연결된 테이블 목록 추출
|
||||
const tableNames = extractTableNames(nodes);
|
||||
|
||||
// 관계 데이터를 JsonRelationship 형태로 변환
|
||||
const jsonRelationships: JsonRelationship[] = tempRelationships.map((rel) => ({
|
||||
id: rel.id,
|
||||
relationshipName: rel.relationshipName, // 🔥 핵심: 관계 이름 포함
|
||||
fromTable: rel.fromTable,
|
||||
toTable: rel.toTable,
|
||||
fromColumns: rel.fromColumns,
|
||||
toColumns: rel.toColumns,
|
||||
connectionType: rel.connectionType,
|
||||
settings: rel.settings,
|
||||
}));
|
||||
|
||||
// 저장 요청 데이터 구성
|
||||
const saveRequest: CreateDiagramRequest = {
|
||||
diagram_name: diagramName,
|
||||
relationships: {
|
||||
relationships: jsonRelationships,
|
||||
tables: tableNames,
|
||||
},
|
||||
node_positions: nodePositions,
|
||||
// 카테고리 정보 추가
|
||||
category: tempRelationships.map((rel) => ({
|
||||
id: rel.id,
|
||||
category: rel.connectionType,
|
||||
})),
|
||||
// 조건부 연결 설정이 있는 경우 추가
|
||||
control: tempRelationships
|
||||
.filter((rel) => rel.settings?.control)
|
||||
.map((rel) => ({
|
||||
id: rel.id,
|
||||
triggerType: rel.settings?.control?.triggerType || "insert",
|
||||
conditions: (rel.settings?.control?.conditionTree || []).map((condition: Record<string, unknown>) => ({
|
||||
...condition,
|
||||
logicalOperator:
|
||||
condition.logicalOperator === "AND" || condition.logicalOperator === "OR"
|
||||
? condition.logicalOperator
|
||||
: undefined,
|
||||
})),
|
||||
})),
|
||||
// 데이터 저장 액션이 있는 경우 추가
|
||||
plan: tempRelationships
|
||||
.filter((rel) => rel.settings?.actions && Array.isArray(rel.settings.actions))
|
||||
.map((rel) => ({
|
||||
id: rel.id,
|
||||
sourceTable: rel.fromTable,
|
||||
actions: rel.settings?.actions || [],
|
||||
})),
|
||||
};
|
||||
|
||||
if (diagramId && diagramId > 0) {
|
||||
// 기존 관계도 수정
|
||||
await DataFlowAPI.updateJsonDataFlowDiagram(
|
||||
diagramId,
|
||||
saveRequest,
|
||||
companyCode,
|
||||
authUser?.userId || "SYSTEM",
|
||||
);
|
||||
} else {
|
||||
// 새로운 관계도 생성
|
||||
await DataFlowAPI.createJsonDataFlowDiagram(saveRequest, companyCode, authUser?.userId || "SYSTEM");
|
||||
}
|
||||
|
||||
toast.success(`관계도 "${diagramName}"가 성공적으로 저장되었습니다.`);
|
||||
setHasUnsavedChanges(false);
|
||||
setShowSaveModal(false);
|
||||
|
|
@ -520,7 +673,16 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
setIsSaving(false);
|
||||
}
|
||||
},
|
||||
[nodes, setIsSaving, setHasUnsavedChanges, setShowSaveModal],
|
||||
[
|
||||
nodes,
|
||||
tempRelationships,
|
||||
diagramId,
|
||||
companyCode,
|
||||
authUser?.userId,
|
||||
setIsSaving,
|
||||
setHasUnsavedChanges,
|
||||
setShowSaveModal,
|
||||
],
|
||||
);
|
||||
|
||||
// 고립된 노드 제거 함수
|
||||
|
|
@ -608,7 +770,11 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
{/* 관계 목록 모달 */}
|
||||
<RelationshipListModal
|
||||
isOpen={showRelationshipListModal}
|
||||
relationships={selectedTablePairRelationships}
|
||||
relationships={selectedTablePairRelationships.map((rel) => {
|
||||
// 최신 tempRelationships에서 해당 관계 찾기
|
||||
const updatedRel = tempRelationships.find((tempRel) => tempRel.id === rel.id);
|
||||
return updatedRel || rel; // 업데이트된 관계가 있으면 사용, 없으면 원본 사용
|
||||
})}
|
||||
nodes={nodes}
|
||||
diagramId={diagramId}
|
||||
companyCode={companyCode}
|
||||
|
|
@ -682,8 +848,76 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
|
|||
setSelectedEdgeForEdit(null);
|
||||
setSelectedColumns({});
|
||||
}}
|
||||
onEdit={() => {}}
|
||||
onDelete={() => {}}
|
||||
onEdit={() => {
|
||||
if (selectedEdgeInfo) {
|
||||
// 기존 관계 찾기
|
||||
const existingRelationship = tempRelationships.find((rel) => rel.id === selectedEdgeInfo.relationshipId);
|
||||
|
||||
if (existingRelationship) {
|
||||
// 편집 모드로 설정
|
||||
setEditingRelationshipId(selectedEdgeInfo.relationshipId);
|
||||
|
||||
// 연결 설정 모달 열기
|
||||
const fromTable = nodes.find((node) => node.data?.table?.tableName === selectedEdgeInfo.fromTable);
|
||||
const toTable = nodes.find((node) => node.data?.table?.tableName === selectedEdgeInfo.toTable);
|
||||
|
||||
if (fromTable && toTable) {
|
||||
setPendingConnection({
|
||||
fromNode: {
|
||||
id: fromTable.id,
|
||||
tableName: selectedEdgeInfo.fromTable,
|
||||
displayName: fromTable.data?.table?.displayName || selectedEdgeInfo.fromTable,
|
||||
},
|
||||
toNode: {
|
||||
id: toTable.id,
|
||||
tableName: selectedEdgeInfo.toTable,
|
||||
displayName: toTable.data?.table?.displayName || selectedEdgeInfo.toTable,
|
||||
},
|
||||
selectedColumnsData: {
|
||||
[selectedEdgeInfo.fromTable]: {
|
||||
displayName: fromTable.data?.table?.displayName || selectedEdgeInfo.fromTable,
|
||||
columns: selectedEdgeInfo.fromColumns || [],
|
||||
},
|
||||
[selectedEdgeInfo.toTable]: {
|
||||
displayName: toTable.data?.table?.displayName || selectedEdgeInfo.toTable,
|
||||
columns: selectedEdgeInfo.toColumns || [],
|
||||
},
|
||||
},
|
||||
existingRelationship: {
|
||||
relationshipName: existingRelationship.relationshipName,
|
||||
connectionType: existingRelationship.connectionType,
|
||||
settings: existingRelationship.settings,
|
||||
},
|
||||
});
|
||||
|
||||
// 패널 닫기
|
||||
setSelectedEdgeInfo(null);
|
||||
setShowEdgeActions(false);
|
||||
setSelectedEdgeForEdit(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
onDelete={() => {
|
||||
if (selectedEdgeInfo) {
|
||||
// 관계 삭제
|
||||
setTempRelationships((prev) => prev.filter((rel) => rel.id !== selectedEdgeInfo.relationshipId));
|
||||
|
||||
// 엣지 삭제
|
||||
setEdges((prev) => prev.filter((edge) => edge.data?.relationshipId !== selectedEdgeInfo.relationshipId));
|
||||
|
||||
// 변경사항 표시
|
||||
setHasUnsavedChanges(true);
|
||||
|
||||
// 패널 닫기
|
||||
setSelectedEdgeInfo(null);
|
||||
setShowEdgeActions(false);
|
||||
setSelectedEdgeForEdit(null);
|
||||
setSelectedColumns({});
|
||||
|
||||
toast.success("관계가 삭제되었습니다.");
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 관계도 저장 모달 */}
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ export const RelationshipListModal: React.FC<RelationshipListModalProps> = ({
|
|||
>
|
||||
<div className="mb-1 flex items-center justify-between">
|
||||
<h4 className="text-sm font-medium text-gray-900">
|
||||
{relationship.fromTable} → {relationship.toTable}
|
||||
{relationship.relationshipName || `${relationship.fromTable} → ${relationship.toTable}`}
|
||||
</h4>
|
||||
<div className="flex items-center gap-1">
|
||||
{/* 편집 버튼 */}
|
||||
|
|
|
|||
|
|
@ -155,11 +155,11 @@ const SaveDiagramModal: React.FC<SaveDiagramModalProps> = ({
|
|||
<div className="flex-1">
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
{relationship.relationshipType}
|
||||
{relationship.connectionType || "simple-key"}
|
||||
</Badge>
|
||||
<span className="font-medium">{relationship.fromTable}</span>
|
||||
<span className="text-gray-500">→</span>
|
||||
<span className="font-medium">{relationship.toTable}</span>
|
||||
<span className="font-medium">
|
||||
{relationship.relationshipName || `${relationship.fromTable} → ${relationship.toTable}`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-1 text-xs text-gray-600">
|
||||
{relationship.fromColumns.join(", ")} → {relationship.toColumns.join(", ")}
|
||||
|
|
|
|||
Loading…
Reference in New Issue