2025-09-16 15:43:18 +09:00
|
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
|
|
import React from "react";
|
|
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
|
|
import { Input } from "@/components/ui/input";
|
|
|
|
|
|
import { Label } from "@/components/ui/label";
|
|
|
|
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
|
|
|
|
import { Trash2 } from "lucide-react";
|
|
|
|
|
|
import { ColumnInfo } from "@/lib/api/dataflow";
|
|
|
|
|
|
import { DataSaveSettings } from "@/types/connectionTypes";
|
|
|
|
|
|
|
|
|
|
|
|
interface ActionSplitConfigProps {
|
|
|
|
|
|
action: DataSaveSettings["actions"][0];
|
|
|
|
|
|
actionIndex: number;
|
|
|
|
|
|
settings: DataSaveSettings;
|
|
|
|
|
|
onSettingsChange: (settings: DataSaveSettings) => void;
|
|
|
|
|
|
fromTableColumns: ColumnInfo[];
|
|
|
|
|
|
toTableColumns: ColumnInfo[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const ActionSplitConfig: React.FC<ActionSplitConfigProps> = ({
|
|
|
|
|
|
action,
|
|
|
|
|
|
actionIndex,
|
|
|
|
|
|
settings,
|
|
|
|
|
|
onSettingsChange,
|
|
|
|
|
|
fromTableColumns,
|
|
|
|
|
|
toTableColumns,
|
|
|
|
|
|
}) => {
|
|
|
|
|
|
const updateSplitConfig = (field: string, value: string) => {
|
|
|
|
|
|
const newActions = [...settings.actions];
|
|
|
|
|
|
if (!newActions[actionIndex].splitConfig) {
|
|
|
|
|
|
newActions[actionIndex].splitConfig = {
|
|
|
|
|
|
sourceField: "",
|
|
|
|
|
|
delimiter: ",",
|
|
|
|
|
|
targetField: "",
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
(newActions[actionIndex].splitConfig as any)[field] = value;
|
|
|
|
|
|
onSettingsChange({ ...settings, actions: newActions });
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const clearSplitConfig = () => {
|
|
|
|
|
|
const newActions = [...settings.actions];
|
|
|
|
|
|
newActions[actionIndex].splitConfig = {
|
|
|
|
|
|
sourceField: "",
|
|
|
|
|
|
delimiter: ",",
|
|
|
|
|
|
targetField: "",
|
|
|
|
|
|
};
|
|
|
|
|
|
onSettingsChange({ ...settings, actions: newActions });
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="mt-3">
|
|
|
|
|
|
<details className="group">
|
|
|
|
|
|
<summary className="flex cursor-pointer items-center justify-between rounded border p-2 text-xs font-medium text-gray-700 hover:bg-gray-50 hover:text-gray-900">
|
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
|
✂️ 데이터 분할 설정 (선택사항)
|
|
|
|
|
|
{action.splitConfig && action.splitConfig.sourceField && (
|
|
|
|
|
|
<span className="rounded-full bg-green-100 px-2 py-0.5 text-xs text-green-700">설정됨</span>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{action.splitConfig && action.splitConfig.sourceField && (
|
|
|
|
|
|
<Button
|
|
|
|
|
|
size="sm"
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
onClick={(e) => {
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
clearSplitConfig();
|
|
|
|
|
|
}}
|
|
|
|
|
|
className="h-5 w-5 p-0 text-red-500 hover:text-red-700"
|
|
|
|
|
|
title="분할 설정 초기화"
|
|
|
|
|
|
>
|
|
|
|
|
|
<Trash2 className="h-3 w-3" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</summary>
|
|
|
|
|
|
<div className="mt-2 space-y-2 border-l-2 border-gray-100 pl-4">
|
|
|
|
|
|
<Label className="text-xs font-medium">데이터 분할 설정</Label>
|
|
|
|
|
|
<div className="mt-1 grid grid-cols-3 gap-2">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<Label className="text-xs text-gray-500">분할할 필드</Label>
|
|
|
|
|
|
<Select
|
|
|
|
|
|
value={action.splitConfig?.sourceField || ""}
|
|
|
|
|
|
onValueChange={(value) => updateSplitConfig("sourceField", value)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<SelectTrigger className="h-6 text-xs">
|
|
|
|
|
|
<SelectValue placeholder="필드 선택" />
|
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
|
<SelectContent>
|
|
|
|
|
|
{fromTableColumns.map((column) => (
|
|
|
|
|
|
<SelectItem key={column.columnName} value={column.columnName}>
|
2025-09-24 18:23:57 +09:00
|
|
|
|
{column.displayName && column.displayName !== column.columnName
|
|
|
|
|
|
? column.displayName
|
|
|
|
|
|
: column.columnName}
|
2025-09-16 15:43:18 +09:00
|
|
|
|
</SelectItem>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</SelectContent>
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<Label className="text-xs text-gray-500">구분자</Label>
|
|
|
|
|
|
<Input
|
|
|
|
|
|
value={action.splitConfig?.delimiter || ""}
|
|
|
|
|
|
onChange={(e) => updateSplitConfig("delimiter", e.target.value)}
|
|
|
|
|
|
className="h-6 text-xs"
|
|
|
|
|
|
placeholder=","
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<Label className="text-xs text-gray-500">저장할 필드</Label>
|
|
|
|
|
|
<Select
|
|
|
|
|
|
value={action.splitConfig?.targetField || ""}
|
|
|
|
|
|
onValueChange={(value) => updateSplitConfig("targetField", value)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<SelectTrigger className="h-6 text-xs">
|
|
|
|
|
|
<SelectValue placeholder="필드 선택" />
|
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
|
<SelectContent>
|
|
|
|
|
|
{toTableColumns.map((column) => (
|
|
|
|
|
|
<SelectItem key={column.columnName} value={column.columnName}>
|
2025-09-24 18:23:57 +09:00
|
|
|
|
{column.displayName && column.displayName !== column.columnName
|
|
|
|
|
|
? column.displayName
|
|
|
|
|
|
: column.columnName}
|
2025-09-16 15:43:18 +09:00
|
|
|
|
</SelectItem>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</SelectContent>
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</details>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|