dashboardity 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/Dashboard.tsx","../src/core/Panel.tsx","../src/widget-wrapper/WidgetContainer.tsx","../src/core/useResponsiveGrid.ts","../src/shared/utils.ts","../src/shared/theme.ts","../src/core/widgetRegistry.tsx","../src/core/DashboardRuntime.tsx","../src/core/DashboardSerializer.ts","../src/core/PanelOptionEditor.tsx","../src/app-shell/TopBar.tsx","../src/app-shell/SideNav.tsx","../src/app-shell/DashboardPicker.tsx","../src/app-shell/TimeRangePicker.tsx","../src/data-adapter/index.ts"],"sourcesContent":["/** Core: Dashboard, Runtime, Serializer, Panel, Widget Registry */\r\nexport {\r\n Dashboard,\r\n DashboardRuntime,\r\n createEmptyPanel,\r\n loadDashboard,\r\n serializeDashboard,\r\n Panel,\r\n PanelOptionEditor,\r\n useResponsiveGrid,\r\n createWidgetRegistry,\r\n FallbackWidget,\r\n} from \"./core\";\r\nexport type {\r\n DashboardProps,\r\n DashboardRuntimeHandle,\r\n DashboardRuntimeProps,\r\n DashboardGridOptions,\r\n DashboardMode,\r\n DashboardSpec,\r\n DataSource,\r\n GridItem,\r\n PanelAction,\r\n PanelConfig,\r\n PanelOptionEditorProps,\r\n PanelProps,\r\n WidgetComponent,\r\n WidgetDefinition,\r\n WidgetOptionSchema,\r\n WidgetOptionSchemaField,\r\n WidgetProps,\r\n WidgetRegistry,\r\n ResponsiveGridSize,\r\n UseResponsiveGridOptions,\r\n} from \"./core\";\r\n\r\n/** Layout store (state for grid) */\r\nexport { createLayoutStore } from \"@dashboardity/layout-store\";\r\nexport type { LayoutStore, LayoutState } from \"@dashboardity/layout-store\";\r\nexport type { LayoutAction } from \"@dashboardity/layout-core\";\r\n\r\n/** App shell: TopBar, SideNav, Pickers */\r\nexport { TopBar, SideNav, DashboardPicker, TimeRangePicker } from \"./app-shell\";\r\nexport type {\r\n TopBarProps,\r\n SideNavProps,\r\n SideNavItem,\r\n DashboardPickerProps,\r\n DashboardOption,\r\n TimeRangePickerProps,\r\n TimeRangePreset,\r\n} from \"./app-shell\";\r\n\r\n/** Data adapter */\r\nexport {\r\n createStaticDataSource,\r\n buildInitialItemsFromPanelConfigs,\r\n} from \"./data-adapter\";\r\nexport type { PanelConfigWithLayout } from \"./data-adapter\";\r\n\r\n/** Shared (types, utils) */\r\nexport type * from \"./shared\";\r\nexport { cn } from \"./shared\";\r\n\r\n/** Theme (via shared) */\r\nexport { colors, spacing, typography, defaultTheme } from \"./shared\";\r\nexport type { Theme } from \"./shared\";\r\n\r\n/** Widget wrapper */\r\nexport { WidgetContainer } from \"./widget-wrapper\";\r\nexport type { WidgetContainerProps } from \"./widget-wrapper\";\r\n","import type { LayoutStore } from \"@dashboardity/layout-store\";\r\nimport React, { useMemo, useRef } from \"react\";\r\nimport { GridLayout } from \"react-griditty\";\r\nimport { Panel } from \"./Panel\";\r\nimport type {\r\n DashboardGridOptions,\r\n DashboardMode,\r\n DataSource,\r\n GridItem,\r\n PanelAction,\r\n PanelConfig,\r\n WidgetComponent,\r\n WidgetDefinition,\r\n WidgetRegistry,\r\n} from \"../shared\";\r\nimport { useResponsiveGrid } from \"./useResponsiveGrid\";\r\nimport { FallbackWidget } from \"./widgetRegistry\";\r\n\r\nconst getWidgetComponent = (\r\n entry: WidgetComponent | WidgetDefinition | undefined,\r\n): WidgetComponent =>\r\n entry == null\r\n ? FallbackWidget\r\n : typeof entry === \"function\"\r\n ? entry\r\n : entry.Component;\r\n\r\nexport type DashboardProps = {\r\n store: LayoutStore;\r\n columns: number;\r\n /** item.id로 조회. JSON 직렬화 가능한 설정만 포함 (layout 제외) */\r\n panelConfigs: PanelConfig[];\r\n dataSource: DataSource;\r\n widgets: WidgetRegistry;\r\n rowHeight?: number;\r\n /** 그리드 UI 옵션: resize 아이콘, 격자 보기 등 */\r\n gridOptions?: DashboardGridOptions;\r\n /** view = 읽기 전용, edit = 드래그/리사이즈/패널 액션 허용 */\r\n mode?: DashboardMode;\r\n /** edit 모드에서 패널 액션(remove/duplicate/edit) 시 호출 */\r\n onPanelAction?: (action: PanelAction) => void;\r\n /** edit 모드에서 패널 클릭 시 선택. 선택된 id */\r\n selectedPanelId?: string | null;\r\n onPanelSelect?: (id: string) => void;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n};\r\n\r\nconst dashboardRootStyle: React.CSSProperties = {\r\n width: \"100%\",\r\n minWidth: 0,\r\n minHeight: 200,\r\n};\r\n\r\nconst cn = (...parts: (string | undefined)[]) =>\r\n parts.filter(Boolean).join(\" \");\r\n\r\nexport const Dashboard: React.FC<DashboardProps> = ({\r\n store,\r\n columns,\r\n panelConfigs,\r\n dataSource,\r\n widgets,\r\n rowHeight,\r\n gridOptions,\r\n mode = \"view\",\r\n onPanelAction,\r\n selectedPanelId,\r\n onPanelSelect,\r\n className,\r\n style,\r\n}) => {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const { cellWidth, cellHeight } = useResponsiveGrid(containerRef, {\r\n columns,\r\n rowHeight,\r\n });\r\n const isEdit = mode === \"edit\";\r\n\r\n const configById = useMemo(\r\n () => new Map(panelConfigs.map((c) => [c.id, c])),\r\n [panelConfigs],\r\n );\r\n\r\n const renderPanel = useMemo(\r\n () => (item: GridItem) => {\r\n const config = configById.get(item.id);\r\n if (!config)\r\n return (\r\n <div key={item.id} style={{ padding: 8 }}>\r\n Unknown panel\r\n </div>\r\n );\r\n const Widget = getWidgetComponent(widgets[config.type]) ?? FallbackWidget;\r\n const data = config.dataSourceId\r\n ? dataSource.getData(config.dataSourceId, item.id)\r\n : null;\r\n const content = (\r\n <Widget\r\n data={data}\r\n options={config.options}\r\n className={config.widgetClassName}\r\n />\r\n );\r\n const title =\r\n config.options?.title != null\r\n ? String(config.options.title)\r\n : undefined;\r\n return (\r\n <Panel\r\n key={item.id}\r\n item={item}\r\n title={title}\r\n content={content}\r\n className={config.className}\r\n style={config.style}\r\n containerClassName={config.containerClassName}\r\n containerStyle={config.containerStyle}\r\n onAction={isEdit ? onPanelAction : undefined}\r\n selected={selectedPanelId === item.id}\r\n onSelect={isEdit ? () => onPanelSelect?.(item.id) : undefined}\r\n />\r\n );\r\n },\r\n [\r\n configById,\r\n dataSource,\r\n widgets,\r\n isEdit,\r\n onPanelAction,\r\n selectedPanelId,\r\n onPanelSelect,\r\n ],\r\n );\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={cn(\"rd-dashboard\", className)}\r\n style={{ ...dashboardRootStyle, ...style }}\r\n >\r\n <GridLayout\r\n store={store}\r\n cellWidth={cellWidth}\r\n cellHeight={cellHeight}\r\n resizeHandle={gridOptions?.resizeHandle}\r\n showGrid={Boolean(gridOptions?.showGrid)}\r\n draggable={isEdit}\r\n resizable={isEdit}\r\n >\r\n {renderPanel}\r\n </GridLayout>\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useRef, useState } from \"react\";\r\nimport { WidgetContainer } from \"../widget-wrapper\";\r\nimport type { PanelProps } from \"../shared\";\r\n\r\n/**\r\n * GridItem 단위 wrapper.\r\n * 위젯은 래퍼만 제공하고, 콘텐츠는 content(props)로 주입.\r\n * drag/resize 이벤트는 GridLayout이 처리하고 store.dispatch로 전달하므로\r\n * 이 컴포넌트는 터치하지 않는다.\r\n */\r\nconst panelRootStyle: React.CSSProperties = {\r\n width: \"100%\",\r\n height: \"100%\",\r\n overflow: \"visible\",\r\n background: \"#fff\",\r\n border: \"1px solid #e0e0e0\",\r\n borderRadius: 6,\r\n boxSizing: \"border-box\",\r\n position: \"relative\",\r\n};\r\n\r\n/** 위젯 콘텐츠 래퍼. overflow: visible 로 두어 위젯 내 툴팁이 패널 밖으로 나와 잘리지 않음 */\r\nconst panelContentClipStyle: React.CSSProperties = {\r\n width: \"100%\",\r\n height: \"100%\",\r\n overflow: \"visible\",\r\n borderRadius: 6,\r\n position: \"relative\",\r\n};\r\n\r\nconst menuButtonStyle: React.CSSProperties = {\r\n position: \"absolute\",\r\n top: 6,\r\n right: 6,\r\n zIndex: 2,\r\n width: 24,\r\n height: 24,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n border: \"none\",\r\n borderRadius: 4,\r\n background: \"rgba(0,0,0,0.06)\",\r\n cursor: \"pointer\",\r\n fontSize: 14,\r\n color: \"#555\",\r\n};\r\n\r\nconst dropdownStyle: React.CSSProperties = {\r\n position: \"absolute\",\r\n top: 32,\r\n right: 6,\r\n zIndex: 10,\r\n minWidth: 120,\r\n background: \"#fff\",\r\n border: \"1px solid #e0e0e0\",\r\n borderRadius: 6,\r\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\",\r\n padding: 4,\r\n};\r\n\r\nconst dropdownItemStyle: React.CSSProperties = {\r\n display: \"block\",\r\n width: \"100%\",\r\n padding: \"6px 10px\",\r\n border: \"none\",\r\n borderRadius: 4,\r\n background: \"none\",\r\n cursor: \"pointer\",\r\n fontSize: 12,\r\n textAlign: \"left\",\r\n color: \"#333\",\r\n};\r\n\r\nconst cn = (...parts: (string | undefined)[]) =>\r\n parts.filter(Boolean).join(\" \");\r\n\r\nexport const Panel: React.FC<PanelProps> = ({\r\n item,\r\n title,\r\n content,\r\n className,\r\n style,\r\n containerClassName,\r\n containerStyle,\r\n onAction,\r\n selected,\r\n onSelect,\r\n}) => {\r\n const [menuOpen, setMenuOpen] = useState(false);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n if (!menuOpen) return;\r\n const close = (e: MouseEvent) => {\r\n if (containerRef.current?.contains(e.target as Node)) return;\r\n setMenuOpen(false);\r\n };\r\n window.addEventListener(\"click\", close);\r\n return () => window.removeEventListener(\"click\", close);\r\n }, [menuOpen]);\r\n\r\n const handleAction = (type: \"remove\" | \"duplicate\" | \"edit\") => {\r\n onAction?.({ type, id: item.id });\r\n setMenuOpen(false);\r\n };\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={cn(\"rd-panel\", className)}\r\n style={{\r\n ...panelRootStyle,\r\n ...style,\r\n ...(selected\r\n ? { border: \"2px solid #1976d2\", boxShadow: \"0 0 0 1px #1976d2\" }\r\n : {}),\r\n }}\r\n onClick={() => onSelect?.()}\r\n role={onSelect ? \"button\" : undefined}\r\n aria-pressed={selected}\r\n >\r\n {onAction != null && (\r\n <>\r\n <button\r\n type=\"button\"\r\n aria-label=\"Panel actions\"\r\n style={menuButtonStyle}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setMenuOpen((v) => !v);\r\n }}\r\n >\r\n ⋮\r\n </button>\r\n {menuOpen && (\r\n <div style={dropdownStyle} role=\"menu\">\r\n <button\r\n type=\"button\"\r\n style={dropdownItemStyle}\r\n role=\"menuitem\"\r\n onClick={() => handleAction(\"duplicate\")}\r\n >\r\n Duplicate\r\n </button>\r\n <button\r\n type=\"button\"\r\n style={dropdownItemStyle}\r\n role=\"menuitem\"\r\n onClick={() => handleAction(\"remove\")}\r\n >\r\n Remove\r\n </button>\r\n <button\r\n type=\"button\"\r\n style={dropdownItemStyle}\r\n role=\"menuitem\"\r\n onClick={() => handleAction(\"edit\")}\r\n >\r\n Edit\r\n </button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n <div style={panelContentClipStyle}>\r\n <WidgetContainer\r\n title={title}\r\n className={containerClassName}\r\n style={containerStyle}\r\n >\r\n {content ?? (\r\n <div style={{ fontSize: 12, color: \"#999\" }}>No content</div>\r\n )}\r\n </WidgetContainer>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React from \"react\";\r\nimport type { CSSProperties } from \"react\";\r\n\r\nexport type WidgetContainerProps = {\r\n /** 위젯 상단에 표시할 제목 (options.title 등) */\r\n title?: string;\r\n children: React.ReactNode;\r\n /** 루트 요소 커스텀 */\r\n className?: string;\r\n style?: CSSProperties;\r\n /** 제목 영역 커스텀 */\r\n titleClassName?: string;\r\n titleStyle?: CSSProperties;\r\n /** 콘텐츠 영역 커스텀 */\r\n contentClassName?: string;\r\n contentStyle?: CSSProperties;\r\n};\r\n\r\nconst rootStyle: CSSProperties = {\r\n padding: 12,\r\n height: \"100%\",\r\n minHeight: 0,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n boxSizing: \"border-box\",\r\n};\r\n\r\nconst titleStyleDefault: CSSProperties = {\r\n fontSize: 12,\r\n fontWeight: 600,\r\n color: \"#333\",\r\n marginBottom: 8,\r\n flexShrink: 0,\r\n};\r\n\r\nconst contentStyleDefault: CSSProperties = {\r\n flex: 1,\r\n minHeight: 0,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n};\r\n\r\nconst cn = (...parts: (string | undefined)[]) => parts.filter(Boolean).join(\" \");\r\n\r\n/**\r\n * 모든 위젯이 공통으로 사용하는 컨테이너.\r\n * 제목 + 콘텐츠 영역 레이아웃과 패딩을 통일. className/style로 커스텀 가능.\r\n */\r\nexport const WidgetContainer: React.FC<WidgetContainerProps> = ({\r\n title,\r\n children,\r\n className,\r\n style,\r\n titleClassName,\r\n titleStyle,\r\n contentClassName,\r\n contentStyle,\r\n}) => {\r\n return (\r\n <div className={cn(\"rd-widget-container\", className)} style={{ ...rootStyle, ...style }}>\r\n {title != null && title !== \"\" && (\r\n <div className={cn(\"rd-widget-container__title\", titleClassName)} style={{ ...titleStyleDefault, ...titleStyle }}>\r\n {title}\r\n </div>\r\n )}\r\n <div\r\n className={cn(\"rd-widget-container__content\", contentClassName)}\r\n style={{ ...contentStyleDefault, ...contentStyle }}\r\n >\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import { useCallback, useEffect, useState } from \"react\";\r\n\r\n/** 반응형 계산 시 사용할 최소 셀 크기 (0이 되면 그리드가 안 보임) */\r\nconst MIN_CELL = 24;\r\n\r\n/**\r\n * 반응형 그리드: 화면(컨테이너) 크기와 columns에 맞춰 cellWidth/cellHeight만 동적 조정.\r\n * GridItem 좌표(x,y,w,h)는 변경하지 않음. 픽셀 변환만 달라짐.\r\n * 좌우 이동 자동 보정 없음. pack-up 규칙은 layout-core/store에서 유지.\r\n */\r\nexport type UseResponsiveGridOptions = {\r\n /** 그리드 열 수 (layout-store의 columns와 동일해야 함) */\r\n columns: number;\r\n /** 셀 높이(px). 미지정 시 cellWidth와 동일(정사각형) */\r\n rowHeight?: number;\r\n};\r\n\r\nexport type ResponsiveGridSize = {\r\n cellWidth: number;\r\n cellHeight: number;\r\n};\r\n\r\nexport const useResponsiveGrid = (\r\n containerRef: React.RefObject<HTMLDivElement | null>,\r\n options: UseResponsiveGridOptions,\r\n): ResponsiveGridSize => {\r\n const { columns, rowHeight } = options;\r\n const [size, setSize] = useState<ResponsiveGridSize>(() => ({\r\n cellWidth: 100,\r\n cellHeight: rowHeight ?? 100,\r\n }));\r\n const update = useCallback(() => {\r\n const el = containerRef.current;\r\n if (!el || columns < 1) return;\r\n const rect = el.getBoundingClientRect();\r\n const width = rect.width;\r\n const rawCellWidth = width / columns;\r\n const cellWidth = Math.max(MIN_CELL, rawCellWidth);\r\n const cellHeight = rowHeight ?? Math.max(MIN_CELL, rawCellWidth);\r\n setSize((prev) =>\r\n prev.cellWidth !== cellWidth || prev.cellHeight !== cellHeight\r\n ? { cellWidth, cellHeight }\r\n : prev,\r\n );\r\n }, [containerRef, columns, rowHeight]);\r\n\r\n useEffect(() => {\r\n const el = containerRef.current;\r\n if (!el) return;\r\n update();\r\n const obs = new ResizeObserver(update);\r\n obs.observe(el);\r\n return () => obs.disconnect();\r\n }, [containerRef, update]);\r\n\r\n return size;\r\n};\r\n","/** className 조합 유틸 */\r\nexport const cn = (...parts: (string | undefined)[]): string =>\r\n parts.filter(Boolean).join(\" \");\r\n","/** 색상 토큰 */\r\nexport const colors = {\r\n text: \"#333\",\r\n textMuted: \"#555\",\r\n textSubtle: \"#999\",\r\n border: \"#e0e0e0\",\r\n background: \"#fff\",\r\n primary: \"#1976d2\",\r\n success: \"#73bf69\",\r\n warning: \"#ff9830\",\r\n danger: \"#f2495c\",\r\n chartGradientStart: \"#73bf69\",\r\n chartGradientEnd: \"#5794f2\",\r\n} as const;\r\n\r\n/** spacing (px) */\r\nexport const spacing = {\r\n xs: 4,\r\n sm: 8,\r\n md: 12,\r\n lg: 16,\r\n xl: 24,\r\n} as const;\r\n\r\n/** typography */\r\nexport const typography = {\r\n fontSize: {\r\n xs: 11,\r\n sm: 12,\r\n md: 14,\r\n lg: 18,\r\n xl: 24,\r\n },\r\n fontWeight: {\r\n normal: 400,\r\n medium: 500,\r\n semibold: 600,\r\n bold: 700,\r\n },\r\n} as const;\r\n\r\nexport type Theme = {\r\n colors: typeof colors;\r\n spacing: typeof spacing;\r\n typography: typeof typography;\r\n};\r\n\r\nexport const defaultTheme: Theme = {\r\n colors,\r\n spacing,\r\n typography,\r\n};\r\n","import React from \"react\";\r\nimport type { WidgetComponent, WidgetRegistry } from \"../shared\";\r\nimport { cn } from \"../shared\";\r\n\r\n/** 존재하지 않는 type용 fallback 위젯 */\r\nexport const FallbackWidget: WidgetComponent = ({ data, className }) => (\r\n <div className={cn(\"rd-fallback-widget\", className)} style={{ fontSize: 12, color: \"#999\" }}>\r\n Unknown widget type. data: {JSON.stringify(data)}\r\n </div>\r\n);\r\n\r\n/**\r\n * Widget Registry 생성.\r\n * 단순 객체 반환. 존재하지 않는 type에 대한 fallback은 Dashboard에서 처리.\r\n */\r\nexport const createWidgetRegistry = (widgets: WidgetRegistry): WidgetRegistry => ({ ...widgets });\r\n","import React, {\r\n forwardRef,\r\n useCallback,\r\n useEffect,\r\n useImperativeHandle,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\nimport { Dashboard } from \"./Dashboard\";\r\nimport {\r\n createEmptyPanel,\r\n loadDashboard,\r\n serializeDashboard,\r\n} from \"./DashboardSerializer\";\r\nimport { PanelOptionEditor } from \"./PanelOptionEditor\";\r\nimport type {\r\n DashboardGridOptions,\r\n DashboardSpec,\r\n DataSource,\r\n GridItem,\r\n PanelAction,\r\n PanelConfig,\r\n WidgetDefinition,\r\n WidgetRegistry,\r\n} from \"../shared\";\r\n\r\nconst getWidgetSchema = (\r\n entry: WidgetRegistry[string] | undefined,\r\n): WidgetDefinition[\"options\"] =>\r\n entry && typeof entry === \"object\" && \"options\" in entry\r\n ? entry.options\r\n : undefined;\r\n\r\nexport type DashboardRuntimeProps = {\r\n /** 초기 스펙. key={initialSpec.id} 로 대시보드 전환 시 리마운트 권장 */\r\n initialSpec: DashboardSpec;\r\n widgets: WidgetRegistry;\r\n dataSource: DataSource;\r\n mode?: \"view\" | \"edit\";\r\n /** 레이아웃/패널 변경 시 직렬화된 스펙 전달 (저장/서버 연동용) */\r\n onChange?: (spec: DashboardSpec) => void;\r\n rowHeight?: number;\r\n gridOptions?: DashboardGridOptions;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n};\r\n\r\n/** ref 로 노출되는 API. 툴바/단축키/저장 연동용 */\r\nexport type DashboardRuntimeHandle = {\r\n addPanel: (type: string) => void;\r\n removePanel: (id: string) => void;\r\n export: () => DashboardSpec;\r\n};\r\n\r\nexport const DashboardRuntime = forwardRef<\r\n DashboardRuntimeHandle,\r\n DashboardRuntimeProps\r\n>((props, ref) => {\r\n const {\r\n initialSpec,\r\n widgets,\r\n dataSource,\r\n mode: modeProp = \"view\",\r\n onChange,\r\n rowHeight,\r\n gridOptions,\r\n className,\r\n style,\r\n } = props;\r\n\r\n const mode = modeProp ?? \"view\";\r\n const isEdit = mode === \"edit\";\r\n\r\n const [loaded] = useState(() => loadDashboard(initialSpec));\r\n const store = loaded.store;\r\n const [panels, setPanels] = useState<PanelConfig[]>(() => [...loaded.panels]);\r\n const [selectedPanelId, setSelectedPanelId] = useState<string | null>(null);\r\n\r\n const meta = useMemo(\r\n () => ({ id: initialSpec.id, title: initialSpec.title }),\r\n [initialSpec.id, initialSpec.title],\r\n );\r\n const panelsRef = useRef(panels);\r\n panelsRef.current = panels;\r\n\r\n const notifyChange = useCallback(() => {\r\n onChange?.(serializeDashboard(store, panelsRef.current, meta));\r\n }, [onChange, store, meta]);\r\n\r\n useEffect(() => {\r\n const unsub = store.subscribe(notifyChange);\r\n return unsub;\r\n }, [store, notifyChange]);\r\n\r\n useEffect(() => {\r\n notifyChange();\r\n }, [panels, notifyChange]);\r\n\r\n const dispatchPanelAction = useCallback(\r\n (action: PanelAction) => {\r\n switch (action.type) {\r\n case \"remove\": {\r\n store.dispatch({ type: \"remove\", id: action.id });\r\n setPanels((p) => p.filter((x) => x.id !== action.id));\r\n break;\r\n }\r\n case \"duplicate\": {\r\n const item = store.getState().items.find((i: GridItem) => i.id === action.id);\r\n const config = panelsRef.current.find((p) => p.id === action.id);\r\n if (!item || !config) break;\r\n const newPanel = createEmptyPanel(config.type, \"New panel\");\r\n const title =\r\n config.options?.title != null\r\n ? `${String(config.options.title)} (copy)`\r\n : \"Copy\";\r\n const newConfig: PanelConfig = {\r\n ...config,\r\n id: newPanel.id,\r\n options: { ...config.options, title },\r\n };\r\n store.dispatch({\r\n type: \"add\",\r\n item: {\r\n id: newPanel.id,\r\n x: item.x,\r\n y: item.y + item.h,\r\n w: item.w,\r\n h: item.h,\r\n },\r\n });\r\n setPanels((p) => [...p, newConfig]);\r\n break;\r\n }\r\n case \"edit\":\r\n notifyChange();\r\n break;\r\n default: {\r\n const _: never = action;\r\n }\r\n }\r\n },\r\n [store],\r\n );\r\n\r\n const addPanel = useCallback(\r\n (type: string) => {\r\n const items = store.getState().items;\r\n const nextY =\r\n items.length === 0 ? 0 : Math.max(...items.map((i: GridItem) => i.y + i.h));\r\n const newPanel = createEmptyPanel(type, \"New panel\");\r\n store.dispatch({\r\n type: \"add\",\r\n item: { id: newPanel.id, x: 0, y: nextY, w: 6, h: 2 },\r\n });\r\n setPanels((p) => [...p, newPanel]);\r\n },\r\n [store],\r\n );\r\n\r\n const removePanel = useCallback(\r\n (id: string) => {\r\n store.dispatch({ type: \"remove\", id });\r\n setPanels((p) => p.filter((x) => x.id !== id));\r\n },\r\n [store],\r\n );\r\n\r\n const exportSpec = useCallback(\r\n (): DashboardSpec => serializeDashboard(store, panelsRef.current, meta),\r\n [store, meta],\r\n );\r\n\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n addPanel,\r\n removePanel,\r\n export: exportSpec,\r\n }),\r\n [addPanel, removePanel, exportSpec],\r\n );\r\n\r\n const handleAddPanel = useCallback(() => {\r\n addPanel(\"text\");\r\n }, [addPanel]);\r\n\r\n const selectedPanel =\r\n selectedPanelId != null\r\n ? panels.find((p) => p.id === selectedPanelId)\r\n : null;\r\n const selectedSchema =\r\n selectedPanel != null\r\n ? getWidgetSchema(widgets[selectedPanel.type])\r\n : undefined;\r\n\r\n const handlePanelOptionChange = useCallback((next: PanelConfig) => {\r\n setPanels((prev) => prev.map((p) => (p.id === next.id ? next : p)));\r\n }, []);\r\n\r\n const layoutStyle: React.CSSProperties = {\r\n display: \"flex\",\r\n gap: 16,\r\n width: \"100%\",\r\n minWidth: 0,\r\n };\r\n const gridWrapStyle: React.CSSProperties = {\r\n flex: 1,\r\n minWidth: 0,\r\n };\r\n const sidePanelStyle: React.CSSProperties = {\r\n width: 260,\r\n flexShrink: 0,\r\n border: \"1px solid #e0e0e0\",\r\n borderRadius: 8,\r\n background: \"#fff\",\r\n overflow: \"auto\",\r\n };\r\n\r\n return (\r\n <div className={className} style={{ ...style, ...layoutStyle }}>\r\n <div style={gridWrapStyle}>\r\n {isEdit && (\r\n <div style={{ marginBottom: 8 }}>\r\n <button\r\n type=\"button\"\r\n onClick={handleAddPanel}\r\n style={{ padding: \"6px 12px\", cursor: \"pointer\" }}\r\n >\r\n Add panel\r\n </button>\r\n </div>\r\n )}\r\n <Dashboard\r\n store={store}\r\n columns={initialSpec.columns}\r\n panelConfigs={panels}\r\n dataSource={dataSource}\r\n widgets={widgets}\r\n rowHeight={rowHeight}\r\n gridOptions={gridOptions}\r\n mode={mode}\r\n onPanelAction={isEdit ? dispatchPanelAction : undefined}\r\n selectedPanelId={selectedPanelId}\r\n onPanelSelect={isEdit ? setSelectedPanelId : undefined}\r\n />\r\n </div>\r\n {isEdit && (\r\n <aside style={sidePanelStyle}>\r\n {selectedPanel != null ? (\r\n <PanelOptionEditor\r\n panel={selectedPanel}\r\n schema={selectedSchema}\r\n onChange={handlePanelOptionChange}\r\n />\r\n ) : (\r\n <div style={{ padding: 12, fontSize: 12, color: \"#999\" }}>\r\n Select a panel to edit options\r\n </div>\r\n )}\r\n </aside>\r\n )}\r\n </div>\r\n );\r\n});\r\n\r\nDashboardRuntime.displayName = \"DashboardRuntime\";\r\n","import type { LayoutStore } from \"@dashboardity/layout-store\";\r\nimport { createLayoutStore } from \"@dashboardity/layout-store\";\r\nimport type { DashboardSpec, PanelConfig } from \"../shared\";\r\n\r\nconst generatePanelId = (): string =>\r\n `panel-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\r\n\r\n/**\r\n * 빈 패널 생성 (Add Panel 플로우용).\r\n * layout은 store.dispatch({ type: \"add\", item: { id, x, y, w, h } })로 호출 측에서 처리.\r\n */\r\nexport const createEmptyPanel = (\r\n type: string,\r\n defaultTitle = \"New panel\",\r\n): PanelConfig => ({\r\n id: generatePanelId(),\r\n type,\r\n options: { title: defaultTitle },\r\n});\r\n\r\n/**\r\n * 라이브러리 레벨: store + panels + meta → JSON 스펙.\r\n * 순서 보존, deterministic, side-effect 없음.\r\n */\r\nexport const serializeDashboard = (\r\n store: LayoutStore,\r\n panels: PanelConfig[],\r\n meta: { id: string; title: string },\r\n): DashboardSpec => {\r\n const state = store.getState();\r\n return {\r\n id: meta.id,\r\n title: meta.title,\r\n columns: state.columns,\r\n layout: {\r\n items: [...state.items],\r\n },\r\n panels: [...panels],\r\n };\r\n};\r\n\r\n/**\r\n * JSON 스펙 → store + panels 복원.\r\n */\r\nexport const loadDashboard = (\r\n spec: DashboardSpec,\r\n): { store: LayoutStore; panels: PanelConfig[] } => {\r\n const store = createLayoutStore({\r\n items: [...spec.layout.items],\r\n columns: spec.columns,\r\n });\r\n const panels: PanelConfig[] = [...spec.panels];\r\n return { store, panels };\r\n};\r\n","import React from \"react\";\r\nimport type {\r\n PanelConfig,\r\n PanelOptionEditorProps,\r\n WidgetOptionSchema,\r\n WidgetOptionSchemaField,\r\n} from \"../shared\";\r\n\r\nconst fieldBlockStyle: React.CSSProperties = {\r\n marginBottom: 12,\r\n};\r\n\r\nconst labelStyle: React.CSSProperties = {\r\n display: \"block\",\r\n fontSize: 11,\r\n fontWeight: 600,\r\n color: \"#555\",\r\n marginBottom: 4,\r\n};\r\n\r\nconst inputStyle: React.CSSProperties = {\r\n width: \"100%\",\r\n padding: \"6px 8px\",\r\n fontSize: 12,\r\n border: \"1px solid #e0e0e0\",\r\n borderRadius: 4,\r\n boxSizing: \"border-box\",\r\n};\r\n\r\nconst selectStyle: React.CSSProperties = {\r\n ...inputStyle,\r\n cursor: \"pointer\",\r\n};\r\n\r\nconst checkboxWrapStyle: React.CSSProperties = {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 8,\r\n};\r\n\r\n/** 스키마 필드 + 값 + 옵션 변경 시 호출. Grafana처럼 schema → form 자동 생성 */\r\nconst renderOptionField = (\r\n key: string,\r\n field: WidgetOptionSchemaField,\r\n value: unknown,\r\n onChange: (value: unknown) => void,\r\n): React.ReactNode => {\r\n const label = <label style={labelStyle}>{field.label}</label>;\r\n\r\n switch (field.type) {\r\n case \"string\":\r\n return (\r\n <div key={key} style={fieldBlockStyle}>\r\n {label}\r\n <input\r\n type=\"text\"\r\n style={inputStyle}\r\n value={value != null ? String(value) : \"\"}\r\n placeholder={field.placeholder}\r\n onChange={(e) => onChange(e.target.value)}\r\n />\r\n </div>\r\n );\r\n case \"number\": {\r\n const num = value != null ? Number(value) : 0;\r\n return (\r\n <div key={key} style={fieldBlockStyle}>\r\n {label}\r\n <input\r\n type=\"number\"\r\n style={inputStyle}\r\n value={num}\r\n min={field.min}\r\n max={field.max}\r\n onChange={(e) => onChange(Number(e.target.value) || 0)}\r\n />\r\n </div>\r\n );\r\n }\r\n case \"boolean\":\r\n return (\r\n <div key={key} style={fieldBlockStyle}>\r\n <div style={checkboxWrapStyle}>\r\n <input\r\n type=\"checkbox\"\r\n id={`opt-${key}`}\r\n checked={value === true || value === \"true\"}\r\n onChange={(e) => onChange(e.target.checked)}\r\n />\r\n <label\r\n htmlFor={`opt-${key}`}\r\n style={{ ...labelStyle, marginBottom: 0 }}\r\n >\r\n {field.label}\r\n </label>\r\n </div>\r\n </div>\r\n );\r\n case \"select\":\r\n return (\r\n <div key={key} style={fieldBlockStyle}>\r\n {label}\r\n <select\r\n style={selectStyle}\r\n value={value != null ? String(value) : \"\"}\r\n onChange={(e) => onChange(e.target.value)}\r\n >\r\n {field.options.map((opt) => (\r\n <option key={opt.value} value={opt.value}>\r\n {opt.label}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n );\r\n case \"color\":\r\n return (\r\n <div key={key} style={fieldBlockStyle}>\r\n {label}\r\n <div style={{ display: \"flex\", gap: 8, alignItems: \"center\" }}>\r\n <input\r\n type=\"color\"\r\n value={value != null ? String(value) : \"#333333\"}\r\n onChange={(e) => onChange(e.target.value)}\r\n style={{\r\n width: 32,\r\n height: 28,\r\n padding: 0,\r\n border: \"1px solid #e0e0e0\",\r\n cursor: \"pointer\",\r\n }}\r\n />\r\n <input\r\n type=\"text\"\r\n style={{ ...inputStyle, flex: 1 }}\r\n value={value != null ? String(value) : \"\"}\r\n onChange={(e) => onChange(e.target.value)}\r\n />\r\n </div>\r\n </div>\r\n );\r\n default: {\r\n const _: never = field;\r\n return null;\r\n }\r\n }\r\n};\r\n\r\n/** 기본 스키마: title 등 공통 옵션. 위젯별 schema 없을 때 사용 */\r\nconst defaultOptionSchema: WidgetOptionSchema = {\r\n title: { type: \"string\", label: \"Title\", placeholder: \"Panel title\" },\r\n};\r\n\r\n/**\r\n * PanelOptionEditor.\r\n * layout/store 접근 없음. PanelConfig.options 만 수정.\r\n */\r\nexport const PanelOptionEditor: React.FC<PanelOptionEditorProps> = ({\r\n panel,\r\n schema,\r\n onChange,\r\n}) => {\r\n const options = panel.options ?? {};\r\n const effectiveSchema = schema ?? defaultOptionSchema;\r\n\r\n const handleOptionChange = (key: string, value: unknown) => {\r\n const next: PanelConfig = {\r\n ...panel,\r\n options: { ...options, [key]: value },\r\n };\r\n onChange(next);\r\n };\r\n\r\n return (\r\n <div style={{ padding: 12 }}>\r\n <div\r\n style={{\r\n fontSize: 12,\r\n fontWeight: 600,\r\n marginBottom: 12,\r\n color: \"#333\",\r\n }}\r\n >\r\n Panel options\r\n </div>\r\n {Object.entries(effectiveSchema).map(([key, field]) =>\r\n renderOptionField(key, field, options[key], (v) =>\r\n handleOptionChange(key, v),\r\n ),\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React from \"react\";\r\n\r\nexport type TopBarProps = {\r\n title?: string;\r\n /** 사용자 정의 대시보드 선택기. 미주입 시 기본 제공 안 함 → children으로 직접 넣거나 자체 컴포넌트 사용 */\r\n dashboardPicker?: React.ReactNode;\r\n /** 사용자 정의 시간 범위 선택기. 미주입 시 기본 제공 안 함 → children으로 직접 넣거나 자체 컴포넌트 사용 */\r\n timeRangePicker?: React.ReactNode;\r\n children?: React.ReactNode;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n};\r\n\r\nconst defaultStyle: React.CSSProperties = {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"space-between\",\r\n gap: 16,\r\n padding: \"8px 16px\",\r\n borderBottom: \"1px solid #e0e0e0\",\r\n background: \"#fff\",\r\n minHeight: 48,\r\n};\r\n\r\nconst rightStyle: React.CSSProperties = {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 12,\r\n flexWrap: \"wrap\",\r\n};\r\n\r\nexport const TopBar: React.FC<TopBarProps> = ({\r\n title,\r\n dashboardPicker,\r\n timeRangePicker,\r\n children,\r\n className,\r\n style,\r\n}) => (\r\n <header className={className} style={{ ...defaultStyle, ...style }} role=\"banner\">\r\n {title != null && <h1 style={{ margin: 0, fontSize: 18, fontWeight: 600 }}>{title}</h1>}\r\n <div style={rightStyle}>\r\n {dashboardPicker}\r\n {timeRangePicker}\r\n {children}\r\n </div>\r\n </header>\r\n);\r\n","import React from \"react\";\r\n\r\nexport type SideNavItem = { id: string; label: string; href?: string };\r\n\r\nexport type SideNavProps = {\r\n items?: SideNavItem[];\r\n activeId?: string;\r\n onSelect?: (id: string) => void;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n};\r\n\r\nconst navStyle: React.CSSProperties = {\r\n width: 220,\r\n flexShrink: 0,\r\n borderRight: \"1px solid #e0e0e0\",\r\n background: \"#fafafa\",\r\n padding: \"16px 0\",\r\n};\r\n\r\nconst itemStyle: React.CSSProperties = {\r\n display: \"block\",\r\n width: \"100%\",\r\n padding: \"8px 16px\",\r\n border: \"none\",\r\n background: \"none\",\r\n textAlign: \"left\",\r\n cursor: \"pointer\",\r\n fontSize: 14,\r\n color: \"#333\",\r\n};\r\n\r\nexport const SideNav: React.FC<SideNavProps> = ({ items = [], activeId, onSelect, className, style }) => (\r\n <nav className={className} style={{ ...navStyle, ...style }} role=\"navigation\">\r\n {items.map((item) => (\r\n <button\r\n key={item.id}\r\n type=\"button\"\r\n style={{\r\n ...itemStyle,\r\n ...(activeId === item.id ? { background: \"rgba(25,118,210,0.08)\", fontWeight: 600 } : {}),\r\n }}\r\n onClick={() => onSelect?.(item.id)}\r\n >\r\n {item.label}\r\n </button>\r\n ))}\r\n </nav>\r\n);\r\n","import React from \"react\";\r\n\r\nexport type DashboardOption = { id: string; title: string };\r\n\r\nexport type DashboardPickerProps = {\r\n options?: DashboardOption[];\r\n value?: string;\r\n onChange?: (id: string) => void;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n};\r\n\r\nconst selectStyle: React.CSSProperties = {\r\n padding: \"6px 10px\",\r\n fontSize: 14,\r\n border: \"1px solid #e0e0e0\",\r\n borderRadius: 6,\r\n background: \"#fff\",\r\n cursor: \"pointer\",\r\n};\r\n\r\nexport const DashboardPicker: React.FC<DashboardPickerProps> = ({\r\n options = [],\r\n value,\r\n onChange,\r\n className,\r\n style,\r\n}) => (\r\n <select\r\n className={className}\r\n style={{ ...selectStyle, ...style }}\r\n value={value ?? \"\"}\r\n onChange={(e) => onChange?.(e.target.value)}\r\n >\r\n {options.map((opt) => (\r\n <option key={opt.id} value={opt.id}>\r\n {opt.title}\r\n </option>\r\n ))}\r\n </select>\r\n);\r\n","import React from \"react\";\r\n\r\nexport type TimeRangePreset = {\r\n label: string;\r\n value: string;\r\n};\r\n\r\nexport type TimeRangePickerProps = {\r\n presets?: TimeRangePreset[];\r\n value?: string;\r\n onChange?: (value: string) => void;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n};\r\n\r\nconst defaultPresets: TimeRangePreset[] = [\r\n { label: \"Last 5m\", value: \"5m\" },\r\n { label: \"Last 15m\", value: \"15m\" },\r\n { label: \"Last 1h\", value: \"1h\" },\r\n { label: \"Last 6h\", value: \"6h\" },\r\n { label: \"Last 24h\", value: \"24h\" },\r\n];\r\n\r\nconst wrapStyle: React.CSSProperties = {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 8,\r\n};\r\n\r\nconst selectStyle: React.CSSProperties = {\r\n padding: \"6px 10px\",\r\n fontSize: 14,\r\n border: \"1px solid #e0e0e0\",\r\n borderRadius: 6,\r\n background: \"#fff\",\r\n cursor: \"pointer\",\r\n};\r\n\r\nexport const TimeRangePicker: React.FC<TimeRangePickerProps> = ({\r\n presets = defaultPresets,\r\n value,\r\n onChange,\r\n className,\r\n style,\r\n}) => (\r\n <div className={className} style={{ ...wrapStyle, ...style }}>\r\n <select\r\n style={selectStyle}\r\n value={value ?? \"\"}\r\n onChange={(e) => onChange?.(e.target.value)}\r\n >\r\n {presets.map((p) => (\r\n <option key={p.value} value={p.value}>\r\n {p.label}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n);\r\n","import type { DataSource as IDataSource, PanelConfig } from \"../shared\";\r\nimport type { GridItem } from \"@dashboardity/layout-core\";\r\n\r\n/**\r\n * 정적 데이터 소스.\r\n * dataSourceId → 데이터 매핑으로 패널에 공급.\r\n */\r\nexport const createStaticDataSource = (payload: {\r\n dataByKey: Record<string, unknown>;\r\n}): IDataSource => ({\r\n getData: (dataSourceId: string, _panelId: string) =>\r\n payload.dataByKey[dataSourceId] ?? null,\r\n});\r\n\r\n/**\r\n * PanelConfig + layout. layout-store 초기 상태용.\r\n * layout은 오직 layout-store가 담당.\r\n */\r\nexport type PanelConfigWithLayout = {\r\n panelConfig: PanelConfig;\r\n layout: { x: number; y: number; w: number; h: number };\r\n};\r\n\r\nexport const buildInitialItemsFromPanelConfigs = (\r\n configs: PanelConfigWithLayout[],\r\n): GridItem[] =>\r\n configs.map(({ panelConfig, layout }) => ({\r\n id: panelConfig.id,\r\n x: layout.x,\r\n y: layout.y,\r\n w: layout.w,\r\n h: layout.h,\r\n }));\r\n"],"mappings":"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","names":["cn","import_react","import_jsx_runtime","cn","import_react","cn","import_jsx_runtime","cn","import_jsx_runtime","cn","import_react","import_jsx_runtime","import_jsx_runtime","import_layout_store","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","selectStyle","import_jsx_runtime","selectStyle"]}