2025-10-14 11:48:04 +09:00
|
|
|
/**
|
|
|
|
|
* 입력 타입(Input Type)과 세부 타입(Detail Type) 매핑 정의
|
|
|
|
|
*
|
|
|
|
|
* 테이블 타입 관리의 8개 핵심 입력 타입을 기반으로
|
|
|
|
|
* 화면 관리에서 선택 가능한 세부 타입들을 정의합니다.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { WebType } from "./unified-core";
|
|
|
|
|
|
|
|
|
|
/**
|
2025-11-06 12:11:49 +09:00
|
|
|
* 9개 핵심 입력 타입
|
2025-10-14 11:48:04 +09:00
|
|
|
*/
|
|
|
|
|
export type BaseInputType =
|
|
|
|
|
| "text" // 텍스트
|
|
|
|
|
| "number" // 숫자
|
|
|
|
|
| "date" // 날짜
|
|
|
|
|
| "code" // 코드
|
|
|
|
|
| "entity" // 엔티티
|
|
|
|
|
| "select" // 선택박스
|
|
|
|
|
| "checkbox" // 체크박스
|
2025-11-06 12:11:49 +09:00
|
|
|
| "radio" // 라디오버튼
|
|
|
|
|
| "image"; // 이미지
|
2025-10-14 11:48:04 +09:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 세부 타입 옵션 인터페이스
|
|
|
|
|
*/
|
|
|
|
|
export interface DetailTypeOption {
|
|
|
|
|
value: WebType;
|
|
|
|
|
label: string;
|
|
|
|
|
description: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 입력 타입별 세부 타입 매핑
|
|
|
|
|
*/
|
|
|
|
|
export const INPUT_TYPE_DETAIL_TYPES: Record<BaseInputType, DetailTypeOption[]> = {
|
|
|
|
|
// 텍스트 → text, email, tel, url, textarea, password
|
|
|
|
|
text: [
|
|
|
|
|
{ value: "text", label: "일반 텍스트", description: "기본 텍스트 입력" },
|
|
|
|
|
{ value: "email", label: "이메일", description: "이메일 주소 입력" },
|
|
|
|
|
{ value: "tel", label: "전화번호", description: "전화번호 입력" },
|
|
|
|
|
{ value: "url", label: "URL", description: "웹사이트 주소 입력" },
|
|
|
|
|
{ value: "textarea", label: "여러 줄 텍스트", description: "긴 텍스트 입력" },
|
|
|
|
|
{ value: "password", label: "비밀번호", description: "비밀번호 입력 (마스킹)" },
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 숫자 → number, decimal, currency, percentage
|
|
|
|
|
number: [
|
|
|
|
|
{ value: "number", label: "정수", description: "정수 숫자 입력" },
|
|
|
|
|
{ value: "decimal", label: "소수", description: "소수점 포함 숫자 입력" },
|
|
|
|
|
{ value: "currency", label: "통화", description: "통화 형식 (₩ 1,000)" },
|
|
|
|
|
{ value: "percentage", label: "퍼센트", description: "퍼센트 형식 (50%)" },
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 날짜 → date, datetime, time, daterange, month, year
|
|
|
|
|
date: [
|
|
|
|
|
{ value: "date", label: "날짜", description: "날짜 선택 (YYYY-MM-DD)" },
|
|
|
|
|
{ value: "datetime", label: "날짜+시간", description: "날짜와 시간 선택" },
|
|
|
|
|
{ value: "time", label: "시간", description: "시간 선택 (HH:mm)" },
|
|
|
|
|
{ value: "daterange", label: "기간", description: "시작일 ~ 종료일" },
|
|
|
|
|
{ value: "month", label: "월", description: "년/월 선택 (YYYY-MM)" },
|
|
|
|
|
{ value: "year", label: "년", description: "년도 선택 (YYYY)" },
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 코드 → code, code-autocomplete, code-radio
|
|
|
|
|
code: [
|
|
|
|
|
{ value: "code", label: "코드 선택박스", description: "드롭다운으로 코드 선택" },
|
|
|
|
|
{ value: "code-autocomplete", label: "코드 자동완성", description: "코드/코드명 검색" },
|
|
|
|
|
{ value: "code-radio", label: "코드 라디오", description: "라디오 버튼으로 선택" },
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 엔티티 → entity (세부 타입 없음, 참조 테이블만 선택)
|
|
|
|
|
entity: [{ value: "entity", label: "엔티티 참조", description: "다른 테이블 데이터 참조" }],
|
|
|
|
|
|
|
|
|
|
// 선택박스 → select, dropdown, multiselect, autocomplete
|
|
|
|
|
select: [
|
|
|
|
|
{ value: "select", label: "선택박스", description: "드롭다운 선택 (단일)" },
|
|
|
|
|
{ value: "dropdown", label: "검색 선택박스", description: "검색 기능 포함" },
|
|
|
|
|
{ value: "multiselect", label: "다중 선택", description: "여러 항목 선택 (태그)" },
|
|
|
|
|
{ value: "autocomplete", label: "자동완성", description: "입력하면 자동완성 제안" },
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 체크박스 → checkbox, boolean, checkbox-group
|
|
|
|
|
checkbox: [
|
|
|
|
|
{ value: "checkbox", label: "체크박스", description: "단일 체크박스" },
|
|
|
|
|
{ value: "boolean", label: "스위치", description: "On/Off 스위치" },
|
|
|
|
|
{ value: "checkbox-group", label: "체크박스 그룹", description: "여러 체크박스" },
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 라디오버튼 → radio, radio-horizontal, radio-vertical
|
|
|
|
|
radio: [
|
|
|
|
|
{ value: "radio", label: "라디오버튼", description: "기본 라디오 버튼" },
|
|
|
|
|
{ value: "radio-horizontal", label: "가로 라디오", description: "가로 배치" },
|
|
|
|
|
{ value: "radio-vertical", label: "세로 라디오", description: "세로 배치" },
|
|
|
|
|
],
|
2025-11-06 12:11:49 +09:00
|
|
|
|
|
|
|
|
// 이미지 → image
|
|
|
|
|
image: [{ value: "image", label: "이미지", description: "이미지 URL 표시" }],
|
2025-10-14 11:48:04 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 웹타입에서 기본 입력 타입 추출
|
|
|
|
|
*/
|
|
|
|
|
export function getBaseInputType(webType: WebType): BaseInputType {
|
|
|
|
|
// text 계열
|
|
|
|
|
if (["text", "email", "tel", "url", "textarea", "password"].includes(webType)) {
|
|
|
|
|
return "text";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// number 계열
|
|
|
|
|
if (["number", "decimal", "currency", "percentage"].includes(webType)) {
|
|
|
|
|
return "number";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// date 계열
|
|
|
|
|
if (["date", "datetime", "time", "daterange", "month", "year"].includes(webType)) {
|
|
|
|
|
return "date";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// code 계열
|
|
|
|
|
if (["code", "code-autocomplete", "code-radio"].includes(webType)) {
|
|
|
|
|
return "code";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// select 계열
|
|
|
|
|
if (["select", "dropdown", "multiselect", "autocomplete"].includes(webType)) {
|
|
|
|
|
return "select";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// checkbox 계열
|
|
|
|
|
if (["checkbox", "boolean", "checkbox-group"].includes(webType)) {
|
|
|
|
|
return "checkbox";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// radio 계열
|
|
|
|
|
if (["radio", "radio-horizontal", "radio-vertical"].includes(webType)) {
|
|
|
|
|
return "radio";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// entity
|
|
|
|
|
if (webType === "entity") return "entity";
|
|
|
|
|
|
2025-11-06 12:11:49 +09:00
|
|
|
// image
|
|
|
|
|
if (webType === "image") return "image";
|
|
|
|
|
|
2025-10-14 11:48:04 +09:00
|
|
|
// 기본값: text
|
|
|
|
|
return "text";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 입력 타입에 해당하는 세부 타입 목록 가져오기
|
|
|
|
|
*/
|
|
|
|
|
export function getDetailTypes(baseInputType: BaseInputType): DetailTypeOption[] {
|
|
|
|
|
return INPUT_TYPE_DETAIL_TYPES[baseInputType] || [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 입력 타입에 해당하는 기본 세부 타입 가져오기
|
|
|
|
|
*/
|
|
|
|
|
export function getDefaultDetailType(baseInputType: BaseInputType): WebType {
|
|
|
|
|
const detailTypes = getDetailTypes(baseInputType);
|
|
|
|
|
return detailTypes[0]?.value || "text";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 입력 타입 옵션 (PropertiesPanel에서 사용)
|
|
|
|
|
*/
|
|
|
|
|
export const BASE_INPUT_TYPE_OPTIONS: Array<{ value: BaseInputType; label: string; description: string }> = [
|
|
|
|
|
{ value: "text", label: "텍스트", description: "텍스트 입력 필드" },
|
|
|
|
|
{ value: "number", label: "숫자", description: "숫자 입력 필드" },
|
|
|
|
|
{ value: "date", label: "날짜", description: "날짜/시간 선택" },
|
|
|
|
|
{ value: "code", label: "코드", description: "공통 코드 선택" },
|
|
|
|
|
{ value: "entity", label: "엔티티", description: "다른 테이블 참조" },
|
|
|
|
|
{ value: "select", label: "선택박스", description: "드롭다운 선택" },
|
|
|
|
|
{ value: "checkbox", label: "체크박스", description: "체크박스/스위치" },
|
|
|
|
|
{ value: "radio", label: "라디오버튼", description: "라디오 버튼 그룹" },
|
2025-11-06 12:11:49 +09:00
|
|
|
{ value: "image", label: "이미지", description: "이미지 표시" },
|
2025-10-14 11:48:04 +09:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 입력 타입 검증
|
|
|
|
|
*/
|
|
|
|
|
export function isValidBaseInputType(value: string): value is BaseInputType {
|
|
|
|
|
return BASE_INPUT_TYPE_OPTIONS.some((opt) => opt.value === value);
|
|
|
|
|
}
|