fix: 다단계 모달 환경에서 부모 데이터 매핑 수정

문제:
- 메인 화면(거래처 선택) → 첫 번째 모달(품목 선택) → 두 번째 모달(상세 입력)
- selectedRowsData는 바로 이전 화면 데이터만 제공하여 2단계 이전 데이터 접근 불가
- customer_id가 NULL로 저장됨

해결:
- modalDataStore의 전역 레지스트리에서 모든 누적 데이터 접근
- sourceTable에 따라 적절한 데이터 소스 자동 선택
- 거래처 데이터(customer_mng)를 modalDataStore에서 직접 가져옴

기술적 변경:
- ButtonPrimaryComponent: allComponents에서 componentConfigs 수집 및 전달
- ButtonActionContext: componentConfigs 속성 추가
- handleBatchSave: modalDataStore에서 테이블별 데이터 조회
- parentDataMapping 로직: sourceTable 기반 데이터 소스 자동 감지
- 디버깅 로그 강화 (modalDataStore 키, 데이터 소스 추적)
This commit is contained in:
kjs 2025-11-19 13:48:44 +09:00
parent f4e4ee13e2
commit 97b5cd7a5b
2 changed files with 53 additions and 10 deletions

View File

@ -393,6 +393,16 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
return;
}
// 🆕 모든 컴포넌트의 설정 수집 (parentDataMapping 등)
const componentConfigs: Record<string, any> = {};
if (allComponents && Array.isArray(allComponents)) {
for (const comp of allComponents) {
if (comp.id && comp.componentConfig) {
componentConfigs[comp.id] = comp.componentConfig;
}
}
}
const context: ButtonActionContext = {
formData: formData || {},
originalData: originalData || {}, // 부분 업데이트용 원본 데이터 추가
@ -418,7 +428,9 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
// 플로우 선택된 데이터 정보 추가
flowSelectedData,
flowSelectedStepId,
};
// 🆕 컴포넌트별 설정 (parentDataMapping 등)
componentConfigs,
} as ButtonActionContext;
// 확인이 필요한 액션인지 확인
if (confirmationRequiredActions.includes(processedConfig.action.type)) {

View File

@ -135,6 +135,9 @@ export interface ButtonActionContext {
currentPage?: number; // 현재 페이지
pageSize?: number; // 페이지 크기
totalItems?: number; // 전체 항목 수
// 🆕 컴포넌트별 설정 (parentDataMapping 등)
componentConfigs?: Record<string, any>; // 컴포넌트 ID → 컴포넌트 설정
}
/**
@ -538,9 +541,19 @@ export class ButtonActionExecutor {
// selectedRowsData 또는 originalData를 parentData로 사용
const parentData = selectedRowsData?.[0] || originalData || {};
// 🆕 modalDataStore에서 누적된 모든 테이블 데이터 가져오기
// (여러 단계 모달에서 전달된 데이터 접근용)
const modalDataStore = typeof window !== 'undefined'
? (window as any).__modalDataRegistry || {}
: {};
console.log(`🔍 [handleBatchSave] 부모 데이터:`, {
hasParentData: Object.keys(parentData).length > 0,
parentDataKeys: Object.keys(parentData),
parentDataFull: parentData,
selectedRowsData,
originalData,
modalDataStoreKeys: Object.keys(modalDataStore),
});
// 각 SelectedItemsDetailInput 컴포넌트의 데이터 처리
@ -555,14 +568,15 @@ export class ButtonActionExecutor {
console.log(`📦 [handleBatchSave] ${key} 처리 중 (${items.length}개 품목)`);
// 🆕 이 컴포넌트의 parentDataMapping 설정 가져오기
// TODO: 실제로는 componentConfig에서 가져와야 함
// 현재는 selectedItemsKeys[0]을 사용하여 임시로 가져옴
const componentConfig = (context as any).componentConfigs?.[key];
const componentConfig = context.componentConfigs?.[key];
const parentDataMapping = componentConfig?.parentDataMapping || [];
console.log(`🔍 [handleBatchSave] parentDataMapping 설정:`, {
componentId: key,
hasComponentConfig: !!componentConfig,
hasMapping: parentDataMapping.length > 0,
mappings: parentDataMapping
mappings: parentDataMapping,
sourceTable: componentConfig?.sourceTable,
});
// 🆕 각 품목의 그룹 간 조합(카티션 곱) 생성
@ -615,8 +629,8 @@ export class ButtonActionExecutor {
let sourceData: any;
// 🔍 sourceTable과 실제 데이터 테이블 비교
// - parentData는 이전 화면 데이터 (예: 거래처 테이블)
// - item.originalData는 선택된 항목 데이터 (예: 품목 테이블)
// - modalDataStore는 모든 이전 화면의 누적 데이터 (예: 거래처, 품목)
// - item.originalData는 현재 선택된 항목 데이터 (예: 품목 테이블)
// 원본 데이터 테이블명 확인 (sourceTable이 config에 명시되어 있음)
const sourceTableName = mapping.sourceTable;
@ -629,13 +643,30 @@ export class ButtonActionExecutor {
sourceData = item.originalData;
console.log(` 📦 소스: 선택된 항목 데이터 (${sourceTableName})`);
} else {
// 이전 화면 데이터 사용
sourceData = parentData;
console.log(` 👤 소스: 이전 화면 데이터 (${sourceTableName})`);
// 🆕 modalDataStore에서 해당 테이블 데이터 가져오기
const tableData = modalDataStore[sourceTableName];
if (tableData && Array.isArray(tableData) && tableData.length > 0) {
sourceData = tableData[0]; // 첫 번째 항목 사용
console.log(` 🌐 소스: modalDataStore (${sourceTableName})`);
} else {
// 폴백: 이전 화면 데이터 사용
sourceData = parentData;
console.log(` 👤 소스: 이전 화면 데이터 (${sourceTableName}) [폴백]`);
}
}
const sourceValue = sourceData[mapping.sourceField];
console.log(` 🔍 데이터 소스 상세:`, {
sourceTable: sourceTableName,
selectedItemTable,
isFromSelectedItem: sourceTableName === selectedItemTable,
sourceDataKeys: Object.keys(sourceData),
sourceField: mapping.sourceField,
sourceValue,
targetField: mapping.targetField
});
if (sourceValue !== undefined && sourceValue !== null) {
mappedData[mapping.targetField] = sourceValue;
console.log(` ✅ [${sourceTableName}] ${mapping.sourceField}${mapping.targetField}: ${sourceValue}`);