@burdenoff/microfe-bigconsole 2026.805.2 → 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 (134) hide show
  1. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +109 -113
  2. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
  3. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +115 -113
  4. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  5. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +71 -62
  6. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  7. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +90 -89
  8. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  9. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +56 -54
  10. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
  11. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +126 -125
  12. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
  13. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +151 -150
  14. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
  15. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +77 -76
  16. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
  17. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +97 -96
  18. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  19. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +172 -191
  20. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  21. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +75 -83
  22. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js.map +1 -1
  23. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +151 -154
  24. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
  25. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +181 -190
  26. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
  27. package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -0
  28. package/dist/bigconsole/components/dashboard/WidgetPalette.js +110 -108
  29. package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
  30. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +102 -103
  31. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  32. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +36 -41
  33. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  34. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +38 -37
  35. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  36. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +113 -117
  37. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
  38. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +182 -197
  39. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  40. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +166 -168
  41. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  42. package/dist/bigconsole/components/parser/DataSinkSelector.js +87 -86
  43. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  44. package/dist/bigconsole/components/parser/ImportParserDialog.js +196 -211
  45. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  46. package/dist/bigconsole/components/parser/ParserSelector.js +130 -128
  47. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  48. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +66 -63
  49. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
  50. package/dist/bigconsole/components/preview/AiPreviewPanel.js +95 -91
  51. package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
  52. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +222 -215
  53. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  54. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +149 -145
  55. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  56. package/dist/bigconsole/components/widgets/PropertiesPanel.js +504 -470
  57. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  58. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +44 -47
  59. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  60. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +143 -142
  61. package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
  62. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +101 -88
  63. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  64. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +135 -134
  65. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
  66. package/dist/bigconsole/components/widgets/form/FormWidget.js +167 -159
  67. package/dist/bigconsole/components/widgets/form/FormWidget.js.map +1 -1
  68. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +69 -68
  69. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
  70. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +64 -72
  71. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
  72. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +60 -59
  73. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  74. package/dist/bigconsole/components/widgets/list/ListConfig.js +57 -56
  75. package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
  76. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +70 -69
  77. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
  78. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +35 -34
  79. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
  80. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +20 -19
  81. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
  82. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +178 -177
  83. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  84. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +76 -75
  85. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  86. package/dist/bigconsole/components/widgets/table/TableConfig.js +183 -168
  87. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  88. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +187 -180
  89. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
  90. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +40 -38
  91. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
  92. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +150 -148
  93. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  94. package/dist/bigconsole/pages/DashboardBuilderPage.js +181 -176
  95. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  96. package/dist/bigconsole/pages/DashboardViewPage.js +196 -192
  97. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  98. package/dist/bigconsole/pages/DashboardsPage.js +223 -219
  99. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  100. package/dist/bigconsole/pages/DataParsersPage.js +167 -170
  101. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  102. package/dist/bigconsole/pages/DataSinkBuilderPage.js +204 -189
  103. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  104. package/dist/bigconsole/pages/DataSinkViewPage.js +175 -169
  105. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  106. package/dist/bigconsole/pages/DataSourcesPage.js +8 -7
  107. package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
  108. package/dist/bigconsole/pages/InsightsPage.js +238 -208
  109. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  110. package/dist/bigconsole/pages/ParserBuilderPage.js +464 -412
  111. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  112. package/dist/bigconsole/pages/ParserViewPage.js +92 -90
  113. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  114. package/dist/bigconsole/pages/PipelineBuilderPage.js +221 -194
  115. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  116. package/dist/bigconsole/pages/PipelineViewPage.js +181 -184
  117. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  118. package/dist/bigconsole/pages/PipelinesPage.js +128 -127
  119. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  120. package/dist/bigconsole/pages/SettingsPage.js +177 -172
  121. package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
  122. package/dist/bigconsole/pages/WidgetDemoPage.js +121 -83
  123. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  124. package/dist/bigconsole/pages/WorkflowViewPage.js +199 -193
  125. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  126. package/dist/bigconsole/pages/WorkflowsPage.js +129 -128
  127. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  128. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +111 -109
  129. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
  130. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +127 -126
  131. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
  132. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +103 -103
  133. package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
  134. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowViewPage.js","names":[],"sources":["../../../src/bigconsole/pages/WorkflowViewPage.tsx"],"sourcesContent":["/**\n * Workflow View Page\n *\n * Page for viewing FluidGrids Workflow details, linked DataSinks,\n * read-only workflow design preview, and real execution with polling.\n */\n\nimport { memo, useState, useEffect, useCallback } from 'react';\nimport { useParams } from 'react-router';\nimport { GlassCard, IllustratedEmptyState, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport type { NextStep } from '@burdenoff/fe-libs/ui';\nimport { useAppNavigate } from '../contexts';\nimport { isNative, nativeCopyText, nativeNotify, nativeToast } from '../../utils/nativeBridge';\nimport { useBigConsole } from '../context';\nimport { formatDistanceToNow } from 'date-fns';\nimport { useWorkflowOperations } from '../hooks/useWorkflowOperations';\nimport { WorkflowStatusBadge } from '../components/workflow/WorkflowStatusBadge';\nimport { WorkflowDeleteDialog } from '../components/workflow/WorkflowDeleteDialog';\nimport type { FluidGridsWorkflow } from '../types';\n\n// FluidGrids FE SDK — read-only embedded builder preview\nimport { WorkflowBuilder } from '@burdenoff/fluidgrids-fe-sdk';\nimport { BOOTSTRAP_RETRY_DELAY_MS } from '../constants';\n\n// RBAC\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst ArrowLeftIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n);\n\nconst EditIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"\n />\n </svg>\n);\n\nconst TrashIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n);\n\nconst PlayIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z\"\n />\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n);\n\nconst CopyIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n);\n\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n);\n\nconst DatabaseIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4\"\n />\n </svg>\n);\n\nconst ErrorIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n);\n\nconst ChevronDownIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const WorkflowViewPage = memo(function WorkflowViewPage() {\n const navigate = useAppNavigate();\n const { workflowId } = useParams<{ workflowId: string }>();\n\n // BigConsole context for apiGatewayUrl and authToken\n const { apiGatewayUrl, authToken, workspaceId } = useBigConsole();\n\n // RBAC\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_READ);\n const canUpdate = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_UPDATE);\n const canDelete = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_DELETE);\n const canExecute = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_EXECUTE);\n\n // Local state\n const [workflow, setWorkflow] = useState<FluidGridsWorkflow | null>(null);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [, setIsDeleting] = useState(false);\n const [isExecuting, setIsExecuting] = useState(false);\n const [webhookCopied, setWebhookCopied] = useState(false);\n const [showDesignPreview, setShowDesignPreview] = useState(false);\n // Track whether initial fetch has completed — prevents \"not found\" flash\n // before data has even been requested (loading starts as false with skipFetch: true)\n const [isReady, setIsReady] = useState(false);\n const [executionResult, setExecutionResult] = useState<{\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n runId?: string;\n } | null>(null);\n\n // Operations\n const { loading, error, fetchWorkflow, deleteWorkflow, executeWorkflow, pollWorkflowExecution } =\n useWorkflowOperations({\n skipFetch: true,\n });\n\n // Load workflow on mount.\n // On a full page reload the workspace token may not be issued yet when this\n // effect first runs, causing the gateway to lack workspace context and\n // the resolver to return null. We retry once after a short delay to give\n // the auth bootstrap time to complete.\n useEffect(() => {\n if (!workflowId) {\n setIsReady(true);\n return;\n }\n\n let cancelled = false;\n\n const load = async (attempt: number) => {\n try {\n const result = await fetchWorkflow(workflowId);\n if (cancelled) return;\n\n if (result) {\n setWorkflow(result);\n setIsReady(true);\n } else if (attempt === 0) {\n // First attempt failed — likely workspace token race on full-page load.\n // Retry once after a short delay.\n setTimeout(() => {\n if (!cancelled) load(1);\n }, BOOTSTRAP_RETRY_DELAY_MS);\n } else {\n // Second attempt also failed — genuinely not found\n setIsReady(true);\n }\n } catch {\n // Network error, GraphQL error, etc. — surface the \"not found\" UI\n // rather than spinning forever with no escape hatch.\n if (!cancelled) setIsReady(true);\n }\n };\n\n load(0);\n return () => {\n cancelled = true;\n };\n }, [workflowId, fetchWorkflow]);\n\n // Handlers\n const handleBack = useCallback(() => {\n navigate(`/workflows`);\n }, [navigate]);\n\n const handleEdit = useCallback(() => {\n navigate(`/workflows/${workflowId}/edit`);\n }, [navigate, workflowId]);\n\n const handleDelete = useCallback(async () => {\n if (!workflowId) return;\n setIsDeleting(true);\n try {\n const success = await deleteWorkflow(workflowId);\n if (success) {\n if (isNative()) void nativeNotify('success');\n navigate(`/workflows`);\n } else if (isNative()) {\n void nativeNotify('error');\n }\n } catch {\n if (isNative()) void nativeNotify('error');\n } finally {\n setIsDeleting(false);\n setShowDeleteConfirm(false);\n }\n }, [workflowId, deleteWorkflow, navigate]);\n\n const handleExecute = useCallback(async () => {\n if (!workflowId) return;\n setIsExecuting(true);\n setExecutionResult(null);\n\n const startTime = Date.now();\n\n try {\n const result = await executeWorkflow(workflowId);\n\n if (result) {\n const executionTimeMs = Date.now() - startTime;\n\n // If workflow has external FluidGrids ID, the execution is async\n if (result.externalWorkflowId) {\n setExecutionResult({\n success: true,\n output: {\n externalWorkflowId: result.externalWorkflowId,\n executionCount: result.executionCount,\n status: 'Triggered — polling for completion...',\n },\n error: null,\n executionTimeMs,\n });\n\n // Poll for completion in the background\n pollWorkflowExecution(workflowId, {\n intervalMs: 3000,\n timeoutMs: 120000,\n onProgress: (updated) => {\n setWorkflow(updated);\n },\n }).then((final) => {\n if (final) {\n setWorkflow(final);\n setExecutionResult((prev) =>\n prev\n ? {\n ...prev,\n output: {\n ...((prev.output as Record<string, unknown>) || {}),\n status: final.status === 'error' ? 'Failed' : 'Completed',\n executionCount: final.executionCount,\n lastExecutedAt: final.lastExecutedAt,\n },\n executionTimeMs: Date.now() - startTime,\n }\n : prev\n );\n }\n });\n } else {\n // Local execution (no external FluidGrids workflow)\n setExecutionResult({\n success: true,\n output: {\n executionCount: result.executionCount,\n lastExecutedAt: result.lastExecutedAt,\n status: 'Completed',\n },\n error: null,\n executionTimeMs,\n });\n }\n\n // Refresh workflow\n const updated = await fetchWorkflow(workflowId);\n if (updated) {\n setWorkflow(updated);\n }\n }\n } catch (err) {\n setExecutionResult({\n success: false,\n output: null,\n error: err instanceof Error ? err.message : 'Execution failed',\n executionTimeMs: Date.now() - startTime,\n });\n } finally {\n setIsExecuting(false);\n }\n }, [workflowId, executeWorkflow, fetchWorkflow, pollWorkflowExecution]);\n\n const handleCopyWebhook = useCallback(async () => {\n if (!workflow?.webhookUrl) return;\n try {\n await nativeCopyText(workflow.webhookUrl);\n setWebhookCopied(true);\n if (isNative()) void nativeToast('Webhook copied');\n setTimeout(() => setWebhookCopied(false), 2000);\n } catch {\n // Clipboard not available\n }\n }, [workflow?.webhookUrl]);\n\n const handleViewDataSink = useCallback(\n (dataSinkId: string) => {\n navigate(`/datasinks/${dataSinkId}`);\n },\n [navigate]\n );\n\n // Loading state — show spinner until initial fetch completes OR during a\n // refetch, and while permissions are still loading (avoids a read-gate flash).\n if (!isReady || (loading && !workflow) || permissionsLoading) {\n return (\n <div className=\"p-6 flex items-center justify-center min-h-[400px]\">\n <svg className=\"w-8 h-8 text-action-primary-bg animate-spin\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n </div>\n );\n }\n\n // Read gate — no permission to view this workflow\n if (!canRead) {\n return <AccessDenied title=\"Access Denied\" description=\"You don't have permission to view this workflow.\" />;\n }\n\n // Error or not found state — only shown AFTER initial fetch completed\n if (error || !workflow) {\n return (\n <div className=\"p-6\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"inline-flex items-center gap-1 text-sm text-text-secondary hover:text-text-primary mb-4\"\n >\n <ArrowLeftIcon className=\"w-4 h-4\" />\n Back to Workflows\n </button>\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"Workflow not found\"\n description={error?.message || 'The workflow you are looking for does not exist.'}\n />\n </div>\n );\n }\n\n const linkedDataSinkCount = workflow.dataSinkLinks?.length || 0;\n\n // Next-step guidance — omit steps that trigger a gated action the caller\n // cannot perform (execute → WORKFLOW_EXECUTE, edit → WORKFLOW_UPDATE).\n const nextSteps: NextStep[] = [\n ...(canExecute\n ? [\n {\n id: 'execute',\n label: 'Run the workflow',\n description: 'Trigger an execution to pull fresh data now.',\n onClick: handleExecute,\n },\n ]\n : []),\n {\n id: 'design',\n label: 'Inspect the design',\n description: 'Expand the read-only preview to see each step.',\n onClick: () => setShowDesignPreview(true),\n },\n ...(canUpdate\n ? [\n {\n id: 'edit',\n label: 'Edit in the builder',\n description: 'Open the FluidGrids visual builder to change the flow.',\n onClick: handleEdit,\n },\n ]\n : []),\n {\n id: 'sinks',\n label: 'Check the linked data sinks',\n description: 'See where this workflow writes its output.',\n onClick: () => navigate('/datasinks'),\n },\n ];\n\n return (\n <div className=\"p-6 max-w-5xl mx-auto\">\n {/* Header */}\n <div className=\"mb-8\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"inline-flex items-center gap-1 text-sm text-text-secondary hover:text-text-primary mb-4\"\n >\n <ArrowLeftIcon className=\"w-4 h-4\" />\n Back to Workflows\n </button>\n\n <div className=\"flex items-start justify-between\">\n <div>\n <div className=\"flex items-center gap-3 mb-2\">\n <h1 className=\"text-2xl font-bold text-text-primary\">{workflow.name}</h1>\n <WorkflowStatusBadge status={workflow.status} />\n </div>\n <p className=\"text-sm text-text-secondary font-mono\">{workflow.key}</p>\n {workflow.externalWorkflowId && (\n <p className=\"text-xs text-text-tertiary mt-1\">\n FluidGrids ID: <span className=\"font-mono\">{workflow.externalWorkflowId}</span>\n </p>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_EXECUTE} deniedBehavior=\"disable\">\n <button\n type=\"button\"\n onClick={handleExecute}\n disabled={isExecuting}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-status-success-bg hover:bg-status-success-bg/90 rounded-md transition-colors disabled:opacity-50\"\n >\n <PlayIcon className=\"w-4 h-4\" />\n {isExecuting ? 'Executing...' : 'Execute'}\n </button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_UPDATE} deniedBehavior=\"disable\">\n <button\n type=\"button\"\n onClick={handleEdit}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken hover:bg-border-default rounded-md transition-colors\"\n >\n <EditIcon className=\"w-4 h-4\" />\n Edit\n </button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_DELETE} deniedBehavior=\"hide\">\n <button\n type=\"button\"\n onClick={() => setShowDeleteConfirm(true)}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-status-error-text bg-status-error-bg/10 hover:bg-status-error-bg/20 rounded-md transition-colors\"\n >\n <TrashIcon className=\"w-4 h-4\" />\n Delete\n </button>\n </PermissionButton>\n </div>\n </div>\n </div>\n\n <PagePurpose className=\"mb-6\">\n A workflow is the visual ETL job that feeds this BigConsole — it fetches, transforms, and delivers data into\n linked data sinks. From here you can run it on demand, inspect its design and execution history, copy its\n webhook trigger, and edit it in the visual builder.\n </PagePurpose>\n\n <NextSteps storageKey=\"bigconsole-workflow-view\" steps={nextSteps} />\n\n {/* Execution Result */}\n {executionResult && (\n <div\n className={`mb-6 p-4 rounded-lg border ${\n executionResult.success\n ? 'bg-status-success-bg/10 border-status-success-border/20'\n : 'bg-status-error-bg/10 border-status-error-border/20'\n }`}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {executionResult.success ? 'Execution Triggered' : 'Execution Failed'}\n </h3>\n <span className=\"text-xs text-text-secondary\">{executionResult.executionTimeMs}ms</span>\n </div>\n {executionResult.error ? (\n <p className=\"text-sm text-status-error-text\">{executionResult.error}</p>\n ) : (\n <pre className=\"text-xs text-text-secondary font-mono bg-bg-sunken p-2 rounded overflow-auto max-h-[200px]\">\n {JSON.stringify(executionResult.output, null, 2)}\n </pre>\n )}\n {executionResult.runId && (\n <p className=\"text-xs text-text-tertiary mt-2\">\n Run ID: <span className=\"font-mono\">{executionResult.runId}</span>\n </p>\n )}\n </div>\n )}\n\n {/* Info Grid */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6 mb-8\">\n {/* Description */}\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">Description</h3>\n <p className=\"text-sm text-text-primary\">{workflow.description || 'No description'}</p>\n </div>\n\n {/* Execution Stats — primary emphasis zone */}\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">Execution Stats</h3>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-2xl font-bold text-text-primary\">{workflow.executionCount}</p>\n <p className=\"text-xs text-text-secondary\">Total Executions</p>\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {workflow.lastExecutedAt\n ? formatDistanceToNow(new Date(workflow.lastExecutedAt), { addSuffix: true })\n : 'Never'}\n </p>\n <p className=\"text-xs text-text-secondary\">Last Executed</p>\n </div>\n </div>\n </GlassCard>\n </div>\n\n {/* Webhook URL */}\n {workflow.webhookUrl && (\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4 mb-8\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">Webhook URL</h3>\n <div className=\"flex items-center gap-2\">\n <code className=\"flex-1 text-sm text-text-primary font-mono bg-bg-sunken px-3 py-2 rounded overflow-auto\">\n {workflow.webhookUrl}\n </code>\n <button\n type=\"button\"\n onClick={handleCopyWebhook}\n className=\"flex items-center gap-1 px-3 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors\"\n >\n {webhookCopied ? (\n <>\n <CheckIcon className=\"w-4 h-4 text-status-success-text\" />\n Copied!\n </>\n ) : (\n <>\n <CopyIcon className=\"w-4 h-4\" />\n Copy\n </>\n )}\n </button>\n </div>\n </div>\n )}\n\n {/* Workflow Design Preview (collapsible) */}\n {workflow.externalWorkflowId && (\n <div className=\"bg-bg-surface border border-border-default rounded-lg mb-8 overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setShowDesignPreview((prev) => !prev)}\n className=\"w-full flex items-center justify-between px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n <span>Workflow Design Preview</span>\n <ChevronDownIcon\n className={`w-4 h-4 text-text-secondary transition-transform ${showDesignPreview ? 'rotate-180' : ''}`}\n />\n </button>\n {showDesignPreview && (\n <div className=\"border-t border-border-default\" style={{ height: '450px' }}>\n <WorkflowBuilder\n apiGatewayUrl={apiGatewayUrl}\n workspaceId={workspaceId || 'default'}\n authToken={authToken}\n workflowId={workflow.externalWorkflowId}\n readonly\n hideHeader\n className=\"h-full\"\n />\n </div>\n )}\n </div>\n )}\n\n {/* Linked DataSinks */}\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4 mb-8\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">Linked DataSinks ({linkedDataSinkCount})</h3>\n {linkedDataSinkCount === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No data sinks linked\"\n description=\"This workflow has no data sinks linked yet — its output isn't being stored.\"\n />\n ) : (\n <div className=\"space-y-2\">\n {workflow.dataSinkLinks?.map((link) => (\n <div key={link.id} className=\"flex items-center justify-between px-3 py-2 bg-bg-sunken rounded-md\">\n <div className=\"flex items-center gap-3\">\n <DatabaseIcon className=\"w-4 h-4 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {link.dataSink?.name || link.dataSink?.key || link.dataSinkId}\n </p>\n {link.dataSink?.key && <p className=\"text-xs text-text-secondary font-mono\">{link.dataSink.key}</p>}\n </div>\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-2\">\n {link.isEnabled ? (\n <span className=\"text-xs text-status-success-text\">Enabled</span>\n ) : (\n <span className=\"text-xs text-text-secondary\">Disabled</span>\n )}\n <span className=\"text-xs text-text-secondary\">Priority: {link.priority}</span>\n </div>\n {link.dataSink && (\n <button\n type=\"button\"\n onClick={() => handleViewDataSink(link.dataSinkId)}\n className=\"text-xs text-action-primary-bg hover:underline\"\n >\n View\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Timestamps */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">Created</h3>\n <p className=\"text-sm text-text-primary\">\n {formatDistanceToNow(new Date(workflow.createdAt), { addSuffix: true })}\n </p>\n <p className=\"text-xs text-text-secondary\">by {workflow.createdBy}</p>\n </div>\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">Last Updated</h3>\n <p className=\"text-sm text-text-primary\">\n {formatDistanceToNow(new Date(workflow.updatedAt), { addSuffix: true })}\n </p>\n <p className=\"text-xs text-text-secondary\">by {workflow.updatedBy || workflow.createdBy}</p>\n </div>\n </div>\n\n {/* Delete Confirmation Dialog */}\n {workflow && (\n <WorkflowDeleteDialog\n workflow={workflow}\n isOpen={showDeleteConfirm}\n onClose={() => setShowDeleteConfirm(false)}\n onConfirm={handleDelete}\n />\n )}\n </div>\n );\n});\n\nexport default WorkflowViewPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"WorkflowViewPage.js","names":[],"sources":["../../../src/bigconsole/pages/WorkflowViewPage.tsx"],"sourcesContent":["/**\n * Workflow View Page\n *\n * Page for viewing FluidGrids Workflow details, linked DataSinks,\n * read-only workflow design preview, and real execution with polling.\n */\n\nimport { memo, useState, useEffect, useCallback } from 'react';\nimport { useParams } from 'react-router';\nimport { GlassCard, IllustratedEmptyState, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport type { NextStep } from '@burdenoff/fe-libs/ui';\nimport { useAppNavigate } from '../contexts';\nimport { isNative, nativeCopyText, nativeNotify, nativeToast } from '../../utils/nativeBridge';\nimport { useBigConsole } from '../context';\nimport { formatDistanceToNow } from 'date-fns';\nimport { useWorkflowOperations } from '../hooks/useWorkflowOperations';\nimport { WorkflowStatusBadge } from '../components/workflow/WorkflowStatusBadge';\nimport { WorkflowDeleteDialog } from '../components/workflow/WorkflowDeleteDialog';\nimport type { FluidGridsWorkflow } from '../types';\n\n// FluidGrids FE SDK — read-only embedded builder preview\nimport { WorkflowBuilder } from '@burdenoff/fluidgrids-fe-sdk';\nimport { BOOTSTRAP_RETRY_DELAY_MS } from '../constants';\n\n// RBAC\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst ArrowLeftIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n);\n\nconst EditIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"\n />\n </svg>\n);\n\nconst TrashIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n);\n\nconst PlayIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z\"\n />\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n);\n\nconst CopyIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n);\n\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n);\n\nconst DatabaseIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4\"\n />\n </svg>\n);\n\nconst ErrorIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n);\n\nconst ChevronDownIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const WorkflowViewPage = memo(function WorkflowViewPage() {\n const navigate = useAppNavigate();\n const { t } = useI18n();\n const { workflowId } = useParams<{ workflowId: string }>();\n\n // BigConsole context for apiGatewayUrl and authToken\n const { apiGatewayUrl, authToken, workspaceId } = useBigConsole();\n\n // RBAC\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_READ);\n const canUpdate = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_UPDATE);\n const canDelete = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_DELETE);\n const canExecute = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_EXECUTE);\n\n // Local state\n const [workflow, setWorkflow] = useState<FluidGridsWorkflow | null>(null);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [, setIsDeleting] = useState(false);\n const [isExecuting, setIsExecuting] = useState(false);\n const [webhookCopied, setWebhookCopied] = useState(false);\n const [showDesignPreview, setShowDesignPreview] = useState(false);\n // Track whether initial fetch has completed — prevents \"not found\" flash\n // before data has even been requested (loading starts as false with skipFetch: true)\n const [isReady, setIsReady] = useState(false);\n const [executionResult, setExecutionResult] = useState<{\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n runId?: string;\n } | null>(null);\n\n // Operations\n const { loading, error, fetchWorkflow, deleteWorkflow, executeWorkflow, pollWorkflowExecution } =\n useWorkflowOperations({\n skipFetch: true,\n });\n\n // Load workflow on mount.\n // On a full page reload the workspace token may not be issued yet when this\n // effect first runs, causing the gateway to lack workspace context and\n // the resolver to return null. We retry once after a short delay to give\n // the auth bootstrap time to complete.\n useEffect(() => {\n if (!workflowId) {\n setIsReady(true);\n return;\n }\n\n let cancelled = false;\n\n const load = async (attempt: number) => {\n try {\n const result = await fetchWorkflow(workflowId);\n if (cancelled) return;\n\n if (result) {\n setWorkflow(result);\n setIsReady(true);\n } else if (attempt === 0) {\n // First attempt failed — likely workspace token race on full-page load.\n // Retry once after a short delay.\n setTimeout(() => {\n if (!cancelled) load(1);\n }, BOOTSTRAP_RETRY_DELAY_MS);\n } else {\n // Second attempt also failed — genuinely not found\n setIsReady(true);\n }\n } catch {\n // Network error, GraphQL error, etc. — surface the \"not found\" UI\n // rather than spinning forever with no escape hatch.\n if (!cancelled) setIsReady(true);\n }\n };\n\n load(0);\n return () => {\n cancelled = true;\n };\n }, [workflowId, fetchWorkflow]);\n\n // Handlers\n const handleBack = useCallback(() => {\n navigate(`/workflows`);\n }, [navigate]);\n\n const handleEdit = useCallback(() => {\n navigate(`/workflows/${workflowId}/edit`);\n }, [navigate, workflowId]);\n\n const handleDelete = useCallback(async () => {\n if (!workflowId) return;\n setIsDeleting(true);\n try {\n const success = await deleteWorkflow(workflowId);\n if (success) {\n if (isNative()) void nativeNotify('success');\n navigate(`/workflows`);\n } else if (isNative()) {\n void nativeNotify('error');\n }\n } catch {\n if (isNative()) void nativeNotify('error');\n } finally {\n setIsDeleting(false);\n setShowDeleteConfirm(false);\n }\n }, [workflowId, deleteWorkflow, navigate]);\n\n const handleExecute = useCallback(async () => {\n if (!workflowId) return;\n setIsExecuting(true);\n setExecutionResult(null);\n\n const startTime = Date.now();\n\n try {\n const result = await executeWorkflow(workflowId);\n\n if (result) {\n const executionTimeMs = Date.now() - startTime;\n\n // If workflow has external FluidGrids ID, the execution is async\n if (result.externalWorkflowId) {\n setExecutionResult({\n success: true,\n output: {\n externalWorkflowId: result.externalWorkflowId,\n executionCount: result.executionCount,\n status: t('bigconsole.workflows.view.executionTriggeredPolling', 'Triggered — polling for completion...'),\n },\n error: null,\n executionTimeMs,\n });\n\n // Poll for completion in the background\n pollWorkflowExecution(workflowId, {\n intervalMs: 3000,\n timeoutMs: 120000,\n onProgress: (updated) => {\n setWorkflow(updated);\n },\n }).then((final) => {\n if (final) {\n setWorkflow(final);\n setExecutionResult((prev) =>\n prev\n ? {\n ...prev,\n output: {\n ...((prev.output as Record<string, unknown>) || {}),\n status:\n final.status === 'error'\n ? t('bigconsole.workflows.view.executionStatusFailed', 'Failed')\n : t('bigconsole.workflows.view.executionStatusCompleted', 'Completed'),\n executionCount: final.executionCount,\n lastExecutedAt: final.lastExecutedAt,\n },\n executionTimeMs: Date.now() - startTime,\n }\n : prev\n );\n }\n });\n } else {\n // Local execution (no external FluidGrids workflow)\n setExecutionResult({\n success: true,\n output: {\n executionCount: result.executionCount,\n lastExecutedAt: result.lastExecutedAt,\n status: t('bigconsole.workflows.view.executionStatusCompleted', 'Completed'),\n },\n error: null,\n executionTimeMs,\n });\n }\n\n // Refresh workflow\n const updated = await fetchWorkflow(workflowId);\n if (updated) {\n setWorkflow(updated);\n }\n }\n } catch (err) {\n setExecutionResult({\n success: false,\n output: null,\n error:\n err instanceof Error ? err.message : t('bigconsole.workflows.errors.executionFailed', 'Execution failed'),\n executionTimeMs: Date.now() - startTime,\n });\n } finally {\n setIsExecuting(false);\n }\n }, [workflowId, executeWorkflow, fetchWorkflow, pollWorkflowExecution, t]);\n\n const handleCopyWebhook = useCallback(async () => {\n if (!workflow?.webhookUrl) return;\n try {\n await nativeCopyText(workflow.webhookUrl);\n setWebhookCopied(true);\n if (isNative()) void nativeToast(t('bigconsole.workflows.view.webhookCopiedToast', 'Webhook copied'));\n setTimeout(() => setWebhookCopied(false), 2000);\n } catch {\n // Clipboard not available\n }\n }, [workflow?.webhookUrl, t]);\n\n const handleViewDataSink = useCallback(\n (dataSinkId: string) => {\n navigate(`/datasinks/${dataSinkId}`);\n },\n [navigate]\n );\n\n // Loading state — show spinner until initial fetch completes OR during a\n // refetch, and while permissions are still loading (avoids a read-gate flash).\n if (!isReady || (loading && !workflow) || permissionsLoading) {\n return (\n <div className=\"p-6 flex items-center justify-center min-h-[400px]\">\n <svg className=\"w-8 h-8 text-action-primary-bg animate-spin\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n </div>\n );\n }\n\n // Read gate — no permission to view this workflow\n if (!canRead) {\n return (\n <AccessDenied\n title={t('bigconsole.workflows.errors.accessDeniedTitle', 'Access Denied')}\n description={t(\n 'bigconsole.workflows.errors.accessDeniedViewDescription',\n \"You don't have permission to view this workflow.\"\n )}\n />\n );\n }\n\n // Error or not found state — only shown AFTER initial fetch completed\n if (error || !workflow) {\n return (\n <div className=\"p-6\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"inline-flex items-center gap-1 text-sm text-text-secondary hover:text-text-primary mb-4\"\n >\n <ArrowLeftIcon className=\"w-4 h-4\" />\n {t('bigconsole.workflows.view.backToWorkflows', 'Back to Workflows')}\n </button>\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('bigconsole.workflows.view.notFoundTitle', 'Workflow not found')}\n description={\n error?.message ||\n t('bigconsole.workflows.view.notFoundDescription', 'The workflow you are looking for does not exist.')\n }\n />\n </div>\n );\n }\n\n const linkedDataSinkCount = workflow.dataSinkLinks?.length || 0;\n\n // Next-step guidance — omit steps that trigger a gated action the caller\n // cannot perform (execute → WORKFLOW_EXECUTE, edit → WORKFLOW_UPDATE).\n const nextSteps: NextStep[] = [\n ...(canExecute\n ? [\n {\n id: 'execute',\n label: t('bigconsole.workflows.view.nextStepExecuteLabel', 'Run the workflow'),\n description: t(\n 'bigconsole.workflows.view.nextStepExecuteDescription',\n 'Trigger an execution to pull fresh data now.'\n ),\n onClick: handleExecute,\n },\n ]\n : []),\n {\n id: 'design',\n label: t('bigconsole.workflows.view.nextStepDesignLabel', 'Inspect the design'),\n description: t(\n 'bigconsole.workflows.view.nextStepDesignDescription',\n 'Expand the read-only preview to see each step.'\n ),\n onClick: () => setShowDesignPreview(true),\n },\n ...(canUpdate\n ? [\n {\n id: 'edit',\n label: t('bigconsole.workflows.view.nextStepEditLabel', 'Edit in the builder'),\n description: t(\n 'bigconsole.workflows.view.nextStepEditDescription',\n 'Open the FluidGrids visual builder to change the flow.'\n ),\n onClick: handleEdit,\n },\n ]\n : []),\n {\n id: 'sinks',\n label: t('bigconsole.workflows.view.nextStepSinksLabel', 'Check the linked data sinks'),\n description: t(\n 'bigconsole.workflows.view.nextStepSinksDescription',\n 'See where this workflow writes its output.'\n ),\n onClick: () => navigate('/datasinks'),\n },\n ];\n\n return (\n <div className=\"p-6 max-w-5xl mx-auto\">\n {/* Header */}\n <div className=\"mb-8\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"inline-flex items-center gap-1 text-sm text-text-secondary hover:text-text-primary mb-4\"\n >\n <ArrowLeftIcon className=\"w-4 h-4\" />\n {t('bigconsole.workflows.view.backToWorkflows', 'Back to Workflows')}\n </button>\n\n <div className=\"flex items-start justify-between\">\n <div>\n <div className=\"flex items-center gap-3 mb-2\">\n <h1 className=\"text-2xl font-bold text-text-primary\">{workflow.name}</h1>\n <WorkflowStatusBadge status={workflow.status} />\n </div>\n <p className=\"text-sm text-text-secondary font-mono\">{workflow.key}</p>\n {workflow.externalWorkflowId && (\n <p className=\"text-xs text-text-tertiary mt-1\">\n {t('bigconsole.workflows.view.fluidGridsIdLabel', 'FluidGrids ID:')}{' '}\n <span className=\"font-mono\">{workflow.externalWorkflowId}</span>\n </p>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_EXECUTE} deniedBehavior=\"disable\">\n <button\n type=\"button\"\n onClick={handleExecute}\n disabled={isExecuting}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-status-success-bg hover:bg-status-success-bg/90 rounded-md transition-colors disabled:opacity-50\"\n >\n <PlayIcon className=\"w-4 h-4\" />\n {isExecuting\n ? t('bigconsole.workflows.actions.executing', 'Executing...')\n : t('bigconsole.workflows.actions.execute', 'Execute')}\n </button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_UPDATE} deniedBehavior=\"disable\">\n <button\n type=\"button\"\n onClick={handleEdit}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken hover:bg-border-default rounded-md transition-colors\"\n >\n <EditIcon className=\"w-4 h-4\" />\n {t('bigconsole.workflows.actions.edit', 'Edit')}\n </button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_DELETE} deniedBehavior=\"hide\">\n <button\n type=\"button\"\n onClick={() => setShowDeleteConfirm(true)}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-status-error-text bg-status-error-bg/10 hover:bg-status-error-bg/20 rounded-md transition-colors\"\n >\n <TrashIcon className=\"w-4 h-4\" />\n {t('bigconsole.workflows.actions.delete', 'Delete')}\n </button>\n </PermissionButton>\n </div>\n </div>\n </div>\n\n <PagePurpose className=\"mb-6\">\n {t(\n 'bigconsole.workflows.view.purpose',\n 'A workflow is the visual ETL job that feeds this BigConsole — it fetches, transforms, and delivers data into linked data sinks. From here you can run it on demand, inspect its design and execution history, copy its webhook trigger, and edit it in the visual builder.'\n )}\n </PagePurpose>\n\n <NextSteps storageKey=\"bigconsole-workflow-view\" steps={nextSteps} />\n\n {/* Execution Result */}\n {executionResult && (\n <div\n className={`mb-6 p-4 rounded-lg border ${\n executionResult.success\n ? 'bg-status-success-bg/10 border-status-success-border/20'\n : 'bg-status-error-bg/10 border-status-error-border/20'\n }`}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {executionResult.success\n ? t('bigconsole.workflows.view.executionResultTriggered', 'Execution Triggered')\n : t('bigconsole.workflows.view.executionResultFailed', 'Execution Failed')}\n </h3>\n <span className=\"text-xs text-text-secondary\">{executionResult.executionTimeMs}ms</span>\n </div>\n {executionResult.error ? (\n <p className=\"text-sm text-status-error-text\">{executionResult.error}</p>\n ) : (\n <pre className=\"text-xs text-text-secondary font-mono bg-bg-sunken p-2 rounded overflow-auto max-h-[200px]\">\n {JSON.stringify(executionResult.output, null, 2)}\n </pre>\n )}\n {executionResult.runId && (\n <p className=\"text-xs text-text-tertiary mt-2\">\n {t('bigconsole.workflows.view.runIdLabel', 'Run ID:')}{' '}\n <span className=\"font-mono\">{executionResult.runId}</span>\n </p>\n )}\n </div>\n )}\n\n {/* Info Grid */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6 mb-8\">\n {/* Description */}\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">\n {t('bigconsole.workflows.view.descriptionLabel', 'Description')}\n </h3>\n <p className=\"text-sm text-text-primary\">\n {workflow.description || t('bigconsole.workflows.view.noDescription', 'No description')}\n </p>\n </div>\n\n {/* Execution Stats — primary emphasis zone */}\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">\n {t('bigconsole.workflows.view.executionStatsLabel', 'Execution Stats')}\n </h3>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-2xl font-bold text-text-primary\">{workflow.executionCount}</p>\n <p className=\"text-xs text-text-secondary\">\n {t('bigconsole.workflows.view.totalExecutionsLabel', 'Total Executions')}\n </p>\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {workflow.lastExecutedAt\n ? formatDistanceToNow(new Date(workflow.lastExecutedAt), { addSuffix: true })\n : t('bigconsole.workflows.view.never', 'Never')}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t('bigconsole.workflows.view.lastExecutedLabel', 'Last Executed')}\n </p>\n </div>\n </div>\n </GlassCard>\n </div>\n\n {/* Webhook URL */}\n {workflow.webhookUrl && (\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4 mb-8\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">\n {t('bigconsole.workflows.view.webhookUrlLabel', 'Webhook URL')}\n </h3>\n <div className=\"flex items-center gap-2\">\n <code className=\"flex-1 text-sm text-text-primary font-mono bg-bg-sunken px-3 py-2 rounded overflow-auto\">\n {workflow.webhookUrl}\n </code>\n <button\n type=\"button\"\n onClick={handleCopyWebhook}\n className=\"flex items-center gap-1 px-3 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors\"\n >\n {webhookCopied ? (\n <>\n <CheckIcon className=\"w-4 h-4 text-status-success-text\" />\n {t('bigconsole.workflows.actions.copied', 'Copied!')}\n </>\n ) : (\n <>\n <CopyIcon className=\"w-4 h-4\" />\n {t('bigconsole.workflows.actions.copy', 'Copy')}\n </>\n )}\n </button>\n </div>\n </div>\n )}\n\n {/* Workflow Design Preview (collapsible) */}\n {workflow.externalWorkflowId && (\n <div className=\"bg-bg-surface border border-border-default rounded-lg mb-8 overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setShowDesignPreview((prev) => !prev)}\n className=\"w-full flex items-center justify-between px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n <span>{t('bigconsole.workflows.view.designPreviewTitle', 'Workflow Design Preview')}</span>\n <ChevronDownIcon\n className={`w-4 h-4 text-text-secondary transition-transform ${showDesignPreview ? 'rotate-180' : ''}`}\n />\n </button>\n {showDesignPreview && (\n <div className=\"border-t border-border-default\" style={{ height: '450px' }}>\n <WorkflowBuilder\n apiGatewayUrl={apiGatewayUrl}\n workspaceId={workspaceId || 'default'}\n authToken={authToken}\n workflowId={workflow.externalWorkflowId}\n readonly\n hideHeader\n className=\"h-full\"\n />\n </div>\n )}\n </div>\n )}\n\n {/* Linked DataSinks */}\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4 mb-8\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {t('bigconsole.workflows.view.linkedDataSinksTitle', 'Linked DataSinks ({{count}})', {\n count: linkedDataSinkCount,\n })}\n </h3>\n {linkedDataSinkCount === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title={t('bigconsole.workflows.view.noDataSinksTitle', 'No data sinks linked')}\n description={t(\n 'bigconsole.workflows.view.noDataSinksDescription',\n \"This workflow has no data sinks linked yet — its output isn't being stored.\"\n )}\n />\n ) : (\n <div className=\"space-y-2\">\n {workflow.dataSinkLinks?.map((link) => (\n <div key={link.id} className=\"flex items-center justify-between px-3 py-2 bg-bg-sunken rounded-md\">\n <div className=\"flex items-center gap-3\">\n <DatabaseIcon className=\"w-4 h-4 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {link.dataSink?.name || link.dataSink?.key || link.dataSinkId}\n </p>\n {link.dataSink?.key && <p className=\"text-xs text-text-secondary font-mono\">{link.dataSink.key}</p>}\n </div>\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-2\">\n {link.isEnabled ? (\n <span className=\"text-xs text-status-success-text\">\n {t('bigconsole.workflows.view.dataSinkEnabled', 'Enabled')}\n </span>\n ) : (\n <span className=\"text-xs text-text-secondary\">\n {t('bigconsole.workflows.view.dataSinkDisabled', 'Disabled')}\n </span>\n )}\n <span className=\"text-xs text-text-secondary\">\n {t('bigconsole.workflows.view.dataSinkPriority', 'Priority: {{priority}}', {\n priority: link.priority,\n })}\n </span>\n </div>\n {link.dataSink && (\n <button\n type=\"button\"\n onClick={() => handleViewDataSink(link.dataSinkId)}\n className=\"text-xs text-action-primary-bg hover:underline\"\n >\n {t('bigconsole.workflows.actions.view', 'View')}\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Timestamps */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">\n {t('bigconsole.workflows.view.createdLabel', 'Created')}\n </h3>\n <p className=\"text-sm text-text-primary\">\n {formatDistanceToNow(new Date(workflow.createdAt), { addSuffix: true })}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t('bigconsole.workflows.view.byAuthor', 'by {{author}}', { author: workflow.createdBy })}\n </p>\n </div>\n <div className=\"bg-bg-surface border border-border-default rounded-lg p-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">\n {t('bigconsole.workflows.view.lastUpdatedLabel', 'Last Updated')}\n </h3>\n <p className=\"text-sm text-text-primary\">\n {formatDistanceToNow(new Date(workflow.updatedAt), { addSuffix: true })}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t('bigconsole.workflows.view.byAuthor', 'by {{author}}', {\n author: workflow.updatedBy || workflow.createdBy,\n })}\n </p>\n </div>\n </div>\n\n {/* Delete Confirmation Dialog */}\n {workflow && (\n <WorkflowDeleteDialog\n workflow={workflow}\n isOpen={showDeleteConfirm}\n onClose={() => setShowDeleteConfirm(false)}\n onConfirm={handleDelete}\n />\n )}\n </div>\n );\n});\n\nexport default WorkflowViewPage;\n"],"mappings":"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"}