@burdenoff/microfe-bigconsole 2026.924.1 → 2026.924.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/bigconsole/BigConsoleRoutes.js +137 -138
  2. package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
  3. package/dist/bigconsole/assistant/previewController.js +10 -10
  4. package/dist/bigconsole/assistant/useAssistantPanelShowsPreview.js +25 -0
  5. package/dist/bigconsole/assistant/useAssistantPanelShowsPreview.js.map +1 -0
  6. package/dist/bigconsole/components/DrilldownDashboardRenderer.js +17 -17
  7. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +32 -32
  8. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +52 -52
  9. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  10. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +7 -7
  11. package/dist/bigconsole/components/dashboard/DashboardStatusPill.js +53 -0
  12. package/dist/bigconsole/components/dashboard/DashboardStatusPill.js.map +1 -0
  13. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +60 -60
  14. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +21 -21
  15. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +30 -30
  16. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +36 -36
  17. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +34 -34
  18. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +38 -38
  19. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  20. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +121 -121
  21. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  22. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +22 -22
  23. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +46 -46
  24. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +53 -53
  25. package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -1
  26. package/dist/bigconsole/components/dashboard/WidgetPalette.js +47 -47
  27. package/dist/bigconsole/components/dashboard/index.js +1 -0
  28. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +35 -35
  29. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +18 -18
  30. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +20 -20
  31. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +30 -29
  32. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
  33. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +48 -48
  34. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +103 -103
  35. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
  36. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +35 -35
  37. package/dist/bigconsole/components/overview/DashboardGuide.js +214 -0
  38. package/dist/bigconsole/components/overview/DashboardGuide.js.map +1 -0
  39. package/dist/bigconsole/components/overview/DataHealthCard.js +97 -0
  40. package/dist/bigconsole/components/overview/DataHealthCard.js.map +1 -0
  41. package/dist/bigconsole/components/overview/OverviewQuickActions.js +32 -0
  42. package/dist/bigconsole/components/overview/OverviewQuickActions.js.map +1 -0
  43. package/dist/bigconsole/components/overview/OverviewStatCard.js +57 -0
  44. package/dist/bigconsole/components/overview/OverviewStatCard.js.map +1 -0
  45. package/dist/bigconsole/components/overview/RecentDashboardsPanel.js +107 -0
  46. package/dist/bigconsole/components/overview/RecentDashboardsPanel.js.map +1 -0
  47. package/dist/bigconsole/components/overview/dashboardGuideSteps.js +119 -0
  48. package/dist/bigconsole/components/overview/dashboardGuideSteps.js.map +1 -0
  49. package/dist/bigconsole/components/overview/index.js +8 -0
  50. package/dist/bigconsole/components/overview/overviewModel.js +119 -0
  51. package/dist/bigconsole/components/overview/overviewModel.js.map +1 -0
  52. package/dist/bigconsole/components/overview/useOverviewData.js +48 -0
  53. package/dist/bigconsole/components/overview/useOverviewData.js.map +1 -0
  54. package/dist/bigconsole/components/parser/DataSinkSelector.js +40 -40
  55. package/dist/bigconsole/components/parser/ImportParserDialog.js +127 -127
  56. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  57. package/dist/bigconsole/components/parser/ParserSelector.js +51 -51
  58. package/dist/bigconsole/components/preview/AiPreviewContent.js +5 -5
  59. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +62 -61
  60. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
  61. package/dist/bigconsole/components/preview/AiPreviewPanel.js +82 -81
  62. package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
  63. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +13 -13
  64. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +70 -70
  65. package/dist/bigconsole/components/widgets/PropertiesPanel.js +28 -28
  66. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +25 -25
  67. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +48 -48
  68. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +46 -46
  69. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +61 -61
  70. package/dist/bigconsole/components/widgets/form/FormWidget.js +36 -36
  71. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +42 -42
  72. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +25 -25
  73. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +21 -21
  74. package/dist/bigconsole/components/widgets/list/ListConfig.js +30 -30
  75. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +38 -38
  76. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +9 -9
  77. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +9 -9
  78. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +49 -49
  79. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +39 -39
  80. package/dist/bigconsole/components/widgets/table/TableConfig.js +73 -73
  81. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +64 -64
  82. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +10 -10
  83. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +68 -68
  84. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  85. package/dist/bigconsole/pages/AdminPage.js +136 -136
  86. package/dist/bigconsole/pages/DashboardBuilderPage.js +10 -10
  87. package/dist/bigconsole/pages/DashboardViewPage.js +61 -61
  88. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  89. package/dist/bigconsole/pages/DashboardsPage.js +327 -348
  90. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  91. package/dist/bigconsole/pages/DataParsersPage.js +5 -5
  92. package/dist/bigconsole/pages/DataSinkBuilderPage.js +10 -10
  93. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  94. package/dist/bigconsole/pages/DataSinkViewPage.js +83 -83
  95. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  96. package/dist/bigconsole/pages/DataSinksPage.js +11 -11
  97. package/dist/bigconsole/pages/DataSourcesPage.js +5 -5
  98. package/dist/bigconsole/pages/InsightsPage.js +315 -315
  99. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  100. package/dist/bigconsole/pages/OverviewPage.js +244 -0
  101. package/dist/bigconsole/pages/OverviewPage.js.map +1 -0
  102. package/dist/bigconsole/pages/ParserBuilderPage.js +5 -5
  103. package/dist/bigconsole/pages/ParserViewPage.js +98 -98
  104. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  105. package/dist/bigconsole/pages/PipelineBuilderPage.js +8 -8
  106. package/dist/bigconsole/pages/PipelineViewPage.js +46 -46
  107. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  108. package/dist/bigconsole/pages/PipelinesPage.js +80 -80
  109. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  110. package/dist/bigconsole/pages/SettingsPage.js +70 -70
  111. package/dist/bigconsole/pages/WidgetDemoPage.js +42 -42
  112. package/dist/bigconsole/pages/WorkflowViewPage.js +200 -200
  113. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  114. package/dist/bigconsole/pages/WorkflowsPage.js +78 -78
  115. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  116. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +34 -34
  117. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +79 -79
  118. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +46 -46
  119. package/dist/bigconsole/utils/createDialogParam.js +14 -0
  120. package/dist/bigconsole/utils/createDialogParam.js.map +1 -0
  121. package/dist/generated/global-operations.js +1 -1
  122. package/dist/generated/wspace-operations.js +285 -222
  123. package/dist/generated/wspace-operations.js.map +1 -1
  124. package/dist/shared/hooks/useTr.js +10 -7
  125. package/dist/shared/hooks/useTr.js.map +1 -1
  126. package/package.json +1 -1
  127. package/dist/bigconsole/pages/HomePage.js +0 -318
  128. package/dist/bigconsole/pages/HomePage.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ParserViewPage.js","names":[],"sources":["../../../src/bigconsole/pages/ParserViewPage.tsx"],"sourcesContent":["/**\n * Parser View Page\n *\n * Page for viewing Parser details, expression, and test execution.\n */\n\nimport { memo, useState, useEffect, useCallback } from 'react';\nimport { useParams } from 'react-router';\nimport { useAppNavigate } from '../contexts';\nimport { isNative, nativeCopyText, nativeImpact, nativeNotify, nativeToast } from '../../utils/nativeBridge';\nimport { formatDistanceToNow } from 'date-fns';\nimport { useParserOperations } from '../hooks/useParserOperations';\nimport { useParserStore } from '../store/parserStore';\nimport { useDataSinkOperations } from '../hooks/useDataSinkOperations';\nimport { ParserStatusBadge } from '../components/parser/ParserStatusBadge';\nimport { ParserTypeBadge } from '../components/parser/ParserTypeBadge';\nimport { ExpressionEditor } from '../components/parser/ExpressionEditor';\nimport { ExportParserDialog } from '../components/parser/ExportParserDialog';\nimport { Section, SectionStack } from '../components/common';\n\n// RBAC\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\n\n// i18n\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n// fe-libs UI components\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { IllustratedEmptyState, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n} from '@burdenoff/fe-libs/ui';\n\n// Lucide icons\nimport {\n ArrowLeft,\n Edit,\n Play,\n Trash2,\n Copy,\n Check,\n FileCode2,\n Database,\n ArrowDown,\n Loader2,\n AlertCircle,\n AlertTriangle,\n Download,\n} from 'lucide-react';\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\n// Default console ID for standalone parser viewing\nconst DEFAULT_CONSOLE_ID = 'default';\n\nexport const ParserViewPage = memo(function ParserViewPage() {\n const { parserId, consoleId: urlConsoleId } = useParams<{ parserId: string; consoleId?: string }>();\n const navigate = useAppNavigate();\n const { t } = useI18n();\n\n // Use URL consoleId or fall back to default\n const consoleId = urlConsoleId || DEFAULT_CONSOLE_ID;\n\n // Permissions\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.PARSER_READ);\n\n // Local state\n const [isDeleting, setIsDeleting] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [expressionCopied, setExpressionCopied] = useState(false);\n const [isTesting, setIsTesting] = useState(false);\n const [isExportDialogOpen, setIsExportDialogOpen] = useState(false);\n const [testResult, setTestResult] = useState<{\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n } | null>(null);\n\n // Store\n const parser = useParserStore((state) => (parserId ? state.parsers.get(parserId) : undefined));\n\n // Operations - use consoleId from URL or default\n const { loading, error, fetchParser, deleteParser, executeParser } = useParserOperations({\n consoleId,\n skipFetch: true,\n });\n\n // DataSink operations for source datasink info\n const { dataSinks, fetchDataSinks } = useDataSinkOperations({ skipFetch: true });\n\n // Load parser on mount - always fetch full data to get expression\n useEffect(() => {\n if (parserId) {\n fetchParser(parserId);\n }\n }, [parserId, fetchParser]);\n\n // Fetch datasinks to show source name\n useEffect(() => {\n fetchDataSinks();\n }, [fetchDataSinks]);\n\n // Get source datasink name\n const sourceDataSink = parser?.inputSinkKey ? dataSinks.find((ds) => ds.key === parser.inputSinkKey) : null;\n\n // Handle back navigation\n const handleBack = useCallback(() => {\n // Navigate to dashboard-scoped parsers list if consoleId is provided\n if (urlConsoleId) {\n navigate(`/dashboards/${urlConsoleId}/parsers`);\n } else {\n navigate(`/parsers`);\n }\n }, [navigate, urlConsoleId]);\n\n // Handle edit\n const handleEdit = useCallback(() => {\n // Navigate to dashboard-scoped parser edit if consoleId is provided\n if (urlConsoleId) {\n navigate(`/dashboards/${urlConsoleId}/parsers/${parserId}/edit`);\n } else {\n navigate(`/parsers/${parserId}/edit`);\n }\n }, [navigate, parserId, urlConsoleId]);\n\n // Handle delete\n const handleDelete = useCallback(async () => {\n if (!parserId) return;\n setIsDeleting(true);\n try {\n const success = await deleteParser(parserId);\n if (success) {\n if (isNative()) void nativeNotify('success');\n // Navigate to dashboard-scoped parsers list if consoleId is provided\n if (urlConsoleId) {\n navigate(`/dashboards/${urlConsoleId}/parsers`);\n } else {\n navigate(`/parsers`);\n }\n } else if (isNative()) {\n void nativeNotify('error');\n }\n } catch {\n if (isNative()) void nativeNotify('error');\n } finally {\n setIsDeleting(false);\n setShowDeleteConfirm(false);\n }\n }, [parserId, deleteParser, navigate, urlConsoleId]);\n\n // Handle copy expression\n const handleCopyExpression = useCallback(async () => {\n if (!parser?.expression) return;\n try {\n await nativeCopyText(parser.expression);\n setExpressionCopied(true);\n if (isNative()) void nativeToast(t('bigconsole.parsers.view.expressionCopied', 'Expression copied'));\n setTimeout(() => setExpressionCopied(false), 2000);\n } catch {\n // Clipboard access is best-effort; the expression stays visible either way.\n }\n }, [parser?.expression, t]);\n\n // Handle test execution\n const handleTestExecute = useCallback(async () => {\n if (!parserId) return;\n setIsTesting(true);\n setTestResult(null);\n try {\n const result = await executeParser(parserId);\n if (result) {\n setTestResult({\n success: result.success,\n output: result.output,\n error: result.error,\n executionTimeMs: result.executionTimeMs,\n });\n }\n } catch (err) {\n setTestResult({\n success: false,\n output: null,\n error: err instanceof Error ? err.message : t('bigconsole.parsers.view.executionFailed', 'Execution failed'),\n executionTimeMs: 0,\n });\n } finally {\n setIsTesting(false);\n }\n }, [parserId, executeParser, t]);\n\n // Navigate to source datasink\n const handleViewSourceDataSink = useCallback(() => {\n if (sourceDataSink) {\n navigate(`/datasinks/${sourceDataSink.id}`);\n }\n }, [navigate, sourceDataSink]);\n\n // Handle export\n const handleExport = useCallback(() => {\n setIsExportDialogOpen(true);\n }, []);\n\n const handleExportClose = useCallback(() => {\n setIsExportDialogOpen(false);\n }, []);\n\n // Loading state (wait for both the parser fetch and the permission load)\n if ((loading && !parser) || permissionsLoading) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Loader2 className=\"w-8 h-8 text-text-secondary animate-spin\" />\n </div>\n );\n }\n\n // Read gate — no permission to view this parser\n if (!canRead) {\n return (\n <AccessDenied\n title={t('bigconsole.parsers.accessDenied.title', 'Access Denied')}\n description={t('bigconsole.parsers.accessDenied.view', \"You don't have permission to view this parser.\")}\n />\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"p-card-padding\">\n <Section\n tone=\"danger\"\n headingLevel={2}\n title={t('bigconsole.parsers.errors.viewLoadFailed', 'Failed to load Parser')}\n description=\"The parser could not be fetched. Go back to the list and try again.\"\n icon={<AlertCircle className=\"h-icon-md w-icon-md text-[var(--color-status-error-text)]\" />}\n actions={\n <Button onClick={handleBack} variant=\"secondary\" size=\"sm\">\n <ArrowLeft className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.goBack', 'Go back')}\n </Button>\n }\n data-testid=\"parser-load-error\"\n >\n <p className=\"font-mono text-xs break-words text-text-secondary\">{error.message}</p>\n </Section>\n </div>\n );\n }\n\n // Not found state\n if (!parser) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px] p-card-padding\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('bigconsole.parsers.view.notFoundTitle', 'Parser not found')}\n description={t(\n 'bigconsole.parsers.view.notFoundDescription',\n \"The Parser you're looking for doesn't exist or has been deleted.\"\n )}\n action={\n <Button onClick={handleBack} variant=\"default\" size=\"default\">\n <ArrowLeft className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.goBackToParsers', 'Go back to Parsers')}\n </Button>\n }\n />\n </div>\n );\n }\n\n // The route exists to show the expression — until a run produces output. Once\n // it does, the freshly produced result becomes the page's primary block and\n // the (static) expression steps down to `standard`, so only one block is ever\n // promoted at a time.\n const hasResult = testResult !== null;\n\n return (\n <div className=\"p-card-padding\">\n <SectionStack>\n {/* Page header strip — structural, no surface of its own */}\n <div className=\"flex flex-col gap-form-gap border-b border-[var(--color-border-subtle)] pb-form-gap sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <Button onClick={handleBack} variant=\"ghost\" size=\"sm\" className=\"mb-4\">\n <ArrowLeft className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.view.backToParsers', 'Back to Parsers')}\n </Button>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h1 className=\"text-2xl font-bold text-text-primary sm:text-3xl\">\n {parser.name || t('bigconsole.parsers.view.untitled', 'Untitled')}\n </h1>\n <ParserTypeBadge type={parser.type} />\n <ParserStatusBadge status={parser.status} />\n </div>\n {parser.description && <p className=\"text-sm text-text-secondary mt-2\">{parser.description}</p>}\n </div>\n\n {/* Actions — Execute is the page's primary verb, so it is the only filled button */}\n <div className=\"flex shrink-0 flex-wrap items-center gap-control-gap\">\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PARSER_EXECUTE} deniedBehavior=\"disable\">\n <Button onClick={handleTestExecute} disabled={isTesting} variant=\"default\" size=\"default\">\n <Play className=\"w-4 h-4 mr-2\" />\n {isTesting\n ? t('bigconsole.parsers.view.running', 'Running...')\n : t('bigconsole.parsers.actions.execute', 'Execute')}\n </Button>\n </PermissionButton>\n <Button onClick={handleExport} variant=\"secondary\" size=\"default\">\n <Download className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.export', 'Export')}\n </Button>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PARSER_UPDATE} deniedBehavior=\"disable\">\n <Button onClick={handleEdit} variant=\"secondary\" size=\"default\">\n <Edit className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.edit', 'Edit')}\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PARSER_DELETE} deniedBehavior=\"hide\">\n <Button\n onClick={() => setShowDeleteConfirm(true)}\n disabled={isDeleting}\n variant=\"destructive\"\n size=\"default\"\n >\n <Trash2 className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.delete', 'Delete')}\n </Button>\n </PermissionButton>\n </div>\n </div>\n\n <PagePurpose className=\"max-w-[80ch]\">\n {t(\n 'bigconsole.parsers.view.purpose',\n 'A parser turns raw input into structured fields using its expression. Review or copy the expression, run it against a sample to see the output, then edit it or use it inside a pipeline to shape incoming data.'\n )}\n </PagePurpose>\n\n {/* Main Content Grid */}\n <div className=\"grid gap-section-gap md:grid-cols-2 lg:grid-cols-3\">\n {/* Expression + result column */}\n <div className=\"flex min-w-0 flex-col gap-section-gap md:col-span-2\">\n {/* Execution result — rendered first once it exists so the outcome of\n the primary action is visible without scrolling past the editor. */}\n {testResult && (\n <Section\n id=\"parser-execution-result\"\n emphasis=\"primary\"\n tone={testResult.success ? 'success' : 'danger'}\n headingLevel={2}\n title={t('bigconsole.parsers.view.executionResult', 'Execution Result')}\n description={\n testResult.success\n ? 'Output produced by the latest run of this parser.'\n : 'The latest run did not complete. Fix the expression or the input and run again.'\n }\n meta={\n <Badge variant={testResult.success ? 'default' : 'destructive'}>\n {testResult.success\n ? t('bigconsole.parsers.view.success', 'Success')\n : t('bigconsole.parsers.view.failed', 'Failed')}\n </Badge>\n }\n actions={\n <Badge variant=\"secondary\" className=\"text-xs\">\n {testResult.executionTimeMs}ms\n </Badge>\n }\n data-testid=\"parser-execution-result\"\n >\n <pre className=\"max-h-[300px] min-w-0 overflow-auto rounded-md bg-bg-sunken p-4 font-mono text-sm text-text-primary\">\n {testResult.error ?? JSON.stringify(testResult.output, null, 2)}\n </pre>\n </Section>\n )}\n\n {/* Expression */}\n <Section\n emphasis={hasResult ? 'standard' : 'primary'}\n headingLevel={2}\n title={t('bigconsole.parsers.view.expression', 'Expression')}\n description=\"The JQ or JSONata program this parser runs against every input record.\"\n icon={<FileCode2 className=\"h-icon-sm w-icon-sm\" />}\n meta={\n <Badge variant=\"secondary\" className=\"text-xs uppercase\">\n {parser.type}\n </Badge>\n }\n actions={\n <Button onClick={handleCopyExpression} variant=\"ghost\" size=\"sm\">\n {expressionCopied ? (\n <>\n <Check className=\"w-3.5 h-3.5 text-status-success-text mr-2\" />\n {t('bigconsole.parsers.view.copied', 'Copied!')}\n </>\n ) : (\n <>\n <Copy className=\"w-3.5 h-3.5 mr-2\" />\n {t('bigconsole.parsers.actions.copy', 'Copy')}\n </>\n )}\n </Button>\n }\n data-testid=\"parser-expression\"\n >\n <ExpressionEditor\n value={parser.expression}\n type={parser.type}\n readOnly\n height=\"clamp(180px, 40vh, 300px)\"\n />\n </Section>\n </div>\n\n {/* Supporting column — steps down from the expression/result column */}\n <div className=\"grid min-w-0 gap-section-gap md:col-span-2 md:grid-cols-2 lg:col-span-1 lg:grid-cols-1\">\n {/* Data Flow */}\n <Section\n headingLevel={2}\n title={t('bigconsole.parsers.view.dataFlow', 'Data Flow')}\n description=\"Where this parser reads from and what it writes.\"\n data-testid=\"parser-data-flow\"\n >\n <dl className=\"space-y-3\">\n {/* Source DataSink */}\n <div>\n <dt className=\"text-xs font-medium uppercase tracking-wide text-text-muted\">\n {t('bigconsole.parsers.view.sourceDataSink', 'Source DataSink')}\n </dt>\n {parser.inputSinkKey ? (\n <dd className=\"mt-1\">\n <p className=\"break-words font-mono text-sm font-medium text-text-primary\">\n {parser.inputSinkKey}\n </p>\n {sourceDataSink && (\n <Button onClick={handleViewSourceDataSink} variant=\"link\" size=\"sm\" className=\"mt-1 p-0 h-auto\">\n <Database className=\"w-3 h-3 mr-1\" />\n {t('bigconsole.parsers.view.viewDataSink', 'View {{name}}', {\n name: sourceDataSink.name || t('bigconsole.parsers.view.dataSinkFallback', 'DataSink'),\n })}\n </Button>\n )}\n </dd>\n ) : (\n <dd className=\"mt-1 text-sm text-text-muted\">\n {t('bigconsole.parsers.view.noneConfigured', 'None configured')}\n </dd>\n )}\n </div>\n\n {/* Arrow */}\n <div aria-hidden=\"true\" className=\"flex items-center justify-center py-1\">\n <ArrowDown className=\"w-4 h-4 text-text-muted\" />\n </div>\n\n {/* Output Key */}\n <div>\n <dt className=\"text-xs font-medium uppercase tracking-wide text-text-muted\">\n {t('bigconsole.parsers.view.outputKey', 'Output Key')}\n </dt>\n <dd className=\"mt-1 break-words font-mono text-sm font-medium text-text-primary\">\n {parser.outputKey || t('bigconsole.parsers.view.notConfigured', 'Not configured')}\n </dd>\n </div>\n </dl>\n </Section>\n\n {/* Configuration */}\n <Section\n headingLevel={2}\n title={t('bigconsole.parsers.view.configuration', 'Configuration')}\n data-testid=\"parser-configuration\"\n >\n <dl className=\"space-y-4 text-sm\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.status', 'Status')}</dt>\n <dd>\n <ParserStatusBadge status={parser.status} />\n </dd>\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.type', 'Type')}</dt>\n <dd>\n <ParserTypeBadge type={parser.type} />\n </dd>\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.cacheTtl', 'Cache TTL')}</dt>\n <dd className=\"text-text-primary font-medium\">\n {parser.ttl\n ? t('bigconsole.parsers.view.ttlSeconds', '{{ttl}}s', { ttl: parser.ttl })\n : t('bigconsole.parsers.view.noCaching', 'No caching')}\n </dd>\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.version', 'Version')}</dt>\n <dd className=\"text-text-primary font-medium\">{parser.version || 1}</dd>\n </div>\n </dl>\n </Section>\n\n {/* Timestamps — least important block on the page, so it is recessed */}\n <Section\n emphasis=\"muted\"\n padding=\"compact\"\n headingLevel={2}\n title={t('bigconsole.parsers.view.timestamps', 'Timestamps')}\n data-testid=\"parser-history\"\n >\n <dl className=\"space-y-4 text-sm\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.created', 'Created')}</dt>\n <dd className=\"text-text-primary font-medium\">\n {parser.createdAt\n ? formatDistanceToNow(new Date(parser.createdAt), { addSuffix: true })\n : t('bigconsole.parsers.view.unknown', 'Unknown')}\n </dd>\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.updated', 'Updated')}</dt>\n <dd className=\"text-text-primary font-medium\">\n {parser.updatedAt\n ? formatDistanceToNow(new Date(parser.updatedAt), { addSuffix: true })\n : t('bigconsole.parsers.view.unknown', 'Unknown')}\n </dd>\n </div>\n </dl>\n </Section>\n </div>\n </div>\n\n {/* Guidance sits after the data it talks about */}\n <NextSteps\n storageKey=\"bigconsole-parser-view\"\n steps={[\n {\n id: 'execute',\n label: t('bigconsole.parsers.view.nextSteps.executeLabel', 'Run a test execution'),\n description: t(\n 'bigconsole.parsers.view.nextSteps.executeDescription',\n 'Check the expression produces the fields you expect.'\n ),\n onClick: handleTestExecute,\n },\n {\n id: 'edit',\n label: t('bigconsole.parsers.view.nextSteps.editLabel', 'Edit the expression'),\n description: t(\n 'bigconsole.parsers.view.nextSteps.editDescription',\n 'Refine how this parser maps your input.'\n ),\n onClick: handleEdit,\n },\n {\n id: 'pipeline',\n label: t('bigconsole.parsers.view.nextSteps.pipelineLabel', 'Use it in a pipeline'),\n description: t(\n 'bigconsole.parsers.view.nextSteps.pipelineDescription',\n 'Chain this parser with a data sink to process data end to end.'\n ),\n onClick: () => navigate('/pipelines'),\n },\n ]}\n />\n </SectionStack>\n\n {/* Delete Confirmation ResponsiveDialog */}\n <ResponsiveDialog open={showDeleteConfirm} onOpenChange={setShowDeleteConfirm}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {t('bigconsole.parsers.view.deleteDialogTitle', 'Delete Parser')}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {t('bigconsole.parsers.view.deleteConfirmPrefix', 'Are you sure you want to delete')}{' '}\n <strong>{parser.name}</strong>\n {t('bigconsole.parsers.view.deleteConfirmSuffix', '? This action cannot be undone.')}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <Section\n tone=\"warning\"\n padding=\"compact\"\n headingLevel={3}\n title=\"Check dependents first\"\n description={t(\n 'bigconsole.parsers.view.deleteWarning',\n 'Widgets and pipelines using this parser may stop working correctly after deletion.'\n )}\n icon={<AlertTriangle className=\"h-icon-sm w-icon-sm text-[var(--color-status-warning-text)]\" />}\n data-testid=\"parser-delete-warning\"\n />\n <ResponsiveDialogFooter>\n <Button onClick={() => setShowDeleteConfirm(false)} variant=\"secondary\">\n {t('bigconsole.parsers.actions.cancel', 'Cancel')}\n </Button>\n <Button\n onClick={() => {\n nativeImpact('medium');\n void handleDelete();\n }}\n disabled={isDeleting}\n variant=\"destructive\"\n >\n {isDeleting\n ? t('bigconsole.parsers.view.deleting', 'Deleting...')\n : t('bigconsole.parsers.view.deleteDialogTitle', 'Delete Parser')}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Export Parser ResponsiveDialog */}\n <ExportParserDialog\n isOpen={isExportDialogOpen}\n parserId={parserId || null}\n parserName={parser.name}\n onClose={handleExportClose}\n />\n </div>\n );\n});\n\nexport default ParserViewPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ParserViewPage.js","names":[],"sources":["../../../src/bigconsole/pages/ParserViewPage.tsx"],"sourcesContent":["/**\n * Parser View Page\n *\n * Page for viewing Parser details, expression, and test execution.\n */\n\nimport { memo, useState, useEffect, useCallback } from 'react';\nimport { useParams } from 'react-router';\nimport { useAppNavigate } from '../contexts';\nimport { isNative, nativeCopyText, nativeImpact, nativeNotify, nativeToast } from '../../utils/nativeBridge';\nimport { formatDistanceToNow } from 'date-fns';\nimport { useParserOperations } from '../hooks/useParserOperations';\nimport { useParserStore } from '../store/parserStore';\nimport { useDataSinkOperations } from '../hooks/useDataSinkOperations';\nimport { ParserStatusBadge } from '../components/parser/ParserStatusBadge';\nimport { ParserTypeBadge } from '../components/parser/ParserTypeBadge';\nimport { ExpressionEditor } from '../components/parser/ExpressionEditor';\nimport { ExportParserDialog } from '../components/parser/ExportParserDialog';\nimport { Section, SectionStack } from '../components/common';\n\n// RBAC\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\n\n// i18n\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n// fe-libs UI components\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { IllustratedEmptyState, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n} from '@burdenoff/fe-libs/ui';\n\n// Lucide icons\nimport {\n ArrowLeft,\n Edit,\n Play,\n Trash2,\n Copy,\n Check,\n FileCode2,\n Database,\n ArrowDown,\n Loader2,\n AlertCircle,\n AlertTriangle,\n Download,\n} from 'lucide-react';\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\n// Default console ID for standalone parser viewing\nconst DEFAULT_CONSOLE_ID = 'default';\n\nexport const ParserViewPage = memo(function ParserViewPage() {\n const { parserId, consoleId: urlConsoleId } = useParams<{ parserId: string; consoleId?: string }>();\n const navigate = useAppNavigate();\n const { t } = useI18n();\n\n // Use URL consoleId or fall back to default\n const consoleId = urlConsoleId || DEFAULT_CONSOLE_ID;\n\n // Permissions\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.PARSER_READ);\n\n // Local state\n const [isDeleting, setIsDeleting] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [expressionCopied, setExpressionCopied] = useState(false);\n const [isTesting, setIsTesting] = useState(false);\n const [isExportDialogOpen, setIsExportDialogOpen] = useState(false);\n const [testResult, setTestResult] = useState<{\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n } | null>(null);\n\n // Store\n const parser = useParserStore((state) => (parserId ? state.parsers.get(parserId) : undefined));\n\n // Operations - use consoleId from URL or default\n const { loading, error, fetchParser, deleteParser, executeParser } = useParserOperations({\n consoleId,\n skipFetch: true,\n });\n\n // DataSink operations for source datasink info\n const { dataSinks, fetchDataSinks } = useDataSinkOperations({ skipFetch: true });\n\n // Load parser on mount - always fetch full data to get expression\n useEffect(() => {\n if (parserId) {\n fetchParser(parserId);\n }\n }, [parserId, fetchParser]);\n\n // Fetch datasinks to show source name\n useEffect(() => {\n fetchDataSinks();\n }, [fetchDataSinks]);\n\n // Get source datasink name\n const sourceDataSink = parser?.inputSinkKey ? dataSinks.find((ds) => ds.key === parser.inputSinkKey) : null;\n\n // Handle back navigation\n const handleBack = useCallback(() => {\n // Navigate to dashboard-scoped parsers list if consoleId is provided\n if (urlConsoleId) {\n navigate(`/dashboards/${urlConsoleId}/parsers`);\n } else {\n navigate(`/parsers`);\n }\n }, [navigate, urlConsoleId]);\n\n // Handle edit\n const handleEdit = useCallback(() => {\n // Navigate to dashboard-scoped parser edit if consoleId is provided\n if (urlConsoleId) {\n navigate(`/dashboards/${urlConsoleId}/parsers/${parserId}/edit`);\n } else {\n navigate(`/parsers/${parserId}/edit`);\n }\n }, [navigate, parserId, urlConsoleId]);\n\n // Handle delete\n const handleDelete = useCallback(async () => {\n if (!parserId) return;\n setIsDeleting(true);\n try {\n const success = await deleteParser(parserId);\n if (success) {\n if (isNative()) void nativeNotify('success');\n // Navigate to dashboard-scoped parsers list if consoleId is provided\n if (urlConsoleId) {\n navigate(`/dashboards/${urlConsoleId}/parsers`);\n } else {\n navigate(`/parsers`);\n }\n } else if (isNative()) {\n void nativeNotify('error');\n }\n } catch {\n if (isNative()) void nativeNotify('error');\n } finally {\n setIsDeleting(false);\n setShowDeleteConfirm(false);\n }\n }, [parserId, deleteParser, navigate, urlConsoleId]);\n\n // Handle copy expression\n const handleCopyExpression = useCallback(async () => {\n if (!parser?.expression) return;\n try {\n await nativeCopyText(parser.expression);\n setExpressionCopied(true);\n if (isNative()) void nativeToast(t('bigconsole.parsers.view.expressionCopied', 'Expression copied'));\n setTimeout(() => setExpressionCopied(false), 2000);\n } catch {\n // Clipboard access is best-effort; the expression stays visible either way.\n }\n }, [parser?.expression, t]);\n\n // Handle test execution\n const handleTestExecute = useCallback(async () => {\n if (!parserId) return;\n setIsTesting(true);\n setTestResult(null);\n try {\n const result = await executeParser(parserId);\n if (result) {\n setTestResult({\n success: result.success,\n output: result.output,\n error: result.error,\n executionTimeMs: result.executionTimeMs,\n });\n }\n } catch (err) {\n setTestResult({\n success: false,\n output: null,\n error: err instanceof Error ? err.message : t('bigconsole.parsers.view.executionFailed', 'Execution failed'),\n executionTimeMs: 0,\n });\n } finally {\n setIsTesting(false);\n }\n }, [parserId, executeParser, t]);\n\n // Navigate to source datasink\n const handleViewSourceDataSink = useCallback(() => {\n if (sourceDataSink) {\n navigate(`/datasinks/${sourceDataSink.id}`);\n }\n }, [navigate, sourceDataSink]);\n\n // Handle export\n const handleExport = useCallback(() => {\n setIsExportDialogOpen(true);\n }, []);\n\n const handleExportClose = useCallback(() => {\n setIsExportDialogOpen(false);\n }, []);\n\n // Loading state (wait for both the parser fetch and the permission load)\n if ((loading && !parser) || permissionsLoading) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Loader2 className=\"w-8 h-8 text-text-secondary animate-spin\" />\n </div>\n );\n }\n\n // Read gate — no permission to view this parser\n if (!canRead) {\n return (\n <AccessDenied\n title={t('bigconsole.parsers.accessDenied.title', 'Access Denied')}\n description={t('bigconsole.parsers.accessDenied.view', \"You don't have permission to view this parser.\")}\n />\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"p-card-padding\">\n <Section\n tone=\"danger\"\n headingLevel={2}\n title={t('bigconsole.parsers.errors.viewLoadFailed', 'Failed to load Parser')}\n description=\"The parser could not be fetched. Go back to the list and try again.\"\n icon={<AlertCircle className=\"h-icon-md w-icon-md text-[var(--color-status-error-text)]\" />}\n actions={\n <Button onClick={handleBack} variant=\"secondary\" size=\"sm\">\n <ArrowLeft className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.goBack', 'Go back')}\n </Button>\n }\n data-testid=\"parser-load-error\"\n >\n <p className=\"font-mono text-xs break-words text-text-secondary\">{error.message}</p>\n </Section>\n </div>\n );\n }\n\n // Not found state\n if (!parser) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px] p-card-padding\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('bigconsole.parsers.view.notFoundTitle', 'Parser not found')}\n description={t(\n 'bigconsole.parsers.view.notFoundDescription',\n \"The Parser you're looking for doesn't exist or has been deleted.\"\n )}\n action={\n <Button onClick={handleBack} variant=\"default\" size=\"default\">\n <ArrowLeft className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.goBackToParsers', 'Go back to Parsers')}\n </Button>\n }\n />\n </div>\n );\n }\n\n // The route exists to show the expression — until a run produces output. Once\n // it does, the freshly produced result becomes the page's primary block and\n // the (static) expression steps down to `standard`, so only one block is ever\n // promoted at a time.\n const hasResult = testResult !== null;\n\n return (\n <div className=\"p-card-padding\">\n <SectionStack>\n {/* Page header strip — structural, no surface of its own */}\n <div className=\"flex flex-col gap-form-gap border-b border-[var(--color-border-subtle)] pb-form-gap sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <Button onClick={handleBack} variant=\"ghost\" size=\"sm\" className=\"mb-4\">\n <ArrowLeft className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.view.backToParsers', 'Back to Parsers')}\n </Button>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h1 className=\"text-2xl font-bold text-text-primary sm:text-3xl\">\n {parser.name || t('bigconsole.parsers.view.untitled', 'Untitled')}\n </h1>\n <ParserTypeBadge type={parser.type} />\n <ParserStatusBadge status={parser.status} />\n </div>\n {parser.description && <p className=\"text-sm text-text-secondary mt-2\">{parser.description}</p>}\n </div>\n\n {/* Actions — Execute is the page's primary verb, so it is the only filled button */}\n <div className=\"flex shrink-0 flex-wrap items-center gap-control-gap\">\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PARSER_EXECUTE} deniedBehavior=\"disable\">\n <Button onClick={handleTestExecute} disabled={isTesting} variant=\"default\" size=\"default\">\n <Play className=\"w-4 h-4 mr-2\" />\n {isTesting\n ? t('bigconsole.parsers.view.running', 'Running...')\n : t('bigconsole.parsers.actions.execute', 'Execute')}\n </Button>\n </PermissionButton>\n <Button onClick={handleExport} variant=\"secondary\" size=\"default\">\n <Download className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.export', 'Export')}\n </Button>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PARSER_UPDATE} deniedBehavior=\"disable\">\n <Button onClick={handleEdit} variant=\"secondary\" size=\"default\">\n <Edit className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.edit', 'Edit')}\n </Button>\n </PermissionButton>\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PARSER_DELETE} deniedBehavior=\"hide\">\n <Button\n onClick={() => setShowDeleteConfirm(true)}\n disabled={isDeleting}\n variant=\"destructive\"\n size=\"default\"\n >\n <Trash2 className=\"w-4 h-4 mr-2\" />\n {t('bigconsole.parsers.actions.delete', 'Delete')}\n </Button>\n </PermissionButton>\n </div>\n </div>\n\n <PagePurpose className=\"max-w-[80ch]\">\n {t(\n 'bigconsole.parsers.view.purpose',\n 'A parser turns raw input into structured fields using its expression. Review or copy the expression, run it against a sample to see the output, then edit it or use it inside a pipeline to shape incoming data.'\n )}\n </PagePurpose>\n\n {/* Main Content Grid */}\n <div className=\"grid gap-section-gap md:grid-cols-2 lg:grid-cols-3\">\n {/* Expression + result column */}\n <div className=\"flex min-w-0 flex-col gap-section-gap md:col-span-2\">\n {/* Execution result — rendered first once it exists so the outcome of\n the primary action is visible without scrolling past the editor. */}\n {testResult && (\n <Section\n id=\"parser-execution-result\"\n emphasis=\"primary\"\n tone={testResult.success ? 'success' : 'danger'}\n headingLevel={2}\n title={t('bigconsole.parsers.view.executionResult', 'Execution Result')}\n description={\n testResult.success\n ? 'Output produced by the latest run of this parser.'\n : 'The latest run did not complete. Fix the expression or the input and run again.'\n }\n meta={\n <Badge variant={testResult.success ? 'default' : 'destructive'}>\n {testResult.success\n ? t('bigconsole.parsers.view.success', 'Success')\n : t('bigconsole.parsers.view.failed', 'Failed')}\n </Badge>\n }\n actions={\n <Badge variant=\"secondary\" className=\"text-xs\">\n {testResult.executionTimeMs}ms\n </Badge>\n }\n data-testid=\"parser-execution-result\"\n >\n <pre className=\"max-h-[300px] min-w-0 overflow-auto rounded-md bg-bg-sunken p-4 font-mono text-sm text-text-primary\">\n {testResult.error ?? JSON.stringify(testResult.output, null, 2)}\n </pre>\n </Section>\n )}\n\n {/* Expression */}\n <Section\n emphasis={hasResult ? 'standard' : 'primary'}\n headingLevel={2}\n title={t('bigconsole.parsers.view.expression', 'Expression')}\n description=\"The JQ or JSONata program this parser runs against every input record.\"\n icon={<FileCode2 className=\"h-icon-sm w-icon-sm\" />}\n meta={\n <Badge variant=\"secondary\" className=\"text-xs uppercase\">\n {parser.type}\n </Badge>\n }\n actions={\n <Button onClick={handleCopyExpression} variant=\"ghost\" size=\"sm\">\n {expressionCopied ? (\n <>\n <Check className=\"w-3.5 h-3.5 text-status-success-text mr-2\" />\n {t('bigconsole.parsers.view.copied', 'Copied!')}\n </>\n ) : (\n <>\n <Copy className=\"w-3.5 h-3.5 mr-2\" />\n {t('bigconsole.parsers.actions.copy', 'Copy')}\n </>\n )}\n </Button>\n }\n data-testid=\"parser-expression\"\n >\n <ExpressionEditor\n value={parser.expression}\n type={parser.type}\n readOnly\n height=\"clamp(180px, 40vh, 300px)\"\n />\n </Section>\n </div>\n\n {/* Supporting column — steps down from the expression/result column */}\n <div className=\"grid min-w-0 gap-section-gap md:col-span-2 md:grid-cols-2 lg:col-span-1 lg:grid-cols-1\">\n {/* Data Flow */}\n <Section\n headingLevel={2}\n title={t('bigconsole.parsers.view.dataFlow', 'Data Flow')}\n description=\"Where this parser reads from and what it writes.\"\n data-testid=\"parser-data-flow\"\n >\n <dl className=\"space-y-3\">\n {/* Source DataSink */}\n <div>\n <dt className=\"text-xs font-medium uppercase tracking-wide text-text-muted\">\n {t('bigconsole.parsers.view.sourceDataSink', 'Source DataSink')}\n </dt>\n {parser.inputSinkKey ? (\n <dd className=\"mt-1\">\n <p className=\"break-words font-mono text-sm font-medium text-text-primary\">\n {parser.inputSinkKey}\n </p>\n {sourceDataSink && (\n <Button onClick={handleViewSourceDataSink} variant=\"link\" size=\"sm\" className=\"mt-1 p-0 h-auto\">\n <Database className=\"w-3 h-3 mr-1\" />\n {t('bigconsole.parsers.view.viewDataSink', 'View {{name}}', {\n name: sourceDataSink.name || t('bigconsole.parsers.view.dataSinkFallback', 'DataSink'),\n })}\n </Button>\n )}\n </dd>\n ) : (\n <dd className=\"mt-1 text-sm text-text-muted\">\n {t('bigconsole.parsers.view.noneConfigured', 'None configured')}\n </dd>\n )}\n </div>\n\n {/* Arrow */}\n <div aria-hidden=\"true\" className=\"flex items-center justify-center py-1\">\n <ArrowDown className=\"w-4 h-4 text-text-muted\" />\n </div>\n\n {/* Output Key */}\n <div>\n <dt className=\"text-xs font-medium uppercase tracking-wide text-text-muted\">\n {t('bigconsole.parsers.view.outputKey', 'Output Key')}\n </dt>\n <dd className=\"mt-1 break-words font-mono text-sm font-medium text-text-primary\">\n {parser.outputKey || t('bigconsole.parsers.view.notConfigured', 'Not configured')}\n </dd>\n </div>\n </dl>\n </Section>\n\n {/* Configuration */}\n <Section\n headingLevel={2}\n title={t('bigconsole.parsers.view.configuration', 'Configuration')}\n data-testid=\"parser-configuration\"\n >\n <dl className=\"space-y-4 text-sm\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.status', 'Status')}</dt>\n <dd>\n <ParserStatusBadge status={parser.status} />\n </dd>\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.type', 'Type')}</dt>\n <dd>\n <ParserTypeBadge type={parser.type} />\n </dd>\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.cacheTtl', 'Cache TTL')}</dt>\n <dd className=\"text-text-primary font-medium\">\n {parser.ttl\n ? t('bigconsole.parsers.view.ttlSeconds', '{{ttl}}s', { ttl: parser.ttl })\n : t('bigconsole.parsers.view.noCaching', 'No caching')}\n </dd>\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.version', 'Version')}</dt>\n <dd className=\"text-text-primary font-medium\">{parser.version || 1}</dd>\n </div>\n </dl>\n </Section>\n\n {/* Timestamps — least important block on the page, so it is recessed */}\n <Section\n emphasis=\"muted\"\n padding=\"compact\"\n headingLevel={2}\n title={t('bigconsole.parsers.view.timestamps', 'Timestamps')}\n data-testid=\"parser-history\"\n >\n <dl className=\"space-y-4 text-sm\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.created', 'Created')}</dt>\n <dd className=\"text-text-primary font-medium\">\n {parser.createdAt\n ? formatDistanceToNow(new Date(parser.createdAt), { addSuffix: true })\n : t('bigconsole.parsers.view.unknown', 'Unknown')}\n </dd>\n </div>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt className=\"text-text-secondary\">{t('bigconsole.parsers.view.updated', 'Updated')}</dt>\n <dd className=\"text-text-primary font-medium\">\n {parser.updatedAt\n ? formatDistanceToNow(new Date(parser.updatedAt), { addSuffix: true })\n : t('bigconsole.parsers.view.unknown', 'Unknown')}\n </dd>\n </div>\n </dl>\n </Section>\n </div>\n </div>\n\n {/* Guidance sits after the data it talks about */}\n <NextSteps\n storageKey=\"bigconsole-parser-view\"\n steps={[\n {\n id: 'execute',\n label: t('bigconsole.parsers.view.nextSteps.executeLabel', 'Run a test execution'),\n description: t(\n 'bigconsole.parsers.view.nextSteps.executeDescription',\n 'Check the expression produces the fields you expect.'\n ),\n onClick: handleTestExecute,\n },\n {\n id: 'edit',\n label: t('bigconsole.parsers.view.nextSteps.editLabel', 'Edit the expression'),\n description: t(\n 'bigconsole.parsers.view.nextSteps.editDescription',\n 'Refine how this parser maps your input.'\n ),\n onClick: handleEdit,\n },\n {\n id: 'pipeline',\n label: t('bigconsole.parsers.view.nextSteps.pipelineLabel', 'Use it in a pipeline'),\n description: t(\n 'bigconsole.parsers.view.nextSteps.pipelineDescription',\n 'Chain this parser with a data sink to process data end to end.'\n ),\n onClick: () => navigate('/pipelines'),\n },\n ]}\n />\n </SectionStack>\n\n {/* Delete Confirmation ResponsiveDialog */}\n <ResponsiveDialog open={showDeleteConfirm} onOpenChange={setShowDeleteConfirm}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {t('bigconsole.parsers.view.deleteDialogTitle', 'Delete Parser')}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {t('bigconsole.parsers.view.deleteConfirmPrefix', 'Are you sure you want to delete')}{' '}\n <strong>{parser.name}</strong>\n {t('bigconsole.parsers.view.deleteConfirmSuffix', '? This action cannot be undone.')}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <Section\n tone=\"warning\"\n padding=\"compact\"\n headingLevel={3}\n title=\"Check dependents first\"\n description={t(\n 'bigconsole.parsers.view.deleteWarning',\n 'Widgets and pipelines using this parser may stop working correctly after deletion.'\n )}\n icon={<AlertTriangle className=\"h-icon-sm w-icon-sm text-[var(--color-status-warning-text)]\" />}\n data-testid=\"parser-delete-warning\"\n />\n <ResponsiveDialogFooter>\n <Button onClick={() => setShowDeleteConfirm(false)} variant=\"secondary\">\n {t('bigconsole.parsers.actions.cancel', 'Cancel')}\n </Button>\n <Button\n onClick={() => {\n nativeImpact('medium');\n void handleDelete();\n }}\n disabled={isDeleting}\n variant=\"destructive\"\n >\n {isDeleting\n ? t('bigconsole.parsers.view.deleting', 'Deleting...')\n : t('bigconsole.parsers.view.deleteDialogTitle', 'Delete Parser')}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Export Parser ResponsiveDialog */}\n <ExportParserDialog\n isOpen={isExportDialogOpen}\n parserId={parserId || null}\n parserName={parser.name}\n onClose={handleExportClose}\n />\n </div>\n );\n});\n\nexport default ParserViewPage;\n"],"mappings":"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"}
@@ -11,9 +11,9 @@ import { memo as o, useCallback as s, useEffect as ne, useId as re, useMemo as c
11
11
  import { useParams as ie } from "react-router";
12
12
  import { AccessDenied as ae } from "@burdenoff/fe-libs/shared/components";
13
13
  import { usePermissions as oe } from "@burdenoff/fe-libs/shared/providers/shell";
14
- import { useI18n as se } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
- import { Button as u, IllustratedEmptyState as ce, PagePurpose as le, Spinner as ue } from "@burdenoff/fe-libs/ui";
16
- import { Fragment as de, jsx as d, jsxs as f } from "react/jsx-runtime";
14
+ import { Button as u, IllustratedEmptyState as se, PagePurpose as ce, Spinner as le } from "@burdenoff/fe-libs/ui";
15
+ import { Fragment as ue, jsx as d, jsxs as f } from "react/jsx-runtime";
16
+ import { useI18n as de } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
17
  //#region src/bigconsole/pages/PipelineBuilderPage.tsx
18
18
  var p = "min-h-[var(--size-controlHeight-md)]", m = "mb-1 block text-sm font-medium text-text-primary", h = "mt-1 text-xs text-text-secondary", g = "mb-1 text-xs font-semibold uppercase tracking-wide text-text-muted", _ = `w-full min-w-0 rounded-input border border-[var(--color-border-subtle)] bg-bg-canvas px-3 py-2 text-sm text-text-primary ${t}`, v = `${_} font-mono`, y = `inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-button text-text-secondary motion-safe:transition-colors disabled:opacity-30 ${t}`, b = `${y} hover:bg-bg-surface hover:text-text-primary`, fe = `${y} hover:bg-[var(--color-status-error-bgSubtle)] hover:text-status-error-text`, pe = ({ className: e }) => /* @__PURE__ */ d("svg", {
19
19
  className: e,
@@ -121,7 +121,7 @@ var p = "min-h-[var(--size-controlHeight-md)]", m = "mb-1 block text-sm font-med
121
121
  fallbackValue: "",
122
122
  description: ""
123
123
  }, w = o(function() {
124
- let { t: o } = se(), { pipelineId: y } = ie(), w = e(), T = !!y && y !== "new", E = "default", D = re(), { hasPermission: O, isLoading: ye } = oe(), be = O(a.PIPELINE_READ), xe = O(a.PIPELINE_CREATE), Se = O(a.PIPELINE_UPDATE), k = T ? Se : xe, [A, j] = l(""), [M, N] = l(""), [P, F] = l("draft"), [I, L] = l([]), [R, Ce] = l(1), [z, B] = l(!1), [V, H] = l(null), { loading: we, error: U, fetchPipeline: W, createPipeline: G, updatePipeline: K } = ee({
124
+ let { t: o } = de(), { pipelineId: y } = ie(), w = e(), T = !!y && y !== "new", E = "default", D = re(), { hasPermission: O, isLoading: ye } = oe(), be = O(a.PIPELINE_READ), xe = O(a.PIPELINE_CREATE), Se = O(a.PIPELINE_UPDATE), k = T ? Se : xe, [A, j] = l(""), [M, N] = l(""), [P, F] = l("draft"), [I, L] = l([]), [R, Ce] = l(1), [z, B] = l(!1), [V, H] = l(null), { loading: we, error: U, fetchPipeline: W, createPipeline: G, updatePipeline: K } = ee({
125
125
  consoleId: E,
126
126
  skipFetch: !0
127
127
  }), { parsers: q } = i({ consoleId: E });
@@ -234,7 +234,7 @@ var p = "min-h-[var(--size-controlHeight-md)]", m = "mb-1 block text-sm font-med
234
234
  children: /* @__PURE__ */ f("div", {
235
235
  className: "flex flex-col items-center justify-center py-16",
236
236
  role: "status",
237
- children: [/* @__PURE__ */ d(ue, { style: {
237
+ children: [/* @__PURE__ */ d(le, { style: {
238
238
  height: "var(--size-icon-xl)",
239
239
  width: "var(--size-icon-xl)"
240
240
  } }), /* @__PURE__ */ d("p", {
@@ -310,7 +310,7 @@ var p = "min-h-[var(--size-controlHeight-md)]", m = "mb-1 block text-sm font-med
310
310
  })]
311
311
  })]
312
312
  }),
313
- /* @__PURE__ */ d(le, {
313
+ /* @__PURE__ */ d(ce, {
314
314
  className: "max-w-[75ch]",
315
315
  children: o("bigconsole.pipelines.builder.header.purpose", "Build a pipeline by chaining parser stages — each stage reads an input key, runs a parser, and writes a structured output key that the next stage (or a data sink) can use. Name it, add your stages in order, then test it before saving so your data flows end to end.")
316
316
  }),
@@ -409,7 +409,7 @@ var p = "min-h-[var(--size-controlHeight-md)]", m = "mb-1 block text-sm font-med
409
409
  children: [/* @__PURE__ */ d(x, { className: "h-icon-sm w-icon-sm" }), o("bigconsole.pipelines.builder.stages.addStage", "Add Stage")]
410
410
  }),
411
411
  "data-testid": "pipeline-stages-editor",
412
- children: I.length === 0 ? /* @__PURE__ */ d(ce, {
412
+ children: I.length === 0 ? /* @__PURE__ */ d(se, {
413
413
  illustration: "empty-generic",
414
414
  title: o("bigconsole.pipelines.builder.stages.emptyTitle", "No stages yet"),
415
415
  description: o("bigconsole.pipelines.builder.stages.emptyDescription", "Add a stage to start building your pipeline."),
@@ -437,7 +437,7 @@ var p = "min-h-[var(--size-controlHeight-md)]", m = "mb-1 block text-sm font-med
437
437
  children: e.parserName || o("bigconsole.pipelines.builder.stages.defaultStageName", "Stage {{number}}", { number: r + 1 })
438
438
  })]
439
439
  }),
440
- actions: /* @__PURE__ */ f(de, { children: [
440
+ actions: /* @__PURE__ */ f(ue, { children: [
441
441
  /* @__PURE__ */ d("button", {
442
442
  type: "button",
443
443
  onClick: () => Q(r, "up"),
@@ -13,11 +13,11 @@ import { memo as l, useCallback as u, useEffect as ne, useId as re, useState as
13
13
  import { useParams as ie, useSearchParams as ae } from "react-router";
14
14
  import { AccessDenied as f } from "@burdenoff/fe-libs/shared/components";
15
15
  import { usePermissions as p } from "@burdenoff/fe-libs/shared/providers/shell";
16
- import { useI18n as m } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
- import { Button as h, IllustratedEmptyState as oe, NextSteps as se, PagePurpose as ce, Spinner as le } from "@burdenoff/fe-libs/ui";
16
+ import { Button as m, IllustratedEmptyState as h, NextSteps as oe, PagePurpose as se, Spinner as ce } from "@burdenoff/fe-libs/ui";
18
17
  import { jsx as g, jsxs as _ } from "react/jsx-runtime";
18
+ import { useI18n as v } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
19
19
  //#region src/bigconsole/pages/PipelineViewPage.tsx
20
- var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary", y = "rounded-button bg-bg-surface px-1.5 py-0.5 font-mono break-all text-text-primary", b = ({ className: e }) => /* @__PURE__ */ g("svg", {
20
+ var y = "min-h-[var(--size-controlHeight-md)]", le = "rounded-pill bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary", b = "rounded-button bg-bg-surface px-1.5 py-0.5 font-mono break-all text-text-primary", x = ({ className: e }) => /* @__PURE__ */ g("svg", {
21
21
  className: e,
22
22
  fill: "none",
23
23
  stroke: "currentColor",
@@ -28,7 +28,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
28
28
  strokeWidth: 2,
29
29
  d: "M10 19l-7-7m0 0l7-7m-7 7h18"
30
30
  })
31
- }), x = ({ className: e }) => /* @__PURE__ */ g("svg", {
31
+ }), S = ({ className: e }) => /* @__PURE__ */ g("svg", {
32
32
  className: e,
33
33
  fill: "none",
34
34
  stroke: "currentColor",
@@ -39,7 +39,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
39
39
  strokeWidth: 2,
40
40
  d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
41
41
  })
42
- }), S = ({ className: e }) => /* @__PURE__ */ g("svg", {
42
+ }), C = ({ className: e }) => /* @__PURE__ */ g("svg", {
43
43
  className: e,
44
44
  fill: "none",
45
45
  stroke: "currentColor",
@@ -50,7 +50,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
50
50
  strokeWidth: 2,
51
51
  d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
52
52
  })
53
- }), C = ({ className: e }) => /* @__PURE__ */ _("svg", {
53
+ }), w = ({ className: e }) => /* @__PURE__ */ _("svg", {
54
54
  className: e,
55
55
  fill: "none",
56
56
  stroke: "currentColor",
@@ -66,7 +66,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
66
66
  strokeWidth: 2,
67
67
  d: "M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
68
68
  })]
69
- }), w = ({ className: e }) => /* @__PURE__ */ g("svg", {
69
+ }), T = ({ className: e }) => /* @__PURE__ */ g("svg", {
70
70
  className: e,
71
71
  fill: "none",
72
72
  stroke: "currentColor",
@@ -77,7 +77,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
77
77
  strokeWidth: 2,
78
78
  d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
79
79
  })
80
- }), de = ({ className: e }) => /* @__PURE__ */ g("svg", {
80
+ }), ue = ({ className: e }) => /* @__PURE__ */ g("svg", {
81
81
  className: e,
82
82
  fill: "none",
83
83
  stroke: "currentColor",
@@ -88,7 +88,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
88
88
  strokeWidth: 2,
89
89
  d: "M5 13l4 4L19 7"
90
90
  })
91
- }), T = ({ className: e }) => /* @__PURE__ */ g("svg", {
91
+ }), E = ({ className: e }) => /* @__PURE__ */ g("svg", {
92
92
  className: e,
93
93
  fill: "none",
94
94
  stroke: "currentColor",
@@ -99,8 +99,8 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
99
99
  strokeWidth: 2,
100
100
  d: "M14 5l7 7m0 0l-7 7m7-7H3"
101
101
  })
102
- }), E = ({ handling: e }) => {
103
- let { t } = m(), n = {
102
+ }), de = ({ handling: e }) => {
103
+ let { t } = v(), n = {
104
104
  fail: {
105
105
  label: t("bigconsole.pipelines.view.errorHandlingFail", "Fail"),
106
106
  className: "bg-[var(--color-status-error-bgSubtle)] text-status-error-text border-[var(--color-status-error-border)]"
@@ -122,7 +122,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
122
122
  }), r.label]
123
123
  });
124
124
  }, D = l(function() {
125
- let { pipelineId: l } = ie(), D = t(), { t: O } = m(), k = "default", [fe] = ae(), A = re(), { hasPermission: j, isLoading: pe } = p(), M = j(a.PIPELINE_READ), N = j(a.PIPELINE_UPDATE), P = j(a.PIPELINE_DELETE), F = j(a.PIPELINE_TEST), [I, L] = d(null), [R, z] = d("{\n \"data\": \"sample\"\n}"), [B, me] = d(null), [V, H] = d(fe.get("test") === "true"), he = e((e) => e.deleteDialogOpen), U = e((e) => e.openDeleteDialog), W = e((e) => e.closeDeleteDialog), { loading: G, error: K, fetchPipeline: q, deletePipeline: J, testPipeline: Y } = ee({
125
+ let { pipelineId: l } = ie(), D = t(), { t: O } = v(), k = "default", [fe] = ae(), A = re(), { hasPermission: j, isLoading: pe } = p(), M = j(a.PIPELINE_READ), N = j(a.PIPELINE_UPDATE), P = j(a.PIPELINE_DELETE), F = j(a.PIPELINE_TEST), [I, L] = d(null), [R, z] = d("{\n \"data\": \"sample\"\n}"), [B, me] = d(null), [V, H] = d(fe.get("test") === "true"), he = e((e) => e.deleteDialogOpen), U = e((e) => e.openDeleteDialog), W = e((e) => e.closeDeleteDialog), { loading: G, error: K, fetchPipeline: q, deletePipeline: J, testPipeline: Y } = ee({
126
126
  consoleId: k,
127
127
  skipFetch: !0
128
128
  });
@@ -164,7 +164,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
164
164
  children: /* @__PURE__ */ _("div", {
165
165
  className: "flex flex-col items-center justify-center py-16",
166
166
  role: "status",
167
- children: [/* @__PURE__ */ g(le, { style: {
167
+ children: [/* @__PURE__ */ g(ce, { style: {
168
168
  height: "var(--size-icon-xl)",
169
169
  width: "var(--size-icon-xl)"
170
170
  } }), /* @__PURE__ */ g("p", {
@@ -184,10 +184,10 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
184
184
  headingLevel: 2,
185
185
  title: O("bigconsole.pipelines.view.loadError", "Failed to load Pipeline"),
186
186
  description: K.message,
187
- icon: /* @__PURE__ */ g(w, { className: "h-icon-sm w-icon-sm" }),
188
- actions: /* @__PURE__ */ g(h, {
187
+ icon: /* @__PURE__ */ g(T, { className: "h-icon-sm w-icon-sm" }),
188
+ actions: /* @__PURE__ */ g(m, {
189
189
  onClick: X,
190
- className: v,
190
+ className: y,
191
191
  children: O("bigconsole.pipelines.actions.backToPipelines", "Back to Pipelines")
192
192
  }),
193
193
  "data-testid": "pipeline-view-error",
@@ -204,10 +204,10 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
204
204
  headingLevel: 2,
205
205
  title: O("bigconsole.pipelines.view.notFoundTitle", "Pipeline not found"),
206
206
  description: O("bigconsole.pipelines.view.notFoundDescription", "The pipeline you're looking for doesn't exist or has been deleted."),
207
- icon: /* @__PURE__ */ g(w, { className: "h-icon-sm w-icon-sm" }),
208
- actions: /* @__PURE__ */ g(h, {
207
+ icon: /* @__PURE__ */ g(T, { className: "h-icon-sm w-icon-sm" }),
208
+ actions: /* @__PURE__ */ g(m, {
209
209
  onClick: X,
210
- className: v,
210
+ className: y,
211
211
  children: O("bigconsole.pipelines.actions.backToPipelines", "Back to Pipelines")
212
212
  }),
213
213
  "data-testid": "pipeline-not-found"
@@ -219,16 +219,16 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
219
219
  title: O("bigconsole.pipelines.view.stagesHeading", "Pipeline Stages ({{count}})", { count: Q }),
220
220
  description: "Data flows top to bottom — each stage reads its input key and writes an output key for the next one.",
221
221
  "data-testid": "pipeline-stages",
222
- children: Q === 0 ? /* @__PURE__ */ g(oe, {
222
+ children: Q === 0 ? /* @__PURE__ */ g(h, {
223
223
  illustration: "empty-generic",
224
224
  title: O("bigconsole.pipelines.view.noStagesTitle", "No stages defined"),
225
225
  description: O("bigconsole.pipelines.view.noStagesDescription", "Edit the pipeline to add parser stages."),
226
- action: /* @__PURE__ */ _(h, {
226
+ action: /* @__PURE__ */ _(m, {
227
227
  variant: "secondary",
228
228
  onClick: Z,
229
229
  disabled: !N,
230
- className: v,
231
- children: [/* @__PURE__ */ g(x, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.edit", "Edit")]
230
+ className: y,
231
+ children: [/* @__PURE__ */ g(S, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.edit", "Edit")]
232
232
  })
233
233
  }) : /* @__PURE__ */ g("ol", {
234
234
  className: "flex flex-col",
@@ -260,7 +260,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
260
260
  ]
261
261
  }), /* @__PURE__ */ _("div", {
262
262
  className: "flex flex-wrap items-center gap-icon-gap",
263
- children: [/* @__PURE__ */ g(E, { handling: e.onError }), !e.enabled && /* @__PURE__ */ g("span", {
263
+ children: [/* @__PURE__ */ g(de, { handling: e.onError }), !e.enabled && /* @__PURE__ */ g("span", {
264
264
  className: "rounded-pill border border-[var(--color-border-strong)] px-2 py-0.5 text-xs font-medium text-text-secondary",
265
265
  children: O("bigconsole.pipelines.view.stageDisabled", "Disabled")
266
266
  })]
@@ -274,16 +274,16 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
274
274
  children: "Reads"
275
275
  }),
276
276
  /* @__PURE__ */ g("code", {
277
- className: y,
277
+ className: b,
278
278
  children: e.inputKey
279
279
  }),
280
- /* @__PURE__ */ g(T, { className: "h-3 w-3 shrink-0" }),
280
+ /* @__PURE__ */ g(E, { className: "h-3 w-3 shrink-0" }),
281
281
  /* @__PURE__ */ g("span", {
282
282
  className: "text-text-muted",
283
283
  children: "writes"
284
284
  }),
285
285
  /* @__PURE__ */ g("code", {
286
- className: y,
286
+ className: b,
287
287
  children: e.outputKey
288
288
  })
289
289
  ]
@@ -302,7 +302,7 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
302
302
  }), t < Q - 1 && /* @__PURE__ */ g("span", {
303
303
  "aria-hidden": "true",
304
304
  className: "flex justify-center py-1",
305
- children: /* @__PURE__ */ g(T, { className: "h-icon-sm w-icon-sm rotate-90 text-text-muted" })
305
+ children: /* @__PURE__ */ g(E, { className: "h-icon-sm w-icon-sm rotate-90 text-text-muted" })
306
306
  })]
307
307
  }, e.id))
308
308
  })
@@ -312,11 +312,11 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
312
312
  headingLevel: 2,
313
313
  title: O("bigconsole.pipelines.view.testPanelHeading", "Test Pipeline"),
314
314
  description: "Run sample input through every enabled stage. Nothing is written to the connected sink.",
315
- actions: /* @__PURE__ */ _(h, {
315
+ actions: /* @__PURE__ */ _(m, {
316
316
  onClick: ye,
317
317
  disabled: G || !F,
318
- className: v,
319
- children: [/* @__PURE__ */ g(C, { className: "h-icon-sm w-icon-sm" }), G ? O("bigconsole.pipelines.view.testRunning", "Running...") : O("bigconsole.pipelines.view.runTest", "Run Test")]
318
+ className: y,
319
+ children: [/* @__PURE__ */ g(w, { className: "h-icon-sm w-icon-sm" }), G ? O("bigconsole.pipelines.view.testRunning", "Running...") : O("bigconsole.pipelines.view.runTest", "Run Test")]
320
320
  }),
321
321
  "data-testid": "pipeline-test-panel",
322
322
  children: /* @__PURE__ */ _("div", {
@@ -339,9 +339,9 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
339
339
  tone: $ ? "success" : "danger",
340
340
  headingLevel: 3,
341
341
  title: $ ? O("bigconsole.pipelines.view.testPassed", "Test Passed") : O("bigconsole.pipelines.view.testFailed", "Test Failed"),
342
- icon: g($ ? de : w, { className: "h-icon-sm w-icon-sm" }),
342
+ icon: g($ ? ue : T, { className: "h-icon-sm w-icon-sm" }),
343
343
  meta: B.totalExecutionTimeMs ? /* @__PURE__ */ _("span", {
344
- className: ue,
344
+ className: le,
345
345
  children: [B.totalExecutionTimeMs, "ms"]
346
346
  }) : null,
347
347
  "data-testid": "pipeline-test-result",
@@ -378,12 +378,12 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
378
378
  children: [/* @__PURE__ */ _("div", {
379
379
  className: "flex min-w-0 flex-col gap-control-gap",
380
380
  children: [
381
- /* @__PURE__ */ _(h, {
381
+ /* @__PURE__ */ _(m, {
382
382
  variant: "ghost",
383
383
  size: "sm",
384
384
  onClick: X,
385
385
  className: "w-fit",
386
- children: [/* @__PURE__ */ g(b, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.backToPipelines", "Back to Pipelines")]
386
+ children: [/* @__PURE__ */ g(x, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.backToPipelines", "Back to Pipelines")]
387
387
  }),
388
388
  /* @__PURE__ */ _("div", {
389
389
  className: "flex flex-wrap items-center gap-icon-gap",
@@ -400,35 +400,35 @@ var v = "min-h-[var(--size-controlHeight-md)]", ue = "rounded-pill bg-bg-sunken
400
400
  }), /* @__PURE__ */ _("div", {
401
401
  className: "flex flex-wrap items-center gap-control-gap",
402
402
  children: [
403
- /* @__PURE__ */ _(h, {
403
+ /* @__PURE__ */ _(m, {
404
404
  onClick: () => H(!V),
405
405
  disabled: !F,
406
406
  "aria-expanded": V,
407
407
  "aria-controls": "pipeline-test-panel",
408
- className: v,
409
- children: [/* @__PURE__ */ g(C, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.test", "Test")]
408
+ className: y,
409
+ children: [/* @__PURE__ */ g(w, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.test", "Test")]
410
410
  }),
411
- /* @__PURE__ */ _(h, {
411
+ /* @__PURE__ */ _(m, {
412
412
  variant: "secondary",
413
413
  onClick: Z,
414
414
  disabled: !N,
415
- className: v,
416
- children: [/* @__PURE__ */ g(x, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.edit", "Edit")]
415
+ className: y,
416
+ children: [/* @__PURE__ */ g(S, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.edit", "Edit")]
417
417
  }),
418
- P && /* @__PURE__ */ _(h, {
418
+ P && /* @__PURE__ */ _(m, {
419
419
  variant: "destructive",
420
420
  onClick: ge,
421
- className: v,
422
- children: [/* @__PURE__ */ g(S, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.delete", "Delete")]
421
+ className: y,
422
+ children: [/* @__PURE__ */ g(C, { className: "h-icon-sm w-icon-sm" }), O("bigconsole.pipelines.actions.delete", "Delete")]
423
423
  })
424
424
  ]
425
425
  })]
426
426
  }),
427
- /* @__PURE__ */ g(ce, {
427
+ /* @__PURE__ */ g(se, {
428
428
  className: "max-w-[75ch]",
429
429
  children: O("bigconsole.pipelines.view.purpose", "A pipeline chains parsers and a data sink into a repeatable flow. Review its stages here, test it with sample input to confirm the output, then edit the stages or run it to process real data into the connected sink.")
430
430
  }),
431
- /* @__PURE__ */ g(se, {
431
+ /* @__PURE__ */ g(oe, {
432
432
  storageKey: "bigconsole-pipeline-view",
433
433
  steps: [
434
434
  ...F ? [{