@burdenoff/microfe-bigconsole 2026.805.1 → 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 (150) hide show
  1. package/dist/bigconsole/AdminRoot.js +21 -16
  2. package/dist/bigconsole/AdminRoot.js.map +1 -1
  3. package/dist/bigconsole/BigConsoleRoot.js +44 -39
  4. package/dist/bigconsole/BigConsoleRoot.js.map +1 -1
  5. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +109 -113
  6. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
  7. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +115 -113
  8. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  9. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +71 -62
  10. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  11. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +116 -100
  12. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  13. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +56 -54
  14. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
  15. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +126 -125
  16. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
  17. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +151 -150
  18. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
  19. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +77 -76
  20. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
  21. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +97 -96
  22. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  23. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +172 -191
  24. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  25. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +100 -98
  26. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
  27. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +75 -83
  28. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js.map +1 -1
  29. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +151 -154
  30. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
  31. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +187 -193
  32. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
  33. package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -0
  34. package/dist/bigconsole/components/dashboard/WidgetPalette.js +110 -108
  35. package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
  36. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +102 -103
  37. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  38. package/dist/bigconsole/components/datasink/DataSinkCard.js +20 -20
  39. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  40. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +36 -41
  41. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  42. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +38 -37
  43. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  44. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +113 -117
  45. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
  46. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +182 -197
  47. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  48. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +166 -168
  49. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  50. package/dist/bigconsole/components/parser/DataSinkSelector.js +87 -86
  51. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  52. package/dist/bigconsole/components/parser/ImportParserDialog.js +196 -211
  53. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  54. package/dist/bigconsole/components/parser/ParserSelector.js +130 -128
  55. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  56. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +66 -63
  57. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
  58. package/dist/bigconsole/components/preview/AiPreviewPanel.js +95 -91
  59. package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
  60. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +243 -230
  61. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  62. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +149 -145
  63. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  64. package/dist/bigconsole/components/widgets/PropertiesPanel.js +504 -470
  65. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  66. package/dist/bigconsole/components/widgets/WidgetMenu.js +87 -76
  67. package/dist/bigconsole/components/widgets/WidgetMenu.js.map +1 -1
  68. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +44 -47
  69. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  70. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +143 -142
  71. package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
  72. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +101 -88
  73. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  74. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +135 -134
  75. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
  76. package/dist/bigconsole/components/widgets/form/FormWidget.js +167 -159
  77. package/dist/bigconsole/components/widgets/form/FormWidget.js.map +1 -1
  78. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +69 -68
  79. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
  80. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +64 -72
  81. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
  82. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +60 -59
  83. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  84. package/dist/bigconsole/components/widgets/list/ListConfig.js +57 -56
  85. package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
  86. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +70 -69
  87. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
  88. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +35 -34
  89. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
  90. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +20 -19
  91. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
  92. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +178 -177
  93. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  94. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +76 -75
  95. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  96. package/dist/bigconsole/components/widgets/table/TableConfig.js +183 -168
  97. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  98. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +187 -180
  99. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
  100. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +120 -118
  101. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  102. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +40 -38
  103. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
  104. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +150 -148
  105. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  106. package/dist/bigconsole/pages/DashboardBuilderPage.js +189 -175
  107. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  108. package/dist/bigconsole/pages/DashboardViewPage.js +200 -187
  109. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  110. package/dist/bigconsole/pages/DashboardsPage.js +379 -324
  111. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  112. package/dist/bigconsole/pages/DataParsersPage.js +185 -178
  113. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  114. package/dist/bigconsole/pages/DataSinkBuilderPage.js +195 -170
  115. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  116. package/dist/bigconsole/pages/DataSinkViewPage.js +224 -200
  117. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  118. package/dist/bigconsole/pages/DataSinksPage.js +281 -268
  119. package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
  120. package/dist/bigconsole/pages/DataSourcesPage.js +8 -7
  121. package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
  122. package/dist/bigconsole/pages/InsightsPage.js +238 -208
  123. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  124. package/dist/bigconsole/pages/ParserBuilderPage.js +480 -413
  125. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  126. package/dist/bigconsole/pages/ParserViewPage.js +192 -172
  127. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  128. package/dist/bigconsole/pages/PipelineBuilderPage.js +198 -163
  129. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  130. package/dist/bigconsole/pages/PipelineViewPage.js +138 -133
  131. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  132. package/dist/bigconsole/pages/PipelinesPage.js +162 -136
  133. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  134. package/dist/bigconsole/pages/SettingsPage.js +177 -172
  135. package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
  136. package/dist/bigconsole/pages/WidgetDemoPage.js +121 -83
  137. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  138. package/dist/bigconsole/pages/WorkflowViewPage.js +269 -242
  139. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  140. package/dist/bigconsole/pages/WorkflowsPage.js +153 -138
  141. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  142. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +111 -109
  143. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
  144. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +127 -126
  145. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
  146. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +103 -103
  147. package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
  148. package/dist/constants/permissions.js +83 -0
  149. package/dist/constants/permissions.js.map +1 -0
  150. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ImportDashboardDialog.js","names":[],"sources":["../../../../src/bigconsole/components/dashboard/ImportDashboardDialog.tsx"],"sourcesContent":["/**\n * ImportDashboardDialog Component\n *\n * Modal dialog for importing a dashboard from JSON file.\n * Supports both creating new dashboards and updating existing ones.\n * Uses fe-libs shared UI components for consistent styling.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect, useRef } 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 { Label } from '@burdenoff/fe-libs/ui';\nimport { Checkbox } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { Upload, FileJson, Check, AlertTriangle, XCircle, ArrowLeft, RefreshCw, Info } from 'lucide-react';\nimport { useImportDashboard, type ImportDashboardOptions } from '../../hooks';\nimport { useBigConsoleAnalytics } from '../../hooks/useBigConsoleAnalytics';\nimport { reportBigConsoleQuotaError } from '../../utils/quota';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImportDashboardDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess?: (dashboardId: string, dashboardName: string, originalUpdated: boolean) => void;\n}\n\ntype ImportStep = 'select' | 'preview' | 'importing' | 'complete';\n\n// ============================================================================\n// Helper: Extract dashboard ID from content\n// ============================================================================\n\nfunction extractDashboardId(content: string | null): string | null {\n if (!content) return null;\n try {\n const parsed = JSON.parse(content);\n return parsed.exportedFrom?.dashboardId || parsed.dashboard?.id || null;\n } catch {\n return null;\n }\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const ImportDashboardDialog: FC<ImportDashboardDialogProps> = memo(function ImportDashboardDialog({\n isOpen,\n onClose,\n onSuccess,\n}) {\n const [step, setStep] = useState<ImportStep>('select');\n const [, setSelectedFile] = useState<File | null>(null);\n const [fileContent, setFileContent] = useState<string | null>(null);\n const [nameOverride, setNameOverride] = useState('');\n const [visibility, setVisibility] = useState<'PRIVATE' | 'TEAM' | 'PUBLIC'>('PRIVATE');\n const [skipWarnings, setSkipWarnings] = useState(false);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { loading, error, validationResult, importResult, validateImport, importDashboard, clearState } =\n useImportDashboard();\n const emitBigConsoleEvent = useBigConsoleAnalytics();\n\n // Reset state when dialog opens\n useEffect(() => {\n if (isOpen) {\n setStep('select');\n setSelectedFile(null);\n setFileContent(null);\n setNameOverride('');\n setVisibility('PRIVATE');\n setSkipWarnings(false);\n clearState();\n }\n }, [isOpen, clearState]);\n\n // Handle file selection\n const handleFileSelect = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n if (!file.name.endsWith('.json')) {\n alert('Please select a JSON file');\n return;\n }\n\n setSelectedFile(file);\n\n const reader = new FileReader();\n reader.onload = async (event) => {\n const content = event.target?.result as string;\n setFileContent(content);\n\n const result = await validateImport(content);\n if (result) {\n setStep('preview');\n if (result.dashboardInfo?.name) {\n setNameOverride(result.dashboardInfo.name);\n }\n }\n };\n reader.onerror = () => {\n alert('Failed to read file');\n };\n reader.readAsText(file);\n },\n [validateImport]\n );\n\n // Handle file drop\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n const file = e.dataTransfer.files?.[0];\n if (file) {\n const dt = new DataTransfer();\n dt.items.add(file);\n if (fileInputRef.current) {\n fileInputRef.current.files = dt.files;\n fileInputRef.current.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }\n }, []);\n\n // Handle import\n const handleImport = useCallback(async () => {\n if (!fileContent) return;\n\n setStep('importing');\n\n const options: ImportDashboardOptions = {\n name: nameOverride.trim() || undefined,\n visibility,\n skipWarnings,\n };\n\n emitBigConsoleEvent('bigconsole.dashboard.import_clicked', { source: 'import' });\n\n try {\n const result = await importDashboard(fileContent, options);\n\n if (result?.success && result.dashboard) {\n setStep('complete');\n emitBigConsoleEvent('bigconsole.dashboard.imported', {\n dashboardId: result.dashboard.id,\n source: 'import',\n originalUpdated: result.originalUpdated ?? false,\n });\n onSuccess?.(result.dashboard.id, result.dashboard.name, result.originalUpdated ?? false);\n } else {\n setStep('preview');\n }\n } catch (err) {\n if (reportBigConsoleQuotaError(err, 'project')) {\n onClose();\n return;\n }\n setStep('preview');\n }\n }, [emitBigConsoleEvent, fileContent, importDashboard, nameOverride, onClose, onSuccess, skipWarnings, visibility]);\n\n const canClose = !loading && step !== 'importing';\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && canClose && onClose()}>\n <DialogContent className=\"sm:max-w-lg max-h-[85vh] flex flex-col\">\n <DialogHeader>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-action-primary-bg/10\">\n <Upload className=\"size-5 text-primary\" />\n </div>\n <DialogTitle>Import Dashboard</DialogTitle>\n </div>\n <DialogDescription>Upload a Dashboard export file to restore it into this workspace.</DialogDescription>\n </DialogHeader>\n\n <div className=\"flex-1 overflow-y-auto py-4 space-y-4\">\n {/* Step 1: File Selection */}\n {step === 'select' && (\n <div\n onDragOver={(e) => e.preventDefault()}\n onDrop={handleDrop}\n className=\"border-2 border-dashed rounded-lg p-8 text-center hover:border-primary transition-colors\"\n >\n <FileJson className=\"size-12 mx-auto text-text-secondary mb-4\" />\n <p className=\"text-sm mb-2\">Drag and drop a dashboard export file here</p>\n <p className=\"text-xs text-text-secondary mb-4\">or</p>\n <input ref={fileInputRef} type=\"file\" accept=\".json\" onChange={handleFileSelect} className=\"hidden\" />\n <Button onClick={() => fileInputRef.current?.click()} disabled={loading}>\n Browse Files\n </Button>\n <p className=\"text-xs text-text-secondary mt-4\">\n Only .json files exported from BigConsole are supported\n </p>\n </div>\n )}\n\n {/* Step 2: Preview & Options */}\n {(step === 'preview' || step === 'importing') && validationResult && (\n <>\n {/* Dashboard Info */}\n <Card>\n <CardContent className=\"p-4 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">Dashboard</span>\n <span className=\"text-sm font-medium\">{validationResult.dashboardInfo.name}</span>\n </div>\n {validationResult.dashboardInfo.description && (\n <div className=\"flex items-start justify-between\">\n <span className=\"text-sm text-text-secondary\">Description</span>\n <span className=\"text-sm text-right max-w-[60%] truncate\">\n {validationResult.dashboardInfo.description}\n </span>\n </div>\n )}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">Pages</span>\n <Badge variant=\"secondary\">{validationResult.dashboardInfo.pageCount}</Badge>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">Widgets</span>\n <Badge variant=\"secondary\">{validationResult.dashboardInfo.widgetCount}</Badge>\n </div>\n {validationResult.dashboardInfo.exportedFrom && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">Source ID</span>\n <span className=\"text-xs text-text-secondary font-mono truncate max-w-[180px]\">\n {validationResult.dashboardInfo.exportedFrom}\n </span>\n </div>\n )}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">Schema Version</span>\n <span className=\"text-xs text-text-secondary\">{validationResult.dashboardInfo.schemaVersion}</span>\n </div>\n </CardContent>\n </Card>\n\n {/* Validation Errors */}\n {validationResult.errors.length > 0 && (\n <Card className=\"border-status-error-border/50 bg-status-error-bg/5\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <XCircle className=\"size-4 text-status-error-text\" />\n <span className=\"text-sm font-medium text-status-error-text\">\n Errors ({validationResult.errors.length})\n </span>\n </div>\n <ul className=\"text-xs text-status-error-text space-y-1\">\n {validationResult.errors.map((err, idx) => (\n <li key={idx}>\n <span className=\"font-mono\">[{err.code}]</span> {err.message}\n </li>\n ))}\n </ul>\n </CardContent>\n </Card>\n )}\n\n {/* Validation Warnings */}\n {validationResult.warnings.length > 0 && (\n <Card className=\"border-yellow-500/50 bg-yellow-500/5\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <AlertTriangle className=\"size-4 text-yellow-600\" />\n <span className=\"text-sm font-medium text-yellow-600\">\n Warnings ({validationResult.warnings.length})\n </span>\n </div>\n <ul className=\"text-xs text-yellow-600 space-y-1\">\n {validationResult.warnings.map((warn, idx) => (\n <li key={idx}>\n <span className=\"font-mono\">[{warn.code}]</span> {warn.message}\n </li>\n ))}\n </ul>\n </CardContent>\n </Card>\n )}\n\n {/* Import Options */}\n {validationResult.isValid && (\n <div className=\"space-y-4\">\n <p className=\"text-sm font-medium\">Import Options</p>\n\n {/* Import Info */}\n <Card className=\"border-blue-500/50 bg-blue-500/5\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-start gap-2\">\n <Info className=\"size-4 text-blue-600 mt-0.5 shrink-0\" />\n <div className=\"text-xs text-blue-700 dark:text-blue-400\">\n {extractDashboardId(fileContent) ? (\n <>\n <p className=\"font-medium mb-1\">Import will check for existing dashboard</p>\n <p>\n If the original dashboard (ID:{' '}\n <code className=\"font-mono bg-blue-200/50 px-1 rounded\">\n {extractDashboardId(fileContent)?.slice(0, 8)}...\n </code>\n ) exists:\n </p>\n <ul className=\"list-disc list-inside mt-1 space-y-0.5\">\n <li>With changes → Update the existing dashboard</li>\n <li>No changes → Show &quot;already exists&quot; message</li>\n </ul>\n <p className=\"mt-1\">If original doesn&apos;t exist → Create a new dashboard</p>\n </>\n ) : (\n <>\n <p className=\"font-medium mb-1\">A new dashboard will be created</p>\n <p>Import as a new dashboard with the specified configuration.</p>\n </>\n )}\n </div>\n </div>\n </CardContent>\n </Card>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"import-name\">Dashboard Name</Label>\n <Input\n id=\"import-name\"\n type=\"text\"\n value={nameOverride}\n onChange={(e) => setNameOverride(e.target.value)}\n placeholder={validationResult.dashboardInfo.name}\n disabled={step === 'importing'}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label>Visibility</Label>\n <div className=\"flex gap-2\">\n {(['PRIVATE', 'TEAM', 'PUBLIC'] as const).map((v) => (\n <Button\n key={v}\n type=\"button\"\n variant={visibility === v ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setVisibility(v)}\n disabled={step === 'importing'}\n >\n {v.charAt(0) + v.slice(1).toLowerCase()}\n </Button>\n ))}\n </div>\n </div>\n\n {validationResult.warnings.length > 0 && (\n <div className=\"flex items-start space-x-3\">\n <Checkbox\n id=\"skipWarnings\"\n checked={skipWarnings}\n onCheckedChange={(checked) => setSkipWarnings(checked === true)}\n disabled={step === 'importing'}\n />\n <div className=\"grid gap-1.5 leading-none\">\n <Label htmlFor=\"skipWarnings\" className=\"cursor-pointer\">\n Acknowledge warnings and proceed\n </Label>\n </div>\n </div>\n )}\n </div>\n )}\n </>\n )}\n\n {/* Step 3: Complete */}\n {step === 'complete' && importResult?.success && (\n <div className=\"text-center py-6\">\n {/* Already Exists - No Changes */}\n {importResult.alreadyExists && (\n <>\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center\">\n <Info className=\"size-8 text-blue-600\" />\n </div>\n <h3 className=\"text-lg font-medium mb-2\">Dashboard Already Exists</h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n Dashboard &quot;{importResult.dashboard?.name}&quot; already exists with the same data. No changes\n were made.\n </p>\n </>\n )}\n\n {/* Updated Existing */}\n {importResult.originalUpdated && !importResult.alreadyExists && (\n <>\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center\">\n <RefreshCw className=\"size-8 text-green-600\" />\n </div>\n <h3 className=\"text-lg font-medium mb-2\">Dashboard Updated!</h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n Dashboard &quot;{importResult.dashboard?.name}&quot; has been updated with the imported data.\n </p>\n </>\n )}\n\n {/* Created New */}\n {!importResult.originalUpdated && !importResult.alreadyExists && (\n <>\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center\">\n <Check className=\"size-8 text-green-600\" />\n </div>\n <h3 className=\"text-lg font-medium mb-2\">Import Successful!</h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n Dashboard &quot;{importResult.dashboard?.name}&quot; has been created.\n </p>\n\n {importResult.stats && (\n <Card className=\"inline-block text-left\">\n <CardContent className=\"p-4\">\n <p className=\"text-xs font-medium text-text-secondary mb-2\">Import Summary</p>\n <div className=\"grid grid-cols-2 gap-x-6 gap-y-1 text-xs\">\n <span className=\"text-text-secondary\">Pages:</span>\n <span>{importResult.stats.pagesCreated}</span>\n <span className=\"text-text-secondary\">Widgets:</span>\n <span>{importResult.stats.widgetsCreated}</span>\n <span className=\"text-text-secondary\">Actions:</span>\n <span>{importResult.stats.actionsCreated}</span>\n </div>\n </CardContent>\n </Card>\n )}\n </>\n )}\n </div>\n )}\n\n {/* Error */}\n {error && (\n <Card className=\"border-status-error-border/50 bg-status-error-bg/5\">\n <CardContent className=\"p-3\">\n <p className=\"text-sm text-status-error-text\">{error.message}</p>\n </CardContent>\n </Card>\n )}\n\n {importResult && !importResult.success && importResult.errorMessage && (\n <Card className=\"border-status-error-border/50 bg-status-error-bg/5\">\n <CardContent className=\"p-3\">\n <p className=\"text-sm text-status-error-text\">{importResult.errorMessage}</p>\n </CardContent>\n </Card>\n )}\n </div>\n\n <DialogFooter className=\"flex-row justify-between sm:justify-between\">\n <div>\n {step === 'preview' && (\n <Button\n variant=\"ghost\"\n onClick={() => {\n setStep('select');\n setSelectedFile(null);\n setFileContent(null);\n clearState();\n }}\n disabled={loading}\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </Button>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {step !== 'complete' && (\n <Button variant=\"outline\" onClick={onClose} disabled={!canClose}>\n Cancel\n </Button>\n )}\n\n {step === 'preview' && validationResult?.isValid && (\n <Button\n onClick={handleImport}\n disabled={loading || (validationResult.warnings.length > 0 && !skipWarnings)}\n >\n <Upload className=\"size-4\" />\n Import Dashboard\n </Button>\n )}\n\n {step === 'importing' && (\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Spinner className=\"size-4\" />\n Importing...\n </div>\n )}\n\n {step === 'complete' && <Button onClick={onClose}>Done</Button>}\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n});\n\nexport default ImportDashboardDialog;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ImportDashboardDialog.js","names":[],"sources":["../../../../src/bigconsole/components/dashboard/ImportDashboardDialog.tsx"],"sourcesContent":["/**\n * ImportDashboardDialog Component\n *\n * Modal dialog for importing a dashboard from JSON file.\n * Supports both creating new dashboards and updating existing ones.\n * Uses fe-libs shared UI components for consistent styling.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect, useRef } 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 { Label } from '@burdenoff/fe-libs/ui';\nimport { Checkbox } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { Upload, FileJson, Check, AlertTriangle, XCircle, ArrowLeft, RefreshCw, Info } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useImportDashboard, type ImportDashboardOptions } from '../../hooks';\nimport { useBigConsoleAnalytics } from '../../hooks/useBigConsoleAnalytics';\nimport { reportBigConsoleQuotaError } from '../../utils/quota';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImportDashboardDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess?: (dashboardId: string, dashboardName: string, originalUpdated: boolean) => void;\n}\n\ntype ImportStep = 'select' | 'preview' | 'importing' | 'complete';\n\n// ============================================================================\n// Helper: Extract dashboard ID from content\n// ============================================================================\n\nfunction extractDashboardId(content: string | null): string | null {\n if (!content) return null;\n try {\n const parsed = JSON.parse(content);\n return parsed.exportedFrom?.dashboardId || parsed.dashboard?.id || null;\n } catch {\n return null;\n }\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const ImportDashboardDialog: FC<ImportDashboardDialogProps> = memo(function ImportDashboardDialog({\n isOpen,\n onClose,\n onSuccess,\n}) {\n const { t } = useI18n();\n const [step, setStep] = useState<ImportStep>('select');\n const [, setSelectedFile] = useState<File | null>(null);\n const [fileContent, setFileContent] = useState<string | null>(null);\n const [nameOverride, setNameOverride] = useState('');\n const [visibility, setVisibility] = useState<'PRIVATE' | 'TEAM' | 'PUBLIC'>('PRIVATE');\n const [skipWarnings, setSkipWarnings] = useState(false);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { loading, error, validationResult, importResult, validateImport, importDashboard, clearState } =\n useImportDashboard();\n const emitBigConsoleEvent = useBigConsoleAnalytics();\n\n // Reset state when dialog opens\n useEffect(() => {\n if (isOpen) {\n setStep('select');\n setSelectedFile(null);\n setFileContent(null);\n setNameOverride('');\n setVisibility('PRIVATE');\n setSkipWarnings(false);\n clearState();\n }\n }, [isOpen, clearState]);\n\n // Handle file selection\n const handleFileSelect = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n if (!file.name.endsWith('.json')) {\n alert(t('bigconsole.dashboards.import.selectJsonFile', 'Please select a JSON file'));\n return;\n }\n\n setSelectedFile(file);\n\n const reader = new FileReader();\n reader.onload = async (event) => {\n const content = event.target?.result as string;\n setFileContent(content);\n\n const result = await validateImport(content);\n if (result) {\n setStep('preview');\n if (result.dashboardInfo?.name) {\n setNameOverride(result.dashboardInfo.name);\n }\n }\n };\n reader.onerror = () => {\n alert(t('bigconsole.dashboards.import.failedToReadFile', 'Failed to read file'));\n };\n reader.readAsText(file);\n },\n [validateImport, t]\n );\n\n // Handle file drop\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n const file = e.dataTransfer.files?.[0];\n if (file) {\n const dt = new DataTransfer();\n dt.items.add(file);\n if (fileInputRef.current) {\n fileInputRef.current.files = dt.files;\n fileInputRef.current.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }\n }, []);\n\n // Handle import\n const handleImport = useCallback(async () => {\n if (!fileContent) return;\n\n setStep('importing');\n\n const options: ImportDashboardOptions = {\n name: nameOverride.trim() || undefined,\n visibility,\n skipWarnings,\n };\n\n emitBigConsoleEvent('bigconsole.dashboard.import_clicked', { source: 'import' });\n\n try {\n const result = await importDashboard(fileContent, options);\n\n if (result?.success && result.dashboard) {\n setStep('complete');\n emitBigConsoleEvent('bigconsole.dashboard.imported', {\n dashboardId: result.dashboard.id,\n source: 'import',\n originalUpdated: result.originalUpdated ?? false,\n });\n onSuccess?.(result.dashboard.id, result.dashboard.name, result.originalUpdated ?? false);\n } else {\n setStep('preview');\n }\n } catch (err) {\n if (reportBigConsoleQuotaError(err, 'project')) {\n onClose();\n return;\n }\n setStep('preview');\n }\n }, [emitBigConsoleEvent, fileContent, importDashboard, nameOverride, onClose, onSuccess, skipWarnings, visibility]);\n\n const canClose = !loading && step !== 'importing';\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && canClose && onClose()}>\n <DialogContent className=\"sm:max-w-lg max-h-[85vh] flex flex-col\">\n <DialogHeader>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-action-primary-bg/10\">\n <Upload className=\"size-5 text-primary\" />\n </div>\n <DialogTitle>{t('bigconsole.dashboards.import.title', 'Import Dashboard')}</DialogTitle>\n </div>\n <DialogDescription>\n {t(\n 'bigconsole.dashboards.import.description',\n 'Upload a Dashboard export file to restore it into this workspace.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"flex-1 overflow-y-auto py-4 space-y-4\">\n {/* Step 1: File Selection */}\n {step === 'select' && (\n <div\n onDragOver={(e) => e.preventDefault()}\n onDrop={handleDrop}\n className=\"border-2 border-dashed rounded-lg p-8 text-center hover:border-primary transition-colors\"\n >\n <FileJson className=\"size-12 mx-auto text-text-secondary mb-4\" />\n <p className=\"text-sm mb-2\">\n {t('bigconsole.dashboards.import.dropzoneTitle', 'Drag and drop a dashboard export file here')}\n </p>\n <p className=\"text-xs text-text-secondary mb-4\">{t('bigconsole.dashboards.import.or', 'or')}</p>\n <input ref={fileInputRef} type=\"file\" accept=\".json\" onChange={handleFileSelect} className=\"hidden\" />\n <Button onClick={() => fileInputRef.current?.click()} disabled={loading}>\n {t('bigconsole.dashboards.import.browseFiles', 'Browse Files')}\n </Button>\n <p className=\"text-xs text-text-secondary mt-4\">\n {t(\n 'bigconsole.dashboards.import.supportedFilesHint',\n 'Only .json files exported from BigConsole are supported'\n )}\n </p>\n </div>\n )}\n\n {/* Step 2: Preview & Options */}\n {(step === 'preview' || step === 'importing') && validationResult && (\n <>\n {/* Dashboard Info */}\n <Card>\n <CardContent className=\"p-4 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('bigconsole.dashboards.import.fieldDashboard', 'Dashboard')}\n </span>\n <span className=\"text-sm font-medium\">{validationResult.dashboardInfo.name}</span>\n </div>\n {validationResult.dashboardInfo.description && (\n <div className=\"flex items-start justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('bigconsole.dashboards.import.fieldDescription', 'Description')}\n </span>\n <span className=\"text-sm text-right max-w-[60%] truncate\">\n {validationResult.dashboardInfo.description}\n </span>\n </div>\n )}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('bigconsole.dashboards.import.fieldPages', 'Pages')}\n </span>\n <Badge variant=\"secondary\">{validationResult.dashboardInfo.pageCount}</Badge>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('bigconsole.dashboards.import.fieldWidgets', 'Widgets')}\n </span>\n <Badge variant=\"secondary\">{validationResult.dashboardInfo.widgetCount}</Badge>\n </div>\n {validationResult.dashboardInfo.exportedFrom && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('bigconsole.dashboards.import.fieldSourceId', 'Source ID')}\n </span>\n <span className=\"text-xs text-text-secondary font-mono truncate max-w-[180px]\">\n {validationResult.dashboardInfo.exportedFrom}\n </span>\n </div>\n )}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('bigconsole.dashboards.import.fieldSchemaVersion', 'Schema Version')}\n </span>\n <span className=\"text-xs text-text-secondary\">{validationResult.dashboardInfo.schemaVersion}</span>\n </div>\n </CardContent>\n </Card>\n\n {/* Validation Errors */}\n {validationResult.errors.length > 0 && (\n <Card className=\"border-status-error-border/50 bg-status-error-bg/5\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <XCircle className=\"size-4 text-status-error-text\" />\n <span className=\"text-sm font-medium text-status-error-text\">\n {t('bigconsole.dashboards.import.errorsCount', 'Errors ({{count}})', {\n count: validationResult.errors.length,\n })}\n </span>\n </div>\n <ul className=\"text-xs text-status-error-text space-y-1\">\n {validationResult.errors.map((err, idx) => (\n <li key={idx}>\n <span className=\"font-mono\">[{err.code}]</span> {err.message}\n </li>\n ))}\n </ul>\n </CardContent>\n </Card>\n )}\n\n {/* Validation Warnings */}\n {validationResult.warnings.length > 0 && (\n <Card className=\"border-yellow-500/50 bg-yellow-500/5\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-center gap-2 mb-2\">\n <AlertTriangle className=\"size-4 text-yellow-600\" />\n <span className=\"text-sm font-medium text-yellow-600\">\n {t('bigconsole.dashboards.import.warningsCount', 'Warnings ({{count}})', {\n count: validationResult.warnings.length,\n })}\n </span>\n </div>\n <ul className=\"text-xs text-yellow-600 space-y-1\">\n {validationResult.warnings.map((warn, idx) => (\n <li key={idx}>\n <span className=\"font-mono\">[{warn.code}]</span> {warn.message}\n </li>\n ))}\n </ul>\n </CardContent>\n </Card>\n )}\n\n {/* Import Options */}\n {validationResult.isValid && (\n <div className=\"space-y-4\">\n <p className=\"text-sm font-medium\">\n {t('bigconsole.dashboards.import.optionsTitle', 'Import Options')}\n </p>\n\n {/* Import Info */}\n <Card className=\"border-blue-500/50 bg-blue-500/5\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-start gap-2\">\n <Info className=\"size-4 text-blue-600 mt-0.5 shrink-0\" />\n <div className=\"text-xs text-blue-700 dark:text-blue-400\">\n {extractDashboardId(fileContent) ? (\n <>\n <p className=\"font-medium mb-1\">\n {t(\n 'bigconsole.dashboards.import.checkExistingTitle',\n 'Import will check for existing dashboard'\n )}\n </p>\n <p>\n {t(\n 'bigconsole.dashboards.import.checkExistingIdPrefix',\n 'If the original dashboard (ID:'\n )}{' '}\n <code className=\"font-mono bg-blue-200/50 px-1 rounded\">\n {extractDashboardId(fileContent)?.slice(0, 8)}...\n </code>\n {t('bigconsole.dashboards.import.checkExistingIdSuffix', ') exists:')}\n </p>\n <ul className=\"list-disc list-inside mt-1 space-y-0.5\">\n <li>\n {t(\n 'bigconsole.dashboards.import.checkExistingWithChanges',\n 'With changes → Update the existing dashboard'\n )}\n </li>\n <li>\n {t(\n 'bigconsole.dashboards.import.checkExistingNoChanges',\n 'No changes → Show \"already exists\" message'\n )}\n </li>\n </ul>\n <p className=\"mt-1\">\n {t(\n 'bigconsole.dashboards.import.checkExistingNotFound',\n \"If original doesn't exist → Create a new dashboard\"\n )}\n </p>\n </>\n ) : (\n <>\n <p className=\"font-medium mb-1\">\n {t('bigconsole.dashboards.import.newDashboardTitle', 'A new dashboard will be created')}\n </p>\n <p>\n {t(\n 'bigconsole.dashboards.import.newDashboardBody',\n 'Import as a new dashboard with the specified configuration.'\n )}\n </p>\n </>\n )}\n </div>\n </div>\n </CardContent>\n </Card>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"import-name\">\n {t('bigconsole.dashboards.import.dashboardNameLabel', 'Dashboard Name')}\n </Label>\n <Input\n id=\"import-name\"\n type=\"text\"\n value={nameOverride}\n onChange={(e) => setNameOverride(e.target.value)}\n placeholder={validationResult.dashboardInfo.name}\n disabled={step === 'importing'}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label>{t('bigconsole.dashboards.import.visibilityLabel', 'Visibility')}</Label>\n <div className=\"flex gap-2\">\n {(['PRIVATE', 'TEAM', 'PUBLIC'] as const).map((v) => (\n <Button\n key={v}\n type=\"button\"\n variant={visibility === v ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setVisibility(v)}\n disabled={step === 'importing'}\n >\n {v === 'PRIVATE'\n ? t('bigconsole.dashboards.import.visibilityPrivate', 'Private')\n : v === 'TEAM'\n ? t('bigconsole.dashboards.import.visibilityTeam', 'Team')\n : t('bigconsole.dashboards.import.visibilityPublic', 'Public')}\n </Button>\n ))}\n </div>\n </div>\n\n {validationResult.warnings.length > 0 && (\n <div className=\"flex items-start space-x-3\">\n <Checkbox\n id=\"skipWarnings\"\n checked={skipWarnings}\n onCheckedChange={(checked) => setSkipWarnings(checked === true)}\n disabled={step === 'importing'}\n />\n <div className=\"grid gap-1.5 leading-none\">\n <Label htmlFor=\"skipWarnings\" className=\"cursor-pointer\">\n {t('bigconsole.dashboards.import.acknowledgeWarnings', 'Acknowledge warnings and proceed')}\n </Label>\n </div>\n </div>\n )}\n </div>\n )}\n </>\n )}\n\n {/* Step 3: Complete */}\n {step === 'complete' && importResult?.success && (\n <div className=\"text-center py-6\">\n {/* Already Exists - No Changes */}\n {importResult.alreadyExists && (\n <>\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center\">\n <Info className=\"size-8 text-blue-600\" />\n </div>\n <h3 className=\"text-lg font-medium mb-2\">\n {t('bigconsole.dashboards.import.alreadyExistsTitle', 'Dashboard Already Exists')}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {t(\n 'bigconsole.dashboards.import.alreadyExistsBody',\n 'Dashboard \"{{name}}\" already exists with the same data. No changes were made.',\n { name: importResult.dashboard?.name ?? '' }\n )}\n </p>\n </>\n )}\n\n {/* Updated Existing */}\n {importResult.originalUpdated && !importResult.alreadyExists && (\n <>\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center\">\n <RefreshCw className=\"size-8 text-green-600\" />\n </div>\n <h3 className=\"text-lg font-medium mb-2\">\n {t('bigconsole.dashboards.import.updatedTitle', 'Dashboard Updated!')}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {t(\n 'bigconsole.dashboards.import.updatedBody',\n 'Dashboard \"{{name}}\" has been updated with the imported data.',\n { name: importResult.dashboard?.name ?? '' }\n )}\n </p>\n </>\n )}\n\n {/* Created New */}\n {!importResult.originalUpdated && !importResult.alreadyExists && (\n <>\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center\">\n <Check className=\"size-8 text-green-600\" />\n </div>\n <h3 className=\"text-lg font-medium mb-2\">\n {t('bigconsole.dashboards.import.successTitle', 'Import Successful!')}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {t('bigconsole.dashboards.import.successBody', 'Dashboard \"{{name}}\" has been created.', {\n name: importResult.dashboard?.name ?? '',\n })}\n </p>\n\n {importResult.stats && (\n <Card className=\"inline-block text-left\">\n <CardContent className=\"p-4\">\n <p className=\"text-xs font-medium text-text-secondary mb-2\">\n {t('bigconsole.dashboards.import.summaryTitle', 'Import Summary')}\n </p>\n <div className=\"grid grid-cols-2 gap-x-6 gap-y-1 text-xs\">\n <span className=\"text-text-secondary\">\n {t('bigconsole.dashboards.import.summaryPages', 'Pages:')}\n </span>\n <span>{importResult.stats.pagesCreated}</span>\n <span className=\"text-text-secondary\">\n {t('bigconsole.dashboards.import.summaryWidgets', 'Widgets:')}\n </span>\n <span>{importResult.stats.widgetsCreated}</span>\n <span className=\"text-text-secondary\">\n {t('bigconsole.dashboards.import.summaryActions', 'Actions:')}\n </span>\n <span>{importResult.stats.actionsCreated}</span>\n </div>\n </CardContent>\n </Card>\n )}\n </>\n )}\n </div>\n )}\n\n {/* Error */}\n {error && (\n <Card className=\"border-status-error-border/50 bg-status-error-bg/5\">\n <CardContent className=\"p-3\">\n <p className=\"text-sm text-status-error-text\">{error.message}</p>\n </CardContent>\n </Card>\n )}\n\n {importResult && !importResult.success && importResult.errorMessage && (\n <Card className=\"border-status-error-border/50 bg-status-error-bg/5\">\n <CardContent className=\"p-3\">\n <p className=\"text-sm text-status-error-text\">{importResult.errorMessage}</p>\n </CardContent>\n </Card>\n )}\n </div>\n\n <DialogFooter className=\"flex-row justify-between sm:justify-between\">\n <div>\n {step === 'preview' && (\n <Button\n variant=\"ghost\"\n onClick={() => {\n setStep('select');\n setSelectedFile(null);\n setFileContent(null);\n clearState();\n }}\n disabled={loading}\n >\n <ArrowLeft className=\"size-4\" />\n {t('bigconsole.dashboards.import.back', 'Back')}\n </Button>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {step !== 'complete' && (\n <Button variant=\"outline\" onClick={onClose} disabled={!canClose}>\n {t('bigconsole.dashboards.import.cancel', 'Cancel')}\n </Button>\n )}\n\n {step === 'preview' && validationResult?.isValid && (\n <Button\n onClick={handleImport}\n disabled={loading || (validationResult.warnings.length > 0 && !skipWarnings)}\n >\n <Upload className=\"size-4\" />\n {t('bigconsole.dashboards.import.importButton', 'Import Dashboard')}\n </Button>\n )}\n\n {step === 'importing' && (\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Spinner className=\"size-4\" />\n {t('bigconsole.dashboards.import.importing', 'Importing...')}\n </div>\n )}\n\n {step === 'complete' && <Button onClick={onClose}>{t('bigconsole.dashboards.import.done', 'Done')}</Button>}\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n});\n\nexport default ImportDashboardDialog;\n"],"mappings":"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"}
@@ -1,137 +1,139 @@
1
- import { SEMANTIC_COLORS as e } from "../../../utils/semanticTokens.js";
2
- import { useCallback as t, useEffect as n, useRef as r, useState as i } from "react";
3
- import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
4
- import { createPortal as c } from "react-dom";
1
+ import { BIGCONSOLE_PERMISSIONS as e } from "../../../../constants/permissions.js";
2
+ import { SEMANTIC_COLORS as t } from "../../../utils/semanticTokens.js";
3
+ import { useCallback as n, useEffect as r, useRef as i, useState as a } from "react";
4
+ import { usePermissions as o } from "@burdenoff/fe-libs/shared/providers/shell";
5
+ import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
6
+ import { createPortal as u } from "react-dom";
5
7
  //#region src/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.tsx
6
- function l({ pages: l, activePageId: u, onPageSelect: d, onPageCreate: f, onPageRename: p, onPageDuplicate: m, onPageDelete: h, onPagesReorder: g, editable: _ = !0, className: v = "" }) {
7
- let [y, b] = i(null), [x, S] = i(null), [C, w] = i(null), [T, E] = i(""), [D, O] = i(null), [k, A] = i({
8
+ function d({ pages: d, activePageId: f, onPageSelect: p, onPageCreate: m, onPageRename: h, onPageDuplicate: g, onPageDelete: _, onPagesReorder: v, editable: y = !0, className: b = "" }) {
9
+ let { hasPermission: x } = o(), S = x(e.DASHBOARD_PAGE_CREATE), C = x(e.DASHBOARD_PAGE_UPDATE), w = x(e.DASHBOARD_PAGE_DELETE), [T, E] = a(null), [D, O] = a(null), [k, A] = a(null), [j, M] = a(""), [N, P] = a(null), [F, I] = a({
8
10
  x: 0,
9
11
  y: 0
10
- }), j = r(null), M = r(null);
11
- n(() => {
12
- C && j.current && (j.current.focus(), j.current.select());
13
- }, [C]), n(() => {
12
+ }), L = i(null), R = i(null);
13
+ r(() => {
14
+ k && L.current && (L.current.focus(), L.current.select());
15
+ }, [k]), r(() => {
14
16
  function e(e) {
15
- M.current && !M.current.contains(e.target) && O(null);
17
+ R.current && !R.current.contains(e.target) && P(null);
16
18
  }
17
19
  return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
18
20
  }, []);
19
- let N = t((e, t) => {
20
- b(t), e.dataTransfer.effectAllowed = "move";
21
- }, []), P = t((e, t) => {
22
- e.preventDefault(), e.dataTransfer.dropEffect = "move", y && y !== t && S(t);
23
- }, [y]), F = t(() => {
24
- if (y && x && y !== x && g) {
25
- let e = [...l], t = e.findIndex((e) => e.id === y), n = e.findIndex((e) => e.id === x);
21
+ let z = n((e, t) => {
22
+ E(t), e.dataTransfer.effectAllowed = "move";
23
+ }, []), B = n((e, t) => {
24
+ e.preventDefault(), e.dataTransfer.dropEffect = "move", T && T !== t && O(t);
25
+ }, [T]), V = n(() => {
26
+ if (T && D && T !== D && v) {
27
+ let e = [...d], t = e.findIndex((e) => e.id === T), n = e.findIndex((e) => e.id === D);
26
28
  if (t !== -1 && n !== -1) {
27
29
  let [r] = e.splice(t, 1);
28
- e.splice(n, 0, r), g(e.map((e) => e.id));
30
+ e.splice(n, 0, r), v(e.map((e) => e.id));
29
31
  }
30
32
  }
31
- b(null), S(null);
33
+ E(null), O(null);
32
34
  }, [
33
- y,
34
- x,
35
- l,
36
- g
37
- ]), I = t((e, t) => {
38
- e.preventDefault(), O(t), A({
35
+ T,
36
+ D,
37
+ d,
38
+ v
39
+ ]), H = n((e, t) => {
40
+ e.preventDefault(), P(t), I({
39
41
  x: e.clientX,
40
42
  y: e.clientY
41
43
  });
42
- }, []), L = t((e, t) => {
43
- w(e), E(t), O(null);
44
- }, []), R = t(() => {
45
- C && T.trim() && p && p(C, T.trim()), w(null), E("");
44
+ }, []), U = n((e, t) => {
45
+ A(e), M(t), P(null);
46
+ }, []), W = n(() => {
47
+ k && j.trim() && h && h(k, j.trim()), A(null), M("");
46
48
  }, [
47
- C,
48
- T,
49
- p
50
- ]), z = t(() => {
51
- w(null), E("");
52
- }, []), B = t((e) => {
53
- e.key === "Enter" ? R() : e.key === "Escape" && z();
54
- }, [R, z]);
55
- return /* @__PURE__ */ s("div", {
56
- ref: M,
57
- className: v,
49
+ k,
50
+ j,
51
+ h
52
+ ]), G = n(() => {
53
+ A(null), M("");
54
+ }, []), K = n((e) => {
55
+ e.key === "Enter" ? W() : e.key === "Escape" && G();
56
+ }, [W, G]);
57
+ return /* @__PURE__ */ l("div", {
58
+ ref: R,
59
+ className: b,
58
60
  style: {
59
61
  display: "flex",
60
62
  alignItems: "center",
61
63
  gap: "4px",
62
64
  padding: "0 8px",
63
65
  overflowX: "auto",
64
- backgroundColor: e.bgSecondary,
65
- borderBottom: `1px solid ${e.borderDefault}`,
66
+ backgroundColor: t.bgSecondary,
67
+ borderBottom: `1px solid ${t.borderDefault}`,
66
68
  minHeight: "40px"
67
69
  },
68
70
  children: [
69
- l.sort((e, t) => e.order - t.order).map((t) => /* @__PURE__ */ o("div", {
70
- draggable: _ && !C,
71
- onDragStart: (e) => N(e, t.id),
72
- onDragOver: (e) => P(e, t.id),
73
- onDragEnd: F,
74
- onContextMenu: (e) => _ && I(e, t.id),
75
- onClick: () => !C && d(t.id),
76
- onDoubleClick: () => _ && L(t.id, t.name),
71
+ d.sort((e, t) => e.order - t.order).map((e) => /* @__PURE__ */ c("div", {
72
+ draggable: y && C && !k,
73
+ onDragStart: (t) => z(t, e.id),
74
+ onDragOver: (t) => B(t, e.id),
75
+ onDragEnd: V,
76
+ onContextMenu: (t) => y && (C || w || !!g) && H(t, e.id),
77
+ onClick: () => !k && p(e.id),
78
+ onDoubleClick: () => y && C && U(e.id, e.name),
77
79
  style: {
78
80
  position: "relative",
79
81
  display: "flex",
80
82
  alignItems: "center",
81
83
  gap: "6px",
82
84
  padding: "8px 12px",
83
- backgroundColor: u === t.id ? e.bgPrimary : "transparent",
84
- borderBottom: u === t.id ? `2px solid ${e.actionPrimaryBg}` : "2px solid transparent",
85
- cursor: C === t.id ? "text" : "pointer",
86
- opacity: y === t.id ? .5 : 1,
87
- borderLeft: x === t.id ? `2px solid ${e.actionPrimaryBg}` : "none",
85
+ backgroundColor: f === e.id ? t.bgPrimary : "transparent",
86
+ borderBottom: f === e.id ? `2px solid ${t.actionPrimaryBg}` : "2px solid transparent",
87
+ cursor: k === e.id ? "text" : "pointer",
88
+ opacity: T === e.id ? .5 : 1,
89
+ borderLeft: D === e.id ? `2px solid ${t.actionPrimaryBg}` : "none",
88
90
  flexShrink: 0,
89
91
  transition: "background-color 0.15s, border-color 0.15s"
90
92
  },
91
- children: C === t.id ? /* @__PURE__ */ o("input", {
92
- ref: j,
93
+ children: k === e.id ? /* @__PURE__ */ c("input", {
94
+ ref: L,
93
95
  type: "text",
94
- value: T,
95
- onChange: (e) => E(e.target.value),
96
- onKeyDown: B,
97
- onBlur: R,
96
+ value: j,
97
+ onChange: (e) => M(e.target.value),
98
+ onKeyDown: K,
99
+ onBlur: W,
98
100
  style: {
99
101
  width: "100px",
100
102
  padding: "2px 4px",
101
- border: `1px solid ${e.actionPrimaryBg}`,
103
+ border: `1px solid ${t.actionPrimaryBg}`,
102
104
  borderRadius: "2px",
103
105
  fontSize: "13px",
104
106
  outline: "none",
105
- backgroundColor: e.bgPrimary,
106
- color: e.textPrimary
107
+ backgroundColor: t.bgPrimary,
108
+ color: t.textPrimary
107
109
  },
108
110
  onClick: (e) => e.stopPropagation()
109
- }) : /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("span", {
111
+ }) : /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("span", {
110
112
  style: {
111
113
  fontSize: "13px",
112
- fontWeight: u === t.id ? 600 : 400,
113
- color: u === t.id ? e.textPrimary : e.textSecondary
114
+ fontWeight: f === e.id ? 600 : 400,
115
+ color: f === e.id ? t.textPrimary : t.textSecondary
114
116
  },
115
- children: t.name
116
- }), t.widgetCount !== void 0 && /* @__PURE__ */ o("span", {
117
+ children: e.name
118
+ }), e.widgetCount !== void 0 && /* @__PURE__ */ c("span", {
117
119
  style: {
118
120
  fontSize: "10px",
119
- color: e.textTertiary,
120
- backgroundColor: e.borderDefault,
121
+ color: t.textTertiary,
122
+ backgroundColor: t.borderDefault,
121
123
  padding: "1px 4px",
122
124
  borderRadius: "8px"
123
125
  },
124
- children: t.widgetCount
126
+ children: e.widgetCount
125
127
  })] })
126
- }, t.id)),
127
- _ && f && /* @__PURE__ */ o("button", {
128
- onClick: f,
128
+ }, e.id)),
129
+ y && m && S && /* @__PURE__ */ c("button", {
130
+ onClick: m,
129
131
  style: {
130
132
  display: "flex",
131
133
  alignItems: "center",
132
134
  justifyContent: "center",
133
135
  padding: "6px 12px",
134
- backgroundColor: e.actionPrimaryBg,
136
+ backgroundColor: t.actionPrimaryBg,
135
137
  border: "none",
136
138
  borderRadius: "4px",
137
139
  cursor: "pointer",
@@ -143,13 +145,13 @@ function l({ pages: l, activePageId: u, onPageSelect: d, onPageCreate: f, onPage
143
145
  },
144
146
  children: "+ Add Page"
145
147
  }),
146
- D && c(/* @__PURE__ */ s("div", {
148
+ N && u(/* @__PURE__ */ l("div", {
147
149
  style: {
148
150
  position: "fixed",
149
- left: k.x,
150
- top: k.y,
151
- backgroundColor: e.bgPrimary,
152
- border: `1px solid ${e.borderDefault}`,
151
+ left: F.x,
152
+ top: F.y,
153
+ backgroundColor: t.bgPrimary,
154
+ border: `1px solid ${t.borderDefault}`,
153
155
  borderRadius: "6px",
154
156
  boxShadow: "0 8px 24px rgba(0,0,0,0.2)",
155
157
  zIndex: 99999,
@@ -157,59 +159,59 @@ function l({ pages: l, activePageId: u, onPageSelect: d, onPageCreate: f, onPage
157
159
  },
158
160
  onClick: (e) => e.stopPropagation(),
159
161
  children: [
160
- /* @__PURE__ */ o("button", {
162
+ C && /* @__PURE__ */ c("button", {
161
163
  onClick: () => {
162
- let e = l.find((e) => e.id === D);
163
- e && L(D, e.name);
164
+ let e = d.find((e) => e.id === N);
165
+ e && U(N, e.name);
164
166
  },
165
167
  style: {
166
168
  display: "block",
167
169
  width: "100%",
168
170
  padding: "8px 12px",
169
171
  textAlign: "left",
170
- backgroundColor: e.bgPrimary,
172
+ backgroundColor: t.bgPrimary,
171
173
  border: "none",
172
174
  cursor: "pointer",
173
175
  fontSize: "13px",
174
- color: e.textPrimary
176
+ color: t.textPrimary
175
177
  },
176
178
  children: "Rename"
177
179
  }),
178
- m && /* @__PURE__ */ o("button", {
180
+ g && S && /* @__PURE__ */ c("button", {
179
181
  onClick: () => {
180
- m(D), O(null);
182
+ g(N), P(null);
181
183
  },
182
184
  style: {
183
185
  display: "block",
184
186
  width: "100%",
185
187
  padding: "8px 12px",
186
188
  textAlign: "left",
187
- backgroundColor: e.bgPrimary,
189
+ backgroundColor: t.bgPrimary,
188
190
  border: "none",
189
191
  cursor: "pointer",
190
192
  fontSize: "13px",
191
- color: e.textPrimary
193
+ color: t.textPrimary
192
194
  },
193
195
  children: "Duplicate"
194
196
  }),
195
- h && l.length > 1 && /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("div", { style: {
197
+ _ && w && d.length > 1 && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("div", { style: {
196
198
  height: "1px",
197
- backgroundColor: e.borderDefault,
199
+ backgroundColor: t.borderDefault,
198
200
  margin: "4px 0"
199
- } }), /* @__PURE__ */ o("button", {
201
+ } }), /* @__PURE__ */ c("button", {
200
202
  onClick: () => {
201
- window.confirm("Are you sure you want to delete this page?") && h(D), O(null);
203
+ window.confirm("Are you sure you want to delete this page?") && _(N), P(null);
202
204
  },
203
205
  style: {
204
206
  display: "block",
205
207
  width: "100%",
206
208
  padding: "8px 12px",
207
209
  textAlign: "left",
208
- backgroundColor: e.bgPrimary,
210
+ backgroundColor: t.bgPrimary,
209
211
  border: "none",
210
212
  cursor: "pointer",
211
213
  fontSize: "13px",
212
- color: e.statusErrorText
214
+ color: t.statusErrorText
213
215
  },
214
216
  children: "Delete"
215
217
  })] })
@@ -219,6 +221,6 @@ function l({ pages: l, activePageId: u, onPageSelect: d, onPageCreate: f, onPage
219
221
  });
220
222
  }
221
223
  //#endregion
222
- export { l as default };
224
+ export { d as default };
223
225
 
224
226
  //# sourceMappingURL=PageTabsManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageTabsManager.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.tsx"],"sourcesContent":["/**\n * PageTabsManager Component\n *\n * Manages dashboard page tabs with drag-and-drop reordering.\n */\n\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { SEMANTIC_COLORS } from '../../../utils/semanticTokens';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DashboardPageTab {\n id: string;\n name: string;\n order: number;\n widgetCount?: number;\n}\n\nexport interface PageTabsManagerProps {\n pages: DashboardPageTab[];\n activePageId: string;\n onPageSelect: (pageId: string) => void;\n onPageCreate?: () => void;\n onPageRename?: (pageId: string, newName: string) => void;\n onPageDuplicate?: (pageId: string) => void;\n onPageDelete?: (pageId: string) => void;\n onPagesReorder?: (pageIds: string[]) => void;\n editable?: boolean;\n className?: string;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function PageTabsManager({\n pages,\n activePageId,\n onPageSelect,\n onPageCreate,\n onPageRename,\n onPageDuplicate,\n onPageDelete,\n onPagesReorder,\n editable = true,\n className = '',\n}: PageTabsManagerProps) {\n const [draggedId, setDraggedId] = useState<string | null>(null);\n const [dragOverId, setDragOverId] = useState<string | null>(null);\n const [editingId, setEditingId] = useState<string | null>(null);\n const [editingName, setEditingName] = useState('');\n const [contextMenuId, setContextMenuId] = useState<string | null>(null);\n const [contextMenuPos, setContextMenuPos] = useState({ x: 0, y: 0 });\n\n const editInputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Focus input when editing\n useEffect(() => {\n if (editingId && editInputRef.current) {\n editInputRef.current.focus();\n editInputRef.current.select();\n }\n }, [editingId]);\n\n // Close context menu on click outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setContextMenuId(null);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n // Drag handlers\n const handleDragStart = useCallback((e: React.DragEvent, pageId: string) => {\n setDraggedId(pageId);\n e.dataTransfer.effectAllowed = 'move';\n }, []);\n\n const handleDragOver = useCallback(\n (e: React.DragEvent, pageId: string) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n if (draggedId && draggedId !== pageId) {\n setDragOverId(pageId);\n }\n },\n [draggedId]\n );\n\n const handleDragEnd = useCallback(() => {\n if (draggedId && dragOverId && draggedId !== dragOverId && onPagesReorder) {\n const orderedPages = [...pages];\n const draggedIndex = orderedPages.findIndex((p) => p.id === draggedId);\n const targetIndex = orderedPages.findIndex((p) => p.id === dragOverId);\n\n if (draggedIndex !== -1 && targetIndex !== -1) {\n const [draggedPage] = orderedPages.splice(draggedIndex, 1);\n orderedPages.splice(targetIndex, 0, draggedPage);\n onPagesReorder(orderedPages.map((p) => p.id));\n }\n }\n\n setDraggedId(null);\n setDragOverId(null);\n }, [draggedId, dragOverId, pages, onPagesReorder]);\n\n // Context menu handler\n const handleContextMenu = useCallback((e: React.MouseEvent, pageId: string) => {\n e.preventDefault();\n setContextMenuId(pageId);\n setContextMenuPos({ x: e.clientX, y: e.clientY });\n }, []);\n\n // Start editing\n const handleStartEdit = useCallback((pageId: string, currentName: string) => {\n setEditingId(pageId);\n setEditingName(currentName);\n setContextMenuId(null);\n }, []);\n\n // Save edit\n const handleSaveEdit = useCallback(() => {\n if (editingId && editingName.trim() && onPageRename) {\n onPageRename(editingId, editingName.trim());\n }\n setEditingId(null);\n setEditingName('');\n }, [editingId, editingName, onPageRename]);\n\n // Cancel edit\n const handleCancelEdit = useCallback(() => {\n setEditingId(null);\n setEditingName('');\n }, []);\n\n // Handle key press in edit mode\n const handleEditKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleSaveEdit();\n } else if (e.key === 'Escape') {\n handleCancelEdit();\n }\n },\n [handleSaveEdit, handleCancelEdit]\n );\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n padding: '0 8px',\n overflowX: 'auto',\n backgroundColor: SEMANTIC_COLORS.bgSecondary,\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n minHeight: '40px',\n }}\n >\n {/* Page Tabs */}\n {pages\n .sort((a, b) => a.order - b.order)\n .map((page) => (\n <div\n key={page.id}\n draggable={editable && !editingId}\n onDragStart={(e) => handleDragStart(e, page.id)}\n onDragOver={(e) => handleDragOver(e, page.id)}\n onDragEnd={handleDragEnd}\n onContextMenu={(e) => editable && handleContextMenu(e, page.id)}\n onClick={() => !editingId && onPageSelect(page.id)}\n onDoubleClick={() => editable && handleStartEdit(page.id, page.name)}\n style={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n padding: '8px 12px',\n backgroundColor: activePageId === page.id ? SEMANTIC_COLORS.bgPrimary : 'transparent',\n borderBottom:\n activePageId === page.id ? `2px solid ${SEMANTIC_COLORS.actionPrimaryBg}` : '2px solid transparent',\n cursor: editingId === page.id ? 'text' : 'pointer',\n opacity: draggedId === page.id ? 0.5 : 1,\n borderLeft: dragOverId === page.id ? `2px solid ${SEMANTIC_COLORS.actionPrimaryBg}` : 'none',\n flexShrink: 0,\n transition: 'background-color 0.15s, border-color 0.15s',\n }}\n >\n {editingId === page.id ? (\n <input\n ref={editInputRef}\n type=\"text\"\n value={editingName}\n onChange={(e) => setEditingName(e.target.value)}\n onKeyDown={handleEditKeyDown}\n onBlur={handleSaveEdit}\n style={{\n width: '100px',\n padding: '2px 4px',\n border: `1px solid ${SEMANTIC_COLORS.actionPrimaryBg}`,\n borderRadius: '2px',\n fontSize: '13px',\n outline: 'none',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n onClick={(e) => e.stopPropagation()}\n />\n ) : (\n <>\n <span\n style={{\n fontSize: '13px',\n fontWeight: activePageId === page.id ? 600 : 400,\n color: activePageId === page.id ? SEMANTIC_COLORS.textPrimary : SEMANTIC_COLORS.textSecondary,\n }}\n >\n {page.name}\n </span>\n {page.widgetCount !== undefined && (\n <span\n style={{\n fontSize: '10px',\n color: SEMANTIC_COLORS.textTertiary,\n backgroundColor: SEMANTIC_COLORS.borderDefault,\n padding: '1px 4px',\n borderRadius: '8px',\n }}\n >\n {page.widgetCount}\n </span>\n )}\n </>\n )}\n </div>\n ))}\n\n {/* Add Page Button */}\n {editable && onPageCreate && (\n <button\n onClick={onPageCreate}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '6px 12px',\n backgroundColor: SEMANTIC_COLORS.actionPrimaryBg,\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n color: '#ffffff',\n fontSize: '12px',\n fontWeight: 500,\n flexShrink: 0,\n marginLeft: '8px',\n }}\n >\n + Add Page\n </button>\n )}\n\n {/* Context Menu - rendered via portal */}\n {contextMenuId &&\n createPortal(\n <div\n style={{\n position: 'fixed',\n left: contextMenuPos.x,\n top: contextMenuPos.y,\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '6px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.2)',\n zIndex: 99999,\n minWidth: '140px',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n <button\n onClick={() => {\n const page = pages.find((p) => p.id === contextMenuId);\n if (page) handleStartEdit(contextMenuId, page.name);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n Rename\n </button>\n {onPageDuplicate && (\n <button\n onClick={() => {\n onPageDuplicate(contextMenuId);\n setContextMenuId(null);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n Duplicate\n </button>\n )}\n {onPageDelete && pages.length > 1 && (\n <>\n <div style={{ height: '1px', backgroundColor: SEMANTIC_COLORS.borderDefault, margin: '4px 0' }} />\n <button\n onClick={() => {\n if (window.confirm('Are you sure you want to delete this page?')) {\n onPageDelete(contextMenuId);\n }\n setContextMenuId(null);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.statusErrorText,\n }}\n >\n Delete\n </button>\n </>\n )}\n </div>,\n document.body\n )}\n </div>\n );\n}\n\nexport default PageTabsManager;\n"],"mappings":"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"}
1
+ {"version":3,"file":"PageTabsManager.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.tsx"],"sourcesContent":["/**\n * PageTabsManager Component\n *\n * Manages dashboard page tabs with drag-and-drop reordering.\n */\n\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { SEMANTIC_COLORS } from '../../../utils/semanticTokens';\nimport { BIGCONSOLE_PERMISSIONS } from '../../../../constants/permissions';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DashboardPageTab {\n id: string;\n name: string;\n order: number;\n widgetCount?: number;\n}\n\nexport interface PageTabsManagerProps {\n pages: DashboardPageTab[];\n activePageId: string;\n onPageSelect: (pageId: string) => void;\n onPageCreate?: () => void;\n onPageRename?: (pageId: string, newName: string) => void;\n onPageDuplicate?: (pageId: string) => void;\n onPageDelete?: (pageId: string) => void;\n onPagesReorder?: (pageIds: string[]) => void;\n editable?: boolean;\n className?: string;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function PageTabsManager({\n pages,\n activePageId,\n onPageSelect,\n onPageCreate,\n onPageRename,\n onPageDuplicate,\n onPageDelete,\n onPagesReorder,\n editable = true,\n className = '',\n}: PageTabsManagerProps) {\n const { hasPermission } = usePermissions();\n const canCreatePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_CREATE);\n const canUpdatePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_UPDATE);\n const canDeletePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_DELETE);\n\n const [draggedId, setDraggedId] = useState<string | null>(null);\n const [dragOverId, setDragOverId] = useState<string | null>(null);\n const [editingId, setEditingId] = useState<string | null>(null);\n const [editingName, setEditingName] = useState('');\n const [contextMenuId, setContextMenuId] = useState<string | null>(null);\n const [contextMenuPos, setContextMenuPos] = useState({ x: 0, y: 0 });\n\n const editInputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Focus input when editing\n useEffect(() => {\n if (editingId && editInputRef.current) {\n editInputRef.current.focus();\n editInputRef.current.select();\n }\n }, [editingId]);\n\n // Close context menu on click outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setContextMenuId(null);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n // Drag handlers\n const handleDragStart = useCallback((e: React.DragEvent, pageId: string) => {\n setDraggedId(pageId);\n e.dataTransfer.effectAllowed = 'move';\n }, []);\n\n const handleDragOver = useCallback(\n (e: React.DragEvent, pageId: string) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n if (draggedId && draggedId !== pageId) {\n setDragOverId(pageId);\n }\n },\n [draggedId]\n );\n\n const handleDragEnd = useCallback(() => {\n if (draggedId && dragOverId && draggedId !== dragOverId && onPagesReorder) {\n const orderedPages = [...pages];\n const draggedIndex = orderedPages.findIndex((p) => p.id === draggedId);\n const targetIndex = orderedPages.findIndex((p) => p.id === dragOverId);\n\n if (draggedIndex !== -1 && targetIndex !== -1) {\n const [draggedPage] = orderedPages.splice(draggedIndex, 1);\n orderedPages.splice(targetIndex, 0, draggedPage);\n onPagesReorder(orderedPages.map((p) => p.id));\n }\n }\n\n setDraggedId(null);\n setDragOverId(null);\n }, [draggedId, dragOverId, pages, onPagesReorder]);\n\n // Context menu handler\n const handleContextMenu = useCallback((e: React.MouseEvent, pageId: string) => {\n e.preventDefault();\n setContextMenuId(pageId);\n setContextMenuPos({ x: e.clientX, y: e.clientY });\n }, []);\n\n // Start editing\n const handleStartEdit = useCallback((pageId: string, currentName: string) => {\n setEditingId(pageId);\n setEditingName(currentName);\n setContextMenuId(null);\n }, []);\n\n // Save edit\n const handleSaveEdit = useCallback(() => {\n if (editingId && editingName.trim() && onPageRename) {\n onPageRename(editingId, editingName.trim());\n }\n setEditingId(null);\n setEditingName('');\n }, [editingId, editingName, onPageRename]);\n\n // Cancel edit\n const handleCancelEdit = useCallback(() => {\n setEditingId(null);\n setEditingName('');\n }, []);\n\n // Handle key press in edit mode\n const handleEditKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleSaveEdit();\n } else if (e.key === 'Escape') {\n handleCancelEdit();\n }\n },\n [handleSaveEdit, handleCancelEdit]\n );\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n padding: '0 8px',\n overflowX: 'auto',\n backgroundColor: SEMANTIC_COLORS.bgSecondary,\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n minHeight: '40px',\n }}\n >\n {/* Page Tabs */}\n {pages\n .sort((a, b) => a.order - b.order)\n .map((page) => (\n <div\n key={page.id}\n draggable={editable && canUpdatePage && !editingId}\n onDragStart={(e) => handleDragStart(e, page.id)}\n onDragOver={(e) => handleDragOver(e, page.id)}\n onDragEnd={handleDragEnd}\n onContextMenu={(e) =>\n editable && (canUpdatePage || canDeletePage || !!onPageDuplicate) && handleContextMenu(e, page.id)\n }\n onClick={() => !editingId && onPageSelect(page.id)}\n onDoubleClick={() => editable && canUpdatePage && handleStartEdit(page.id, page.name)}\n style={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n padding: '8px 12px',\n backgroundColor: activePageId === page.id ? SEMANTIC_COLORS.bgPrimary : 'transparent',\n borderBottom:\n activePageId === page.id ? `2px solid ${SEMANTIC_COLORS.actionPrimaryBg}` : '2px solid transparent',\n cursor: editingId === page.id ? 'text' : 'pointer',\n opacity: draggedId === page.id ? 0.5 : 1,\n borderLeft: dragOverId === page.id ? `2px solid ${SEMANTIC_COLORS.actionPrimaryBg}` : 'none',\n flexShrink: 0,\n transition: 'background-color 0.15s, border-color 0.15s',\n }}\n >\n {editingId === page.id ? (\n <input\n ref={editInputRef}\n type=\"text\"\n value={editingName}\n onChange={(e) => setEditingName(e.target.value)}\n onKeyDown={handleEditKeyDown}\n onBlur={handleSaveEdit}\n style={{\n width: '100px',\n padding: '2px 4px',\n border: `1px solid ${SEMANTIC_COLORS.actionPrimaryBg}`,\n borderRadius: '2px',\n fontSize: '13px',\n outline: 'none',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n onClick={(e) => e.stopPropagation()}\n />\n ) : (\n <>\n <span\n style={{\n fontSize: '13px',\n fontWeight: activePageId === page.id ? 600 : 400,\n color: activePageId === page.id ? SEMANTIC_COLORS.textPrimary : SEMANTIC_COLORS.textSecondary,\n }}\n >\n {page.name}\n </span>\n {page.widgetCount !== undefined && (\n <span\n style={{\n fontSize: '10px',\n color: SEMANTIC_COLORS.textTertiary,\n backgroundColor: SEMANTIC_COLORS.borderDefault,\n padding: '1px 4px',\n borderRadius: '8px',\n }}\n >\n {page.widgetCount}\n </span>\n )}\n </>\n )}\n </div>\n ))}\n\n {/* Add Page Button */}\n {editable && onPageCreate && canCreatePage && (\n <button\n onClick={onPageCreate}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '6px 12px',\n backgroundColor: SEMANTIC_COLORS.actionPrimaryBg,\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n color: '#ffffff',\n fontSize: '12px',\n fontWeight: 500,\n flexShrink: 0,\n marginLeft: '8px',\n }}\n >\n + Add Page\n </button>\n )}\n\n {/* Context Menu - rendered via portal */}\n {contextMenuId &&\n createPortal(\n <div\n style={{\n position: 'fixed',\n left: contextMenuPos.x,\n top: contextMenuPos.y,\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '6px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.2)',\n zIndex: 99999,\n minWidth: '140px',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {canUpdatePage && (\n <button\n onClick={() => {\n const page = pages.find((p) => p.id === contextMenuId);\n if (page) handleStartEdit(contextMenuId, page.name);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n Rename\n </button>\n )}\n {onPageDuplicate && canCreatePage && (\n <button\n onClick={() => {\n onPageDuplicate(contextMenuId);\n setContextMenuId(null);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n Duplicate\n </button>\n )}\n {onPageDelete && canDeletePage && pages.length > 1 && (\n <>\n <div style={{ height: '1px', backgroundColor: SEMANTIC_COLORS.borderDefault, margin: '4px 0' }} />\n <button\n onClick={() => {\n if (window.confirm('Are you sure you want to delete this page?')) {\n onPageDelete(contextMenuId);\n }\n setContextMenuId(null);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.statusErrorText,\n }}\n >\n Delete\n </button>\n </>\n )}\n </div>,\n document.body\n )}\n </div>\n );\n}\n\nexport default PageTabsManager;\n"],"mappings":"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"}