@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.
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +109 -113
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +115 -113
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +71 -62
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +90 -89
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +56 -54
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +126 -125
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +151 -150
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +77 -76
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +97 -96
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +172 -191
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +75 -83
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +151 -154
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +181 -190
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
- package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -0
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +110 -108
- package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +102 -103
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +36 -41
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +38 -37
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +113 -117
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +182 -197
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +166 -168
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/DataSinkSelector.js +87 -86
- package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ImportParserDialog.js +196 -211
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +130 -128
- package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +66 -63
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +95 -91
- package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +222 -215
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +149 -145
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +504 -470
- package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +44 -47
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +143 -142
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +101 -88
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +135 -134
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
- package/dist/bigconsole/components/widgets/form/FormWidget.js +167 -159
- package/dist/bigconsole/components/widgets/form/FormWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +69 -68
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +64 -72
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +60 -59
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListConfig.js +57 -56
- package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +70 -69
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +35 -34
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +20 -19
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +178 -177
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +76 -75
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableConfig.js +183 -168
- package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +187 -180
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +40 -38
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +150 -148
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/pages/DashboardBuilderPage.js +181 -176
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +196 -192
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +223 -219
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +167 -170
- package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +204 -189
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +175 -169
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSourcesPage.js +8 -7
- package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
- package/dist/bigconsole/pages/InsightsPage.js +238 -208
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +464 -412
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +92 -90
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +221 -194
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +181 -184
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +128 -127
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/SettingsPage.js +177 -172
- package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
- package/dist/bigconsole/pages/WidgetDemoPage.js +121 -83
- package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowViewPage.js +199 -193
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +129 -128
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +111 -109
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +127 -126
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js +103 -103
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
- 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:
|
|
31
|
-
let C = m(null), w = m(null), [T,
|
|
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:
|
|
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),
|
|
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]),
|
|
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
|
-
|
|
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
|
|
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]),
|
|
69
|
+
}, [K]), Fe = p((e) => {
|
|
69
70
|
W(e);
|
|
70
|
-
}, [W]),
|
|
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
|
-
|
|
139
|
+
U,
|
|
140
|
+
S
|
|
141
|
+
]), Y = p((e) => {
|
|
140
142
|
A(!0), j(e);
|
|
141
|
-
}, []),
|
|
143
|
+
}, []), Ie = p(() => {
|
|
142
144
|
A(!1), j(null);
|
|
143
|
-
}, []),
|
|
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
|
-
|
|
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,
|
|
182
|
+
}, [T, J]), Re = p((e) => {
|
|
181
183
|
e.preventDefault(), e.dataTransfer.dropEffect = "copy";
|
|
182
|
-
}, []),
|
|
184
|
+
}, []), ze = p((e, t) => {
|
|
183
185
|
let n = t || i(e);
|
|
184
|
-
|
|
186
|
+
J({
|
|
185
187
|
type: e,
|
|
186
188
|
title: n.name,
|
|
187
189
|
config: n.defaultConfig
|
|
188
190
|
});
|
|
189
|
-
}, [
|
|
191
|
+
}, [J]), X = p(() => {
|
|
190
192
|
R();
|
|
191
193
|
}, [R]), Z = p(() => {
|
|
192
194
|
L && R(), window.requestAnimationFrame(() => {
|
|
193
|
-
|
|
195
|
+
let e = S("bigconsole.dashboards.widgetPalette.searchPlaceholder", "Search widgets...");
|
|
196
|
+
document.querySelector(`input[placeholder="${e}"]`)?.focus();
|
|
194
197
|
});
|
|
195
|
-
}, [
|
|
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:
|
|
209
|
-
onSave:
|
|
210
|
-
isSaving:
|
|
211
|
-
onExport:
|
|
212
|
-
onPublishTemplate:
|
|
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:
|
|
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
|
-
|
|
247
|
+
Se && /* @__PURE__ */ g(d, {
|
|
241
248
|
dashboardId: f,
|
|
242
|
-
onFilterChange:
|
|
249
|
+
onFilterChange: je,
|
|
243
250
|
collapsible: !0
|
|
244
251
|
}),
|
|
245
|
-
|
|
252
|
+
Ce && (M || b.length > 0) && /* @__PURE__ */ g(ne, {
|
|
246
253
|
pages: b,
|
|
247
|
-
activePageId:
|
|
254
|
+
activePageId: ge || b[0]?.id,
|
|
248
255
|
editable: M,
|
|
249
|
-
onPageSelect:
|
|
250
|
-
onPagesReorder:
|
|
251
|
-
|
|
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:
|
|
254
|
-
onPageRename:
|
|
255
|
-
onPageDuplicate:
|
|
256
|
-
onPageDelete:
|
|
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:
|
|
268
|
-
onDragStart:
|
|
269
|
-
onDragEnd:
|
|
270
|
-
installedWidgets:
|
|
271
|
-
installedWidgetsLoading:
|
|
272
|
-
definitions:
|
|
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:
|
|
277
|
-
onDragOver:
|
|
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
|
-
|
|
310
|
-
"
|
|
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:
|
|
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:
|
|
328
|
-
onWidgetSelect:
|
|
329
|
-
selectedWidgetId:
|
|
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:
|
|
390
|
+
onClose: Ne
|
|
382
391
|
}),
|
|
383
392
|
/* @__PURE__ */ g(re, {
|
|
384
393
|
dashboardId: f,
|
|
385
|
-
dashboardName: y || "Dashboard",
|
|
386
|
-
isOpen:
|
|
394
|
+
dashboardName: y || S("bigconsole.dashboards.canvas.dashboardFallbackName", "Dashboard"),
|
|
395
|
+
isOpen: Ee,
|
|
387
396
|
onClose: () => E(!1)
|
|
388
397
|
})
|
|
389
398
|
]
|