|
|
|
|
@ -216,6 +216,12 @@ export function UniversalFormModalComponent({
|
|
|
|
|
|
|
|
|
|
// 초기화 - 최초 마운트 시 또는 initialData가 변경되었을 때 실행
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
console.log("[UniversalFormModal] useEffect 시작", {
|
|
|
|
|
initialData,
|
|
|
|
|
hasInitialized: hasInitialized.current,
|
|
|
|
|
lastInitializedId: lastInitializedId.current,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// initialData에서 ID 값 추출 (id, ID, objid 등)
|
|
|
|
|
const currentId = initialData?.id || initialData?.ID || initialData?.objid;
|
|
|
|
|
const currentIdString = currentId !== undefined ? String(currentId) : undefined;
|
|
|
|
|
@ -229,9 +235,20 @@ export function UniversalFormModalComponent({
|
|
|
|
|
if (hasInitialized.current && lastInitializedId.current === currentIdString) {
|
|
|
|
|
// 생성 모드에서 데이터가 새로 전달된 경우는 재초기화 필요
|
|
|
|
|
if (!createModeDataHash || capturedInitialData.current) {
|
|
|
|
|
console.log("[UniversalFormModal] 초기화 스킵 - 이미 초기화됨");
|
|
|
|
|
// 🆕 채번 플래그가 true인데 formData에 값이 없으면 재생성 필요
|
|
|
|
|
// (컴포넌트 remount로 인해 state가 초기화된 경우)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 🆕 컴포넌트 remount 감지: hasInitialized가 true인데 formData가 비어있으면 재초기화
|
|
|
|
|
// (React의 Strict Mode나 EmbeddedScreen 리렌더링으로 인한 remount)
|
|
|
|
|
if (hasInitialized.current && !currentIdString) {
|
|
|
|
|
console.log("[UniversalFormModal] 컴포넌트 remount 감지 - 채번 플래그 초기화");
|
|
|
|
|
numberingGeneratedRef.current = false;
|
|
|
|
|
isGeneratingRef.current = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 🆕 수정 모드: initialData에 데이터가 있으면서 ID가 변경된 경우 재초기화
|
|
|
|
|
if (hasInitialized.current && currentIdString && lastInitializedId.current !== currentIdString) {
|
|
|
|
|
@ -252,6 +269,7 @@ export function UniversalFormModalComponent({
|
|
|
|
|
console.log("[UniversalFormModal] 초기 데이터 캡처:", capturedInitialData.current);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log("[UniversalFormModal] initializeForm 호출 예정");
|
|
|
|
|
hasInitialized.current = true;
|
|
|
|
|
initializeForm();
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
|
@ -389,6 +407,94 @@ export function UniversalFormModalComponent({
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
|
}, [config.sections]);
|
|
|
|
|
|
|
|
|
|
// 채번규칙 자동 생성 (중복 호출 방지)
|
|
|
|
|
// 중요: initializeForm에서 호출되므로 반드시 initializeForm보다 먼저 선언해야 함
|
|
|
|
|
const numberingGeneratedRef = useRef(false);
|
|
|
|
|
const isGeneratingRef = useRef(false); // 진행 중 플래그 추가
|
|
|
|
|
|
|
|
|
|
const generateNumberingValues = useCallback(
|
|
|
|
|
async (currentFormData: FormDataState) => {
|
|
|
|
|
// 이미 생성되었거나 진행 중이면 스킵
|
|
|
|
|
if (numberingGeneratedRef.current) {
|
|
|
|
|
console.log("[채번] 이미 생성됨 - 스킵");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isGeneratingRef.current) {
|
|
|
|
|
console.log("[채번] 생성 진행 중 - 스킵");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isGeneratingRef.current = true; // 진행 중 표시
|
|
|
|
|
console.log("[채번] 생성 시작", { sectionsCount: config.sections.length });
|
|
|
|
|
|
|
|
|
|
const updatedData = { ...currentFormData };
|
|
|
|
|
let hasChanges = false;
|
|
|
|
|
|
|
|
|
|
for (const section of config.sections) {
|
|
|
|
|
console.log("[채번] 섹션 검사:", section.title, { type: section.type, repeatable: section.repeatable, fieldsCount: section.fields?.length });
|
|
|
|
|
if (section.repeatable || section.type === "table") continue;
|
|
|
|
|
|
|
|
|
|
for (const field of (section.fields || [])) {
|
|
|
|
|
// generateOnOpen은 기본값 true (undefined일 경우 true로 처리)
|
|
|
|
|
const shouldGenerateOnOpen = field.numberingRule?.generateOnOpen !== false;
|
|
|
|
|
console.log("[채번] 필드 검사:", field.columnName, {
|
|
|
|
|
hasNumberingRule: !!field.numberingRule,
|
|
|
|
|
enabled: field.numberingRule?.enabled,
|
|
|
|
|
generateOnOpen: field.numberingRule?.generateOnOpen,
|
|
|
|
|
shouldGenerateOnOpen,
|
|
|
|
|
ruleId: field.numberingRule?.ruleId,
|
|
|
|
|
currentValue: updatedData[field.columnName],
|
|
|
|
|
});
|
|
|
|
|
if (
|
|
|
|
|
field.numberingRule?.enabled &&
|
|
|
|
|
shouldGenerateOnOpen &&
|
|
|
|
|
field.numberingRule?.ruleId &&
|
|
|
|
|
!updatedData[field.columnName]
|
|
|
|
|
) {
|
|
|
|
|
try {
|
|
|
|
|
console.log(`[채번 미리보기 API 호출] ${field.columnName}, ruleId: ${field.numberingRule.ruleId}`);
|
|
|
|
|
// generateOnOpen: 미리보기만 표시 (DB 시퀀스 증가 안 함)
|
|
|
|
|
const response = await previewNumberingCode(field.numberingRule.ruleId);
|
|
|
|
|
if (response.success && response.data?.generatedCode) {
|
|
|
|
|
updatedData[field.columnName] = response.data.generatedCode;
|
|
|
|
|
|
|
|
|
|
// 저장 시 실제 할당을 위해 ruleId 저장 (TextInput과 동일한 키 형식)
|
|
|
|
|
const ruleIdKey = `${field.columnName}_numberingRuleId`;
|
|
|
|
|
updatedData[ruleIdKey] = field.numberingRule.ruleId;
|
|
|
|
|
|
|
|
|
|
hasChanges = true;
|
|
|
|
|
numberingGeneratedRef.current = true; // 생성 완료 표시
|
|
|
|
|
console.log(
|
|
|
|
|
`[채번 미리보기 완료] ${field.columnName} = ${response.data.generatedCode} (저장 시 실제 할당)`,
|
|
|
|
|
);
|
|
|
|
|
console.log(`[채번 규칙 ID 저장] ${ruleIdKey} = ${field.numberingRule.ruleId}`);
|
|
|
|
|
|
|
|
|
|
// 부모 컴포넌트에도 ruleId 전달 (ModalRepeaterTable → ScreenModal)
|
|
|
|
|
if (onChange) {
|
|
|
|
|
onChange({
|
|
|
|
|
...updatedData,
|
|
|
|
|
[ruleIdKey]: field.numberingRule.ruleId,
|
|
|
|
|
});
|
|
|
|
|
console.log(`[채번] 부모에게 ruleId 전달: ${ruleIdKey}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(`채번규칙 미리보기 실패 (${field.columnName}):`, error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isGeneratingRef.current = false; // 진행 완료
|
|
|
|
|
|
|
|
|
|
if (hasChanges) {
|
|
|
|
|
setFormData(updatedData);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[config, onChange],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 폼 초기화
|
|
|
|
|
const initializeForm = useCallback(async () => {
|
|
|
|
|
console.log("[initializeForm] 시작");
|
|
|
|
|
@ -585,82 +691,6 @@ export function UniversalFormModalComponent({
|
|
|
|
|
return item;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 채번규칙 자동 생성 (중복 호출 방지)
|
|
|
|
|
const numberingGeneratedRef = useRef(false);
|
|
|
|
|
const isGeneratingRef = useRef(false); // 진행 중 플래그 추가
|
|
|
|
|
|
|
|
|
|
const generateNumberingValues = useCallback(
|
|
|
|
|
async (currentFormData: FormDataState) => {
|
|
|
|
|
// 이미 생성되었거나 진행 중이면 스킵
|
|
|
|
|
if (numberingGeneratedRef.current) {
|
|
|
|
|
console.log("[채번] 이미 생성됨 - 스킵");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isGeneratingRef.current) {
|
|
|
|
|
console.log("[채번] 생성 진행 중 - 스킵");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isGeneratingRef.current = true; // 진행 중 표시
|
|
|
|
|
console.log("[채번] 생성 시작");
|
|
|
|
|
|
|
|
|
|
const updatedData = { ...currentFormData };
|
|
|
|
|
let hasChanges = false;
|
|
|
|
|
|
|
|
|
|
for (const section of config.sections) {
|
|
|
|
|
if (section.repeatable || section.type === "table") continue;
|
|
|
|
|
|
|
|
|
|
for (const field of (section.fields || [])) {
|
|
|
|
|
if (
|
|
|
|
|
field.numberingRule?.enabled &&
|
|
|
|
|
field.numberingRule?.generateOnOpen &&
|
|
|
|
|
field.numberingRule?.ruleId &&
|
|
|
|
|
!updatedData[field.columnName]
|
|
|
|
|
) {
|
|
|
|
|
try {
|
|
|
|
|
console.log(`[채번 미리보기 API 호출] ${field.columnName}, ruleId: ${field.numberingRule.ruleId}`);
|
|
|
|
|
// generateOnOpen: 미리보기만 표시 (DB 시퀀스 증가 안 함)
|
|
|
|
|
const response = await previewNumberingCode(field.numberingRule.ruleId);
|
|
|
|
|
if (response.success && response.data?.generatedCode) {
|
|
|
|
|
updatedData[field.columnName] = response.data.generatedCode;
|
|
|
|
|
|
|
|
|
|
// 저장 시 실제 할당을 위해 ruleId 저장 (TextInput과 동일한 키 형식)
|
|
|
|
|
const ruleIdKey = `${field.columnName}_numberingRuleId`;
|
|
|
|
|
updatedData[ruleIdKey] = field.numberingRule.ruleId;
|
|
|
|
|
|
|
|
|
|
hasChanges = true;
|
|
|
|
|
numberingGeneratedRef.current = true; // 생성 완료 표시
|
|
|
|
|
console.log(
|
|
|
|
|
`[채번 미리보기 완료] ${field.columnName} = ${response.data.generatedCode} (저장 시 실제 할당)`,
|
|
|
|
|
);
|
|
|
|
|
console.log(`[채번 규칙 ID 저장] ${ruleIdKey} = ${field.numberingRule.ruleId}`);
|
|
|
|
|
|
|
|
|
|
// 부모 컴포넌트에도 ruleId 전달 (ModalRepeaterTable → ScreenModal)
|
|
|
|
|
if (onChange) {
|
|
|
|
|
onChange({
|
|
|
|
|
...updatedData,
|
|
|
|
|
[ruleIdKey]: field.numberingRule.ruleId,
|
|
|
|
|
});
|
|
|
|
|
console.log(`[채번] 부모에게 ruleId 전달: ${ruleIdKey}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(`채번규칙 미리보기 실패 (${field.columnName}):`, error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isGeneratingRef.current = false; // 진행 완료
|
|
|
|
|
|
|
|
|
|
if (hasChanges) {
|
|
|
|
|
setFormData(updatedData);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[config, onChange],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 필드 값 변경 핸들러
|
|
|
|
|
const handleFieldChange = useCallback(
|
|
|
|
|
(columnName: string, value: any) => {
|
|
|
|
|
|