@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":"AiPreviewPanel.js","names":[],"sources":["../../../../src/bigconsole/components/preview/AiPreviewPanel.tsx"],"sourcesContent":["/**\n * AI Preview — watch the assistant build, with the real content inline.\n *\n * Opens by itself the moment a prompt starts. A step rail (driven by the agent's\n * own narration) shows DataSink → Dashboard → Parser → Widget filling in, and\n * the four tabs show the ACTUAL content of each entity as it lands — the data\n * sink's rows, the live dashboard, the parser's transformed output, the rendered\n * widget charts — not a list of links. Each tab has an \"Open\" button that jumps\n * to the real page.\n *\n * The content renderers need Apollo + the BigConsole providers, which is why\n * this full panel lives inside BigConsoleRoot; the store-only app-shell mini\n * panel (AiPreviewMiniPanel) keeps the lighter link view for other pages.\n *\n * ★★★ THE SHELL, RAIL AND TABS ARE fe-libs' NOW (`AssistantEntityPreview`).\n * What stays here is what is actually BigConsole's: which entities exist, how to\n * render each one, and where the panel sits relative to the assistant sidebar.\n * The shared surface brought three things this file could not have on its own:\n *\n * - a viewer's tab choice is HONOURED. The local `useEffect` re-selected a tab\n * on every store tick, so clicking one held for about 1.5 seconds before the\n * next progress update took it back — you could not read a tab while the\n * build continued.\n * - the rail can show a FAILED step instead of drawing a failure as \"not\n * started\" (the store still cannot produce one — see `assistantRunStore` —\n * but the surface no longer loses it if it ever does).\n * - keyboard navigation across the tabs, which the Radix tablist here never\n * had overflow handling for below ~430px.\n */\nimport { useEffect, useRef, useState, type ReactNode } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport {\n AssistantEntityPreview,\n type AssistantPreviewStep,\n type AssistantPreviewTab,\n} from '@burdenoff/fe-libs/shared/assistant';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ArrowUpRight, Loader2, Sparkles, X } from 'lucide-react';\n\nimport { PREVIEW_STEPS, useAssistantRunStore } from '../../assistant/assistantRunStore';\nimport { useBigConsoleNavigate } from '../../context';\nimport { Section } from '../common';\nimport { DOCK_CLEARANCE, PreviewMeta, STEP_LABEL, formatAgo, previewLabels } from './previewShared';\nimport { DashboardContent, DataSinkContent, ParserContent, WidgetsContent } from './AiPreviewContent';\n\n/**\n * The scroll box each tab's content sits in.\n *\n * ★★ The cap is NOT cosmetic and does not belong in fe-libs: the shared surface\n * is laid out by whatever contains it, and this panel is injected ABOVE a\n * routed page — so without a cap a long data-sink preview pushes the whole page\n * down. `min(440px, 60vh)` is the original value; the hard 440px alone ate most\n * of the fold on a short laptop screen.\n */\nfunction TabBody({ children }: { children: ReactNode }) {\n return (\n <div className=\"min-w-0 overflow-y-auto p-3\" style={{ maxHeight: 'min(440px, 60vh)' }}>\n {children}\n </div>\n );\n}\n\n/** Jump-to-the-real-page button, shared by all four tabs. */\nfunction OpenEntityButton({ onOpen }: { onOpen: () => void }) {\n const { t } = useI18n();\n return (\n <Button size=\"sm\" variant=\"outline\" onClick={onOpen} data-testid=\"ai-preview-open-entity\">\n {t('bigconsole.widget.aiPreview.open', 'Open')}\n <ArrowUpRight className=\"ml-1 size-3.5\" />\n </Button>\n );\n}\n\nexport function AiPreviewPanel() {\n const { t } = useI18n();\n const navigate = useBigConsoleNavigate();\n\n const isRunning = useAssistantRunStore((state) => state.isRunning);\n const previewOpen = useAssistantRunStore((state) => state.previewOpen);\n const hasRun = useAssistantRunStore((state) => state.hasRun);\n const steps = useAssistantRunStore((state) => state.steps);\n const entityIds = useAssistantRunStore((state) => state.entityIds);\n const caption = useAssistantRunStore((state) => state.caption);\n const error = useAssistantRunStore((state) => state.error);\n const updatedAt = useAssistantRunStore((state) => state.updatedAt);\n const openPreview = useAssistantRunStore((state) => state.openPreview);\n const closePreview = useAssistantRunStore((state) => state.closePreview);\n const setRichMounted = useAssistantRunStore((state) => state.setRichMounted);\n\n useEffect(() => {\n setRichMounted(true);\n return () => {\n setRichMounted(false);\n };\n }, [setRichMounted]);\n\n /**\n * ★★★ WHAT COUNTS AS A \"RUN\" HERE, for the purpose of releasing a pinned tab.\n *\n * The store has no run id and deliberately never resets — a new prompt\n * CONTINUES the same build, preserving every step and entity id already made\n * (`assistantRunStore.startRun`). So the key is minted here, on the rising\n * edge of `isRunning`: each new turn is a new run, which releases a tab the\n * viewer pinned during the previous one. That is the right side to err on —\n * asking for something new and being shown the old tab is worse than losing a\n * pin you made a turn ago.\n */\n const [runKey, setRunKey] = useState(0);\n const wasRunningRef = useRef(false);\n useEffect(() => {\n if (isRunning && !wasRunningRef.current) setRunKey((n) => n + 1);\n wasRunningRef.current = isRunning;\n }, [isRunning]);\n\n if (!hasRun) return null;\n\n if (!previewOpen) {\n return (\n <div\n className=\"flex flex-wrap items-center justify-end gap-control-gap px-4 pt-3 md:px-6\"\n style={{ marginRight: DOCK_CLEARANCE }}\n >\n {/* The lone button gave no clue what it belonged to. */}\n <span className=\"text-xs text-text-muted\">\n {isRunning\n ? t('bigconsole.widget.aiPreview.buildRunning', 'AI build running')\n : t('bigconsole.widget.aiPreview.buildFinished', 'AI build finished')}\n </span>\n <Button size=\"sm\" variant=\"outline\" onClick={openPreview} data-testid=\"ai-preview-open\">\n <Sparkles className=\"mr-1.5 size-4\" />\n {t('bigconsole.widget.aiPreview.previewButton', 'Preview')}\n {isRunning ? <Loader2 className=\"ml-1.5 size-3.5 animate-spin\" /> : null}\n </Button>\n </div>\n );\n }\n\n const dashboardId = entityIds.dashboard;\n\n const railSteps: AssistantPreviewStep[] = PREVIEW_STEPS.map((key) => ({\n id: key,\n label: t(STEP_LABEL[key].key, STEP_LABEL[key].fallback),\n status: steps[key],\n }));\n\n const tabs: AssistantPreviewTab[] = [\n {\n id: 'datasink',\n label: t('bigconsole.widget.aiPreview.tab.dataSink', 'Data Sink'),\n render: () => (\n <TabBody>\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.dataSinkRows', 'Data sink rows')}\n description={t(\n 'bigconsole.widget.aiPreview.dataSinkRowsHint',\n 'The rows the assistant just landed, straight from the sink.'\n )}\n actions={\n entityIds.datasink ? (\n <OpenEntityButton onOpen={() => navigate(`/datasinks/${entityIds.datasink}`)} />\n ) : undefined\n }\n >\n <DataSinkContent id={entityIds.datasink} live={isRunning} />\n </Section>\n </TabBody>\n ),\n },\n {\n id: 'dashboard',\n label: t('bigconsole.widget.aiPreview.tab.dashboard', 'Dashboard'),\n render: () => (\n <TabBody>\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.tab.dashboard', 'Dashboard')}\n description={t(\n 'bigconsole.widget.aiPreview.dashboardHint',\n 'The live board, rendered exactly as the real page renders it.'\n )}\n actions={\n dashboardId ? <OpenEntityButton onOpen={() => navigate(`/dashboards/${dashboardId}`)} /> : undefined\n }\n >\n <DashboardContent dashboardId={dashboardId} />\n </Section>\n </TabBody>\n ),\n },\n {\n id: 'parser',\n label: t('bigconsole.widget.aiPreview.tab.parser', 'Parser'),\n render: () => (\n <TabBody>\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.parserOutput', 'Parser output')}\n description={t(\n 'bigconsole.widget.aiPreview.parserOutputHint',\n \"The rows after the parser's transform, so you can check the shape.\"\n )}\n actions={\n entityIds.parser ? (\n <OpenEntityButton onOpen={() => navigate(`/parsers/${entityIds.parser}`)} />\n ) : undefined\n }\n >\n <ParserContent parserId={entityIds.parser} live={isRunning} />\n </Section>\n </TabBody>\n ),\n },\n {\n id: 'widget',\n label: t('bigconsole.widget.aiPreview.tab.widget', 'Widget'),\n render: () => (\n <TabBody>\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.widgets', 'Widgets')}\n description={t(\n 'bigconsole.widget.aiPreview.widgetsHint',\n 'Every widget on the new dashboard, rendered live.'\n )}\n actions={\n dashboardId ? <OpenEntityButton onOpen={() => navigate(`/dashboards/${dashboardId}`)} /> : undefined\n }\n >\n <WidgetsContent dashboardId={dashboardId} live={isRunning} />\n </Section>\n </TabBody>\n ),\n },\n ];\n\n return (\n // ★ The wrapper owns POSITIONING only — clearance for the assistant dock,\n // page gutters, and the testid BigConsole already had. Everything visual\n // belongs to the shared surface.\n //\n // ★★ PADDING, not margin: `mx-4 md:mx-6` is the page gutter and it is\n // RESPONSIVE. See DOCK_CLEARANCE's docblock.\n <div data-testid=\"ai-preview-panel\" style={{ paddingRight: DOCK_CLEARANCE }} className=\"mx-4 mt-3 min-w-0 md:mx-6\">\n {/* ★★ The panel's own heading, restored. The shared surface renders its\n title as a styled <span> inside a <section aria-label>, which labels\n the region but leaves NO heading — while it still renders an <h3> for\n the step rail. main had <h2>AI Preview</h2> above that <h3>, so the\n migration both removed the panel from screen-reader heading navigation\n and orphaned the h3 under whatever <h2> the page beneath happens to\n end with. Visually hidden because the surface already shows the title;\n this only restores the structure. */}\n <h2 className=\"sr-only\">{t('bigconsole.widget.aiPreview.title', 'AI Preview')}</h2>\n <AssistantEntityPreview\n title={t('bigconsole.widget.aiPreview.title', 'AI Preview')}\n runKey={String(runKey)}\n steps={railSteps}\n tabs={tabs}\n // ★ Explicit, though it is the default: this panel's own rule was\n // \"show the LATEST thing that actually landed — so the moment the data\n // sink is created you see its rows, not an empty 'waiting for the\n // dashboard' tab\". Stating it keeps that reasoning attached to the\n // consumer that discovered it, not only to the library that adopted it.\n follow=\"produced\"\n // ★★ TWO branches, not three, and deliberately so: the shared surface\n // renders `{error ? '' : caption}` — it BLANKS the caption whenever\n // `error` is set, so a failure branch here would compute a string that\n // is then discarded. The failure is named in `meta` instead, which\n // `PreviewHeader` renders without consulting `error`.\n caption={\n isRunning\n ? caption || t('bigconsole.widget.aiPreview.working', 'Working…')\n : t('bigconsole.widget.aiPreview.done', 'Done')\n }\n error={error}\n meta={\n <PreviewMeta\n state={isRunning ? 'running' : error ? 'stopped' : 'idle'}\n stateLabel={\n isRunning\n ? t('bigconsole.widget.aiPreview.live', 'Live')\n : error\n ? t('bigconsole.widget.aiPreview.stopped', 'Stopped')\n : null\n }\n updatedLabel={t('bigconsole.widget.aiPreview.updated', 'updated')}\n updatedAt={updatedAt}\n ago={(seconds) => formatAgo(seconds, t)}\n />\n }\n headerActions={\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={closePreview}\n aria-label={t('bigconsole.widget.aiPreview.closeAriaLabel', 'Close preview')}\n data-testid=\"ai-preview-close\"\n >\n <X className=\"size-4\" />\n </Button>\n }\n labels={previewLabels(t)}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AiPreviewPanel.js","names":[],"sources":["../../../../src/bigconsole/components/preview/AiPreviewPanel.tsx"],"sourcesContent":["/**\n * AI Preview — watch the assistant build, with the real content inline.\n *\n * Opens by itself the moment a prompt starts. A step rail (driven by the agent's\n * own narration) shows DataSink → Dashboard → Parser → Widget filling in, and\n * the four tabs show the ACTUAL content of each entity as it lands — the data\n * sink's rows, the live dashboard, the parser's transformed output, the rendered\n * widget charts — not a list of links. Each tab has an \"Open\" button that jumps\n * to the real page.\n *\n * The content renderers need Apollo + the BigConsole providers, which is why\n * this full panel lives inside BigConsoleRoot; the store-only app-shell mini\n * panel (AiPreviewMiniPanel) keeps the lighter link view for other pages.\n *\n * ★★★ THE SHELL, RAIL AND TABS ARE fe-libs' NOW (`AssistantEntityPreview`).\n * What stays here is what is actually BigConsole's: which entities exist, how to\n * render each one, and where the panel sits relative to the assistant sidebar.\n * The shared surface brought three things this file could not have on its own:\n *\n * - a viewer's tab choice is HONOURED. The local `useEffect` re-selected a tab\n * on every store tick, so clicking one held for about 1.5 seconds before the\n * next progress update took it back — you could not read a tab while the\n * build continued.\n * - the rail can show a FAILED step instead of drawing a failure as \"not\n * started\" (the store still cannot produce one — see `assistantRunStore` —\n * but the surface no longer loses it if it ever does).\n * - keyboard navigation across the tabs, which the Radix tablist here never\n * had overflow handling for below ~430px.\n */\nimport { useEffect, useRef, useState, type ReactNode } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport {\n AssistantEntityPreview,\n type AssistantPreviewStep,\n type AssistantPreviewTab,\n} from '@burdenoff/fe-libs/shared/assistant';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useAssistantPanelShowsPreview } from '../../assistant/useAssistantPanelShowsPreview';\nimport { ArrowUpRight, Loader2, Sparkles, X } from 'lucide-react';\n\nimport { PREVIEW_STEPS, useAssistantRunStore } from '../../assistant/assistantRunStore';\nimport { useBigConsoleNavigate } from '../../context';\nimport { Section } from '../common';\nimport { DOCK_CLEARANCE, PreviewMeta, STEP_LABEL, formatAgo, previewLabels } from './previewShared';\nimport { DashboardContent, DataSinkContent, ParserContent, WidgetsContent } from './AiPreviewContent';\n\n/**\n * The scroll box each tab's content sits in.\n *\n * ★★ The cap is NOT cosmetic and does not belong in fe-libs: the shared surface\n * is laid out by whatever contains it, and this panel is injected ABOVE a\n * routed page — so without a cap a long data-sink preview pushes the whole page\n * down. `min(440px, 60vh)` is the original value; the hard 440px alone ate most\n * of the fold on a short laptop screen.\n */\nfunction TabBody({ children }: { children: ReactNode }) {\n return (\n <div className=\"min-w-0 overflow-y-auto p-3\" style={{ maxHeight: 'min(440px, 60vh)' }}>\n {children}\n </div>\n );\n}\n\n/** Jump-to-the-real-page button, shared by all four tabs. */\nfunction OpenEntityButton({ onOpen }: { onOpen: () => void }) {\n const { t } = useI18n();\n return (\n <Button size=\"sm\" variant=\"outline\" onClick={onOpen} data-testid=\"ai-preview-open-entity\">\n {t('bigconsole.widget.aiPreview.open', 'Open')}\n <ArrowUpRight className=\"ml-1 size-3.5\" />\n </Button>\n );\n}\n\nexport function AiPreviewPanel() {\n const { t } = useI18n();\n // ★★★ ONE SURFACE PER RUN. fe-libs renders this same controller inside its own\n // in-chat overlay; without this the page surface stayed up beside it and one\n // run was drawn twice, side by side (measured in prod, BOFF-7799).\n const panelShowsPreview = useAssistantPanelShowsPreview();\n const navigate = useBigConsoleNavigate();\n\n const isRunning = useAssistantRunStore((state) => state.isRunning);\n const previewOpen = useAssistantRunStore((state) => state.previewOpen);\n const hasRun = useAssistantRunStore((state) => state.hasRun);\n const steps = useAssistantRunStore((state) => state.steps);\n const entityIds = useAssistantRunStore((state) => state.entityIds);\n const caption = useAssistantRunStore((state) => state.caption);\n const error = useAssistantRunStore((state) => state.error);\n const updatedAt = useAssistantRunStore((state) => state.updatedAt);\n const openPreview = useAssistantRunStore((state) => state.openPreview);\n const closePreview = useAssistantRunStore((state) => state.closePreview);\n const setRichMounted = useAssistantRunStore((state) => state.setRichMounted);\n\n useEffect(() => {\n setRichMounted(true);\n return () => {\n setRichMounted(false);\n };\n }, [setRichMounted]);\n\n /**\n * ★★★ WHAT COUNTS AS A \"RUN\" HERE, for the purpose of releasing a pinned tab.\n *\n * The store has no run id and deliberately never resets — a new prompt\n * CONTINUES the same build, preserving every step and entity id already made\n * (`assistantRunStore.startRun`). So the key is minted here, on the rising\n * edge of `isRunning`: each new turn is a new run, which releases a tab the\n * viewer pinned during the previous one. That is the right side to err on —\n * asking for something new and being shown the old tab is worse than losing a\n * pin you made a turn ago.\n */\n const [runKey, setRunKey] = useState(0);\n const wasRunningRef = useRef(false);\n useEffect(() => {\n if (isRunning && !wasRunningRef.current) setRunKey((n) => n + 1);\n wasRunningRef.current = isRunning;\n }, [isRunning]);\n\n if (!hasRun) return null;\n // The shared panel's overlay is already showing this run — stand down rather\n // than draw it a second time beside itself.\n if (panelShowsPreview) return null;\n\n if (!previewOpen) {\n return (\n <div\n className=\"flex flex-wrap items-center justify-end gap-control-gap px-4 pt-3 md:px-6\"\n style={{ marginRight: DOCK_CLEARANCE }}\n >\n {/* The lone button gave no clue what it belonged to. */}\n <span className=\"text-xs text-text-muted\">\n {isRunning\n ? t('bigconsole.widget.aiPreview.buildRunning', 'AI build running')\n : t('bigconsole.widget.aiPreview.buildFinished', 'AI build finished')}\n </span>\n <Button size=\"sm\" variant=\"outline\" onClick={openPreview} data-testid=\"ai-preview-open\">\n <Sparkles className=\"mr-1.5 size-4\" />\n {t('bigconsole.widget.aiPreview.previewButton', 'Preview')}\n {isRunning ? <Loader2 className=\"ml-1.5 size-3.5 animate-spin\" /> : null}\n </Button>\n </div>\n );\n }\n\n const dashboardId = entityIds.dashboard;\n\n const railSteps: AssistantPreviewStep[] = PREVIEW_STEPS.map((key) => ({\n id: key,\n label: t(STEP_LABEL[key].key, STEP_LABEL[key].fallback),\n status: steps[key],\n }));\n\n const tabs: AssistantPreviewTab[] = [\n {\n id: 'datasink',\n label: t('bigconsole.widget.aiPreview.tab.dataSink', 'Data Sink'),\n render: () => (\n <TabBody>\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.dataSinkRows', 'Data sink rows')}\n description={t(\n 'bigconsole.widget.aiPreview.dataSinkRowsHint',\n 'The rows the assistant just landed, straight from the sink.'\n )}\n actions={\n entityIds.datasink ? (\n <OpenEntityButton onOpen={() => navigate(`/datasinks/${entityIds.datasink}`)} />\n ) : undefined\n }\n >\n <DataSinkContent id={entityIds.datasink} live={isRunning} />\n </Section>\n </TabBody>\n ),\n },\n {\n id: 'dashboard',\n label: t('bigconsole.widget.aiPreview.tab.dashboard', 'Dashboard'),\n render: () => (\n <TabBody>\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.tab.dashboard', 'Dashboard')}\n description={t(\n 'bigconsole.widget.aiPreview.dashboardHint',\n 'The live board, rendered exactly as the real page renders it.'\n )}\n actions={\n dashboardId ? <OpenEntityButton onOpen={() => navigate(`/dashboards/${dashboardId}`)} /> : undefined\n }\n >\n <DashboardContent dashboardId={dashboardId} />\n </Section>\n </TabBody>\n ),\n },\n {\n id: 'parser',\n label: t('bigconsole.widget.aiPreview.tab.parser', 'Parser'),\n render: () => (\n <TabBody>\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.parserOutput', 'Parser output')}\n description={t(\n 'bigconsole.widget.aiPreview.parserOutputHint',\n \"The rows after the parser's transform, so you can check the shape.\"\n )}\n actions={\n entityIds.parser ? (\n <OpenEntityButton onOpen={() => navigate(`/parsers/${entityIds.parser}`)} />\n ) : undefined\n }\n >\n <ParserContent parserId={entityIds.parser} live={isRunning} />\n </Section>\n </TabBody>\n ),\n },\n {\n id: 'widget',\n label: t('bigconsole.widget.aiPreview.tab.widget', 'Widget'),\n render: () => (\n <TabBody>\n <Section\n emphasis=\"standard\"\n padding=\"compact\"\n headingLevel={3}\n title={t('bigconsole.widget.aiPreview.widgets', 'Widgets')}\n description={t(\n 'bigconsole.widget.aiPreview.widgetsHint',\n 'Every widget on the new dashboard, rendered live.'\n )}\n actions={\n dashboardId ? <OpenEntityButton onOpen={() => navigate(`/dashboards/${dashboardId}`)} /> : undefined\n }\n >\n <WidgetsContent dashboardId={dashboardId} live={isRunning} />\n </Section>\n </TabBody>\n ),\n },\n ];\n\n return (\n // ★ The wrapper owns POSITIONING only — clearance for the assistant dock,\n // page gutters, and the testid BigConsole already had. Everything visual\n // belongs to the shared surface.\n //\n // ★★ PADDING, not margin: `mx-4 md:mx-6` is the page gutter and it is\n // RESPONSIVE. See DOCK_CLEARANCE's docblock.\n <div data-testid=\"ai-preview-panel\" style={{ paddingRight: DOCK_CLEARANCE }} className=\"mx-4 mt-3 min-w-0 md:mx-6\">\n {/* ★★ The panel's own heading, restored. The shared surface renders its\n title as a styled <span> inside a <section aria-label>, which labels\n the region but leaves NO heading — while it still renders an <h3> for\n the step rail. main had <h2>AI Preview</h2> above that <h3>, so the\n migration both removed the panel from screen-reader heading navigation\n and orphaned the h3 under whatever <h2> the page beneath happens to\n end with. Visually hidden because the surface already shows the title;\n this only restores the structure. */}\n <h2 className=\"sr-only\">{t('bigconsole.widget.aiPreview.title', 'AI Preview')}</h2>\n <AssistantEntityPreview\n title={t('bigconsole.widget.aiPreview.title', 'AI Preview')}\n runKey={String(runKey)}\n steps={railSteps}\n tabs={tabs}\n // ★ Explicit, though it is the default: this panel's own rule was\n // \"show the LATEST thing that actually landed — so the moment the data\n // sink is created you see its rows, not an empty 'waiting for the\n // dashboard' tab\". Stating it keeps that reasoning attached to the\n // consumer that discovered it, not only to the library that adopted it.\n follow=\"produced\"\n // ★★ TWO branches, not three, and deliberately so: the shared surface\n // renders `{error ? '' : caption}` — it BLANKS the caption whenever\n // `error` is set, so a failure branch here would compute a string that\n // is then discarded. The failure is named in `meta` instead, which\n // `PreviewHeader` renders without consulting `error`.\n caption={\n isRunning\n ? caption || t('bigconsole.widget.aiPreview.working', 'Working…')\n : t('bigconsole.widget.aiPreview.done', 'Done')\n }\n error={error}\n meta={\n <PreviewMeta\n state={isRunning ? 'running' : error ? 'stopped' : 'idle'}\n stateLabel={\n isRunning\n ? t('bigconsole.widget.aiPreview.live', 'Live')\n : error\n ? t('bigconsole.widget.aiPreview.stopped', 'Stopped')\n : null\n }\n updatedLabel={t('bigconsole.widget.aiPreview.updated', 'updated')}\n updatedAt={updatedAt}\n ago={(seconds) => formatAgo(seconds, t)}\n />\n }\n headerActions={\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={closePreview}\n aria-label={t('bigconsole.widget.aiPreview.closeAriaLabel', 'Close preview')}\n data-testid=\"ai-preview-close\"\n >\n <X className=\"size-4\" />\n </Button>\n }\n labels={previewLabels(t)}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -4,9 +4,9 @@ import { BIGCONSOLE_PERMISSIONS as t } from "../../../constants/permissions.js";
|
|
|
4
4
|
import { memo as n, useCallback as r, useEffect as ee, useMemo as i, useRef as te, useState as a } from "react";
|
|
5
5
|
import { PermissionButton as ne } from "@burdenoff/fe-libs/shared/components";
|
|
6
6
|
import { ChevronDown as re, ChevronRight as ie, Pencil as ae, Plus as oe, Zap as se } from "lucide-react";
|
|
7
|
-
import {
|
|
8
|
-
import { Button as le, Checkbox as o, Dialog as ue, DialogContent as de, DialogDescription as fe, DialogFooter as pe, DialogHeader as me, DialogTitle as he, Input as s, Select as c, SelectContent as l, SelectItem as u, SelectTrigger as d, SelectValue as f, Spinner as ge, Textarea as _e } from "@burdenoff/fe-libs/ui";
|
|
7
|
+
import { Button as ce, Checkbox as o, Dialog as le, DialogContent as ue, DialogDescription as de, DialogFooter as fe, DialogHeader as pe, DialogTitle as me, Input as s, Select as c, SelectContent as l, SelectItem as u, SelectTrigger as d, SelectValue as f, Spinner as he, Textarea as ge } from "@burdenoff/fe-libs/ui";
|
|
9
8
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
9
|
+
import { useI18n as _e } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
10
10
|
//#region src/bigconsole/components/widgets/ActionConfigDialog.tsx
|
|
11
11
|
var ve = [
|
|
12
12
|
"POST",
|
|
@@ -78,7 +78,7 @@ var g = {
|
|
|
78
78
|
boxShadow: "var(--shadow-elevation-3)",
|
|
79
79
|
borderRadius: "var(--radius-button)"
|
|
80
80
|
}, y = n(function({ isOpen: n, action: y, initialWebhook: b, isLoading: x = !1, saveError: Se, onClose: Ce, onSave: we }) {
|
|
81
|
-
let { t: S } =
|
|
81
|
+
let { t: S } = _e(), C = !!y, Te = te(null), w = te(!1), [T, E] = a(""), [D, O] = a(""), [k, A] = a(!1), [j, M] = a("PRIMARY"), [N, Ee] = a(""), [P, F] = a("WEBHOOK"), [I, L] = a(""), [R, z] = a("POST"), [B, V] = a(!1), [H, U] = a(!1), [W, De] = a(!1), [G, K] = a(!1), [q, J] = a(() => S("bigconsole.widget.actions.confirm.defaultTitle", "Confirm Action")), [Oe, Y] = a(() => S("bigconsole.widget.actions.confirm.defaultMessage", "Are you sure you want to proceed?")), [ke, X] = a(() => S("bigconsole.widget.actions.confirm.defaultConfirmLabel", "Confirm")), [Ae, Z] = a(() => S("bigconsole.widget.actions.confirm.defaultCancelLabel", "Cancel")), [Q, $] = a(null), je = i(() => [{
|
|
82
82
|
value: "WEBHOOK",
|
|
83
83
|
label: S("bigconsole.widget.actions.outcome.webhook.label", "Call a webhook / my API"),
|
|
84
84
|
hint: S("bigconsole.widget.actions.outcome.webhook.hint", "Sends an HTTP request to the URL below every time the button is clicked.")
|
|
@@ -210,16 +210,16 @@ var g = {
|
|
|
210
210
|
we,
|
|
211
211
|
S
|
|
212
212
|
]), Ie = (e) => Me.find((t) => t.value === e)?.color || "var(--color-action-primary-bg)", Le = je.find((e) => e.value === P);
|
|
213
|
-
return /* @__PURE__ */ p(
|
|
213
|
+
return /* @__PURE__ */ p(le, {
|
|
214
214
|
open: n,
|
|
215
215
|
onOpenChange: (e) => !e && !x && Ce(),
|
|
216
|
-
children: /* @__PURE__ */ m(
|
|
216
|
+
children: /* @__PURE__ */ m(ue, {
|
|
217
217
|
style: {
|
|
218
218
|
width: "min(500px, calc(100vw - 2rem))",
|
|
219
219
|
maxWidth: "calc(100vw - 2rem)",
|
|
220
220
|
padding: 0
|
|
221
221
|
},
|
|
222
|
-
children: [/* @__PURE__ */ p(
|
|
222
|
+
children: [/* @__PURE__ */ p(pe, {
|
|
223
223
|
style: { padding: "var(--space-cardPadding) var(--space-cardPadding) 0" },
|
|
224
224
|
children: /* @__PURE__ */ m("div", {
|
|
225
225
|
style: {
|
|
@@ -245,7 +245,7 @@ var g = {
|
|
|
245
245
|
width: "var(--size-icon-lg)",
|
|
246
246
|
color: "var(--color-action-primary-text)"
|
|
247
247
|
} })
|
|
248
|
-
}), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p(
|
|
248
|
+
}), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p(me, {
|
|
249
249
|
style: {
|
|
250
250
|
fontSize: "var(--font-size-body-md)",
|
|
251
251
|
fontWeight: "var(--font-weight-bold)",
|
|
@@ -253,7 +253,7 @@ var g = {
|
|
|
253
253
|
margin: 0
|
|
254
254
|
},
|
|
255
255
|
children: C ? S("bigconsole.widget.actions.header.editTitle", "Edit Button") : S("bigconsole.widget.actions.header.addTitle", "Add Button")
|
|
256
|
-
}), /* @__PURE__ */ p(
|
|
256
|
+
}), /* @__PURE__ */ p(de, {
|
|
257
257
|
style: {
|
|
258
258
|
fontSize: "var(--font-size-body-sm)",
|
|
259
259
|
color: "var(--color-text-secondary)",
|
|
@@ -588,7 +588,7 @@ var g = {
|
|
|
588
588
|
marginBottom: "var(--space-controlGap)"
|
|
589
589
|
},
|
|
590
590
|
children: S("bigconsole.widget.actions.confirm.messageLabel", "Message")
|
|
591
|
-
}), /* @__PURE__ */ p(
|
|
591
|
+
}), /* @__PURE__ */ p(ge, {
|
|
592
592
|
value: Oe,
|
|
593
593
|
onChange: (e) => Y(e.target.value),
|
|
594
594
|
rows: 2,
|
|
@@ -765,7 +765,7 @@ var g = {
|
|
|
765
765
|
})]
|
|
766
766
|
})
|
|
767
767
|
]
|
|
768
|
-
}), /* @__PURE__ */ m(
|
|
768
|
+
}), /* @__PURE__ */ m(fe, {
|
|
769
769
|
style: {
|
|
770
770
|
padding: "var(--space-formGap) var(--space-pagePadding)",
|
|
771
771
|
borderTop: "1px solid var(--color-border-subtle)",
|
|
@@ -774,7 +774,7 @@ var g = {
|
|
|
774
774
|
justifyContent: "flex-end",
|
|
775
775
|
gap: "var(--space-controlGap)"
|
|
776
776
|
},
|
|
777
|
-
children: [/* @__PURE__ */ p(
|
|
777
|
+
children: [/* @__PURE__ */ p(ce, {
|
|
778
778
|
type: "button",
|
|
779
779
|
variant: "outline",
|
|
780
780
|
onClick: Ce,
|
|
@@ -784,7 +784,7 @@ var g = {
|
|
|
784
784
|
}), /* @__PURE__ */ p(ne, {
|
|
785
785
|
permission: C ? t.WIDGET_ACTION_UPDATE : t.WIDGET_ACTION_CREATE,
|
|
786
786
|
deniedBehavior: "disable",
|
|
787
|
-
children: /* @__PURE__ */ p(
|
|
787
|
+
children: /* @__PURE__ */ p(ce, {
|
|
788
788
|
type: "submit",
|
|
789
789
|
disabled: x || !T.trim(),
|
|
790
790
|
style: {
|
|
@@ -797,7 +797,7 @@ var g = {
|
|
|
797
797
|
alignItems: "center",
|
|
798
798
|
gap: "var(--space-iconGap)"
|
|
799
799
|
},
|
|
800
|
-
children: [/* @__PURE__ */ p(
|
|
800
|
+
children: [/* @__PURE__ */ p(he, { style: {
|
|
801
801
|
height: "var(--size-icon-sm)",
|
|
802
802
|
width: "var(--size-icon-sm)"
|
|
803
803
|
} }), S("bigconsole.widget.actions.footer.saving", "Saving...")]
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ListDashboardsDocument as e } from "../../../generated/wspace-operations.js";
|
|
2
|
+
import { SECTION_FOCUS_RING as t } from "../common/sectionStyles.js";
|
|
3
|
+
import { Section as n } from "../common/Section.js";
|
|
3
4
|
import "../common/index.js";
|
|
4
|
-
import { ListDashboardsDocument as n } from "../../../generated/wspace-operations.js";
|
|
5
5
|
import "../../hooks/useDrilldown.js";
|
|
6
6
|
import { memo as r, useCallback as i, useEffect as a, useMemo as o, useState as s } from "react";
|
|
7
7
|
import { useApolloClient as c } from "@apollo/client/react";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
9
|
+
import { useI18n as f } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
10
10
|
//#region src/bigconsole/components/widgets/DrilldownConfigPanel.tsx
|
|
11
11
|
var p = "min-h-control-md rounded-input border border-[var(--color-border-subtle)] bg-bg-surface py-2 text-sm text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface", m = `${p} w-full px-3`, h = "bg-action-primary-bg border-action-primary-bg", g = "bg-bg-sunken border-[var(--color-border-strong)]", _ = "bg-bg-surface shadow-[var(--shadow-elevation-1)]";
|
|
12
12
|
function v(e, t = "") {
|
|
@@ -20,7 +20,7 @@ function v(e, t = "") {
|
|
|
20
20
|
return n;
|
|
21
21
|
}
|
|
22
22
|
var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
23
|
-
let { t: x } =
|
|
23
|
+
let { t: x } = f(), S = c(), [C, w] = s(r.drilldown?.enabled ?? !1), [T, E] = s(r.drilldown?.targetDashboardId ?? ""), [D, O] = s(r.drilldown?.navigationMode ?? "MODAL"), [k, A] = s(r.drilldown?.passGlobalFilters ?? !0), [j, M] = s(r.drilldown?.maxDepth ?? 3), [N, P] = s(r.drilldown?.openIn ?? "same"), [F, I] = s(() => {
|
|
24
24
|
let e = r.drilldown?.parameterMapping;
|
|
25
25
|
return e ? Object.entries(e).map(([e, t]) => ({
|
|
26
26
|
key: e,
|
|
@@ -73,11 +73,11 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
73
73
|
N,
|
|
74
74
|
W
|
|
75
75
|
]), a(() => {
|
|
76
|
-
async function
|
|
76
|
+
async function t() {
|
|
77
77
|
B(!0);
|
|
78
78
|
try {
|
|
79
79
|
R(((await S.query({
|
|
80
|
-
query:
|
|
80
|
+
query: e,
|
|
81
81
|
variables: { first: 100 },
|
|
82
82
|
fetchPolicy: "cache-first"
|
|
83
83
|
})).data?.listDashboards?.edges || []).map((e) => {
|
|
@@ -91,7 +91,7 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
91
91
|
B(!1);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
t();
|
|
95
95
|
}, [S]);
|
|
96
96
|
let G = i(() => {
|
|
97
97
|
I((e) => [...e, {
|
|
@@ -106,51 +106,51 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
106
106
|
[t]: n
|
|
107
107
|
} : r));
|
|
108
108
|
}, []);
|
|
109
|
-
return /* @__PURE__ */
|
|
109
|
+
return /* @__PURE__ */ d("div", {
|
|
110
110
|
className: "min-w-0 space-y-form-gap",
|
|
111
111
|
children: [
|
|
112
|
-
/* @__PURE__ */
|
|
112
|
+
/* @__PURE__ */ d("div", {
|
|
113
113
|
className: "flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-card border border-[var(--color-border-subtle)] bg-bg-surface p-3",
|
|
114
|
-
children: [/* @__PURE__ */
|
|
114
|
+
children: [/* @__PURE__ */ u("label", {
|
|
115
115
|
htmlFor: "drilldown-enable",
|
|
116
116
|
className: "text-sm font-medium text-text-primary",
|
|
117
117
|
children: x("bigconsole.widget.drilldown.enableLabel", "Enable Drilldown")
|
|
118
|
-
}), /* @__PURE__ */
|
|
118
|
+
}), /* @__PURE__ */ u("button", {
|
|
119
119
|
id: "drilldown-enable",
|
|
120
120
|
type: "button",
|
|
121
121
|
role: "switch",
|
|
122
122
|
"aria-checked": C,
|
|
123
123
|
onClick: () => w(!C),
|
|
124
|
-
className: `relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border motion-safe:transition-colors ${
|
|
125
|
-
children: /* @__PURE__ */
|
|
124
|
+
className: `relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border motion-safe:transition-colors ${t} ${C ? h : g}`,
|
|
125
|
+
children: /* @__PURE__ */ u("span", { className: `inline-block h-4 w-4 transform rounded-full motion-safe:transition-transform ${_} ${C ? "translate-x-6" : "translate-x-1"}` })
|
|
126
126
|
})]
|
|
127
127
|
}),
|
|
128
|
-
C && /* @__PURE__ */
|
|
129
|
-
/* @__PURE__ */
|
|
128
|
+
C && /* @__PURE__ */ d(l, { children: [
|
|
129
|
+
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
|
|
130
130
|
htmlFor: "drilldown-target",
|
|
131
131
|
className: "mb-1 block text-sm font-medium text-text-primary",
|
|
132
132
|
children: x("bigconsole.widget.drilldown.targetDashboardLabel", "Target Dashboard")
|
|
133
|
-
}), /* @__PURE__ */
|
|
133
|
+
}), /* @__PURE__ */ d("select", {
|
|
134
134
|
id: "drilldown-target",
|
|
135
135
|
value: T,
|
|
136
136
|
onChange: (e) => E(e.target.value),
|
|
137
137
|
disabled: z,
|
|
138
138
|
className: m,
|
|
139
|
-
children: [/* @__PURE__ */
|
|
139
|
+
children: [/* @__PURE__ */ u("option", {
|
|
140
140
|
value: "",
|
|
141
141
|
children: x("bigconsole.widget.drilldown.selectDashboard", "Select a dashboard...")
|
|
142
|
-
}), L.filter((e) => e.id !== r.dashboardId).map((e) => /* @__PURE__ */
|
|
142
|
+
}), L.filter((e) => e.id !== r.dashboardId).map((e) => /* @__PURE__ */ u("option", {
|
|
143
143
|
value: e.id,
|
|
144
144
|
children: e.name
|
|
145
145
|
}, e.id))]
|
|
146
146
|
})] }),
|
|
147
|
-
/* @__PURE__ */
|
|
148
|
-
/* @__PURE__ */
|
|
147
|
+
/* @__PURE__ */ d("div", { children: [
|
|
148
|
+
/* @__PURE__ */ u("p", {
|
|
149
149
|
className: "mb-1 text-sm font-medium text-text-primary",
|
|
150
150
|
id: "drilldown-nav-mode-label",
|
|
151
151
|
children: x("bigconsole.widget.drilldown.navigationModeLabel", "Navigation Mode")
|
|
152
152
|
}),
|
|
153
|
-
/* @__PURE__ */
|
|
153
|
+
/* @__PURE__ */ u("div", {
|
|
154
154
|
className: "flex flex-wrap gap-2",
|
|
155
155
|
role: "group",
|
|
156
156
|
"aria-labelledby": "drilldown-nav-mode-label",
|
|
@@ -158,7 +158,7 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
158
158
|
"MODAL",
|
|
159
159
|
"NEW_TAB",
|
|
160
160
|
"SAME_WINDOW"
|
|
161
|
-
].map((e) => /* @__PURE__ */
|
|
161
|
+
].map((e) => /* @__PURE__ */ d("button", {
|
|
162
162
|
type: "button",
|
|
163
163
|
"aria-pressed": D === e,
|
|
164
164
|
onClick: () => O(e),
|
|
@@ -170,7 +170,7 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
170
170
|
]
|
|
171
171
|
}, e))
|
|
172
172
|
}),
|
|
173
|
-
/* @__PURE__ */
|
|
173
|
+
/* @__PURE__ */ d("p", {
|
|
174
174
|
className: "mt-1 text-xs text-text-muted",
|
|
175
175
|
children: [
|
|
176
176
|
D === "MODAL" && x("bigconsole.widget.drilldown.modeHelp.modal", "Opens target dashboard in a modal overlay"),
|
|
@@ -179,27 +179,27 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
179
179
|
]
|
|
180
180
|
})
|
|
181
181
|
] }),
|
|
182
|
-
/* @__PURE__ */
|
|
183
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ d("div", { children: [
|
|
183
|
+
/* @__PURE__ */ d("div", {
|
|
184
184
|
className: "mb-2 flex flex-wrap items-center justify-between gap-2",
|
|
185
|
-
children: [/* @__PURE__ */
|
|
185
|
+
children: [/* @__PURE__ */ u("p", {
|
|
186
186
|
className: "text-sm font-medium text-text-primary",
|
|
187
187
|
children: x("bigconsole.widget.drilldown.parameterMappingsLabel", "Parameter Mappings")
|
|
188
|
-
}), /* @__PURE__ */
|
|
188
|
+
}), /* @__PURE__ */ u("button", {
|
|
189
189
|
type: "button",
|
|
190
190
|
onClick: G,
|
|
191
191
|
className: "rounded-button px-1 text-xs text-text-link hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface",
|
|
192
192
|
children: x("bigconsole.widget.drilldown.addParameter", "+ Add Parameter")
|
|
193
193
|
})]
|
|
194
194
|
}),
|
|
195
|
-
/* @__PURE__ */
|
|
195
|
+
/* @__PURE__ */ u("div", {
|
|
196
196
|
className: "space-y-2",
|
|
197
|
-
children: F.map((e, t) => /* @__PURE__ */
|
|
197
|
+
children: F.map((e, t) => /* @__PURE__ */ u("div", {
|
|
198
198
|
className: "relative",
|
|
199
|
-
children: /* @__PURE__ */
|
|
199
|
+
children: /* @__PURE__ */ d("div", {
|
|
200
200
|
className: "flex min-w-0 flex-wrap items-center gap-2",
|
|
201
201
|
children: [
|
|
202
|
-
/* @__PURE__ */
|
|
202
|
+
/* @__PURE__ */ u("input", {
|
|
203
203
|
type: "text",
|
|
204
204
|
value: e.key,
|
|
205
205
|
onChange: (e) => q(t, "key", e.target.value),
|
|
@@ -207,14 +207,14 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
207
207
|
"aria-label": `Parameter ${t + 1} name`,
|
|
208
208
|
className: `${m} min-w-[7rem] flex-1`
|
|
209
209
|
}),
|
|
210
|
-
/* @__PURE__ */
|
|
210
|
+
/* @__PURE__ */ u("span", {
|
|
211
211
|
"aria-hidden": "true",
|
|
212
212
|
className: "text-text-muted",
|
|
213
213
|
children: "="
|
|
214
214
|
}),
|
|
215
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ d("div", {
|
|
216
216
|
className: "relative min-w-[7rem] flex-1",
|
|
217
|
-
children: [/* @__PURE__ */
|
|
217
|
+
children: [/* @__PURE__ */ u("input", {
|
|
218
218
|
type: "text",
|
|
219
219
|
value: e.value,
|
|
220
220
|
onChange: (e) => q(t, "value", e.target.value),
|
|
@@ -223,9 +223,9 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
223
223
|
placeholder: x("bigconsole.widget.drilldown.parameterValuePlaceholder", "{{row.field}} or static"),
|
|
224
224
|
"aria-label": `Parameter ${t + 1} value`,
|
|
225
225
|
className: m
|
|
226
|
-
}), V === t && U.length > 0 && /* @__PURE__ */
|
|
226
|
+
}), V === t && U.length > 0 && /* @__PURE__ */ u("div", {
|
|
227
227
|
className: "absolute left-0 right-0 top-full z-10 mt-1 max-h-40 overflow-y-auto rounded-input border border-[var(--color-border-subtle)] bg-bg-surface shadow-[var(--shadow-elevation-2)]",
|
|
228
|
-
children: U.slice(0, 10).map((e) => /* @__PURE__ */
|
|
228
|
+
children: U.slice(0, 10).map((e) => /* @__PURE__ */ u("button", {
|
|
229
229
|
type: "button",
|
|
230
230
|
onClick: () => {
|
|
231
231
|
q(t, "value", e), H(null);
|
|
@@ -235,17 +235,17 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
235
235
|
}, e))
|
|
236
236
|
})]
|
|
237
237
|
}),
|
|
238
|
-
F.length > 1 && /* @__PURE__ */
|
|
238
|
+
F.length > 1 && /* @__PURE__ */ u("button", {
|
|
239
239
|
type: "button",
|
|
240
240
|
onClick: () => K(t),
|
|
241
241
|
"aria-label": `Remove parameter ${t + 1}`,
|
|
242
242
|
className: "rounded-button p-1 text-text-muted hover:text-[var(--color-status-error-text)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface",
|
|
243
|
-
children: /* @__PURE__ */
|
|
243
|
+
children: /* @__PURE__ */ u("svg", {
|
|
244
244
|
className: "h-icon-sm w-icon-sm",
|
|
245
245
|
fill: "none",
|
|
246
246
|
stroke: "currentColor",
|
|
247
247
|
viewBox: "0 0 24 24",
|
|
248
|
-
children: /* @__PURE__ */
|
|
248
|
+
children: /* @__PURE__ */ u("path", {
|
|
249
249
|
strokeLinecap: "round",
|
|
250
250
|
strokeLinejoin: "round",
|
|
251
251
|
strokeWidth: 2,
|
|
@@ -257,84 +257,84 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
257
257
|
})
|
|
258
258
|
}, t))
|
|
259
259
|
}),
|
|
260
|
-
/* @__PURE__ */
|
|
260
|
+
/* @__PURE__ */ d("p", {
|
|
261
261
|
className: "mt-2 text-xs text-text-muted",
|
|
262
262
|
children: [
|
|
263
263
|
x("bigconsole.widget.drilldown.paramHelp.usePrefix", "Use"),
|
|
264
264
|
" ",
|
|
265
|
-
/* @__PURE__ */
|
|
265
|
+
/* @__PURE__ */ u("code", {
|
|
266
266
|
className: "px-1 bg-bg-sunken rounded",
|
|
267
267
|
children: "{{row.field}}"
|
|
268
268
|
}),
|
|
269
269
|
" ",
|
|
270
270
|
x("bigconsole.widget.drilldown.paramHelp.useSuffix", "for dynamic values or enter static text."),
|
|
271
|
-
/* @__PURE__ */
|
|
271
|
+
/* @__PURE__ */ u("br", {}),
|
|
272
272
|
x("bigconsole.widget.drilldown.paramHelp.examples", "Examples:"),
|
|
273
273
|
" ",
|
|
274
|
-
/* @__PURE__ */
|
|
274
|
+
/* @__PURE__ */ u("code", {
|
|
275
275
|
className: "px-1 bg-bg-sunken rounded",
|
|
276
276
|
children: "{{row.category}}"
|
|
277
277
|
}),
|
|
278
278
|
",",
|
|
279
279
|
" ",
|
|
280
|
-
/* @__PURE__ */
|
|
280
|
+
/* @__PURE__ */ u("code", {
|
|
281
281
|
className: "px-1 bg-bg-sunken rounded",
|
|
282
282
|
children: "{{item.id}}"
|
|
283
283
|
}),
|
|
284
284
|
",",
|
|
285
285
|
" ",
|
|
286
|
-
/* @__PURE__ */
|
|
286
|
+
/* @__PURE__ */ u("code", {
|
|
287
287
|
className: "px-1 bg-bg-sunken rounded",
|
|
288
288
|
children: "{{globals.vars.dateFrom}}"
|
|
289
289
|
})
|
|
290
290
|
]
|
|
291
291
|
})
|
|
292
292
|
] }),
|
|
293
|
-
/* @__PURE__ */
|
|
293
|
+
/* @__PURE__ */ u(n, {
|
|
294
294
|
emphasis: "muted",
|
|
295
295
|
padding: "compact",
|
|
296
296
|
headingLevel: 4,
|
|
297
297
|
title: x("bigconsole.widget.drilldown.advancedOptions", "Advanced Options"),
|
|
298
298
|
description: "Rarely changed. Defaults suit most drilldowns.",
|
|
299
299
|
"data-testid": "drilldown-advanced",
|
|
300
|
-
children: /* @__PURE__ */
|
|
300
|
+
children: /* @__PURE__ */ d("div", {
|
|
301
301
|
className: "flex flex-col gap-2",
|
|
302
302
|
children: [
|
|
303
|
-
/* @__PURE__ */
|
|
303
|
+
/* @__PURE__ */ d("div", {
|
|
304
304
|
className: "flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-button bg-bg-surface p-2",
|
|
305
|
-
children: [/* @__PURE__ */
|
|
305
|
+
children: [/* @__PURE__ */ d("div", {
|
|
306
306
|
className: "min-w-0",
|
|
307
|
-
children: [/* @__PURE__ */
|
|
307
|
+
children: [/* @__PURE__ */ u("label", {
|
|
308
308
|
htmlFor: "drilldown-pass-filters",
|
|
309
309
|
className: "text-sm text-text-primary",
|
|
310
310
|
children: x("bigconsole.widget.drilldown.passGlobalFiltersLabel", "Pass Global Filters")
|
|
311
|
-
}), /* @__PURE__ */
|
|
311
|
+
}), /* @__PURE__ */ u("p", {
|
|
312
312
|
className: "text-xs text-text-muted",
|
|
313
313
|
children: x("bigconsole.widget.drilldown.passGlobalFiltersHelp", "Include current dashboard filters in drilldown")
|
|
314
314
|
})]
|
|
315
|
-
}), /* @__PURE__ */
|
|
315
|
+
}), /* @__PURE__ */ u("button", {
|
|
316
316
|
id: "drilldown-pass-filters",
|
|
317
317
|
type: "button",
|
|
318
318
|
role: "switch",
|
|
319
319
|
"aria-checked": k,
|
|
320
320
|
onClick: () => A(!k),
|
|
321
321
|
className: `relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface ${k ? h : g}`,
|
|
322
|
-
children: /* @__PURE__ */
|
|
322
|
+
children: /* @__PURE__ */ u("span", { className: `inline-block h-3 w-3 transform rounded-full motion-safe:transition-transform ${_} ${k ? "translate-x-5" : "translate-x-1"}` })
|
|
323
323
|
})]
|
|
324
324
|
}),
|
|
325
|
-
/* @__PURE__ */
|
|
325
|
+
/* @__PURE__ */ d("div", {
|
|
326
326
|
className: "flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-button bg-bg-surface p-2",
|
|
327
|
-
children: [/* @__PURE__ */
|
|
327
|
+
children: [/* @__PURE__ */ d("div", {
|
|
328
328
|
className: "min-w-0",
|
|
329
|
-
children: [/* @__PURE__ */
|
|
329
|
+
children: [/* @__PURE__ */ u("label", {
|
|
330
330
|
htmlFor: "drilldown-max-depth",
|
|
331
331
|
className: "text-sm text-text-primary",
|
|
332
332
|
children: x("bigconsole.widget.drilldown.maxDepthLabel", "Max Drilldown Depth")
|
|
333
|
-
}), /* @__PURE__ */
|
|
333
|
+
}), /* @__PURE__ */ u("p", {
|
|
334
334
|
className: "text-xs text-text-muted",
|
|
335
335
|
children: x("bigconsole.widget.drilldown.maxDepthHelp", "Limit nested drilldown levels")
|
|
336
336
|
})]
|
|
337
|
-
}), /* @__PURE__ */
|
|
337
|
+
}), /* @__PURE__ */ u("select", {
|
|
338
338
|
id: "drilldown-max-depth",
|
|
339
339
|
value: j,
|
|
340
340
|
onChange: (e) => M(Number(e.target.value)),
|
|
@@ -345,35 +345,35 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
345
345
|
3,
|
|
346
346
|
4,
|
|
347
347
|
5
|
|
348
|
-
].map((e) => /* @__PURE__ */
|
|
348
|
+
].map((e) => /* @__PURE__ */ u("option", {
|
|
349
349
|
value: e,
|
|
350
350
|
children: e
|
|
351
351
|
}, e))
|
|
352
352
|
})]
|
|
353
353
|
}),
|
|
354
|
-
D === "SAME_WINDOW" && /* @__PURE__ */
|
|
354
|
+
D === "SAME_WINDOW" && /* @__PURE__ */ d("div", {
|
|
355
355
|
className: "flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-button bg-bg-surface p-2",
|
|
356
|
-
children: [/* @__PURE__ */
|
|
356
|
+
children: [/* @__PURE__ */ d("div", {
|
|
357
357
|
className: "min-w-0",
|
|
358
|
-
children: [/* @__PURE__ */
|
|
358
|
+
children: [/* @__PURE__ */ u("p", {
|
|
359
359
|
className: "text-sm text-text-primary",
|
|
360
360
|
id: "drilldown-open-in-label",
|
|
361
361
|
children: x("bigconsole.widget.drilldown.openInLabel", "Open In")
|
|
362
|
-
}), /* @__PURE__ */
|
|
362
|
+
}), /* @__PURE__ */ u("p", {
|
|
363
363
|
className: "text-xs text-text-muted",
|
|
364
364
|
children: x("bigconsole.widget.drilldown.openInHelp", "Tab behavior for navigation")
|
|
365
365
|
})]
|
|
366
|
-
}), /* @__PURE__ */
|
|
366
|
+
}), /* @__PURE__ */ d("div", {
|
|
367
367
|
className: "flex shrink-0 flex-wrap gap-1",
|
|
368
368
|
role: "group",
|
|
369
369
|
"aria-labelledby": "drilldown-open-in-label",
|
|
370
|
-
children: [/* @__PURE__ */
|
|
370
|
+
children: [/* @__PURE__ */ u("button", {
|
|
371
371
|
type: "button",
|
|
372
372
|
"aria-pressed": N === "same",
|
|
373
373
|
onClick: () => P("same"),
|
|
374
374
|
className: `min-h-control-md rounded-button px-2 text-xs font-medium motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface ${N === "same" ? "bg-action-primary-bg text-action-primary-text" : "border border-[var(--color-border-subtle)] bg-bg-surface text-text-secondary hover:text-text-primary"}`,
|
|
375
375
|
children: x("bigconsole.widget.drilldown.openIn.sameTab", "Same Tab")
|
|
376
|
-
}), /* @__PURE__ */
|
|
376
|
+
}), /* @__PURE__ */ u("button", {
|
|
377
377
|
type: "button",
|
|
378
378
|
"aria-pressed": N === "new",
|
|
379
379
|
onClick: () => P("new"),
|
|
@@ -386,13 +386,13 @@ var y = r(function({ widget: r, onChange: y, widgetData: b }) {
|
|
|
386
386
|
})
|
|
387
387
|
})
|
|
388
388
|
] }),
|
|
389
|
-
!C && r.drilldown?.id && /* @__PURE__ */
|
|
389
|
+
!C && r.drilldown?.id && /* @__PURE__ */ u(n, {
|
|
390
390
|
tone: "warning",
|
|
391
391
|
padding: "compact",
|
|
392
392
|
headingLevel: 4,
|
|
393
393
|
title: "Drilldown will be removed",
|
|
394
394
|
"data-testid": "drilldown-removal-notice",
|
|
395
|
-
children: /* @__PURE__ */
|
|
395
|
+
children: /* @__PURE__ */ u("p", {
|
|
396
396
|
className: "text-xs text-text-secondary",
|
|
397
397
|
children: x("bigconsole.widget.drilldown.removalWarning", "Drilldown will be removed when you save changes.")
|
|
398
398
|
})
|