@burdenoff/microfe-bigconsole 2026.805.3 → 2026.812.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/dist/bigconsole/components/DrilldownDashboardRenderer.js +118 -106
  2. package/dist/bigconsole/components/DrilldownDashboardRenderer.js.map +1 -1
  3. package/dist/bigconsole/components/DrilldownModal.js +54 -50
  4. package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
  5. package/dist/bigconsole/components/builder/BuilderCanvas.js +2 -2
  6. package/dist/bigconsole/components/builder/BuilderCanvas.js.map +1 -1
  7. package/dist/bigconsole/components/builder/BuilderTopbar.js +3 -3
  8. package/dist/bigconsole/components/builder/BuilderTopbar.js.map +1 -1
  9. package/dist/bigconsole/components/builder/inspector/AdvancedSection.js +24 -25
  10. package/dist/bigconsole/components/builder/inspector/AdvancedSection.js.map +1 -1
  11. package/dist/bigconsole/components/builder/inspector/AppearanceSection.js +40 -29
  12. package/dist/bigconsole/components/builder/inspector/AppearanceSection.js.map +1 -1
  13. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +135 -97
  14. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
  15. package/dist/bigconsole/components/builder/inspector/GeneralSection.js +58 -44
  16. package/dist/bigconsole/components/builder/inspector/GeneralSection.js.map +1 -1
  17. package/dist/bigconsole/components/common/Section.js +70 -0
  18. package/dist/bigconsole/components/common/Section.js.map +1 -0
  19. package/dist/bigconsole/components/common/index.js +2 -0
  20. package/dist/bigconsole/components/common/sectionStyles.js +42 -0
  21. package/dist/bigconsole/components/common/sectionStyles.js.map +1 -0
  22. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +209 -193
  23. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  24. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +213 -231
  25. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  26. package/dist/bigconsole/components/dashboard/DashboardGrid.js +12 -18
  27. package/dist/bigconsole/components/dashboard/DashboardGrid.js.map +1 -1
  28. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +109 -102
  29. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  30. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +81 -70
  31. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
  32. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js +125 -159
  33. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js.map +1 -1
  34. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +25 -23
  35. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
  36. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +3 -3
  37. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
  38. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +5 -3
  39. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
  40. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +170 -284
  41. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  42. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +147 -151
  43. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  44. package/dist/bigconsole/components/dashboard/LiveBoardBanner.js +45 -53
  45. package/dist/bigconsole/components/dashboard/LiveBoardBanner.js.map +1 -1
  46. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +157 -148
  47. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
  48. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +17 -8
  49. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
  50. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +101 -95
  51. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
  52. package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js +20 -18
  53. package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js.map +1 -1
  54. package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js +26 -58
  55. package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js.map +1 -1
  56. package/dist/bigconsole/components/dashboard/WidgetPalette.js +307 -231
  57. package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
  58. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +29 -29
  59. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  60. package/dist/bigconsole/components/datasink/DataSinkCard.js +78 -79
  61. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  62. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +33 -34
  63. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
  64. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +79 -56
  65. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  66. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +75 -65
  67. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  68. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +1 -1
  69. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
  70. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +20 -19
  71. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
  72. package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js +127 -171
  73. package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js.map +1 -1
  74. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +263 -243
  75. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  76. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +65 -66
  77. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
  78. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +121 -127
  79. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
  80. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +33 -26
  81. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  82. package/dist/bigconsole/components/datasink/SetupStateBadge.js +3 -3
  83. package/dist/bigconsole/components/datasink/SetupStateBadge.js.map +1 -1
  84. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +95 -95
  85. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
  86. package/dist/bigconsole/components/parser/DataSinkSelector.js +154 -123
  87. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  88. package/dist/bigconsole/components/parser/ExpressionEditor.js +3 -3
  89. package/dist/bigconsole/components/parser/ExpressionEditor.js.map +1 -1
  90. package/dist/bigconsole/components/parser/ImportParserDialog.js +235 -275
  91. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  92. package/dist/bigconsole/components/parser/ParserCard.js +133 -114
  93. package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
  94. package/dist/bigconsole/components/parser/ParserSelector.js +191 -174
  95. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  96. package/dist/bigconsole/components/parser/ParserStatusBadge.js +2 -2
  97. package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
  98. package/dist/bigconsole/components/parser/ParserTypeBadge.js +4 -4
  99. package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
  100. package/dist/bigconsole/components/pipeline/PipelineCard.js +134 -89
  101. package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
  102. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +77 -64
  103. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
  104. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +7 -10
  105. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
  106. package/dist/bigconsole/components/preview/AiPreviewContent.js +31 -32
  107. package/dist/bigconsole/components/preview/AiPreviewContent.js.map +1 -1
  108. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +152 -106
  109. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
  110. package/dist/bigconsole/components/preview/AiPreviewPanel.js +193 -152
  111. package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
  112. package/dist/bigconsole/components/preview/previewShared.js +41 -23
  113. package/dist/bigconsole/components/preview/previewShared.js.map +1 -1
  114. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +342 -308
  115. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  116. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +262 -238
  117. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  118. package/dist/bigconsole/components/widgets/PropertiesPanel.js +783 -867
  119. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  120. package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js +7 -5
  121. package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js.map +1 -1
  122. package/dist/bigconsole/components/widgets/WidgetHeader.js +7 -8
  123. package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
  124. package/dist/bigconsole/components/widgets/WidgetRegistry.js +4 -4
  125. package/dist/bigconsole/components/widgets/WidgetRegistry.js.map +1 -1
  126. package/dist/bigconsole/components/widgets/WidgetWrapper.js +8 -7
  127. package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
  128. package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js +1 -1
  129. package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js.map +1 -1
  130. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +2 -2
  131. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  132. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +11 -5
  133. package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
  134. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +19 -15
  135. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  136. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +154 -102
  137. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
  138. package/dist/bigconsole/components/widgets/gauge/CircularGauge.js +36 -32
  139. package/dist/bigconsole/components/widgets/gauge/CircularGauge.js.map +1 -1
  140. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +85 -60
  141. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
  142. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +64 -35
  143. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
  144. package/dist/bigconsole/components/widgets/gauge/LinearGauge.js +46 -45
  145. package/dist/bigconsole/components/widgets/gauge/LinearGauge.js.map +1 -1
  146. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +35 -24
  147. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
  148. package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js +2 -2
  149. package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js.map +1 -1
  150. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +4 -4
  151. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  152. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +153 -90
  153. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
  154. package/dist/bigconsole/components/widgets/list/ListConfig.js +8 -2
  155. package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
  156. package/dist/bigconsole/components/widgets/list/ListItem.js +1 -1
  157. package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
  158. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +1 -1
  159. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
  160. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +14 -4
  161. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
  162. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +112 -89
  163. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
  164. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +21 -13
  165. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
  166. package/dist/bigconsole/components/widgets/metric-card/index.js +4 -4
  167. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +3 -3
  168. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  169. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +34 -25
  170. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  171. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +129 -114
  172. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
  173. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +3 -3
  174. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
  175. package/dist/bigconsole/components/widgets/states/EmptyState.js +6 -4
  176. package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
  177. package/dist/bigconsole/components/widgets/states/ErrorState.js +7 -5
  178. package/dist/bigconsole/components/widgets/states/ErrorState.js.map +1 -1
  179. package/dist/bigconsole/components/widgets/states/LoadingState.js +5 -4
  180. package/dist/bigconsole/components/widgets/states/LoadingState.js.map +1 -1
  181. package/dist/bigconsole/components/widgets/table/TableConfig.js +10 -4
  182. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  183. package/dist/bigconsole/components/widgets/table/TableHeader.js +1 -1
  184. package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
  185. package/dist/bigconsole/components/widgets/table/TableWidget.js +1 -1
  186. package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
  187. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +1 -1
  188. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
  189. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +3 -3
  190. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
  191. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +2 -2
  192. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -1
  193. package/dist/bigconsole/components/widgets/utils/targetProgress.js +13 -0
  194. package/dist/bigconsole/components/widgets/utils/targetProgress.js.map +1 -0
  195. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +112 -85
  196. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
  197. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +28 -20
  198. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  199. package/dist/bigconsole/components/workflow/WorkflowCard.js +92 -77
  200. package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
  201. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +70 -51
  202. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
  203. package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js +16 -17
  204. package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js.map +1 -1
  205. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +6 -4
  206. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
  207. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +360 -338
  208. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  209. package/dist/bigconsole/hooks/useModalFocusTrap.js +53 -0
  210. package/dist/bigconsole/hooks/useModalFocusTrap.js.map +1 -0
  211. package/dist/bigconsole/pages/DashboardBuilderPage.js +209 -203
  212. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  213. package/dist/bigconsole/pages/DashboardViewPage.js +126 -120
  214. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  215. package/dist/bigconsole/pages/DashboardsPage.js +838 -800
  216. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  217. package/dist/bigconsole/pages/DataParsersPage.js +263 -315
  218. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  219. package/dist/bigconsole/pages/DataSinkBuilderPage.js +301 -341
  220. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  221. package/dist/bigconsole/pages/DataSinkViewPage.js +346 -339
  222. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  223. package/dist/bigconsole/pages/DataSinksPage.js +356 -458
  224. package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
  225. package/dist/bigconsole/pages/DataSourcesPage.js +7 -2
  226. package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
  227. package/dist/bigconsole/pages/HomePage.js +186 -193
  228. package/dist/bigconsole/pages/HomePage.js.map +1 -1
  229. package/dist/bigconsole/pages/InsightsPage.js +887 -740
  230. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  231. package/dist/bigconsole/pages/ParserBuilderPage.js +679 -637
  232. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  233. package/dist/bigconsole/pages/ParserViewPage.js +368 -342
  234. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  235. package/dist/bigconsole/pages/PipelineBuilderPage.js +537 -444
  236. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  237. package/dist/bigconsole/pages/PipelineViewPage.js +412 -377
  238. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  239. package/dist/bigconsole/pages/PipelinesPage.js +248 -298
  240. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  241. package/dist/bigconsole/pages/WidgetDemoPage.js +251 -153
  242. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  243. package/dist/bigconsole/pages/WorkflowViewPage.js +381 -371
  244. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  245. package/dist/bigconsole/pages/WorkflowsPage.js +171 -286
  246. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  247. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WebhookConfigPanel.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.tsx"],"sourcesContent":["/**\n * WebhookConfigPanel Component (v2.0)\n *\n * Panel for managing event webhook mappings.\n * Allows creating, editing, testing, and deleting webhooks.\n */\n\nimport React, { memo, useState, useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n useEventWebhooks,\n type HttpMethod,\n type EventWebhookMapping,\n type CreateEventWebhookMappingInput,\n type UpdateEventWebhookMappingInput,\n type WebhookTestResult,\n} from '../../../hooks/useEventWebhooks';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WebhookConfigPanelProps {\n /** Dashboard ID for webhook scope */\n dashboardId?: string;\n /** Widget ID for webhook scope */\n widgetId?: string;\n /** Callback when webhook is created */\n onWebhookCreated?: (webhook: EventWebhookMapping) => void;\n /** Callback when webhook is deleted */\n onWebhookDeleted?: (id: string) => void;\n}\n\n// ============================================================================\n// Styles\n// ============================================================================\n\nconst styles = {\n container: {\n padding: '16px',\n backgroundColor: 'var(--color-bg-surface)',\n borderRadius: '8px',\n } as React.CSSProperties,\n header: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: '16px',\n } as React.CSSProperties,\n title: {\n fontSize: '16px',\n fontWeight: 600,\n color: 'var(--color-text-primary)',\n margin: 0,\n } as React.CSSProperties,\n addButton: {\n padding: '8px 16px',\n backgroundColor: 'var(--color-action-primary-bg)',\n color: 'var(--color-text-inverse)',\n border: 'none',\n borderRadius: '6px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: 'pointer',\n } as React.CSSProperties,\n webhookList: {\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n } as React.CSSProperties,\n webhookCard: {\n padding: '16px',\n backgroundColor: 'var(--color-bg-subtle)',\n borderRadius: '8px',\n border: '1px solid var(--color-border-subtle)',\n } as React.CSSProperties,\n webhookHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n marginBottom: '8px',\n } as React.CSSProperties,\n webhookTitle: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n } as React.CSSProperties,\n webhookName: {\n fontSize: '14px',\n fontWeight: 600,\n color: 'var(--color-text-primary)',\n } as React.CSSProperties,\n statusBadge: {\n padding: '2px 8px',\n borderRadius: '12px',\n fontSize: '12px',\n fontWeight: 500,\n } as React.CSSProperties,\n activeBadge: {\n backgroundColor: 'var(--color-status-success-bgSubtle)',\n color: 'var(--color-status-success-text)',\n } as React.CSSProperties,\n inactiveBadge: {\n backgroundColor: 'var(--color-status-warning-bgSubtle)',\n color: 'var(--color-status-warning-text)',\n } as React.CSSProperties,\n webhookDetails: {\n fontSize: '13px',\n color: 'var(--color-text-muted)',\n marginBottom: '4px',\n } as React.CSSProperties,\n webhookUrl: {\n fontSize: '12px',\n color: 'var(--color-text-placeholder)',\n fontFamily: 'monospace',\n wordBreak: 'break-all',\n } as React.CSSProperties,\n webhookActions: {\n display: 'flex',\n gap: '8px',\n marginTop: '12px',\n } as React.CSSProperties,\n actionButton: {\n padding: '6px 12px',\n fontSize: '12px',\n fontWeight: 500,\n borderRadius: '4px',\n border: 'none',\n cursor: 'pointer',\n } as React.CSSProperties,\n editButton: {\n backgroundColor: 'var(--color-bg-sunken)',\n color: 'var(--color-text-primary)',\n } as React.CSSProperties,\n testButton: {\n backgroundColor: 'var(--color-status-info-bgSubtle)',\n color: 'var(--color-status-info-text)',\n } as React.CSSProperties,\n deleteButton: {\n backgroundColor: 'var(--color-status-error-bgSubtle)',\n color: 'var(--color-status-error-text)',\n } as React.CSSProperties,\n toggleButton: {\n backgroundColor: 'var(--color-bg-sunken)',\n color: 'var(--color-text-muted)',\n } as React.CSSProperties,\n emptyState: {\n textAlign: 'center',\n padding: '32px',\n color: 'var(--color-text-placeholder)',\n } as React.CSSProperties,\n form: {\n padding: '16px',\n backgroundColor: 'var(--color-bg-subtle)',\n borderRadius: '8px',\n marginBottom: '16px',\n } as React.CSSProperties,\n formGroup: {\n marginBottom: '12px',\n } as React.CSSProperties,\n label: {\n display: 'block',\n fontSize: '13px',\n fontWeight: 500,\n color: 'var(--color-text-primary)',\n marginBottom: '4px',\n } as React.CSSProperties,\n input: {\n width: '100%',\n padding: '8px 12px',\n fontSize: '14px',\n border: '1px solid var(--color-border-default)',\n borderRadius: '6px',\n boxSizing: 'border-box',\n } as React.CSSProperties,\n select: {\n width: '100%',\n padding: '8px 12px',\n fontSize: '14px',\n border: '1px solid var(--color-border-default)',\n borderRadius: '6px',\n boxSizing: 'border-box',\n backgroundColor: 'var(--color-bg-surface)',\n } as React.CSSProperties,\n textarea: {\n width: '100%',\n padding: '8px 12px',\n fontSize: '14px',\n border: '1px solid var(--color-border-default)',\n borderRadius: '6px',\n boxSizing: 'border-box',\n fontFamily: 'monospace',\n minHeight: '80px',\n resize: 'vertical',\n } as React.CSSProperties,\n formActions: {\n display: 'flex',\n gap: '8px',\n justifyContent: 'flex-end',\n marginTop: '16px',\n } as React.CSSProperties,\n cancelButton: {\n padding: '8px 16px',\n backgroundColor: 'var(--color-bg-sunken)',\n color: 'var(--color-text-primary)',\n border: 'none',\n borderRadius: '6px',\n fontSize: '14px',\n cursor: 'pointer',\n } as React.CSSProperties,\n saveButton: {\n padding: '8px 16px',\n backgroundColor: 'var(--color-action-primary-bg)',\n color: 'var(--color-text-inverse)',\n border: 'none',\n borderRadius: '6px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: 'pointer',\n } as React.CSSProperties,\n testResult: {\n marginTop: '12px',\n padding: '12px',\n borderRadius: '6px',\n fontSize: '13px',\n } as React.CSSProperties,\n testSuccess: {\n backgroundColor: 'var(--color-status-success-bgSubtle)',\n color: 'var(--color-status-success-text)',\n } as React.CSSProperties,\n testFailure: {\n backgroundColor: 'var(--color-status-error-bgSubtle)',\n color: 'var(--color-status-error-text)',\n } as React.CSSProperties,\n helpText: {\n fontSize: '12px',\n color: 'var(--color-text-placeholder)',\n marginTop: '4px',\n } as React.CSSProperties,\n};\n\n// ============================================================================\n// Webhook Form Component\n// ============================================================================\n\ninterface WebhookFormProps {\n webhook?: EventWebhookMapping;\n dashboardId?: string;\n widgetId?: string;\n onSave: (data: CreateEventWebhookMappingInput | UpdateEventWebhookMappingInput) => Promise<void>;\n onCancel: () => void;\n loading?: boolean;\n}\n\nconst WebhookForm: React.FC<WebhookFormProps> = memo(function WebhookForm({\n webhook,\n dashboardId,\n widgetId,\n onSave,\n onCancel,\n loading,\n}) {\n const { t } = useI18n();\n const [eventPattern, setEventPattern] = useState(webhook?.eventPattern || 'widget:*:clicked');\n const [webhookUrl, setWebhookUrl] = useState(webhook?.webhookUrl || '');\n const [method, setMethod] = useState(webhook?.method || 'POST');\n const [headers, setHeaders] = useState(webhook?.headers ? JSON.stringify(webhook.headers, null, 2) : '');\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n let parsedHeaders: Record<string, string> | undefined;\n if (headers.trim()) {\n try {\n parsedHeaders = JSON.parse(headers);\n } catch {\n alert(t('bigconsole.widget.webhookConfig.invalidJson', 'Invalid JSON in headers field'));\n return;\n }\n }\n\n if (webhook) {\n // Update\n await onSave({\n id: webhook.id,\n eventPattern,\n webhookUrl,\n method: method as 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n headers: parsedHeaders || null,\n });\n } else {\n // Create\n await onSave({\n dashboardId,\n widgetId,\n eventPattern,\n webhookUrl,\n method: method as 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n headers: parsedHeaders,\n });\n }\n };\n\n return (\n <form style={styles.form} onSubmit={handleSubmit}>\n <div style={styles.formGroup}>\n <label style={styles.label}>{t('bigconsole.widget.webhookConfig.eventPatternLabel', 'Event Pattern *')}</label>\n <input\n type=\"text\"\n value={eventPattern}\n onChange={(e) => setEventPattern(e.target.value)}\n placeholder=\"widget:*:clicked\"\n style={styles.input}\n required\n />\n <p style={styles.helpText}>\n {t(\n 'bigconsole.widget.webhookConfig.eventPatternHelp',\n 'Use * as wildcard. Examples: widget:*:clicked, *:submit, button:save:*'\n )}\n </p>\n </div>\n\n <div style={styles.formGroup}>\n <label style={styles.label}>{t('bigconsole.widget.webhookConfig.webhookUrlLabel', 'Webhook URL *')}</label>\n <input\n type=\"url\"\n value={webhookUrl}\n onChange={(e) => setWebhookUrl(e.target.value)}\n placeholder=\"https://your-api.com/webhooks/bigconsole\"\n style={styles.input}\n required\n />\n </div>\n\n <div style={styles.formGroup}>\n <label style={styles.label}>{t('bigconsole.widget.webhookConfig.httpMethodLabel', 'HTTP Method')}</label>\n <select value={method} onChange={(e) => setMethod(e.target.value as HttpMethod)} style={styles.select}>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"PATCH\">PATCH</option>\n <option value=\"GET\">GET</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n\n <div style={styles.formGroup}>\n <label style={styles.label}>\n {t('bigconsole.widget.webhookConfig.customHeadersLabel', 'Custom Headers (JSON)')}\n </label>\n <textarea\n value={headers}\n onChange={(e) => setHeaders(e.target.value)}\n placeholder={'{\\n \"Authorization\": \"Bearer your-token\"\\n}'}\n style={styles.textarea as React.CSSProperties}\n />\n </div>\n\n <div style={styles.formActions}>\n <button type=\"button\" onClick={onCancel} style={styles.cancelButton}>\n {t('bigconsole.widget.webhookConfig.cancel', 'Cancel')}\n </button>\n <button type=\"submit\" disabled={loading} style={styles.saveButton}>\n {loading\n ? t('bigconsole.widget.webhookConfig.saving', 'Saving...')\n : webhook\n ? t('bigconsole.widget.webhookConfig.updateWebhook', 'Update Webhook')\n : t('bigconsole.widget.webhookConfig.createWebhook', 'Create Webhook')}\n </button>\n </div>\n </form>\n );\n});\n\n// ============================================================================\n// Webhook Card Component\n// ============================================================================\n\ninterface WebhookCardProps {\n webhook: EventWebhookMapping;\n onEdit: () => void;\n onDelete: () => void;\n onToggle: () => void;\n onTest: () => void;\n testResult?: WebhookTestResult | null;\n testing?: boolean;\n}\n\nconst WebhookCard: React.FC<WebhookCardProps> = memo(function WebhookCard({\n webhook,\n onEdit,\n onDelete,\n onToggle,\n onTest,\n testResult,\n testing,\n}) {\n const { t } = useI18n();\n return (\n <div style={styles.webhookCard}>\n <div style={styles.webhookHeader}>\n <div style={styles.webhookTitle}>\n <span style={{ fontSize: '16px' }}>📡</span>\n <span style={styles.webhookName}>{webhook.eventPattern}</span>\n <span\n style={{\n ...styles.statusBadge,\n ...(webhook.isActive ? styles.activeBadge : styles.inactiveBadge),\n }}\n >\n {webhook.isActive\n ? t('bigconsole.widget.webhookConfig.active', 'Active')\n : t('bigconsole.widget.webhookConfig.inactive', 'Inactive')}\n </span>\n </div>\n </div>\n\n <div style={styles.webhookDetails}>\n {t('bigconsole.widget.webhookConfig.methodLabel', 'Method:')} <strong>{webhook.method}</strong>\n </div>\n <div style={styles.webhookUrl}>{webhook.webhookUrl}</div>\n\n {testResult && (\n <div\n style={{\n ...styles.testResult,\n ...(testResult.success ? styles.testSuccess : styles.testFailure),\n }}\n >\n {testResult.success ? (\n <>\n {t(\n 'bigconsole.widget.webhookConfig.testSuccess',\n '✅ Test successful! Status: {{statusCode}}, Latency: {{latencyMs}}ms',\n { statusCode: testResult.statusCode ?? '', latencyMs: testResult.latencyMs ?? '' }\n )}\n </>\n ) : (\n <>\n {t('bigconsole.widget.webhookConfig.testFailure', '❌ Test failed: {{error}}', {\n error: testResult.errorMessage || t('bigconsole.widget.webhookConfig.unknownError', 'Unknown error'),\n })}\n </>\n )}\n </div>\n )}\n\n <div style={styles.webhookActions}>\n <button onClick={onEdit} style={{ ...styles.actionButton, ...styles.editButton }}>\n {t('bigconsole.widget.webhookConfig.edit', 'Edit')}\n </button>\n <button onClick={onTest} disabled={testing} style={{ ...styles.actionButton, ...styles.testButton }}>\n {testing\n ? t('bigconsole.widget.webhookConfig.testing', 'Testing...')\n : t('bigconsole.widget.webhookConfig.test', 'Test')}\n </button>\n <button onClick={onToggle} style={{ ...styles.actionButton, ...styles.toggleButton }}>\n {webhook.isActive\n ? t('bigconsole.widget.webhookConfig.disable', 'Disable')\n : t('bigconsole.widget.webhookConfig.enable', 'Enable')}\n </button>\n <button onClick={onDelete} style={{ ...styles.actionButton, ...styles.deleteButton }}>\n {t('bigconsole.widget.webhookConfig.delete', 'Delete')}\n </button>\n </div>\n </div>\n );\n});\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport const WebhookConfigPanel: React.FC<WebhookConfigPanelProps> = memo(function WebhookConfigPanel({\n dashboardId,\n widgetId,\n onWebhookCreated,\n onWebhookDeleted,\n}) {\n const { t } = useI18n();\n const [showForm, setShowForm] = useState(false);\n const [editingWebhook, setEditingWebhook] = useState<EventWebhookMapping | null>(null);\n const [testResults, setTestResults] = useState<Record<string, WebhookTestResult | null>>({});\n const [testingId, setTestingId] = useState<string | null>(null);\n\n const { webhooks, loading, createWebhook, updateWebhook, deleteWebhook, toggleWebhook, testWebhook } =\n useEventWebhooks({ dashboardId, widgetId });\n\n const handleSave = useCallback(\n async (data: CreateEventWebhookMappingInput | UpdateEventWebhookMappingInput) => {\n if ('id' in data) {\n const result = await updateWebhook(data);\n if (result) {\n setEditingWebhook(null);\n setShowForm(false);\n }\n } else {\n const result = await createWebhook(data);\n if (result) {\n setShowForm(false);\n onWebhookCreated?.(result);\n }\n }\n },\n [createWebhook, updateWebhook, onWebhookCreated]\n );\n\n const handleDelete = useCallback(\n async (id: string) => {\n if (\n confirm(t('bigconsole.widget.webhookConfig.deleteConfirm', 'Are you sure you want to delete this webhook?'))\n ) {\n const success = await deleteWebhook(id);\n if (success) {\n onWebhookDeleted?.(id);\n }\n }\n },\n [deleteWebhook, onWebhookDeleted, t]\n );\n\n const handleToggle = useCallback(\n async (webhook: EventWebhookMapping) => {\n await toggleWebhook(webhook.id, !webhook.isActive);\n },\n [toggleWebhook]\n );\n\n const handleTest = useCallback(\n async (id: string) => {\n setTestingId(id);\n const result = await testWebhook(id);\n setTestResults((prev) => ({ ...prev, [id]: result }));\n setTestingId(null);\n },\n [testWebhook]\n );\n\n const handleEdit = useCallback((webhook: EventWebhookMapping) => {\n setEditingWebhook(webhook);\n setShowForm(true);\n }, []);\n\n const handleCancel = useCallback(() => {\n setShowForm(false);\n setEditingWebhook(null);\n }, []);\n\n return (\n <div style={styles.container}>\n <div style={styles.header}>\n <h3 style={styles.title}>{t('bigconsole.widget.webhookConfig.title', 'Webhook Configuration')}</h3>\n {!showForm && (\n <button onClick={() => setShowForm(true)} style={styles.addButton}>\n {t('bigconsole.widget.webhookConfig.addWebhook', '+ Add Webhook')}\n </button>\n )}\n </div>\n\n {showForm && (\n <WebhookForm\n webhook={editingWebhook || undefined}\n dashboardId={dashboardId}\n widgetId={widgetId}\n onSave={handleSave}\n onCancel={handleCancel}\n loading={loading}\n />\n )}\n\n {loading && webhooks.length === 0 ? (\n <div style={styles.emptyState}>{t('bigconsole.widget.webhookConfig.loading', 'Loading...')}</div>\n ) : webhooks.length === 0 ? (\n <div style={styles.emptyState}>\n <p>{t('bigconsole.widget.webhookConfig.noWebhooks', 'No webhooks configured')}</p>\n <p style={{ fontSize: '13px', marginTop: '8px' }}>\n {t(\n 'bigconsole.widget.webhookConfig.noWebhooksHelp',\n 'Add a webhook to receive events when actions are triggered.'\n )}\n </p>\n </div>\n ) : (\n <div style={styles.webhookList as React.CSSProperties}>\n {webhooks.map((webhook) => (\n <WebhookCard\n key={webhook.id}\n webhook={webhook}\n onEdit={() => handleEdit(webhook)}\n onDelete={() => handleDelete(webhook.id)}\n onToggle={() => handleToggle(webhook)}\n onTest={() => handleTest(webhook.id)}\n testResult={testResults[webhook.id]}\n testing={testingId === webhook.id}\n />\n ))}\n </div>\n )}\n </div>\n );\n});\n\nexport default WebhookConfigPanel;\n"],"mappings":"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"}
1
+ {"version":3,"file":"WebhookConfigPanel.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.tsx"],"sourcesContent":["/**\n * WebhookConfigPanel Component (v2.0)\n *\n * Panel for managing event webhook mappings.\n * Allows creating, editing, testing, and deleting webhooks.\n */\n\nimport React, { memo, useState, useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n useEventWebhooks,\n type HttpMethod,\n type EventWebhookMapping,\n type CreateEventWebhookMappingInput,\n type UpdateEventWebhookMappingInput,\n type WebhookTestResult,\n} from '../../../hooks/useEventWebhooks';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WebhookConfigPanelProps {\n /** Dashboard ID for webhook scope */\n dashboardId?: string;\n /** Widget ID for webhook scope */\n widgetId?: string;\n /** Callback when webhook is created */\n onWebhookCreated?: (webhook: EventWebhookMapping) => void;\n /** Callback when webhook is deleted */\n onWebhookDeleted?: (id: string) => void;\n}\n\n// ============================================================================\n// Styles\n// ============================================================================\n\n/**\n * Section emphasis (BOFF-5636). This panel used to draw its own card (16px\n * padding, surface fill, 8px radius) and its own 16px `<h3>Webhook\n * Configuration</h3>` — directly beneath the inspector's own 14px \"Webhooks\"\n * heading, so the child heading was larger than its parent. The owning\n * `<Section>` now supplies the surface, the heading and the description; this\n * component supplies only the toolbar, the list and the form.\n */\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-formGap)',\n minWidth: 0,\n } as React.CSSProperties,\n header: {\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n } as React.CSSProperties,\n addButton: {\n minHeight: 'var(--size-controlHeight-md)',\n padding: '0 var(--space-formGap)',\n backgroundColor: 'var(--color-action-primary-bg)',\n color: 'var(--color-action-primary-text)',\n border: 'none',\n borderRadius: 'var(--radius-button)',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 500,\n cursor: 'pointer',\n } as React.CSSProperties,\n webhookList: {\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n } as React.CSSProperties,\n webhookCard: {\n padding: 'var(--space-cardPadding)',\n backgroundColor: 'var(--color-bg-sunken)',\n borderRadius: 'var(--radius-card)',\n border: '1px solid var(--color-border-subtle)',\n minWidth: 0,\n } as React.CSSProperties,\n webhookHeader: {\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n gap: 'var(--space-iconGap)',\n marginBottom: '8px',\n minWidth: 0,\n } as React.CSSProperties,\n webhookTitle: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '8px',\n minWidth: 0,\n } as React.CSSProperties,\n webhookName: {\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 600,\n color: 'var(--color-text-primary)',\n wordBreak: 'break-word',\n } as React.CSSProperties,\n statusBadge: {\n padding: '2px 8px',\n borderRadius: '12px',\n fontSize: '12px',\n fontWeight: 500,\n } as React.CSSProperties,\n activeBadge: {\n backgroundColor: 'var(--color-status-success-bgSubtle)',\n color: 'var(--color-status-success-text)',\n } as React.CSSProperties,\n inactiveBadge: {\n backgroundColor: 'var(--color-status-warning-bgSubtle)',\n color: 'var(--color-status-warning-text)',\n } as React.CSSProperties,\n webhookDetails: {\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-secondary)',\n marginBottom: '4px',\n } as React.CSSProperties,\n webhookUrl: {\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n fontFamily: 'var(--font-family-mono)',\n wordBreak: 'break-all',\n } as React.CSSProperties,\n // Four buttons in a 420px sheet: they wrap rather than overflow the panel.\n webhookActions: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '8px',\n marginTop: '12px',\n } as React.CSSProperties,\n actionButton: {\n minHeight: 'var(--size-controlHeight-md)',\n padding: '0 12px',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 500,\n borderRadius: 'var(--radius-button)',\n border: 'none',\n cursor: 'pointer',\n } as React.CSSProperties,\n editButton: {\n backgroundColor: 'var(--color-bg-sunken)',\n color: 'var(--color-text-primary)',\n } as React.CSSProperties,\n testButton: {\n backgroundColor: 'var(--color-status-info-bgSubtle)',\n color: 'var(--color-status-info-text)',\n } as React.CSSProperties,\n deleteButton: {\n backgroundColor: 'var(--color-status-error-bgSubtle)',\n color: 'var(--color-status-error-text)',\n } as React.CSSProperties,\n toggleButton: {\n backgroundColor: 'var(--color-bg-sunken)',\n color: 'var(--color-text-muted)',\n } as React.CSSProperties,\n emptyState: {\n textAlign: 'center',\n padding: 'var(--space-pagePadding) var(--space-formGap)',\n color: 'var(--color-text-secondary)',\n backgroundColor: 'var(--color-status-info-bgSubtle)',\n border: '1px solid var(--color-status-info-border)',\n borderRadius: 'var(--radius-card)',\n } as React.CSSProperties,\n emptyTitle: {\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 600,\n color: 'var(--color-status-info-text)',\n margin: 0,\n } as React.CSSProperties,\n form: {\n padding: 'var(--space-cardPadding)',\n backgroundColor: 'var(--color-bg-sunken)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 'var(--radius-card)',\n minWidth: 0,\n } as React.CSSProperties,\n formGroup: {\n marginBottom: '12px',\n } as React.CSSProperties,\n label: {\n display: 'block',\n fontSize: '13px',\n fontWeight: 500,\n color: 'var(--color-text-primary)',\n marginBottom: '4px',\n } as React.CSSProperties,\n input: {\n width: '100%',\n minHeight: 'var(--size-controlHeight-md)',\n padding: '8px 12px',\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-primary)',\n backgroundColor: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 'var(--radius-input)',\n boxSizing: 'border-box',\n } as React.CSSProperties,\n select: {\n width: '100%',\n minHeight: 'var(--size-controlHeight-md)',\n padding: '8px 12px',\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-primary)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 'var(--radius-input)',\n boxSizing: 'border-box',\n backgroundColor: 'var(--color-bg-surface)',\n } as React.CSSProperties,\n textarea: {\n width: '100%',\n padding: '8px 12px',\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-primary)',\n backgroundColor: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 'var(--radius-input)',\n boxSizing: 'border-box',\n fontFamily: 'var(--font-family-mono)',\n minHeight: '80px',\n resize: 'vertical',\n } as React.CSSProperties,\n formActions: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '8px',\n justifyContent: 'flex-end',\n marginTop: 'var(--space-formGap)',\n } as React.CSSProperties,\n cancelButton: {\n minHeight: 'var(--size-controlHeight-md)',\n padding: '0 var(--space-formGap)',\n backgroundColor: 'var(--color-bg-surface)',\n color: 'var(--color-text-primary)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 'var(--radius-button)',\n fontSize: 'var(--font-size-body-sm)',\n cursor: 'pointer',\n } as React.CSSProperties,\n saveButton: {\n minHeight: 'var(--size-controlHeight-md)',\n padding: '0 var(--space-formGap)',\n backgroundColor: 'var(--color-action-primary-bg)',\n color: 'var(--color-action-primary-text)',\n border: 'none',\n borderRadius: 'var(--radius-button)',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 500,\n cursor: 'pointer',\n } as React.CSSProperties,\n testResult: {\n marginTop: '12px',\n padding: '12px',\n borderRadius: '6px',\n fontSize: '13px',\n } as React.CSSProperties,\n testSuccess: {\n backgroundColor: 'var(--color-status-success-bgSubtle)',\n color: 'var(--color-status-success-text)',\n } as React.CSSProperties,\n testFailure: {\n backgroundColor: 'var(--color-status-error-bgSubtle)',\n color: 'var(--color-status-error-text)',\n } as React.CSSProperties,\n helpText: {\n fontSize: '12px',\n color: 'var(--color-text-placeholder)',\n marginTop: '4px',\n } as React.CSSProperties,\n};\n\n// ============================================================================\n// Webhook Form Component\n// ============================================================================\n\ninterface WebhookFormProps {\n webhook?: EventWebhookMapping;\n dashboardId?: string;\n widgetId?: string;\n onSave: (data: CreateEventWebhookMappingInput | UpdateEventWebhookMappingInput) => Promise<void>;\n onCancel: () => void;\n loading?: boolean;\n}\n\nconst WebhookForm: React.FC<WebhookFormProps> = memo(function WebhookForm({\n webhook,\n dashboardId,\n widgetId,\n onSave,\n onCancel,\n loading,\n}) {\n const { t } = useI18n();\n const [eventPattern, setEventPattern] = useState(webhook?.eventPattern || 'widget:*:clicked');\n const [webhookUrl, setWebhookUrl] = useState(webhook?.webhookUrl || '');\n const [method, setMethod] = useState(webhook?.method || 'POST');\n const [headers, setHeaders] = useState(webhook?.headers ? JSON.stringify(webhook.headers, null, 2) : '');\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n let parsedHeaders: Record<string, string> | undefined;\n if (headers.trim()) {\n try {\n parsedHeaders = JSON.parse(headers);\n } catch {\n alert(t('bigconsole.widget.webhookConfig.invalidJson', 'Invalid JSON in headers field'));\n return;\n }\n }\n\n if (webhook) {\n // Update\n await onSave({\n id: webhook.id,\n eventPattern,\n webhookUrl,\n method: method as 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n headers: parsedHeaders || null,\n });\n } else {\n // Create\n await onSave({\n dashboardId,\n widgetId,\n eventPattern,\n webhookUrl,\n method: method as 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n headers: parsedHeaders,\n });\n }\n };\n\n return (\n <form style={styles.form} onSubmit={handleSubmit}>\n <div style={styles.formGroup}>\n <label style={styles.label}>{t('bigconsole.widget.webhookConfig.eventPatternLabel', 'Event Pattern *')}</label>\n <input\n type=\"text\"\n value={eventPattern}\n onChange={(e) => setEventPattern(e.target.value)}\n placeholder=\"widget:*:clicked\"\n style={styles.input}\n required\n />\n <p style={styles.helpText}>\n {t(\n 'bigconsole.widget.webhookConfig.eventPatternHelp',\n 'Use * as wildcard. Examples: widget:*:clicked, *:submit, button:save:*'\n )}\n </p>\n </div>\n\n <div style={styles.formGroup}>\n <label style={styles.label}>{t('bigconsole.widget.webhookConfig.webhookUrlLabel', 'Webhook URL *')}</label>\n <input\n type=\"url\"\n value={webhookUrl}\n onChange={(e) => setWebhookUrl(e.target.value)}\n placeholder=\"https://your-api.com/webhooks/bigconsole\"\n style={styles.input}\n required\n />\n </div>\n\n <div style={styles.formGroup}>\n <label style={styles.label}>{t('bigconsole.widget.webhookConfig.httpMethodLabel', 'HTTP Method')}</label>\n <select value={method} onChange={(e) => setMethod(e.target.value as HttpMethod)} style={styles.select}>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"PATCH\">PATCH</option>\n <option value=\"GET\">GET</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n\n <div style={styles.formGroup}>\n <label style={styles.label}>\n {t('bigconsole.widget.webhookConfig.customHeadersLabel', 'Custom Headers (JSON)')}\n </label>\n <textarea\n value={headers}\n onChange={(e) => setHeaders(e.target.value)}\n placeholder={'{\\n \"Authorization\": \"Bearer your-token\"\\n}'}\n style={styles.textarea as React.CSSProperties}\n />\n </div>\n\n <div style={styles.formActions}>\n <button type=\"button\" onClick={onCancel} style={styles.cancelButton}>\n {t('bigconsole.widget.webhookConfig.cancel', 'Cancel')}\n </button>\n <button type=\"submit\" disabled={loading} style={styles.saveButton}>\n {loading\n ? t('bigconsole.widget.webhookConfig.saving', 'Saving...')\n : webhook\n ? t('bigconsole.widget.webhookConfig.updateWebhook', 'Update Webhook')\n : t('bigconsole.widget.webhookConfig.createWebhook', 'Create Webhook')}\n </button>\n </div>\n </form>\n );\n});\n\n// ============================================================================\n// Webhook Card Component\n// ============================================================================\n\ninterface WebhookCardProps {\n webhook: EventWebhookMapping;\n onEdit: () => void;\n onDelete: () => void;\n onToggle: () => void;\n onTest: () => void;\n testResult?: WebhookTestResult | null;\n testing?: boolean;\n}\n\nconst WebhookCard: React.FC<WebhookCardProps> = memo(function WebhookCard({\n webhook,\n onEdit,\n onDelete,\n onToggle,\n onTest,\n testResult,\n testing,\n}) {\n const { t } = useI18n();\n return (\n <div style={styles.webhookCard}>\n <div style={styles.webhookHeader}>\n <div style={styles.webhookTitle}>\n <span style={styles.webhookName}>{webhook.eventPattern}</span>\n <span\n style={{\n ...styles.statusBadge,\n ...(webhook.isActive ? styles.activeBadge : styles.inactiveBadge),\n }}\n >\n {webhook.isActive\n ? t('bigconsole.widget.webhookConfig.active', 'Active')\n : t('bigconsole.widget.webhookConfig.inactive', 'Inactive')}\n </span>\n </div>\n </div>\n\n <div style={styles.webhookDetails}>\n {t('bigconsole.widget.webhookConfig.methodLabel', 'Method:')} <strong>{webhook.method}</strong>\n </div>\n <div style={styles.webhookUrl}>{webhook.webhookUrl}</div>\n\n {testResult && (\n <div\n role=\"status\"\n style={{\n ...styles.testResult,\n ...(testResult.success ? styles.testSuccess : styles.testFailure),\n }}\n >\n {testResult.success ? (\n <>\n {t(\n 'bigconsole.widget.webhookConfig.testSuccess',\n 'Test successful! Status: {{statusCode}}, Latency: {{latencyMs}}ms',\n { statusCode: testResult.statusCode ?? '', latencyMs: testResult.latencyMs ?? '' }\n )}\n </>\n ) : (\n <>\n {t('bigconsole.widget.webhookConfig.testFailure', 'Test failed: {{error}}', {\n error: testResult.errorMessage || t('bigconsole.widget.webhookConfig.unknownError', 'Unknown error'),\n })}\n </>\n )}\n </div>\n )}\n\n <div style={styles.webhookActions}>\n <button onClick={onEdit} style={{ ...styles.actionButton, ...styles.editButton }}>\n {t('bigconsole.widget.webhookConfig.edit', 'Edit')}\n </button>\n <button onClick={onTest} disabled={testing} style={{ ...styles.actionButton, ...styles.testButton }}>\n {testing\n ? t('bigconsole.widget.webhookConfig.testing', 'Testing...')\n : t('bigconsole.widget.webhookConfig.test', 'Test')}\n </button>\n <button onClick={onToggle} style={{ ...styles.actionButton, ...styles.toggleButton }}>\n {webhook.isActive\n ? t('bigconsole.widget.webhookConfig.disable', 'Disable')\n : t('bigconsole.widget.webhookConfig.enable', 'Enable')}\n </button>\n <button onClick={onDelete} style={{ ...styles.actionButton, ...styles.deleteButton }}>\n {t('bigconsole.widget.webhookConfig.delete', 'Delete')}\n </button>\n </div>\n </div>\n );\n});\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport const WebhookConfigPanel: React.FC<WebhookConfigPanelProps> = memo(function WebhookConfigPanel({\n dashboardId,\n widgetId,\n onWebhookCreated,\n onWebhookDeleted,\n}) {\n const { t } = useI18n();\n const [showForm, setShowForm] = useState(false);\n const [editingWebhook, setEditingWebhook] = useState<EventWebhookMapping | null>(null);\n const [testResults, setTestResults] = useState<Record<string, WebhookTestResult | null>>({});\n const [testingId, setTestingId] = useState<string | null>(null);\n\n const { webhooks, loading, createWebhook, updateWebhook, deleteWebhook, toggleWebhook, testWebhook } =\n useEventWebhooks({ dashboardId, widgetId });\n\n const handleSave = useCallback(\n async (data: CreateEventWebhookMappingInput | UpdateEventWebhookMappingInput) => {\n if ('id' in data) {\n const result = await updateWebhook(data);\n if (result) {\n setEditingWebhook(null);\n setShowForm(false);\n }\n } else {\n const result = await createWebhook(data);\n if (result) {\n setShowForm(false);\n onWebhookCreated?.(result);\n }\n }\n },\n [createWebhook, updateWebhook, onWebhookCreated]\n );\n\n const handleDelete = useCallback(\n async (id: string) => {\n if (\n confirm(t('bigconsole.widget.webhookConfig.deleteConfirm', 'Are you sure you want to delete this webhook?'))\n ) {\n const success = await deleteWebhook(id);\n if (success) {\n onWebhookDeleted?.(id);\n }\n }\n },\n [deleteWebhook, onWebhookDeleted, t]\n );\n\n const handleToggle = useCallback(\n async (webhook: EventWebhookMapping) => {\n await toggleWebhook(webhook.id, !webhook.isActive);\n },\n [toggleWebhook]\n );\n\n const handleTest = useCallback(\n async (id: string) => {\n setTestingId(id);\n const result = await testWebhook(id);\n setTestResults((prev) => ({ ...prev, [id]: result }));\n setTestingId(null);\n },\n [testWebhook]\n );\n\n const handleEdit = useCallback((webhook: EventWebhookMapping) => {\n setEditingWebhook(webhook);\n setShowForm(true);\n }, []);\n\n const handleCancel = useCallback(() => {\n setShowForm(false);\n setEditingWebhook(null);\n }, []);\n\n return (\n <div style={styles.container} data-testid=\"webhook-config-panel\">\n {!showForm && (\n <div style={styles.header}>\n <button type=\"button\" onClick={() => setShowForm(true)} style={styles.addButton}>\n {t('bigconsole.widget.webhookConfig.addWebhook', '+ Add Webhook')}\n </button>\n </div>\n )}\n\n {showForm && (\n <WebhookForm\n webhook={editingWebhook || undefined}\n dashboardId={dashboardId}\n widgetId={widgetId}\n onSave={handleSave}\n onCancel={handleCancel}\n loading={loading}\n />\n )}\n\n {loading && webhooks.length === 0 ? (\n <div style={styles.emptyState} role=\"status\">\n <p style={styles.emptyTitle}>{t('bigconsole.widget.webhookConfig.loading', 'Loading...')}</p>\n </div>\n ) : webhooks.length === 0 ? (\n <div style={styles.emptyState} role=\"status\">\n <p style={styles.emptyTitle}>{t('bigconsole.widget.webhookConfig.noWebhooks', 'No webhooks configured')}</p>\n <p style={{ fontSize: 'var(--font-size-body-sm)', marginTop: '8px' }}>\n {t(\n 'bigconsole.widget.webhookConfig.noWebhooksHelp',\n 'Add a webhook to receive events when actions are triggered.'\n )}\n </p>\n </div>\n ) : (\n <div style={styles.webhookList as React.CSSProperties}>\n {webhooks.map((webhook) => (\n <WebhookCard\n key={webhook.id}\n webhook={webhook}\n onEdit={() => handleEdit(webhook)}\n onDelete={() => handleDelete(webhook.id)}\n onToggle={() => handleToggle(webhook)}\n onTest={() => handleTest(webhook.id)}\n testResult={testResults[webhook.id]}\n testing={testingId === webhook.id}\n />\n ))}\n </div>\n )}\n </div>\n );\n});\n\nexport default WebhookConfigPanel;\n"],"mappings":"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"}
@@ -243,34 +243,36 @@ var g = t(function({ name: e, className: t = "w-4 h-4" }) {
243
243
  justifyContent: "center"
244
244
  },
245
245
  children: [/* @__PURE__ */ l("div", {
246
- className: "absolute inset-0 bg-black/50",
246
+ className: "absolute inset-0",
247
247
  style: {
248
248
  position: "absolute",
249
249
  top: 0,
250
250
  left: 0,
251
251
  right: 0,
252
252
  bottom: 0,
253
- backgroundColor: "rgba(0,0,0,0.5)"
253
+ backgroundColor: "var(--color-overlay-scrim, var(--color-bg-canvas))",
254
+ opacity: .6
254
255
  },
255
256
  onClick: o
256
257
  }), /* @__PURE__ */ u("div", {
257
- className: "relative bg-surface rounded-lg shadow-xl max-w-md w-full mx-4 p-6 animate-in fade-in zoom-in-95 duration-200",
258
+ className: "relative mx-4 w-full max-w-md rounded-card p-6",
258
259
  style: {
259
260
  position: "relative",
260
261
  backgroundColor: "var(--color-bg-surface)",
261
- borderRadius: "8px",
262
- boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
262
+ border: "1px solid var(--color-border-subtle)",
263
+ borderRadius: "var(--radius-card)",
264
+ boxShadow: "var(--shadow-elevation-3)",
263
265
  maxWidth: "28rem",
264
266
  width: "100%",
265
267
  margin: "0 16px",
266
- padding: "24px",
268
+ padding: "var(--space-cardPadding)",
267
269
  zIndex: 1e4
268
270
  },
269
271
  children: [
270
272
  /* @__PURE__ */ l("h3", {
271
- className: "text-lg font-semibold text-primary",
273
+ className: "text-base font-semibold text-text-primary",
272
274
  style: {
273
- fontSize: "18px",
275
+ fontSize: "var(--font-size-body-lg)",
274
276
  fontWeight: 600,
275
277
  color: "var(--color-text-primary)",
276
278
  margin: 0
@@ -278,34 +280,36 @@ var g = t(function({ name: e, className: t = "w-4 h-4" }) {
278
280
  children: e
279
281
  }),
280
282
  /* @__PURE__ */ l("p", {
281
- className: "mt-2 text-sm text-secondary",
283
+ className: "mt-2 text-sm text-text-secondary",
282
284
  style: {
283
285
  marginTop: "8px",
284
- fontSize: "14px",
286
+ fontSize: "var(--font-size-body-sm)",
285
287
  color: "var(--color-text-secondary)"
286
288
  },
287
289
  children: t
288
290
  }),
289
291
  /* @__PURE__ */ u("div", {
290
- className: "mt-4 flex justify-end gap-3",
292
+ className: "mt-4 flex flex-wrap justify-end gap-3",
291
293
  style: {
292
294
  marginTop: "16px",
293
295
  display: "flex",
296
+ flexWrap: "wrap",
294
297
  justifyContent: "flex-end",
295
298
  gap: "12px"
296
299
  },
297
300
  children: [/* @__PURE__ */ l("button", {
298
301
  type: "button",
299
302
  onClick: o,
300
- className: "px-4 py-2 text-sm font-medium text-secondary bg-bg-sunken hover:bg-bg-sunken/80 rounded-md transition-colors",
303
+ className: "min-h-control-md rounded-button px-4 text-sm font-medium text-text-secondary hover:text-text-primary motion-safe:transition-colors",
301
304
  style: {
302
- padding: "8px 16px",
303
- fontSize: "14px",
305
+ minHeight: "var(--size-controlHeight-md)",
306
+ padding: "0 16px",
307
+ fontSize: "var(--font-size-body-sm)",
304
308
  fontWeight: 500,
305
309
  color: "var(--color-text-secondary)",
306
- backgroundColor: "var(--color-bg-muted)",
307
- borderRadius: "6px",
308
- border: "none",
310
+ backgroundColor: "var(--color-bg-sunken)",
311
+ borderRadius: "var(--radius-button)",
312
+ border: "1px solid var(--color-border-subtle)",
309
313
  cursor: "pointer"
310
314
  },
311
315
  children: r
@@ -353,10 +357,14 @@ var g = t(function({ name: e, className: t = "w-4 h-4" }) {
353
357
  className: "fixed inset-0 z-[9998]",
354
358
  onClick: S
355
359
  }), /* @__PURE__ */ l("div", {
356
- className: "fixed w-48 bg-surface rounded-md shadow-lg ring-1 ring-border z-[9999] animate-in fade-in slide-in-from-top-2 duration-150",
360
+ className: "fixed z-[9999] w-48 max-w-[calc(100vw-1rem)] rounded-card",
357
361
  style: {
358
362
  top: v.top,
359
- left: Math.max(8, v.left)
363
+ left: Math.max(8, v.left),
364
+ backgroundColor: "var(--color-bg-surface)",
365
+ border: "1px solid var(--color-border-subtle)",
366
+ borderRadius: "var(--radius-card)",
367
+ boxShadow: "var(--shadow-elevation-3)"
360
368
  },
361
369
  children: /* @__PURE__ */ l("div", {
362
370
  className: "py-1",
@@ -364,7 +372,7 @@ var g = t(function({ name: e, className: t = "w-4 h-4" }) {
364
372
  type: "button",
365
373
  onClick: () => x(e),
366
374
  disabled: e.disabled,
367
- className: "w-full text-left px-4 py-2 text-sm text-secondary hover:bg-bg-sunken hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2 transition-colors",
375
+ className: "flex min-h-control-md w-full items-center gap-2 px-4 text-left text-sm text-text-secondary hover:bg-bg-sunken hover:text-text-primary disabled:cursor-not-allowed disabled:opacity-50 motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
368
376
  children: [e.icon && /* @__PURE__ */ l(g, {
369
377
  name: e.icon,
370
378
  className: "w-4 h-4"
@@ -1 +1 @@
1
- {"version":3,"file":"WidgetActions.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/widget-actions/WidgetActions.tsx"],"sourcesContent":["/**\n * Widget Actions Component (v2.0)\n *\n * Renders interactive action buttons for widgets.\n * Supports multiple action types, styles, confirmation dialogs, and icons.\n */\n\nimport React, { memo, useCallback, useState, useMemo, useRef, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport type { WidgetAction, ActionContext, ActionResult } from '../../../renderers/types/renderer';\nimport { BIGCONSOLE_PERMISSIONS } from '../../../../constants/permissions';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetActionsProps {\n /** List of actions to render */\n actions: WidgetAction[];\n /** Action context (widget ID, data, etc.) */\n context: ActionContext;\n /** Callback when action is triggered */\n onAction?: (action: WidgetAction, context: ActionContext) => Promise<ActionResult | void>;\n /** Whether actions are disabled */\n disabled?: boolean;\n /** Layout direction */\n layout?: 'horizontal' | 'vertical';\n /** Size of action buttons */\n size?: 'sm' | 'md' | 'lg';\n /** Whether to show labels */\n showLabels?: boolean;\n /** Maximum number of visible actions (rest go to overflow menu) */\n maxVisible?: number;\n /** Custom class name */\n className?: string;\n}\n\ninterface ConfirmationDialogProps {\n title: string;\n message: string;\n confirmLabel: string;\n cancelLabel: string;\n style: WidgetAction['style'];\n onConfirm: () => void;\n onCancel: () => void;\n}\n\n// ============================================================================\n// Style Utilities\n// ============================================================================\n\nfunction getButtonClasses(\n style: WidgetAction['style'] | undefined,\n size: 'sm' | 'md' | 'lg',\n disabled: boolean\n): string {\n const baseClasses =\n 'inline-flex items-center justify-center font-medium rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2';\n\n const sizeClasses = {\n sm: 'px-2.5 py-1.5 text-xs',\n md: 'px-4 py-2 text-sm',\n lg: 'px-6 py-3 text-base',\n };\n\n const styleClasses: Record<string, string> = {\n PRIMARY: 'bg-action-primary text-white hover:bg-action-primary/90 focus:ring-action-primary/50 transition-colors',\n SECONDARY: 'bg-bg-sunken text-primary hover:bg-bg-sunken/80 focus:ring-muted transition-colors',\n DANGER:\n 'bg-status-error-bg text-white hover:bg-status-error-bg/90 focus:ring-status-error-border/50 transition-colors',\n SUCCESS:\n 'bg-status-success-bg text-white hover:bg-status-success-bg/90 focus:ring-status-success-border/50 transition-colors',\n WARNING:\n 'bg-status-warning-bg text-white hover:bg-status-warning-bg/90 focus:ring-status-warning-border/50 transition-colors',\n };\n\n const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer';\n\n // Default to SECONDARY if style is undefined\n const effectiveStyle = style || 'SECONDARY';\n const styleClass = styleClasses[effectiveStyle] || styleClasses.SECONDARY;\n\n return `${baseClasses} ${sizeClasses[size]} ${styleClass} ${disabledClasses}`;\n}\n\n// Get inline styles as fallback for button visibility\nfunction getButtonInlineStyles(style: WidgetAction['style'] | undefined): React.CSSProperties {\n const styles: Record<string, React.CSSProperties> = {\n PRIMARY: { backgroundColor: 'var(--color-action-primary-bg)', color: 'var(--color-action-primary-text)' },\n SECONDARY: { backgroundColor: 'var(--color-bg-muted)', color: 'var(--color-text-primary)' },\n DANGER: { backgroundColor: 'var(--color-status-error-bg)', color: 'var(--color-action-primary-text)' },\n SUCCESS: { backgroundColor: 'var(--color-status-success-bg)', color: 'var(--color-action-primary-text)' },\n WARNING: { backgroundColor: 'var(--color-status-warning-bg)', color: 'var(--color-action-primary-text)' },\n };\n const effectiveStyle = style || 'SECONDARY';\n return styles[effectiveStyle] || styles.SECONDARY;\n}\n\nfunction getConfirmButtonClasses(style: WidgetAction['style']): string {\n const styleClasses = {\n PRIMARY: 'bg-action-primary text-white hover:bg-action-primary/90',\n SECONDARY: 'bg-secondary text-white hover:bg-secondary/90',\n DANGER: 'bg-status-error-bg text-white hover:bg-status-error-bg/90',\n SUCCESS: 'bg-status-success-bg text-white hover:bg-status-success-bg/90',\n WARNING: 'bg-status-warning-bg text-white hover:bg-status-warning-bg/90',\n };\n\n const effectiveStyle = style || 'PRIMARY';\n return `px-4 py-2 text-sm font-medium rounded-md transition-colors ${styleClasses[effectiveStyle] || styleClasses.PRIMARY}`;\n}\n\n// Get inline styles for confirm button to ensure visibility\nfunction getConfirmButtonInlineStyles(style: WidgetAction['style'] | undefined): React.CSSProperties {\n const styles: Record<string, React.CSSProperties> = {\n PRIMARY: {\n backgroundColor: 'var(--color-action-primary-bg)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n SECONDARY: {\n backgroundColor: 'var(--color-text-secondary)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n DANGER: {\n backgroundColor: 'var(--color-status-error-bg)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n SUCCESS: {\n backgroundColor: 'var(--color-status-success-bg)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n WARNING: {\n backgroundColor: 'var(--color-status-warning-bg)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n };\n const effectiveStyle = style || 'PRIMARY';\n return styles[effectiveStyle] || styles.PRIMARY;\n}\n\n// ============================================================================\n// Icon Component\n// ============================================================================\n\ninterface ActionIconProps {\n name: string;\n className?: string;\n}\n\nconst ActionIcon: React.FC<ActionIconProps> = memo(function ActionIcon({ name, className = 'w-4 h-4' }) {\n // Common icons used in actions\n const icons: Record<string, React.ReactNode> = {\n 'external-link': (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n ),\n save: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4\"\n />\n </svg>\n ),\n trash: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n ),\n edit: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"\n />\n </svg>\n ),\n refresh: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n ),\n download: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"\n />\n </svg>\n ),\n upload: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12\"\n />\n </svg>\n ),\n plus: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n ),\n check: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n ),\n x: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ),\n 'more-horizontal': (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z\"\n />\n </svg>\n ),\n };\n\n return icons[name] || null;\n});\n\n// ============================================================================\n// Confirmation Dialog\n// ============================================================================\n\nconst ConfirmationDialog: React.FC<ConfirmationDialogProps> = memo(function ConfirmationDialog({\n title,\n message,\n confirmLabel,\n cancelLabel,\n style,\n onConfirm,\n onCancel,\n}) {\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {/* Backdrop */}\n <div\n className=\"absolute inset-0 bg-black/50\"\n style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.5)' }}\n onClick={onCancel}\n />\n\n {/* Dialog */}\n <div\n className=\"relative bg-surface rounded-lg shadow-xl max-w-md w-full mx-4 p-6 animate-in fade-in zoom-in-95 duration-200\"\n style={{\n position: 'relative',\n backgroundColor: 'var(--color-bg-surface)',\n borderRadius: '8px',\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)',\n maxWidth: '28rem',\n width: '100%',\n margin: '0 16px',\n padding: '24px',\n zIndex: 10000,\n }}\n >\n <h3\n className=\"text-lg font-semibold text-primary\"\n style={{ fontSize: '18px', fontWeight: 600, color: 'var(--color-text-primary)', margin: 0 }}\n >\n {title}\n </h3>\n <p\n className=\"mt-2 text-sm text-secondary\"\n style={{ marginTop: '8px', fontSize: '14px', color: 'var(--color-text-secondary)' }}\n >\n {message}\n </p>\n <div\n className=\"mt-4 flex justify-end gap-3\"\n style={{ marginTop: '16px', display: 'flex', justifyContent: 'flex-end', gap: '12px' }}\n >\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-4 py-2 text-sm font-medium text-secondary bg-bg-sunken hover:bg-bg-sunken/80 rounded-md transition-colors\"\n style={{\n padding: '8px 16px',\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--color-text-secondary)',\n backgroundColor: 'var(--color-bg-muted)',\n borderRadius: '6px',\n border: 'none',\n cursor: 'pointer',\n }}\n >\n {cancelLabel}\n </button>\n <button\n type=\"button\"\n onClick={onConfirm}\n className={getConfirmButtonClasses(style)}\n style={getConfirmButtonInlineStyles(style)}\n >\n {confirmLabel}\n </button>\n </div>\n </div>\n </div>\n );\n});\n\n// ============================================================================\n// Overflow Menu\n// ============================================================================\n\ninterface OverflowMenuProps {\n actions: WidgetAction[];\n context: ActionContext;\n onAction: (action: WidgetAction) => void;\n disabled?: boolean;\n size: 'sm' | 'md' | 'lg';\n}\n\nconst OverflowMenu: React.FC<OverflowMenuProps> = memo(function OverflowMenu({\n actions,\n context: _context,\n onAction,\n disabled,\n size,\n}) {\n const [isOpen, setIsOpen] = useState(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });\n\n const handleToggle = useCallback(() => {\n if (!disabled) {\n setIsOpen((prev) => !prev);\n }\n }, [disabled]);\n\n const handleAction = useCallback(\n (action: WidgetAction) => {\n setIsOpen(false);\n onAction(action);\n },\n [onAction]\n );\n\n const handleClickOutside = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n // Calculate menu position when opening\n useEffect(() => {\n if (isOpen && buttonRef.current) {\n const rect = buttonRef.current.getBoundingClientRect();\n setMenuPosition({\n top: rect.bottom + 4, // 4px gap below button\n left: rect.right - 192, // 192px = w-48, align right edge\n });\n }\n }, [isOpen]);\n\n if (actions.length === 0) return null;\n\n return (\n <div className=\"relative\">\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={handleToggle}\n disabled={disabled}\n className={getButtonClasses('SECONDARY', size, disabled ?? false)}\n aria-label=\"More actions\"\n >\n <ActionIcon name=\"more-horizontal\" />\n </button>\n\n {isOpen &&\n createPortal(\n <>\n {/* Click-outside handler */}\n <div className=\"fixed inset-0 z-[9998]\" onClick={handleClickOutside} />\n\n {/* Menu - rendered via portal at body level */}\n <div\n className=\"fixed w-48 bg-surface rounded-md shadow-lg ring-1 ring-border z-[9999] animate-in fade-in slide-in-from-top-2 duration-150\"\n style={{\n top: menuPosition.top,\n left: Math.max(8, menuPosition.left), // Ensure at least 8px from left edge\n }}\n >\n <div className=\"py-1\">\n {actions.map((action) => (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => handleAction(action)}\n disabled={action.disabled}\n className=\"w-full text-left px-4 py-2 text-sm text-secondary hover:bg-bg-sunken hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2 transition-colors\"\n >\n {action.icon && <ActionIcon name={action.icon} className=\"w-4 h-4\" />}\n {action.label}\n </button>\n ))}\n </div>\n </div>\n </>,\n document.body\n )}\n </div>\n );\n});\n\n// ============================================================================\n// Action Button\n// ============================================================================\n\ninterface ActionButtonProps {\n action: WidgetAction;\n context: ActionContext;\n onAction: (action: WidgetAction) => void;\n disabled?: boolean;\n size: 'sm' | 'md' | 'lg';\n showLabel?: boolean;\n}\n\nconst ActionButton: React.FC<ActionButtonProps> = memo(function ActionButton({\n action,\n context: _context,\n onAction,\n disabled,\n size,\n showLabel = true,\n}) {\n const isDisabled = disabled || action.disabled;\n\n const handleClick = useCallback(() => {\n if (!isDisabled) {\n onAction(action);\n }\n }, [action, isDisabled, onAction]);\n\n // Get both classes and inline styles for guaranteed visibility\n const buttonClasses = getButtonClasses(action.style, size, isDisabled);\n const buttonInlineStyles = getButtonInlineStyles(action.style);\n\n // Handle LINK type\n if (action.type === 'LINK' && action.metadata?.url) {\n return (\n <a\n href={action.metadata.url as string}\n target={(action.metadata.target as string) || '_blank'}\n rel=\"noopener noreferrer\"\n className={buttonClasses}\n style={buttonInlineStyles}\n aria-disabled={isDisabled}\n >\n {action.icon && <ActionIcon name={action.icon} className=\"w-4 h-4 mr-1.5\" />}\n {showLabel && action.label}\n {!action.icon && <ActionIcon name=\"external-link\" className=\"w-4 h-4 ml-1.5\" />}\n </a>\n );\n }\n\n return (\n <button\n type={action.type === 'SUBMIT' ? 'submit' : 'button'}\n onClick={handleClick}\n disabled={isDisabled}\n className={buttonClasses}\n style={buttonInlineStyles}\n >\n {action.icon && <ActionIcon name={action.icon} className=\"w-4 h-4 mr-1.5\" />}\n {showLabel && action.label}\n </button>\n );\n});\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport const WidgetActions: React.FC<WidgetActionsProps> = memo(function WidgetActions({\n actions,\n context,\n onAction,\n disabled = false,\n layout = 'horizontal',\n size = 'md',\n showLabels = true,\n maxVisible = 3,\n className = '',\n}) {\n const [pendingAction, setPendingAction] = useState<WidgetAction | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n // Triggering a widget action emits `widget:<name>:clicked` (and may fire a bound\n // webhook), which is gateway-enforced by `execute`. Gate the emitting buttons on\n // the same permission. LINK actions are pure client-side navigation (they render\n // an <a> that bypasses onAction), so they stay available regardless.\n const { hasPermission } = usePermissions();\n const canExecute = hasPermission(BIGCONSOLE_PERMISSIONS.WIDGET_ACTION_EXECUTE);\n\n // Filter visible actions (not hidden)\n const visibleActions = useMemo(() => {\n return actions.filter((a) => !a.hidden).sort((a, b) => a.order - b.order);\n }, [actions]);\n\n // Split into main and overflow actions\n const { mainActions, overflowActions } = useMemo(() => {\n if (visibleActions.length <= maxVisible) {\n return { mainActions: visibleActions, overflowActions: [] };\n }\n return {\n mainActions: visibleActions.slice(0, maxVisible - 1),\n overflowActions: visibleActions.slice(maxVisible - 1),\n };\n }, [visibleActions, maxVisible]);\n\n // Execute action\n const executeAction = useCallback(\n async (action: WidgetAction) => {\n if (!onAction) return;\n\n setIsLoading(true);\n try {\n await onAction(action, context);\n } catch (error) {\n } finally {\n setIsLoading(false);\n }\n },\n [onAction, context]\n );\n\n // Handle action trigger\n const handleTriggerAction = useCallback(\n (action: WidgetAction) => {\n // If action has confirmation, show dialog\n if (action.confirmation) {\n setPendingAction(action);\n return;\n }\n\n // Execute action immediately\n executeAction(action);\n },\n [executeAction]\n );\n\n // Handle confirmation\n const handleConfirm = useCallback(() => {\n if (pendingAction) {\n executeAction(pendingAction);\n setPendingAction(null);\n }\n }, [pendingAction, executeAction]);\n\n const handleCancel = useCallback(() => {\n setPendingAction(null);\n }, []);\n\n // No actions to render\n if (visibleActions.length === 0) {\n return null;\n }\n\n const layoutClasses = layout === 'horizontal' ? 'flex flex-row flex-wrap gap-2' : 'flex flex-col gap-2';\n\n return (\n <>\n <div className={`${layoutClasses} ${className}`}>\n {mainActions.map((action) => (\n <ActionButton\n key={action.id}\n action={action}\n context={context}\n onAction={handleTriggerAction}\n // LINK actions only navigate, so they aren't execute-gated; every\n // other action emits an event on click and requires `execute`.\n disabled={disabled || isLoading || (!canExecute && action.type !== 'LINK')}\n size={size}\n showLabel={showLabels}\n />\n ))}\n\n {overflowActions.length > 0 && (\n <OverflowMenu\n actions={overflowActions}\n context={context}\n onAction={handleTriggerAction}\n // Overflow items always route through onAction (never a raw <a>), so\n // the whole menu is disabled when the caller can't execute actions.\n disabled={disabled || isLoading || !canExecute}\n size={size}\n />\n )}\n </div>\n\n {/* Confirmation Dialog */}\n {pendingAction?.confirmation && (\n <ConfirmationDialog\n title={pendingAction.confirmation.title || 'Confirm Action'}\n message={pendingAction.confirmation.message || 'Are you sure you want to proceed?'}\n confirmLabel={pendingAction.confirmation.confirmLabel || 'OK'}\n cancelLabel={pendingAction.confirmation.cancelLabel || 'Cancel'}\n style={pendingAction.style}\n onConfirm={handleConfirm}\n onCancel={handleCancel}\n />\n )}\n </>\n );\n});\n\nexport default WidgetActions;\n"],"mappings":"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"}
1
+ {"version":3,"file":"WidgetActions.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/widget-actions/WidgetActions.tsx"],"sourcesContent":["/**\n * Widget Actions Component (v2.0)\n *\n * Renders interactive action buttons for widgets.\n * Supports multiple action types, styles, confirmation dialogs, and icons.\n */\n\nimport React, { memo, useCallback, useState, useMemo, useRef, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport type { WidgetAction, ActionContext, ActionResult } from '../../../renderers/types/renderer';\nimport { BIGCONSOLE_PERMISSIONS } from '../../../../constants/permissions';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WidgetActionsProps {\n /** List of actions to render */\n actions: WidgetAction[];\n /** Action context (widget ID, data, etc.) */\n context: ActionContext;\n /** Callback when action is triggered */\n onAction?: (action: WidgetAction, context: ActionContext) => Promise<ActionResult | void>;\n /** Whether actions are disabled */\n disabled?: boolean;\n /** Layout direction */\n layout?: 'horizontal' | 'vertical';\n /** Size of action buttons */\n size?: 'sm' | 'md' | 'lg';\n /** Whether to show labels */\n showLabels?: boolean;\n /** Maximum number of visible actions (rest go to overflow menu) */\n maxVisible?: number;\n /** Custom class name */\n className?: string;\n}\n\ninterface ConfirmationDialogProps {\n title: string;\n message: string;\n confirmLabel: string;\n cancelLabel: string;\n style: WidgetAction['style'];\n onConfirm: () => void;\n onCancel: () => void;\n}\n\n// ============================================================================\n// Style Utilities\n// ============================================================================\n\nfunction getButtonClasses(\n style: WidgetAction['style'] | undefined,\n size: 'sm' | 'md' | 'lg',\n disabled: boolean\n): string {\n const baseClasses =\n 'inline-flex items-center justify-center font-medium rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2';\n\n const sizeClasses = {\n sm: 'px-2.5 py-1.5 text-xs',\n md: 'px-4 py-2 text-sm',\n lg: 'px-6 py-3 text-base',\n };\n\n const styleClasses: Record<string, string> = {\n PRIMARY: 'bg-action-primary text-white hover:bg-action-primary/90 focus:ring-action-primary/50 transition-colors',\n SECONDARY: 'bg-bg-sunken text-primary hover:bg-bg-sunken/80 focus:ring-muted transition-colors',\n DANGER:\n 'bg-status-error-bg text-white hover:bg-status-error-bg/90 focus:ring-status-error-border/50 transition-colors',\n SUCCESS:\n 'bg-status-success-bg text-white hover:bg-status-success-bg/90 focus:ring-status-success-border/50 transition-colors',\n WARNING:\n 'bg-status-warning-bg text-white hover:bg-status-warning-bg/90 focus:ring-status-warning-border/50 transition-colors',\n };\n\n const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer';\n\n // Default to SECONDARY if style is undefined\n const effectiveStyle = style || 'SECONDARY';\n const styleClass = styleClasses[effectiveStyle] || styleClasses.SECONDARY;\n\n return `${baseClasses} ${sizeClasses[size]} ${styleClass} ${disabledClasses}`;\n}\n\n// Get inline styles as fallback for button visibility\nfunction getButtonInlineStyles(style: WidgetAction['style'] | undefined): React.CSSProperties {\n const styles: Record<string, React.CSSProperties> = {\n PRIMARY: { backgroundColor: 'var(--color-action-primary-bg)', color: 'var(--color-action-primary-text)' },\n SECONDARY: { backgroundColor: 'var(--color-bg-muted)', color: 'var(--color-text-primary)' },\n DANGER: { backgroundColor: 'var(--color-status-error-bg)', color: 'var(--color-action-primary-text)' },\n SUCCESS: { backgroundColor: 'var(--color-status-success-bg)', color: 'var(--color-action-primary-text)' },\n WARNING: { backgroundColor: 'var(--color-status-warning-bg)', color: 'var(--color-action-primary-text)' },\n };\n const effectiveStyle = style || 'SECONDARY';\n return styles[effectiveStyle] || styles.SECONDARY;\n}\n\nfunction getConfirmButtonClasses(style: WidgetAction['style']): string {\n const styleClasses = {\n PRIMARY: 'bg-action-primary text-white hover:bg-action-primary/90',\n SECONDARY: 'bg-secondary text-white hover:bg-secondary/90',\n DANGER: 'bg-status-error-bg text-white hover:bg-status-error-bg/90',\n SUCCESS: 'bg-status-success-bg text-white hover:bg-status-success-bg/90',\n WARNING: 'bg-status-warning-bg text-white hover:bg-status-warning-bg/90',\n };\n\n const effectiveStyle = style || 'PRIMARY';\n return `px-4 py-2 text-sm font-medium rounded-md transition-colors ${styleClasses[effectiveStyle] || styleClasses.PRIMARY}`;\n}\n\n// Get inline styles for confirm button to ensure visibility\nfunction getConfirmButtonInlineStyles(style: WidgetAction['style'] | undefined): React.CSSProperties {\n const styles: Record<string, React.CSSProperties> = {\n PRIMARY: {\n backgroundColor: 'var(--color-action-primary-bg)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n SECONDARY: {\n backgroundColor: 'var(--color-text-secondary)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n DANGER: {\n backgroundColor: 'var(--color-status-error-bg)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n SUCCESS: {\n backgroundColor: 'var(--color-status-success-bg)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n WARNING: {\n backgroundColor: 'var(--color-status-warning-bg)',\n color: 'var(--color-action-primary-text)',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 500,\n },\n };\n const effectiveStyle = style || 'PRIMARY';\n return styles[effectiveStyle] || styles.PRIMARY;\n}\n\n// ============================================================================\n// Icon Component\n// ============================================================================\n\ninterface ActionIconProps {\n name: string;\n className?: string;\n}\n\nconst ActionIcon: React.FC<ActionIconProps> = memo(function ActionIcon({ name, className = 'w-4 h-4' }) {\n // Common icons used in actions\n const icons: Record<string, React.ReactNode> = {\n 'external-link': (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n ),\n save: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4\"\n />\n </svg>\n ),\n trash: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n ),\n edit: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"\n />\n </svg>\n ),\n refresh: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n ),\n download: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\"\n />\n </svg>\n ),\n upload: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12\"\n />\n </svg>\n ),\n plus: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n ),\n check: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n ),\n x: (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ),\n 'more-horizontal': (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z\"\n />\n </svg>\n ),\n };\n\n return icons[name] || null;\n});\n\n// ============================================================================\n// Confirmation Dialog\n// ============================================================================\n\nconst ConfirmationDialog: React.FC<ConfirmationDialogProps> = memo(function ConfirmationDialog({\n title,\n message,\n confirmLabel,\n cancelLabel,\n style,\n onConfirm,\n onCancel,\n}) {\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {/*\n Scrim + panel. The raw `bg-black/50` and the `animate-in fade-in\n zoom-in-95` utilities are gone: the first is a literal colour, the second\n is an unregistered class set that emitted no CSS in this shell\n (BOFF-5636). The scrim now uses the overlay token and the panel uses the\n elevation scale.\n */}\n <div\n className=\"absolute inset-0\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'var(--color-overlay-scrim, var(--color-bg-canvas))',\n opacity: 0.6,\n }}\n onClick={onCancel}\n />\n\n {/* Dialog */}\n <div\n className=\"relative mx-4 w-full max-w-md rounded-card p-6\"\n style={{\n position: 'relative',\n backgroundColor: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 'var(--radius-card)',\n boxShadow: 'var(--shadow-elevation-3)',\n maxWidth: '28rem',\n width: '100%',\n margin: '0 16px',\n padding: 'var(--space-cardPadding)',\n zIndex: 10000,\n }}\n >\n <h3\n className=\"text-base font-semibold text-text-primary\"\n style={{\n fontSize: 'var(--font-size-body-lg)',\n fontWeight: 600,\n color: 'var(--color-text-primary)',\n margin: 0,\n }}\n >\n {title}\n </h3>\n <p\n className=\"mt-2 text-sm text-text-secondary\"\n style={{ marginTop: '8px', fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-secondary)' }}\n >\n {message}\n </p>\n <div\n className=\"mt-4 flex flex-wrap justify-end gap-3\"\n style={{ marginTop: '16px', display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-end', gap: '12px' }}\n >\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"min-h-control-md rounded-button px-4 text-sm font-medium text-text-secondary hover:text-text-primary motion-safe:transition-colors\"\n style={{\n minHeight: 'var(--size-controlHeight-md)',\n padding: '0 16px',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 500,\n color: 'var(--color-text-secondary)',\n backgroundColor: 'var(--color-bg-sunken)',\n borderRadius: 'var(--radius-button)',\n border: '1px solid var(--color-border-subtle)',\n cursor: 'pointer',\n }}\n >\n {cancelLabel}\n </button>\n <button\n type=\"button\"\n onClick={onConfirm}\n className={getConfirmButtonClasses(style)}\n style={getConfirmButtonInlineStyles(style)}\n >\n {confirmLabel}\n </button>\n </div>\n </div>\n </div>\n );\n});\n\n// ============================================================================\n// Overflow Menu\n// ============================================================================\n\ninterface OverflowMenuProps {\n actions: WidgetAction[];\n context: ActionContext;\n onAction: (action: WidgetAction) => void;\n disabled?: boolean;\n size: 'sm' | 'md' | 'lg';\n}\n\nconst OverflowMenu: React.FC<OverflowMenuProps> = memo(function OverflowMenu({\n actions,\n context: _context,\n onAction,\n disabled,\n size,\n}) {\n const [isOpen, setIsOpen] = useState(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });\n\n const handleToggle = useCallback(() => {\n if (!disabled) {\n setIsOpen((prev) => !prev);\n }\n }, [disabled]);\n\n const handleAction = useCallback(\n (action: WidgetAction) => {\n setIsOpen(false);\n onAction(action);\n },\n [onAction]\n );\n\n const handleClickOutside = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n // Calculate menu position when opening\n useEffect(() => {\n if (isOpen && buttonRef.current) {\n const rect = buttonRef.current.getBoundingClientRect();\n setMenuPosition({\n top: rect.bottom + 4, // 4px gap below button\n left: rect.right - 192, // 192px = w-48, align right edge\n });\n }\n }, [isOpen]);\n\n if (actions.length === 0) return null;\n\n return (\n <div className=\"relative\">\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={handleToggle}\n disabled={disabled}\n className={getButtonClasses('SECONDARY', size, disabled ?? false)}\n aria-label=\"More actions\"\n >\n <ActionIcon name=\"more-horizontal\" />\n </button>\n\n {isOpen &&\n createPortal(\n <>\n {/* Click-outside handler */}\n <div className=\"fixed inset-0 z-[9998]\" onClick={handleClickOutside} />\n\n {/* Menu - rendered via portal at body level */}\n <div\n className=\"fixed z-[9999] w-48 max-w-[calc(100vw-1rem)] rounded-card\"\n style={{\n top: menuPosition.top,\n left: Math.max(8, menuPosition.left), // Ensure at least 8px from left edge\n backgroundColor: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 'var(--radius-card)',\n boxShadow: 'var(--shadow-elevation-3)',\n }}\n >\n <div className=\"py-1\">\n {actions.map((action) => (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => handleAction(action)}\n disabled={action.disabled}\n className=\"flex min-h-control-md w-full items-center gap-2 px-4 text-left text-sm text-text-secondary hover:bg-bg-sunken hover:text-text-primary disabled:cursor-not-allowed disabled:opacity-50 motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\"\n >\n {action.icon && <ActionIcon name={action.icon} className=\"w-4 h-4\" />}\n {action.label}\n </button>\n ))}\n </div>\n </div>\n </>,\n document.body\n )}\n </div>\n );\n});\n\n// ============================================================================\n// Action Button\n// ============================================================================\n\ninterface ActionButtonProps {\n action: WidgetAction;\n context: ActionContext;\n onAction: (action: WidgetAction) => void;\n disabled?: boolean;\n size: 'sm' | 'md' | 'lg';\n showLabel?: boolean;\n}\n\nconst ActionButton: React.FC<ActionButtonProps> = memo(function ActionButton({\n action,\n context: _context,\n onAction,\n disabled,\n size,\n showLabel = true,\n}) {\n const isDisabled = disabled || action.disabled;\n\n const handleClick = useCallback(() => {\n if (!isDisabled) {\n onAction(action);\n }\n }, [action, isDisabled, onAction]);\n\n // Get both classes and inline styles for guaranteed visibility\n const buttonClasses = getButtonClasses(action.style, size, isDisabled);\n const buttonInlineStyles = getButtonInlineStyles(action.style);\n\n // Handle LINK type\n if (action.type === 'LINK' && action.metadata?.url) {\n return (\n <a\n href={action.metadata.url as string}\n target={(action.metadata.target as string) || '_blank'}\n rel=\"noopener noreferrer\"\n className={buttonClasses}\n style={buttonInlineStyles}\n aria-disabled={isDisabled}\n >\n {action.icon && <ActionIcon name={action.icon} className=\"w-4 h-4 mr-1.5\" />}\n {showLabel && action.label}\n {!action.icon && <ActionIcon name=\"external-link\" className=\"w-4 h-4 ml-1.5\" />}\n </a>\n );\n }\n\n return (\n <button\n type={action.type === 'SUBMIT' ? 'submit' : 'button'}\n onClick={handleClick}\n disabled={isDisabled}\n className={buttonClasses}\n style={buttonInlineStyles}\n >\n {action.icon && <ActionIcon name={action.icon} className=\"w-4 h-4 mr-1.5\" />}\n {showLabel && action.label}\n </button>\n );\n});\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport const WidgetActions: React.FC<WidgetActionsProps> = memo(function WidgetActions({\n actions,\n context,\n onAction,\n disabled = false,\n layout = 'horizontal',\n size = 'md',\n showLabels = true,\n maxVisible = 3,\n className = '',\n}) {\n const [pendingAction, setPendingAction] = useState<WidgetAction | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n // Triggering a widget action emits `widget:<name>:clicked` (and may fire a bound\n // webhook), which is gateway-enforced by `execute`. Gate the emitting buttons on\n // the same permission. LINK actions are pure client-side navigation (they render\n // an <a> that bypasses onAction), so they stay available regardless.\n const { hasPermission } = usePermissions();\n const canExecute = hasPermission(BIGCONSOLE_PERMISSIONS.WIDGET_ACTION_EXECUTE);\n\n // Filter visible actions (not hidden)\n const visibleActions = useMemo(() => {\n return actions.filter((a) => !a.hidden).sort((a, b) => a.order - b.order);\n }, [actions]);\n\n // Split into main and overflow actions\n const { mainActions, overflowActions } = useMemo(() => {\n if (visibleActions.length <= maxVisible) {\n return { mainActions: visibleActions, overflowActions: [] };\n }\n return {\n mainActions: visibleActions.slice(0, maxVisible - 1),\n overflowActions: visibleActions.slice(maxVisible - 1),\n };\n }, [visibleActions, maxVisible]);\n\n // Execute action\n const executeAction = useCallback(\n async (action: WidgetAction) => {\n if (!onAction) return;\n\n setIsLoading(true);\n try {\n await onAction(action, context);\n } catch (error) {\n } finally {\n setIsLoading(false);\n }\n },\n [onAction, context]\n );\n\n // Handle action trigger\n const handleTriggerAction = useCallback(\n (action: WidgetAction) => {\n // If action has confirmation, show dialog\n if (action.confirmation) {\n setPendingAction(action);\n return;\n }\n\n // Execute action immediately\n executeAction(action);\n },\n [executeAction]\n );\n\n // Handle confirmation\n const handleConfirm = useCallback(() => {\n if (pendingAction) {\n executeAction(pendingAction);\n setPendingAction(null);\n }\n }, [pendingAction, executeAction]);\n\n const handleCancel = useCallback(() => {\n setPendingAction(null);\n }, []);\n\n // No actions to render\n if (visibleActions.length === 0) {\n return null;\n }\n\n const layoutClasses = layout === 'horizontal' ? 'flex flex-row flex-wrap gap-2' : 'flex flex-col gap-2';\n\n return (\n <>\n <div className={`${layoutClasses} ${className}`}>\n {mainActions.map((action) => (\n <ActionButton\n key={action.id}\n action={action}\n context={context}\n onAction={handleTriggerAction}\n // LINK actions only navigate, so they aren't execute-gated; every\n // other action emits an event on click and requires `execute`.\n disabled={disabled || isLoading || (!canExecute && action.type !== 'LINK')}\n size={size}\n showLabel={showLabels}\n />\n ))}\n\n {overflowActions.length > 0 && (\n <OverflowMenu\n actions={overflowActions}\n context={context}\n onAction={handleTriggerAction}\n // Overflow items always route through onAction (never a raw <a>), so\n // the whole menu is disabled when the caller can't execute actions.\n disabled={disabled || isLoading || !canExecute}\n size={size}\n />\n )}\n </div>\n\n {/* Confirmation Dialog */}\n {pendingAction?.confirmation && (\n <ConfirmationDialog\n title={pendingAction.confirmation.title || 'Confirm Action'}\n message={pendingAction.confirmation.message || 'Are you sure you want to proceed?'}\n confirmLabel={pendingAction.confirmation.confirmLabel || 'OK'}\n cancelLabel={pendingAction.confirmation.cancelLabel || 'Cancel'}\n style={pendingAction.style}\n onConfirm={handleConfirm}\n onCancel={handleCancel}\n />\n )}\n </>\n );\n});\n\nexport default WidgetActions;\n"],"mappings":"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"}