화면 분할패널 중간커밋
This commit is contained in:
116
frontend/contexts/ScreenContext.tsx
Normal file
116
frontend/contexts/ScreenContext.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* 화면 컨텍스트
|
||||
* 같은 화면 내의 컴포넌트들이 서로 통신할 수 있도록 합니다.
|
||||
*/
|
||||
|
||||
"use client";
|
||||
|
||||
import React, { createContext, useContext, useCallback, useRef } from "react";
|
||||
import type { DataProvidable, DataReceivable } from "@/types/data-transfer";
|
||||
import { logger } from "@/lib/utils/logger";
|
||||
|
||||
interface ScreenContextValue {
|
||||
screenId?: number;
|
||||
tableName?: string;
|
||||
|
||||
// 컴포넌트 등록
|
||||
registerDataProvider: (componentId: string, provider: DataProvidable) => void;
|
||||
unregisterDataProvider: (componentId: string) => void;
|
||||
registerDataReceiver: (componentId: string, receiver: DataReceivable) => void;
|
||||
unregisterDataReceiver: (componentId: string) => void;
|
||||
|
||||
// 컴포넌트 조회
|
||||
getDataProvider: (componentId: string) => DataProvidable | undefined;
|
||||
getDataReceiver: (componentId: string) => DataReceivable | undefined;
|
||||
|
||||
// 모든 컴포넌트 조회
|
||||
getAllDataProviders: () => Map<string, DataProvidable>;
|
||||
getAllDataReceivers: () => Map<string, DataReceivable>;
|
||||
}
|
||||
|
||||
const ScreenContext = createContext<ScreenContextValue | null>(null);
|
||||
|
||||
interface ScreenContextProviderProps {
|
||||
screenId?: number;
|
||||
tableName?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 화면 컨텍스트 프로바이더
|
||||
*/
|
||||
export function ScreenContextProvider({ screenId, tableName, children }: ScreenContextProviderProps) {
|
||||
const dataProvidersRef = useRef<Map<string, DataProvidable>>(new Map());
|
||||
const dataReceiversRef = useRef<Map<string, DataReceivable>>(new Map());
|
||||
|
||||
const registerDataProvider = useCallback((componentId: string, provider: DataProvidable) => {
|
||||
dataProvidersRef.current.set(componentId, provider);
|
||||
logger.debug("데이터 제공자 등록", { componentId, componentType: provider.componentType });
|
||||
}, []);
|
||||
|
||||
const unregisterDataProvider = useCallback((componentId: string) => {
|
||||
dataProvidersRef.current.delete(componentId);
|
||||
logger.debug("데이터 제공자 해제", { componentId });
|
||||
}, []);
|
||||
|
||||
const registerDataReceiver = useCallback((componentId: string, receiver: DataReceivable) => {
|
||||
dataReceiversRef.current.set(componentId, receiver);
|
||||
logger.debug("데이터 수신자 등록", { componentId, componentType: receiver.componentType });
|
||||
}, []);
|
||||
|
||||
const unregisterDataReceiver = useCallback((componentId: string) => {
|
||||
dataReceiversRef.current.delete(componentId);
|
||||
logger.debug("데이터 수신자 해제", { componentId });
|
||||
}, []);
|
||||
|
||||
const getDataProvider = useCallback((componentId: string) => {
|
||||
return dataProvidersRef.current.get(componentId);
|
||||
}, []);
|
||||
|
||||
const getDataReceiver = useCallback((componentId: string) => {
|
||||
return dataReceiversRef.current.get(componentId);
|
||||
}, []);
|
||||
|
||||
const getAllDataProviders = useCallback(() => {
|
||||
return new Map(dataProvidersRef.current);
|
||||
}, []);
|
||||
|
||||
const getAllDataReceivers = useCallback(() => {
|
||||
return new Map(dataReceiversRef.current);
|
||||
}, []);
|
||||
|
||||
const value: ScreenContextValue = {
|
||||
screenId,
|
||||
tableName,
|
||||
registerDataProvider,
|
||||
unregisterDataProvider,
|
||||
registerDataReceiver,
|
||||
unregisterDataReceiver,
|
||||
getDataProvider,
|
||||
getDataReceiver,
|
||||
getAllDataProviders,
|
||||
getAllDataReceivers,
|
||||
};
|
||||
|
||||
return <ScreenContext.Provider value={value}>{children}</ScreenContext.Provider>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 화면 컨텍스트 훅
|
||||
*/
|
||||
export function useScreenContext() {
|
||||
const context = useContext(ScreenContext);
|
||||
if (!context) {
|
||||
throw new Error("useScreenContext는 ScreenContextProvider 내부에서만 사용할 수 있습니다.");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* 화면 컨텍스트 훅 (선택적)
|
||||
* 컨텍스트가 없어도 에러를 발생시키지 않습니다.
|
||||
*/
|
||||
export function useScreenContextOptional() {
|
||||
return useContext(ScreenContext);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user