기타 수정사항 적용

This commit is contained in:
hyeonsu 2025-09-11 10:45:16 +09:00
parent fe6c0af5a8
commit 8e64b338a1
4 changed files with 36 additions and 82 deletions

View File

@ -15,7 +15,6 @@ export default function DataFlowPage() {
const { user } = useAuth(); const { user } = useAuth();
const router = useRouter(); const router = useRouter();
const [currentStep, setCurrentStep] = useState<Step>("list"); const [currentStep, setCurrentStep] = useState<Step>("list");
const [selectedDiagram, setSelectedDiagram] = useState<DataFlowDiagram | null>(null);
const [stepHistory, setStepHistory] = useState<Step[]>(["list"]); const [stepHistory, setStepHistory] = useState<Step[]>(["list"]);
// 단계별 제목과 설명 // 단계별 제목과 설명
@ -26,10 +25,8 @@ export default function DataFlowPage() {
icon: "📊", icon: "📊",
}, },
design: { design: {
title: selectedDiagram ? `${selectedDiagram.diagramName} 관계도 설계` : "새 관계도 설계", title: "새 관계도 설계",
description: selectedDiagram description: "테이블 간 데이터 관계를 시각적으로 설계하세요",
? "기존 관계도를 수정하거나 새로운 관계를 추가하세요"
: "테이블 간 데이터 관계를 시각적으로 설계하세요",
icon: "🎨", icon: "🎨",
}, },
}; };
@ -47,11 +44,6 @@ export default function DataFlowPage() {
const previousStep = newHistory[newHistory.length - 1]; const previousStep = newHistory[newHistory.length - 1];
setStepHistory(newHistory); setStepHistory(newHistory);
setCurrentStep(previousStep); setCurrentStep(previousStep);
// list로 돌아갈 때 선택된 관계도 초기화
if (previousStep === "list") {
setSelectedDiagram(null);
}
} }
}; };
@ -63,11 +55,6 @@ export default function DataFlowPage() {
if (stepIndex !== -1) { if (stepIndex !== -1) {
setStepHistory(stepHistory.slice(0, stepIndex + 1)); setStepHistory(stepHistory.slice(0, stepIndex + 1));
} }
// list로 이동할 때 선택된 관계도 초기화
if (step === "list") {
setSelectedDiagram(null);
}
}; };
const handleSave = (relationships: TableRelationship[]) => { const handleSave = (relationships: TableRelationship[]) => {
@ -78,17 +65,12 @@ export default function DataFlowPage() {
}, 0); }, 0);
}; };
const handleDiagramSelect = (diagram: DataFlowDiagram) => {
setSelectedDiagram(diagram);
};
const handleDesignDiagram = (diagram: DataFlowDiagram | null) => { const handleDesignDiagram = (diagram: DataFlowDiagram | null) => {
if (diagram) { if (diagram) {
// 기존 관계도 편집 - 새로운 URL로 이동 // 기존 관계도 편집 - 새로운 URL로 이동
router.push(`/admin/dataflow/edit/${diagram.diagramId}`); router.push(`/admin/dataflow/edit/${diagram.diagramId}`);
} else { } else {
// 새 관계도 생성 - 현재 페이지에서 처리 // 새 관계도 생성 - 현재 페이지에서 처리
setSelectedDiagram(null);
goToNextStep("design"); goToNextStep("design");
} }
}; };
@ -121,11 +103,7 @@ export default function DataFlowPage() {
{/* 관계도 목록 단계 */} {/* 관계도 목록 단계 */}
{currentStep === "list" && ( {currentStep === "list" && (
<div className="h-full p-6"> <div className="h-full p-6">
<DataFlowList <DataFlowList onDesignDiagram={handleDesignDiagram} />
onDiagramSelect={handleDiagramSelect}
selectedDiagram={selectedDiagram}
onDesignDiagram={handleDesignDiagram}
/>
</div> </div>
)} )}
@ -135,7 +113,7 @@ export default function DataFlowPage() {
<DataFlowDesigner <DataFlowDesigner
companyCode={user?.company_code || "COMP001"} companyCode={user?.company_code || "COMP001"}
onSave={handleSave} onSave={handleSave}
selectedDiagram={selectedDiagram} selectedDiagram={null}
onBackToList={() => goToStep("list")} onBackToList={() => goToStep("list")}
/> />
</div> </div>

View File

@ -32,6 +32,12 @@ interface ConnectionInfo {
columns: string[]; columns: string[];
}; };
}; };
existingRelationship?: {
relationshipName: string;
relationshipType: string;
connectionType: string;
settings?: any;
};
} }
// 연결 설정 타입 // 연결 설정 타입
@ -150,14 +156,18 @@ export const ConnectionSetupModal: React.FC<ConnectionSetupModalProps> = ({
setSelectedFromTable(fromTableName); setSelectedFromTable(fromTableName);
setSelectedToTable(toTableName); setSelectedToTable(toTableName);
// 기존 관계 정보가 있으면 사용, 없으면 기본값 설정
const existingRel = connection.existingRelationship;
setConfig({ setConfig({
relationshipName: `${fromDisplayName}${toDisplayName}`, relationshipName: existingRel?.relationshipName || `${fromDisplayName}${toDisplayName}`,
relationshipType: "one-to-one", relationshipType:
connectionType: "simple-key", (existingRel?.relationshipType as "one-to-one" | "one-to-many" | "many-to-one" | "many-to-many") ||
"one-to-one",
connectionType: (existingRel?.connectionType as "simple-key" | "data-save" | "external-call") || "simple-key",
fromColumnName: "", fromColumnName: "",
toColumnName: "", toColumnName: "",
description: `${fromDisplayName}${toDisplayName} 간의 데이터 관계`, description: existingRel?.settings?.description || `${fromDisplayName}${toDisplayName} 간의 데이터 관계`,
settings: {}, settings: existingRel?.settings || {},
}); });
// 단순 키값 연결 기본값 설정 // 단순 키값 연결 기본값 설정

View File

@ -101,6 +101,12 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
columns: string[]; columns: string[];
}; };
}; };
existingRelationship?: {
relationshipName: string;
relationshipType: string;
connectionType: string;
settings?: any;
};
} | null>(null); } | null>(null);
const [relationships, setRelationships] = useState<TableRelationship[]>([]); // eslint-disable-line @typescript-eslint/no-unused-vars const [relationships, setRelationships] = useState<TableRelationship[]>([]); // eslint-disable-line @typescript-eslint/no-unused-vars
const [currentDiagramId, setCurrentDiagramId] = useState<number | null>(null); // 현재 화면의 diagram_id const [currentDiagramId, setCurrentDiagramId] = useState<number | null>(null); // 현재 화면의 diagram_id
@ -989,6 +995,13 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
columns: edgeData.toColumns, columns: edgeData.toColumns,
}, },
}, },
// 기존 관계 정보 추가 (연결 이름 유지를 위해)
existingRelationship: {
relationshipName: existingRelationship.relationshipName,
relationshipType: existingRelationship.relationshipType,
connectionType: existingRelationship.connectionType,
settings: existingRelationship.settings,
},
}; };
// ConnectionSetupModal을 위한 연결 정보 설정 // ConnectionSetupModal을 위한 연결 정보 설정
@ -1123,8 +1136,8 @@ export const DataFlowDesigner: React.FC<DataFlowDesignerProps> = ({
<Background variant={BackgroundVariant.Dots} gap={20} size={1} color="#E5E7EB" /> <Background variant={BackgroundVariant.Dots} gap={20} size={1} color="#E5E7EB" />
</ReactFlow> </ReactFlow>
{/* 선택된 컬럼 팝업 - 캔버스 좌측 상단 고정 (엣지 정보 팝업이 없을 때만 표시) */} {/* 선택된 컬럼 팝업 - 캔버스 좌측 상단 고정 (신규 관계도 생성 시에만 표시) */}
{Object.keys(selectedColumns).length > 0 && !showEdgeActions && ( {Object.keys(selectedColumns).length > 0 && !showEdgeActions && !pendingConnection && !diagramId && (
<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="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 justify-between rounded-t-xl border-b border-blue-100 bg-gradient-to-r from-blue-50 to-indigo-50 p-3">

View File

@ -3,7 +3,6 @@
import { useState, useEffect, useCallback } from "react"; import { useState, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { import {
@ -26,12 +25,10 @@ import { toast } from "sonner";
import { useAuth } from "@/hooks/useAuth"; import { useAuth } from "@/hooks/useAuth";
interface DataFlowListProps { interface DataFlowListProps {
onDiagramSelect: (diagram: DataFlowDiagram) => void;
selectedDiagram: DataFlowDiagram | null;
onDesignDiagram: (diagram: DataFlowDiagram | null) => void; onDesignDiagram: (diagram: DataFlowDiagram | null) => void;
} }
export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesignDiagram }: DataFlowListProps) { export default function DataFlowList({ onDesignDiagram }: DataFlowListProps) {
const { user } = useAuth(); const { user } = useAuth();
const [diagrams, setDiagrams] = useState<DataFlowDiagram[]>([]); const [diagrams, setDiagrams] = useState<DataFlowDiagram[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@ -88,10 +85,6 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
loadDiagrams(); loadDiagrams();
}, [loadDiagrams]); }, [loadDiagrams]);
const handleDiagramSelect = (diagram: DataFlowDiagram) => {
onDiagramSelect(diagram);
};
const handleDelete = (diagram: DataFlowDiagram) => { const handleDelete = (diagram: DataFlowDiagram) => {
setSelectedDiagramForAction(diagram); setSelectedDiagramForAction(diagram);
setShowDeleteModal(true); setShowDeleteModal(true);
@ -149,38 +142,6 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
} }
}; };
// 연결 타입에 따른 배지 색상
const getConnectionTypeBadge = (connectionType: string) => {
switch (connectionType) {
case "simple-key":
return (
<Badge variant="outline" className="border-blue-200 bg-blue-50 text-blue-700">
</Badge>
);
case "data-save":
return (
<Badge variant="outline" className="border-green-200 bg-green-50 text-green-700">
</Badge>
);
case "external-call":
return (
<Badge variant="outline" className="border-purple-200 bg-purple-50 text-purple-700">
</Badge>
);
case "json-based":
return (
<Badge variant="outline" className="border-indigo-200 bg-indigo-50 text-indigo-700">
JSON
</Badge>
);
default:
return <Badge variant="outline">{connectionType}</Badge>;
}
};
if (loading) { if (loading) {
return ( return (
<div className="flex items-center justify-center py-8"> <div className="flex items-center justify-center py-8">
@ -224,7 +185,6 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead></TableHead> <TableHead></TableHead>
<TableHead> </TableHead>
<TableHead> </TableHead> <TableHead> </TableHead>
<TableHead> </TableHead> <TableHead> </TableHead>
<TableHead> </TableHead> <TableHead> </TableHead>
@ -234,13 +194,7 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{diagrams.map((diagram) => ( {diagrams.map((diagram) => (
<TableRow <TableRow key={diagram.diagramId} className="hover:bg-gray-50">
key={diagram.diagramId}
className={`cursor-pointer hover:bg-gray-50 ${
selectedDiagram?.diagramId === diagram.diagramId ? "border-blue-200 bg-blue-50" : ""
}`}
onClick={() => handleDiagramSelect(diagram)}
>
<TableCell> <TableCell>
<div> <div>
<div className="flex items-center font-medium text-gray-900"> <div className="flex items-center font-medium text-gray-900">
@ -253,7 +207,6 @@ export default function DataFlowList({ onDiagramSelect, selectedDiagram, onDesig
</div> </div>
</div> </div>
</TableCell> </TableCell>
<TableCell>{getConnectionTypeBadge(diagram.connectionType)}</TableCell>
<TableCell>{diagram.companyCode || "*"}</TableCell> <TableCell>{diagram.companyCode || "*"}</TableCell>
<TableCell> <TableCell>
<div className="flex items-center"> <div className="flex items-center">