/** 박창현 image 2 의 8개 — 사용자가 테이블 타입 관리에서 직접 고를 수 있는 base */ export type UserSelectableInputType = | "text" | "number" | "date" | "code" | "entity" | "numbering" | "file" | "image"; /** 화면관리 widget 의 세부 variant */ export interface WidgetVariantOption { value: string; label: string; description: string; } /** * 8개 base 별 widget variant 매핑. * vexplor_rps `input-type-mapping.ts:37-102` 의 variant 그대로 포팅. * 박창현 결정 (Q3): select/checkbox/radio base 의 variant 는 모두 code base 로 흡수. */ export const INPUT_TYPE_DETAIL_TYPES: Record = { text: [ { value: "text", label: "일반 텍스트", description: "기본 텍스트 입력" }, { value: "email", label: "이메일", description: "이메일 주소 입력" }, { value: "tel", label: "전화번호", description: "전화번호 입력" }, { value: "url", label: "URL", description: "웹사이트 주소 입력" }, { value: "password", label: "비밀번호", description: "마스킹 입력" }, { value: "textarea", label: "여러 줄 텍스트", description: "긴 텍스트 영역" }, ], number: [ { value: "number", label: "정수", description: "정수 숫자 입력" }, { value: "decimal", label: "소수", description: "소수점 포함" }, { value: "currency", label: "통화", description: "₩ 1,000 형식" }, { value: "percentage", label: "퍼센트", description: "50% 형식" }, ], 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: [ { value: "code", label: "코드 선택박스", description: "드롭다운으로 코드 선택" }, { value: "code-autocomplete", label: "코드 자동완성", description: "코드/코드명 검색" }, { value: "code-radio", label: "코드 라디오", description: "라디오 버튼 그룹" }, { value: "code-radio-horizontal", label: "가로 라디오", description: "가로 배치 라디오" }, { value: "code-radio-vertical", label: "세로 라디오", description: "세로 배치 라디오" }, { value: "dropdown", label: "검색 선택박스", description: "검색 기능 포함 (vexplor_rps select base)" }, { value: "multiselect", label: "다중 선택", description: "여러 항목 선택 (vexplor_rps select base)" }, { value: "autocomplete", label: "자동완성", description: "입력하면 자동완성 제안 (vexplor_rps select base)" }, { value: "checkbox", label: "체크박스", description: "단일 체크박스 (vexplor_rps checkbox base)" }, { value: "checkbox-group", label: "체크박스 그룹", description: "여러 체크박스 (vexplor_rps checkbox base)" }, { value: "boolean", label: "On/Off 스위치", description: "boolean 스위치 (vexplor_rps checkbox base)" }, ], entity: [ { value: "entity", label: "엔티티 참조", description: "다른 테이블 데이터 참조" }, { value: "entity-autocomplete", label: "엔티티 자동완성", description: "검색 결과 inline 표시" }, { value: "entity-popup", label: "엔티티 팝업", description: "별도 검색 팝업" }, ], file: [ { value: "file", label: "단일 파일", description: "파일 1개 첨부" }, { value: "file-list", label: "다중 파일", description: "여러 파일 첨부" }, { value: "file-drop", label: "드래그 앤 드롭", description: "drop zone 형태" }, ], image: [ { value: "image", label: "이미지", description: "이미지 1장 표시/업로드" }, { value: "image-gallery", label: "이미지 갤러리", description: "여러 장 grid 표시" }, { value: "image-upload", label: "이미지 업로드", description: "크롭/리사이즈 포함" }, ], numbering: [ { value: "numbering", label: "자동 채번", description: "옵션설정의 채번 규칙으로 자동 생성" }, ], }; /** 8개 base 의 한글 라벨 */ export const USER_SELECTABLE_INPUT_TYPE_LABELS: Record = { text: "텍스트", number: "숫자", date: "날짜", code: "코드", entity: "테이블참조", numbering: "채번", file: "파일", image: "이미지", }; /** 8개 base 의 순서 (드롭다운/카드 표시 순서) */ export const USER_SELECTABLE_INPUT_TYPE_ORDER: UserSelectableInputType[] = [ "text", "number", "date", "code", "entity", "numbering", "file", "image", ]; export function isUserSelectableInputType(value: string): value is UserSelectableInputType { return USER_SELECTABLE_INPUT_TYPE_ORDER.includes(value as UserSelectableInputType); } // ───────────────────────────────────────────────────────────────────────── // Backward Shim — 사용처 3곳 (V2PropertiesPanel/PropertiesPanel/DetailSettingsPanel) 임시 호환 // ───────────────────────────────────────────────────────────────────────── /** * @deprecated v3.2: BaseInputType 은 UserSelectableInputType (8개) 로 대체. * 이 export 는 backward shim — 사용처 3곳 임시 호환. 후속 PR 에서 strangle. */ export type BaseInputType = | UserSelectableInputType | "textarea" | "select" | "checkbox" | "radio"; /** * @deprecated v3.2: WidgetVariantOption 로 대체. * 사용처 3곳의 DetailTypeOption import 호환용. */ export type DetailTypeOption = WidgetVariantOption; /** * @deprecated v3.2: UserSelectableInputType 의 8개로 사용 권장. * 사용처 3곳의 BASE_INPUT_TYPE_OPTIONS import 호환용. */ export const BASE_INPUT_TYPE_OPTIONS: Array<{ value: BaseInputType; label: string; description: string }> = [ { value: "text", label: "텍스트", description: "텍스트 입력 필드" }, { value: "textarea", label: "텍스트 에리어", description: "여러 줄 텍스트 입력 (legacy — text base 의 variant)" }, { value: "number", label: "숫자", description: "숫자 입력 필드" }, { value: "date", label: "날짜", description: "날짜/시간 선택" }, { value: "code", label: "코드", description: "공통 코드 선택" }, { value: "entity", label: "엔티티", description: "다른 테이블 참조" }, { value: "select", label: "선택박스", description: "드롭다운 선택 (legacy — code base 의 variant)" }, { value: "checkbox", label: "체크박스", description: "체크박스/스위치 (legacy — code base 의 variant)" }, { value: "radio", label: "라디오버튼", description: "라디오 버튼 그룹 (legacy — code base 의 variant)" }, { value: "image", label: "이미지", description: "이미지 표시" }, { value: "numbering", label: "자동 채번", description: "옵션설정 기반 자동 번호" }, { value: "file", label: "파일", description: "파일 업로드" }, ]; /** * @deprecated v3.2: webType → UserSelectableInputType 로 매핑 권장 (`getUserSelectableInputType`). * 사용처 3곳의 getBaseInputType 호환용. */ export function getBaseInputType(webType: string): BaseInputType { if (["text", "email", "tel", "url", "password"].includes(webType)) return "text"; if (webType === "textarea") return "textarea"; if (["number", "decimal", "currency", "percentage"].includes(webType)) return "number"; if (["date", "datetime", "time", "daterange", "month", "year"].includes(webType)) return "date"; if (["code", "code-autocomplete", "code-radio", "code-radio-horizontal", "code-radio-vertical"].includes(webType)) return "code"; if (["select", "dropdown", "multiselect", "autocomplete"].includes(webType)) return "select"; if (["checkbox", "boolean", "checkbox-group"].includes(webType)) return "checkbox"; if (["radio", "radio-horizontal", "radio-vertical"].includes(webType)) return "radio"; if (webType === "entity" || webType.startsWith("entity-")) return "entity"; if (webType === "image" || webType.startsWith("image-")) return "image"; if (webType === "file" || webType.startsWith("file-")) return "file"; if (webType === "numbering") return "numbering"; return "text"; } /** 신규 권장 함수 — UserSelectableInputType 직접 반환 */ export function getUserSelectableInputType(webType: string): UserSelectableInputType { const base = getBaseInputType(webType); if (base === "textarea") return "text"; if (base === "select" || base === "checkbox" || base === "radio") return "code"; return base as UserSelectableInputType; } /** * @deprecated v3.2: getWidgetVariants (lib/utils/getDetailType.ts) 권장. * 사용처의 getDetailTypes import 호환용. */ export function getDetailTypes(baseInputType: BaseInputType): DetailTypeOption[] { // legacy base → UserSelectableInputType 매핑 후 variant 조회 let key: UserSelectableInputType; if (baseInputType === "textarea") key = "text"; else if (baseInputType === "select" || baseInputType === "checkbox" || baseInputType === "radio") key = "code"; else key = baseInputType; return INPUT_TYPE_DETAIL_TYPES[key] ?? []; } /** * @deprecated v3.2: getDefaultWidgetVariant (lib/utils/getDetailType.ts) 권장. * 사용처의 getDefaultDetailType import 호환용. */ export function getDefaultDetailType(baseInputType: BaseInputType): string { const variants = getDetailTypes(baseInputType); return variants[0]?.value ?? baseInputType; }