/** * UnifiedRepeater 컴포넌트 타입 정의 * * 렌더링 모드: * - inline: 현재 테이블 컬럼 직접 입력 (simple-repeater-table) * - modal: 소스 테이블에서 검색/선택 후 복사 (modal-repeater-table) * - mixed: inline + modal 혼합 */ // 렌더링 모드 export type RepeaterRenderMode = "inline" | "modal"; // 모달 크기 export type ModalSize = "sm" | "md" | "lg" | "xl" | "full"; // 컬럼 너비 옵션 export type ColumnWidthOption = "auto" | "60px" | "80px" | "100px" | "120px" | "150px" | "200px" | "250px" | "300px"; // 컬럼 설정 export interface RepeaterColumnConfig { key: string; title: string; width: ColumnWidthOption; visible: boolean; editable?: boolean; // 편집 가능 여부 (inline 모드) isJoinColumn?: boolean; sourceTable?: string; // 입력 타입 (테이블 타입 관리의 inputType을 따름) inputType?: string; // text, number, date, code, entity 등 // 입력 타입별 상세 설정 detailSettings?: { codeGroup?: string; // code 타입용 referenceTable?: string; // entity 타입용 referenceColumn?: string; displayColumn?: string; format?: string; // date, number 타입용 }; } // 모달 표시 컬럼 (라벨 포함) export interface ModalDisplayColumn { key: string; label: string; } // 모달 설정 export interface RepeaterModalConfig { // 기본 설정 size: ModalSize; title?: string; // 모달 제목 buttonText?: string; // 검색 버튼 텍스트 // 소스 테이블 표시 설정 (modal 모드) sourceDisplayColumns?: ModalDisplayColumn[]; // 모달에 표시할 소스 테이블 컬럼 (라벨 포함) searchFields?: string[]; // 검색에 사용할 필드 // 화면 기반 모달 (옵션) screenId?: number; titleTemplate?: { prefix?: string; columnKey?: string; suffix?: string; }; } // 기능 옵션 export interface RepeaterFeatureOptions { showAddButton: boolean; showDeleteButton: boolean; inlineEdit: boolean; dragSort: boolean; showRowNumber: boolean; selectable: boolean; multiSelect: boolean; } // 데이터 소스 설정 export interface RepeaterDataSource { // inline 모드: 현재 테이블 설정은 필요 없음 (컬럼만 선택) // modal 모드: 소스 테이블 설정 sourceTable?: string; // 검색할 테이블 (엔티티 참조 테이블) foreignKey?: string; // 현재 테이블의 FK 컬럼 (part_objid 등) referenceKey?: string; // 소스 테이블의 PK 컬럼 (id 등) displayColumn?: string; // 표시할 컬럼 (item_name 등) // 추가 필터 filter?: { column: string; value: string; }; } // 컬럼 매핑 (modal 모드에서 소스→타겟 복사용) export interface ColumnMapping { sourceColumn: string; targetColumn: string; transform?: "copy" | "reference"; // copy: 값 복사, reference: ID 참조 } // 계산 규칙 export interface CalculationRule { id: string; targetColumn: string; formula: string; // 예: "quantity * unit_price" label?: string; } // 메인 설정 타입 export interface UnifiedRepeaterConfig { // 렌더링 모드 renderMode: RepeaterRenderMode; // 데이터 소스 설정 dataSource: RepeaterDataSource; // 컬럼 설정 (inline: 입력 컬럼, modal: 표시 컬럼) columns: RepeaterColumnConfig[]; // 컬럼 매핑 (modal 모드) columnMappings?: ColumnMapping[]; // 계산 규칙 (modal 모드) calculationRules?: CalculationRule[]; // 모달 설정 (modal, mixed 모드) modal?: RepeaterModalConfig; // 기능 옵션 features: RepeaterFeatureOptions; // 스타일 style?: { maxHeight?: string; minHeight?: string; borderless?: boolean; compact?: boolean; }; } // 컴포넌트 Props export interface UnifiedRepeaterProps { config: UnifiedRepeaterConfig; parentId?: string | number; // 부모 레코드 ID data?: any[]; // 초기 데이터 (없으면 API로 로드) onDataChange?: (data: any[]) => void; onRowClick?: (row: any) => void; className?: string; } // 기본 설정값 export const DEFAULT_REPEATER_CONFIG: UnifiedRepeaterConfig = { renderMode: "inline", dataSource: {}, columns: [], modal: { size: "lg", sourceDisplayColumns: [], searchFields: [], }, features: { showAddButton: true, showDeleteButton: true, inlineEdit: true, dragSort: false, showRowNumber: false, selectable: false, multiSelect: true, }, }; // 고정 옵션들 (콤보박스용) export const RENDER_MODE_OPTIONS = [ { value: "inline", label: "인라인 (직접 입력)" }, { value: "modal", label: "모달 (검색 선택)" }, ] as const; export const MODAL_SIZE_OPTIONS = [ { value: "sm", label: "작게 (sm)" }, { value: "md", label: "중간 (md)" }, { value: "lg", label: "크게 (lg)" }, { value: "xl", label: "매우 크게 (xl)" }, { value: "full", label: "전체 화면" }, ] as const; export const COLUMN_WIDTH_OPTIONS = [ { value: "auto", label: "자동" }, { value: "60px", label: "60px" }, { value: "80px", label: "80px" }, { value: "100px", label: "100px" }, { value: "120px", label: "120px" }, { value: "150px", label: "150px" }, { value: "200px", label: "200px" }, { value: "250px", label: "250px" }, { value: "300px", label: "300px" }, ] as const;