ERP-node/frontend/types/component-events.ts

242 lines
6.6 KiB
TypeScript
Raw Normal View History

/**
* V2
*
* V2 .
* / .
*/
// ============================================================
// 이벤트 상세 데이터 타입 (event.detail)
// ============================================================
/**
*
* 발행: v2-table-list
* 구독: v2-aggregation-widget, v2-repeat-container
*/
export interface TableListDataChangeDetail {
componentId: string;
tableName: string;
data: any[];
selectedRows: string[] | number[];
}
/**
*
* 발행: v2-unified-repeater
* 구독: v2-aggregation-widget, v2-repeat-container
*/
export interface RepeaterDataChangeDetail {
componentId: string;
tableName: string;
data: any[];
selectedData?: any[];
}
/**
*
* 발행: buttonActions, UnifiedFormContext
* 구독: v2-unified-repeater, simple-repeater-table, modal-repeater-table
*/
export interface BeforeFormSaveDetail {
formData: Record<string, any>;
skipDefaultSave?: boolean;
}
/**
*
* 발행: UnifiedFormContext
* 구독: 저장
*/
export interface AfterFormSaveDetail {
success: boolean;
data?: any;
error?: string;
}
/**
* (- FK )
* 발행: InteractiveScreenViewerDynamic
* 구독: v2-unified-repeater
*/
export interface RepeaterSaveDetail {
parentId?: string | number;
masterRecordId: string | number;
mainFormData: Record<string, any>;
tableName: string;
}
/**
*
* 발행: v2-button-primary, buttonActions
* 구독: v2-table-list, v2-split-panel-layout
*/
export interface RefreshTableDetail {
tableName?: string;
componentId?: string;
}
/**
*
* 발행: buttonActions, InteractiveScreenViewerDynamic
* 구독: v2-card-display
*/
export interface RefreshCardDisplayDetail {
componentId?: string;
}
/**
*
* 발행: buttonActions
* 구독: v2-unified-repeater
*/
export interface ComponentDataTransferDetail {
sourceComponentId: string;
targetComponentId: string;
data: any[];
mode: "append" | "replace" | "merge";
mappingRules?: Array<{
sourceField: string;
targetField: string;
defaultValue?: any;
}>;
}
/**
*
* 발행: buttonActions
* 구독: v2-unified-repeater, repeater-field-group
*/
export interface SplitPanelDataTransferDetail {
sourcePosition: "left" | "right";
targetPosition: "left" | "right";
data: any[];
mode: "append" | "replace" | "merge";
mappingRules?: Array<{
sourceField: string;
targetField: string;
defaultValue?: any;
}>;
}
/**
*
* 발행: related-data-buttons
* 구독: v2-table-list
*/
export interface RelatedButtonSelectDetail {
targetTable: string;
filterColumn: string;
filterValue: any;
selectedData?: any;
}
/**
*
*/
export interface EditModalDetail {
screenId?: number;
recordId?: string | number;
data?: any;
}
// ============================================================
// 이벤트 이름 상수
// ============================================================
export const V2_EVENTS = {
// 데이터 변경 이벤트
TABLE_LIST_DATA_CHANGE: "tableListDataChange",
REPEATER_DATA_CHANGE: "repeaterDataChange",
// 폼 저장 이벤트
BEFORE_FORM_SAVE: "beforeFormSave",
AFTER_FORM_SAVE: "afterFormSave",
REPEATER_SAVE: "repeaterSave",
// UI 갱신 이벤트
REFRESH_TABLE: "refreshTable",
REFRESH_CARD_DISPLAY: "refreshCardDisplay",
// 데이터 전달 이벤트
COMPONENT_DATA_TRANSFER: "componentDataTransfer",
SPLIT_PANEL_DATA_TRANSFER: "splitPanelDataTransfer",
// 모달 제어 이벤트
OPEN_EDIT_MODAL: "openEditModal",
CLOSE_EDIT_MODAL: "closeEditModal",
SAVE_SUCCESS_IN_MODAL: "saveSuccessInModal",
// 연관 데이터 버튼 이벤트
RELATED_BUTTON_SELECT: "related-button-select",
RELATED_BUTTON_REGISTER: "related-button-register",
RELATED_BUTTON_UNREGISTER: "related-button-unregister",
} as const;
// ============================================================
// Window EventMap 확장 (타입 안전한 이벤트 리스너)
// ============================================================
declare global {
interface WindowEventMap {
// 데이터 변경 이벤트
[V2_EVENTS.TABLE_LIST_DATA_CHANGE]: CustomEvent<TableListDataChangeDetail>;
[V2_EVENTS.REPEATER_DATA_CHANGE]: CustomEvent<RepeaterDataChangeDetail>;
// 폼 저장 이벤트
[V2_EVENTS.BEFORE_FORM_SAVE]: CustomEvent<BeforeFormSaveDetail>;
[V2_EVENTS.AFTER_FORM_SAVE]: CustomEvent<AfterFormSaveDetail>;
[V2_EVENTS.REPEATER_SAVE]: CustomEvent<RepeaterSaveDetail>;
// UI 갱신 이벤트
[V2_EVENTS.REFRESH_TABLE]: CustomEvent<RefreshTableDetail>;
[V2_EVENTS.REFRESH_CARD_DISPLAY]: CustomEvent<RefreshCardDisplayDetail>;
// 데이터 전달 이벤트
[V2_EVENTS.COMPONENT_DATA_TRANSFER]: CustomEvent<ComponentDataTransferDetail>;
[V2_EVENTS.SPLIT_PANEL_DATA_TRANSFER]: CustomEvent<SplitPanelDataTransferDetail>;
// 연관 데이터 버튼 이벤트
[V2_EVENTS.RELATED_BUTTON_SELECT]: CustomEvent<RelatedButtonSelectDetail>;
}
}
// ============================================================
// 유틸리티 함수
// ============================================================
/**
*
*/
export function dispatchV2Event<K extends keyof WindowEventMap>(
eventName: K,
detail: WindowEventMap[K] extends CustomEvent<infer D> ? D : never
): void {
if (typeof window !== "undefined") {
window.dispatchEvent(new CustomEvent(eventName, { detail }));
}
}
/**
*
*/
export function subscribeV2Event<K extends keyof WindowEventMap>(
eventName: K,
handler: (event: WindowEventMap[K]) => void
): () => void {
if (typeof window === "undefined") {
return () => {};
}
window.addEventListener(eventName, handler as EventListener);
return () => {
window.removeEventListener(eventName, handler as EventListener);
};
}
// ============================================================
// 내보내기
// ============================================================
export type V2EventName = typeof V2_EVENTS[keyof typeof V2_EVENTS];