/** * 플로우 조건 빌더 * 동적 조건 생성 UI */ import { useState, useEffect } from "react"; import { Plus, Trash2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; import { FlowConditionGroup, FlowCondition, ConditionOperator } from "@/types/flow"; import { getTableColumns } from "@/lib/api/tableManagement"; interface FlowConditionBuilderProps { flowId: number; tableName?: string; // 조회할 테이블명 condition?: FlowConditionGroup; onChange: (condition: FlowConditionGroup | undefined) => void; } const OPERATORS: { value: ConditionOperator; label: string }[] = [ { value: "equals", label: "같음 (=)" }, { value: "not_equals", label: "같지 않음 (!=)" }, { value: "greater_than", label: "보다 큼 (>)" }, { value: "less_than", label: "보다 작음 (<)" }, { value: "greater_than_or_equal", label: "이상 (>=)" }, { value: "less_than_or_equal", label: "이하 (<=)" }, { value: "in", label: "포함 (IN)" }, { value: "not_in", label: "제외 (NOT IN)" }, { value: "like", label: "유사 (LIKE)" }, { value: "not_like", label: "유사하지 않음 (NOT LIKE)" }, { value: "is_null", label: "NULL" }, { value: "is_not_null", label: "NOT NULL" }, ]; export function FlowConditionBuilder({ flowId, tableName, condition, onChange }: FlowConditionBuilderProps) { const [columns, setColumns] = useState([]); const [loadingColumns, setLoadingColumns] = useState(false); const [conditionType, setConditionType] = useState<"AND" | "OR">(condition?.type || "AND"); const [conditions, setConditions] = useState(condition?.conditions || []); // 테이블 컬럼 로드 useEffect(() => { if (!tableName) { setColumns([]); return; } const loadColumns = async () => { try { setLoadingColumns(true); console.log("🔍 Loading columns for table:", tableName); const response = await getTableColumns(tableName); console.log("📦 Column API response:", response); if (response.success && response.data?.columns) { const columnArray = Array.isArray(response.data.columns) ? response.data.columns : []; console.log("✅ Setting columns:", columnArray.length, "items"); setColumns(columnArray); } else { console.error("❌ Failed to load columns:", response.message); setColumns([]); } } catch (error) { console.error("❌ Exception loading columns:", error); setColumns([]); } finally { setLoadingColumns(false); } }; loadColumns(); }, [tableName]); // 조건 변경 시 부모에 전달 useEffect(() => { if (conditions.length === 0) { onChange(undefined); } else { onChange({ type: conditionType, conditions, }); } }, [conditionType, conditions]); // 조건 추가 const addCondition = () => { setConditions([ ...conditions, { column: "", operator: "equals", value: "", }, ]); }; // 조건 수정 const updateCondition = (index: number, field: keyof FlowCondition, value: any) => { const newConditions = [...conditions]; newConditions[index] = { ...newConditions[index], [field]: value, }; setConditions(newConditions); }; // 조건 삭제 const removeCondition = (index: number) => { setConditions(conditions.filter((_, i) => i !== index)); }; // value가 필요 없는 연산자 체크 const needsValue = (operator: ConditionOperator) => { return operator !== "is_null" && operator !== "is_not_null"; }; return (
{/* 조건 타입 선택 */}
{/* 조건 목록 */}
{conditions.length === 0 ? (
조건이 없습니다
조건을 추가하여 데이터를 필터링하세요
) : ( conditions.map((cond, index) => (
{/* 조건 번호 및 삭제 버튼 */}
조건 {index + 1}
{/* 컬럼 선택 */}
{loadingColumns ? ( ) : !Array.isArray(columns) || columns.length === 0 ? ( updateCondition(index, "column", e.target.value)} placeholder="테이블을 먼저 선택하세요" className="h-8" /> ) : ( )}
{/* 연산자 선택 */}
{/* 값 입력 */} {needsValue(cond.operator) && (
updateCondition(index, "value", e.target.value)} placeholder="값 입력" className="h-8" /> {(cond.operator === "in" || cond.operator === "not_in") && (

쉼표(,)로 구분하여 여러 값 입력

)}
)}
)) )}
{/* 조건 추가 버튼 */} {/* 조건 요약 */} {conditions.length > 0 && (
조건 요약:
{conditions.map((cond, index) => (
{cond.column} {OPERATORS.find((op) => op.value === cond.operator)?.label} {needsValue(cond.operator) && {cond.value}} {index < conditions.length - 1 && {conditionType}}
))}
)}
); }