From 5fa905f9abf5e73945df426732b7e1a533fa8834 Mon Sep 17 00:00:00 2001 From: kjs Date: Wed, 18 Mar 2026 17:59:27 +0900 Subject: [PATCH 1/3] refactor: simplify FileUploadComponent logic and remove unnecessary condition - Removed the check for record mode in the FileUploadComponent, streamlining the file loading process. - Updated the dependency array in the useEffect hook to exclude isRecordMode, ensuring cleaner and more efficient component behavior. These changes aim to enhance the clarity and maintainability of the FileUploadComponent, improving overall functionality. --- .../components/v2-file-upload/FileUploadComponent.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/lib/registry/components/v2-file-upload/FileUploadComponent.tsx b/frontend/lib/registry/components/v2-file-upload/FileUploadComponent.tsx index 2baa6887..8c42b957 100644 --- a/frontend/lib/registry/components/v2-file-upload/FileUploadComponent.tsx +++ b/frontend/lib/registry/components/v2-file-upload/FileUploadComponent.tsx @@ -207,9 +207,6 @@ const FileUploadComponent: React.FC = ({ return; } - // 등록 모드(새 레코드)일 때는 이전 파일을 로드하지 않음 - if (!isRecordMode) return; - const rawValue = String(imageObjidFromFormData); // 콤마 구분 다중 objid 또는 단일 objid 모두 처리 const objids = rawValue.split(',').map(s => s.trim()).filter(s => /^\d+$/.test(s)); @@ -265,7 +262,7 @@ const FileUploadComponent: React.FC = ({ console.error("🖼️ [FileUploadComponent] 파일 정보 조회 오류:", error); } })(); - }, [imageObjidFromFormData, columnName, component.id, isRecordMode]); + }, [imageObjidFromFormData, columnName, component.id]); // 🎯 화면설계 모드에서 실제 화면으로의 실시간 동기화 이벤트 리스너 // 🆕 columnName도 체크하여 같은 화면의 다른 파일 업로드 컴포넌트와 구분 -- 2.43.0 From 43a394df316f8f43fac798424b127201738b7e13 Mon Sep 17 00:00:00 2001 From: kjs Date: Wed, 18 Mar 2026 18:34:00 +0900 Subject: [PATCH 2/3] feat: add required field validation in V2Repeater component - Implemented validation logic to ensure required fields are filled before saving data in the V2Repeater component. - Added error messages to notify users of missing required fields, enhancing user experience and data integrity. - Updated column configuration to include isRequired property for better handling of required fields. These changes aim to improve data validation and user feedback during data entry processes. --- .gitignore | 4 +++- frontend/components/v2/V2Repeater.tsx | 24 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2566257f..972957ba 100644 --- a/.gitignore +++ b/.gitignore @@ -194,4 +194,6 @@ mcp-task-queue/ # 파이프라인 회고록 (자동 생성) docs/retrospectives/ -mes-architecture-guide.md \ No newline at end of file +mes-architecture-guide.md +# MES Reference Documents +docs/mes-reference/ diff --git a/frontend/components/v2/V2Repeater.tsx b/frontend/components/v2/V2Repeater.tsx index f2f46f82..9290f21c 100644 --- a/frontend/components/v2/V2Repeater.tsx +++ b/frontend/components/v2/V2Repeater.tsx @@ -367,6 +367,20 @@ export const V2Repeater: React.FC = ({ }); try { + // 🆕 필수값 검증 + const requiredColumns = repeaterColumnsRef.current.filter(col => col.required); + for (let i = 0; i < currentData.length; i++) { + const row = currentData[i]; + for (const col of requiredColumns) { + const val = row[col.field]; + if (val === undefined || val === null || val === "") { + toast.error(`${i + 1}번째 행의 '${col.label}'은(는) 필수 입력 항목입니다.`); + window.dispatchEvent(new CustomEvent("repeaterSaveComplete")); + return; + } + } + } + let validColumns: Set = new Set(); try { const columnsResponse = await apiClient.get(`/table-management/tables/${tableName}/columns`); @@ -706,6 +720,7 @@ export const V2Repeater: React.FC = ({ displayName: col.displayName || col.display_name || col.label || name, detailSettings: col.detailSettings || col.detail_settings, categoryRef: typeInfo?.categoryRef || null, + isRequired: col.isRequired || col.is_required || col.notNull || col.not_null === true || col.not_null === 'Y' || col.not_null === 'y', }; }); setCurrentTableColumnInfo(columnMap); @@ -808,10 +823,12 @@ export const V2Repeater: React.FC = ({ loadSourceColumnLabels(); }, [resolvedSourceTable, isModalMode]); + const repeaterColumnsRef = useRef([]); + // V2ColumnConfig → RepeaterColumnConfig 변환 // 🆕 모든 컬럼을 columns 배열의 순서대로 처리 (isSourceDisplay 플래그로 구분) const repeaterColumns: RepeaterColumnConfig[] = useMemo(() => { - return config.columns + const cols = config.columns .filter((col: V2ColumnConfig) => col.visible !== false) .map((col: V2ColumnConfig): RepeaterColumnConfig => { const colInfo = currentTableColumnInfo[col.key]; @@ -858,12 +875,15 @@ export const V2Repeater: React.FC = ({ type, editable: col.editable !== false, width: col.width === "auto" ? undefined : col.width, - required: false, + required: colInfo?.isRequired || false, categoryRef, // 🆕 카테고리 참조 ID 전달 hidden: col.hidden, // 🆕 히든 처리 autoFill: col.autoFill, // 🆕 자동 입력 설정 }; }); + + repeaterColumnsRef.current = cols; + return cols; }, [config.columns, sourceColumnLabels, currentTableColumnInfo, resolvedSourceTable, config.dataSource?.tableName]); // 리피터 컬럼 설정에서 카테고리 타입 컬럼 자동 감지 -- 2.43.0 From 1064397be235ba939a56bd10a82cbe581d6dd8f4 Mon Sep 17 00:00:00 2001 From: kjs Date: Thu, 19 Mar 2026 09:47:15 +0900 Subject: [PATCH 3/3] fix: update required field handling in V2Repeater and RepeaterTable components - Modified the logic in the V2Repeater component to determine required fields based on the isNullable property, enhancing validation accuracy. - Updated the RepeaterTable component to visually indicate required fields with an asterisk, improving user awareness during data entry. These changes aim to enhance data validation and user experience by ensuring that required fields are clearly marked and accurately validated. --- frontend/components/v2/V2Repeater.tsx | 2 +- .../registry/components/modal-repeater-table/RepeaterTable.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/components/v2/V2Repeater.tsx b/frontend/components/v2/V2Repeater.tsx index 9290f21c..31a80c18 100644 --- a/frontend/components/v2/V2Repeater.tsx +++ b/frontend/components/v2/V2Repeater.tsx @@ -720,7 +720,7 @@ export const V2Repeater: React.FC = ({ displayName: col.displayName || col.display_name || col.label || name, detailSettings: col.detailSettings || col.detail_settings, categoryRef: typeInfo?.categoryRef || null, - isRequired: col.isRequired || col.is_required || col.notNull || col.not_null === true || col.not_null === 'Y' || col.not_null === 'y', + isRequired: col.isNullable === 'NO' || col.is_nullable === 'NO' || col.isRequired || col.is_required || col.notNull || col.not_null === true || col.not_null === 'Y' || col.not_null === 'y', }; }); setCurrentTableColumnInfo(columnMap); diff --git a/frontend/lib/registry/components/modal-repeater-table/RepeaterTable.tsx b/frontend/lib/registry/components/modal-repeater-table/RepeaterTable.tsx index 4b8cb23d..e9df58d5 100644 --- a/frontend/lib/registry/components/modal-repeater-table/RepeaterTable.tsx +++ b/frontend/lib/registry/components/modal-repeater-table/RepeaterTable.tsx @@ -792,6 +792,7 @@ export function RepeaterTable({ {/* 컬럼명 - 선택된 옵션라벨 형식으로 표시 */} {activeOption?.headerLabel || `${col.label} - ${activeOption?.label || ""}`} + {col.required && *} -- 2.43.0