import type React from 'react'; import type { WidgetCategory } from '../types/widgetDashboard'; import CandleChartWidgetHost from './hosts/CandleChartWidgetHost'; import StrategyChartWidgetHost from './hosts/StrategyChartWidgetHost'; import MiniChartWidgetHost from './hosts/MiniChartWidgetHost'; import MarketListWidgetHost from './hosts/MarketListWidgetHost'; import MarketMoversWidgetHost from './hosts/MarketMoversWidgetHost'; import TickerTapeWidgetHost from './hosts/TickerTapeWidgetHost'; import QuoteWidgetHost from './hosts/QuoteWidgetHost'; import WatchlistWidgetHost from './hosts/WatchlistWidgetHost'; import MarketHeatmapWidgetHost from './hosts/MarketHeatmapWidgetHost'; import MarketSummaryWidgetHost from './hosts/MarketSummaryWidgetHost'; import BuySellWidgetHost from './hosts/BuySellWidgetHost'; import OrderbookWidgetHost from './hosts/OrderbookWidgetHost'; import DepthChartWidgetHost from './hosts/DepthChartWidgetHost'; import TimeSalesWidgetHost from './hosts/TimeSalesWidgetHost'; import TradeHistoryWidgetHost from './hosts/TradeHistoryWidgetHost'; import PendingOrdersWidgetHost from './hosts/PendingOrdersWidgetHost'; import PositionsWidgetHost from './hosts/PositionsWidgetHost'; import AccountBalanceWidgetHost from './hosts/AccountBalanceWidgetHost'; import NotificationListWidgetHost from './hosts/NotificationListWidgetHost'; import StrategyListWidgetHost from './hosts/StrategyListWidgetHost'; import BacktestListWidgetHost from './hosts/BacktestListWidgetHost'; import PaperKpiWidgetHost from './hosts/PaperKpiWidgetHost'; import SignalSummaryWidgetHost from './hosts/SignalSummaryWidgetHost'; import SignalMatchWidgetHost from './hosts/SignalMatchWidgetHost'; import StrategyConditionWidgetHost from './hosts/StrategyConditionWidgetHost'; import BacktestSignalsWidgetHost from './hosts/BacktestSignalsWidgetHost'; import IndicatorStatusWidgetHost from './hosts/IndicatorStatusWidgetHost'; export type WidgetGroupId = | 'chart' | 'market' | 'trade' | 'portfolio' | 'strategy' | 'analysis' | 'alert'; export interface WidgetDefinition { type: string; label: string; description: string; category: WidgetCategory; group: WidgetGroupId; defaultConfig?: Record; Host: React.FC<{ config?: Record }>; } export const WIDGET_GROUP_LABELS: Record = { chart: '차트', market: '시세·종목', trade: '매매·호가', portfolio: '계좌·포트폴리오', strategy: '전략·분석', analysis: '매매 시그널', alert: '알림', }; export const WIDGET_REGISTRY: WidgetDefinition[] = [ { type: 'chart.candle', label: '캔들 차트', description: '종목 검색 + 좌·우 툴바 실시간 캔들', category: 'center', group: 'chart', Host: CandleChartWidgetHost, }, { type: 'chart.strategy', label: '전략 분석 차트', description: '선택 전략 백테스트 시그널 차트', category: 'center', group: 'chart', Host: StrategyChartWidgetHost, }, { type: 'chart.mini', label: '미니 차트', description: '선택 종목 소형 캔들 차트', category: 'center', group: 'chart', Host: MiniChartWidgetHost, }, { type: 'market.list', label: '종목 목록', description: 'KRW·BTC·보유·관심 종목', category: 'side', group: 'market', Host: MarketListWidgetHost, }, { type: 'market.watchlist', label: '관심종목', description: '즐겨찾기 종목 컴팩트 목록', category: 'side', group: 'market', Host: WatchlistWidgetHost, }, { type: 'market.movers', label: '급등·급락', description: '상승·하락·거래대금 TOP 종목', category: 'side', group: 'market', Host: MarketMoversWidgetHost, }, { type: 'market.tickerTape', label: '티커 테이프', description: '주요 종목 시세 흐름 스크롤', category: 'side', group: 'market', Host: TickerTapeWidgetHost, }, { type: 'market.quote', label: '종목 시세', description: '선택 종목 상세 시세·OHLC', category: 'side', group: 'market', Host: QuoteWidgetHost, }, { type: 'market.heatmap', label: '히트맵', description: '등락률 색상 그리드', category: 'side', group: 'market', Host: MarketHeatmapWidgetHost, }, { type: 'market.summary', label: '시장 요약', description: '상승/하락 종목 수·주요 지수', category: 'side', group: 'market', Host: MarketSummaryWidgetHost, }, { type: 'trade.buySell', label: '매수·매도', description: '모의 매매 주문 패널', category: 'side', group: 'trade', Host: BuySellWidgetHost, }, { type: 'trade.orderbook', label: '호가', description: '실시간 호가·체결', category: 'side', group: 'trade', Host: OrderbookWidgetHost, }, { type: 'trade.depth', label: '호가 깊이', description: '매수·매도 호가 깊이 차트', category: 'side', group: 'trade', Host: DepthChartWidgetHost, }, { type: 'trade.timeSales', label: '체결', description: '실시간 체결(Time & Sales)', category: 'side', group: 'trade', Host: TimeSalesWidgetHost, }, { type: 'trade.history', label: '거래 내역', description: '모의·가상 체결 이력', category: 'side', group: 'trade', Host: TradeHistoryWidgetHost, }, { type: 'trade.pendingOrders', label: '미체결 주문', description: '대기 중인 모의 주문', category: 'side', group: 'trade', Host: PendingOrdersWidgetHost, }, { type: 'paper.kpi', label: '투자 KPI', description: '총자산·수익률·예수금', category: 'side', group: 'portfolio', Host: PaperKpiWidgetHost, }, { type: 'paper.balance', label: '계좌 잔고', description: '예수금·평가·손익 상세', category: 'side', group: 'portfolio', Host: AccountBalanceWidgetHost, }, { type: 'paper.positions', label: '보유 종목', description: '포지션·평가손익', category: 'side', group: 'portfolio', Host: PositionsWidgetHost, }, { type: 'notification.list', label: '알림 목록', description: '매매 시그널 알림', category: 'side', group: 'alert', Host: NotificationListWidgetHost, }, { type: 'strategy.list', label: '전략 목록', description: '등록된 투자 전략', category: 'side', group: 'strategy', Host: StrategyListWidgetHost, }, { type: 'backtest.list', label: '백테스트 목록', description: '백테스팅·실시간 매매 실행', category: 'side', group: 'strategy', Host: BacktestListWidgetHost, }, { type: 'analysis.signalSummary', label: '매매 시그널 요약', description: '선택 종목·전략 실시간 신호 카드', category: 'side', group: 'analysis', Host: SignalSummaryWidgetHost, }, { type: 'analysis.signalMatch', label: '조건 일치율', description: '매수·매도 조건별 지표 충족률', category: 'side', group: 'analysis', Host: SignalMatchWidgetHost, }, { type: 'analysis.strategyCondition', label: '전략 조건', description: '매수·매도 DSL 조건 트리', category: 'side', group: 'analysis', Host: StrategyConditionWidgetHost, }, { type: 'analysis.backtestSignals', label: '백테스트 시그널', description: '최근 캔들 구간 매매 시그널 목록', category: 'side', group: 'analysis', Host: BacktestSignalsWidgetHost, }, { type: 'analysis.indicatorDetail', label: '지표별 상태', description: '조건별 현재값·충족 여부 상세', category: 'side', group: 'analysis', Host: IndicatorStatusWidgetHost, }, ]; const byType = new Map(WIDGET_REGISTRY.map(w => [w.type, w])); export function getWidgetDefinition(type: string | null | undefined): WidgetDefinition | undefined { if (!type) return undefined; return byType.get(type); } export function widgetsForCategory(category: WidgetCategory): WidgetDefinition[] { return WIDGET_REGISTRY.filter(w => w.category === category); } export function widgetsByGroup(category: WidgetCategory): { group: WidgetGroupId; label: string; items: WidgetDefinition[] }[] { const items = widgetsForCategory(category); const order: WidgetGroupId[] = category === 'center' ? ['chart'] : ['market', 'trade', 'portfolio', 'strategy', 'analysis', 'alert']; return order .map(group => ({ group, label: WIDGET_GROUP_LABELS[group], items: items.filter(w => w.group === group), })) .filter(g => g.items.length > 0); } /** 플로팅 위젯 — 메인·패널 위젯 전체 */ export function widgetsByGroupAll(): { group: WidgetGroupId; label: string; items: WidgetDefinition[] }[] { return [ ...widgetsByGroup('center'), ...widgetsByGroup('side'), ]; } export function widgetLabel(type: string | null | undefined): string { return getWidgetDefinition(type)?.label ?? '위젯 선택'; }