From 57662df8cb4756b24ca3f12ebdd8c6d58cb7fe85 Mon Sep 17 00:00:00 2001 From: SeongHyun Kim Date: Thu, 22 Jan 2026 10:57:15 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20UniversalFormModal=20=ED=95=84=EC=88=98?= =?UTF-8?q?=EA=B0=92=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - beforeFormSave 이벤트 핸들러에서 validateRequiredFields() 호출 추가 - 검증 실패 시 validationFailed 플래그로 저장 중단 처리 - 누락된 필수 필드명을 사용자에게 toast로 명확히 표시 - 패널 설정에서 필수 체크 하여도 작동하지 않는 문제 해결 --- .../UniversalFormModalComponent.tsx | 10 ++++++++++ frontend/lib/utils/buttonActions.ts | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/frontend/lib/registry/components/universal-form-modal/UniversalFormModalComponent.tsx b/frontend/lib/registry/components/universal-form-modal/UniversalFormModalComponent.tsx index 939bb5d5..ba206683 100644 --- a/frontend/lib/registry/components/universal-form-modal/UniversalFormModalComponent.tsx +++ b/frontend/lib/registry/components/universal-form-modal/UniversalFormModalComponent.tsx @@ -380,6 +380,16 @@ export function UniversalFormModalComponent({ const handleBeforeFormSave = (event: Event) => { if (!(event instanceof CustomEvent) || !event.detail?.formData) return; + // 필수값 검증 실행 + const validation = validateRequiredFields(); + if (!validation.valid) { + event.detail.validationFailed = true; + event.detail.validationErrors = validation.missingFields; + toast.error(`필수 항목을 입력해주세요: ${validation.missingFields.join(", ")}`); + console.log("[UniversalFormModal] 필수값 검증 실패:", validation.missingFields); + return; // 검증 실패 시 데이터 병합 중단 + } + // 설정에 정의된 필드 columnName 목록 수집 const configuredFields = new Set(); config.sections.forEach((section) => { diff --git a/frontend/lib/utils/buttonActions.ts b/frontend/lib/utils/buttonActions.ts index a4b6074c..edc6861a 100644 --- a/frontend/lib/utils/buttonActions.ts +++ b/frontend/lib/utils/buttonActions.ts @@ -542,6 +542,8 @@ export class ButtonActionExecutor { const beforeSaveEventDetail = { formData: context.formData, skipDefaultSave: false, + validationFailed: false, + validationErrors: [] as string[], }; window.dispatchEvent( new CustomEvent("beforeFormSave", { @@ -552,6 +554,12 @@ export class ButtonActionExecutor { // 약간의 대기 시간을 주어 이벤트 핸들러가 formData를 업데이트할 수 있도록 함 await new Promise((resolve) => setTimeout(resolve, 100)); + // 검증 실패 시 저장 중단 + if (beforeSaveEventDetail.validationFailed) { + console.log("❌ [handleSave] 검증 실패로 저장 중단:", beforeSaveEventDetail.validationErrors); + return false; + } + // 🔧 skipDefaultSave 플래그 확인 - SelectedItemsDetailInput 등에서 자체 UPSERT 처리 시 기본 저장 건너뛰기 if (beforeSaveEventDetail.skipDefaultSave) { console.log("🚫 [handleSave] skipDefaultSave=true - 기본 저장 로직 건너뛰기 (컴포넌트에서 자체 처리)");