@burdenoff/microfe-bigconsole 2026.805.1 → 2026.805.3

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 (150) hide show
  1. package/dist/bigconsole/AdminRoot.js +21 -16
  2. package/dist/bigconsole/AdminRoot.js.map +1 -1
  3. package/dist/bigconsole/BigConsoleRoot.js +44 -39
  4. package/dist/bigconsole/BigConsoleRoot.js.map +1 -1
  5. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +109 -113
  6. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
  7. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +115 -113
  8. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  9. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +71 -62
  10. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  11. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +116 -100
  12. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  13. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +56 -54
  14. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
  15. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +126 -125
  16. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
  17. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +151 -150
  18. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
  19. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +77 -76
  20. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
  21. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +97 -96
  22. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  23. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +172 -191
  24. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  25. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +100 -98
  26. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
  27. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +75 -83
  28. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js.map +1 -1
  29. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +151 -154
  30. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
  31. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +187 -193
  32. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
  33. package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -0
  34. package/dist/bigconsole/components/dashboard/WidgetPalette.js +110 -108
  35. package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
  36. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +102 -103
  37. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  38. package/dist/bigconsole/components/datasink/DataSinkCard.js +20 -20
  39. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  40. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +36 -41
  41. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  42. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +38 -37
  43. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  44. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +113 -117
  45. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
  46. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +182 -197
  47. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  48. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +166 -168
  49. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  50. package/dist/bigconsole/components/parser/DataSinkSelector.js +87 -86
  51. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  52. package/dist/bigconsole/components/parser/ImportParserDialog.js +196 -211
  53. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  54. package/dist/bigconsole/components/parser/ParserSelector.js +130 -128
  55. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  56. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +66 -63
  57. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
  58. package/dist/bigconsole/components/preview/AiPreviewPanel.js +95 -91
  59. package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
  60. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +243 -230
  61. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  62. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +149 -145
  63. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  64. package/dist/bigconsole/components/widgets/PropertiesPanel.js +504 -470
  65. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  66. package/dist/bigconsole/components/widgets/WidgetMenu.js +87 -76
  67. package/dist/bigconsole/components/widgets/WidgetMenu.js.map +1 -1
  68. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +44 -47
  69. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  70. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +143 -142
  71. package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
  72. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +101 -88
  73. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  74. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +135 -134
  75. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
  76. package/dist/bigconsole/components/widgets/form/FormWidget.js +167 -159
  77. package/dist/bigconsole/components/widgets/form/FormWidget.js.map +1 -1
  78. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +69 -68
  79. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
  80. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +64 -72
  81. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
  82. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +60 -59
  83. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  84. package/dist/bigconsole/components/widgets/list/ListConfig.js +57 -56
  85. package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
  86. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +70 -69
  87. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
  88. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +35 -34
  89. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
  90. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +20 -19
  91. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
  92. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +178 -177
  93. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  94. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +76 -75
  95. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  96. package/dist/bigconsole/components/widgets/table/TableConfig.js +183 -168
  97. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  98. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +187 -180
  99. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
  100. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +120 -118
  101. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  102. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +40 -38
  103. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
  104. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +150 -148
  105. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  106. package/dist/bigconsole/pages/DashboardBuilderPage.js +189 -175
  107. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  108. package/dist/bigconsole/pages/DashboardViewPage.js +200 -187
  109. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  110. package/dist/bigconsole/pages/DashboardsPage.js +379 -324
  111. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  112. package/dist/bigconsole/pages/DataParsersPage.js +185 -178
  113. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  114. package/dist/bigconsole/pages/DataSinkBuilderPage.js +195 -170
  115. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  116. package/dist/bigconsole/pages/DataSinkViewPage.js +224 -200
  117. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  118. package/dist/bigconsole/pages/DataSinksPage.js +281 -268
  119. package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
  120. package/dist/bigconsole/pages/DataSourcesPage.js +8 -7
  121. package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
  122. package/dist/bigconsole/pages/InsightsPage.js +238 -208
  123. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  124. package/dist/bigconsole/pages/ParserBuilderPage.js +480 -413
  125. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  126. package/dist/bigconsole/pages/ParserViewPage.js +192 -172
  127. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  128. package/dist/bigconsole/pages/PipelineBuilderPage.js +198 -163
  129. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  130. package/dist/bigconsole/pages/PipelineViewPage.js +138 -133
  131. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  132. package/dist/bigconsole/pages/PipelinesPage.js +162 -136
  133. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  134. package/dist/bigconsole/pages/SettingsPage.js +177 -172
  135. package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
  136. package/dist/bigconsole/pages/WidgetDemoPage.js +121 -83
  137. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  138. package/dist/bigconsole/pages/WorkflowViewPage.js +269 -242
  139. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  140. package/dist/bigconsole/pages/WorkflowsPage.js +153 -138
  141. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  142. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +111 -109
  143. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
  144. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +127 -126
  145. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
  146. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +103 -103
  147. package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
  148. package/dist/constants/permissions.js +83 -0
  149. package/dist/constants/permissions.js.map +1 -0
  150. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"BlockKitRenderer.js","names":[],"sources":["../../../../src/bigconsole/renderers/adapters/BlockKitRenderer.tsx"],"sourcesContent":["/**\n * Slack Block Kit Renderer (v2.0)\n *\n * Renders widgets using Slack Block Kit format.\n * Supports common block types: section, divider, header, context, image, actions.\n */\n\nimport React, { memo, useCallback, useMemo, type ReactNode } from 'react';\nimport type { RendererProps, BlockKitTemplate, BlockKitElement, BlockKitText } from '../types/renderer';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Render Block Kit text (plain_text or mrkdwn)\n * Uses React elements instead of dangerouslySetInnerHTML for better security\n */\nfunction renderText(text: BlockKitText | string | undefined): React.ReactNode {\n if (!text) return null;\n\n if (typeof text === 'string') {\n return text;\n }\n\n if (text.type === 'mrkdwn') {\n // Parse mrkdwn and convert to React elements\n const content = text.text || '';\n\n // Parse the markdown into React elements\n const elements: React.ReactNode[] = [];\n let remaining = content;\n let key = 0;\n\n // Process text segment by segment\n while (remaining.length > 0) {\n // Try to match bold: *text*\n const boldMatch = remaining.match(/^\\*([^*]+)\\*/);\n if (boldMatch) {\n elements.push(<strong key={key++}>{boldMatch[1]}</strong>);\n remaining = remaining.slice(boldMatch[0].length);\n continue;\n }\n\n // Try to match italic: _text_\n const italicMatch = remaining.match(/^_([^_]+)_/);\n if (italicMatch) {\n elements.push(<em key={key++}>{italicMatch[1]}</em>);\n remaining = remaining.slice(italicMatch[0].length);\n continue;\n }\n\n // Try to match strike: ~text~\n const strikeMatch = remaining.match(/^~([^~]+)~/);\n if (strikeMatch) {\n elements.push(<del key={key++}>{strikeMatch[1]}</del>);\n remaining = remaining.slice(strikeMatch[0].length);\n continue;\n }\n\n // Try to match code: `text`\n const codeMatch = remaining.match(/^`([^`]+)`/);\n if (codeMatch) {\n elements.push(\n <code key={key++} className=\"bg-bg-sunken px-1 rounded text-sm\">\n {codeMatch[1]}\n </code>\n );\n remaining = remaining.slice(codeMatch[0].length);\n continue;\n }\n\n // Try to match link with text: <url|text>\n const linkTextMatch = remaining.match(/^<([^|>]+)\\|([^>]+)>/);\n if (linkTextMatch) {\n elements.push(\n <a\n key={key++}\n href={linkTextMatch[1]}\n className=\"text-blue-600 dark:text-blue-400 underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {linkTextMatch[2]}\n </a>\n );\n remaining = remaining.slice(linkTextMatch[0].length);\n continue;\n }\n\n // Try to match plain link: <url>\n const linkMatch = remaining.match(/^<([^|>]+)>/);\n if (linkMatch) {\n elements.push(\n <a\n key={key++}\n href={linkMatch[1]}\n className=\"text-blue-600 dark:text-blue-400 underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {linkMatch[1]}\n </a>\n );\n remaining = remaining.slice(linkMatch[0].length);\n continue;\n }\n\n // No special formatting found at start - extract plain text until next special char\n const plainMatch = remaining.match(/^[^*_~`<]+/);\n if (plainMatch) {\n elements.push(<React.Fragment key={key++}>{plainMatch[0]}</React.Fragment>);\n remaining = remaining.slice(plainMatch[0].length);\n continue;\n }\n\n // Single special char that didn't match a pattern - output as-is\n elements.push(<React.Fragment key={key++}>{remaining[0]}</React.Fragment>);\n remaining = remaining.slice(1);\n }\n\n return <span>{elements}</span>;\n }\n\n // Plain text with optional emoji\n return text.text;\n}\n\n/**\n * Get button style class\n */\nfunction getButtonStyleClass(style?: string): string {\n switch (style) {\n case 'primary':\n return 'bg-status-success-bg hover:bg-status-success-bg/90 text-white transition-colors';\n case 'danger':\n return 'bg-status-error-bg hover:bg-status-error-bg/90 text-white transition-colors';\n default:\n return 'bg-bg-sunken hover:bg-bg-sunken/80 text-primary transition-colors';\n }\n}\n\n// ============================================================================\n// Template Binding\n// ============================================================================\n\nfunction bindDataToTemplate<T>(template: T, data: Record<string, unknown>): T {\n if (template === null || template === undefined) {\n return template;\n }\n\n if (typeof template === 'string') {\n // Replace ${path} with actual values\n return template.replace(/\\$\\{([^}]+)\\}/g, (_, path) => {\n const value = getNestedValue(data, path.trim());\n return value !== undefined ? String(value) : '';\n }) as T;\n }\n\n if (Array.isArray(template)) {\n return template.map((item) => bindDataToTemplate(item, data)) as T;\n }\n\n if (typeof template === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(template)) {\n result[key] = bindDataToTemplate(value, data);\n }\n return result as T;\n }\n\n return template;\n}\n\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current && typeof current === 'object' && part in (current as Record<string, unknown>)) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n// ============================================================================\n// Block Renderers\n// ============================================================================\n\ninterface BlockRendererProps {\n block: BlockKitElement;\n index: number;\n onAction?: (actionId: string, value?: string, data?: Record<string, unknown>) => void;\n}\n\nconst BlockRenderer: React.FC<BlockRendererProps> = memo(function BlockRenderer({ block, index: _index, onAction }) {\n switch (block.type) {\n // Header block\n case 'header':\n return (\n <div className=\"py-2\">\n <h2 className=\"text-lg font-bold text-primary\">{renderText(block.text)}</h2>\n </div>\n );\n\n // Section block\n case 'section':\n return (\n <div className=\"py-2 flex items-start gap-4\">\n <div className=\"flex-1\">\n {block.text && <p className=\"text-primary\">{renderText(block.text)}</p>}\n {block.fields && block.fields.length > 0 && (\n <div className=\"grid grid-cols-2 gap-2 mt-2\">\n {block.fields.map((field, i) => (\n <div key={i} className=\"text-sm\">\n {renderText(field)}\n </div>\n ))}\n </div>\n )}\n </div>\n {block.accessory && (\n <div className=\"flex-shrink-0\">\n <AccessoryRenderer accessory={block.accessory as BlockKitElement} onAction={onAction} />\n </div>\n )}\n </div>\n );\n\n // Divider block\n case 'divider':\n return <hr className=\"my-2 border-default\" />;\n\n // Image block\n case 'image':\n return (\n <div className=\"py-2\">\n {block.title && <p className=\"text-sm text-secondary mb-1\">{renderText(block.title)}</p>}\n <img src={block.image_url} alt={block.alt_text || ''} className=\"max-w-full h-auto rounded\" />\n </div>\n );\n\n // Context block\n case 'context':\n return (\n <div className=\"py-1 flex items-center gap-2 flex-wrap text-sm text-secondary\">\n {block.elements?.map((element, i) => (\n <span key={i}>\n {element.type === 'image' ? (\n <img src={element.image_url} alt={element.alt_text || ''} className=\"w-5 h-5 rounded inline-block\" />\n ) : (\n renderText(element.text as BlockKitText)\n )}\n </span>\n ))}\n </div>\n );\n\n // Actions block\n case 'actions':\n return (\n <div className=\"py-2 flex gap-2 flex-wrap\">\n {block.elements?.map((element, i) => (\n <ActionRenderer key={i} element={element} onAction={onAction} />\n ))}\n </div>\n );\n\n // Input block (simplified)\n case 'input':\n return (\n <div className=\"py-2\">\n {block.label ? (\n <label className=\"block text-sm font-medium text-secondary mb-1\">\n {renderText(block.label as BlockKitText) as ReactNode}\n </label>\n ) : null}\n <input\n type=\"text\"\n className=\"w-full px-3 py-2 border border-default rounded-md bg-surface text-primary transition-colors focus:ring-2 focus:ring-primary/20\"\n placeholder={(() => {\n const element = block.element as Record<string, unknown> | undefined;\n return element?.placeholder ? (renderText(element.placeholder as BlockKitText) as string) : '';\n })()}\n />\n </div>\n );\n\n // Rich text block (simplified)\n case 'rich_text':\n return (\n <div className=\"py-2 text-primary\">\n {block.elements?.map((element, i) => (\n <span key={i}>{renderText(element.text as BlockKitText)}</span>\n ))}\n </div>\n );\n\n default:\n return null;\n }\n});\n\n// ============================================================================\n// Accessory Renderer\n// ============================================================================\n\ninterface AccessoryRendererProps {\n accessory: BlockKitElement;\n onAction?: (actionId: string, value?: string, data?: Record<string, unknown>) => void;\n}\n\nconst AccessoryRenderer: React.FC<AccessoryRendererProps> = memo(function AccessoryRenderer({ accessory, onAction }) {\n switch (accessory.type) {\n case 'image':\n return (\n <img src={accessory.image_url} alt={accessory.alt_text || ''} className=\"w-12 h-12 rounded object-cover\" />\n );\n\n case 'button':\n return (\n <button\n type=\"button\"\n onClick={() => onAction?.(accessory.action_id || '', accessory.value)}\n className={`px-3 py-1.5 text-sm font-medium rounded ${getButtonStyleClass(accessory.style)}`}\n >\n {renderText(accessory.text)}\n </button>\n );\n\n case 'overflow':\n return (\n <button type=\"button\" className=\"p-1 text-secondary hover:text-primary transition-colors\">\n <svg className=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z\" />\n </svg>\n </button>\n );\n\n default:\n return null;\n }\n});\n\n// ============================================================================\n// Action Renderer\n// ============================================================================\n\ninterface ActionRendererProps {\n element: BlockKitElement;\n onAction?: (actionId: string, value?: string, data?: Record<string, unknown>) => void;\n}\n\nconst ActionRenderer: React.FC<ActionRendererProps> = memo(function ActionRenderer({ element, onAction }) {\n const handleClick = useCallback(() => {\n if (element.action_id) {\n onAction?.(element.action_id, element.value);\n }\n if (element.url) {\n window.open(element.url, '_blank');\n }\n }, [element, onAction]);\n\n switch (element.type) {\n case 'button':\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n className={`px-4 py-2 text-sm font-medium rounded ${getButtonStyleClass(element.style)}`}\n >\n {renderText(element.text)}\n </button>\n );\n\n case 'static_select':\n return (\n <select\n className=\"px-3 py-2 text-sm border border-default rounded bg-surface text-primary transition-colors focus:ring-2 focus:ring-primary/20\"\n onChange={(e) => onAction?.(element.action_id || '', e.target.value)}\n >\n {element.placeholder ? (\n <option value=\"\">{renderText(element.placeholder as BlockKitText) as ReactNode}</option>\n ) : null}\n {(element.options as Array<{ text: BlockKitText; value: string }>)?.map((option, i) => (\n <option key={i} value={option.value}>\n {renderText(option.text)}\n </option>\n ))}\n </select>\n );\n\n case 'datepicker':\n return (\n <input\n type=\"date\"\n className=\"px-3 py-2 text-sm border border-default rounded bg-surface text-primary transition-colors focus:ring-2 focus:ring-primary/20\"\n onChange={(e) => onAction?.(element.action_id || '', e.target.value)}\n />\n );\n\n case 'checkboxes':\n return (\n <div className=\"space-y-1\">\n {(element.options as Array<{ text: BlockKitText; value: string }>)?.map((option, i) => (\n <label key={i} className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n className=\"rounded border-default transition-colors\"\n onChange={(e) => onAction?.(element.action_id || '', option.value, { checked: e.target.checked })}\n />\n {renderText(option.text)}\n </label>\n ))}\n </div>\n );\n\n case 'radio_buttons':\n return (\n <div className=\"space-y-1\">\n {(element.options as Array<{ text: BlockKitText; value: string }>)?.map((option, i) => (\n <label key={i} className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"radio\"\n name={element.action_id}\n className=\"border-default transition-colors\"\n onChange={() => onAction?.(element.action_id || '', option.value)}\n />\n {renderText(option.text)}\n </label>\n ))}\n </div>\n );\n\n default:\n return null;\n }\n});\n\n// ============================================================================\n// Auto-generate BlockKit blocks from arbitrary data\n// ============================================================================\n\nfunction generateBlocksFromData(data: Record<string, unknown>): BlockKitElement[] {\n const blocks: BlockKitElement[] = [];\n\n for (const [key, value] of Object.entries(data)) {\n if (value === null || value === undefined) continue;\n\n // Handle arrays\n if (Array.isArray(value)) {\n // Add header for the array\n blocks.push({\n type: 'header',\n text: {\n type: 'plain_text',\n text: formatKey(key),\n emoji: true,\n },\n });\n\n // Add each item\n value.forEach((item, index) => {\n if (typeof item === 'object' && item !== null) {\n // Object items - render as section with fields\n const fields: BlockKitText[] = [];\n for (const [itemKey, itemValue] of Object.entries(item)) {\n if (itemValue !== null && itemValue !== undefined) {\n fields.push({\n type: 'mrkdwn',\n text: `*${formatKey(itemKey)}:*\\n${formatValue(itemValue)}`,\n });\n }\n }\n if (fields.length > 0) {\n blocks.push({\n type: 'section',\n fields: fields.slice(0, 10), // BlockKit max 10 fields\n });\n }\n } else {\n // Primitive items - render as simple section\n blocks.push({\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `${index + 1}. ${formatValue(item)}`,\n },\n });\n }\n\n // Add divider between items (except last)\n if (index < value.length - 1) {\n blocks.push({ type: 'divider' });\n }\n });\n }\n // Handle objects\n else if (typeof value === 'object') {\n blocks.push({\n type: 'header',\n text: {\n type: 'plain_text',\n text: formatKey(key),\n emoji: true,\n },\n });\n\n const fields: BlockKitText[] = [];\n for (const [objKey, objValue] of Object.entries(value as Record<string, unknown>)) {\n if (objValue !== null && objValue !== undefined) {\n fields.push({\n type: 'mrkdwn',\n text: `*${formatKey(objKey)}:*\\n${formatValue(objValue)}`,\n });\n }\n }\n if (fields.length > 0) {\n blocks.push({\n type: 'section',\n fields: fields.slice(0, 10),\n });\n }\n }\n // Handle primitives\n else {\n blocks.push({\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `*${formatKey(key)}:* ${formatValue(value)}`,\n },\n });\n }\n }\n\n return blocks;\n}\n\nfunction formatKey(key: string): string {\n // Convert camelCase or snake_case to Title Case\n return key\n .replace(/_/g, ' ')\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (str) => str.toUpperCase())\n .trim();\n}\n\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) return '-';\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n}\n\n// ============================================================================\n// Main Renderer Component\n// ============================================================================\n\nexport const BlockKitRenderer: React.FC<RendererProps> = memo(function BlockKitRenderer({\n widget,\n data,\n template,\n isLoading,\n error,\n onDrilldown: _onDrilldown,\n onAction,\n}) {\n // Debug logging\n\n // Parse and bind template\n const boundTemplate = useMemo(() => {\n // 1. If template has blocks, bind data and use it\n if (template && 'blocks' in (template as Record<string, unknown>)) {\n return bindDataToTemplate(template as unknown as BlockKitTemplate, data);\n }\n\n // 2. If data has blocks, use it directly as BlockKit format\n if (data && 'blocks' in data) {\n return data as unknown as BlockKitTemplate;\n }\n\n // 3. If we have any data, auto-generate blocks from it\n if (data && Object.keys(data).length > 0) {\n const generatedBlocks = generateBlocksFromData(data);\n if (generatedBlocks.length > 0) {\n return { blocks: generatedBlocks } as BlockKitTemplate;\n }\n }\n\n // 4. If template exists but no blocks, try to bind and check again\n if (template) {\n const bound = bindDataToTemplate(template as unknown as BlockKitTemplate, data);\n if (bound?.blocks?.length) {\n return bound;\n }\n }\n\n return null;\n }, [template, data]);\n\n // Handle action clicks\n const handleAction = useCallback(\n (actionId: string, value?: string, actionData?: Record<string, unknown>) => {\n if (onAction) {\n onAction(actionId, { value, ...actionData });\n }\n },\n [onAction]\n );\n\n // Loading state\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 animate-in fade-in duration-200\">\n <div className=\"animate-pulse space-y-2 w-full\">\n <div className=\"h-4 bg-bg-sunken rounded w-3/4\" />\n <div className=\"h-4 bg-bg-sunken rounded w-1/2\" />\n <div className=\"h-4 bg-bg-sunken rounded w-5/6\" />\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-red-600 dark:text-red-400\">\n <div className=\"text-center\">\n <p className=\"font-medium\">Error rendering blocks</p>\n <p className=\"text-sm mt-1\">{error}</p>\n </div>\n </div>\n );\n }\n\n // Empty state\n if (!boundTemplate?.blocks?.length) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200\">\n <div className=\"text-center\">\n <p>No content to display</p>\n <p className=\"text-sm mt-1\">Configure blocks or provide data</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full p-4 bg-surface\">\n {/* Render blocks */}\n {boundTemplate.blocks.map((block, i) => (\n <BlockRenderer key={i} block={block} index={i} onAction={handleAction} />\n ))}\n\n {/* Render attachments */}\n {boundTemplate.attachments?.map((attachment, i) => (\n <div\n key={`attachment-${i}`}\n className=\"mt-4 border-l-4 pl-3\"\n style={{ borderLeftColor: attachment.color || 'var(--color-border)' }}\n >\n {attachment.blocks?.map((block, j) => (\n <BlockRenderer key={j} block={block} index={j} onAction={handleAction} />\n ))}\n {attachment.fallback && !attachment.blocks && <p className=\"text-sm text-secondary\">{attachment.fallback}</p>}\n </div>\n ))}\n </div>\n );\n});\n\nexport default BlockKitRenderer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BlockKitRenderer.js","names":[],"sources":["../../../../src/bigconsole/renderers/adapters/BlockKitRenderer.tsx"],"sourcesContent":["/**\n * Slack Block Kit Renderer (v2.0)\n *\n * Renders widgets using Slack Block Kit format.\n * Supports common block types: section, divider, header, context, image, actions.\n */\n\nimport React, { memo, useCallback, useMemo, type ReactNode } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { RendererProps, BlockKitTemplate, BlockKitElement, BlockKitText } from '../types/renderer';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Render Block Kit text (plain_text or mrkdwn)\n * Uses React elements instead of dangerouslySetInnerHTML for better security\n */\nfunction renderText(text: BlockKitText | string | undefined): React.ReactNode {\n if (!text) return null;\n\n if (typeof text === 'string') {\n return text;\n }\n\n if (text.type === 'mrkdwn') {\n // Parse mrkdwn and convert to React elements\n const content = text.text || '';\n\n // Parse the markdown into React elements\n const elements: React.ReactNode[] = [];\n let remaining = content;\n let key = 0;\n\n // Process text segment by segment\n while (remaining.length > 0) {\n // Try to match bold: *text*\n const boldMatch = remaining.match(/^\\*([^*]+)\\*/);\n if (boldMatch) {\n elements.push(<strong key={key++}>{boldMatch[1]}</strong>);\n remaining = remaining.slice(boldMatch[0].length);\n continue;\n }\n\n // Try to match italic: _text_\n const italicMatch = remaining.match(/^_([^_]+)_/);\n if (italicMatch) {\n elements.push(<em key={key++}>{italicMatch[1]}</em>);\n remaining = remaining.slice(italicMatch[0].length);\n continue;\n }\n\n // Try to match strike: ~text~\n const strikeMatch = remaining.match(/^~([^~]+)~/);\n if (strikeMatch) {\n elements.push(<del key={key++}>{strikeMatch[1]}</del>);\n remaining = remaining.slice(strikeMatch[0].length);\n continue;\n }\n\n // Try to match code: `text`\n const codeMatch = remaining.match(/^`([^`]+)`/);\n if (codeMatch) {\n elements.push(\n <code key={key++} className=\"bg-bg-sunken px-1 rounded text-sm\">\n {codeMatch[1]}\n </code>\n );\n remaining = remaining.slice(codeMatch[0].length);\n continue;\n }\n\n // Try to match link with text: <url|text>\n const linkTextMatch = remaining.match(/^<([^|>]+)\\|([^>]+)>/);\n if (linkTextMatch) {\n elements.push(\n <a\n key={key++}\n href={linkTextMatch[1]}\n className=\"text-blue-600 dark:text-blue-400 underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {linkTextMatch[2]}\n </a>\n );\n remaining = remaining.slice(linkTextMatch[0].length);\n continue;\n }\n\n // Try to match plain link: <url>\n const linkMatch = remaining.match(/^<([^|>]+)>/);\n if (linkMatch) {\n elements.push(\n <a\n key={key++}\n href={linkMatch[1]}\n className=\"text-blue-600 dark:text-blue-400 underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {linkMatch[1]}\n </a>\n );\n remaining = remaining.slice(linkMatch[0].length);\n continue;\n }\n\n // No special formatting found at start - extract plain text until next special char\n const plainMatch = remaining.match(/^[^*_~`<]+/);\n if (plainMatch) {\n elements.push(<React.Fragment key={key++}>{plainMatch[0]}</React.Fragment>);\n remaining = remaining.slice(plainMatch[0].length);\n continue;\n }\n\n // Single special char that didn't match a pattern - output as-is\n elements.push(<React.Fragment key={key++}>{remaining[0]}</React.Fragment>);\n remaining = remaining.slice(1);\n }\n\n return <span>{elements}</span>;\n }\n\n // Plain text with optional emoji\n return text.text;\n}\n\n/**\n * Get button style class\n */\nfunction getButtonStyleClass(style?: string): string {\n switch (style) {\n case 'primary':\n return 'bg-status-success-bg hover:bg-status-success-bg/90 text-white transition-colors';\n case 'danger':\n return 'bg-status-error-bg hover:bg-status-error-bg/90 text-white transition-colors';\n default:\n return 'bg-bg-sunken hover:bg-bg-sunken/80 text-primary transition-colors';\n }\n}\n\n// ============================================================================\n// Template Binding\n// ============================================================================\n\nfunction bindDataToTemplate<T>(template: T, data: Record<string, unknown>): T {\n if (template === null || template === undefined) {\n return template;\n }\n\n if (typeof template === 'string') {\n // Replace ${path} with actual values\n return template.replace(/\\$\\{([^}]+)\\}/g, (_, path) => {\n const value = getNestedValue(data, path.trim());\n return value !== undefined ? String(value) : '';\n }) as T;\n }\n\n if (Array.isArray(template)) {\n return template.map((item) => bindDataToTemplate(item, data)) as T;\n }\n\n if (typeof template === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(template)) {\n result[key] = bindDataToTemplate(value, data);\n }\n return result as T;\n }\n\n return template;\n}\n\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current && typeof current === 'object' && part in (current as Record<string, unknown>)) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n// ============================================================================\n// Block Renderers\n// ============================================================================\n\ninterface BlockRendererProps {\n block: BlockKitElement;\n index: number;\n onAction?: (actionId: string, value?: string, data?: Record<string, unknown>) => void;\n}\n\nconst BlockRenderer: React.FC<BlockRendererProps> = memo(function BlockRenderer({ block, index: _index, onAction }) {\n switch (block.type) {\n // Header block\n case 'header':\n return (\n <div className=\"py-2\">\n <h2 className=\"text-lg font-bold text-primary\">{renderText(block.text)}</h2>\n </div>\n );\n\n // Section block\n case 'section':\n return (\n <div className=\"py-2 flex items-start gap-4\">\n <div className=\"flex-1\">\n {block.text && <p className=\"text-primary\">{renderText(block.text)}</p>}\n {block.fields && block.fields.length > 0 && (\n <div className=\"grid grid-cols-2 gap-2 mt-2\">\n {block.fields.map((field, i) => (\n <div key={i} className=\"text-sm\">\n {renderText(field)}\n </div>\n ))}\n </div>\n )}\n </div>\n {block.accessory && (\n <div className=\"flex-shrink-0\">\n <AccessoryRenderer accessory={block.accessory as BlockKitElement} onAction={onAction} />\n </div>\n )}\n </div>\n );\n\n // Divider block\n case 'divider':\n return <hr className=\"my-2 border-default\" />;\n\n // Image block\n case 'image':\n return (\n <div className=\"py-2\">\n {block.title && <p className=\"text-sm text-secondary mb-1\">{renderText(block.title)}</p>}\n <img src={block.image_url} alt={block.alt_text || ''} className=\"max-w-full h-auto rounded\" />\n </div>\n );\n\n // Context block\n case 'context':\n return (\n <div className=\"py-1 flex items-center gap-2 flex-wrap text-sm text-secondary\">\n {block.elements?.map((element, i) => (\n <span key={i}>\n {element.type === 'image' ? (\n <img src={element.image_url} alt={element.alt_text || ''} className=\"w-5 h-5 rounded inline-block\" />\n ) : (\n renderText(element.text as BlockKitText)\n )}\n </span>\n ))}\n </div>\n );\n\n // Actions block\n case 'actions':\n return (\n <div className=\"py-2 flex gap-2 flex-wrap\">\n {block.elements?.map((element, i) => (\n <ActionRenderer key={i} element={element} onAction={onAction} />\n ))}\n </div>\n );\n\n // Input block (simplified)\n case 'input':\n return (\n <div className=\"py-2\">\n {block.label ? (\n <label className=\"block text-sm font-medium text-secondary mb-1\">\n {renderText(block.label as BlockKitText) as ReactNode}\n </label>\n ) : null}\n <input\n type=\"text\"\n className=\"w-full px-3 py-2 border border-default rounded-md bg-surface text-primary transition-colors focus:ring-2 focus:ring-primary/20\"\n placeholder={(() => {\n const element = block.element as Record<string, unknown> | undefined;\n return element?.placeholder ? (renderText(element.placeholder as BlockKitText) as string) : '';\n })()}\n />\n </div>\n );\n\n // Rich text block (simplified)\n case 'rich_text':\n return (\n <div className=\"py-2 text-primary\">\n {block.elements?.map((element, i) => (\n <span key={i}>{renderText(element.text as BlockKitText)}</span>\n ))}\n </div>\n );\n\n default:\n return null;\n }\n});\n\n// ============================================================================\n// Accessory Renderer\n// ============================================================================\n\ninterface AccessoryRendererProps {\n accessory: BlockKitElement;\n onAction?: (actionId: string, value?: string, data?: Record<string, unknown>) => void;\n}\n\nconst AccessoryRenderer: React.FC<AccessoryRendererProps> = memo(function AccessoryRenderer({ accessory, onAction }) {\n switch (accessory.type) {\n case 'image':\n return (\n <img src={accessory.image_url} alt={accessory.alt_text || ''} className=\"w-12 h-12 rounded object-cover\" />\n );\n\n case 'button':\n return (\n <button\n type=\"button\"\n onClick={() => onAction?.(accessory.action_id || '', accessory.value)}\n className={`px-3 py-1.5 text-sm font-medium rounded ${getButtonStyleClass(accessory.style)}`}\n >\n {renderText(accessory.text)}\n </button>\n );\n\n case 'overflow':\n return (\n <button type=\"button\" className=\"p-1 text-secondary hover:text-primary transition-colors\">\n <svg className=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z\" />\n </svg>\n </button>\n );\n\n default:\n return null;\n }\n});\n\n// ============================================================================\n// Action Renderer\n// ============================================================================\n\ninterface ActionRendererProps {\n element: BlockKitElement;\n onAction?: (actionId: string, value?: string, data?: Record<string, unknown>) => void;\n}\n\nconst ActionRenderer: React.FC<ActionRendererProps> = memo(function ActionRenderer({ element, onAction }) {\n const handleClick = useCallback(() => {\n if (element.action_id) {\n onAction?.(element.action_id, element.value);\n }\n if (element.url) {\n window.open(element.url, '_blank');\n }\n }, [element, onAction]);\n\n switch (element.type) {\n case 'button':\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n className={`px-4 py-2 text-sm font-medium rounded ${getButtonStyleClass(element.style)}`}\n >\n {renderText(element.text)}\n </button>\n );\n\n case 'static_select':\n return (\n <select\n className=\"px-3 py-2 text-sm border border-default rounded bg-surface text-primary transition-colors focus:ring-2 focus:ring-primary/20\"\n onChange={(e) => onAction?.(element.action_id || '', e.target.value)}\n >\n {element.placeholder ? (\n <option value=\"\">{renderText(element.placeholder as BlockKitText) as ReactNode}</option>\n ) : null}\n {(element.options as Array<{ text: BlockKitText; value: string }>)?.map((option, i) => (\n <option key={i} value={option.value}>\n {renderText(option.text)}\n </option>\n ))}\n </select>\n );\n\n case 'datepicker':\n return (\n <input\n type=\"date\"\n className=\"px-3 py-2 text-sm border border-default rounded bg-surface text-primary transition-colors focus:ring-2 focus:ring-primary/20\"\n onChange={(e) => onAction?.(element.action_id || '', e.target.value)}\n />\n );\n\n case 'checkboxes':\n return (\n <div className=\"space-y-1\">\n {(element.options as Array<{ text: BlockKitText; value: string }>)?.map((option, i) => (\n <label key={i} className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n className=\"rounded border-default transition-colors\"\n onChange={(e) => onAction?.(element.action_id || '', option.value, { checked: e.target.checked })}\n />\n {renderText(option.text)}\n </label>\n ))}\n </div>\n );\n\n case 'radio_buttons':\n return (\n <div className=\"space-y-1\">\n {(element.options as Array<{ text: BlockKitText; value: string }>)?.map((option, i) => (\n <label key={i} className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"radio\"\n name={element.action_id}\n className=\"border-default transition-colors\"\n onChange={() => onAction?.(element.action_id || '', option.value)}\n />\n {renderText(option.text)}\n </label>\n ))}\n </div>\n );\n\n default:\n return null;\n }\n});\n\n// ============================================================================\n// Auto-generate BlockKit blocks from arbitrary data\n// ============================================================================\n\nfunction generateBlocksFromData(data: Record<string, unknown>): BlockKitElement[] {\n const blocks: BlockKitElement[] = [];\n\n for (const [key, value] of Object.entries(data)) {\n if (value === null || value === undefined) continue;\n\n // Handle arrays\n if (Array.isArray(value)) {\n // Add header for the array\n blocks.push({\n type: 'header',\n text: {\n type: 'plain_text',\n text: formatKey(key),\n emoji: true,\n },\n });\n\n // Add each item\n value.forEach((item, index) => {\n if (typeof item === 'object' && item !== null) {\n // Object items - render as section with fields\n const fields: BlockKitText[] = [];\n for (const [itemKey, itemValue] of Object.entries(item)) {\n if (itemValue !== null && itemValue !== undefined) {\n fields.push({\n type: 'mrkdwn',\n text: `*${formatKey(itemKey)}:*\\n${formatValue(itemValue)}`,\n });\n }\n }\n if (fields.length > 0) {\n blocks.push({\n type: 'section',\n fields: fields.slice(0, 10), // BlockKit max 10 fields\n });\n }\n } else {\n // Primitive items - render as simple section\n blocks.push({\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `${index + 1}. ${formatValue(item)}`,\n },\n });\n }\n\n // Add divider between items (except last)\n if (index < value.length - 1) {\n blocks.push({ type: 'divider' });\n }\n });\n }\n // Handle objects\n else if (typeof value === 'object') {\n blocks.push({\n type: 'header',\n text: {\n type: 'plain_text',\n text: formatKey(key),\n emoji: true,\n },\n });\n\n const fields: BlockKitText[] = [];\n for (const [objKey, objValue] of Object.entries(value as Record<string, unknown>)) {\n if (objValue !== null && objValue !== undefined) {\n fields.push({\n type: 'mrkdwn',\n text: `*${formatKey(objKey)}:*\\n${formatValue(objValue)}`,\n });\n }\n }\n if (fields.length > 0) {\n blocks.push({\n type: 'section',\n fields: fields.slice(0, 10),\n });\n }\n }\n // Handle primitives\n else {\n blocks.push({\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `*${formatKey(key)}:* ${formatValue(value)}`,\n },\n });\n }\n }\n\n return blocks;\n}\n\nfunction formatKey(key: string): string {\n // Convert camelCase or snake_case to Title Case\n return key\n .replace(/_/g, ' ')\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (str) => str.toUpperCase())\n .trim();\n}\n\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) return '-';\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n}\n\n// ============================================================================\n// Main Renderer Component\n// ============================================================================\n\nexport const BlockKitRenderer: React.FC<RendererProps> = memo(function BlockKitRenderer({\n widget,\n data,\n template,\n isLoading,\n error,\n onDrilldown: _onDrilldown,\n onAction,\n}) {\n const { t } = useI18n();\n\n // Debug logging\n\n // Parse and bind template\n const boundTemplate = useMemo(() => {\n // 1. If template has blocks, bind data and use it\n if (template && 'blocks' in (template as Record<string, unknown>)) {\n return bindDataToTemplate(template as unknown as BlockKitTemplate, data);\n }\n\n // 2. If data has blocks, use it directly as BlockKit format\n if (data && 'blocks' in data) {\n return data as unknown as BlockKitTemplate;\n }\n\n // 3. If we have any data, auto-generate blocks from it\n if (data && Object.keys(data).length > 0) {\n const generatedBlocks = generateBlocksFromData(data);\n if (generatedBlocks.length > 0) {\n return { blocks: generatedBlocks } as BlockKitTemplate;\n }\n }\n\n // 4. If template exists but no blocks, try to bind and check again\n if (template) {\n const bound = bindDataToTemplate(template as unknown as BlockKitTemplate, data);\n if (bound?.blocks?.length) {\n return bound;\n }\n }\n\n return null;\n }, [template, data]);\n\n // Handle action clicks\n const handleAction = useCallback(\n (actionId: string, value?: string, actionData?: Record<string, unknown>) => {\n if (onAction) {\n onAction(actionId, { value, ...actionData });\n }\n },\n [onAction]\n );\n\n // Loading state\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 animate-in fade-in duration-200\">\n <div className=\"animate-pulse space-y-2 w-full\">\n <div className=\"h-4 bg-bg-sunken rounded w-3/4\" />\n <div className=\"h-4 bg-bg-sunken rounded w-1/2\" />\n <div className=\"h-4 bg-bg-sunken rounded w-5/6\" />\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-red-600 dark:text-red-400\">\n <div className=\"text-center\">\n <p className=\"font-medium\">\n {t('bigconsole.widget.renderer.blockKit.errorRendering', 'Error rendering blocks')}\n </p>\n <p className=\"text-sm mt-1\">{error}</p>\n </div>\n </div>\n );\n }\n\n // Empty state\n if (!boundTemplate?.blocks?.length) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200\">\n <div className=\"text-center\">\n <p>{t('bigconsole.widget.renderer.blockKit.noContent', 'No content to display')}</p>\n <p className=\"text-sm mt-1\">\n {t('bigconsole.widget.renderer.blockKit.configureBlocks', 'Configure blocks or provide data')}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full p-4 bg-surface\">\n {/* Render blocks */}\n {boundTemplate.blocks.map((block, i) => (\n <BlockRenderer key={i} block={block} index={i} onAction={handleAction} />\n ))}\n\n {/* Render attachments */}\n {boundTemplate.attachments?.map((attachment, i) => (\n <div\n key={`attachment-${i}`}\n className=\"mt-4 border-l-4 pl-3\"\n style={{ borderLeftColor: attachment.color || 'var(--color-border)' }}\n >\n {attachment.blocks?.map((block, j) => (\n <BlockRenderer key={j} block={block} index={j} onAction={handleAction} />\n ))}\n {attachment.fallback && !attachment.blocks && <p className=\"text-sm text-secondary\">{attachment.fallback}</p>}\n </div>\n ))}\n </div>\n );\n});\n\nexport default BlockKitRenderer;\n"],"mappings":"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"}
@@ -1,172 +1,172 @@
1
1
  import { memo as e, useMemo as t } from "react";
2
- import { jsx as n, jsxs as r } from "react/jsx-runtime";
2
+ import { useI18n as n } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
3
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
3
4
  //#region src/bigconsole/renderers/adapters/CustomRenderer.tsx
4
- var i = /* @__PURE__ */ new Map();
5
- function a(e, t) {
6
- i.set(e, t);
5
+ var a = /* @__PURE__ */ new Map();
6
+ function o(e, t) {
7
+ a.set(e, t);
7
8
  }
8
- function o(e) {
9
- return i.get(e);
9
+ function s(e) {
10
+ return a.get(e);
10
11
  }
11
- function s() {
12
- return Array.from(i.keys());
12
+ function c() {
13
+ return Array.from(a.keys());
13
14
  }
14
- a("SimpleText", ({ data: e, props: t }) => {
15
- let r = e.text || t?.text, i = t?.align || "left";
16
- return r ? /* @__PURE__ */ n("div", {
17
- className: `p-4 text-${i}`,
18
- children: /* @__PURE__ */ n("p", {
15
+ o("SimpleText", ({ data: e, props: t }) => {
16
+ let { t: i } = n(), a = e.text || t?.text, o = t?.align || "left";
17
+ return a ? /* @__PURE__ */ r("div", {
18
+ className: `p-4 text-${o}`,
19
+ children: /* @__PURE__ */ r("p", {
19
20
  className: "text-primary",
20
- children: r
21
+ children: a
21
22
  })
22
- }) : /* @__PURE__ */ n("div", {
23
+ }) : /* @__PURE__ */ r("div", {
23
24
  className: "flex items-center justify-center h-full p-4 text-secondary",
24
- children: /* @__PURE__ */ n("p", {
25
+ children: /* @__PURE__ */ r("p", {
25
26
  className: "text-sm",
26
- children: "No data available"
27
+ children: i("bigconsole.widget.renderer.custom.noData", "No data available")
27
28
  })
28
29
  });
29
- }), a("Counter", ({ data: e, props: t }) => {
30
- let i = e.value ?? t?.value, a = e.label || t?.label, o = t?.format || "number";
31
- if (i == null) return /* @__PURE__ */ n("div", {
30
+ }), o("Counter", ({ data: e, props: t }) => {
31
+ let { t: a } = n(), o = e.value ?? t?.value, s = e.label || t?.label, c = t?.format || "number";
32
+ if (o == null) return /* @__PURE__ */ r("div", {
32
33
  className: "flex flex-col items-center justify-center h-full p-4 text-secondary",
33
- children: /* @__PURE__ */ n("p", {
34
+ children: /* @__PURE__ */ r("p", {
34
35
  className: "text-sm",
35
- children: "No data available"
36
+ children: a("bigconsole.widget.renderer.custom.noData", "No data available")
36
37
  })
37
38
  });
38
- let s = i;
39
- return /* @__PURE__ */ r("div", {
39
+ let l = o;
40
+ return /* @__PURE__ */ i("div", {
40
41
  className: "flex flex-col items-center justify-center h-full p-4 animate-in fade-in duration-200",
41
- children: [/* @__PURE__ */ n("span", {
42
+ children: [/* @__PURE__ */ r("span", {
42
43
  className: "text-3xl font-bold text-primary",
43
- children: o === "currency" ? new Intl.NumberFormat("en-US", {
44
+ children: c === "currency" ? new Intl.NumberFormat("en-US", {
44
45
  style: "currency",
45
46
  currency: "USD"
46
- }).format(s) : o === "percent" ? `${(s * 100).toFixed(1)}%` : new Intl.NumberFormat().format(s)
47
- }), a && /* @__PURE__ */ n("span", {
47
+ }).format(l) : c === "percent" ? `${(l * 100).toFixed(1)}%` : new Intl.NumberFormat().format(l)
48
+ }), s && /* @__PURE__ */ r("span", {
48
49
  className: "text-sm text-secondary mt-1",
49
- children: a
50
+ children: s
50
51
  })]
51
52
  });
52
- }), a("Card", ({ data: e, props: t, onAction: i }) => {
53
- let a = e.title || t?.title, o = e.description || t?.description || "";
54
- if (!a && !o) return /* @__PURE__ */ n("div", {
53
+ }), o("Card", ({ data: e, props: t, onAction: a }) => {
54
+ let { t: o } = n(), s = e.title || t?.title, c = e.description || t?.description || "";
55
+ if (!s && !c) return /* @__PURE__ */ r("div", {
55
56
  className: "flex items-center justify-center h-full p-4 text-secondary",
56
- children: /* @__PURE__ */ n("p", {
57
+ children: /* @__PURE__ */ r("p", {
57
58
  className: "text-sm",
58
- children: "No data available"
59
+ children: o("bigconsole.widget.renderer.custom.noData", "No data available")
59
60
  })
60
61
  });
61
- let s = e.image || t?.image, c = t?.actionLabel || "View Details", l = t?.showAction !== !1;
62
- return /* @__PURE__ */ r("div", {
62
+ let l = e.image || t?.image, u = t?.actionLabel || o("bigconsole.widget.renderer.custom.viewDetails", "View Details"), d = t?.showAction !== !1;
63
+ return /* @__PURE__ */ i("div", {
63
64
  className: "flex flex-col h-full bg-surface rounded-lg overflow-hidden animate-in fade-in duration-200",
64
65
  children: [
65
- s && /* @__PURE__ */ n("div", {
66
+ l && /* @__PURE__ */ r("div", {
66
67
  className: "aspect-video bg-bg-sunken",
67
- children: /* @__PURE__ */ n("img", {
68
- src: s,
68
+ children: /* @__PURE__ */ r("img", {
69
+ src: l,
69
70
  alt: "",
70
71
  className: "w-full h-full object-cover"
71
72
  })
72
73
  }),
73
- /* @__PURE__ */ r("div", {
74
+ /* @__PURE__ */ i("div", {
74
75
  className: "flex-1 p-4",
75
- children: [a && /* @__PURE__ */ n("h3", {
76
+ children: [s && /* @__PURE__ */ r("h3", {
76
77
  className: "text-lg font-semibold text-primary",
77
- children: a
78
- }), o && /* @__PURE__ */ n("p", {
78
+ children: s
79
+ }), c && /* @__PURE__ */ r("p", {
79
80
  className: "text-sm text-secondary mt-1",
80
- children: o
81
+ children: c
81
82
  })]
82
83
  }),
83
- l && /* @__PURE__ */ n("div", {
84
+ d && /* @__PURE__ */ r("div", {
84
85
  className: "p-4 pt-0",
85
- children: /* @__PURE__ */ n("button", {
86
+ children: /* @__PURE__ */ r("button", {
86
87
  type: "button",
87
- onClick: () => i?.("click", { title: a }),
88
+ onClick: () => a?.("click", { title: s }),
88
89
  className: "w-full px-4 py-2 text-sm font-medium text-white bg-action-primary hover:bg-action-primary/90 rounded-md transition-colors",
89
- children: c
90
+ children: u
90
91
  })
91
92
  })
92
93
  ]
93
94
  });
94
95
  });
95
- var c = ({ componentName: e }) => /* @__PURE__ */ n("div", {
96
- className: "flex flex-col items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200",
97
- children: /* @__PURE__ */ r("div", {
98
- className: "text-center",
99
- children: [
100
- /* @__PURE__ */ n("p", {
101
- className: "font-medium",
102
- children: "Component Not Found"
103
- }),
104
- /* @__PURE__ */ r("p", {
105
- className: "text-sm mt-1",
106
- children: [
107
- "Component \"",
108
- e,
109
- "\" is not registered"
110
- ]
111
- }),
112
- /* @__PURE__ */ r("div", {
113
- className: "mt-4 text-xs",
114
- children: [/* @__PURE__ */ n("p", { children: "Available components:" }), /* @__PURE__ */ n("ul", {
115
- className: "mt-1",
116
- children: s().map((e) => /* @__PURE__ */ n("li", {
117
- className: "text-link",
118
- children: e
119
- }, e))
120
- })]
121
- })
122
- ]
123
- })
124
- }), l = e(function({ widget: e, data: i, template: a, isLoading: s, error: l, onDrilldown: u, onAction: d }) {
125
- let f = t(() => {
126
- if (a && typeof a == "object" && "componentName" in a) return a.componentName;
96
+ var l = ({ componentName: e }) => {
97
+ let { t } = n();
98
+ return /* @__PURE__ */ r("div", {
99
+ className: "flex flex-col items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200",
100
+ children: /* @__PURE__ */ i("div", {
101
+ className: "text-center",
102
+ children: [
103
+ /* @__PURE__ */ r("p", {
104
+ className: "font-medium",
105
+ children: t("bigconsole.widget.renderer.custom.componentNotFound", "Component Not Found")
106
+ }),
107
+ /* @__PURE__ */ r("p", {
108
+ className: "text-sm mt-1",
109
+ children: t("bigconsole.widget.renderer.custom.componentNotRegistered", "Component \"{{name}}\" is not registered", { name: e ?? "" })
110
+ }),
111
+ /* @__PURE__ */ i("div", {
112
+ className: "mt-4 text-xs",
113
+ children: [/* @__PURE__ */ r("p", { children: t("bigconsole.widget.renderer.custom.availableComponents", "Available components:") }), /* @__PURE__ */ r("ul", {
114
+ className: "mt-1",
115
+ children: c().map((e) => /* @__PURE__ */ r("li", {
116
+ className: "text-link",
117
+ children: e
118
+ }, e))
119
+ })]
120
+ })
121
+ ]
122
+ })
123
+ });
124
+ }, u = e(function({ widget: e, data: a, template: o, isLoading: c, error: u, onDrilldown: d, onAction: f }) {
125
+ let { t: p } = n(), m = t(() => {
126
+ if (o && typeof o == "object" && "componentName" in o) return o.componentName;
127
127
  let t = e.config;
128
128
  return t?.componentName || t?.componentId || "";
129
- }, [a, e.config]), p = t(() => a && typeof a == "object" && "props" in a ? a.props : {}, [a]), m = t(() => f ? o(f) : null, [f]);
130
- return s ? /* @__PURE__ */ n("div", {
129
+ }, [o, e.config]), h = t(() => o && typeof o == "object" && "props" in o ? o.props : {}, [o]), g = t(() => m ? s(m) : null, [m]);
130
+ return c ? /* @__PURE__ */ r("div", {
131
131
  className: "flex items-center justify-center h-full p-4 animate-in fade-in duration-200",
132
- children: /* @__PURE__ */ r("div", {
132
+ children: /* @__PURE__ */ i("div", {
133
133
  className: "animate-pulse space-y-2 w-full",
134
- children: [/* @__PURE__ */ n("div", { className: "h-4 bg-bg-sunken rounded w-3/4" }), /* @__PURE__ */ n("div", { className: "h-4 bg-bg-sunken rounded w-1/2" })]
134
+ children: [/* @__PURE__ */ r("div", { className: "h-4 bg-bg-sunken rounded w-3/4" }), /* @__PURE__ */ r("div", { className: "h-4 bg-bg-sunken rounded w-1/2" })]
135
135
  })
136
- }) : l ? /* @__PURE__ */ n("div", {
136
+ }) : u ? /* @__PURE__ */ r("div", {
137
137
  className: "flex items-center justify-center h-full p-4 text-red-600 dark:text-red-400",
138
- children: /* @__PURE__ */ r("div", {
138
+ children: /* @__PURE__ */ i("div", {
139
139
  className: "text-center",
140
- children: [/* @__PURE__ */ n("p", {
140
+ children: [/* @__PURE__ */ r("p", {
141
141
  className: "font-medium",
142
- children: "Error rendering component"
143
- }), /* @__PURE__ */ n("p", {
142
+ children: p("bigconsole.widget.renderer.custom.errorRendering", "Error rendering component")
143
+ }), /* @__PURE__ */ r("p", {
144
144
  className: "text-sm mt-1",
145
- children: l
145
+ children: u
146
146
  })]
147
147
  })
148
- }) : f ? m ? /* @__PURE__ */ n(m, {
148
+ }) : m ? g ? /* @__PURE__ */ r(g, {
149
149
  widget: e,
150
- data: i,
151
- template: a,
152
- props: p,
153
- onAction: d,
154
- onDrilldown: u
155
- }) : /* @__PURE__ */ n(c, { componentName: f }) : /* @__PURE__ */ n("div", {
150
+ data: a,
151
+ template: o,
152
+ props: h,
153
+ onAction: f,
154
+ onDrilldown: d
155
+ }) : /* @__PURE__ */ r(l, { componentName: m }) : /* @__PURE__ */ r("div", {
156
156
  className: "flex items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200",
157
- children: /* @__PURE__ */ r("div", {
157
+ children: /* @__PURE__ */ i("div", {
158
158
  className: "text-center",
159
- children: [/* @__PURE__ */ n("p", {
159
+ children: [/* @__PURE__ */ r("p", {
160
160
  className: "font-medium",
161
- children: "No Component Specified"
162
- }), /* @__PURE__ */ n("p", {
161
+ children: p("bigconsole.widget.renderer.custom.noComponentSpecified", "No Component Specified")
162
+ }), /* @__PURE__ */ r("p", {
163
163
  className: "text-sm mt-1",
164
- children: "Set componentName in template or widget config"
164
+ children: p("bigconsole.widget.renderer.custom.setComponentName", "Set componentName in template or widget config")
165
165
  })]
166
166
  })
167
167
  });
168
168
  });
169
169
  //#endregion
170
- export { l as default };
170
+ export { u as default };
171
171
 
172
172
  //# sourceMappingURL=CustomRenderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CustomRenderer.js","names":[],"sources":["../../../../src/bigconsole/renderers/adapters/CustomRenderer.tsx"],"sourcesContent":["/**\n * Custom Renderer (v2.0)\n *\n * Renders widgets using custom React components registered by the application.\n * Supports dynamic component resolution and prop mapping.\n */\n\nimport React, { memo, useMemo, type ComponentType } from 'react';\nimport type { RendererProps } from '../types/renderer';\n\n// ============================================================================\n// Custom Component Registry\n// ============================================================================\n\n// Registry of custom components\nconst customComponentRegistry = new Map<string, ComponentType<CustomComponentProps>>();\n\nexport interface CustomComponentProps {\n widget: RendererProps['widget'];\n data: Record<string, unknown>;\n template?: Record<string, unknown> | null;\n props?: Record<string, unknown>;\n onAction?: (actionName: string, payload: Record<string, unknown>) => void;\n onDrilldown?: (params: Record<string, unknown>) => void;\n}\n\n/**\n * Register a custom component\n */\nexport function registerCustomComponent(name: string, component: ComponentType<CustomComponentProps>): void {\n customComponentRegistry.set(name, component);\n}\n\n/**\n * Unregister a custom component\n */\nexport function unregisterCustomComponent(name: string): boolean {\n return customComponentRegistry.delete(name);\n}\n\n/**\n * Check if a custom component is registered\n */\nexport function hasCustomComponent(name: string): boolean {\n return customComponentRegistry.has(name);\n}\n\n/**\n * Get a registered custom component\n */\nexport function getCustomComponent(name: string): ComponentType<CustomComponentProps> | undefined {\n return customComponentRegistry.get(name);\n}\n\n/**\n * Get all registered component names\n */\nexport function getRegisteredComponentNames(): string[] {\n return Array.from(customComponentRegistry.keys());\n}\n\n// ============================================================================\n// Default Custom Components\n// ============================================================================\n\n/**\n * Simple Text Display Component\n */\nexport const SimpleTextComponent: React.FC<CustomComponentProps> = ({ data, props }) => {\n const text = (data.text || props?.text) as string | undefined;\n const align = (props?.align || 'left') as string;\n\n if (!text) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-secondary\">\n <p className=\"text-sm\">No data available</p>\n </div>\n );\n }\n\n return (\n <div className={`p-4 text-${align}`}>\n <p className=\"text-primary\">{text}</p>\n </div>\n );\n};\n\n/**\n * Simple Counter Component\n */\nexport const CounterComponent: React.FC<CustomComponentProps> = ({ data, props }) => {\n const rawValue = data.value ?? props?.value;\n const label = (data.label || props?.label) as string | undefined;\n const format = (props?.format || 'number') as string;\n\n if (rawValue === undefined || rawValue === null) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-4 text-secondary\">\n <p className=\"text-sm\">No data available</p>\n </div>\n );\n }\n\n const value = rawValue as number;\n\n const formattedValue =\n format === 'currency'\n ? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value)\n : format === 'percent'\n ? `${(value * 100).toFixed(1)}%`\n : new Intl.NumberFormat().format(value);\n\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-4 animate-in fade-in duration-200\">\n <span className=\"text-3xl font-bold text-primary\">{formattedValue}</span>\n {label && <span className=\"text-sm text-secondary mt-1\">{label}</span>}\n </div>\n );\n};\n\n/**\n * Simple Card Component\n */\nexport const CardComponent: React.FC<CustomComponentProps> = ({ data, props, onAction }) => {\n const title = (data.title || props?.title) as string | undefined;\n const description = (data.description || props?.description || '') as string;\n\n if (!title && !description) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-secondary\">\n <p className=\"text-sm\">No data available</p>\n </div>\n );\n }\n const image = (data.image || props?.image) as string | undefined;\n const actionLabel = (props?.actionLabel || 'View Details') as string;\n const showAction = props?.showAction !== false;\n\n return (\n <div className=\"flex flex-col h-full bg-surface rounded-lg overflow-hidden animate-in fade-in duration-200\">\n {image && (\n <div className=\"aspect-video bg-bg-sunken\">\n <img src={image} alt=\"\" className=\"w-full h-full object-cover\" />\n </div>\n )}\n <div className=\"flex-1 p-4\">\n {title && <h3 className=\"text-lg font-semibold text-primary\">{title}</h3>}\n {description && <p className=\"text-sm text-secondary mt-1\">{description}</p>}\n </div>\n {showAction && (\n <div className=\"p-4 pt-0\">\n <button\n type=\"button\"\n onClick={() => onAction?.('click', { title })}\n className=\"w-full px-4 py-2 text-sm font-medium text-white bg-action-primary hover:bg-action-primary/90 rounded-md transition-colors\"\n >\n {actionLabel}\n </button>\n </div>\n )}\n </div>\n );\n};\n\n// Register default components\nregisterCustomComponent('SimpleText', SimpleTextComponent);\nregisterCustomComponent('Counter', CounterComponent);\nregisterCustomComponent('Card', CardComponent);\n\n// ============================================================================\n// Fallback Component\n// ============================================================================\n\nconst FallbackComponent: React.FC<{ componentName: string }> = ({ componentName }) => (\n <div className=\"flex flex-col items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200\">\n <div className=\"text-center\">\n <p className=\"font-medium\">Component Not Found</p>\n <p className=\"text-sm mt-1\">Component &quot;{componentName}&quot; is not registered</p>\n <div className=\"mt-4 text-xs\">\n <p>Available components:</p>\n <ul className=\"mt-1\">\n {getRegisteredComponentNames().map((name) => (\n <li key={name} className=\"text-link\">\n {name}\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n);\n\n// ============================================================================\n// Main Renderer Component\n// ============================================================================\n\nexport const CustomRenderer: React.FC<RendererProps> = memo(function CustomRenderer({\n widget,\n data,\n template,\n isLoading,\n error,\n onDrilldown,\n onAction,\n}) {\n // Get component name from template\n const componentName = useMemo(() => {\n if (template && typeof template === 'object' && 'componentName' in template) {\n return template.componentName as string;\n }\n // Fallback to widget config\n const config = widget.config as Record<string, unknown>;\n return (config?.componentName || config?.componentId || '') as string;\n }, [template, widget.config]);\n\n // Get additional props from template\n const componentProps = useMemo(() => {\n if (template && typeof template === 'object' && 'props' in template) {\n return template.props as Record<string, unknown>;\n }\n return {};\n }, [template]);\n\n // Get the component\n const Component = useMemo(() => {\n if (!componentName) return null;\n return getCustomComponent(componentName);\n }, [componentName]);\n\n // Loading state\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 animate-in fade-in duration-200\">\n <div className=\"animate-pulse space-y-2 w-full\">\n <div className=\"h-4 bg-bg-sunken rounded w-3/4\" />\n <div className=\"h-4 bg-bg-sunken rounded w-1/2\" />\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-red-600 dark:text-red-400\">\n <div className=\"text-center\">\n <p className=\"font-medium\">Error rendering component</p>\n <p className=\"text-sm mt-1\">{error}</p>\n </div>\n </div>\n );\n }\n\n // No component name\n if (!componentName) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200\">\n <div className=\"text-center\">\n <p className=\"font-medium\">No Component Specified</p>\n <p className=\"text-sm mt-1\">Set componentName in template or widget config</p>\n </div>\n </div>\n );\n }\n\n // Component not found\n if (!Component) {\n return <FallbackComponent componentName={componentName} />;\n }\n\n // Render the custom component\n return (\n <Component\n widget={widget}\n data={data}\n template={template}\n props={componentProps}\n onAction={onAction}\n onDrilldown={onDrilldown}\n />\n );\n});\n\nexport default CustomRenderer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CustomRenderer.js","names":[],"sources":["../../../../src/bigconsole/renderers/adapters/CustomRenderer.tsx"],"sourcesContent":["/**\n * Custom Renderer (v2.0)\n *\n * Renders widgets using custom React components registered by the application.\n * Supports dynamic component resolution and prop mapping.\n */\n\nimport React, { memo, useMemo, type ComponentType } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { RendererProps } from '../types/renderer';\n\n// ============================================================================\n// Custom Component Registry\n// ============================================================================\n\n// Registry of custom components\nconst customComponentRegistry = new Map<string, ComponentType<CustomComponentProps>>();\n\nexport interface CustomComponentProps {\n widget: RendererProps['widget'];\n data: Record<string, unknown>;\n template?: Record<string, unknown> | null;\n props?: Record<string, unknown>;\n onAction?: (actionName: string, payload: Record<string, unknown>) => void;\n onDrilldown?: (params: Record<string, unknown>) => void;\n}\n\n/**\n * Register a custom component\n */\nexport function registerCustomComponent(name: string, component: ComponentType<CustomComponentProps>): void {\n customComponentRegistry.set(name, component);\n}\n\n/**\n * Unregister a custom component\n */\nexport function unregisterCustomComponent(name: string): boolean {\n return customComponentRegistry.delete(name);\n}\n\n/**\n * Check if a custom component is registered\n */\nexport function hasCustomComponent(name: string): boolean {\n return customComponentRegistry.has(name);\n}\n\n/**\n * Get a registered custom component\n */\nexport function getCustomComponent(name: string): ComponentType<CustomComponentProps> | undefined {\n return customComponentRegistry.get(name);\n}\n\n/**\n * Get all registered component names\n */\nexport function getRegisteredComponentNames(): string[] {\n return Array.from(customComponentRegistry.keys());\n}\n\n// ============================================================================\n// Default Custom Components\n// ============================================================================\n\n/**\n * Simple Text Display Component\n */\nexport const SimpleTextComponent: React.FC<CustomComponentProps> = ({ data, props }) => {\n const { t } = useI18n();\n const text = (data.text || props?.text) as string | undefined;\n const align = (props?.align || 'left') as string;\n\n if (!text) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-secondary\">\n <p className=\"text-sm\">{t('bigconsole.widget.renderer.custom.noData', 'No data available')}</p>\n </div>\n );\n }\n\n return (\n <div className={`p-4 text-${align}`}>\n <p className=\"text-primary\">{text}</p>\n </div>\n );\n};\n\n/**\n * Simple Counter Component\n */\nexport const CounterComponent: React.FC<CustomComponentProps> = ({ data, props }) => {\n const { t } = useI18n();\n const rawValue = data.value ?? props?.value;\n const label = (data.label || props?.label) as string | undefined;\n const format = (props?.format || 'number') as string;\n\n if (rawValue === undefined || rawValue === null) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-4 text-secondary\">\n <p className=\"text-sm\">{t('bigconsole.widget.renderer.custom.noData', 'No data available')}</p>\n </div>\n );\n }\n\n const value = rawValue as number;\n\n const formattedValue =\n format === 'currency'\n ? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value)\n : format === 'percent'\n ? `${(value * 100).toFixed(1)}%`\n : new Intl.NumberFormat().format(value);\n\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-4 animate-in fade-in duration-200\">\n <span className=\"text-3xl font-bold text-primary\">{formattedValue}</span>\n {label && <span className=\"text-sm text-secondary mt-1\">{label}</span>}\n </div>\n );\n};\n\n/**\n * Simple Card Component\n */\nexport const CardComponent: React.FC<CustomComponentProps> = ({ data, props, onAction }) => {\n const { t } = useI18n();\n const title = (data.title || props?.title) as string | undefined;\n const description = (data.description || props?.description || '') as string;\n\n if (!title && !description) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-secondary\">\n <p className=\"text-sm\">{t('bigconsole.widget.renderer.custom.noData', 'No data available')}</p>\n </div>\n );\n }\n const image = (data.image || props?.image) as string | undefined;\n const actionLabel = (props?.actionLabel ||\n t('bigconsole.widget.renderer.custom.viewDetails', 'View Details')) as string;\n const showAction = props?.showAction !== false;\n\n return (\n <div className=\"flex flex-col h-full bg-surface rounded-lg overflow-hidden animate-in fade-in duration-200\">\n {image && (\n <div className=\"aspect-video bg-bg-sunken\">\n <img src={image} alt=\"\" className=\"w-full h-full object-cover\" />\n </div>\n )}\n <div className=\"flex-1 p-4\">\n {title && <h3 className=\"text-lg font-semibold text-primary\">{title}</h3>}\n {description && <p className=\"text-sm text-secondary mt-1\">{description}</p>}\n </div>\n {showAction && (\n <div className=\"p-4 pt-0\">\n <button\n type=\"button\"\n onClick={() => onAction?.('click', { title })}\n className=\"w-full px-4 py-2 text-sm font-medium text-white bg-action-primary hover:bg-action-primary/90 rounded-md transition-colors\"\n >\n {actionLabel}\n </button>\n </div>\n )}\n </div>\n );\n};\n\n// Register default components\nregisterCustomComponent('SimpleText', SimpleTextComponent);\nregisterCustomComponent('Counter', CounterComponent);\nregisterCustomComponent('Card', CardComponent);\n\n// ============================================================================\n// Fallback Component\n// ============================================================================\n\nconst FallbackComponent: React.FC<{ componentName: string }> = ({ componentName }) => {\n const { t } = useI18n();\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200\">\n <div className=\"text-center\">\n <p className=\"font-medium\">{t('bigconsole.widget.renderer.custom.componentNotFound', 'Component Not Found')}</p>\n <p className=\"text-sm mt-1\">\n {t('bigconsole.widget.renderer.custom.componentNotRegistered', 'Component \"{{name}}\" is not registered', {\n name: componentName ?? '',\n })}\n </p>\n <div className=\"mt-4 text-xs\">\n <p>{t('bigconsole.widget.renderer.custom.availableComponents', 'Available components:')}</p>\n <ul className=\"mt-1\">\n {getRegisteredComponentNames().map((name) => (\n <li key={name} className=\"text-link\">\n {name}\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n );\n};\n\n// ============================================================================\n// Main Renderer Component\n// ============================================================================\n\nexport const CustomRenderer: React.FC<RendererProps> = memo(function CustomRenderer({\n widget,\n data,\n template,\n isLoading,\n error,\n onDrilldown,\n onAction,\n}) {\n const { t } = useI18n();\n\n // Get component name from template\n const componentName = useMemo(() => {\n if (template && typeof template === 'object' && 'componentName' in template) {\n return template.componentName as string;\n }\n // Fallback to widget config\n const config = widget.config as Record<string, unknown>;\n return (config?.componentName || config?.componentId || '') as string;\n }, [template, widget.config]);\n\n // Get additional props from template\n const componentProps = useMemo(() => {\n if (template && typeof template === 'object' && 'props' in template) {\n return template.props as Record<string, unknown>;\n }\n return {};\n }, [template]);\n\n // Get the component\n const Component = useMemo(() => {\n if (!componentName) return null;\n return getCustomComponent(componentName);\n }, [componentName]);\n\n // Loading state\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 animate-in fade-in duration-200\">\n <div className=\"animate-pulse space-y-2 w-full\">\n <div className=\"h-4 bg-bg-sunken rounded w-3/4\" />\n <div className=\"h-4 bg-bg-sunken rounded w-1/2\" />\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-red-600 dark:text-red-400\">\n <div className=\"text-center\">\n <p className=\"font-medium\">\n {t('bigconsole.widget.renderer.custom.errorRendering', 'Error rendering component')}\n </p>\n <p className=\"text-sm mt-1\">{error}</p>\n </div>\n </div>\n );\n }\n\n // No component name\n if (!componentName) {\n return (\n <div className=\"flex items-center justify-center h-full p-4 text-secondary animate-in fade-in duration-200\">\n <div className=\"text-center\">\n <p className=\"font-medium\">\n {t('bigconsole.widget.renderer.custom.noComponentSpecified', 'No Component Specified')}\n </p>\n <p className=\"text-sm mt-1\">\n {t('bigconsole.widget.renderer.custom.setComponentName', 'Set componentName in template or widget config')}\n </p>\n </div>\n </div>\n );\n }\n\n // Component not found\n if (!Component) {\n return <FallbackComponent componentName={componentName} />;\n }\n\n // Render the custom component\n return (\n <Component\n widget={widget}\n data={data}\n template={template}\n props={componentProps}\n onAction={onAction}\n onDrilldown={onDrilldown}\n />\n );\n});\n\nexport default CustomRenderer;\n"],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ //#region src/constants/permissions.ts
2
+ var e = {
3
+ DASHBOARD_READ: "bigconsole-dashboard:read",
4
+ DASHBOARD_CREATE: "bigconsole-dashboard:create",
5
+ DASHBOARD_UPDATE: "bigconsole-dashboard:update",
6
+ DASHBOARD_DELETE: "bigconsole-dashboard:delete",
7
+ DASHBOARD_EXPORT: "bigconsole-dashboard:export",
8
+ DASHBOARD_IMPORT: "bigconsole-dashboard:import",
9
+ DASHBOARD_PUBLISH: "bigconsole-dashboard:publish",
10
+ DASHBOARD_SHARE: "bigconsole-dashboard:share",
11
+ DASHBOARD_MANAGE_EMBED: "bigconsole-dashboard:manage_embed",
12
+ DASHBOARD_PAGE_CREATE: "bigconsole-dashboard-page:create",
13
+ DASHBOARD_PAGE_UPDATE: "bigconsole-dashboard-page:update",
14
+ DASHBOARD_PAGE_DELETE: "bigconsole-dashboard-page:delete",
15
+ FILTER_CREATE: "bigconsole-filter:create",
16
+ FILTER_UPDATE: "bigconsole-filter:update",
17
+ FILTER_DELETE: "bigconsole-filter:delete",
18
+ FILTER_PRESET_READ: "bigconsole-filter-preset:read",
19
+ FILTER_PRESET_CREATE: "bigconsole-filter-preset:create",
20
+ FILTER_PRESET_UPDATE: "bigconsole-filter-preset:update",
21
+ FILTER_PRESET_DELETE: "bigconsole-filter-preset:delete",
22
+ RLS_POLICY_READ: "bigconsole-rls-policy:read",
23
+ RLS_POLICY_CREATE: "bigconsole-rls-policy:create",
24
+ RLS_POLICY_UPDATE: "bigconsole-rls-policy:update",
25
+ RLS_POLICY_DELETE: "bigconsole-rls-policy:delete",
26
+ SHARE_READ: "bigconsole-share:read",
27
+ TEMPLATE_READ: "bigconsole-template:read",
28
+ TEMPLATE_CREATE: "bigconsole-template:create",
29
+ TEMPLATE_UPDATE: "bigconsole-template:update",
30
+ TEMPLATE_DELETE: "bigconsole-template:delete",
31
+ TEMPLATE_PUBLISH: "bigconsole-template:publish",
32
+ VIEW_READ: "bigconsole-view:read",
33
+ VIEW_CREATE: "bigconsole-view:create",
34
+ VIEW_UPDATE: "bigconsole-view:update",
35
+ VIEW_DELETE: "bigconsole-view:delete",
36
+ DATASINK_READ: "bigconsole-datasink:read",
37
+ DATASINK_CREATE: "bigconsole-datasink:create",
38
+ DATASINK_UPDATE: "bigconsole-datasink:update",
39
+ DATASINK_DELETE: "bigconsole-datasink:delete",
40
+ DATASINK_EXECUTE: "bigconsole-datasink:execute",
41
+ DATASINK_MANAGE: "bigconsole-datasink:manage",
42
+ PARSER_READ: "bigconsole-parser:read",
43
+ PARSER_CREATE: "bigconsole-parser:create",
44
+ PARSER_UPDATE: "bigconsole-parser:update",
45
+ PARSER_DELETE: "bigconsole-parser:delete",
46
+ PARSER_EXECUTE: "bigconsole-parser:execute",
47
+ PARSER_TEST: "bigconsole-parser:test",
48
+ PIPELINE_READ: "bigconsole-pipeline:read",
49
+ PIPELINE_CREATE: "bigconsole-pipeline:create",
50
+ PIPELINE_UPDATE: "bigconsole-pipeline:update",
51
+ PIPELINE_DELETE: "bigconsole-pipeline:delete",
52
+ PIPELINE_EXECUTE: "bigconsole-pipeline:execute",
53
+ PIPELINE_TEST: "bigconsole-pipeline:test",
54
+ PROMPT_READ: "bigconsole-prompt:read",
55
+ PROMPT_CREATE: "bigconsole-prompt:create",
56
+ PROMPT_UPDATE: "bigconsole-prompt:update",
57
+ PROMPT_DELETE: "bigconsole-prompt:delete",
58
+ WORKFLOW_READ: "bigconsole-workflow:read",
59
+ WORKFLOW_CREATE: "bigconsole-workflow:create",
60
+ WORKFLOW_UPDATE: "bigconsole-workflow:update",
61
+ WORKFLOW_DELETE: "bigconsole-workflow:delete",
62
+ WORKFLOW_EXECUTE: "bigconsole-workflow:execute",
63
+ WIDGET_READ: "bigconsole-widget:read",
64
+ WIDGET_CREATE: "bigconsole-widget:create",
65
+ WIDGET_UPDATE: "bigconsole-widget:update",
66
+ WIDGET_DELETE: "bigconsole-widget:delete",
67
+ WIDGET_ACTION_READ: "bigconsole-widget-action:read",
68
+ WIDGET_ACTION_CREATE: "bigconsole-widget-action:create",
69
+ WIDGET_ACTION_UPDATE: "bigconsole-widget-action:update",
70
+ WIDGET_ACTION_DELETE: "bigconsole-widget-action:delete",
71
+ WIDGET_ACTION_EXECUTE: "bigconsole-widget-action:execute",
72
+ EVENT_LOG_READ: "bigconsole-event-log:read",
73
+ EVENT_LOG_EXECUTE: "bigconsole-event-log:execute",
74
+ WEBHOOK_READ: "bigconsole-webhook:read",
75
+ WEBHOOK_CREATE: "bigconsole-webhook:create",
76
+ WEBHOOK_UPDATE: "bigconsole-webhook:update",
77
+ WEBHOOK_DELETE: "bigconsole-webhook:delete",
78
+ WEBHOOK_TEST: "bigconsole-webhook:test"
79
+ };
80
+ //#endregion
81
+ export { e as BIGCONSOLE_PERMISSIONS };
82
+
83
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","names":[],"sources":["../../src/constants/permissions.ts"],"sourcesContent":["/**\n * BigConsole Permission Constants\n *\n * All permission strings for BigConsole resources.\n * Use with fe-libs usePermissions hook:\n * hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_CREATE)\n *\n * IMPORTANT — only strings present in the wspace-rbac-svc seed\n * (`prisma/seed-unified-rbac.ts` ACTION_DEFINITIONS, `// BIGCONSOLE MODULE`\n * section) are ever returned by `myPermissions` / `hasPermission`. Gating on a\n * string the seed does NOT define makes `hasPermission` return false for\n * EVERYONE → a full lockout. Every constant below is verified against the seed\n * as of 2026-08-05.\n *\n * NOTE ON `list` — the BigConsole backend has NO `*:list` action. Every list\n * query (`listDashboards`, `listDataSinks`, …) is gated by the resource's\n * `read` action via its `@rbac` directive. Therefore list pages MUST gate on\n * `<resource>:read`, NOT a `:list` string (which is unseeded → lockout).\n *\n * Resource types (17) and their seeded actions:\n * - bigconsole-dashboard: read, create, update, delete, export, import, publish, share, manage_embed\n * - bigconsole-dashboard-page: create, update, delete\n * - bigconsole-filter: create, update, delete\n * - bigconsole-filter-preset: read, create, update, delete\n * - bigconsole-rls-policy: read, create, update, delete\n * - bigconsole-share: read\n * - bigconsole-template: read, create, update, delete, publish\n * - bigconsole-view: read, create, update, delete\n * - bigconsole-datasink: read, create, update, delete, execute, manage\n * - bigconsole-parser: read, create, update, delete, execute, test\n * - bigconsole-pipeline: read, create, update, delete, execute, test\n * - bigconsole-prompt: read, create, update, delete\n * - bigconsole-workflow: read, create, update, delete, execute\n * - bigconsole-widget: read, create, update, delete\n * - bigconsole-widget-action: read, create, update, delete, execute\n * - bigconsole-event-log: read, execute\n * - bigconsole-webhook: read, create, update, delete, test\n */\n\nexport const BIGCONSOLE_PERMISSIONS = {\n // Dashboard resources\n DASHBOARD_READ: 'bigconsole-dashboard:read',\n DASHBOARD_CREATE: 'bigconsole-dashboard:create',\n DASHBOARD_UPDATE: 'bigconsole-dashboard:update',\n DASHBOARD_DELETE: 'bigconsole-dashboard:delete',\n DASHBOARD_EXPORT: 'bigconsole-dashboard:export',\n DASHBOARD_IMPORT: 'bigconsole-dashboard:import',\n DASHBOARD_PUBLISH: 'bigconsole-dashboard:publish',\n DASHBOARD_SHARE: 'bigconsole-dashboard:share',\n // Embed policy CRUD (`manage_embed` on all embed.gql operations)\n DASHBOARD_MANAGE_EMBED: 'bigconsole-dashboard:manage_embed',\n\n // Dashboard page (sub-resource) resources\n DASHBOARD_PAGE_CREATE: 'bigconsole-dashboard-page:create',\n DASHBOARD_PAGE_UPDATE: 'bigconsole-dashboard-page:update',\n DASHBOARD_PAGE_DELETE: 'bigconsole-dashboard-page:delete',\n\n // Global filter resources\n FILTER_CREATE: 'bigconsole-filter:create',\n FILTER_UPDATE: 'bigconsole-filter:update',\n FILTER_DELETE: 'bigconsole-filter:delete',\n\n // Filter preset resources\n FILTER_PRESET_READ: 'bigconsole-filter-preset:read',\n FILTER_PRESET_CREATE: 'bigconsole-filter-preset:create',\n FILTER_PRESET_UPDATE: 'bigconsole-filter-preset:update',\n FILTER_PRESET_DELETE: 'bigconsole-filter-preset:delete',\n\n // Row-level-security policy resources\n RLS_POLICY_READ: 'bigconsole-rls-policy:read',\n RLS_POLICY_CREATE: 'bigconsole-rls-policy:create',\n RLS_POLICY_UPDATE: 'bigconsole-rls-policy:update',\n RLS_POLICY_DELETE: 'bigconsole-rls-policy:delete',\n\n // Dashboard share resources (read-only surface; share mutations enforce\n // `bigconsole-dashboard:share`, see DASHBOARD_SHARE)\n SHARE_READ: 'bigconsole-share:read',\n\n // Template resources\n TEMPLATE_READ: 'bigconsole-template:read',\n TEMPLATE_CREATE: 'bigconsole-template:create',\n TEMPLATE_UPDATE: 'bigconsole-template:update',\n TEMPLATE_DELETE: 'bigconsole-template:delete',\n TEMPLATE_PUBLISH: 'bigconsole-template:publish',\n\n // Dashboard view resources\n VIEW_READ: 'bigconsole-view:read',\n VIEW_CREATE: 'bigconsole-view:create',\n VIEW_UPDATE: 'bigconsole-view:update',\n VIEW_DELETE: 'bigconsole-view:delete',\n\n // DataSink resources\n DATASINK_READ: 'bigconsole-datasink:read',\n DATASINK_CREATE: 'bigconsole-datasink:create',\n DATASINK_UPDATE: 'bigconsole-datasink:update',\n DATASINK_DELETE: 'bigconsole-datasink:delete',\n // `refreshDataSink` enforces `execute`\n DATASINK_EXECUTE: 'bigconsole-datasink:execute',\n // `invalidateDataSinkCache` enforces `manage`\n DATASINK_MANAGE: 'bigconsole-datasink:manage',\n\n // Parser resources\n PARSER_READ: 'bigconsole-parser:read',\n PARSER_CREATE: 'bigconsole-parser:create',\n PARSER_UPDATE: 'bigconsole-parser:update',\n PARSER_DELETE: 'bigconsole-parser:delete',\n // `executeParser` enforces `execute`\n PARSER_EXECUTE: 'bigconsole-parser:execute',\n // `testParserExpression` enforces `test`\n PARSER_TEST: 'bigconsole-parser:test',\n\n // Pipeline resources\n PIPELINE_READ: 'bigconsole-pipeline:read',\n PIPELINE_CREATE: 'bigconsole-pipeline:create',\n PIPELINE_UPDATE: 'bigconsole-pipeline:update',\n PIPELINE_DELETE: 'bigconsole-pipeline:delete',\n // `executePipeline` enforces `execute`\n PIPELINE_EXECUTE: 'bigconsole-pipeline:execute',\n // `testPipeline` enforces `test`\n PIPELINE_TEST: 'bigconsole-pipeline:test',\n\n // Prompt / AI-generation resources\n PROMPT_READ: 'bigconsole-prompt:read',\n PROMPT_CREATE: 'bigconsole-prompt:create',\n PROMPT_UPDATE: 'bigconsole-prompt:update',\n PROMPT_DELETE: 'bigconsole-prompt:delete',\n\n // Workflow resources\n WORKFLOW_READ: 'bigconsole-workflow:read',\n WORKFLOW_CREATE: 'bigconsole-workflow:create',\n WORKFLOW_UPDATE: 'bigconsole-workflow:update',\n WORKFLOW_DELETE: 'bigconsole-workflow:delete',\n // `executeWorkflow` enforces `execute`\n WORKFLOW_EXECUTE: 'bigconsole-workflow:execute',\n\n // Widget resources\n WIDGET_READ: 'bigconsole-widget:read',\n WIDGET_CREATE: 'bigconsole-widget:create',\n WIDGET_UPDATE: 'bigconsole-widget:update',\n WIDGET_DELETE: 'bigconsole-widget:delete',\n\n // Widget action resources (widget event/action bindings)\n WIDGET_ACTION_READ: 'bigconsole-widget-action:read',\n WIDGET_ACTION_CREATE: 'bigconsole-widget-action:create',\n WIDGET_ACTION_UPDATE: 'bigconsole-widget-action:update',\n WIDGET_ACTION_DELETE: 'bigconsole-widget-action:delete',\n // `emitWidgetEvent` enforces `execute`\n WIDGET_ACTION_EXECUTE: 'bigconsole-widget-action:execute',\n\n // Event log resources\n EVENT_LOG_READ: 'bigconsole-event-log:read',\n // `retryEventDelivery` enforces `execute`\n EVENT_LOG_EXECUTE: 'bigconsole-event-log:execute',\n\n // Event webhook mapping resources\n WEBHOOK_READ: 'bigconsole-webhook:read',\n WEBHOOK_CREATE: 'bigconsole-webhook:create',\n WEBHOOK_UPDATE: 'bigconsole-webhook:update',\n WEBHOOK_DELETE: 'bigconsole-webhook:delete',\n // `testWebhookMapping` enforces `test`\n WEBHOOK_TEST: 'bigconsole-webhook:test',\n} as const;\n\nexport type BigConsolePermission = (typeof BIGCONSOLE_PERMISSIONS)[keyof typeof BIGCONSOLE_PERMISSIONS];\n"],"mappings":";AAuCA,IAAa,IAAyB;CAEpC,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,mBAAmB;CACnB,iBAAiB;CAEjB,wBAAwB;CAGxB,uBAAuB;CACvB,uBAAuB;CACvB,uBAAuB;CAGvB,eAAe;CACf,eAAe;CACf,eAAe;CAGf,oBAAoB;CACpB,sBAAsB;CACtB,sBAAsB;CACtB,sBAAsB;CAGtB,iBAAiB;CACjB,mBAAmB;CACnB,mBAAmB;CACnB,mBAAmB;CAInB,YAAY;CAGZ,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,kBAAkB;CAGlB,WAAW;CACX,aAAa;CACb,aAAa;CACb,aAAa;CAGb,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CAEjB,kBAAkB;CAElB,iBAAiB;CAGjB,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CAEf,gBAAgB;CAEhB,aAAa;CAGb,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CAEjB,kBAAkB;CAElB,eAAe;CAGf,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CAGf,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CAEjB,kBAAkB;CAGlB,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CAGf,oBAAoB;CACpB,sBAAsB;CACtB,sBAAsB;CACtB,sBAAsB;CAEtB,uBAAuB;CAGvB,gBAAgB;CAEhB,mBAAmB;CAGnB,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAEhB,cAAc;CACf"}