@burdenoff/microfe-bigconsole 2026.805.3 → 2026.812.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bigconsole/components/DrilldownDashboardRenderer.js +118 -106
- package/dist/bigconsole/components/DrilldownDashboardRenderer.js.map +1 -1
- package/dist/bigconsole/components/DrilldownModal.js +54 -50
- package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
- package/dist/bigconsole/components/builder/BuilderCanvas.js +2 -2
- package/dist/bigconsole/components/builder/BuilderCanvas.js.map +1 -1
- package/dist/bigconsole/components/builder/BuilderTopbar.js +3 -3
- package/dist/bigconsole/components/builder/BuilderTopbar.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/AdvancedSection.js +24 -25
- package/dist/bigconsole/components/builder/inspector/AdvancedSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/AppearanceSection.js +40 -29
- package/dist/bigconsole/components/builder/inspector/AppearanceSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +135 -97
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/GeneralSection.js +58 -44
- package/dist/bigconsole/components/builder/inspector/GeneralSection.js.map +1 -1
- package/dist/bigconsole/components/common/Section.js +70 -0
- package/dist/bigconsole/components/common/Section.js.map +1 -0
- package/dist/bigconsole/components/common/index.js +2 -0
- package/dist/bigconsole/components/common/sectionStyles.js +42 -0
- package/dist/bigconsole/components/common/sectionStyles.js.map +1 -0
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +209 -193
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +213 -231
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardGrid.js +12 -18
- package/dist/bigconsole/components/dashboard/DashboardGrid.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +109 -102
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +81 -70
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js +125 -159
- package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +25 -23
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +3 -3
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +5 -3
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +170 -284
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +147 -151
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/LiveBoardBanner.js +45 -53
- package/dist/bigconsole/components/dashboard/LiveBoardBanner.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +157 -148
- package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +17 -8
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +101 -95
- package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js +20 -18
- package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js.map +1 -1
- package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js +26 -58
- package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js.map +1 -1
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +307 -231
- package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +29 -29
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkCard.js +78 -79
- package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +33 -34
- package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +79 -56
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +75 -65
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +1 -1
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +20 -19
- package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
- package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js +127 -171
- package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +263 -243
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +65 -66
- package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
- package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +121 -127
- package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +33 -26
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/SetupStateBadge.js +3 -3
- package/dist/bigconsole/components/datasink/SetupStateBadge.js.map +1 -1
- package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +95 -95
- package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
- package/dist/bigconsole/components/parser/DataSinkSelector.js +154 -123
- package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ExpressionEditor.js +3 -3
- package/dist/bigconsole/components/parser/ExpressionEditor.js.map +1 -1
- package/dist/bigconsole/components/parser/ImportParserDialog.js +235 -275
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserCard.js +133 -114
- package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +191 -174
- package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserStatusBadge.js +2 -2
- package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserTypeBadge.js +4 -4
- package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineCard.js +134 -89
- package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +77 -64
- package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +7 -10
- package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewContent.js +31 -32
- package/dist/bigconsole/components/preview/AiPreviewContent.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +152 -106
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +193 -152
- package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/previewShared.js +41 -23
- package/dist/bigconsole/components/preview/previewShared.js.map +1 -1
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +342 -308
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +262 -238
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +783 -867
- package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js +7 -5
- package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetHeader.js +7 -8
- package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetRegistry.js +4 -4
- package/dist/bigconsole/components/widgets/WidgetRegistry.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetWrapper.js +8 -7
- package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
- package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js +1 -1
- package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +2 -2
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +11 -5
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +19 -15
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +154 -102
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/CircularGauge.js +36 -32
- package/dist/bigconsole/components/widgets/gauge/CircularGauge.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +85 -60
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +64 -35
- package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/LinearGauge.js +46 -45
- package/dist/bigconsole/components/widgets/gauge/LinearGauge.js.map +1 -1
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +35 -24
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js +2 -2
- package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +4 -4
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +153 -90
- package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListConfig.js +8 -2
- package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListItem.js +1 -1
- package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
- package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +1 -1
- package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +14 -4
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +112 -89
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +21 -13
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/index.js +4 -4
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +3 -3
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +34 -25
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +129 -114
- package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +3 -3
- package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/EmptyState.js +6 -4
- package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/ErrorState.js +7 -5
- package/dist/bigconsole/components/widgets/states/ErrorState.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/LoadingState.js +5 -4
- package/dist/bigconsole/components/widgets/states/LoadingState.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableConfig.js +10 -4
- package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableHeader.js +1 -1
- package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableWidget.js +1 -1
- package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +1 -1
- package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +3 -3
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +2 -2
- package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -1
- package/dist/bigconsole/components/widgets/utils/targetProgress.js +13 -0
- package/dist/bigconsole/components/widgets/utils/targetProgress.js.map +1 -0
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +112 -85
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +28 -20
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowCard.js +92 -77
- package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +70 -51
- package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js +16 -17
- package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +6 -4
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +360 -338
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/hooks/useModalFocusTrap.js +53 -0
- package/dist/bigconsole/hooks/useModalFocusTrap.js.map +1 -0
- package/dist/bigconsole/pages/DashboardBuilderPage.js +209 -203
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +126 -120
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +838 -800
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +263 -315
- package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +301 -341
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +346 -339
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinksPage.js +356 -458
- package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSourcesPage.js +7 -2
- package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
- package/dist/bigconsole/pages/HomePage.js +186 -193
- package/dist/bigconsole/pages/HomePage.js.map +1 -1
- package/dist/bigconsole/pages/InsightsPage.js +887 -740
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +679 -637
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +368 -342
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +537 -444
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +412 -377
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +248 -298
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/WidgetDemoPage.js +251 -153
- package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowViewPage.js +381 -371
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +171 -286
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -21,13 +21,14 @@ var r = class extends e {
|
|
|
21
21
|
if (!e) return this.props.children;
|
|
22
22
|
let { widgetType: r, widgetTitle: i } = this.props;
|
|
23
23
|
return /* @__PURE__ */ n("div", {
|
|
24
|
-
className: "flex
|
|
24
|
+
className: "flex h-full w-full min-w-0 min-h-[120px] flex-col items-center justify-center px-3 text-center",
|
|
25
25
|
role: "alert",
|
|
26
26
|
"data-widget-error": "true",
|
|
27
27
|
children: [
|
|
28
28
|
/* @__PURE__ */ t("div", {
|
|
29
|
-
className: "
|
|
29
|
+
className: "mb-3 flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-status-error-bg-subtle text-[var(--color-status-error-text)]",
|
|
30
30
|
children: /* @__PURE__ */ t("svg", {
|
|
31
|
+
"aria-hidden": "true",
|
|
31
32
|
className: "w-6 h-6",
|
|
32
33
|
fill: "none",
|
|
33
34
|
stroke: "currentColor",
|
|
@@ -41,18 +42,19 @@ var r = class extends e {
|
|
|
41
42
|
})
|
|
42
43
|
}),
|
|
43
44
|
/* @__PURE__ */ t("p", {
|
|
44
|
-
className: "text-sm font-
|
|
45
|
+
className: "mb-1 text-sm font-semibold text-[var(--color-status-error-text)]",
|
|
45
46
|
children: "Widget failed to render"
|
|
46
47
|
}),
|
|
47
48
|
/* @__PURE__ */ n("p", {
|
|
48
|
-
className: "
|
|
49
|
+
className: "mb-3 max-w-[32ch] text-xs text-text-secondary",
|
|
49
50
|
children: [i || r || "This widget", " hit an unexpected error. Check the console for details or retry."]
|
|
50
51
|
}),
|
|
51
52
|
/* @__PURE__ */ n("button", {
|
|
52
53
|
type: "button",
|
|
53
54
|
onClick: this.handleRetry,
|
|
54
|
-
className: "inline-flex items-center gap-1.5 px-3
|
|
55
|
+
className: "inline-flex min-h-control-md items-center gap-1.5 rounded-button bg-action-primary-bg px-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bgHover motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface",
|
|
55
56
|
children: [/* @__PURE__ */ t("svg", {
|
|
57
|
+
"aria-hidden": "true",
|
|
56
58
|
className: "w-4 h-4",
|
|
57
59
|
fill: "none",
|
|
58
60
|
stroke: "currentColor",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetErrorBoundary.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/WidgetErrorBoundary.tsx"],"sourcesContent":["// Per-widget error boundary — isolates render errors so one bad widget can't\n// unmount the whole dashboard (BOFF-2242).\n\nimport { Component, type ErrorInfo, type ReactNode } from 'react';\n\nexport interface WidgetErrorBoundaryProps {\n widgetId: string;\n widgetType?: string;\n widgetTitle?: string;\n // Change to reset even when widgetId is stable (e.g. parser re-bind or config edit).\n resetKey?: string | number;\n children: ReactNode;\n onError?: (error: Error, info: ErrorInfo) => void;\n}\n\ninterface WidgetErrorBoundaryState {\n error: Error | null;\n}\n\nexport class WidgetErrorBoundary extends Component<WidgetErrorBoundaryProps, WidgetErrorBoundaryState> {\n state: WidgetErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): WidgetErrorBoundaryState {\n return { error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo): void {\n const { widgetId, widgetType, widgetTitle, onError } = this.props;\n // eslint-disable-next-line no-console -- boundary needs a visible trace\n console.error(\n `[WidgetErrorBoundary] widget ${widgetId}${widgetType ? ` (${widgetType})` : ''}${\n widgetTitle ? ` \"${widgetTitle}\"` : ''\n } threw:`,\n error,\n info.componentStack\n );\n onError?.(error, info);\n }\n\n componentDidUpdate(prevProps: WidgetErrorBoundaryProps): void {\n // Reset on widgetId or resetKey change so config edits auto-recover without requiring Retry.\n if (\n this.state.error &&\n (prevProps.widgetId !== this.props.widgetId || prevProps.resetKey !== this.props.resetKey)\n ) {\n this.setState({ error: null });\n }\n }\n\n private handleRetry = (): void => {\n this.setState({ error: null });\n };\n\n render(): ReactNode {\n const { error } = this.state;\n if (!error) return this.props.children;\n\n // Full error is logged via componentDidCatch — never render raw error\n // text in the DOM (title, data-*, etc.) since it can leak internal paths.\n const { widgetType, widgetTitle } = this.props;\n const label = widgetTitle || widgetType || 'This widget';\n\n return (\n <div\n className=\"flex
|
|
1
|
+
{"version":3,"file":"WidgetErrorBoundary.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/WidgetErrorBoundary.tsx"],"sourcesContent":["// Per-widget error boundary — isolates render errors so one bad widget can't\n// unmount the whole dashboard (BOFF-2242).\n\nimport { Component, type ErrorInfo, type ReactNode } from 'react';\n\nexport interface WidgetErrorBoundaryProps {\n widgetId: string;\n widgetType?: string;\n widgetTitle?: string;\n // Change to reset even when widgetId is stable (e.g. parser re-bind or config edit).\n resetKey?: string | number;\n children: ReactNode;\n onError?: (error: Error, info: ErrorInfo) => void;\n}\n\ninterface WidgetErrorBoundaryState {\n error: Error | null;\n}\n\nexport class WidgetErrorBoundary extends Component<WidgetErrorBoundaryProps, WidgetErrorBoundaryState> {\n state: WidgetErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): WidgetErrorBoundaryState {\n return { error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo): void {\n const { widgetId, widgetType, widgetTitle, onError } = this.props;\n // eslint-disable-next-line no-console -- boundary needs a visible trace\n console.error(\n `[WidgetErrorBoundary] widget ${widgetId}${widgetType ? ` (${widgetType})` : ''}${\n widgetTitle ? ` \"${widgetTitle}\"` : ''\n } threw:`,\n error,\n info.componentStack\n );\n onError?.(error, info);\n }\n\n componentDidUpdate(prevProps: WidgetErrorBoundaryProps): void {\n // Reset on widgetId or resetKey change so config edits auto-recover without requiring Retry.\n if (\n this.state.error &&\n (prevProps.widgetId !== this.props.widgetId || prevProps.resetKey !== this.props.resetKey)\n ) {\n this.setState({ error: null });\n }\n }\n\n private handleRetry = (): void => {\n this.setState({ error: null });\n };\n\n render(): ReactNode {\n const { error } = this.state;\n if (!error) return this.props.children;\n\n // Full error is logged via componentDidCatch — never render raw error\n // text in the DOM (title, data-*, etc.) since it can leak internal paths.\n const { widgetType, widgetTitle } = this.props;\n const label = widgetTitle || widgetType || 'This widget';\n\n return (\n /* Shares the widget-state recipe (chip, copy width, padding, retry button). */\n <div\n className=\"flex h-full w-full min-w-0 min-h-[120px] flex-col items-center justify-center px-3 text-center\"\n role=\"alert\"\n data-widget-error=\"true\"\n >\n <div className=\"mb-3 flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-status-error-bg-subtle text-[var(--color-status-error-text)]\">\n <svg aria-hidden=\"true\" className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n\n <p className=\"mb-1 text-sm font-semibold text-[var(--color-status-error-text)]\">Widget failed to render</p>\n <p className=\"mb-3 max-w-[32ch] text-xs text-text-secondary\">\n {label} hit an unexpected error. Check the console for details or retry.\n </p>\n\n <button\n type=\"button\"\n onClick={this.handleRetry}\n className=\"inline-flex min-h-control-md items-center gap-1.5 rounded-button bg-action-primary-bg px-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bgHover motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface\"\n >\n <svg aria-hidden=\"true\" className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n Retry\n </button>\n </div>\n );\n }\n}\n\nexport default WidgetErrorBoundary;\n"],"mappings":";;;AAmBA,IAAa,IAAb,cAAyC,EAA8D;CACrG,QAAkC,EAAE,OAAO,MAAM;CAEjD,OAAO,yBAAyB,GAAwC;AACtE,SAAO,EAAE,UAAO;;CAGlB,kBAAkB,GAAc,GAAuB;EACrD,IAAM,EAAE,aAAU,eAAY,gBAAa,eAAY,KAAK;AAS5D,EAPA,QAAQ,MACN,gCAAgC,IAAW,IAAa,KAAK,EAAW,KAAK,KAC3E,IAAc,KAAK,EAAY,KAAK,GACrC,UACD,GACA,EAAK,eACN,EACD,IAAU,GAAO,EAAK;;CAGxB,mBAAmB,GAA2C;AAE5D,EACE,KAAK,MAAM,UACV,EAAU,aAAa,KAAK,MAAM,YAAY,EAAU,aAAa,KAAK,MAAM,aAEjF,KAAK,SAAS,EAAE,OAAO,MAAM,CAAC;;CAIlC,oBAAkC;AAChC,OAAK,SAAS,EAAE,OAAO,MAAM,CAAC;;CAGhC,SAAoB;EAClB,IAAM,EAAE,aAAU,KAAK;AACvB,MAAI,CAAC,EAAO,QAAO,KAAK,MAAM;EAI9B,IAAM,EAAE,eAAY,mBAAgB,KAAK;AAGzC,SAEE,kBAAC,OAAD;GACE,WAAU;GACV,MAAK;GACL,qBAAkB;aAHpB;IAKE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,eAAY;MAAO,WAAU;MAAU,MAAK;MAAO,QAAO;MAAe,SAAQ;gBACpF,kBAAC,QAAD;OACE,eAAc;OACd,gBAAe;OACf,aAAa;OACb,GAAE;OACF,CAAA;MACE,CAAA;KACF,CAAA;IAEN,kBAAC,KAAD;KAAG,WAAU;eAAmE;KAA2B,CAAA;IAC3G,kBAAC,KAAD;KAAG,WAAU;eAAb,CArBU,KAAe,KAAc,eAsB9B,oEACL;;IAEJ,kBAAC,UAAD;KACE,MAAK;KACL,SAAS,KAAK;KACd,WAAU;eAHZ,CAKE,kBAAC,OAAD;MAAK,eAAY;MAAO,WAAU;MAAU,MAAK;MAAO,QAAO;MAAe,SAAQ;gBACpF,kBAAC,QAAD;OACE,eAAc;OACd,gBAAe;OACf,aAAa;OACb,GAAE;OACF,CAAA;MACE,CAAA,EAAA,QAEC;;IACL"}
|
|
@@ -6,11 +6,10 @@ import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
|
6
6
|
var a = t(function({ widget: t, definition: a, isSelected: s, isEditMode: c, isLoading: l, isSampleData: u, timeUntilRefresh: d, hasDrilldown: f, onRefresh: p, onExportCSV: m, onExportPNG: h, onDrilldown: g, onToggleComments: _, commentsOpen: v, commentCount: y = 0 }) {
|
|
7
7
|
return /* @__PURE__ */ i("div", {
|
|
8
8
|
className: `
|
|
9
|
-
flex items-center justify-between
|
|
10
|
-
px-
|
|
11
|
-
border-b border-border-
|
|
12
|
-
bg-bg-
|
|
13
|
-
${s && c ? "bg-action-primary-bg/5" : ""}
|
|
9
|
+
flex min-w-0 items-center justify-between gap-1
|
|
10
|
+
px-3 py-2 sm:px-4
|
|
11
|
+
border-b border-[var(--color-border-subtle)]
|
|
12
|
+
${s && c ? "bg-action-primary-bg/5" : "bg-bg-surface"}
|
|
14
13
|
`,
|
|
15
14
|
children: [/* @__PURE__ */ i("div", {
|
|
16
15
|
className: `
|
|
@@ -21,14 +20,14 @@ var a = t(function({ widget: t, definition: a, isSelected: s, isEditMode: c, isL
|
|
|
21
20
|
children: [
|
|
22
21
|
/* @__PURE__ */ r("div", {
|
|
23
22
|
className: `
|
|
24
|
-
flex-shrink-0
|
|
23
|
+
flex-shrink-0 h-icon-md w-icon-md
|
|
25
24
|
text-text-secondary
|
|
26
25
|
${l ? "animate-pulse" : ""}
|
|
27
26
|
`,
|
|
28
27
|
children: /* @__PURE__ */ r(o, { name: a.icon })
|
|
29
28
|
}),
|
|
30
29
|
/* @__PURE__ */ r("h3", {
|
|
31
|
-
className: "\n text-sm font-
|
|
30
|
+
className: "\n truncate text-sm font-semibold leading-tight tracking-tight\n text-text-primary\n ",
|
|
32
31
|
title: t.title,
|
|
33
32
|
children: t.title
|
|
34
33
|
}),
|
|
@@ -60,7 +59,7 @@ var a = t(function({ widget: t, definition: a, isSelected: s, isEditMode: c, isL
|
|
|
60
59
|
})
|
|
61
60
|
]
|
|
62
61
|
}), /* @__PURE__ */ i("div", {
|
|
63
|
-
className: "flex items-center gap-
|
|
62
|
+
className: "flex min-w-0 shrink items-center gap-0.5",
|
|
64
63
|
children: [
|
|
65
64
|
g && !c && /* @__PURE__ */ r("button", {
|
|
66
65
|
type: "button",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetHeader.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/WidgetHeader.tsx"],"sourcesContent":["/**\n * WidgetHeader Component\n *\n * Header section of a widget with title, icon, and action menu.\n */\n\nimport { type FC, type ReactElement, memo } from 'react';\nimport { MessageSquare } from 'lucide-react';\nimport type { Widget } from '../../types';\nimport type { WidgetDefinition } from './WidgetRegistry';\nimport { WidgetMenu } from './WidgetMenu';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetHeaderProps {\n /** The widget data */\n widget: Widget;\n /** Widget definition from registry */\n definition: WidgetDefinition;\n /** Whether the widget is selected */\n isSelected?: boolean;\n /** Whether in edit mode */\n isEditMode?: boolean;\n /**\n * The rendered values come from a template's embedded sample, not a\n * connected data source. Badged so nobody mistakes example numbers for\n * their own.\n */\n isSampleData?: boolean;\n /** Whether the widget is loading */\n isLoading?: boolean;\n /** Time until next refresh (formatted string) */\n timeUntilRefresh?: string;\n /** Whether drilldown is enabled on this widget */\n hasDrilldown?: boolean;\n /** Callback to refresh widget */\n onRefresh?: () => void;\n /** Callback to export as CSV */\n onExportCSV?: () => void;\n /** Callback to export as PNG */\n onExportPNG?: () => void;\n /** Callback for drilldown */\n onDrilldown?: () => void;\n /** Toggle the widget comments panel */\n onToggleComments?: () => void;\n /** Whether the comments panel is currently open */\n commentsOpen?: boolean;\n /** Number of comments on this widget (badge) */\n commentCount?: number;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const WidgetHeader: FC<WidgetHeaderProps> = memo(function WidgetHeader({\n widget,\n definition,\n isSelected,\n isEditMode,\n isLoading,\n isSampleData,\n timeUntilRefresh,\n hasDrilldown,\n onRefresh,\n onExportCSV,\n onExportPNG,\n onDrilldown,\n onToggleComments,\n commentsOpen,\n commentCount = 0,\n}) {\n return (\n <div\n className={`\n flex items-center justify-between\n px-4 py-3\n border-b border-border-default\n bg-bg-sunken\n ${isSelected && isEditMode ? 'bg-action-primary-bg/5' : ''}\n `}\n >\n {/* Left side: Icon and Title - THIS IS THE DRAG HANDLE */}\n <div\n className={`\n widget-drag-handle\n flex items-center gap-2 min-w-0 flex-1\n ${isEditMode ? 'cursor-move' : ''}\n `}\n >\n {/* Widget type icon */}\n <div\n className={`\n flex-shrink-0 w-5 h-5\n text-text-secondary\n ${isLoading ? 'animate-pulse' : ''}\n `}\n >\n <WidgetIcon name={definition.icon} />\n </div>\n\n {/* Title */}\n <h3\n className=\"\n text-sm font-medium\n text-text-primary\n truncate\n \"\n title={widget.title}\n >\n {widget.title}\n </h3>\n\n {/* Sample-data badge — example values, not the viewer's own data */}\n {isSampleData && (\n <span\n className=\"\n flex-shrink-0\n px-1.5 py-0.5\n rounded\n text-[10px] font-medium uppercase tracking-wide\n bg-status-info-bg-subtle text-status-info-text\n \"\n title=\"Example values from the template. Connect a data source to see your own data.\"\n >\n Sample\n </span>\n )}\n\n {/* Drilldown indicator badge */}\n {hasDrilldown && (\n <span\n className=\"\n flex-shrink-0 inline-flex items-center gap-0.5\n px-1.5 py-0.5 rounded-md\n bg-action-primary-bg/10 text-action-primary-text\n text-[10px] font-medium\n \"\n title=\"Click data to drill down\"\n >\n <svg className=\"w-2.5 h-2.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2.5}\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n Drilldown\n </span>\n )}\n\n {/* Refresh indicator */}\n {timeUntilRefresh && !isEditMode && (\n <span\n className=\"\n flex-shrink-0 text-xs\n text-text-secondary\n tabular-nums\n \"\n title=\"Time until next refresh\"\n >\n {timeUntilRefresh}\n </span>\n )}\n </div>\n\n {/* Right side: Actions */}\n <div className=\"flex items-center gap-1 ml-2\">\n {/* Drilldown button (shown in view mode) */}\n {onDrilldown && !isEditMode && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDrilldown();\n }}\n className=\"\n p-1.5 rounded-md\n text-text-secondary\n hover:text-text-primary\n hover:bg-bg-sunken\n transition-colors\n \"\n title=\"Drill down to details\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n </button>\n )}\n\n {/* Refresh button */}\n {onRefresh && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onRefresh();\n }}\n disabled={isLoading}\n className={`\n p-1.5 rounded-md\n text-text-secondary\n hover:text-text-primary\n hover:bg-bg-sunken\n transition-colors\n disabled:opacity-50 disabled:cursor-not-allowed\n ${isLoading ? 'animate-spin' : ''}\n `}\n title=\"Refresh data\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n </button>\n )}\n\n {/* Comments toggle */}\n {onToggleComments && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onToggleComments();\n }}\n aria-label=\"Toggle comments\"\n aria-pressed={commentsOpen}\n className={`\n relative p-1.5 rounded-md\n transition-colors\n ${\n commentsOpen\n ? 'text-action-primary-text bg-action-primary-bg/10'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n }\n `}\n title=\"Comments\"\n >\n <MessageSquare className=\"w-4 h-4\" />\n {commentCount > 0 && (\n <span className=\"absolute -top-0.5 -right-0.5 min-w-[14px] h-[14px] px-0.5 rounded-full bg-action-primary-bg text-action-primary-text text-[9px] font-semibold leading-[14px] text-center tabular-nums\">\n {commentCount > 99 ? '99+' : commentCount}\n </span>\n )}\n </button>\n )}\n\n {/* Menu (always visible) */}\n <div className=\"block\">\n <WidgetMenu\n widget={widget}\n isEditMode={isEditMode}\n onRefresh={onRefresh}\n onExportCSV={onExportCSV}\n onExportPNG={onExportPNG}\n />\n </div>\n </div>\n </div>\n );\n});\n\n// ============================================================================\n// Widget Icon Component\n// ============================================================================\n\ninterface WidgetIconProps {\n name: string;\n className?: string;\n}\n\nconst WidgetIcon: FC<WidgetIconProps> = ({ name, className = '' }) => {\n // Simple icon mapping - in production, use lucide-react or similar\n const icons: Record<string, ReactElement> = {\n TrendingUp: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6\" />\n </svg>\n ),\n BarChart3: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M18 20V10M12 20V4M6 20v-6\" />\n </svg>\n ),\n LineChart: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M7 20l4-16m2 16l4-16M6 9h14M4 15h14\" />\n </svg>\n ),\n Table: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n ),\n Gauge: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n ),\n Activity: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M22 12h-4l-3 9L9 3l-3 9H2\" />\n </svg>\n ),\n List: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 10h16M4 14h16M4 18h16\" />\n </svg>\n ),\n PieChart: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M11 3.055A9.001 9.001 0 1020.945 13H11V3.055z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M20.488 9H15V3.512A9.025 9.025 0 0120.488 9z\"\n />\n </svg>\n ),\n BarChart: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z\"\n />\n </svg>\n ),\n AreaChart: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4v16\"\n />\n </svg>\n ),\n };\n\n // Default icon\n const defaultIcon = (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z\"\n />\n </svg>\n );\n\n return icons[name] || defaultIcon;\n};\n\nexport default WidgetHeader;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WidgetHeader.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/WidgetHeader.tsx"],"sourcesContent":["/**\n * WidgetHeader Component\n *\n * Header section of a widget with title, icon, and action menu.\n */\n\nimport { type FC, type ReactElement, memo } from 'react';\nimport { MessageSquare } from 'lucide-react';\nimport type { Widget } from '../../types';\nimport type { WidgetDefinition } from './WidgetRegistry';\nimport { WidgetMenu } from './WidgetMenu';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetHeaderProps {\n /** The widget data */\n widget: Widget;\n /** Widget definition from registry */\n definition: WidgetDefinition;\n /** Whether the widget is selected */\n isSelected?: boolean;\n /** Whether in edit mode */\n isEditMode?: boolean;\n /**\n * The rendered values come from a template's embedded sample, not a\n * connected data source. Badged so nobody mistakes example numbers for\n * their own.\n */\n isSampleData?: boolean;\n /** Whether the widget is loading */\n isLoading?: boolean;\n /** Time until next refresh (formatted string) */\n timeUntilRefresh?: string;\n /** Whether drilldown is enabled on this widget */\n hasDrilldown?: boolean;\n /** Callback to refresh widget */\n onRefresh?: () => void;\n /** Callback to export as CSV */\n onExportCSV?: () => void;\n /** Callback to export as PNG */\n onExportPNG?: () => void;\n /** Callback for drilldown */\n onDrilldown?: () => void;\n /** Toggle the widget comments panel */\n onToggleComments?: () => void;\n /** Whether the comments panel is currently open */\n commentsOpen?: boolean;\n /** Number of comments on this widget (badge) */\n commentCount?: number;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const WidgetHeader: FC<WidgetHeaderProps> = memo(function WidgetHeader({\n widget,\n definition,\n isSelected,\n isEditMode,\n isLoading,\n isSampleData,\n timeUntilRefresh,\n hasDrilldown,\n onRefresh,\n onExportCSV,\n onExportPNG,\n onDrilldown,\n onToggleComments,\n commentsOpen,\n commentCount = 0,\n}) {\n return (\n /*\n The card's title band. It is the anchor of the card, so the title is\n `font-semibold` (was `font-medium`, identical to body copy) and the band\n sits on the card surface with a seam — the sunken fill now belongs to the\n action tray at the bottom, so the two strips read as different jobs\n (BOFF-5636).\n\n The fill is chosen in ONE branch rather than layering\n `bg-action-primary-bg/5` on top of `bg-bg-surface`: two background-colour\n utilities on the same element are resolved by Tailwind's output order, not\n by the order they are written, so the selected tint was not reliably\n winning.\n */\n <div\n className={`\n flex min-w-0 items-center justify-between gap-1\n px-3 py-2 sm:px-4\n border-b border-[var(--color-border-subtle)]\n ${isSelected && isEditMode ? 'bg-action-primary-bg/5' : 'bg-bg-surface'}\n `}\n >\n {/* Left side: Icon and Title - THIS IS THE DRAG HANDLE */}\n <div\n className={`\n widget-drag-handle\n flex items-center gap-2 min-w-0 flex-1\n ${isEditMode ? 'cursor-move' : ''}\n `}\n >\n {/* Widget type icon */}\n <div\n className={`\n flex-shrink-0 h-icon-md w-icon-md\n text-text-secondary\n ${isLoading ? 'animate-pulse' : ''}\n `}\n >\n <WidgetIcon name={definition.icon} />\n </div>\n\n {/* Title */}\n <h3\n className=\"\n truncate text-sm font-semibold leading-tight tracking-tight\n text-text-primary\n \"\n title={widget.title}\n >\n {widget.title}\n </h3>\n\n {/* Sample-data badge — example values, not the viewer's own data */}\n {isSampleData && (\n <span\n className=\"\n flex-shrink-0\n px-1.5 py-0.5\n rounded\n text-[10px] font-medium uppercase tracking-wide\n bg-status-info-bg-subtle text-status-info-text\n \"\n title=\"Example values from the template. Connect a data source to see your own data.\"\n >\n Sample\n </span>\n )}\n\n {/* Drilldown indicator badge */}\n {hasDrilldown && (\n <span\n className=\"\n flex-shrink-0 inline-flex items-center gap-0.5\n px-1.5 py-0.5 rounded-md\n bg-action-primary-bg/10 text-action-primary-text\n text-[10px] font-medium\n \"\n title=\"Click data to drill down\"\n >\n <svg className=\"w-2.5 h-2.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2.5}\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n Drilldown\n </span>\n )}\n\n {/* Refresh indicator */}\n {timeUntilRefresh && !isEditMode && (\n <span\n className=\"\n flex-shrink-0 text-xs\n text-text-secondary\n tabular-nums\n \"\n title=\"Time until next refresh\"\n >\n {timeUntilRefresh}\n </span>\n )}\n </div>\n\n {/* Right side: Actions — allowed to shrink so a narrow card keeps its title */}\n <div className=\"flex min-w-0 shrink items-center gap-0.5\">\n {/* Drilldown button (shown in view mode) */}\n {onDrilldown && !isEditMode && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDrilldown();\n }}\n className=\"\n p-1.5 rounded-md\n text-text-secondary\n hover:text-text-primary\n hover:bg-bg-sunken\n transition-colors\n \"\n title=\"Drill down to details\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n </button>\n )}\n\n {/* Refresh button */}\n {onRefresh && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onRefresh();\n }}\n disabled={isLoading}\n className={`\n p-1.5 rounded-md\n text-text-secondary\n hover:text-text-primary\n hover:bg-bg-sunken\n transition-colors\n disabled:opacity-50 disabled:cursor-not-allowed\n ${isLoading ? 'animate-spin' : ''}\n `}\n title=\"Refresh data\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n </button>\n )}\n\n {/* Comments toggle */}\n {onToggleComments && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onToggleComments();\n }}\n aria-label=\"Toggle comments\"\n aria-pressed={commentsOpen}\n className={`\n relative p-1.5 rounded-md\n transition-colors\n ${\n commentsOpen\n ? 'text-action-primary-text bg-action-primary-bg/10'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n }\n `}\n title=\"Comments\"\n >\n <MessageSquare className=\"w-4 h-4\" />\n {commentCount > 0 && (\n <span className=\"absolute -top-0.5 -right-0.5 min-w-[14px] h-[14px] px-0.5 rounded-full bg-action-primary-bg text-action-primary-text text-[9px] font-semibold leading-[14px] text-center tabular-nums\">\n {commentCount > 99 ? '99+' : commentCount}\n </span>\n )}\n </button>\n )}\n\n {/* Menu (always visible) */}\n <div className=\"block\">\n <WidgetMenu\n widget={widget}\n isEditMode={isEditMode}\n onRefresh={onRefresh}\n onExportCSV={onExportCSV}\n onExportPNG={onExportPNG}\n />\n </div>\n </div>\n </div>\n );\n});\n\n// ============================================================================\n// Widget Icon Component\n// ============================================================================\n\ninterface WidgetIconProps {\n name: string;\n className?: string;\n}\n\nconst WidgetIcon: FC<WidgetIconProps> = ({ name, className = '' }) => {\n // Simple icon mapping - in production, use lucide-react or similar\n const icons: Record<string, ReactElement> = {\n TrendingUp: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6\" />\n </svg>\n ),\n BarChart3: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M18 20V10M12 20V4M6 20v-6\" />\n </svg>\n ),\n LineChart: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M7 20l4-16m2 16l4-16M6 9h14M4 15h14\" />\n </svg>\n ),\n Table: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n ),\n Gauge: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n ),\n Activity: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M22 12h-4l-3 9L9 3l-3 9H2\" />\n </svg>\n ),\n List: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 10h16M4 14h16M4 18h16\" />\n </svg>\n ),\n PieChart: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M11 3.055A9.001 9.001 0 1020.945 13H11V3.055z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M20.488 9H15V3.512A9.025 9.025 0 0120.488 9z\"\n />\n </svg>\n ),\n BarChart: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z\"\n />\n </svg>\n ),\n AreaChart: (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4v16\"\n />\n </svg>\n ),\n };\n\n // Default icon\n const defaultIcon = (\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" className={className}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z\"\n />\n </svg>\n );\n\n return icons[name] || defaultIcon;\n};\n\nexport default WidgetHeader;\n"],"mappings":"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"}
|
|
@@ -50,7 +50,7 @@ var e = {
|
|
|
50
50
|
category: "KPI",
|
|
51
51
|
component: null,
|
|
52
52
|
defaultConfig: {
|
|
53
|
-
format: "
|
|
53
|
+
format: "auto",
|
|
54
54
|
decimalPlaces: 0,
|
|
55
55
|
showTrend: !0,
|
|
56
56
|
showSparkline: !1
|
|
@@ -278,15 +278,15 @@ var e = {
|
|
|
278
278
|
thresholds: [
|
|
279
279
|
{
|
|
280
280
|
value: 33,
|
|
281
|
-
color: "
|
|
281
|
+
color: "error"
|
|
282
282
|
},
|
|
283
283
|
{
|
|
284
284
|
value: 66,
|
|
285
|
-
color: "
|
|
285
|
+
color: "warning"
|
|
286
286
|
},
|
|
287
287
|
{
|
|
288
288
|
value: 100,
|
|
289
|
-
color: "
|
|
289
|
+
color: "success"
|
|
290
290
|
}
|
|
291
291
|
]
|
|
292
292
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetRegistry.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/WidgetRegistry.ts"],"sourcesContent":["/**\n * Widget Registry\n *\n * Central registry mapping widget types to their components,\n * metadata, and configuration schemas.\n */\n\nimport type { ComponentType } from 'react';\nimport type { WidgetType, WidgetCategory, Widget } from '../../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetComponentProps {\n /** The widget data */\n widget: Widget;\n /** Widget data (processed) */\n data: Record<string, unknown>;\n /** Whether the widget is in edit mode */\n isEditMode?: boolean;\n /** Whether the widget is selected */\n isSelected?: boolean;\n /** Whether data is loading */\n isLoading?: boolean;\n /** Error message if any */\n error?: string | null;\n /** Callback when widget is clicked */\n onClick?: () => void;\n /** Callback for drilldown navigation */\n onDrilldown?: (params: Record<string, unknown>) => void;\n}\n\nexport interface WidgetDefinition {\n /** Widget type */\n type: WidgetType;\n /** Human-readable name */\n name: string;\n /** Description */\n description: string;\n /** Lucide icon name */\n icon: string;\n /** Category for grouping */\n category: WidgetCategory;\n /** Component to render. Null for all current widget types because the render path\n * uses WidgetRendererFactory + RendererRegistry instead of this field. */\n component: ComponentType<WidgetComponentProps> | null;\n /** Default configuration */\n defaultConfig: Record<string, unknown>;\n /** Default size (fixed grid) */\n defaultSize: { width: number; height: number };\n /**\n * Default responsive position (v1.0 spec). `xl` is optional and falls back\n * to `lg` when not set so existing widget defaults remain valid.\n */\n defaultResponsive: { xs: number; sm: number; md: number; lg: number; xl?: number };\n /** Minimum size constraints */\n minSize: { width: number; height: number };\n /** Maximum size constraints */\n maxSize: { width: number; height: number };\n /** Whether the widget supports data binding */\n supportsDataBinding: boolean;\n /** Whether the widget supports drilldown */\n supportsDrilldown: boolean;\n /** Whether the widget supports auto-refresh */\n supportsAutoRefresh: boolean;\n /**\n * Whether the widget honors rule-based conditional formatting\n * (`config.conditionalRules`). Drives which options the config UI shows.\n */\n supportsConditionalFormat?: boolean;\n /**\n * Whether the widget supports reference / threshold lines & bands\n * (`config.referenceLines`).\n */\n supportsThresholds?: boolean;\n /** Whether the widget supports a combo / dual-axis layout (`config.dualAxis`). */\n supportsDualAxis?: boolean;\n /** Whether the widget supports a totals/aggregate footer (`config.showTotals`). */\n supportsTotals?: boolean;\n /** Tags for search/filter */\n tags: string[];\n}\n\n// ============================================================================\n// Widget Definitions\n// ============================================================================\n\nexport const WIDGET_DEFINITIONS: Record<WidgetType, WidgetDefinition> = {\n // ============================================================================\n // Core Visualization (6 types)\n // ============================================================================\n\n kpi_card_comparison: {\n type: 'kpi_card_comparison',\n name: 'KPI Card Comparison',\n description: 'Compare multiple KPIs side by side with trends',\n icon: 'LayoutDashboard',\n category: 'KPI',\n component: null,\n defaultConfig: {\n comparisons: [],\n showSparklines: true,\n layout: 'horizontal',\n format: 'number',\n },\n defaultSize: { width: 6, height: 3 },\n defaultResponsive: { xs: 12, sm: 6, md: 6, lg: 4 },\n minSize: { width: 4, height: 2 },\n maxSize: { width: 12, height: 6 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n supportsConditionalFormat: true,\n tags: ['kpi', 'comparison', 'metrics', 'multi'],\n },\n\n metric_card: {\n type: 'metric_card',\n name: 'Metric Card',\n description: 'Display a single KPI value with trend indicator',\n icon: 'TrendingUp',\n category: 'KPI',\n component: null,\n defaultConfig: {\n format: 'number',\n decimalPlaces: 0,\n showTrend: true,\n showSparkline: false,\n },\n defaultSize: { width: 3, height: 2 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 3 },\n minSize: { width: 2, height: 2 },\n maxSize: { width: 6, height: 4 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n supportsConditionalFormat: true,\n tags: ['kpi', 'metric', 'number', 'trend'],\n },\n\n chart: {\n type: 'chart',\n name: 'Chart',\n description: 'Multi-type chart (Line, Bar, Area, Pie)',\n icon: 'BarChart3',\n category: 'Visualization',\n component: null,\n defaultConfig: {\n chartType: 'line',\n showLegend: true,\n legendPosition: 'bottom',\n showGrid: true,\n showTooltip: true,\n },\n defaultSize: { width: 6, height: 4 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 3, height: 3 },\n maxSize: { width: 12, height: 8 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n supportsConditionalFormat: true,\n supportsThresholds: true,\n supportsDualAxis: true,\n tags: ['chart', 'graph', 'visualization', 'line', 'bar', 'area', 'pie', 'combo', 'dual-axis'],\n },\n\n funnel_chart: {\n type: 'funnel_chart',\n name: 'Funnel Chart',\n description: 'Visualize conversion or drop-off stages',\n icon: 'Filter',\n category: 'Visualization',\n component: null,\n defaultConfig: {\n // ChartWidget dispatches on `chartType` and falls back to 'line' when it is\n // absent, so a palette-created funnel must seed it explicitly.\n chartType: 'funnel',\n showLabels: true,\n showValues: true,\n showPercentages: true,\n orientation: 'vertical',\n },\n defaultSize: { width: 4, height: 5 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 3, height: 4 },\n maxSize: { width: 8, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['funnel', 'conversion', 'stages', 'pipeline'],\n },\n\n table: {\n type: 'table',\n name: 'Data Table',\n description: 'Display data in sortable, filterable rows and columns',\n icon: 'Table',\n category: 'Data',\n component: null,\n defaultConfig: {\n pageSize: 10,\n sortable: true,\n filterable: true,\n stickyHeader: true,\n columns: [],\n },\n defaultSize: { width: 8, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 8, lg: 8 },\n minSize: { width: 4, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n supportsConditionalFormat: true,\n supportsTotals: true,\n tags: ['table', 'data', 'grid', 'rows'],\n },\n\n pivot_table: {\n type: 'pivot_table',\n name: 'Pivot Table',\n description: 'Interactive pivot table for data analysis',\n icon: 'Grid3x3',\n category: 'Data',\n component: null,\n defaultConfig: {\n rows: [],\n columns: [],\n values: [],\n aggregation: 'sum',\n showTotals: true,\n },\n defaultSize: { width: 10, height: 6 },\n defaultResponsive: { xs: 12, sm: 12, md: 12, lg: 10 },\n minSize: { width: 6, height: 4 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['pivot', 'table', 'analysis', 'aggregation'],\n },\n\n // ============================================================================\n // Indicators (2 types)\n // ============================================================================\n\n gauge: {\n type: 'gauge',\n name: 'Gauge',\n description: 'Display a value within a range',\n icon: 'Gauge',\n category: 'KPI',\n component: null,\n defaultConfig: {\n variant: 'circular',\n min: 0,\n max: 100,\n showValue: true,\n showLabels: true,\n thresholds: [\n { value: 33, color: 'red' },\n { value: 66, color: 'yellow' },\n { value: 100, color: 'green' },\n ],\n },\n defaultSize: { width: 3, height: 3 },\n defaultResponsive: { xs: 6, sm: 4, md: 3, lg: 3 },\n minSize: { width: 2, height: 2 },\n maxSize: { width: 6, height: 6 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: true,\n tags: ['gauge', 'meter', 'dial', 'indicator'],\n },\n\n progress: {\n type: 'progress',\n name: 'Progress Bar',\n description: 'Show progress towards a goal with milestones',\n icon: 'Activity',\n category: 'KPI',\n component: null,\n defaultConfig: {\n showPercentage: true,\n showValue: false,\n target: null,\n milestones: [],\n },\n defaultSize: { width: 4, height: 2 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 3, height: 2 },\n maxSize: { width: 12, height: 3 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: true,\n tags: ['progress', 'bar', 'goal', 'completion'],\n },\n\n // ============================================================================\n // Data Display (2 types)\n // ============================================================================\n\n list: {\n type: 'list',\n name: 'List',\n description: 'Display items in a scrollable list',\n icon: 'List',\n category: 'Data',\n component: null,\n defaultConfig: {\n showMetadata: true,\n showActions: false,\n showBadges: true,\n maxItems: 10,\n itemClickable: true,\n },\n defaultSize: { width: 4, height: 5 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 3, height: 3 },\n maxSize: { width: 8, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['list', 'items', 'scroll'],\n },\n\n form: {\n type: 'form',\n name: 'Form',\n description: 'Interactive form widget for data input',\n icon: 'FileText',\n category: 'Data',\n component: null,\n defaultConfig: {\n fields: [],\n submitAction: null,\n layout: 'vertical',\n showLabels: true,\n },\n defaultSize: { width: 6, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 4, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: false,\n tags: ['form', 'input', 'submit', 'fields'],\n },\n\n // ============================================================================\n // Content (2 types)\n // ============================================================================\n\n text: {\n type: 'text',\n name: 'Text',\n description: 'Rich text or markdown content widget',\n icon: 'Type',\n category: 'Content',\n component: null,\n defaultConfig: {\n content: '',\n format: 'markdown',\n alignment: 'left',\n },\n defaultSize: { width: 4, height: 3 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 2, height: 1 },\n maxSize: { width: 12, height: 12 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: false,\n tags: ['text', 'markdown', 'content', 'rich text'],\n },\n\n iframe: {\n type: 'iframe',\n name: 'Iframe',\n description: 'Embed external content via iframe',\n icon: 'ExternalLink',\n category: 'Content',\n component: null,\n defaultConfig: {\n url: '',\n sandbox: 'allow-scripts allow-same-origin',\n allowFullscreen: false,\n },\n defaultSize: { width: 6, height: 4 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 3, height: 2 },\n maxSize: { width: 12, height: 12 },\n supportsDataBinding: false,\n supportsDrilldown: false,\n supportsAutoRefresh: false,\n tags: ['iframe', 'embed', 'external', 'web'],\n },\n\n // ============================================================================\n // Spatial & Temporal (5 types)\n // ============================================================================\n\n map: {\n type: 'map',\n name: 'Map',\n description: 'Geographic map visualization with markers',\n icon: 'MapPin',\n category: 'Visualization',\n component: null,\n defaultConfig: {\n provider: 'mapbox',\n center: { lat: 0, lng: 0 },\n zoom: 2,\n showMarkers: true,\n showRegions: false,\n },\n defaultSize: { width: 6, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 4, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['map', 'geo', 'location', 'markers'],\n },\n\n heatmap: {\n type: 'heatmap',\n name: 'Heatmap',\n description: 'Display values in a color-coded grid',\n icon: 'Grid3x3',\n category: 'Visualization',\n component: null,\n defaultConfig: {\n xAxisField: '',\n yAxisField: '',\n valueField: '',\n // HeatmapWidget renders intensity from `colorScheme` (token-based Tailwind\n // classes), not `colorScale`; keep the scale empty rather than seeding it\n // with CSS var() strings that a data array can never resolve.\n colorScale: [],\n colorScheme: 'blue',\n showValues: true,\n },\n defaultSize: { width: 6, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 4, height: 4 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['heatmap', 'grid', 'density', 'color'],\n },\n\n calendar: {\n type: 'calendar',\n name: 'Calendar',\n description: 'Calendar view for events and schedules',\n icon: 'Calendar',\n category: 'Temporal',\n component: null,\n defaultConfig: {\n view: 'month',\n showWeekNumbers: false,\n firstDayOfWeek: 0,\n eventField: '',\n },\n defaultSize: { width: 8, height: 6 },\n defaultResponsive: { xs: 12, sm: 12, md: 8, lg: 8 },\n minSize: { width: 6, height: 4 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['calendar', 'events', 'schedule', 'dates'],\n },\n\n kanban: {\n type: 'kanban',\n name: 'Kanban Board',\n description: 'Kanban board for task and workflow management',\n icon: 'Columns',\n category: 'Data',\n component: null,\n defaultConfig: {\n columns: [],\n cardTitleField: '',\n cardDescriptionField: '',\n columnField: '',\n allowDragDrop: true,\n },\n defaultSize: { width: 12, height: 6 },\n defaultResponsive: { xs: 12, sm: 12, md: 12, lg: 12 },\n minSize: { width: 8, height: 4 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['kanban', 'board', 'tasks', 'workflow'],\n },\n\n timeline: {\n type: 'timeline',\n name: 'Timeline',\n description: 'Timeline or Gantt chart for project scheduling',\n icon: 'GitBranch',\n category: 'Temporal',\n component: null,\n defaultConfig: {\n startDateField: '',\n endDateField: '',\n titleField: '',\n groupField: '',\n showToday: true,\n },\n defaultSize: { width: 12, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 12, lg: 12 },\n minSize: { width: 8, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['timeline', 'gantt', 'project', 'schedule'],\n },\n\n // ============================================================================\n // Cohort / Retention (1 type)\n // ============================================================================\n\n retention: {\n type: 'retention',\n name: 'Retention / Cohort',\n description: 'Cohort-by-period retention grid with decay shading',\n icon: 'Grid3x3',\n category: 'Data',\n component: null,\n defaultConfig: {\n cohortField: 'cohort',\n periodField: 'period',\n valueField: 'value',\n periodType: 'month',\n showPercentages: true,\n showAverages: true,\n showLegend: true,\n },\n defaultSize: { width: 8, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 8, lg: 8 },\n minSize: { width: 4, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: true,\n tags: ['retention', 'cohort', 'grid', 'churn', 'saas'],\n },\n\n // ============================================================================\n // Extensibility (1 type)\n // ============================================================================\n\n custom: {\n type: 'custom',\n name: 'Custom Widget',\n description: 'Custom widget with user-defined rendering',\n icon: 'Puzzle',\n category: 'Custom',\n component: null,\n defaultConfig: {\n componentId: '',\n props: {},\n },\n defaultSize: { width: 4, height: 4 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 2, height: 2 },\n maxSize: { width: 12, height: 12 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['custom', 'plugin', 'extension'],\n },\n};\n\n// ============================================================================\n// Registry Functions\n// ============================================================================\n\n/**\n * Default widget definition for unknown types\n */\nconst DEFAULT_WIDGET_DEFINITION: WidgetDefinition = {\n type: 'custom' as WidgetType,\n name: 'Unknown Widget',\n description: 'Unknown widget type',\n icon: 'Puzzle',\n category: 'Custom',\n component: null,\n defaultConfig: {},\n defaultSize: { width: 4, height: 4 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 2, height: 2 },\n maxSize: { width: 12, height: 12 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['unknown'],\n};\n\n/**\n * Get widget definition by type\n * Handles both lowercase (frontend) and uppercase (backend) types\n */\nexport function getWidgetDefinition(type: WidgetType | string): WidgetDefinition {\n // Try exact match first\n if (WIDGET_DEFINITIONS[type as WidgetType]) {\n return WIDGET_DEFINITIONS[type as WidgetType];\n }\n\n // Try lowercase version (backend returns uppercase for some types)\n const lowerType = type.toLowerCase() as WidgetType;\n if (WIDGET_DEFINITIONS[lowerType]) {\n return WIDGET_DEFINITIONS[lowerType];\n }\n\n // Return default definition for unknown types\n return { ...DEFAULT_WIDGET_DEFINITION, type: type as WidgetType };\n}\n\n/**\n * Get all widget definitions\n */\nexport function getAllWidgetDefinitions(): WidgetDefinition[] {\n return Object.values(WIDGET_DEFINITIONS);\n}\n\n/**\n * Get widget definitions by category\n */\nexport function getWidgetsByCategory(category: WidgetCategory): WidgetDefinition[] {\n return Object.values(WIDGET_DEFINITIONS).filter((def) => def.category === category);\n}\n\n/**\n * Search widget definitions by query\n */\nexport function searchWidgets(query: string): WidgetDefinition[] {\n const lowerQuery = query.toLowerCase();\n return Object.values(WIDGET_DEFINITIONS).filter(\n (def) =>\n def.name.toLowerCase().includes(lowerQuery) ||\n def.description.toLowerCase().includes(lowerQuery) ||\n def.tags.some((tag) => tag.includes(lowerQuery))\n );\n}\n\n/**\n * Canonical mapping from widget category to human-readable label.\n * Shared across WidgetTypeSelector, WidgetPalette, and other UI.\n */\nexport const WIDGET_CATEGORY_LABELS: Record<WidgetCategory, string> = {\n KPI: 'Metrics & KPIs',\n Visualization: 'Charts & Visualization',\n Data: 'Data Display',\n Content: 'Content',\n Temporal: 'Temporal & Scheduling',\n Custom: 'Custom',\n Installed: 'Installed from Store',\n};\n\n/**\n * Get widget categories with their definitions\n */\nexport function getWidgetCategories(): {\n category: WidgetCategory;\n label: string;\n widgets: WidgetDefinition[];\n}[] {\n const categories: WidgetCategory[] = ['KPI', 'Visualization', 'Data', 'Content', 'Temporal', 'Custom', 'Installed'];\n\n return categories.map((category) => ({\n category,\n label: WIDGET_CATEGORY_LABELS[category],\n widgets: getWidgetsByCategory(category),\n }));\n}\n\n/**\n * Validate widget size constraints\n */\nexport function validateWidgetSize(\n type: WidgetType,\n width: number,\n height: number\n): { valid: boolean; width: number; height: number } {\n const def = WIDGET_DEFINITIONS[type];\n\n const clampedWidth = Math.min(Math.max(width, def.minSize.width), def.maxSize.width);\n const clampedHeight = Math.min(Math.max(height, def.minSize.height), def.maxSize.height);\n\n return {\n valid: width === clampedWidth && height === clampedHeight,\n width: clampedWidth,\n height: clampedHeight,\n };\n}\n\n/**\n * Get a stable key for a widget definition (handles installed widgets with componentId)\n */\nexport function getWidgetKey(widget: WidgetDefinition): string {\n if (widget.defaultConfig?.componentId) {\n return `installed-${widget.defaultConfig.componentId}`;\n }\n if (widget.category === 'Installed') {\n return `installed-${widget.name}`;\n }\n return widget.type;\n}\n\nexport default WIDGET_DEFINITIONS;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WidgetRegistry.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/WidgetRegistry.ts"],"sourcesContent":["/**\n * Widget Registry\n *\n * Central registry mapping widget types to their components,\n * metadata, and configuration schemas.\n */\n\nimport type { ComponentType } from 'react';\nimport type { WidgetType, WidgetCategory, Widget } from '../../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetComponentProps {\n /** The widget data */\n widget: Widget;\n /** Widget data (processed) */\n data: Record<string, unknown>;\n /** Whether the widget is in edit mode */\n isEditMode?: boolean;\n /** Whether the widget is selected */\n isSelected?: boolean;\n /** Whether data is loading */\n isLoading?: boolean;\n /** Error message if any */\n error?: string | null;\n /** Callback when widget is clicked */\n onClick?: () => void;\n /** Callback for drilldown navigation */\n onDrilldown?: (params: Record<string, unknown>) => void;\n}\n\nexport interface WidgetDefinition {\n /** Widget type */\n type: WidgetType;\n /** Human-readable name */\n name: string;\n /** Description */\n description: string;\n /** Lucide icon name */\n icon: string;\n /** Category for grouping */\n category: WidgetCategory;\n /** Component to render. Null for all current widget types because the render path\n * uses WidgetRendererFactory + RendererRegistry instead of this field. */\n component: ComponentType<WidgetComponentProps> | null;\n /** Default configuration */\n defaultConfig: Record<string, unknown>;\n /** Default size (fixed grid) */\n defaultSize: { width: number; height: number };\n /**\n * Default responsive position (v1.0 spec). `xl` is optional and falls back\n * to `lg` when not set so existing widget defaults remain valid.\n */\n defaultResponsive: { xs: number; sm: number; md: number; lg: number; xl?: number };\n /** Minimum size constraints */\n minSize: { width: number; height: number };\n /** Maximum size constraints */\n maxSize: { width: number; height: number };\n /** Whether the widget supports data binding */\n supportsDataBinding: boolean;\n /** Whether the widget supports drilldown */\n supportsDrilldown: boolean;\n /** Whether the widget supports auto-refresh */\n supportsAutoRefresh: boolean;\n /**\n * Whether the widget honors rule-based conditional formatting\n * (`config.conditionalRules`). Drives which options the config UI shows.\n */\n supportsConditionalFormat?: boolean;\n /**\n * Whether the widget supports reference / threshold lines & bands\n * (`config.referenceLines`).\n */\n supportsThresholds?: boolean;\n /** Whether the widget supports a combo / dual-axis layout (`config.dualAxis`). */\n supportsDualAxis?: boolean;\n /** Whether the widget supports a totals/aggregate footer (`config.showTotals`). */\n supportsTotals?: boolean;\n /** Tags for search/filter */\n tags: string[];\n}\n\n// ============================================================================\n// Widget Definitions\n// ============================================================================\n\nexport const WIDGET_DEFINITIONS: Record<WidgetType, WidgetDefinition> = {\n // ============================================================================\n // Core Visualization (6 types)\n // ============================================================================\n\n kpi_card_comparison: {\n type: 'kpi_card_comparison',\n name: 'KPI Card Comparison',\n description: 'Compare multiple KPIs side by side with trends',\n icon: 'LayoutDashboard',\n category: 'KPI',\n component: null,\n defaultConfig: {\n comparisons: [],\n showSparklines: true,\n layout: 'horizontal',\n format: 'number',\n },\n defaultSize: { width: 6, height: 3 },\n defaultResponsive: { xs: 12, sm: 6, md: 6, lg: 4 },\n minSize: { width: 4, height: 2 },\n maxSize: { width: 12, height: 6 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n supportsConditionalFormat: true,\n tags: ['kpi', 'comparison', 'metrics', 'multi'],\n },\n\n metric_card: {\n type: 'metric_card',\n name: 'Metric Card',\n description: 'Display a single KPI value with trend indicator',\n icon: 'TrendingUp',\n category: 'KPI',\n component: null,\n defaultConfig: {\n // 'auto' defers the numeric style to the payload's `isCurrency`, so a\n // parser emitting the documented MetricCardData contract renders as\n // currency without the user having to re-pick it in the Style tab.\n format: 'auto',\n decimalPlaces: 0,\n showTrend: true,\n showSparkline: false,\n },\n defaultSize: { width: 3, height: 2 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 3 },\n minSize: { width: 2, height: 2 },\n maxSize: { width: 6, height: 4 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n supportsConditionalFormat: true,\n tags: ['kpi', 'metric', 'number', 'trend'],\n },\n\n chart: {\n type: 'chart',\n name: 'Chart',\n description: 'Multi-type chart (Line, Bar, Area, Pie)',\n icon: 'BarChart3',\n category: 'Visualization',\n component: null,\n defaultConfig: {\n chartType: 'line',\n showLegend: true,\n legendPosition: 'bottom',\n showGrid: true,\n showTooltip: true,\n },\n defaultSize: { width: 6, height: 4 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 3, height: 3 },\n maxSize: { width: 12, height: 8 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n supportsConditionalFormat: true,\n supportsThresholds: true,\n supportsDualAxis: true,\n tags: ['chart', 'graph', 'visualization', 'line', 'bar', 'area', 'pie', 'combo', 'dual-axis'],\n },\n\n funnel_chart: {\n type: 'funnel_chart',\n name: 'Funnel Chart',\n description: 'Visualize conversion or drop-off stages',\n icon: 'Filter',\n category: 'Visualization',\n component: null,\n defaultConfig: {\n // ChartWidget dispatches on `chartType` and falls back to 'line' when it is\n // absent, so a palette-created funnel must seed it explicitly.\n chartType: 'funnel',\n showLabels: true,\n showValues: true,\n showPercentages: true,\n orientation: 'vertical',\n },\n defaultSize: { width: 4, height: 5 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 3, height: 4 },\n maxSize: { width: 8, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['funnel', 'conversion', 'stages', 'pipeline'],\n },\n\n table: {\n type: 'table',\n name: 'Data Table',\n description: 'Display data in sortable, filterable rows and columns',\n icon: 'Table',\n category: 'Data',\n component: null,\n defaultConfig: {\n pageSize: 10,\n sortable: true,\n filterable: true,\n stickyHeader: true,\n columns: [],\n },\n defaultSize: { width: 8, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 8, lg: 8 },\n minSize: { width: 4, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n supportsConditionalFormat: true,\n supportsTotals: true,\n tags: ['table', 'data', 'grid', 'rows'],\n },\n\n pivot_table: {\n type: 'pivot_table',\n name: 'Pivot Table',\n description: 'Interactive pivot table for data analysis',\n icon: 'Grid3x3',\n category: 'Data',\n component: null,\n defaultConfig: {\n rows: [],\n columns: [],\n values: [],\n aggregation: 'sum',\n showTotals: true,\n },\n defaultSize: { width: 10, height: 6 },\n defaultResponsive: { xs: 12, sm: 12, md: 12, lg: 10 },\n minSize: { width: 6, height: 4 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['pivot', 'table', 'analysis', 'aggregation'],\n },\n\n // ============================================================================\n // Indicators (2 types)\n // ============================================================================\n\n gauge: {\n type: 'gauge',\n name: 'Gauge',\n description: 'Display a value within a range',\n icon: 'Gauge',\n category: 'KPI',\n component: null,\n defaultConfig: {\n variant: 'circular',\n min: 0,\n max: 100,\n showValue: true,\n showLabels: true,\n // Semantic threshold vocabulary — matches what the Gauge inspector\n // writes (GaugeConfig.tsx) and what GaugeWidget maps onto fe-libs\n // `--color-status-*` tokens. Raw colour names are not permitted in UI.\n thresholds: [\n { value: 33, color: 'error' },\n { value: 66, color: 'warning' },\n { value: 100, color: 'success' },\n ],\n },\n defaultSize: { width: 3, height: 3 },\n defaultResponsive: { xs: 6, sm: 4, md: 3, lg: 3 },\n minSize: { width: 2, height: 2 },\n maxSize: { width: 6, height: 6 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: true,\n tags: ['gauge', 'meter', 'dial', 'indicator'],\n },\n\n progress: {\n type: 'progress',\n name: 'Progress Bar',\n description: 'Show progress towards a goal with milestones',\n icon: 'Activity',\n category: 'KPI',\n component: null,\n defaultConfig: {\n showPercentage: true,\n showValue: false,\n target: null,\n milestones: [],\n },\n defaultSize: { width: 4, height: 2 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 3, height: 2 },\n maxSize: { width: 12, height: 3 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: true,\n tags: ['progress', 'bar', 'goal', 'completion'],\n },\n\n // ============================================================================\n // Data Display (2 types)\n // ============================================================================\n\n list: {\n type: 'list',\n name: 'List',\n description: 'Display items in a scrollable list',\n icon: 'List',\n category: 'Data',\n component: null,\n defaultConfig: {\n showMetadata: true,\n showActions: false,\n showBadges: true,\n maxItems: 10,\n itemClickable: true,\n },\n defaultSize: { width: 4, height: 5 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 3, height: 3 },\n maxSize: { width: 8, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['list', 'items', 'scroll'],\n },\n\n form: {\n type: 'form',\n name: 'Form',\n description: 'Interactive form widget for data input',\n icon: 'FileText',\n category: 'Data',\n component: null,\n defaultConfig: {\n fields: [],\n submitAction: null,\n layout: 'vertical',\n showLabels: true,\n },\n defaultSize: { width: 6, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 4, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: false,\n tags: ['form', 'input', 'submit', 'fields'],\n },\n\n // ============================================================================\n // Content (2 types)\n // ============================================================================\n\n text: {\n type: 'text',\n name: 'Text',\n description: 'Rich text or markdown content widget',\n icon: 'Type',\n category: 'Content',\n component: null,\n defaultConfig: {\n content: '',\n format: 'markdown',\n alignment: 'left',\n },\n defaultSize: { width: 4, height: 3 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 2, height: 1 },\n maxSize: { width: 12, height: 12 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: false,\n tags: ['text', 'markdown', 'content', 'rich text'],\n },\n\n iframe: {\n type: 'iframe',\n name: 'Iframe',\n description: 'Embed external content via iframe',\n icon: 'ExternalLink',\n category: 'Content',\n component: null,\n defaultConfig: {\n url: '',\n sandbox: 'allow-scripts allow-same-origin',\n allowFullscreen: false,\n },\n defaultSize: { width: 6, height: 4 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 3, height: 2 },\n maxSize: { width: 12, height: 12 },\n supportsDataBinding: false,\n supportsDrilldown: false,\n supportsAutoRefresh: false,\n tags: ['iframe', 'embed', 'external', 'web'],\n },\n\n // ============================================================================\n // Spatial & Temporal (5 types)\n // ============================================================================\n\n map: {\n type: 'map',\n name: 'Map',\n description: 'Geographic map visualization with markers',\n icon: 'MapPin',\n category: 'Visualization',\n component: null,\n defaultConfig: {\n provider: 'mapbox',\n center: { lat: 0, lng: 0 },\n zoom: 2,\n showMarkers: true,\n showRegions: false,\n },\n defaultSize: { width: 6, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 4, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['map', 'geo', 'location', 'markers'],\n },\n\n heatmap: {\n type: 'heatmap',\n name: 'Heatmap',\n description: 'Display values in a color-coded grid',\n icon: 'Grid3x3',\n category: 'Visualization',\n component: null,\n defaultConfig: {\n xAxisField: '',\n yAxisField: '',\n valueField: '',\n // HeatmapWidget renders intensity from `colorScheme` (token-based Tailwind\n // classes), not `colorScale`; keep the scale empty rather than seeding it\n // with CSS var() strings that a data array can never resolve.\n colorScale: [],\n colorScheme: 'blue',\n showValues: true,\n },\n defaultSize: { width: 6, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 6, lg: 6 },\n minSize: { width: 4, height: 4 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['heatmap', 'grid', 'density', 'color'],\n },\n\n calendar: {\n type: 'calendar',\n name: 'Calendar',\n description: 'Calendar view for events and schedules',\n icon: 'Calendar',\n category: 'Temporal',\n component: null,\n defaultConfig: {\n view: 'month',\n showWeekNumbers: false,\n firstDayOfWeek: 0,\n eventField: '',\n },\n defaultSize: { width: 8, height: 6 },\n defaultResponsive: { xs: 12, sm: 12, md: 8, lg: 8 },\n minSize: { width: 6, height: 4 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['calendar', 'events', 'schedule', 'dates'],\n },\n\n kanban: {\n type: 'kanban',\n name: 'Kanban Board',\n description: 'Kanban board for task and workflow management',\n icon: 'Columns',\n category: 'Data',\n component: null,\n defaultConfig: {\n columns: [],\n cardTitleField: '',\n cardDescriptionField: '',\n columnField: '',\n allowDragDrop: true,\n },\n defaultSize: { width: 12, height: 6 },\n defaultResponsive: { xs: 12, sm: 12, md: 12, lg: 12 },\n minSize: { width: 8, height: 4 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['kanban', 'board', 'tasks', 'workflow'],\n },\n\n timeline: {\n type: 'timeline',\n name: 'Timeline',\n description: 'Timeline or Gantt chart for project scheduling',\n icon: 'GitBranch',\n category: 'Temporal',\n component: null,\n defaultConfig: {\n startDateField: '',\n endDateField: '',\n titleField: '',\n groupField: '',\n showToday: true,\n },\n defaultSize: { width: 12, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 12, lg: 12 },\n minSize: { width: 8, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['timeline', 'gantt', 'project', 'schedule'],\n },\n\n // ============================================================================\n // Cohort / Retention (1 type)\n // ============================================================================\n\n retention: {\n type: 'retention',\n name: 'Retention / Cohort',\n description: 'Cohort-by-period retention grid with decay shading',\n icon: 'Grid3x3',\n category: 'Data',\n component: null,\n defaultConfig: {\n cohortField: 'cohort',\n periodField: 'period',\n valueField: 'value',\n periodType: 'month',\n showPercentages: true,\n showAverages: true,\n showLegend: true,\n },\n defaultSize: { width: 8, height: 5 },\n defaultResponsive: { xs: 12, sm: 12, md: 8, lg: 8 },\n minSize: { width: 4, height: 3 },\n maxSize: { width: 12, height: 10 },\n supportsDataBinding: true,\n supportsDrilldown: false,\n supportsAutoRefresh: true,\n tags: ['retention', 'cohort', 'grid', 'churn', 'saas'],\n },\n\n // ============================================================================\n // Extensibility (1 type)\n // ============================================================================\n\n custom: {\n type: 'custom',\n name: 'Custom Widget',\n description: 'Custom widget with user-defined rendering',\n icon: 'Puzzle',\n category: 'Custom',\n component: null,\n defaultConfig: {\n componentId: '',\n props: {},\n },\n defaultSize: { width: 4, height: 4 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 2, height: 2 },\n maxSize: { width: 12, height: 12 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['custom', 'plugin', 'extension'],\n },\n};\n\n// ============================================================================\n// Registry Functions\n// ============================================================================\n\n/**\n * Default widget definition for unknown types\n */\nconst DEFAULT_WIDGET_DEFINITION: WidgetDefinition = {\n type: 'custom' as WidgetType,\n name: 'Unknown Widget',\n description: 'Unknown widget type',\n icon: 'Puzzle',\n category: 'Custom',\n component: null,\n defaultConfig: {},\n defaultSize: { width: 4, height: 4 },\n defaultResponsive: { xs: 12, sm: 6, md: 4, lg: 4 },\n minSize: { width: 2, height: 2 },\n maxSize: { width: 12, height: 12 },\n supportsDataBinding: true,\n supportsDrilldown: true,\n supportsAutoRefresh: true,\n tags: ['unknown'],\n};\n\n/**\n * Get widget definition by type\n * Handles both lowercase (frontend) and uppercase (backend) types\n */\nexport function getWidgetDefinition(type: WidgetType | string): WidgetDefinition {\n // Try exact match first\n if (WIDGET_DEFINITIONS[type as WidgetType]) {\n return WIDGET_DEFINITIONS[type as WidgetType];\n }\n\n // Try lowercase version (backend returns uppercase for some types)\n const lowerType = type.toLowerCase() as WidgetType;\n if (WIDGET_DEFINITIONS[lowerType]) {\n return WIDGET_DEFINITIONS[lowerType];\n }\n\n // Return default definition for unknown types\n return { ...DEFAULT_WIDGET_DEFINITION, type: type as WidgetType };\n}\n\n/**\n * Get all widget definitions\n */\nexport function getAllWidgetDefinitions(): WidgetDefinition[] {\n return Object.values(WIDGET_DEFINITIONS);\n}\n\n/**\n * Get widget definitions by category\n */\nexport function getWidgetsByCategory(category: WidgetCategory): WidgetDefinition[] {\n return Object.values(WIDGET_DEFINITIONS).filter((def) => def.category === category);\n}\n\n/**\n * Search widget definitions by query\n */\nexport function searchWidgets(query: string): WidgetDefinition[] {\n const lowerQuery = query.toLowerCase();\n return Object.values(WIDGET_DEFINITIONS).filter(\n (def) =>\n def.name.toLowerCase().includes(lowerQuery) ||\n def.description.toLowerCase().includes(lowerQuery) ||\n def.tags.some((tag) => tag.includes(lowerQuery))\n );\n}\n\n/**\n * Canonical mapping from widget category to human-readable label.\n * Shared across WidgetTypeSelector, WidgetPalette, and other UI.\n */\nexport const WIDGET_CATEGORY_LABELS: Record<WidgetCategory, string> = {\n KPI: 'Metrics & KPIs',\n Visualization: 'Charts & Visualization',\n Data: 'Data Display',\n Content: 'Content',\n Temporal: 'Temporal & Scheduling',\n Custom: 'Custom',\n Installed: 'Installed from Store',\n};\n\n/**\n * Get widget categories with their definitions\n */\nexport function getWidgetCategories(): {\n category: WidgetCategory;\n label: string;\n widgets: WidgetDefinition[];\n}[] {\n const categories: WidgetCategory[] = ['KPI', 'Visualization', 'Data', 'Content', 'Temporal', 'Custom', 'Installed'];\n\n return categories.map((category) => ({\n category,\n label: WIDGET_CATEGORY_LABELS[category],\n widgets: getWidgetsByCategory(category),\n }));\n}\n\n/**\n * Validate widget size constraints\n */\nexport function validateWidgetSize(\n type: WidgetType,\n width: number,\n height: number\n): { valid: boolean; width: number; height: number } {\n const def = WIDGET_DEFINITIONS[type];\n\n const clampedWidth = Math.min(Math.max(width, def.minSize.width), def.maxSize.width);\n const clampedHeight = Math.min(Math.max(height, def.minSize.height), def.maxSize.height);\n\n return {\n valid: width === clampedWidth && height === clampedHeight,\n width: clampedWidth,\n height: clampedHeight,\n };\n}\n\n/**\n * Get a stable key for a widget definition (handles installed widgets with componentId)\n */\nexport function getWidgetKey(widget: WidgetDefinition): string {\n if (widget.defaultConfig?.componentId) {\n return `installed-${widget.defaultConfig.componentId}`;\n }\n if (widget.category === 'Installed') {\n return `installed-${widget.name}`;\n }\n return widget.type;\n}\n\nexport default WIDGET_DEFINITIONS;\n"],"mappings":"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"}
|
|
@@ -463,11 +463,12 @@ var v = d(function({ widget: u, children: d, data: _, className: v = "", isLoadi
|
|
|
463
463
|
ref: B,
|
|
464
464
|
className: `
|
|
465
465
|
group relative flex flex-col
|
|
466
|
-
h-full w-full
|
|
467
|
-
rounded-
|
|
466
|
+
h-full w-full min-w-0
|
|
467
|
+
rounded-card border
|
|
468
468
|
bg-bg-surface
|
|
469
|
-
|
|
470
|
-
|
|
469
|
+
shadow-[var(--shadow-elevation-1)]
|
|
470
|
+
motion-safe:transition-[box-shadow,border-color] motion-safe:duration-200
|
|
471
|
+
${T && C ? "border-[var(--color-action-primary-border)] ring-2 ring-[var(--color-action-primary-border)]/30 shadow-[var(--shadow-elevation-2)]" : "border-[var(--color-border-subtle)] hover:border-action-primary-bg hover:shadow-[var(--shadow-elevation-2)]"}
|
|
471
472
|
${C ? "cursor-pointer" : ""}
|
|
472
473
|
${v}
|
|
473
474
|
`,
|
|
@@ -500,12 +501,12 @@ var v = d(function({ widget: u, children: d, data: _, className: v = "", isLoadi
|
|
|
500
501
|
}),
|
|
501
502
|
/* @__PURE__ */ g("div", {
|
|
502
503
|
className: `
|
|
503
|
-
flex-1 overflow-hidden p-
|
|
504
|
+
flex-1 overflow-hidden p-3 min-h-0 min-w-0 sm:p-4
|
|
504
505
|
${Z && !C ? "cursor-pointer" : ""}
|
|
505
506
|
`,
|
|
506
507
|
title: Z && !C ? "Click data to drill down" : void 0,
|
|
507
508
|
children: /* @__PURE__ */ g("div", {
|
|
508
|
-
className: "h-full overflow-auto",
|
|
509
|
+
className: "h-full min-w-0 overflow-auto",
|
|
509
510
|
children: (() => {
|
|
510
511
|
if (L) return /* @__PURE__ */ g(se, {});
|
|
511
512
|
if (R) return /* @__PURE__ */ g(ce, {
|
|
@@ -532,7 +533,7 @@ var v = d(function({ widget: u, children: d, data: _, className: v = "", isLoadi
|
|
|
532
533
|
})
|
|
533
534
|
}),
|
|
534
535
|
b && b.length > 0 && !L && !R && /* @__PURE__ */ g("div", {
|
|
535
|
-
className: "
|
|
536
|
+
className: "min-w-0 border-t border-[var(--color-border-subtle)] bg-bg-sunken px-3 py-2 sm:px-4",
|
|
536
537
|
style: { flexShrink: 0 },
|
|
537
538
|
children: /* @__PURE__ */ g(me, {
|
|
538
539
|
actions: b,
|