feat: 중첩 구조 지원을 위한 컴포넌트 선택 및 기본값 적용 기능 추가
- ScreenManagementService에서 company_code 저장 로직을 개선하여 SUPER_ADMIN의 경우 화면 정의에 따라 company_code를 저장하도록 수정하였습니다. - ScreenDesigner에서 중첩 구조를 지원하는 탭 내부 컴포넌트 선택 상태 및 핸들러를 추가하였습니다. - SplitPanelLayoutComponent에서 분할 패널 내부 컴포넌트의 기본값을 재귀적으로 적용하는 헬퍼 함수를 구현하였습니다. - TimelineSchedulerConfigPanel에서 필드 매핑 업데이트 로직을 개선하여 이전 형식과 새 형식을 모두 지원하도록 하였습니다. - useTimelineData 훅에서 필드 매핑을 JSON 문자열로 안정화하여 객체 참조 변경 방지를 위한 메모이제이션을 적용하였습니다.
This commit is contained in:
@@ -67,10 +67,38 @@ export function useTimelineData(
|
||||
|
||||
const resourceTableName = config.resourceTable;
|
||||
|
||||
// 필드 매핑
|
||||
const fieldMapping = config.fieldMapping || defaultTimelineSchedulerConfig.fieldMapping!;
|
||||
const resourceFieldMapping =
|
||||
config.resourceFieldMapping || defaultTimelineSchedulerConfig.resourceFieldMapping!;
|
||||
// 필드 매핑을 JSON 문자열로 안정화 (객체 참조 변경 방지)
|
||||
const fieldMappingKey = useMemo(() => {
|
||||
return JSON.stringify(config.fieldMapping || {});
|
||||
}, [config.fieldMapping]);
|
||||
|
||||
const resourceFieldMappingKey = useMemo(() => {
|
||||
return JSON.stringify(config.resourceFieldMapping || {});
|
||||
}, [config.resourceFieldMapping]);
|
||||
|
||||
// 🆕 필드 매핑 정규화 (이전 형식 → 새 형식 변환) - useMemo로 메모이제이션
|
||||
const fieldMapping = useMemo(() => {
|
||||
const mapping = config.fieldMapping;
|
||||
if (!mapping) return defaultTimelineSchedulerConfig.fieldMapping!;
|
||||
|
||||
return {
|
||||
id: mapping.id || mapping.idField || "id",
|
||||
resourceId: mapping.resourceId || mapping.resourceIdField || "resource_id",
|
||||
title: mapping.title || mapping.titleField || "title",
|
||||
startDate: mapping.startDate || mapping.startDateField || "start_date",
|
||||
endDate: mapping.endDate || mapping.endDateField || "end_date",
|
||||
status: mapping.status || mapping.statusField || undefined,
|
||||
progress: mapping.progress || mapping.progressField || undefined,
|
||||
color: mapping.color || mapping.colorField || undefined,
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [fieldMappingKey]);
|
||||
|
||||
// 리소스 필드 매핑 - useMemo로 메모이제이션
|
||||
const resourceFieldMapping = useMemo(() => {
|
||||
return config.resourceFieldMapping || defaultTimelineSchedulerConfig.resourceFieldMapping!;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [resourceFieldMappingKey]);
|
||||
|
||||
// 스케줄 데이터 로드
|
||||
const fetchSchedules = useCallback(async () => {
|
||||
@@ -125,13 +153,10 @@ export function useTimelineData(
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [
|
||||
tableName,
|
||||
externalSchedules,
|
||||
fieldMapping,
|
||||
viewStartDate,
|
||||
viewEndDate,
|
||||
]);
|
||||
// fieldMappingKey를 의존성으로 사용하여 객체 참조 변경 방지
|
||||
// viewStartDate, viewEndDate는 API 호출에 사용되지 않으므로 제거
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [tableName, externalSchedules, fieldMappingKey]);
|
||||
|
||||
// 리소스 데이터 로드
|
||||
const fetchResources = useCallback(async () => {
|
||||
@@ -173,7 +198,9 @@ export function useTimelineData(
|
||||
console.error("리소스 로드 오류:", err);
|
||||
setResources([]);
|
||||
}
|
||||
}, [resourceTableName, externalResources, resourceFieldMapping]);
|
||||
// resourceFieldMappingKey를 의존성으로 사용하여 객체 참조 변경 방지
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [resourceTableName, externalResources, resourceFieldMappingKey]);
|
||||
|
||||
// 초기 로드
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user