docs: inputType 사용 가이드 추가
- webType은 레거시, inputType만 사용해야 함을 명시 - API 호출 및 캐시 처리 방법 설명 - 실제 적용 사례 및 마이그레이션 체크리스트 포함 - 디버깅 팁 및 주요 inputType 종류 문서화
This commit is contained in:
parent
85e1b532fa
commit
b5a83bb0f3
|
|
@ -0,0 +1,279 @@
|
|||
# inputType 사용 가이드
|
||||
|
||||
## 핵심 원칙
|
||||
|
||||
**컬럼 타입 판단 시 반드시 `inputType`을 사용해야 합니다. `webType`은 레거시이며 더 이상 사용하지 않습니다.**
|
||||
|
||||
---
|
||||
|
||||
## 올바른 사용법
|
||||
|
||||
### ✅ inputType 사용 (권장)
|
||||
|
||||
```typescript
|
||||
// 카테고리 타입 체크
|
||||
if (columnMeta.inputType === "category") {
|
||||
// 카테고리 처리 로직
|
||||
}
|
||||
|
||||
// 코드 타입 체크
|
||||
if (meta.inputType === "code") {
|
||||
// 코드 처리 로직
|
||||
}
|
||||
|
||||
// 필터링
|
||||
const categoryColumns = Object.entries(columnMeta)
|
||||
.filter(([_, meta]) => meta.inputType === "category")
|
||||
.map(([columnName, _]) => columnName);
|
||||
```
|
||||
|
||||
### ❌ webType 사용 (금지)
|
||||
|
||||
```typescript
|
||||
// ❌ 절대 사용 금지!
|
||||
if (columnMeta.webType === "category") { ... }
|
||||
|
||||
// ❌ 이것도 금지!
|
||||
const categoryColumns = columns.filter(col => col.webType === "category");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API에서 inputType 가져오기
|
||||
|
||||
### Backend API
|
||||
|
||||
```typescript
|
||||
// 컬럼 입력 타입 정보 가져오기
|
||||
const inputTypes = await tableTypeApi.getColumnInputTypes(tableName);
|
||||
|
||||
// inputType 맵 생성
|
||||
const inputTypeMap: Record<string, string> = {};
|
||||
inputTypes.forEach((col: any) => {
|
||||
inputTypeMap[col.columnName] = col.inputType;
|
||||
});
|
||||
```
|
||||
|
||||
### columnMeta 구조
|
||||
|
||||
```typescript
|
||||
interface ColumnMeta {
|
||||
webType?: string; // 레거시, 사용 금지
|
||||
codeCategory?: string;
|
||||
inputType?: string; // ✅ 반드시 이것 사용!
|
||||
}
|
||||
|
||||
const columnMeta: Record<string, ColumnMeta> = {
|
||||
material: {
|
||||
webType: "category", // 무시
|
||||
codeCategory: "",
|
||||
inputType: "category" // ✅ 이것만 사용
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 캐시 사용 시 주의사항
|
||||
|
||||
### ❌ 잘못된 캐시 처리 (inputType 누락)
|
||||
|
||||
```typescript
|
||||
const cached = tableColumnCache.get(cacheKey);
|
||||
if (cached) {
|
||||
const meta: Record<string, ColumnMeta> = {};
|
||||
|
||||
cached.columns.forEach((col: any) => {
|
||||
meta[col.columnName] = {
|
||||
webType: col.webType,
|
||||
codeCategory: col.codeCategory,
|
||||
// ❌ inputType 누락!
|
||||
};
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ 올바른 캐시 처리 (inputType 포함)
|
||||
|
||||
```typescript
|
||||
const cached = tableColumnCache.get(cacheKey);
|
||||
if (cached) {
|
||||
const meta: Record<string, ColumnMeta> = {};
|
||||
|
||||
// 캐시된 inputTypes 맵 생성
|
||||
const inputTypeMap: Record<string, string> = {};
|
||||
if (cached.inputTypes) {
|
||||
cached.inputTypes.forEach((col: any) => {
|
||||
inputTypeMap[col.columnName] = col.inputType;
|
||||
});
|
||||
}
|
||||
|
||||
cached.columns.forEach((col: any) => {
|
||||
meta[col.columnName] = {
|
||||
webType: col.webType,
|
||||
codeCategory: col.codeCategory,
|
||||
inputType: inputTypeMap[col.columnName], // ✅ inputType 포함!
|
||||
};
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 주요 inputType 종류
|
||||
|
||||
| inputType | 설명 | 사용 예시 |
|
||||
|-----------|------|-----------|
|
||||
| `text` | 일반 텍스트 입력 | 이름, 설명 등 |
|
||||
| `number` | 숫자 입력 | 금액, 수량 등 |
|
||||
| `date` | 날짜 입력 | 생성일, 수정일 등 |
|
||||
| `datetime` | 날짜+시간 입력 | 타임스탬프 등 |
|
||||
| `category` | 카테고리 선택 | 분류, 상태 등 |
|
||||
| `code` | 공통 코드 선택 | 코드 마스터 데이터 |
|
||||
| `boolean` | 예/아니오 | 활성화 여부 등 |
|
||||
| `email` | 이메일 입력 | 이메일 주소 |
|
||||
| `url` | URL 입력 | 웹사이트 주소 |
|
||||
| `image` | 이미지 업로드 | 프로필 사진 등 |
|
||||
| `file` | 파일 업로드 | 첨부파일 등 |
|
||||
|
||||
---
|
||||
|
||||
## 실제 적용 사례
|
||||
|
||||
### 1. TableListComponent - 카테고리 매핑 로드
|
||||
|
||||
```typescript
|
||||
// ✅ inputType으로 카테고리 컬럼 필터링
|
||||
const categoryColumns = Object.entries(columnMeta)
|
||||
.filter(([_, meta]) => meta.inputType === "category")
|
||||
.map(([columnName, _]) => columnName);
|
||||
|
||||
// 각 카테고리 컬럼의 값 목록 조회
|
||||
for (const columnName of categoryColumns) {
|
||||
const response = await apiClient.get(
|
||||
`/table-categories/${tableName}/${columnName}/values`
|
||||
);
|
||||
// 매핑 처리...
|
||||
}
|
||||
```
|
||||
|
||||
### 2. InteractiveDataTable - 셀 값 렌더링
|
||||
|
||||
```typescript
|
||||
// ✅ inputType으로 렌더링 분기
|
||||
const inputType = columnMeta[column.columnName]?.inputType;
|
||||
|
||||
switch (inputType) {
|
||||
case "category":
|
||||
// 카테고리 배지 렌더링
|
||||
return <Badge>{categoryLabel}</Badge>;
|
||||
|
||||
case "code":
|
||||
// 코드명 표시
|
||||
return codeName;
|
||||
|
||||
case "date":
|
||||
// 날짜 포맷팅
|
||||
return formatDate(value);
|
||||
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 검색 필터 생성
|
||||
|
||||
```typescript
|
||||
// ✅ inputType에 따라 다른 검색 UI 제공
|
||||
const renderSearchInput = (column: ColumnConfig) => {
|
||||
const inputType = columnMeta[column.columnName]?.inputType;
|
||||
|
||||
switch (inputType) {
|
||||
case "category":
|
||||
return <CategorySelect column={column} />;
|
||||
|
||||
case "code":
|
||||
return <CodeSelect column={column} />;
|
||||
|
||||
case "date":
|
||||
return <DateRangePicker column={column} />;
|
||||
|
||||
case "number":
|
||||
return <NumberRangeInput column={column} />;
|
||||
|
||||
default:
|
||||
return <TextInput column={column} />;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 마이그레이션 체크리스트
|
||||
|
||||
기존 코드에서 `webType`을 `inputType`으로 전환할 때:
|
||||
|
||||
- [ ] `webType` 참조를 모두 `inputType`으로 변경
|
||||
- [ ] API 호출 시 `getColumnInputTypes()` 포함 확인
|
||||
- [ ] 캐시 사용 시 `cached.inputTypes` 매핑 확인
|
||||
- [ ] 타입 정의에서 `inputType` 필드 포함
|
||||
- [ ] 조건문에서 `inputType` 체크로 변경
|
||||
- [ ] 테스트 실행하여 정상 동작 확인
|
||||
|
||||
---
|
||||
|
||||
## 디버깅 팁
|
||||
|
||||
### inputType이 undefined인 경우
|
||||
|
||||
```typescript
|
||||
// 디버깅 로그 추가
|
||||
console.log("columnMeta:", columnMeta);
|
||||
console.log("inputType:", columnMeta[columnName]?.inputType);
|
||||
|
||||
// 체크 포인트:
|
||||
// 1. getColumnInputTypes() 호출 확인
|
||||
// 2. inputTypeMap 생성 확인
|
||||
// 3. meta 객체에 inputType 할당 확인
|
||||
// 4. 캐시 사용 시 cached.inputTypes 확인
|
||||
```
|
||||
|
||||
### webType만 있고 inputType이 없는 경우
|
||||
|
||||
```typescript
|
||||
// ❌ 잘못된 데이터 구조
|
||||
{
|
||||
material: {
|
||||
webType: "category",
|
||||
codeCategory: "",
|
||||
// inputType 누락!
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 올바른 데이터 구조
|
||||
{
|
||||
material: {
|
||||
webType: "category", // 레거시, 무시됨
|
||||
codeCategory: "",
|
||||
inputType: "category" // ✅ 필수!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 참고 자료
|
||||
|
||||
- **컴포넌트**: `/frontend/lib/registry/components/table-list/TableListComponent.tsx`
|
||||
- **API 클라이언트**: `/frontend/lib/api/tableType.ts`
|
||||
- **타입 정의**: `/frontend/types/table.ts`
|
||||
|
||||
---
|
||||
|
||||
## 요약
|
||||
|
||||
1. **항상 `inputType` 사용**, `webType` 사용 금지
|
||||
2. **API에서 `getColumnInputTypes()` 호출** 필수
|
||||
3. **캐시 사용 시 `inputTypes` 포함** 확인
|
||||
4. **디버깅 시 `inputType` 값 확인**
|
||||
5. **기존 코드 마이그레이션** 시 체크리스트 활용
|
||||
Loading…
Reference in New Issue