ERP-node/frontend/types/component.ts

360 lines
10 KiB
TypeScript
Raw Normal View History

2025-09-11 18:38:28 +09:00
/**
*
*
*/
import React from "react";
import type { WebType } from "./screen";
/**
*
* enum으로
*/
export enum ComponentCategory {
UI = "ui", // 기본 UI 컴포넌트 (버튼, 입력 등)
INPUT = "input", // 입력 컴포넌트 (텍스트, 셀렉트, 체크박스 등)
DISPLAY = "display", // 표시 컴포넌트 (라벨, 이미지, 아이콘 등)
ACTION = "action", // 액션 컴포넌트 (버튼, 링크 등)
LAYOUT = "layout", // 레이아웃 컴포넌트 (컨테이너, 그룹 등)
CHART = "chart", // 차트 컴포넌트 (그래프, 차트 등)
FORM = "form", // 폼 컴포넌트 (폼 그룹, 필드셋 등)
MEDIA = "media", // 미디어 컴포넌트 (이미지, 비디오 등)
NAVIGATION = "navigation", // 네비게이션 컴포넌트 (메뉴, 탭 등)
FEEDBACK = "feedback", // 피드백 컴포넌트 (알림, 토스트 등)
UTILITY = "utility", // 유틸리티 컴포넌트 (로딩, 스피너 등)
CONTAINER = "container", // 컨테이너 컴포넌트 (패널, 카드 등)
SYSTEM = "system", // 시스템 컴포넌트 (에러 바운더리 등)
ADMIN = "admin", // 관리자 전용 컴포넌트
CUSTOM = "custom", // 커스텀 컴포넌트
}
/**
*
*
*/
export interface ComponentConfig {
[key: string]: any;
}
/**
*
*/
export interface ComponentSize {
width: number;
height: number;
}
/**
* Props
* Props
*/
export interface ComponentRendererProps {
component: any; // ComponentData from screen.ts
isDesignMode?: boolean;
isSelected?: boolean;
2025-09-12 14:24:25 +09:00
isInteractive?: boolean;
2025-09-11 18:38:28 +09:00
onClick?: () => void;
onDragStart?: (e: React.DragEvent) => void;
onDragEnd?: (e: React.DragEvent) => void;
onUpdate?: (updates: Partial<any>) => void;
className?: string;
style?: React.CSSProperties;
2025-09-12 14:24:25 +09:00
formData?: Record<string, any>;
onFormDataChange?: (fieldName: string, value: any) => void;
2025-09-11 18:38:28 +09:00
[key: string]: any;
}
/**
*
*/
export interface ComponentRendererClass {
new (props: ComponentRendererProps): {
render(): React.ReactElement;
};
componentDefinition: ComponentDefinition;
registerSelf(): void;
}
/**
*
*
*/
export interface ComponentDefinition {
// 기본 정보
id: string; // 고유 ID (kebab-case)
name: string; // 한글 표시명
nameEng?: string; // 영문명
description: string; // 설명
// 분류 및 타입
category: ComponentCategory; // 카테고리 (enum)
webType: WebType; // 웹 타입 (기존 WebType 재사용)
// React 컴포넌트
component: React.ComponentType<any>; // 실제 React 컴포넌트
renderer?: ComponentRendererClass; // 렌더러 클래스 (선택사항)
// 설정
defaultConfig: ComponentConfig; // 기본 설정값
defaultSize: ComponentSize; // 기본 크기
configPanel?: React.ComponentType<any>; // 설정 패널 컴포넌트
// UI 요소
icon?: React.ComponentType | string; // 아이콘 (컴포넌트 또는 문자열)
previewImage?: string; // 미리보기 이미지 URL
// 메타데이터
tags?: string[]; // 검색용 태그
version?: string; // 버전
author?: string; // 작성자
documentation?: string; // 문서 URL
// 검증 및 제약
validation?: ComponentValidation; // 유효성 검사 규칙
dependencies?: string[]; // 의존성 컴포넌트 ID
// 생성 정보
createdAt?: Date; // 생성일
updatedAt?: Date; // 수정일
}
/**
*
*/
export interface ComponentValidation {
required?: string[]; // 필수 속성들
minSize?: ComponentSize; // 최소 크기
maxSize?: ComponentSize; // 최대 크기
allowedParents?: string[]; // 허용되는 부모 컴포넌트 타입
allowedChildren?: string[]; // 허용되는 자식 컴포넌트 타입
maxLength?: { [field: string]: number }; // 필드별 최대 길이
pattern?: { [field: string]: RegExp }; // 필드별 정규식 패턴
custom?: (component: any) => string | null; // 커스텀 검증 함수
}
/**
*
*/
export interface ComponentRegistryEvent {
type: "component_registered" | "component_unregistered" | "component_updated";
data: ComponentDefinition;
timestamp: Date;
}
/**
*
*/
export interface ComponentSearchOptions {
query?: string; // 검색어
category?: ComponentCategory; // 카테고리 필터
webType?: WebType; // 웹타입 필터
tags?: string[]; // 태그 필터
author?: string; // 작성자 필터
limit?: number; // 결과 제한
offset?: number; // 시작 위치
}
/**
*
*/
export interface ComponentStats {
total: number; // 전체 컴포넌트 수
byCategory: Array<{
// 카테고리별 통계
category: ComponentCategory;
count: number;
}>;
byWebType: Array<{
// 웹타입별 통계
webType: WebType;
count: number;
}>;
byAuthor: Array<{
// 작성자별 통계
author: string;
count: number;
}>;
recentlyAdded: ComponentDefinition[]; // 최근 추가된 컴포넌트
}
/**
*
*/
export interface ComponentAutoDiscoveryOptions {
pattern?: string; // 파일 패턴
baseDir?: string; // 기본 디렉토리
verbose?: boolean; // 상세 로그
continueOnError?: boolean; // 오류 시 계속 진행
timeout?: number; // 타임아웃 (ms)
}
/**
*
*/
export interface ComponentDiscoveryResult {
success: boolean; // 성공 여부
componentsFound: number; // 발견된 컴포넌트 수
componentsLoaded: number; // 로드된 컴포넌트 수
errors: Error[]; // 발생한 오류들
duration: number; // 소요 시간 (ms)
details: ComponentModuleInfo[]; // 상세 정보
}
/**
*
*/
export interface ComponentModuleInfo {
path: string; // 파일 경로
id: string; // 컴포넌트 ID
name: string; // 컴포넌트 이름
loaded: boolean; // 로드 여부
error?: Error; // 오류 (있는 경우)
timestamp: number; // 타임스탬프
}
/**
* (CLI용)
*/
export interface CreateComponentOptions {
id: string; // 컴포넌트 ID
name: string; // 컴포넌트 이름
nameEng?: string; // 영문명
description: string; // 설명
category: ComponentCategory; // 카테고리
webType: WebType; // 웹타입
defaultSize: ComponentSize; // 기본 크기
author?: string; // 작성자
tags?: string[]; // 태그
icon?: string; // 아이콘
template?: string; // 템플릿 이름
}
/**
*
*/
export interface ComponentMigrationOptions {
componentCode: string; // 기존 컴포넌트 코드
newId: string; // 새 컴포넌트 ID
preserveConfig?: boolean; // 설정 보존 여부
updateReferences?: boolean; // 참조 업데이트 여부
dryRun?: boolean; // 테스트 실행 여부
}
/**
*
*/
export interface CreateComponentDefinitionOptions {
id: string;
name: string;
nameEng?: string;
description: string;
category: ComponentCategory;
webType: WebType;
component: React.ComponentType<any>;
renderer?: ComponentRendererClass;
defaultConfig?: ComponentConfig;
defaultSize: ComponentSize;
configPanel?: React.ComponentType<any>;
icon?: React.ComponentType | string;
previewImage?: string;
tags?: string[];
version?: string;
author?: string;
documentation?: string;
validation?: ComponentValidation;
dependencies?: string[];
}
/**
*
*/
export type ComponentId = string;
export type ComponentName = string;
export type ComponentCategoryKey = keyof typeof ComponentCategory;
/**
*
*/
export const DEFAULT_COMPONENT_SIZE: ComponentSize = {
width: 200,
height: 36,
};
export const COMPONENT_CATEGORIES_INFO = {
[ComponentCategory.UI]: {
name: "UI",
description: "기본 UI 컴포넌트",
color: "#3b82f6",
},
[ComponentCategory.INPUT]: {
name: "입력",
description: "사용자 입력을 받는 컴포넌트",
color: "#10b981",
},
[ComponentCategory.DISPLAY]: {
name: "표시",
description: "정보를 표시하는 컴포넌트",
color: "#f59e0b",
},
[ComponentCategory.ACTION]: {
name: "액션",
description: "사용자 동작을 처리하는 컴포넌트",
color: "#ef4444",
},
[ComponentCategory.LAYOUT]: {
name: "레이아웃",
description: "화면 구조를 제공하는 컴포넌트",
color: "#8b5cf6",
},
[ComponentCategory.CHART]: {
name: "차트",
description: "데이터 시각화 컴포넌트",
color: "#06b6d4",
},
[ComponentCategory.FORM]: {
name: "폼",
description: "폼 관련 컴포넌트",
color: "#84cc16",
},
[ComponentCategory.MEDIA]: {
name: "미디어",
description: "이미지, 비디오 등 미디어 컴포넌트",
color: "#f97316",
},
[ComponentCategory.NAVIGATION]: {
name: "네비게이션",
description: "화면 이동을 도와주는 컴포넌트",
color: "#6366f1",
},
[ComponentCategory.FEEDBACK]: {
name: "피드백",
description: "사용자 피드백을 제공하는 컴포넌트",
color: "#ec4899",
},
[ComponentCategory.UTILITY]: {
name: "유틸리티",
description: "보조 기능 컴포넌트",
color: "#6b7280",
},
[ComponentCategory.CONTAINER]: {
name: "컨테이너",
description: "다른 컴포넌트를 담는 컨테이너",
color: "#374151",
},
[ComponentCategory.SYSTEM]: {
name: "시스템",
description: "시스템 관련 컴포넌트",
color: "#1f2937",
},
[ComponentCategory.ADMIN]: {
name: "관리",
description: "관리자 전용 컴포넌트",
color: "#7c2d12",
},
[ComponentCategory.CUSTOM]: {
name: "커스텀",
description: "사용자 정의 컴포넌트",
color: "#059669",
},
} as const;