ERP-node/frontend/components/dataflow/connection/ActionConditionsSection.tsx

143 lines
5.2 KiB
TypeScript

"use client";
import React from "react";
import { Button } from "@/components/ui/button";
import { Plus, Trash2 } from "lucide-react";
import { ColumnInfo } from "@/lib/api/dataflow";
import { DataSaveSettings } from "@/types/connectionTypes";
import { generateConditionId } from "@/utils/connectionUtils";
import { useActionConditionHelpers } from "@/hooks/useConditionManager";
import { ActionConditionRenderer } from "./ActionConditionRenderer";
interface ActionConditionsSectionProps {
action: DataSaveSettings["actions"][0];
actionIndex: number;
settings: DataSaveSettings;
onSettingsChange: (settings: DataSaveSettings) => void;
fromTableColumns: ColumnInfo[];
toTableColumns: ColumnInfo[];
fromTableName?: string;
toTableName?: string;
}
export const ActionConditionsSection: React.FC<ActionConditionsSectionProps> = ({
action,
actionIndex,
settings,
onSettingsChange,
fromTableColumns,
toTableColumns,
fromTableName,
toTableName,
}) => {
const { addActionGroupStart, addActionGroupEnd, getActionCurrentGroupLevel } = useActionConditionHelpers();
const addActionCondition = () => {
const newActions = [...settings.actions];
if (!newActions[actionIndex].conditions) {
newActions[actionIndex].conditions = [];
}
const currentConditions = newActions[actionIndex].conditions || [];
const newCondition = {
id: generateConditionId(),
type: "condition" as const,
field: "",
operator: "=" as const,
value: "",
dataType: "string",
tableType: undefined, // 사용자가 직접 선택하도록
// 첫 번째 조건이 아니고, 바로 앞이 group-start가 아니면 logicalOperator 추가
...(currentConditions.length > 0 &&
currentConditions[currentConditions.length - 1]?.type !== "group-start" && {
logicalOperator: "AND" as const,
}),
};
newActions[actionIndex].conditions = [...currentConditions, newCondition];
onSettingsChange({ ...settings, actions: newActions });
};
const clearAllConditions = () => {
const newActions = [...settings.actions];
newActions[actionIndex].conditions = [];
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.conditions && action.conditions.length > 0 && (
<span className="rounded-full bg-blue-100 px-2 py-0.5 text-xs text-blue-700">
{action.conditions.length}
</span>
)}
</div>
{action.conditions && action.conditions.length > 0 && (
<Button
size="sm"
variant="ghost"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
clearAllConditions();
}}
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">
<div className="mb-2 flex items-center justify-between">
<div className="flex gap-1">
<Button size="sm" variant="outline" onClick={addActionCondition} className="h-6 text-xs">
<Plus className="mr-1 h-2 w-2" />
</Button>
<Button
size="sm"
variant="outline"
onClick={() => addActionGroupStart(actionIndex, settings, onSettingsChange)}
className="h-6 text-xs"
>
(
</Button>
<Button
size="sm"
variant="outline"
onClick={() => addActionGroupEnd(actionIndex, settings, onSettingsChange)}
className="h-6 text-xs"
>
)
</Button>
</div>
</div>
{action.conditions && action.conditions.length > 0 && (
<div className="space-y-2">
{action.conditions.map((condition, condIndex) => (
<div key={`action-${actionIndex}-condition-${condition.id}`}>
<ActionConditionRenderer
condition={condition}
condIndex={condIndex}
actionIndex={actionIndex}
settings={settings}
onSettingsChange={onSettingsChange}
fromTableColumns={fromTableColumns}
toTableColumns={toTableColumns}
fromTableName={fromTableName}
toTableName={toTableName}
getActionCurrentGroupLevel={getActionCurrentGroupLevel}
/>
</div>
))}
</div>
)}
</div>
</details>
</div>
);
};