get요청 db 저장기능
This commit is contained in:
@@ -30,6 +30,7 @@ interface DataMappingSettingsProps {
|
||||
httpMethod: string;
|
||||
availableTables?: TableInfo[];
|
||||
readonly?: boolean;
|
||||
tablesLoading?: boolean;
|
||||
}
|
||||
|
||||
export const DataMappingSettings: React.FC<DataMappingSettingsProps> = ({
|
||||
@@ -38,6 +39,7 @@ export const DataMappingSettings: React.FC<DataMappingSettingsProps> = ({
|
||||
httpMethod,
|
||||
availableTables = [],
|
||||
readonly = false,
|
||||
tablesLoading = false,
|
||||
}) => {
|
||||
const [localConfig, setLocalConfig] = useState<DataMappingConfig>(config);
|
||||
|
||||
@@ -228,17 +230,27 @@ export const DataMappingSettings: React.FC<DataMappingSettingsProps> = ({
|
||||
<Select
|
||||
value={localConfig.inboundMapping?.targetTable || ""}
|
||||
onValueChange={(value) => handleInboundMappingChange({ targetTable: value })}
|
||||
disabled={readonly}
|
||||
disabled={readonly || tablesLoading}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="저장할 테이블을 선택하세요" />
|
||||
<SelectValue placeholder={tablesLoading ? "테이블 목록 로딩 중..." : "저장할 테이블을 선택하세요"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{availableTables.map((table) => (
|
||||
<SelectItem key={table.name} value={table.name}>
|
||||
{table.displayName || table.name}
|
||||
{tablesLoading ? (
|
||||
<SelectItem value="" disabled>
|
||||
테이블 목록 로딩 중...
|
||||
</SelectItem>
|
||||
))}
|
||||
) : availableTables.length === 0 ? (
|
||||
<SelectItem value="" disabled>
|
||||
사용 가능한 테이블이 없습니다
|
||||
</SelectItem>
|
||||
) : (
|
||||
availableTables.map((table) => (
|
||||
<SelectItem key={table.name} value={table.name}>
|
||||
{table.displayName || table.name}
|
||||
</SelectItem>
|
||||
))
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,10 @@ import {
|
||||
} from "@/types/external-call/ExternalCallTypes";
|
||||
import { DataMappingConfig, TableInfo } from "@/types/external-call/DataMappingTypes";
|
||||
|
||||
// API import
|
||||
import { DataFlowAPI } from "@/lib/api/dataflow";
|
||||
import { toast } from "sonner";
|
||||
|
||||
// 하위 컴포넌트 import
|
||||
import RestApiSettings from "./RestApiSettings";
|
||||
import ExternalCallTestPanel from "./ExternalCallTestPanel";
|
||||
@@ -41,8 +45,14 @@ const ExternalCallPanel: React.FC<ExternalCallPanelProps> = ({
|
||||
});
|
||||
// 상태 관리
|
||||
const [config, setConfig] = useState<ExternalCallConfig>(
|
||||
() =>
|
||||
initialSettings || {
|
||||
() => {
|
||||
if (initialSettings) {
|
||||
console.log("🔄 [ExternalCallPanel] 기존 설정 로드:", initialSettings);
|
||||
return initialSettings;
|
||||
}
|
||||
|
||||
console.log("🔄 [ExternalCallPanel] 기본 설정 사용");
|
||||
return {
|
||||
callType: "rest-api",
|
||||
restApiSettings: {
|
||||
apiUrl: "",
|
||||
@@ -63,7 +73,8 @@ const ExternalCallPanel: React.FC<ExternalCallPanelProps> = ({
|
||||
timeout: 30000, // 30초
|
||||
retryCount: 3,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
const [activeTab, setActiveTab] = useState<string>("settings");
|
||||
@@ -71,48 +82,69 @@ const ExternalCallPanel: React.FC<ExternalCallPanelProps> = ({
|
||||
const [isConfigValid, setIsConfigValid] = useState<boolean>(false);
|
||||
|
||||
// 데이터 매핑 상태
|
||||
const [dataMappingConfig, setDataMappingConfig] = useState<DataMappingConfig>(() => ({
|
||||
direction: "none",
|
||||
}));
|
||||
const [dataMappingConfig, setDataMappingConfig] = useState<DataMappingConfig>(() => {
|
||||
// initialSettings에서 데이터 매핑 정보 불러오기
|
||||
if (initialSettings?.dataMappingConfig) {
|
||||
console.log("🔄 [ExternalCallPanel] 기존 데이터 매핑 설정 로드:", initialSettings.dataMappingConfig);
|
||||
return initialSettings.dataMappingConfig;
|
||||
}
|
||||
|
||||
console.log("🔄 [ExternalCallPanel] 기본 데이터 매핑 설정 사용");
|
||||
return {
|
||||
direction: "none",
|
||||
};
|
||||
});
|
||||
|
||||
// 사용 가능한 테이블 목록 (임시 데이터)
|
||||
const [availableTables] = useState<TableInfo[]>([
|
||||
{
|
||||
name: "customers",
|
||||
displayName: "고객",
|
||||
fields: [
|
||||
{ name: "id", dataType: "number", nullable: false, isPrimaryKey: true },
|
||||
{ name: "name", dataType: "string", nullable: false },
|
||||
{ name: "email", dataType: "string", nullable: true },
|
||||
{ name: "phone", dataType: "string", nullable: true },
|
||||
{ name: "created_at", dataType: "date", nullable: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "orders",
|
||||
displayName: "주문",
|
||||
fields: [
|
||||
{ name: "id", dataType: "number", nullable: false, isPrimaryKey: true },
|
||||
{ name: "customer_id", dataType: "number", nullable: false },
|
||||
{ name: "product_name", dataType: "string", nullable: false },
|
||||
{ name: "quantity", dataType: "number", nullable: false },
|
||||
{ name: "price", dataType: "number", nullable: false },
|
||||
{ name: "status", dataType: "string", nullable: false },
|
||||
{ name: "order_date", dataType: "date", nullable: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "products",
|
||||
displayName: "제품",
|
||||
fields: [
|
||||
{ name: "id", dataType: "number", nullable: false, isPrimaryKey: true },
|
||||
{ name: "name", dataType: "string", nullable: false },
|
||||
{ name: "price", dataType: "number", nullable: false },
|
||||
{ name: "stock", dataType: "number", nullable: false },
|
||||
{ name: "category", dataType: "string", nullable: true },
|
||||
],
|
||||
},
|
||||
]);
|
||||
// 사용 가능한 테이블 목록 (실제 API에서 로드)
|
||||
const [availableTables, setAvailableTables] = useState<TableInfo[]>([]);
|
||||
const [tablesLoading, setTablesLoading] = useState(false);
|
||||
|
||||
// 테이블 목록 로드
|
||||
useEffect(() => {
|
||||
const loadTables = async () => {
|
||||
try {
|
||||
setTablesLoading(true);
|
||||
const tables = await DataFlowAPI.getTables();
|
||||
|
||||
// 테이블 정보를 TableInfo 형식으로 변환
|
||||
const tableInfos: TableInfo[] = await Promise.all(
|
||||
tables.map(async (table) => {
|
||||
try {
|
||||
const columns = await DataFlowAPI.getTableColumns(table.tableName);
|
||||
return {
|
||||
name: table.tableName,
|
||||
displayName: table.displayName || table.tableName,
|
||||
fields: columns.map((col) => ({
|
||||
name: col.columnName,
|
||||
dataType: col.dataType,
|
||||
nullable: col.nullable,
|
||||
isPrimaryKey: col.isPrimaryKey || false,
|
||||
})),
|
||||
};
|
||||
} catch (error) {
|
||||
console.warn(`테이블 ${table.tableName} 컬럼 정보 로드 실패:`, error);
|
||||
return {
|
||||
name: table.tableName,
|
||||
displayName: table.displayName || table.tableName,
|
||||
fields: [],
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
setAvailableTables(tableInfos);
|
||||
} catch (error) {
|
||||
console.error("테이블 목록 로드 실패:", error);
|
||||
toast.error("테이블 목록을 불러오는데 실패했습니다.");
|
||||
// 실패 시 빈 배열로 설정
|
||||
setAvailableTables([]);
|
||||
} finally {
|
||||
setTablesLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadTables();
|
||||
}, []);
|
||||
|
||||
// 설정 변경 핸들러
|
||||
const handleRestApiSettingsChange = useCallback(
|
||||
@@ -136,6 +168,22 @@ const ExternalCallPanel: React.FC<ExternalCallPanelProps> = ({
|
||||
[config, onSettingsChange, dataMappingConfig],
|
||||
);
|
||||
|
||||
// 데이터 매핑 설정 변경 핸들러
|
||||
const handleDataMappingConfigChange = useCallback(
|
||||
(newMappingConfig: DataMappingConfig) => {
|
||||
console.log("🔄 [ExternalCallPanel] 데이터 매핑 설정 변경:", newMappingConfig);
|
||||
|
||||
setDataMappingConfig(newMappingConfig);
|
||||
|
||||
// 전체 설정에 데이터 매핑 정보 포함하여 상위로 전달
|
||||
onSettingsChange({
|
||||
...config,
|
||||
dataMappingConfig: newMappingConfig,
|
||||
});
|
||||
},
|
||||
[config, onSettingsChange],
|
||||
);
|
||||
|
||||
// 테스트 결과 핸들러
|
||||
const handleTestResult = useCallback((result: ApiTestResult) => {
|
||||
setLastTestResult(result);
|
||||
@@ -225,10 +273,11 @@ const ExternalCallPanel: React.FC<ExternalCallPanelProps> = ({
|
||||
<TabsContent value="mapping" className="flex-1 space-y-2 overflow-y-auto">
|
||||
<DataMappingSettings
|
||||
config={dataMappingConfig}
|
||||
onConfigChange={setDataMappingConfig}
|
||||
onConfigChange={handleDataMappingConfigChange}
|
||||
httpMethod={config.restApiSettings?.httpMethod || "GET"}
|
||||
availableTables={availableTables}
|
||||
readonly={readonly}
|
||||
tablesLoading={tablesLoading}
|
||||
/>
|
||||
</TabsContent>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user