fix: field_key 저장 및 표시 기능 완전 수정

- field_key 저장 시 백엔드 형식({ID}_{사용자입력})으로 전송
- API 요청 전 field_key 유효성 검증 추가
- 계층구조 탭 필드 추가/수정 시 field_key 반영
- 섹션 탭에서 field_key 표시 시 사용자입력 부분만 추출
- sectionsAsTemplates useMemo에서 linkedSections/unlinkedSections 모두 수정
- 마스터 필드, 템플릿 필드 다이얼로그에서 field_key 입력 지원
- ItemMasterContext에 field_key 상태 업데이트 로직 추가
- transformers에서 field_key 변환 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2025-11-28 19:57:52 +09:00
parent 9d0cb073ba
commit 8fd9cf2d40
9 changed files with 133 additions and 34 deletions

View File

@@ -329,18 +329,25 @@ export function ItemMasterDataManagement() {
description: section.description || null,
default_fields: null,
// ItemField → TemplateField 변환
fields: section.fields?.map(field => ({
id: field.id.toString(),
name: field.field_name,
fieldKey: field.field_name.toLowerCase().replace(/\s+/g, '_'),
property: {
inputType: field.field_type,
// 2025-11-27: is_required와 properties.required 둘 다 체크
required: field.is_required || field.properties?.required,
options: field.options?.map((opt: { label: string; value: string }) => opt.label || opt.value),
},
description: field.placeholder || undefined,
} as TemplateField)),
// 2025-11-28: field_key에서 사용자입력 부분만 추출 (백엔드 형식: {ID}_{사용자입력})
fields: section.fields?.map(field => {
const rawKey = field.field_key || '';
const displayKey = rawKey.includes('_')
? rawKey.substring(rawKey.indexOf('_') + 1)
: rawKey || field.field_name.toLowerCase().replace(/\s+/g, '_');
return {
id: field.id.toString(),
name: field.field_name,
fieldKey: displayKey,
property: {
inputType: field.field_type,
// 2025-11-27: is_required와 properties.required 둘 다 체크
required: field.is_required || field.properties?.required,
options: field.options?.map((opt: { label: string; value: string }) => opt.label || opt.value),
},
description: field.placeholder || undefined,
} as TemplateField;
}),
bomItems: section.bom_items,
created_by: section.created_by || null,
updated_by: section.updated_by || null,
@@ -350,6 +357,7 @@ export function ItemMasterDataManagement() {
);
// 2. 독립 섹션들 (page_id = null, 연결 해제된 섹션)
// 2025-11-28: field_key에서 사용자입력 부분만 추출 (백엔드 형식: {ID}_{사용자입력})
const unlinkedSections = independentSections.map(section => ({
id: section.id,
tenant_id: section.tenant_id || 0,
@@ -357,18 +365,24 @@ export function ItemMasterDataManagement() {
section_type: section.section_type,
description: section.description || null,
default_fields: null,
fields: section.fields?.map(field => ({
id: field.id.toString(),
name: field.field_name,
fieldKey: field.field_name.toLowerCase().replace(/\s+/g, '_'),
property: {
inputType: field.field_type,
// 2025-11-27: is_required와 properties.required 둘 다 체크
required: field.is_required || field.properties?.required,
options: field.options?.map((opt: { label: string; value: string }) => opt.label || opt.value),
},
description: field.placeholder || undefined,
} as TemplateField)),
fields: section.fields?.map(field => {
const rawKey = field.field_key || '';
const displayKey = rawKey.includes('_')
? rawKey.substring(rawKey.indexOf('_') + 1)
: rawKey || field.field_name.toLowerCase().replace(/\s+/g, '_');
return {
id: field.id.toString(),
name: field.field_name,
fieldKey: displayKey,
property: {
inputType: field.field_type,
// 2025-11-27: is_required와 properties.required 둘 다 체크
required: field.is_required || field.properties?.required,
options: field.options?.map((opt: { label: string; value: string }) => opt.label || opt.value),
},
description: field.placeholder || undefined,
} as TemplateField;
}),
bomItems: section.bom_items,
created_by: section.created_by || null,
updated_by: section.updated_by || null,