feat: V2 Core 및 이벤트 시스템 추가
- V2 Core 라이브러리를 추가하여 느슨한 결합 아키텍처를 지원합니다. - V2 EventBus를 통해 타입 안전한 이벤트 발행 및 구독 기능을 구현하였습니다. - V2ErrorBoundary 컴포넌트를 추가하여 각 컴포넌트의 에러를 격리하고, 사용자 정의 폴백 UI 및 재시도 기능을 제공합니다. - UnifiedRepeater 및 ButtonPrimaryComponent에서 V2 EventBus를 활용하여 이벤트 처리 로직을 개선하였습니다. - 레거시 이벤트와의 호환성을 위해 LegacyEventAdapter를 추가하여 점진적 마이그레이션을 지원합니다. - V2 컴포넌트 간의 통신을 위한 이벤트 타입을 정의하였습니다.
This commit is contained in:
@@ -27,6 +27,7 @@ import { useScreenContextOptional } from "@/contexts/ScreenContext";
|
||||
import { useSplitPanelContext, SplitPanelPosition } from "@/contexts/SplitPanelContext";
|
||||
import { applyMappingRules } from "@/lib/utils/dataMapping";
|
||||
import { apiClient } from "@/lib/api/client";
|
||||
import { V2ErrorBoundary, v2EventBus, V2_EVENTS } from "@/lib/v2-core";
|
||||
|
||||
export interface ButtonPrimaryComponentProps extends ComponentRendererProps {
|
||||
config?: ButtonPrimaryConfig;
|
||||
@@ -668,23 +669,32 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
|
||||
// 저장/수정 성공 시 자동 처리
|
||||
if (actionConfig.type === "save" || actionConfig.type === "edit") {
|
||||
if (typeof window !== "undefined") {
|
||||
// 1. 테이블 새로고침 이벤트 먼저 발송 (모달이 닫히기 전에)
|
||||
window.dispatchEvent(new CustomEvent("refreshTable"));
|
||||
// 1. 테이블 새로고침 이벤트 먼저 발송 (모달이 닫히기 전에)
|
||||
// V2 EventBus 사용 (레거시 어댑터가 자동으로 window 이벤트로도 브릿지)
|
||||
v2EventBus.emitSync(V2_EVENTS.TABLE_REFRESH, {
|
||||
tableName: context.tableName,
|
||||
target: "all",
|
||||
});
|
||||
|
||||
// 2. 모달 닫기 (약간의 딜레이)
|
||||
setTimeout(() => {
|
||||
// EditModal 내부인지 확인 (isInModal prop 사용)
|
||||
const isInEditModal = (props as any).isInModal;
|
||||
// 2. 모달 닫기 (약간의 딜레이)
|
||||
setTimeout(() => {
|
||||
// EditModal 내부인지 확인 (isInModal prop 사용)
|
||||
const isInEditModal = (props as any).isInModal;
|
||||
|
||||
if (isInEditModal) {
|
||||
window.dispatchEvent(new CustomEvent("closeEditModal"));
|
||||
}
|
||||
if (isInEditModal) {
|
||||
v2EventBus.emitSync(V2_EVENTS.MODAL_CLOSE, {
|
||||
modalId: "edit-modal",
|
||||
reason: "save",
|
||||
});
|
||||
}
|
||||
|
||||
// ScreenModal은 연속 등록 모드를 지원하므로 saveSuccessInModal 이벤트 발생
|
||||
window.dispatchEvent(new CustomEvent("saveSuccessInModal"));
|
||||
}, 100);
|
||||
}
|
||||
// ScreenModal은 연속 등록 모드를 지원하므로 saveSuccessInModal 이벤트 발생
|
||||
v2EventBus.emitSync(V2_EVENTS.MODAL_SAVE_SUCCESS, {
|
||||
modalId: "screen-modal",
|
||||
savedData: context.formData || {},
|
||||
tableName: context.tableName || "",
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
} catch (error) {
|
||||
// 로딩 토스트 제거
|
||||
@@ -1355,8 +1365,17 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||
|
||||
/**
|
||||
* ButtonPrimary 래퍼 컴포넌트
|
||||
* 추가적인 로직이나 상태 관리가 필요한 경우 사용
|
||||
* V2 ErrorBoundary로 감싸서 에러 격리 제공
|
||||
*/
|
||||
export const ButtonPrimaryWrapper: React.FC<ButtonPrimaryComponentProps> = (props) => {
|
||||
return <ButtonPrimaryComponent {...props} />;
|
||||
return (
|
||||
<V2ErrorBoundary
|
||||
componentId={props.component?.id || `button-${Date.now()}`}
|
||||
componentType="v2-button-primary"
|
||||
fallbackStyle="minimal"
|
||||
recoverable={true}
|
||||
>
|
||||
<ButtonPrimaryComponent {...props} />
|
||||
</V2ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user