ERP-node/frontend/lib/registry/DynamicConfigPanel.tsx

113 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, { useMemo } from "react";
import { WebTypeRegistry } from "./WebTypeRegistry";
import { WebTypeConfigPanelProps } from "./types";
/**
* 동적 설정 패널 렌더러 컴포넌트
* 레지스트리에서 웹타입을 조회하여 해당 설정 패널을 동적으로 렌더링합니다.
*/
export const DynamicConfigPanel: React.FC<
WebTypeConfigPanelProps & {
webType: string;
}
> = ({ webType, component, onUpdateComponent, onUpdateProperty }) => {
// 레지스트리에서 웹타입 정의 조회
const webTypeDefinition = useMemo(() => {
return WebTypeRegistry.getWebType(webType);
}, [webType]);
// 웹타입이 등록되지 않은 경우
if (!webTypeDefinition) {
console.warn(`웹타입 "${webType}"이 레지스트리에 등록되지 않았습니다.`);
return (
<div className="rounded-md border border-dashed border-red-300 bg-red-50 p-4">
<div className="flex items-center gap-2 text-red-600">
<span className="text-sm font-medium"> </span>
</div>
<p className="mt-1 text-xs text-red-500"> "{webType}" .</p>
</div>
);
}
// 설정 패널 컴포넌트가 없는 경우
if (!webTypeDefinition.configPanel) {
return (
<div className="rounded-md border border-dashed border-yellow-300 bg-yellow-50 p-4">
<div className="flex items-center gap-2 text-yellow-600">
<span className="text-sm font-medium"> </span>
</div>
<p className="mt-1 text-xs text-yellow-500"> "{webType}" .</p>
</div>
);
}
const ConfigPanelComponent = webTypeDefinition.configPanel;
// 설정 패널 props 구성
const configPanelProps: WebTypeConfigPanelProps = {
component,
onUpdateComponent,
onUpdateProperty,
};
try {
return <ConfigPanelComponent {...configPanelProps} />;
} catch (error) {
console.error(`웹타입 "${webType}" 설정 패널 렌더링 중 오류 발생:`, error);
return (
<div className="rounded-md border border-dashed border-red-300 bg-red-50 p-4">
<div className="flex items-center gap-2 text-red-600">
<span className="text-sm font-medium">💥 </span>
</div>
<p className="mt-1 text-xs text-red-500"> "{webType}" .</p>
{process.env.NODE_ENV === "development" && (
<pre className="mt-2 overflow-auto text-xs text-red-400">
{error instanceof Error ? error.stack : String(error)}
</pre>
)}
</div>
);
}
};
DynamicConfigPanel.displayName = "DynamicConfigPanel";
/**
* 웹타입별 설정 패널을 렌더링하는 헬퍼 함수
*/
export function renderConfigPanel(
webType: string,
component: any,
onUpdateComponent: (component: any) => void,
onUpdateProperty: (property: string, value: any) => void,
): React.ReactElement | null {
return (
<DynamicConfigPanel
webType={webType}
component={component}
onUpdateComponent={onUpdateComponent}
onUpdateProperty={onUpdateProperty}
/>
);
}
/**
* 웹타입이 설정 패널을 지원하는지 확인하는 헬퍼 함수
*/
export function hasConfigPanel(webType: string): boolean {
const webTypeDefinition = WebTypeRegistry.getWebType(webType);
return !!(webTypeDefinition && webTypeDefinition.configPanel);
}
/**
* 웹타입의 기본 설정을 가져오는 헬퍼 함수
*/
export function getDefaultConfig(webType: string): Record<string, any> | null {
const webTypeDefinition = WebTypeRegistry.getWebType(webType);
return webTypeDefinition ? webTypeDefinition.defaultConfig : null;
}