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:
@@ -127,6 +127,9 @@ export function FieldDialog({
|
||||
// 유효성 검사
|
||||
const isNameEmpty = !newFieldName.trim();
|
||||
const isKeyEmpty = !newFieldKey.trim();
|
||||
// 2025-11-28: field_key validation - 영문 시작, 영문+숫자+언더스코어만 허용
|
||||
const fieldKeyPattern = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
||||
const isKeyInvalid = newFieldKey.trim() !== '' && !fieldKeyPattern.test(newFieldKey);
|
||||
|
||||
const handleClose = () => {
|
||||
setIsSubmitted(false);
|
||||
@@ -288,11 +291,14 @@ export function FieldDialog({
|
||||
value={newFieldKey}
|
||||
onChange={(e) => setNewFieldKey(e.target.value)}
|
||||
placeholder="예: itemName"
|
||||
className={isSubmitted && isKeyEmpty ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
className={(isSubmitted && isKeyEmpty) || isKeyInvalid ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
/>
|
||||
{isSubmitted && isKeyEmpty && (
|
||||
<p className="text-xs text-red-500 mt-1">필드 키를 입력해주세요</p>
|
||||
)}
|
||||
{isKeyInvalid && (
|
||||
<p className="text-xs text-red-500 mt-1">영문으로 시작하고, 영문/숫자/언더스코어(_)만 사용 가능합니다</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -420,7 +426,8 @@ export function FieldDialog({
|
||||
<Button variant="outline" onClick={handleClose}>취소</Button>
|
||||
<Button onClick={async () => {
|
||||
setIsSubmitted(true);
|
||||
if ((fieldInputMode === 'custom' || editingFieldId) && (isNameEmpty || isKeyEmpty)) return;
|
||||
// 2025-11-28: field_key validation 추가
|
||||
if ((fieldInputMode === 'custom' || editingFieldId) && (isNameEmpty || isKeyEmpty || isKeyInvalid)) return;
|
||||
await handleAddField();
|
||||
setIsSubmitted(false);
|
||||
}}>저장</Button>
|
||||
|
||||
@@ -85,6 +85,9 @@ export function MasterFieldDialog({
|
||||
// 유효성 검사
|
||||
const isNameEmpty = !newMasterFieldName.trim();
|
||||
const isKeyEmpty = !newMasterFieldKey.trim();
|
||||
// 2025-11-28: field_key validation - 영문 시작, 영문+숫자+언더스코어만 허용
|
||||
const fieldKeyPattern = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
||||
const isKeyInvalid = newMasterFieldKey.trim() !== '' && !fieldKeyPattern.test(newMasterFieldKey);
|
||||
|
||||
const handleClose = () => {
|
||||
setIsMasterFieldDialogOpen(false);
|
||||
@@ -105,7 +108,8 @@ export function MasterFieldDialog({
|
||||
|
||||
const handleSubmit = () => {
|
||||
setIsSubmitted(true);
|
||||
if (!isNameEmpty && !isKeyEmpty) {
|
||||
// 2025-11-28: field_key validation 추가
|
||||
if (!isNameEmpty && !isKeyEmpty && !isKeyInvalid) {
|
||||
if (editingMasterFieldId) {
|
||||
handleUpdateMasterField();
|
||||
} else {
|
||||
@@ -147,11 +151,14 @@ export function MasterFieldDialog({
|
||||
value={newMasterFieldKey}
|
||||
onChange={(e) => setNewMasterFieldKey(e.target.value)}
|
||||
placeholder="예: itemName"
|
||||
className={isSubmitted && isKeyEmpty ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
className={(isSubmitted && isKeyEmpty) || isKeyInvalid ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
/>
|
||||
{isSubmitted && isKeyEmpty && (
|
||||
<p className="text-xs text-red-500 mt-1">필드 키를 입력해주세요</p>
|
||||
)}
|
||||
{isKeyInvalid && (
|
||||
<p className="text-xs text-red-500 mt-1">영문으로 시작하고, 영문/숫자/언더스코어(_)만 사용 가능합니다</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user