refactor: 로딩 스피너 표준화 및 프로젝트 헬스 개선
- LoadingSpinner 컴포넌트 5가지 변형 구현 - LoadingSpinner (인라인/버튼용) - ContentLoadingSpinner (상세/수정 페이지) - PageLoadingSpinner (페이지 전환) - TableLoadingSpinner (테이블/리스트) - ButtonSpinner (버튼 내부) - 18개+ 페이지 로딩 UI 표준화 - HR 페이지 (사원, 휴가, 부서, 급여, 근태) - 영업 페이지 (견적, 거래처) - 게시판, 팝업관리, 품목기준정보 - API 키 보안 개선 (NEXT_PUBLIC_API_KEY → API_KEY) - Textarea 다크모드 스타일 개선 - DropdownField Radix UI Select 버그 수정 (key prop) - 프로젝트 헬스 개선 계획서 문서화 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,7 +55,24 @@ export function DropdownField({
|
||||
unitOptions,
|
||||
}: DynamicFieldRendererProps) {
|
||||
const fieldKey = field.field_key || `field_${field.id}`;
|
||||
const stringValue = value !== null && value !== undefined ? String(value) : '';
|
||||
|
||||
// is_active 필드인지 확인
|
||||
const isActiveField = fieldKey === 'is_active' || fieldKey.endsWith('_is_active');
|
||||
|
||||
// 옵션을 먼저 정규화 (is_active 값 변환에 필요)
|
||||
const rawOptions = normalizeOptions(field.options);
|
||||
|
||||
// is_active 필드일 때 boolean 값을 옵션에 맞게 변환
|
||||
let stringValue = '';
|
||||
if (value !== null && value !== undefined) {
|
||||
if (isActiveField && rawOptions.length >= 2) {
|
||||
// boolean/숫자 값을 첫번째(활성) 또는 두번째(비활성) 옵션 값으로 매핑
|
||||
const isActive = value === true || value === 'true' || value === 1 || value === '1' || value === '활성';
|
||||
stringValue = isActive ? rawOptions[0].value : rawOptions[1].value;
|
||||
} else {
|
||||
stringValue = String(value);
|
||||
}
|
||||
}
|
||||
|
||||
// field_key 또는 field_name이 '단위'/'unit' 관련이면 unitOptions 사용
|
||||
const isUnitField =
|
||||
@@ -73,8 +90,8 @@ export function DropdownField({
|
||||
value: u.value,
|
||||
}));
|
||||
} else {
|
||||
// field.options를 정규화
|
||||
options = normalizeOptions(field.options);
|
||||
// rawOptions는 이미 위에서 정규화됨
|
||||
options = rawOptions;
|
||||
}
|
||||
|
||||
// 옵션이 없으면 드롭다운을 disabled로 표시
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { DynamicFormData, ItemType, StructuredFieldConfig } from '../types';
|
||||
import { ItemFieldResponse } from '@/types/item';
|
||||
import { DynamicFormData, ItemType, StructuredFieldConfig, ItemFieldResponse } from '../types';
|
||||
|
||||
/**
|
||||
* 부품 유형 탐지 결과
|
||||
@@ -27,7 +26,7 @@ export interface UseFieldDetectionParams {
|
||||
/** 폼 구조 정보 */
|
||||
structure: StructuredFieldConfig | null;
|
||||
/** 현재 선택된 품목 유형 (FG, PT, SM, RM, CS) */
|
||||
selectedItemType: ItemType;
|
||||
selectedItemType: ItemType | '';
|
||||
/** 현재 폼 데이터 */
|
||||
formData: DynamicFormData;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { DynamicFormData, ItemType, StructuredFieldConfig } from '../types';
|
||||
import { BendingFieldKeys, CategoryKeyWithId } from './useItemCodeGeneration';
|
||||
import { BendingDetail } from '@/types/item';
|
||||
import type { DynamicFormData, DynamicFieldValue, ItemType, StructuredFieldConfig } from '../types';
|
||||
import type { BendingFieldKeys, CategoryKeyWithId } from './useItemCodeGeneration';
|
||||
import type { BendingDetail } from '@/types/item';
|
||||
|
||||
/**
|
||||
* usePartTypeHandling 훅 입력 파라미터
|
||||
@@ -20,7 +20,7 @@ export interface UsePartTypeHandlingParams {
|
||||
/** 품목명 필드 키 */
|
||||
itemNameKey: string;
|
||||
/** 필드 값 설정 함수 */
|
||||
setFieldValue: (key: string, value: unknown) => void;
|
||||
setFieldValue: (key: string, value: DynamicFieldValue) => void;
|
||||
/** 현재 폼 데이터 */
|
||||
formData: DynamicFormData;
|
||||
/** 절곡부품 필드 키 정보 */
|
||||
|
||||
@@ -12,6 +12,10 @@ import type {
|
||||
PageStructureResponse,
|
||||
} from '@/types/item-master-api';
|
||||
|
||||
// Re-export types for hooks
|
||||
export type { ItemFieldResponse } from '@/types/item-master-api';
|
||||
export type { ItemType } from '@/types/item';
|
||||
|
||||
// ============================================
|
||||
// 조건부 표시 타입
|
||||
// ============================================
|
||||
@@ -244,4 +248,14 @@ export function convertToFormStructure(
|
||||
orderNo: f.order_no,
|
||||
})),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 타입 별칭 (하위 호환성)
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* StructuredFieldConfig는 DynamicFormStructure의 별칭
|
||||
* (hooks에서 사용하는 이름)
|
||||
*/
|
||||
export type StructuredFieldConfig = DynamicFormStructure;
|
||||
Reference in New Issue
Block a user