@burdenoff/microfe-bigconsole 2026.805.2 → 2026.812.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 (253) 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 +145 -111
  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 +269 -251
  23. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  24. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +214 -223
  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 +110 -102
  29. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  30. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +81 -68
  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 +147 -144
  35. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
  36. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +154 -153
  37. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
  38. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +82 -79
  39. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
  40. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +171 -284
  41. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  42. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +250 -273
  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/PublishToStoreDialog.js +75 -83
  49. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js.map +1 -1
  50. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +167 -161
  51. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
  52. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +181 -190
  53. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
  54. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +101 -95
  55. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
  56. package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js +20 -18
  57. package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js.map +1 -1
  58. package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -0
  59. package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js +26 -58
  60. package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js.map +1 -1
  61. package/dist/bigconsole/components/dashboard/WidgetPalette.js +307 -229
  62. package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
  63. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +128 -129
  64. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  65. package/dist/bigconsole/components/datasink/DataSinkCard.js +78 -79
  66. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  67. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +33 -34
  68. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
  69. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +79 -61
  70. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  71. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +75 -64
  72. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  73. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +1 -1
  74. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
  75. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +20 -19
  76. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
  77. package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js +127 -171
  78. package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js.map +1 -1
  79. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +113 -117
  80. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
  81. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +312 -307
  82. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  83. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +65 -66
  84. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
  85. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +121 -127
  86. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
  87. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +194 -189
  88. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  89. package/dist/bigconsole/components/datasink/SetupStateBadge.js +3 -3
  90. package/dist/bigconsole/components/datasink/SetupStateBadge.js.map +1 -1
  91. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +95 -95
  92. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
  93. package/dist/bigconsole/components/parser/DataSinkSelector.js +163 -131
  94. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  95. package/dist/bigconsole/components/parser/ExpressionEditor.js +3 -3
  96. package/dist/bigconsole/components/parser/ExpressionEditor.js.map +1 -1
  97. package/dist/bigconsole/components/parser/ImportParserDialog.js +205 -260
  98. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  99. package/dist/bigconsole/components/parser/ParserCard.js +133 -114
  100. package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
  101. package/dist/bigconsole/components/parser/ParserSelector.js +193 -174
  102. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  103. package/dist/bigconsole/components/parser/ParserStatusBadge.js +2 -2
  104. package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
  105. package/dist/bigconsole/components/parser/ParserTypeBadge.js +4 -4
  106. package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
  107. package/dist/bigconsole/components/pipeline/PipelineCard.js +134 -89
  108. package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
  109. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +77 -64
  110. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
  111. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +7 -10
  112. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
  113. package/dist/bigconsole/components/preview/AiPreviewContent.js +31 -32
  114. package/dist/bigconsole/components/preview/AiPreviewContent.js.map +1 -1
  115. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +152 -103
  116. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
  117. package/dist/bigconsole/components/preview/AiPreviewPanel.js +193 -148
  118. package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
  119. package/dist/bigconsole/components/preview/previewShared.js +41 -23
  120. package/dist/bigconsole/components/preview/previewShared.js.map +1 -1
  121. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +405 -364
  122. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  123. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +265 -237
  124. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  125. package/dist/bigconsole/components/widgets/PropertiesPanel.js +764 -821
  126. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  127. package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js +7 -5
  128. package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js.map +1 -1
  129. package/dist/bigconsole/components/widgets/WidgetHeader.js +7 -8
  130. package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
  131. package/dist/bigconsole/components/widgets/WidgetWrapper.js +8 -7
  132. package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
  133. package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js +1 -1
  134. package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js.map +1 -1
  135. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +46 -49
  136. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  137. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +154 -147
  138. package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
  139. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +118 -101
  140. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  141. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +244 -191
  142. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
  143. package/dist/bigconsole/components/widgets/form/FormWidget.js +167 -159
  144. package/dist/bigconsole/components/widgets/form/FormWidget.js.map +1 -1
  145. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +92 -76
  146. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
  147. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +1 -1
  148. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
  149. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +89 -86
  150. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
  151. package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js +2 -2
  152. package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js.map +1 -1
  153. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +64 -63
  154. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  155. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +2 -2
  156. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
  157. package/dist/bigconsole/components/widgets/list/ListConfig.js +65 -58
  158. package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
  159. package/dist/bigconsole/components/widgets/list/ListItem.js +1 -1
  160. package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
  161. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +1 -1
  162. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
  163. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +79 -72
  164. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
  165. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +35 -34
  166. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
  167. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +20 -19
  168. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
  169. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +181 -180
  170. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  171. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +100 -90
  172. package/dist/bigconsole/components/widgets/progress/ProgressConfig.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 +193 -172
  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/webhook-config/WebhookConfigPanel.js +283 -249
  194. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
  195. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +28 -20
  196. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  197. package/dist/bigconsole/components/workflow/WorkflowCard.js +92 -77
  198. package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
  199. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +70 -51
  200. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
  201. package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js +16 -17
  202. package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js.map +1 -1
  203. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +46 -42
  204. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
  205. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +372 -348
  206. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  207. package/dist/bigconsole/hooks/useModalFocusTrap.js +53 -0
  208. package/dist/bigconsole/hooks/useModalFocusTrap.js.map +1 -0
  209. package/dist/bigconsole/pages/DashboardBuilderPage.js +153 -142
  210. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  211. package/dist/bigconsole/pages/DashboardViewPage.js +230 -220
  212. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  213. package/dist/bigconsole/pages/DashboardsPage.js +832 -790
  214. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  215. package/dist/bigconsole/pages/DataParsersPage.js +249 -304
  216. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  217. package/dist/bigconsole/pages/DataSinkBuilderPage.js +324 -349
  218. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  219. package/dist/bigconsole/pages/DataSinkViewPage.js +336 -323
  220. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  221. package/dist/bigconsole/pages/DataSinksPage.js +356 -458
  222. package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
  223. package/dist/bigconsole/pages/DataSourcesPage.js +14 -8
  224. package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
  225. package/dist/bigconsole/pages/HomePage.js +186 -193
  226. package/dist/bigconsole/pages/HomePage.js.map +1 -1
  227. package/dist/bigconsole/pages/InsightsPage.js +901 -724
  228. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  229. package/dist/bigconsole/pages/ParserBuilderPage.js +769 -675
  230. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  231. package/dist/bigconsole/pages/ParserViewPage.js +382 -354
  232. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  233. package/dist/bigconsole/pages/PipelineBuilderPage.js +540 -420
  234. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  235. package/dist/bigconsole/pages/PipelineViewPage.js +416 -384
  236. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  237. package/dist/bigconsole/pages/PipelinesPage.js +260 -309
  238. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  239. package/dist/bigconsole/pages/SettingsPage.js +177 -172
  240. package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
  241. package/dist/bigconsole/pages/WidgetDemoPage.js +278 -142
  242. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  243. package/dist/bigconsole/pages/WorkflowViewPage.js +382 -366
  244. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  245. package/dist/bigconsole/pages/WorkflowsPage.js +202 -316
  246. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  247. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +111 -109
  248. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
  249. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +127 -126
  250. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
  251. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +103 -103
  252. package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
  253. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardsPage.js","names":[],"sources":["../../../src/bigconsole/pages/DashboardsPage.tsx"],"sourcesContent":["/**\n * DashboardsPage\n *\n * List and manage dashboards - fetches data from real backend.\n * Uses fe-libs shared UI components and semantic tokens for consistent styling.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\nimport { useBigConsoleNavigate } from '../context';\nimport { isNative, nativeConfirm, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport {\n AuroraBackground,\n GradientText,\n GlassCard,\n IllustratedEmptyState,\n CTAOverflowMenu,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Plus,\n Upload,\n Search,\n LayoutDashboard,\n Calendar,\n Layers,\n FileText,\n Pencil,\n Trash2,\n Copy,\n LayoutGrid,\n List,\n ChevronLeft,\n ChevronRight,\n} from 'lucide-react';\nimport { useDashboardOperations } from '../hooks';\nimport { CreateDashboardDialog } from '../components/dashboard/CreateDashboardDialog';\nimport { ImportDashboardDialog } from '../components/dashboard/ImportDashboardDialog';\nimport { reportBigConsoleQuotaError } from '../utils/quota';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst VIEW_MODE_STORAGE_KEY = 'bf-bigconsole-dashboards-view';\n\n/** Number of dashboards shown per page in the list/grid views. */\nconst PAGE_SIZE = 12;\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const DashboardsPage: FC = memo(function DashboardsPage() {\n const navigate = useBigConsoleNavigate();\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n },\n [t]\n );\n const [searchQuery, setSearchQuery] = useState('');\n const [currentPage, setCurrentPage] = useState(1);\n const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);\n const [isCreating, setIsCreating] = useState(false);\n const [isImportDialogOpen, setIsImportDialogOpen] = useState(false);\n\n // View mode (grid/list) persisted to localStorage so it survives reloads\n const [viewMode, setViewMode] = useState<'grid' | 'list'>(() => {\n try {\n const stored = window.localStorage.getItem(VIEW_MODE_STORAGE_KEY);\n return stored === 'list' ? 'list' : 'grid';\n } catch {\n return 'grid';\n }\n });\n\n const handleSetViewMode = useCallback((mode: 'grid' | 'list') => {\n setViewMode(mode);\n try {\n window.localStorage.setItem(VIEW_MODE_STORAGE_KEY, mode);\n } catch {\n // Ignore storage errors (e.g. private mode) - view mode still works in-session\n }\n }, []);\n\n const { loading, error, dashboards, createDashboard, deleteDashboard, cloneDashboard, refetch } =\n useDashboardOperations();\n\n // RBAC gating — permission set is resolved by the root PermissionProvider.\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_READ);\n const canCreate = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE);\n const canImport = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_IMPORT);\n\n // Filter dashboards by search query\n const filteredDashboards = dashboards.filter(\n (d) =>\n d.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n d.description?.toLowerCase().includes(searchQuery.toLowerCase())\n );\n\n // Client-side pagination over the filtered result set\n const totalPages = Math.max(1, Math.ceil(filteredDashboards.length / PAGE_SIZE));\n const pageStartIndex = (currentPage - 1) * PAGE_SIZE;\n const paginatedDashboards = filteredDashboards.slice(pageStartIndex, pageStartIndex + PAGE_SIZE);\n\n // Reset to the first page when the search query or view changes so the\n // visible slice always starts from the top of the (possibly new) result set.\n useEffect(() => {\n setCurrentPage(1);\n }, [searchQuery, viewMode]);\n\n // Guard against the current page exceeding the available pages (e.g. after a\n // delete removes the last item on the final page).\n useEffect(() => {\n if (currentPage > totalPages) {\n setCurrentPage(totalPages);\n }\n }, [currentPage, totalPages]);\n\n const handlePrevPage = useCallback(() => {\n setCurrentPage((prev) => Math.max(1, prev - 1));\n }, []);\n\n const handleNextPage = useCallback(() => {\n setCurrentPage((prev) => Math.min(totalPages, prev + 1));\n }, [totalPages]);\n\n const handleGoToPage = useCallback((page: number) => {\n setCurrentPage(page);\n }, []);\n\n const handleOpenCreateDialog = useCallback(() => {\n setIsCreateDialogOpen(true);\n }, []);\n\n /**\n * A template install creates the dashboard inside the dialog rather than\n * through onCreate, so the list has no idea it happened. Refetch and open the\n * new board — landing on it is what makes the \"connect your data\" prompts\n * discoverable.\n */\n const handleTemplateInstalled = useCallback(\n ({ dashboardId }: { dashboardId: string; widgetsNeedingData: number }) => {\n refetch();\n navigate(`/dashboards/${dashboardId}`);\n },\n [refetch, navigate]\n );\n\n const handleCloseCreateDialog = useCallback(() => {\n if (!isCreating) {\n setIsCreateDialogOpen(false);\n }\n }, [isCreating]);\n\n const handleCreateDashboard = useCallback(\n async (data: { name: string; description: string; category: string; tags?: string[] }) => {\n setIsCreating(true);\n try {\n const newDashboard = await createDashboard({\n name: data.name,\n description: data.description,\n category: data.category,\n tags: data.tags,\n });\n\n if (newDashboard) {\n setIsCreateDialogOpen(false);\n navigate(`/dashboards/${newDashboard.id}/builder`);\n }\n } catch (err) {\n if (reportBigConsoleQuotaError(err, 'project')) {\n setIsCreateDialogOpen(false);\n return;\n }\n // Surface the failure instead of swallowing it: log for debugging,\n // notify on native, and rethrow so CreateDashboardDialog displays the error.\n console.error('Failed to create dashboard:', err);\n if (isNative()) void nativeNotify('error');\n throw err;\n } finally {\n setIsCreating(false);\n }\n },\n [createDashboard, navigate]\n );\n\n const handleOpenDashboard = useCallback(\n (dashboardId: string) => {\n navigate(`/dashboards/${dashboardId}`);\n },\n [navigate]\n );\n\n const handleEditDashboard = useCallback(\n (dashboardId: string, e: React.MouseEvent) => {\n e.stopPropagation();\n navigate(`/dashboards/${dashboardId}/builder`);\n },\n [navigate]\n );\n\n const handleDeleteDashboard = useCallback(\n async (dashboardId: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const msg = tr('bigconsole.dashboards.confirmDelete', 'Are you sure you want to delete this dashboard?');\n const native = await nativeConfirm({\n title: 'Delete dashboard?',\n message: msg,\n okButtonTitle: 'Delete',\n cancelButtonTitle: 'Cancel',\n });\n const ok = native === null ? window.confirm(msg) : native;\n if (ok) {\n nativeImpact('medium');\n try {\n await deleteDashboard(dashboardId);\n if (isNative()) void nativeNotify('success');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n }\n },\n [deleteDashboard, tr]\n );\n\n const handleCloneDashboard = useCallback(\n async (dashboardId: string, sourceName: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const defaultName = tr('bigconsole.dashboards.clone.defaultSuffix', `${sourceName} (Copy)`);\n const name = window.prompt(\n tr('bigconsole.dashboards.clone.namePrompt', 'Name for the cloned dashboard:'),\n defaultName\n );\n if (!name || !name.trim()) return;\n nativeImpact('medium');\n try {\n const cloned = await cloneDashboard(dashboardId, name.trim());\n if (cloned) {\n if (isNative()) void nativeNotify('success');\n navigate(`/dashboards/${cloned.id}`);\n }\n } catch (err) {\n if (reportBigConsoleQuotaError(err, 'project')) {\n return;\n }\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n },\n [cloneDashboard, navigate, tr]\n );\n\n const handleOpenImportDialog = useCallback(() => {\n setIsImportDialogOpen(true);\n }, []);\n\n const handleCloseImportDialog = useCallback(() => {\n setIsImportDialogOpen(false);\n }, []);\n\n const handleImportSuccess = useCallback(\n (dashboardId: string, dashboardName: string) => {\n refetch();\n },\n [refetch]\n );\n\n // Format relative date\n const formatRelativeDate = (dateStr: string) => {\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return tr('bigconsole.dashboards.time.justNow', 'Just now');\n if (diffMins < 60) return `${diffMins}${tr('bigconsole.dashboards.time.minutesAgoSuffix', 'm ago')}`;\n if (diffHours < 24) return `${diffHours}${tr('bigconsole.dashboards.time.hoursAgoSuffix', 'h ago')}`;\n if (diffDays < 7) return `${diffDays}${tr('bigconsole.dashboards.time.daysAgoSuffix', 'd ago')}`;\n\n return new Intl.DateTimeFormat('en-US', {\n month: 'short',\n day: 'numeric',\n year: date.getFullYear() !== now.getFullYear() ? 'numeric' : undefined,\n }).format(date);\n };\n\n // Get widget count - uses widgetCount field from backend\n const getWidgetCount = (dashboard: (typeof dashboards)[0]) => {\n return dashboard.widgetCount ?? 0;\n };\n\n // Get page count\n const getPageCount = (dashboard: (typeof dashboards)[0]) => {\n return dashboard.pageCount || 0;\n };\n\n // Error state\n if (error) {\n return (\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <Card\n style={{\n borderColor: 'var(--color-status-error-border)',\n backgroundColor: 'var(--color-status-error-bgSubtle)',\n }}\n >\n <CardContent style={{ padding: 'var(--space-pagePadding)' }}>\n <h3\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-status-error-text)',\n }}\n >\n {tr('bigconsole.dashboards.error.title', 'Error loading dashboards')}\n </h3>\n <p\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-secondary)',\n marginTop: 'var(--space-controlGap)',\n }}\n >\n {error.message}\n </p>\n <Button size=\"sm\" onClick={() => refetch()} style={{ marginTop: 'var(--space-formGap)' }}>\n {tr('bigconsole.dashboards.error.retry', 'Retry')}\n </Button>\n </CardContent>\n </Card>\n </div>\n );\n }\n\n // Permission read gate — wait for the provider to resolve before deciding,\n // then block the page body for callers without dashboard read access.\n if (permissionsLoading) {\n return (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '80px 0' }}>\n <Spinner\n style={{\n height: 'var(--size-icon-xl)',\n width: 'var(--size-icon-xl)',\n }}\n />\n </div>\n );\n }\n\n if (!canRead) {\n return <AccessDenied title=\"Access Denied\" description=\"You don't have permission to view dashboards.\" />;\n }\n\n return (\n <div style={{ minHeight: '100vh', backgroundColor: 'var(--color-bg-canvas)' }}>\n {/* Header Section */}\n <div className=\"relative overflow-hidden border-b border-border-seam bg-gloss-card\">\n <AuroraBackground intensity=\"subtle\" />\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n gap: 'var(--space-formGap)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-formGap)', minWidth: 0 }}>\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-card)',\n backgroundColor: 'var(--color-action-primary-bg)',\n }}\n >\n <LayoutDashboard\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n </div>\n <div>\n <h1\n style={{\n fontSize: 'var(--font-size-heading-h4)',\n fontWeight: 'var(--font-weight-bold)',\n margin: 0,\n color: 'var(--color-text-primary)',\n }}\n >\n <GradientText>{tr('bigconsole.dashboards.title', 'Dashboards')}</GradientText>\n </h1>\n <p style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-secondary)', margin: 0 }}>\n {tr('bigconsole.dashboards.subtitle', 'Create and manage your analytics dashboards')}\n </p>\n </div>\n </div>\n\n <CTAOverflowMenu\n primary={{\n label: tr('bigconsole.dashboards.actions.create', 'Create Dashboard'),\n onSelect: handleOpenCreateDialog,\n disabled: !canCreate,\n icon: (\n <Plus\n style={{\n marginRight: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n ),\n }}\n actions={[\n {\n label: tr('bigconsole.dashboards.actions.import', 'Import'),\n onSelect: handleOpenImportDialog,\n disabled: !canImport,\n icon: <Upload style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />,\n },\n ]}\n />\n </div>\n </div>\n </div>\n\n {/* Main Content */}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <PagePurpose className=\"mb-[var(--space-sectionGap)]\">\n Dashboards are live, shareable views built from widgets that query your data sinks — charts, tables, metrics,\n and drill-downs in one place. Compose a board to monitor a system, share KPIs with your team, or explore data\n interactively.\n </PagePurpose>\n\n {/* Search Bar + View Toggle */}\n <div\n style={{\n marginBottom: 'var(--space-sectionGap)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n gap: 'var(--space-formGap)',\n }}\n >\n <div style={{ position: 'relative', flex: 1, minWidth: 0, maxWidth: '400px' }}>\n <Search\n style={{\n position: 'absolute',\n left: 'var(--space-controlGap)',\n top: '50%',\n transform: 'translateY(-50%)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-text-muted)',\n }}\n />\n <Input\n type=\"text\"\n placeholder={tr('bigconsole.dashboards.search.placeholder', 'Search dashboards...')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={{ paddingLeft: 'var(--size-controlHeight-md)', height: 'var(--size-controlHeight-md)' }}\n />\n </div>\n\n {/* Grid / List view toggle */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-iconGap)',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-bg-sunken)',\n }}\n >\n <Button\n variant={viewMode === 'grid' ? 'default' : 'ghost'}\n size=\"sm\"\n onClick={() => handleSetViewMode('grid')}\n aria-label={tr('bigconsole.dashboards.view.grid', 'Grid view')}\n aria-pressed={viewMode === 'grid'}\n title={tr('bigconsole.dashboards.view.grid', 'Grid view')}\n style={{\n height: 'var(--size-controlHeight-sm)',\n width: 'var(--size-controlHeight-sm)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n >\n <LayoutGrid style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'ghost'}\n size=\"sm\"\n onClick={() => handleSetViewMode('list')}\n aria-label={tr('bigconsole.dashboards.view.list', 'List view')}\n aria-pressed={viewMode === 'list'}\n title={tr('bigconsole.dashboards.view.list', 'List view')}\n style={{\n height: 'var(--size-controlHeight-sm)',\n width: 'var(--size-controlHeight-sm)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n >\n <List style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </div>\n </div>\n\n {/* Loading state */}\n {loading && dashboards.length === 0 && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '80px 0' }}>\n <div style={{ textAlign: 'center' }}>\n <Spinner\n style={{\n height: 'var(--size-icon-xl)',\n width: 'var(--size-icon-xl)',\n margin: '0 auto var(--space-formGap)',\n }}\n />\n <p style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.loading', 'Loading dashboards...')}\n </p>\n </div>\n </div>\n )}\n\n {/* Dashboard Grid */}\n {!loading && viewMode === 'grid' && filteredDashboards.length > 0 && (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(min(320px, 100%), 1fr))',\n gap: 'var(--space-formGap)',\n }}\n >\n {paginatedDashboards.map((dashboard) => (\n <Card\n key={dashboard.id}\n onClick={() => handleOpenDashboard(dashboard.id)}\n style={{\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n }}\n className=\"hover:shadow-md hover:border-primary/50\"\n >\n <CardContent style={{ padding: 'var(--space-cardPadding)' }}>\n {/* Card Header with Icon and Name */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n marginBottom: 'var(--space-formGap)',\n }}\n >\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n flexShrink: 0,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-action-primary-bg)',\n }}\n >\n <LayoutDashboard\n style={{\n height: 'var(--size-icon-md)',\n width: 'var(--size-icon-md)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <h3\n style={{\n fontWeight: 'var(--font-weight-bold)',\n fontSize: 'var(--font-size-body-md)',\n margin: 0,\n color: 'var(--color-text-primary)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {dashboard.name}\n </h3>\n {dashboard.category && (\n <Badge\n variant=\"secondary\"\n style={{\n marginTop: 'var(--space-controlGap)',\n fontSize: '10px',\n fontWeight: 'var(--font-weight-semibold)',\n textTransform: 'uppercase',\n }}\n >\n {dashboard.category}\n </Badge>\n )}\n </div>\n </div>\n\n {/* Description */}\n <p\n style={{\n fontSize: 'var(--font-size-body-sm)',\n lineHeight: 'var(--font-lineHeight-normal)',\n color: 'var(--color-text-secondary)',\n margin: '0 0 var(--space-formGap) 0',\n minHeight: '40px',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {dashboard.description || tr('bigconsole.dashboards.card.noDescription', 'No description provided')}\n </p>\n\n {/* Stats Row */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-formGap)',\n marginBottom: 'var(--space-formGap)',\n padding: 'var(--space-controlGap) var(--space-cardPadding)',\n backgroundColor: 'var(--color-bg-sunken)',\n borderRadius: 'var(--radius-button)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Layers\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {getPageCount(dashboard)}\n </span>\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.card.pages', 'pages')}\n </span>\n </div>\n <div\n style={{ width: '1px', height: 'var(--size-icon-sm)', backgroundColor: 'var(--color-border)' }}\n />\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <FileText\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {getWidgetCount(dashboard)}\n </span>\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.card.widgets', 'widgets')}\n </span>\n </div>\n </div>\n\n {/* Footer with Date and Actions */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingTop: 'var(--space-controlGap)',\n borderTop: '1px solid var(--color-border)',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n }}\n >\n <Calendar\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-text-muted)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-muted)',\n }}\n >\n {formatRelativeDate(dashboard.updatedAt)}\n </span>\n </div>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-controlGap)' }}>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_UPDATE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleEditDashboard(dashboard.id, e)}\n style={{\n height: 'var(--size-controlHeight-sm)',\n width: 'var(--size-controlHeight-sm)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n title={tr('bigconsole.dashboards.actions.editTitle', 'Edit Dashboard')}\n >\n <Pencil style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleCloneDashboard(dashboard.id, dashboard.name, e)}\n style={{\n height: 'var(--size-controlHeight-sm)',\n width: 'var(--size-controlHeight-sm)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n title={tr('bigconsole.dashboards.actions.cloneTitle', 'Clone Dashboard')}\n >\n <Copy style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_DELETE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleDeleteDashboard(dashboard.id, e)}\n style={{\n height: 'var(--size-controlHeight-sm)',\n width: 'var(--size-controlHeight-sm)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n className=\"hover:text-status-error-text hover:bg-status-error-bg/10\"\n title={tr('bigconsole.dashboards.actions.deleteTitle', 'Delete Dashboard')}\n >\n <Trash2 style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {/* Dashboard List */}\n {!loading && viewMode === 'list' && filteredDashboards.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-controlGap)',\n }}\n >\n {paginatedDashboards.map((dashboard) => (\n <Card\n key={dashboard.id}\n onClick={() => handleOpenDashboard(dashboard.id)}\n style={{\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n }}\n className=\"hover:shadow-md hover:border-primary/50\"\n >\n <CardContent style={{ padding: 'var(--space-cardPadding)' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-formGap)',\n flexWrap: 'wrap',\n }}\n >\n {/* Icon */}\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n flexShrink: 0,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-action-primary-bg)',\n }}\n >\n <LayoutDashboard\n style={{\n height: 'var(--size-icon-md)',\n width: 'var(--size-icon-md)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n </div>\n\n {/* Name + Description */}\n <div style={{ flex: 1, minWidth: '180px' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n flexWrap: 'wrap',\n }}\n >\n <h3\n style={{\n fontWeight: 'var(--font-weight-bold)',\n fontSize: 'var(--font-size-body-md)',\n margin: 0,\n color: 'var(--color-text-primary)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n }}\n >\n {dashboard.name}\n </h3>\n {dashboard.category && (\n <Badge\n variant=\"secondary\"\n style={{\n fontSize: '10px',\n fontWeight: 'var(--font-weight-semibold)',\n textTransform: 'uppercase',\n }}\n >\n {dashboard.category}\n </Badge>\n )}\n </div>\n <p\n style={{\n fontSize: 'var(--font-size-body-sm)',\n lineHeight: 'var(--font-lineHeight-normal)',\n color: 'var(--color-text-secondary)',\n margin: 'var(--space-controlGap) 0 0 0',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {dashboard.description ||\n tr('bigconsole.dashboards.card.noDescription', 'No description provided')}\n </p>\n </div>\n\n {/* Stats + Date */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-formGap)',\n flexWrap: 'wrap',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Layers\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {getPageCount(dashboard)}\n </span>\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.card.pages', 'pages')}\n </span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <FileText\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {getWidgetCount(dashboard)}\n </span>\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.card.widgets', 'widgets')}\n </span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Calendar\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-text-muted)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-muted)',\n }}\n >\n {formatRelativeDate(dashboard.updatedAt)}\n </span>\n </div>\n </div>\n\n {/* Actions */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-controlGap)' }}>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_UPDATE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleEditDashboard(dashboard.id, e)}\n style={{\n height: 'var(--size-controlHeight-sm)',\n width: 'var(--size-controlHeight-sm)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n title={tr('bigconsole.dashboards.actions.editTitle', 'Edit Dashboard')}\n >\n <Pencil style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleCloneDashboard(dashboard.id, dashboard.name, e)}\n style={{\n height: 'var(--size-controlHeight-sm)',\n width: 'var(--size-controlHeight-sm)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n title={tr('bigconsole.dashboards.actions.cloneTitle', 'Clone Dashboard')}\n >\n <Copy style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_DELETE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleDeleteDashboard(dashboard.id, e)}\n style={{\n height: 'var(--size-controlHeight-sm)',\n width: 'var(--size-controlHeight-sm)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n className=\"hover:text-status-error-text hover:bg-status-error-bg/10\"\n title={tr('bigconsole.dashboards.actions.deleteTitle', 'Delete Dashboard')}\n >\n <Trash2 style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {/* Pagination controls */}\n {!loading && filteredDashboards.length > PAGE_SIZE && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-controlGap)',\n flexWrap: 'wrap',\n marginTop: 'var(--space-sectionGap)',\n }}\n >\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handlePrevPage}\n disabled={currentPage <= 1}\n aria-label={tr('bigconsole.dashboards.pagination.previous', 'Previous')}\n >\n <ChevronLeft\n style={{\n marginRight: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n {tr('bigconsole.dashboards.pagination.previous', 'Previous')}\n </Button>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)', flexWrap: 'wrap' }}>\n {Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => (\n <Button\n key={page}\n variant={page === currentPage ? 'default' : 'ghost'}\n size=\"sm\"\n onClick={() => handleGoToPage(page)}\n aria-current={page === currentPage ? 'page' : undefined}\n style={{\n minWidth: 'var(--size-controlHeight-sm)',\n height: 'var(--size-controlHeight-sm)',\n padding: '0 var(--space-controlGap)',\n borderRadius: 'var(--radius-button)',\n }}\n >\n {page}\n </Button>\n ))}\n </div>\n\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleNextPage}\n disabled={currentPage >= totalPages}\n aria-label={tr('bigconsole.dashboards.pagination.next', 'Next')}\n >\n {tr('bigconsole.dashboards.pagination.next', 'Next')}\n <ChevronRight\n style={{\n marginLeft: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n </Button>\n\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n marginLeft: 'var(--space-controlGap)',\n }}\n >\n {tr('bigconsole.dashboards.pagination.pageOf', `Page ${currentPage} of ${totalPages}`)}\n </span>\n </div>\n )}\n\n {/* Empty state */}\n {!loading && filteredDashboards.length === 0 && (\n <GlassCard treatment=\"insight\" className=\"border-border-seam\">\n <IllustratedEmptyState\n illustration={searchQuery ? 'empty-search' : 'empty-data'}\n title={\n searchQuery\n ? tr('bigconsole.dashboards.empty.filteredTitle', 'No dashboards found')\n : tr('bigconsole.dashboards.empty.title', 'No dashboards yet')\n }\n description={\n searchQuery\n ? tr('bigconsole.dashboards.empty.filteredDescription', 'Try adjusting your search terms')\n : tr(\n 'bigconsole.dashboards.empty.description',\n 'Get started by creating your first dashboard to visualize your data'\n )\n }\n action={\n !searchQuery ? (\n <div\n style={{\n display: 'flex',\n gap: 'var(--space-controlGap)',\n flexWrap: 'wrap',\n justifyContent: 'center',\n }}\n >\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE} deniedBehavior=\"hide\">\n <Button onClick={handleOpenCreateDialog}>\n <Plus\n style={{\n marginRight: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n {tr('bigconsole.dashboards.actions.create', 'Create Dashboard')}\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_IMPORT} deniedBehavior=\"hide\">\n <Button variant=\"outline\" onClick={handleOpenImportDialog}>\n <Upload\n style={{\n marginRight: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n {tr('bigconsole.dashboards.actions.importDashboard', 'Import Dashboard')}\n </Button>\n </PermissionButton>\n </div>\n ) : undefined\n }\n />\n </GlassCard>\n )}\n </div>\n\n {/* Create Dashboard Dialog */}\n <CreateDashboardDialog\n isOpen={isCreateDialogOpen}\n isCreating={isCreating}\n onClose={handleCloseCreateDialog}\n onCreate={handleCreateDashboard}\n onTemplateInstalled={handleTemplateInstalled}\n />\n\n {/* Import Dashboard Dialog */}\n <ImportDashboardDialog\n isOpen={isImportDialogOpen}\n onClose={handleCloseImportDialog}\n onSuccess={handleImportSuccess}\n />\n </div>\n );\n});\n\nexport default DashboardsPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardsPage.js","names":[],"sources":["../../../src/bigconsole/pages/DashboardsPage.tsx"],"sourcesContent":["/**\n * DashboardsPage\n *\n * List and manage dashboards - fetches data from real backend.\n * Uses fe-libs shared UI components and semantic tokens for consistent styling.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\nimport { useBigConsoleNavigate } from '../context';\nimport { isNative, nativeConfirm, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport {\n AuroraBackground,\n GradientText,\n GlassCard,\n IllustratedEmptyState,\n CTAOverflowMenu,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Plus,\n Upload,\n Search,\n LayoutDashboard,\n Calendar,\n Layers,\n FileText,\n Pencil,\n Trash2,\n Copy,\n LayoutGrid,\n List,\n ChevronLeft,\n ChevronRight,\n} from 'lucide-react';\nimport { useDashboardOperations } from '../hooks';\nimport { CreateDashboardDialog } from '../components/dashboard/CreateDashboardDialog';\nimport { ImportDashboardDialog } from '../components/dashboard/ImportDashboardDialog';\nimport { Section, SectionStack } from '../components/common';\nimport { reportBigConsoleQuotaError } from '../utils/quota';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst VIEW_MODE_STORAGE_KEY = 'bf-bigconsole-dashboards-view';\n\n/** Number of dashboards shown per page in the list/grid views. */\nconst PAGE_SIZE = 12;\n\n/** How many numbered page buttons to render before falling back to a window. */\nconst MAX_PAGE_BUTTONS = 7;\n\n/**\n * Numbered pages to render around the current one.\n *\n * Rendering one button per page turns a workspace with a hundred boards into a\n * multi-line wall of numbers — on a 390px viewport that block is taller than\n * the result it paginates. Windowing keeps the footer to a single row at every\n * breakpoint; `null` marks an elided run.\n */\nfunction getPageWindow(currentPage: number, totalPages: number): Array<number | null> {\n if (totalPages <= MAX_PAGE_BUTTONS) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages = new Set<number>([1, totalPages, currentPage]);\n if (currentPage - 1 > 1) pages.add(currentPage - 1);\n if (currentPage + 1 < totalPages) pages.add(currentPage + 1);\n\n const ordered = Array.from(pages).sort((a, b) => a - b);\n const windowed: Array<number | null> = [];\n ordered.forEach((page, index) => {\n if (index > 0 && page - ordered[index - 1] > 1) windowed.push(null);\n windowed.push(page);\n });\n return windowed;\n}\n\n// ============================================================================\n// Page header band\n// ============================================================================\n\ninterface DashboardsHeaderBandProps {\n title: string;\n subtitle: string;\n createLabel: string;\n importLabel: string;\n onCreate: () => void;\n onImport: () => void;\n /** RBAC: the CTA is rendered but disabled without dashboard:create. */\n canCreate: boolean;\n /** RBAC: the overflow import action is disabled without dashboard:import. */\n canImport: boolean;\n}\n\n/**\n * The route's identity strip. It is deliberately the only decorated band on the\n * page: everything below it steps down to plain sections, so the eye always\n * knows where the page starts and where the content starts. Shared with the\n * error state so a failed fetch never costs the user the page identity.\n */\nconst DashboardsHeaderBand: FC<DashboardsHeaderBandProps> = memo(function DashboardsHeaderBand({\n title,\n subtitle,\n createLabel,\n importLabel,\n onCreate,\n onImport,\n canCreate,\n canImport,\n}) {\n return (\n <div className=\"relative overflow-hidden border-b border-[var(--color-border-seam)] bg-[image:var(--gradient-gloss-card)]\">\n <AuroraBackground intensity=\"subtle\" />\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n gap: 'var(--space-formGap)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-formGap)', minWidth: 0 }}>\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n flexShrink: 0,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-card)',\n backgroundColor: 'var(--color-action-primary-bg)',\n }}\n >\n <LayoutDashboard\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n </div>\n <div style={{ minWidth: 0 }}>\n <h1\n style={{\n fontSize: 'var(--font-size-heading-h4)',\n fontWeight: 'var(--font-weight-bold)',\n margin: 0,\n color: 'var(--color-text-primary)',\n }}\n >\n <GradientText>{title}</GradientText>\n </h1>\n <p style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-secondary)', margin: 0 }}>\n {subtitle}\n </p>\n </div>\n </div>\n\n <CTAOverflowMenu\n primary={{\n label: createLabel,\n onSelect: onCreate,\n disabled: !canCreate,\n icon: (\n <Plus\n style={{\n marginRight: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n ),\n }}\n actions={[\n {\n label: importLabel,\n onSelect: onImport,\n disabled: !canImport,\n icon: <Upload style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />,\n },\n ]}\n />\n </div>\n </div>\n </div>\n );\n});\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const DashboardsPage: FC = memo(function DashboardsPage() {\n const navigate = useBigConsoleNavigate();\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n },\n [t]\n );\n const [searchQuery, setSearchQuery] = useState('');\n const [currentPage, setCurrentPage] = useState(1);\n const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);\n const [isCreating, setIsCreating] = useState(false);\n const [isImportDialogOpen, setIsImportDialogOpen] = useState(false);\n\n // View mode (grid/list) persisted to localStorage so it survives reloads\n const [viewMode, setViewMode] = useState<'grid' | 'list'>(() => {\n try {\n const stored = window.localStorage.getItem(VIEW_MODE_STORAGE_KEY);\n return stored === 'list' ? 'list' : 'grid';\n } catch {\n return 'grid';\n }\n });\n\n const handleSetViewMode = useCallback((mode: 'grid' | 'list') => {\n setViewMode(mode);\n try {\n window.localStorage.setItem(VIEW_MODE_STORAGE_KEY, mode);\n } catch {\n // Ignore storage errors (e.g. private mode) - view mode still works in-session\n }\n }, []);\n\n const { loading, error, dashboards, createDashboard, deleteDashboard, cloneDashboard, refetch } =\n useDashboardOperations();\n\n // RBAC gating — permission set is resolved by the root PermissionProvider.\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_READ);\n const canCreate = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE);\n const canImport = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_IMPORT);\n\n // Filter dashboards by search query\n const filteredDashboards = dashboards.filter(\n (d) =>\n d.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n d.description?.toLowerCase().includes(searchQuery.toLowerCase())\n );\n\n // Client-side pagination over the filtered result set\n const totalPages = Math.max(1, Math.ceil(filteredDashboards.length / PAGE_SIZE));\n const pageStartIndex = (currentPage - 1) * PAGE_SIZE;\n const paginatedDashboards = filteredDashboards.slice(pageStartIndex, pageStartIndex + PAGE_SIZE);\n\n // Reset to the first page when the search query or view changes so the\n // visible slice always starts from the top of the (possibly new) result set.\n useEffect(() => {\n setCurrentPage(1);\n }, [searchQuery, viewMode]);\n\n // Guard against the current page exceeding the available pages (e.g. after a\n // delete removes the last item on the final page).\n useEffect(() => {\n if (currentPage > totalPages) {\n setCurrentPage(totalPages);\n }\n }, [currentPage, totalPages]);\n\n const handlePrevPage = useCallback(() => {\n setCurrentPage((prev) => Math.max(1, prev - 1));\n }, []);\n\n const handleNextPage = useCallback(() => {\n setCurrentPage((prev) => Math.min(totalPages, prev + 1));\n }, [totalPages]);\n\n const handleGoToPage = useCallback((page: number) => {\n setCurrentPage(page);\n }, []);\n\n const handleOpenCreateDialog = useCallback(() => {\n setIsCreateDialogOpen(true);\n }, []);\n\n /**\n * A template install creates the dashboard inside the dialog rather than\n * through onCreate, so the list has no idea it happened. Refetch and open the\n * new board — landing on it is what makes the \"connect your data\" prompts\n * discoverable.\n */\n const handleTemplateInstalled = useCallback(\n ({ dashboardId }: { dashboardId: string; widgetsNeedingData: number }) => {\n refetch();\n navigate(`/dashboards/${dashboardId}`);\n },\n [refetch, navigate]\n );\n\n const handleCloseCreateDialog = useCallback(() => {\n if (!isCreating) {\n setIsCreateDialogOpen(false);\n }\n }, [isCreating]);\n\n const handleCreateDashboard = useCallback(\n async (data: { name: string; description: string; category: string; tags?: string[] }) => {\n setIsCreating(true);\n try {\n const newDashboard = await createDashboard({\n name: data.name,\n description: data.description,\n category: data.category,\n tags: data.tags,\n });\n\n if (newDashboard) {\n setIsCreateDialogOpen(false);\n navigate(`/dashboards/${newDashboard.id}/builder`);\n }\n } catch (err) {\n if (reportBigConsoleQuotaError(err, 'project')) {\n setIsCreateDialogOpen(false);\n return;\n }\n // Surface the failure instead of swallowing it: log for debugging,\n // notify on native, and rethrow so CreateDashboardDialog displays the error.\n console.error('Failed to create dashboard:', err);\n if (isNative()) void nativeNotify('error');\n throw err;\n } finally {\n setIsCreating(false);\n }\n },\n [createDashboard, navigate]\n );\n\n const handleOpenDashboard = useCallback(\n (dashboardId: string) => {\n navigate(`/dashboards/${dashboardId}`);\n },\n [navigate]\n );\n\n const handleEditDashboard = useCallback(\n (dashboardId: string, e: React.MouseEvent) => {\n e.stopPropagation();\n navigate(`/dashboards/${dashboardId}/builder`);\n },\n [navigate]\n );\n\n const handleDeleteDashboard = useCallback(\n async (dashboardId: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const msg = tr('bigconsole.dashboards.confirmDelete', 'Are you sure you want to delete this dashboard?');\n const native = await nativeConfirm({\n title: 'Delete dashboard?',\n message: msg,\n okButtonTitle: 'Delete',\n cancelButtonTitle: 'Cancel',\n });\n const ok = native === null ? window.confirm(msg) : native;\n if (ok) {\n nativeImpact('medium');\n try {\n await deleteDashboard(dashboardId);\n if (isNative()) void nativeNotify('success');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n }\n },\n [deleteDashboard, tr]\n );\n\n const handleCloneDashboard = useCallback(\n async (dashboardId: string, sourceName: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const defaultName = t('bigconsole.dashboards.clone.defaultSuffix', '{{sourceName}} (Copy)', {\n sourceName,\n });\n const name = window.prompt(\n tr('bigconsole.dashboards.clone.namePrompt', 'Name for the cloned dashboard:'),\n defaultName\n );\n if (!name || !name.trim()) return;\n nativeImpact('medium');\n try {\n const cloned = await cloneDashboard(dashboardId, name.trim());\n if (cloned) {\n if (isNative()) void nativeNotify('success');\n navigate(`/dashboards/${cloned.id}`);\n }\n } catch (err) {\n if (reportBigConsoleQuotaError(err, 'project')) {\n return;\n }\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n },\n [cloneDashboard, navigate, tr, t]\n );\n\n const handleOpenImportDialog = useCallback(() => {\n setIsImportDialogOpen(true);\n }, []);\n\n const handleCloseImportDialog = useCallback(() => {\n setIsImportDialogOpen(false);\n }, []);\n\n const handleImportSuccess = useCallback(\n (_dashboardId: string, _dashboardName: string) => {\n refetch();\n },\n [refetch]\n );\n\n // Format relative date\n const formatRelativeDate = (dateStr: string) => {\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return tr('bigconsole.dashboards.time.justNow', 'Just now');\n if (diffMins < 60) return `${diffMins}${tr('bigconsole.dashboards.time.minutesAgoSuffix', 'm ago')}`;\n if (diffHours < 24) return `${diffHours}${tr('bigconsole.dashboards.time.hoursAgoSuffix', 'h ago')}`;\n if (diffDays < 7) return `${diffDays}${tr('bigconsole.dashboards.time.daysAgoSuffix', 'd ago')}`;\n\n return new Intl.DateTimeFormat('en-US', {\n month: 'short',\n day: 'numeric',\n year: date.getFullYear() !== now.getFullYear() ? 'numeric' : undefined,\n }).format(date);\n };\n\n // Get widget count - uses widgetCount field from backend\n const getWidgetCount = (dashboard: (typeof dashboards)[0]) => {\n return dashboard.widgetCount ?? 0;\n };\n\n // Get page count\n const getPageCount = (dashboard: (typeof dashboards)[0]) => {\n return dashboard.pageCount || 0;\n };\n\n const headerBand = (\n <DashboardsHeaderBand\n title={tr('bigconsole.dashboards.title', 'Dashboards')}\n subtitle={tr('bigconsole.dashboards.subtitle', 'Create and manage your analytics dashboards')}\n createLabel={tr('bigconsole.dashboards.actions.create', 'Create Dashboard')}\n importLabel={tr('bigconsole.dashboards.actions.import', 'Import')}\n onCreate={handleOpenCreateDialog}\n onImport={handleOpenImportDialog}\n canCreate={canCreate}\n canImport={canImport}\n />\n );\n\n // Permission read gate — wait for the provider to resolve before deciding,\n // then block the page body for callers without dashboard read access.\n if (permissionsLoading) {\n return (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '80px 0' }}>\n <Spinner\n style={{\n height: 'var(--size-icon-xl)',\n width: 'var(--size-icon-xl)',\n }}\n />\n </div>\n );\n }\n\n if (!canRead) {\n return <AccessDenied title=\"Access Denied\" description=\"You don't have permission to view dashboards.\" />;\n }\n\n // Error state — keeps the page identity so the user still knows where they are.\n if (error) {\n return (\n <div style={{ minHeight: '100vh', backgroundColor: 'var(--color-bg-canvas)' }}>\n {headerBand}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <Section\n headingLevel={2}\n tone=\"danger\"\n title={tr('bigconsole.dashboards.error.title', 'Error loading dashboards')}\n description={error.message}\n data-testid=\"dashboards-error\"\n actions={\n <Button size=\"sm\" onClick={() => refetch()}>\n {tr('bigconsole.dashboards.error.retry', 'Retry')}\n </Button>\n }\n />\n </div>\n </div>\n );\n }\n\n const resultCount = filteredDashboards.length;\n\n return (\n <div style={{ minHeight: '100vh', backgroundColor: 'var(--color-bg-canvas)' }}>\n {/* Header Section */}\n {headerBand}\n\n {/* Main Content */}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <SectionStack>\n {/* Supporting context — deliberately recessed so it never competes\n with the results it introduces. */}\n <Section\n emphasis=\"muted\"\n padding=\"compact\"\n aria-label={tr('bigconsole.dashboards.about', 'About dashboards')}\n >\n <PagePurpose className=\"max-w-[80ch]\">\n Dashboards are live, shareable views built from widgets that query your data sinks — charts, tables,\n metrics, and drill-downs in one place. Compose a board to monitor a system, share KPIs with your team, or\n explore data interactively.\n </PagePurpose>\n </Section>\n\n {/* The point of this route: the boards themselves. */}\n <Section\n headingLevel={2}\n emphasis=\"primary\"\n data-testid=\"dashboards-results\"\n title={tr('bigconsole.dashboards.results.title', 'Your dashboards')}\n description={tr(\n 'bigconsole.dashboards.results.description',\n 'Open a board to view it, or use the card actions to edit, duplicate or delete.'\n )}\n meta={\n <Badge\n variant=\"secondary\"\n aria-label={tr('bigconsole.dashboards.results.count', `${resultCount} dashboards`)}\n >\n {resultCount}\n </Badge>\n }\n actions={\n <div\n role=\"group\"\n aria-label={tr('bigconsole.dashboards.view.label', 'Result layout')}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n padding: 'var(--space-iconGap)',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-bg-sunken)',\n }}\n >\n <Button\n variant={viewMode === 'grid' ? 'default' : 'ghost'}\n size=\"sm\"\n onClick={() => handleSetViewMode('grid')}\n aria-label={tr('bigconsole.dashboards.view.grid', 'Grid view')}\n aria-pressed={viewMode === 'grid'}\n title={tr('bigconsole.dashboards.view.grid', 'Grid view')}\n style={{\n height: 'var(--size-controlHeight-md)',\n width: 'var(--size-controlHeight-md)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n >\n <LayoutGrid style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'ghost'}\n size=\"sm\"\n onClick={() => handleSetViewMode('list')}\n aria-label={tr('bigconsole.dashboards.view.list', 'List view')}\n aria-pressed={viewMode === 'list'}\n title={tr('bigconsole.dashboards.view.list', 'List view')}\n style={{\n height: 'var(--size-controlHeight-md)',\n width: 'var(--size-controlHeight-md)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n >\n <List style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </div>\n }\n bodyClassName=\"flex flex-col gap-form-gap\"\n >\n {/* Search — grouped with the results it filters, not floating above them */}\n <div style={{ position: 'relative', width: '100%', maxWidth: '420px' }}>\n <Search\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n left: 'var(--space-controlGap)',\n top: '50%',\n transform: 'translateY(-50%)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-text-muted)',\n }}\n />\n <Input\n type=\"search\"\n aria-label={tr('bigconsole.dashboards.search.placeholder', 'Search dashboards...')}\n placeholder={tr('bigconsole.dashboards.search.placeholder', 'Search dashboards...')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={{ paddingLeft: 'var(--size-controlHeight-md)', height: 'var(--size-controlHeight-md)' }}\n />\n </div>\n\n {/* Loading state */}\n {loading && dashboards.length === 0 && (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '80px 0' }}>\n <div style={{ textAlign: 'center' }}>\n <Spinner\n style={{\n height: 'var(--size-icon-xl)',\n width: 'var(--size-icon-xl)',\n margin: '0 auto var(--space-formGap)',\n }}\n />\n <p style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.loading', 'Loading dashboards...')}\n </p>\n </div>\n </div>\n )}\n\n {/* Dashboard Grid */}\n {!loading && viewMode === 'grid' && filteredDashboards.length > 0 && (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(min(320px, 100%), 1fr))',\n gap: 'var(--space-formGap)',\n }}\n >\n {paginatedDashboards.map((dashboard) => (\n <Card\n key={dashboard.id}\n onClick={() => handleOpenDashboard(dashboard.id)}\n style={{ cursor: 'pointer' }}\n className=\"motion-safe:transition-[box-shadow,border-color] hover:border-[var(--color-border-hover)] hover:shadow-[var(--shadow-elevation-2)]\"\n >\n <CardContent style={{ padding: 'var(--space-cardPadding)' }}>\n {/* Card Header with Icon and Name */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n marginBottom: 'var(--space-formGap)',\n }}\n >\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n flexShrink: 0,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-bg-accentSubtle)',\n }}\n >\n <LayoutDashboard\n aria-hidden=\"true\"\n style={{\n height: 'var(--size-icon-md)',\n width: 'var(--size-icon-md)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <h3\n style={{\n fontWeight: 'var(--font-weight-bold)',\n fontSize: 'var(--font-size-body-md)',\n margin: 0,\n color: 'var(--color-text-primary)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {dashboard.name}\n </h3>\n {dashboard.category && (\n <Badge\n variant=\"secondary\"\n style={{\n marginTop: 'var(--space-controlGap)',\n fontSize: '10px',\n fontWeight: 'var(--font-weight-semibold)',\n textTransform: 'uppercase',\n }}\n >\n {dashboard.category}\n </Badge>\n )}\n </div>\n </div>\n\n {/* Description */}\n <p\n style={{\n fontSize: 'var(--font-size-body-sm)',\n lineHeight: 'var(--font-lineHeight-normal)',\n color: 'var(--color-text-secondary)',\n margin: '0 0 var(--space-formGap) 0',\n minHeight: '40px',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {dashboard.description ||\n tr('bigconsole.dashboards.card.noDescription', 'No description provided')}\n </p>\n\n {/* Stats Row */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-formGap)',\n marginBottom: 'var(--space-formGap)',\n padding: 'var(--space-controlGap) var(--space-cardPadding)',\n backgroundColor: 'var(--color-bg-sunken)',\n borderRadius: 'var(--radius-button)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Layers\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {getPageCount(dashboard)}\n </span>\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.card.pages', 'pages')}\n </span>\n </div>\n <div\n style={{\n width: '1px',\n height: 'var(--size-icon-sm)',\n backgroundColor: 'var(--color-border-subtle)',\n }}\n />\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <FileText\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {getWidgetCount(dashboard)}\n </span>\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.card.widgets', 'widgets')}\n </span>\n </div>\n </div>\n\n {/* Footer with Date and Actions */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n gap: 'var(--space-controlGap)',\n paddingTop: 'var(--space-controlGap)',\n borderTop: '1px solid var(--color-border-subtle)',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n }}\n >\n <Calendar\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-text-muted)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-muted)',\n }}\n >\n {formatRelativeDate(dashboard.updatedAt)}\n </span>\n </div>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-controlGap)' }}>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_UPDATE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleEditDashboard(dashboard.id, e)}\n style={{\n height: 'var(--size-controlHeight-md)',\n width: 'var(--size-controlHeight-md)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n title={tr('bigconsole.dashboards.actions.editTitle', 'Edit Dashboard')}\n >\n <Pencil style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleCloneDashboard(dashboard.id, dashboard.name, e)}\n style={{\n height: 'var(--size-controlHeight-md)',\n width: 'var(--size-controlHeight-md)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n title={tr('bigconsole.dashboards.actions.cloneTitle', 'Clone Dashboard')}\n >\n <Copy style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_DELETE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleDeleteDashboard(dashboard.id, e)}\n style={{\n height: 'var(--size-controlHeight-md)',\n width: 'var(--size-controlHeight-md)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n className=\"hover:text-status-error-text hover:bg-status-error-bg/10\"\n title={tr('bigconsole.dashboards.actions.deleteTitle', 'Delete Dashboard')}\n >\n <Trash2 style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {/* Dashboard List */}\n {!loading && viewMode === 'list' && filteredDashboards.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-controlGap)',\n }}\n >\n {paginatedDashboards.map((dashboard) => (\n <Card\n key={dashboard.id}\n onClick={() => handleOpenDashboard(dashboard.id)}\n style={{ cursor: 'pointer' }}\n className=\"motion-safe:transition-[box-shadow,border-color] hover:border-[var(--color-border-hover)] hover:shadow-[var(--shadow-elevation-2)]\"\n >\n <CardContent style={{ padding: 'var(--space-cardPadding)' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-formGap)',\n flexWrap: 'wrap',\n }}\n >\n {/* Icon */}\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n flexShrink: 0,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-button)',\n backgroundColor: 'var(--color-bg-accentSubtle)',\n }}\n >\n <LayoutDashboard\n aria-hidden=\"true\"\n style={{\n height: 'var(--size-icon-md)',\n width: 'var(--size-icon-md)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n </div>\n\n {/* Name + Description */}\n <div style={{ flex: '1 1 12rem', minWidth: 0 }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n flexWrap: 'wrap',\n }}\n >\n <h3\n style={{\n fontWeight: 'var(--font-weight-bold)',\n fontSize: 'var(--font-size-body-md)',\n margin: 0,\n color: 'var(--color-text-primary)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n }}\n >\n {dashboard.name}\n </h3>\n {dashboard.category && (\n <Badge\n variant=\"secondary\"\n style={{\n fontSize: '10px',\n fontWeight: 'var(--font-weight-semibold)',\n textTransform: 'uppercase',\n }}\n >\n {dashboard.category}\n </Badge>\n )}\n </div>\n <p\n style={{\n fontSize: 'var(--font-size-body-sm)',\n lineHeight: 'var(--font-lineHeight-normal)',\n color: 'var(--color-text-secondary)',\n margin: 'var(--space-controlGap) 0 0 0',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {dashboard.description ||\n tr('bigconsole.dashboards.card.noDescription', 'No description provided')}\n </p>\n </div>\n\n {/* Stats + Date */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-formGap)',\n flexWrap: 'wrap',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Layers\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {getPageCount(dashboard)}\n </span>\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.card.pages', 'pages')}\n </span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <FileText\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-action-primary-bg)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {getWidgetCount(dashboard)}\n </span>\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {tr('bigconsole.dashboards.card.widgets', 'widgets')}\n </span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Calendar\n style={{\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-text-muted)',\n }}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-muted)',\n }}\n >\n {formatRelativeDate(dashboard.updatedAt)}\n </span>\n </div>\n </div>\n\n {/* Actions */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-controlGap)' }}>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_UPDATE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleEditDashboard(dashboard.id, e)}\n style={{\n height: 'var(--size-controlHeight-md)',\n width: 'var(--size-controlHeight-md)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n title={tr('bigconsole.dashboards.actions.editTitle', 'Edit Dashboard')}\n >\n <Pencil style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleCloneDashboard(dashboard.id, dashboard.name, e)}\n style={{\n height: 'var(--size-controlHeight-md)',\n width: 'var(--size-controlHeight-md)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n title={tr('bigconsole.dashboards.actions.cloneTitle', 'Clone Dashboard')}\n >\n <Copy style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_DELETE} deniedBehavior=\"hide\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => handleDeleteDashboard(dashboard.id, e)}\n style={{\n height: 'var(--size-controlHeight-md)',\n width: 'var(--size-controlHeight-md)',\n padding: 0,\n borderRadius: 'var(--radius-button)',\n }}\n className=\"hover:text-status-error-text hover:bg-status-error-bg/10\"\n title={tr('bigconsole.dashboards.actions.deleteTitle', 'Delete Dashboard')}\n >\n <Trash2 style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n </Button>\n </PermissionButton>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {/* Pagination — a footer control, separated from the results it pages */}\n {!loading && filteredDashboards.length > PAGE_SIZE && (\n <nav\n aria-label={tr('bigconsole.dashboards.pagination.label', 'Dashboard pages')}\n className=\"flex flex-wrap items-center justify-center gap-control-gap border-t border-[var(--color-border-subtle)] pt-control-gap\"\n >\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handlePrevPage}\n disabled={currentPage <= 1}\n aria-label={tr('bigconsole.dashboards.pagination.previous', 'Previous')}\n style={{ minHeight: 'var(--size-controlHeight-md)' }}\n >\n <ChevronLeft\n style={{\n marginRight: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n {tr('bigconsole.dashboards.pagination.previous', 'Previous')}\n </Button>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)', flexWrap: 'wrap' }}>\n {getPageWindow(currentPage, totalPages).map((page, index) =>\n page === null ? (\n <span\n key={`gap-${index}`}\n aria-hidden=\"true\"\n style={{ color: 'var(--color-text-muted)', padding: '0 var(--space-iconGap)' }}\n >\n …\n </span>\n ) : (\n <Button\n key={page}\n variant={page === currentPage ? 'default' : 'ghost'}\n size=\"sm\"\n onClick={() => handleGoToPage(page)}\n aria-current={page === currentPage ? 'page' : undefined}\n aria-label={tr('bigconsole.dashboards.pagination.page', `Page ${page}`)}\n style={{\n minWidth: 'var(--size-controlHeight-md)',\n height: 'var(--size-controlHeight-md)',\n padding: '0 var(--space-controlGap)',\n borderRadius: 'var(--radius-button)',\n }}\n >\n {page}\n </Button>\n )\n )}\n </div>\n\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleNextPage}\n disabled={currentPage >= totalPages}\n aria-label={tr('bigconsole.dashboards.pagination.next', 'Next')}\n style={{ minHeight: 'var(--size-controlHeight-md)' }}\n >\n {tr('bigconsole.dashboards.pagination.next', 'Next')}\n <ChevronRight\n style={{\n marginLeft: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n </Button>\n\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n }}\n >\n {t('bigconsole.dashboards.pagination.pageOf', 'Page {{currentPage}} of {{totalPages}}', {\n currentPage,\n totalPages,\n })}\n </span>\n </nav>\n )}\n\n {/* Empty state */}\n {!loading && filteredDashboards.length === 0 && (\n <GlassCard treatment=\"insight\" className=\"border-[var(--color-border-seam)]\">\n <IllustratedEmptyState\n illustration={searchQuery ? 'empty-search' : 'empty-data'}\n title={\n searchQuery\n ? tr('bigconsole.dashboards.empty.filteredTitle', 'No dashboards found')\n : tr('bigconsole.dashboards.empty.title', 'No dashboards yet')\n }\n description={\n searchQuery\n ? tr('bigconsole.dashboards.empty.filteredDescription', 'Try adjusting your search terms')\n : tr(\n 'bigconsole.dashboards.empty.description',\n 'Get started by creating your first dashboard to visualize your data'\n )\n }\n action={\n !searchQuery ? (\n <div\n style={{\n display: 'flex',\n gap: 'var(--space-controlGap)',\n flexWrap: 'wrap',\n justifyContent: 'center',\n }}\n >\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE} deniedBehavior=\"hide\">\n <Button onClick={handleOpenCreateDialog}>\n <Plus\n style={{\n marginRight: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n {tr('bigconsole.dashboards.actions.create', 'Create Dashboard')}\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.DASHBOARD_IMPORT} deniedBehavior=\"hide\">\n <Button variant=\"outline\" onClick={handleOpenImportDialog}>\n <Upload\n style={{\n marginRight: 'var(--space-iconGap)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n }}\n />\n {tr('bigconsole.dashboards.actions.importDashboard', 'Import Dashboard')}\n </Button>\n </PermissionButton>\n </div>\n ) : undefined\n }\n />\n </GlassCard>\n )}\n </Section>\n </SectionStack>\n </div>\n\n {/* Create Dashboard Dialog */}\n <CreateDashboardDialog\n isOpen={isCreateDialogOpen}\n isCreating={isCreating}\n onClose={handleCloseCreateDialog}\n onCreate={handleCreateDashboard}\n onTemplateInstalled={handleTemplateInstalled}\n />\n\n {/* Import Dashboard Dialog */}\n <ImportDashboardDialog\n isOpen={isImportDialogOpen}\n onClose={handleCloseImportDialog}\n onSuccess={handleImportSuccess}\n />\n </div>\n );\n});\n\nexport default DashboardsPage;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqDA,IAAM,IAAwB,iCAGxB,IAAY,IAGZ,IAAmB;AAUzB,SAAS,GAAc,GAAqB,GAA0C;AACpF,KAAI,KAAc,EAChB,QAAO,MAAM,KAAK,EAAE,QAAQ,GAAY,GAAG,GAAG,MAAM,IAAI,EAAE;CAG5D,IAAM,IAAQ,IAAI,IAAY;EAAC;EAAG;EAAY;EAAY,CAAC;AAE3D,CADI,IAAc,IAAI,KAAG,EAAM,IAAI,IAAc,EAAE,EAC/C,IAAc,IAAI,KAAY,EAAM,IAAI,IAAc,EAAE;CAE5D,IAAM,IAAU,MAAM,KAAK,EAAM,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE,EACjD,IAAiC,EAAE;AAKzC,QAJA,EAAQ,SAAS,GAAM,MAAU;AAE/B,EADI,IAAQ,KAAK,IAAO,EAAQ,IAAQ,KAAK,KAAG,EAAS,KAAK,KAAK,EACnE,EAAS,KAAK,EAAK;GACnB,EACK;;AA0BT,IAAM,KAAsD,EAAK,SAA8B,EAC7F,UACA,aACA,gBACA,gBACA,aACA,aACA,cACA,gBACC;AACD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD,EAAkB,WAAU,UAAW,CAAA,EACvC,kBAAC,OAAD;GAAK,OAAO,EAAE,SAAS,4BAA4B;aACjD,kBAAC,OAAD;IACE,OAAO;KACL,SAAS;KACT,YAAY;KACZ,gBAAgB;KAChB,UAAU;KACV,KAAK;KACN;cAPH,CASE,kBAAC,OAAD;KAAK,OAAO;MAAE,SAAS;MAAQ,YAAY;MAAU,KAAK;MAAwB,UAAU;MAAG;eAA/F,CACE,kBAAC,OAAD;MACE,OAAO;OACL,SAAS;OACT,QAAQ;OACR,OAAO;OACP,YAAY;OACZ,YAAY;OACZ,gBAAgB;OAChB,cAAc;OACd,iBAAiB;OAClB;gBAED,kBAAC,GAAD,EACE,OAAO;OACL,QAAQ;OACR,OAAO;OACP,OAAO;OACR,EACD,CAAA;MACE,CAAA,EACN,kBAAC,OAAD;MAAK,OAAO,EAAE,UAAU,GAAG;gBAA3B,CACE,kBAAC,MAAD;OACE,OAAO;QACL,UAAU;QACV,YAAY;QACZ,QAAQ;QACR,OAAO;QACR;iBAED,kBAAC,GAAD,EAAA,UAAe,GAAqB,CAAA;OACjC,CAAA,EACL,kBAAC,KAAD;OAAG,OAAO;QAAE,UAAU;QAA4B,OAAO;QAA+B,QAAQ;QAAG;iBAChG;OACC,CAAA,CACA;QACF;QAEN,kBAAC,GAAD;KACE,SAAS;MACP,OAAO;MACP,UAAU;MACV,UAAU,CAAC;MACX,MACE,kBAAC,GAAD,EACE,OAAO;OACL,aAAa;OACb,QAAQ;OACR,OAAO;OACR,EACD,CAAA;MAEL;KACD,SAAS,CACP;MACE,OAAO;MACP,UAAU;MACV,UAAU,CAAC;MACX,MAAM,kBAAC,IAAD,EAAQ,OAAO;OAAE,QAAQ;OAAuB,OAAO;OAAuB,EAAI,CAAA;MACzF,CACF;KACD,CAAA,CACE;;GACF,CAAA,CACF;;EAER,EAMW,IAAqB,EAAK,WAA0B;CAC/D,IAAM,IAAW,GAAuB,EAClC,EAAE,SAAM,IAAS,EACjB,IAAK,GACR,GAAa,MAAqB;EACjC,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAEzC,CAAC,EAAE,CACJ,EACK,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAa,KAAkB,EAAS,EAAE,EAC3C,CAAC,IAAoB,KAAyB,EAAS,GAAM,EAC7D,CAAC,GAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,IAAoB,KAAyB,EAAS,GAAM,EAG7D,CAAC,GAAU,MAAe,QAAgC;AAC9D,MAAI;AAEF,UADe,OAAO,aAAa,QAAQ,EAAsB,KAC/C,SAAS,SAAS;UAC9B;AACN,UAAO;;GAET,EAEI,IAAoB,GAAa,MAA0B;AAC/D,KAAY,EAAK;AACjB,MAAI;AACF,UAAO,aAAa,QAAQ,GAAuB,EAAK;UAClD;IAGP,EAAE,CAAC,EAEA,EAAE,YAAS,WAAO,eAAY,oBAAiB,oBAAiB,mBAAgB,eACpF,GAAwB,EAGpB,EAAE,kBAAe,WAAW,OAAuB,IAAgB,EACnE,KAAU,EAAc,EAAuB,eAAe,EAC9D,KAAY,EAAc,EAAuB,iBAAiB,EAClE,KAAY,EAAc,EAAuB,iBAAiB,EAGlE,IAAqB,EAAW,QACnC,MACC,EAAE,KAAK,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,IACxD,EAAE,aAAa,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,CACnE,EAGK,IAAa,KAAK,IAAI,GAAG,KAAK,KAAK,EAAmB,SAAS,EAAU,CAAC,EAC1E,MAAkB,IAAc,KAAK,GACrC,KAAsB,EAAmB,MAAM,IAAgB,KAAiB,EAAU;AAUhG,CANA,QAAgB;AACd,IAAe,EAAE;IAChB,CAAC,GAAa,EAAS,CAAC,EAI3B,QAAgB;AACd,EAAI,IAAc,KAChB,EAAe,EAAW;IAE3B,CAAC,GAAa,EAAW,CAAC;CAE7B,IAAM,KAAiB,QAAkB;AACvC,KAAgB,MAAS,KAAK,IAAI,GAAG,IAAO,EAAE,CAAC;IAC9C,EAAE,CAAC,EAEA,KAAiB,QAAkB;AACvC,KAAgB,MAAS,KAAK,IAAI,GAAY,IAAO,EAAE,CAAC;IACvD,CAAC,EAAW,CAAC,EAEV,KAAiB,GAAa,MAAiB;AACnD,IAAe,EAAK;IACnB,EAAE,CAAC,EAEA,KAAyB,QAAkB;AAC/C,IAAsB,GAAK;IAC1B,EAAE,CAAC,EAQA,KAA0B,GAC7B,EAAE,qBAAuE;AAExE,EADA,GAAS,EACT,EAAS,eAAe,IAAc;IAExC,CAAC,GAAS,EAAS,CACpB,EAEK,KAA0B,QAAkB;AAChD,EAAK,KACH,EAAsB,GAAM;IAE7B,CAAC,EAAW,CAAC,EAEV,KAAwB,EAC5B,OAAO,MAAmF;AACxF,IAAc,GAAK;AACnB,MAAI;GACF,IAAM,IAAe,MAAM,EAAgB;IACzC,MAAM,EAAK;IACX,aAAa,EAAK;IAClB,UAAU,EAAK;IACf,MAAM,EAAK;IACZ,CAAC;AAEF,GAAI,MACF,EAAsB,GAAM,EAC5B,EAAS,eAAe,EAAa,GAAG,UAAU;WAE7C,GAAK;AACZ,OAAI,EAA2B,GAAK,UAAU,EAAE;AAC9C,MAAsB,GAAM;AAC5B;;AAMF,SAFA,QAAQ,MAAM,+BAA+B,EAAI,EAC7C,GAAU,IAAO,EAAa,QAAQ,EACpC;YACE;AACR,KAAc,GAAM;;IAGxB,CAAC,GAAiB,EAAS,CAC5B,EAEK,KAAsB,GACzB,MAAwB;AACvB,IAAS,eAAe,IAAc;IAExC,CAAC,EAAS,CACX,EAEK,IAAsB,GACzB,GAAqB,MAAwB;AAE5C,EADA,EAAE,iBAAiB,EACnB,EAAS,eAAe,EAAY,UAAU;IAEhD,CAAC,EAAS,CACX,EAEK,KAAwB,EAC5B,OAAO,GAAqB,MAAwB;AAClD,IAAE,iBAAiB;EACnB,IAAM,IAAM,EAAG,uCAAuC,kDAAkD,EAClG,IAAS,MAAM,GAAc;GACjC,OAAO;GACP,SAAS;GACT,eAAe;GACf,mBAAmB;GACpB,CAAC;AAEF,MADW,MAAW,OAAO,OAAO,QAAQ,EAAI,GAAG,GAC3C;AACN,KAAa,SAAS;AACtB,OAAI;AAEF,IADA,MAAM,EAAgB,EAAY,EAC9B,GAAU,IAAO,EAAa,UAAU;YACrC,GAAK;AAEZ,UADI,GAAU,IAAO,EAAa,QAAQ,EACpC;;;IAIZ,CAAC,GAAiB,EAAG,CACtB,EAEK,KAAuB,EAC3B,OAAO,GAAqB,GAAoB,MAAwB;AACtE,IAAE,iBAAiB;EACnB,IAAM,IAAc,EAAE,6CAA6C,yBAAyB,EAC1F,eACD,CAAC,EACI,IAAO,OAAO,OAClB,EAAG,0CAA0C,iCAAiC,EAC9E,EACD;AACG,SAAC,KAAQ,CAAC,EAAK,MAAM,GACzB;KAAa,SAAS;AACtB,OAAI;IACF,IAAM,IAAS,MAAM,EAAe,GAAa,EAAK,MAAM,CAAC;AAC7D,IAAI,MACE,GAAU,IAAO,EAAa,UAAU,EAC5C,EAAS,eAAe,EAAO,KAAK;YAE/B,GAAK;AACZ,QAAI,EAA2B,GAAK,UAAU,CAC5C;AAGF,UADI,GAAU,IAAO,EAAa,QAAQ,EACpC;;;IAGV;EAAC;EAAgB;EAAU;EAAI;EAAE,CAClC,EAEK,KAAyB,QAAkB;AAC/C,IAAsB,GAAK;IAC1B,EAAE,CAAC,EAEA,KAA0B,QAAkB;AAChD,IAAsB,GAAM;IAC3B,EAAE,CAAC,EAEA,KAAsB,GACzB,GAAsB,MAA2B;AAChD,KAAS;IAEX,CAAC,EAAQ,CACV,EAGK,MAAsB,MAAoB;EAC9C,IAAM,IAAO,IAAI,KAAK,EAAQ,EACxB,oBAAM,IAAI,MAAM,EAChB,IAAS,EAAI,SAAS,GAAG,EAAK,SAAS,EACvC,IAAW,KAAK,MAAM,IAAS,IAAM,EACrC,IAAY,KAAK,MAAM,IAAS,KAAQ,EACxC,IAAW,KAAK,MAAM,IAAS,MAAS;AAO9C,SALI,IAAW,IAAU,EAAG,sCAAsC,WAAW,GACzE,IAAW,KAAW,GAAG,IAAW,EAAG,+CAA+C,QAAQ,KAC9F,IAAY,KAAW,GAAG,IAAY,EAAG,6CAA6C,QAAQ,KAC9F,IAAW,IAAU,GAAG,IAAW,EAAG,4CAA4C,QAAQ,KAEvF,IAAI,KAAK,eAAe,SAAS;GACtC,OAAO;GACP,KAAK;GACL,MAAM,EAAK,aAAa,KAAK,EAAI,aAAa,GAAe,KAAA,IAAZ;GAClD,CAAC,CAAC,OAAO,EAAK;IAIX,MAAkB,MACf,EAAU,eAAe,GAI5B,MAAgB,MACb,EAAU,aAAa,GAG1B,KACJ,kBAAC,IAAD;EACE,OAAO,EAAG,+BAA+B,aAAa;EACtD,UAAU,EAAG,kCAAkC,8CAA8C;EAC7F,aAAa,EAAG,wCAAwC,mBAAmB;EAC3E,aAAa,EAAG,wCAAwC,SAAS;EACjE,UAAU;EACV,UAAU;EACC;EACA;EACX,CAAA;AAKJ,KAAI,GACF,QACE,kBAAC,OAAD;EAAK,OAAO;GAAE,SAAS;GAAQ,YAAY;GAAU,gBAAgB;GAAU,SAAS;GAAU;YAChG,kBAAC,GAAD,EACE,OAAO;GACL,QAAQ;GACR,OAAO;GACR,EACD,CAAA;EACE,CAAA;AAIV,KAAI,CAAC,GACH,QAAO,kBAAC,IAAD;EAAc,OAAM;EAAgB,aAAY;EAAkD,CAAA;AAI3G,KAAI,GACF,QACE,kBAAC,OAAD;EAAK,OAAO;GAAE,WAAW;GAAS,iBAAiB;GAA0B;YAA7E,CACG,IACD,kBAAC,OAAD;GAAK,OAAO,EAAE,SAAS,4BAA4B;aACjD,kBAAC,GAAD;IACE,cAAc;IACd,MAAK;IACL,OAAO,EAAG,qCAAqC,2BAA2B;IAC1E,aAAa,GAAM;IACnB,eAAY;IACZ,SACE,kBAAC,GAAD;KAAQ,MAAK;KAAK,eAAe,GAAS;eACvC,EAAG,qCAAqC,QAAQ;KAC1C,CAAA;IAEX,CAAA;GACE,CAAA,CACF;;CAIV,IAAM,KAAc,EAAmB;AAEvC,QACE,kBAAC,OAAD;EAAK,OAAO;GAAE,WAAW;GAAS,iBAAiB;GAA0B;YAA7E;GAEG;GAGD,kBAAC,OAAD;IAAK,OAAO,EAAE,SAAS,4BAA4B;cACjD,kBAAC,GAAD,EAAA,UAAA,CAGE,kBAAC,GAAD;KACE,UAAS;KACT,SAAQ;KACR,cAAY,EAAG,+BAA+B,mBAAmB;eAEjE,kBAAC,IAAD;MAAa,WAAU;gBAAe;MAIxB,CAAA;KACN,CAAA,EAGV,kBAAC,GAAD;KACE,cAAc;KACd,UAAS;KACT,eAAY;KACZ,OAAO,EAAG,uCAAuC,kBAAkB;KACnE,aAAa,EACX,6CACA,iFACD;KACD,MACE,kBAAC,GAAD;MACE,SAAQ;MACR,cAAY,EAAG,uCAAuC,GAAG,GAAY,aAAa;gBAEjF;MACK,CAAA;KAEV,SACE,kBAAC,OAAD;MACE,MAAK;MACL,cAAY,EAAG,oCAAoC,gBAAgB;MACnE,OAAO;OACL,SAAS;OACT,YAAY;OACZ,KAAK;OACL,SAAS;OACT,cAAc;OACd,iBAAiB;OAClB;gBAVH,CAYE,kBAAC,GAAD;OACE,SAAS,MAAa,SAAS,YAAY;OAC3C,MAAK;OACL,eAAe,EAAkB,OAAO;OACxC,cAAY,EAAG,mCAAmC,YAAY;OAC9D,gBAAc,MAAa;OAC3B,OAAO,EAAG,mCAAmC,YAAY;OACzD,OAAO;QACL,QAAQ;QACR,OAAO;QACP,SAAS;QACT,cAAc;QACf;iBAED,kBAAC,IAAD,EAAY,OAAO;QAAE,QAAQ;QAAuB,OAAO;QAAuB,EAAI,CAAA;OAC/E,CAAA,EACT,kBAAC,GAAD;OACE,SAAS,MAAa,SAAS,YAAY;OAC3C,MAAK;OACL,eAAe,EAAkB,OAAO;OACxC,cAAY,EAAG,mCAAmC,YAAY;OAC9D,gBAAc,MAAa;OAC3B,OAAO,EAAG,mCAAmC,YAAY;OACzD,OAAO;QACL,QAAQ;QACR,OAAO;QACP,SAAS;QACT,cAAc;QACf;iBAED,kBAAC,IAAD,EAAM,OAAO;QAAE,QAAQ;QAAuB,OAAO;QAAuB,EAAI,CAAA;OACzE,CAAA,CACL;;KAER,eAAc;eAhEhB;MAmEE,kBAAC,OAAD;OAAK,OAAO;QAAE,UAAU;QAAY,OAAO;QAAQ,UAAU;QAAS;iBAAtE,CACE,kBAAC,IAAD;QACE,eAAY;QACZ,OAAO;SACL,UAAU;SACV,MAAM;SACN,KAAK;SACL,WAAW;SACX,QAAQ;SACR,OAAO;SACP,OAAO;SACR;QACD,CAAA,EACF,kBAAC,IAAD;QACE,MAAK;QACL,cAAY,EAAG,4CAA4C,uBAAuB;QAClF,aAAa,EAAG,4CAA4C,uBAAuB;QACnF,OAAO;QACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;QAC/C,OAAO;SAAE,aAAa;SAAgC,QAAQ;SAAgC;QAC9F,CAAA,CACE;;MAGL,KAAW,EAAW,WAAW,KAChC,kBAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,YAAY;QAAU,gBAAgB;QAAU,SAAS;QAAU;iBAChG,kBAAC,OAAD;QAAK,OAAO,EAAE,WAAW,UAAU;kBAAnC,CACE,kBAAC,GAAD,EACE,OAAO;SACL,QAAQ;SACR,OAAO;SACP,QAAQ;SACT,EACD,CAAA,EACF,kBAAC,KAAD;SAAG,OAAO;UAAE,UAAU;UAA4B,OAAO;UAA2B;mBACjF,EAAG,iCAAiC,wBAAwB;SAC3D,CAAA,CACA;;OACF,CAAA;MAIP,CAAC,KAAW,MAAa,UAAU,EAAmB,SAAS,KAC9D,kBAAC,OAAD;OACE,OAAO;QACL,SAAS;QACT,qBAAqB;QACrB,KAAK;QACN;iBAEA,GAAoB,KAAK,MACxB,kBAAC,GAAD;QAEE,eAAe,GAAoB,EAAU,GAAG;QAChD,OAAO,EAAE,QAAQ,WAAW;QAC5B,WAAU;kBAEV,kBAAC,GAAD;SAAa,OAAO,EAAE,SAAS,4BAA4B;mBAA3D;UAEE,kBAAC,OAAD;WACE,OAAO;YACL,SAAS;YACT,YAAY;YACZ,KAAK;YACL,cAAc;YACf;qBANH,CAQE,kBAAC,OAAD;YACE,OAAO;aACL,SAAS;aACT,QAAQ;aACR,OAAO;aACP,YAAY;aACZ,YAAY;aACZ,gBAAgB;aAChB,cAAc;aACd,iBAAiB;aAClB;sBAED,kBAAC,GAAD;aACE,eAAY;aACZ,OAAO;cACL,QAAQ;cACR,OAAO;cACP,OAAO;cACR;aACD,CAAA;YACE,CAAA,EACN,kBAAC,OAAD;YAAK,OAAO;aAAE,MAAM;aAAG,UAAU;aAAG;sBAApC,CACE,kBAAC,MAAD;aACE,OAAO;cACL,YAAY;cACZ,UAAU;cACV,QAAQ;cACR,OAAO;cACP,UAAU;cACV,cAAc;cACd,YAAY;cACb;uBAEA,EAAU;aACR,CAAA,EACJ,EAAU,YACT,kBAAC,GAAD;aACE,SAAQ;aACR,OAAO;cACL,WAAW;cACX,UAAU;cACV,YAAY;cACZ,eAAe;cAChB;uBAEA,EAAU;aACL,CAAA,CAEN;cACF;;UAGN,kBAAC,KAAD;WACE,OAAO;YACL,UAAU;YACV,YAAY;YACZ,OAAO;YACP,QAAQ;YACR,WAAW;YACX,SAAS;YACT,iBAAiB;YACjB,iBAAiB;YACjB,UAAU;YACX;qBAEA,EAAU,eACT,EAAG,4CAA4C,0BAA0B;WACzE,CAAA;UAGJ,kBAAC,OAAD;WACE,OAAO;YACL,SAAS;YACT,YAAY;YACZ,KAAK;YACL,cAAc;YACd,SAAS;YACT,iBAAiB;YACjB,cAAc;YACf;qBATH;YAWE,kBAAC,OAAD;aAAK,OAAO;cAAE,SAAS;cAAQ,YAAY;cAAU,KAAK;cAAwB;uBAAlF;cACE,kBAAC,GAAD,EACE,OAAO;eACL,QAAQ;eACR,OAAO;eACP,OAAO;eACR,EACD,CAAA;cACF,kBAAC,QAAD;eACE,OAAO;gBACL,UAAU;gBACV,YAAY;gBACZ,OAAO;gBACR;yBAEA,GAAa,EAAU;eACnB,CAAA;cACP,kBAAC,QAAD;eAAM,OAAO;gBAAE,UAAU;gBAA4B,OAAO;gBAA2B;yBACpF,EAAG,oCAAoC,QAAQ;eAC3C,CAAA;cACH;;YACN,kBAAC,OAAD,EACE,OAAO;aACL,OAAO;aACP,QAAQ;aACR,iBAAiB;aAClB,EACD,CAAA;YACF,kBAAC,OAAD;aAAK,OAAO;cAAE,SAAS;cAAQ,YAAY;cAAU,KAAK;cAAwB;uBAAlF;cACE,kBAAC,GAAD,EACE,OAAO;eACL,QAAQ;eACR,OAAO;eACP,OAAO;eACR,EACD,CAAA;cACF,kBAAC,QAAD;eACE,OAAO;gBACL,UAAU;gBACV,YAAY;gBACZ,OAAO;gBACR;yBAEA,GAAe,EAAU;eACrB,CAAA;cACP,kBAAC,QAAD;eAAM,OAAO;gBAAE,UAAU;gBAA4B,OAAO;gBAA2B;yBACpF,EAAG,sCAAsC,UAAU;eAC/C,CAAA;cACH;;YACF;;UAGN,kBAAC,OAAD;WACE,OAAO;YACL,SAAS;YACT,YAAY;YACZ,gBAAgB;YAChB,UAAU;YACV,KAAK;YACL,YAAY;YACZ,WAAW;YACZ;qBATH,CAWE,kBAAC,OAAD;YACE,OAAO;aACL,SAAS;aACT,YAAY;aACZ,KAAK;aACN;sBALH,CAOE,kBAAC,GAAD,EACE,OAAO;aACL,QAAQ;aACR,OAAO;aACP,OAAO;aACR,EACD,CAAA,EACF,kBAAC,QAAD;aACE,OAAO;cACL,UAAU;cACV,YAAY;cACZ,OAAO;cACR;uBAEA,GAAmB,EAAU,UAAU;aACnC,CAAA,CACH;eAEN,kBAAC,OAAD;YAAK,OAAO;aAAE,SAAS;aAAQ,YAAY;aAAU,KAAK;aAA2B;sBAArF;aACE,kBAAC,GAAD;cAAkB,YAAY,EAAuB;cAAkB,gBAAe;wBACpF,kBAAC,GAAD;eACE,SAAQ;eACR,MAAK;eACL,UAAU,MAAM,EAAoB,EAAU,IAAI,EAAE;eACpD,OAAO;gBACL,QAAQ;gBACR,OAAO;gBACP,SAAS;gBACT,cAAc;gBACf;eACD,OAAO,EAAG,2CAA2C,iBAAiB;yBAEtE,kBAAC,GAAD,EAAQ,OAAO;gBAAE,QAAQ;gBAAuB,OAAO;gBAAuB,EAAI,CAAA;eAC3E,CAAA;cACQ,CAAA;aACnB,kBAAC,GAAD;cAAkB,YAAY,EAAuB;cAAkB,gBAAe;wBACpF,kBAAC,GAAD;eACE,SAAQ;eACR,MAAK;eACL,UAAU,MAAM,GAAqB,EAAU,IAAI,EAAU,MAAM,EAAE;eACrE,OAAO;gBACL,QAAQ;gBACR,OAAO;gBACP,SAAS;gBACT,cAAc;gBACf;eACD,OAAO,EAAG,4CAA4C,kBAAkB;yBAExE,kBAAC,GAAD,EAAM,OAAO;gBAAE,QAAQ;gBAAuB,OAAO;gBAAuB,EAAI,CAAA;eACzE,CAAA;cACQ,CAAA;aACnB,kBAAC,GAAD;cAAkB,YAAY,EAAuB;cAAkB,gBAAe;wBACpF,kBAAC,GAAD;eACE,SAAQ;eACR,MAAK;eACL,UAAU,MAAM,GAAsB,EAAU,IAAI,EAAE;eACtD,OAAO;gBACL,QAAQ;gBACR,OAAO;gBACP,SAAS;gBACT,cAAc;gBACf;eACD,WAAU;eACV,OAAO,EAAG,6CAA6C,mBAAmB;yBAE1E,kBAAC,IAAD,EAAQ,OAAO;gBAAE,QAAQ;gBAAuB,OAAO;gBAAuB,EAAI,CAAA;eAC3E,CAAA;cACQ,CAAA;aACf;cACF;;UACM;;QACT,EA7OA,EAAU,GA6OV,CACP;OACE,CAAA;MAIP,CAAC,KAAW,MAAa,UAAU,EAAmB,SAAS,KAC9D,kBAAC,OAAD;OACE,OAAO;QACL,SAAS;QACT,eAAe;QACf,KAAK;QACN;iBAEA,GAAoB,KAAK,MACxB,kBAAC,GAAD;QAEE,eAAe,GAAoB,EAAU,GAAG;QAChD,OAAO,EAAE,QAAQ,WAAW;QAC5B,WAAU;kBAEV,kBAAC,GAAD;SAAa,OAAO,EAAE,SAAS,4BAA4B;mBACzD,kBAAC,OAAD;UACE,OAAO;WACL,SAAS;WACT,YAAY;WACZ,KAAK;WACL,UAAU;WACX;oBANH;WASE,kBAAC,OAAD;YACE,OAAO;aACL,SAAS;aACT,QAAQ;aACR,OAAO;aACP,YAAY;aACZ,YAAY;aACZ,gBAAgB;aAChB,cAAc;aACd,iBAAiB;aAClB;sBAED,kBAAC,GAAD;aACE,eAAY;aACZ,OAAO;cACL,QAAQ;cACR,OAAO;cACP,OAAO;cACR;aACD,CAAA;YACE,CAAA;WAGN,kBAAC,OAAD;YAAK,OAAO;aAAE,MAAM;aAAa,UAAU;aAAG;sBAA9C,CACE,kBAAC,OAAD;aACE,OAAO;cACL,SAAS;cACT,YAAY;cACZ,KAAK;cACL,UAAU;cACX;uBANH,CAQE,kBAAC,MAAD;cACE,OAAO;eACL,YAAY;eACZ,UAAU;eACV,QAAQ;eACR,OAAO;eACP,UAAU;eACV,cAAc;eACd,YAAY;eACZ,UAAU;eACX;wBAEA,EAAU;cACR,CAAA,EACJ,EAAU,YACT,kBAAC,GAAD;cACE,SAAQ;cACR,OAAO;eACL,UAAU;eACV,YAAY;eACZ,eAAe;eAChB;wBAEA,EAAU;cACL,CAAA,CAEN;gBACN,kBAAC,KAAD;aACE,OAAO;cACL,UAAU;cACV,YAAY;cACZ,OAAO;cACP,QAAQ;cACR,UAAU;cACV,cAAc;cACd,YAAY;cACb;uBAEA,EAAU,eACT,EAAG,4CAA4C,0BAA0B;aACzE,CAAA,CACA;;WAGN,kBAAC,OAAD;YACE,OAAO;aACL,SAAS;aACT,YAAY;aACZ,KAAK;aACL,UAAU;aACX;sBANH;aAQE,kBAAC,OAAD;cAAK,OAAO;eAAE,SAAS;eAAQ,YAAY;eAAU,KAAK;eAAwB;wBAAlF;eACE,kBAAC,GAAD,EACE,OAAO;gBACL,QAAQ;gBACR,OAAO;gBACP,OAAO;gBACR,EACD,CAAA;eACF,kBAAC,QAAD;gBACE,OAAO;iBACL,UAAU;iBACV,YAAY;iBACZ,OAAO;iBACR;0BAEA,GAAa,EAAU;gBACnB,CAAA;eACP,kBAAC,QAAD;gBAAM,OAAO;iBAAE,UAAU;iBAA4B,OAAO;iBAA2B;0BACpF,EAAG,oCAAoC,QAAQ;gBAC3C,CAAA;eACH;;aACN,kBAAC,OAAD;cAAK,OAAO;eAAE,SAAS;eAAQ,YAAY;eAAU,KAAK;eAAwB;wBAAlF;eACE,kBAAC,GAAD,EACE,OAAO;gBACL,QAAQ;gBACR,OAAO;gBACP,OAAO;gBACR,EACD,CAAA;eACF,kBAAC,QAAD;gBACE,OAAO;iBACL,UAAU;iBACV,YAAY;iBACZ,OAAO;iBACR;0BAEA,GAAe,EAAU;gBACrB,CAAA;eACP,kBAAC,QAAD;gBAAM,OAAO;iBAAE,UAAU;iBAA4B,OAAO;iBAA2B;0BACpF,EAAG,sCAAsC,UAAU;gBAC/C,CAAA;eACH;;aACN,kBAAC,OAAD;cAAK,OAAO;eAAE,SAAS;eAAQ,YAAY;eAAU,KAAK;eAAwB;wBAAlF,CACE,kBAAC,GAAD,EACE,OAAO;eACL,QAAQ;eACR,OAAO;eACP,OAAO;eACR,EACD,CAAA,EACF,kBAAC,QAAD;eACE,OAAO;gBACL,UAAU;gBACV,YAAY;gBACZ,OAAO;gBACR;yBAEA,GAAmB,EAAU,UAAU;eACnC,CAAA,CACH;;aACF;;WAGN,kBAAC,OAAD;YAAK,OAAO;aAAE,SAAS;aAAQ,YAAY;aAAU,KAAK;aAA2B;sBAArF;aACE,kBAAC,GAAD;cAAkB,YAAY,EAAuB;cAAkB,gBAAe;wBACpF,kBAAC,GAAD;eACE,SAAQ;eACR,MAAK;eACL,UAAU,MAAM,EAAoB,EAAU,IAAI,EAAE;eACpD,OAAO;gBACL,QAAQ;gBACR,OAAO;gBACP,SAAS;gBACT,cAAc;gBACf;eACD,OAAO,EAAG,2CAA2C,iBAAiB;yBAEtE,kBAAC,GAAD,EAAQ,OAAO;gBAAE,QAAQ;gBAAuB,OAAO;gBAAuB,EAAI,CAAA;eAC3E,CAAA;cACQ,CAAA;aACnB,kBAAC,GAAD;cAAkB,YAAY,EAAuB;cAAkB,gBAAe;wBACpF,kBAAC,GAAD;eACE,SAAQ;eACR,MAAK;eACL,UAAU,MAAM,GAAqB,EAAU,IAAI,EAAU,MAAM,EAAE;eACrE,OAAO;gBACL,QAAQ;gBACR,OAAO;gBACP,SAAS;gBACT,cAAc;gBACf;eACD,OAAO,EAAG,4CAA4C,kBAAkB;yBAExE,kBAAC,GAAD,EAAM,OAAO;gBAAE,QAAQ;gBAAuB,OAAO;gBAAuB,EAAI,CAAA;eACzE,CAAA;cACQ,CAAA;aACnB,kBAAC,GAAD;cAAkB,YAAY,EAAuB;cAAkB,gBAAe;wBACpF,kBAAC,GAAD;eACE,SAAQ;eACR,MAAK;eACL,UAAU,MAAM,GAAsB,EAAU,IAAI,EAAE;eACtD,OAAO;gBACL,QAAQ;gBACR,OAAO;gBACP,SAAS;gBACT,cAAc;gBACf;eACD,WAAU;eACV,OAAO,EAAG,6CAA6C,mBAAmB;yBAE1E,kBAAC,IAAD,EAAQ,OAAO;gBAAE,QAAQ;gBAAuB,OAAO;gBAAuB,EAAI,CAAA;eAC3E,CAAA;cACQ,CAAA;aACf;;WACF;;SACM,CAAA;QACT,EAvNA,EAAU,GAuNV,CACP;OACE,CAAA;MAIP,CAAC,KAAW,EAAmB,SAAS,KACvC,kBAAC,OAAD;OACE,cAAY,EAAG,0CAA0C,kBAAkB;OAC3E,WAAU;iBAFZ;QAIE,kBAAC,GAAD;SACE,SAAQ;SACR,MAAK;SACL,SAAS;SACT,UAAU,KAAe;SACzB,cAAY,EAAG,6CAA6C,WAAW;SACvE,OAAO,EAAE,WAAW,gCAAgC;mBANtD,CAQE,kBAAC,IAAD,EACE,OAAO;UACL,aAAa;UACb,QAAQ;UACR,OAAO;UACR,EACD,CAAA,EACD,EAAG,6CAA6C,WAAW,CACrD;;QAET,kBAAC,OAAD;SAAK,OAAO;UAAE,SAAS;UAAQ,YAAY;UAAU,KAAK;UAAwB,UAAU;UAAQ;mBACjG,GAAc,GAAa,EAAW,CAAC,KAAK,GAAM,MACjD,MAAS,OACP,kBAAC,QAAD;UAEE,eAAY;UACZ,OAAO;WAAE,OAAO;WAA2B,SAAS;WAA0B;oBAC/E;UAEM,EALA,OAAO,IAKP,GAEP,kBAAC,GAAD;UAEE,SAAS,MAAS,IAAc,YAAY;UAC5C,MAAK;UACL,eAAe,GAAe,EAAK;UACnC,gBAAc,MAAS,IAAc,SAAS,KAAA;UAC9C,cAAY,EAAG,yCAAyC,QAAQ,IAAO;UACvE,OAAO;WACL,UAAU;WACV,QAAQ;WACR,SAAS;WACT,cAAc;WACf;oBAEA;UACM,EAdF,EAcE,CAEZ;SACG,CAAA;QAEN,kBAAC,GAAD;SACE,SAAQ;SACR,MAAK;SACL,SAAS;SACT,UAAU,KAAe;SACzB,cAAY,EAAG,yCAAyC,OAAO;SAC/D,OAAO,EAAE,WAAW,gCAAgC;mBANtD,CAQG,EAAG,yCAAyC,OAAO,EACpD,kBAAC,IAAD,EACE,OAAO;UACL,YAAY;UACZ,QAAQ;UACR,OAAO;UACR,EACD,CAAA,CACK;;QAET,kBAAC,QAAD;SACE,OAAO;UACL,UAAU;UACV,OAAO;UACR;mBAEA,EAAE,2CAA2C,0CAA0C;UACtF;UACA;UACD,CAAC;SACG,CAAA;QACH;;MAIP,CAAC,KAAW,EAAmB,WAAW,KACzC,kBAAC,IAAD;OAAW,WAAU;OAAU,WAAU;iBACvC,kBAAC,IAAD;QACE,cAAc,IAAc,iBAAiB;QAC7C,OACE,IACI,EAAG,6CAA6C,sBAAsB,GACtE,EAAG,qCAAqC,oBAAoB;QAElE,aACE,IACI,EAAG,mDAAmD,kCAAkC,GACxF,EACE,2CACA,sEACD;QAEP,QACG,IAkCG,KAAA,IAjCF,kBAAC,OAAD;SACE,OAAO;UACL,SAAS;UACT,KAAK;UACL,UAAU;UACV,gBAAgB;UACjB;mBANH,CAQE,kBAAC,GAAD;UAAkB,YAAY,EAAuB;UAAkB,gBAAe;oBACpF,kBAAC,GAAD;WAAQ,SAAS;qBAAjB,CACE,kBAAC,GAAD,EACE,OAAO;YACL,aAAa;YACb,QAAQ;YACR,OAAO;YACR,EACD,CAAA,EACD,EAAG,wCAAwC,mBAAmB,CACxD;;UACQ,CAAA,EACnB,kBAAC,GAAD;UAAkB,YAAY,EAAuB;UAAkB,gBAAe;oBACpF,kBAAC,GAAD;WAAQ,SAAQ;WAAU,SAAS;qBAAnC,CACE,kBAAC,IAAD,EACE,OAAO;YACL,aAAa;YACb,QAAQ;YACR,OAAO;YACR,EACD,CAAA,EACD,EAAG,iDAAiD,mBAAmB,CACjE;;UACQ,CAAA,CACf;;QAGV,CAAA;OACQ,CAAA;MAEN;OACG,EAAA,CAAA;IACX,CAAA;GAGN,kBAAC,GAAD;IACE,QAAQ;IACI;IACZ,SAAS;IACT,UAAU;IACV,qBAAqB;IACrB,CAAA;GAGF,kBAAC,GAAD;IACE,QAAQ;IACR,SAAS;IACT,WAAW;IACX,CAAA;GACE;;EAER"}