@burdenoff/microfe-bigconsole 2026.712.1 → 2026.713.2

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.
Files changed (38) hide show
  1. package/dist/bigconsole/assistant/createSandboxAssistantTransport.js +144 -69
  2. package/dist/bigconsole/assistant/createSandboxAssistantTransport.js.map +1 -1
  3. package/dist/bigconsole/components/builder/BuilderCanvas.js +21 -0
  4. package/dist/bigconsole/components/builder/BuilderCanvas.js.map +1 -0
  5. package/dist/bigconsole/components/builder/BuilderTopbar.js +33 -0
  6. package/dist/bigconsole/components/builder/BuilderTopbar.js.map +1 -0
  7. package/dist/bigconsole/components/builder/DashboardEditorShell.js +20 -0
  8. package/dist/bigconsole/components/builder/DashboardEditorShell.js.map +1 -0
  9. package/dist/bigconsole/components/builder/WidgetInspector.js +14 -0
  10. package/dist/bigconsole/components/builder/WidgetInspector.js.map +1 -0
  11. package/dist/bigconsole/components/builder/index.js +4 -0
  12. package/dist/bigconsole/components/builder/inspector/AdvancedSection.js +45 -0
  13. package/dist/bigconsole/components/builder/inspector/AdvancedSection.js.map +1 -0
  14. package/dist/bigconsole/components/builder/inspector/AppearanceSection.js +43 -0
  15. package/dist/bigconsole/components/builder/inspector/AppearanceSection.js.map +1 -0
  16. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +124 -0
  17. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -0
  18. package/dist/bigconsole/components/builder/inspector/GeneralSection.js +50 -0
  19. package/dist/bigconsole/components/builder/inspector/GeneralSection.js.map +1 -0
  20. package/dist/bigconsole/components/builder/inspector/index.js +4 -0
  21. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +221 -199
  22. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  23. package/dist/bigconsole/components/dashboard/WidgetPalette.js +145 -102
  24. package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
  25. package/dist/bigconsole/components/dashboard/index.js +4 -0
  26. package/dist/bigconsole/components/widgets/PropertiesPanel.js +529 -742
  27. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  28. package/dist/bigconsole/components/widgets/WidgetWrapper.js +227 -226
  29. package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
  30. package/dist/bigconsole/pages/DashboardBuilderPage.js +221 -316
  31. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  32. package/dist/bigconsole/utils/widgetBinding.js +115 -0
  33. package/dist/bigconsole/utils/widgetBinding.js.map +1 -0
  34. package/package.json +2 -2
  35. package/dist/bigconsole/components/widgets/WidgetConfigDialog.js +0 -883
  36. package/dist/bigconsole/components/widgets/WidgetConfigDialog.js.map +0 -1
  37. package/dist/bigconsole/components/widgets/WidgetTypeSelector.js +0 -311
  38. package/dist/bigconsole/components/widgets/WidgetTypeSelector.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WidgetPalette.js","names":[],"sources":["../../../../src/bigconsole/components/dashboard/WidgetPalette.tsx"],"sourcesContent":["/**\n * WidgetPalette Component\n *\n * Sidebar panel with draggable widget types for the dashboard builder.\n * Uses semantic tokens for consistent theming.\n * Features categorized widgets, search, and drag-and-drop support.\n */\n\nimport { type FC, memo, useState, useCallback, useMemo } from 'react';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n ChevronDown,\n ChevronRight,\n TrendingUp,\n BarChart3,\n Filter,\n Table,\n Grid3x3,\n Gauge,\n Activity,\n List,\n FileText,\n Type,\n ExternalLink,\n MapPin,\n Calendar,\n Columns,\n GitBranch,\n Puzzle,\n LayoutDashboard,\n GripVertical,\n X,\n Layers,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n getWidgetCategories,\n getWidgetKey,\n WIDGET_CATEGORY_LABELS,\n type WidgetDefinition,\n} from '../widgets/WidgetRegistry';\nimport type { WidgetType, WidgetCategory } from '../../types';\n\n// ============================================================================\n// Icon Mapping\n// ============================================================================\n\nconst ICON_MAP: Record<string, LucideIcon> = {\n TrendingUp,\n BarChart3,\n Filter,\n Table,\n Grid3x3,\n Gauge,\n Activity,\n List,\n FileText,\n Type,\n ExternalLink,\n MapPin,\n Calendar,\n Columns,\n GitBranch,\n Puzzle,\n LayoutDashboard,\n};\n\nfunction getIconComponent(iconName: string): LucideIcon {\n return ICON_MAP[iconName] || Puzzle;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetPaletteProps {\n /** Whether the palette is open */\n isOpen: boolean;\n /** Callback to close the palette */\n onClose: () => void;\n /** Callback when a widget is selected (for quick add without drag) */\n onWidgetSelect?: (type: WidgetType, definition?: WidgetDefinition) => void;\n /** Callback when drag starts */\n onDragStart?: (type: WidgetType, definition: WidgetDefinition) => void;\n /** Callback when drag ends */\n onDragEnd?: () => void;\n /** Installed widgets from the store (fetched by parent) */\n installedWidgets?: WidgetDefinition[];\n /** Whether installed widgets are still loading */\n installedWidgetsLoading?: boolean;\n /**\n * Built-in widget catalog (from the backend `getWidgetTypes`, fetched by the\n * parent via useWidgetCatalog). When omitted, falls back to the bundled\n * static registry.\n */\n definitions?: WidgetDefinition[];\n}\n\n// ============================================================================\n// Styles using semantic tokens\n// ============================================================================\n\nconst styles = {\n container: {\n width: '300px',\n height: '100%',\n backgroundColor: 'var(--color-bg-surface)',\n borderRight: '1px solid var(--color-border)',\n display: 'flex',\n flexDirection: 'column' as const,\n flexShrink: 0,\n overflow: 'hidden',\n position: 'relative' as const,\n },\n header: {\n padding: 'var(--space-formGap)',\n borderBottom: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-sunken)',\n flexShrink: 0,\n },\n headerTop: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: 'var(--space-controlGap)',\n },\n headerTitle: {\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n },\n headerIcon: {\n width: '32px',\n height: '32px',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-action-primary-bg)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n title: {\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-semibold)' as const,\n color: 'var(--color-text-primary)',\n margin: 0,\n },\n subtitle: {\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n margin: '2px 0 0 0',\n },\n closeButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n border: 'none',\n background: 'transparent',\n borderRadius: 'var(--radius-button)',\n cursor: 'pointer',\n color: 'var(--color-text-secondary)',\n transition: 'background-color 0.15s',\n },\n searchContainer: {\n position: 'relative' as const,\n },\n searchIcon: {\n position: 'absolute' as const,\n left: '10px',\n top: '50%',\n transform: 'translateY(-50%)',\n width: '16px',\n height: '16px',\n color: 'var(--color-text-muted)',\n pointerEvents: 'none' as const,\n },\n searchInput: {\n width: '100%',\n paddingLeft: '36px',\n height: 'var(--size-controlHeight-sm)',\n fontSize: 'var(--font-size-body-sm)',\n },\n content: {\n flex: '1 1 0',\n minHeight: 0,\n overflow: 'hidden',\n position: 'relative' as const,\n },\n scrollArea: {\n position: 'absolute' as const,\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n overflowY: 'auto' as const,\n overflowX: 'hidden' as const,\n padding: 'var(--space-controlGap)',\n },\n categoryContainer: {\n marginBottom: 'var(--space-controlGap)',\n },\n categoryHeader: {\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-controlGap) var(--space-iconGap)',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n borderRadius: 'var(--radius-button)',\n transition: 'background-color 0.15s',\n },\n categoryChevron: {\n width: '16px',\n height: '16px',\n color: 'var(--color-text-muted)',\n flexShrink: 0,\n },\n categoryLabel: {\n flex: 1,\n textAlign: 'left' as const,\n fontSize: 'var(--font-size-body-xs)',\n fontWeight: 'var(--font-weight-semibold)' as const,\n color: 'var(--color-text-secondary)',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n },\n categoryCount: {\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n backgroundColor: 'var(--color-bg-sunken)',\n padding: '2px 8px',\n borderRadius: 'var(--radius-full)',\n },\n widgetList: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '4px',\n marginTop: 'var(--space-controlGap)',\n paddingLeft: '4px',\n },\n widgetCard: {\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-controlGap)',\n borderRadius: 'var(--radius-card)',\n cursor: 'grab',\n backgroundColor: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border)',\n transition: 'all 0.15s ease',\n },\n widgetCardHover: {\n backgroundColor: 'var(--color-bg-hover)',\n borderColor: 'var(--color-action-primary-border)',\n boxShadow: 'var(--shadow-elevation-1)',\n },\n dragHandle: {\n width: '16px',\n height: '16px',\n color: 'var(--color-text-muted)',\n opacity: 0.5,\n flexShrink: 0,\n },\n widgetIcon: {\n width: '36px',\n height: '36px',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-bg-sunken)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n },\n widgetIconInner: {\n width: '18px',\n height: '18px',\n color: 'var(--color-action-primary-bg)',\n },\n widgetText: {\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n },\n widgetName: {\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)' as const,\n color: 'var(--color-text-primary)',\n whiteSpace: 'nowrap' as const,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n marginBottom: '2px',\n },\n widgetDescription: {\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n lineHeight: 1.3,\n overflow: 'hidden',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical' as const,\n },\n emptyState: {\n textAlign: 'center' as const,\n padding: 'var(--space-pagePadding)',\n },\n emptyIcon: {\n width: '48px',\n height: '48px',\n borderRadius: 'var(--radius-card)',\n backgroundColor: 'var(--color-bg-sunken)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto var(--space-formGap)',\n },\n emptyText: {\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n margin: 0,\n },\n clearButton: {\n marginTop: 'var(--space-controlGap)',\n padding: 'var(--space-controlGap) var(--space-formGap)',\n fontSize: 'var(--font-size-body-xs)',\n fontWeight: 'var(--font-weight-medium)' as const,\n color: 'var(--color-action-primary-text)',\n backgroundColor: 'var(--color-action-primary-bg)',\n border: 'none',\n borderRadius: 'var(--radius-button)',\n cursor: 'pointer',\n },\n footer: {\n padding: 'var(--space-controlGap) var(--space-formGap)',\n borderTop: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-sunken)',\n flexShrink: 0,\n },\n footerText: {\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n margin: 0,\n textAlign: 'center' as const,\n },\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const WidgetPalette: FC<WidgetPaletteProps> = memo(function WidgetPalette({\n isOpen,\n onClose,\n onWidgetSelect,\n onDragStart,\n onDragEnd,\n installedWidgets = [],\n installedWidgetsLoading = false,\n definitions,\n}) {\n const [searchQuery, setSearchQuery] = useState('');\n const [expandedCategories, setExpandedCategories] = useState<Set<WidgetCategory>>(\n new Set(['KPI', 'Visualization', 'Data', 'Content', 'Temporal', 'Custom', 'Installed'])\n );\n const [hoveredWidget, setHoveredWidget] = useState<string | null>(null);\n\n // Get categorized widgets, merging in installed widgets. When the parent\n // supplies a backend-sourced catalog (`definitions`), group that by category;\n // otherwise fall back to the bundled static registry.\n const categories = useMemo(() => {\n const baseCategories = definitions\n ? (Object.keys(WIDGET_CATEGORY_LABELS) as WidgetCategory[]).map((category) => ({\n category,\n label: WIDGET_CATEGORY_LABELS[category],\n widgets: definitions.filter((def) => def.category === category),\n }))\n : getWidgetCategories();\n\n return baseCategories\n .map((cat) => {\n if (cat.category === 'Installed') {\n // Two sources feed \"Installed from Store\": the registry-driven backend\n // catalog (getWidgetTypes store types — rich metadata, install-gated,\n // BOFF-2858) which arrives via `definitions` under this category, and\n // the legacy workspaceInstalledApps listing passed as `installedWidgets`.\n // Merge both, deduping by name (the catalog entry wins) so a widget\n // present in both sources shows once with the richer definition, while\n // legacy installs not yet in the registry are still preserved.\n const byName = new Map<string, WidgetDefinition>();\n for (const w of installedWidgets) byName.set(w.name.toLowerCase(), w);\n for (const w of cat.widgets) {\n const key = w.name.toLowerCase();\n const legacy = byName.get(key);\n // Catalog wins for metadata but MERGE defaultConfig so the legacy\n // workspaceInstalledApps fields survive — notably `componentId`, which the\n // current render path needs and the catalog store entry lacks until\n // widgetTypeKey rendering is wired. Keeps overlapping store widgets renderable.\n byName.set(key, legacy ? { ...w, defaultConfig: { ...legacy.defaultConfig, ...w.defaultConfig } } : w);\n }\n return { ...cat, widgets: Array.from(byName.values()) };\n }\n return cat;\n })\n .filter((cat) => cat.category !== 'Installed' || cat.widgets.length > 0);\n }, [installedWidgets, definitions]);\n\n // Filter widgets by search query\n const filteredCategories = useMemo(() => {\n if (!searchQuery.trim()) {\n return categories;\n }\n\n const query = searchQuery.toLowerCase();\n return categories\n .map((cat) => ({\n ...cat,\n widgets: cat.widgets.filter(\n (w) =>\n w.name.toLowerCase().includes(query) ||\n w.description.toLowerCase().includes(query) ||\n w.tags.some((tag) => tag.includes(query))\n ),\n }))\n .filter((cat) => cat.widgets.length > 0);\n }, [categories, searchQuery]);\n\n // Toggle category expansion\n const toggleCategory = useCallback((category: WidgetCategory) => {\n setExpandedCategories((prev) => {\n const next = new Set(prev);\n if (next.has(category)) {\n next.delete(category);\n } else {\n next.add(category);\n }\n return next;\n });\n }, []);\n\n // Handle drag start\n const handleDragStart = useCallback(\n (e: React.DragEvent, widget: WidgetDefinition) => {\n e.dataTransfer.setData(\n 'application/json',\n JSON.stringify({\n type: widget.type,\n name: widget.name,\n defaultSize: widget.defaultSize,\n defaultConfig: widget.defaultConfig,\n category: widget.category,\n })\n );\n e.dataTransfer.effectAllowed = 'copy';\n\n // Create custom drag image\n const dragImage = document.createElement('div');\n dragImage.style.cssText = `\n position: absolute;\n top: -1000px;\n left: -1000px;\n padding: 8px 12px;\n background: var(--color-bg-surface);\n border: 2px solid var(--color-action-primary-bg);\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--color-text-primary);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n `;\n dragImage.textContent = widget.name;\n document.body.appendChild(dragImage);\n e.dataTransfer.setDragImage(dragImage, 0, 0);\n\n setTimeout(() => {\n document.body.removeChild(dragImage);\n }, 0);\n\n onDragStart?.(widget.type, widget);\n },\n [onDragStart]\n );\n\n // Handle drag end\n const handleDragEnd = useCallback(() => {\n onDragEnd?.();\n }, [onDragEnd]);\n\n // Handle click to quick-add\n const handleWidgetClick = useCallback(\n (widget: WidgetDefinition) => {\n onWidgetSelect?.(widget.type, widget);\n },\n [onWidgetSelect]\n );\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <div style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n <div style={styles.headerTop}>\n <div style={styles.headerTitle}>\n <div style={styles.headerIcon}>\n <Layers style={{ width: '18px', height: '18px', color: 'var(--color-action-primary-text)' }} />\n </div>\n <div>\n <h3 style={styles.title}>Widgets</h3>\n <p style={styles.subtitle}>Drag or click to add</p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n style={styles.closeButton}\n onMouseOver={(e) => (e.currentTarget.style.backgroundColor = 'var(--color-bg-hover)')}\n onMouseOut={(e) => (e.currentTarget.style.backgroundColor = 'transparent')}\n >\n <X style={{ width: '16px', height: '16px' }} />\n </button>\n </div>\n\n {/* Search */}\n <div style={styles.searchContainer}>\n <Search style={styles.searchIcon} />\n <Input\n type=\"text\"\n placeholder=\"Search widgets...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={styles.searchInput}\n />\n </div>\n </div>\n\n {/* Widget Categories */}\n <div style={styles.content}>\n <div style={styles.scrollArea}>\n {filteredCategories.map((category) => (\n <div key={category.category} style={styles.categoryContainer}>\n {/* Category Header */}\n <button\n type=\"button\"\n onClick={() => toggleCategory(category.category)}\n style={styles.categoryHeader}\n onMouseOver={(e) => (e.currentTarget.style.backgroundColor = 'var(--color-bg-hover)')}\n onMouseOut={(e) => (e.currentTarget.style.backgroundColor = 'transparent')}\n >\n {expandedCategories.has(category.category) ? (\n <ChevronDown style={styles.categoryChevron} />\n ) : (\n <ChevronRight style={styles.categoryChevron} />\n )}\n <span style={styles.categoryLabel}>{category.label}</span>\n <span style={styles.categoryCount}>{category.widgets.length}</span>\n </button>\n\n {/* Widget Items */}\n {expandedCategories.has(category.category) && (\n <div style={styles.widgetList}>\n {installedWidgetsLoading && category.category === 'Installed' && (\n <div\n style={{\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n padding: 'var(--space-controlGap)',\n }}\n >\n Loading...\n </div>\n )}\n {category.widgets.map((widget) => {\n const IconComponent = getIconComponent(widget.icon);\n const widgetKey = getWidgetKey(widget);\n const isHovered = hoveredWidget === widgetKey;\n\n return (\n <div\n key={widgetKey}\n draggable\n onDragStart={(e) => handleDragStart(e, widget)}\n onDragEnd={handleDragEnd}\n onClick={() => handleWidgetClick(widget)}\n onMouseEnter={() => setHoveredWidget(widgetKey)}\n onMouseLeave={() => setHoveredWidget(null)}\n style={{\n ...styles.widgetCard,\n ...(isHovered ? styles.widgetCardHover : {}),\n }}\n >\n {/* Drag Handle */}\n <GripVertical style={styles.dragHandle} />\n\n {/* Icon */}\n <div style={styles.widgetIcon}>\n <IconComponent style={styles.widgetIconInner} />\n </div>\n\n {/* Text */}\n <div style={styles.widgetText}>\n <div style={styles.widgetName}>{widget.name}</div>\n <div style={styles.widgetDescription}>{widget.description}</div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n ))}\n\n {filteredCategories.length === 0 && (\n <div style={styles.emptyState}>\n <div style={styles.emptyIcon}>\n <Search style={{ width: '24px', height: '24px', color: 'var(--color-text-muted)' }} />\n </div>\n <p style={styles.emptyText}>\n No widgets found for \"<strong>{searchQuery}</strong>\"\n </p>\n <button type=\"button\" onClick={() => setSearchQuery('')} style={styles.clearButton}>\n Clear search\n </button>\n </div>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <div style={styles.footer}>\n <p style={styles.footerText}>Drag widgets to position them on the canvas</p>\n </div>\n </div>\n );\n});\n\nexport default WidgetPalette;\n"],"mappings":"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"}
1
+ {"version":3,"file":"WidgetPalette.js","names":[],"sources":["../../../../src/bigconsole/components/dashboard/WidgetPalette.tsx"],"sourcesContent":["/**\n * WidgetPalette Component\n *\n * Sidebar panel with draggable widget types for the dashboard builder.\n * Uses semantic tokens for consistent theming.\n * Features categorized widgets, search, and drag-and-drop support.\n */\n\nimport { type FC, memo, useState, useCallback, useMemo } from 'react';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n ChevronDown,\n ChevronRight,\n TrendingUp,\n BarChart3,\n Filter,\n Table,\n Grid3x3,\n Gauge,\n Activity,\n List,\n FileText,\n Type,\n ExternalLink,\n MapPin,\n Calendar,\n Columns,\n GitBranch,\n Puzzle,\n LayoutDashboard,\n GripVertical,\n X,\n Layers,\n Store,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n getWidgetCategories,\n getWidgetKey,\n WIDGET_CATEGORY_LABELS,\n type WidgetDefinition,\n} from '../widgets/WidgetRegistry';\nimport type { WidgetType, WidgetCategory } from '../../types';\n\n// ============================================================================\n// Icon Mapping\n// ============================================================================\n\nconst ICON_MAP: Record<string, LucideIcon> = {\n TrendingUp,\n BarChart3,\n Filter,\n Table,\n Grid3x3,\n Gauge,\n Activity,\n List,\n FileText,\n Type,\n ExternalLink,\n MapPin,\n Calendar,\n Columns,\n GitBranch,\n Puzzle,\n LayoutDashboard,\n};\n\nfunction getIconComponent(iconName: string): LucideIcon {\n return ICON_MAP[iconName] || Puzzle;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetPaletteProps {\n /** Whether the palette is open */\n isOpen: boolean;\n /** Callback to close the palette */\n onClose: () => void;\n /** Callback when a widget is selected (for quick add without drag) */\n onWidgetSelect?: (type: WidgetType, definition?: WidgetDefinition) => void;\n /** Callback when drag starts */\n onDragStart?: (type: WidgetType, definition: WidgetDefinition) => void;\n /** Callback when drag ends */\n onDragEnd?: () => void;\n /** Installed widgets from the store (fetched by parent) */\n installedWidgets?: WidgetDefinition[];\n /** Whether installed widgets are still loading */\n installedWidgetsLoading?: boolean;\n /**\n * Built-in widget catalog (from the backend `getWidgetTypes`, fetched by the\n * parent via useWidgetCatalog). When omitted, falls back to the bundled\n * static registry.\n */\n definitions?: WidgetDefinition[];\n}\n\n// ============================================================================\n// Styles using semantic tokens\n// ============================================================================\n\nconst styles = {\n container: {\n width: '300px',\n height: '100%',\n backgroundColor: 'var(--color-bg-surface)',\n borderRight: '1px solid var(--color-border)',\n display: 'flex',\n flexDirection: 'column' as const,\n flexShrink: 0,\n overflow: 'hidden',\n position: 'relative' as const,\n },\n header: {\n padding: 'var(--space-formGap)',\n borderBottom: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-sunken)',\n flexShrink: 0,\n },\n headerTop: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: 'var(--space-controlGap)',\n },\n headerTitle: {\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n },\n headerIcon: {\n width: '32px',\n height: '32px',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-action-primary-bg)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n title: {\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-semibold)' as const,\n color: 'var(--color-text-primary)',\n margin: 0,\n },\n subtitle: {\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n margin: '2px 0 0 0',\n },\n closeButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n border: 'none',\n background: 'transparent',\n borderRadius: 'var(--radius-button)',\n cursor: 'pointer',\n color: 'var(--color-text-secondary)',\n transition: 'background-color 0.15s',\n },\n searchContainer: {\n position: 'relative' as const,\n },\n searchIcon: {\n position: 'absolute' as const,\n left: '10px',\n top: '50%',\n transform: 'translateY(-50%)',\n width: '16px',\n height: '16px',\n color: 'var(--color-text-muted)',\n pointerEvents: 'none' as const,\n },\n searchInput: {\n width: '100%',\n paddingLeft: '36px',\n height: 'var(--size-controlHeight-sm)',\n fontSize: 'var(--font-size-body-sm)',\n },\n content: {\n flex: '1 1 0',\n minHeight: 0,\n overflow: 'hidden',\n position: 'relative' as const,\n },\n scrollArea: {\n position: 'absolute' as const,\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n overflowY: 'auto' as const,\n overflowX: 'hidden' as const,\n padding: 'var(--space-controlGap)',\n },\n categoryContainer: {\n marginBottom: 'var(--space-controlGap)',\n },\n categoryHeader: {\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-controlGap) var(--space-iconGap)',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n borderRadius: 'var(--radius-button)',\n transition: 'background-color 0.15s',\n },\n categoryChevron: {\n width: '16px',\n height: '16px',\n color: 'var(--color-text-muted)',\n flexShrink: 0,\n },\n categoryLabel: {\n flex: 1,\n textAlign: 'left' as const,\n fontSize: 'var(--font-size-body-xs)',\n fontWeight: 'var(--font-weight-semibold)' as const,\n color: 'var(--color-text-secondary)',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n },\n categoryCount: {\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n backgroundColor: 'var(--color-bg-sunken)',\n padding: '2px 8px',\n borderRadius: 'var(--radius-full)',\n },\n widgetList: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '4px',\n marginTop: 'var(--space-controlGap)',\n paddingLeft: '4px',\n },\n widgetCard: {\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-controlGap)',\n borderRadius: 'var(--radius-card)',\n cursor: 'grab',\n backgroundColor: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border)',\n transition: 'all 0.15s ease',\n },\n widgetCardHover: {\n backgroundColor: 'var(--color-bg-hover)',\n borderColor: 'var(--color-action-primary-border)',\n boxShadow: 'var(--shadow-elevation-1)',\n },\n dragHandle: {\n width: '16px',\n height: '16px',\n color: 'var(--color-text-muted)',\n opacity: 0.5,\n flexShrink: 0,\n },\n widgetIcon: {\n width: '36px',\n height: '36px',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-bg-sunken)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n },\n widgetIconInner: {\n width: '18px',\n height: '18px',\n color: 'var(--color-action-primary-bg)',\n },\n widgetText: {\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n },\n widgetName: {\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)' as const,\n color: 'var(--color-text-primary)',\n whiteSpace: 'nowrap' as const,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n marginBottom: '2px',\n },\n widgetDescription: {\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n lineHeight: 1.3,\n overflow: 'hidden',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical' as const,\n },\n emptyState: {\n textAlign: 'center' as const,\n padding: 'var(--space-pagePadding)',\n },\n emptyIcon: {\n width: '48px',\n height: '48px',\n borderRadius: 'var(--radius-card)',\n backgroundColor: 'var(--color-bg-sunken)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto var(--space-formGap)',\n },\n emptyText: {\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n margin: 0,\n },\n clearButton: {\n marginTop: 'var(--space-controlGap)',\n padding: 'var(--space-controlGap) var(--space-formGap)',\n fontSize: 'var(--font-size-body-xs)',\n fontWeight: 'var(--font-weight-medium)' as const,\n color: 'var(--color-action-primary-text)',\n backgroundColor: 'var(--color-action-primary-bg)',\n border: 'none',\n borderRadius: 'var(--radius-button)',\n cursor: 'pointer',\n },\n footer: {\n padding: 'var(--space-controlGap) var(--space-formGap)',\n borderTop: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-sunken)',\n flexShrink: 0,\n },\n footerText: {\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n margin: 0,\n textAlign: 'center' as const,\n },\n browseStoreButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-iconGap)',\n width: '100%',\n padding: 'var(--space-controlGap)',\n marginBottom: 'var(--space-controlGap)',\n borderRadius: 'var(--radius-button)',\n border: '1px dashed var(--color-border)',\n backgroundColor: 'transparent',\n color: 'var(--color-text-secondary)',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)' as const,\n cursor: 'pointer',\n transition: 'border-color 0.15s, color 0.15s',\n },\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const WidgetPalette: FC<WidgetPaletteProps> = memo(function WidgetPalette({\n isOpen,\n onClose,\n onWidgetSelect,\n onDragStart,\n onDragEnd,\n installedWidgets = [],\n installedWidgetsLoading = false,\n definitions,\n}) {\n const [searchQuery, setSearchQuery] = useState('');\n const [expandedCategories, setExpandedCategories] = useState<Set<WidgetCategory>>(\n new Set(['KPI', 'Visualization', 'Data', 'Content', 'Temporal', 'Custom', 'Installed'])\n );\n const [hoveredWidget, setHoveredWidget] = useState<string | null>(null);\n\n // Get categorized widgets, merging in installed widgets. When the parent\n // supplies a backend-sourced catalog (`definitions`), group that by category;\n // otherwise fall back to the bundled static registry.\n const categories = useMemo(() => {\n const baseCategories = definitions\n ? (Object.keys(WIDGET_CATEGORY_LABELS) as WidgetCategory[]).map((category) => ({\n category,\n label: WIDGET_CATEGORY_LABELS[category],\n widgets: definitions.filter((def) => def.category === category),\n }))\n : getWidgetCategories();\n\n return baseCategories\n .map((cat) => {\n if (cat.category === 'Installed') {\n // Two sources feed \"Installed from Store\": the registry-driven backend\n // catalog (getWidgetTypes store types — rich metadata, install-gated,\n // BOFF-2858) which arrives via `definitions` under this category, and\n // the legacy workspaceInstalledApps listing passed as `installedWidgets`.\n // Merge both, deduping by name (the catalog entry wins) so a widget\n // present in both sources shows once with the richer definition, while\n // legacy installs not yet in the registry are still preserved.\n const byName = new Map<string, WidgetDefinition>();\n for (const w of installedWidgets) byName.set(w.name.toLowerCase(), w);\n for (const w of cat.widgets) {\n const key = w.name.toLowerCase();\n const legacy = byName.get(key);\n // Catalog wins for metadata but MERGE defaultConfig so the legacy\n // workspaceInstalledApps fields survive — notably `componentId`, which the\n // current render path needs and the catalog store entry lacks until\n // widgetTypeKey rendering is wired. Keeps overlapping store widgets renderable.\n byName.set(key, legacy ? { ...w, defaultConfig: { ...legacy.defaultConfig, ...w.defaultConfig } } : w);\n }\n return { ...cat, widgets: Array.from(byName.values()) };\n }\n return cat;\n })\n .filter((cat) => cat.category !== 'Installed' || cat.widgets.length > 0);\n }, [installedWidgets, definitions]);\n\n // Filter widgets by search query\n const filteredCategories = useMemo(() => {\n if (!searchQuery.trim()) {\n return categories;\n }\n\n const query = searchQuery.toLowerCase();\n return categories\n .map((cat) => ({\n ...cat,\n widgets: cat.widgets.filter(\n (w) =>\n w.name.toLowerCase().includes(query) ||\n w.description.toLowerCase().includes(query) ||\n w.tags.some((tag) => tag.includes(query))\n ),\n }))\n .filter((cat) => cat.widgets.length > 0);\n }, [categories, searchQuery]);\n\n // Toggle category expansion\n const toggleCategory = useCallback((category: WidgetCategory) => {\n setExpandedCategories((prev) => {\n const next = new Set(prev);\n if (next.has(category)) {\n next.delete(category);\n } else {\n next.add(category);\n }\n return next;\n });\n }, []);\n\n // Handle drag start\n const handleDragStart = useCallback(\n (e: React.DragEvent, widget: WidgetDefinition) => {\n e.dataTransfer.setData(\n 'application/json',\n JSON.stringify({\n type: widget.type,\n name: widget.name,\n defaultSize: widget.defaultSize,\n defaultConfig: widget.defaultConfig,\n category: widget.category,\n })\n );\n e.dataTransfer.effectAllowed = 'copy';\n\n // Create custom drag image\n const dragImage = document.createElement('div');\n dragImage.style.cssText = `\n position: absolute;\n top: -1000px;\n left: -1000px;\n padding: 8px 12px;\n background: var(--color-bg-surface);\n border: 2px solid var(--color-action-primary-bg);\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--color-text-primary);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n `;\n dragImage.textContent = widget.name;\n document.body.appendChild(dragImage);\n e.dataTransfer.setDragImage(dragImage, 0, 0);\n\n setTimeout(() => {\n document.body.removeChild(dragImage);\n }, 0);\n\n onDragStart?.(widget.type, widget);\n },\n [onDragStart]\n );\n\n // Handle drag end\n const handleDragEnd = useCallback(() => {\n onDragEnd?.();\n }, [onDragEnd]);\n\n // Handle click to quick-add\n const handleWidgetClick = useCallback(\n (widget: WidgetDefinition) => {\n onWidgetSelect?.(widget.type, widget);\n },\n [onWidgetSelect]\n );\n\n // Open the widget store in a new tab so the builder (and any unsaved edits)\n // stays intact. Preserves the current org/workspace/project query params.\n const handleBrowseStore = useCallback(() => {\n if (typeof window === 'undefined') return;\n const url = `${window.location.origin}/bigconsole/store${window.location.search}`;\n window.open(url, '_blank', 'noopener,noreferrer');\n }, []);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <div style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n <div style={styles.headerTop}>\n <div style={styles.headerTitle}>\n <div style={styles.headerIcon}>\n <Layers style={{ width: '18px', height: '18px', color: 'var(--color-action-primary-text)' }} />\n </div>\n <div>\n <h3 style={styles.title}>Widgets</h3>\n <p style={styles.subtitle}>Drag or click to add</p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n style={styles.closeButton}\n onMouseOver={(e) => (e.currentTarget.style.backgroundColor = 'var(--color-bg-hover)')}\n onMouseOut={(e) => (e.currentTarget.style.backgroundColor = 'transparent')}\n >\n <X style={{ width: '16px', height: '16px' }} />\n </button>\n </div>\n\n {/* Search */}\n <div style={styles.searchContainer}>\n <Search style={styles.searchIcon} />\n <Input\n type=\"text\"\n placeholder=\"Search widgets...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={styles.searchInput}\n />\n </div>\n </div>\n\n {/* Widget Categories */}\n <div style={styles.content}>\n <div style={styles.scrollArea}>\n {filteredCategories.map((category) => (\n <div key={category.category} style={styles.categoryContainer}>\n {/* Category Header */}\n <button\n type=\"button\"\n onClick={() => toggleCategory(category.category)}\n style={styles.categoryHeader}\n onMouseOver={(e) => (e.currentTarget.style.backgroundColor = 'var(--color-bg-hover)')}\n onMouseOut={(e) => (e.currentTarget.style.backgroundColor = 'transparent')}\n >\n {expandedCategories.has(category.category) ? (\n <ChevronDown style={styles.categoryChevron} />\n ) : (\n <ChevronRight style={styles.categoryChevron} />\n )}\n <span style={styles.categoryLabel}>{category.label}</span>\n <span style={styles.categoryCount}>{category.widgets.length}</span>\n </button>\n\n {/* Widget Items */}\n {expandedCategories.has(category.category) && (\n <div style={styles.widgetList}>\n {installedWidgetsLoading && category.category === 'Installed' && (\n <div\n style={{\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n padding: 'var(--space-controlGap)',\n }}\n >\n Loading...\n </div>\n )}\n {category.widgets.map((widget) => {\n const IconComponent = getIconComponent(widget.icon);\n const widgetKey = getWidgetKey(widget);\n const isHovered = hoveredWidget === widgetKey;\n\n return (\n <div\n key={widgetKey}\n draggable\n onDragStart={(e) => handleDragStart(e, widget)}\n onDragEnd={handleDragEnd}\n onClick={() => handleWidgetClick(widget)}\n onMouseEnter={() => setHoveredWidget(widgetKey)}\n onMouseLeave={() => setHoveredWidget(null)}\n style={{\n ...styles.widgetCard,\n ...(isHovered ? styles.widgetCardHover : {}),\n }}\n >\n {/* Drag Handle */}\n <GripVertical style={styles.dragHandle} />\n\n {/* Icon */}\n <div style={styles.widgetIcon}>\n <IconComponent style={styles.widgetIconInner} />\n </div>\n\n {/* Text */}\n <div style={styles.widgetText}>\n <div style={styles.widgetName}>{widget.name}</div>\n <div style={styles.widgetDescription}>{widget.description}</div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n ))}\n\n {filteredCategories.length === 0 && (\n <div style={styles.emptyState}>\n <div style={styles.emptyIcon}>\n <Search style={{ width: '24px', height: '24px', color: 'var(--color-text-muted)' }} />\n </div>\n <p style={styles.emptyText}>\n No widgets found for \"<strong>{searchQuery}</strong>\"\n </p>\n <button type=\"button\" onClick={() => setSearchQuery('')} style={styles.clearButton}>\n Clear search\n </button>\n </div>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <div style={styles.footer}>\n <button\n type=\"button\"\n onClick={handleBrowseStore}\n style={styles.browseStoreButton}\n onMouseOver={(e) => {\n e.currentTarget.style.borderColor = 'var(--color-action-primary-bg)';\n e.currentTarget.style.color = 'var(--color-action-primary-text)';\n }}\n onMouseOut={(e) => {\n e.currentTarget.style.borderColor = 'var(--color-border)';\n e.currentTarget.style.color = 'var(--color-text-secondary)';\n }}\n >\n <Store style={{ width: '15px', height: '15px' }} />\n Browse widget store\n <ExternalLink style={{ width: '13px', height: '13px', opacity: 0.7 }} />\n </button>\n <p style={styles.footerText}>Drag widgets to position them on the canvas</p>\n </div>\n </div>\n );\n});\n\nexport default WidgetPalette;\n"],"mappings":"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"}
@@ -12,6 +12,10 @@ import "./PageTabsManager/index.js";
12
12
  import "./ShareDialog/ShareDialog.js";
13
13
  import "./ShareDialog/index.js";
14
14
  import "./WidgetPalette.js";
15
+ import "../builder/BuilderCanvas.js";
16
+ import "../builder/BuilderTopbar.js";
17
+ import "../builder/DashboardEditorShell.js";
18
+ import "../builder/index.js";
15
19
  import "./DashboardCanvas.js";
16
20
  import "./LiveCanvasToggle.js";
17
21
  import "./TemplatePicker/TemplatePicker.js";