ERP-node/frontend/types/screen.ts

1003 lines
30 KiB
TypeScript
Raw Normal View History

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"
| "file"
| "email"
| "tel"
| "datetime"
| "dropdown"
| "text_area"
| "boolean"
| "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" // 페이지 이동
| "control"; // 제어 전용 (조건 체크만)
2025-09-01 11:48:12 +09:00
// 위치 정보
export interface Position {
x: number;
y: number;
z?: number; // z-index (레이어 순서)
2025-09-01 11:48:12 +09:00
}
// 크기 정보
export interface Size {
width: number; // 1-12 그리드
height: number; // 픽셀
}
// 테이블 정보
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 type AutoGenerationType =
| "uuid" // UUID 생성
| "current_user" // 현재 사용자 ID
| "current_time" // 현재 시간
| "sequence" // 시퀀스 번호
| "random_string" // 랜덤 문자열
| "random_number" // 랜덤 숫자
| "company_code" // 회사 코드
| "department" // 부서 코드
| "none"; // 자동생성 없음
// 자동생성 설정
export interface AutoGenerationConfig {
type: AutoGenerationType;
enabled: boolean;
options?: {
length?: number; // 랜덤 문자열/숫자 길이
prefix?: string; // 접두사
suffix?: string; // 접미사
format?: string; // 시간 형식 (current_time용)
startValue?: number; // 시퀀스 시작값
};
}
2025-09-01 11:48:12 +09:00
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; // 스타일 속성 추가
tableName?: string; // 테이블명 추가
label?: string; // 라벨 추가
2025-09-03 11:32:09 +09:00
gridColumns?: number; // 그리드에서 차지할 컬럼 수 (1-12)
inputType?: "direct" | "auto"; // 입력 타입 (직접입력/자동입력)
autoValueType?:
| "current_datetime"
| "current_date"
| "current_time"
| "current_user"
| "uuid"
| "sequence"
| "user_defined"; // 자동 값 타입 (레거시)
// 새로운 기능들
hidden?: boolean; // 숨김 기능 (편집기에서는 연하게, 실제 화면에서는 숨김)
autoGeneration?: AutoGenerationConfig; // 자동생성 설정
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 (계층 구조용)
// 테이블 연결 설정 (새로 추가)
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;
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-15 15:38:48 +09:00
// 레거시 지원용 (테이블 타입 관리에서 설정된 값)
codeCategory?: string; // 코드 카테고리 (코드 타입용)
referenceTable?: string; // 참조 테이블 (엔티티 타입용)
// 가상 파일 컬럼 관련 속성
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;
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과 동일)
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; // 정규식 패턴
format?: "none" | "email" | "phone" | "url" | "korean" | "english" | "alphanumeric" | "numeric";
2025-09-03 11:32:09 +09:00
placeholder?: string;
defaultValue?: string; // 기본값
2025-09-03 11:32:09 +09:00
autocomplete?: string;
spellcheck?: boolean;
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>; // 추가 필터 조건
}
// 버튼 타입 설정
export interface ButtonTypeConfig {
actionType: ButtonActionType;
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";
icon?: string; // Lucide 아이콘 이름
confirmMessage?: string; // 확인 메시지 (delete, submit 등에서 사용)
// 모달 관련 설정
popupTitle?: string;
popupContent?: string;
popupScreenId?: number; // 모달로 열 화면 ID
// 네비게이션 관련 설정
navigateType?: "url" | "screen"; // 네비게이션 방식: URL 직접 입력 또는 화면 선택
navigateUrl?: string;
navigateScreenId?: number; // 이동할 화면 ID
navigateTarget?: "_self" | "_blank";
// 커스텀 액션 설정
customAction?: string; // JavaScript 코드 또는 함수명
2025-09-18 10:05:50 +09:00
// 🔥 NEW: 제어관리 기능 추가
enableDataflowControl?: boolean; // 제어관리 활성화 여부
dataflowConfig?: ButtonDataflowConfig; // 제어관리 설정
dataflowTiming?: "before" | "after" | "replace"; // 실행 타이밍
// 스타일 설정
backgroundColor?: string;
textColor?: string;
borderColor?: string;
}
2025-09-18 10:05:50 +09:00
// 🔥 NEW: 버튼 데이터플로우 설정
export interface ButtonDataflowConfig {
// 제어 방식 선택
controlMode: "simple" | "advanced";
// Simple 모드: 기존 관계도 선택
selectedDiagramId?: number;
selectedRelationshipId?: string;
// Advanced 모드: 직접 조건 설정
directControl?: {
sourceTable: string;
triggerType: "insert" | "update" | "delete";
conditions: DataflowCondition[];
actions: DataflowAction[];
};
// 실행 옵션
executionOptions?: {
rollbackOnError?: boolean;
enableLogging?: boolean;
maxRetryCount?: number;
asyncExecution?: boolean;
};
}
// 데이터플로우 조건
export interface DataflowCondition {
id: string;
type: "condition" | "group-start" | "group-end";
field?: string;
operator?: "=" | "!=" | ">" | "<" | ">=" | "<=" | "LIKE";
value?: any;
dataType?: "string" | "number" | "boolean" | "date";
logicalOperator?: "AND" | "OR";
groupId?: string;
groupLevel?: number;
}
// 데이터플로우 액션
export interface DataflowAction {
id: string;
name: string;
actionType: "insert" | "update" | "delete" | "upsert";
targetTable: string;
conditions?: DataflowCondition[];
fieldMappings: DataflowFieldMapping[];
splitConfig?: {
sourceField: string;
delimiter: string;
targetField: string;
};
}
// 필드 매핑
export interface DataflowFieldMapping {
sourceTable?: string;
sourceField: string;
targetTable?: string;
targetField: string;
defaultValue?: string;
transformFunction?: string;
}
// 실행 결과
export interface DataflowExecutionResult {
success: boolean;
executedActions: number;
message?: string;
error?: string;
timing?: "before" | "after" | "replace";
originalActionResult?: any;
dataflowResult?: any;
}
// 화면 해상도 설정
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
| EntityTypeConfig
| ButtonTypeConfig;