"use client"; import React, { useState, useCallback, useEffect } from "react"; import { DashboardElement, ChartDataSource, QueryResult, ListWidgetConfig } from "../types"; import { X } from "lucide-react"; import { cn } from "@/lib/utils"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { DatabaseConfig } from "../data-sources/DatabaseConfig"; import { ApiConfig } from "../data-sources/ApiConfig"; import { QueryEditor } from "../QueryEditor"; import { UnifiedColumnEditor } from "./list-widget/UnifiedColumnEditor"; import { ListTableOptions } from "./list-widget/ListTableOptions"; interface ListWidgetConfigSidebarProps { element: DashboardElement; isOpen: boolean; onClose: () => void; onApply: (element: DashboardElement) => void; } /** * 리스트 위젯 설정 사이드바 */ export function ListWidgetConfigSidebar({ element, isOpen, onClose, onApply }: ListWidgetConfigSidebarProps) { const [title, setTitle] = useState(element.title || "📋 리스트"); const [dataSource, setDataSource] = useState( element.dataSource || { type: "database", connectionType: "current", refreshInterval: 0 }, ); const [queryResult, setQueryResult] = useState(null); const [listConfig, setListConfig] = useState( element.listConfig || { viewMode: "table", columns: [], pageSize: 10, enablePagination: true, showHeader: true, stripedRows: true, compactMode: false, cardColumns: 3, }, ); // 사이드바 열릴 때 초기화 useEffect(() => { if (isOpen) { setTitle(element.title || "📋 리스트"); if (element.dataSource) { setDataSource(element.dataSource); } if (element.listConfig) { setListConfig(element.listConfig); } } }, [isOpen, element]); // Esc 키로 닫기 useEffect(() => { if (!isOpen) return; const handleEsc = (e: KeyboardEvent) => { if (e.key === "Escape") { onClose(); } }; window.addEventListener("keydown", handleEsc); return () => window.removeEventListener("keydown", handleEsc); }, [isOpen, onClose]); // 데이터 소스 타입 변경 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); }, []); // 데이터 소스 업데이트 const handleDataSourceUpdate = useCallback((updates: Partial) => { setDataSource((prev) => ({ ...prev, ...updates })); }, []); // 쿼리 실행 결과 처리 const handleQueryTest = useCallback((result: QueryResult) => { setQueryResult(result); // 쿼리 실행 시마다 컬럼 설정 초기화 (새로운 쿼리 결과로 덮어쓰기) const newColumns = result.columns.map((col, idx) => ({ id: `col_${Date.now()}_${idx}`, field: col, label: col, visible: true, align: "left" as const, })); setListConfig((prev) => ({ ...prev, columns: newColumns, })); }, []); // 컬럼 설정 변경 const handleListConfigChange = useCallback((updates: Partial) => { setListConfig((prev) => ({ ...prev, ...updates })); }, []); // 적용 const handleApply = useCallback(() => { const updatedElement: DashboardElement = { ...element, title, dataSource, listConfig, }; onApply(updatedElement); }, [element, title, dataSource, listConfig, onApply]); // 저장 가능 여부 const canApply = listConfig.columns.length > 0 && listConfig.columns.some((col) => col.visible && col.field); return (
{/* 헤더 */}
📋
리스트 위젯 설정
{/* 본문: 스크롤 가능 영역 */}
{/* 기본 설정 */}
기본 설정
setTitle(e.target.value)} onKeyDown={(e) => e.stopPropagation()} placeholder="리스트 이름" className="focus:border-primary focus:ring-primary/20 h-8 w-full rounded border border-border bg-muted px-2 text-xs placeholder:text-muted-foreground focus:bg-background focus:ring-1 focus:outline-none" />
{/* 데이터 소스 */}
데이터 소스
handleDataSourceTypeChange(value as "database" | "api")} className="w-full" > 데이터베이스 REST API {/* 데이터 로드 상태 */} {queryResult && (
{queryResult.rows.length}개 데이터 로드됨
)}
{/* 컬럼 설정 - 쿼리 실행 후에만 표시 */} {queryResult && (
컬럼 설정
)} {/* 테이블 옵션 - 컬럼이 있을 때만 표시 */} {listConfig.columns.length > 0 && (
테이블 옵션
)}
{/* 푸터: 적용 버튼 */}
); }