@burdenoff/microfe-bigconsole 2026.624.1 → 2026.625.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/dist/bigconsole/BigConsoleRoutes.js +94 -94
  2. package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
  3. package/dist/bigconsole/assistant/assistantApi.js +215 -0
  4. package/dist/bigconsole/assistant/assistantApi.js.map +1 -0
  5. package/dist/bigconsole/assistant/createSandboxAssistantTransport.js +119 -0
  6. package/dist/bigconsole/assistant/createSandboxAssistantTransport.js.map +1 -0
  7. package/dist/bigconsole/assistant/index.js +2 -0
  8. package/dist/bigconsole/assistant/pageContext.js +51 -0
  9. package/dist/bigconsole/assistant/pageContext.js.map +1 -0
  10. package/dist/bigconsole/components/DrilldownModal.js +4 -4
  11. package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
  12. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +48 -48
  13. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +1 -1
  14. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  15. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +54 -54
  16. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  17. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +1 -1
  18. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
  19. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js +33 -33
  20. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +205 -205
  21. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  22. package/dist/bigconsole/components/dashboard/WidgetPalette.js +38 -38
  23. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +1 -1
  24. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  25. package/dist/bigconsole/components/datasink/DataSinkCard.js +4 -4
  26. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  27. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +2 -2
  28. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
  29. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +2 -2
  30. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  31. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +2 -2
  32. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  33. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +34 -34
  34. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
  35. package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js +31 -31
  36. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +121 -121
  37. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  38. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +1 -1
  39. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
  40. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +3 -3
  41. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
  42. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +2 -2
  43. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  44. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +2 -2
  45. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
  46. package/dist/bigconsole/components/parser/DataSinkSelector.js +3 -3
  47. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  48. package/dist/bigconsole/components/parser/ExportParserDialog.js +31 -31
  49. package/dist/bigconsole/components/parser/ImportParserDialog.js +186 -186
  50. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  51. package/dist/bigconsole/components/parser/ParserCard.js +5 -5
  52. package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
  53. package/dist/bigconsole/components/parser/ParserSelector.js +6 -6
  54. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  55. package/dist/bigconsole/components/parser/ParserStatusBadge.js +1 -1
  56. package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
  57. package/dist/bigconsole/components/parser/ParserTypeBadge.js +1 -1
  58. package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
  59. package/dist/bigconsole/components/pipeline/PipelineCard.js +2 -2
  60. package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
  61. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +1 -1
  62. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
  63. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +1 -1
  64. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
  65. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +79 -79
  66. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  67. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +11 -11
  68. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  69. package/dist/bigconsole/components/widgets/PropertiesPanel.js +322 -322
  70. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  71. package/dist/bigconsole/components/widgets/WidgetConfigDialog.js +234 -234
  72. package/dist/bigconsole/components/widgets/WidgetConfigDialog.js.map +1 -1
  73. package/dist/bigconsole/components/widgets/WidgetHeader.js +4 -4
  74. package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
  75. package/dist/bigconsole/components/widgets/WidgetMenu.js +3 -3
  76. package/dist/bigconsole/components/widgets/WidgetMenu.js.map +1 -1
  77. package/dist/bigconsole/components/widgets/WidgetTypeSelector.js +23 -23
  78. package/dist/bigconsole/components/widgets/WidgetWrapper.js +1 -1
  79. package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
  80. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +1 -1
  81. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  82. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +2 -2
  83. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  84. package/dist/bigconsole/components/widgets/custom/CustomWidget.js +5 -5
  85. package/dist/bigconsole/components/widgets/custom/CustomWidget.js.map +1 -1
  86. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +1 -1
  87. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
  88. package/dist/bigconsole/components/widgets/gauge/LinearGauge.js +1 -1
  89. package/dist/bigconsole/components/widgets/gauge/LinearGauge.js.map +1 -1
  90. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +2 -2
  91. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  92. package/dist/bigconsole/components/widgets/kpi/KPIWidget.js +2 -2
  93. package/dist/bigconsole/components/widgets/kpi/KPIWidget.js.map +1 -1
  94. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +2 -2
  95. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
  96. package/dist/bigconsole/components/widgets/list/ListItem.js +3 -3
  97. package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
  98. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +3 -3
  99. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
  100. package/dist/bigconsole/components/widgets/metric-card/ComparisonBadge.js +1 -1
  101. package/dist/bigconsole/components/widgets/metric-card/ComparisonBadge.js.map +1 -1
  102. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +2 -2
  103. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
  104. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +12 -12
  105. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  106. package/dist/bigconsole/components/widgets/progress/ProgressBar.js +2 -2
  107. package/dist/bigconsole/components/widgets/progress/ProgressBar.js.map +1 -1
  108. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +1 -1
  109. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  110. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +1 -1
  111. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
  112. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +2 -2
  113. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
  114. package/dist/bigconsole/components/widgets/states/EmptyState.js +1 -1
  115. package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
  116. package/dist/bigconsole/components/widgets/table/TableCell.js +1 -1
  117. package/dist/bigconsole/components/widgets/table/TableCell.js.map +1 -1
  118. package/dist/bigconsole/components/widgets/table/TableConfig.js +1 -1
  119. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  120. package/dist/bigconsole/components/widgets/table/TableHeader.js +2 -2
  121. package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
  122. package/dist/bigconsole/components/widgets/table/TablePagination.js +4 -4
  123. package/dist/bigconsole/components/widgets/table/TablePagination.js.map +1 -1
  124. package/dist/bigconsole/components/widgets/table/TableWidget.js +5 -5
  125. package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
  126. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +1 -1
  127. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
  128. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +3 -3
  129. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
  130. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +2 -2
  131. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -1
  132. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +3 -3
  133. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  134. package/dist/bigconsole/components/workflow/WorkflowCard.js +2 -2
  135. package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
  136. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +1 -1
  137. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
  138. package/dist/bigconsole/index.js +3 -0
  139. package/dist/bigconsole/pages/DashboardBuilderPage.js +76 -76
  140. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  141. package/dist/bigconsole/pages/DashboardViewPage.js +169 -190
  142. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  143. package/dist/bigconsole/pages/DashboardsPage.js +268 -312
  144. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  145. package/dist/bigconsole/pages/DataParsersPage.js +148 -194
  146. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  147. package/dist/bigconsole/pages/DataSinkBuilderPage.js +254 -248
  148. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  149. package/dist/bigconsole/pages/DataSinkViewPage.js +256 -231
  150. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  151. package/dist/bigconsole/pages/DataSinksPage.js +173 -219
  152. package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
  153. package/dist/bigconsole/pages/HomePage.js +125 -141
  154. package/dist/bigconsole/pages/HomePage.js.map +1 -1
  155. package/dist/bigconsole/pages/InsightsPage.js +159 -184
  156. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  157. package/dist/bigconsole/pages/ParserBuilderPage.js +404 -396
  158. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  159. package/dist/bigconsole/pages/ParserViewPage.js +221 -202
  160. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  161. package/dist/bigconsole/pages/PipelineBuilderPage.js +216 -210
  162. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  163. package/dist/bigconsole/pages/PipelineViewPage.js +213 -190
  164. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  165. package/dist/bigconsole/pages/PipelinesPage.js +107 -150
  166. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  167. package/dist/bigconsole/pages/SettingsPage.js +184 -171
  168. package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
  169. package/dist/bigconsole/pages/WidgetDemoPage.js +71 -83
  170. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  171. package/dist/bigconsole/pages/WorkflowViewPage.js +235 -221
  172. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  173. package/dist/bigconsole/pages/WorkflowsPage.js +106 -149
  174. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  175. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +12 -12
  176. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
  177. package/dist/bigconsole/renderers/adapters/BigConsoleRenderer.js +2 -2
  178. package/dist/bigconsole/renderers/adapters/BigConsoleRenderer.js.map +1 -1
  179. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +5 -5
  180. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
  181. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +2 -2
  182. package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
  183. package/dist/generated/wspace-operations.js +87 -36
  184. package/dist/generated/wspace-operations.js.map +1 -1
  185. package/dist/index.js +3 -1
  186. package/package.json +6 -2
@@ -2,8 +2,8 @@ import e from "./TemplatePicker/TemplatePicker.js";
2
2
  import "./TemplatePicker/index.js";
3
3
  import { memo as t, useCallback as n, useEffect as r, useRef as i, useState as a } from "react";
4
4
  import { Copy as o, LayoutDashboard as s, Plus as c, Tag as l, X as u } from "lucide-react";
5
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
6
- import { Badge as p, Button as m, Dialog as h, DialogContent as g, DialogDescription as _, DialogFooter as v, DialogHeader as y, DialogTitle as b, Input as x, Spinner as S, Textarea as C } from "@burdenoff/fe-libs/ui";
5
+ import { Badge as d, Button as f, Dialog as p, DialogContent as m, DialogDescription as h, DialogFooter as g, DialogHeader as _, DialogTitle as v, Input as y, Spinner as b, Textarea as x } from "@burdenoff/fe-libs/ui";
6
+ import { jsx as S, jsxs as C } from "react/jsx-runtime";
7
7
  //#region src/bigconsole/components/dashboard/CreateDashboardDialog.tsx
8
8
  var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, showTemplates: D = !0 }) {
9
9
  let [O, k] = a("blank"), [A, j] = a(""), [M, N] = a(""), [P, F] = a([]), [I, L] = a(""), [R, z] = a(null), [B, V] = a(null), H = i(null);
@@ -63,24 +63,24 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
63
63
  R,
64
64
  E
65
65
  ]);
66
- return /* @__PURE__ */ d(h, {
66
+ return /* @__PURE__ */ S(p, {
67
67
  open: t,
68
68
  onOpenChange: (e) => !e && !w && T(),
69
- children: /* @__PURE__ */ f(g, {
69
+ children: /* @__PURE__ */ C(m, {
70
70
  style: {
71
71
  maxWidth: O === "template" ? "900px" : "480px",
72
72
  padding: 0,
73
73
  transition: "max-width 0.2s ease"
74
74
  },
75
- children: [/* @__PURE__ */ d(y, {
75
+ children: [/* @__PURE__ */ S(_, {
76
76
  style: { padding: "var(--space-pagePadding) var(--space-pagePadding) 0" },
77
- children: /* @__PURE__ */ f("div", {
77
+ children: /* @__PURE__ */ C("div", {
78
78
  style: {
79
79
  display: "flex",
80
80
  alignItems: "center",
81
81
  gap: "var(--space-formGap)"
82
82
  },
83
- children: [/* @__PURE__ */ d("div", {
83
+ children: [/* @__PURE__ */ S("div", {
84
84
  style: {
85
85
  display: "flex",
86
86
  height: "var(--size-controlHeight-lg)",
@@ -91,12 +91,12 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
91
91
  backgroundColor: "var(--color-action-primary-bg)",
92
92
  boxShadow: "var(--shadow-elevation-2)"
93
93
  },
94
- children: /* @__PURE__ */ d(s, { style: {
94
+ children: /* @__PURE__ */ S(s, { style: {
95
95
  height: "var(--size-icon-lg)",
96
96
  width: "var(--size-icon-lg)",
97
97
  color: "var(--color-action-primary-text)"
98
98
  } })
99
- }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d(b, {
99
+ }), /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S(v, {
100
100
  style: {
101
101
  fontSize: "var(--font-size-heading-h4)",
102
102
  fontWeight: "var(--font-weight-bold)",
@@ -104,7 +104,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
104
104
  margin: 0
105
105
  },
106
106
  children: "Create New Dashboard"
107
- }), /* @__PURE__ */ d(_, {
107
+ }), /* @__PURE__ */ S(h, {
108
108
  style: {
109
109
  fontSize: "var(--font-size-body-sm)",
110
110
  color: "var(--color-text-secondary)",
@@ -113,12 +113,12 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
113
113
  children: "Create a new dashboard to visualize your data"
114
114
  })] })]
115
115
  })
116
- }), /* @__PURE__ */ f("form", {
116
+ }), /* @__PURE__ */ C("form", {
117
117
  onSubmit: q,
118
118
  children: [
119
- D && /* @__PURE__ */ d("div", {
119
+ D && /* @__PURE__ */ S("div", {
120
120
  style: { padding: "var(--space-pagePadding) var(--space-pagePadding) 0" },
121
- children: /* @__PURE__ */ f("div", {
121
+ children: /* @__PURE__ */ C("div", {
122
122
  style: {
123
123
  display: "flex",
124
124
  gap: "var(--space-controlGap)",
@@ -126,7 +126,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
126
126
  backgroundColor: "var(--color-bg-sunken)",
127
127
  borderRadius: "var(--radius-button)"
128
128
  },
129
- children: [/* @__PURE__ */ f("button", {
129
+ children: [/* @__PURE__ */ C("button", {
130
130
  type: "button",
131
131
  onClick: () => {
132
132
  k("blank"), z(null);
@@ -148,11 +148,11 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
148
148
  boxShadow: O === "blank" ? "var(--shadow-elevation-1)" : "none",
149
149
  transition: "all 0.15s ease"
150
150
  },
151
- children: [/* @__PURE__ */ d(c, { style: {
151
+ children: [/* @__PURE__ */ S(c, { style: {
152
152
  height: "var(--size-icon-sm)",
153
153
  width: "var(--size-icon-sm)"
154
154
  } }), "Blank Dashboard"]
155
- }), /* @__PURE__ */ f("button", {
155
+ }), /* @__PURE__ */ C("button", {
156
156
  type: "button",
157
157
  onClick: () => k("template"),
158
158
  style: {
@@ -172,32 +172,32 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
172
172
  boxShadow: O === "template" ? "var(--shadow-elevation-1)" : "none",
173
173
  transition: "all 0.15s ease"
174
174
  },
175
- children: [/* @__PURE__ */ d(o, { style: {
175
+ children: [/* @__PURE__ */ S(o, { style: {
176
176
  height: "var(--size-icon-sm)",
177
177
  width: "var(--size-icon-sm)"
178
178
  } }), "From Template"]
179
179
  })]
180
180
  })
181
181
  }),
182
- O === "template" && /* @__PURE__ */ d("div", {
182
+ O === "template" && /* @__PURE__ */ S("div", {
183
183
  style: {
184
184
  padding: "var(--space-pagePadding)",
185
185
  maxHeight: "400px",
186
186
  overflowY: "auto"
187
187
  },
188
- children: /* @__PURE__ */ d(e, {
188
+ children: /* @__PURE__ */ S(e, {
189
189
  selectedTemplateId: R?.id,
190
190
  onSelect: K,
191
191
  compact: !0
192
192
  })
193
193
  }),
194
- /* @__PURE__ */ f("div", {
194
+ /* @__PURE__ */ C("div", {
195
195
  style: { padding: "var(--space-pagePadding)" },
196
196
  children: [
197
- /* @__PURE__ */ f("div", {
197
+ /* @__PURE__ */ C("div", {
198
198
  style: { marginBottom: "var(--space-formGap)" },
199
199
  children: [
200
- /* @__PURE__ */ f("label", {
200
+ /* @__PURE__ */ C("label", {
201
201
  htmlFor: "dashboard-name",
202
202
  style: {
203
203
  display: "block",
@@ -206,7 +206,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
206
206
  color: "var(--color-text-primary)",
207
207
  marginBottom: "var(--space-controlGap)"
208
208
  },
209
- children: ["Dashboard Name", /* @__PURE__ */ d("span", {
209
+ children: ["Dashboard Name", /* @__PURE__ */ S("span", {
210
210
  style: {
211
211
  color: "var(--color-status-error-text)",
212
212
  marginLeft: "var(--space-controlGap)"
@@ -214,7 +214,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
214
214
  children: "*"
215
215
  })]
216
216
  }),
217
- /* @__PURE__ */ d(x, {
217
+ /* @__PURE__ */ S(y, {
218
218
  ref: H,
219
219
  id: "dashboard-name",
220
220
  type: "text",
@@ -230,7 +230,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
230
230
  borderColor: B ? "var(--color-status-error-border)" : void 0
231
231
  }
232
232
  }),
233
- B && /* @__PURE__ */ d("p", {
233
+ B && /* @__PURE__ */ S("p", {
234
234
  style: {
235
235
  fontSize: "var(--font-size-body-sm)",
236
236
  color: "var(--color-status-error-text)",
@@ -241,9 +241,9 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
241
241
  })
242
242
  ]
243
243
  }),
244
- /* @__PURE__ */ f("div", {
244
+ /* @__PURE__ */ C("div", {
245
245
  style: { marginBottom: "var(--space-formGap)" },
246
- children: [/* @__PURE__ */ f("label", {
246
+ children: [/* @__PURE__ */ C("label", {
247
247
  htmlFor: "dashboard-description",
248
248
  style: {
249
249
  display: "block",
@@ -252,7 +252,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
252
252
  color: "var(--color-text-primary)",
253
253
  marginBottom: "var(--space-controlGap)"
254
254
  },
255
- children: ["Description", /* @__PURE__ */ d("span", {
255
+ children: ["Description", /* @__PURE__ */ S("span", {
256
256
  style: {
257
257
  color: "var(--color-text-muted)",
258
258
  fontWeight: "var(--font-weight-regular)",
@@ -260,7 +260,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
260
260
  },
261
261
  children: "(optional)"
262
262
  })]
263
- }), /* @__PURE__ */ d(C, {
263
+ }), /* @__PURE__ */ S(x, {
264
264
  id: "dashboard-description",
265
265
  value: M,
266
266
  onChange: (e) => N(e.target.value),
@@ -273,8 +273,8 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
273
273
  }
274
274
  })]
275
275
  }),
276
- /* @__PURE__ */ f("div", { children: [
277
- /* @__PURE__ */ f("label", {
276
+ /* @__PURE__ */ C("div", { children: [
277
+ /* @__PURE__ */ C("label", {
278
278
  htmlFor: "dashboard-tags",
279
279
  style: {
280
280
  display: "flex",
@@ -286,12 +286,12 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
286
286
  marginBottom: "var(--space-controlGap)"
287
287
  },
288
288
  children: [
289
- /* @__PURE__ */ d(l, { style: {
289
+ /* @__PURE__ */ S(l, { style: {
290
290
  height: "var(--size-icon-sm)",
291
291
  width: "var(--size-icon-sm)"
292
292
  } }),
293
293
  "Tags",
294
- /* @__PURE__ */ d("span", {
294
+ /* @__PURE__ */ S("span", {
295
295
  style: {
296
296
  color: "var(--color-text-muted)",
297
297
  fontWeight: "var(--font-weight-regular)"
@@ -300,14 +300,14 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
300
300
  })
301
301
  ]
302
302
  }),
303
- P.length > 0 && /* @__PURE__ */ d("div", {
303
+ P.length > 0 && /* @__PURE__ */ S("div", {
304
304
  style: {
305
305
  display: "flex",
306
306
  flexWrap: "wrap",
307
307
  gap: "var(--space-controlGap)",
308
308
  marginBottom: "var(--space-controlGap)"
309
309
  },
310
- children: P.map((e) => /* @__PURE__ */ f(p, {
310
+ children: P.map((e) => /* @__PURE__ */ C(d, {
311
311
  variant: "secondary",
312
312
  style: {
313
313
  display: "flex",
@@ -315,7 +315,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
315
315
  gap: "4px",
316
316
  paddingRight: "4px"
317
317
  },
318
- children: [e, /* @__PURE__ */ d("button", {
318
+ children: [e, /* @__PURE__ */ S("button", {
319
319
  type: "button",
320
320
  onClick: () => W(e),
321
321
  disabled: w,
@@ -333,19 +333,19 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
333
333
  },
334
334
  onMouseOver: (e) => e.currentTarget.style.opacity = "1",
335
335
  onMouseOut: (e) => e.currentTarget.style.opacity = "0.7",
336
- children: /* @__PURE__ */ d(u, { style: {
336
+ children: /* @__PURE__ */ S(u, { style: {
337
337
  height: "12px",
338
338
  width: "12px"
339
339
  } })
340
340
  })]
341
341
  }, e))
342
342
  }),
343
- /* @__PURE__ */ f("div", {
343
+ /* @__PURE__ */ C("div", {
344
344
  style: {
345
345
  display: "flex",
346
346
  gap: "var(--space-controlGap)"
347
347
  },
348
- children: [/* @__PURE__ */ d(x, {
348
+ children: [/* @__PURE__ */ S(y, {
349
349
  id: "dashboard-tags",
350
350
  type: "text",
351
351
  value: I,
@@ -358,7 +358,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
358
358
  height: "var(--size-controlHeight-md)",
359
359
  fontSize: "var(--font-size-body-sm)"
360
360
  }
361
- }), /* @__PURE__ */ d(m, {
361
+ }), /* @__PURE__ */ S(f, {
362
362
  type: "button",
363
363
  variant: "outline",
364
364
  onClick: U,
@@ -367,7 +367,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
367
367
  children: "Add"
368
368
  })]
369
369
  }),
370
- /* @__PURE__ */ d("p", {
370
+ /* @__PURE__ */ S("p", {
371
371
  style: {
372
372
  fontSize: "var(--font-size-body-xs)",
373
373
  color: "var(--color-text-muted)",
@@ -378,7 +378,7 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
378
378
  ] })
379
379
  ]
380
380
  }),
381
- /* @__PURE__ */ f(v, {
381
+ /* @__PURE__ */ C(g, {
382
382
  style: {
383
383
  padding: "var(--space-formGap) var(--space-pagePadding)",
384
384
  borderTop: "1px solid var(--color-border)",
@@ -387,37 +387,37 @@ var w = t(function({ isOpen: t, isCreating: w = !1, onClose: T, onCreate: E, sho
387
387
  justifyContent: "flex-end",
388
388
  gap: "var(--space-controlGap)"
389
389
  },
390
- children: [/* @__PURE__ */ d(m, {
390
+ children: [/* @__PURE__ */ S(f, {
391
391
  type: "button",
392
392
  variant: "outline",
393
393
  onClick: T,
394
394
  disabled: w,
395
395
  style: { height: "var(--size-controlHeight-md)" },
396
396
  children: "Cancel"
397
- }), /* @__PURE__ */ d(m, {
397
+ }), /* @__PURE__ */ S(f, {
398
398
  type: "submit",
399
399
  disabled: w || !A.trim(),
400
400
  style: {
401
401
  height: "var(--size-controlHeight-md)",
402
402
  backgroundColor: "var(--color-action-primary-bg)"
403
403
  },
404
- children: w ? /* @__PURE__ */ f("span", {
404
+ children: w ? /* @__PURE__ */ C("span", {
405
405
  style: {
406
406
  display: "flex",
407
407
  alignItems: "center",
408
408
  gap: "var(--space-iconGap)"
409
409
  },
410
- children: [/* @__PURE__ */ d(S, { style: {
410
+ children: [/* @__PURE__ */ S(b, { style: {
411
411
  height: "var(--size-icon-sm)",
412
412
  width: "var(--size-icon-sm)"
413
413
  } }), "Creating..."]
414
- }) : /* @__PURE__ */ f("span", {
414
+ }) : /* @__PURE__ */ C("span", {
415
415
  style: {
416
416
  display: "flex",
417
417
  alignItems: "center",
418
418
  gap: "var(--space-iconGap)"
419
419
  },
420
- children: [/* @__PURE__ */ d(c, { style: {
420
+ children: [/* @__PURE__ */ S(c, { style: {
421
421
  height: "var(--size-icon-sm)",
422
422
  width: "var(--size-icon-sm)"
423
423
  } }), "Create Dashboard"]
@@ -232,7 +232,7 @@ var g = u(function({ dashboardId: u, pageId: g, title: _, onPaste: fe, onSave: p
232
232
  definitions: Oe
233
233
  }), /* @__PURE__ */ h("div", {
234
234
  ref: S,
235
- className: "flex-1 min-w-0 overflow-auto bg-bg-muted",
235
+ className: "flex-1 min-w-0 overflow-auto bg-bg-sunken",
236
236
  onDrop: Le,
237
237
  onDragOver: Re,
238
238
  onClick: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardCanvas.js","names":[],"sources":["../../../../src/bigconsole/components/dashboard/DashboardCanvas.tsx"],"sourcesContent":["/**\n * DashboardCanvas Component\n *\n * Main canvas for dashboard with grid layout and widget rendering.\n * Phase 2: Added GlobalFiltersBar and PageTabsManager integration.\n * Phase 3: Added WidgetPalette sidebar for drag-and-drop widget creation.\n */\n\nimport { type FC, memo, useRef, useState, useCallback, useEffect, useMemo } from 'react';\nimport type { Layout } from 'react-grid-layout';\nimport type { Widget, WidgetType } from '../../types';\nimport { useDashboardStore, useWidgetStore } from '../../store';\nimport { useWidgetOperations } from '../../hooks/useWidgetOperations';\nimport { useInstalledWidgets } from '../../hooks/useInstalledWidgets';\nimport { useWidgetCatalog } from '../../hooks/useWidgetCatalog';\nimport { useDashboardImageExport } from '../../hooks/useDashboardImageExport';\nimport { useBigConsole } from '../../context';\nimport { DashboardGrid } from './DashboardGrid';\nimport { DashboardToolbar } from './DashboardToolbar';\nimport { GlobalFiltersBar } from './GlobalFiltersBar';\nimport { LiveBoardBanner } from './LiveBoardBanner';\nimport { PageTabsManager, type DashboardPageTab } from './PageTabsManager';\nimport { ShareDialog } from './ShareDialog';\nimport { WidgetPalette } from './WidgetPalette';\nimport { WidgetConfigDialog } from '../widgets/WidgetConfigDialog';\nimport { PropertiesPanel } from '../widgets/PropertiesPanel';\nimport { getWidgetDefinition, type WidgetDefinition } from '../widgets/WidgetRegistry';\n// Phase 2: Cross-filtering context\nimport { CrossFilterProvider } from '../../contexts';\n// Smart widget positioning\nimport { findNextAvailablePosition, calculatePositionFromDrop } from '../../utils/widgetPositioning';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DashboardCanvasProps {\n /** Dashboard ID */\n dashboardId: string;\n /** Page ID (for loading widgets) */\n pageId?: string;\n /** Dashboard title */\n title?: string;\n /** Callback to paste widget */\n onPaste?: () => void;\n /** Callback when dashboard is saved */\n onSave?: () => void;\n /** Whether save is in progress */\n isSaving?: boolean;\n /** Callback to export dashboard */\n onExport?: () => void;\n /** Dashboard pages for PageTabsManager */\n pages?: DashboardPageTab[];\n /** Active page ID */\n activePageId?: string;\n /** Callback when page changes */\n onPageChange?: (pageId: string) => void;\n /** Callback when pages are reordered */\n onPagesReorder?: (pages: DashboardPageTab[]) => void;\n /** Callback when page is added */\n onPageAdd?: () => void;\n /** Callback when page is renamed */\n onPageRename?: (pageId: string, newName: string) => void;\n /** Callback when page is duplicated */\n onPageDuplicate?: (pageId: string) => void;\n /** Callback when page is deleted */\n onPageDelete?: (pageId: string) => void;\n /** Whether to show global filters bar */\n showFilters?: boolean;\n /** Whether to show page tabs */\n showPageTabs?: boolean;\n /** Whether to enable cross-filtering (widget clicks update filters) */\n enableCrossFilter?: boolean;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const DashboardCanvas: FC<DashboardCanvasProps> = memo(function DashboardCanvas({\n dashboardId,\n pageId,\n title,\n onPaste,\n onSave,\n isSaving = false,\n onExport,\n pages = [],\n activePageId,\n onPageChange,\n onPagesReorder,\n onPageAdd,\n onPageRename,\n onPageDuplicate,\n onPageDelete,\n showFilters = true,\n showPageTabs = true,\n enableCrossFilter = true,\n}) {\n const containerRef = useRef<HTMLDivElement>(null);\n // Inner board element (the grid surface) — rasterized for PNG/PDF board-pack export.\n const boardRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState(1200);\n const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);\n const [isShareDialogOpen, setIsShareDialogOpen] = useState(false);\n const [isPaletteOpen, setIsPaletteOpen] = useState(false);\n const [isDraggingWidget, setIsDraggingWidget] = useState(false);\n const [dragWidgetType, setDragWidgetType] = useState<WidgetType | null>(null);\n // State for drag & drop widget creation (stores pending position and type)\n const [pendingDropPosition, setPendingDropPosition] = useState<{\n x: number;\n y: number;\n width: number;\n height: number;\n } | null>(null);\n const [pendingDropType, setPendingDropType] = useState<WidgetType | null>(null);\n // Stores the full WidgetDefinition for installed/store widgets dropped from the palette,\n // so the config dialog can use the store metadata instead of the generic 'custom' definition.\n const [pendingDropDefinition, setPendingDropDefinition] = useState<WidgetDefinition | null>(null);\n\n // Store state\n const isEditMode = useDashboardStore((state) => state.viewMode === 'edit');\n\n // Fetch installed widgets only in edit mode — the palette and add-widget dialog\n // are not usable in read-only view, so skip the request for viewer-only sessions.\n const { workspaceId, apiGatewayUrl, authToken } = useBigConsole();\n const { installedWidgets, loading: installedWidgetsLoading } = useInstalledWidgets({\n workspaceId,\n apiGatewayUrl,\n authToken,\n enabled: isEditMode,\n });\n // Built-in widget catalog from the backend (getWidgetTypes); falls back to the\n // bundled registry while loading or if the supergraph hasn't adopted it yet.\n const { definitions: widgetCatalog } = useWidgetCatalog({\n workspaceId,\n apiGatewayUrl,\n authToken,\n enabled: isEditMode,\n });\n const zoomLevel = useDashboardStore((state) => state.zoomLevel);\n const setGlobalFilterValues = useDashboardStore((state) => state.setGlobalFilterValues);\n\n // Handle filter changes - update store for widget access\n const handleFilterChange = useCallback(\n (filterValues: Record<string, unknown>) => {\n // Update global filter values in dashboard store\n setGlobalFilterValues(filterValues);\n\n // Widgets can now access filter values via useGlobalFilterValues() hook\n // When backend supports filter parameters, widget queries will include these values\n },\n [setGlobalFilterValues]\n );\n\n // Widget operations hook (connects to backend) - skipFetch since parent page fetches\n const { createWidget: createWidgetApi } = useWidgetOperations(pageId, dashboardId, { skipFetch: true });\n\n const widgetsMap = useWidgetStore((state) => state.widgets);\n // Filter widgets to only show widgets for the current page\n const widgetsArray = useMemo(() => {\n const allWidgets = Array.from(widgetsMap.values());\n if (!pageId) return allWidgets;\n return allWidgets.filter((widget) => widget.pageId === pageId);\n }, [widgetsMap, pageId]);\n const selectedWidgetId = useWidgetStore((state) => state.selectedWidgetId);\n const selectWidget = useWidgetStore((state) => state.selectWidget);\n const addWidgetToStore = useWidgetStore((state) => state.addWidget);\n const updateWidgetPosition = useWidgetStore((state) => state.updateWidgetPosition);\n const configPanelOpen = useWidgetStore((state) => state.configPanelOpen);\n const closeConfigPanel = useWidgetStore((state) => state.closeConfigPanel);\n\n // Handle resize\n useEffect(() => {\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.offsetWidth);\n }\n };\n\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, []);\n\n // Handle layout change\n const handleLayoutChange = useCallback(\n (layout: Layout[]) => {\n layout.forEach((item) => {\n updateWidgetPosition(item.i, {\n x: item.x,\n y: item.y,\n width: item.w,\n height: item.h,\n });\n });\n },\n [updateWidgetPosition]\n );\n\n // Handle widget select\n const handleWidgetSelect = useCallback(\n (widgetId: string) => {\n selectWidget(widgetId);\n },\n [selectWidget]\n );\n\n // Handle add widget - tries API first, falls back to local store\n const handleAddWidget = useCallback(\n async (widgetData: Partial<Widget>) => {\n // Get widget definition for default size; prefer the pending drop definition\n // which preserves installed/store widget metadata over the generic registry lookup.\n const definition = pendingDropDefinition || (widgetData.type ? getWidgetDefinition(widgetData.type) : null);\n const widgetSize = {\n width: definition?.defaultSize?.width ?? 4,\n height: definition?.defaultSize?.height ?? 4,\n };\n\n // Use pending drop position if available (from drag & drop), otherwise use smart placement\n let position: { x: number; y: number; width: number; height: number };\n if (pendingDropPosition) {\n position = pendingDropPosition;\n } else {\n // Use smart placement algorithm - horizontal first, then next row\n const { x, y } = findNextAvailablePosition(widgetsArray, widgetSize, { cols: 12 });\n position = {\n x,\n y,\n width: widgetSize.width,\n height: widgetSize.height,\n };\n }\n\n // Extract dataSinkId and parserId from widgetData (passed from WidgetConfigDialog)\n const extendedData = widgetData as Partial<Widget> & { dataSinkId?: string; parserId?: string };\n\n // Try to create via API first\n if (pageId) {\n const widget = await createWidgetApi({\n pageId,\n dashboardId,\n type: widgetData.type!,\n title: widgetData.title || 'Untitled Widget',\n description: widgetData.description,\n // v2.0: Renderer and template support\n renderer: widgetData.renderer,\n template: widgetData.template,\n config: widgetData.config || {},\n position,\n refreshInterval: widgetData.refreshInterval ?? undefined,\n // v2.0: Data source fields (DataSink → Parser → Widget)\n dataSinkId: extendedData.dataSinkId,\n parserId: extendedData.parserId,\n });\n\n if (widget) {\n selectWidget(widget.id);\n setIsAddDialogOpen(false);\n // Clear pending drop state\n setPendingDropPosition(null);\n setPendingDropType(null);\n setPendingDropDefinition(null);\n return;\n }\n }\n\n // Fallback to local store if API fails or no pageId\n const newWidget: Widget = {\n id: crypto.randomUUID(),\n dashboardId,\n pageId: pageId || 'local',\n type: widgetData.type!,\n title: widgetData.title || 'Untitled Widget',\n description: widgetData.description,\n // v2.0: Renderer and template support\n renderer: widgetData.renderer,\n template: widgetData.template,\n refreshInterval: widgetData.refreshInterval,\n config: widgetData.config || {},\n position,\n positionX: position.x,\n positionY: position.y,\n positionWidth: position.width,\n positionHeight: position.height,\n // v2.0: Data source fields (DataSink → Parser → Widget)\n dataSinkId: extendedData.dataSinkId,\n parserId: extendedData.parserId,\n translations: [],\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n\n addWidgetToStore(newWidget);\n selectWidget(newWidget.id);\n setIsAddDialogOpen(false);\n // Clear pending drop state\n setPendingDropPosition(null);\n setPendingDropType(null);\n setPendingDropDefinition(null);\n },\n [\n dashboardId,\n pageId,\n createWidgetApi,\n addWidgetToStore,\n selectWidget,\n widgetsArray,\n pendingDropPosition,\n pendingDropDefinition,\n ]\n );\n\n // Handle drag start from palette\n const handlePaletteDragStart = useCallback((type: WidgetType) => {\n setIsDraggingWidget(true);\n setDragWidgetType(type);\n }, []);\n\n // Handle drag end from palette\n const handlePaletteDragEnd = useCallback(() => {\n setIsDraggingWidget(false);\n setDragWidgetType(null);\n }, []);\n\n // Handle drop on canvas - opens config dialog instead of creating widget directly\n const handleCanvasDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n setIsDraggingWidget(false);\n setDragWidgetType(null);\n\n try {\n const data = e.dataTransfer.getData('application/json');\n if (!data) return;\n\n const widgetData = JSON.parse(data);\n const definition = getWidgetDefinition(widgetData.type);\n\n // If the dropped data includes defaultConfig (from WidgetPalette drag serialization),\n // reconstruct a full WidgetDefinition so installed/store widget identity is preserved.\n let droppedDefinition: WidgetDefinition | null = null;\n if (widgetData.defaultConfig && widgetData.category) {\n droppedDefinition = {\n ...definition,\n name: widgetData.name || definition.name,\n category: widgetData.category,\n defaultConfig: widgetData.defaultConfig,\n defaultSize: widgetData.defaultSize || definition.defaultSize,\n };\n }\n\n // Calculate drop position relative to canvas\n const canvasRect = containerRef.current?.getBoundingClientRect();\n if (!canvasRect) return;\n\n // Use utility to calculate grid position from drop coordinates\n const widgetSize = {\n width: definition.defaultSize.width,\n height: definition.defaultSize.height,\n };\n\n const { x: gridX, y: gridY } = calculatePositionFromDrop(\n e.clientX,\n e.clientY,\n canvasRect,\n containerWidth,\n widgetSize,\n { cols: 12 }\n );\n\n const position = {\n x: gridX,\n y: gridY,\n width: widgetSize.width,\n height: widgetSize.height,\n };\n\n // Store the drop position, type, and full definition, then open the config dialog\n setPendingDropPosition(position);\n setPendingDropType(widgetData.type as WidgetType);\n setPendingDropDefinition(droppedDefinition);\n setIsAddDialogOpen(true);\n } catch (error) {\n console.error('Failed to handle widget drop:', error);\n }\n },\n [containerWidth]\n );\n\n // Handle drag over to allow drop\n const handleCanvasDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n }, []);\n\n // Handle widget select from palette (quick add without drag)\n const handlePaletteWidgetSelect = useCallback(\n (type: WidgetType, paletteDefinition?: WidgetDefinition) => {\n const definition = paletteDefinition || getWidgetDefinition(type);\n handleAddWidget({\n type,\n title: definition.name,\n config: definition.defaultConfig,\n });\n setIsPaletteOpen(false);\n },\n [handleAddWidget]\n );\n\n // Toggle palette\n const togglePalette = useCallback(() => {\n setIsPaletteOpen((prev) => !prev);\n }, []);\n\n // Board-pack export (PNG + PDF) — rasterizes the inner board element.\n const {\n exportPNG,\n exportPDF,\n isExporting: isExportingImage,\n } = useDashboardImageExport({ containerRef: boardRef, name: title || 'dashboard' });\n const handleExportImage = useCallback(() => {\n void exportPNG();\n }, [exportPNG]);\n const handleExportPdf = useCallback(() => {\n void exportPDF();\n }, [exportPDF]);\n\n return (\n <div className=\"flex flex-col h-full min-w-0 overflow-hidden\">\n {/* Toolbar */}\n <DashboardToolbar\n dashboardId={dashboardId}\n title={title}\n onAddWidget={() => setIsAddDialogOpen(true)}\n onTogglePalette={togglePalette}\n isPaletteOpen={isPaletteOpen}\n onPaste={onPaste}\n onSave={onSave}\n isSaving={isSaving}\n onExport={onExport}\n onExportImage={handleExportImage}\n onExportPdf={handleExportPdf}\n isExportingImage={isExportingImage}\n onShare={() => setIsShareDialogOpen(true)}\n />\n\n {/* Live wall-board freshness banner — renders only when the page has\n auto-refreshing widgets (e.g. the Live Bed Board) and not in edit mode. */}\n <LiveBoardBanner widgets={widgetsArray} isEditMode={isEditMode} />\n\n {/* Global Filters Bar */}\n {showFilters && <GlobalFiltersBar dashboardId={dashboardId} onFilterChange={handleFilterChange} collapsible />}\n\n {/* Page Tabs - always show in edit mode so user can add first page */}\n {showPageTabs && (isEditMode || pages.length > 0) && (\n <PageTabsManager\n pages={pages}\n activePageId={activePageId || pages[0]?.id}\n editable={isEditMode}\n onPageSelect={onPageChange || (() => {})}\n onPagesReorder={\n onPagesReorder\n ? (pageIds) => {\n // Convert string[] to DashboardPageTab[] for the callback\n const reorderedPages = pageIds.map((id) => pages.find((p) => p.id === id)!).filter(Boolean);\n onPagesReorder(reorderedPages);\n }\n : undefined\n }\n onPageCreate={onPageAdd}\n onPageRename={onPageRename}\n onPageDuplicate={onPageDuplicate}\n onPageDelete={onPageDelete}\n />\n )}\n\n {/* Main content area with palette and canvas */}\n <div className=\"flex flex-1 min-w-0 overflow-hidden\">\n {/* Widget Palette Sidebar */}\n {isEditMode && (\n <WidgetPalette\n isOpen={isPaletteOpen}\n onClose={() => setIsPaletteOpen(false)}\n onWidgetSelect={handlePaletteWidgetSelect}\n onDragStart={handlePaletteDragStart}\n onDragEnd={handlePaletteDragEnd}\n installedWidgets={installedWidgets}\n installedWidgetsLoading={installedWidgetsLoading}\n definitions={widgetCatalog}\n />\n )}\n\n {/* Canvas area */}\n <div\n ref={containerRef}\n className=\"flex-1 min-w-0 overflow-auto bg-bg-muted\"\n onDrop={handleCanvasDrop}\n onDragOver={handleCanvasDragOver}\n onClick={() => {\n if (isEditMode) {\n selectWidget(null);\n }\n }}\n style={{\n position: 'relative',\n border: isDraggingWidget ? '2px dashed var(--color-action-primary-bg)' : 'none',\n backgroundColor: isDraggingWidget ? 'var(--color-bg-hover)' : undefined,\n transition: 'border-color 0.2s, background-color 0.2s',\n }}\n >\n {/* Drop zone indicator */}\n {isDraggingWidget && (\n <div\n style={{\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n padding: 'var(--space-pagePadding)',\n backgroundColor: 'var(--color-bg-surface)',\n borderRadius: 'var(--radius-card)',\n boxShadow: 'var(--shadow-elevation-2)',\n textAlign: 'center',\n pointerEvents: 'none',\n zIndex: 100,\n }}\n >\n <p style={{ fontSize: 'var(--font-size-body-md)', color: 'var(--color-text-primary)', margin: 0 }}>\n Drop to add <strong>{dragWidgetType}</strong> widget\n </p>\n </div>\n )}\n\n <div\n ref={boardRef}\n className=\"min-h-full origin-top-left transition-transform\"\n style={{\n transform: `scale(${zoomLevel / 100})`,\n width: `${100 / (zoomLevel / 100)}%`,\n }}\n >\n {widgetsArray.length > 0 ? (\n <CrossFilterProvider\n enabled={enableCrossFilter}\n onCrossFilter={(_filters) => {\n // Cross-filter applied - widget queries can access filter values\n }}\n >\n <DashboardGrid\n widgets={widgetsArray}\n isEditMode={isEditMode}\n width={containerWidth}\n onLayoutChange={handleLayoutChange}\n onWidgetSelect={handleWidgetSelect}\n selectedWidgetId={selectedWidgetId}\n />\n </CrossFilterProvider>\n ) : (\n <div className=\"flex flex-col items-center justify-center min-h-[400px] p-8\">\n <div className=\"w-16 h-16 mb-4 flex items-center justify-center rounded-full bg-bg-surface\">\n <svg className=\"w-8 h-8 text-text-secondary\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\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 </div>\n <h3 className=\"text-lg font-medium text-text-primary mb-2\">No widgets yet</h3>\n <p className=\"text-sm text-text-secondary mb-4 text-center max-w-[300px]\">\n Add widgets to build your dashboard. Click the &quot;Add Widget&quot; button to get started.\n </p>\n {isEditMode && (\n <button\n type=\"button\"\n onClick={() => setIsAddDialogOpen(true)}\n className=\"\n inline-flex items-center gap-2\n px-4 py-2\n text-sm font-medium\n text-action-primary-fg\n bg-action-primary-bg\n hover:bg-action-primary-bgHover\n rounded-md\n transition-colors\n \"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n Add Widget\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Properties Panel */}\n <PropertiesPanel isOpen={configPanelOpen} onClose={closeConfigPanel} />\n\n {/* Add Widget Dialog */}\n <WidgetConfigDialog\n isOpen={isAddDialogOpen}\n onClose={() => {\n setIsAddDialogOpen(false);\n // Clear pending drop state when dialog is closed\n setPendingDropPosition(null);\n setPendingDropType(null);\n setPendingDropDefinition(null);\n }}\n onSave={handleAddWidget}\n preselectedType={pendingDropType || undefined}\n preselectedDefinition={pendingDropDefinition || undefined}\n dashboardId={dashboardId}\n installedWidgets={installedWidgets}\n />\n\n {/* Share Dialog */}\n <ShareDialog\n dashboardId={dashboardId}\n dashboardName={title || 'Dashboard'}\n isOpen={isShareDialogOpen}\n onClose={() => setIsShareDialogOpen(false)}\n />\n </div>\n );\n});\n\nexport default DashboardCanvas;\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardCanvas.js","names":[],"sources":["../../../../src/bigconsole/components/dashboard/DashboardCanvas.tsx"],"sourcesContent":["/**\n * DashboardCanvas Component\n *\n * Main canvas for dashboard with grid layout and widget rendering.\n * Phase 2: Added GlobalFiltersBar and PageTabsManager integration.\n * Phase 3: Added WidgetPalette sidebar for drag-and-drop widget creation.\n */\n\nimport { type FC, memo, useRef, useState, useCallback, useEffect, useMemo } from 'react';\nimport type { Layout } from 'react-grid-layout';\nimport type { Widget, WidgetType } from '../../types';\nimport { useDashboardStore, useWidgetStore } from '../../store';\nimport { useWidgetOperations } from '../../hooks/useWidgetOperations';\nimport { useInstalledWidgets } from '../../hooks/useInstalledWidgets';\nimport { useWidgetCatalog } from '../../hooks/useWidgetCatalog';\nimport { useDashboardImageExport } from '../../hooks/useDashboardImageExport';\nimport { useBigConsole } from '../../context';\nimport { DashboardGrid } from './DashboardGrid';\nimport { DashboardToolbar } from './DashboardToolbar';\nimport { GlobalFiltersBar } from './GlobalFiltersBar';\nimport { LiveBoardBanner } from './LiveBoardBanner';\nimport { PageTabsManager, type DashboardPageTab } from './PageTabsManager';\nimport { ShareDialog } from './ShareDialog';\nimport { WidgetPalette } from './WidgetPalette';\nimport { WidgetConfigDialog } from '../widgets/WidgetConfigDialog';\nimport { PropertiesPanel } from '../widgets/PropertiesPanel';\nimport { getWidgetDefinition, type WidgetDefinition } from '../widgets/WidgetRegistry';\n// Phase 2: Cross-filtering context\nimport { CrossFilterProvider } from '../../contexts';\n// Smart widget positioning\nimport { findNextAvailablePosition, calculatePositionFromDrop } from '../../utils/widgetPositioning';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DashboardCanvasProps {\n /** Dashboard ID */\n dashboardId: string;\n /** Page ID (for loading widgets) */\n pageId?: string;\n /** Dashboard title */\n title?: string;\n /** Callback to paste widget */\n onPaste?: () => void;\n /** Callback when dashboard is saved */\n onSave?: () => void;\n /** Whether save is in progress */\n isSaving?: boolean;\n /** Callback to export dashboard */\n onExport?: () => void;\n /** Dashboard pages for PageTabsManager */\n pages?: DashboardPageTab[];\n /** Active page ID */\n activePageId?: string;\n /** Callback when page changes */\n onPageChange?: (pageId: string) => void;\n /** Callback when pages are reordered */\n onPagesReorder?: (pages: DashboardPageTab[]) => void;\n /** Callback when page is added */\n onPageAdd?: () => void;\n /** Callback when page is renamed */\n onPageRename?: (pageId: string, newName: string) => void;\n /** Callback when page is duplicated */\n onPageDuplicate?: (pageId: string) => void;\n /** Callback when page is deleted */\n onPageDelete?: (pageId: string) => void;\n /** Whether to show global filters bar */\n showFilters?: boolean;\n /** Whether to show page tabs */\n showPageTabs?: boolean;\n /** Whether to enable cross-filtering (widget clicks update filters) */\n enableCrossFilter?: boolean;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const DashboardCanvas: FC<DashboardCanvasProps> = memo(function DashboardCanvas({\n dashboardId,\n pageId,\n title,\n onPaste,\n onSave,\n isSaving = false,\n onExport,\n pages = [],\n activePageId,\n onPageChange,\n onPagesReorder,\n onPageAdd,\n onPageRename,\n onPageDuplicate,\n onPageDelete,\n showFilters = true,\n showPageTabs = true,\n enableCrossFilter = true,\n}) {\n const containerRef = useRef<HTMLDivElement>(null);\n // Inner board element (the grid surface) — rasterized for PNG/PDF board-pack export.\n const boardRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState(1200);\n const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);\n const [isShareDialogOpen, setIsShareDialogOpen] = useState(false);\n const [isPaletteOpen, setIsPaletteOpen] = useState(false);\n const [isDraggingWidget, setIsDraggingWidget] = useState(false);\n const [dragWidgetType, setDragWidgetType] = useState<WidgetType | null>(null);\n // State for drag & drop widget creation (stores pending position and type)\n const [pendingDropPosition, setPendingDropPosition] = useState<{\n x: number;\n y: number;\n width: number;\n height: number;\n } | null>(null);\n const [pendingDropType, setPendingDropType] = useState<WidgetType | null>(null);\n // Stores the full WidgetDefinition for installed/store widgets dropped from the palette,\n // so the config dialog can use the store metadata instead of the generic 'custom' definition.\n const [pendingDropDefinition, setPendingDropDefinition] = useState<WidgetDefinition | null>(null);\n\n // Store state\n const isEditMode = useDashboardStore((state) => state.viewMode === 'edit');\n\n // Fetch installed widgets only in edit mode — the palette and add-widget dialog\n // are not usable in read-only view, so skip the request for viewer-only sessions.\n const { workspaceId, apiGatewayUrl, authToken } = useBigConsole();\n const { installedWidgets, loading: installedWidgetsLoading } = useInstalledWidgets({\n workspaceId,\n apiGatewayUrl,\n authToken,\n enabled: isEditMode,\n });\n // Built-in widget catalog from the backend (getWidgetTypes); falls back to the\n // bundled registry while loading or if the supergraph hasn't adopted it yet.\n const { definitions: widgetCatalog } = useWidgetCatalog({\n workspaceId,\n apiGatewayUrl,\n authToken,\n enabled: isEditMode,\n });\n const zoomLevel = useDashboardStore((state) => state.zoomLevel);\n const setGlobalFilterValues = useDashboardStore((state) => state.setGlobalFilterValues);\n\n // Handle filter changes - update store for widget access\n const handleFilterChange = useCallback(\n (filterValues: Record<string, unknown>) => {\n // Update global filter values in dashboard store\n setGlobalFilterValues(filterValues);\n\n // Widgets can now access filter values via useGlobalFilterValues() hook\n // When backend supports filter parameters, widget queries will include these values\n },\n [setGlobalFilterValues]\n );\n\n // Widget operations hook (connects to backend) - skipFetch since parent page fetches\n const { createWidget: createWidgetApi } = useWidgetOperations(pageId, dashboardId, { skipFetch: true });\n\n const widgetsMap = useWidgetStore((state) => state.widgets);\n // Filter widgets to only show widgets for the current page\n const widgetsArray = useMemo(() => {\n const allWidgets = Array.from(widgetsMap.values());\n if (!pageId) return allWidgets;\n return allWidgets.filter((widget) => widget.pageId === pageId);\n }, [widgetsMap, pageId]);\n const selectedWidgetId = useWidgetStore((state) => state.selectedWidgetId);\n const selectWidget = useWidgetStore((state) => state.selectWidget);\n const addWidgetToStore = useWidgetStore((state) => state.addWidget);\n const updateWidgetPosition = useWidgetStore((state) => state.updateWidgetPosition);\n const configPanelOpen = useWidgetStore((state) => state.configPanelOpen);\n const closeConfigPanel = useWidgetStore((state) => state.closeConfigPanel);\n\n // Handle resize\n useEffect(() => {\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.offsetWidth);\n }\n };\n\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, []);\n\n // Handle layout change\n const handleLayoutChange = useCallback(\n (layout: Layout[]) => {\n layout.forEach((item) => {\n updateWidgetPosition(item.i, {\n x: item.x,\n y: item.y,\n width: item.w,\n height: item.h,\n });\n });\n },\n [updateWidgetPosition]\n );\n\n // Handle widget select\n const handleWidgetSelect = useCallback(\n (widgetId: string) => {\n selectWidget(widgetId);\n },\n [selectWidget]\n );\n\n // Handle add widget - tries API first, falls back to local store\n const handleAddWidget = useCallback(\n async (widgetData: Partial<Widget>) => {\n // Get widget definition for default size; prefer the pending drop definition\n // which preserves installed/store widget metadata over the generic registry lookup.\n const definition = pendingDropDefinition || (widgetData.type ? getWidgetDefinition(widgetData.type) : null);\n const widgetSize = {\n width: definition?.defaultSize?.width ?? 4,\n height: definition?.defaultSize?.height ?? 4,\n };\n\n // Use pending drop position if available (from drag & drop), otherwise use smart placement\n let position: { x: number; y: number; width: number; height: number };\n if (pendingDropPosition) {\n position = pendingDropPosition;\n } else {\n // Use smart placement algorithm - horizontal first, then next row\n const { x, y } = findNextAvailablePosition(widgetsArray, widgetSize, { cols: 12 });\n position = {\n x,\n y,\n width: widgetSize.width,\n height: widgetSize.height,\n };\n }\n\n // Extract dataSinkId and parserId from widgetData (passed from WidgetConfigDialog)\n const extendedData = widgetData as Partial<Widget> & { dataSinkId?: string; parserId?: string };\n\n // Try to create via API first\n if (pageId) {\n const widget = await createWidgetApi({\n pageId,\n dashboardId,\n type: widgetData.type!,\n title: widgetData.title || 'Untitled Widget',\n description: widgetData.description,\n // v2.0: Renderer and template support\n renderer: widgetData.renderer,\n template: widgetData.template,\n config: widgetData.config || {},\n position,\n refreshInterval: widgetData.refreshInterval ?? undefined,\n // v2.0: Data source fields (DataSink → Parser → Widget)\n dataSinkId: extendedData.dataSinkId,\n parserId: extendedData.parserId,\n });\n\n if (widget) {\n selectWidget(widget.id);\n setIsAddDialogOpen(false);\n // Clear pending drop state\n setPendingDropPosition(null);\n setPendingDropType(null);\n setPendingDropDefinition(null);\n return;\n }\n }\n\n // Fallback to local store if API fails or no pageId\n const newWidget: Widget = {\n id: crypto.randomUUID(),\n dashboardId,\n pageId: pageId || 'local',\n type: widgetData.type!,\n title: widgetData.title || 'Untitled Widget',\n description: widgetData.description,\n // v2.0: Renderer and template support\n renderer: widgetData.renderer,\n template: widgetData.template,\n refreshInterval: widgetData.refreshInterval,\n config: widgetData.config || {},\n position,\n positionX: position.x,\n positionY: position.y,\n positionWidth: position.width,\n positionHeight: position.height,\n // v2.0: Data source fields (DataSink → Parser → Widget)\n dataSinkId: extendedData.dataSinkId,\n parserId: extendedData.parserId,\n translations: [],\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n\n addWidgetToStore(newWidget);\n selectWidget(newWidget.id);\n setIsAddDialogOpen(false);\n // Clear pending drop state\n setPendingDropPosition(null);\n setPendingDropType(null);\n setPendingDropDefinition(null);\n },\n [\n dashboardId,\n pageId,\n createWidgetApi,\n addWidgetToStore,\n selectWidget,\n widgetsArray,\n pendingDropPosition,\n pendingDropDefinition,\n ]\n );\n\n // Handle drag start from palette\n const handlePaletteDragStart = useCallback((type: WidgetType) => {\n setIsDraggingWidget(true);\n setDragWidgetType(type);\n }, []);\n\n // Handle drag end from palette\n const handlePaletteDragEnd = useCallback(() => {\n setIsDraggingWidget(false);\n setDragWidgetType(null);\n }, []);\n\n // Handle drop on canvas - opens config dialog instead of creating widget directly\n const handleCanvasDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n setIsDraggingWidget(false);\n setDragWidgetType(null);\n\n try {\n const data = e.dataTransfer.getData('application/json');\n if (!data) return;\n\n const widgetData = JSON.parse(data);\n const definition = getWidgetDefinition(widgetData.type);\n\n // If the dropped data includes defaultConfig (from WidgetPalette drag serialization),\n // reconstruct a full WidgetDefinition so installed/store widget identity is preserved.\n let droppedDefinition: WidgetDefinition | null = null;\n if (widgetData.defaultConfig && widgetData.category) {\n droppedDefinition = {\n ...definition,\n name: widgetData.name || definition.name,\n category: widgetData.category,\n defaultConfig: widgetData.defaultConfig,\n defaultSize: widgetData.defaultSize || definition.defaultSize,\n };\n }\n\n // Calculate drop position relative to canvas\n const canvasRect = containerRef.current?.getBoundingClientRect();\n if (!canvasRect) return;\n\n // Use utility to calculate grid position from drop coordinates\n const widgetSize = {\n width: definition.defaultSize.width,\n height: definition.defaultSize.height,\n };\n\n const { x: gridX, y: gridY } = calculatePositionFromDrop(\n e.clientX,\n e.clientY,\n canvasRect,\n containerWidth,\n widgetSize,\n { cols: 12 }\n );\n\n const position = {\n x: gridX,\n y: gridY,\n width: widgetSize.width,\n height: widgetSize.height,\n };\n\n // Store the drop position, type, and full definition, then open the config dialog\n setPendingDropPosition(position);\n setPendingDropType(widgetData.type as WidgetType);\n setPendingDropDefinition(droppedDefinition);\n setIsAddDialogOpen(true);\n } catch (error) {\n console.error('Failed to handle widget drop:', error);\n }\n },\n [containerWidth]\n );\n\n // Handle drag over to allow drop\n const handleCanvasDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n }, []);\n\n // Handle widget select from palette (quick add without drag)\n const handlePaletteWidgetSelect = useCallback(\n (type: WidgetType, paletteDefinition?: WidgetDefinition) => {\n const definition = paletteDefinition || getWidgetDefinition(type);\n handleAddWidget({\n type,\n title: definition.name,\n config: definition.defaultConfig,\n });\n setIsPaletteOpen(false);\n },\n [handleAddWidget]\n );\n\n // Toggle palette\n const togglePalette = useCallback(() => {\n setIsPaletteOpen((prev) => !prev);\n }, []);\n\n // Board-pack export (PNG + PDF) — rasterizes the inner board element.\n const {\n exportPNG,\n exportPDF,\n isExporting: isExportingImage,\n } = useDashboardImageExport({ containerRef: boardRef, name: title || 'dashboard' });\n const handleExportImage = useCallback(() => {\n void exportPNG();\n }, [exportPNG]);\n const handleExportPdf = useCallback(() => {\n void exportPDF();\n }, [exportPDF]);\n\n return (\n <div className=\"flex flex-col h-full min-w-0 overflow-hidden\">\n {/* Toolbar */}\n <DashboardToolbar\n dashboardId={dashboardId}\n title={title}\n onAddWidget={() => setIsAddDialogOpen(true)}\n onTogglePalette={togglePalette}\n isPaletteOpen={isPaletteOpen}\n onPaste={onPaste}\n onSave={onSave}\n isSaving={isSaving}\n onExport={onExport}\n onExportImage={handleExportImage}\n onExportPdf={handleExportPdf}\n isExportingImage={isExportingImage}\n onShare={() => setIsShareDialogOpen(true)}\n />\n\n {/* Live wall-board freshness banner — renders only when the page has\n auto-refreshing widgets (e.g. the Live Bed Board) and not in edit mode. */}\n <LiveBoardBanner widgets={widgetsArray} isEditMode={isEditMode} />\n\n {/* Global Filters Bar */}\n {showFilters && <GlobalFiltersBar dashboardId={dashboardId} onFilterChange={handleFilterChange} collapsible />}\n\n {/* Page Tabs - always show in edit mode so user can add first page */}\n {showPageTabs && (isEditMode || pages.length > 0) && (\n <PageTabsManager\n pages={pages}\n activePageId={activePageId || pages[0]?.id}\n editable={isEditMode}\n onPageSelect={onPageChange || (() => {})}\n onPagesReorder={\n onPagesReorder\n ? (pageIds) => {\n // Convert string[] to DashboardPageTab[] for the callback\n const reorderedPages = pageIds.map((id) => pages.find((p) => p.id === id)!).filter(Boolean);\n onPagesReorder(reorderedPages);\n }\n : undefined\n }\n onPageCreate={onPageAdd}\n onPageRename={onPageRename}\n onPageDuplicate={onPageDuplicate}\n onPageDelete={onPageDelete}\n />\n )}\n\n {/* Main content area with palette and canvas */}\n <div className=\"flex flex-1 min-w-0 overflow-hidden\">\n {/* Widget Palette Sidebar */}\n {isEditMode && (\n <WidgetPalette\n isOpen={isPaletteOpen}\n onClose={() => setIsPaletteOpen(false)}\n onWidgetSelect={handlePaletteWidgetSelect}\n onDragStart={handlePaletteDragStart}\n onDragEnd={handlePaletteDragEnd}\n installedWidgets={installedWidgets}\n installedWidgetsLoading={installedWidgetsLoading}\n definitions={widgetCatalog}\n />\n )}\n\n {/* Canvas area */}\n <div\n ref={containerRef}\n className=\"flex-1 min-w-0 overflow-auto bg-bg-sunken\"\n onDrop={handleCanvasDrop}\n onDragOver={handleCanvasDragOver}\n onClick={() => {\n if (isEditMode) {\n selectWidget(null);\n }\n }}\n style={{\n position: 'relative',\n border: isDraggingWidget ? '2px dashed var(--color-action-primary-bg)' : 'none',\n backgroundColor: isDraggingWidget ? 'var(--color-bg-hover)' : undefined,\n transition: 'border-color 0.2s, background-color 0.2s',\n }}\n >\n {/* Drop zone indicator */}\n {isDraggingWidget && (\n <div\n style={{\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n padding: 'var(--space-pagePadding)',\n backgroundColor: 'var(--color-bg-surface)',\n borderRadius: 'var(--radius-card)',\n boxShadow: 'var(--shadow-elevation-2)',\n textAlign: 'center',\n pointerEvents: 'none',\n zIndex: 100,\n }}\n >\n <p style={{ fontSize: 'var(--font-size-body-md)', color: 'var(--color-text-primary)', margin: 0 }}>\n Drop to add <strong>{dragWidgetType}</strong> widget\n </p>\n </div>\n )}\n\n <div\n ref={boardRef}\n className=\"min-h-full origin-top-left transition-transform\"\n style={{\n transform: `scale(${zoomLevel / 100})`,\n width: `${100 / (zoomLevel / 100)}%`,\n }}\n >\n {widgetsArray.length > 0 ? (\n <CrossFilterProvider\n enabled={enableCrossFilter}\n onCrossFilter={(_filters) => {\n // Cross-filter applied - widget queries can access filter values\n }}\n >\n <DashboardGrid\n widgets={widgetsArray}\n isEditMode={isEditMode}\n width={containerWidth}\n onLayoutChange={handleLayoutChange}\n onWidgetSelect={handleWidgetSelect}\n selectedWidgetId={selectedWidgetId}\n />\n </CrossFilterProvider>\n ) : (\n <div className=\"flex flex-col items-center justify-center min-h-[400px] p-8\">\n <div className=\"w-16 h-16 mb-4 flex items-center justify-center rounded-full bg-bg-surface\">\n <svg className=\"w-8 h-8 text-text-secondary\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\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 </div>\n <h3 className=\"text-lg font-medium text-text-primary mb-2\">No widgets yet</h3>\n <p className=\"text-sm text-text-secondary mb-4 text-center max-w-[300px]\">\n Add widgets to build your dashboard. Click the &quot;Add Widget&quot; button to get started.\n </p>\n {isEditMode && (\n <button\n type=\"button\"\n onClick={() => setIsAddDialogOpen(true)}\n className=\"\n inline-flex items-center gap-2\n px-4 py-2\n text-sm font-medium\n text-action-primary-fg\n bg-action-primary-bg\n hover:bg-action-primary-bgHover\n rounded-md\n transition-colors\n \"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n Add Widget\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Properties Panel */}\n <PropertiesPanel isOpen={configPanelOpen} onClose={closeConfigPanel} />\n\n {/* Add Widget Dialog */}\n <WidgetConfigDialog\n isOpen={isAddDialogOpen}\n onClose={() => {\n setIsAddDialogOpen(false);\n // Clear pending drop state when dialog is closed\n setPendingDropPosition(null);\n setPendingDropType(null);\n setPendingDropDefinition(null);\n }}\n onSave={handleAddWidget}\n preselectedType={pendingDropType || undefined}\n preselectedDefinition={pendingDropDefinition || undefined}\n dashboardId={dashboardId}\n installedWidgets={installedWidgets}\n />\n\n {/* Share Dialog */}\n <ShareDialog\n dashboardId={dashboardId}\n dashboardName={title || 'Dashboard'}\n isOpen={isShareDialogOpen}\n onClose={() => setIsShareDialogOpen(false)}\n />\n </div>\n );\n});\n\nexport default DashboardCanvas;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+EA,IAAa,IAA4C,EAAK,SAAyB,EACrF,gBACA,WACA,UACA,aACA,YACA,eAAW,IACX,cACA,WAAQ,EAAE,EACV,iBACA,kBACA,mBACA,cACA,kBACA,qBACA,kBACA,kBAAc,IACd,mBAAe,IACf,wBAAoB,MACnB;CACD,IAAM,IAAe,EAAuB,KAAK,EAE3C,IAAW,EAAuB,KAAK,EACvC,CAAC,GAAgB,MAAqB,EAAS,KAAK,EACpD,CAAC,IAAiB,KAAsB,EAAS,GAAM,EACvD,CAAC,IAAmB,KAAwB,EAAS,GAAM,EAC3D,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAkB,KAAuB,EAAS,GAAM,EACzD,CAAC,IAAgB,KAAqB,EAA4B,KAAK,EAEvE,CAAC,GAAqB,KAA0B,EAK5C,KAAK,EACT,CAAC,GAAiB,KAAsB,EAA4B,KAAK,EAGzE,CAAC,GAAuB,KAA4B,EAAkC,KAAK,EAG3F,IAAa,GAAmB,MAAU,EAAM,aAAa,OAAO,EAIpE,EAAE,gBAAa,kBAAe,iBAAc,GAAe,EAC3D,EAAE,qBAAkB,SAAS,OAA4B,EAAoB;EACjF;EACA;EACA;EACA,SAAS;EACV,CAAC,EAGI,EAAE,aAAa,OAAkB,EAAiB;EACtD;EACA;EACA;EACA,SAAS;EACV,CAAC,EACI,IAAY,GAAmB,MAAU,EAAM,UAAU,EACzD,IAAwB,GAAmB,MAAU,EAAM,sBAAsB,EAGjF,KAAqB,GACxB,MAA0C;AAEzC,IAAsB,EAAa;IAKrC,CAAC,EAAsB,CACxB,EAGK,EAAE,cAAc,MAAoB,EAAoB,GAAQ,GAAa,EAAE,WAAW,IAAM,CAAC,EAEjG,IAAa,GAAgB,MAAU,EAAM,QAAQ,EAErD,IAAe,SAAc;EACjC,IAAM,IAAa,MAAM,KAAK,EAAW,QAAQ,CAAC;AAElD,SADK,IACE,EAAW,QAAQ,MAAW,EAAO,WAAW,EAAO,GAD1C;IAEnB,CAAC,GAAY,EAAO,CAAC,EAClB,KAAmB,GAAgB,MAAU,EAAM,iBAAiB,EACpE,IAAe,GAAgB,MAAU,EAAM,aAAa,EAC5D,IAAmB,GAAgB,MAAU,EAAM,UAAU,EAC7D,IAAuB,GAAgB,MAAU,EAAM,qBAAqB,EAC5E,KAAkB,GAAgB,MAAU,EAAM,gBAAgB,EAClE,KAAmB,GAAgB,MAAU,EAAM,iBAAiB;AAG1E,UAAgB;EACd,IAAM,UAAoB;AACxB,GAAI,EAAa,WACf,GAAkB,EAAa,QAAQ,YAAY;;AAMvD,SAFA,GAAa,EACb,OAAO,iBAAiB,UAAU,EAAY,QACjC,OAAO,oBAAoB,UAAU,EAAY;IAC7D,EAAE,CAAC;CAGN,IAAM,KAAqB,GACxB,MAAqB;AACpB,IAAO,SAAS,MAAS;AACvB,KAAqB,EAAK,GAAG;IAC3B,GAAG,EAAK;IACR,GAAG,EAAK;IACR,OAAO,EAAK;IACZ,QAAQ,EAAK;IACd,CAAC;IACF;IAEJ,CAAC,EAAqB,CACvB,EAGK,KAAqB,GACxB,MAAqB;AACpB,IAAa,EAAS;IAExB,CAAC,EAAa,CACf,EAGK,IAAkB,EACtB,OAAO,MAAgC;EAGrC,IAAM,IAAa,MAA0B,EAAW,OAAO,EAAoB,EAAW,KAAK,GAAG,OAChG,IAAa;GACjB,OAAO,GAAY,aAAa,SAAS;GACzC,QAAQ,GAAY,aAAa,UAAU;GAC5C,EAGG;AACJ,MAAI,EACF,KAAW;OACN;GAEL,IAAM,EAAE,MAAG,SAAM,GAA0B,GAAc,GAAY,EAAE,MAAM,IAAI,CAAC;AAClF,OAAW;IACT;IACA;IACA,OAAO,EAAW;IAClB,QAAQ,EAAW;IACpB;;EAIH,IAAM,IAAe;AAGrB,MAAI,GAAQ;GACV,IAAM,IAAS,MAAM,EAAgB;IACnC;IACA;IACA,MAAM,EAAW;IACjB,OAAO,EAAW,SAAS;IAC3B,aAAa,EAAW;IAExB,UAAU,EAAW;IACrB,UAAU,EAAW;IACrB,QAAQ,EAAW,UAAU,EAAE;IAC/B;IACA,iBAAiB,EAAW,mBAAmB,KAAA;IAE/C,YAAY,EAAa;IACzB,UAAU,EAAa;IACxB,CAAC;AAEF,OAAI,GAAQ;AAMV,IALA,EAAa,EAAO,GAAG,EACvB,EAAmB,GAAM,EAEzB,EAAuB,KAAK,EAC5B,EAAmB,KAAK,EACxB,EAAyB,KAAK;AAC9B;;;EAKJ,IAAM,IAAoB;GACxB,IAAI,OAAO,YAAY;GACvB;GACA,QAAQ,KAAU;GAClB,MAAM,EAAW;GACjB,OAAO,EAAW,SAAS;GAC3B,aAAa,EAAW;GAExB,UAAU,EAAW;GACrB,UAAU,EAAW;GACrB,iBAAiB,EAAW;GAC5B,QAAQ,EAAW,UAAU,EAAE;GAC/B;GACA,WAAW,EAAS;GACpB,WAAW,EAAS;GACpB,eAAe,EAAS;GACxB,gBAAgB,EAAS;GAEzB,YAAY,EAAa;GACzB,UAAU,EAAa;GACvB,cAAc,EAAE;GAChB,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,4BAAW,IAAI,MAAM,EAAC,aAAa;GACpC;AAQD,EANA,EAAiB,EAAU,EAC3B,EAAa,EAAU,GAAG,EAC1B,EAAmB,GAAM,EAEzB,EAAuB,KAAK,EAC5B,EAAmB,KAAK,EACxB,EAAyB,KAAK;IAEhC;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF,EAGK,KAAyB,GAAa,MAAqB;AAE/D,EADA,EAAoB,GAAK,EACzB,EAAkB,EAAK;IACtB,EAAE,CAAC,EAGA,KAAuB,QAAkB;AAE7C,EADA,EAAoB,GAAM,EAC1B,EAAkB,KAAK;IACtB,EAAE,CAAC,EAGA,KAAmB,GACtB,MAAuB;AAGtB,EAFA,EAAE,gBAAgB,EAClB,EAAoB,GAAM,EAC1B,EAAkB,KAAK;AAEvB,MAAI;GACF,IAAM,IAAO,EAAE,aAAa,QAAQ,mBAAmB;AACvD,OAAI,CAAC,EAAM;GAEX,IAAM,IAAa,KAAK,MAAM,EAAK,EAC7B,IAAa,EAAoB,EAAW,KAAK,EAInD,IAA6C;AACjD,GAAI,EAAW,iBAAiB,EAAW,aACzC,IAAoB;IAClB,GAAG;IACH,MAAM,EAAW,QAAQ,EAAW;IACpC,UAAU,EAAW;IACrB,eAAe,EAAW;IAC1B,aAAa,EAAW,eAAe,EAAW;IACnD;GAIH,IAAM,IAAa,EAAa,SAAS,uBAAuB;AAChE,OAAI,CAAC,EAAY;GAGjB,IAAM,IAAa;IACjB,OAAO,EAAW,YAAY;IAC9B,QAAQ,EAAW,YAAY;IAChC,EAEK,EAAE,GAAG,GAAO,GAAG,MAAU,GAC7B,EAAE,SACF,EAAE,SACF,GACA,GACA,GACA,EAAE,MAAM,IAAI,CACb;AAaD,GAHA,EARiB;IACf,GAAG;IACH,GAAG;IACH,OAAO,EAAW;IAClB,QAAQ,EAAW;IACpB,CAG+B,EAChC,EAAmB,EAAW,KAAmB,EACjD,EAAyB,EAAkB,EAC3C,EAAmB,GAAK;WACjB,GAAO;AACd,WAAQ,MAAM,iCAAiC,EAAM;;IAGzD,CAAC,EAAe,CACjB,EAGK,KAAuB,GAAa,MAAuB;AAE/D,EADA,EAAE,gBAAgB,EAClB,EAAE,aAAa,aAAa;IAC3B,EAAE,CAAC,EAGA,KAA4B,GAC/B,GAAkB,MAAyC;EAC1D,IAAM,IAAa,KAAqB,EAAoB,EAAK;AAMjE,EALA,EAAgB;GACd;GACA,OAAO,EAAW;GAClB,QAAQ,EAAW;GACpB,CAAC,EACF,EAAiB,GAAM;IAEzB,CAAC,EAAgB,CAClB,EAGK,KAAgB,QAAkB;AACtC,KAAkB,MAAS,CAAC,EAAK;IAChC,EAAE,CAAC,EAGA,EACJ,cACA,cACA,aAAa,OACX,EAAwB;EAAE,cAAc;EAAU,MAAM,KAAS;EAAa,CAAC;AAQnF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,IAAD;IACe;IACN;IACP,mBAAmB,EAAmB,GAAK;IAC3C,iBAAiB;IACF;IACN;IACD;IACE;IACA;IACV,eApBoB,QAAkB;AACrC,QAAW;OACf,CAAC,EAAU,CAAC;IAmBT,aAlBkB,QAAkB;AACnC,QAAW;OACf,CAAC,EAAU,CAAC;IAiBS;IAClB,eAAe,EAAqB,GAAK;IACzC,CAAA;GAIF,kBAAC,IAAD;IAAiB,SAAS;IAA0B;IAAc,CAAA;GAGjE,MAAe,kBAAC,IAAD;IAA+B;IAAa,gBAAgB;IAAoB,aAAA;IAAc,CAAA;GAG7G,OAAiB,KAAc,EAAM,SAAS,MAC7C,kBAAC,IAAD;IACS;IACP,cAAc,KAAgB,EAAM,IAAI;IACxC,UAAU;IACV,cAAc,aAAuB;IACrC,gBACE,KACK,MAAY;AAGX,OADuB,EAAQ,KAAK,MAAO,EAAM,MAAM,MAAM,EAAE,OAAO,EAAG,CAAE,CAAC,OAAO,QAAQ,CAC7D;QAEhC,KAAA;IAEN,cAAc;IACA;IACG;IACH;IACd,CAAA;GAIJ,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEG,KACC,kBAAC,IAAD;KACE,QAAQ;KACR,eAAe,EAAiB,GAAM;KACtC,gBAAgB;KAChB,aAAa;KACb,WAAW;KACO;KACO;KACzB,aAAa;KACb,CAAA,EAIJ,kBAAC,OAAD;KACE,KAAK;KACL,WAAU;KACV,QAAQ;KACR,YAAY;KACZ,eAAe;AACb,MAAI,KACF,EAAa,KAAK;;KAGtB,OAAO;MACL,UAAU;MACV,QAAQ,IAAmB,8CAA8C;MACzE,iBAAiB,IAAmB,0BAA0B,KAAA;MAC9D,YAAY;MACb;eAfH,CAkBG,KACC,kBAAC,OAAD;MACE,OAAO;OACL,UAAU;OACV,KAAK;OACL,MAAM;OACN,WAAW;OACX,SAAS;OACT,iBAAiB;OACjB,cAAc;OACd,WAAW;OACX,WAAW;OACX,eAAe;OACf,QAAQ;OACT;gBAED,kBAAC,KAAD;OAAG,OAAO;QAAE,UAAU;QAA4B,OAAO;QAA6B,QAAQ;QAAG;iBAAjG;QAAmG;QACrF,kBAAC,UAAD,EAAA,UAAS,IAAwB,CAAA;;QAC3C;;MACA,CAAA,EAGR,kBAAC,OAAD;MACE,KAAK;MACL,WAAU;MACV,OAAO;OACL,WAAW,SAAS,IAAY,IAAI;OACpC,OAAO,GAAG,OAAO,IAAY,KAAK;OACnC;gBAEA,EAAa,SAAS,IACrB,kBAAC,GAAD;OACE,SAAS;OACT,gBAAgB,MAAa;iBAI7B,kBAAC,GAAD;QACE,SAAS;QACG;QACZ,OAAO;QACP,gBAAgB;QAChB,gBAAgB;QACE;QAClB,CAAA;OACkB,CAAA,GAEtB,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UAAK,WAAU;UAA8B,MAAK;UAAO,QAAO;UAAe,SAAQ;oBACrF,kBAAC,QAAD;WACE,eAAc;WACd,gBAAe;WACf,aAAa;WACb,GAAE;WACF,CAAA;UACE,CAAA;SACF,CAAA;QACN,kBAAC,MAAD;SAAI,WAAU;mBAA6C;SAAmB,CAAA;QAC9E,kBAAC,KAAD;SAAG,WAAU;mBAA6D;SAEtE,CAAA;QACH,KACC,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAmB,GAAK;SACvC,WAAU;mBAHZ,CAcE,kBAAC,OAAD;UAAK,WAAU;UAAU,MAAK;UAAO,QAAO;UAAe,SAAQ;oBACjE,kBAAC,QAAD;WAAM,eAAc;WAAQ,gBAAe;WAAQ,aAAa;WAAG,GAAE;WAAmB,CAAA;UACpF,CAAA,EAAA,aAEC;;QAEP;;MAEJ,CAAA,CACF;OACF;;GAGN,kBAAC,IAAD;IAAiB,QAAQ;IAAiB,SAAS;IAAoB,CAAA;GAGvE,kBAAC,IAAD;IACE,QAAQ;IACR,eAAe;AAKb,KAJA,EAAmB,GAAM,EAEzB,EAAuB,KAAK,EAC5B,EAAmB,KAAK,EACxB,EAAyB,KAAK;;IAEhC,QAAQ;IACR,iBAAiB,KAAmB,KAAA;IACpC,uBAAuB,KAAyB,KAAA;IACnC;IACK;IAClB,CAAA;GAGF,kBAAC,IAAD;IACe;IACb,eAAe,KAAS;IACxB,QAAQ;IACR,eAAe,EAAqB,GAAM;IAC1C,CAAA;GACE;;EAER"}