196 lines
5.7 KiB
TypeScript
196 lines
5.7 KiB
TypeScript
|
|
/**
|
||
|
|
* 통합 웹 타입 정의
|
||
|
|
* 프론트엔드와 백엔드에서 공통으로 사용하는 웹 타입 정의
|
||
|
|
*
|
||
|
|
* 주의: 이 파일을 수정할 때는 반드시 백엔드 타입도 함께 업데이트 해야 합니다.
|
||
|
|
*/
|
||
|
|
|
||
|
|
// 기본 웹 타입 (DB web_type_standards와 동기화)
|
||
|
|
export type BaseWebType =
|
||
|
|
| "text" // 일반 텍스트
|
||
|
|
| "number" // 숫자 (정수)
|
||
|
|
| "decimal" // 소수점 숫자
|
||
|
|
| "date" // 날짜
|
||
|
|
| "datetime" // 날짜시간
|
||
|
|
| "time" // 시간
|
||
|
|
| "textarea" // 여러줄 텍스트
|
||
|
|
| "select" // 선택박스
|
||
|
|
| "dropdown" // 드롭다운 (select와 동일)
|
||
|
|
| "checkbox" // 체크박스
|
||
|
|
| "radio" // 라디오버튼
|
||
|
|
| "boolean" // 불린값
|
||
|
|
| "file" // 파일 업로드
|
||
|
|
| "email" // 이메일
|
||
|
|
| "tel" // 전화번호
|
||
|
|
| "url" // URL
|
||
|
|
| "password" // 패스워드
|
||
|
|
| "code" // 공통코드 참조
|
||
|
|
| "entity" // 엔티티 참조
|
||
|
|
| "button"; // 버튼
|
||
|
|
|
||
|
|
// 레거시 지원용 (기존 시스템과의 호환성)
|
||
|
|
export type LegacyWebType = "text_area"; // textarea와 동일
|
||
|
|
|
||
|
|
// 전체 웹 타입 (DB 동적 로딩 지원)
|
||
|
|
export type WebType = BaseWebType | LegacyWebType;
|
||
|
|
|
||
|
|
// 동적 웹 타입 (런타임에 DB에서 로드되는 타입 포함)
|
||
|
|
export type DynamicWebType = WebType | string;
|
||
|
|
|
||
|
|
// 웹 타입 카테고리
|
||
|
|
export type WebTypeCategory =
|
||
|
|
| "input" // 입력 컴포넌트
|
||
|
|
| "selection" // 선택 컴포넌트
|
||
|
|
| "display" // 표시 컴포넌트
|
||
|
|
| "action" // 액션 컴포넌트
|
||
|
|
| "upload" // 업로드 컴포넌트
|
||
|
|
| "reference"; // 참조 컴포넌트
|
||
|
|
|
||
|
|
// 웹 타입 정보
|
||
|
|
export interface WebTypeInfo {
|
||
|
|
webType: WebType;
|
||
|
|
typeName: string;
|
||
|
|
typeNameEng?: string;
|
||
|
|
description?: string;
|
||
|
|
category: WebTypeCategory;
|
||
|
|
defaultConfig?: Record<string, any>;
|
||
|
|
validationRules?: Record<string, any>;
|
||
|
|
componentName?: string;
|
||
|
|
configPanel?: string;
|
||
|
|
isActive: boolean;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 웹 타입 매핑 (레거시 지원)
|
||
|
|
export const WEB_TYPE_MAPPINGS: Record<LegacyWebType, BaseWebType> = {
|
||
|
|
text_area: "textarea",
|
||
|
|
};
|
||
|
|
|
||
|
|
// 웹 타입 정규화 함수
|
||
|
|
export const normalizeWebType = (webType: DynamicWebType): WebType => {
|
||
|
|
if (webType in WEB_TYPE_MAPPINGS) {
|
||
|
|
return WEB_TYPE_MAPPINGS[webType as LegacyWebType];
|
||
|
|
}
|
||
|
|
return webType as WebType;
|
||
|
|
};
|
||
|
|
|
||
|
|
// 웹 타입 검증 함수
|
||
|
|
export const isValidWebType = (webType: string): webType is WebType => {
|
||
|
|
return (
|
||
|
|
[
|
||
|
|
"text",
|
||
|
|
"number",
|
||
|
|
"decimal",
|
||
|
|
"date",
|
||
|
|
"datetime",
|
||
|
|
"time",
|
||
|
|
"textarea",
|
||
|
|
"select",
|
||
|
|
"dropdown",
|
||
|
|
"checkbox",
|
||
|
|
"radio",
|
||
|
|
"boolean",
|
||
|
|
"file",
|
||
|
|
"email",
|
||
|
|
"tel",
|
||
|
|
"url",
|
||
|
|
"password",
|
||
|
|
"code",
|
||
|
|
"entity",
|
||
|
|
"button",
|
||
|
|
"text_area", // 레거시 지원
|
||
|
|
] as string[]
|
||
|
|
).includes(webType);
|
||
|
|
};
|
||
|
|
|
||
|
|
// DB 타입과 웹 타입 매핑
|
||
|
|
export const DB_TYPE_TO_WEB_TYPE: Record<string, WebType> = {
|
||
|
|
// 텍스트 타입
|
||
|
|
"character varying": "text",
|
||
|
|
varchar: "text",
|
||
|
|
text: "textarea",
|
||
|
|
char: "text",
|
||
|
|
|
||
|
|
// 숫자 타입
|
||
|
|
integer: "number",
|
||
|
|
bigint: "number",
|
||
|
|
smallint: "number",
|
||
|
|
serial: "number",
|
||
|
|
bigserial: "number",
|
||
|
|
numeric: "decimal",
|
||
|
|
decimal: "decimal",
|
||
|
|
real: "decimal",
|
||
|
|
"double precision": "decimal",
|
||
|
|
|
||
|
|
// 날짜/시간 타입
|
||
|
|
date: "date",
|
||
|
|
timestamp: "datetime",
|
||
|
|
"timestamp with time zone": "datetime",
|
||
|
|
"timestamp without time zone": "datetime",
|
||
|
|
time: "time",
|
||
|
|
"time with time zone": "time",
|
||
|
|
"time without time zone": "time",
|
||
|
|
|
||
|
|
// 불린 타입
|
||
|
|
boolean: "boolean",
|
||
|
|
|
||
|
|
// JSON 타입 (텍스트로 처리)
|
||
|
|
json: "textarea",
|
||
|
|
jsonb: "textarea",
|
||
|
|
|
||
|
|
// 배열 타입 (텍스트로 처리)
|
||
|
|
ARRAY: "textarea",
|
||
|
|
|
||
|
|
// UUID 타입
|
||
|
|
uuid: "text",
|
||
|
|
};
|
||
|
|
|
||
|
|
// 웹 타입별 기본 설정
|
||
|
|
export const WEB_TYPE_DEFAULT_CONFIGS: Record<WebType, Record<string, any>> = {
|
||
|
|
text: { maxLength: 255, placeholder: "텍스트를 입력하세요" },
|
||
|
|
number: { min: 0, max: 2147483647, step: 1 },
|
||
|
|
decimal: { min: 0, step: 0.01, decimalPlaces: 2 },
|
||
|
|
date: { format: "YYYY-MM-DD" },
|
||
|
|
datetime: { format: "YYYY-MM-DD HH:mm:ss", showTime: true },
|
||
|
|
time: { format: "HH:mm:ss" },
|
||
|
|
textarea: { rows: 4, cols: 50, maxLength: 1000 },
|
||
|
|
select: { placeholder: "선택하세요", searchable: false },
|
||
|
|
dropdown: { placeholder: "선택하세요", searchable: true },
|
||
|
|
checkbox: { defaultChecked: false },
|
||
|
|
radio: { inline: false },
|
||
|
|
boolean: { trueValue: true, falseValue: false },
|
||
|
|
file: { multiple: false, preview: true },
|
||
|
|
email: { placeholder: "이메일을 입력하세요" },
|
||
|
|
tel: { placeholder: "전화번호를 입력하세요" },
|
||
|
|
url: { placeholder: "URL을 입력하세요" },
|
||
|
|
password: { placeholder: "비밀번호를 입력하세요" },
|
||
|
|
code: { placeholder: "코드를 선택하세요", searchable: true },
|
||
|
|
entity: { placeholder: "항목을 선택하세요", searchable: true },
|
||
|
|
button: { variant: "default" },
|
||
|
|
text_area: { rows: 4, cols: 50, maxLength: 1000 }, // 레거시 지원
|
||
|
|
};
|
||
|
|
|
||
|
|
// 웹 타입별 검증 규칙
|
||
|
|
export const WEB_TYPE_VALIDATION_RULES: Record<WebType, Record<string, any>> = {
|
||
|
|
text: { type: "string", trim: true },
|
||
|
|
number: { type: "number", integer: true },
|
||
|
|
decimal: { type: "number", float: true },
|
||
|
|
date: { type: "date", format: "YYYY-MM-DD" },
|
||
|
|
datetime: { type: "datetime" },
|
||
|
|
time: { type: "time" },
|
||
|
|
textarea: { type: "string", multiline: true },
|
||
|
|
select: { type: "string", options: true },
|
||
|
|
dropdown: { type: "string", options: true },
|
||
|
|
checkbox: { type: "boolean" },
|
||
|
|
radio: { type: "string", options: true },
|
||
|
|
boolean: { type: "boolean" },
|
||
|
|
file: { type: "file" },
|
||
|
|
email: { type: "email" },
|
||
|
|
tel: { type: "tel" },
|
||
|
|
url: { type: "url" },
|
||
|
|
password: { type: "string", password: true },
|
||
|
|
code: { type: "string", code: true },
|
||
|
|
entity: { type: "string", entity: true },
|
||
|
|
button: { type: "action" },
|
||
|
|
text_area: { type: "string", multiline: true }, // 레거시 지원
|
||
|
|
};
|