/** * 조건부 표시 평가 유틸리티 * 컴포넌트의 조건부 표시 설정을 평가하여 visible/disabled 상태를 반환합니다. */ import { ComponentData } from "@/types/screen"; export interface ConditionalResult { visible: boolean; disabled: boolean; } export interface ConditionalConfig { enabled: boolean; field: string; operator: "=" | "!=" | ">" | "<" | "in" | "notIn" | "isEmpty" | "isNotEmpty"; value: string | string[]; action: "show" | "hide" | "enable" | "disable"; } /** * 조건부 표시를 평가합니다. * @param conditional - 컴포넌트의 조건부 설정 * @param formData - 현재 폼 데이터 * @param allComponents - 화면의 모든 컴포넌트 (필드 참조용) * @returns visible/disabled 상태 */ export function evaluateConditional( conditional: ConditionalConfig | undefined, formData: Record, allComponents: ComponentData[], ): ConditionalResult { // 조건부 설정이 없거나 비활성화된 경우 기본값 반환 if (!conditional || !conditional.enabled) { return { visible: true, disabled: false }; } const { field, operator, value, action } = conditional; // 필드가 설정되지 않은 경우 기본값 반환 if (!field) { console.warn("[evaluateConditional] 조건 필드가 설정되지 않음"); return { visible: true, disabled: false }; } // 참조 필드의 현재 값 가져오기 // field 값은 columnName 또는 id일 수 있으므로 양쪽으로 찾기 const refComponent = allComponents.find((c) => { const columnName = (c as any)?.columnName; return c.id === field || columnName === field; }); // formData에서 값 조회: columnName 우선, 없으면 field 값 직접 사용 const fieldName = (refComponent as any)?.columnName || field; const fieldValue = formData[fieldName]; // 조건 평가 let conditionMet = false; switch (operator) { case "=": conditionMet = fieldValue === value || String(fieldValue) === String(value); break; case "!=": conditionMet = fieldValue !== value && String(fieldValue) !== String(value); break; case ">": conditionMet = Number(fieldValue) > Number(value); break; case "<": conditionMet = Number(fieldValue) < Number(value); break; case "in": if (Array.isArray(value)) { conditionMet = value.includes(fieldValue) || value.map(String).includes(String(fieldValue)); } break; case "notIn": if (Array.isArray(value)) { conditionMet = !value.includes(fieldValue) && !value.map(String).includes(String(fieldValue)); } else { conditionMet = true; } break; case "isEmpty": conditionMet = fieldValue === null || fieldValue === undefined || fieldValue === "" || (Array.isArray(fieldValue) && fieldValue.length === 0); break; case "isNotEmpty": conditionMet = fieldValue !== null && fieldValue !== undefined && fieldValue !== "" && !(Array.isArray(fieldValue) && fieldValue.length === 0); break; default: conditionMet = true; } // 액션에 따른 결과 반환 switch (action) { case "show": // 조건이 참이면 표시, 거짓이면 숨김 return { visible: conditionMet, disabled: false }; case "hide": // 조건이 참이면 숨김, 거짓이면 표시 return { visible: !conditionMet, disabled: false }; case "enable": return { visible: true, disabled: !conditionMet }; case "disable": return { visible: true, disabled: conditionMet }; default: return { visible: true, disabled: false }; } }