@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.
- package/dist/bigconsole/BigConsoleRoutes.js +1 -1
- package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
- package/dist/bigconsole/components/DrilldownModal.js +4 -4
- package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +2 -2
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +1 -1
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +28 -28
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +1 -1
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkCard.js +4 -4
- package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +2 -2
- package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +2 -2
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +2 -2
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +2 -2
- package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +25 -25
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +1 -1
- package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
- package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +3 -3
- package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +2 -2
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +2 -2
- package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
- package/dist/bigconsole/components/parser/DataSinkSelector.js +3 -3
- package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ImportParserDialog.js +26 -26
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserCard.js +5 -5
- package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +6 -6
- package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserStatusBadge.js +1 -1
- package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserTypeBadge.js +1 -1
- package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineCard.js +2 -2
- package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +1 -1
- package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +1 -1
- package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +11 -11
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +17 -17
- package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetConfigDialog.js +14 -14
- package/dist/bigconsole/components/widgets/WidgetConfigDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetHeader.js +4 -4
- package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetMenu.js +3 -3
- package/dist/bigconsole/components/widgets/WidgetMenu.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetWrapper.js +266 -238
- package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +2 -2
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
- package/dist/bigconsole/components/widgets/custom/CustomWidget.js +5 -5
- package/dist/bigconsole/components/widgets/custom/CustomWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/LinearGauge.js +1 -1
- package/dist/bigconsole/components/widgets/gauge/LinearGauge.js.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +2 -2
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/kpi/KPIWidget.js +2 -2
- package/dist/bigconsole/components/widgets/kpi/KPIWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +2 -2
- package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListItem.js +3 -3
- package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
- package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +3 -3
- package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/ComparisonBadge.js +1 -1
- package/dist/bigconsole/components/widgets/metric-card/ComparisonBadge.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +2 -2
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +12 -12
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressBar.js +2 -2
- package/dist/bigconsole/components/widgets/progress/ProgressBar.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +2 -2
- package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/EmptyState.js +1 -1
- package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableCell.js +1 -1
- package/dist/bigconsole/components/widgets/table/TableCell.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableConfig.js +1 -1
- package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableHeader.js +2 -2
- package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TablePagination.js +4 -4
- package/dist/bigconsole/components/widgets/table/TablePagination.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableWidget.js +5 -5
- package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +1 -1
- package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +3 -3
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +2 -2
- package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -1
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +3 -3
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowCard.js +2 -2
- package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +1 -1
- package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
- package/dist/bigconsole/pages/DashboardBuilderPage.js +2 -2
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +2 -2
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +3 -3
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +2 -2
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +5 -5
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +4 -4
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +9 -9
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WidgetDemoPage.js +2 -2
- package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowViewPage.js +5 -5
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +12 -12
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/BigConsoleRenderer.js +2 -2
- package/dist/bigconsole/renderers/adapters/BigConsoleRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +5 -5
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js +2 -2
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
- 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":"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"}
|
|
@@ -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-
|
|
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-
|
|
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 "Refresh" 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 "Refresh" 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":";;;AAgDA,IAAM,IAAqC;CACzC;EACE,OAAO;EACP,MAAM;EACN,aAAa;EACd;CACD;EACE,OAAO;EACP,MAAM;EACN,aAAa;EACd;CACD;EACE,OAAO;EACP,MAAM;EACN,aAAa;EACd;CACD;EACE,OAAO;EACP,MAAM;EACN,aAAa;EACd;CACF,EAEK,IAAqC;CACzC;EAAE,OAAO;EAAO,OAAO;EAAO;CAC9B;EAAE,OAAO;EAAoB,OAAO;EAAqB;CACzD;EAAE,OAAO;EAAuB,OAAO;EAAqB;CAC5D;EAAE,OAAO;EAAiB,OAAO;EAAe;CAChD;EAAE,OAAO;EAAgB,OAAO;EAAc;CAC9C;EAAE,OAAO;EAAc,OAAO;EAAiB;CAC/C;EAAE,OAAO;EAAgB,OAAO;EAAe;CAC/C;EAAE,OAAO;EAAoB,OAAO;EAAsB;CAC3D;AASD,SAAS,EAAiB,GAAqC;AAC7D,QAAO,EAAiB,MAAM,MAAW,EAAO,SAAS,EAAK,IAAI;;AAOpE,IAAa,IAAsB,EAAK,SAA6B,EACnE,UACA,aACA,cAAW,IACX,YAC2B;CAE3B,IAAM,CAAC,GAAa,KAAkB,EAAiC,GAAO,QAAQ,SAAS,EACzF,CAAC,GAAgB,KAAqB,EAC1C,GAAO,WAAW,EAAiB,EAAM,SAAS,KAAK,IAAI,OAAO,EAAiB,GACpF,EACK,CAAC,GAAkB,KAAuB,EAC9C,GAAO,WAAW,CAAC,EAAiB,EAAM,SAAS,KAAK,GAAG,GAC5D,EACK,CAAC,GAAY,KAAiB,EAAS,GAAO,UAAU,QAAQ,GAAG,EACnE,CAAC,GAAU,KAAe,EAAS,GAAO,UAAU,YAAY,MAAM,EACtE,IAAe,EAAO,EAAM;AAGlC,SAAgB;AACd,EAAI,EAAa,YAAY,KAAS,MACpC,EAAa,UAAU,GAEvB,qBAAqB;AAEnB,OADA,EAAe,EAAM,KAAK,EACtB,EAAM,UAAU;AAClB,MAAY,EAAM,SAAS,SAAS;IACpC,IAAM,IAAS,EAAiB,EAAM,SAAS,KAAK;AACpD,IAAI,KACF,EAAkB,EAAO,EACzB,EAAoB,GAAM,KAE1B,EAAc,EAAM,SAAS,KAAK,EAClC,EAAoB,GAAK;;IAG7B;IAEH,CAAC,EAAM,CAAC;CAGX,IAAM,IAAmB,GACtB,MAAiC;AAC5B,QACJ,EAAe,EAAK,EAElB,EADE,MAAS,WACF,EAAE,MAAM,UAAU,GAGlB;GACP,MAAM;GACN,UAAU;IAAE,MAHD,IAAmB,IAAa,GAAgB,QAAQ,EAAiB,GAAG;IAGrE;IAAU;GAC7B,CAAC;IAGN;EAAC;EAAU;EAAU;EAAkB;EAAY;EAAgB;EAAS,CAC7E,EAGK,IAAqB,GACxB,MAA2B;AACtB,QACJ,EAAkB,EAAO,EACzB,EAAoB,GAAM,EAC1B,EAAS;GACP,MAAM;GACN,UAAU;IAAE,MAAM,EAAO;IAAM;IAAU;GAC1C,CAAC;IAEJ;EAAC;EAAU;EAAU;EAAS,CAC/B,EAGK,IAAqB,QAAkB;AACvC,QACJ,EAAoB,GAAK,EACzB,EAAkB,KAAK,EACnB,KACF,EAAS;GACP,MAAM;GACN,UAAU;IAAE,MAAM;IAAY;IAAU;GACzC,CAAC;IAEH;EAAC;EAAU;EAAU;EAAY;EAAS,CAAC,EAGxC,IAAyB,GAC5B,MAA2C;EAC1C,IAAM,IAAO,EAAE,OAAO;AAEtB,EADA,EAAc,EAAK,EACf,EAAK,MAAM,IACb,EAAS;GACP,MAAM;GACN,UAAU;IAAE;IAAM;IAAU;GAC7B,CAAC;IAGN,CAAC,GAAU,EAAS,CACrB,EAGK,IAAuB,GAC1B,MAA4C;EAC3C,IAAM,IAAK,EAAE,OAAO;AAEpB,EADA,EAAY,EAAG,EACX,MAAgB,eAElB,EAAS;GACP,MAAM;GACN,UAAU;IAAE,MAHD,IAAmB,IAAa,GAAgB,QAAQ;IAGjD,UAAU;IAAI;GACjC,CAAC;IAGN;EAAC;EAAU;EAAa;EAAkB;EAAY;EAAe,CACtE;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;IAAO,WAAU;cAAmD;IAAoB,CAAA,EACxF,kBAAC,KAAD;IAAG,WAAU;cAA8B;IAAqC,CAAA,CAC5E,EAAA,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,SAAD;KACE,WAAW;;;;;;cAMP,IAAW,kCAAkC,GAAG;cAEhD,MAAgB,WACZ,oDACA,kDACL;;eAZL,CAeE,kBAAC,SAAD;MACE,MAAK;MACL,MAAK;MACL,SAAS,MAAgB;MACzB,gBAAgB,EAAiB,SAAS;MAChC;MACV,WAAW;MAQX,CAAA,EACF,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAwC;OAAa,CAAA,EACrE,kBAAC,KAAD;OAAG,WAAU;iBAAqC;OAE9C,CAAA,CACA;QACA;QAGR,kBAAC,OAAD;KACE,WAAW;;;cAGP,IAAW,eAAe,GAAG;cAC7B,MAAgB,cAAc,oDAAoD,wBAAwB;;eALhH,CAQE,kBAAC,SAAD;MACE,WAAW;;;;gBAIP,IAAW,uBAAuB,GAAG;;gBAL3C,CAQE,kBAAC,SAAD;OACE,MAAK;OACL,MAAK;OACL,SAAS,MAAgB;OACzB,gBAAgB,EAAiB,YAAY;OACnC;OACV,WAAW;OAQX,CAAA,EACF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAAgB,CAAA,EACxE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAgC,CAAA,CAC9E;SACA;SAGP,MAAgB,eACf,kBAAC,OAAD;MAAK,WAAU;gBAAf;OAEE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SAAO,WAAU;mBAAqD;SAAgB,CAAA,EACtF,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAiB,KAAK,MACrB,kBAAC,UAAD;UAEE,MAAK;UACL,eAAe,EAAmB,EAAO;UAC/B;UACV,WAAW;;;;;0BAKP,IAAW,uBAAuB,iBAAiB;0BAEnD,CAAC,KAAoB,GAAgB,SAAS,EAAO,OACjD,4EACA,kDACL;;oBAGH,kBAAC,QAAD;WAAM,WAAU;qBAAuB,EAAO;WAAa,CAAA;UACpD,EAlBF,EAAO,KAkBL,CACT;SACE,CAAA,CACF;;OAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,UAAD;QACE,MAAK;QACL,SAAS;QACC;QACV,WAAW;;sBAEP,IAAmB,2BAA2B,8CAA8C;;kBAG/F,IAAmB,0BAA0B;QACvC,CAAA,EACR,KACC,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SACE,MAAK;SACL,OAAO;SACP,UAAU;SACA;SACV,aAAY;SACZ,WAAW;SAaX,CAAA,EACF,kBAAC,KAAD;SAAG,WAAU;mBAAkC;SAE3C,CAAA,CACA;UAEJ,EAAA,CAAA;OAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAqD;QAAgB,CAAA,EACtF,kBAAC,UAAD;QACE,OAAO;QACP,UAAU;QACA;QACV,WAAW;kBAWV,EAAiB,KAAK,MACrB,kBAAC,UAAD;SAAuB,OAAO,EAAG;mBAC9B,EAAG;SACG,EAFI,EAAG,MAEP,CACT;QACK,CAAA,CACL,EAAA,CAAA;OACF;QAEJ;OACF;;GAGL,KACC,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KACE,WAAU;KACV,MAAK;KACL,QAAO;KACP,SAAQ;eAER,kBAAC,QAAD;MACE,eAAc;MACd,gBAAe;MACf,aAAa;MACb,GAAE;MACF,CAAA;KACE,CAAA,EACN,kBAAC,KAAD;KAAG,WAAU;eAA4B;KAAU,CAAA,CAC/C;;GAEJ;;EAER"}
|
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
151
|
+
className: "text-sm text-text-secondary",
|
|
152
152
|
children: "Source ID"
|
|
153
153
|
}), /* @__PURE__ */ m("span", {
|
|
154
|
-
className: "text-xs text-
|
|
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-
|
|
161
|
+
className: "text-sm text-text-secondary",
|
|
162
162
|
children: "Schema Version"
|
|
163
163
|
}), /* @__PURE__ */ m("span", {
|
|
164
|
-
className: "text-xs text-
|
|
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-
|
|
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-
|
|
177
|
-
className: "text-sm font-medium text-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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(_, {
|