diff --git a/frontend/components/screen/EditModal.tsx b/frontend/components/screen/EditModal.tsx index b3c94ade..7c722ad6 100644 --- a/frontend/components/screen/EditModal.tsx +++ b/frontend/components/screen/EditModal.tsx @@ -309,17 +309,10 @@ export const EditModal: React.FC = ({ className }) => { // 🆕 그룹 데이터 조회 함수 const loadGroupData = async () => { if (!modalState.tableName || !modalState.groupByColumns || modalState.groupByColumns.length === 0) { - // console.warn("테이블명 또는 그룹핑 컬럼이 없습니다."); return; } try { - // console.log("🔍 그룹 데이터 조회 시작:", { - // tableName: modalState.tableName, - // groupByColumns: modalState.groupByColumns, - // editData: modalState.editData, - // }); - // 그룹핑 컬럼 값 추출 (예: order_no = "ORD-20251124-001") const groupValues: Record = {}; modalState.groupByColumns.forEach((column) => { @@ -329,15 +322,9 @@ export const EditModal: React.FC = ({ className }) => { }); if (Object.keys(groupValues).length === 0) { - // console.warn("그룹핑 컬럼 값이 없습니다:", modalState.groupByColumns); return; } - // console.log("🔍 그룹 조회 요청:", { - // tableName: modalState.tableName, - // groupValues, - // }); - // 같은 그룹의 모든 레코드 조회 (entityJoinApi 사용) const { entityJoinApi } = await import("@/lib/api/entityJoin"); const response = await entityJoinApi.getTableDataWithJoins(modalState.tableName, { @@ -347,23 +334,19 @@ export const EditModal: React.FC = ({ className }) => { enableEntityJoin: true, }); - // console.log("🔍 그룹 조회 응답:", response); - // entityJoinApi는 배열 또는 { data: [] } 형식으로 반환 const dataArray = Array.isArray(response) ? response : response?.data || []; if (dataArray.length > 0) { - // console.log("✅ 그룹 데이터 조회 성공:", dataArray.length, "건"); setGroupData(dataArray); setOriginalGroupData(JSON.parse(JSON.stringify(dataArray))); // Deep copy toast.info(`${dataArray.length}개의 관련 품목을 불러왔습니다.`); } else { - console.warn("그룹 데이터가 없습니다:", response); setGroupData([modalState.editData]); // 기본값: 선택된 행만 setOriginalGroupData([JSON.parse(JSON.stringify(modalState.editData))]); } } catch (error: any) { - console.error("❌ 그룹 데이터 조회 오류:", error); + console.error("그룹 데이터 조회 오류:", error); toast.error("관련 데이터를 불러오는 중 오류가 발생했습니다."); setGroupData([modalState.editData]); // 기본값: 선택된 행만 setOriginalGroupData([JSON.parse(JSON.stringify(modalState.editData))]); @@ -1043,17 +1026,18 @@ export const EditModal: React.FC = ({ className }) => { const groupedDataProp = groupData.length > 0 ? groupData : undefined; // 🆕 UniversalFormModal이 있는지 확인 (자체 저장 로직 사용) - // 최상위 컴포넌트 또는 조건부 컨테이너 내부 화면에 universal-form-modal이 있는지 확인 + // 최상위 컴포넌트에 universal-form-modal이 있는지 확인 + // ⚠️ 수정: conditional-container는 제외 (groupData가 있으면 EditModal.handleSave 사용) const hasUniversalFormModal = screenData.components.some( (c) => { - // 최상위에 universal-form-modal이 있는 경우 + // 최상위에 universal-form-modal이 있는 경우만 자체 저장 로직 사용 if (c.componentType === "universal-form-modal") return true; - // 조건부 컨테이너 내부에 universal-form-modal이 있는 경우 - // (조건부 컨테이너가 있으면 내부 화면에서 universal-form-modal을 사용하는 것으로 가정) - if (c.componentType === "conditional-container") return true; return false; } ); + + // 🆕 그룹 데이터가 있으면 EditModal.handleSave 사용 (일괄 저장) + const shouldUseEditModalSave = groupData.length > 0 || !hasUniversalFormModal; // 🔑 첨부파일 컴포넌트가 행(레코드) 단위로 파일을 저장할 수 있도록 tableName 추가 const enrichedFormData = { @@ -1095,9 +1079,9 @@ export const EditModal: React.FC = ({ className }) => { id: modalState.screenId!, tableName: screenData.screenInfo?.tableName, }} - // 🆕 UniversalFormModal이 있으면 onSave 전달 안 함 (자체 저장 로직 사용) - // ModalRepeaterTable만 있으면 기존대로 onSave 전달 (호환성 유지) - onSave={hasUniversalFormModal ? undefined : handleSave} + // 🆕 그룹 데이터가 있거나 UniversalFormModal이 없으면 EditModal.handleSave 사용 + // groupData가 있으면 일괄 저장을 위해 반드시 EditModal.handleSave 사용 + onSave={shouldUseEditModalSave ? handleSave : undefined} isInModal={true} // 🆕 그룹 데이터를 ModalRepeaterTable에 전달 groupedData={groupedDataProp} diff --git a/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx b/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx index 2caf1332..153cebdf 100644 --- a/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx +++ b/frontend/lib/registry/components/modal-repeater-table/ModalRepeaterTableComponent.tsx @@ -180,8 +180,11 @@ export function ModalRepeaterTableComponent({ filterCondition: propFilterCondition, companyCode: propCompanyCode, + // 🆕 그룹 데이터 (EditModal에서 전달, 같은 그룹의 여러 품목) + groupedData, + ...props -}: ModalRepeaterTableComponentProps) { +}: ModalRepeaterTableComponentProps & { groupedData?: Record[] }) { // ✅ config 또는 component.config 또는 개별 prop 우선순위로 병합 const componentConfig = { ...config, @@ -208,9 +211,16 @@ export function ModalRepeaterTableComponent({ // 모달 필터 설정 const modalFilters = componentConfig?.modalFilters || []; - // ✅ value는 formData[columnName] 우선, 없으면 prop 사용 + // ✅ value는 groupedData 우선, 없으면 formData[columnName], 없으면 prop 사용 const columnName = component?.columnName; - const externalValue = (columnName && formData?.[columnName]) || componentConfig?.value || propValue || []; + + // 🆕 groupedData가 전달되면 (EditModal에서 그룹 조회 결과) 우선 사용 + const externalValue = (() => { + if (groupedData && groupedData.length > 0) { + return groupedData; + } + return (columnName && formData?.[columnName]) || componentConfig?.value || propValue || []; + })(); // 빈 객체 판단 함수 (수정 모달의 실제 데이터는 유지) const isEmptyRow = (item: any): boolean => {