@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":"ActionConfigDialog.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/ActionConfigDialog.tsx"],"sourcesContent":["/**\n * ActionConfigDialog Component (v2.1)\n *\n * Modal dialog for creating/editing widget actions.\n *\n * v2.1 (BOFF-5659): reframed around the *outcome* — \"When clicked, do this\" —\n * instead of the abstract action Type. A button always emits\n * `widget:<name>:clicked`; the dialog now lets the user attach the behaviour\n * inline. Today the two shippable outcomes are:\n * - \"Call a webhook / my API\" → captures a URL + method; the parent pairs the\n * action with an EventWebhookMapping bound to that event (no backend change).\n * - \"Just emit an event\" → the raw emit, for callers wiring their own\n * consumers.\n * The action `name` (the event id) is auto-derived from the label and tucked\n * under Advanced so there is a single required field.\n *\n * Uses fe-libs shared UI components and semantic tokens for consistent styling.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect, useMemo, useRef } from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Textarea } from '@burdenoff/fe-libs/ui';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@burdenoff/fe-libs/ui';\nimport { Checkbox } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { Zap, Plus, Pencil, ChevronDown, ChevronRight } from 'lucide-react';\nimport { BIGCONSOLE_PERMISSIONS } from '../../../constants/permissions';\nimport type {\n WidgetAction,\n ActionStyle,\n ActionConfirmation,\n CreateWidgetActionInput,\n UpdateWidgetActionInput,\n} from '../../hooks/useWidgetActions';\nimport type { HttpMethod } from '../../hooks/useEventWebhooks';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** What should happen when the button is clicked. */\nexport type ActionOutcome = 'WEBHOOK' | 'EMIT';\n\n/** Webhook binding drafted in the dialog and reconciled by the parent. */\nexport interface ActionWebhookDraft {\n url: string;\n method: HttpMethod;\n}\n\n/**\n * The action fields passed to the create/update mutation. The webhook binding\n * is passed as a SEPARATE onSave argument (never embedded here) so it can never\n * leak into the GraphQL input.\n */\nexport type ActionSaveData = Omit<CreateWidgetActionInput, 'widgetId'> | UpdateWidgetActionInput;\n\nexport interface ActionConfigDialogProps {\n isOpen: boolean;\n action?: WidgetAction;\n /** Existing webhook binding for the edited action (prefills the URL field). */\n initialWebhook?: ActionWebhookDraft | null;\n isLoading?: boolean;\n /** A save failure from the parent (action or webhook mutation) to surface inline. */\n saveError?: string | null;\n onClose: () => void;\n /** `webhook` is the paired binding, or `null` to remove any existing one. */\n onSave: (data: ActionSaveData, webhook: ActionWebhookDraft | null) => void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst HTTP_METHODS: HttpMethod[] = ['POST', 'GET', 'PUT', 'PATCH', 'DELETE'];\n\n/** Stable style values + preview colors; labels are resolved via i18n in-component. */\nconst ACTION_STYLE_META: { value: ActionStyle; color: string }[] = [\n { value: 'PRIMARY', color: 'var(--color-action-primary-bg)' },\n { value: 'SECONDARY', color: 'var(--color-action-secondary-bg)' },\n { value: 'SUCCESS', color: 'var(--color-status-success-bg)' },\n { value: 'WARNING', color: 'var(--color-status-warning-bg)' },\n { value: 'DANGER', color: 'var(--color-action-danger-bg)' },\n];\n\n/** Stable icon values; labels are resolved via i18n in-component. */\nconst ICON_VALUES = [\n '',\n 'refresh',\n 'download',\n 'upload',\n 'trash',\n 'edit',\n 'plus',\n 'check',\n 'eye',\n 'copy',\n 'share',\n 'settings',\n 'filter',\n 'search',\n] as const;\n\n// Derive the event-id (action name) from a human label: \"Refresh Data\" -> \"refresh_data\".\nfunction slugifyName(label: string): string {\n return label\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '');\n}\n\nconst labelStyle: React.CSSProperties = {\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 'var(--space-controlGap)',\n};\n\nconst hintStyle: React.CSSProperties = {\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n marginTop: 'var(--space-controlGap)',\n};\n\nconst selectContentStyle: React.CSSProperties = {\n zIndex: 9999,\n backgroundColor: 'var(--color-overlay-popoverBg, var(--color-bg-surface))',\n border: '1px solid var(--color-border)',\n boxShadow: 'var(--shadow-elevation-3)',\n borderRadius: 'var(--radius-button)',\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const ActionConfigDialog: FC<ActionConfigDialogProps> = memo(function ActionConfigDialog({\n isOpen,\n action,\n initialWebhook,\n isLoading = false,\n saveError,\n onClose,\n onSave,\n}) {\n const { t } = useI18n();\n const isEditMode = !!action;\n const labelInputRef = useRef<HTMLInputElement>(null);\n // True once the user touches the webhook fields, so a late-arriving\n // `initialWebhook` fetch can seed the form without clobbering in-progress edits.\n const webhookTouchedRef = useRef(false);\n\n // Form state\n const [label, setLabel] = useState('');\n const [name, setName] = useState('');\n const [nameEdited, setNameEdited] = useState(false);\n const [style, setStyle] = useState<ActionStyle>('PRIMARY');\n const [icon, setIcon] = useState('');\n const [outcome, setOutcome] = useState<ActionOutcome>('WEBHOOK');\n const [webhookUrl, setWebhookUrl] = useState('');\n const [webhookMethod, setWebhookMethod] = useState<HttpMethod>('POST');\n const [disabled, setDisabled] = useState(false);\n const [hidden, setHidden] = useState(false);\n const [showAdvanced, setShowAdvanced] = useState(false);\n const [hasConfirmation, setHasConfirmation] = useState(false);\n const [confirmTitle, setConfirmTitle] = useState(() =>\n t('bigconsole.widget.actions.confirm.defaultTitle', 'Confirm Action')\n );\n const [confirmMessage, setConfirmMessage] = useState(() =>\n t('bigconsole.widget.actions.confirm.defaultMessage', 'Are you sure you want to proceed?')\n );\n const [confirmLabel, setConfirmLabel] = useState(() =>\n t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm')\n );\n const [cancelLabel, setCancelLabel] = useState(() =>\n t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel')\n );\n const [error, setError] = useState<string | null>(null);\n\n // Localized option lists — value/enum fields stay stable; only the display copy is translated.\n const OUTCOMES = useMemo<{ value: ActionOutcome; label: string; hint: string }[]>(\n () => [\n {\n value: 'WEBHOOK',\n label: t('bigconsole.widget.actions.outcome.webhook.label', 'Call a webhook / my API'),\n hint: t(\n 'bigconsole.widget.actions.outcome.webhook.hint',\n 'Sends an HTTP request to the URL below every time the button is clicked.'\n ),\n },\n {\n value: 'EMIT',\n label: t('bigconsole.widget.actions.outcome.emit.label', 'Just emit an event (advanced)'),\n hint: t(\n 'bigconsole.widget.actions.outcome.emit.hint',\n 'Emits widget:<name>:clicked. Wire it up yourself in the Webhooks/Events section.'\n ),\n },\n ],\n [t]\n );\n\n const ACTION_STYLES = useMemo<{ value: ActionStyle; label: string; color: string }[]>(() => {\n const labels: Record<ActionStyle, string> = {\n PRIMARY: t('bigconsole.widget.actions.style.primary', 'Primary'),\n SECONDARY: t('bigconsole.widget.actions.style.secondary', 'Secondary'),\n SUCCESS: t('bigconsole.widget.actions.style.success', 'Success'),\n WARNING: t('bigconsole.widget.actions.style.warning', 'Warning'),\n DANGER: t('bigconsole.widget.actions.style.danger', 'Danger'),\n GHOST: t('bigconsole.widget.actions.style.ghost', 'Ghost'),\n LINK: t('bigconsole.widget.actions.style.link', 'Link'),\n };\n return ACTION_STYLE_META.map((s) => ({ value: s.value, label: labels[s.value], color: s.color }));\n }, [t]);\n\n const ICON_OPTIONS = useMemo(() => {\n const labels: Record<(typeof ICON_VALUES)[number], string> = {\n '': t('bigconsole.widget.actions.icon.none', 'No icon'),\n refresh: t('bigconsole.widget.actions.icon.refresh', 'Refresh'),\n download: t('bigconsole.widget.actions.icon.download', 'Download'),\n upload: t('bigconsole.widget.actions.icon.upload', 'Upload'),\n trash: t('bigconsole.widget.actions.icon.trash', 'Trash'),\n edit: t('bigconsole.widget.actions.icon.edit', 'Edit'),\n plus: t('bigconsole.widget.actions.icon.plus', 'Plus'),\n check: t('bigconsole.widget.actions.icon.check', 'Check'),\n eye: t('bigconsole.widget.actions.icon.eye', 'View'),\n copy: t('bigconsole.widget.actions.icon.copy', 'Copy'),\n share: t('bigconsole.widget.actions.icon.share', 'Share'),\n settings: t('bigconsole.widget.actions.icon.settings', 'Settings'),\n filter: t('bigconsole.widget.actions.icon.filter', 'Filter'),\n search: t('bigconsole.widget.actions.icon.search', 'Search'),\n };\n return ICON_VALUES.map((value) => ({ value, label: labels[value] }));\n }, [t]);\n\n // Reset form when the dialog opens or the edited action changes. Deliberately\n // does NOT depend on `initialWebhook` — that fetch can settle after the dialog\n // is open, and re-running this would wipe the user's in-progress edits (#6).\n // The webhook fields are seeded by the separate effect below.\n useEffect(() => {\n if (!isOpen) return;\n\n webhookTouchedRef.current = false;\n setWebhookUrl('');\n setWebhookMethod('POST');\n\n if (action) {\n setLabel(action.label);\n setName(action.name);\n setNameEdited(false);\n setStyle(action.style);\n setIcon(action.icon || '');\n setDisabled(action.disabled);\n setHidden(action.hidden);\n // Default to \"emit\"; the seed effect flips to WEBHOOK if a mapping exists.\n setOutcome('EMIT');\n setHasConfirmation(!!action.confirmation);\n if (action.confirmation) {\n setConfirmTitle(action.confirmation.title);\n setConfirmMessage(action.confirmation.message);\n setConfirmLabel(\n action.confirmation.confirmLabel || t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm')\n );\n setCancelLabel(\n action.confirmation.cancelLabel || t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel')\n );\n } else {\n setConfirmTitle(t('bigconsole.widget.actions.confirm.defaultTitle', 'Confirm Action'));\n setConfirmMessage(t('bigconsole.widget.actions.confirm.defaultMessage', 'Are you sure you want to proceed?'));\n setConfirmLabel(t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm'));\n setCancelLabel(t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel'));\n }\n } else {\n setLabel('');\n setName('');\n setNameEdited(false);\n setStyle('PRIMARY');\n setIcon('');\n setOutcome('WEBHOOK');\n setDisabled(false);\n setHidden(false);\n setHasConfirmation(false);\n setConfirmTitle(t('bigconsole.widget.actions.confirm.defaultTitle', 'Confirm Action'));\n setConfirmMessage(t('bigconsole.widget.actions.confirm.defaultMessage', 'Are you sure you want to proceed?'));\n setConfirmLabel(t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm'));\n setCancelLabel(t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel'));\n }\n setShowAdvanced(false);\n setError(null);\n // Focus the label after the dialog paints — a double rAF is more reliable than\n // a magic setTimeout delay and doesn't race the open animation.\n const raf = requestAnimationFrame(() => requestAnimationFrame(() => labelInputRef.current?.focus()));\n return () => cancelAnimationFrame(raf);\n }, [isOpen, action, t]);\n\n // Seed the webhook fields from the (possibly late-arriving) mapping fetch,\n // unless the user has already started editing them.\n useEffect(() => {\n if (!isOpen || !initialWebhook || webhookTouchedRef.current) return;\n setOutcome('WEBHOOK');\n setWebhookUrl(initialWebhook.url);\n setWebhookMethod(initialWebhook.method);\n }, [isOpen, initialWebhook]);\n\n // Keep the auto-derived name in sync with the label until the user overrides it.\n const handleLabelChange = useCallback(\n (value: string) => {\n setLabel(value);\n if (!nameEdited) setName(slugifyName(value));\n if (error) setError(null);\n },\n [nameEdited, error]\n );\n\n const handleSubmit = useCallback(\n (e: React.FormEvent) => {\n e.preventDefault();\n\n const trimmedLabel = label.trim();\n if (!trimmedLabel) {\n setError(t('bigconsole.widget.actions.validation.labelRequired', 'Button label is required'));\n labelInputRef.current?.focus();\n return;\n }\n\n // The action name is the event id (webhook contract). It is set once at\n // creation and never rewritten on edit — re-slugifying a stored name like\n // `refresh-v2` would silently change `widget:refresh-v2:clicked` and break\n // existing bindings/consumers (#1).\n const finalName =\n isEditMode && action ? action.name : slugifyName(nameEdited ? name : label) || slugifyName(label);\n if (!finalName) {\n setError(\n t('bigconsole.widget.actions.validation.labelLettersOrNumbers', 'Enter a label using letters or numbers')\n );\n return;\n }\n\n if (outcome === 'WEBHOOK') {\n const url = webhookUrl.trim();\n if (!url) {\n setError(\n t('bigconsole.widget.actions.validation.urlRequired', 'Enter the URL to call when the button is clicked')\n );\n return;\n }\n if (!/^https?:\\/\\//i.test(url)) {\n setError(\n t('bigconsole.widget.actions.validation.urlScheme', 'Webhook URL must start with http:// or https://')\n );\n return;\n }\n }\n\n const confirmation: ActionConfirmation | undefined = hasConfirmation\n ? {\n title: confirmTitle.trim() || t('bigconsole.widget.actions.confirm.defaultTitle', 'Confirm Action'),\n message: confirmMessage.trim() || t('bigconsole.widget.actions.confirm.fallbackMessage', 'Are you sure?'),\n confirmLabel: confirmLabel.trim() || t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm'),\n cancelLabel: cancelLabel.trim() || t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel'),\n }\n : undefined;\n\n const webhook: ActionWebhookDraft | null =\n outcome === 'WEBHOOK' ? { url: webhookUrl.trim(), method: webhookMethod } : null;\n\n if (isEditMode && action) {\n const updateData: ActionSaveData = {\n id: action.id,\n name: finalName,\n label: trimmedLabel,\n // Webhook/emit outcomes must be a BUTTON so the click runs onAction and\n // emits the event. Saving a stale LINK type would render an <a> that\n // bypasses onAction, so the webhook would never fire (#3).\n type: 'BUTTON',\n style,\n icon: icon || undefined,\n confirmation: hasConfirmation ? confirmation : null,\n disabled,\n hidden,\n };\n onSave(updateData, webhook);\n } else {\n const createData: ActionSaveData = {\n name: finalName,\n label: trimmedLabel,\n // Webhook/emit outcomes must be a BUTTON so the click runs onAction and\n // emits the event. Saving a stale LINK type would render an <a> that\n // bypasses onAction, so the webhook would never fire (#3).\n type: 'BUTTON',\n style,\n icon: icon || undefined,\n confirmation,\n disabled,\n hidden,\n };\n onSave(createData, webhook);\n }\n },\n [\n label,\n name,\n nameEdited,\n outcome,\n webhookUrl,\n webhookMethod,\n style,\n icon,\n disabled,\n hidden,\n hasConfirmation,\n confirmTitle,\n confirmMessage,\n confirmLabel,\n cancelLabel,\n isEditMode,\n action,\n onSave,\n t,\n ]\n );\n\n const getStyleColor = (s: ActionStyle) =>\n ACTION_STYLES.find((as) => as.value === s)?.color || 'var(--color-action-primary-bg)';\n\n const activeOutcome = OUTCOMES.find((o) => o.value === outcome);\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && !isLoading && onClose()}>\n <DialogContent style={{ maxWidth: '500px', padding: 0 }}>\n {/* Header */}\n <DialogHeader style={{ padding: 'var(--space-pagePadding) var(--space-pagePadding) 0' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-formGap)' }}>\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-card)',\n backgroundColor: 'var(--color-action-primary-bg)',\n boxShadow: 'var(--shadow-elevation-2)',\n }}\n >\n {isEditMode ? (\n <Pencil\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n ) : (\n <Zap\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n )}\n </div>\n <div>\n <DialogTitle\n style={{\n fontSize: 'var(--font-size-heading-h4)',\n fontWeight: 'var(--font-weight-bold)',\n color: 'var(--color-text-primary)',\n margin: 0,\n }}\n >\n {isEditMode\n ? t('bigconsole.widget.actions.header.editTitle', 'Edit Button')\n : t('bigconsole.widget.actions.header.addTitle', 'Add Button')}\n </DialogTitle>\n <DialogDescription\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-secondary)',\n margin: 'var(--space-controlGap) 0 0 0',\n }}\n >\n {isEditMode\n ? t('bigconsole.widget.actions.header.editDescription', 'Update the button and what it does')\n : t('bigconsole.widget.actions.header.addDescription', 'Add a button and choose what it does')}\n </DialogDescription>\n </div>\n </div>\n </DialogHeader>\n\n <form onSubmit={handleSubmit}>\n {/* Form Content */}\n <div style={{ padding: 'var(--space-pagePadding)', maxHeight: '60vh', overflowY: 'auto' }}>\n {/* Error Display — local validation error or a save failure from the parent. */}\n {(error || saveError) && (\n <div\n style={{\n padding: 'var(--space-controlGap)',\n backgroundColor: 'var(--color-status-error-bgSubtle)',\n border: '1px solid var(--color-status-error-border)',\n borderRadius: 'var(--radius-button)',\n marginBottom: 'var(--space-formGap)',\n }}\n >\n <p style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-status-error-text)', margin: 0 }}>\n {error || saveError}\n </p>\n </div>\n )}\n\n {/* Label Field */}\n <div style={{ marginBottom: 'var(--space-formGap)' }}>\n <label style={labelStyle}>\n {t('bigconsole.widget.actions.field.buttonLabel', 'Button label')}{' '}\n <span style={{ color: 'var(--color-status-error-text)' }}>*</span>\n </label>\n <Input\n ref={labelInputRef}\n value={label}\n onChange={(e) => handleLabelChange(e.target.value)}\n placeholder={t(\n 'bigconsole.widget.actions.field.buttonLabelPlaceholder',\n 'e.g., Refresh Data, Export CSV'\n )}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n />\n <p style={hintStyle}>\n {t('bigconsole.widget.actions.field.buttonLabelHint', 'Text shown on the button')}\n </p>\n </div>\n\n {/* Style + Icon Row */}\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: 'var(--space-formGap)',\n marginBottom: 'var(--space-formGap)',\n }}\n >\n <div>\n <label style={labelStyle}>{t('bigconsole.widget.actions.field.style', 'Style')}</label>\n <Select value={style} onValueChange={(v) => setStyle(v as ActionStyle)} disabled={isLoading}>\n <SelectTrigger\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent style={selectContentStyle}>\n {ACTION_STYLES.map((s) => (\n <SelectItem key={s.value} value={s.value}>\n {s.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div>\n <label style={labelStyle}>{t('bigconsole.widget.actions.field.icon', 'Icon')}</label>\n <Select value={icon} onValueChange={setIcon} disabled={isLoading}>\n <SelectTrigger\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n >\n <SelectValue placeholder={t('bigconsole.widget.actions.icon.none', 'No icon')} />\n </SelectTrigger>\n <SelectContent style={{ ...selectContentStyle, maxHeight: '200px' }}>\n {ICON_OPTIONS.map((i) => (\n <SelectItem key={i.value || 'none'} value={i.value || 'none'}>\n {i.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* Style Preview */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n marginBottom: 'var(--space-formGap)',\n padding: 'var(--space-controlGap)',\n backgroundColor: 'var(--color-bg-sunken)',\n borderRadius: 'var(--radius-button)',\n }}\n >\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {t('bigconsole.widget.actions.preview.label', 'Preview:')}\n </span>\n <button\n type=\"button\"\n style={{\n padding: 'var(--space-controlGap) var(--space-formGap)',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n borderRadius: 'var(--radius-button)',\n backgroundColor: getStyleColor(style),\n color: 'var(--color-action-primary-text)',\n border: 'none',\n cursor: 'default',\n }}\n >\n {label || t('bigconsole.widget.actions.preview.buttonFallback', 'Button')}\n </button>\n </div>\n\n {/* When clicked (outcome) */}\n <div style={{ marginBottom: 'var(--space-formGap)' }}>\n <label style={labelStyle}>{t('bigconsole.widget.actions.field.whenClicked', 'When clicked')}</label>\n <Select\n value={outcome}\n onValueChange={(v) => {\n webhookTouchedRef.current = true;\n setOutcome(v as ActionOutcome);\n }}\n disabled={isLoading}\n >\n <SelectTrigger style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent style={selectContentStyle}>\n {OUTCOMES.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {activeOutcome && <p style={hintStyle}>{activeOutcome.hint}</p>}\n </div>\n\n {/* Webhook config (only for the WEBHOOK outcome) */}\n {outcome === 'WEBHOOK' && (\n <div\n style={{\n marginBottom: 'var(--space-formGap)',\n paddingLeft: 'var(--space-formGap)',\n borderLeft: '2px solid var(--color-border)',\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-controlGap)',\n }}\n >\n <div>\n <label style={labelStyle}>\n {t('bigconsole.widget.actions.webhook.urlLabel', 'URL')}{' '}\n <span style={{ color: 'var(--color-status-error-text)' }}>*</span>\n </label>\n <Input\n value={webhookUrl}\n onChange={(e) => {\n webhookTouchedRef.current = true;\n setWebhookUrl(e.target.value);\n if (error) setError(null);\n }}\n placeholder={t('bigconsole.widget.actions.webhook.urlPlaceholder', 'https://your-service.com/hook')}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n />\n </div>\n <div style={{ maxWidth: '160px' }}>\n <label style={labelStyle}>{t('bigconsole.widget.actions.webhook.methodLabel', 'Method')}</label>\n <Select\n value={webhookMethod}\n onValueChange={(v) => {\n webhookTouchedRef.current = true;\n setWebhookMethod(v as HttpMethod);\n }}\n disabled={isLoading}\n >\n <SelectTrigger\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent style={selectContentStyle}>\n {HTTP_METHODS.map((m) => (\n <SelectItem key={m} value={m}>\n {m}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <p style={hintStyle}>\n {t(\n 'bigconsole.widget.actions.webhook.payloadHint',\n \"The widget's current data is sent as the request payload.\"\n )}\n </p>\n {/^http:\\/\\//i.test(webhookUrl.trim()) && (\n <p style={{ ...hintStyle, color: 'var(--color-status-warning-text)' }}>\n {t('bigconsole.widget.actions.webhook.insecureWarningPrefix', 'Warning:')} <code>http://</code>{' '}\n {t(\n 'bigconsole.widget.actions.webhook.insecureWarningMiddle',\n \"is unencrypted — the widget's data will be sent in plaintext. Use\"\n )}{' '}\n <code>https://</code>{' '}\n {t(\n 'bigconsole.widget.actions.webhook.insecureWarningSuffix',\n 'if it may contain anything sensitive.'\n )}\n </p>\n )}\n </div>\n )}\n\n {/* Confirmation Section */}\n <div style={{ paddingTop: 'var(--space-formGap)', borderTop: '1px solid var(--color-border)' }}>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n cursor: 'pointer',\n marginBottom: 'var(--space-formGap)',\n }}\n >\n <Checkbox\n checked={hasConfirmation}\n onCheckedChange={(c) => setHasConfirmation(c === true)}\n disabled={isLoading}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.toggleLabel', 'Ask for confirmation first')}\n </span>\n </label>\n\n {hasConfirmation && (\n <div\n style={{\n paddingLeft: 'var(--space-formGap)',\n borderLeft: '2px solid var(--color-border)',\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-controlGap)',\n }}\n >\n <div>\n <label\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-secondary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.dialogTitleLabel', 'Dialog Title')}\n </label>\n <Input\n value={confirmTitle}\n onChange={(e) => setConfirmTitle(e.target.value)}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-sm)', fontSize: 'var(--font-size-body-sm)' }}\n />\n </div>\n <div>\n <label\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-secondary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.messageLabel', 'Message')}\n </label>\n <Textarea\n value={confirmMessage}\n onChange={(e) => setConfirmMessage(e.target.value)}\n rows={2}\n disabled={isLoading}\n style={{ fontSize: 'var(--font-size-body-sm)', resize: 'none' }}\n />\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--space-controlGap)' }}>\n <div>\n <label\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-secondary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.confirmButtonLabel', 'Confirm Button')}\n </label>\n <Input\n value={confirmLabel}\n onChange={(e) => setConfirmLabel(e.target.value)}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-sm)', fontSize: 'var(--font-size-body-sm)' }}\n />\n </div>\n <div>\n <label\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-secondary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.cancelButtonLabel', 'Cancel Button')}\n </label>\n <Input\n value={cancelLabel}\n onChange={(e) => setCancelLabel(e.target.value)}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-sm)', fontSize: 'var(--font-size-body-sm)' }}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n\n {/* Advanced disclosure — event name + visibility */}\n <div style={{ paddingTop: 'var(--space-formGap)', borderTop: '1px solid var(--color-border)' }}>\n <button\n type=\"button\"\n onClick={() => setShowAdvanced((v) => !v)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n background: 'none',\n border: 'none',\n padding: 0,\n cursor: 'pointer',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {showAdvanced ? (\n <ChevronDown style={{ height: '14px', width: '14px' }} />\n ) : (\n <ChevronRight style={{ height: '14px', width: '14px' }} />\n )}\n {t('bigconsole.widget.actions.advanced.toggle', 'Advanced')}\n </button>\n\n {showAdvanced && (\n <div\n style={{\n marginTop: 'var(--space-formGap)',\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-formGap)',\n }}\n >\n <div>\n <label style={labelStyle}>\n {t('bigconsole.widget.actions.advanced.eventNameLabel', 'Event name (id)')}\n </label>\n <Input\n value={isEditMode && action ? action.name : name}\n onChange={(e) => {\n setName(e.target.value);\n setNameEdited(true);\n }}\n placeholder={t('bigconsole.widget.actions.advanced.eventNamePlaceholder', 'auto from label')}\n // The event id is the webhook/consumer contract; it is fixed\n // once the action exists and cannot be changed on edit (#1).\n disabled={isLoading || isEditMode}\n style={{\n height: 'var(--size-controlHeight-md)',\n fontSize: 'var(--font-size-body-sm)',\n fontFamily: 'var(--font-family-mono)',\n }}\n />\n <p style={hintStyle}>\n {t('bigconsole.widget.actions.advanced.emitsPrefix', 'Emits')}{' '}\n <code>\n widget:{isEditMode && action ? action.name : slugifyName(name || label) || '<name>'}:clicked\n </code>\n .{' '}\n {isEditMode\n ? t('bigconsole.widget.actions.advanced.emitsFixed', 'Fixed once created.')\n : t('bigconsole.widget.actions.advanced.emitsAutoDerived', 'Auto-derived from the label.')}\n </p>\n </div>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-sectionGap)' }}>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n cursor: 'pointer',\n }}\n >\n <Checkbox\n checked={disabled}\n onCheckedChange={(c) => setDisabled(c === true)}\n disabled={isLoading}\n />\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-primary)' }}>\n {t('bigconsole.widget.actions.advanced.disabled', 'Disabled')}\n </span>\n </label>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n cursor: 'pointer',\n }}\n >\n <Checkbox checked={hidden} onCheckedChange={(c) => setHidden(c === true)} disabled={isLoading} />\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-primary)' }}>\n {t('bigconsole.widget.actions.advanced.hidden', 'Hidden')}\n </span>\n </label>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <DialogFooter\n style={{\n padding: 'var(--space-formGap) var(--space-pagePadding)',\n borderTop: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-sunken)',\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 'var(--space-controlGap)',\n }}\n >\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onClose}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-md)' }}\n >\n {t('bigconsole.widget.actions.footer.cancel', 'Cancel')}\n </Button>\n {/*\n Gate the save on the matching widget-action permission — create for\n a new button, update for an edit. `disable` keeps the button visible\n (so the reason is discoverable) but non-submittable when denied.\n */}\n <PermissionButton\n permission={\n isEditMode ? BIGCONSOLE_PERMISSIONS.WIDGET_ACTION_UPDATE : BIGCONSOLE_PERMISSIONS.WIDGET_ACTION_CREATE\n }\n deniedBehavior=\"disable\"\n >\n <Button\n type=\"submit\"\n disabled={isLoading || !label.trim()}\n style={{ height: 'var(--size-controlHeight-md)', backgroundColor: 'var(--color-action-primary-bg)' }}\n >\n {isLoading ? (\n <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Spinner style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n {t('bigconsole.widget.actions.footer.saving', 'Saving...')}\n </span>\n ) : (\n <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n {isEditMode ? (\n <Pencil style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n ) : (\n <Plus style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n )}\n {isEditMode\n ? t('bigconsole.widget.actions.footer.updateButton', 'Update Button')\n : t('bigconsole.widget.actions.footer.addButton', 'Add Button')}\n </span>\n )}\n </Button>\n </PermissionButton>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n});\n\nexport default ActionConfigDialog;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ActionConfigDialog.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/ActionConfigDialog.tsx"],"sourcesContent":["/**\n * ActionConfigDialog Component (v2.1)\n *\n * Modal dialog for creating/editing widget actions.\n *\n * v2.1 (BOFF-5659): reframed around the *outcome* — \"When clicked, do this\" —\n * instead of the abstract action Type. A button always emits\n * `widget:<name>:clicked`; the dialog now lets the user attach the behaviour\n * inline. Today the two shippable outcomes are:\n * - \"Call a webhook / my API\" → captures a URL + method; the parent pairs the\n * action with an EventWebhookMapping bound to that event (no backend change).\n * - \"Just emit an event\" → the raw emit, for callers wiring their own\n * consumers.\n * The action `name` (the event id) is auto-derived from the label and tucked\n * under Advanced so there is a single required field.\n *\n * Uses fe-libs shared UI components and semantic tokens for consistent styling.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect, useMemo, useRef } from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Textarea } from '@burdenoff/fe-libs/ui';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@burdenoff/fe-libs/ui';\nimport { Checkbox } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { Zap, Plus, Pencil, ChevronDown, ChevronRight } from 'lucide-react';\nimport { BIGCONSOLE_PERMISSIONS } from '../../../constants/permissions';\nimport type {\n WidgetAction,\n ActionStyle,\n ActionConfirmation,\n CreateWidgetActionInput,\n UpdateWidgetActionInput,\n} from '../../hooks/useWidgetActions';\nimport type { HttpMethod } from '../../hooks/useEventWebhooks';\nimport { Section } from '../common';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** What should happen when the button is clicked. */\nexport type ActionOutcome = 'WEBHOOK' | 'EMIT';\n\n/** Webhook binding drafted in the dialog and reconciled by the parent. */\nexport interface ActionWebhookDraft {\n url: string;\n method: HttpMethod;\n}\n\n/**\n * The action fields passed to the create/update mutation. The webhook binding\n * is passed as a SEPARATE onSave argument (never embedded here) so it can never\n * leak into the GraphQL input.\n */\nexport type ActionSaveData = Omit<CreateWidgetActionInput, 'widgetId'> | UpdateWidgetActionInput;\n\nexport interface ActionConfigDialogProps {\n isOpen: boolean;\n action?: WidgetAction;\n /** Existing webhook binding for the edited action (prefills the URL field). */\n initialWebhook?: ActionWebhookDraft | null;\n isLoading?: boolean;\n /** A save failure from the parent (action or webhook mutation) to surface inline. */\n saveError?: string | null;\n onClose: () => void;\n /** `webhook` is the paired binding, or `null` to remove any existing one. */\n onSave: (data: ActionSaveData, webhook: ActionWebhookDraft | null) => void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst HTTP_METHODS: HttpMethod[] = ['POST', 'GET', 'PUT', 'PATCH', 'DELETE'];\n\n/** Stable style values + preview colors; labels are resolved via i18n in-component. */\nconst ACTION_STYLE_META: { value: ActionStyle; color: string }[] = [\n { value: 'PRIMARY', color: 'var(--color-action-primary-bg)' },\n { value: 'SECONDARY', color: 'var(--color-action-secondary-bg)' },\n { value: 'SUCCESS', color: 'var(--color-status-success-bg)' },\n { value: 'WARNING', color: 'var(--color-status-warning-bg)' },\n { value: 'DANGER', color: 'var(--color-action-danger-bg)' },\n];\n\n/** Stable icon values; labels are resolved via i18n in-component. */\nconst ICON_VALUES = [\n '',\n 'refresh',\n 'download',\n 'upload',\n 'trash',\n 'edit',\n 'plus',\n 'check',\n 'eye',\n 'copy',\n 'share',\n 'settings',\n 'filter',\n 'search',\n] as const;\n\n// Derive the event-id (action name) from a human label: \"Refresh Data\" -> \"refresh_data\".\nfunction slugifyName(label: string): string {\n return label\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '');\n}\n\n// Field labels sit BELOW group headings in the type ladder: `medium` here,\n// `bold` + uppercase tracking for the group heading. Previously both were\n// semibold body-sm, so a label and a group heading were indistinguishable.\nconst labelStyle: React.CSSProperties = {\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-primary)',\n marginBottom: 'var(--space-controlGap)',\n};\n\n/** Group heading inside the dialog body: \"Appearance\" / \"Behaviour\" / \"Advanced\". */\nconst groupHeadingStyle: React.CSSProperties = {\n margin: '0 0 var(--space-controlGap) 0',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-bold)',\n letterSpacing: '0.06em',\n textTransform: 'uppercase',\n color: 'var(--color-text-secondary)',\n};\n\nconst hintStyle: React.CSSProperties = {\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n marginTop: 'var(--space-controlGap)',\n};\n\nconst selectContentStyle: React.CSSProperties = {\n zIndex: 9999,\n backgroundColor: 'var(--color-overlay-popoverBg, var(--color-bg-surface))',\n border: '1px solid var(--color-border-subtle)',\n boxShadow: 'var(--shadow-elevation-3)',\n borderRadius: 'var(--radius-button)',\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const ActionConfigDialog: FC<ActionConfigDialogProps> = memo(function ActionConfigDialog({\n isOpen,\n action,\n initialWebhook,\n isLoading = false,\n saveError,\n onClose,\n onSave,\n}) {\n const { t } = useI18n();\n const isEditMode = !!action;\n const labelInputRef = useRef<HTMLInputElement>(null);\n // True once the user touches the webhook fields, so a late-arriving\n // `initialWebhook` fetch can seed the form without clobbering in-progress edits.\n const webhookTouchedRef = useRef(false);\n\n // Form state\n const [label, setLabel] = useState('');\n const [name, setName] = useState('');\n const [nameEdited, setNameEdited] = useState(false);\n const [style, setStyle] = useState<ActionStyle>('PRIMARY');\n const [icon, setIcon] = useState('');\n const [outcome, setOutcome] = useState<ActionOutcome>('WEBHOOK');\n const [webhookUrl, setWebhookUrl] = useState('');\n const [webhookMethod, setWebhookMethod] = useState<HttpMethod>('POST');\n const [disabled, setDisabled] = useState(false);\n const [hidden, setHidden] = useState(false);\n const [showAdvanced, setShowAdvanced] = useState(false);\n const [hasConfirmation, setHasConfirmation] = useState(false);\n const [confirmTitle, setConfirmTitle] = useState(() =>\n t('bigconsole.widget.actions.confirm.defaultTitle', 'Confirm Action')\n );\n const [confirmMessage, setConfirmMessage] = useState(() =>\n t('bigconsole.widget.actions.confirm.defaultMessage', 'Are you sure you want to proceed?')\n );\n const [confirmLabel, setConfirmLabel] = useState(() =>\n t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm')\n );\n const [cancelLabel, setCancelLabel] = useState(() =>\n t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel')\n );\n const [error, setError] = useState<string | null>(null);\n\n // Localized option lists — value/enum fields stay stable; only the display copy is translated.\n const OUTCOMES = useMemo<{ value: ActionOutcome; label: string; hint: string }[]>(\n () => [\n {\n value: 'WEBHOOK',\n label: t('bigconsole.widget.actions.outcome.webhook.label', 'Call a webhook / my API'),\n hint: t(\n 'bigconsole.widget.actions.outcome.webhook.hint',\n 'Sends an HTTP request to the URL below every time the button is clicked.'\n ),\n },\n {\n value: 'EMIT',\n label: t('bigconsole.widget.actions.outcome.emit.label', 'Just emit an event (advanced)'),\n hint: t(\n 'bigconsole.widget.actions.outcome.emit.hint',\n 'Emits widget:<name>:clicked. Wire it up yourself in the Webhooks/Events section.'\n ),\n },\n ],\n [t]\n );\n\n const ACTION_STYLES = useMemo<{ value: ActionStyle; label: string; color: string }[]>(() => {\n const labels: Record<ActionStyle, string> = {\n PRIMARY: t('bigconsole.widget.actions.style.primary', 'Primary'),\n SECONDARY: t('bigconsole.widget.actions.style.secondary', 'Secondary'),\n SUCCESS: t('bigconsole.widget.actions.style.success', 'Success'),\n WARNING: t('bigconsole.widget.actions.style.warning', 'Warning'),\n DANGER: t('bigconsole.widget.actions.style.danger', 'Danger'),\n GHOST: t('bigconsole.widget.actions.style.ghost', 'Ghost'),\n LINK: t('bigconsole.widget.actions.style.link', 'Link'),\n };\n return ACTION_STYLE_META.map((s) => ({ value: s.value, label: labels[s.value], color: s.color }));\n }, [t]);\n\n const ICON_OPTIONS = useMemo(() => {\n const labels: Record<(typeof ICON_VALUES)[number], string> = {\n '': t('bigconsole.widget.actions.icon.none', 'No icon'),\n refresh: t('bigconsole.widget.actions.icon.refresh', 'Refresh'),\n download: t('bigconsole.widget.actions.icon.download', 'Download'),\n upload: t('bigconsole.widget.actions.icon.upload', 'Upload'),\n trash: t('bigconsole.widget.actions.icon.trash', 'Trash'),\n edit: t('bigconsole.widget.actions.icon.edit', 'Edit'),\n plus: t('bigconsole.widget.actions.icon.plus', 'Plus'),\n check: t('bigconsole.widget.actions.icon.check', 'Check'),\n eye: t('bigconsole.widget.actions.icon.eye', 'View'),\n copy: t('bigconsole.widget.actions.icon.copy', 'Copy'),\n share: t('bigconsole.widget.actions.icon.share', 'Share'),\n settings: t('bigconsole.widget.actions.icon.settings', 'Settings'),\n filter: t('bigconsole.widget.actions.icon.filter', 'Filter'),\n search: t('bigconsole.widget.actions.icon.search', 'Search'),\n };\n return ICON_VALUES.map((value) => ({ value, label: labels[value] }));\n }, [t]);\n\n // Reset form when the dialog opens or the edited action changes. Deliberately\n // does NOT depend on `initialWebhook` — that fetch can settle after the dialog\n // is open, and re-running this would wipe the user's in-progress edits (#6).\n // The webhook fields are seeded by the separate effect below.\n useEffect(() => {\n if (!isOpen) return;\n\n webhookTouchedRef.current = false;\n setWebhookUrl('');\n setWebhookMethod('POST');\n\n if (action) {\n setLabel(action.label);\n setName(action.name);\n setNameEdited(false);\n setStyle(action.style);\n setIcon(action.icon || '');\n setDisabled(action.disabled);\n setHidden(action.hidden);\n // Default to \"emit\"; the seed effect flips to WEBHOOK if a mapping exists.\n setOutcome('EMIT');\n setHasConfirmation(!!action.confirmation);\n if (action.confirmation) {\n setConfirmTitle(action.confirmation.title);\n setConfirmMessage(action.confirmation.message);\n setConfirmLabel(\n action.confirmation.confirmLabel || t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm')\n );\n setCancelLabel(\n action.confirmation.cancelLabel || t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel')\n );\n } else {\n setConfirmTitle(t('bigconsole.widget.actions.confirm.defaultTitle', 'Confirm Action'));\n setConfirmMessage(t('bigconsole.widget.actions.confirm.defaultMessage', 'Are you sure you want to proceed?'));\n setConfirmLabel(t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm'));\n setCancelLabel(t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel'));\n }\n } else {\n setLabel('');\n setName('');\n setNameEdited(false);\n setStyle('PRIMARY');\n setIcon('');\n setOutcome('WEBHOOK');\n setDisabled(false);\n setHidden(false);\n setHasConfirmation(false);\n setConfirmTitle(t('bigconsole.widget.actions.confirm.defaultTitle', 'Confirm Action'));\n setConfirmMessage(t('bigconsole.widget.actions.confirm.defaultMessage', 'Are you sure you want to proceed?'));\n setConfirmLabel(t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm'));\n setCancelLabel(t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel'));\n }\n setShowAdvanced(false);\n setError(null);\n // Focus the label after the dialog paints — a double rAF is more reliable than\n // a magic setTimeout delay and doesn't race the open animation.\n const raf = requestAnimationFrame(() => requestAnimationFrame(() => labelInputRef.current?.focus()));\n return () => cancelAnimationFrame(raf);\n }, [isOpen, action, t]);\n\n // Seed the webhook fields from the (possibly late-arriving) mapping fetch,\n // unless the user has already started editing them.\n useEffect(() => {\n if (!isOpen || !initialWebhook || webhookTouchedRef.current) return;\n setOutcome('WEBHOOK');\n setWebhookUrl(initialWebhook.url);\n setWebhookMethod(initialWebhook.method);\n }, [isOpen, initialWebhook]);\n\n // Keep the auto-derived name in sync with the label until the user overrides it.\n const handleLabelChange = useCallback(\n (value: string) => {\n setLabel(value);\n if (!nameEdited) setName(slugifyName(value));\n if (error) setError(null);\n },\n [nameEdited, error]\n );\n\n const handleSubmit = useCallback(\n (e: React.FormEvent) => {\n e.preventDefault();\n\n const trimmedLabel = label.trim();\n if (!trimmedLabel) {\n setError(t('bigconsole.widget.actions.validation.labelRequired', 'Button label is required'));\n labelInputRef.current?.focus();\n return;\n }\n\n // The action name is the event id (webhook contract). It is set once at\n // creation and never rewritten on edit — re-slugifying a stored name like\n // `refresh-v2` would silently change `widget:refresh-v2:clicked` and break\n // existing bindings/consumers (#1).\n const finalName =\n isEditMode && action ? action.name : slugifyName(nameEdited ? name : label) || slugifyName(label);\n if (!finalName) {\n setError(\n t('bigconsole.widget.actions.validation.labelLettersOrNumbers', 'Enter a label using letters or numbers')\n );\n return;\n }\n\n if (outcome === 'WEBHOOK') {\n const url = webhookUrl.trim();\n if (!url) {\n setError(\n t('bigconsole.widget.actions.validation.urlRequired', 'Enter the URL to call when the button is clicked')\n );\n return;\n }\n if (!/^https?:\\/\\//i.test(url)) {\n setError(\n t('bigconsole.widget.actions.validation.urlScheme', 'Webhook URL must start with http:// or https://')\n );\n return;\n }\n }\n\n const confirmation: ActionConfirmation | undefined = hasConfirmation\n ? {\n title: confirmTitle.trim() || t('bigconsole.widget.actions.confirm.defaultTitle', 'Confirm Action'),\n message: confirmMessage.trim() || t('bigconsole.widget.actions.confirm.fallbackMessage', 'Are you sure?'),\n confirmLabel: confirmLabel.trim() || t('bigconsole.widget.actions.confirm.defaultConfirmLabel', 'Confirm'),\n cancelLabel: cancelLabel.trim() || t('bigconsole.widget.actions.confirm.defaultCancelLabel', 'Cancel'),\n }\n : undefined;\n\n const webhook: ActionWebhookDraft | null =\n outcome === 'WEBHOOK' ? { url: webhookUrl.trim(), method: webhookMethod } : null;\n\n if (isEditMode && action) {\n const updateData: ActionSaveData = {\n id: action.id,\n name: finalName,\n label: trimmedLabel,\n // Webhook/emit outcomes must be a BUTTON so the click runs onAction and\n // emits the event. Saving a stale LINK type would render an <a> that\n // bypasses onAction, so the webhook would never fire (#3).\n type: 'BUTTON',\n style,\n icon: icon || undefined,\n confirmation: hasConfirmation ? confirmation : null,\n disabled,\n hidden,\n };\n onSave(updateData, webhook);\n } else {\n const createData: ActionSaveData = {\n name: finalName,\n label: trimmedLabel,\n // Webhook/emit outcomes must be a BUTTON so the click runs onAction and\n // emits the event. Saving a stale LINK type would render an <a> that\n // bypasses onAction, so the webhook would never fire (#3).\n type: 'BUTTON',\n style,\n icon: icon || undefined,\n confirmation,\n disabled,\n hidden,\n };\n onSave(createData, webhook);\n }\n },\n [\n label,\n name,\n nameEdited,\n outcome,\n webhookUrl,\n webhookMethod,\n style,\n icon,\n disabled,\n hidden,\n hasConfirmation,\n confirmTitle,\n confirmMessage,\n confirmLabel,\n cancelLabel,\n isEditMode,\n action,\n onSave,\n t,\n ]\n );\n\n const getStyleColor = (s: ActionStyle) =>\n ACTION_STYLES.find((as) => as.value === s)?.color || 'var(--color-action-primary-bg)';\n\n const activeOutcome = OUTCOMES.find((o) => o.value === outcome);\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && !isLoading && onClose()}>\n {/*\n Section emphasis (BOFF-5636). The dialog now sizes to the viewport\n (`min(500px, 100vw - 2rem)`) and its title uses the same body-md scale as\n the inspector that spawns it — a modal opened FROM a panel should not\n outrank the panel. Its three groups (appearance / behaviour / advanced)\n carry real headings instead of three competing border tricks.\n */}\n <DialogContent style={{ width: 'min(500px, calc(100vw - 2rem))', maxWidth: 'calc(100vw - 2rem)', padding: 0 }}>\n {/* Header */}\n <DialogHeader style={{ padding: 'var(--space-cardPadding) var(--space-cardPadding) 0' }}>\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n minWidth: 0,\n }}\n >\n <div\n style={{\n display: 'flex',\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 'var(--radius-card)',\n backgroundColor: 'var(--color-action-primary-bg)',\n boxShadow: 'var(--shadow-elevation-2)',\n }}\n >\n {isEditMode ? (\n <Pencil\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n ) : (\n <Zap\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n )}\n </div>\n <div>\n <DialogTitle\n style={{\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-bold)',\n color: 'var(--color-text-primary)',\n margin: 0,\n }}\n >\n {isEditMode\n ? t('bigconsole.widget.actions.header.editTitle', 'Edit Button')\n : t('bigconsole.widget.actions.header.addTitle', 'Add Button')}\n </DialogTitle>\n <DialogDescription\n style={{\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-secondary)',\n margin: 'var(--space-controlGap) 0 0 0',\n }}\n >\n {isEditMode\n ? t('bigconsole.widget.actions.header.editDescription', 'Update the button and what it does')\n : t('bigconsole.widget.actions.header.addDescription', 'Add a button and choose what it does')}\n </DialogDescription>\n </div>\n </div>\n </DialogHeader>\n\n <form onSubmit={handleSubmit}>\n {/* Form Content */}\n <div style={{ padding: 'var(--space-cardPadding)', maxHeight: '65vh', minWidth: 0, overflowY: 'auto' }}>\n {/* Error Display — local validation error or a save failure from the parent. */}\n {(error || saveError) && (\n <Section\n tone=\"danger\"\n padding=\"compact\"\n headingLevel={3}\n title=\"This button could not be saved\"\n className=\"mb-form-gap\"\n data-testid=\"action-config-error\"\n >\n <p role=\"alert\" className=\"break-words text-sm text-[var(--color-status-error-text)]\">\n {error || saveError}\n </p>\n </Section>\n )}\n\n {/* ---- Group 1: how the button looks ---- */}\n <h3 style={groupHeadingStyle}>Appearance</h3>\n\n {/* Label Field */}\n <div style={{ marginBottom: 'var(--space-formGap)' }}>\n <label style={labelStyle}>\n {t('bigconsole.widget.actions.field.buttonLabel', 'Button label')}{' '}\n <span style={{ color: 'var(--color-status-error-text)' }}>*</span>\n </label>\n <Input\n ref={labelInputRef}\n value={label}\n onChange={(e) => handleLabelChange(e.target.value)}\n placeholder={t(\n 'bigconsole.widget.actions.field.buttonLabelPlaceholder',\n 'e.g., Refresh Data, Export CSV'\n )}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n />\n <p style={hintStyle}>\n {t('bigconsole.widget.actions.field.buttonLabelHint', 'Text shown on the button')}\n </p>\n </div>\n\n {/* Style + Icon Row */}\n <div\n style={{\n display: 'grid',\n // Collapses to one column below ~440px so each control keeps a\n // usable width inside a phone-width dialog.\n gridTemplateColumns: 'repeat(auto-fit, minmax(11rem, 1fr))',\n gap: 'var(--space-formGap)',\n marginBottom: 'var(--space-formGap)',\n }}\n >\n <div>\n <label style={labelStyle}>{t('bigconsole.widget.actions.field.style', 'Style')}</label>\n <Select value={style} onValueChange={(v) => setStyle(v as ActionStyle)} disabled={isLoading}>\n <SelectTrigger\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent style={selectContentStyle}>\n {ACTION_STYLES.map((s) => (\n <SelectItem key={s.value} value={s.value}>\n {s.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div>\n <label style={labelStyle}>{t('bigconsole.widget.actions.field.icon', 'Icon')}</label>\n <Select value={icon} onValueChange={setIcon} disabled={isLoading}>\n <SelectTrigger\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n >\n <SelectValue placeholder={t('bigconsole.widget.actions.icon.none', 'No icon')} />\n </SelectTrigger>\n <SelectContent style={{ ...selectContentStyle, maxHeight: '200px' }}>\n {ICON_OPTIONS.map((i) => (\n <SelectItem key={i.value || 'none'} value={i.value || 'none'}>\n {i.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* Style Preview */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n marginBottom: 'var(--space-formGap)',\n padding: 'var(--space-controlGap)',\n backgroundColor: 'var(--color-bg-sunken)',\n borderRadius: 'var(--radius-button)',\n }}\n >\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-muted)' }}>\n {t('bigconsole.widget.actions.preview.label', 'Preview:')}\n </span>\n <button\n type=\"button\"\n style={{\n padding: 'var(--space-controlGap) var(--space-formGap)',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n borderRadius: 'var(--radius-button)',\n backgroundColor: getStyleColor(style),\n color: 'var(--color-action-primary-text)',\n border: 'none',\n cursor: 'default',\n }}\n >\n {label || t('bigconsole.widget.actions.preview.buttonFallback', 'Button')}\n </button>\n </div>\n\n {/* ---- Group 2: what the button does ---- */}\n <h3 style={{ ...groupHeadingStyle, marginTop: 'var(--space-formGap)' }}>Behaviour</h3>\n\n {/* When clicked (outcome) */}\n <div style={{ marginBottom: 'var(--space-formGap)' }}>\n <label style={labelStyle}>{t('bigconsole.widget.actions.field.whenClicked', 'When clicked')}</label>\n <Select\n value={outcome}\n onValueChange={(v) => {\n webhookTouchedRef.current = true;\n setOutcome(v as ActionOutcome);\n }}\n disabled={isLoading}\n >\n <SelectTrigger style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent style={selectContentStyle}>\n {OUTCOMES.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {activeOutcome && <p style={hintStyle}>{activeOutcome.hint}</p>}\n </div>\n\n {/* Webhook config (only for the WEBHOOK outcome) */}\n {outcome === 'WEBHOOK' && (\n <div\n style={{\n marginBottom: 'var(--space-formGap)',\n paddingLeft: 'var(--space-formGap)',\n borderLeft: '2px solid var(--color-border-subtle)',\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-controlGap)',\n }}\n >\n <div>\n <label style={labelStyle}>\n {t('bigconsole.widget.actions.webhook.urlLabel', 'URL')}{' '}\n <span style={{ color: 'var(--color-status-error-text)' }}>*</span>\n </label>\n <Input\n value={webhookUrl}\n onChange={(e) => {\n webhookTouchedRef.current = true;\n setWebhookUrl(e.target.value);\n if (error) setError(null);\n }}\n placeholder={t('bigconsole.widget.actions.webhook.urlPlaceholder', 'https://your-service.com/hook')}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n />\n </div>\n <div style={{ maxWidth: '160px', minWidth: 0 }}>\n <label style={labelStyle}>{t('bigconsole.widget.actions.webhook.methodLabel', 'Method')}</label>\n <Select\n value={webhookMethod}\n onValueChange={(v) => {\n webhookTouchedRef.current = true;\n setWebhookMethod(v as HttpMethod);\n }}\n disabled={isLoading}\n >\n <SelectTrigger\n style={{ height: 'var(--size-controlHeight-md)', fontSize: 'var(--font-size-body-sm)' }}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent style={selectContentStyle}>\n {HTTP_METHODS.map((m) => (\n <SelectItem key={m} value={m}>\n {m}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <p style={hintStyle}>\n {t(\n 'bigconsole.widget.actions.webhook.payloadHint',\n \"The widget's current data is sent as the request payload.\"\n )}\n </p>\n {/^http:\\/\\//i.test(webhookUrl.trim()) && (\n <p style={{ ...hintStyle, color: 'var(--color-status-warning-text)' }}>\n {t('bigconsole.widget.actions.webhook.insecureWarningPrefix', 'Warning:')} <code>http://</code>{' '}\n {t(\n 'bigconsole.widget.actions.webhook.insecureWarningMiddle',\n \"is unencrypted — the widget's data will be sent in plaintext. Use\"\n )}{' '}\n <code>https://</code>{' '}\n {t(\n 'bigconsole.widget.actions.webhook.insecureWarningSuffix',\n 'if it may contain anything sensitive.'\n )}\n </p>\n )}\n </div>\n )}\n\n {/* Confirmation Section */}\n <div style={{ paddingTop: 'var(--space-formGap)', borderTop: '1px solid var(--color-border-subtle)' }}>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n cursor: 'pointer',\n marginBottom: 'var(--space-formGap)',\n }}\n >\n <Checkbox\n checked={hasConfirmation}\n onCheckedChange={(c) => setHasConfirmation(c === true)}\n disabled={isLoading}\n />\n <span\n style={{\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.toggleLabel', 'Ask for confirmation first')}\n </span>\n </label>\n\n {hasConfirmation && (\n <div\n style={{\n paddingLeft: 'var(--space-formGap)',\n borderLeft: '2px solid var(--color-border-subtle)',\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-controlGap)',\n }}\n >\n <div>\n <label\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-secondary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.dialogTitleLabel', 'Dialog Title')}\n </label>\n <Input\n value={confirmTitle}\n onChange={(e) => setConfirmTitle(e.target.value)}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-sm)', fontSize: 'var(--font-size-body-sm)' }}\n />\n </div>\n <div>\n <label\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-secondary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.messageLabel', 'Message')}\n </label>\n <Textarea\n value={confirmMessage}\n onChange={(e) => setConfirmMessage(e.target.value)}\n rows={2}\n disabled={isLoading}\n style={{ fontSize: 'var(--font-size-body-sm)', resize: 'none' }}\n />\n </div>\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fit, minmax(11rem, 1fr))',\n gap: 'var(--space-controlGap)',\n }}\n >\n <div>\n <label\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-secondary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.confirmButtonLabel', 'Confirm Button')}\n </label>\n <Input\n value={confirmLabel}\n onChange={(e) => setConfirmLabel(e.target.value)}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-sm)', fontSize: 'var(--font-size-body-sm)' }}\n />\n </div>\n <div>\n <label\n style={{\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-secondary)',\n marginBottom: 'var(--space-controlGap)',\n }}\n >\n {t('bigconsole.widget.actions.confirm.cancelButtonLabel', 'Cancel Button')}\n </label>\n <Input\n value={cancelLabel}\n onChange={(e) => setCancelLabel(e.target.value)}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-sm)', fontSize: 'var(--font-size-body-sm)' }}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n\n {/* ---- Group 3: advanced disclosure — event name + visibility ---- */}\n <div style={{ paddingTop: 'var(--space-formGap)', borderTop: '1px solid var(--color-border-subtle)' }}>\n {/* The disclosure button IS this group's heading, so the heading wraps it. */}\n <h3 style={{ ...groupHeadingStyle, margin: 0 }}>\n <button\n type=\"button\"\n onClick={() => setShowAdvanced((v) => !v)}\n aria-expanded={showAdvanced}\n aria-controls=\"action-config-advanced\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n minHeight: 'var(--size-controlHeight-md)',\n background: 'none',\n border: 'none',\n padding: 0,\n cursor: 'pointer',\n font: 'inherit',\n letterSpacing: 'inherit',\n textTransform: 'inherit',\n color: 'inherit',\n }}\n >\n {showAdvanced ? (\n <ChevronDown style={{ height: '14px', width: '14px' }} />\n ) : (\n <ChevronRight style={{ height: '14px', width: '14px' }} />\n )}\n {t('bigconsole.widget.actions.advanced.toggle', 'Advanced')}\n </button>\n </h3>\n\n {showAdvanced && (\n <div\n id=\"action-config-advanced\"\n style={{\n marginTop: 'var(--space-formGap)',\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-formGap)',\n }}\n >\n <div>\n <label style={labelStyle}>\n {t('bigconsole.widget.actions.advanced.eventNameLabel', 'Event name (id)')}\n </label>\n <Input\n value={isEditMode && action ? action.name : name}\n onChange={(e) => {\n setName(e.target.value);\n setNameEdited(true);\n }}\n placeholder={t('bigconsole.widget.actions.advanced.eventNamePlaceholder', 'auto from label')}\n // The event id is the webhook/consumer contract; it is fixed\n // once the action exists and cannot be changed on edit (#1).\n disabled={isLoading || isEditMode}\n style={{\n height: 'var(--size-controlHeight-md)',\n fontSize: 'var(--font-size-body-sm)',\n fontFamily: 'var(--font-family-mono)',\n }}\n />\n <p style={hintStyle}>\n {t('bigconsole.widget.actions.advanced.emitsPrefix', 'Emits')}{' '}\n <code>\n widget:{isEditMode && action ? action.name : slugifyName(name || label) || '<name>'}:clicked\n </code>\n .{' '}\n {isEditMode\n ? t('bigconsole.widget.actions.advanced.emitsFixed', 'Fixed once created.')\n : t('bigconsole.widget.actions.advanced.emitsAutoDerived', 'Auto-derived from the label.')}\n </p>\n </div>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-sectionGap)' }}>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n cursor: 'pointer',\n }}\n >\n <Checkbox\n checked={disabled}\n onCheckedChange={(c) => setDisabled(c === true)}\n disabled={isLoading}\n />\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-primary)' }}>\n {t('bigconsole.widget.actions.advanced.disabled', 'Disabled')}\n </span>\n </label>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-controlGap)',\n cursor: 'pointer',\n }}\n >\n <Checkbox checked={hidden} onCheckedChange={(c) => setHidden(c === true)} disabled={isLoading} />\n <span style={{ fontSize: 'var(--font-size-body-sm)', color: 'var(--color-text-primary)' }}>\n {t('bigconsole.widget.actions.advanced.hidden', 'Hidden')}\n </span>\n </label>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Footer */}\n <DialogFooter\n style={{\n padding: 'var(--space-formGap) var(--space-pagePadding)',\n borderTop: '1px solid var(--color-border-subtle)',\n backgroundColor: 'var(--color-bg-sunken)',\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 'var(--space-controlGap)',\n }}\n >\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onClose}\n disabled={isLoading}\n style={{ height: 'var(--size-controlHeight-md)' }}\n >\n {t('bigconsole.widget.actions.footer.cancel', 'Cancel')}\n </Button>\n {/*\n Gate the save on the matching widget-action permission — create for\n a new button, update for an edit. `disable` keeps the button visible\n (so the reason is discoverable) but non-submittable when denied.\n */}\n <PermissionButton\n permission={\n isEditMode ? BIGCONSOLE_PERMISSIONS.WIDGET_ACTION_UPDATE : BIGCONSOLE_PERMISSIONS.WIDGET_ACTION_CREATE\n }\n deniedBehavior=\"disable\"\n >\n <Button\n type=\"submit\"\n disabled={isLoading || !label.trim()}\n style={{ height: 'var(--size-controlHeight-md)', backgroundColor: 'var(--color-action-primary-bg)' }}\n >\n {isLoading ? (\n <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Spinner style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n {t('bigconsole.widget.actions.footer.saving', 'Saving...')}\n </span>\n ) : (\n <span style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n {isEditMode ? (\n <Pencil style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n ) : (\n <Plus style={{ height: 'var(--size-icon-sm)', width: 'var(--size-icon-sm)' }} />\n )}\n {isEditMode\n ? t('bigconsole.widget.actions.footer.updateButton', 'Update Button')\n : t('bigconsole.widget.actions.footer.addButton', 'Add Button')}\n </span>\n )}\n </Button>\n </PermissionButton>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n});\n\nexport default ActionConfigDialog;\n"],"mappings":"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"}