@burdenoff/microfe-bigconsole 2026.805.2 → 2026.805.3

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 (134) hide show
  1. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +109 -113
  2. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
  3. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +115 -113
  4. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  5. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +71 -62
  6. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  7. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +90 -89
  8. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  9. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +56 -54
  10. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
  11. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +126 -125
  12. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
  13. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +151 -150
  14. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
  15. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +77 -76
  16. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
  17. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +97 -96
  18. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  19. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +172 -191
  20. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  21. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +75 -83
  22. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js.map +1 -1
  23. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +151 -154
  24. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
  25. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +181 -190
  26. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
  27. package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -0
  28. package/dist/bigconsole/components/dashboard/WidgetPalette.js +110 -108
  29. package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
  30. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +102 -103
  31. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  32. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +36 -41
  33. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  34. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +38 -37
  35. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  36. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +113 -117
  37. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
  38. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +182 -197
  39. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  40. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +166 -168
  41. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  42. package/dist/bigconsole/components/parser/DataSinkSelector.js +87 -86
  43. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  44. package/dist/bigconsole/components/parser/ImportParserDialog.js +196 -211
  45. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  46. package/dist/bigconsole/components/parser/ParserSelector.js +130 -128
  47. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  48. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +66 -63
  49. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
  50. package/dist/bigconsole/components/preview/AiPreviewPanel.js +95 -91
  51. package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
  52. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +222 -215
  53. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  54. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +149 -145
  55. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  56. package/dist/bigconsole/components/widgets/PropertiesPanel.js +504 -470
  57. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  58. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +44 -47
  59. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  60. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +143 -142
  61. package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
  62. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +101 -88
  63. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  64. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +135 -134
  65. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
  66. package/dist/bigconsole/components/widgets/form/FormWidget.js +167 -159
  67. package/dist/bigconsole/components/widgets/form/FormWidget.js.map +1 -1
  68. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +69 -68
  69. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
  70. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +64 -72
  71. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
  72. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +60 -59
  73. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  74. package/dist/bigconsole/components/widgets/list/ListConfig.js +57 -56
  75. package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
  76. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +70 -69
  77. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
  78. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +35 -34
  79. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
  80. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +20 -19
  81. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
  82. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +178 -177
  83. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  84. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +76 -75
  85. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  86. package/dist/bigconsole/components/widgets/table/TableConfig.js +183 -168
  87. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  88. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +187 -180
  89. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
  90. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +40 -38
  91. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
  92. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +150 -148
  93. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  94. package/dist/bigconsole/pages/DashboardBuilderPage.js +181 -176
  95. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  96. package/dist/bigconsole/pages/DashboardViewPage.js +196 -192
  97. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  98. package/dist/bigconsole/pages/DashboardsPage.js +223 -219
  99. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  100. package/dist/bigconsole/pages/DataParsersPage.js +167 -170
  101. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  102. package/dist/bigconsole/pages/DataSinkBuilderPage.js +204 -189
  103. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  104. package/dist/bigconsole/pages/DataSinkViewPage.js +175 -169
  105. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  106. package/dist/bigconsole/pages/DataSourcesPage.js +8 -7
  107. package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
  108. package/dist/bigconsole/pages/InsightsPage.js +238 -208
  109. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  110. package/dist/bigconsole/pages/ParserBuilderPage.js +464 -412
  111. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  112. package/dist/bigconsole/pages/ParserViewPage.js +92 -90
  113. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  114. package/dist/bigconsole/pages/PipelineBuilderPage.js +221 -194
  115. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  116. package/dist/bigconsole/pages/PipelineViewPage.js +181 -184
  117. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  118. package/dist/bigconsole/pages/PipelinesPage.js +128 -127
  119. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  120. package/dist/bigconsole/pages/SettingsPage.js +177 -172
  121. package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
  122. package/dist/bigconsole/pages/WidgetDemoPage.js +121 -83
  123. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  124. package/dist/bigconsole/pages/WorkflowViewPage.js +199 -193
  125. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  126. package/dist/bigconsole/pages/WorkflowsPage.js +129 -128
  127. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  128. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +111 -109
  129. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
  130. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +127 -126
  131. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
  132. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +103 -103
  133. package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
  134. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CreateDashboardDialog.js","names":[],"sources":["../../../../src/bigconsole/components/dashboard/CreateDashboardDialog.tsx"],"sourcesContent":["/**\n * CreateDashboardDialog Component\n *\n * Modal dialog for creating a new dashboard with name and description.\n * Uses fe-libs shared UI components and semantic tokens for consistent styling.\n * Phase 2: Added TemplatePicker integration for creating from templates.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect, useRef, type KeyboardEvent } from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Textarea } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { Plus, LayoutDashboard, Copy, X, Tag } from 'lucide-react';\nimport { StoreTemplatePicker } from './StoreTemplatePicker';\nimport { useStoreDashboardTemplates, type StoreDashboardTemplate } from '../../hooks/useStoreDashboardTemplates';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CreateDashboardDialogProps {\n isOpen: boolean;\n isCreating?: boolean;\n onClose: () => void;\n onCreate: (data: {\n name: string;\n description: string;\n category: string;\n tags?: string[];\n templateId?: string;\n }) => void | Promise<void>;\n /** Whether to show the template picker option */\n showTemplates?: boolean;\n /**\n * Called after a store template has been installed. Receives the new\n * dashboard id and how many widgets still need a data source, so the host can\n * navigate and surface the \"connect your data\" prompts.\n */\n onTemplateInstalled?: (result: { dashboardId: string; widgetsNeedingData: number }) => void;\n}\n\ntype CreateMode = 'blank' | 'template';\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const CreateDashboardDialog: FC<CreateDashboardDialogProps> = memo(function CreateDashboardDialog({\n isOpen,\n isCreating = false,\n onClose,\n onCreate,\n showTemplates = true,\n onTemplateInstalled,\n}) {\n const {\n templates,\n loading: templatesLoading,\n error: templatesError,\n fetchTemplateContent,\n installTemplate,\n } = useStoreDashboardTemplates({ autoLoad: showTemplates });\n const [installing, setInstalling] = useState(false);\n const [mode, setMode] = useState<CreateMode>('blank');\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [tags, setTags] = useState<string[]>([]);\n const [tagInput, setTagInput] = useState('');\n const [selectedTemplate, setSelectedTemplate] = useState<StoreDashboardTemplate | null>(null);\n const [error, setError] = useState<string | null>(null);\n const nameInputRef = useRef<HTMLInputElement>(null);\n\n // Reset form when dialog opens\n useEffect(() => {\n if (isOpen) {\n setMode('blank');\n setName('');\n setDescription('');\n setTags([]);\n setTagInput('');\n setSelectedTemplate(null);\n setError(null);\n setTimeout(() => {\n nameInputRef.current?.focus();\n }, 100);\n }\n }, [isOpen]);\n\n // Handle adding a tag\n const handleAddTag = useCallback(() => {\n const trimmedTag = tagInput.trim().toLowerCase();\n if (trimmedTag && !tags.includes(trimmedTag) && tags.length < 10) {\n setTags((prev) => [...prev, trimmedTag]);\n setTagInput('');\n }\n }, [tagInput, tags]);\n\n // Handle removing a tag\n const handleRemoveTag = useCallback((tagToRemove: string) => {\n setTags((prev) => prev.filter((tag) => tag !== tagToRemove));\n }, []);\n\n // Handle tag input key press\n const handleTagKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddTag();\n } else if (e.key === 'Backspace' && !tagInput && tags.length > 0) {\n // Remove last tag when backspace is pressed on empty input\n setTags((prev) => prev.slice(0, -1));\n }\n },\n [handleAddTag, tagInput, tags.length]\n );\n\n // Handle template selection\n const handleTemplateSelect = useCallback((template: StoreDashboardTemplate) => {\n setSelectedTemplate(template);\n // Pre-fill name and description from template\n setName(template.name);\n setDescription(template.description || '');\n }, []);\n\n // Handle form submission\n const handleSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n\n // For template mode without selection, show error\n if (mode === 'template' && !selectedTemplate) {\n setError('Please select a template');\n return;\n }\n\n const trimmedName = name.trim();\n if (!trimmedName) {\n setError('Dashboard name is required');\n nameInputRef.current?.focus();\n return;\n }\n\n if (trimmedName.length < 3) {\n setError('Dashboard name must be at least 3 characters');\n nameInputRef.current?.focus();\n return;\n }\n\n if (trimmedName.length > 100) {\n setError('Dashboard name must be less than 100 characters');\n nameInputRef.current?.focus();\n return;\n }\n\n setError(null);\n\n // Store templates are installed here rather than through onCreate: the\n // install carries data-sink bindings and returns which slots are still\n // unconnected, neither of which the plain create path models.\n if (mode === 'template' && selectedTemplate) {\n setInstalling(true);\n try {\n const content = await fetchTemplateContent(selectedTemplate.id);\n if (!content) {\n setError('This template has no dashboard definition attached and cannot be installed.');\n return;\n }\n\n const result = await installTemplate({\n templateId: selectedTemplate.id,\n templateName: selectedTemplate.name,\n content,\n name: trimmedName,\n });\n\n if (!result.success) {\n setError(result.errorMessage ?? 'Failed to create dashboard from template.');\n return;\n }\n\n if (result.dashboardId) {\n onTemplateInstalled?.({\n dashboardId: result.dashboardId,\n widgetsNeedingData: result.widgetsNeedingData,\n });\n }\n onClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to create dashboard from template.');\n } finally {\n setInstalling(false);\n }\n return;\n }\n\n try {\n await onCreate({\n name: trimmedName,\n description: description.trim(),\n category: 'CUSTOM',\n tags: tags.length > 0 ? tags : undefined,\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to create dashboard. Please try again.');\n }\n },\n [\n name,\n description,\n tags,\n mode,\n selectedTemplate,\n onCreate,\n onClose,\n fetchTemplateContent,\n installTemplate,\n onTemplateInstalled,\n ]\n );\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && !isCreating && onClose()}>\n <DialogContent\n style={{ maxWidth: mode === 'template' ? '900px' : '480px', padding: 0, transition: 'max-width 0.2s ease' }}\n >\n {/* Header */}\n <DialogHeader style={{ padding: 'var(--space-pagePadding) var(--space-pagePadding) 0' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-formGap)' }}>\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-card)',\n backgroundColor: 'var(--color-action-primary-bg)',\n boxShadow: 'var(--shadow-elevation-2)',\n }}\n >\n <LayoutDashboard\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n </div>\n <div>\n <DialogTitle\n style={{\n fontSize: 'var(--font-size-heading-h4)',\n fontWeight: 'var(--font-weight-bold)',\n color: 'var(--color-text-primary)',\n margin: 0,\n }}\n >\n Create New Dashboard\n </DialogTitle>\n <DialogDescription\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-secondary)',\n margin: 'var(--space-controlGap) 0 0 0',\n }}\n >\n Create a new dashboard to visualize your data\n </DialogDescription>\n </div>\n </div>\n </DialogHeader>\n\n <form onSubmit={handleSubmit}>\n {/* Mode Selection Tabs */}\n {showTemplates && (\n <div style={{ padding: 'var(--space-pagePadding) var(--space-pagePadding) 0' }}>\n <div\n style={{\n display: 'flex',\n gap: 'var(--space-controlGap)',\n padding: 'var(--space-controlGap)',\n backgroundColor: 'var(--color-bg-sunken)',\n borderRadius: 'var(--radius-button)',\n }}\n >\n <button\n type=\"button\"\n onClick={() => {\n setMode('blank');\n setSelectedTemplate(null);\n }}\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-controlGap) var(--space-formGap)',\n borderRadius: 'var(--radius-button)',\n border: 'none',\n backgroundColor: mode === 'blank' ? 'var(--color-bg-surface)' : 'transparent',\n color: mode === 'blank' ? 'var(--color-text-primary)' : 'var(--color-text-secondary)',\n fontWeight: mode === 'blank' ? 'var(--font-weight-semibold)' : 'var(--font-weight-regular)',\n fontSize: 'var(--font-size-body-sm)',\n cursor: 'pointer',\n boxShadow: mode === 'blank' ? 'var(--shadow-elevation-1)' : 'none',\n transition: 'all 0.15s ease',\n }}\n >\n <Plus style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n Blank Dashboard\n </button>\n <button\n type=\"button\"\n onClick={() => setMode('template')}\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-controlGap) var(--space-formGap)',\n borderRadius: 'var(--radius-button)',\n border: 'none',\n backgroundColor: mode === 'template' ? 'var(--color-bg-surface)' : 'transparent',\n color: mode === 'template' ? 'var(--color-text-primary)' : 'var(--color-text-secondary)',\n fontWeight: mode === 'template' ? 'var(--font-weight-semibold)' : 'var(--font-weight-regular)',\n fontSize: 'var(--font-size-body-sm)',\n cursor: 'pointer',\n boxShadow: mode === 'template' ? 'var(--shadow-elevation-1)' : 'none',\n transition: 'all 0.15s ease',\n }}\n >\n <Copy style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n From Template\n </button>\n </div>\n </div>\n )}\n\n {/* Template Picker (when in template mode) */}\n {mode === 'template' && (\n <div style={{ padding: 'var(--space-pagePadding)', maxHeight: '400px', overflowY: 'auto' }}>\n <StoreTemplatePicker\n templates={templates}\n loading={templatesLoading}\n error={templatesError}\n selectedTemplateId={selectedTemplate?.id}\n onSelect={handleTemplateSelect}\n />\n </div>\n )}\n\n {/* Form Content */}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n {/* Name Field */}\n <div style={{ marginBottom: 'var(--space-formGap)' }}>\n <label\n htmlFor=\"dashboard-name\"\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n Dashboard Name\n <span style={{ color: 'var(--color-status-error-text)', marginLeft: 'var(--space-controlGap)' }}>\n *\n </span>\n </label>\n <Input\n ref={nameInputRef}\n id=\"dashboard-name\"\n type=\"text\"\n value={name}\n onChange={(e) => {\n setName(e.target.value);\n if (error) setError(null);\n }}\n placeholder=\"Enter dashboard name\"\n disabled={isCreating || installing}\n style={{\n height: 'var(--size-controlHeight-md)',\n fontSize: 'var(--font-size-body-sm)',\n borderColor: error ? 'var(--color-status-error-border)' : undefined,\n }}\n />\n {error && (\n <p\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-status-error-text)',\n marginTop: 'var(--space-controlGap)',\n fontWeight: 'var(--font-weight-medium)',\n }}\n >\n {error}\n </p>\n )}\n </div>\n\n {/* Description Field */}\n <div style={{ marginBottom: 'var(--space-formGap)' }}>\n <label\n htmlFor=\"dashboard-description\"\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n Description\n <span\n style={{\n color: 'var(--color-text-muted)',\n fontWeight: 'var(--font-weight-regular)',\n marginLeft: 'var(--space-controlGap)',\n }}\n >\n (optional)\n </span>\n </label>\n <Textarea\n id=\"dashboard-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Enter a brief description for this dashboard\"\n rows={3}\n disabled={isCreating || installing}\n style={{\n fontSize: 'var(--font-size-body-sm)',\n resize: 'none',\n }}\n />\n </div>\n\n {/* Tags Field */}\n <div>\n <label\n htmlFor=\"dashboard-tags\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n <Tag style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n Tags\n <span\n style={{\n color: 'var(--color-text-muted)',\n fontWeight: 'var(--font-weight-regular)',\n }}\n >\n (optional, max 10)\n </span>\n </label>\n {/* Tag chips display */}\n {tags.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 'var(--space-controlGap)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {tags.map((tag) => (\n <Badge\n key={tag}\n variant=\"secondary\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n paddingRight: '4px',\n }}\n >\n {tag}\n <button\n type=\"button\"\n onClick={() => handleRemoveTag(tag)}\n disabled={isCreating || installing}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: '2px',\n borderRadius: '50%',\n color: 'inherit',\n opacity: 0.7,\n }}\n onMouseOver={(e) => (e.currentTarget.style.opacity = '1')}\n onMouseOut={(e) => (e.currentTarget.style.opacity = '0.7')}\n >\n <X style={{ height: '12px', width: '12px' }} />\n </button>\n </Badge>\n ))}\n </div>\n )}\n {/* Tag input */}\n <div style={{ display: 'flex', gap: 'var(--space-controlGap)' }}>\n <Input\n id=\"dashboard-tags\"\n type=\"text\"\n value={tagInput}\n onChange={(e) => setTagInput(e.target.value)}\n onKeyDown={handleTagKeyDown}\n placeholder={tags.length >= 10 ? 'Max tags reached' : 'Type a tag and press Enter'}\n disabled={isCreating || installing || tags.length >= 10}\n style={{\n flex: 1,\n height: 'var(--size-controlHeight-md)',\n fontSize: 'var(--font-size-body-sm)',\n }}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleAddTag}\n disabled={isCreating || installing || !tagInput.trim() || tags.length >= 10}\n style={{ height: 'var(--size-controlHeight-md)' }}\n >\n Add\n </Button>\n </div>\n <p\n style={{\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n marginTop: 'var(--space-controlGap)',\n }}\n >\n Press Enter to add a tag, or click Add\n </p>\n </div>\n </div>\n\n {/* Footer */}\n <DialogFooter\n style={{\n padding: 'var(--space-formGap) var(--space-pagePadding)',\n borderTop: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-sunken)',\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 'var(--space-controlGap)',\n }}\n >\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onClose}\n disabled={isCreating || installing}\n style={{ height: 'var(--size-controlHeight-md)' }}\n >\n Cancel\n </Button>\n <Button\n type=\"submit\"\n disabled={isCreating || installing || !name.trim()}\n style={{\n height: 'var(--size-controlHeight-md)',\n backgroundColor: 'var(--color-action-primary-bg)',\n }}\n >\n {isCreating || installing ? (\n <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Spinner style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n Creating...\n </span>\n ) : (\n <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Plus style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n Create Dashboard\n </span>\n )}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n});\n\nexport default CreateDashboardDialog;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CreateDashboardDialog.js","names":[],"sources":["../../../../src/bigconsole/components/dashboard/CreateDashboardDialog.tsx"],"sourcesContent":["/**\n * CreateDashboardDialog Component\n *\n * Modal dialog for creating a new dashboard with name and description.\n * Uses fe-libs shared UI components and semantic tokens for consistent styling.\n * Phase 2: Added TemplatePicker integration for creating from templates.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect, useRef, type KeyboardEvent } from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Textarea } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { Plus, LayoutDashboard, Copy, X, Tag } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { StoreTemplatePicker } from './StoreTemplatePicker';\nimport { useStoreDashboardTemplates, type StoreDashboardTemplate } from '../../hooks/useStoreDashboardTemplates';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CreateDashboardDialogProps {\n isOpen: boolean;\n isCreating?: boolean;\n onClose: () => void;\n onCreate: (data: {\n name: string;\n description: string;\n category: string;\n tags?: string[];\n templateId?: string;\n }) => void | Promise<void>;\n /** Whether to show the template picker option */\n showTemplates?: boolean;\n /**\n * Called after a store template has been installed. Receives the new\n * dashboard id and how many widgets still need a data source, so the host can\n * navigate and surface the \"connect your data\" prompts.\n */\n onTemplateInstalled?: (result: { dashboardId: string; widgetsNeedingData: number }) => void;\n}\n\ntype CreateMode = 'blank' | 'template';\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const CreateDashboardDialog: FC<CreateDashboardDialogProps> = memo(function CreateDashboardDialog({\n isOpen,\n isCreating = false,\n onClose,\n onCreate,\n showTemplates = true,\n onTemplateInstalled,\n}) {\n const { t } = useI18n();\n const {\n templates,\n loading: templatesLoading,\n error: templatesError,\n fetchTemplateContent,\n installTemplate,\n } = useStoreDashboardTemplates({ autoLoad: showTemplates });\n const [installing, setInstalling] = useState(false);\n const [mode, setMode] = useState<CreateMode>('blank');\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [tags, setTags] = useState<string[]>([]);\n const [tagInput, setTagInput] = useState('');\n const [selectedTemplate, setSelectedTemplate] = useState<StoreDashboardTemplate | null>(null);\n const [error, setError] = useState<string | null>(null);\n const nameInputRef = useRef<HTMLInputElement>(null);\n\n // Reset form when dialog opens\n useEffect(() => {\n if (isOpen) {\n setMode('blank');\n setName('');\n setDescription('');\n setTags([]);\n setTagInput('');\n setSelectedTemplate(null);\n setError(null);\n setTimeout(() => {\n nameInputRef.current?.focus();\n }, 100);\n }\n }, [isOpen]);\n\n // Handle adding a tag\n const handleAddTag = useCallback(() => {\n const trimmedTag = tagInput.trim().toLowerCase();\n if (trimmedTag && !tags.includes(trimmedTag) && tags.length < 10) {\n setTags((prev) => [...prev, trimmedTag]);\n setTagInput('');\n }\n }, [tagInput, tags]);\n\n // Handle removing a tag\n const handleRemoveTag = useCallback((tagToRemove: string) => {\n setTags((prev) => prev.filter((tag) => tag !== tagToRemove));\n }, []);\n\n // Handle tag input key press\n const handleTagKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddTag();\n } else if (e.key === 'Backspace' && !tagInput && tags.length > 0) {\n // Remove last tag when backspace is pressed on empty input\n setTags((prev) => prev.slice(0, -1));\n }\n },\n [handleAddTag, tagInput, tags.length]\n );\n\n // Handle template selection\n const handleTemplateSelect = useCallback((template: StoreDashboardTemplate) => {\n setSelectedTemplate(template);\n // Pre-fill name and description from template\n setName(template.name);\n setDescription(template.description || '');\n }, []);\n\n // Handle form submission\n const handleSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n\n // For template mode without selection, show error\n if (mode === 'template' && !selectedTemplate) {\n setError(t('bigconsole.dashboards.createDialog.error.selectTemplate', 'Please select a template'));\n return;\n }\n\n const trimmedName = name.trim();\n if (!trimmedName) {\n setError(t('bigconsole.dashboards.createDialog.error.nameRequired', 'Dashboard name is required'));\n nameInputRef.current?.focus();\n return;\n }\n\n if (trimmedName.length < 3) {\n setError(\n t('bigconsole.dashboards.createDialog.error.nameTooShort', 'Dashboard name must be at least 3 characters')\n );\n nameInputRef.current?.focus();\n return;\n }\n\n if (trimmedName.length > 100) {\n setError(\n t('bigconsole.dashboards.createDialog.error.nameTooLong', 'Dashboard name must be less than 100 characters')\n );\n nameInputRef.current?.focus();\n return;\n }\n\n setError(null);\n\n // Store templates are installed here rather than through onCreate: the\n // install carries data-sink bindings and returns which slots are still\n // unconnected, neither of which the plain create path models.\n if (mode === 'template' && selectedTemplate) {\n setInstalling(true);\n try {\n const content = await fetchTemplateContent(selectedTemplate.id);\n if (!content) {\n setError(\n t(\n 'bigconsole.dashboards.createDialog.error.noDefinition',\n 'This template has no dashboard definition attached and cannot be installed.'\n )\n );\n return;\n }\n\n const result = await installTemplate({\n templateId: selectedTemplate.id,\n templateName: selectedTemplate.name,\n content,\n name: trimmedName,\n });\n\n if (!result.success) {\n setError(\n result.errorMessage ??\n t('bigconsole.dashboards.createDialog.error.installFailed', 'Failed to create dashboard from template.')\n );\n return;\n }\n\n if (result.dashboardId) {\n onTemplateInstalled?.({\n dashboardId: result.dashboardId,\n widgetsNeedingData: result.widgetsNeedingData,\n });\n }\n onClose();\n } catch (err) {\n setError(\n err instanceof Error\n ? err.message\n : t('bigconsole.dashboards.createDialog.error.installFailed', 'Failed to create dashboard from template.')\n );\n } finally {\n setInstalling(false);\n }\n return;\n }\n\n try {\n await onCreate({\n name: trimmedName,\n description: description.trim(),\n category: 'CUSTOM',\n tags: tags.length > 0 ? tags : undefined,\n });\n } catch (err) {\n setError(\n err instanceof Error\n ? err.message\n : t(\n 'bigconsole.dashboards.createDialog.error.createFailed',\n 'Failed to create dashboard. Please try again.'\n )\n );\n }\n },\n [\n name,\n description,\n tags,\n mode,\n selectedTemplate,\n onCreate,\n onClose,\n fetchTemplateContent,\n installTemplate,\n onTemplateInstalled,\n t,\n ]\n );\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && !isCreating && onClose()}>\n <DialogContent\n style={{ maxWidth: mode === 'template' ? '900px' : '480px', padding: 0, transition: 'max-width 0.2s ease' }}\n >\n {/* Header */}\n <DialogHeader style={{ padding: 'var(--space-pagePadding) var(--space-pagePadding) 0' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-formGap)' }}>\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-card)',\n backgroundColor: 'var(--color-action-primary-bg)',\n boxShadow: 'var(--shadow-elevation-2)',\n }}\n >\n <LayoutDashboard\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n </div>\n <div>\n <DialogTitle\n style={{\n fontSize: 'var(--font-size-heading-h4)',\n fontWeight: 'var(--font-weight-bold)',\n color: 'var(--color-text-primary)',\n margin: 0,\n }}\n >\n {t('bigconsole.dashboards.createDialog.title', 'Create New Dashboard')}\n </DialogTitle>\n <DialogDescription\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-secondary)',\n margin: 'var(--space-controlGap) 0 0 0',\n }}\n >\n {t('bigconsole.dashboards.createDialog.subtitle', 'Create a new dashboard to visualize your data')}\n </DialogDescription>\n </div>\n </div>\n </DialogHeader>\n\n <form onSubmit={handleSubmit}>\n {/* Mode Selection Tabs */}\n {showTemplates && (\n <div style={{ padding: 'var(--space-pagePadding) var(--space-pagePadding) 0' }}>\n <div\n style={{\n display: 'flex',\n gap: 'var(--space-controlGap)',\n padding: 'var(--space-controlGap)',\n backgroundColor: 'var(--color-bg-sunken)',\n borderRadius: 'var(--radius-button)',\n }}\n >\n <button\n type=\"button\"\n onClick={() => {\n setMode('blank');\n setSelectedTemplate(null);\n }}\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-controlGap) var(--space-formGap)',\n borderRadius: 'var(--radius-button)',\n border: 'none',\n backgroundColor: mode === 'blank' ? 'var(--color-bg-surface)' : 'transparent',\n color: mode === 'blank' ? 'var(--color-text-primary)' : 'var(--color-text-secondary)',\n fontWeight: mode === 'blank' ? 'var(--font-weight-semibold)' : 'var(--font-weight-regular)',\n fontSize: 'var(--font-size-body-sm)',\n cursor: 'pointer',\n boxShadow: mode === 'blank' ? 'var(--shadow-elevation-1)' : 'none',\n transition: 'all 0.15s ease',\n }}\n >\n <Plus style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n {t('bigconsole.dashboards.createDialog.tab.blank', 'Blank Dashboard')}\n </button>\n <button\n type=\"button\"\n onClick={() => setMode('template')}\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-controlGap) var(--space-formGap)',\n borderRadius: 'var(--radius-button)',\n border: 'none',\n backgroundColor: mode === 'template' ? 'var(--color-bg-surface)' : 'transparent',\n color: mode === 'template' ? 'var(--color-text-primary)' : 'var(--color-text-secondary)',\n fontWeight: mode === 'template' ? 'var(--font-weight-semibold)' : 'var(--font-weight-regular)',\n fontSize: 'var(--font-size-body-sm)',\n cursor: 'pointer',\n boxShadow: mode === 'template' ? 'var(--shadow-elevation-1)' : 'none',\n transition: 'all 0.15s ease',\n }}\n >\n <Copy style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n {t('bigconsole.dashboards.createDialog.tab.template', 'From Template')}\n </button>\n </div>\n </div>\n )}\n\n {/* Template Picker (when in template mode) */}\n {mode === 'template' && (\n <div style={{ padding: 'var(--space-pagePadding)', maxHeight: '400px', overflowY: 'auto' }}>\n <StoreTemplatePicker\n templates={templates}\n loading={templatesLoading}\n error={templatesError}\n selectedTemplateId={selectedTemplate?.id}\n onSelect={handleTemplateSelect}\n />\n </div>\n )}\n\n {/* Form Content */}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n {/* Name Field */}\n <div style={{ marginBottom: 'var(--space-formGap)' }}>\n <label\n htmlFor=\"dashboard-name\"\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.dashboards.createDialog.field.name', 'Dashboard Name')}\n <span style={{ color: 'var(--color-status-error-text)', marginLeft: 'var(--space-controlGap)' }}>\n *\n </span>\n </label>\n <Input\n ref={nameInputRef}\n id=\"dashboard-name\"\n type=\"text\"\n value={name}\n onChange={(e) => {\n setName(e.target.value);\n if (error) setError(null);\n }}\n placeholder={t('bigconsole.dashboards.createDialog.field.namePlaceholder', 'Enter dashboard name')}\n disabled={isCreating || installing}\n style={{\n height: 'var(--size-controlHeight-md)',\n fontSize: 'var(--font-size-body-sm)',\n borderColor: error ? 'var(--color-status-error-border)' : undefined,\n }}\n />\n {error && (\n <p\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-status-error-text)',\n marginTop: 'var(--space-controlGap)',\n fontWeight: 'var(--font-weight-medium)',\n }}\n >\n {error}\n </p>\n )}\n </div>\n\n {/* Description Field */}\n <div style={{ marginBottom: 'var(--space-formGap)' }}>\n <label\n htmlFor=\"dashboard-description\"\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.dashboards.createDialog.field.description', 'Description')}\n <span\n style={{\n color: 'var(--color-text-muted)',\n fontWeight: 'var(--font-weight-regular)',\n marginLeft: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.dashboards.createDialog.field.optional', '(optional)')}\n </span>\n </label>\n <Textarea\n id=\"dashboard-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t(\n 'bigconsole.dashboards.createDialog.field.descriptionPlaceholder',\n 'Enter a brief description for this dashboard'\n )}\n rows={3}\n disabled={isCreating || installing}\n style={{\n fontSize: 'var(--font-size-body-sm)',\n resize: 'none',\n }}\n />\n </div>\n\n {/* Tags Field */}\n <div>\n <label\n htmlFor=\"dashboard-tags\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n <Tag style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n {t('bigconsole.dashboards.createDialog.field.tags', 'Tags')}\n <span\n style={{\n color: 'var(--color-text-muted)',\n fontWeight: 'var(--font-weight-regular)',\n }}\n >\n {t('bigconsole.dashboards.createDialog.field.tagsOptional', '(optional, max 10)')}\n </span>\n </label>\n {/* Tag chips display */}\n {tags.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 'var(--space-controlGap)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {tags.map((tag) => (\n <Badge\n key={tag}\n variant=\"secondary\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n paddingRight: '4px',\n }}\n >\n {tag}\n <button\n type=\"button\"\n onClick={() => handleRemoveTag(tag)}\n disabled={isCreating || installing}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: '2px',\n borderRadius: '50%',\n color: 'inherit',\n opacity: 0.7,\n }}\n onMouseOver={(e) => (e.currentTarget.style.opacity = '1')}\n onMouseOut={(e) => (e.currentTarget.style.opacity = '0.7')}\n >\n <X style={{ height: '12px', width: '12px' }} />\n </button>\n </Badge>\n ))}\n </div>\n )}\n {/* Tag input */}\n <div style={{ display: 'flex', gap: 'var(--space-controlGap)' }}>\n <Input\n id=\"dashboard-tags\"\n type=\"text\"\n value={tagInput}\n onChange={(e) => setTagInput(e.target.value)}\n onKeyDown={handleTagKeyDown}\n placeholder={\n tags.length >= 10\n ? t('bigconsole.dashboards.createDialog.field.tagsMaxReached', 'Max tags reached')\n : t('bigconsole.dashboards.createDialog.field.tagsInputPlaceholder', 'Type a tag and press Enter')\n }\n disabled={isCreating || installing || tags.length >= 10}\n style={{\n flex: 1,\n height: 'var(--size-controlHeight-md)',\n fontSize: 'var(--font-size-body-sm)',\n }}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleAddTag}\n disabled={isCreating || installing || !tagInput.trim() || tags.length >= 10}\n style={{ height: 'var(--size-controlHeight-md)' }}\n >\n {t('bigconsole.dashboards.createDialog.action.addTag', 'Add')}\n </Button>\n </div>\n <p\n style={{\n fontSize: 'var(--font-size-body-xs)',\n color: 'var(--color-text-muted)',\n marginTop: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.dashboards.createDialog.field.tagsHelp', 'Press Enter to add a tag, or click Add')}\n </p>\n </div>\n </div>\n\n {/* Footer */}\n <DialogFooter\n style={{\n padding: 'var(--space-formGap) var(--space-pagePadding)',\n borderTop: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-sunken)',\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 'var(--space-controlGap)',\n }}\n >\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onClose}\n disabled={isCreating || installing}\n style={{ height: 'var(--size-controlHeight-md)' }}\n >\n {t('bigconsole.dashboards.createDialog.action.cancel', 'Cancel')}\n </Button>\n <Button\n type=\"submit\"\n disabled={isCreating || installing || !name.trim()}\n style={{\n height: 'var(--size-controlHeight-md)',\n backgroundColor: 'var(--color-action-primary-bg)',\n }}\n >\n {isCreating || installing ? (\n <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Spinner style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n {t('bigconsole.dashboards.createDialog.action.creating', 'Creating...')}\n </span>\n ) : (\n <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Plus style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n {t('bigconsole.dashboards.createDialog.action.create', 'Create Dashboard')}\n </span>\n )}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n});\n\nexport default CreateDashboardDialog;\n"],"mappings":"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"}
@@ -25,30 +25,31 @@ import { WidgetInspector as ae } from "../builder/WidgetInspector.js";
25
25
  import "../builder/index.js";
26
26
  import { calculatePositionFromDrop as oe, findNextAvailablePosition as se } from "../../utils/widgetPositioning.js";
27
27
  import { memo as f, useCallback as p, useEffect as ce, useMemo as le, useRef as m, useState as h } from "react";
28
+ import { useI18n as ue } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
28
29
  import { jsx as g, jsxs as _ } from "react/jsx-runtime";
29
30
  //#region src/bigconsole/components/dashboard/DashboardCanvas.tsx
30
- var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: de, isSaving: fe = !1, onExport: pe, onPublishTemplate: me, pages: b = [], activePageId: x, onPageChange: he, onPagesReorder: S, onPageAdd: ge, onPageRename: _e, onPageDuplicate: ve, onPageDelete: ye, showFilters: be = !0, showPageTabs: xe = !0, enableCrossFilter: Se = !0 }) {
31
- let C = m(null), w = m(null), [T, Ce] = h(1200), [we, E] = h(!1), [D, O] = h(null), [k, A] = h(!1), [Te, j] = h(null), M = t((e) => e.viewMode === "edit"), { workspaceId: N, apiGatewayUrl: P, authToken: F } = r(), { installedWidgets: Ee, loading: De } = c({
31
+ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: de, onSave: fe, isSaving: pe = !1, onExport: me, onPublishTemplate: he, pages: b = [], activePageId: ge, onPageChange: _e, onPagesReorder: x, onPageAdd: ve, onPageRename: ye, onPageDuplicate: be, onPageDelete: xe, showFilters: Se = !0, showPageTabs: Ce = !0, enableCrossFilter: we = !0 }) {
32
+ let { t: S } = ue(), C = m(null), w = m(null), [T, Te] = h(1200), [Ee, E] = h(!1), [D, O] = h(null), [k, A] = h(!1), [De, j] = h(null), M = t((e) => e.viewMode === "edit"), { workspaceId: N, apiGatewayUrl: P, authToken: F } = r(), { installedWidgets: Oe, loading: ke } = c({
32
33
  workspaceId: N,
33
34
  apiGatewayUrl: P,
34
35
  authToken: F,
35
36
  enabled: M
36
- }), { definitions: Oe } = a({
37
+ }), { definitions: Ae } = a({
37
38
  workspaceId: N,
38
39
  apiGatewayUrl: P,
39
40
  authToken: F,
40
41
  enabled: M
41
- }), I = t((e) => e.zoomLevel), L = t((e) => e.sidebarCollapsed), R = t((e) => e.toggleSidebar), z = !L, B = t((e) => e.setGlobalFilterValues), ke = p((e) => {
42
+ }), I = t((e) => e.zoomLevel), L = t((e) => e.sidebarCollapsed), R = t((e) => e.toggleSidebar), z = !L, B = t((e) => e.setGlobalFilterValues), je = p((e) => {
42
43
  B(e);
43
44
  }, [B]), { createWidget: V } = o(v, f, { skipFetch: !0 }), H = e((e) => e.widgets), U = le(() => {
44
45
  let e = Array.from(H.values());
45
46
  return v ? e.filter((e) => e.pageId === v) : e;
46
- }, [H, v]), Ae = e((e) => e.selectedWidgetId), W = e((e) => e.selectWidget), G = e((e) => e.addWidget), K = e((e) => e.updateWidgetPosition), q = e((e) => e.configPanelOpen), J = e((e) => e.closeConfigPanel);
47
+ }, [H, v]), Me = e((e) => e.selectedWidgetId), W = e((e) => e.selectWidget), G = e((e) => e.addWidget), K = e((e) => e.updateWidgetPosition), q = e((e) => e.configPanelOpen), Ne = e((e) => e.closeConfigPanel);
47
48
  ce(() => {
48
49
  let e = C.current;
49
50
  if (!e) return;
50
51
  let t = () => {
51
- Ce(e.offsetWidth);
52
+ Te(e.offsetWidth);
52
53
  };
53
54
  if (t(), typeof ResizeObserver < "u") {
54
55
  let n = new ResizeObserver(t);
@@ -56,7 +57,7 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
56
57
  }
57
58
  return window.addEventListener("resize", t), () => window.removeEventListener("resize", t);
58
59
  }, []);
59
- let je = p((e) => {
60
+ let Pe = p((e) => {
60
61
  e.forEach((e) => {
61
62
  K(e.i, {
62
63
  x: e.x,
@@ -65,9 +66,9 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
65
66
  height: e.h
66
67
  });
67
68
  });
68
- }, [K]), Me = p((e) => {
69
+ }, [K]), Fe = p((e) => {
69
70
  W(e);
70
- }, [W]), Y = p(async (e, t) => {
71
+ }, [W]), J = p(async (e, t) => {
71
72
  O(null);
72
73
  let n = t?.definition || (e.type ? i(e.type) : null), r = {
73
74
  width: n?.defaultSize?.width ?? 4,
@@ -89,7 +90,7 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
89
90
  pageId: v,
90
91
  dashboardId: f,
91
92
  type: e.type,
92
- title: e.title || "Untitled Widget",
93
+ title: e.title || S("bigconsole.dashboards.canvas.untitledWidget", "Untitled Widget"),
93
94
  description: e.description,
94
95
  renderer: e.renderer,
95
96
  template: e.template,
@@ -103,7 +104,7 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
103
104
  W(t.id);
104
105
  return;
105
106
  }
106
- O("Could not create the widget. Check the connection and try again.");
107
+ O(S("bigconsole.dashboards.canvas.widgetCreateError", "Could not create the widget. Check the connection and try again."));
107
108
  return;
108
109
  }
109
110
  let s = {
@@ -111,7 +112,7 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
111
112
  dashboardId: f,
112
113
  pageId: v || "local",
113
114
  type: e.type,
114
- title: e.title || "Untitled Widget",
115
+ title: e.title || S("bigconsole.dashboards.canvas.untitledWidget", "Untitled Widget"),
115
116
  description: e.description,
116
117
  renderer: e.renderer,
117
118
  template: e.template,
@@ -135,12 +136,13 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
135
136
  V,
136
137
  G,
137
138
  W,
138
- U
139
- ]), Ne = p((e) => {
139
+ U,
140
+ S
141
+ ]), Y = p((e) => {
140
142
  A(!0), j(e);
141
- }, []), Pe = p(() => {
143
+ }, []), Ie = p(() => {
142
144
  A(!1), j(null);
143
- }, []), Fe = p((e) => {
145
+ }, []), Le = p((e) => {
144
146
  e.preventDefault(), A(!1), j(null);
145
147
  try {
146
148
  let t = e.dataTransfer.getData("application/json");
@@ -166,7 +168,7 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
166
168
  width: c.width,
167
169
  height: c.height
168
170
  };
169
- Y({
171
+ J({
170
172
  type: r.type,
171
173
  title: r.name || a.name,
172
174
  config: r.defaultConfig || a.defaultConfig
@@ -177,22 +179,27 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
177
179
  } catch (e) {
178
180
  console.error("Failed to handle widget drop:", e);
179
181
  }
180
- }, [T, Y]), Ie = p((e) => {
182
+ }, [T, J]), Re = p((e) => {
181
183
  e.preventDefault(), e.dataTransfer.dropEffect = "copy";
182
- }, []), Le = p((e, t) => {
184
+ }, []), ze = p((e, t) => {
183
185
  let n = t || i(e);
184
- Y({
186
+ J({
185
187
  type: e,
186
188
  title: n.name,
187
189
  config: n.defaultConfig
188
190
  });
189
- }, [Y]), X = p(() => {
191
+ }, [J]), X = p(() => {
190
192
  R();
191
193
  }, [R]), Z = p(() => {
192
194
  L && R(), window.requestAnimationFrame(() => {
193
- document.querySelector("input[placeholder=\"Search widgets...\"]")?.focus();
195
+ let e = S("bigconsole.dashboards.widgetPalette.searchPlaceholder", "Search widgets...");
196
+ document.querySelector(`input[placeholder="${e}"]`)?.focus();
194
197
  });
195
- }, [L, R]), { exportPNG: Q, exportPDF: $, isExporting: Re } = s({
198
+ }, [
199
+ L,
200
+ R,
201
+ S
202
+ ]), { exportPNG: Q, exportPDF: $, isExporting: Be } = s({
196
203
  containerRef: w,
197
204
  name: y || "dashboard"
198
205
  });
@@ -205,18 +212,18 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
205
212
  onAddWidget: Z,
206
213
  onTogglePalette: X,
207
214
  isPaletteOpen: z,
208
- onPaste: ue,
209
- onSave: de,
210
- isSaving: fe,
211
- onExport: pe,
212
- onPublishTemplate: me,
215
+ onPaste: de,
216
+ onSave: fe,
217
+ isSaving: pe,
218
+ onExport: me,
219
+ onPublishTemplate: he,
213
220
  onExportImage: p(() => {
214
221
  Q();
215
222
  }, [Q]),
216
223
  onExportPdf: p(() => {
217
224
  $();
218
225
  }, [$]),
219
- isExportingImage: Re,
226
+ isExportingImage: Be,
220
227
  onShare: () => E(!0)
221
228
  }),
222
229
  D && /* @__PURE__ */ _("div", {
@@ -226,7 +233,7 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
226
233
  type: "button",
227
234
  className: "font-medium underline underline-offset-2",
228
235
  onClick: () => O(null),
229
- children: "Dismiss"
236
+ children: S("bigconsole.dashboards.canvas.dismiss", "Dismiss")
230
237
  })]
231
238
  }),
232
239
  /* @__PURE__ */ g(te, {
@@ -237,23 +244,23 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
237
244
  widgets: U,
238
245
  isEditMode: M
239
246
  }),
240
- be && /* @__PURE__ */ g(d, {
247
+ Se && /* @__PURE__ */ g(d, {
241
248
  dashboardId: f,
242
- onFilterChange: ke,
249
+ onFilterChange: je,
243
250
  collapsible: !0
244
251
  }),
245
- xe && (M || b.length > 0) && /* @__PURE__ */ g(ne, {
252
+ Ce && (M || b.length > 0) && /* @__PURE__ */ g(ne, {
246
253
  pages: b,
247
- activePageId: x || b[0]?.id,
254
+ activePageId: ge || b[0]?.id,
248
255
  editable: M,
249
- onPageSelect: he || (() => {}),
250
- onPagesReorder: S ? (e) => {
251
- S(e.map((e) => b.find((t) => t.id === e)).filter(Boolean));
256
+ onPageSelect: _e || (() => {}),
257
+ onPagesReorder: x ? (e) => {
258
+ x(e.map((e) => b.find((t) => t.id === e)).filter(Boolean));
252
259
  } : void 0,
253
- onPageCreate: ge,
254
- onPageRename: _e,
255
- onPageDuplicate: ve,
256
- onPageDelete: ye
260
+ onPageCreate: ve,
261
+ onPageRename: ye,
262
+ onPageDuplicate: be,
263
+ onPageDelete: xe
257
264
  }),
258
265
  /* @__PURE__ */ _("div", {
259
266
  className: "flex flex-1 min-w-0 overflow-hidden",
@@ -264,17 +271,17 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
264
271
  children: [M && /* @__PURE__ */ g(ie, {
265
272
  isOpen: z,
266
273
  onClose: X,
267
- onWidgetSelect: Le,
268
- onDragStart: Ne,
269
- onDragEnd: Pe,
270
- installedWidgets: Ee,
271
- installedWidgetsLoading: De,
272
- definitions: Oe
274
+ onWidgetSelect: ze,
275
+ onDragStart: Y,
276
+ onDragEnd: Ie,
277
+ installedWidgets: Oe,
278
+ installedWidgetsLoading: ke,
279
+ definitions: Ae
273
280
  }), /* @__PURE__ */ _("div", {
274
281
  ref: C,
275
282
  className: "flex-1 min-w-0 overflow-auto bg-bg-sunken",
276
- onDrop: Fe,
277
- onDragOver: Ie,
283
+ onDrop: Le,
284
+ onDragOver: Re,
278
285
  onClick: () => {
279
286
  M && W(null);
280
287
  },
@@ -305,9 +312,11 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
305
312
  margin: 0
306
313
  },
307
314
  children: [
308
- "Drop to add ",
309
- /* @__PURE__ */ g("strong", { children: Te }),
310
- " widget"
315
+ S("bigconsole.dashboards.canvas.dropToAddBefore", "Drop to add"),
316
+ " ",
317
+ /* @__PURE__ */ g("strong", { children: De }),
318
+ " ",
319
+ S("bigconsole.dashboards.canvas.dropToAddAfter", "widget")
311
320
  ]
312
321
  })
313
322
  }), /* @__PURE__ */ g("div", {
@@ -318,15 +327,15 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
318
327
  width: `${100 / (I / 100)}%`
319
328
  },
320
329
  children: U.length > 0 ? /* @__PURE__ */ g(n, {
321
- enabled: Se,
330
+ enabled: we,
322
331
  onCrossFilter: (e) => {},
323
332
  children: /* @__PURE__ */ g(l, {
324
333
  widgets: U,
325
334
  isEditMode: M,
326
335
  width: T,
327
- onLayoutChange: je,
328
- onWidgetSelect: Me,
329
- selectedWidgetId: Ae
336
+ onLayoutChange: Pe,
337
+ onWidgetSelect: Fe,
338
+ selectedWidgetId: Me
330
339
  })
331
340
  }) : /* @__PURE__ */ _("div", {
332
341
  className: "flex flex-col items-center justify-center min-h-[400px] p-8",
@@ -348,11 +357,11 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
348
357
  }),
349
358
  /* @__PURE__ */ g("h3", {
350
359
  className: "text-lg font-medium text-text-primary mb-2",
351
- children: "No widgets yet"
360
+ children: S("bigconsole.dashboards.canvas.noWidgetsTitle", "No widgets yet")
352
361
  }),
353
362
  /* @__PURE__ */ g("p", {
354
363
  className: "text-sm text-text-secondary mb-4 text-center max-w-[300px]",
355
- children: "Add widgets to build your dashboard. Click the \"Add Widget\" button to get started."
364
+ children: S("bigconsole.dashboards.canvas.noWidgetsDescription", "Add widgets to build your dashboard. Click the \"Add Widget\" button to get started.")
356
365
  }),
357
366
  M && /* @__PURE__ */ _("button", {
358
367
  type: "button",
@@ -369,7 +378,7 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
369
378
  strokeWidth: 2,
370
379
  d: "M12 4v16m8-8H4"
371
380
  })
372
- }), "Add Widget"]
381
+ }), S("bigconsole.dashboards.canvas.addWidget", "Add Widget")]
373
382
  })
374
383
  ]
375
384
  })
@@ -378,12 +387,12 @@ var v = f(function({ dashboardId: f, pageId: v, title: y, onPaste: ue, onSave: d
378
387
  }),
379
388
  /* @__PURE__ */ g(ae, {
380
389
  isOpen: q,
381
- onClose: J
390
+ onClose: Ne
382
391
  }),
383
392
  /* @__PURE__ */ g(re, {
384
393
  dashboardId: f,
385
- dashboardName: y || "Dashboard",
386
- isOpen: we,
394
+ dashboardName: y || S("bigconsole.dashboards.canvas.dashboardFallbackName", "Dashboard"),
395
+ isOpen: Ee,
387
396
  onClose: () => E(!1)
388
397
  })
389
398
  ]