Merge remote-tracking branch 'origin/ycshin-node' into ycshin-node

Resolve conflict in InteractiveScreenViewerDynamic.tsx:
- Keep horizontal label code (fd5c61b side)
- Remove old inline required field validation (replaced by useDialogAutoValidation hook)
- Clean up checkAllRequiredFieldsFilled usage from SaveModal, ButtonPrimaryComponent
- Remove isFieldEmpty, isInputComponent, checkAllRequiredFieldsFilled from formValidation.ts

Made-with: Cursor
This commit is contained in:
2026-03-03 13:12:48 +09:00
38 changed files with 1642 additions and 525 deletions

View File

@@ -662,75 +662,3 @@ const calculateStringSimilarity = (str1: string, str2: string): number => {
return maxLen === 0 ? 1 : (maxLen - distance) / maxLen;
};
/**
* 값이 비어있는지 판별
*/
export const isFieldEmpty = (value: any): boolean => {
return (
value === null ||
value === undefined ||
(typeof value === "string" && value.trim() === "") ||
(Array.isArray(value) && value.length === 0)
);
};
/**
* 입력 가능한 컴포넌트인지 판별 (위젯 또는 V2 입력 컴포넌트)
*/
const isInputComponent = (comp: any): boolean => {
if (comp.type === "widget") return true;
if (comp.type === "component") {
const ct = comp.componentType || "";
return ct.startsWith("v2-input") ||
ct.startsWith("v2-select") ||
ct.startsWith("v2-date") ||
ct.startsWith("v2-textarea") ||
ct.startsWith("v2-number") ||
ct === "entity-search-input" ||
ct === "autocomplete-search-input";
}
return false;
};
/**
* 모든 필수 필드가 채워졌는지 판별 (모달 저장 버튼 비활성화용)
* auto 입력 필드, readonly 필드는 검증 제외
*/
export const checkAllRequiredFieldsFilled = (
allComponents: any[],
formData: Record<string, any>,
): boolean => {
for (const comp of allComponents) {
if (!isInputComponent(comp)) continue;
const isRequired =
comp.required === true ||
comp.style?.required === true ||
comp.componentConfig?.required === true ||
comp.overrides?.required === true;
if (!isRequired) continue;
const isAutoInput =
comp.inputType === "auto" ||
comp.componentConfig?.inputType === "auto" ||
comp.overrides?.inputType === "auto";
const isReadonly =
comp.readonly === true ||
comp.componentConfig?.readonly === true ||
comp.overrides?.readonly === true;
if (isAutoInput || isReadonly) continue;
const fieldName =
comp.columnName ||
comp.componentConfig?.columnName ||
comp.overrides?.columnName ||
comp.id;
const value = formData[fieldName];
if (isFieldEmpty(value)) {
return false;
}
}
return true;
};