- 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.
94 lines
3.4 KiB
TypeScript
94 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import { AutoRegisteringComponentRenderer } from "../../AutoRegisteringComponentRenderer";
|
|
import { V2InputDefinition } from "./index";
|
|
import { V2Input } from "@/components/v2/V2Input";
|
|
import { isColumnRequiredByMeta } from "../../DynamicComponentRenderer";
|
|
|
|
/**
|
|
* V2Input 렌더러
|
|
* 자동 등록 시스템을 사용하여 컴포넌트를 레지스트리에 등록
|
|
*/
|
|
export class V2InputRenderer extends AutoRegisteringComponentRenderer {
|
|
static componentDefinition = V2InputDefinition;
|
|
|
|
render(): React.ReactElement {
|
|
const { component, formData, onFormDataChange, isDesignMode, isSelected, isInteractive, ...restProps } = this.props;
|
|
|
|
// 컴포넌트 설정 추출
|
|
const config = component.componentConfig || component.config || {};
|
|
const columnName = component.columnName;
|
|
const tableName = component.tableName || this.props.tableName;
|
|
|
|
// formData에서 현재 값 가져오기
|
|
const currentValue = formData?.[columnName] ?? component.value ?? "";
|
|
|
|
// 값 변경 핸들러
|
|
const handleChange = (value: any) => {
|
|
console.log("🔄 [V2InputRenderer] handleChange 호출:", {
|
|
columnName,
|
|
value,
|
|
isInteractive,
|
|
hasOnFormDataChange: !!onFormDataChange,
|
|
});
|
|
if (isInteractive && onFormDataChange && columnName) {
|
|
onFormDataChange(columnName, value);
|
|
} else {
|
|
console.warn("⚠️ [V2InputRenderer] onFormDataChange 호출 스킵:", {
|
|
isInteractive,
|
|
hasOnFormDataChange: !!onFormDataChange,
|
|
columnName,
|
|
});
|
|
}
|
|
};
|
|
|
|
// 라벨: style.labelText 우선, 없으면 component.label 사용
|
|
// 🔧 style.labelDisplay를 먼저 체크 (속성 패널에서 style 객체로 업데이트하므로)
|
|
const style = component.style || {};
|
|
const labelDisplay = style.labelDisplay ?? (component as any).labelDisplay;
|
|
// labelDisplay: true → 라벨 표시, false → 숨김, undefined → 기존 동작 유지(숨김)
|
|
const effectiveLabel = labelDisplay === true ? style.labelText || component.label : undefined;
|
|
|
|
return (
|
|
<V2Input
|
|
id={component.id}
|
|
value={currentValue}
|
|
onChange={handleChange}
|
|
onFormDataChange={onFormDataChange}
|
|
config={{
|
|
type: config.inputType || config.webType || "text",
|
|
inputType: config.inputType || config.webType || "text",
|
|
placeholder: config.placeholder,
|
|
format: config.format,
|
|
min: config.min,
|
|
max: config.max,
|
|
step: config.step,
|
|
rows: config.rows,
|
|
autoGeneration: config.autoGeneration || component.autoGeneration,
|
|
}}
|
|
style={component.style}
|
|
size={component.size}
|
|
formData={formData}
|
|
columnName={columnName}
|
|
tableName={tableName}
|
|
autoGeneration={config.autoGeneration || component.autoGeneration}
|
|
originalData={(this.props as any).originalData}
|
|
{...restProps}
|
|
label={effectiveLabel}
|
|
required={component.required || isColumnRequiredByMeta(tableName, columnName)}
|
|
readonly={config.readonly || component.readonly}
|
|
disabled={config.disabled || component.disabled}
|
|
/>
|
|
);
|
|
}
|
|
}
|
|
|
|
// 자동 등록 실행
|
|
V2InputRenderer.registerSelf();
|
|
|
|
// Hot Reload 지원 (개발 모드)
|
|
if (process.env.NODE_ENV === "development") {
|
|
V2InputRenderer.enableHotReload();
|
|
}
|