feat: Implement NOT NULL validation for form fields based on table metadata
- Added a new function `isColumnRequired` to determine if a column is required based on its NOT NULL status from the table schema. - Updated the `SaveModal` and `InteractiveScreenViewer` components to incorporate this validation, ensuring that required fields are accurately assessed during form submission. - Enhanced the `DynamicComponentRenderer` to reflect the NOT NULL requirement in the component's required state. - Improved user feedback by marking required fields with an asterisk based on both manual settings and database constraints. These changes enhance the form validation process, ensuring that users are prompted for all necessary information based on the underlying data structure.
This commit is contained in:
@@ -245,6 +245,17 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
|
||||
// 통합된 폼 데이터
|
||||
const finalFormData = { ...localFormData, ...externalFormData };
|
||||
|
||||
// 테이블 타입관리 NOT NULL 기반 필수 여부 판단
|
||||
const isColumnRequired = useCallback((columnName: string): boolean => {
|
||||
if (!columnName || tableColumns.length === 0) return false;
|
||||
const colInfo = tableColumns.find(
|
||||
(c: any) => (c.columnName || c.column_name || "").toLowerCase() === columnName.toLowerCase()
|
||||
);
|
||||
if (!colInfo) return false;
|
||||
const nullable = (colInfo as any).isNullable || (colInfo as any).is_nullable;
|
||||
return nullable === "NO" || nullable === "N";
|
||||
}, [tableColumns]);
|
||||
|
||||
// 🆕 조건부 레이어 로직 (formData 변경 시 자동 평가)
|
||||
useEffect(() => {
|
||||
layers.forEach((layer) => {
|
||||
@@ -1612,8 +1623,11 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
|
||||
return;
|
||||
}
|
||||
|
||||
// 필수 항목 검증
|
||||
const requiredFields = allComponents.filter(c => c.required && (c.columnName || c.id));
|
||||
// 필수 항목 검증 (테이블 타입관리 NOT NULL 기반 + 기존 required 속성 폴백)
|
||||
const requiredFields = allComponents.filter(c => {
|
||||
const colName = c.columnName || c.id;
|
||||
return (c.required || isColumnRequired(colName)) && colName;
|
||||
});
|
||||
const missingFields = requiredFields.filter(field => {
|
||||
const fieldName = field.columnName || field.id;
|
||||
const value = currentFormData[fieldName];
|
||||
@@ -2486,7 +2500,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
|
||||
style={labelStyle}
|
||||
>
|
||||
{labelText}
|
||||
{(component.required || component.componentConfig?.required) && <span className="ml-1 text-destructive">*</span>}
|
||||
{(component.required || component.componentConfig?.required || isColumnRequired(component.columnName || component.style?.columnName || "")) && <span className="ml-1 text-destructive">*</span>}
|
||||
</label>
|
||||
)}
|
||||
|
||||
@@ -2505,7 +2519,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
|
||||
}}
|
||||
>
|
||||
{labelText}
|
||||
{(component.required || component.componentConfig?.required) && <span className="ml-1 text-destructive">*</span>}
|
||||
{(component.required || component.componentConfig?.required || isColumnRequired(component.columnName || component.style?.columnName || "")) && <span className="ml-1 text-destructive">*</span>}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user