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.
This commit is contained in:
parent
e5aa44e0d4
commit
43a394df31
|
|
@ -194,4 +194,6 @@ mcp-task-queue/
|
||||||
|
|
||||||
# 파이프라인 회고록 (자동 생성)
|
# 파이프라인 회고록 (자동 생성)
|
||||||
docs/retrospectives/
|
docs/retrospectives/
|
||||||
mes-architecture-guide.md
|
mes-architecture-guide.md
|
||||||
|
# MES Reference Documents
|
||||||
|
docs/mes-reference/
|
||||||
|
|
|
||||||
|
|
@ -367,6 +367,20 @@ export const V2Repeater: React.FC<V2RepeaterProps> = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
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<string> = new Set();
|
let validColumns: Set<string> = new Set();
|
||||||
try {
|
try {
|
||||||
const columnsResponse = await apiClient.get(`/table-management/tables/${tableName}/columns`);
|
const columnsResponse = await apiClient.get(`/table-management/tables/${tableName}/columns`);
|
||||||
|
|
@ -706,6 +720,7 @@ export const V2Repeater: React.FC<V2RepeaterProps> = ({
|
||||||
displayName: col.displayName || col.display_name || col.label || name,
|
displayName: col.displayName || col.display_name || col.label || name,
|
||||||
detailSettings: col.detailSettings || col.detail_settings,
|
detailSettings: col.detailSettings || col.detail_settings,
|
||||||
categoryRef: typeInfo?.categoryRef || null,
|
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);
|
setCurrentTableColumnInfo(columnMap);
|
||||||
|
|
@ -808,10 +823,12 @@ export const V2Repeater: React.FC<V2RepeaterProps> = ({
|
||||||
loadSourceColumnLabels();
|
loadSourceColumnLabels();
|
||||||
}, [resolvedSourceTable, isModalMode]);
|
}, [resolvedSourceTable, isModalMode]);
|
||||||
|
|
||||||
|
const repeaterColumnsRef = useRef<RepeaterColumnConfig[]>([]);
|
||||||
|
|
||||||
// V2ColumnConfig → RepeaterColumnConfig 변환
|
// V2ColumnConfig → RepeaterColumnConfig 변환
|
||||||
// 🆕 모든 컬럼을 columns 배열의 순서대로 처리 (isSourceDisplay 플래그로 구분)
|
// 🆕 모든 컬럼을 columns 배열의 순서대로 처리 (isSourceDisplay 플래그로 구분)
|
||||||
const repeaterColumns: RepeaterColumnConfig[] = useMemo(() => {
|
const repeaterColumns: RepeaterColumnConfig[] = useMemo(() => {
|
||||||
return config.columns
|
const cols = config.columns
|
||||||
.filter((col: V2ColumnConfig) => col.visible !== false)
|
.filter((col: V2ColumnConfig) => col.visible !== false)
|
||||||
.map((col: V2ColumnConfig): RepeaterColumnConfig => {
|
.map((col: V2ColumnConfig): RepeaterColumnConfig => {
|
||||||
const colInfo = currentTableColumnInfo[col.key];
|
const colInfo = currentTableColumnInfo[col.key];
|
||||||
|
|
@ -858,12 +875,15 @@ export const V2Repeater: React.FC<V2RepeaterProps> = ({
|
||||||
type,
|
type,
|
||||||
editable: col.editable !== false,
|
editable: col.editable !== false,
|
||||||
width: col.width === "auto" ? undefined : col.width,
|
width: col.width === "auto" ? undefined : col.width,
|
||||||
required: false,
|
required: colInfo?.isRequired || false,
|
||||||
categoryRef, // 🆕 카테고리 참조 ID 전달
|
categoryRef, // 🆕 카테고리 참조 ID 전달
|
||||||
hidden: col.hidden, // 🆕 히든 처리
|
hidden: col.hidden, // 🆕 히든 처리
|
||||||
autoFill: col.autoFill, // 🆕 자동 입력 설정
|
autoFill: col.autoFill, // 🆕 자동 입력 설정
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
repeaterColumnsRef.current = cols;
|
||||||
|
return cols;
|
||||||
}, [config.columns, sourceColumnLabels, currentTableColumnInfo, resolvedSourceTable, config.dataSource?.tableName]);
|
}, [config.columns, sourceColumnLabels, currentTableColumnInfo, resolvedSourceTable, config.dataSource?.tableName]);
|
||||||
|
|
||||||
// 리피터 컬럼 설정에서 카테고리 타입 컬럼 자동 감지
|
// 리피터 컬럼 설정에서 카테고리 타입 컬럼 자동 감지
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue