@burdenoff/microfe-bigconsole 2026.924.2 → 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.
- package/dist/bigconsole/BigConsoleRoutes.js +137 -138
- package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
- package/dist/bigconsole/assistant/previewController.js +10 -10
- package/dist/bigconsole/components/DrilldownDashboardRenderer.js +17 -17
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +32 -32
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +52 -52
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +7 -7
- package/dist/bigconsole/components/dashboard/DashboardStatusPill.js +53 -0
- package/dist/bigconsole/components/dashboard/DashboardStatusPill.js.map +1 -0
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +60 -60
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +21 -21
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +30 -30
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +36 -36
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +34 -34
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +38 -38
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +121 -121
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +22 -22
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +46 -46
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +53 -53
- package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -1
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +47 -47
- package/dist/bigconsole/components/dashboard/index.js +1 -0
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +35 -35
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +18 -18
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +20 -20
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +30 -29
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +48 -48
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +103 -103
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +35 -35
- package/dist/bigconsole/components/overview/DashboardGuide.js +214 -0
- package/dist/bigconsole/components/overview/DashboardGuide.js.map +1 -0
- package/dist/bigconsole/components/overview/DataHealthCard.js +97 -0
- package/dist/bigconsole/components/overview/DataHealthCard.js.map +1 -0
- package/dist/bigconsole/components/overview/OverviewQuickActions.js +32 -0
- package/dist/bigconsole/components/overview/OverviewQuickActions.js.map +1 -0
- package/dist/bigconsole/components/overview/OverviewStatCard.js +57 -0
- package/dist/bigconsole/components/overview/OverviewStatCard.js.map +1 -0
- package/dist/bigconsole/components/overview/RecentDashboardsPanel.js +107 -0
- package/dist/bigconsole/components/overview/RecentDashboardsPanel.js.map +1 -0
- package/dist/bigconsole/components/overview/dashboardGuideSteps.js +119 -0
- package/dist/bigconsole/components/overview/dashboardGuideSteps.js.map +1 -0
- package/dist/bigconsole/components/overview/index.js +8 -0
- package/dist/bigconsole/components/overview/overviewModel.js +119 -0
- package/dist/bigconsole/components/overview/overviewModel.js.map +1 -0
- package/dist/bigconsole/components/overview/useOverviewData.js +48 -0
- package/dist/bigconsole/components/overview/useOverviewData.js.map +1 -0
- package/dist/bigconsole/components/parser/DataSinkSelector.js +40 -40
- package/dist/bigconsole/components/parser/ImportParserDialog.js +127 -127
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +51 -51
- package/dist/bigconsole/components/preview/AiPreviewContent.js +5 -5
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +33 -33
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +38 -38
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +13 -13
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +70 -70
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +28 -28
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +25 -25
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +48 -48
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +46 -46
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +61 -61
- package/dist/bigconsole/components/widgets/form/FormWidget.js +36 -36
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +42 -42
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +25 -25
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +21 -21
- package/dist/bigconsole/components/widgets/list/ListConfig.js +30 -30
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +38 -38
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +9 -9
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +9 -9
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +49 -49
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +39 -39
- package/dist/bigconsole/components/widgets/table/TableConfig.js +73 -73
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +64 -64
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +10 -10
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +68 -68
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/pages/AdminPage.js +136 -136
- package/dist/bigconsole/pages/DashboardBuilderPage.js +10 -10
- package/dist/bigconsole/pages/DashboardViewPage.js +61 -61
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +327 -348
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +5 -5
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +10 -10
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +83 -83
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinksPage.js +11 -11
- package/dist/bigconsole/pages/DataSourcesPage.js +5 -5
- package/dist/bigconsole/pages/InsightsPage.js +315 -315
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/OverviewPage.js +244 -0
- package/dist/bigconsole/pages/OverviewPage.js.map +1 -0
- package/dist/bigconsole/pages/ParserBuilderPage.js +5 -5
- package/dist/bigconsole/pages/ParserViewPage.js +98 -98
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +8 -8
- package/dist/bigconsole/pages/PipelineViewPage.js +46 -46
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +80 -80
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/SettingsPage.js +70 -70
- package/dist/bigconsole/pages/WidgetDemoPage.js +42 -42
- package/dist/bigconsole/pages/WorkflowViewPage.js +200 -200
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +78 -78
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +34 -34
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +79 -79
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js +46 -46
- package/dist/bigconsole/utils/createDialogParam.js +14 -0
- package/dist/bigconsole/utils/createDialogParam.js.map +1 -0
- package/dist/generated/global-operations.js +1 -1
- package/dist/generated/wspace-operations.js +285 -222
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/shared/hooks/useTr.js +10 -7
- package/dist/shared/hooks/useTr.js.map +1 -1
- package/package.json +1 -1
- package/dist/bigconsole/pages/HomePage.js +0 -318
- 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 {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
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 } =
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
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
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
103
|
-
let { t } =
|
|
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 } =
|
|
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(
|
|
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(
|
|
188
|
-
actions: /* @__PURE__ */ g(
|
|
187
|
+
icon: /* @__PURE__ */ g(T, { className: "h-icon-sm w-icon-sm" }),
|
|
188
|
+
actions: /* @__PURE__ */ g(m, {
|
|
189
189
|
onClick: X,
|
|
190
|
-
className:
|
|
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(
|
|
208
|
-
actions: /* @__PURE__ */ g(
|
|
207
|
+
icon: /* @__PURE__ */ g(T, { className: "h-icon-sm w-icon-sm" }),
|
|
208
|
+
actions: /* @__PURE__ */ g(m, {
|
|
209
209
|
onClick: X,
|
|
210
|
-
className:
|
|
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(
|
|
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__ */ _(
|
|
226
|
+
action: /* @__PURE__ */ _(m, {
|
|
227
227
|
variant: "secondary",
|
|
228
228
|
onClick: Z,
|
|
229
229
|
disabled: !N,
|
|
230
|
-
className:
|
|
231
|
-
children: [/* @__PURE__ */ g(
|
|
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(
|
|
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:
|
|
277
|
+
className: b,
|
|
278
278
|
children: e.inputKey
|
|
279
279
|
}),
|
|
280
|
-
/* @__PURE__ */ g(
|
|
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:
|
|
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(
|
|
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__ */ _(
|
|
315
|
+
actions: /* @__PURE__ */ _(m, {
|
|
316
316
|
onClick: ye,
|
|
317
317
|
disabled: G || !F,
|
|
318
|
-
className:
|
|
319
|
-
children: [/* @__PURE__ */ g(
|
|
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($ ?
|
|
342
|
+
icon: g($ ? ue : T, { className: "h-icon-sm w-icon-sm" }),
|
|
343
343
|
meta: B.totalExecutionTimeMs ? /* @__PURE__ */ _("span", {
|
|
344
|
-
className:
|
|
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__ */ _(
|
|
381
|
+
/* @__PURE__ */ _(m, {
|
|
382
382
|
variant: "ghost",
|
|
383
383
|
size: "sm",
|
|
384
384
|
onClick: X,
|
|
385
385
|
className: "w-fit",
|
|
386
|
-
children: [/* @__PURE__ */ g(
|
|
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__ */ _(
|
|
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:
|
|
409
|
-
children: [/* @__PURE__ */ g(
|
|
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__ */ _(
|
|
411
|
+
/* @__PURE__ */ _(m, {
|
|
412
412
|
variant: "secondary",
|
|
413
413
|
onClick: Z,
|
|
414
414
|
disabled: !N,
|
|
415
|
-
className:
|
|
416
|
-
children: [/* @__PURE__ */ g(
|
|
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__ */ _(
|
|
418
|
+
P && /* @__PURE__ */ _(m, {
|
|
419
419
|
variant: "destructive",
|
|
420
420
|
onClick: ge,
|
|
421
|
-
className:
|
|
422
|
-
children: [/* @__PURE__ */ g(
|
|
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(
|
|
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(
|
|
431
|
+
/* @__PURE__ */ g(oe, {
|
|
432
432
|
storageKey: "bigconsole-pipeline-view",
|
|
433
433
|
steps: [
|
|
434
434
|
...F ? [{
|