@burdenoff/microfe-bigconsole 2026.622.1 → 2026.624.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/dist/bigconsole/BigConsoleRoutes.js +1 -1
  2. package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
  3. package/dist/bigconsole/components/DrilldownModal.js +4 -4
  4. package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
  5. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +1 -1
  6. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  7. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +2 -2
  8. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  9. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +1 -1
  10. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
  11. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +28 -28
  12. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  13. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +1 -1
  14. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  15. package/dist/bigconsole/components/datasink/DataSinkCard.js +4 -4
  16. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  17. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +2 -2
  18. package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
  19. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +2 -2
  20. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  21. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +2 -2
  22. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
  23. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +2 -2
  24. package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
  25. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +25 -25
  26. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  27. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +1 -1
  28. package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
  29. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +3 -3
  30. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
  31. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +2 -2
  32. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  33. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +2 -2
  34. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
  35. package/dist/bigconsole/components/parser/DataSinkSelector.js +3 -3
  36. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  37. package/dist/bigconsole/components/parser/ImportParserDialog.js +26 -26
  38. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  39. package/dist/bigconsole/components/parser/ParserCard.js +5 -5
  40. package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
  41. package/dist/bigconsole/components/parser/ParserSelector.js +6 -6
  42. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  43. package/dist/bigconsole/components/parser/ParserStatusBadge.js +1 -1
  44. package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
  45. package/dist/bigconsole/components/parser/ParserTypeBadge.js +1 -1
  46. package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
  47. package/dist/bigconsole/components/pipeline/PipelineCard.js +2 -2
  48. package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
  49. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +1 -1
  50. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
  51. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +1 -1
  52. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
  53. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +11 -11
  54. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  55. package/dist/bigconsole/components/widgets/PropertiesPanel.js +17 -17
  56. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  57. package/dist/bigconsole/components/widgets/WidgetConfigDialog.js +14 -14
  58. package/dist/bigconsole/components/widgets/WidgetConfigDialog.js.map +1 -1
  59. package/dist/bigconsole/components/widgets/WidgetHeader.js +4 -4
  60. package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
  61. package/dist/bigconsole/components/widgets/WidgetMenu.js +3 -3
  62. package/dist/bigconsole/components/widgets/WidgetMenu.js.map +1 -1
  63. package/dist/bigconsole/components/widgets/WidgetWrapper.js +266 -238
  64. package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
  65. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +1 -1
  66. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  67. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +2 -2
  68. package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
  69. package/dist/bigconsole/components/widgets/custom/CustomWidget.js +5 -5
  70. package/dist/bigconsole/components/widgets/custom/CustomWidget.js.map +1 -1
  71. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +1 -1
  72. package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
  73. package/dist/bigconsole/components/widgets/gauge/LinearGauge.js +1 -1
  74. package/dist/bigconsole/components/widgets/gauge/LinearGauge.js.map +1 -1
  75. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +2 -2
  76. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  77. package/dist/bigconsole/components/widgets/kpi/KPIWidget.js +2 -2
  78. package/dist/bigconsole/components/widgets/kpi/KPIWidget.js.map +1 -1
  79. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +2 -2
  80. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
  81. package/dist/bigconsole/components/widgets/list/ListItem.js +3 -3
  82. package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
  83. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +3 -3
  84. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
  85. package/dist/bigconsole/components/widgets/metric-card/ComparisonBadge.js +1 -1
  86. package/dist/bigconsole/components/widgets/metric-card/ComparisonBadge.js.map +1 -1
  87. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +2 -2
  88. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
  89. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +12 -12
  90. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  91. package/dist/bigconsole/components/widgets/progress/ProgressBar.js +2 -2
  92. package/dist/bigconsole/components/widgets/progress/ProgressBar.js.map +1 -1
  93. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +1 -1
  94. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  95. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +1 -1
  96. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
  97. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +2 -2
  98. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
  99. package/dist/bigconsole/components/widgets/states/EmptyState.js +1 -1
  100. package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
  101. package/dist/bigconsole/components/widgets/table/TableCell.js +1 -1
  102. package/dist/bigconsole/components/widgets/table/TableCell.js.map +1 -1
  103. package/dist/bigconsole/components/widgets/table/TableConfig.js +1 -1
  104. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  105. package/dist/bigconsole/components/widgets/table/TableHeader.js +2 -2
  106. package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
  107. package/dist/bigconsole/components/widgets/table/TablePagination.js +4 -4
  108. package/dist/bigconsole/components/widgets/table/TablePagination.js.map +1 -1
  109. package/dist/bigconsole/components/widgets/table/TableWidget.js +5 -5
  110. package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
  111. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +1 -1
  112. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
  113. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +3 -3
  114. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
  115. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +2 -2
  116. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -1
  117. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +3 -3
  118. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  119. package/dist/bigconsole/components/workflow/WorkflowCard.js +2 -2
  120. package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
  121. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +1 -1
  122. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
  123. package/dist/bigconsole/pages/DashboardBuilderPage.js +2 -2
  124. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  125. package/dist/bigconsole/pages/DashboardViewPage.js +1 -1
  126. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  127. package/dist/bigconsole/pages/DashboardsPage.js +2 -2
  128. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  129. package/dist/bigconsole/pages/DataSinkBuilderPage.js +3 -3
  130. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  131. package/dist/bigconsole/pages/DataSinkViewPage.js +2 -2
  132. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  133. package/dist/bigconsole/pages/ParserBuilderPage.js +5 -5
  134. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  135. package/dist/bigconsole/pages/ParserViewPage.js +1 -1
  136. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  137. package/dist/bigconsole/pages/PipelineBuilderPage.js +4 -4
  138. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  139. package/dist/bigconsole/pages/PipelineViewPage.js +9 -9
  140. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  141. package/dist/bigconsole/pages/WidgetDemoPage.js +2 -2
  142. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  143. package/dist/bigconsole/pages/WorkflowViewPage.js +5 -5
  144. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  145. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +12 -12
  146. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
  147. package/dist/bigconsole/renderers/adapters/BigConsoleRenderer.js +2 -2
  148. package/dist/bigconsole/renderers/adapters/BigConsoleRenderer.js.map +1 -1
  149. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +5 -5
  150. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
  151. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +2 -2
  152. package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
  153. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"LinkedWorkflowsPanel.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/LinkedWorkflowsPanel.tsx"],"sourcesContent":["/**\n * Linked Workflows Panel\n *\n * Panel displaying workflows linked to a DataSink.\n */\n\nimport { memo } from 'react';\nimport { formatDistanceToNow } from 'date-fns';\nimport { AppLink } from '../../contexts';\nimport type { DataSinkWorkflowLink, FluidGridsWorkflowStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface LinkedWorkflowsPanelProps {\n /** Workflow links */\n workflowLinks?: DataSinkWorkflowLink[];\n /** Whether loading */\n isLoading?: boolean;\n}\n\ninterface StatusConfig {\n label: string;\n bgColor: string;\n textColor: string;\n dotColor: string;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Get status display configuration\n */\nfunction getStatusConfig(status: FluidGridsWorkflowStatus): StatusConfig {\n switch (status) {\n case 'active':\n return {\n label: 'Active',\n bgColor: 'bg-state-success/10',\n textColor: 'text-state-success',\n dotColor: 'bg-state-success',\n };\n case 'paused':\n return {\n label: 'Paused',\n bgColor: 'bg-state-warning/10',\n textColor: 'text-state-warning',\n dotColor: 'bg-state-warning',\n };\n case 'error':\n return {\n label: 'Error',\n bgColor: 'bg-state-error/10',\n textColor: 'text-state-error',\n dotColor: 'bg-state-error',\n };\n case 'archived':\n return {\n label: 'Archived',\n bgColor: 'bg-text-tertiary/10',\n textColor: 'text-text-tertiary',\n dotColor: 'bg-text-tertiary',\n };\n default:\n return {\n label: 'Draft',\n bgColor: 'bg-action-primary-bg/10',\n textColor: 'text-action-primary-bg',\n dotColor: 'bg-action-primary-bg',\n };\n }\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst WorkflowIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M13 10V3L4 14h7v7l9-11h-7z\" />\n </svg>\n);\n\nconst LinkIcon = ({ 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=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"\n />\n </svg>\n);\n\nconst ChevronRightIcon = ({ 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=\"M9 5l7 7-7 7\" />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const LinkedWorkflowsPanel = memo(function LinkedWorkflowsPanel({\n workflowLinks = [],\n isLoading = false,\n}: LinkedWorkflowsPanelProps) {\n const enabledLinks = workflowLinks.filter((link) => link.isEnabled);\n const disabledLinks = workflowLinks.filter((link) => !link.isEnabled);\n\n return (\n <div className=\"border border-border-default rounded-lg bg-bg-surface overflow-hidden\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-border-default bg-bg-muted flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <LinkIcon className=\"w-4 h-4 text-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">Linked Workflows</h3>\n </div>\n <span className=\"text-xs text-text-secondary\">\n {workflowLinks.length} workflow{workflowLinks.length !== 1 ? 's' : ''}\n </span>\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n {/* Loading state */}\n {isLoading ? (\n <div className=\"flex items-center justify-center py-8\">\n <svg className=\"w-6 h-6 text-text-secondary 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 ) : workflowLinks.length === 0 ? (\n /* Empty state */\n <div className=\"text-center py-8\">\n <WorkflowIcon className=\"w-10 h-10 text-text-tertiary mx-auto mb-3\" />\n <p className=\"text-sm text-text-secondary mb-2\">No workflows linked</p>\n <p className=\"text-xs text-text-tertiary\">\n Link workflows from the Workflows page to push data to this DataSink\n </p>\n <AppLink\n to=\"/workflows\"\n className={`\n inline-flex items-center gap-1\n mt-4\n text-xs font-medium\n text-action-primary-bg\n hover:underline\n `}\n >\n Go to Workflows\n <ChevronRightIcon className=\"w-3 h-3\" />\n </AppLink>\n </div>\n ) : (\n /* Workflow list */\n <div className=\"space-y-3\">\n {/* Enabled workflows */}\n {enabledLinks.map((link) => {\n if (!link.workflow) return null;\n const statusConfig = getStatusConfig(link.workflow.status);\n return (\n <AppLink\n key={link.id}\n to={`/workflows/${link.workflow.id}`}\n className={`\n flex items-center justify-between\n p-3\n bg-bg-muted\n rounded-md\n hover:bg-border-default\n transition-colors\n group\n `}\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <WorkflowIcon className=\"w-5 h-5 text-text-secondary flex-shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate group-hover:text-action-primary-bg\">\n {link.workflow.name}\n </p>\n <p className=\"text-xs text-text-secondary font-mono truncate\">{link.workflow.key}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-3 flex-shrink-0\">\n {link.workflow.lastExecutedAt && (\n <span className=\"text-xs text-text-secondary hidden sm:inline\">\n {formatDistanceToNow(new Date(link.workflow.lastExecutedAt), {\n addSuffix: true,\n })}\n </span>\n )}\n <div className={`flex items-center gap-1.5 px-2 py-0.5 rounded-full ${statusConfig.bgColor}`}>\n <span className={`w-1.5 h-1.5 rounded-full ${statusConfig.dotColor}`} />\n <span className={`text-xs font-medium ${statusConfig.textColor}`}>{statusConfig.label}</span>\n </div>\n </div>\n </AppLink>\n );\n })}\n\n {/* Disabled workflows */}\n {disabledLinks.length > 0 && (\n <>\n <div className=\"pt-2 mt-2 border-t border-border-muted\">\n <p className=\"text-xs text-text-tertiary mb-2\">Disabled ({disabledLinks.length})</p>\n </div>\n {disabledLinks.map((link) => {\n if (!link.workflow) return null;\n return (\n <AppLink\n key={link.id}\n to={`/workflows/${link.workflow.id}`}\n className={`\n flex items-center justify-between\n p-3\n bg-bg-muted/50\n rounded-md\n hover:bg-bg-muted\n transition-colors\n opacity-60\n group\n `}\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <WorkflowIcon className=\"w-5 h-5 text-text-tertiary flex-shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-secondary truncate group-hover:text-text-primary\">\n {link.workflow.name}\n </p>\n <p className=\"text-xs text-text-tertiary font-mono truncate\">{link.workflow.key}</p>\n </div>\n </div>\n <span className=\"text-xs text-text-tertiary flex-shrink-0\">Disabled</span>\n </AppLink>\n );\n })}\n </>\n )}\n </div>\n )}\n </div>\n </div>\n );\n});\n\nexport default LinkedWorkflowsPanel;\n"],"mappings":"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"}
1
+ {"version":3,"file":"LinkedWorkflowsPanel.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/LinkedWorkflowsPanel.tsx"],"sourcesContent":["/**\n * Linked Workflows Panel\n *\n * Panel displaying workflows linked to a DataSink.\n */\n\nimport { memo } from 'react';\nimport { formatDistanceToNow } from 'date-fns';\nimport { AppLink } from '../../contexts';\nimport type { DataSinkWorkflowLink, FluidGridsWorkflowStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface LinkedWorkflowsPanelProps {\n /** Workflow links */\n workflowLinks?: DataSinkWorkflowLink[];\n /** Whether loading */\n isLoading?: boolean;\n}\n\ninterface StatusConfig {\n label: string;\n bgColor: string;\n textColor: string;\n dotColor: string;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Get status display configuration\n */\nfunction getStatusConfig(status: FluidGridsWorkflowStatus): StatusConfig {\n switch (status) {\n case 'active':\n return {\n label: 'Active',\n bgColor: 'bg-state-success/10',\n textColor: 'text-state-success',\n dotColor: 'bg-state-success',\n };\n case 'paused':\n return {\n label: 'Paused',\n bgColor: 'bg-state-warning/10',\n textColor: 'text-state-warning',\n dotColor: 'bg-state-warning',\n };\n case 'error':\n return {\n label: 'Error',\n bgColor: 'bg-state-error/10',\n textColor: 'text-state-error',\n dotColor: 'bg-state-error',\n };\n case 'archived':\n return {\n label: 'Archived',\n bgColor: 'bg-text-tertiary/10',\n textColor: 'text-text-tertiary',\n dotColor: 'bg-text-tertiary',\n };\n default:\n return {\n label: 'Draft',\n bgColor: 'bg-action-primary-bg/10',\n textColor: 'text-action-primary-bg',\n dotColor: 'bg-action-primary-bg',\n };\n }\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst WorkflowIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M13 10V3L4 14h7v7l9-11h-7z\" />\n </svg>\n);\n\nconst LinkIcon = ({ 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=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"\n />\n </svg>\n);\n\nconst ChevronRightIcon = ({ 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=\"M9 5l7 7-7 7\" />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const LinkedWorkflowsPanel = memo(function LinkedWorkflowsPanel({\n workflowLinks = [],\n isLoading = false,\n}: LinkedWorkflowsPanelProps) {\n const enabledLinks = workflowLinks.filter((link) => link.isEnabled);\n const disabledLinks = workflowLinks.filter((link) => !link.isEnabled);\n\n return (\n <div className=\"border border-border-default rounded-lg bg-bg-surface overflow-hidden\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-border-default bg-bg-sunken flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <LinkIcon className=\"w-4 h-4 text-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">Linked Workflows</h3>\n </div>\n <span className=\"text-xs text-text-secondary\">\n {workflowLinks.length} workflow{workflowLinks.length !== 1 ? 's' : ''}\n </span>\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n {/* Loading state */}\n {isLoading ? (\n <div className=\"flex items-center justify-center py-8\">\n <svg className=\"w-6 h-6 text-text-secondary 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 ) : workflowLinks.length === 0 ? (\n /* Empty state */\n <div className=\"text-center py-8\">\n <WorkflowIcon className=\"w-10 h-10 text-text-tertiary mx-auto mb-3\" />\n <p className=\"text-sm text-text-secondary mb-2\">No workflows linked</p>\n <p className=\"text-xs text-text-tertiary\">\n Link workflows from the Workflows page to push data to this DataSink\n </p>\n <AppLink\n to=\"/workflows\"\n className={`\n inline-flex items-center gap-1\n mt-4\n text-xs font-medium\n text-action-primary-bg\n hover:underline\n `}\n >\n Go to Workflows\n <ChevronRightIcon className=\"w-3 h-3\" />\n </AppLink>\n </div>\n ) : (\n /* Workflow list */\n <div className=\"space-y-3\">\n {/* Enabled workflows */}\n {enabledLinks.map((link) => {\n if (!link.workflow) return null;\n const statusConfig = getStatusConfig(link.workflow.status);\n return (\n <AppLink\n key={link.id}\n to={`/workflows/${link.workflow.id}`}\n className={`\n flex items-center justify-between\n p-3\n bg-bg-sunken\n rounded-md\n hover:bg-border-default\n transition-colors\n group\n `}\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <WorkflowIcon className=\"w-5 h-5 text-text-secondary flex-shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate group-hover:text-action-primary-bg\">\n {link.workflow.name}\n </p>\n <p className=\"text-xs text-text-secondary font-mono truncate\">{link.workflow.key}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-3 flex-shrink-0\">\n {link.workflow.lastExecutedAt && (\n <span className=\"text-xs text-text-secondary hidden sm:inline\">\n {formatDistanceToNow(new Date(link.workflow.lastExecutedAt), {\n addSuffix: true,\n })}\n </span>\n )}\n <div className={`flex items-center gap-1.5 px-2 py-0.5 rounded-full ${statusConfig.bgColor}`}>\n <span className={`w-1.5 h-1.5 rounded-full ${statusConfig.dotColor}`} />\n <span className={`text-xs font-medium ${statusConfig.textColor}`}>{statusConfig.label}</span>\n </div>\n </div>\n </AppLink>\n );\n })}\n\n {/* Disabled workflows */}\n {disabledLinks.length > 0 && (\n <>\n <div className=\"pt-2 mt-2 border-t border-border-muted\">\n <p className=\"text-xs text-text-tertiary mb-2\">Disabled ({disabledLinks.length})</p>\n </div>\n {disabledLinks.map((link) => {\n if (!link.workflow) return null;\n return (\n <AppLink\n key={link.id}\n to={`/workflows/${link.workflow.id}`}\n className={`\n flex items-center justify-between\n p-3\n bg-bg-sunken/50\n rounded-md\n hover:bg-bg-sunken\n transition-colors\n opacity-60\n group\n `}\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <WorkflowIcon className=\"w-5 h-5 text-text-tertiary flex-shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-secondary truncate group-hover:text-text-primary\">\n {link.workflow.name}\n </p>\n <p className=\"text-xs text-text-tertiary font-mono truncate\">{link.workflow.key}</p>\n </div>\n </div>\n <span className=\"text-xs text-text-tertiary flex-shrink-0\">Disabled</span>\n </AppLink>\n );\n })}\n </>\n )}\n </div>\n )}\n </div>\n </div>\n );\n});\n\nexport default LinkedWorkflowsPanel;\n"],"mappings":";;;;;;AAoCA,SAAS,EAAgB,GAAgD;AACvE,SAAQ,GAAR;EACE,KAAK,SACH,QAAO;GACL,OAAO;GACP,SAAS;GACT,WAAW;GACX,UAAU;GACX;EACH,KAAK,SACH,QAAO;GACL,OAAO;GACP,SAAS;GACT,WAAW;GACX,UAAU;GACX;EACH,KAAK,QACH,QAAO;GACL,OAAO;GACP,SAAS;GACT,WAAW;GACX,UAAU;GACX;EACH,KAAK,WACH,QAAO;GACL,OAAO;GACP,SAAS;GACT,WAAW;GACX,UAAU;GACX;EACH,QACE,QAAO;GACL,OAAO;GACP,SAAS;GACT,WAAW;GACX,UAAU;GACX;;;AAQP,IAAM,KAAgB,EAAE,mBACtB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EAAM,eAAc;EAAQ,gBAAe;EAAQ,aAAa;EAAK,GAAE;EAA+B,CAAA;CAClG,CAAA,EAGF,KAAY,EAAE,mBAClB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAGF,KAAoB,EAAE,mBAC1B,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EAAM,eAAc;EAAQ,gBAAe;EAAQ,aAAa;EAAG,GAAE;EAAiB,CAAA;CAClF,CAAA,EAOK,IAAuB,EAAK,SAA8B,EACrE,mBAAgB,EAAE,EAClB,eAAY,MACgB;CAC5B,IAAM,IAAe,EAAc,QAAQ,MAAS,EAAK,UAAU,EAC7D,IAAgB,EAAc,QAAQ,MAAS,CAAC,EAAK,UAAU;AAErE,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA,EACpD,kBAAC,MAAD;KAAI,WAAU;eAA0C;KAAqB,CAAA,CACzE;OACN,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACG,EAAc;KAAO;KAAU,EAAc,WAAW,IAAU,KAAN;KACxD;MACH;MAGN,kBAAC,OAAD;GAAK,WAAU;aAEZ,IACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;KAA2C,MAAK;KAAO,SAAQ;eAA9E,CACE,kBAAC,UAAD;MAAQ,WAAU;MAAa,IAAG;MAAK,IAAG;MAAK,GAAE;MAAK,QAAO;MAAe,aAAY;MAAM,CAAA,EAC9F,kBAAC,QAAD;MACE,WAAU;MACV,MAAK;MACL,GAAE;MACF,CAAA,CACE;;IACF,CAAA,GACJ,EAAc,WAAW,IAE3B,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAc,WAAU,6CAA8C,CAAA;KACtE,kBAAC,KAAD;MAAG,WAAU;gBAAmC;MAAuB,CAAA;KACvE,kBAAC,KAAD;MAAG,WAAU;gBAA6B;MAEtC,CAAA;KACJ,kBAAC,GAAD;MACE,IAAG;MACH,WAAW;gBAFb,CASC,mBAEC,kBAAC,GAAD,EAAkB,WAAU,WAAY,CAAA,CAChC;;KACN;QAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEG,EAAa,KAAK,MAAS;AAC1B,SAAI,CAAC,EAAK,SAAU,QAAO;KAC3B,IAAM,IAAe,EAAgB,EAAK,SAAS,OAAO;AAC1D,YACE,kBAAC,GAAD;MAEE,IAAI,cAAc,EAAK,SAAS;MAChC,WAAW;gBAHb,CAaE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAc,WAAU,6CAA8C,CAAA,EACtE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAK,SAAS;SACb,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBAAkD,EAAK,SAAS;SAAQ,CAAA,CACjF;UACF;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,EAAK,SAAS,kBACb,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAoB,IAAI,KAAK,EAAK,SAAS,eAAe,EAAE,EAC3D,WAAW,IACZ,CAAC;QACG,CAAA,EAET,kBAAC,OAAD;QAAK,WAAW,sDAAsD,EAAa;kBAAnF,CACE,kBAAC,QAAD,EAAM,WAAW,4BAA4B,EAAa,YAAc,CAAA,EACxE,kBAAC,QAAD;SAAM,WAAW,uBAAuB,EAAa;mBAAc,EAAa;SAAa,CAAA,CACzF;UACF;SACE;QAlCH,EAAK,GAkCF;MAEZ,EAGD,EAAc,SAAS,KACtB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,KAAD;MAAG,WAAU;gBAAb;OAA+C;OAAW,EAAc;OAAO;OAAK;;KAChF,CAAA,EACL,EAAc,KAAK,MACb,EAAK,WAER,kBAAC,GAAD;KAEE,IAAI,cAAc,EAAK,SAAS;KAChC,WAAW;eAHb,CAcE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAc,WAAU,4CAA6C,CAAA,EACrE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAK,SAAS;QACb,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAAiD,EAAK,SAAS;QAAQ,CAAA,CAChF;SACF;SACN,kBAAC,QAAD;MAAM,WAAU;gBAA2C;MAAe,CAAA,CAClE;OAvBH,EAAK,GAuBF,GA1Be,KA4B3B,CACD,EAAA,CAAA,CAED;;GAEJ,CAAA,CACF;;EAER"}
@@ -251,7 +251,7 @@ var u = e(function({ value: e, onChange: u, disabled: d = !1, error: f }) {
251
251
  onChange: D,
252
252
  disabled: d,
253
253
  placeholder: "*/15 * * * *",
254
- className: "\n w-full px-3 py-2\n bg-bg-muted\n border rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n font-mono\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n border-border-default\n "
254
+ className: "\n w-full px-3 py-2\n bg-bg-sunken\n border rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n font-mono\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n border-border-default\n "
255
255
  }), /* @__PURE__ */ a("p", {
256
256
  className: "mt-1 text-xs text-text-tertiary",
257
257
  children: "Enter a cron expression (e.g., */15 * * * * for every 15 minutes)"
@@ -264,7 +264,7 @@ var u = e(function({ value: e, onChange: u, disabled: d = !1, error: f }) {
264
264
  value: x,
265
265
  onChange: O,
266
266
  disabled: d,
267
- className: "\n w-full px-3 py-2\n bg-bg-muted\n border border-border-default rounded-md\n text-sm text-text-primary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n ",
267
+ className: "\n w-full px-3 py-2\n bg-bg-sunken\n border border-border-default rounded-md\n text-sm text-text-primary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n ",
268
268
  children: c.map((e) => /* @__PURE__ */ a("option", {
269
269
  value: e.value,
270
270
  children: e.label
@@ -1 +1 @@
1
- {"version":3,"file":"RefreshTypeSelector.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/RefreshTypeSelector.tsx"],"sourcesContent":["/**\n * Refresh Type Selector\n *\n * Component for selecting data refresh type (manual or scheduled).\n */\n\nimport { memo, useState, useEffect, useCallback, useRef } from 'react';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface SchedulePreset {\n label: string;\n cron: string;\n description: string;\n}\n\ninterface TimezoneOption {\n value: string;\n label: string;\n}\n\ninterface RefreshSchedule {\n cron: string;\n timezone: string;\n}\n\ninterface RefreshConfig {\n type: 'manual' | 'scheduled';\n schedule?: RefreshSchedule;\n}\n\ninterface RefreshTypeSelectorProps {\n /** Current refresh configuration */\n value?: RefreshConfig;\n /** Callback when configuration changes */\n onChange: (config: RefreshConfig) => void;\n /** Whether selector is disabled */\n disabled?: boolean;\n /** Error message */\n error?: string;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst SCHEDULE_PRESETS: SchedulePreset[] = [\n {\n label: 'Every 5 minutes',\n cron: '*/5 * * * *',\n description: 'High frequency updates',\n },\n {\n label: 'Every 15 minutes',\n cron: '*/15 * * * *',\n description: 'Balanced frequency',\n },\n {\n label: 'Every hour',\n cron: '0 * * * *',\n description: 'Hourly updates',\n },\n {\n label: 'Every day at midnight',\n cron: '0 0 * * *',\n description: 'Daily updates',\n },\n];\n\nconst TIMEZONE_OPTIONS: TimezoneOption[] = [\n { value: 'UTC', label: 'UTC' },\n { value: 'America/New_York', label: 'Eastern Time (US)' },\n { value: 'America/Los_Angeles', label: 'Pacific Time (US)' },\n { value: 'Europe/London', label: 'London (UK)' },\n { value: 'Europe/Paris', label: 'Paris (EU)' },\n { value: 'Asia/Tokyo', label: 'Tokyo (Japan)' },\n { value: 'Asia/Kolkata', label: 'India (IST)' },\n { value: 'Australia/Sydney', label: 'Sydney (Australia)' },\n];\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Find preset by cron expression\n */\nfunction findPresetByCron(cron: string): SchedulePreset | null {\n return SCHEDULE_PRESETS.find((preset) => preset.cron === cron) || null;\n}\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const RefreshTypeSelector = memo(function RefreshTypeSelector({\n value,\n onChange,\n disabled = false,\n error,\n}: RefreshTypeSelectorProps) {\n // State\n const [refreshType, setRefreshType] = useState<'manual' | 'scheduled'>(value?.type || 'manual');\n const [selectedPreset, setSelectedPreset] = useState<SchedulePreset | null>(\n value?.schedule ? findPresetByCron(value.schedule.cron) || null : SCHEDULE_PRESETS[1]\n );\n const [isCustomSchedule, setIsCustomSchedule] = useState(\n value?.schedule ? !findPresetByCron(value.schedule.cron) : false\n );\n const [customCron, setCustomCron] = useState(value?.schedule?.cron || '');\n const [timezone, setTimezone] = useState(value?.schedule?.timezone || 'UTC');\n const prevValueRef = useRef(value);\n\n // Sync state when value changes (using deferred update to avoid cascading renders)\n useEffect(() => {\n if (prevValueRef.current !== value && value) {\n prevValueRef.current = value;\n // Defer state updates to avoid synchronous setState in effect\n queueMicrotask(() => {\n setRefreshType(value.type);\n if (value.schedule) {\n setTimezone(value.schedule.timezone);\n const preset = findPresetByCron(value.schedule.cron);\n if (preset) {\n setSelectedPreset(preset);\n setIsCustomSchedule(false);\n } else {\n setCustomCron(value.schedule.cron);\n setIsCustomSchedule(true);\n }\n }\n });\n }\n }, [value]);\n\n // Handle refresh type change\n const handleTypeChange = useCallback(\n (type: 'manual' | 'scheduled') => {\n if (disabled) return;\n setRefreshType(type);\n if (type === 'manual') {\n onChange({ type: 'manual' });\n } else {\n const cron = isCustomSchedule ? customCron : selectedPreset?.cron || SCHEDULE_PRESETS[1].cron;\n onChange({\n type: 'scheduled',\n schedule: { cron, timezone },\n });\n }\n },\n [disabled, onChange, isCustomSchedule, customCron, selectedPreset, timezone]\n );\n\n // Handle preset selection\n const handlePresetSelect = useCallback(\n (preset: SchedulePreset) => {\n if (disabled) return;\n setSelectedPreset(preset);\n setIsCustomSchedule(false);\n onChange({\n type: 'scheduled',\n schedule: { cron: preset.cron, timezone },\n });\n },\n [disabled, onChange, timezone]\n );\n\n // Handle custom schedule toggle\n const handleCustomToggle = useCallback(() => {\n if (disabled) return;\n setIsCustomSchedule(true);\n setSelectedPreset(null);\n if (customCron) {\n onChange({\n type: 'scheduled',\n schedule: { cron: customCron, timezone },\n });\n }\n }, [disabled, onChange, customCron, timezone]);\n\n // Handle custom cron change\n const handleCustomCronChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const cron = e.target.value;\n setCustomCron(cron);\n if (cron.trim()) {\n onChange({\n type: 'scheduled',\n schedule: { cron, timezone },\n });\n }\n },\n [onChange, timezone]\n );\n\n // Handle timezone change\n const handleTimezoneChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const tz = e.target.value;\n setTimezone(tz);\n if (refreshType === 'scheduled') {\n const cron = isCustomSchedule ? customCron : selectedPreset?.cron || '';\n onChange({\n type: 'scheduled',\n schedule: { cron, timezone: tz },\n });\n }\n },\n [onChange, refreshType, isCustomSchedule, customCron, selectedPreset]\n );\n\n return (\n <div className=\"space-y-4\">\n {/* Label */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Refresh Type</label>\n <p className=\"text-xs text-text-secondary\">When should this data be updated?</p>\n </div>\n\n {/* Options */}\n <div className=\"space-y-3\">\n {/* Manual option */}\n <label\n className={`\n flex items-start gap-3\n p-4\n border rounded-lg\n cursor-pointer\n transition-all\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${\n refreshType === 'manual'\n ? 'border-action-primary-bg bg-action-primary-bg/5'\n : 'border-border-default hover:border-border-hover'\n }\n `}\n >\n <input\n type=\"radio\"\n name=\"refresh-type\"\n checked={refreshType === 'manual'}\n onChange={() => handleTypeChange('manual')}\n disabled={disabled}\n className={`\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n `}\n />\n <div className=\"flex-1\">\n <span className=\"text-sm font-medium text-text-primary\">Manual</span>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n Data refreshes only when you click the &quot;Refresh&quot; button\n </p>\n </div>\n </label>\n\n {/* Scheduled option */}\n <div\n className={`\n border rounded-lg\n transition-all\n ${disabled ? 'opacity-50' : ''}\n ${refreshType === 'scheduled' ? 'border-action-primary-bg bg-action-primary-bg/5' : 'border-border-default'}\n `}\n >\n <label\n className={`\n flex items-start gap-3\n p-4\n cursor-pointer\n ${disabled ? 'cursor-not-allowed' : ''}\n `}\n >\n <input\n type=\"radio\"\n name=\"refresh-type\"\n checked={refreshType === 'scheduled'}\n onChange={() => handleTypeChange('scheduled')}\n disabled={disabled}\n className={`\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n `}\n />\n <div className=\"flex-1\">\n <span className=\"text-sm font-medium text-text-primary\">Automatic</span>\n <p className=\"text-xs text-text-secondary mt-0.5\">Data refreshes on a schedule</p>\n </div>\n </label>\n\n {/* Schedule options (shown when scheduled is selected) */}\n {refreshType === 'scheduled' && (\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Schedule presets */}\n <div className=\"border-t border-border-default pt-4\">\n <label className=\"block text-xs font-medium text-text-secondary mb-2\">Schedule</label>\n <div className=\"grid grid-cols-2 gap-2\">\n {SCHEDULE_PRESETS.map((preset) => (\n <button\n key={preset.cron}\n type=\"button\"\n onClick={() => handlePresetSelect(preset)}\n disabled={disabled}\n className={`\n px-3 py-2\n text-left\n border rounded-md\n transition-colors\n ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}\n ${\n !isCustomSchedule && selectedPreset?.cron === preset.cron\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default hover:border-border-hover'\n }\n `}\n >\n <span className=\"text-sm font-medium\">{preset.label}</span>\n </button>\n ))}\n </div>\n </div>\n\n {/* Custom schedule */}\n <div>\n <button\n type=\"button\"\n onClick={handleCustomToggle}\n disabled={disabled}\n className={`\n text-xs\n ${isCustomSchedule ? 'text-action-primary-bg' : 'text-text-secondary hover:text-text-primary'}\n `}\n >\n {isCustomSchedule ? 'Using custom schedule' : 'Use custom schedule...'}\n </button>\n {isCustomSchedule && (\n <div className=\"mt-2\">\n <input\n type=\"text\"\n value={customCron}\n onChange={handleCustomCronChange}\n disabled={disabled}\n placeholder=\"*/15 * * * *\"\n className={`\n w-full px-3 py-2\n bg-bg-muted\n border rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n font-mono\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n border-border-default\n `}\n />\n <p className=\"mt-1 text-xs text-text-tertiary\">\n Enter a cron expression (e.g., */15 * * * * for every 15 minutes)\n </p>\n </div>\n )}\n </div>\n\n {/* Timezone */}\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-2\">Timezone</label>\n <select\n value={timezone}\n onChange={handleTimezoneChange}\n disabled={disabled}\n className={`\n w-full px-3 py-2\n bg-bg-muted\n border border-border-default rounded-md\n text-sm text-text-primary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n `}\n >\n {TIMEZONE_OPTIONS.map((tz) => (\n <option key={tz.value} value={tz.value}>\n {tz.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Error message */}\n {error && (\n <div className=\"flex items-start gap-2\">\n <svg\n className=\"w-4 h-4 text-state-error flex-shrink-0 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\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 <p className=\"text-xs text-state-error\">{error}</p>\n </div>\n )}\n </div>\n );\n});\n\nexport default RefreshTypeSelector;\n"],"mappings":"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"}
1
+ {"version":3,"file":"RefreshTypeSelector.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/RefreshTypeSelector.tsx"],"sourcesContent":["/**\n * Refresh Type Selector\n *\n * Component for selecting data refresh type (manual or scheduled).\n */\n\nimport { memo, useState, useEffect, useCallback, useRef } from 'react';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface SchedulePreset {\n label: string;\n cron: string;\n description: string;\n}\n\ninterface TimezoneOption {\n value: string;\n label: string;\n}\n\ninterface RefreshSchedule {\n cron: string;\n timezone: string;\n}\n\ninterface RefreshConfig {\n type: 'manual' | 'scheduled';\n schedule?: RefreshSchedule;\n}\n\ninterface RefreshTypeSelectorProps {\n /** Current refresh configuration */\n value?: RefreshConfig;\n /** Callback when configuration changes */\n onChange: (config: RefreshConfig) => void;\n /** Whether selector is disabled */\n disabled?: boolean;\n /** Error message */\n error?: string;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst SCHEDULE_PRESETS: SchedulePreset[] = [\n {\n label: 'Every 5 minutes',\n cron: '*/5 * * * *',\n description: 'High frequency updates',\n },\n {\n label: 'Every 15 minutes',\n cron: '*/15 * * * *',\n description: 'Balanced frequency',\n },\n {\n label: 'Every hour',\n cron: '0 * * * *',\n description: 'Hourly updates',\n },\n {\n label: 'Every day at midnight',\n cron: '0 0 * * *',\n description: 'Daily updates',\n },\n];\n\nconst TIMEZONE_OPTIONS: TimezoneOption[] = [\n { value: 'UTC', label: 'UTC' },\n { value: 'America/New_York', label: 'Eastern Time (US)' },\n { value: 'America/Los_Angeles', label: 'Pacific Time (US)' },\n { value: 'Europe/London', label: 'London (UK)' },\n { value: 'Europe/Paris', label: 'Paris (EU)' },\n { value: 'Asia/Tokyo', label: 'Tokyo (Japan)' },\n { value: 'Asia/Kolkata', label: 'India (IST)' },\n { value: 'Australia/Sydney', label: 'Sydney (Australia)' },\n];\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Find preset by cron expression\n */\nfunction findPresetByCron(cron: string): SchedulePreset | null {\n return SCHEDULE_PRESETS.find((preset) => preset.cron === cron) || null;\n}\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const RefreshTypeSelector = memo(function RefreshTypeSelector({\n value,\n onChange,\n disabled = false,\n error,\n}: RefreshTypeSelectorProps) {\n // State\n const [refreshType, setRefreshType] = useState<'manual' | 'scheduled'>(value?.type || 'manual');\n const [selectedPreset, setSelectedPreset] = useState<SchedulePreset | null>(\n value?.schedule ? findPresetByCron(value.schedule.cron) || null : SCHEDULE_PRESETS[1]\n );\n const [isCustomSchedule, setIsCustomSchedule] = useState(\n value?.schedule ? !findPresetByCron(value.schedule.cron) : false\n );\n const [customCron, setCustomCron] = useState(value?.schedule?.cron || '');\n const [timezone, setTimezone] = useState(value?.schedule?.timezone || 'UTC');\n const prevValueRef = useRef(value);\n\n // Sync state when value changes (using deferred update to avoid cascading renders)\n useEffect(() => {\n if (prevValueRef.current !== value && value) {\n prevValueRef.current = value;\n // Defer state updates to avoid synchronous setState in effect\n queueMicrotask(() => {\n setRefreshType(value.type);\n if (value.schedule) {\n setTimezone(value.schedule.timezone);\n const preset = findPresetByCron(value.schedule.cron);\n if (preset) {\n setSelectedPreset(preset);\n setIsCustomSchedule(false);\n } else {\n setCustomCron(value.schedule.cron);\n setIsCustomSchedule(true);\n }\n }\n });\n }\n }, [value]);\n\n // Handle refresh type change\n const handleTypeChange = useCallback(\n (type: 'manual' | 'scheduled') => {\n if (disabled) return;\n setRefreshType(type);\n if (type === 'manual') {\n onChange({ type: 'manual' });\n } else {\n const cron = isCustomSchedule ? customCron : selectedPreset?.cron || SCHEDULE_PRESETS[1].cron;\n onChange({\n type: 'scheduled',\n schedule: { cron, timezone },\n });\n }\n },\n [disabled, onChange, isCustomSchedule, customCron, selectedPreset, timezone]\n );\n\n // Handle preset selection\n const handlePresetSelect = useCallback(\n (preset: SchedulePreset) => {\n if (disabled) return;\n setSelectedPreset(preset);\n setIsCustomSchedule(false);\n onChange({\n type: 'scheduled',\n schedule: { cron: preset.cron, timezone },\n });\n },\n [disabled, onChange, timezone]\n );\n\n // Handle custom schedule toggle\n const handleCustomToggle = useCallback(() => {\n if (disabled) return;\n setIsCustomSchedule(true);\n setSelectedPreset(null);\n if (customCron) {\n onChange({\n type: 'scheduled',\n schedule: { cron: customCron, timezone },\n });\n }\n }, [disabled, onChange, customCron, timezone]);\n\n // Handle custom cron change\n const handleCustomCronChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const cron = e.target.value;\n setCustomCron(cron);\n if (cron.trim()) {\n onChange({\n type: 'scheduled',\n schedule: { cron, timezone },\n });\n }\n },\n [onChange, timezone]\n );\n\n // Handle timezone change\n const handleTimezoneChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const tz = e.target.value;\n setTimezone(tz);\n if (refreshType === 'scheduled') {\n const cron = isCustomSchedule ? customCron : selectedPreset?.cron || '';\n onChange({\n type: 'scheduled',\n schedule: { cron, timezone: tz },\n });\n }\n },\n [onChange, refreshType, isCustomSchedule, customCron, selectedPreset]\n );\n\n return (\n <div className=\"space-y-4\">\n {/* Label */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Refresh Type</label>\n <p className=\"text-xs text-text-secondary\">When should this data be updated?</p>\n </div>\n\n {/* Options */}\n <div className=\"space-y-3\">\n {/* Manual option */}\n <label\n className={`\n flex items-start gap-3\n p-4\n border rounded-lg\n cursor-pointer\n transition-all\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${\n refreshType === 'manual'\n ? 'border-action-primary-bg bg-action-primary-bg/5'\n : 'border-border-default hover:border-border-hover'\n }\n `}\n >\n <input\n type=\"radio\"\n name=\"refresh-type\"\n checked={refreshType === 'manual'}\n onChange={() => handleTypeChange('manual')}\n disabled={disabled}\n className={`\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n `}\n />\n <div className=\"flex-1\">\n <span className=\"text-sm font-medium text-text-primary\">Manual</span>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n Data refreshes only when you click the &quot;Refresh&quot; button\n </p>\n </div>\n </label>\n\n {/* Scheduled option */}\n <div\n className={`\n border rounded-lg\n transition-all\n ${disabled ? 'opacity-50' : ''}\n ${refreshType === 'scheduled' ? 'border-action-primary-bg bg-action-primary-bg/5' : 'border-border-default'}\n `}\n >\n <label\n className={`\n flex items-start gap-3\n p-4\n cursor-pointer\n ${disabled ? 'cursor-not-allowed' : ''}\n `}\n >\n <input\n type=\"radio\"\n name=\"refresh-type\"\n checked={refreshType === 'scheduled'}\n onChange={() => handleTypeChange('scheduled')}\n disabled={disabled}\n className={`\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n `}\n />\n <div className=\"flex-1\">\n <span className=\"text-sm font-medium text-text-primary\">Automatic</span>\n <p className=\"text-xs text-text-secondary mt-0.5\">Data refreshes on a schedule</p>\n </div>\n </label>\n\n {/* Schedule options (shown when scheduled is selected) */}\n {refreshType === 'scheduled' && (\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Schedule presets */}\n <div className=\"border-t border-border-default pt-4\">\n <label className=\"block text-xs font-medium text-text-secondary mb-2\">Schedule</label>\n <div className=\"grid grid-cols-2 gap-2\">\n {SCHEDULE_PRESETS.map((preset) => (\n <button\n key={preset.cron}\n type=\"button\"\n onClick={() => handlePresetSelect(preset)}\n disabled={disabled}\n className={`\n px-3 py-2\n text-left\n border rounded-md\n transition-colors\n ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}\n ${\n !isCustomSchedule && selectedPreset?.cron === preset.cron\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default hover:border-border-hover'\n }\n `}\n >\n <span className=\"text-sm font-medium\">{preset.label}</span>\n </button>\n ))}\n </div>\n </div>\n\n {/* Custom schedule */}\n <div>\n <button\n type=\"button\"\n onClick={handleCustomToggle}\n disabled={disabled}\n className={`\n text-xs\n ${isCustomSchedule ? 'text-action-primary-bg' : 'text-text-secondary hover:text-text-primary'}\n `}\n >\n {isCustomSchedule ? 'Using custom schedule' : 'Use custom schedule...'}\n </button>\n {isCustomSchedule && (\n <div className=\"mt-2\">\n <input\n type=\"text\"\n value={customCron}\n onChange={handleCustomCronChange}\n disabled={disabled}\n placeholder=\"*/15 * * * *\"\n className={`\n w-full px-3 py-2\n bg-bg-sunken\n border rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n font-mono\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n border-border-default\n `}\n />\n <p className=\"mt-1 text-xs text-text-tertiary\">\n Enter a cron expression (e.g., */15 * * * * for every 15 minutes)\n </p>\n </div>\n )}\n </div>\n\n {/* Timezone */}\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-2\">Timezone</label>\n <select\n value={timezone}\n onChange={handleTimezoneChange}\n disabled={disabled}\n className={`\n w-full px-3 py-2\n bg-bg-sunken\n border border-border-default rounded-md\n text-sm text-text-primary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n `}\n >\n {TIMEZONE_OPTIONS.map((tz) => (\n <option key={tz.value} value={tz.value}>\n {tz.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Error message */}\n {error && (\n <div className=\"flex items-start gap-2\">\n <svg\n className=\"w-4 h-4 text-state-error flex-shrink-0 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\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 <p className=\"text-xs text-state-error\">{error}</p>\n </div>\n )}\n </div>\n );\n});\n\nexport default RefreshTypeSelector;\n"],"mappings":"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"}
@@ -74,7 +74,7 @@ var o = ({ className: e }) => /* @__PURE__ */ n("svg", {
74
74
  return /* @__PURE__ */ r("div", {
75
75
  className: "border border-border-default rounded-lg bg-bg-surface overflow-hidden",
76
76
  children: [/* @__PURE__ */ r("div", {
77
- className: "px-4 py-3 border-b border-border-default bg-bg-muted flex items-center justify-between",
77
+ className: "px-4 py-3 border-b border-border-default bg-bg-sunken flex items-center justify-between",
78
78
  children: [/* @__PURE__ */ r("div", {
79
79
  className: "flex items-center gap-2",
80
80
  children: [/* @__PURE__ */ n(o, { className: "w-4 h-4 text-text-secondary" }), /* @__PURE__ */ n("h3", {
@@ -149,7 +149,7 @@ var o = ({ className: e }) => /* @__PURE__ */ n("svg", {
149
149
  }), g && /* @__PURE__ */ r("button", {
150
150
  type: "button",
151
151
  onClick: g,
152
- className: "\n flex items-center gap-1.5\n px-3 py-1.5\n text-xs font-medium\n text-text-secondary\n rounded-md\n hover:bg-bg-muted\n transition-colors\n ",
152
+ className: "\n flex items-center gap-1.5\n px-3 py-1.5\n text-xs font-medium\n text-text-secondary\n rounded-md\n hover:bg-bg-sunken\n transition-colors\n ",
153
153
  children: [/* @__PURE__ */ n(c, { className: "w-3.5 h-3.5" }), "View in FluidGrids"]
154
154
  })]
155
155
  })
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowStatusPanel.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/WorkflowStatusPanel.tsx"],"sourcesContent":["/**\n * Workflow Status Panel\n *\n * Panel showing FluidGrids workflow status and execution details.\n */\n\nimport { memo, useMemo } from 'react';\nimport { formatDistanceToNow } from 'date-fns';\nimport type { DataSinkSetupState, DataSinkStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface WorkflowStatusPanelProps {\n /** Workflow ID */\n workflowId?: string;\n /** Execution ID */\n executionId?: string;\n /** Last refreshed timestamp */\n lastRefreshedAt?: string;\n /** Setup state */\n setupState?: DataSinkSetupState;\n /** DataSink status */\n status?: DataSinkStatus;\n /** Error metadata */\n errorMetadata?: {\n code?: string;\n message?: string;\n };\n /** Callback to re-run workflow */\n onRerunWorkflow?: () => void;\n /** Callback to view workflow */\n onViewWorkflow?: () => void;\n /** Whether controls are disabled */\n disabled?: boolean;\n /** Whether re-run is in progress */\n isRerunning?: boolean;\n}\n\ninterface StatusConfig {\n label: string;\n bgColor: string;\n textColor: string;\n dotColor: string;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Get status display configuration\n */\nfunction getStatusConfig(setupState?: DataSinkSetupState, status?: DataSinkStatus): StatusConfig {\n if (status === 'refreshing' || setupState === 'workflow_running') {\n return {\n label: 'Running',\n bgColor: 'bg-action-primary-bg/10',\n textColor: 'text-action-primary-bg',\n dotColor: 'bg-action-primary-bg',\n };\n }\n if (status === 'error') {\n return {\n label: 'Failed',\n bgColor: 'bg-state-error/10',\n textColor: 'text-state-error',\n dotColor: 'bg-state-error',\n };\n }\n if (setupState === 'workflow_pending') {\n return {\n label: 'Pending',\n bgColor: 'bg-state-warning/10',\n textColor: 'text-state-warning',\n dotColor: 'bg-state-warning',\n };\n }\n return {\n label: 'Completed',\n bgColor: 'bg-state-success/10',\n textColor: 'text-state-success',\n dotColor: 'bg-state-success',\n };\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst WorkflowIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M13 10V3L4 14h7v7l9-11h-7z\" />\n </svg>\n);\n\nconst RefreshIcon = ({ className, spinning }: { className?: string; spinning?: boolean }) => (\n <svg\n className={`${className} ${spinning ? 'animate-spin' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n);\n\nconst ExternalLinkIcon = ({ 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=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n);\n\nconst AlertIcon = ({ 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 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const WorkflowStatusPanel = memo(function WorkflowStatusPanel({\n workflowId,\n executionId,\n lastRefreshedAt,\n setupState,\n status,\n errorMetadata,\n onRerunWorkflow,\n onViewWorkflow,\n disabled = false,\n isRerunning = false,\n}: WorkflowStatusPanelProps) {\n // Get status config\n const statusConfig = useMemo(() => getStatusConfig(setupState, status), [setupState, status]);\n\n const isRunning = status === 'refreshing' || setupState === 'workflow_running' || isRerunning;\n\n const lastRefreshedText = lastRefreshedAt\n ? formatDistanceToNow(new Date(lastRefreshedAt), { addSuffix: true })\n : 'Never';\n\n return (\n <div className=\"border border-border-default rounded-lg bg-bg-surface overflow-hidden\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-border-default bg-bg-muted flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <WorkflowIcon className=\"w-4 h-4 text-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">FluidGrids Workflow</h3>\n </div>\n <div className={`flex items-center gap-1.5 px-2 py-0.5 rounded-full ${statusConfig.bgColor}`}>\n <span className={`w-1.5 h-1.5 rounded-full ${statusConfig.dotColor} ${isRunning ? 'animate-pulse' : ''}`} />\n <span className={`text-xs font-medium ${statusConfig.textColor}`}>{statusConfig.label}</span>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"p-4 space-y-4\">\n {/* Details grid */}\n <div className=\"grid grid-cols-2 gap-4 text-sm\">\n <div>\n <p className=\"text-text-secondary text-xs mb-1\">Workflow ID</p>\n <p className=\"text-text-primary font-mono text-xs truncate\" title={workflowId}>\n {workflowId || 'Not linked'}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary text-xs mb-1\">Last Execution</p>\n <p className=\"text-text-primary text-xs\">{lastRefreshedText}</p>\n </div>\n {executionId && (\n <div className=\"col-span-2\">\n <p className=\"text-text-secondary text-xs mb-1\">Execution ID</p>\n <p className=\"text-text-primary font-mono text-xs truncate\" title={executionId}>\n {executionId}\n </p>\n </div>\n )}\n </div>\n\n {/* Error display */}\n {status === 'error' && errorMetadata && (\n <div className=\"flex items-start gap-2 p-3 bg-state-error/10 rounded-md\">\n <AlertIcon className=\"w-4 h-4 text-state-error flex-shrink-0 mt-0.5\" />\n <div className=\"min-w-0\">\n {errorMetadata.code && <p className=\"text-xs font-medium text-state-error\">{errorMetadata.code}</p>}\n <p className=\"text-xs text-state-error/80 mt-0.5\">\n {errorMetadata.message || 'An error occurred during workflow execution'}\n </p>\n </div>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-muted\">\n {onRerunWorkflow && (\n <button\n type=\"button\"\n onClick={onRerunWorkflow}\n disabled={disabled || isRunning}\n className={`\n flex items-center gap-1.5\n px-3 py-1.5\n text-xs font-medium\n bg-action-primary-bg\n text-action-primary-fg\n rounded-md\n hover:bg-action-primary-bgHover\n disabled:opacity-50\n disabled:cursor-not-allowed\n transition-colors\n `}\n >\n <RefreshIcon className=\"w-3.5 h-3.5\" spinning={isRunning} />\n {isRunning ? 'Running...' : 'Re-run Workflow'}\n </button>\n )}\n {onViewWorkflow && (\n <button\n type=\"button\"\n onClick={onViewWorkflow}\n className={`\n flex items-center gap-1.5\n px-3 py-1.5\n text-xs font-medium\n text-text-secondary\n rounded-md\n hover:bg-bg-muted\n transition-colors\n `}\n >\n <ExternalLinkIcon className=\"w-3.5 h-3.5\" />\n View in FluidGrids\n </button>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nexport default WorkflowStatusPanel;\n"],"mappings":"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"}
1
+ {"version":3,"file":"WorkflowStatusPanel.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/WorkflowStatusPanel.tsx"],"sourcesContent":["/**\n * Workflow Status Panel\n *\n * Panel showing FluidGrids workflow status and execution details.\n */\n\nimport { memo, useMemo } from 'react';\nimport { formatDistanceToNow } from 'date-fns';\nimport type { DataSinkSetupState, DataSinkStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface WorkflowStatusPanelProps {\n /** Workflow ID */\n workflowId?: string;\n /** Execution ID */\n executionId?: string;\n /** Last refreshed timestamp */\n lastRefreshedAt?: string;\n /** Setup state */\n setupState?: DataSinkSetupState;\n /** DataSink status */\n status?: DataSinkStatus;\n /** Error metadata */\n errorMetadata?: {\n code?: string;\n message?: string;\n };\n /** Callback to re-run workflow */\n onRerunWorkflow?: () => void;\n /** Callback to view workflow */\n onViewWorkflow?: () => void;\n /** Whether controls are disabled */\n disabled?: boolean;\n /** Whether re-run is in progress */\n isRerunning?: boolean;\n}\n\ninterface StatusConfig {\n label: string;\n bgColor: string;\n textColor: string;\n dotColor: string;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Get status display configuration\n */\nfunction getStatusConfig(setupState?: DataSinkSetupState, status?: DataSinkStatus): StatusConfig {\n if (status === 'refreshing' || setupState === 'workflow_running') {\n return {\n label: 'Running',\n bgColor: 'bg-action-primary-bg/10',\n textColor: 'text-action-primary-bg',\n dotColor: 'bg-action-primary-bg',\n };\n }\n if (status === 'error') {\n return {\n label: 'Failed',\n bgColor: 'bg-state-error/10',\n textColor: 'text-state-error',\n dotColor: 'bg-state-error',\n };\n }\n if (setupState === 'workflow_pending') {\n return {\n label: 'Pending',\n bgColor: 'bg-state-warning/10',\n textColor: 'text-state-warning',\n dotColor: 'bg-state-warning',\n };\n }\n return {\n label: 'Completed',\n bgColor: 'bg-state-success/10',\n textColor: 'text-state-success',\n dotColor: 'bg-state-success',\n };\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst WorkflowIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M13 10V3L4 14h7v7l9-11h-7z\" />\n </svg>\n);\n\nconst RefreshIcon = ({ className, spinning }: { className?: string; spinning?: boolean }) => (\n <svg\n className={`${className} ${spinning ? 'animate-spin' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n);\n\nconst ExternalLinkIcon = ({ 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=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n);\n\nconst AlertIcon = ({ 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 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const WorkflowStatusPanel = memo(function WorkflowStatusPanel({\n workflowId,\n executionId,\n lastRefreshedAt,\n setupState,\n status,\n errorMetadata,\n onRerunWorkflow,\n onViewWorkflow,\n disabled = false,\n isRerunning = false,\n}: WorkflowStatusPanelProps) {\n // Get status config\n const statusConfig = useMemo(() => getStatusConfig(setupState, status), [setupState, status]);\n\n const isRunning = status === 'refreshing' || setupState === 'workflow_running' || isRerunning;\n\n const lastRefreshedText = lastRefreshedAt\n ? formatDistanceToNow(new Date(lastRefreshedAt), { addSuffix: true })\n : 'Never';\n\n return (\n <div className=\"border border-border-default rounded-lg bg-bg-surface overflow-hidden\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-border-default bg-bg-sunken flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <WorkflowIcon className=\"w-4 h-4 text-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">FluidGrids Workflow</h3>\n </div>\n <div className={`flex items-center gap-1.5 px-2 py-0.5 rounded-full ${statusConfig.bgColor}`}>\n <span className={`w-1.5 h-1.5 rounded-full ${statusConfig.dotColor} ${isRunning ? 'animate-pulse' : ''}`} />\n <span className={`text-xs font-medium ${statusConfig.textColor}`}>{statusConfig.label}</span>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"p-4 space-y-4\">\n {/* Details grid */}\n <div className=\"grid grid-cols-2 gap-4 text-sm\">\n <div>\n <p className=\"text-text-secondary text-xs mb-1\">Workflow ID</p>\n <p className=\"text-text-primary font-mono text-xs truncate\" title={workflowId}>\n {workflowId || 'Not linked'}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary text-xs mb-1\">Last Execution</p>\n <p className=\"text-text-primary text-xs\">{lastRefreshedText}</p>\n </div>\n {executionId && (\n <div className=\"col-span-2\">\n <p className=\"text-text-secondary text-xs mb-1\">Execution ID</p>\n <p className=\"text-text-primary font-mono text-xs truncate\" title={executionId}>\n {executionId}\n </p>\n </div>\n )}\n </div>\n\n {/* Error display */}\n {status === 'error' && errorMetadata && (\n <div className=\"flex items-start gap-2 p-3 bg-state-error/10 rounded-md\">\n <AlertIcon className=\"w-4 h-4 text-state-error flex-shrink-0 mt-0.5\" />\n <div className=\"min-w-0\">\n {errorMetadata.code && <p className=\"text-xs font-medium text-state-error\">{errorMetadata.code}</p>}\n <p className=\"text-xs text-state-error/80 mt-0.5\">\n {errorMetadata.message || 'An error occurred during workflow execution'}\n </p>\n </div>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-muted\">\n {onRerunWorkflow && (\n <button\n type=\"button\"\n onClick={onRerunWorkflow}\n disabled={disabled || isRunning}\n className={`\n flex items-center gap-1.5\n px-3 py-1.5\n text-xs font-medium\n bg-action-primary-bg\n text-action-primary-fg\n rounded-md\n hover:bg-action-primary-bgHover\n disabled:opacity-50\n disabled:cursor-not-allowed\n transition-colors\n `}\n >\n <RefreshIcon className=\"w-3.5 h-3.5\" spinning={isRunning} />\n {isRunning ? 'Running...' : 'Re-run Workflow'}\n </button>\n )}\n {onViewWorkflow && (\n <button\n type=\"button\"\n onClick={onViewWorkflow}\n className={`\n flex items-center gap-1.5\n px-3 py-1.5\n text-xs font-medium\n text-text-secondary\n rounded-md\n hover:bg-bg-sunken\n transition-colors\n `}\n >\n <ExternalLinkIcon className=\"w-3.5 h-3.5\" />\n View in FluidGrids\n </button>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nexport default WorkflowStatusPanel;\n"],"mappings":"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"}
@@ -96,7 +96,7 @@ var u = ({ className: e }) => /* @__PURE__ */ s("svg", {
96
96
  placeholder: "Search data sources...",
97
97
  value: y,
98
98
  onChange: (e) => b(e.target.value),
99
- className: "\n w-full px-3 py-2\n bg-bg-muted\n border border-border-default\n rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n "
99
+ className: "\n w-full px-3 py-2\n bg-bg-sunken\n border border-border-default\n rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n "
100
100
  })
101
101
  }), /* @__PURE__ */ s("div", {
102
102
  className: "overflow-y-auto flex-1",
@@ -112,7 +112,7 @@ var u = ({ className: e }) => /* @__PURE__ */ s("svg", {
112
112
  className: `
113
113
  w-full px-3 py-2
114
114
  text-left text-sm
115
- hover:bg-bg-muted
115
+ hover:bg-bg-sunken
116
116
  transition-colors
117
117
  ${r === null ? "bg-action-primary-bg/10 text-action-primary-bg" : "text-text-secondary"}
118
118
  `,
@@ -126,7 +126,7 @@ var u = ({ className: e }) => /* @__PURE__ */ s("svg", {
126
126
  className: `
127
127
  w-full px-3 py-2.5
128
128
  text-left
129
- hover:bg-bg-muted
129
+ hover:bg-bg-sunken
130
130
  transition-colors
131
131
  border-b border-border-default last:border-b-0
132
132
  ${r === e.key ? "bg-action-primary-bg/10" : ""}
@@ -1 +1 @@
1
- {"version":3,"file":"DataSinkSelector.js","names":[],"sources":["../../../../src/bigconsole/components/parser/DataSinkSelector.tsx"],"sourcesContent":["/**\n * DataSink Selector\n *\n * Dropdown component for selecting a DataSink as a parser's input source.\n */\n\nimport { memo, useState, useMemo, useCallback, Fragment } from 'react';\nimport { useDataSinkOperations } from '../../hooks/useDataSinkOperations';\nimport { DataSinkStatusBadge } from '../datasink/DataSinkStatusBadge';\nimport type { DataSinkStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface DataSinkSelectorProps {\n /** Currently selected DataSink key */\n value: string | null;\n /** Callback when selection changes */\n onChange: (key: string | null) => void;\n /** Filter by status */\n filterStatus?: DataSinkStatus;\n /** Placeholder text */\n placeholder?: string;\n /** Whether the selector is disabled */\n disabled?: boolean;\n /** Whether to show error state */\n error?: boolean;\n /** Error message to display */\n errorMessage?: string;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Format relative time from date string\n */\nfunction formatRelativeTime(dateString: string | null | undefined): string {\n if (!dateString) return 'Never';\n\n const date = new Date(dateString);\n const diff = Date.now() - date.getTime();\n const minutes = Math.floor(diff / 60000);\n\n if (minutes < 1) return 'Just now';\n if (minutes < 60) return `${minutes}m ago`;\n\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n\n const days = Math.floor(hours / 24);\n if (days < 7) return `${days}d ago`;\n\n return date.toLocaleDateString();\n}\n\n// ============================================================================\n// ICONS\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 DataSinkSelector = memo(function DataSinkSelector({\n value,\n onChange,\n filterStatus,\n placeholder = 'Select a data source...',\n disabled = false,\n error = false,\n errorMessage,\n}: DataSinkSelectorProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n\n const { dataSinks, loading } = useDataSinkOperations({ skipFetch: false });\n\n // Filter data sinks\n const filteredDataSinks = useMemo(\n () =>\n dataSinks.filter((ds) => {\n // Filter by status if specified\n if (filterStatus && ds.status !== filterStatus) return false;\n\n // Filter by search query\n if (searchQuery) {\n const query = searchQuery.toLowerCase();\n return (\n (ds.name || ds.key).toLowerCase().includes(query) ||\n ds.key.toLowerCase().includes(query) ||\n ds.description?.toLowerCase().includes(query)\n );\n }\n\n return true;\n }),\n [dataSinks, filterStatus, searchQuery]\n );\n\n // Find selected DataSink\n const selectedDataSink = useMemo(() => dataSinks.find((ds) => ds.key === value), [dataSinks, value]);\n\n // Handle selection\n const handleSelect = useCallback(\n (key: string | null) => {\n onChange(key);\n setIsOpen(false);\n setSearchQuery('');\n },\n [onChange]\n );\n\n // Toggle dropdown\n const handleToggle = useCallback(() => {\n if (!disabled) {\n setIsOpen((prev) => !prev);\n }\n }, [disabled]);\n\n // Close dropdown\n const handleClose = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n return (\n <div className=\"relative\">\n {/* Trigger button */}\n <button\n type=\"button\"\n onClick={handleToggle}\n disabled={disabled}\n className={`\n w-full\n px-3 py-2\n bg-bg-surface\n border rounded-md\n text-left\n flex items-center justify-between gap-2\n transition-colors\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-action-primary-bg cursor-pointer'}\n ${error ? 'border-state-error' : 'border-border-default'}\n ${isOpen ? 'border-action-primary-bg ring-2 ring-action-primary-bg/20' : ''}\n `}\n >\n <div className=\"flex-1 min-w-0\">\n {selectedDataSink ? (\n <div className=\"flex items-center gap-2\">\n <DataSinkStatusBadge status={selectedDataSink.status} size=\"sm\" showIcon={false} />\n <span className=\"text-sm text-text-primary truncate\">\n {selectedDataSink.name || selectedDataSink.key}\n </span>\n </div>\n ) : (\n <span className=\"text-sm text-text-tertiary\">{placeholder}</span>\n )}\n </div>\n\n <ChevronDownIcon\n className={`w-4 h-4 text-text-secondary transition-transform ${isOpen ? 'transform rotate-180' : ''}`}\n />\n </button>\n\n {/* Error message */}\n {error && errorMessage && <p className=\"mt-1 text-xs text-state-error\">{errorMessage}</p>}\n\n {/* Dropdown */}\n {isOpen && (\n <Fragment>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-10\" onClick={handleClose} />\n\n {/* Dropdown content */}\n <div className=\"absolute left-0 right-0 top-full mt-1 z-20 bg-bg-surface border border-border-default rounded-md shadow-lg max-h-80 flex flex-col overflow-hidden\">\n {/* Search input */}\n <div className=\"p-2 border-b border-border-default\">\n <input\n type=\"text\"\n placeholder=\"Search data sources...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className={`\n w-full px-3 py-2\n bg-bg-muted\n border border-border-default\n rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n `}\n />\n </div>\n\n {/* Options list */}\n <div className=\"overflow-y-auto flex-1\">\n {loading ? (\n <div className=\"p-4 text-center text-sm text-text-secondary\">Loading data sources...</div>\n ) : filteredDataSinks.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-text-secondary\">\n {searchQuery ? 'No matching data sources found' : 'No data sources available'}\n </div>\n ) : (\n <Fragment>\n {/* None option */}\n <button\n type=\"button\"\n onClick={() => handleSelect(null)}\n className={`\n w-full px-3 py-2\n text-left text-sm\n hover:bg-bg-muted\n transition-colors\n ${value === null ? 'bg-action-primary-bg/10 text-action-primary-bg' : 'text-text-secondary'}\n `}\n >\n <span className=\"italic\">None</span>\n </button>\n\n {/* DataSink options */}\n {filteredDataSinks.map((ds) => (\n <button\n key={ds.id}\n type=\"button\"\n onClick={() => handleSelect(ds.key)}\n className={`\n w-full px-3 py-2.5\n text-left\n hover:bg-bg-muted\n transition-colors\n border-b border-border-default last:border-b-0\n ${value === ds.key ? 'bg-action-primary-bg/10' : ''}\n `}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n {/* Name and status */}\n <div className=\"flex items-center gap-2 mb-1\">\n <DataSinkStatusBadge status={ds.status} size=\"sm\" showIcon={false} />\n <span className=\"text-sm font-medium text-text-primary truncate\">{ds.name || ds.key}</span>\n </div>\n\n {/* Description */}\n {ds.description && (\n <p className=\"text-xs text-text-secondary line-clamp-1 mb-1\">{ds.description}</p>\n )}\n\n {/* Metadata */}\n <div className=\"flex items-center gap-2 text-xs text-text-tertiary\">\n <span>key: {ds.key}</span>\n <span>•</span>\n <span>Refreshed: {formatRelativeTime(ds.lastRefreshedAt)}</span>\n </div>\n </div>\n </div>\n </button>\n ))}\n </Fragment>\n )}\n </div>\n </div>\n </Fragment>\n )}\n </div>\n );\n});\n\nexport default DataSinkSelector;\n"],"mappings":"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"}
1
+ {"version":3,"file":"DataSinkSelector.js","names":[],"sources":["../../../../src/bigconsole/components/parser/DataSinkSelector.tsx"],"sourcesContent":["/**\n * DataSink Selector\n *\n * Dropdown component for selecting a DataSink as a parser's input source.\n */\n\nimport { memo, useState, useMemo, useCallback, Fragment } from 'react';\nimport { useDataSinkOperations } from '../../hooks/useDataSinkOperations';\nimport { DataSinkStatusBadge } from '../datasink/DataSinkStatusBadge';\nimport type { DataSinkStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface DataSinkSelectorProps {\n /** Currently selected DataSink key */\n value: string | null;\n /** Callback when selection changes */\n onChange: (key: string | null) => void;\n /** Filter by status */\n filterStatus?: DataSinkStatus;\n /** Placeholder text */\n placeholder?: string;\n /** Whether the selector is disabled */\n disabled?: boolean;\n /** Whether to show error state */\n error?: boolean;\n /** Error message to display */\n errorMessage?: string;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Format relative time from date string\n */\nfunction formatRelativeTime(dateString: string | null | undefined): string {\n if (!dateString) return 'Never';\n\n const date = new Date(dateString);\n const diff = Date.now() - date.getTime();\n const minutes = Math.floor(diff / 60000);\n\n if (minutes < 1) return 'Just now';\n if (minutes < 60) return `${minutes}m ago`;\n\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n\n const days = Math.floor(hours / 24);\n if (days < 7) return `${days}d ago`;\n\n return date.toLocaleDateString();\n}\n\n// ============================================================================\n// ICONS\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 DataSinkSelector = memo(function DataSinkSelector({\n value,\n onChange,\n filterStatus,\n placeholder = 'Select a data source...',\n disabled = false,\n error = false,\n errorMessage,\n}: DataSinkSelectorProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n\n const { dataSinks, loading } = useDataSinkOperations({ skipFetch: false });\n\n // Filter data sinks\n const filteredDataSinks = useMemo(\n () =>\n dataSinks.filter((ds) => {\n // Filter by status if specified\n if (filterStatus && ds.status !== filterStatus) return false;\n\n // Filter by search query\n if (searchQuery) {\n const query = searchQuery.toLowerCase();\n return (\n (ds.name || ds.key).toLowerCase().includes(query) ||\n ds.key.toLowerCase().includes(query) ||\n ds.description?.toLowerCase().includes(query)\n );\n }\n\n return true;\n }),\n [dataSinks, filterStatus, searchQuery]\n );\n\n // Find selected DataSink\n const selectedDataSink = useMemo(() => dataSinks.find((ds) => ds.key === value), [dataSinks, value]);\n\n // Handle selection\n const handleSelect = useCallback(\n (key: string | null) => {\n onChange(key);\n setIsOpen(false);\n setSearchQuery('');\n },\n [onChange]\n );\n\n // Toggle dropdown\n const handleToggle = useCallback(() => {\n if (!disabled) {\n setIsOpen((prev) => !prev);\n }\n }, [disabled]);\n\n // Close dropdown\n const handleClose = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n return (\n <div className=\"relative\">\n {/* Trigger button */}\n <button\n type=\"button\"\n onClick={handleToggle}\n disabled={disabled}\n className={`\n w-full\n px-3 py-2\n bg-bg-surface\n border rounded-md\n text-left\n flex items-center justify-between gap-2\n transition-colors\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-action-primary-bg cursor-pointer'}\n ${error ? 'border-state-error' : 'border-border-default'}\n ${isOpen ? 'border-action-primary-bg ring-2 ring-action-primary-bg/20' : ''}\n `}\n >\n <div className=\"flex-1 min-w-0\">\n {selectedDataSink ? (\n <div className=\"flex items-center gap-2\">\n <DataSinkStatusBadge status={selectedDataSink.status} size=\"sm\" showIcon={false} />\n <span className=\"text-sm text-text-primary truncate\">\n {selectedDataSink.name || selectedDataSink.key}\n </span>\n </div>\n ) : (\n <span className=\"text-sm text-text-tertiary\">{placeholder}</span>\n )}\n </div>\n\n <ChevronDownIcon\n className={`w-4 h-4 text-text-secondary transition-transform ${isOpen ? 'transform rotate-180' : ''}`}\n />\n </button>\n\n {/* Error message */}\n {error && errorMessage && <p className=\"mt-1 text-xs text-state-error\">{errorMessage}</p>}\n\n {/* Dropdown */}\n {isOpen && (\n <Fragment>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-10\" onClick={handleClose} />\n\n {/* Dropdown content */}\n <div className=\"absolute left-0 right-0 top-full mt-1 z-20 bg-bg-surface border border-border-default rounded-md shadow-lg max-h-80 flex flex-col overflow-hidden\">\n {/* Search input */}\n <div className=\"p-2 border-b border-border-default\">\n <input\n type=\"text\"\n placeholder=\"Search data sources...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className={`\n w-full px-3 py-2\n bg-bg-sunken\n border border-border-default\n rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n `}\n />\n </div>\n\n {/* Options list */}\n <div className=\"overflow-y-auto flex-1\">\n {loading ? (\n <div className=\"p-4 text-center text-sm text-text-secondary\">Loading data sources...</div>\n ) : filteredDataSinks.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-text-secondary\">\n {searchQuery ? 'No matching data sources found' : 'No data sources available'}\n </div>\n ) : (\n <Fragment>\n {/* None option */}\n <button\n type=\"button\"\n onClick={() => handleSelect(null)}\n className={`\n w-full px-3 py-2\n text-left text-sm\n hover:bg-bg-sunken\n transition-colors\n ${value === null ? 'bg-action-primary-bg/10 text-action-primary-bg' : 'text-text-secondary'}\n `}\n >\n <span className=\"italic\">None</span>\n </button>\n\n {/* DataSink options */}\n {filteredDataSinks.map((ds) => (\n <button\n key={ds.id}\n type=\"button\"\n onClick={() => handleSelect(ds.key)}\n className={`\n w-full px-3 py-2.5\n text-left\n hover:bg-bg-sunken\n transition-colors\n border-b border-border-default last:border-b-0\n ${value === ds.key ? 'bg-action-primary-bg/10' : ''}\n `}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n {/* Name and status */}\n <div className=\"flex items-center gap-2 mb-1\">\n <DataSinkStatusBadge status={ds.status} size=\"sm\" showIcon={false} />\n <span className=\"text-sm font-medium text-text-primary truncate\">{ds.name || ds.key}</span>\n </div>\n\n {/* Description */}\n {ds.description && (\n <p className=\"text-xs text-text-secondary line-clamp-1 mb-1\">{ds.description}</p>\n )}\n\n {/* Metadata */}\n <div className=\"flex items-center gap-2 text-xs text-text-tertiary\">\n <span>key: {ds.key}</span>\n <span>•</span>\n <span>Refreshed: {formatRelativeTime(ds.lastRefreshedAt)}</span>\n </div>\n </div>\n </div>\n </button>\n ))}\n </Fragment>\n )}\n </div>\n </div>\n </Fragment>\n )}\n </div>\n );\n});\n\nexport default DataSinkSelector;\n"],"mappings":"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"}
@@ -62,7 +62,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
62
62
  /* @__PURE__ */ h(w, { children: [/* @__PURE__ */ h("div", {
63
63
  className: "flex items-center gap-3",
64
64
  children: [/* @__PURE__ */ m("div", {
65
- className: "flex size-10 items-center justify-center rounded-lg bg-primary/10",
65
+ className: "flex size-10 items-center justify-center rounded-lg bg-action-primary-bg/10",
66
66
  children: /* @__PURE__ */ m(d, { className: "size-5 text-primary" })
67
67
  }), /* @__PURE__ */ m(T, { children: "Import Parser" })]
68
68
  }), /* @__PURE__ */ m(S, { children: "Upload a Parser export file to restore it into this workspace." })] }),
@@ -74,13 +74,13 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
74
74
  onDrop: te,
75
75
  className: "border-2 border-dashed rounded-lg p-8 text-center hover:border-primary transition-colors",
76
76
  children: [
77
- /* @__PURE__ */ m(c, { className: "size-12 mx-auto text-muted-foreground mb-4" }),
77
+ /* @__PURE__ */ m(c, { className: "size-12 mx-auto text-text-secondary mb-4" }),
78
78
  /* @__PURE__ */ m("p", {
79
79
  className: "text-sm mb-2",
80
80
  children: "Drag and drop a parser export file here"
81
81
  }),
82
82
  /* @__PURE__ */ m("p", {
83
- className: "text-xs text-muted-foreground mb-4",
83
+ className: "text-xs text-text-secondary mb-4",
84
84
  children: "or"
85
85
  }),
86
86
  /* @__PURE__ */ m("input", {
@@ -96,7 +96,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
96
96
  children: "Browse Files"
97
97
  }),
98
98
  /* @__PURE__ */ m("p", {
99
- className: "text-xs text-muted-foreground mt-4",
99
+ className: "text-xs text-text-secondary mt-4",
100
100
  children: "Only .json files exported from BigConsole are supported"
101
101
  })
102
102
  ]
@@ -108,7 +108,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
108
108
  /* @__PURE__ */ h("div", {
109
109
  className: "flex items-center justify-between",
110
110
  children: [/* @__PURE__ */ m("span", {
111
- className: "text-sm text-muted-foreground",
111
+ className: "text-sm text-text-secondary",
112
112
  children: "Parser"
113
113
  }), /* @__PURE__ */ m("span", {
114
114
  className: "text-sm font-medium",
@@ -118,7 +118,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
118
118
  /* @__PURE__ */ h("div", {
119
119
  className: "flex items-center justify-between",
120
120
  children: [/* @__PURE__ */ m("span", {
121
- className: "text-sm text-muted-foreground",
121
+ className: "text-sm text-text-secondary",
122
122
  children: "Type"
123
123
  }), /* @__PURE__ */ m(g, {
124
124
  variant: "secondary",
@@ -128,7 +128,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
128
128
  /* @__PURE__ */ h("div", {
129
129
  className: "flex items-center justify-between",
130
130
  children: [/* @__PURE__ */ m("span", {
131
- className: "text-sm text-muted-foreground",
131
+ className: "text-sm text-text-secondary",
132
132
  children: "Input Sink"
133
133
  }), /* @__PURE__ */ m("span", {
134
134
  className: "text-xs font-mono",
@@ -138,7 +138,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
138
138
  /* @__PURE__ */ h("div", {
139
139
  className: "flex items-center justify-between",
140
140
  children: [/* @__PURE__ */ m("span", {
141
- className: "text-sm text-muted-foreground",
141
+ className: "text-sm text-text-secondary",
142
142
  children: "Output Key"
143
143
  }), /* @__PURE__ */ m("span", {
144
144
  className: "text-xs font-mono",
@@ -148,33 +148,33 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
148
148
  K.parserInfo.exportedFrom && /* @__PURE__ */ h("div", {
149
149
  className: "flex items-center justify-between",
150
150
  children: [/* @__PURE__ */ m("span", {
151
- className: "text-sm text-muted-foreground",
151
+ className: "text-sm text-text-secondary",
152
152
  children: "Source ID"
153
153
  }), /* @__PURE__ */ m("span", {
154
- className: "text-xs text-muted-foreground font-mono truncate max-w-[180px]",
154
+ className: "text-xs text-text-secondary font-mono truncate max-w-[180px]",
155
155
  children: K.parserInfo.exportedFrom
156
156
  })]
157
157
  }),
158
158
  /* @__PURE__ */ h("div", {
159
159
  className: "flex items-center justify-between",
160
160
  children: [/* @__PURE__ */ m("span", {
161
- className: "text-sm text-muted-foreground",
161
+ className: "text-sm text-text-secondary",
162
162
  children: "Schema Version"
163
163
  }), /* @__PURE__ */ m("span", {
164
- className: "text-xs text-muted-foreground",
164
+ className: "text-xs text-text-secondary",
165
165
  children: K.parserInfo.schemaVersion
166
166
  })]
167
167
  })
168
168
  ]
169
169
  }) }),
170
170
  K.errors.length > 0 && /* @__PURE__ */ m(v, {
171
- className: "border-destructive/50 bg-destructive/5",
171
+ className: "border-status-error-border/50 bg-status-error-bg/5",
172
172
  children: /* @__PURE__ */ h(y, {
173
173
  className: "p-3",
174
174
  children: [/* @__PURE__ */ h("div", {
175
175
  className: "flex items-center gap-2 mb-2",
176
- children: [/* @__PURE__ */ m(f, { className: "size-4 text-destructive" }), /* @__PURE__ */ h("span", {
177
- className: "text-sm font-medium text-destructive",
176
+ children: [/* @__PURE__ */ m(f, { className: "size-4 text-status-error-text" }), /* @__PURE__ */ h("span", {
177
+ className: "text-sm font-medium text-status-error-text",
178
178
  children: [
179
179
  "Errors (",
180
180
  K.errors.length,
@@ -182,7 +182,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
182
182
  ]
183
183
  })]
184
184
  }), /* @__PURE__ */ m("ul", {
185
- className: "text-xs text-destructive space-y-1",
185
+ className: "text-xs text-status-error-text space-y-1",
186
186
  children: K.errors.map((e, t) => /* @__PURE__ */ h("li", { children: [
187
187
  /* @__PURE__ */ h("span", {
188
188
  className: "font-mono",
@@ -273,7 +273,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
273
273
  disabled: M === "importing"
274
274
  }),
275
275
  /* @__PURE__ */ m("p", {
276
- className: "text-xs text-muted-foreground",
276
+ className: "text-xs text-text-secondary",
277
277
  children: "The DataSink key to read input data from."
278
278
  })
279
279
  ]
@@ -294,7 +294,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
294
294
  disabled: M === "importing"
295
295
  }),
296
296
  /* @__PURE__ */ m("p", {
297
- className: "text-xs text-muted-foreground",
297
+ className: "text-xs text-text-secondary",
298
298
  children: "The key to store parsed output data under."
299
299
  })
300
300
  ]
@@ -315,7 +315,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
315
315
  children: "Parser Already Exists"
316
316
  }),
317
317
  /* @__PURE__ */ h("p", {
318
- className: "text-sm text-muted-foreground mb-4",
318
+ className: "text-sm text-text-secondary mb-4",
319
319
  children: [
320
320
  "Parser \"",
321
321
  q.parser?.name,
@@ -333,7 +333,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
333
333
  children: "Parser Updated!"
334
334
  }),
335
335
  /* @__PURE__ */ h("p", {
336
- className: "text-sm text-muted-foreground mb-4",
336
+ className: "text-sm text-text-secondary mb-4",
337
337
  children: [
338
338
  "Parser \"",
339
339
  q.parser?.name,
@@ -351,7 +351,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
351
351
  children: "Import Successful!"
352
352
  }),
353
353
  /* @__PURE__ */ h("p", {
354
- className: "text-sm text-muted-foreground mb-4",
354
+ className: "text-sm text-text-secondary mb-4",
355
355
  children: [
356
356
  "Parser \"",
357
357
  q.parser?.name,
@@ -362,21 +362,21 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
362
362
  ]
363
363
  }),
364
364
  G && /* @__PURE__ */ m(v, {
365
- className: "border-destructive/50 bg-destructive/5",
365
+ className: "border-status-error-border/50 bg-status-error-bg/5",
366
366
  children: /* @__PURE__ */ m(y, {
367
367
  className: "p-3",
368
368
  children: /* @__PURE__ */ m("p", {
369
- className: "text-sm text-destructive",
369
+ className: "text-sm text-status-error-text",
370
370
  children: G.message
371
371
  })
372
372
  })
373
373
  }),
374
374
  q && !q.success && q.errorMessage && /* @__PURE__ */ m(v, {
375
- className: "border-destructive/50 bg-destructive/5",
375
+ className: "border-status-error-border/50 bg-status-error-bg/5",
376
376
  children: /* @__PURE__ */ m(y, {
377
377
  className: "p-3",
378
378
  children: /* @__PURE__ */ m("p", {
379
- className: "text-sm text-destructive",
379
+ className: "text-sm text-status-error-text",
380
380
  children: q.errorMessage
381
381
  })
382
382
  })
@@ -407,7 +407,7 @@ var k = t(function({ isOpen: t, onClose: k, consoleId: A, onSuccess: j }) {
407
407
  children: [/* @__PURE__ */ m(d, { className: "size-4" }), "Import Parser"]
408
408
  }),
409
409
  M === "importing" && /* @__PURE__ */ h("div", {
410
- className: "flex items-center gap-2 text-sm text-muted-foreground",
410
+ className: "flex items-center gap-2 text-sm text-text-secondary",
411
411
  children: [/* @__PURE__ */ m(O, { className: "size-4" }), "Importing..."]
412
412
  }),
413
413
  M === "complete" && /* @__PURE__ */ m(_, {