feat: V2Input 및 DynamicComponentRenderer에서 tableName 및 inputType 처리 개선
- V2Input 컴포넌트에서 tableName을 여러 소스(프롭스, 설정, 오버라이드, 화면 정보)에서 추출하도록 로직을 개선하였습니다. - inputType을 props에서 직접 전달받거나 config에서 설정된 값으로 확인하도록 수정하여 유연성을 높였습니다. - DynamicComponentRenderer에서 v2-input 컴포넌트의 tableName을 올바르게 처리하도록 업데이트하였습니다. - 채번 규칙 ID를 formData에 저장하는 로직을 개선하여 데이터 처리의 일관성을 강화하였습니다.
This commit is contained in:
parent
dff27c522f
commit
f7dda7a666
|
|
@ -361,8 +361,17 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
|||
const [isGeneratingNumbering, setIsGeneratingNumbering] = useState(false);
|
||||
const hasGeneratedNumberingRef = useRef(false);
|
||||
|
||||
// tableName 추출 (props에서 전달받거나 config에서)
|
||||
const tableName = (props as any).tableName || (config as any).tableName;
|
||||
// tableName 추출 (여러 소스에서 확인)
|
||||
// 1. props에서 직접 전달받은 값
|
||||
// 2. config에서 설정된 값
|
||||
// 3. 컴포넌트 overrides에서 설정된 값 (V2 레이아웃)
|
||||
// 4. screenInfo에서 화면 테이블명
|
||||
const tableName =
|
||||
(props as any).tableName ||
|
||||
(config as any).tableName ||
|
||||
(props as any).component?.tableName ||
|
||||
(props as any).component?.overrides?.tableName ||
|
||||
(props as any).screenInfo?.tableName;
|
||||
|
||||
// 수정 모드 여부 확인
|
||||
const originalData = (props as any).originalData || (props as any)._originalData;
|
||||
|
|
@ -445,8 +454,10 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
|||
|
||||
// formData에서 카테고리 관련 값 추출 (채번 파트에서 카테고리 사용 시)
|
||||
// 채번 필드 자체의 값은 제외해야 함 (무한 루프 방지)
|
||||
// inputType을 여러 소스에서 확인
|
||||
const propsInputType = (props as any).inputType;
|
||||
const categoryValuesForNumbering = useMemo(() => {
|
||||
const inputType = config.inputType || config.type || "text";
|
||||
const inputType = propsInputType || config.inputType || config.type || "text";
|
||||
if (inputType !== "numbering") return "";
|
||||
// formData에서 category 타입 필드 값들을 추출 (채번 필드 자체는 제외)
|
||||
const categoryFields: Record<string, string> = {};
|
||||
|
|
@ -458,12 +469,13 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
|||
}
|
||||
}
|
||||
return JSON.stringify(categoryFields);
|
||||
}, [config.inputType, config.type, formData, columnName]);
|
||||
}, [propsInputType, config.inputType, config.type, formData, columnName]);
|
||||
|
||||
// 채번 타입 자동생성 로직 (테이블 관리에서 설정된 numberingRuleId 사용)
|
||||
useEffect(() => {
|
||||
const generateNumberingCode = async () => {
|
||||
const inputType = config.inputType || config.type || "text";
|
||||
// inputType을 여러 소스에서 확인 (props에서 직접 전달받거나 config에서)
|
||||
const inputType = (props as any).inputType || config.inputType || config.type || "text";
|
||||
|
||||
// numbering 타입이 아니면 스킵
|
||||
if (inputType !== "numbering") {
|
||||
|
|
@ -524,9 +536,12 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
|||
}
|
||||
|
||||
// detailSettings에서 numberingRuleId 추출
|
||||
if (targetColumn.detailSettings && typeof targetColumn.detailSettings === "string") {
|
||||
if (targetColumn.detailSettings) {
|
||||
try {
|
||||
const parsed = JSON.parse(targetColumn.detailSettings);
|
||||
// 문자열이면 파싱, 객체면 그대로 사용
|
||||
const parsed = typeof targetColumn.detailSettings === "string"
|
||||
? JSON.parse(targetColumn.detailSettings)
|
||||
: targetColumn.detailSettings;
|
||||
numberingRuleIdRef.current = parsed.numberingRuleId || null;
|
||||
|
||||
// 🆕 채번 규칙 ID를 formData에 저장 (저장 시 allocateCode 호출을 위해)
|
||||
|
|
@ -618,7 +633,7 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
|||
|
||||
// 타입별 입력 컴포넌트 렌더링
|
||||
const renderInput = () => {
|
||||
const inputType = config.inputType || config.type || "text";
|
||||
const inputType = propsInputType || config.inputType || config.type || "text";
|
||||
switch (inputType) {
|
||||
case "text":
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -506,10 +506,12 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
|||
};
|
||||
|
||||
// 🆕 엔티티 검색 컴포넌트는 componentConfig.tableName을 사용해야 함 (화면 테이블이 아닌 검색 대상 테이블)
|
||||
// 🆕 v2-input도 포함 (채번 규칙 조회 시 tableName 필요)
|
||||
const useConfigTableName =
|
||||
componentType === "entity-search-input" ||
|
||||
componentType === "autocomplete-search-input" ||
|
||||
componentType === "modal-repeater-table";
|
||||
componentType === "modal-repeater-table" ||
|
||||
componentType === "v2-input";
|
||||
|
||||
const rendererProps = {
|
||||
component,
|
||||
|
|
@ -524,9 +526,21 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
|||
componentConfig: component.componentConfig,
|
||||
// componentConfig의 모든 속성을 props로 spread (tableName, displayField 등)
|
||||
...(component.componentConfig || {}),
|
||||
// 🆕 V2 레이아웃에서 overrides에서 복원된 상위 레벨 속성들도 전달
|
||||
inputType: (component as any).inputType || component.componentConfig?.inputType,
|
||||
columnName: (component as any).columnName || component.componentConfig?.columnName,
|
||||
value: currentValue, // formData에서 추출한 현재 값 전달
|
||||
// 새로운 기능들 전달
|
||||
autoGeneration: component.autoGeneration || component.componentConfig?.autoGeneration,
|
||||
// 🆕 webTypeConfig.numberingRuleId가 있으면 autoGeneration으로 변환
|
||||
autoGeneration: component.autoGeneration ||
|
||||
component.componentConfig?.autoGeneration ||
|
||||
((component as any).webTypeConfig?.numberingRuleId ? {
|
||||
type: "numbering_rule" as const,
|
||||
enabled: true,
|
||||
options: {
|
||||
numberingRuleId: (component as any).webTypeConfig.numberingRuleId,
|
||||
},
|
||||
} : undefined),
|
||||
hidden: hiddenValue,
|
||||
// React 전용 props들은 직접 전달 (DOM에 전달되지 않음)
|
||||
isInteractive,
|
||||
|
|
@ -534,7 +548,10 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
|||
onFormDataChange,
|
||||
onChange: handleChange, // 개선된 onChange 핸들러 전달
|
||||
// 🆕 엔티티 검색 컴포넌트는 componentConfig.tableName 유지, 그 외는 화면 테이블명 사용
|
||||
tableName: useConfigTableName ? component.componentConfig?.tableName || tableName : tableName,
|
||||
// 🆕 component.tableName도 확인 (V2 레이아웃에서 overrides.tableName이 복원됨)
|
||||
tableName: useConfigTableName
|
||||
? component.componentConfig?.tableName || (component as any).tableName || tableName
|
||||
: tableName,
|
||||
menuId, // 🆕 메뉴 ID
|
||||
menuObjid, // 🆕 메뉴 OBJID (메뉴 스코프)
|
||||
selectedScreen, // 🆕 화면 정보
|
||||
|
|
|
|||
|
|
@ -3043,8 +3043,12 @@ export class ButtonActionExecutor {
|
|||
}
|
||||
|
||||
// 4. 모달 열기 이벤트 발생
|
||||
// passSelectedData가 true이면 editData로 전달 (수정 모드처럼 모든 필드 표시)
|
||||
// 🔧 수정: openModalWithData는 "신규 등록 + 연결 데이터 전달"용이므로
|
||||
// editData가 아닌 splitPanelParentData로 전달해야 채번 등이 정상 작동함
|
||||
const isPassDataMode = passSelectedData && selectedData.length > 0;
|
||||
|
||||
// 🔧 isEditMode 옵션이 명시적으로 true인 경우에만 수정 모드로 처리
|
||||
const useAsEditData = config.isEditMode === true;
|
||||
|
||||
const modalEvent = new CustomEvent("openScreenModal", {
|
||||
detail: {
|
||||
|
|
@ -3054,9 +3058,10 @@ export class ButtonActionExecutor {
|
|||
size: config.modalSize || "md",
|
||||
selectedData: selectedData,
|
||||
selectedIds: selectedData.map((row: any) => row.id).filter(Boolean),
|
||||
// 🆕 데이터 전달 모드일 때는 editData로 전달하여 모든 필드가 표시되도록 함
|
||||
editData: isPassDataMode ? parentData : undefined,
|
||||
splitPanelParentData: isPassDataMode ? undefined : parentData,
|
||||
// 🔧 수정: isEditMode가 명시적으로 true인 경우에만 editData로 전달
|
||||
// 기본적으로는 splitPanelParentData로 전달하여 신규 등록 + 연결 데이터 모드
|
||||
editData: useAsEditData && isPassDataMode ? parentData : undefined,
|
||||
splitPanelParentData: isPassDataMode ? parentData : undefined,
|
||||
urlParams: dataSourceId ? { dataSourceId } : undefined,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue