make: RepeaterFieldGroup 컴포넌트
- 하위 데이터 조회 연동 방식 개선 - 필드 정의 레벨에서 subDataSource 설정 추가 - 필드별 숨김(isHidden) 옵션 추가 - 기존 fieldMappings 방식 제거, 필드별 연동으로 변경 _repeaterFieldsConfig 메타데이터로 설정 전달 : "이 필드들의 하위 조회 결과에서 값 가져와서 추가로 저장해줘"라는 주문서 역할
This commit is contained in:
@@ -287,12 +287,18 @@ const RepeaterFieldGroupComponent: React.FC<ComponentRendererProps> = (props) =>
|
||||
if (onChange && items.length > 0) {
|
||||
// 🆕 RepeaterFieldGroup이 관리하는 필드 목록 추출
|
||||
const repeaterFieldNames = (configRef.current.fields || []).map((f: any) => f.name);
|
||||
// 🆕 subDataSource 설정이 있는 필드 목록 (하위 데이터 조회 연동)
|
||||
const fieldsConfig = (configRef.current.fields || []).map((f: any) => ({
|
||||
name: f.name,
|
||||
subDataSource: f.subDataSource,
|
||||
}));
|
||||
const dataWithMeta = items.map((item: any) => ({
|
||||
...item,
|
||||
_targetTable: targetTable,
|
||||
_originalItemIds: itemIds, // 🆕 원본 ID 목록도 함께 전달
|
||||
_existingRecord: !!item.id, // 🆕 기존 레코드 플래그 (id가 있으면 기존 레코드)
|
||||
_repeaterFields: repeaterFieldNames, // 🆕 품목 고유 필드 목록
|
||||
_repeaterFieldsConfig: fieldsConfig, // 🆕 필드 설정 (subDataSource 등)
|
||||
}));
|
||||
onChange(dataWithMeta);
|
||||
}
|
||||
@@ -393,11 +399,17 @@ const RepeaterFieldGroupComponent: React.FC<ComponentRendererProps> = (props) =>
|
||||
if (items.length > 0) {
|
||||
// 🆕 RepeaterFieldGroup이 관리하는 필드 목록 추출
|
||||
const repeaterFieldNames = (configRef.current.fields || []).map((f: any) => f.name);
|
||||
// 🆕 subDataSource 설정이 있는 필드 목록
|
||||
const fieldsConfig = (configRef.current.fields || []).map((f: any) => ({
|
||||
name: f.name,
|
||||
subDataSource: f.subDataSource,
|
||||
}));
|
||||
const dataWithMeta = items.map((item: any) => ({
|
||||
...item,
|
||||
_targetTable: effectiveTargetTable,
|
||||
_existingRecord: !!item.id,
|
||||
_repeaterFields: repeaterFieldNames, // 🆕 품목 고유 필드 목록
|
||||
_repeaterFieldsConfig: fieldsConfig, // 🆕 필드 설정 (subDataSource 등)
|
||||
}));
|
||||
onChange(dataWithMeta);
|
||||
} else {
|
||||
@@ -681,6 +693,11 @@ const RepeaterFieldGroupComponent: React.FC<ComponentRendererProps> = (props) =>
|
||||
(newValue: any[]) => {
|
||||
// 🆕 RepeaterFieldGroup이 관리하는 필드 목록 추출
|
||||
const repeaterFieldNames = (configRef.current.fields || []).map((f: any) => f.name);
|
||||
// 🆕 subDataSource 설정이 있는 필드 목록
|
||||
const fieldsConfig = (configRef.current.fields || []).map((f: any) => ({
|
||||
name: f.name,
|
||||
subDataSource: f.subDataSource,
|
||||
}));
|
||||
|
||||
// 🆕 모든 항목에 메타데이터 추가
|
||||
let valueWithMeta = newValue.map((item: any) => ({
|
||||
@@ -688,6 +705,7 @@ const RepeaterFieldGroupComponent: React.FC<ComponentRendererProps> = (props) =>
|
||||
_targetTable: effectiveTargetTable || targetTable,
|
||||
_existingRecord: !!item.id,
|
||||
_repeaterFields: repeaterFieldNames, // 🆕 품목 고유 필드 목록
|
||||
_repeaterFieldsConfig: fieldsConfig, // 🆕 필드 설정 (subDataSource 등)
|
||||
}));
|
||||
|
||||
// 🆕 분할 패널에서 우측인 경우, FK 값 추가
|
||||
|
||||
@@ -803,7 +803,7 @@ export class ButtonActionExecutor {
|
||||
|
||||
for (const item of parsedData) {
|
||||
// 메타 필드 제거
|
||||
const { _targetTable, _isNewItem, _existingRecord, _originalItemIds, _deletedItemIds, _repeaterFields, ...itemData } = item;
|
||||
const { _targetTable, _isNewItem, _existingRecord, _originalItemIds, _deletedItemIds, _repeaterFields, _subDataSelection, _subDataMaxValue, ...itemData } = item;
|
||||
|
||||
// 🔧 품목 고유 필드만 추출 (RepeaterFieldGroup 설정 기반)
|
||||
const itemOnlyData: Record<string, any> = {};
|
||||
@@ -812,6 +812,42 @@ export class ButtonActionExecutor {
|
||||
itemOnlyData[field] = itemData[field];
|
||||
}
|
||||
});
|
||||
|
||||
// 🆕 하위 데이터 선택에서 값 추출 (subDataSource 설정 기반)
|
||||
// 필드 정의에서 subDataSource.enabled가 true이고 sourceColumn이 설정된 필드만 처리
|
||||
if (_subDataSelection && typeof _subDataSelection === 'object') {
|
||||
// _repeaterFieldsConfig에서 subDataSource 설정 확인
|
||||
const fieldsConfig = item._repeaterFieldsConfig as Array<{
|
||||
name: string;
|
||||
subDataSource?: { enabled: boolean; sourceColumn: string };
|
||||
}> | undefined;
|
||||
|
||||
if (fieldsConfig && Array.isArray(fieldsConfig)) {
|
||||
fieldsConfig.forEach((fieldConfig) => {
|
||||
if (fieldConfig.subDataSource?.enabled && fieldConfig.subDataSource?.sourceColumn) {
|
||||
const targetField = fieldConfig.name; // 필드명 = 저장할 컬럼명
|
||||
const sourceColumn = fieldConfig.subDataSource.sourceColumn;
|
||||
const sourceValue = _subDataSelection[sourceColumn];
|
||||
|
||||
if (sourceValue !== undefined && sourceValue !== null) {
|
||||
itemOnlyData[targetField] = sourceValue;
|
||||
console.log(`📋 [handleSave] 하위 데이터 값 매핑: ${sourceColumn} → ${targetField} = ${sourceValue}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 하위 호환성: fieldsConfig가 없으면 기존 방식 사용
|
||||
Object.keys(_subDataSelection).forEach((subDataKey) => {
|
||||
if (itemOnlyData[subDataKey] === undefined || itemOnlyData[subDataKey] === null || itemOnlyData[subDataKey] === '') {
|
||||
const subDataValue = _subDataSelection[subDataKey];
|
||||
if (subDataValue !== undefined && subDataValue !== null) {
|
||||
itemOnlyData[subDataKey] = subDataValue;
|
||||
console.log(`📋 [handleSave] 하위 데이터 선택 값 추가 (레거시): ${subDataKey} = ${subDataValue}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 🔧 마스터 정보 + 품목 고유 정보 병합
|
||||
// masterFields: 상단 폼에서 수정한 최신 마스터 정보
|
||||
|
||||
Reference in New Issue
Block a user