화면간 데이터 전달기능 구현
This commit is contained in:
@@ -26,6 +26,15 @@ export interface ParentDataMapping {
|
||||
targetColumn: string; // 우측 화면 저장 시 사용할 컬럼명 (예: equipment_code)
|
||||
}
|
||||
|
||||
/**
|
||||
* 연결 필터 설정
|
||||
* 좌측 화면에서 선택한 데이터로 우측 화면의 테이블을 자동 필터링
|
||||
*/
|
||||
export interface LinkedFilter {
|
||||
sourceColumn: string; // 좌측 화면의 컬럼명 (예: equipment_code)
|
||||
targetColumn: string; // 우측 화면 필터링에 사용할 컬럼명 (예: equipment_code)
|
||||
}
|
||||
|
||||
/**
|
||||
* 분할 패널 컨텍스트 값
|
||||
*/
|
||||
@@ -73,6 +82,12 @@ interface SplitPanelContextValue {
|
||||
|
||||
// 🆕 매핑된 부모 데이터 가져오기 (우측 화면 저장 시 사용)
|
||||
getMappedParentData: () => Record<string, any>;
|
||||
|
||||
// 🆕 연결 필터 설정 (좌측 선택 → 우측 테이블 필터링)
|
||||
linkedFilters: LinkedFilter[];
|
||||
|
||||
// 🆕 연결 필터 값 가져오기 (우측 테이블 조회 시 사용)
|
||||
getLinkedFilterValues: () => Record<string, any>;
|
||||
}
|
||||
|
||||
const SplitPanelContext = createContext<SplitPanelContextValue | null>(null);
|
||||
@@ -82,6 +97,7 @@ interface SplitPanelProviderProps {
|
||||
leftScreenId: number | null;
|
||||
rightScreenId: number | null;
|
||||
parentDataMapping?: ParentDataMapping[]; // 🆕 부모 데이터 매핑 설정
|
||||
linkedFilters?: LinkedFilter[]; // 🆕 연결 필터 설정
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
@@ -93,6 +109,7 @@ export function SplitPanelProvider({
|
||||
leftScreenId,
|
||||
rightScreenId,
|
||||
parentDataMapping = [],
|
||||
linkedFilters = [],
|
||||
children,
|
||||
}: SplitPanelProviderProps) {
|
||||
// 좌측/우측 화면의 데이터 수신자 맵
|
||||
@@ -270,26 +287,68 @@ export function SplitPanelProvider({
|
||||
/**
|
||||
* 🆕 매핑된 부모 데이터 가져오기
|
||||
* 우측 화면에서 저장 시 이 함수를 호출하여 부모 키 값을 가져옴
|
||||
*
|
||||
* 동작 방식:
|
||||
* 1. 좌측 데이터의 모든 컬럼을 자동으로 전달 (동일한 컬럼명이면 자동 매핑)
|
||||
* 2. 명시적 매핑이 있으면 소스→타겟 변환 적용 (다른 컬럼명으로 매핑 시)
|
||||
*/
|
||||
const getMappedParentData = useCallback((): Record<string, any> => {
|
||||
if (!selectedLeftData || parentDataMapping.length === 0) {
|
||||
if (!selectedLeftData) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const mappedData: Record<string, any> = {};
|
||||
|
||||
// 1단계: 좌측 데이터의 모든 컬럼을 자동으로 전달 (동일 컬럼명 자동 매핑)
|
||||
for (const [key, value] of Object.entries(selectedLeftData)) {
|
||||
if (value !== undefined && value !== null) {
|
||||
mappedData[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// 2단계: 명시적 매핑이 있으면 추가 적용 (다른 컬럼명으로 변환)
|
||||
for (const mapping of parentDataMapping) {
|
||||
const value = selectedLeftData[mapping.sourceColumn];
|
||||
if (value !== undefined && value !== null) {
|
||||
mappedData[mapping.targetColumn] = value;
|
||||
logger.debug(`[SplitPanelContext] 부모 데이터 매핑: ${mapping.sourceColumn} → ${mapping.targetColumn} = ${value}`);
|
||||
// 소스와 타겟이 다른 경우에만 추가 매핑
|
||||
if (mapping.sourceColumn !== mapping.targetColumn) {
|
||||
mappedData[mapping.targetColumn] = value;
|
||||
logger.debug(`[SplitPanelContext] 명시적 매핑: ${mapping.sourceColumn} → ${mapping.targetColumn} = ${value}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`[SplitPanelContext] 매핑된 부모 데이터:`, mappedData);
|
||||
logger.info(`[SplitPanelContext] 매핑된 부모 데이터 (자동+명시적):`, {
|
||||
autoMappedKeys: Object.keys(selectedLeftData),
|
||||
explicitMappings: parentDataMapping.length,
|
||||
finalKeys: Object.keys(mappedData),
|
||||
});
|
||||
return mappedData;
|
||||
}, [selectedLeftData, parentDataMapping]);
|
||||
|
||||
/**
|
||||
* 🆕 연결 필터 값 가져오기
|
||||
* 우측 화면의 테이블 조회 시 이 값으로 필터링
|
||||
*/
|
||||
const getLinkedFilterValues = useCallback((): Record<string, any> => {
|
||||
if (!selectedLeftData || linkedFilters.length === 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const filterValues: Record<string, any> = {};
|
||||
|
||||
for (const filter of linkedFilters) {
|
||||
const value = selectedLeftData[filter.sourceColumn];
|
||||
if (value !== undefined && value !== null && value !== "") {
|
||||
filterValues[filter.targetColumn] = value;
|
||||
logger.debug(`[SplitPanelContext] 연결 필터: ${filter.sourceColumn} → ${filter.targetColumn} = ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`[SplitPanelContext] 연결 필터 값:`, filterValues);
|
||||
return filterValues;
|
||||
}, [selectedLeftData, linkedFilters]);
|
||||
|
||||
// 🆕 useMemo로 value 객체 메모이제이션 (무한 루프 방지)
|
||||
const value = React.useMemo<SplitPanelContextValue>(() => ({
|
||||
splitPanelId,
|
||||
@@ -310,6 +369,9 @@ export function SplitPanelProvider({
|
||||
setSelectedLeftData: handleSetSelectedLeftData,
|
||||
parentDataMapping,
|
||||
getMappedParentData,
|
||||
// 🆕 연결 필터 관련
|
||||
linkedFilters,
|
||||
getLinkedFilterValues,
|
||||
}), [
|
||||
splitPanelId,
|
||||
leftScreenId,
|
||||
@@ -327,6 +389,8 @@ export function SplitPanelProvider({
|
||||
handleSetSelectedLeftData,
|
||||
parentDataMapping,
|
||||
getMappedParentData,
|
||||
linkedFilters,
|
||||
getLinkedFilterValues,
|
||||
]);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user