"use client"; import React, { useState, useCallback, useEffect } from "react"; import { DashboardElement, ChartDataSource, ChartConfig, QueryResult } from "./types"; import { QueryEditor } from "./QueryEditor"; import { ChartConfigPanel } from "./ChartConfigPanel"; import { DataSourceSelector } from "./data-sources/DataSourceSelector"; import { DatabaseConfig } from "./data-sources/DatabaseConfig"; import { ApiConfig } from "./data-sources/ApiConfig"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Progress } from "@/components/ui/progress"; import { X, ChevronLeft, ChevronRight, Save } from "lucide-react"; interface ElementConfigModalProps { element: DashboardElement; isOpen: boolean; onClose: () => void; onSave: (element: DashboardElement) => void; } /** * 요소 설정 모달 컴포넌트 (리팩토링) * - 2단계 플로우: 데이터 소스 선택 → 데이터 설정 및 차트 설정 * - 새로운 데이터 소스 컴포넌트 통합 */ export function ElementConfigModal({ element, isOpen, onClose, onSave }: ElementConfigModalProps) { const [dataSource, setDataSource] = useState( element.dataSource || { type: "database", connectionType: "current", refreshInterval: 0 }, ); const [chartConfig, setChartConfig] = useState(element.chartConfig || {}); const [queryResult, setQueryResult] = useState(null); const [currentStep, setCurrentStep] = useState<1 | 2>(1); // 주석 // 모달이 열릴 때 초기화 useEffect(() => { if (isOpen) { setDataSource(element.dataSource || { type: "database", connectionType: "current", refreshInterval: 0 }); setChartConfig(element.chartConfig || {}); setQueryResult(null); setCurrentStep(1); } }, [isOpen, element]); // 데이터 소스 타입 변경 const handleDataSourceTypeChange = useCallback((type: "database" | "api") => { if (type === "database") { setDataSource({ type: "database", connectionType: "current", refreshInterval: 0, }); } else { setDataSource({ type: "api", method: "GET", refreshInterval: 0, }); } // 데이터 소스 변경 시 쿼리 결과와 차트 설정 초기화 setQueryResult(null); setChartConfig({}); }, []); // 데이터 소스 업데이트 const handleDataSourceUpdate = useCallback((updates: Partial) => { setDataSource((prev) => ({ ...prev, ...updates })); }, []); // 차트 설정 변경 처리 const handleChartConfigChange = useCallback((newConfig: ChartConfig) => { setChartConfig(newConfig); }, []); // 쿼리 테스트 결과 처리 const handleQueryTest = useCallback((result: QueryResult) => { setQueryResult(result); }, []); // 다음 단계로 이동 const handleNext = useCallback(() => { if (currentStep === 1) { setCurrentStep(2); } }, [currentStep]); // 이전 단계로 이동 const handlePrev = useCallback(() => { if (currentStep > 1) { setCurrentStep((prev) => (prev - 1) as 1 | 2); } }, [currentStep]); // 저장 처리 const handleSave = useCallback(() => { const updatedElement: DashboardElement = { ...element, dataSource, chartConfig, }; onSave(updatedElement); onClose(); }, [element, dataSource, chartConfig, onSave, onClose]); // 모달이 열려있지 않으면 렌더링하지 않음 if (!isOpen) return null; // 시계, 달력, 기사관리 위젯은 자체 설정 UI를 가지고 있으므로 모달 표시하지 않음 if ( element.type === "widget" && (element.subtype === "clock" || element.subtype === "calendar" || element.subtype === "driver-management") ) { return null; } // 저장 가능 여부 확인 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)); return (
{/* 모달 헤더 */}

{element.title} 설정

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

{/* 진행 상황 표시 */}
단계 {currentStep} / 2: {currentStep === 1 ? "데이터 소스 선택" : "데이터 설정 및 차트 설정"}
{Math.round((currentStep / 2) * 100)}% 완료
{/* 단계별 내용 */}
{currentStep === 1 && ( )} {currentStep === 2 && (
{/* 왼쪽: 데이터 설정 */}
{dataSource.type === "database" ? ( <> ) : ( )}
{/* 오른쪽: 차트 설정 */}
{queryResult && queryResult.rows.length > 0 ? ( ) : (
데이터를 가져온 후 차트 설정이 표시됩니다
)}
)}
{/* 모달 푸터 */}
{queryResult && ( 📊 {queryResult.rows.length}개 데이터 로드됨 )}
{currentStep > 1 && ( )} {currentStep === 1 ? ( ) : ( )}
); }