2025-09-01 11:48:12 +09:00
|
|
|
|
// 화면관리 시스템 타입 정의
|
|
|
|
|
|
|
|
|
|
|
|
// 기본 컴포넌트 타입
|
2025-09-10 18:36:28 +09:00
|
|
|
|
export type ComponentType =
|
|
|
|
|
|
| "container"
|
|
|
|
|
|
| "row"
|
|
|
|
|
|
| "column"
|
|
|
|
|
|
| "widget"
|
|
|
|
|
|
| "group"
|
|
|
|
|
|
| "datatable"
|
|
|
|
|
|
| "file"
|
|
|
|
|
|
| "area"
|
|
|
|
|
|
| "layout";
|
2025-09-01 11:48:12 +09:00
|
|
|
|
|
|
|
|
|
|
// 웹 타입 정의
|
|
|
|
|
|
export type WebType =
|
|
|
|
|
|
| "text"
|
|
|
|
|
|
| "number"
|
|
|
|
|
|
| "date"
|
|
|
|
|
|
| "code"
|
|
|
|
|
|
| "entity"
|
|
|
|
|
|
| "textarea"
|
|
|
|
|
|
| "select"
|
|
|
|
|
|
| "checkbox"
|
|
|
|
|
|
| "radio"
|
2025-09-01 14:00:31 +09:00
|
|
|
|
| "file"
|
|
|
|
|
|
| "email"
|
|
|
|
|
|
| "tel"
|
|
|
|
|
|
| "datetime"
|
|
|
|
|
|
| "dropdown"
|
|
|
|
|
|
| "text_area"
|
|
|
|
|
|
| "boolean"
|
2025-09-04 11:33:52 +09:00
|
|
|
|
| "decimal"
|
|
|
|
|
|
| "button";
|
|
|
|
|
|
|
|
|
|
|
|
// 버튼 기능 타입 정의
|
|
|
|
|
|
export type ButtonActionType =
|
|
|
|
|
|
| "save" // 저장
|
|
|
|
|
|
| "delete" // 삭제
|
|
|
|
|
|
| "edit" // 수정
|
|
|
|
|
|
| "add" // 추가
|
|
|
|
|
|
| "search" // 검색
|
|
|
|
|
|
| "reset" // 초기화
|
|
|
|
|
|
| "submit" // 제출
|
|
|
|
|
|
| "close" // 닫기
|
2025-09-12 14:24:25 +09:00
|
|
|
|
| "popup" // 팝업 열기
|
|
|
|
|
|
| "modal" // 모달 열기
|
|
|
|
|
|
| "newWindow" // 새 창 열기
|
|
|
|
|
|
| "navigate"; // 페이지 이동
|
2025-09-01 11:48:12 +09:00
|
|
|
|
|
|
|
|
|
|
// 위치 정보
|
|
|
|
|
|
export interface Position {
|
|
|
|
|
|
x: number;
|
|
|
|
|
|
y: number;
|
2025-09-02 10:33:41 +09:00
|
|
|
|
z?: number; // z-index (레이어 순서)
|
2025-09-01 11:48:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 크기 정보
|
|
|
|
|
|
export interface Size {
|
|
|
|
|
|
width: number; // 1-12 그리드
|
|
|
|
|
|
height: number; // 픽셀
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-01 14:00:31 +09:00
|
|
|
|
// 테이블 정보
|
|
|
|
|
|
export interface TableInfo {
|
|
|
|
|
|
tableName: string;
|
|
|
|
|
|
tableLabel: string;
|
|
|
|
|
|
columns: ColumnInfo[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-01 11:48:12 +09:00
|
|
|
|
// 스타일 관련 타입
|
|
|
|
|
|
export interface ComponentStyle {
|
|
|
|
|
|
// 레이아웃
|
|
|
|
|
|
width?: string | number;
|
|
|
|
|
|
height?: string | number;
|
|
|
|
|
|
minWidth?: string | number;
|
|
|
|
|
|
minHeight?: string | number;
|
|
|
|
|
|
maxWidth?: string | number;
|
|
|
|
|
|
maxHeight?: string | number;
|
|
|
|
|
|
|
|
|
|
|
|
// 여백
|
|
|
|
|
|
margin?: string;
|
|
|
|
|
|
marginTop?: string | number;
|
|
|
|
|
|
marginRight?: string | number;
|
|
|
|
|
|
marginBottom?: string | number;
|
|
|
|
|
|
marginLeft?: string | number;
|
|
|
|
|
|
|
|
|
|
|
|
// 패딩
|
|
|
|
|
|
padding?: string;
|
|
|
|
|
|
paddingTop?: string | number;
|
|
|
|
|
|
paddingRight?: string | number;
|
|
|
|
|
|
paddingBottom?: string | number;
|
|
|
|
|
|
paddingLeft?: string | number;
|
|
|
|
|
|
|
|
|
|
|
|
// 테두리
|
|
|
|
|
|
border?: string;
|
|
|
|
|
|
borderWidth?: string | number;
|
|
|
|
|
|
borderStyle?: "solid" | "dashed" | "dotted" | "none";
|
|
|
|
|
|
borderColor?: string;
|
|
|
|
|
|
borderRadius?: string | number;
|
|
|
|
|
|
|
|
|
|
|
|
// 배경
|
|
|
|
|
|
backgroundColor?: string;
|
|
|
|
|
|
backgroundImage?: string;
|
|
|
|
|
|
backgroundSize?: "cover" | "contain" | "auto";
|
|
|
|
|
|
backgroundPosition?: string;
|
|
|
|
|
|
backgroundRepeat?: "repeat" | "no-repeat" | "repeat-x" | "repeat-y";
|
|
|
|
|
|
|
|
|
|
|
|
// 텍스트
|
|
|
|
|
|
color?: string;
|
|
|
|
|
|
fontSize?: string | number;
|
|
|
|
|
|
fontWeight?: "normal" | "bold" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900";
|
|
|
|
|
|
fontFamily?: string;
|
|
|
|
|
|
textAlign?: "left" | "center" | "right" | "justify";
|
|
|
|
|
|
lineHeight?: string | number;
|
|
|
|
|
|
textDecoration?: "none" | "underline" | "line-through";
|
|
|
|
|
|
|
|
|
|
|
|
// 정렬
|
|
|
|
|
|
display?: "block" | "inline" | "inline-block" | "flex" | "grid" | "none";
|
|
|
|
|
|
flexDirection?: "row" | "row-reverse" | "column" | "column-reverse";
|
|
|
|
|
|
justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
|
|
|
|
|
|
alignItems?: "stretch" | "flex-start" | "flex-end" | "center" | "baseline";
|
|
|
|
|
|
gap?: string | number;
|
|
|
|
|
|
|
|
|
|
|
|
// 위치
|
|
|
|
|
|
position?: "static" | "relative" | "absolute" | "fixed" | "sticky";
|
|
|
|
|
|
top?: string | number;
|
|
|
|
|
|
right?: string | number;
|
|
|
|
|
|
bottom?: string | number;
|
|
|
|
|
|
left?: string | number;
|
|
|
|
|
|
zIndex?: number;
|
|
|
|
|
|
|
|
|
|
|
|
// 그림자
|
|
|
|
|
|
boxShadow?: string;
|
|
|
|
|
|
|
|
|
|
|
|
// 기타
|
|
|
|
|
|
opacity?: number;
|
|
|
|
|
|
overflow?: "visible" | "hidden" | "scroll" | "auto";
|
|
|
|
|
|
cursor?: string;
|
|
|
|
|
|
transition?: string;
|
|
|
|
|
|
transform?: string;
|
2025-09-02 16:46:54 +09:00
|
|
|
|
|
|
|
|
|
|
// 라벨 스타일
|
|
|
|
|
|
labelDisplay?: boolean; // 라벨 표시 여부
|
|
|
|
|
|
labelText?: string; // 라벨 텍스트 (기본값은 label 속성 사용)
|
|
|
|
|
|
labelFontSize?: string | number; // 라벨 폰트 크기
|
|
|
|
|
|
labelColor?: string; // 라벨 색상
|
|
|
|
|
|
labelFontWeight?: "normal" | "bold" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900"; // 라벨 폰트 굵기
|
|
|
|
|
|
labelFontFamily?: string; // 라벨 폰트 패밀리
|
|
|
|
|
|
labelTextAlign?: "left" | "center" | "right"; // 라벨 텍스트 정렬
|
|
|
|
|
|
labelMarginBottom?: string | number; // 라벨과 컴포넌트 사이의 간격
|
|
|
|
|
|
labelBackgroundColor?: string; // 라벨 배경색
|
|
|
|
|
|
labelPadding?: string; // 라벨 패딩
|
|
|
|
|
|
labelBorderRadius?: string | number; // 라벨 모서리 둥글기
|
2025-09-01 11:48:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// BaseComponent에 스타일 속성 추가
|
|
|
|
|
|
export interface BaseComponent {
|
|
|
|
|
|
id: string;
|
|
|
|
|
|
type: ComponentType;
|
2025-09-02 16:18:38 +09:00
|
|
|
|
position: Position;
|
2025-09-01 11:48:12 +09:00
|
|
|
|
size: { width: number; height: number };
|
|
|
|
|
|
parentId?: string;
|
2025-09-11 12:22:39 +09:00
|
|
|
|
zoneId?: string; // 레이아웃 존 ID (레이아웃 내 배치용)
|
2025-09-01 11:48:12 +09:00
|
|
|
|
style?: ComponentStyle; // 스타일 속성 추가
|
2025-09-01 14:00:31 +09:00
|
|
|
|
tableName?: string; // 테이블명 추가
|
|
|
|
|
|
label?: string; // 라벨 추가
|
2025-09-03 11:32:09 +09:00
|
|
|
|
gridColumns?: number; // 그리드에서 차지할 컬럼 수 (1-12)
|
2025-09-04 14:23:35 +09:00
|
|
|
|
inputType?: "direct" | "auto"; // 입력 타입 (직접입력/자동입력)
|
|
|
|
|
|
autoValueType?:
|
|
|
|
|
|
| "current_datetime"
|
|
|
|
|
|
| "current_date"
|
|
|
|
|
|
| "current_time"
|
|
|
|
|
|
| "current_user"
|
|
|
|
|
|
| "uuid"
|
|
|
|
|
|
| "sequence"
|
|
|
|
|
|
| "user_defined"; // 자동 값 타입
|
2025-09-01 11:48:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 컨테이너 컴포넌트
|
|
|
|
|
|
export interface ContainerComponent extends BaseComponent {
|
|
|
|
|
|
type: "container";
|
|
|
|
|
|
title?: string;
|
|
|
|
|
|
backgroundColor?: string;
|
|
|
|
|
|
border?: string;
|
|
|
|
|
|
borderRadius?: number;
|
|
|
|
|
|
shadow?: string;
|
|
|
|
|
|
children?: string[]; // 자식 컴포넌트 ID 목록
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 그룹 컴포넌트
|
|
|
|
|
|
export interface GroupComponent extends BaseComponent {
|
|
|
|
|
|
type: "group";
|
|
|
|
|
|
title?: string;
|
|
|
|
|
|
backgroundColor?: string;
|
|
|
|
|
|
border?: string;
|
|
|
|
|
|
borderRadius?: number;
|
|
|
|
|
|
shadow?: string;
|
|
|
|
|
|
collapsible?: boolean;
|
|
|
|
|
|
collapsed?: boolean;
|
|
|
|
|
|
children?: string[]; // 자식 컴포넌트 ID 목록
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 행 컴포넌트
|
|
|
|
|
|
export interface RowComponent extends BaseComponent {
|
|
|
|
|
|
type: "row";
|
|
|
|
|
|
gap?: number;
|
|
|
|
|
|
alignItems?: "start" | "center" | "end" | "stretch";
|
|
|
|
|
|
justifyContent?: "start" | "center" | "end" | "space-between" | "space-around";
|
|
|
|
|
|
children?: string[]; // 자식 컴포넌트 ID 목록
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 열 컴포넌트
|
|
|
|
|
|
export interface ColumnComponent extends BaseComponent {
|
|
|
|
|
|
type: "column";
|
|
|
|
|
|
gap?: number;
|
|
|
|
|
|
alignItems?: "start" | "center" | "end" | "stretch";
|
|
|
|
|
|
justifyContent?: "start" | "center" | "end" | "space-between" | "space-around";
|
|
|
|
|
|
children?: string[]; // 자식 컴포넌트 ID 목록
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 13:10:09 +09:00
|
|
|
|
// 영역 레이아웃 타입
|
|
|
|
|
|
export type AreaLayoutType =
|
|
|
|
|
|
| "box" // 기본 박스
|
|
|
|
|
|
| "card" // 카드 형태 (그림자 + 둥근 모서리)
|
|
|
|
|
|
| "panel" // 패널 형태 (헤더 포함)
|
|
|
|
|
|
| "section" // 섹션 형태 (제목 + 구분선)
|
|
|
|
|
|
| "grid" // 그리드 레이아웃
|
|
|
|
|
|
| "flex-row" // 가로 플렉스
|
|
|
|
|
|
| "flex-column" // 세로 플렉스
|
|
|
|
|
|
| "sidebar" // 사이드바 레이아웃
|
|
|
|
|
|
| "header-content" // 헤더-컨텐츠 레이아웃
|
|
|
|
|
|
| "tabs" // 탭 레이아웃
|
|
|
|
|
|
| "accordion"; // 아코디언 레이아웃
|
|
|
|
|
|
|
|
|
|
|
|
// 영역 컴포넌트
|
|
|
|
|
|
export interface AreaComponent extends BaseComponent {
|
|
|
|
|
|
type: "area";
|
|
|
|
|
|
layoutType: AreaLayoutType;
|
|
|
|
|
|
title?: string;
|
|
|
|
|
|
description?: string;
|
|
|
|
|
|
|
|
|
|
|
|
// 레이아웃별 설정
|
|
|
|
|
|
layoutConfig?: {
|
|
|
|
|
|
// 그리드 레이아웃 설정
|
|
|
|
|
|
gridColumns?: number;
|
|
|
|
|
|
gridRows?: number;
|
|
|
|
|
|
gridGap?: number;
|
|
|
|
|
|
|
|
|
|
|
|
// 플렉스 레이아웃 설정
|
|
|
|
|
|
flexDirection?: "row" | "column";
|
|
|
|
|
|
flexWrap?: "nowrap" | "wrap" | "wrap-reverse";
|
|
|
|
|
|
justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
|
|
|
|
|
|
alignItems?: "stretch" | "flex-start" | "flex-end" | "center" | "baseline";
|
|
|
|
|
|
gap?: number;
|
|
|
|
|
|
|
|
|
|
|
|
// 탭 레이아웃 설정
|
|
|
|
|
|
tabPosition?: "top" | "bottom" | "left" | "right";
|
|
|
|
|
|
defaultActiveTab?: string;
|
|
|
|
|
|
|
|
|
|
|
|
// 사이드바 레이아웃 설정
|
|
|
|
|
|
sidebarPosition?: "left" | "right";
|
|
|
|
|
|
sidebarWidth?: number;
|
|
|
|
|
|
collapsible?: boolean;
|
|
|
|
|
|
|
|
|
|
|
|
// 아코디언 설정
|
|
|
|
|
|
allowMultiple?: boolean;
|
|
|
|
|
|
defaultExpanded?: string[];
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 스타일 설정
|
|
|
|
|
|
areaStyle?: {
|
|
|
|
|
|
backgroundColor?: string;
|
|
|
|
|
|
borderColor?: string;
|
|
|
|
|
|
borderWidth?: number;
|
|
|
|
|
|
borderStyle?: "solid" | "dashed" | "dotted" | "none";
|
|
|
|
|
|
borderRadius?: number;
|
|
|
|
|
|
padding?: number;
|
|
|
|
|
|
margin?: number;
|
|
|
|
|
|
shadow?: "none" | "sm" | "md" | "lg" | "xl";
|
|
|
|
|
|
|
|
|
|
|
|
// 헤더 스타일 (panel, section 타입용)
|
|
|
|
|
|
headerBackgroundColor?: string;
|
|
|
|
|
|
headerTextColor?: string;
|
|
|
|
|
|
headerHeight?: number;
|
|
|
|
|
|
headerPadding?: number;
|
|
|
|
|
|
|
|
|
|
|
|
// 그리드 라인 표시 (grid 타입용)
|
|
|
|
|
|
showGridLines?: boolean;
|
|
|
|
|
|
gridLineColor?: string;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
children?: string[]; // 자식 컴포넌트 ID 목록
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-05 21:52:19 +09:00
|
|
|
|
// 파일 첨부 컴포넌트
|
|
|
|
|
|
export interface FileComponent extends BaseComponent {
|
|
|
|
|
|
type: "file";
|
|
|
|
|
|
fileConfig: {
|
|
|
|
|
|
// 파일 업로드 설정
|
|
|
|
|
|
accept: string[]; // 허용 파일 타입 ['image/*', '.pdf', '.doc']
|
|
|
|
|
|
multiple: boolean; // 다중 파일 선택 허용
|
|
|
|
|
|
maxSize: number; // 최대 파일 크기 (MB)
|
|
|
|
|
|
maxFiles: number; // 최대 파일 개수
|
|
|
|
|
|
|
|
|
|
|
|
// 문서 분류 설정
|
|
|
|
|
|
docType: string; // 문서 타입 (CONTRACT, DRAWING, PHOTO, DOCUMENT, REPORT, OTHER)
|
|
|
|
|
|
docTypeName: string; // 문서 타입 표시명
|
|
|
|
|
|
|
|
|
|
|
|
// 연결 객체 설정
|
|
|
|
|
|
targetObjid?: string; // 연결된 주 객체 ID (예: 계약 ID, 프로젝트 ID)
|
|
|
|
|
|
parentTargetObjid?: string; // 부모 객체 ID (계층 구조용)
|
|
|
|
|
|
|
2025-09-06 00:16:27 +09:00
|
|
|
|
// 테이블 연결 설정 (새로 추가)
|
|
|
|
|
|
linkedTable?: string; // 연결할 테이블명 (예: company_mng, user_info)
|
|
|
|
|
|
linkedField?: string; // 연결할 필드명 (예: emp_id, user_id)
|
|
|
|
|
|
autoLink?: boolean; // 자동 연결 여부 (현재 레코드와 자동 연결)
|
|
|
|
|
|
recordId?: string; // 연결할 레코드 ID
|
|
|
|
|
|
|
|
|
|
|
|
// 가상 파일 컬럼 전용 설정
|
|
|
|
|
|
columnName?: string; // 가상 파일 컬럼명 (tableName:recordId:columnName 형태로 target_objid 생성)
|
|
|
|
|
|
isVirtualFileColumn?: boolean; // 가상 파일 컬럼 여부
|
|
|
|
|
|
|
2025-09-05 21:52:19 +09:00
|
|
|
|
// UI 설정
|
|
|
|
|
|
showPreview: boolean; // 미리보기 표시 여부
|
|
|
|
|
|
showProgress: boolean; // 업로드 진행률 표시
|
|
|
|
|
|
dragDropText: string; // 드래그앤드롭 안내 텍스트
|
|
|
|
|
|
uploadButtonText: string; // 업로드 버튼 텍스트
|
|
|
|
|
|
|
|
|
|
|
|
// 자동 업로드 설정
|
|
|
|
|
|
autoUpload: boolean; // 파일 선택 시 자동 업로드
|
|
|
|
|
|
chunkedUpload: boolean; // 대용량 파일 분할 업로드
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 업로드된 파일 목록
|
|
|
|
|
|
uploadedFiles: AttachedFileInfo[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 첨부파일 정보 (attach_file_info 테이블 기반)
|
|
|
|
|
|
export interface AttachedFileInfo {
|
|
|
|
|
|
objid: string; // 파일 고유 ID
|
|
|
|
|
|
savedFileName: string; // 서버에 저장된 파일명
|
|
|
|
|
|
realFileName: string; // 실제 파일명 (사용자가 본 원본명)
|
|
|
|
|
|
fileSize: number; // 파일 크기 (bytes)
|
|
|
|
|
|
fileExt: string; // 파일 확장자
|
|
|
|
|
|
filePath: string; // 파일 저장 경로
|
|
|
|
|
|
docType: string; // 문서 분류
|
|
|
|
|
|
docTypeName: string; // 문서 분류 표시명
|
|
|
|
|
|
targetObjid: string; // 연결 객체 ID
|
|
|
|
|
|
parentTargetObjid?: string; // 부모 객체 ID
|
|
|
|
|
|
companyCode: string; // 회사 코드
|
|
|
|
|
|
writer: string; // 작성자
|
|
|
|
|
|
regdate: string; // 등록일시
|
|
|
|
|
|
status: string; // 상태 (ACTIVE, DELETED)
|
|
|
|
|
|
|
|
|
|
|
|
// UI용 추가 속성
|
|
|
|
|
|
uploadProgress?: number; // 업로드 진행률 (0-100)
|
|
|
|
|
|
isUploading?: boolean; // 업로드 중 여부
|
|
|
|
|
|
hasError?: boolean; // 에러 발생 여부
|
|
|
|
|
|
errorMessage?: string; // 에러 메시지
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-01 11:48:12 +09:00
|
|
|
|
// 위젯 컴포넌트
|
|
|
|
|
|
export interface WidgetComponent extends BaseComponent {
|
|
|
|
|
|
type: "widget";
|
|
|
|
|
|
tableName: string;
|
|
|
|
|
|
columnName: string;
|
|
|
|
|
|
widgetType: WebType;
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
placeholder?: string;
|
|
|
|
|
|
required: boolean;
|
|
|
|
|
|
readonly: boolean;
|
|
|
|
|
|
validationRules?: ValidationRule[];
|
2025-09-03 11:32:09 +09:00
|
|
|
|
displayProperties?: Record<string, any>; // 레거시 지원용 (향후 제거 예정)
|
|
|
|
|
|
webTypeConfig?: WebTypeConfig; // 웹타입별 상세 설정
|
2025-09-01 11:48:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-03 15:23:12 +09:00
|
|
|
|
// 데이터 테이블 컬럼 설정
|
|
|
|
|
|
export interface DataTableColumn {
|
|
|
|
|
|
id: string;
|
2025-09-06 00:16:27 +09:00
|
|
|
|
columnName: string; // 실제 DB 컬럼명 (가상 컬럼의 경우 고유 식별자)
|
2025-09-03 15:23:12 +09:00
|
|
|
|
label: string; // 화면에 표시될 라벨
|
|
|
|
|
|
widgetType: WebType; // 컬럼의 데이터 타입
|
|
|
|
|
|
gridColumns: number; // 그리드에서 차지할 컬럼 수 (1-12)
|
|
|
|
|
|
visible: boolean; // 테이블에 표시할지 여부
|
|
|
|
|
|
filterable: boolean; // 필터링 가능 여부
|
|
|
|
|
|
sortable: boolean; // 정렬 가능 여부
|
|
|
|
|
|
searchable: boolean; // 검색 대상 여부
|
|
|
|
|
|
webTypeConfig?: WebTypeConfig; // 컬럼별 상세 설정
|
2025-09-06 00:16:27 +09:00
|
|
|
|
|
2025-09-15 15:38:48 +09:00
|
|
|
|
// 레거시 지원용 (테이블 타입 관리에서 설정된 값)
|
|
|
|
|
|
codeCategory?: string; // 코드 카테고리 (코드 타입용)
|
|
|
|
|
|
referenceTable?: string; // 참조 테이블 (엔티티 타입용)
|
|
|
|
|
|
|
2025-09-06 00:16:27 +09:00
|
|
|
|
// 가상 파일 컬럼 관련 속성
|
|
|
|
|
|
isVirtualFileColumn?: boolean; // 가상 파일 컬럼인지 여부
|
|
|
|
|
|
fileColumnConfig?: {
|
|
|
|
|
|
docType?: string; // 문서 타입 (CONTRACT, DRAWING, PHOTO 등)
|
|
|
|
|
|
docTypeName?: string; // 문서 타입 표시명
|
|
|
|
|
|
maxFiles?: number; // 최대 파일 개수
|
|
|
|
|
|
accept?: string[]; // 허용 파일 타입
|
|
|
|
|
|
};
|
2025-09-03 15:23:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 데이터 테이블 필터 설정
|
|
|
|
|
|
export interface DataTableFilter {
|
|
|
|
|
|
columnName: string;
|
|
|
|
|
|
widgetType: WebType;
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
gridColumns: number; // 필터에서 차지할 컬럼 수
|
|
|
|
|
|
webTypeConfig?: WebTypeConfig;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 데이터 테이블 페이지네이션 설정
|
|
|
|
|
|
export interface DataTablePagination {
|
|
|
|
|
|
enabled: boolean;
|
|
|
|
|
|
pageSize: number; // 페이지당 행 수
|
|
|
|
|
|
pageSizeOptions: number[]; // 선택 가능한 페이지 크기들
|
|
|
|
|
|
showPageSizeSelector: boolean; // 페이지 크기 선택기 표시 여부
|
|
|
|
|
|
showPageInfo: boolean; // 페이지 정보 표시 여부
|
|
|
|
|
|
showFirstLast: boolean; // 처음/마지막 버튼 표시 여부
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-03 16:38:10 +09:00
|
|
|
|
// 필드 자동 값 타입
|
|
|
|
|
|
export type FieldAutoValueType =
|
|
|
|
|
|
| "none" // 일반 입력
|
|
|
|
|
|
| "current_datetime" // 현재 날짜시간
|
|
|
|
|
|
| "current_date" // 현재 날짜
|
|
|
|
|
|
| "current_time" // 현재 시간
|
|
|
|
|
|
| "current_user" // 현재 사용자
|
|
|
|
|
|
| "uuid" // UUID 생성
|
|
|
|
|
|
| "sequence" // 시퀀스 번호
|
|
|
|
|
|
| "custom" // 사용자 정의 값
|
|
|
|
|
|
| "calculated"; // 계산 필드
|
|
|
|
|
|
|
|
|
|
|
|
// 고급 필드 설정
|
|
|
|
|
|
export interface AdvancedFieldConfig {
|
|
|
|
|
|
columnName: string; // 컬럼명
|
|
|
|
|
|
inputType: "normal" | "readonly" | "hidden" | "auto"; // 입력 타입
|
|
|
|
|
|
autoValueType: FieldAutoValueType; // 자동 값 타입
|
|
|
|
|
|
defaultValue?: string; // 기본값
|
|
|
|
|
|
customValue?: string; // 사용자 정의 값
|
|
|
|
|
|
calculationFormula?: string; // 계산 공식 (예: "{price} * {quantity}")
|
|
|
|
|
|
placeholder?: string; // 플레이스홀더
|
|
|
|
|
|
helpText?: string; // 도움말 텍스트
|
|
|
|
|
|
validationRules?: {
|
|
|
|
|
|
min?: number;
|
|
|
|
|
|
max?: number;
|
|
|
|
|
|
minLength?: number;
|
|
|
|
|
|
maxLength?: number;
|
|
|
|
|
|
pattern?: string;
|
|
|
|
|
|
customValidation?: string;
|
|
|
|
|
|
};
|
|
|
|
|
|
conditionalDisplay?: {
|
|
|
|
|
|
enabled: boolean;
|
|
|
|
|
|
condition: string; // 조건식 (예: "{status} === 'active'")
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 데이터 추가 모달 커스터마이징 설정
|
|
|
|
|
|
export interface DataTableAddModalConfig {
|
|
|
|
|
|
title: string; // 모달 제목
|
|
|
|
|
|
description: string; // 모달 설명
|
|
|
|
|
|
width: "sm" | "md" | "lg" | "xl" | "2xl" | "full"; // 모달 크기
|
|
|
|
|
|
layout: "single" | "two-column" | "grid"; // 레이아웃 타입
|
|
|
|
|
|
gridColumns: number; // 그리드 레이아웃 시 컬럼 수 (2-4)
|
|
|
|
|
|
fieldOrder: string[]; // 필드 표시 순서 (컬럼명 배열)
|
|
|
|
|
|
requiredFields: string[]; // 필수 필드 (컬럼명 배열)
|
|
|
|
|
|
hiddenFields: string[]; // 숨길 필드 (컬럼명 배열)
|
|
|
|
|
|
advancedFieldConfigs: Record<string, AdvancedFieldConfig>; // 고급 필드 설정
|
|
|
|
|
|
submitButtonText: string; // 제출 버튼 텍스트
|
|
|
|
|
|
cancelButtonText: string; // 취소 버튼 텍스트
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-03 15:23:12 +09:00
|
|
|
|
// 데이터 테이블 컴포넌트
|
|
|
|
|
|
export interface DataTableComponent extends BaseComponent {
|
|
|
|
|
|
type: "datatable";
|
|
|
|
|
|
tableName: string; // 연결된 테이블명
|
|
|
|
|
|
title?: string; // 테이블 제목
|
|
|
|
|
|
columns: DataTableColumn[]; // 테이블 컬럼 설정
|
|
|
|
|
|
filters: DataTableFilter[]; // 검색 필터 설정
|
|
|
|
|
|
pagination: DataTablePagination; // 페이지네이션 설정
|
|
|
|
|
|
showSearchButton: boolean; // 검색 버튼 표시 여부
|
|
|
|
|
|
searchButtonText: string; // 검색 버튼 텍스트
|
|
|
|
|
|
enableExport: boolean; // 내보내기 기능 활성화
|
|
|
|
|
|
enableRefresh: boolean; // 새로고침 기능 활성화
|
2025-09-03 16:38:10 +09:00
|
|
|
|
enableAdd: boolean; // 데이터 추가 기능 활성화
|
|
|
|
|
|
enableEdit: boolean; // 데이터 수정 기능 활성화
|
|
|
|
|
|
enableDelete: boolean; // 데이터 삭제 기능 활성화
|
|
|
|
|
|
addButtonText: string; // 추가 버튼 텍스트
|
|
|
|
|
|
editButtonText: string; // 수정 버튼 텍스트
|
|
|
|
|
|
deleteButtonText: string; // 삭제 버튼 텍스트
|
|
|
|
|
|
addModalConfig: DataTableAddModalConfig; // 추가 모달 커스터마이징 설정
|
2025-09-03 15:23:12 +09:00
|
|
|
|
gridColumns: number; // 테이블이 차지할 그리드 컬럼 수
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-01 11:48:12 +09:00
|
|
|
|
// 컴포넌트 유니온 타입
|
2025-09-03 15:23:12 +09:00
|
|
|
|
export type ComponentData =
|
|
|
|
|
|
| ContainerComponent
|
|
|
|
|
|
| GroupComponent
|
|
|
|
|
|
| RowComponent
|
|
|
|
|
|
| ColumnComponent
|
2025-09-08 13:10:09 +09:00
|
|
|
|
| AreaComponent
|
2025-09-03 15:23:12 +09:00
|
|
|
|
| WidgetComponent
|
2025-09-05 21:52:19 +09:00
|
|
|
|
| DataTableComponent
|
2025-09-10 18:36:28 +09:00
|
|
|
|
| FileComponent
|
|
|
|
|
|
| LayoutComponent;
|
2025-09-01 11:48:12 +09:00
|
|
|
|
|
|
|
|
|
|
// 레이아웃 데이터
|
|
|
|
|
|
export interface LayoutData {
|
|
|
|
|
|
components: ComponentData[];
|
|
|
|
|
|
gridSettings?: GridSettings;
|
2025-09-04 15:20:26 +09:00
|
|
|
|
screenResolution?: ScreenResolution;
|
2025-09-01 11:48:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 그리드 설정
|
|
|
|
|
|
export interface GridSettings {
|
|
|
|
|
|
columns: number; // 기본값: 12
|
|
|
|
|
|
gap: number; // 기본값: 16px
|
|
|
|
|
|
padding: number; // 기본값: 16px
|
2025-09-02 11:16:40 +09:00
|
|
|
|
snapToGrid?: boolean; // 격자에 맞춤 여부 (기본값: true)
|
2025-09-02 16:18:38 +09:00
|
|
|
|
showGrid?: boolean; // 격자 표시 여부 (기본값: true)
|
|
|
|
|
|
gridColor?: string; // 격자 색상 (기본값: #d1d5db)
|
|
|
|
|
|
gridOpacity?: number; // 격자 투명도 (기본값: 0.5)
|
2025-09-01 11:48:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 유효성 검증 규칙
|
|
|
|
|
|
export interface ValidationRule {
|
|
|
|
|
|
type: "required" | "minLength" | "maxLength" | "pattern" | "min" | "max" | "email" | "url";
|
|
|
|
|
|
value?: any;
|
|
|
|
|
|
message: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 화면 정의
|
|
|
|
|
|
export interface ScreenDefinition {
|
|
|
|
|
|
screenId: number;
|
|
|
|
|
|
screenName: string;
|
|
|
|
|
|
screenCode: string;
|
|
|
|
|
|
tableName: string;
|
2025-09-08 14:20:01 +09:00
|
|
|
|
tableLabel?: string; // 테이블 라벨 (한글명)
|
2025-09-01 11:48:12 +09:00
|
|
|
|
companyCode: string;
|
|
|
|
|
|
description?: string;
|
|
|
|
|
|
isActive: string;
|
|
|
|
|
|
createdDate: Date;
|
|
|
|
|
|
updatedDate: Date;
|
|
|
|
|
|
createdBy?: string;
|
|
|
|
|
|
updatedBy?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 화면 생성 요청
|
|
|
|
|
|
export interface CreateScreenRequest {
|
|
|
|
|
|
screenName: string;
|
|
|
|
|
|
screenCode: string;
|
|
|
|
|
|
tableName: string;
|
|
|
|
|
|
companyCode: string;
|
|
|
|
|
|
description?: string;
|
|
|
|
|
|
createdBy?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-10 18:36:28 +09:00
|
|
|
|
// 레이아웃 컴포넌트 (layout.ts에서 import)
|
|
|
|
|
|
export interface LayoutComponent extends BaseComponent {
|
|
|
|
|
|
type: "layout";
|
|
|
|
|
|
layoutType: import("./layout").LayoutType;
|
|
|
|
|
|
layoutConfig: import("./layout").LayoutConfig;
|
|
|
|
|
|
children: ComponentData[];
|
|
|
|
|
|
zones: import("./layout").LayoutZone[];
|
|
|
|
|
|
allowedComponentTypes?: ComponentType[];
|
|
|
|
|
|
dropZoneConfig?: import("./layout").DropZoneConfig;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-01 11:48:12 +09:00
|
|
|
|
// 화면 수정 요청
|
|
|
|
|
|
export interface UpdateScreenRequest {
|
|
|
|
|
|
screenName?: string;
|
|
|
|
|
|
description?: string;
|
|
|
|
|
|
isActive?: boolean;
|
|
|
|
|
|
updatedBy?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 레이아웃 저장 요청
|
|
|
|
|
|
export interface SaveLayoutRequest {
|
|
|
|
|
|
components: ComponentData[];
|
|
|
|
|
|
gridSettings?: GridSettings;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 화면 템플릿
|
|
|
|
|
|
export interface ScreenTemplate {
|
|
|
|
|
|
templateId: number;
|
|
|
|
|
|
templateName: string;
|
|
|
|
|
|
templateType: string;
|
|
|
|
|
|
companyCode: string;
|
|
|
|
|
|
description?: string;
|
|
|
|
|
|
layoutData?: LayoutData;
|
|
|
|
|
|
isPublic: boolean;
|
|
|
|
|
|
createdBy?: string;
|
|
|
|
|
|
createdDate: Date;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 메뉴 할당 요청
|
|
|
|
|
|
export interface MenuAssignmentRequest {
|
|
|
|
|
|
menuObjid: number;
|
|
|
|
|
|
companyCode: string;
|
|
|
|
|
|
displayOrder?: number;
|
|
|
|
|
|
createdBy?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 드래그 상태
|
|
|
|
|
|
export interface DragState {
|
|
|
|
|
|
isDragging: boolean;
|
|
|
|
|
|
draggedItem: ComponentData | null;
|
|
|
|
|
|
draggedComponent?: ComponentData | null; // 컴포넌트 재배치용
|
|
|
|
|
|
dragSource: "toolbox" | "canvas";
|
|
|
|
|
|
dropTarget: string | null;
|
|
|
|
|
|
dropZone?: DropZone;
|
|
|
|
|
|
dragOffset?: { x: number; y: number }; // 드래그 오프셋
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 드롭 영역
|
|
|
|
|
|
export interface DropZone {
|
|
|
|
|
|
id: string;
|
|
|
|
|
|
accepts: ComponentType[];
|
|
|
|
|
|
position: Position;
|
|
|
|
|
|
size: Size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 그룹화 상태
|
|
|
|
|
|
export interface GroupState {
|
|
|
|
|
|
isGrouping: boolean;
|
|
|
|
|
|
selectedComponents: string[];
|
2025-09-02 16:18:38 +09:00
|
|
|
|
groupTarget?: string | null;
|
|
|
|
|
|
groupMode?: "create" | "add" | "remove" | "ungroup";
|
2025-09-01 15:22:47 +09:00
|
|
|
|
groupTitle?: string;
|
|
|
|
|
|
groupStyle?: ComponentStyle;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 그룹화 작업 타입
|
|
|
|
|
|
export interface GroupingAction {
|
|
|
|
|
|
type: "create" | "add" | "remove" | "ungroup";
|
|
|
|
|
|
componentIds: string[];
|
|
|
|
|
|
groupId?: string;
|
|
|
|
|
|
groupTitle?: string;
|
|
|
|
|
|
groupStyle?: ComponentStyle;
|
2025-09-01 11:48:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 컬럼 정보 (테이블 타입관리 연계용)
|
|
|
|
|
|
export interface ColumnInfo {
|
|
|
|
|
|
tableName: string;
|
|
|
|
|
|
columnName: string;
|
|
|
|
|
|
columnLabel?: string;
|
|
|
|
|
|
dataType: string;
|
|
|
|
|
|
webType?: WebType;
|
2025-09-02 16:18:38 +09:00
|
|
|
|
widgetType?: WebType; // 프론트엔드에서 사용하는 필드 (webType과 동일)
|
2025-09-04 14:23:35 +09:00
|
|
|
|
inputType?: "direct" | "auto"; // 입력 타입
|
2025-09-01 11:48:12 +09:00
|
|
|
|
isNullable: string;
|
2025-09-02 16:18:38 +09:00
|
|
|
|
required?: boolean; // isNullable에서 변환된 필드
|
2025-09-01 11:48:12 +09:00
|
|
|
|
columnDefault?: string;
|
|
|
|
|
|
characterMaximumLength?: number;
|
|
|
|
|
|
numericPrecision?: number;
|
|
|
|
|
|
numericScale?: number;
|
|
|
|
|
|
detailSettings?: string; // JSON 문자열
|
|
|
|
|
|
codeCategory?: string;
|
|
|
|
|
|
referenceTable?: string;
|
|
|
|
|
|
referenceColumn?: string;
|
2025-09-16 15:13:00 +09:00
|
|
|
|
displayColumn?: string; // 🎯 Entity 조인에서 표시할 컬럼명
|
2025-09-01 11:48:12 +09:00
|
|
|
|
isVisible?: boolean;
|
|
|
|
|
|
displayOrder?: number;
|
|
|
|
|
|
description?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 웹 타입 설정
|
|
|
|
|
|
export interface ColumnWebTypeSetting {
|
|
|
|
|
|
tableName: string;
|
|
|
|
|
|
columnName: string;
|
|
|
|
|
|
webType: WebType;
|
|
|
|
|
|
columnLabel?: string;
|
|
|
|
|
|
detailSettings?: Record<string, any>;
|
|
|
|
|
|
codeCategory?: string;
|
|
|
|
|
|
referenceTable?: string;
|
|
|
|
|
|
referenceColumn?: string;
|
2025-09-16 15:13:00 +09:00
|
|
|
|
displayColumn?: string; // 🎯 Entity 조인에서 표시할 컬럼명
|
2025-09-01 11:48:12 +09:00
|
|
|
|
isVisible?: boolean;
|
|
|
|
|
|
displayOrder?: number;
|
|
|
|
|
|
description?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 위젯 데이터
|
|
|
|
|
|
export interface WidgetData {
|
|
|
|
|
|
id: string;
|
|
|
|
|
|
tableName: string;
|
|
|
|
|
|
columnName: string;
|
|
|
|
|
|
type: WebType;
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
required: boolean;
|
|
|
|
|
|
readonly: boolean;
|
|
|
|
|
|
[key: string]: any; // 추가 속성들
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// API 응답 타입
|
|
|
|
|
|
export interface ApiResponse<T> {
|
|
|
|
|
|
success: boolean;
|
|
|
|
|
|
data?: T;
|
|
|
|
|
|
message?: string;
|
|
|
|
|
|
errorCode?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 페이지네이션 응답
|
|
|
|
|
|
export interface PaginatedResponse<T> {
|
|
|
|
|
|
data: T[];
|
|
|
|
|
|
total: number;
|
|
|
|
|
|
page: number;
|
|
|
|
|
|
size: number;
|
|
|
|
|
|
totalPages: number;
|
|
|
|
|
|
}
|
2025-09-03 11:32:09 +09:00
|
|
|
|
|
|
|
|
|
|
// ===== 웹타입별 상세 설정 인터페이스 =====
|
|
|
|
|
|
|
|
|
|
|
|
// 날짜/시간 타입 설정
|
|
|
|
|
|
export interface DateTypeConfig {
|
|
|
|
|
|
format: "YYYY-MM-DD" | "YYYY-MM-DD HH:mm" | "YYYY-MM-DD HH:mm:ss";
|
|
|
|
|
|
showTime: boolean;
|
|
|
|
|
|
minDate?: string;
|
|
|
|
|
|
maxDate?: string;
|
|
|
|
|
|
defaultValue?: string;
|
|
|
|
|
|
placeholder?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 숫자 타입 설정
|
|
|
|
|
|
export interface NumberTypeConfig {
|
|
|
|
|
|
min?: number;
|
|
|
|
|
|
max?: number;
|
|
|
|
|
|
step?: number;
|
|
|
|
|
|
format?: "integer" | "decimal" | "currency" | "percentage";
|
|
|
|
|
|
decimalPlaces?: number;
|
|
|
|
|
|
thousandSeparator?: boolean;
|
|
|
|
|
|
prefix?: string; // 접두사 (예: $, ₩)
|
|
|
|
|
|
suffix?: string; // 접미사 (예: %, kg)
|
|
|
|
|
|
placeholder?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 선택박스 타입 설정
|
|
|
|
|
|
export interface SelectTypeConfig {
|
|
|
|
|
|
options: Array<{ label: string; value: string; disabled?: boolean }>;
|
|
|
|
|
|
multiple?: boolean;
|
|
|
|
|
|
searchable?: boolean;
|
|
|
|
|
|
placeholder?: string;
|
|
|
|
|
|
allowClear?: boolean;
|
|
|
|
|
|
maxSelections?: number; // 다중 선택 시 최대 선택 개수
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 텍스트 타입 설정
|
|
|
|
|
|
export interface TextTypeConfig {
|
|
|
|
|
|
minLength?: number;
|
|
|
|
|
|
maxLength?: number;
|
|
|
|
|
|
pattern?: string; // 정규식 패턴
|
2025-09-04 18:36:40 +09:00
|
|
|
|
format?: "none" | "email" | "phone" | "url" | "korean" | "english" | "alphanumeric" | "numeric";
|
2025-09-03 11:32:09 +09:00
|
|
|
|
placeholder?: string;
|
2025-09-04 18:36:40 +09:00
|
|
|
|
defaultValue?: string; // 기본값
|
2025-09-03 11:32:09 +09:00
|
|
|
|
autocomplete?: string;
|
|
|
|
|
|
spellcheck?: boolean;
|
2025-09-04 18:36:40 +09:00
|
|
|
|
multiline?: boolean; // 여러 줄 입력 여부
|
|
|
|
|
|
// 자동입력 관련 설정
|
|
|
|
|
|
autoInput?: boolean; // 자동입력 활성화
|
|
|
|
|
|
autoValueType?:
|
|
|
|
|
|
| "current_datetime"
|
|
|
|
|
|
| "current_date"
|
|
|
|
|
|
| "current_time"
|
|
|
|
|
|
| "current_user"
|
|
|
|
|
|
| "uuid"
|
|
|
|
|
|
| "sequence"
|
|
|
|
|
|
| "custom"; // 자동값 타입
|
|
|
|
|
|
customValue?: string; // 사용자 정의 값
|
2025-09-03 11:32:09 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 파일 타입 설정
|
|
|
|
|
|
export interface FileTypeConfig {
|
|
|
|
|
|
accept?: string; // MIME 타입 또는 확장자 (예: ".jpg,.png" 또는 "image/*")
|
|
|
|
|
|
multiple?: boolean;
|
|
|
|
|
|
maxSize?: number; // bytes
|
|
|
|
|
|
maxFiles?: number; // 다중 업로드 시 최대 파일 개수
|
|
|
|
|
|
preview?: boolean; // 미리보기 표시 여부
|
|
|
|
|
|
dragDrop?: boolean; // 드래그 앤 드롭 지원 여부
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 텍스트 영역 타입 설정
|
|
|
|
|
|
export interface TextareaTypeConfig extends TextTypeConfig {
|
|
|
|
|
|
rows?: number;
|
|
|
|
|
|
cols?: number;
|
|
|
|
|
|
resize?: "none" | "both" | "horizontal" | "vertical";
|
|
|
|
|
|
wrap?: "soft" | "hard" | "off";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 체크박스 타입 설정
|
|
|
|
|
|
export interface CheckboxTypeConfig {
|
|
|
|
|
|
defaultChecked?: boolean;
|
|
|
|
|
|
trueValue?: string | number | boolean; // 체크 시 값
|
|
|
|
|
|
falseValue?: string | number | boolean; // 미체크 시 값
|
|
|
|
|
|
indeterminate?: boolean; // 불확실한 상태 지원
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 라디오 타입 설정
|
|
|
|
|
|
export interface RadioTypeConfig {
|
|
|
|
|
|
options: Array<{ label: string; value: string; disabled?: boolean }>;
|
|
|
|
|
|
inline?: boolean; // 가로 배치 여부
|
|
|
|
|
|
defaultValue?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 코드 타입 설정 (공통코드 연계)
|
|
|
|
|
|
export interface CodeTypeConfig {
|
|
|
|
|
|
codeCategory: string; // 공통코드 카테고리
|
|
|
|
|
|
displayFormat?: "label" | "value" | "both"; // 표시 형식
|
|
|
|
|
|
searchable?: boolean;
|
|
|
|
|
|
placeholder?: string;
|
|
|
|
|
|
allowClear?: boolean;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 엔티티 타입 설정 (참조 테이블 연계)
|
|
|
|
|
|
export interface EntityTypeConfig {
|
|
|
|
|
|
referenceTable: string;
|
|
|
|
|
|
referenceColumn: string;
|
|
|
|
|
|
displayColumn?: string; // 표시할 컬럼명 (기본값: referenceColumn)
|
|
|
|
|
|
searchable?: boolean;
|
|
|
|
|
|
placeholder?: string;
|
|
|
|
|
|
allowClear?: boolean;
|
|
|
|
|
|
filters?: Record<string, any>; // 추가 필터 조건
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-04 11:33:52 +09:00
|
|
|
|
// 버튼 타입 설정
|
|
|
|
|
|
export interface ButtonTypeConfig {
|
|
|
|
|
|
actionType: ButtonActionType;
|
|
|
|
|
|
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";
|
|
|
|
|
|
icon?: string; // Lucide 아이콘 이름
|
|
|
|
|
|
confirmMessage?: string; // 확인 메시지 (delete, submit 등에서 사용)
|
|
|
|
|
|
|
2025-09-04 18:36:40 +09:00
|
|
|
|
// 모달 관련 설정
|
2025-09-04 11:33:52 +09:00
|
|
|
|
popupTitle?: string;
|
|
|
|
|
|
popupContent?: string;
|
2025-09-04 18:36:40 +09:00
|
|
|
|
popupScreenId?: number; // 모달로 열 화면 ID
|
2025-09-04 11:33:52 +09:00
|
|
|
|
|
|
|
|
|
|
// 네비게이션 관련 설정
|
2025-09-04 18:36:40 +09:00
|
|
|
|
navigateType?: "url" | "screen"; // 네비게이션 방식: URL 직접 입력 또는 화면 선택
|
2025-09-04 11:33:52 +09:00
|
|
|
|
navigateUrl?: string;
|
2025-09-04 18:36:40 +09:00
|
|
|
|
navigateScreenId?: number; // 이동할 화면 ID
|
2025-09-04 11:33:52 +09:00
|
|
|
|
navigateTarget?: "_self" | "_blank";
|
|
|
|
|
|
|
|
|
|
|
|
// 커스텀 액션 설정
|
|
|
|
|
|
customAction?: string; // JavaScript 코드 또는 함수명
|
|
|
|
|
|
|
|
|
|
|
|
// 스타일 설정
|
|
|
|
|
|
backgroundColor?: string;
|
|
|
|
|
|
textColor?: string;
|
|
|
|
|
|
borderColor?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-04 15:20:26 +09:00
|
|
|
|
// 화면 해상도 설정
|
|
|
|
|
|
export interface ScreenResolution {
|
|
|
|
|
|
width: number;
|
|
|
|
|
|
height: number;
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
category: "desktop" | "tablet" | "mobile" | "custom";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 미리 정의된 해상도 프리셋
|
|
|
|
|
|
export const SCREEN_RESOLUTIONS: ScreenResolution[] = [
|
|
|
|
|
|
// Desktop
|
|
|
|
|
|
{ width: 1920, height: 1080, name: "Full HD (1920×1080)", category: "desktop" },
|
|
|
|
|
|
{ width: 1366, height: 768, name: "HD (1366×768)", category: "desktop" },
|
|
|
|
|
|
{ width: 1440, height: 900, name: "WXGA+ (1440×900)", category: "desktop" },
|
|
|
|
|
|
{ width: 1280, height: 1024, name: "SXGA (1280×1024)", category: "desktop" },
|
|
|
|
|
|
|
|
|
|
|
|
// Tablet
|
|
|
|
|
|
{ width: 1024, height: 768, name: "iPad (1024×768)", category: "tablet" },
|
|
|
|
|
|
{ width: 768, height: 1024, name: "iPad Portrait (768×1024)", category: "tablet" },
|
|
|
|
|
|
{ width: 1112, height: 834, name: "iPad Pro 10.5 (1112×834)", category: "tablet" },
|
|
|
|
|
|
|
|
|
|
|
|
// Mobile
|
|
|
|
|
|
{ width: 375, height: 667, name: "iPhone SE (375×667)", category: "mobile" },
|
|
|
|
|
|
{ width: 414, height: 896, name: "iPhone 11 (414×896)", category: "mobile" },
|
|
|
|
|
|
{ width: 360, height: 640, name: "Android (360×640)", category: "mobile" },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
2025-09-03 11:32:09 +09:00
|
|
|
|
// 웹타입별 설정 유니온 타입
|
|
|
|
|
|
export type WebTypeConfig =
|
|
|
|
|
|
| DateTypeConfig
|
|
|
|
|
|
| NumberTypeConfig
|
|
|
|
|
|
| SelectTypeConfig
|
|
|
|
|
|
| TextTypeConfig
|
|
|
|
|
|
| FileTypeConfig
|
|
|
|
|
|
| TextareaTypeConfig
|
|
|
|
|
|
| CheckboxTypeConfig
|
|
|
|
|
|
| RadioTypeConfig
|
|
|
|
|
|
| CodeTypeConfig
|
2025-09-04 11:33:52 +09:00
|
|
|
|
| EntityTypeConfig
|
|
|
|
|
|
| ButtonTypeConfig;
|