/** * 입력 타입(Input Type)과 세부 타입(Detail Type) 매핑 정의 * * 테이블 타입 관리의 8개 핵심 입력 타입을 기반으로 * 화면 관리에서 선택 가능한 세부 타입들을 정의합니다. */ import { WebType } from "./unified-core"; /** * 핵심 입력 타입 */ export type BaseInputType = | "text" // 텍스트 | "textarea" // 텍스트 에리어 (여러 줄) | "number" // 숫자 | "date" // 날짜 | "code" // 코드 | "entity" // 엔티티 | "select" // 선택박스 | "checkbox" // 체크박스 | "radio" // 라디오버튼 | "image"; // 이미지 /** * 세부 타입 옵션 인터페이스 */ export interface DetailTypeOption { value: WebType; label: string; description: string; } /** * 입력 타입별 세부 타입 매핑 */ export const INPUT_TYPE_DETAIL_TYPES: Record = { // 텍스트 → text, email, tel, url, password text: [ { value: "text", label: "일반 텍스트", description: "기본 텍스트 입력" }, { value: "email", label: "이메일", description: "이메일 주소 입력" }, { value: "tel", label: "전화번호", description: "전화번호 입력" }, { value: "url", label: "URL", description: "웹사이트 주소 입력" }, { value: "password", label: "비밀번호", description: "비밀번호 입력 (마스킹)" }, ], // 텍스트 에리어 → textarea textarea: [{ value: "textarea", 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: "세로 배치" }, ], // 이미지 → image image: [{ value: "image", label: "이미지", description: "이미지 URL 표시" }], }; /** * 웹타입에서 기본 입력 타입 추출 */ export function getBaseInputType(webType: WebType): BaseInputType { // textarea (별도 타입으로 분리) if (webType === "textarea") { return "textarea"; } // text 계열 if (["text", "email", "tel", "url", "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"; // image if (webType === "image") return "image"; // 기본값: 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: "textarea", 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: "라디오 버튼 그룹" }, { value: "image", label: "이미지", description: "이미지 표시" }, ]; /** * 입력 타입 검증 */ export function isValidBaseInputType(value: string): value is BaseInputType { return BASE_INPUT_TYPE_OPTIONS.some((opt) => opt.value === value); }