@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.
- 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/assistant/useAssistantPanelShowsPreview.js +25 -0
- package/dist/bigconsole/assistant/useAssistantPanelShowsPreview.js.map +1 -0
- 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 +62 -61
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +82 -81
- package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
- 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":"PipelinesPage.js","names":[],"sources":["../../../src/bigconsole/pages/PipelinesPage.tsx"],"sourcesContent":["/**\n * Pipelines Page\n *\n * List and manage Pipelines.\n *\n * Section ladder (BOFF-5635):\n * bare — page header band, filter/search toolbar (structure only)\n * primary — \"Your pipelines\" results region: the block this route exists for\n * muted — nested empty / no-match states inside the results region\n * danger — load failure, rendered under the header so navigation survives\n */\n\nimport { memo, useState, useMemo, useCallback } from 'react';\nimport { useAppNavigate } from '../contexts';\nimport { isNative, nativeNotify } from '../../utils/nativeBridge';\nimport { usePipelineOperations } from '../hooks/usePipelineOperations';\nimport { usePipelineStore } from '../store/pipelineStore';\nimport { PipelineCard } from '../components/pipeline/PipelineCard';\nimport { PipelineDeleteDialog } from '../components/pipeline/PipelineDeleteDialog';\nimport { Section, SectionStack, SECTION_FOCUS_RING, sectionSurfaceClasses } from '../components/common';\nimport type { PipelineStatus } from '../types';\n\n// fe-libs RBAC\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\n\n// fe-libs UI components\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { AuroraBackground, GradientText, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\n// Lucide icons\nimport { Plus, Search, GitBranch, AlertCircle } from 'lucide-react';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ntype StatusFilter = 'all' | PipelineStatus;\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const PipelinesPage = memo(function PipelinesPage() {\n const navigate = useAppNavigate();\n const { t } = useI18n();\n\n // Permissions\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.PIPELINE_READ);\n // Create is gated inline via <PermissionButton permission=PIPELINE_CREATE>.\n const canUpdate = hasPermission(BIGCONSOLE_PERMISSIONS.PIPELINE_UPDATE);\n const canDelete = hasPermission(BIGCONSOLE_PERMISSIONS.PIPELINE_DELETE);\n const canTest = hasPermission(BIGCONSOLE_PERMISSIONS.PIPELINE_TEST);\n\n // Local state\n const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');\n\n // Store state\n const searchQuery = usePipelineStore((state) => state.searchQuery);\n const setSearchQuery = usePipelineStore((state) => state.setSearchQuery);\n const deleteDialogOpen = usePipelineStore((state) => state.deleteDialogOpen);\n const currentPipeline = usePipelineStore((state) => state.currentPipeline);\n const openDeleteDialog = usePipelineStore((state) => state.openDeleteDialog);\n const closeDeleteDialog = usePipelineStore((state) => state.closeDeleteDialog);\n\n // Operations\n const { loading, error, pipelines, deletePipeline, refetch } = usePipelineOperations({\n consoleId: 'default',\n });\n\n // Filter pipelines\n const filteredPipelines = useMemo(() => {\n let filtered = [...pipelines];\n\n // Apply status filter\n if (statusFilter !== 'all') {\n filtered = filtered.filter((p) => p.status === statusFilter);\n }\n\n // Apply search filter\n if (searchQuery.trim()) {\n const query = searchQuery.toLowerCase();\n filtered = filtered.filter(\n (p) => p.name.toLowerCase().includes(query) || p.description?.toLowerCase().includes(query)\n );\n }\n\n // Sort by updatedAt descending\n return filtered.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());\n }, [pipelines, statusFilter, searchQuery]);\n\n // Handlers\n const handleCreatePipeline = useCallback(() => {\n navigate('/pipelines/new');\n }, [navigate]);\n\n const handleViewPipeline = useCallback(\n (id: string) => {\n navigate(`/pipelines/${id}`);\n },\n [navigate]\n );\n\n const handleEditPipeline = useCallback(\n (id: string) => {\n navigate(`/pipelines/${id}/edit`);\n },\n [navigate]\n );\n\n const handleTestPipeline = useCallback(\n (id: string) => {\n navigate(`/pipelines/${id}?test=true`);\n },\n [navigate]\n );\n\n const handleDeleteClick = useCallback(\n (id: string) => {\n const pipeline = pipelines.find((p) => p.id === id);\n if (pipeline) {\n openDeleteDialog(pipeline);\n }\n },\n [pipelines, openDeleteDialog]\n );\n\n const handleDeleteConfirm = useCallback(async () => {\n if (currentPipeline) {\n try {\n await deletePipeline(currentPipeline.id);\n if (isNative()) void nativeNotify('success');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n closeDeleteDialog();\n }\n }, [currentPipeline, deletePipeline, closeDeleteDialog]);\n\n const handleClearFilters = useCallback(() => {\n setStatusFilter('all');\n setSearchQuery('');\n }, [setSearchQuery]);\n\n // Status filter options\n const statusOptions: { value: StatusFilter; label: string }[] = [\n { value: 'all', label: t('bigconsole.pipelines.filters.all', 'All') },\n { value: 'draft', label: t('bigconsole.pipelines.filters.draft', 'Draft') },\n { value: 'active', label: t('bigconsole.pipelines.filters.active', 'Active') },\n { value: 'inactive', label: t('bigconsole.pipelines.filters.inactive', 'Inactive') },\n { value: 'error', label: t('bigconsole.pipelines.filters.error', 'Error') },\n ];\n\n // Permission gate — wait for permissions to resolve, then block callers\n // without pipeline read access before rendering the page body.\n if (permissionsLoading) {\n return (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '80px 0' }}>\n <Spinner\n style={{\n height: 'var(--size-icon-xl)',\n width: 'var(--size-icon-xl)',\n }}\n />\n </div>\n );\n }\n\n if (!canRead) {\n return (\n <AccessDenied\n title={t('bigconsole.pipelines.errors.accessDeniedTitle', 'Access Denied')}\n description={t(\n 'bigconsole.pipelines.errors.accessDeniedListDescription',\n \"You don't have permission to view pipelines.\"\n )}\n />\n );\n }\n\n /**\n * Page header band. `bare` in the emphasis ladder: it carries the page\n * identity and the single create action, never a content surface. Rendered in\n * both the error and the normal branch so a failed load keeps its \"you are\n * here\" anchor instead of replacing the whole page.\n */\n const pageHeader = (\n <header className=\"relative overflow-hidden border-b border-[var(--color-border-seam)] bg-[image:var(--gradient-gloss-card)]\">\n <AuroraBackground intensity=\"subtle\" />\n <div\n className=\"flex flex-col gap-form-gap sm:flex-row sm:items-center sm:justify-between\"\n style={{ padding: 'var(--space-pagePadding)' }}\n >\n <div className=\"flex min-w-0 items-center gap-form-gap\">\n <span\n aria-hidden=\"true\"\n className=\"flex shrink-0 items-center justify-center rounded-card\"\n style={{\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n backgroundColor: 'var(--color-action-primary-bg)',\n }}\n >\n <GitBranch\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n </span>\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-bold leading-tight text-text-primary\">\n <GradientText>{t('bigconsole.pipelines.list.heading', 'Pipelines')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'bigconsole.pipelines.list.subtitle',\n 'Create and manage sequential parser chains for data transformation'\n )}\n </p>\n </div>\n </div>\n\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PIPELINE_CREATE} deniedBehavior=\"disable\">\n <Button\n onClick={handleCreatePipeline}\n className=\"w-full shrink-0 min-h-[var(--size-controlHeight-md)] sm:w-auto\"\n >\n <Plus className=\"h-icon-sm w-icon-sm\" />\n {t('bigconsole.pipelines.actions.createPipeline', 'Create Pipeline')}\n </Button>\n </PermissionButton>\n </div>\n </header>\n );\n\n // Error state — keep the header so the page never loses its context.\n if (error) {\n return (\n <div className=\"min-h-screen bg-bg-canvas\">\n {pageHeader}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <Section\n tone=\"danger\"\n headingLevel={2}\n title={t('bigconsole.pipelines.errors.loadListTitle', 'Failed to load Pipelines')}\n description={error.message}\n icon={<AlertCircle className=\"h-icon-sm w-icon-sm\" />}\n actions={\n <Button size=\"sm\" onClick={() => refetch()}>\n {t('bigconsole.pipelines.actions.tryAgain', 'Try Again')}\n </Button>\n }\n data-testid=\"pipelines-error\"\n >\n <p className=\"text-sm text-text-secondary\">\n Nothing was changed. Retry once the console service is reachable again.\n </p>\n </Section>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"min-h-screen bg-bg-canvas\">\n {pageHeader}\n\n {/* Main Content */}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <SectionStack>\n <PagePurpose className=\"max-w-[75ch]\">\n {t(\n 'bigconsole.pipelines.list.purpose',\n 'Pipelines chain parsers and data sinks into a repeatable flow — they take raw input, run it through your parsers, and route the structured result into a sink. Use them to turn messy logs, files, or API payloads into clean, queryable data your dashboards can use.'\n )}\n </PagePurpose>\n\n {/* Toolbar — `bare` in the ladder: filters + search grouped so the eye\n reads one control row instead of two floating stripes. Written with\n `sectionSurfaceClasses` rather than <Section> because the block has\n no visible heading (see the ticket note on Section's required\n `title` prop). */}\n <section\n aria-label=\"Filter and search pipelines\"\n data-testid=\"pipelines-toolbar\"\n data-section-emphasis=\"bare\"\n className={sectionSurfaceClasses('bare', 'neutral', 'none')}\n >\n <div className=\"flex flex-col gap-control-gap md:flex-row md:items-center md:justify-between\">\n {/* `min-w-0`: the pills are `shrink-0`, so without it this scroller\n refuses to shrink in the md row and pushes the search field out. */}\n <div\n role=\"group\"\n aria-label=\"Filter by status\"\n className=\"flex min-w-0 max-w-full items-center gap-1 overflow-x-auto rounded-card bg-bg-sunken p-1\"\n >\n {statusOptions.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n aria-pressed={statusFilter === option.value}\n onClick={() => setStatusFilter(option.value)}\n className={`shrink-0 whitespace-nowrap rounded-button text-sm font-medium motion-safe:transition-colors ${SECTION_FOCUS_RING}`}\n style={{\n minHeight: 'var(--size-controlHeight-md)',\n padding: '0 var(--space-formGap)',\n border: 'none',\n cursor: 'pointer',\n backgroundColor: statusFilter === option.value ? 'var(--color-bg-surface)' : 'transparent',\n color:\n statusFilter === option.value ? 'var(--color-text-primary)' : 'var(--color-text-secondary)',\n boxShadow: statusFilter === option.value ? 'var(--shadow-elevation-1)' : 'none',\n }}\n >\n {option.label}\n </button>\n ))}\n </div>\n\n <div className=\"relative w-full md:max-w-[320px]\">\n <Search\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n left: 'var(--space-controlGap)',\n top: '50%',\n transform: 'translateY(-50%)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-text-muted)',\n }}\n />\n <Input\n type=\"text\"\n aria-label={t('bigconsole.pipelines.list.searchPlaceholder', 'Search pipelines...')}\n placeholder={t('bigconsole.pipelines.list.searchPlaceholder', 'Search pipelines...')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={{ paddingLeft: 'var(--size-controlHeight-md)', height: 'var(--size-controlHeight-md)' }}\n />\n </div>\n </div>\n </section>\n\n {/* Results — the one primary block on this route. */}\n <Section\n emphasis=\"primary\"\n headingLevel={2}\n title=\"Your pipelines\"\n description=\"Open one to review its stages, or run a quick test against sample input.\"\n meta={\n !loading || pipelines.length > 0 ? (\n <span className=\"rounded-pill bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {filteredPipelines.length}\n {filteredPipelines.length === pipelines.length ? '' : ` of ${pipelines.length}`}\n </span>\n ) : null\n }\n data-testid=\"pipelines-results\"\n >\n {/* Loading state */}\n {loading && pipelines.length === 0 && (\n <div className=\"flex items-center justify-center py-12\" role=\"status\">\n <div className=\"text-center\">\n <Spinner\n style={{\n height: 'var(--size-icon-xl)',\n width: 'var(--size-icon-xl)',\n margin: '0 auto var(--space-formGap)',\n }}\n />\n <p className=\"text-sm text-text-muted\">\n {t('bigconsole.pipelines.list.loading', 'Loading pipelines...')}\n </p>\n </div>\n </div>\n )}\n\n {/* Empty state — nothing created yet (onboarding). */}\n {!loading && pipelines.length === 0 && (\n <div data-testid=\"pipelines-empty\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('bigconsole.pipelines.list.emptyTitle', 'No Pipelines yet')}\n description={t(\n 'bigconsole.pipelines.list.emptyDescription',\n 'Create a pipeline to chain parsers together for sequential data transformation. Each stage processes the output of the previous stage.'\n )}\n action={\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PIPELINE_CREATE} deniedBehavior=\"disable\">\n <Button onClick={handleCreatePipeline} className=\"min-h-[var(--size-controlHeight-md)]\">\n <Plus className=\"h-icon-sm w-icon-sm\" />\n {t('bigconsole.pipelines.actions.createPipeline', 'Create Pipeline')}\n </Button>\n </PermissionButton>\n }\n />\n </div>\n )}\n\n {/* No results state — a filter problem, not an onboarding problem. */}\n {!loading && filteredPipelines.length === 0 && pipelines.length > 0 && (\n <Section\n emphasis=\"muted\"\n tone=\"info\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.pipelines.list.noResultsTitle', 'No matching pipelines')}\n description={t('bigconsole.pipelines.list.noResultsDescription', 'No pipelines match your filters')}\n actions={\n <Button size=\"sm\" variant=\"secondary\" onClick={handleClearFilters}>\n Clear filters\n </Button>\n }\n data-testid=\"pipelines-no-results\"\n />\n )}\n\n {/* Pipeline Grid */}\n {filteredPipelines.length > 0 && (\n <div className=\"grid grid-cols-1 gap-form-gap sm:grid-cols-2 xl:grid-cols-3\">\n {filteredPipelines.map((pipeline) => (\n <PipelineCard\n key={pipeline.id}\n pipeline={pipeline}\n onView={handleViewPipeline}\n onEdit={canUpdate ? handleEditPipeline : undefined}\n onTest={canTest ? handleTestPipeline : undefined}\n onDelete={canDelete ? handleDeleteClick : undefined}\n />\n ))}\n </div>\n )}\n </Section>\n </SectionStack>\n </div>\n\n {/* Delete Dialog */}\n {currentPipeline && (\n <PipelineDeleteDialog\n pipeline={currentPipeline}\n isOpen={deleteDialogOpen}\n onClose={closeDeleteDialog}\n onConfirm={handleDeleteConfirm}\n />\n )}\n </div>\n );\n});\n\nexport default PipelinesPage;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PipelinesPage.js","names":[],"sources":["../../../src/bigconsole/pages/PipelinesPage.tsx"],"sourcesContent":["/**\n * Pipelines Page\n *\n * List and manage Pipelines.\n *\n * Section ladder (BOFF-5635):\n * bare — page header band, filter/search toolbar (structure only)\n * primary — \"Your pipelines\" results region: the block this route exists for\n * muted — nested empty / no-match states inside the results region\n * danger — load failure, rendered under the header so navigation survives\n */\n\nimport { memo, useState, useMemo, useCallback } from 'react';\nimport { useAppNavigate } from '../contexts';\nimport { isNative, nativeNotify } from '../../utils/nativeBridge';\nimport { usePipelineOperations } from '../hooks/usePipelineOperations';\nimport { usePipelineStore } from '../store/pipelineStore';\nimport { PipelineCard } from '../components/pipeline/PipelineCard';\nimport { PipelineDeleteDialog } from '../components/pipeline/PipelineDeleteDialog';\nimport { Section, SectionStack, SECTION_FOCUS_RING, sectionSurfaceClasses } from '../components/common';\nimport type { PipelineStatus } from '../types';\n\n// fe-libs RBAC\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\n\n// fe-libs UI components\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { AuroraBackground, GradientText, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\n// Lucide icons\nimport { Plus, Search, GitBranch, AlertCircle } from 'lucide-react';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ntype StatusFilter = 'all' | PipelineStatus;\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const PipelinesPage = memo(function PipelinesPage() {\n const navigate = useAppNavigate();\n const { t } = useI18n();\n\n // Permissions\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.PIPELINE_READ);\n // Create is gated inline via <PermissionButton permission=PIPELINE_CREATE>.\n const canUpdate = hasPermission(BIGCONSOLE_PERMISSIONS.PIPELINE_UPDATE);\n const canDelete = hasPermission(BIGCONSOLE_PERMISSIONS.PIPELINE_DELETE);\n const canTest = hasPermission(BIGCONSOLE_PERMISSIONS.PIPELINE_TEST);\n\n // Local state\n const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');\n\n // Store state\n const searchQuery = usePipelineStore((state) => state.searchQuery);\n const setSearchQuery = usePipelineStore((state) => state.setSearchQuery);\n const deleteDialogOpen = usePipelineStore((state) => state.deleteDialogOpen);\n const currentPipeline = usePipelineStore((state) => state.currentPipeline);\n const openDeleteDialog = usePipelineStore((state) => state.openDeleteDialog);\n const closeDeleteDialog = usePipelineStore((state) => state.closeDeleteDialog);\n\n // Operations\n const { loading, error, pipelines, deletePipeline, refetch } = usePipelineOperations({\n consoleId: 'default',\n });\n\n // Filter pipelines\n const filteredPipelines = useMemo(() => {\n let filtered = [...pipelines];\n\n // Apply status filter\n if (statusFilter !== 'all') {\n filtered = filtered.filter((p) => p.status === statusFilter);\n }\n\n // Apply search filter\n if (searchQuery.trim()) {\n const query = searchQuery.toLowerCase();\n filtered = filtered.filter(\n (p) => p.name.toLowerCase().includes(query) || p.description?.toLowerCase().includes(query)\n );\n }\n\n // Sort by updatedAt descending\n return filtered.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());\n }, [pipelines, statusFilter, searchQuery]);\n\n // Handlers\n const handleCreatePipeline = useCallback(() => {\n navigate('/pipelines/new');\n }, [navigate]);\n\n const handleViewPipeline = useCallback(\n (id: string) => {\n navigate(`/pipelines/${id}`);\n },\n [navigate]\n );\n\n const handleEditPipeline = useCallback(\n (id: string) => {\n navigate(`/pipelines/${id}/edit`);\n },\n [navigate]\n );\n\n const handleTestPipeline = useCallback(\n (id: string) => {\n navigate(`/pipelines/${id}?test=true`);\n },\n [navigate]\n );\n\n const handleDeleteClick = useCallback(\n (id: string) => {\n const pipeline = pipelines.find((p) => p.id === id);\n if (pipeline) {\n openDeleteDialog(pipeline);\n }\n },\n [pipelines, openDeleteDialog]\n );\n\n const handleDeleteConfirm = useCallback(async () => {\n if (currentPipeline) {\n try {\n await deletePipeline(currentPipeline.id);\n if (isNative()) void nativeNotify('success');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n closeDeleteDialog();\n }\n }, [currentPipeline, deletePipeline, closeDeleteDialog]);\n\n const handleClearFilters = useCallback(() => {\n setStatusFilter('all');\n setSearchQuery('');\n }, [setSearchQuery]);\n\n // Status filter options\n const statusOptions: { value: StatusFilter; label: string }[] = [\n { value: 'all', label: t('bigconsole.pipelines.filters.all', 'All') },\n { value: 'draft', label: t('bigconsole.pipelines.filters.draft', 'Draft') },\n { value: 'active', label: t('bigconsole.pipelines.filters.active', 'Active') },\n { value: 'inactive', label: t('bigconsole.pipelines.filters.inactive', 'Inactive') },\n { value: 'error', label: t('bigconsole.pipelines.filters.error', 'Error') },\n ];\n\n // Permission gate — wait for permissions to resolve, then block callers\n // without pipeline read access before rendering the page body.\n if (permissionsLoading) {\n return (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '80px 0' }}>\n <Spinner\n style={{\n height: 'var(--size-icon-xl)',\n width: 'var(--size-icon-xl)',\n }}\n />\n </div>\n );\n }\n\n if (!canRead) {\n return (\n <AccessDenied\n title={t('bigconsole.pipelines.errors.accessDeniedTitle', 'Access Denied')}\n description={t(\n 'bigconsole.pipelines.errors.accessDeniedListDescription',\n \"You don't have permission to view pipelines.\"\n )}\n />\n );\n }\n\n /**\n * Page header band. `bare` in the emphasis ladder: it carries the page\n * identity and the single create action, never a content surface. Rendered in\n * both the error and the normal branch so a failed load keeps its \"you are\n * here\" anchor instead of replacing the whole page.\n */\n const pageHeader = (\n <header className=\"relative overflow-hidden border-b border-[var(--color-border-seam)] bg-[image:var(--gradient-gloss-card)]\">\n <AuroraBackground intensity=\"subtle\" />\n <div\n className=\"flex flex-col gap-form-gap sm:flex-row sm:items-center sm:justify-between\"\n style={{ padding: 'var(--space-pagePadding)' }}\n >\n <div className=\"flex min-w-0 items-center gap-form-gap\">\n <span\n aria-hidden=\"true\"\n className=\"flex shrink-0 items-center justify-center rounded-card\"\n style={{\n height: 'var(--size-controlHeight-lg)',\n width: 'var(--size-controlHeight-lg)',\n backgroundColor: 'var(--color-action-primary-bg)',\n }}\n >\n <GitBranch\n style={{\n height: 'var(--size-icon-lg)',\n width: 'var(--size-icon-lg)',\n color: 'var(--color-action-primary-text)',\n }}\n />\n </span>\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-bold leading-tight text-text-primary\">\n <GradientText>{t('bigconsole.pipelines.list.heading', 'Pipelines')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'bigconsole.pipelines.list.subtitle',\n 'Create and manage sequential parser chains for data transformation'\n )}\n </p>\n </div>\n </div>\n\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PIPELINE_CREATE} deniedBehavior=\"disable\">\n <Button\n onClick={handleCreatePipeline}\n className=\"w-full shrink-0 min-h-[var(--size-controlHeight-md)] sm:w-auto\"\n >\n <Plus className=\"h-icon-sm w-icon-sm\" />\n {t('bigconsole.pipelines.actions.createPipeline', 'Create Pipeline')}\n </Button>\n </PermissionButton>\n </div>\n </header>\n );\n\n // Error state — keep the header so the page never loses its context.\n if (error) {\n return (\n <div className=\"min-h-screen bg-bg-canvas\">\n {pageHeader}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <Section\n tone=\"danger\"\n headingLevel={2}\n title={t('bigconsole.pipelines.errors.loadListTitle', 'Failed to load Pipelines')}\n description={error.message}\n icon={<AlertCircle className=\"h-icon-sm w-icon-sm\" />}\n actions={\n <Button size=\"sm\" onClick={() => refetch()}>\n {t('bigconsole.pipelines.actions.tryAgain', 'Try Again')}\n </Button>\n }\n data-testid=\"pipelines-error\"\n >\n <p className=\"text-sm text-text-secondary\">\n Nothing was changed. Retry once the console service is reachable again.\n </p>\n </Section>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"min-h-screen bg-bg-canvas\">\n {pageHeader}\n\n {/* Main Content */}\n <div style={{ padding: 'var(--space-pagePadding)' }}>\n <SectionStack>\n <PagePurpose className=\"max-w-[75ch]\">\n {t(\n 'bigconsole.pipelines.list.purpose',\n 'Pipelines chain parsers and data sinks into a repeatable flow — they take raw input, run it through your parsers, and route the structured result into a sink. Use them to turn messy logs, files, or API payloads into clean, queryable data your dashboards can use.'\n )}\n </PagePurpose>\n\n {/* Toolbar — `bare` in the ladder: filters + search grouped so the eye\n reads one control row instead of two floating stripes. Written with\n `sectionSurfaceClasses` rather than <Section> because the block has\n no visible heading (see the ticket note on Section's required\n `title` prop). */}\n <section\n aria-label=\"Filter and search pipelines\"\n data-testid=\"pipelines-toolbar\"\n data-section-emphasis=\"bare\"\n className={sectionSurfaceClasses('bare', 'neutral', 'none')}\n >\n <div className=\"flex flex-col gap-control-gap md:flex-row md:items-center md:justify-between\">\n {/* `min-w-0`: the pills are `shrink-0`, so without it this scroller\n refuses to shrink in the md row and pushes the search field out. */}\n <div\n role=\"group\"\n aria-label=\"Filter by status\"\n className=\"flex min-w-0 max-w-full items-center gap-1 overflow-x-auto rounded-card bg-bg-sunken p-1\"\n >\n {statusOptions.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n aria-pressed={statusFilter === option.value}\n onClick={() => setStatusFilter(option.value)}\n className={`shrink-0 whitespace-nowrap rounded-button text-sm font-medium motion-safe:transition-colors ${SECTION_FOCUS_RING}`}\n style={{\n minHeight: 'var(--size-controlHeight-md)',\n padding: '0 var(--space-formGap)',\n border: 'none',\n cursor: 'pointer',\n backgroundColor: statusFilter === option.value ? 'var(--color-bg-surface)' : 'transparent',\n color:\n statusFilter === option.value ? 'var(--color-text-primary)' : 'var(--color-text-secondary)',\n boxShadow: statusFilter === option.value ? 'var(--shadow-elevation-1)' : 'none',\n }}\n >\n {option.label}\n </button>\n ))}\n </div>\n\n <div className=\"relative w-full md:max-w-[320px]\">\n <Search\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n left: 'var(--space-controlGap)',\n top: '50%',\n transform: 'translateY(-50%)',\n height: 'var(--size-icon-sm)',\n width: 'var(--size-icon-sm)',\n color: 'var(--color-text-muted)',\n }}\n />\n <Input\n type=\"text\"\n aria-label={t('bigconsole.pipelines.list.searchPlaceholder', 'Search pipelines...')}\n placeholder={t('bigconsole.pipelines.list.searchPlaceholder', 'Search pipelines...')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={{ paddingLeft: 'var(--size-controlHeight-md)', height: 'var(--size-controlHeight-md)' }}\n />\n </div>\n </div>\n </section>\n\n {/* Results — the one primary block on this route. */}\n <Section\n emphasis=\"primary\"\n headingLevel={2}\n title=\"Your pipelines\"\n description=\"Open one to review its stages, or run a quick test against sample input.\"\n meta={\n !loading || pipelines.length > 0 ? (\n <span className=\"rounded-pill bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {filteredPipelines.length}\n {filteredPipelines.length === pipelines.length ? '' : ` of ${pipelines.length}`}\n </span>\n ) : null\n }\n data-testid=\"pipelines-results\"\n >\n {/* Loading state */}\n {loading && pipelines.length === 0 && (\n <div className=\"flex items-center justify-center py-12\" role=\"status\">\n <div className=\"text-center\">\n <Spinner\n style={{\n height: 'var(--size-icon-xl)',\n width: 'var(--size-icon-xl)',\n margin: '0 auto var(--space-formGap)',\n }}\n />\n <p className=\"text-sm text-text-muted\">\n {t('bigconsole.pipelines.list.loading', 'Loading pipelines...')}\n </p>\n </div>\n </div>\n )}\n\n {/* Empty state — nothing created yet (onboarding). */}\n {!loading && pipelines.length === 0 && (\n <div data-testid=\"pipelines-empty\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('bigconsole.pipelines.list.emptyTitle', 'No Pipelines yet')}\n description={t(\n 'bigconsole.pipelines.list.emptyDescription',\n 'Create a pipeline to chain parsers together for sequential data transformation. Each stage processes the output of the previous stage.'\n )}\n action={\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.PIPELINE_CREATE} deniedBehavior=\"disable\">\n <Button onClick={handleCreatePipeline} className=\"min-h-[var(--size-controlHeight-md)]\">\n <Plus className=\"h-icon-sm w-icon-sm\" />\n {t('bigconsole.pipelines.actions.createPipeline', 'Create Pipeline')}\n </Button>\n </PermissionButton>\n }\n />\n </div>\n )}\n\n {/* No results state — a filter problem, not an onboarding problem. */}\n {!loading && filteredPipelines.length === 0 && pipelines.length > 0 && (\n <Section\n emphasis=\"muted\"\n tone=\"info\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.pipelines.list.noResultsTitle', 'No matching pipelines')}\n description={t('bigconsole.pipelines.list.noResultsDescription', 'No pipelines match your filters')}\n actions={\n <Button size=\"sm\" variant=\"secondary\" onClick={handleClearFilters}>\n Clear filters\n </Button>\n }\n data-testid=\"pipelines-no-results\"\n />\n )}\n\n {/* Pipeline Grid */}\n {filteredPipelines.length > 0 && (\n <div className=\"grid grid-cols-1 gap-form-gap sm:grid-cols-2 xl:grid-cols-3\">\n {filteredPipelines.map((pipeline) => (\n <PipelineCard\n key={pipeline.id}\n pipeline={pipeline}\n onView={handleViewPipeline}\n onEdit={canUpdate ? handleEditPipeline : undefined}\n onTest={canTest ? handleTestPipeline : undefined}\n onDelete={canDelete ? handleDeleteClick : undefined}\n />\n ))}\n </div>\n )}\n </Section>\n </SectionStack>\n </div>\n\n {/* Delete Dialog */}\n {currentPipeline && (\n <PipelineDeleteDialog\n pipeline={currentPipeline}\n isOpen={deleteDialogOpen}\n onClose={closeDeleteDialog}\n onConfirm={handleDeleteConfirm}\n />\n )}\n </div>\n );\n});\n\nexport default PipelinesPage;\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { memo as e, useCallback as t, useEffect as n, useState as r } from "react";
|
|
2
2
|
import { RotateCcw as i, Save as a, Settings as o } from "lucide-react";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { AuroraBackground as s, EmphasisPanel as c, GradientText as l, PagePurpose as u } from "@burdenoff/fe-libs/ui";
|
|
4
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
5
|
+
import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
6
6
|
//#region src/bigconsole/pages/SettingsPage.tsx
|
|
7
7
|
var m = "bigconsole-settings", h = {
|
|
8
8
|
defaultRefreshInterval: 0,
|
|
@@ -28,7 +28,7 @@ function _(e) {
|
|
|
28
28
|
localStorage.setItem(m, JSON.stringify(e));
|
|
29
29
|
}
|
|
30
30
|
var v = e(function() {
|
|
31
|
-
let { t: e } =
|
|
31
|
+
let { t: e } = p(), [m, v] = r(g), [y, b] = r(!1);
|
|
32
32
|
n(() => {
|
|
33
33
|
if (y) {
|
|
34
34
|
let e = setTimeout(() => b(!1), 2e3);
|
|
@@ -71,19 +71,19 @@ var v = e(function() {
|
|
|
71
71
|
marginBottom: "var(--space-sectionGap)",
|
|
72
72
|
boxShadow: "var(--shadow-pop)"
|
|
73
73
|
};
|
|
74
|
-
return /* @__PURE__ */
|
|
74
|
+
return /* @__PURE__ */ d("div", {
|
|
75
75
|
style: {
|
|
76
76
|
minHeight: "100vh",
|
|
77
77
|
backgroundColor: "var(--color-bg-canvas)"
|
|
78
78
|
},
|
|
79
|
-
children: /* @__PURE__ */
|
|
79
|
+
children: /* @__PURE__ */ f("div", {
|
|
80
80
|
style: {
|
|
81
81
|
padding: "var(--space-pagePadding)",
|
|
82
82
|
maxWidth: 720,
|
|
83
83
|
margin: "0 auto"
|
|
84
84
|
},
|
|
85
85
|
children: [
|
|
86
|
-
/* @__PURE__ */
|
|
86
|
+
/* @__PURE__ */ f("div", {
|
|
87
87
|
className: "relative overflow-hidden rounded-card border border-border-seam bg-gloss-card p-6",
|
|
88
88
|
style: {
|
|
89
89
|
display: "flex",
|
|
@@ -94,25 +94,25 @@ var v = e(function() {
|
|
|
94
94
|
gap: "var(--space-formGap)"
|
|
95
95
|
},
|
|
96
96
|
children: [
|
|
97
|
-
/* @__PURE__ */
|
|
98
|
-
/* @__PURE__ */
|
|
97
|
+
/* @__PURE__ */ d(s, { intensity: "subtle" }),
|
|
98
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ f("div", {
|
|
99
99
|
style: {
|
|
100
100
|
display: "flex",
|
|
101
101
|
alignItems: "center",
|
|
102
102
|
gap: "var(--space-iconGap)"
|
|
103
103
|
},
|
|
104
|
-
children: [/* @__PURE__ */
|
|
104
|
+
children: [/* @__PURE__ */ d(o, {
|
|
105
105
|
size: 24,
|
|
106
106
|
style: { color: "var(--color-text-primary)" }
|
|
107
|
-
}), /* @__PURE__ */
|
|
107
|
+
}), /* @__PURE__ */ d("h1", {
|
|
108
108
|
style: {
|
|
109
109
|
fontSize: "var(--font-size-heading-h4)",
|
|
110
110
|
fontWeight: "var(--font-weight-bold)",
|
|
111
111
|
color: "var(--color-text-primary)"
|
|
112
112
|
},
|
|
113
|
-
children: /* @__PURE__ */
|
|
113
|
+
children: /* @__PURE__ */ d(l, { children: e("bigconsole.settings.header.title", "Settings") })
|
|
114
114
|
})]
|
|
115
|
-
}), /* @__PURE__ */
|
|
115
|
+
}), /* @__PURE__ */ d("p", {
|
|
116
116
|
style: {
|
|
117
117
|
fontSize: "var(--font-size-body-md)",
|
|
118
118
|
color: "var(--color-text-secondary)",
|
|
@@ -120,12 +120,12 @@ var v = e(function() {
|
|
|
120
120
|
},
|
|
121
121
|
children: e("bigconsole.settings.header.subtitle", "Configure BigConsole preferences")
|
|
122
122
|
})] }),
|
|
123
|
-
/* @__PURE__ */
|
|
123
|
+
/* @__PURE__ */ f("div", {
|
|
124
124
|
style: {
|
|
125
125
|
display: "flex",
|
|
126
126
|
gap: 8
|
|
127
127
|
},
|
|
128
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ f("button", {
|
|
129
129
|
onClick: C,
|
|
130
130
|
style: {
|
|
131
131
|
display: "flex",
|
|
@@ -140,11 +140,11 @@ var v = e(function() {
|
|
|
140
140
|
cursor: "pointer"
|
|
141
141
|
},
|
|
142
142
|
children: [
|
|
143
|
-
/* @__PURE__ */
|
|
143
|
+
/* @__PURE__ */ d(i, { size: 14 }),
|
|
144
144
|
" ",
|
|
145
145
|
e("bigconsole.settings.actions.reset", "Reset")
|
|
146
146
|
]
|
|
147
|
-
}), /* @__PURE__ */
|
|
147
|
+
}), /* @__PURE__ */ f("button", {
|
|
148
148
|
onClick: S,
|
|
149
149
|
style: {
|
|
150
150
|
display: "flex",
|
|
@@ -161,7 +161,7 @@ var v = e(function() {
|
|
|
161
161
|
transition: "background-color 200ms"
|
|
162
162
|
},
|
|
163
163
|
children: [
|
|
164
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ d(a, { size: 14 }),
|
|
165
165
|
" ",
|
|
166
166
|
y ? e("bigconsole.settings.actions.savedLocally", "Saved locally") : e("bigconsole.settings.actions.saveLocally", "Save locally")
|
|
167
167
|
]
|
|
@@ -169,13 +169,13 @@ var v = e(function() {
|
|
|
169
169
|
})
|
|
170
170
|
]
|
|
171
171
|
}),
|
|
172
|
-
/* @__PURE__ */
|
|
172
|
+
/* @__PURE__ */ d(u, {
|
|
173
173
|
className: "mb-[var(--space-sectionGap)]",
|
|
174
174
|
children: e("bigconsole.settings.purpose", "Settings control the defaults BigConsole applies everywhere — how new dashboards are laid out, how aggressively widget data is cached, and how the UI is displayed. Tune these once to match how your team works; they apply across every dashboard you build. These preferences are saved locally in this browser until the backend settings API is available.")
|
|
175
175
|
}),
|
|
176
|
-
/* @__PURE__ */
|
|
176
|
+
/* @__PURE__ */ f(c, {
|
|
177
177
|
className: "mb-[var(--space-sectionGap)] p-[var(--space-cardPadding)]",
|
|
178
|
-
children: [/* @__PURE__ */
|
|
178
|
+
children: [/* @__PURE__ */ d("h2", {
|
|
179
179
|
style: {
|
|
180
180
|
fontSize: "var(--font-size-body-md)",
|
|
181
181
|
fontWeight: "var(--font-weight-semibold)",
|
|
@@ -183,19 +183,19 @@ var v = e(function() {
|
|
|
183
183
|
marginBottom: 16
|
|
184
184
|
},
|
|
185
185
|
children: e("bigconsole.settings.dashboardDefaults.title", "Dashboard Defaults")
|
|
186
|
-
}), /* @__PURE__ */
|
|
186
|
+
}), /* @__PURE__ */ f("div", {
|
|
187
187
|
style: {
|
|
188
188
|
display: "grid",
|
|
189
189
|
gap: 16
|
|
190
190
|
},
|
|
191
191
|
children: [
|
|
192
|
-
/* @__PURE__ */
|
|
193
|
-
/* @__PURE__ */
|
|
192
|
+
/* @__PURE__ */ f("div", { children: [
|
|
193
|
+
/* @__PURE__ */ d("label", {
|
|
194
194
|
htmlFor: "grid-cols",
|
|
195
195
|
style: T,
|
|
196
196
|
children: e("bigconsole.settings.dashboardDefaults.gridColumns.label", "Grid Columns")
|
|
197
197
|
}),
|
|
198
|
-
/* @__PURE__ */
|
|
198
|
+
/* @__PURE__ */ d("input", {
|
|
199
199
|
id: "grid-cols",
|
|
200
200
|
type: "number",
|
|
201
201
|
min: 4,
|
|
@@ -204,18 +204,18 @@ var v = e(function() {
|
|
|
204
204
|
onChange: (e) => x("defaultGridColumns", parseInt(e.target.value) || 12),
|
|
205
205
|
style: w
|
|
206
206
|
}),
|
|
207
|
-
/* @__PURE__ */
|
|
207
|
+
/* @__PURE__ */ d("p", {
|
|
208
208
|
style: E,
|
|
209
209
|
children: e("bigconsole.settings.dashboardDefaults.gridColumns.help", "Number of columns in the dashboard grid (4-24)")
|
|
210
210
|
})
|
|
211
211
|
] }),
|
|
212
|
-
/* @__PURE__ */
|
|
213
|
-
/* @__PURE__ */
|
|
212
|
+
/* @__PURE__ */ f("div", { children: [
|
|
213
|
+
/* @__PURE__ */ d("label", {
|
|
214
214
|
htmlFor: "widget-height",
|
|
215
215
|
style: T,
|
|
216
216
|
children: e("bigconsole.settings.dashboardDefaults.widgetHeight.label", "Default Widget Height")
|
|
217
217
|
}),
|
|
218
|
-
/* @__PURE__ */
|
|
218
|
+
/* @__PURE__ */ d("input", {
|
|
219
219
|
id: "widget-height",
|
|
220
220
|
type: "number",
|
|
221
221
|
min: 2,
|
|
@@ -224,50 +224,50 @@ var v = e(function() {
|
|
|
224
224
|
onChange: (e) => x("defaultWidgetHeight", parseInt(e.target.value) || 4),
|
|
225
225
|
style: w
|
|
226
226
|
}),
|
|
227
|
-
/* @__PURE__ */
|
|
227
|
+
/* @__PURE__ */ d("p", {
|
|
228
228
|
style: E,
|
|
229
229
|
children: e("bigconsole.settings.dashboardDefaults.widgetHeight.help", "Default height units for new widgets (2-12)")
|
|
230
230
|
})
|
|
231
231
|
] }),
|
|
232
|
-
/* @__PURE__ */
|
|
233
|
-
/* @__PURE__ */
|
|
232
|
+
/* @__PURE__ */ f("div", { children: [
|
|
233
|
+
/* @__PURE__ */ d("label", {
|
|
234
234
|
htmlFor: "refresh-interval",
|
|
235
235
|
style: T,
|
|
236
236
|
children: e("bigconsole.settings.dashboardDefaults.refreshInterval.label", "Auto-Refresh Interval (seconds)")
|
|
237
237
|
}),
|
|
238
|
-
/* @__PURE__ */
|
|
238
|
+
/* @__PURE__ */ f("select", {
|
|
239
239
|
id: "refresh-interval",
|
|
240
240
|
value: m.defaultRefreshInterval,
|
|
241
241
|
onChange: (e) => x("defaultRefreshInterval", parseInt(e.target.value)),
|
|
242
242
|
style: w,
|
|
243
243
|
children: [
|
|
244
|
-
/* @__PURE__ */
|
|
244
|
+
/* @__PURE__ */ d("option", {
|
|
245
245
|
value: 0,
|
|
246
246
|
children: e("bigconsole.settings.dashboardDefaults.refreshInterval.disabled", "Disabled")
|
|
247
247
|
}),
|
|
248
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ d("option", {
|
|
249
249
|
value: 10,
|
|
250
250
|
children: e("bigconsole.settings.dashboardDefaults.refreshInterval.seconds10", "10 seconds")
|
|
251
251
|
}),
|
|
252
|
-
/* @__PURE__ */
|
|
252
|
+
/* @__PURE__ */ d("option", {
|
|
253
253
|
value: 30,
|
|
254
254
|
children: e("bigconsole.settings.dashboardDefaults.refreshInterval.seconds30", "30 seconds")
|
|
255
255
|
}),
|
|
256
|
-
/* @__PURE__ */
|
|
256
|
+
/* @__PURE__ */ d("option", {
|
|
257
257
|
value: 60,
|
|
258
258
|
children: e("bigconsole.settings.dashboardDefaults.refreshInterval.minute1", "1 minute")
|
|
259
259
|
}),
|
|
260
|
-
/* @__PURE__ */
|
|
260
|
+
/* @__PURE__ */ d("option", {
|
|
261
261
|
value: 300,
|
|
262
262
|
children: e("bigconsole.settings.dashboardDefaults.refreshInterval.minutes5", "5 minutes")
|
|
263
263
|
}),
|
|
264
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ d("option", {
|
|
265
265
|
value: 600,
|
|
266
266
|
children: e("bigconsole.settings.dashboardDefaults.refreshInterval.minutes10", "10 minutes")
|
|
267
267
|
})
|
|
268
268
|
]
|
|
269
269
|
}),
|
|
270
|
-
/* @__PURE__ */
|
|
270
|
+
/* @__PURE__ */ d("p", {
|
|
271
271
|
style: E,
|
|
272
272
|
children: e("bigconsole.settings.dashboardDefaults.refreshInterval.help", "How often widgets refresh their data automatically")
|
|
273
273
|
})
|
|
@@ -275,9 +275,9 @@ var v = e(function() {
|
|
|
275
275
|
]
|
|
276
276
|
})]
|
|
277
277
|
}),
|
|
278
|
-
/* @__PURE__ */
|
|
278
|
+
/* @__PURE__ */ f("div", {
|
|
279
279
|
style: D,
|
|
280
|
-
children: [/* @__PURE__ */
|
|
280
|
+
children: [/* @__PURE__ */ d("h2", {
|
|
281
281
|
style: {
|
|
282
282
|
fontSize: "var(--font-size-body-md)",
|
|
283
283
|
fontWeight: "var(--font-weight-semibold)",
|
|
@@ -285,24 +285,24 @@ var v = e(function() {
|
|
|
285
285
|
marginBottom: 16
|
|
286
286
|
},
|
|
287
287
|
children: e("bigconsole.settings.cache.title", "Cache")
|
|
288
|
-
}), /* @__PURE__ */
|
|
288
|
+
}), /* @__PURE__ */ f("div", {
|
|
289
289
|
style: {
|
|
290
290
|
display: "grid",
|
|
291
291
|
gap: 16
|
|
292
292
|
},
|
|
293
|
-
children: [/* @__PURE__ */
|
|
293
|
+
children: [/* @__PURE__ */ f("div", {
|
|
294
294
|
style: {
|
|
295
295
|
display: "flex",
|
|
296
296
|
alignItems: "center",
|
|
297
297
|
justifyContent: "space-between"
|
|
298
298
|
},
|
|
299
|
-
children: [/* @__PURE__ */
|
|
299
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
300
300
|
style: T,
|
|
301
301
|
children: e("bigconsole.settings.cache.enable.label", "Enable Cache")
|
|
302
|
-
}), /* @__PURE__ */
|
|
302
|
+
}), /* @__PURE__ */ d("p", {
|
|
303
303
|
style: E,
|
|
304
304
|
children: e("bigconsole.settings.cache.enable.help", "Cache widget data to reduce API calls")
|
|
305
|
-
})] }), /* @__PURE__ */
|
|
305
|
+
})] }), /* @__PURE__ */ d("button", {
|
|
306
306
|
onClick: () => x("cacheEnabled", !m.cacheEnabled),
|
|
307
307
|
role: "switch",
|
|
308
308
|
"aria-checked": m.cacheEnabled,
|
|
@@ -317,7 +317,7 @@ var v = e(function() {
|
|
|
317
317
|
position: "relative",
|
|
318
318
|
transition: "background-color 200ms"
|
|
319
319
|
},
|
|
320
|
-
children: /* @__PURE__ */
|
|
320
|
+
children: /* @__PURE__ */ d("div", { style: {
|
|
321
321
|
width: 18,
|
|
322
322
|
height: 18,
|
|
323
323
|
borderRadius: "50%",
|
|
@@ -328,13 +328,13 @@ var v = e(function() {
|
|
|
328
328
|
transition: "left 200ms"
|
|
329
329
|
} })
|
|
330
330
|
})]
|
|
331
|
-
}), m.cacheEnabled && /* @__PURE__ */
|
|
332
|
-
/* @__PURE__ */
|
|
331
|
+
}), m.cacheEnabled && /* @__PURE__ */ f("div", { children: [
|
|
332
|
+
/* @__PURE__ */ d("label", {
|
|
333
333
|
htmlFor: "cache-ttl",
|
|
334
334
|
style: T,
|
|
335
335
|
children: e("bigconsole.settings.cache.ttl.label", "Cache TTL (seconds)")
|
|
336
336
|
}),
|
|
337
|
-
/* @__PURE__ */
|
|
337
|
+
/* @__PURE__ */ d("input", {
|
|
338
338
|
id: "cache-ttl",
|
|
339
339
|
type: "number",
|
|
340
340
|
min: 30,
|
|
@@ -343,16 +343,16 @@ var v = e(function() {
|
|
|
343
343
|
onChange: (e) => x("cacheTTLSeconds", parseInt(e.target.value) || 300),
|
|
344
344
|
style: w
|
|
345
345
|
}),
|
|
346
|
-
/* @__PURE__ */
|
|
346
|
+
/* @__PURE__ */ d("p", {
|
|
347
347
|
style: E,
|
|
348
348
|
children: e("bigconsole.settings.cache.ttl.help", "How long cached data is considered fresh (30-3600)")
|
|
349
349
|
})
|
|
350
350
|
] })]
|
|
351
351
|
})]
|
|
352
352
|
}),
|
|
353
|
-
/* @__PURE__ */
|
|
353
|
+
/* @__PURE__ */ f("div", {
|
|
354
354
|
style: D,
|
|
355
|
-
children: [/* @__PURE__ */
|
|
355
|
+
children: [/* @__PURE__ */ d("h2", {
|
|
356
356
|
style: {
|
|
357
357
|
fontSize: "var(--font-size-body-md)",
|
|
358
358
|
fontWeight: "var(--font-weight-semibold)",
|
|
@@ -360,25 +360,25 @@ var v = e(function() {
|
|
|
360
360
|
marginBottom: 16
|
|
361
361
|
},
|
|
362
362
|
children: e("bigconsole.settings.display.title", "Display")
|
|
363
|
-
}), /* @__PURE__ */
|
|
363
|
+
}), /* @__PURE__ */ f("div", {
|
|
364
364
|
style: {
|
|
365
365
|
display: "grid",
|
|
366
366
|
gap: 16
|
|
367
367
|
},
|
|
368
368
|
children: [
|
|
369
|
-
/* @__PURE__ */
|
|
369
|
+
/* @__PURE__ */ f("div", {
|
|
370
370
|
style: {
|
|
371
371
|
display: "flex",
|
|
372
372
|
alignItems: "center",
|
|
373
373
|
justifyContent: "space-between"
|
|
374
374
|
},
|
|
375
|
-
children: [/* @__PURE__ */
|
|
375
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
376
376
|
style: T,
|
|
377
377
|
children: e("bigconsole.settings.display.widgetBorders.label", "Show Widget Borders")
|
|
378
|
-
}), /* @__PURE__ */
|
|
378
|
+
}), /* @__PURE__ */ d("p", {
|
|
379
379
|
style: E,
|
|
380
380
|
children: e("bigconsole.settings.display.widgetBorders.help", "Display borders around widgets in dashboards")
|
|
381
|
-
})] }), /* @__PURE__ */
|
|
381
|
+
})] }), /* @__PURE__ */ d("button", {
|
|
382
382
|
onClick: () => x("showWidgetBorders", !m.showWidgetBorders),
|
|
383
383
|
role: "switch",
|
|
384
384
|
"aria-checked": m.showWidgetBorders,
|
|
@@ -393,7 +393,7 @@ var v = e(function() {
|
|
|
393
393
|
position: "relative",
|
|
394
394
|
transition: "background-color 200ms"
|
|
395
395
|
},
|
|
396
|
-
children: /* @__PURE__ */
|
|
396
|
+
children: /* @__PURE__ */ d("div", { style: {
|
|
397
397
|
width: 18,
|
|
398
398
|
height: 18,
|
|
399
399
|
borderRadius: "50%",
|
|
@@ -405,19 +405,19 @@ var v = e(function() {
|
|
|
405
405
|
} })
|
|
406
406
|
})]
|
|
407
407
|
}),
|
|
408
|
-
/* @__PURE__ */
|
|
408
|
+
/* @__PURE__ */ f("div", {
|
|
409
409
|
style: {
|
|
410
410
|
display: "flex",
|
|
411
411
|
alignItems: "center",
|
|
412
412
|
justifyContent: "space-between"
|
|
413
413
|
},
|
|
414
|
-
children: [/* @__PURE__ */
|
|
414
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
415
415
|
style: T,
|
|
416
416
|
children: e("bigconsole.settings.display.compactMode.label", "Compact Mode")
|
|
417
|
-
}), /* @__PURE__ */
|
|
417
|
+
}), /* @__PURE__ */ d("p", {
|
|
418
418
|
style: E,
|
|
419
419
|
children: e("bigconsole.settings.display.compactMode.help", "Reduce padding and spacing for more content")
|
|
420
|
-
})] }), /* @__PURE__ */
|
|
420
|
+
})] }), /* @__PURE__ */ d("button", {
|
|
421
421
|
onClick: () => x("compactMode", !m.compactMode),
|
|
422
422
|
role: "switch",
|
|
423
423
|
"aria-checked": m.compactMode,
|
|
@@ -432,7 +432,7 @@ var v = e(function() {
|
|
|
432
432
|
position: "relative",
|
|
433
433
|
transition: "background-color 200ms"
|
|
434
434
|
},
|
|
435
|
-
children: /* @__PURE__ */
|
|
435
|
+
children: /* @__PURE__ */ d("div", { style: {
|
|
436
436
|
width: 18,
|
|
437
437
|
height: 18,
|
|
438
438
|
borderRadius: "50%",
|
|
@@ -444,19 +444,19 @@ var v = e(function() {
|
|
|
444
444
|
} })
|
|
445
445
|
})]
|
|
446
446
|
}),
|
|
447
|
-
/* @__PURE__ */
|
|
447
|
+
/* @__PURE__ */ f("div", {
|
|
448
448
|
style: {
|
|
449
449
|
display: "flex",
|
|
450
450
|
alignItems: "center",
|
|
451
451
|
justifyContent: "space-between"
|
|
452
452
|
},
|
|
453
|
-
children: [/* @__PURE__ */
|
|
453
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
|
|
454
454
|
style: T,
|
|
455
455
|
children: e("bigconsole.settings.display.animations.label", "Animations")
|
|
456
|
-
}), /* @__PURE__ */
|
|
456
|
+
}), /* @__PURE__ */ d("p", {
|
|
457
457
|
style: E,
|
|
458
458
|
children: e("bigconsole.settings.display.animations.help", "Enable transition animations and effects")
|
|
459
|
-
})] }), /* @__PURE__ */
|
|
459
|
+
})] }), /* @__PURE__ */ d("button", {
|
|
460
460
|
onClick: () => x("animationsEnabled", !m.animationsEnabled),
|
|
461
461
|
role: "switch",
|
|
462
462
|
"aria-checked": m.animationsEnabled,
|
|
@@ -471,7 +471,7 @@ var v = e(function() {
|
|
|
471
471
|
position: "relative",
|
|
472
472
|
transition: "background-color 200ms"
|
|
473
473
|
},
|
|
474
|
-
children: /* @__PURE__ */
|
|
474
|
+
children: /* @__PURE__ */ d("div", { style: {
|
|
475
475
|
width: 18,
|
|
476
476
|
height: 18,
|
|
477
477
|
borderRadius: "50%",
|