feat: 테이블 관리 페이지의 컬럼 설정 저장 로직 개선

- 컬럼의 detailSettings을 동적으로 계산하여 다양한 입력 타입에 맞는 설정을 포함하도록 수정하였습니다.
- Numbering, Entity, Code 타입에 대한 추가 설정을 detailSettings에 포함시켜 데이터 저장 시 유연성을 높였습니다.
- V2Input 컴포넌트에서 채번 규칙 ID를 formData에 저장하는 기능을 추가하여 데이터 처리의 일관성을 강화하였습니다.
- 레이아웃 변환 함수에 메타데이터를 포함하여 레이아웃 정보를 더욱 풍부하게 하였습니다.
This commit is contained in:
kjs 2026-02-03 11:02:13 +09:00
parent dd1ddd6418
commit 3e19218382
4 changed files with 97 additions and 13 deletions

View File

@ -773,18 +773,81 @@ export default function TableManagementPage() {
// 2. 모든 컬럼 설정 저장
if (columns.length > 0) {
const columnSettings = columns.map((column) => ({
columnName: column.columnName, // 실제 DB 컬럼명 (변경 불가)
columnLabel: column.displayName, // 사용자가 입력한 표시명
inputType: column.inputType || "text",
detailSettings: column.detailSettings || "",
description: column.description || "",
codeCategory: column.codeCategory || "",
codeValue: column.codeValue || "",
referenceTable: column.referenceTable || "",
referenceColumn: column.referenceColumn || "",
displayColumn: column.displayColumn || "", // 🎯 Entity 조인에서 표시할 컬럼명
}));
const columnSettings = columns.map((column) => {
// detailSettings 계산
let finalDetailSettings = column.detailSettings || "";
// 🆕 Numbering 타입인 경우 numberingRuleId를 detailSettings에 포함
if (column.inputType === "numbering" && column.numberingRuleId) {
let existingSettings: Record<string, unknown> = {};
if (typeof finalDetailSettings === "string" && finalDetailSettings.trim().startsWith("{")) {
try {
existingSettings = JSON.parse(finalDetailSettings);
} catch {
existingSettings = {};
}
}
const numberingSettings = {
...existingSettings,
numberingRuleId: column.numberingRuleId,
};
finalDetailSettings = JSON.stringify(numberingSettings);
console.log("🔧 전체저장 - Numbering 설정 JSON 생성:", {
columnName: column.columnName,
numberingRuleId: column.numberingRuleId,
finalDetailSettings,
});
}
// 🆕 Entity 타입인 경우 detailSettings에 엔티티 설정 포함
if (column.inputType === "entity" && column.referenceTable) {
let existingSettings: Record<string, unknown> = {};
if (typeof finalDetailSettings === "string" && finalDetailSettings.trim().startsWith("{")) {
try {
existingSettings = JSON.parse(finalDetailSettings);
} catch {
existingSettings = {};
}
}
const entitySettings = {
...existingSettings,
entityTable: column.referenceTable,
entityCodeColumn: column.referenceColumn || "id",
entityLabelColumn: column.displayColumn || "name",
};
finalDetailSettings = JSON.stringify(entitySettings);
}
// 🆕 Code 타입인 경우 hierarchyRole을 detailSettings에 포함
if (column.inputType === "code" && column.hierarchyRole) {
let existingSettings: Record<string, unknown> = {};
if (typeof finalDetailSettings === "string" && finalDetailSettings.trim().startsWith("{")) {
try {
existingSettings = JSON.parse(finalDetailSettings);
} catch {
existingSettings = {};
}
}
const codeSettings = {
...existingSettings,
hierarchyRole: column.hierarchyRole,
};
finalDetailSettings = JSON.stringify(codeSettings);
}
return {
columnName: column.columnName, // 실제 DB 컬럼명 (변경 불가)
columnLabel: column.displayName, // 사용자가 입력한 표시명
inputType: column.inputType || "text",
detailSettings: finalDetailSettings,
description: column.description || "",
codeCategory: column.codeCategory || "",
codeValue: column.codeValue || "",
referenceTable: column.referenceTable || "",
referenceColumn: column.referenceColumn || "",
displayColumn: column.displayColumn || "", // 🎯 Entity 조인에서 표시할 컬럼명
};
});
// console.log("저장할 전체 설정:", { tableLabel, tableDescription, columnSettings });

View File

@ -334,6 +334,8 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
// formData 추출 (채번규칙 날짜 컬럼 기준 생성 시 사용)
const formData = (props as any).formData || {};
const columnName = (props as any).columnName;
// onFormDataChange 추출 (채번 규칙 ID를 formData에 저장하기 위함)
const onFormDataChange = (props as any).onFormDataChange;
// config가 없으면 기본값 사용
const config = (configProp || { type: "text" }) as V2InputConfig & {
@ -526,6 +528,15 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
try {
const parsed = JSON.parse(targetColumn.detailSettings);
numberingRuleIdRef.current = parsed.numberingRuleId || null;
// 🆕 채번 규칙 ID를 formData에 저장 (저장 시 allocateCode 호출을 위해)
if (parsed.numberingRuleId && onFormDataChange && columnName) {
onFormDataChange(`${columnName}_numberingRuleId`, parsed.numberingRuleId);
console.log("🔧 채번 규칙 ID를 formData에 저장:", {
key: `${columnName}_numberingRuleId`,
value: parsed.numberingRuleId,
});
}
} catch {
// JSON 파싱 실패
}

View File

@ -30,15 +30,21 @@ export class V2InputRenderer extends AutoRegisteringComponentRenderer {
}
};
// 라벨: style.labelText 우선, 없으면 component.label 사용
// style.labelDisplay가 false면 라벨 숨김
const style = component.style || {};
const effectiveLabel = style.labelDisplay === false ? undefined : (style.labelText || component.label);
return (
<V2Input
id={component.id}
label={component.label}
label={effectiveLabel}
required={component.required}
readonly={config.readonly || component.readonly}
disabled={config.disabled || component.disabled}
value={currentValue}
onChange={handleChange}
onFormDataChange={onFormDataChange}
config={{
type: config.inputType || config.webType || "text",
inputType: config.inputType || config.webType || "text",

View File

@ -260,6 +260,10 @@ export function convertLegacyToV2(legacyLayout: LegacyLayoutData): LayoutV2 {
return {
version: "2.0",
components,
// 레이아웃 메타데이터 포함
gridSettings: legacyLayout.gridSettings,
screenResolution: legacyLayout.screenResolution,
metadata: legacyLayout.metadata,
};
}