@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.
Files changed (247) hide show
  1. package/dist/bigconsole/components/DrilldownDashboardRenderer.js +118 -106
  2. package/dist/bigconsole/components/DrilldownDashboardRenderer.js.map +1 -1
  3. package/dist/bigconsole/components/DrilldownModal.js +54 -50
  4. package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
  5. package/dist/bigconsole/components/builder/BuilderCanvas.js +2 -2
  6. package/dist/bigconsole/components/builder/BuilderCanvas.js.map +1 -1
  7. package/dist/bigconsole/components/builder/BuilderTopbar.js +3 -3
  8. package/dist/bigconsole/components/builder/BuilderTopbar.js.map +1 -1
  9. package/dist/bigconsole/components/builder/inspector/AdvancedSection.js +24 -25
  10. package/dist/bigconsole/components/builder/inspector/AdvancedSection.js.map +1 -1
  11. package/dist/bigconsole/components/builder/inspector/AppearanceSection.js +40 -29
  12. package/dist/bigconsole/components/builder/inspector/AppearanceSection.js.map +1 -1
  13. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +135 -97
  14. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
  15. package/dist/bigconsole/components/builder/inspector/GeneralSection.js +58 -44
  16. package/dist/bigconsole/components/builder/inspector/GeneralSection.js.map +1 -1
  17. package/dist/bigconsole/components/common/Section.js +70 -0
  18. package/dist/bigconsole/components/common/Section.js.map +1 -0
  19. package/dist/bigconsole/components/common/index.js +2 -0
  20. package/dist/bigconsole/components/common/sectionStyles.js +42 -0
  21. package/dist/bigconsole/components/common/sectionStyles.js.map +1 -0
  22. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +209 -193
  23. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  24. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +213 -231
  25. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  26. package/dist/bigconsole/components/dashboard/DashboardGrid.js +12 -18
  27. package/dist/bigconsole/components/dashboard/DashboardGrid.js.map +1 -1
  28. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +109 -102
  29. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  30. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +81 -70
  31. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
  32. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js +125 -159
  33. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js.map +1 -1
  34. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +25 -23
  35. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
  36. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +3 -3
  37. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
  38. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +5 -3
  39. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
  40. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +170 -284
  41. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  42. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +147 -151
  43. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  44. package/dist/bigconsole/components/dashboard/LiveBoardBanner.js +45 -53
  45. package/dist/bigconsole/components/dashboard/LiveBoardBanner.js.map +1 -1
  46. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +157 -148
  47. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
  48. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +17 -8
  49. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
  50. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +101 -95
  51. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
  52. package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js +20 -18
  53. package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js.map +1 -1
  54. package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js +26 -58
  55. package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js.map +1 -1
  56. package/dist/bigconsole/components/dashboard/WidgetPalette.js +307 -231
  57. package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
  58. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +29 -29
  59. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  60. package/dist/bigconsole/components/datasink/DataSinkCard.js +78 -79
  61. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  62. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +33 -34
  63. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
  64. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +79 -56
  65. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  66. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +75 -65
  67. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  68. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +1 -1
  69. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
  70. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +20 -19
  71. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
  72. package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js +127 -171
  73. package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js.map +1 -1
  74. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +263 -243
  75. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  76. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +65 -66
  77. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
  78. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +121 -127
  79. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
  80. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +33 -26
  81. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  82. package/dist/bigconsole/components/datasink/SetupStateBadge.js +3 -3
  83. package/dist/bigconsole/components/datasink/SetupStateBadge.js.map +1 -1
  84. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +95 -95
  85. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
  86. package/dist/bigconsole/components/parser/DataSinkSelector.js +154 -123
  87. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  88. package/dist/bigconsole/components/parser/ExpressionEditor.js +3 -3
  89. package/dist/bigconsole/components/parser/ExpressionEditor.js.map +1 -1
  90. package/dist/bigconsole/components/parser/ImportParserDialog.js +235 -275
  91. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  92. package/dist/bigconsole/components/parser/ParserCard.js +133 -114
  93. package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
  94. package/dist/bigconsole/components/parser/ParserSelector.js +191 -174
  95. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  96. package/dist/bigconsole/components/parser/ParserStatusBadge.js +2 -2
  97. package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
  98. package/dist/bigconsole/components/parser/ParserTypeBadge.js +4 -4
  99. package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
  100. package/dist/bigconsole/components/pipeline/PipelineCard.js +134 -89
  101. package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
  102. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +77 -64
  103. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
  104. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +7 -10
  105. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
  106. package/dist/bigconsole/components/preview/AiPreviewContent.js +31 -32
  107. package/dist/bigconsole/components/preview/AiPreviewContent.js.map +1 -1
  108. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +152 -106
  109. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
  110. package/dist/bigconsole/components/preview/AiPreviewPanel.js +193 -152
  111. package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
  112. package/dist/bigconsole/components/preview/previewShared.js +41 -23
  113. package/dist/bigconsole/components/preview/previewShared.js.map +1 -1
  114. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +342 -308
  115. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  116. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +262 -238
  117. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  118. package/dist/bigconsole/components/widgets/PropertiesPanel.js +783 -867
  119. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  120. package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js +7 -5
  121. package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js.map +1 -1
  122. package/dist/bigconsole/components/widgets/WidgetHeader.js +7 -8
  123. package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
  124. package/dist/bigconsole/components/widgets/WidgetRegistry.js +4 -4
  125. package/dist/bigconsole/components/widgets/WidgetRegistry.js.map +1 -1
  126. package/dist/bigconsole/components/widgets/WidgetWrapper.js +8 -7
  127. package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
  128. package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js +1 -1
  129. package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js.map +1 -1
  130. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +2 -2
  131. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  132. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +11 -5
  133. package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
  134. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +19 -15
  135. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  136. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +154 -102
  137. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
  138. package/dist/bigconsole/components/widgets/gauge/CircularGauge.js +36 -32
  139. package/dist/bigconsole/components/widgets/gauge/CircularGauge.js.map +1 -1
  140. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +85 -60
  141. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
  142. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +64 -35
  143. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
  144. package/dist/bigconsole/components/widgets/gauge/LinearGauge.js +46 -45
  145. package/dist/bigconsole/components/widgets/gauge/LinearGauge.js.map +1 -1
  146. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +35 -24
  147. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
  148. package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js +2 -2
  149. package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js.map +1 -1
  150. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +4 -4
  151. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  152. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +153 -90
  153. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
  154. package/dist/bigconsole/components/widgets/list/ListConfig.js +8 -2
  155. package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
  156. package/dist/bigconsole/components/widgets/list/ListItem.js +1 -1
  157. package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
  158. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +1 -1
  159. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
  160. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +14 -4
  161. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
  162. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +112 -89
  163. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
  164. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +21 -13
  165. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
  166. package/dist/bigconsole/components/widgets/metric-card/index.js +4 -4
  167. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +3 -3
  168. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  169. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +34 -25
  170. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  171. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +129 -114
  172. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
  173. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +3 -3
  174. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
  175. package/dist/bigconsole/components/widgets/states/EmptyState.js +6 -4
  176. package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
  177. package/dist/bigconsole/components/widgets/states/ErrorState.js +7 -5
  178. package/dist/bigconsole/components/widgets/states/ErrorState.js.map +1 -1
  179. package/dist/bigconsole/components/widgets/states/LoadingState.js +5 -4
  180. package/dist/bigconsole/components/widgets/states/LoadingState.js.map +1 -1
  181. package/dist/bigconsole/components/widgets/table/TableConfig.js +10 -4
  182. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  183. package/dist/bigconsole/components/widgets/table/TableHeader.js +1 -1
  184. package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
  185. package/dist/bigconsole/components/widgets/table/TableWidget.js +1 -1
  186. package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
  187. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +1 -1
  188. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
  189. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +3 -3
  190. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
  191. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +2 -2
  192. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -1
  193. package/dist/bigconsole/components/widgets/utils/targetProgress.js +13 -0
  194. package/dist/bigconsole/components/widgets/utils/targetProgress.js.map +1 -0
  195. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +112 -85
  196. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
  197. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +28 -20
  198. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  199. package/dist/bigconsole/components/workflow/WorkflowCard.js +92 -77
  200. package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
  201. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +70 -51
  202. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
  203. package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js +16 -17
  204. package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js.map +1 -1
  205. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +6 -4
  206. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
  207. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +360 -338
  208. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  209. package/dist/bigconsole/hooks/useModalFocusTrap.js +53 -0
  210. package/dist/bigconsole/hooks/useModalFocusTrap.js.map +1 -0
  211. package/dist/bigconsole/pages/DashboardBuilderPage.js +209 -203
  212. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  213. package/dist/bigconsole/pages/DashboardViewPage.js +126 -120
  214. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  215. package/dist/bigconsole/pages/DashboardsPage.js +838 -800
  216. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  217. package/dist/bigconsole/pages/DataParsersPage.js +263 -315
  218. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  219. package/dist/bigconsole/pages/DataSinkBuilderPage.js +301 -341
  220. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  221. package/dist/bigconsole/pages/DataSinkViewPage.js +346 -339
  222. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  223. package/dist/bigconsole/pages/DataSinksPage.js +356 -458
  224. package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
  225. package/dist/bigconsole/pages/DataSourcesPage.js +7 -2
  226. package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
  227. package/dist/bigconsole/pages/HomePage.js +186 -193
  228. package/dist/bigconsole/pages/HomePage.js.map +1 -1
  229. package/dist/bigconsole/pages/InsightsPage.js +887 -740
  230. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  231. package/dist/bigconsole/pages/ParserBuilderPage.js +679 -637
  232. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  233. package/dist/bigconsole/pages/ParserViewPage.js +368 -342
  234. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  235. package/dist/bigconsole/pages/PipelineBuilderPage.js +537 -444
  236. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  237. package/dist/bigconsole/pages/PipelineViewPage.js +412 -377
  238. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  239. package/dist/bigconsole/pages/PipelinesPage.js +248 -298
  240. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  241. package/dist/bigconsole/pages/WidgetDemoPage.js +251 -153
  242. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  243. package/dist/bigconsole/pages/WorkflowViewPage.js +381 -371
  244. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  245. package/dist/bigconsole/pages/WorkflowsPage.js +171 -286
  246. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  247. package/package.json +1 -1
@@ -1,191 +1,232 @@
1
- import { useBigConsoleNavigate as e } from "../../context/BigConsoleContext.js";
1
+ import { Section as e } from "../common/Section.js";
2
+ import "../common/index.js";
3
+ import { useBigConsoleNavigate as t } from "../../context/BigConsoleContext.js";
2
4
  import "../../context/index.js";
3
- import { PREVIEW_STEPS as t, useAssistantRunStore as n } from "../../assistant/assistantRunStore.js";
4
- import { StepRail as r, formatAgo as i, useAssistantSidebarWidth as a } from "./previewShared.js";
5
- import { DashboardContent as o, DataSinkContent as s, ParserContent as c, WidgetsContent as l } from "./AiPreviewContent.js";
6
- import { useEffect as u, useState as d } from "react";
7
- import { ArrowUpRight as f, Loader2 as p, Sparkles as m, X as h } from "lucide-react";
8
- import { useI18n as g } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
9
- import { Button as _, Tabs as v, TabsContent as y, TabsList as b, TabsTrigger as x } from "@burdenoff/fe-libs/ui";
10
- import { jsx as S, jsxs as C } from "react/jsx-runtime";
5
+ import { PREVIEW_STEPS as n, useAssistantRunStore as r } from "../../assistant/assistantRunStore.js";
6
+ import { PREVIEW_CHROME_DIVIDER as i, PREVIEW_PANEL_SHELL as a, StepRail as o, formatAgo as s, useAssistantSidebarWidth as c } from "./previewShared.js";
7
+ import { DashboardContent as l, DataSinkContent as u, ParserContent as d, WidgetsContent as f } from "./AiPreviewContent.js";
8
+ import { useEffect as p, useState as m } from "react";
9
+ import { AlertCircle as h, ArrowUpRight as g, Loader2 as _, Sparkles as v, X as y } from "lucide-react";
10
+ import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
+ import { Button as x, Tabs as S, TabsContent as C, TabsList as w, TabsTrigger as T } from "@burdenoff/fe-libs/ui";
12
+ import { jsx as E, jsxs as D } from "react/jsx-runtime";
11
13
  //#region src/bigconsole/components/preview/AiPreviewPanel.tsx
12
- function w({ label: e, onOpen: t }) {
13
- let { t: n } = g();
14
- return /* @__PURE__ */ C("div", {
15
- className: "mb-2 flex items-center justify-between gap-2",
16
- children: [/* @__PURE__ */ S("span", {
17
- className: "text-xs font-semibold uppercase tracking-wide text-text-muted",
18
- children: e
19
- }), t ? /* @__PURE__ */ C(_, {
20
- size: "sm",
21
- variant: "outline",
22
- onClick: t,
23
- "data-testid": "ai-preview-open-entity",
24
- children: [n("bigconsole.widget.aiPreview.open", "Open"), /* @__PURE__ */ S(f, { className: "ml-1 size-3.5" })]
25
- }) : null]
14
+ function O({ onOpen: e }) {
15
+ let { t } = b();
16
+ return /* @__PURE__ */ D(x, {
17
+ size: "sm",
18
+ variant: "outline",
19
+ onClick: e,
20
+ "data-testid": "ai-preview-open-entity",
21
+ children: [t("bigconsole.widget.aiPreview.open", "Open"), /* @__PURE__ */ E(g, { className: "ml-1 size-3.5" })]
26
22
  });
27
23
  }
28
- function T() {
29
- let { t: f } = g(), T = e(), E = n((e) => e.isRunning), D = n((e) => e.previewOpen), O = n((e) => e.hasRun), k = n((e) => e.steps), A = n((e) => e.entityIds), j = n((e) => e.caption), M = n((e) => e.error), N = n((e) => e.updatedAt), P = n((e) => e.openPreview), F = n((e) => e.closePreview), I = n((e) => e.setRichMounted);
30
- u(() => (I(!0), () => I(!1)), [I]);
31
- let [L, R] = d("datasink"), [z, B] = d(() => Date.now()), V = A.dashboard;
32
- u(() => {
33
- if (!E) return;
34
- let e = window.setInterval(() => B(Date.now()), 1e3);
24
+ function k() {
25
+ let { t: g } = b(), k = t(), A = r((e) => e.isRunning), j = r((e) => e.previewOpen), M = r((e) => e.hasRun), N = r((e) => e.steps), P = r((e) => e.entityIds), F = r((e) => e.caption), I = r((e) => e.error), L = r((e) => e.updatedAt), R = r((e) => e.openPreview), z = r((e) => e.closePreview), B = r((e) => e.setRichMounted);
26
+ p(() => (B(!0), () => B(!1)), [B]);
27
+ let [V, H] = m("datasink"), [U, W] = m(() => Date.now()), G = P.dashboard;
28
+ p(() => {
29
+ if (!A) return;
30
+ let e = window.setInterval(() => W(Date.now()), 1e3);
35
31
  return () => window.clearInterval(e);
36
- }, [E]), u(() => {
37
- let e = t.filter((e) => k[e] === "done"), n = e[e.length - 1];
38
- if (n) {
39
- R(n);
32
+ }, [A]), p(() => {
33
+ let e = n.filter((e) => N[e] === "done"), t = e[e.length - 1];
34
+ if (t) {
35
+ H(t);
40
36
  return;
41
37
  }
42
- let r = t.find((e) => k[e] === "running");
43
- r && R(r);
44
- }, [k]);
45
- let H = N ? Math.max(0, Math.floor((z - N) / 1e3)) : 0, U = a();
46
- return O ? D ? /* @__PURE__ */ C("section", {
38
+ let r = n.find((e) => N[e] === "running");
39
+ r && H(r);
40
+ }, [N]);
41
+ let K = L ? Math.max(0, Math.floor((U - L) / 1e3)) : 0, q = c();
42
+ return M ? j ? /* @__PURE__ */ D("section", {
47
43
  "data-testid": "ai-preview-panel",
48
- "aria-label": f("bigconsole.widget.aiPreview.ariaLabel", "AI preview"),
49
- style: { marginRight: U ? U + 16 : void 0 },
50
- className: "mx-4 mt-3 overflow-hidden rounded-lg border border-border-default bg-bg-sunken shadow-sm md:mx-6",
44
+ "aria-label": g("bigconsole.widget.aiPreview.ariaLabel", "AI preview"),
45
+ style: { marginRight: q ? q + 16 : void 0 },
46
+ className: `${a} mx-4 mt-3 md:mx-6`,
51
47
  children: [
52
- /* @__PURE__ */ C("div", {
53
- className: "flex items-center justify-between gap-3 border-b border-border-subtle bg-bg-surface px-3 py-2",
54
- children: [/* @__PURE__ */ C("div", {
55
- className: "flex min-w-0 items-center gap-2",
56
- children: [
57
- /* @__PURE__ */ S(m, { className: "size-4 shrink-0 text-action-primary-bg" }),
58
- /* @__PURE__ */ S("h2", {
59
- className: "truncate text-sm font-semibold text-text-primary",
60
- children: f("bigconsole.widget.aiPreview.title", "AI Preview")
61
- }),
62
- E ? /* @__PURE__ */ C("span", {
63
- className: "inline-flex items-center gap-1.5 rounded-full bg-status-success-bg px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-status-success-text",
64
- "data-testid": "ai-preview-live",
65
- children: [/* @__PURE__ */ C("span", {
66
- className: "relative flex size-2",
67
- children: [/* @__PURE__ */ S("span", { className: "absolute inline-flex size-full animate-ping rounded-full bg-status-success-text opacity-75" }), /* @__PURE__ */ S("span", { className: "relative inline-flex size-2 rounded-full bg-status-success-text" })]
68
- }), f("bigconsole.widget.aiPreview.live", "Live")]
69
- }) : null,
70
- /* @__PURE__ */ C("span", {
71
- className: "truncate text-xs text-text-muted",
72
- "data-testid": "ai-preview-ago",
73
- children: [
74
- E ? j || f("bigconsole.widget.aiPreview.working", "Working…") : M ? f("bigconsole.widget.aiPreview.stopped", "Stopped") : f("bigconsole.widget.aiPreview.done", "Done"),
75
- " ",
76
- ",
77
- f("bigconsole.widget.aiPreview.updated", "updated"),
78
- " ",
79
- i(H)
80
- ]
81
- })
82
- ]
83
- }), /* @__PURE__ */ S(_, {
48
+ /* @__PURE__ */ D("div", {
49
+ className: `flex items-start justify-between gap-control-gap bg-bg-surface px-3 py-2 ${i}`,
50
+ children: [/* @__PURE__ */ D("div", {
51
+ className: "flex min-w-0 flex-col gap-0.5",
52
+ children: [/* @__PURE__ */ D("div", {
53
+ className: "flex min-w-0 flex-wrap items-center gap-2",
54
+ children: [
55
+ /* @__PURE__ */ E(v, { className: "size-4 shrink-0 text-action-primary-bg" }),
56
+ /* @__PURE__ */ E("h2", {
57
+ className: "text-sm font-semibold text-text-primary",
58
+ children: g("bigconsole.widget.aiPreview.title", "AI Preview")
59
+ }),
60
+ A ? /* @__PURE__ */ D("span", {
61
+ className: "inline-flex items-center gap-1.5 rounded-full bg-status-success-bg px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-status-success-text",
62
+ "data-testid": "ai-preview-live",
63
+ children: [/* @__PURE__ */ D("span", {
64
+ className: "relative flex size-2",
65
+ children: [/* @__PURE__ */ E("span", { className: "absolute inline-flex size-full rounded-full bg-status-success-text opacity-75 motion-safe:animate-ping" }), /* @__PURE__ */ E("span", { className: "relative inline-flex size-2 rounded-full bg-status-success-text" })]
66
+ }), g("bigconsole.widget.aiPreview.live", "Live")]
67
+ }) : null
68
+ ]
69
+ }), /* @__PURE__ */ D("span", {
70
+ className: "min-w-0 break-words text-xs text-text-muted",
71
+ "data-testid": "ai-preview-ago",
72
+ children: [
73
+ A ? F || g("bigconsole.widget.aiPreview.working", "Working…") : I ? g("bigconsole.widget.aiPreview.stopped", "Stopped") : g("bigconsole.widget.aiPreview.done", "Done"),
74
+ " ",
75
+ "· ",
76
+ g("bigconsole.widget.aiPreview.updated", "updated"),
77
+ " ",
78
+ s(K)
79
+ ]
80
+ })]
81
+ }), /* @__PURE__ */ E(x, {
84
82
  size: "sm",
85
83
  variant: "ghost",
86
- onClick: F,
87
- "aria-label": f("bigconsole.widget.aiPreview.closeAriaLabel", "Close preview"),
84
+ onClick: z,
85
+ "aria-label": g("bigconsole.widget.aiPreview.closeAriaLabel", "Close preview"),
88
86
  "data-testid": "ai-preview-close",
89
- children: /* @__PURE__ */ S(h, { className: "size-4" })
87
+ children: /* @__PURE__ */ E(y, { className: "size-4" })
90
88
  })]
91
89
  }),
92
- /* @__PURE__ */ S("div", {
93
- className: "border-b border-border-subtle px-3 py-2",
94
- children: /* @__PURE__ */ S(r, { steps: k })
90
+ /* @__PURE__ */ D("div", {
91
+ className: `px-3 py-2 ${i}`,
92
+ children: [/* @__PURE__ */ E("h3", {
93
+ className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-text-muted",
94
+ children: "Build progress"
95
+ }), /* @__PURE__ */ E(o, { steps: N })]
95
96
  }),
96
- /* @__PURE__ */ C(v, {
97
- value: L,
98
- onValueChange: (e) => R(e),
99
- children: [/* @__PURE__ */ C(b, {
100
- className: "mx-3 mt-2",
97
+ /* @__PURE__ */ D(S, {
98
+ value: V,
99
+ onValueChange: (e) => H(e),
100
+ children: [/* @__PURE__ */ E("div", {
101
+ className: "min-w-0 overflow-x-auto px-3 pt-2",
102
+ children: /* @__PURE__ */ D(w, {
103
+ className: "w-max",
104
+ children: [
105
+ /* @__PURE__ */ E(T, {
106
+ value: "datasink",
107
+ "data-testid": "ai-preview-tab-datasink",
108
+ children: g("bigconsole.widget.aiPreview.tab.dataSink", "Data Sink")
109
+ }),
110
+ /* @__PURE__ */ E(T, {
111
+ value: "dashboard",
112
+ "data-testid": "ai-preview-tab-dashboard",
113
+ children: g("bigconsole.widget.aiPreview.tab.dashboard", "Dashboard")
114
+ }),
115
+ /* @__PURE__ */ E(T, {
116
+ value: "parser",
117
+ "data-testid": "ai-preview-tab-parser",
118
+ children: g("bigconsole.widget.aiPreview.tab.parser", "Parser")
119
+ }),
120
+ /* @__PURE__ */ E(T, {
121
+ value: "widget",
122
+ "data-testid": "ai-preview-tab-widget",
123
+ children: g("bigconsole.widget.aiPreview.tab.widget", "Widget")
124
+ })
125
+ ]
126
+ })
127
+ }), /* @__PURE__ */ D("div", {
128
+ className: "min-w-0 overflow-y-auto p-3",
129
+ style: { maxHeight: "min(440px, 60vh)" },
101
130
  children: [
102
- /* @__PURE__ */ S(x, {
131
+ /* @__PURE__ */ E(C, {
103
132
  value: "datasink",
104
- "data-testid": "ai-preview-tab-datasink",
105
- children: f("bigconsole.widget.aiPreview.tab.dataSink", "Data Sink")
133
+ children: /* @__PURE__ */ E(e, {
134
+ emphasis: "standard",
135
+ padding: "compact",
136
+ headingLevel: 3,
137
+ title: "Data sink rows",
138
+ description: "The rows the assistant just landed, straight from the sink.",
139
+ actions: P.datasink ? /* @__PURE__ */ E(O, { onOpen: () => k(`/datasinks/${P.datasink ?? ""}`) }) : void 0,
140
+ children: /* @__PURE__ */ E(u, {
141
+ id: P.datasink,
142
+ live: A
143
+ })
144
+ })
106
145
  }),
107
- /* @__PURE__ */ S(x, {
146
+ /* @__PURE__ */ E(C, {
108
147
  value: "dashboard",
109
- "data-testid": "ai-preview-tab-dashboard",
110
- children: f("bigconsole.widget.aiPreview.tab.dashboard", "Dashboard")
148
+ children: /* @__PURE__ */ E(e, {
149
+ emphasis: "standard",
150
+ padding: "compact",
151
+ headingLevel: 3,
152
+ title: g("bigconsole.widget.aiPreview.tab.dashboard", "Dashboard"),
153
+ description: "The live board, rendered exactly as the real page renders it.",
154
+ actions: P.dashboard ? /* @__PURE__ */ E(O, { onOpen: () => k(`/dashboards/${P.dashboard ?? ""}`) }) : void 0,
155
+ children: /* @__PURE__ */ E(l, { dashboardId: P.dashboard })
156
+ })
111
157
  }),
112
- /* @__PURE__ */ S(x, {
158
+ /* @__PURE__ */ E(C, {
113
159
  value: "parser",
114
- "data-testid": "ai-preview-tab-parser",
115
- children: f("bigconsole.widget.aiPreview.tab.parser", "Parser")
160
+ children: /* @__PURE__ */ E(e, {
161
+ emphasis: "standard",
162
+ padding: "compact",
163
+ headingLevel: 3,
164
+ title: "Parser output",
165
+ description: "The rows after the parser's transform, so you can check the shape.",
166
+ actions: P.parser ? /* @__PURE__ */ E(O, { onOpen: () => k(`/parsers/${P.parser ?? ""}`) }) : void 0,
167
+ children: /* @__PURE__ */ E(d, {
168
+ parserId: P.parser,
169
+ live: A
170
+ })
171
+ })
116
172
  }),
117
- /* @__PURE__ */ S(x, {
173
+ /* @__PURE__ */ E(C, {
118
174
  value: "widget",
119
- "data-testid": "ai-preview-tab-widget",
120
- children: f("bigconsole.widget.aiPreview.tab.widget", "Widget")
121
- })
122
- ]
123
- }), /* @__PURE__ */ C("div", {
124
- className: "max-h-[440px] overflow-y-auto p-3",
125
- children: [
126
- /* @__PURE__ */ C(y, {
127
- value: "datasink",
128
- children: [/* @__PURE__ */ S(w, {
129
- label: f("bigconsole.widget.aiPreview.tab.dataSink", "Data Sink"),
130
- onOpen: A.datasink ? () => T(`/datasinks/${A.datasink}`) : void 0
131
- }), /* @__PURE__ */ S(s, {
132
- id: A.datasink,
133
- live: E
134
- })]
135
- }),
136
- /* @__PURE__ */ C(y, {
137
- value: "dashboard",
138
- children: [/* @__PURE__ */ S(w, {
139
- label: f("bigconsole.widget.aiPreview.tab.dashboard", "Dashboard"),
140
- onOpen: A.dashboard ? () => T(`/dashboards/${A.dashboard}`) : void 0
141
- }), /* @__PURE__ */ S(o, { dashboardId: A.dashboard })]
142
- }),
143
- /* @__PURE__ */ C(y, {
144
- value: "parser",
145
- children: [/* @__PURE__ */ S(w, {
146
- label: f("bigconsole.widget.aiPreview.tab.parser", "Parser"),
147
- onOpen: A.parser ? () => T(`/parsers/${A.parser}`) : void 0
148
- }), /* @__PURE__ */ S(c, {
149
- parserId: A.parser,
150
- live: E
151
- })]
152
- }),
153
- /* @__PURE__ */ C(y, {
154
- value: "widget",
155
- children: [/* @__PURE__ */ S(w, {
156
- label: f("bigconsole.widget.aiPreview.tab.widget", "Widget"),
157
- onOpen: V ? () => T(`/dashboards/${V}`) : void 0
158
- }), /* @__PURE__ */ S(l, {
159
- dashboardId: V,
160
- live: E
161
- })]
175
+ children: /* @__PURE__ */ E(e, {
176
+ emphasis: "standard",
177
+ padding: "compact",
178
+ headingLevel: 3,
179
+ title: "Widgets",
180
+ description: "Every widget on the new dashboard, rendered live.",
181
+ actions: G ? /* @__PURE__ */ E(O, { onOpen: () => k(`/dashboards/${G}`) }) : void 0,
182
+ children: /* @__PURE__ */ E(f, {
183
+ dashboardId: G,
184
+ live: A
185
+ })
186
+ })
162
187
  })
163
188
  ]
164
189
  })]
165
190
  }),
166
- M ? /* @__PURE__ */ S("p", {
167
- className: "border-t border-border-subtle px-3 py-2 text-xs text-status-error-text",
168
- "data-testid": "ai-preview-error",
169
- children: M
191
+ I ? /* @__PURE__ */ D("div", {
192
+ role: "alert",
193
+ className: "border-t border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] px-3 py-2",
194
+ children: [/* @__PURE__ */ E("h3", {
195
+ className: "text-[11px] font-semibold uppercase tracking-wide text-[var(--color-status-error-text)]",
196
+ children: "Build stopped"
197
+ }), /* @__PURE__ */ D("p", {
198
+ className: "mt-0.5 flex items-start gap-icon-gap text-xs text-[var(--color-status-error-text)]",
199
+ "data-testid": "ai-preview-error",
200
+ children: [/* @__PURE__ */ E(h, {
201
+ className: "mt-0.5 size-3.5 shrink-0",
202
+ "aria-hidden": "true"
203
+ }), /* @__PURE__ */ E("span", {
204
+ className: "min-w-0 break-words",
205
+ children: I
206
+ })]
207
+ })]
170
208
  }) : null
171
209
  ]
172
- }) : /* @__PURE__ */ S("div", {
173
- className: "flex justify-end px-4 pt-3 md:px-6",
174
- style: { marginRight: U },
175
- children: /* @__PURE__ */ C(_, {
210
+ }) : /* @__PURE__ */ D("div", {
211
+ className: "flex flex-wrap items-center justify-end gap-control-gap px-4 pt-3 md:px-6",
212
+ style: { marginRight: q },
213
+ children: [/* @__PURE__ */ E("span", {
214
+ className: "text-xs text-text-muted",
215
+ children: A ? "AI build running" : "AI build finished"
216
+ }), /* @__PURE__ */ D(x, {
176
217
  size: "sm",
177
218
  variant: "outline",
178
- onClick: P,
219
+ onClick: R,
179
220
  "data-testid": "ai-preview-open",
180
221
  children: [
181
- /* @__PURE__ */ S(m, { className: "mr-1.5 size-4" }),
182
- f("bigconsole.widget.aiPreview.previewButton", "Preview"),
183
- E ? /* @__PURE__ */ S(p, { className: "ml-1.5 size-3.5 animate-spin" }) : null
222
+ /* @__PURE__ */ E(v, { className: "mr-1.5 size-4" }),
223
+ g("bigconsole.widget.aiPreview.previewButton", "Preview"),
224
+ A ? /* @__PURE__ */ E(_, { className: "ml-1.5 size-3.5 animate-spin" }) : null
184
225
  ]
185
- })
226
+ })]
186
227
  }) : null;
187
228
  }
188
229
  //#endregion
189
- export { T as default };
230
+ export { k as default };
190
231
 
191
232
  //# sourceMappingURL=AiPreviewPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AiPreviewPanel.js","names":[],"sources":["../../../../src/bigconsole/components/preview/AiPreviewPanel.tsx"],"sourcesContent":["/**\n * AI Preview — watch the assistant build, with the real content inline.\n *\n * Opens by itself the moment a prompt starts. A step rail (driven by the agent's\n * own narration) shows DataSink → Dashboard → Parser → Widget filling in, and\n * the four tabs show the ACTUAL content of each entity as it lands — the data\n * sink's rows, the live dashboard, the parser's transformed output, the rendered\n * widget charts — not a list of links. The tab auto-switches to whatever step is\n * being worked on, and each tab has an \"Open\" button (top-right) that jumps to\n * the real page.\n *\n * The content renderers need Apollo + the BigConsole providers, which is why\n * this full panel lives inside BigConsoleRoot; the store-only app-shell mini\n * panel (AiPreviewMiniPanel) keeps the lighter link view for other pages.\n */\nimport { useEffect, useState } from 'react';\nimport { Button, Tabs, TabsContent, TabsList, TabsTrigger } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ArrowUpRight, Loader2, Sparkles, X } from 'lucide-react';\n\nimport { PREVIEW_STEPS, type PreviewStepKey, useAssistantRunStore } from '../../assistant/assistantRunStore';\nimport { useBigConsoleNavigate } from '../../context';\nimport { StepRail, formatAgo, useAssistantSidebarWidth } from './previewShared';\nimport { DashboardContent, DataSinkContent, ParserContent, WidgetsContent } from './AiPreviewContent';\n\n/** A tab's top bar: what this tab is, plus a jump-to-the-real-page button. */\nfunction TabHeader({ label, onOpen }: { label: string; onOpen?: () => void }) {\n const { t } = useI18n();\n return (\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold uppercase tracking-wide text-text-muted\">{label}</span>\n {onOpen ? (\n <Button size=\"sm\" variant=\"outline\" onClick={onOpen} data-testid=\"ai-preview-open-entity\">\n {t('bigconsole.widget.aiPreview.open', 'Open')}\n <ArrowUpRight className=\"ml-1 size-3.5\" />\n </Button>\n ) : null}\n </div>\n );\n}\n\nexport function AiPreviewPanel() {\n const { t } = useI18n();\n const navigate = useBigConsoleNavigate();\n\n const isRunning = useAssistantRunStore((state) => state.isRunning);\n const previewOpen = useAssistantRunStore((state) => state.previewOpen);\n const hasRun = useAssistantRunStore((state) => state.hasRun);\n const steps = useAssistantRunStore((state) => state.steps);\n const entityIds = useAssistantRunStore((state) => state.entityIds);\n const caption = useAssistantRunStore((state) => state.caption);\n const error = useAssistantRunStore((state) => state.error);\n const updatedAt = useAssistantRunStore((state) => state.updatedAt);\n const openPreview = useAssistantRunStore((state) => state.openPreview);\n const closePreview = useAssistantRunStore((state) => state.closePreview);\n const setRichMounted = useAssistantRunStore((state) => state.setRichMounted);\n\n // Tell the app-shell mini panel to stand down while this full panel is on a\n // /bigconsole page. On unmount (e.g. navigating to /workflows mid-run) this\n // flips false and the mini panel takes over so the build stays visible.\n useEffect(() => {\n setRichMounted(true);\n return () => setRichMounted(false);\n }, [setRichMounted]);\n\n const [tab, setTab] = useState<PreviewStepKey>('datasink');\n const [now, setNow] = useState(() => Date.now());\n\n const dashboardId = entityIds.dashboard;\n\n // Tick the \"updated Xs ago\" label while a turn is live.\n useEffect(() => {\n if (!isRunning) return;\n const intervalId = window.setInterval(() => setNow(Date.now()), 1000);\n return () => window.clearInterval(intervalId);\n }, [isRunning]);\n\n // Follow the build by showing the LATEST thing that actually landed — so the\n // moment the data sink is created you see its rows, not an empty \"waiting for\n // the dashboard\" tab. (The rail still shows the spinner on the next step.) If\n // nothing has landed yet, sit on whatever is being worked on.\n useEffect(() => {\n const done = PREVIEW_STEPS.filter((key) => steps[key] === 'done');\n const latestDone = done[done.length - 1];\n if (latestDone) {\n setTab(latestDone);\n return;\n }\n const running = PREVIEW_STEPS.find((key) => steps[key] === 'running');\n if (running) setTab(running);\n }, [steps]);\n\n const agoSeconds = updatedAt ? Math.max(0, Math.floor((now - updatedAt) / 1000)) : 0;\n\n // Keep clear of the assistant.\n //\n // The assistant sidebar is `position: fixed` — it OVERLAYS the page instead of\n // reflowing it. A panel that spans the full content width therefore runs\n // underneath it, and everything in that overlapped strip (tabs, Open buttons)\n // silently stops taking clicks. Measure the real element rather than hardcoding\n // 560px: the widget is responsive, and it can be closed mid-run.\n const assistantWidth = useAssistantSidebarWidth();\n\n if (!hasRun) return null;\n\n if (!previewOpen) {\n return (\n <div className=\"flex justify-end px-4 pt-3 md:px-6\" style={{ marginRight: assistantWidth }}>\n <Button size=\"sm\" variant=\"outline\" onClick={openPreview} data-testid=\"ai-preview-open\">\n <Sparkles className=\"mr-1.5 size-4\" />\n {t('bigconsole.widget.aiPreview.previewButton', 'Preview')}\n {isRunning ? <Loader2 className=\"ml-1.5 size-3.5 animate-spin\" /> : null}\n </Button>\n </div>\n );\n }\n\n return (\n <section\n data-testid=\"ai-preview-panel\"\n aria-label={t('bigconsole.widget.aiPreview.ariaLabel', 'AI preview')}\n style={{ marginRight: assistantWidth ? assistantWidth + 16 : undefined }}\n className=\"mx-4 mt-3 overflow-hidden rounded-lg border border-border-default bg-bg-sunken shadow-sm md:mx-6\"\n >\n {/* Header + live strip */}\n <div className=\"flex items-center justify-between gap-3 border-b border-border-subtle bg-bg-surface px-3 py-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Sparkles className=\"size-4 shrink-0 text-action-primary-bg\" />\n <h2 className=\"truncate text-sm font-semibold text-text-primary\">\n {t('bigconsole.widget.aiPreview.title', 'AI Preview')}\n </h2>\n {isRunning ? (\n <span\n className=\"inline-flex items-center gap-1.5 rounded-full bg-status-success-bg px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-status-success-text\"\n data-testid=\"ai-preview-live\"\n >\n <span className=\"relative flex size-2\">\n <span className=\"absolute inline-flex size-full animate-ping rounded-full bg-status-success-text opacity-75\" />\n <span className=\"relative inline-flex size-2 rounded-full bg-status-success-text\" />\n </span>\n {t('bigconsole.widget.aiPreview.live', 'Live')}\n </span>\n ) : null}\n <span className=\"truncate text-xs text-text-muted\" data-testid=\"ai-preview-ago\">\n {isRunning\n ? caption\n ? caption\n : t('bigconsole.widget.aiPreview.working', 'Working…')\n : error\n ? t('bigconsole.widget.aiPreview.stopped', 'Stopped')\n : t('bigconsole.widget.aiPreview.done', 'Done')}{' '}\n · {t('bigconsole.widget.aiPreview.updated', 'updated')} {formatAgo(agoSeconds)}\n </span>\n </div>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={closePreview}\n aria-label={t('bigconsole.widget.aiPreview.closeAriaLabel', 'Close preview')}\n data-testid=\"ai-preview-close\"\n >\n <X className=\"size-4\" />\n </Button>\n </div>\n\n {/* Step rail */}\n <div className=\"border-b border-border-subtle px-3 py-2\">\n <StepRail steps={steps} />\n </div>\n\n {/* Tabs — each shows the real content of the built entity */}\n <Tabs value={tab} onValueChange={(value) => setTab(value as PreviewStepKey)}>\n <TabsList className=\"mx-3 mt-2\">\n <TabsTrigger value=\"datasink\" data-testid=\"ai-preview-tab-datasink\">\n {t('bigconsole.widget.aiPreview.tab.dataSink', 'Data Sink')}\n </TabsTrigger>\n <TabsTrigger value=\"dashboard\" data-testid=\"ai-preview-tab-dashboard\">\n {t('bigconsole.widget.aiPreview.tab.dashboard', 'Dashboard')}\n </TabsTrigger>\n <TabsTrigger value=\"parser\" data-testid=\"ai-preview-tab-parser\">\n {t('bigconsole.widget.aiPreview.tab.parser', 'Parser')}\n </TabsTrigger>\n <TabsTrigger value=\"widget\" data-testid=\"ai-preview-tab-widget\">\n {t('bigconsole.widget.aiPreview.tab.widget', 'Widget')}\n </TabsTrigger>\n </TabsList>\n\n <div className=\"max-h-[440px] overflow-y-auto p-3\">\n <TabsContent value=\"datasink\">\n <TabHeader\n label={t('bigconsole.widget.aiPreview.tab.dataSink', 'Data Sink')}\n onOpen={entityIds.datasink ? () => navigate(`/datasinks/${entityIds.datasink}`) : undefined}\n />\n <DataSinkContent id={entityIds.datasink} live={isRunning} />\n </TabsContent>\n\n <TabsContent value=\"dashboard\">\n <TabHeader\n label={t('bigconsole.widget.aiPreview.tab.dashboard', 'Dashboard')}\n onOpen={entityIds.dashboard ? () => navigate(`/dashboards/${entityIds.dashboard}`) : undefined}\n />\n <DashboardContent dashboardId={entityIds.dashboard} />\n </TabsContent>\n\n <TabsContent value=\"parser\">\n <TabHeader\n label={t('bigconsole.widget.aiPreview.tab.parser', 'Parser')}\n onOpen={entityIds.parser ? () => navigate(`/parsers/${entityIds.parser}`) : undefined}\n />\n <ParserContent parserId={entityIds.parser} live={isRunning} />\n </TabsContent>\n\n <TabsContent value=\"widget\">\n <TabHeader\n label={t('bigconsole.widget.aiPreview.tab.widget', 'Widget')}\n onOpen={dashboardId ? () => navigate(`/dashboards/${dashboardId}`) : undefined}\n />\n <WidgetsContent dashboardId={dashboardId} live={isRunning} />\n </TabsContent>\n </div>\n </Tabs>\n\n {error ? (\n <p\n className=\"border-t border-border-subtle px-3 py-2 text-xs text-status-error-text\"\n data-testid=\"ai-preview-error\"\n >\n {error}\n </p>\n ) : null}\n </section>\n );\n}\n\nexport default AiPreviewPanel;\n"],"mappings":"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"}
1
+ {"version":3,"file":"AiPreviewPanel.js","names":[],"sources":["../../../../src/bigconsole/components/preview/AiPreviewPanel.tsx"],"sourcesContent":["/**\n * AI Preview — watch the assistant build, with the real content inline.\n *\n * Opens by itself the moment a prompt starts. A step rail (driven by the agent's\n * own narration) shows DataSink → Dashboard → Parser → Widget filling in, and\n * the four tabs show the ACTUAL content of each entity as it lands — the data\n * sink's rows, the live dashboard, the parser's transformed output, the rendered\n * widget charts — not a list of links. The tab auto-switches to whatever step is\n * being worked on, and each tab has an \"Open\" button that jumps to the real page.\n *\n * The content renderers need Apollo + the BigConsole providers, which is why\n * this full panel lives inside BigConsoleRoot; the store-only app-shell mini\n * panel (AiPreviewMiniPanel) keeps the lighter link view for other pages.\n *\n * Section emphasis (BOFF-5639): the panel is a recessed shell (chrome, progress\n * and tabs sit on `bg-bg-sunken`) wrapped around ONE raised result surface — the\n * live entity for the selected tab. That keeps the built thing the loudest part\n * of the panel without adding a second page-level `primary` on every route the\n * panel is injected into.\n */\nimport { useEffect, useState } from 'react';\nimport { Button, Tabs, TabsContent, TabsList, TabsTrigger } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AlertCircle, ArrowUpRight, Loader2, Sparkles, X } from 'lucide-react';\n\nimport { PREVIEW_STEPS, type PreviewStepKey, useAssistantRunStore } from '../../assistant/assistantRunStore';\nimport { useBigConsoleNavigate } from '../../context';\nimport { Section } from '../common';\nimport {\n PREVIEW_CHROME_DIVIDER,\n PREVIEW_PANEL_SHELL,\n StepRail,\n formatAgo,\n useAssistantSidebarWidth,\n} from './previewShared';\nimport { DashboardContent, DataSinkContent, ParserContent, WidgetsContent } from './AiPreviewContent';\n\n/** Jump-to-the-real-page button, shared by all four tabs. */\nfunction OpenEntityButton({ onOpen }: { onOpen: () => void }) {\n const { t } = useI18n();\n return (\n <Button size=\"sm\" variant=\"outline\" onClick={onOpen} data-testid=\"ai-preview-open-entity\">\n {t('bigconsole.widget.aiPreview.open', 'Open')}\n <ArrowUpRight className=\"ml-1 size-3.5\" />\n </Button>\n );\n}\n\nexport function AiPreviewPanel() {\n const { t } = useI18n();\n const navigate = useBigConsoleNavigate();\n\n const isRunning = useAssistantRunStore((state) => state.isRunning);\n const previewOpen = useAssistantRunStore((state) => state.previewOpen);\n const hasRun = useAssistantRunStore((state) => state.hasRun);\n const steps = useAssistantRunStore((state) => state.steps);\n const entityIds = useAssistantRunStore((state) => state.entityIds);\n const caption = useAssistantRunStore((state) => state.caption);\n const error = useAssistantRunStore((state) => state.error);\n const updatedAt = useAssistantRunStore((state) => state.updatedAt);\n const openPreview = useAssistantRunStore((state) => state.openPreview);\n const closePreview = useAssistantRunStore((state) => state.closePreview);\n const setRichMounted = useAssistantRunStore((state) => state.setRichMounted);\n\n // Tell the app-shell mini panel to stand down while this full panel is on a\n // /bigconsole page. On unmount (e.g. navigating to /workflows mid-run) this\n // flips false and the mini panel takes over so the build stays visible.\n useEffect(() => {\n setRichMounted(true);\n return () => setRichMounted(false);\n }, [setRichMounted]);\n\n const [tab, setTab] = useState<PreviewStepKey>('datasink');\n const [now, setNow] = useState(() => Date.now());\n\n const dashboardId = entityIds.dashboard;\n\n // Tick the \"updated Xs ago\" label while a turn is live.\n useEffect(() => {\n if (!isRunning) return;\n const intervalId = window.setInterval(() => setNow(Date.now()), 1000);\n return () => window.clearInterval(intervalId);\n }, [isRunning]);\n\n // Follow the build by showing the LATEST thing that actually landed — so the\n // moment the data sink is created you see its rows, not an empty \"waiting for\n // the dashboard\" tab. (The rail still shows the spinner on the next step.) If\n // nothing has landed yet, sit on whatever is being worked on.\n useEffect(() => {\n const done = PREVIEW_STEPS.filter((key) => steps[key] === 'done');\n const latestDone = done[done.length - 1];\n if (latestDone) {\n setTab(latestDone);\n return;\n }\n const running = PREVIEW_STEPS.find((key) => steps[key] === 'running');\n if (running) setTab(running);\n }, [steps]);\n\n const agoSeconds = updatedAt ? Math.max(0, Math.floor((now - updatedAt) / 1000)) : 0;\n\n // Keep clear of the assistant.\n //\n // The assistant sidebar is `position: fixed` — it OVERLAYS the page instead of\n // reflowing it. A panel that spans the full content width therefore runs\n // underneath it, and everything in that overlapped strip (tabs, Open buttons)\n // silently stops taking clicks. Measure the real element rather than hardcoding\n // 560px: the widget is responsive, and it can be closed mid-run.\n const assistantWidth = useAssistantSidebarWidth();\n\n if (!hasRun) return null;\n\n if (!previewOpen) {\n return (\n <div\n className=\"flex flex-wrap items-center justify-end gap-control-gap px-4 pt-3 md:px-6\"\n style={{ marginRight: assistantWidth }}\n >\n {/* The lone button gave no clue what it belonged to. */}\n <span className=\"text-xs text-text-muted\">{isRunning ? 'AI build running' : 'AI build finished'}</span>\n <Button size=\"sm\" variant=\"outline\" onClick={openPreview} data-testid=\"ai-preview-open\">\n <Sparkles className=\"mr-1.5 size-4\" />\n {t('bigconsole.widget.aiPreview.previewButton', 'Preview')}\n {isRunning ? <Loader2 className=\"ml-1.5 size-3.5 animate-spin\" /> : null}\n </Button>\n </div>\n );\n }\n\n return (\n <section\n data-testid=\"ai-preview-panel\"\n aria-label={t('bigconsole.widget.aiPreview.ariaLabel', 'AI preview')}\n style={{ marginRight: assistantWidth ? assistantWidth + 16 : undefined }}\n className={`${PREVIEW_PANEL_SHELL} mx-4 mt-3 md:mx-6`}\n >\n {/* Header + live strip. Title/badge on the first line, the caption on its\n own line: it is the most useful string during a run and it used to be\n the first thing to truncate away. */}\n <div\n className={`flex items-start justify-between gap-control-gap bg-bg-surface px-3 py-2 ${PREVIEW_CHROME_DIVIDER}`}\n >\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <Sparkles className=\"size-4 shrink-0 text-action-primary-bg\" />\n <h2 className=\"text-sm font-semibold text-text-primary\">\n {t('bigconsole.widget.aiPreview.title', 'AI Preview')}\n </h2>\n {isRunning ? (\n <span\n className=\"inline-flex items-center gap-1.5 rounded-full bg-status-success-bg px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-status-success-text\"\n data-testid=\"ai-preview-live\"\n >\n <span className=\"relative flex size-2\">\n <span className=\"absolute inline-flex size-full rounded-full bg-status-success-text opacity-75 motion-safe:animate-ping\" />\n <span className=\"relative inline-flex size-2 rounded-full bg-status-success-text\" />\n </span>\n {t('bigconsole.widget.aiPreview.live', 'Live')}\n </span>\n ) : null}\n </div>\n <span className=\"min-w-0 break-words text-xs text-text-muted\" data-testid=\"ai-preview-ago\">\n {isRunning\n ? caption\n ? caption\n : t('bigconsole.widget.aiPreview.working', 'Working…')\n : error\n ? t('bigconsole.widget.aiPreview.stopped', 'Stopped')\n : t('bigconsole.widget.aiPreview.done', 'Done')}{' '}\n · {t('bigconsole.widget.aiPreview.updated', 'updated')} {formatAgo(agoSeconds)}\n </span>\n </div>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={closePreview}\n aria-label={t('bigconsole.widget.aiPreview.closeAriaLabel', 'Close preview')}\n data-testid=\"ai-preview-close\"\n >\n <X className=\"size-4\" />\n </Button>\n </div>\n\n {/* Step rail — the panel's progress narrative, now a labelled block\n instead of four unexplained pills. */}\n <div className={`px-3 py-2 ${PREVIEW_CHROME_DIVIDER}`}>\n <h3 className=\"mb-1 text-[11px] font-semibold uppercase tracking-wide text-text-muted\">Build progress</h3>\n <StepRail steps={steps} />\n </div>\n\n {/* Tabs — each shows the real content of the built entity */}\n <Tabs value={tab} onValueChange={(value) => setTab(value as PreviewStepKey)}>\n {/* fe-libs TabsList is `w-fit inline-flex` with nowrap triggers and no\n overflow handling, inside a panel that is `overflow-hidden` — below\n ~430px the fourth tab was clipped instead of reachable. */}\n <div className=\"min-w-0 overflow-x-auto px-3 pt-2\">\n <TabsList className=\"w-max\">\n <TabsTrigger value=\"datasink\" data-testid=\"ai-preview-tab-datasink\">\n {t('bigconsole.widget.aiPreview.tab.dataSink', 'Data Sink')}\n </TabsTrigger>\n <TabsTrigger value=\"dashboard\" data-testid=\"ai-preview-tab-dashboard\">\n {t('bigconsole.widget.aiPreview.tab.dashboard', 'Dashboard')}\n </TabsTrigger>\n <TabsTrigger value=\"parser\" data-testid=\"ai-preview-tab-parser\">\n {t('bigconsole.widget.aiPreview.tab.parser', 'Parser')}\n </TabsTrigger>\n <TabsTrigger value=\"widget\" data-testid=\"ai-preview-tab-widget\">\n {t('bigconsole.widget.aiPreview.tab.widget', 'Widget')}\n </TabsTrigger>\n </TabsList>\n </div>\n\n {/* The hard 440px cap ate most of the fold on a short laptop screen. */}\n <div className=\"min-w-0 overflow-y-auto p-3\" style={{ maxHeight: 'min(440px, 60vh)' }}>\n <TabsContent value=\"datasink\">\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title=\"Data sink rows\"\n description=\"The rows the assistant just landed, straight from the sink.\"\n actions={\n entityIds.datasink ? (\n <OpenEntityButton onOpen={() => navigate(`/datasinks/${entityIds.datasink ?? ''}`)} />\n ) : undefined\n }\n >\n <DataSinkContent id={entityIds.datasink} live={isRunning} />\n </Section>\n </TabsContent>\n\n <TabsContent value=\"dashboard\">\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.tab.dashboard', 'Dashboard')}\n description=\"The live board, rendered exactly as the real page renders it.\"\n actions={\n entityIds.dashboard ? (\n <OpenEntityButton onOpen={() => navigate(`/dashboards/${entityIds.dashboard ?? ''}`)} />\n ) : undefined\n }\n >\n <DashboardContent dashboardId={entityIds.dashboard} />\n </Section>\n </TabsContent>\n\n <TabsContent value=\"parser\">\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title=\"Parser output\"\n description=\"The rows after the parser's transform, so you can check the shape.\"\n actions={\n entityIds.parser ? (\n <OpenEntityButton onOpen={() => navigate(`/parsers/${entityIds.parser ?? ''}`)} />\n ) : undefined\n }\n >\n <ParserContent parserId={entityIds.parser} live={isRunning} />\n </Section>\n </TabsContent>\n\n <TabsContent value=\"widget\">\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title=\"Widgets\"\n description=\"Every widget on the new dashboard, rendered live.\"\n actions={\n dashboardId ? <OpenEntityButton onOpen={() => navigate(`/dashboards/${dashboardId}`)} /> : undefined\n }\n >\n <WidgetsContent dashboardId={dashboardId} live={isRunning} />\n </Section>\n </TabsContent>\n </div>\n </Tabs>\n\n {/* A failed run used to be 12px red text in a bare footer — the quietest\n treatment on the panel for its most important message. */}\n {error ? (\n <div\n role=\"alert\"\n className=\"border-t border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] px-3 py-2\"\n >\n <h3 className=\"text-[11px] font-semibold uppercase tracking-wide text-[var(--color-status-error-text)]\">\n Build stopped\n </h3>\n <p\n className=\"mt-0.5 flex items-start gap-icon-gap text-xs text-[var(--color-status-error-text)]\"\n data-testid=\"ai-preview-error\"\n >\n <AlertCircle className=\"mt-0.5 size-3.5 shrink-0\" aria-hidden=\"true\" />\n <span className=\"min-w-0 break-words\">{error}</span>\n </p>\n </div>\n ) : null}\n </section>\n );\n}\n\nexport default AiPreviewPanel;\n"],"mappings":"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"}
@@ -1,39 +1,57 @@
1
- import { PREVIEW_STEPS as e, PREVIEW_STEP_LABEL as t } from "../../assistant/assistantRunStore.js";
2
- import { useEffect as n, useState as r } from "react";
3
- import { Check as i, ChevronRight as a, Loader2 as o, Minus as s } from "lucide-react";
4
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
1
+ import { SECTION_MOTION as e } from "../common/sectionStyles.js";
2
+ import "../common/index.js";
3
+ import { PREVIEW_STEPS as t, PREVIEW_STEP_LABEL as n } from "../../assistant/assistantRunStore.js";
4
+ import { useEffect as r, useState as i } from "react";
5
+ import { Check as a, ChevronRight as o, Loader2 as s, Minus as c } from "lucide-react";
6
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
7
  //#region src/bigconsole/components/preview/previewShared.tsx
6
- function u({ status: e }) {
7
- return e === "done" ? /* @__PURE__ */ c(i, { className: "size-3.5 text-status-success-text" }) : e === "running" ? /* @__PURE__ */ c(o, { className: "size-3.5 animate-spin text-action-primary-bg" }) : e === "skipped" ? /* @__PURE__ */ c(s, { className: "size-3.5 text-text-muted" }) : /* @__PURE__ */ c("span", { className: "size-1.5 rounded-full bg-border-strong" });
8
+ var d = [
9
+ "min-w-0 overflow-hidden rounded-card border border-[var(--color-border-subtle)]",
10
+ "bg-bg-sunken shadow-[var(--shadow-elevation-1)]",
11
+ e
12
+ ].join(" "), f = "border-b border-[var(--color-border-subtle)]";
13
+ function p({ status: e }) {
14
+ return e === "done" ? /* @__PURE__ */ l(a, { className: "size-3.5 text-status-success-text" }) : e === "running" ? /* @__PURE__ */ l(s, { className: "size-3.5 animate-spin text-action-primary-bg" }) : e === "skipped" ? /* @__PURE__ */ l(c, { className: "size-3.5 text-text-muted" }) : /* @__PURE__ */ l("span", { className: "size-1.5 rounded-full bg-[var(--color-border-strong)]" });
8
15
  }
9
- function d({ steps: n }) {
10
- return /* @__PURE__ */ c("div", {
11
- className: "flex flex-wrap items-center gap-1",
16
+ function m(e) {
17
+ let t = "inline-flex shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs";
18
+ return e === "done" ? `${t} border-status-success-border bg-status-success-bg font-medium text-status-success-text` : e === "running" ? `${t} border-[var(--color-action-primary-bg)] bg-bg-surface font-semibold text-text-primary shadow-[var(--shadow-elevation-1)]` : `${t} border-[var(--color-border-subtle)] font-medium text-text-muted`;
19
+ }
20
+ function h({ steps: e }) {
21
+ return /* @__PURE__ */ l("div", {
22
+ role: "list",
23
+ className: "flex min-w-0 items-center gap-1 overflow-x-auto pb-0.5",
12
24
  "data-testid": "ai-preview-step-rail",
13
- children: e.map((r, i) => /* @__PURE__ */ l("div", {
14
- className: "flex items-center gap-1",
15
- children: [/* @__PURE__ */ l("span", {
25
+ "aria-label": "Build steps",
26
+ children: t.map((r, i) => /* @__PURE__ */ u("div", {
27
+ role: "listitem",
28
+ className: "flex shrink-0 items-center gap-1",
29
+ children: [/* @__PURE__ */ u("span", {
16
30
  "data-testid": `ai-preview-step-${r}`,
17
- "data-status": n[r],
18
- className: ["inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium", n[r] === "done" ? "border-status-success-border bg-status-success-bg text-status-success-text" : n[r] === "running" ? "border-border-strong bg-bg-surface text-text-primary" : "border-border-default text-text-muted"].join(" "),
31
+ "data-status": e[r],
32
+ "aria-current": e[r] === "running" ? "step" : void 0,
33
+ className: m(e[r]),
19
34
  children: [
20
- /* @__PURE__ */ c(u, { status: n[r] }),
21
- t[r],
22
- n[r] === "skipped" ? /* @__PURE__ */ c("span", {
35
+ /* @__PURE__ */ l(p, { status: e[r] }),
36
+ n[r],
37
+ e[r] === "skipped" ? /* @__PURE__ */ l("span", {
23
38
  className: "text-[10px]",
24
39
  children: "skipped"
25
40
  }) : null
26
41
  ]
27
- }), i < e.length - 1 ? /* @__PURE__ */ c(a, { className: "size-3.5 text-text-muted" }) : null]
42
+ }), i < t.length - 1 ? /* @__PURE__ */ l(o, {
43
+ className: "size-3.5 shrink-0 text-text-muted",
44
+ "aria-hidden": "true"
45
+ }) : null]
28
46
  }, r))
29
47
  });
30
48
  }
31
- function f(e) {
49
+ function g(e) {
32
50
  return e < 5 ? "just now" : e < 60 ? `${String(e)}s ago` : `${String(Math.floor(e / 60))}m ago`;
33
51
  }
34
- function p() {
35
- let [e, t] = r(0);
36
- return n(() => {
52
+ function _() {
53
+ let [e, t] = i(0);
54
+ return r(() => {
37
55
  let e = () => {
38
56
  let e = document.querySelector("[data-testid=\"assistant-widget-window\"][data-layout=\"sidebar\"]")?.getBoundingClientRect(), n = e && e.width < window.innerWidth * .75 ? Math.round(e.width) : 0;
39
57
  t((e) => e === n ? e : n);
@@ -46,6 +64,6 @@ function p() {
46
64
  }, []), e;
47
65
  }
48
66
  //#endregion
49
- export { d as StepRail, f as formatAgo, p as useAssistantSidebarWidth };
67
+ export { f as PREVIEW_CHROME_DIVIDER, d as PREVIEW_PANEL_SHELL, h as StepRail, g as formatAgo, _ as useAssistantSidebarWidth };
50
68
 
51
69
  //# sourceMappingURL=previewShared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"previewShared.js","names":[],"sources":["../../../../src/bigconsole/components/preview/previewShared.tsx"],"sourcesContent":["/**\n * Presentational bits shared by the two AI-preview surfaces:\n * - AiPreviewPanel — the full panel with live entity tabs, mounted inside\n * BigConsoleRoot (needs the BigConsole Apollo context).\n * - AiPreviewMiniPanel — the lightweight, store-only panel mounted by the app\n * shell so the build stays visible on ANY page.\n *\n * Nothing here touches Apollo, React Query, or BigConsole context — it is pure\n * store-shape + DOM, which is exactly why the mini panel can live in the app\n * shell without dragging the data layer along.\n */\nimport { useEffect, useState } from 'react';\nimport { Check, ChevronRight, Loader2, Minus } from 'lucide-react';\n\nimport {\n PREVIEW_STEP_LABEL,\n PREVIEW_STEPS,\n type PreviewStepKey,\n type PreviewStepStatus,\n} from '../../assistant/assistantRunStore';\n\nexport function StepPip({ status }: { status: PreviewStepStatus }) {\n if (status === 'done') return <Check className=\"size-3.5 text-status-success-text\" />;\n if (status === 'running') return <Loader2 className=\"size-3.5 animate-spin text-action-primary-bg\" />;\n if (status === 'skipped') return <Minus className=\"size-3.5 text-text-muted\" />;\n return <span className=\"size-1.5 rounded-full bg-border-strong\" />;\n}\n\nexport function StepRail({ steps }: { steps: Record<PreviewStepKey, PreviewStepStatus> }) {\n return (\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"ai-preview-step-rail\">\n {PREVIEW_STEPS.map((key, index) => (\n <div key={key} className=\"flex items-center gap-1\">\n <span\n data-testid={`ai-preview-step-${key}`}\n data-status={steps[key]}\n className={[\n 'inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium',\n steps[key] === 'done'\n ? 'border-status-success-border bg-status-success-bg text-status-success-text'\n : steps[key] === 'running'\n ? 'border-border-strong bg-bg-surface text-text-primary'\n : 'border-border-default text-text-muted',\n ].join(' ')}\n >\n <StepPip status={steps[key]} />\n {PREVIEW_STEP_LABEL[key]}\n {steps[key] === 'skipped' ? <span className=\"text-[10px]\">skipped</span> : null}\n </span>\n {index < PREVIEW_STEPS.length - 1 ? <ChevronRight className=\"size-3.5 text-text-muted\" /> : null}\n </div>\n ))}\n </div>\n );\n}\n\nexport function formatAgo(seconds: number): string {\n if (seconds < 5) return 'just now';\n if (seconds < 60) return `${String(seconds)}s ago`;\n return `${String(Math.floor(seconds / 60))}m ago`;\n}\n\n/**\n * Width of the assistant sidebar, or 0 when it is closed.\n *\n * Polled rather than subscribed: the widget lives in fe-libs, is mounted by the\n * app shell, and emits nothing when it opens or closes. Reading the DOM is the\n * only honest signal available, and it is cheap.\n */\nexport function useAssistantSidebarWidth(): number {\n const [width, setWidth] = useState(0);\n\n useEffect(() => {\n const measure = () => {\n const el = document.querySelector('[data-testid=\"assistant-widget-window\"][data-layout=\"sidebar\"]');\n const rect = el?.getBoundingClientRect();\n // Below `sm` the sidebar is full-width; reserving that would leave no room\n // for the preview at all, so on small screens let it stack underneath.\n const next = rect && rect.width < window.innerWidth * 0.75 ? Math.round(rect.width) : 0;\n setWidth((current) => (current === next ? current : next));\n };\n measure();\n const intervalId = window.setInterval(measure, 500);\n window.addEventListener('resize', measure);\n return () => {\n window.clearInterval(intervalId);\n window.removeEventListener('resize', measure);\n };\n }, []);\n\n return width;\n}\n"],"mappings":";;;;;AAqBA,SAAgB,EAAQ,EAAE,aAAyC;AAIjE,QAHI,MAAW,SAAe,kBAAC,GAAD,EAAO,WAAU,qCAAsC,CAAA,GACjF,MAAW,YAAkB,kBAAC,GAAD,EAAS,WAAU,gDAAiD,CAAA,GACjG,MAAW,YAAkB,kBAAC,GAAD,EAAO,WAAU,4BAA6B,CAAA,GACxE,kBAAC,QAAD,EAAM,WAAU,0CAA2C,CAAA;;AAGpE,SAAgB,EAAS,EAAE,YAA+D;AACxF,QACE,kBAAC,OAAD;EAAK,WAAU;EAAoC,eAAY;YAC5D,EAAc,KAAK,GAAK,MACvB,kBAAC,OAAD;GAAe,WAAU;aAAzB,CACE,kBAAC,QAAD;IACE,eAAa,mBAAmB;IAChC,eAAa,EAAM;IACnB,WAAW,CACT,wFACA,EAAM,OAAS,SACX,+EACA,EAAM,OAAS,YACb,yDACA,wCACP,CAAC,KAAK,IAAI;cAVb;KAYE,kBAAC,GAAD,EAAS,QAAQ,EAAM,IAAQ,CAAA;KAC9B,EAAmB;KACnB,EAAM,OAAS,YAAY,kBAAC,QAAD;MAAM,WAAU;gBAAc;MAAc,CAAA,GAAG;KACtE;OACN,IAAQ,EAAc,SAAS,IAAI,kBAAC,GAAD,EAAc,WAAU,4BAA6B,CAAA,GAAG,KACxF;KAlBI,EAkBJ,CACN;EACE,CAAA;;AAIV,SAAgB,EAAU,GAAyB;AAGjD,QAFI,IAAU,IAAU,aACpB,IAAU,KAAW,GAAG,OAAO,EAAQ,CAAC,SACrC,GAAG,OAAO,KAAK,MAAM,IAAU,GAAG,CAAC,CAAC;;AAU7C,SAAgB,IAAmC;CACjD,IAAM,CAAC,GAAO,KAAY,EAAS,EAAE;AAoBrC,QAlBA,QAAgB;EACd,IAAM,UAAgB;GAEpB,IAAM,IADK,SAAS,cAAc,qEAAiE,EAClF,uBAAuB,EAGlC,IAAO,KAAQ,EAAK,QAAQ,OAAO,aAAa,MAAO,KAAK,MAAM,EAAK,MAAM,GAAG;AACtF,MAAU,MAAa,MAAY,IAAO,IAAU,EAAM;;AAE5D,KAAS;EACT,IAAM,IAAa,OAAO,YAAY,GAAS,IAAI;AAEnD,SADA,OAAO,iBAAiB,UAAU,EAAQ,QAC7B;AAEX,GADA,OAAO,cAAc,EAAW,EAChC,OAAO,oBAAoB,UAAU,EAAQ;;IAE9C,EAAE,CAAC,EAEC"}
1
+ {"version":3,"file":"previewShared.js","names":[],"sources":["../../../../src/bigconsole/components/preview/previewShared.tsx"],"sourcesContent":["/**\n * Presentational bits shared by the two AI-preview surfaces:\n * - AiPreviewPanel — the full panel with live entity tabs, mounted inside\n * BigConsoleRoot (needs the BigConsole Apollo context).\n * - AiPreviewMiniPanel — the lightweight, store-only panel mounted by the app\n * shell so the build stays visible on ANY page.\n *\n * Nothing here touches Apollo, React Query, or BigConsole context — it is pure\n * store-shape + DOM, which is exactly why the mini panel can live in the app\n * shell without dragging the data layer along.\n */\nimport { useEffect, useState } from 'react';\nimport { Check, ChevronRight, Loader2, Minus } from 'lucide-react';\n\nimport {\n PREVIEW_STEP_LABEL,\n PREVIEW_STEPS,\n type PreviewStepKey,\n type PreviewStepStatus,\n} from '../../assistant/assistantRunStore';\nimport { SECTION_MOTION } from '../common';\n\n/**\n * The panel shell, shared by both preview surfaces.\n *\n * `rounded-lg` + `border-border-default` used to make this a fourth surface\n * recipe in a product that otherwise uses `rounded-card` and the theme-aware\n * `--color-border-subtle` — and the plain `border-*` utilities are registered\n * as frozen light hex in this shell, so they do not follow dark mode. Both\n * panels now read the recipe from here, so they cannot drift apart.\n */\nexport const PREVIEW_PANEL_SHELL = [\n 'min-w-0 overflow-hidden rounded-card border border-[var(--color-border-subtle)]',\n 'bg-bg-sunken shadow-[var(--shadow-elevation-1)]',\n SECTION_MOTION,\n].join(' ');\n\n/** Chrome strips (header, progress, tabs) share one recessed treatment. */\nexport const PREVIEW_CHROME_DIVIDER = 'border-b border-[var(--color-border-subtle)]';\n\nexport function StepPip({ status }: { status: PreviewStepStatus }) {\n if (status === 'done') return <Check className=\"size-3.5 text-status-success-text\" />;\n if (status === 'running') return <Loader2 className=\"size-3.5 animate-spin text-action-primary-bg\" />;\n if (status === 'skipped') return <Minus className=\"size-3.5 text-text-muted\" />;\n // `bg-border-strong` is registered as a frozen light hex in this shell, so the\n // not-started pip stayed light grey in dark mode.\n return <span className=\"size-1.5 rounded-full bg-[var(--color-border-strong)]\" />;\n}\n\n/**\n * Per-step chip treatment. The step you are ON has to out-rank a not-started\n * step at a glance — they used to differ only by border shade, which is the\n * weakest possible signal for the panel's only progress narrative.\n */\nfunction stepChipClasses(status: PreviewStepStatus): string {\n // `rounded-full` rather than `rounded-pill`: this rail also renders inside the\n // app shell's own Tailwind build, and `rounded-full` needs no token registry.\n const base = 'inline-flex shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs';\n if (status === 'done') {\n return `${base} border-status-success-border bg-status-success-bg font-medium text-status-success-text`;\n }\n if (status === 'running') {\n return `${base} border-[var(--color-action-primary-bg)] bg-bg-surface font-semibold text-text-primary shadow-[var(--shadow-elevation-1)]`;\n }\n return `${base} border-[var(--color-border-subtle)] font-medium text-text-muted`;\n}\n\nexport function StepRail({ steps }: { steps: Record<PreviewStepKey, PreviewStepStatus> }) {\n return (\n // One scrolling line rather than `flex-wrap`: wrapping left chevrons\n // dangling at the end of a line, pointing at nothing.\n //\n // `role=\"list\"` is what makes the `aria-label` count: an aria-label on a\n // role-less <div> is dropped by every screen reader, so the rail would have\n // been announced as four unrelated strings.\n <div\n role=\"list\"\n className=\"flex min-w-0 items-center gap-1 overflow-x-auto pb-0.5\"\n data-testid=\"ai-preview-step-rail\"\n aria-label=\"Build steps\"\n >\n {PREVIEW_STEPS.map((key, index) => (\n <div key={key} role=\"listitem\" className=\"flex shrink-0 items-center gap-1\">\n <span\n data-testid={`ai-preview-step-${key}`}\n data-status={steps[key]}\n aria-current={steps[key] === 'running' ? 'step' : undefined}\n className={stepChipClasses(steps[key])}\n >\n <StepPip status={steps[key]} />\n {PREVIEW_STEP_LABEL[key]}\n {steps[key] === 'skipped' ? <span className=\"text-[10px]\">skipped</span> : null}\n </span>\n {index < PREVIEW_STEPS.length - 1 ? (\n <ChevronRight className=\"size-3.5 shrink-0 text-text-muted\" aria-hidden=\"true\" />\n ) : null}\n </div>\n ))}\n </div>\n );\n}\n\nexport function formatAgo(seconds: number): string {\n if (seconds < 5) return 'just now';\n if (seconds < 60) return `${String(seconds)}s ago`;\n return `${String(Math.floor(seconds / 60))}m ago`;\n}\n\n/**\n * Width of the assistant sidebar, or 0 when it is closed.\n *\n * Polled rather than subscribed: the widget lives in fe-libs, is mounted by the\n * app shell, and emits nothing when it opens or closes. Reading the DOM is the\n * only honest signal available, and it is cheap.\n */\nexport function useAssistantSidebarWidth(): number {\n const [width, setWidth] = useState(0);\n\n useEffect(() => {\n const measure = () => {\n const el = document.querySelector('[data-testid=\"assistant-widget-window\"][data-layout=\"sidebar\"]');\n const rect = el?.getBoundingClientRect();\n // Below `sm` the sidebar is full-width; reserving that would leave no room\n // for the preview at all, so on small screens let it stack underneath.\n const next = rect && rect.width < window.innerWidth * 0.75 ? Math.round(rect.width) : 0;\n setWidth((current) => (current === next ? current : next));\n };\n measure();\n const intervalId = window.setInterval(measure, 500);\n window.addEventListener('resize', measure);\n return () => {\n window.clearInterval(intervalId);\n window.removeEventListener('resize', measure);\n };\n }, []);\n\n return width;\n}\n"],"mappings":";;;;;;;AA+BA,IAAa,IAAsB;CACjC;CACA;CACA;CACD,CAAC,KAAK,IAAI,EAGE,IAAyB;AAEtC,SAAgB,EAAQ,EAAE,aAAyC;AAMjE,QALI,MAAW,SAAe,kBAAC,GAAD,EAAO,WAAU,qCAAsC,CAAA,GACjF,MAAW,YAAkB,kBAAC,GAAD,EAAS,WAAU,gDAAiD,CAAA,GACjG,MAAW,YAAkB,kBAAC,GAAD,EAAO,WAAU,4BAA6B,CAAA,GAGxE,kBAAC,QAAD,EAAM,WAAU,yDAA0D,CAAA;;AAQnF,SAAS,EAAgB,GAAmC;CAG1D,IAAM,IAAO;AAOb,QANI,MAAW,SACN,GAAG,EAAK,2FAEb,MAAW,YACN,GAAG,EAAK,6HAEV,GAAG,EAAK;;AAGjB,SAAgB,EAAS,EAAE,YAA+D;AACxF,QAOE,kBAAC,OAAD;EACE,MAAK;EACL,WAAU;EACV,eAAY;EACZ,cAAW;YAEV,EAAc,KAAK,GAAK,MACvB,kBAAC,OAAD;GAAe,MAAK;GAAW,WAAU;aAAzC,CACE,kBAAC,QAAD;IACE,eAAa,mBAAmB;IAChC,eAAa,EAAM;IACnB,gBAAc,EAAM,OAAS,YAAY,SAAS,KAAA;IAClD,WAAW,EAAgB,EAAM,GAAK;cAJxC;KAME,kBAAC,GAAD,EAAS,QAAQ,EAAM,IAAQ,CAAA;KAC9B,EAAmB;KACnB,EAAM,OAAS,YAAY,kBAAC,QAAD;MAAM,WAAU;gBAAc;MAAc,CAAA,GAAG;KACtE;OACN,IAAQ,EAAc,SAAS,IAC9B,kBAAC,GAAD;IAAc,WAAU;IAAoC,eAAY;IAAS,CAAA,GAC/E,KACA;KAdI,EAcJ,CACN;EACE,CAAA;;AAIV,SAAgB,EAAU,GAAyB;AAGjD,QAFI,IAAU,IAAU,aACpB,IAAU,KAAW,GAAG,OAAO,EAAQ,CAAC,SACrC,GAAG,OAAO,KAAK,MAAM,IAAU,GAAG,CAAC,CAAC;;AAU7C,SAAgB,IAAmC;CACjD,IAAM,CAAC,GAAO,KAAY,EAAS,EAAE;AAoBrC,QAlBA,QAAgB;EACd,IAAM,UAAgB;GAEpB,IAAM,IADK,SAAS,cAAc,qEAAiE,EAClF,uBAAuB,EAGlC,IAAO,KAAQ,EAAK,QAAQ,OAAO,aAAa,MAAO,KAAK,MAAM,EAAK,MAAM,GAAG;AACtF,MAAU,MAAa,MAAY,IAAO,IAAU,EAAM;;AAE5D,KAAS;EACT,IAAM,IAAa,OAAO,YAAY,GAAS,IAAI;AAEnD,SADA,OAAO,iBAAiB,UAAU,EAAQ,QAC7B;AAEX,GADA,OAAO,cAAc,EAAW,EAChC,OAAO,oBAAoB,UAAU,EAAQ;;IAE9C,EAAE,CAAC,EAEC"}