feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
/**
|
2025-12-04 12:48:41 +09:00
|
|
|
* 품목기준관리 API에서 폼 구조를 로드하는 훅
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
*
|
2025-12-04 12:48:41 +09:00
|
|
|
* - init API에서 페이지 목록 조회
|
|
|
|
|
* - 품목 유형(itemType)에 해당하는 페이지 찾기
|
|
|
|
|
* - 해당 페이지의 전체 구조(섹션, 필드) 로드
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
'use client';
|
|
|
|
|
|
2025-12-04 12:48:41 +09:00
|
|
|
import { useState, useEffect, useCallback } from 'react';
|
|
|
|
|
import { itemMasterApi } from '@/lib/api/item-master';
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
import type {
|
2025-12-04 12:48:41 +09:00
|
|
|
DynamicFormStructure,
|
|
|
|
|
UseFormStructureResult,
|
|
|
|
|
SimpleUnitOption,
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
} from '../types';
|
2025-12-04 12:48:41 +09:00
|
|
|
import { convertToFormStructure } from '../types';
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
|
2025-12-04 12:48:41 +09:00
|
|
|
export function useFormStructure(
|
|
|
|
|
itemType: 'FG' | 'PT' | 'SM' | 'RM' | 'CS'
|
|
|
|
|
): UseFormStructureResult {
|
|
|
|
|
const [structure, setStructure] = useState<DynamicFormStructure | null>(null);
|
|
|
|
|
const [unitOptions, setUnitOptions] = useState<SimpleUnitOption[]>([]);
|
|
|
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
|
const [error, setError] = useState<string | null>(null);
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
|
2025-12-04 12:48:41 +09:00
|
|
|
const loadStructure = useCallback(async () => {
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
setIsLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
|
|
|
|
|
try {
|
2025-12-04 12:48:41 +09:00
|
|
|
// 1. init API에서 전체 데이터 로드
|
|
|
|
|
const initData = await itemMasterApi.init();
|
|
|
|
|
|
|
|
|
|
// 단위 옵션 저장 (SimpleUnitOption 형식으로 변환)
|
|
|
|
|
const simpleUnitOptions: SimpleUnitOption[] = (initData.unitOptions || []).map((u) => ({
|
2025-12-22 09:04:28 +09:00
|
|
|
label: u.unit_name,
|
|
|
|
|
value: u.unit_code,
|
2025-12-04 12:48:41 +09:00
|
|
|
}));
|
|
|
|
|
setUnitOptions(simpleUnitOptions);
|
|
|
|
|
|
|
|
|
|
// 2. 품목 유형에 해당하는 페이지 찾기
|
|
|
|
|
const page = initData.pages.find((p) => p.item_type === itemType);
|
|
|
|
|
|
|
|
|
|
if (!page) {
|
|
|
|
|
// 페이지가 없으면 빈 구조 반환 (품목기준관리에서 아직 설정 안된 경우)
|
|
|
|
|
setStructure({
|
|
|
|
|
page: {
|
|
|
|
|
id: 0,
|
|
|
|
|
tenant_id: 0,
|
|
|
|
|
page_name: `${itemType} 기본 페이지`,
|
|
|
|
|
item_type: itemType,
|
|
|
|
|
description: null,
|
|
|
|
|
absolute_path: null,
|
|
|
|
|
is_active: true,
|
|
|
|
|
order_no: 0,
|
|
|
|
|
created_by: null,
|
|
|
|
|
updated_by: null,
|
|
|
|
|
created_at: '',
|
|
|
|
|
updated_at: '',
|
|
|
|
|
},
|
|
|
|
|
sections: [],
|
|
|
|
|
directFields: [],
|
|
|
|
|
});
|
|
|
|
|
return;
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
}
|
|
|
|
|
|
2025-12-04 12:48:41 +09:00
|
|
|
// 3. 페이지 전체 구조 로드
|
|
|
|
|
const pageStructure = await itemMasterApi.pages.getStructure(page.id);
|
|
|
|
|
const formStructure = convertToFormStructure(pageStructure);
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
|
2025-12-04 12:48:41 +09:00
|
|
|
setStructure(formStructure);
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
} catch (err) {
|
2025-12-04 12:48:41 +09:00
|
|
|
console.error('품목 폼 구조 로드 실패:', err);
|
|
|
|
|
setError(err instanceof Error ? err.message : '폼 구조를 불러올 수 없습니다.');
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
} finally {
|
|
|
|
|
setIsLoading(false);
|
|
|
|
|
}
|
2025-12-04 12:48:41 +09:00
|
|
|
}, [itemType]);
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2025-12-04 12:48:41 +09:00
|
|
|
loadStructure();
|
|
|
|
|
}, [loadStructure]);
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
|
|
|
|
|
return {
|
2025-12-04 12:48:41 +09:00
|
|
|
structure,
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
isLoading,
|
|
|
|
|
error,
|
2025-12-04 12:48:41 +09:00
|
|
|
unitOptions,
|
|
|
|
|
refetch: loadStructure,
|
feat: 품목관리 동적 렌더링 시스템 구현
- DynamicItemForm 컴포넌트 구조 생성
- DynamicField: 필드 타입별 렌더링
- DynamicSection: 섹션 단위 렌더링
- DynamicFormRenderer: 페이지 전체 렌더링
- 필드 타입별 컴포넌트 (TextField, NumberField, DropdownField, CheckboxField, DateField, FileField, CustomField)
- 커스텀 훅 (useDynamicFormState, useFormStructure, useConditionalFields)
- DataTable 공통 컴포넌트 (테이블, 페이지네이션, 검색, 탭필터, 통계카드)
- ItemFormWrapper: Feature Flag 기반 폼 선택
- 타입 정의 및 문서화
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:14:43 +09:00
|
|
|
};
|
|
|
|
|
}
|