ERP-node/frontend/types/screen.ts

617 lines
17 KiB
TypeScript

// 화면관리 시스템 타입 정의
// 기본 컴포넌트 타입
export type ComponentType = "container" | "row" | "column" | "widget" | "group" | "datatable";
// 웹 타입 정의
export type WebType =
| "text"
| "number"
| "date"
| "code"
| "entity"
| "textarea"
| "select"
| "checkbox"
| "radio"
| "file"
| "email"
| "tel"
| "datetime"
| "dropdown"
| "text_area"
| "boolean"
| "decimal";
// 위치 정보
export interface Position {
x: number;
y: number;
z?: number; // z-index (레이어 순서)
}
// 크기 정보
export interface Size {
width: number; // 1-12 그리드
height: number; // 픽셀
}
// 테이블 정보
export interface TableInfo {
tableName: string;
tableLabel: string;
columns: ColumnInfo[];
}
// 스타일 관련 타입
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;
// 라벨 스타일
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; // 라벨 모서리 둥글기
}
// BaseComponent에 스타일 속성 추가
export interface BaseComponent {
id: string;
type: ComponentType;
position: Position;
size: { width: number; height: number };
parentId?: string;
style?: ComponentStyle; // 스타일 속성 추가
tableName?: string; // 테이블명 추가
label?: string; // 라벨 추가
gridColumns?: number; // 그리드에서 차지할 컬럼 수 (1-12)
}
// 컨테이너 컴포넌트
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 목록
}
// 위젯 컴포넌트
export interface WidgetComponent extends BaseComponent {
type: "widget";
tableName: string;
columnName: string;
widgetType: WebType;
label: string;
placeholder?: string;
required: boolean;
readonly: boolean;
validationRules?: ValidationRule[];
displayProperties?: Record<string, any>; // 레거시 지원용 (향후 제거 예정)
webTypeConfig?: WebTypeConfig; // 웹타입별 상세 설정
}
// 데이터 테이블 컬럼 설정
export interface DataTableColumn {
id: string;
columnName: string; // 실제 DB 컬럼명
label: string; // 화면에 표시될 라벨
widgetType: WebType; // 컬럼의 데이터 타입
gridColumns: number; // 그리드에서 차지할 컬럼 수 (1-12)
visible: boolean; // 테이블에 표시할지 여부
filterable: boolean; // 필터링 가능 여부
sortable: boolean; // 정렬 가능 여부
searchable: boolean; // 검색 대상 여부
webTypeConfig?: WebTypeConfig; // 컬럼별 상세 설정
}
// 데이터 테이블 필터 설정
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; // 처음/마지막 버튼 표시 여부
}
// 필드 자동 값 타입
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; // 취소 버튼 텍스트
}
// 데이터 테이블 컴포넌트
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; // 새로고침 기능 활성화
enableAdd: boolean; // 데이터 추가 기능 활성화
enableEdit: boolean; // 데이터 수정 기능 활성화
enableDelete: boolean; // 데이터 삭제 기능 활성화
addButtonText: string; // 추가 버튼 텍스트
editButtonText: string; // 수정 버튼 텍스트
deleteButtonText: string; // 삭제 버튼 텍스트
addModalConfig: DataTableAddModalConfig; // 추가 모달 커스터마이징 설정
gridColumns: number; // 테이블이 차지할 그리드 컬럼 수
}
// 컴포넌트 유니온 타입
export type ComponentData =
| ContainerComponent
| GroupComponent
| RowComponent
| ColumnComponent
| WidgetComponent
| DataTableComponent;
// 레이아웃 데이터
export interface LayoutData {
components: ComponentData[];
gridSettings?: GridSettings;
}
// 그리드 설정
export interface GridSettings {
columns: number; // 기본값: 12
gap: number; // 기본값: 16px
padding: number; // 기본값: 16px
snapToGrid?: boolean; // 격자에 맞춤 여부 (기본값: true)
showGrid?: boolean; // 격자 표시 여부 (기본값: true)
gridColor?: string; // 격자 색상 (기본값: #d1d5db)
gridOpacity?: number; // 격자 투명도 (기본값: 0.5)
}
// 유효성 검증 규칙
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;
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;
}
// 화면 수정 요청
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[];
groupTarget?: string | null;
groupMode?: "create" | "add" | "remove" | "ungroup";
groupTitle?: string;
groupStyle?: ComponentStyle;
}
// 그룹화 작업 타입
export interface GroupingAction {
type: "create" | "add" | "remove" | "ungroup";
componentIds: string[];
groupId?: string;
groupTitle?: string;
groupStyle?: ComponentStyle;
}
// 컬럼 정보 (테이블 타입관리 연계용)
export interface ColumnInfo {
tableName: string;
columnName: string;
columnLabel?: string;
dataType: string;
webType?: WebType;
widgetType?: WebType; // 프론트엔드에서 사용하는 필드 (webType과 동일)
isNullable: string;
required?: boolean; // isNullable에서 변환된 필드
columnDefault?: string;
characterMaximumLength?: number;
numericPrecision?: number;
numericScale?: number;
detailSettings?: string; // JSON 문자열
codeCategory?: string;
referenceTable?: string;
referenceColumn?: string;
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;
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;
}
// ===== 웹타입별 상세 설정 인터페이스 =====
// 날짜/시간 타입 설정
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";
placeholder?: string;
autocomplete?: string;
spellcheck?: boolean;
}
// 파일 타입 설정
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 type WebTypeConfig =
| DateTypeConfig
| NumberTypeConfig
| SelectTypeConfig
| TextTypeConfig
| FileTypeConfig
| TextareaTypeConfig
| CheckboxTypeConfig
| RadioTypeConfig
| CodeTypeConfig
| EntityTypeConfig;