ERP-node/frontend/lib/registry/useRegistry.ts

222 lines
5.8 KiB
TypeScript

"use client";
import { useState, useEffect, useCallback, useMemo } from "react";
import { WebTypeRegistry } from "./WebTypeRegistry";
import {
WebTypeDefinition,
ButtonActionDefinition,
UseRegistryReturn,
WebTypeFilterOptions,
ButtonActionFilterOptions,
} from "./types";
/**
* 레지스트리 관리를 위한 React 훅
*/
export function useRegistry(): UseRegistryReturn {
const [webTypes, setWebTypes] = useState<WebTypeDefinition[]>([]);
const [buttonActions, setButtonActions] = useState<ButtonActionDefinition[]>([]);
// 웹타입 목록 업데이트
const updateWebTypes = useCallback(() => {
setWebTypes(WebTypeRegistry.getAllWebTypes());
}, []);
// 버튼 액션 목록 업데이트
const updateButtonActions = useCallback(() => {
setButtonActions(WebTypeRegistry.getAllButtonActions());
}, []);
// 레지스트리 이벤트 구독
useEffect(() => {
// 초기 데이터 로드
updateWebTypes();
updateButtonActions();
// 이벤트 리스너 등록
const unsubscribe = WebTypeRegistry.subscribe((event) => {
if (event.type === "webtype_registered" || event.type === "webtype_unregistered") {
updateWebTypes();
} else if (event.type === "buttonaction_registered" || event.type === "buttonaction_unregistered") {
updateButtonActions();
}
});
return unsubscribe;
}, [updateWebTypes, updateButtonActions]);
// 웹타입 등록
const registerWebType = useCallback((definition: WebTypeDefinition) => {
WebTypeRegistry.registerWebType(definition);
}, []);
// 웹타입 등록 해제
const unregisterWebType = useCallback((id: string) => {
WebTypeRegistry.unregisterWebType(id);
}, []);
// 버튼 액션 등록
const registerButtonAction = useCallback((definition: ButtonActionDefinition) => {
WebTypeRegistry.registerButtonAction(definition);
}, []);
// 버튼 액션 등록 해제
const unregisterButtonAction = useCallback((id: string) => {
WebTypeRegistry.unregisterButtonAction(id);
}, []);
// 웹타입 조회
const getWebType = useCallback((id: string) => {
return WebTypeRegistry.getWebType(id);
}, []);
// 버튼 액션 조회
const getButtonAction = useCallback((id: string) => {
return WebTypeRegistry.getButtonAction(id);
}, []);
// 이벤트 구독
const subscribe = useCallback((callback: (event: any) => void) => {
return WebTypeRegistry.subscribe(callback);
}, []);
return {
webTypes,
buttonActions,
registerWebType,
unregisterWebType,
registerButtonAction,
unregisterButtonAction,
getWebType,
getButtonAction,
subscribe,
};
}
/**
* 필터링된 웹타입을 가져오는 훅
*/
export function useWebTypes(options: WebTypeFilterOptions = {}) {
const [webTypes, setWebTypes] = useState<WebTypeDefinition[]>([]);
const filteredWebTypes = useMemo(() => {
return WebTypeRegistry.getWebTypes(options);
}, [options]);
useEffect(() => {
const currentWebTypes = WebTypeRegistry.getWebTypes(options);
setWebTypes(currentWebTypes);
// 레지스트리 변경 감지
const unsubscribe = WebTypeRegistry.subscribe((event) => {
if (event.type === "webtype_registered" || event.type === "webtype_unregistered") {
setWebTypes(WebTypeRegistry.getWebTypes(options));
}
});
return unsubscribe;
}, [options]);
return webTypes;
}
/**
* 필터링된 버튼 액션을 가져오는 훅
*/
export function useButtonActions(options: ButtonActionFilterOptions = {}) {
const [buttonActions, setButtonActions] = useState<ButtonActionDefinition[]>([]);
const filteredButtonActions = useMemo(() => {
return WebTypeRegistry.getButtonActions(options);
}, [options]);
useEffect(() => {
setButtonActions(filteredButtonActions);
// 레지스트리 변경 감지
const unsubscribe = WebTypeRegistry.subscribe((event) => {
if (event.type === "buttonaction_registered" || event.type === "buttonaction_unregistered") {
setButtonActions(WebTypeRegistry.getButtonActions(options));
}
});
return unsubscribe;
}, [filteredButtonActions, options]);
return buttonActions;
}
/**
* 웹타입별로 그룹화된 데이터를 가져오는 훅
*/
export function useWebTypesByCategory() {
const [groupedWebTypes, setGroupedWebTypes] = useState<Record<string, WebTypeDefinition[]>>({});
useEffect(() => {
const updateGroupedWebTypes = () => {
setGroupedWebTypes(WebTypeRegistry.getWebTypesByCategory());
};
updateGroupedWebTypes();
// 레지스트리 변경 감지
const unsubscribe = WebTypeRegistry.subscribe((event) => {
if (event.type === "webtype_registered" || event.type === "webtype_unregistered") {
updateGroupedWebTypes();
}
});
return unsubscribe;
}, []);
return groupedWebTypes;
}
/**
* 레지스트리 상태 정보를 가져오는 훅
*/
export function useRegistryInfo() {
const [registryInfo, setRegistryInfo] = useState(WebTypeRegistry.getRegistryInfo());
useEffect(() => {
const updateRegistryInfo = () => {
setRegistryInfo(WebTypeRegistry.getRegistryInfo());
};
// 레지스트리 변경 감지
const unsubscribe = WebTypeRegistry.subscribe(() => {
updateRegistryInfo();
});
return unsubscribe;
}, []);
return registryInfo;
}
/**
* 특정 웹타입의 존재 여부를 확인하는 훅
*/
export function useWebTypeExists(webTypeId: string) {
const [exists, setExists] = useState(false);
useEffect(() => {
const checkExists = () => {
setExists(WebTypeRegistry.hasWebType(webTypeId));
};
checkExists();
// 레지스트리 변경 감지
const unsubscribe = WebTypeRegistry.subscribe((event) => {
if (event.type === "webtype_registered" || event.type === "webtype_unregistered") {
checkExists();
}
});
return unsubscribe;
}, [webTypeId]);
return exists;
}