183 lines
5.8 KiB
TypeScript
183 lines
5.8 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useCallback } from "react";
|
|
import { ConditionNode } from "@/lib/api/dataflow";
|
|
import {
|
|
generateConditionId,
|
|
generateGroupId,
|
|
generateActionGroupId,
|
|
findOpenGroups,
|
|
getNextGroupLevel,
|
|
getCurrentGroupLevel,
|
|
} from "@/utils/connectionUtils";
|
|
import toast from "react-hot-toast";
|
|
|
|
export const useConditionManager = () => {
|
|
const [conditions, setConditions] = useState<ConditionNode[]>([]);
|
|
|
|
// 조건 추가
|
|
const addCondition = useCallback(() => {
|
|
const newCondition: ConditionNode = {
|
|
id: generateConditionId(),
|
|
type: "condition" as const,
|
|
field: "",
|
|
operator: "=",
|
|
value: "",
|
|
dataType: "string",
|
|
// 첫 번째 조건이 아니고, 바로 앞이 group-start가 아니면 logicalOperator 추가
|
|
...(conditions.length > 0 &&
|
|
conditions[conditions.length - 1]?.type !== "group-start" && { logicalOperator: "AND" as const }),
|
|
};
|
|
|
|
setConditions([...conditions, newCondition]);
|
|
}, [conditions]);
|
|
|
|
// 그룹 시작 추가
|
|
const addGroupStart = useCallback(() => {
|
|
const groupId = generateGroupId();
|
|
const groupLevel = getNextGroupLevel(conditions);
|
|
|
|
const groupStart: ConditionNode = {
|
|
id: generateConditionId(),
|
|
type: "group-start" as const,
|
|
groupId,
|
|
groupLevel,
|
|
// 첫 번째 그룹이 아니면 logicalOperator 추가
|
|
...(conditions.length > 0 && { logicalOperator: "AND" as const }),
|
|
};
|
|
|
|
setConditions([...conditions, groupStart]);
|
|
}, [conditions]);
|
|
|
|
// 그룹 끝 추가
|
|
const addGroupEnd = useCallback(() => {
|
|
// 가장 최근에 열린 그룹 찾기
|
|
const openGroups = findOpenGroups(conditions);
|
|
if (openGroups.length === 0) {
|
|
toast.error("닫을 그룹이 없습니다.");
|
|
return;
|
|
}
|
|
|
|
const lastOpenGroup = openGroups[openGroups.length - 1];
|
|
const groupEnd: ConditionNode = {
|
|
id: generateConditionId(),
|
|
type: "group-end" as const,
|
|
groupId: lastOpenGroup.groupId,
|
|
groupLevel: lastOpenGroup.groupLevel,
|
|
};
|
|
|
|
setConditions([...conditions, groupEnd]);
|
|
}, [conditions]);
|
|
|
|
// 조건 업데이트
|
|
const updateCondition = useCallback(
|
|
(index: number, field: keyof ConditionNode, value: string) => {
|
|
const updatedConditions = [...conditions];
|
|
updatedConditions[index] = { ...updatedConditions[index], [field]: value };
|
|
setConditions(updatedConditions);
|
|
},
|
|
[conditions],
|
|
);
|
|
|
|
// 조건 제거
|
|
const removeCondition = useCallback(
|
|
(index: number) => {
|
|
const conditionToRemove = conditions[index];
|
|
|
|
// 그룹 시작/끝을 삭제하는 경우 해당 그룹 전체 삭제
|
|
if (conditionToRemove.type === "group-start" || conditionToRemove.type === "group-end") {
|
|
const updatedConditions = conditions.filter((c) => c.groupId !== conditionToRemove.groupId);
|
|
setConditions(updatedConditions);
|
|
} else {
|
|
const updatedConditions = conditions.filter((_, i) => i !== index);
|
|
setConditions(updatedConditions);
|
|
}
|
|
},
|
|
[conditions],
|
|
);
|
|
|
|
// 그룹 전체 삭제
|
|
const removeGroup = useCallback(
|
|
(groupId: string) => {
|
|
const updatedConditions = conditions.filter((c) => c.groupId !== groupId);
|
|
setConditions(updatedConditions);
|
|
},
|
|
[conditions],
|
|
);
|
|
|
|
return {
|
|
conditions,
|
|
setConditions,
|
|
addCondition,
|
|
addGroupStart,
|
|
addGroupEnd,
|
|
updateCondition,
|
|
removeCondition,
|
|
removeGroup,
|
|
getCurrentGroupLevel: (conditionIndex: number) => getCurrentGroupLevel(conditions, conditionIndex),
|
|
};
|
|
};
|
|
|
|
// 액션별 조건 관리를 위한 헬퍼 함수들
|
|
export const useActionConditionHelpers = () => {
|
|
// 액션별 그룹 시작 추가
|
|
const addActionGroupStart = useCallback(
|
|
(actionIndex: number, dataSaveSettings: any, setDataSaveSettings: (settings: any) => void) => {
|
|
const groupId = generateActionGroupId();
|
|
const currentConditions = dataSaveSettings.actions[actionIndex].conditions || [];
|
|
const groupLevel = getNextGroupLevel(currentConditions);
|
|
|
|
const groupStart: ConditionNode = {
|
|
id: generateConditionId(),
|
|
type: "group-start" as const,
|
|
groupId,
|
|
groupLevel,
|
|
// 첫 번째 그룹이 아니면 logicalOperator 추가
|
|
...(currentConditions.length > 0 && { logicalOperator: "AND" as const }),
|
|
};
|
|
|
|
const newActions = [...dataSaveSettings.actions];
|
|
newActions[actionIndex].conditions = [...currentConditions, groupStart];
|
|
setDataSaveSettings({ ...dataSaveSettings, actions: newActions });
|
|
},
|
|
[],
|
|
);
|
|
|
|
// 액션별 그룹 끝 추가
|
|
const addActionGroupEnd = useCallback(
|
|
(actionIndex: number, dataSaveSettings: any, setDataSaveSettings: (settings: any) => void) => {
|
|
const currentConditions = dataSaveSettings.actions[actionIndex].conditions || [];
|
|
const openGroups = findOpenGroups(currentConditions);
|
|
|
|
if (openGroups.length === 0) {
|
|
toast.error("닫을 그룹이 없습니다.");
|
|
return;
|
|
}
|
|
|
|
const lastOpenGroup = openGroups[openGroups.length - 1];
|
|
const groupEnd: ConditionNode = {
|
|
id: generateConditionId(),
|
|
type: "group-end" as const,
|
|
groupId: lastOpenGroup.groupId,
|
|
groupLevel: lastOpenGroup.groupLevel,
|
|
};
|
|
|
|
const newActions = [...dataSaveSettings.actions];
|
|
newActions[actionIndex].conditions = [...currentConditions, groupEnd];
|
|
setDataSaveSettings({ ...dataSaveSettings, actions: newActions });
|
|
},
|
|
[],
|
|
);
|
|
|
|
// 액션별 현재 조건의 그룹 레벨 계산
|
|
const getActionCurrentGroupLevel = useCallback((conditions: ConditionNode[], conditionIndex: number): number => {
|
|
return getCurrentGroupLevel(conditions, conditionIndex);
|
|
}, []);
|
|
|
|
return {
|
|
addActionGroupStart,
|
|
addActionGroupEnd,
|
|
getActionCurrentGroupLevel,
|
|
};
|
|
};
|