fix: 수주등록 항목추가 시 정보출력 가능하게 수정

문제:
- 조건부 컨테이너 내부의 modal-repeater-table 컴포넌트가 데이터 업데이트 불가
- ConditionalSectionViewer가 RealtimePreview에 formData/onFormDataChange 미전달

해결:
- ConditionalSectionViewer.tsx: RealtimePreview에 formData, onFormDataChange props 추가
- DynamicComponentRenderer.tsx: 디버깅 로그 정리
- ScreenModal.tsx: 디버깅 로그 정리

영향:
- 수주 등록 화면 품목 추가 기능 정상 작동
- 조건부 컨테이너 내부 모든 폼 컴포넌트 데이터 바인딩 정상화

Refs: #수주관리 #modal-repeater-table #ConditionalContainer
This commit is contained in:
SeongHyun Kim
2025-11-19 11:48:00 +09:00
parent bfc86fbcfa
commit 8eccdd0b4c
8 changed files with 312 additions and 41 deletions

View File

@@ -5,7 +5,7 @@ import { Button } from "@/components/ui/button";
import { Plus } from "lucide-react";
import { ItemSelectionModal } from "./ItemSelectionModal";
import { RepeaterTable } from "./RepeaterTable";
import { ModalRepeaterTableProps } from "./types";
import { ModalRepeaterTableProps, RepeaterColumnConfig } from "./types";
import { useCalculation } from "./useCalculation";
import { cn } from "@/lib/utils";
@@ -32,19 +32,87 @@ export function ModalRepeaterTableComponent({
}: ModalRepeaterTableComponentProps) {
// config prop 우선, 없으면 개별 prop 사용
const sourceTable = config?.sourceTable || propSourceTable || "";
const sourceColumns = config?.sourceColumns || propSourceColumns || [];
// sourceColumns에서 빈 문자열 필터링
const rawSourceColumns = config?.sourceColumns || propSourceColumns || [];
const sourceColumns = rawSourceColumns.filter((col) => col && col.trim() !== "");
const sourceSearchFields = config?.sourceSearchFields || propSourceSearchFields || [];
const modalTitle = config?.modalTitle || propModalTitle || "항목 검색";
const modalButtonText = config?.modalButtonText || propModalButtonText || "품목 검색";
const multiSelect = config?.multiSelect ?? propMultiSelect ?? true;
const columns = config?.columns || propColumns || [];
const calculationRules = config?.calculationRules || propCalculationRules || [];
const value = config?.value || propValue || [];
const onChange = config?.onChange || propOnChange || (() => {});
const uniqueField = config?.uniqueField || propUniqueField;
// uniqueField 자동 보정: order_no는 item_info 테이블에 없으므로 item_number로 변경
const rawUniqueField = config?.uniqueField || propUniqueField;
const uniqueField = rawUniqueField === "order_no" && sourceTable === "item_info"
? "item_number"
: rawUniqueField;
const filterCondition = config?.filterCondition || propFilterCondition || {};
const companyCode = config?.companyCode || propCompanyCode;
const [modalOpen, setModalOpen] = useState(false);
// columns가 비어있으면 sourceColumns로부터 자동 생성
const columns = React.useMemo((): RepeaterColumnConfig[] => {
const configuredColumns = config?.columns || propColumns || [];
if (configuredColumns.length > 0) {
console.log("✅ 설정된 columns 사용:", configuredColumns);
return configuredColumns;
}
// columns가 비어있으면 sourceColumns로부터 자동 생성
if (sourceColumns.length > 0) {
console.log("🔄 sourceColumns로부터 자동 생성:", sourceColumns);
const autoColumns: RepeaterColumnConfig[] = sourceColumns.map((field) => ({
field: field,
label: field, // 필드명을 라벨로 사용 (나중에 설정에서 변경 가능)
editable: false, // 기본적으로 읽기 전용
type: "text" as const,
width: "150px",
}));
console.log("📋 자동 생성된 columns:", autoColumns);
return autoColumns;
}
console.warn("⚠️ columns와 sourceColumns 모두 비어있음!");
return [];
}, [config?.columns, propColumns, sourceColumns]);
// 초기 props 로깅
useEffect(() => {
if (rawSourceColumns.length !== sourceColumns.length) {
console.warn(`⚠️ sourceColumns 필터링: ${rawSourceColumns.length}개 → ${sourceColumns.length}개 (빈 문자열 제거)`);
}
if (rawUniqueField !== uniqueField) {
console.warn(`⚠️ uniqueField 자동 보정: "${rawUniqueField}" → "${uniqueField}"`);
}
console.log("🎬 ModalRepeaterTableComponent 마운트:", {
columnsLength: columns.length,
sourceTable,
sourceColumns,
uniqueField,
});
if (columns.length === 0) {
console.error("❌ columns가 비어있습니다! sourceColumns:", sourceColumns);
} else {
console.log("✅ columns 설정 완료:", columns.map(c => c.label || c.field).join(", "));
}
}, []);
// value 변경 감지
useEffect(() => {
console.log("📦 ModalRepeaterTableComponent value 변경:", {
valueLength: value.length,
});
}, [value]);
const { calculateRow, calculateAll } = useCalculation(calculationRules);
// 초기 데이터에 계산 필드 적용
@@ -59,6 +127,8 @@ export function ModalRepeaterTableComponent({
}, []);
const handleAddItems = (items: any[]) => {
console.log(" handleAddItems 호출:", items.length, "개 항목");
// 기본값 적용
const itemsWithDefaults = items.map((item) => {
const newItem = { ...item };
@@ -74,7 +144,10 @@ export function ModalRepeaterTableComponent({
const calculatedItems = calculateAll(itemsWithDefaults);
// 기존 데이터에 추가
onChange([...value, ...calculatedItems]);
const newData = [...value, ...calculatedItems];
console.log("✅ 최종 데이터:", newData.length, "개 항목");
onChange(newData);
};
const handleRowChange = (index: number, newRow: any) => {