From cb2377b8d7fd2dc998586fefcd89d18d573de064 Mon Sep 17 00:00:00 2001 From: leeheejin Date: Wed, 15 Oct 2025 13:32:20 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9C=84=EC=A0=AF=20=EC=A0=84=EC=9A=A9=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=AA=A8=EB=8B=AC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=EC=B0=A8=ED=8A=B8=EC=99=80=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EC=97=AC=20=EC=B6=A9=EB=8F=8C=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 간단한 위젯(차량상태/목록, 배송/화물, 기사관리): 쿼리만으로 저장 가능 - 지도 위젯(차량위치지도): 위도/경도 매핑 패널 표시 - 차트: 기존 로직 유지 (차트 설정 필수) - 모달 z-index 9999로 상향 조정 --- .../admin/dashboard/ElementConfigModal.tsx | 136 ++++++++++++------ 1 file changed, 94 insertions(+), 42 deletions(-) diff --git a/frontend/components/admin/dashboard/ElementConfigModal.tsx b/frontend/components/admin/dashboard/ElementConfigModal.tsx index f069e477..9dca3f95 100644 --- a/frontend/components/admin/dashboard/ElementConfigModal.tsx +++ b/frontend/components/admin/dashboard/ElementConfigModal.tsx @@ -4,6 +4,7 @@ import React, { useState, useCallback, useEffect } from "react"; import { DashboardElement, ChartDataSource, ChartConfig, QueryResult } from "./types"; import { QueryEditor } from "./QueryEditor"; import { ChartConfigPanel } from "./ChartConfigPanel"; +import { VehicleMapConfigPanel } from "./VehicleMapConfigPanel"; import { DataSourceSelector } from "./data-sources/DataSourceSelector"; import { DatabaseConfig } from "./data-sources/DatabaseConfig"; import { ApiConfig } from "./data-sources/ApiConfig"; @@ -31,6 +32,17 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element const [chartConfig, setChartConfig] = useState(element.chartConfig || {}); const [queryResult, setQueryResult] = useState(null); const [currentStep, setCurrentStep] = useState<1 | 2>(1); + + // 차트 설정이 필요 없는 위젯 (쿼리/API만 필요) + const isSimpleWidget = + element.subtype === "vehicle-status" || + element.subtype === "vehicle-list" || + element.subtype === "delivery-status" || + element.subtype === "driver-management"; + + // 지도 위젯 (위도/경도 매핑 필요) + const isMapWidget = element.subtype === "vehicle-map"; + // 주석 // 모달이 열릴 때 초기화 useEffect(() => { @@ -118,21 +130,33 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element const isPieChart = element.subtype === "pie" || element.subtype === "donut"; const isApiSource = dataSource.type === "api"; - const canSave = - currentStep === 2 && - queryResult && - queryResult.rows.length > 0 && - chartConfig.xAxis && - (isPieChart || isApiSource - ? // 파이/도넛 차트 또는 REST API: Y축 또는 집계 함수 필요 - chartConfig.yAxis || - (Array.isArray(chartConfig.yAxis) && chartConfig.yAxis.length > 0) || - chartConfig.aggregation === "count" - : // 일반 차트 (DB): Y축 필수 - chartConfig.yAxis || (Array.isArray(chartConfig.yAxis) && chartConfig.yAxis.length > 0)); + const canSave = isSimpleWidget + ? // 간단한 위젯: 2단계에서 쿼리 테스트 후 저장 가능 + currentStep === 2 && + queryResult && + queryResult.rows.length > 0 + : isMapWidget + ? // 지도 위젯: 위도/경도 매핑 필요 + currentStep === 2 && + queryResult && + queryResult.rows.length > 0 && + chartConfig.latitudeColumn && + chartConfig.longitudeColumn + : // 차트: 기존 로직 (2단계에서 차트 설정 필요) + currentStep === 2 && + queryResult && + queryResult.rows.length > 0 && + chartConfig.xAxis && + (isPieChart || isApiSource + ? // 파이/도넛 차트 또는 REST API: Y축 또는 집계 함수 필요 + chartConfig.yAxis || + (Array.isArray(chartConfig.yAxis) && chartConfig.yAxis.length > 0) || + chartConfig.aggregation === "count" + : // 일반 차트 (DB): Y축 필수 + chartConfig.yAxis || (Array.isArray(chartConfig.yAxis) && chartConfig.yAxis.length > 0)); return ( -
+

{element.title} 설정

- {currentStep === 1 ? "데이터 소스를 선택하세요" : "쿼리를 실행하고 차트를 설정하세요"} + {isSimpleWidget + ? "데이터 소스를 설정하세요" + : currentStep === 1 + ? "데이터 소스를 선택하세요" + : "쿼리를 실행하고 차트를 설정하세요"}

- {/* 진행 상황 표시 */} -
-
-
- 단계 {currentStep} / 2: {currentStep === 1 ? "데이터 소스 선택" : "데이터 설정 및 차트 설정"} + {/* 진행 상황 표시 - 간단한 위젯은 표시 안 함 */} + {!isSimpleWidget && ( +
+
+
+ 단계 {currentStep} / 2: {currentStep === 1 ? "데이터 소스 선택" : "데이터 설정 및 차트 설정"} +
+ {Math.round((currentStep / 2) * 100)}% 완료
- {Math.round((currentStep / 2) * 100)}% 완료 +
- -
+ )} {/* 단계별 내용 */}
@@ -169,7 +199,7 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element )} {currentStep === 2 && ( -
+
{/* 왼쪽: 데이터 설정 */}
{dataSource.type === "database" ? ( @@ -186,24 +216,44 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element )}
- {/* 오른쪽: 차트 설정 */} -
- {queryResult && queryResult.rows.length > 0 ? ( - - ) : ( -
-
-
데이터를 가져온 후 차트 설정이 표시됩니다
-
-
- )} -
+ {/* 오른쪽: 설정 패널 */} + {!isSimpleWidget && ( +
+ {isMapWidget ? ( + // 지도 위젯: 위도/경도 매핑 패널 + queryResult && queryResult.rows.length > 0 ? ( + + ) : ( +
+
+
데이터를 가져온 후 지도 설정이 표시됩니다
+
+
+ ) + ) : ( + // 차트: 차트 설정 패널 + queryResult && queryResult.rows.length > 0 ? ( + + ) : ( +
+
+
데이터를 가져온 후 차트 설정이 표시됩니다
+
+
+ ) + )} +
+ )}
)}
@@ -219,7 +269,7 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element
- {currentStep > 1 && ( + {!isSimpleWidget && currentStep > 1 && ( {currentStep === 1 ? ( + // 1단계: 다음 버튼 (모든 타입 공통) ) : ( + // 2단계: 저장 버튼 (모든 타입 공통)