From 6d9c7ed7bf09dea54920bee1f215160b3b6df280 Mon Sep 17 00:00:00 2001 From: dohyeons Date: Fri, 31 Oct 2025 14:07:02 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A7=80=EB=8F=84=EC=AA=BD=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=98=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/dashboard/WidgetConfigSidebar.tsx | 117 +++++++++++------- 1 file changed, 74 insertions(+), 43 deletions(-) diff --git a/frontend/components/admin/dashboard/WidgetConfigSidebar.tsx b/frontend/components/admin/dashboard/WidgetConfigSidebar.tsx index 4f2b14a5..4fb44de0 100644 --- a/frontend/components/admin/dashboard/WidgetConfigSidebar.tsx +++ b/frontend/components/admin/dashboard/WidgetConfigSidebar.tsx @@ -25,6 +25,7 @@ import { ChartConfigSection } from "./widget-sections/ChartConfigSection"; import { CustomMetricSection } from "./widget-sections/CustomMetricSection"; import { MapConfigSection } from "./widget-sections/MapConfigSection"; import { RiskAlertSection } from "./widget-sections/RiskAlertSection"; +import MultiDataSourceConfig from "@/components/admin/dashboard/data-sources/MultiDataSourceConfig"; interface WidgetConfigSidebarProps { element: DashboardElement | null; @@ -121,6 +122,9 @@ export function WidgetConfigSidebar({ element, isOpen, onClose, onApply }: Widge refreshInterval: 0, }); + // 다중 데이터 소스 상태 추가 + const [dataSources, setDataSources] = useState(element?.dataSources || []); + // 쿼리 결과 const [queryResult, setQueryResult] = useState(null); @@ -148,6 +152,7 @@ export function WidgetConfigSidebar({ element, isOpen, onClose, onApply }: Widge setCustomTitle(element.customTitle || ""); setShowHeader(element.showHeader !== false); setDataSource(element.dataSource || { type: "database", connectionType: "current", refreshInterval: 0 }); + setDataSources(element.dataSources || []); setQueryResult(null); // 리스트 위젯 설정 초기화 @@ -176,6 +181,7 @@ export function WidgetConfigSidebar({ element, isOpen, onClose, onApply }: Widge setCustomTitle(""); setShowHeader(true); setDataSource({ type: "database", connectionType: "current", refreshInterval: 0 }); + setDataSources([]); setQueryResult(null); setListConfig({ viewMode: "table", @@ -228,6 +234,11 @@ export function WidgetConfigSidebar({ element, isOpen, onClose, onApply }: Widge setDataSource((prev) => ({ ...prev, ...updates })); }, []); + // 다중 데이터 소스 변경 핸들러 + const handleDataSourcesChange = useCallback((updatedSources: ChartDataSource[]) => { + setDataSources(updatedSources); + }, []); + // 쿼리 테스트 결과 처리 const handleQueryTest = useCallback( (result: QueryResult) => { @@ -289,7 +300,7 @@ export function WidgetConfigSidebar({ element, isOpen, onClose, onApply }: Widge // 다중 데이터 소스 위젯은 dataSources도 포함 ...(isMultiDataSourceWidget ? { - dataSources: element.dataSources || [], + dataSources: dataSources.length > 0 ? dataSources : element.dataSources || [], } : {}), } @@ -307,12 +318,12 @@ export function WidgetConfigSidebar({ element, isOpen, onClose, onApply }: Widge ? { // 다중 데이터 소스 위젯은 chartConfig에 dataSources 포함 chartConfig: isMultiDataSourceWidget - ? { ...chartConfig, dataSources: element.dataSources || [] } + ? { ...chartConfig, dataSources: dataSources.length > 0 ? dataSources : element.dataSources || [] } : chartConfig, // 프론트엔드 호환성을 위해 dataSources도 element에 직접 포함 ...(isMultiDataSourceWidget ? { - dataSources: element.dataSources || [], + dataSources: dataSources.length > 0 ? dataSources : element.dataSources || [], } : {}), } @@ -327,7 +338,18 @@ export function WidgetConfigSidebar({ element, isOpen, onClose, onApply }: Widge onApply(updatedElement); onClose(); - }, [element, customTitle, showHeader, dataSource, listConfig, chartConfig, customMetricConfig, onApply, onClose]); + }, [ + element, + customTitle, + showHeader, + dataSource, + dataSources, + listConfig, + chartConfig, + customMetricConfig, + onApply, + onClose, + ]); if (!element) return null; @@ -408,48 +430,57 @@ export function WidgetConfigSidebar({ element, isOpen, onClose, onApply }: Widge {hasDataTab && (
- {/* 데이터 소스 선택 */} -
- + {/* 데이터 소스 선택 - 단일 데이터 소스 위젯에만 표시 */} + {!["map-summary-v2", "chart", "list-v2", "custom-metric-v2", "risk-alert-v2"].includes( + element.subtype, + ) && ( +
+ - handleDataSourceTypeChange(value as "database" | "api")} - className="w-full" - > - - - 데이터베이스 - - - REST API - - + handleDataSourceTypeChange(value as "database" | "api")} + className="w-full" + > + + + 데이터베이스 + + + REST API + + - - - - + + + + - - - - -
+ + + + +
+ )} + + {/* 다중 데이터 소스 설정 */} + {["map-summary-v2", "chart", "list-v2", "custom-metric-v2", "risk-alert-v2"].includes( + element.subtype, + ) && } {/* 위젯별 커스텀 섹션 */} {element.subtype === "list-v2" && (