@burdenoff/microfe-bigconsole 2026.1004.3 → 2026.1004.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/bigconsole/BigConsoleRoutes.d.ts +1 -1
  2. package/dist/bigconsole/BigConsoleRoutes.d.ts.map +1 -1
  3. package/dist/bigconsole/BigConsoleRoutes.js +15 -1
  4. package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
  5. package/dist/bigconsole/components/DrilldownDashboardRenderer.d.ts.map +1 -1
  6. package/dist/bigconsole/components/DrilldownDashboardRenderer.js +57 -56
  7. package/dist/bigconsole/components/DrilldownDashboardRenderer.js.map +1 -1
  8. package/dist/bigconsole/components/DrilldownModal.d.ts.map +1 -1
  9. package/dist/bigconsole/components/DrilldownModal.js +55 -53
  10. package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
  11. package/dist/bigconsole/components/builder/inspector/DataBindingSection.d.ts +3 -1
  12. package/dist/bigconsole/components/builder/inspector/DataBindingSection.d.ts.map +1 -1
  13. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +40 -39
  14. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
  15. package/dist/bigconsole/components/dashboard/DashboardCanvas.d.ts.map +1 -1
  16. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +184 -177
  17. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  18. package/dist/bigconsole/components/dashboard/DashboardGrid.d.ts.map +1 -1
  19. package/dist/bigconsole/components/dashboard/DashboardGrid.js +40 -22
  20. package/dist/bigconsole/components/dashboard/DashboardGrid.js.map +1 -1
  21. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.d.ts.map +1 -1
  22. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js +31 -25
  23. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js.map +1 -1
  24. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.d.ts +1 -1
  25. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.d.ts.map +1 -1
  26. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +115 -80
  27. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
  28. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.d.ts.map +1 -1
  29. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +177 -146
  30. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
  31. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.d.ts +1 -1
  32. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.d.ts.map +1 -1
  33. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +375 -325
  34. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
  35. package/dist/bigconsole/components/datasink/CacheTTLSelector.d.ts.map +1 -1
  36. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +7 -1
  37. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  38. package/dist/bigconsole/components/parser/ParserSelector.d.ts +3 -1
  39. package/dist/bigconsole/components/parser/ParserSelector.d.ts.map +1 -1
  40. package/dist/bigconsole/components/parser/ParserSelector.js +94 -94
  41. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  42. package/dist/bigconsole/components/pipeline/PipelineCard.d.ts.map +1 -1
  43. package/dist/bigconsole/components/pipeline/PipelineCard.js +111 -89
  44. package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
  45. package/dist/bigconsole/components/pipeline/PipelineScopePicker.d.ts +8 -0
  46. package/dist/bigconsole/components/pipeline/PipelineScopePicker.d.ts.map +1 -0
  47. package/dist/bigconsole/components/pipeline/PipelineScopePicker.js +52 -0
  48. package/dist/bigconsole/components/pipeline/PipelineScopePicker.js.map +1 -0
  49. package/dist/bigconsole/components/widgets/PropertiesPanel.d.ts.map +1 -1
  50. package/dist/bigconsole/components/widgets/PropertiesPanel.js +257 -221
  51. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  52. package/dist/bigconsole/components/widgets/WidgetHeader.d.ts +1 -0
  53. package/dist/bigconsole/components/widgets/WidgetHeader.d.ts.map +1 -1
  54. package/dist/bigconsole/components/widgets/WidgetHeader.js +29 -29
  55. package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
  56. package/dist/bigconsole/components/widgets/WidgetWrapper.d.ts +2 -0
  57. package/dist/bigconsole/components/widgets/WidgetWrapper.d.ts.map +1 -1
  58. package/dist/bigconsole/components/widgets/WidgetWrapper.js +247 -239
  59. package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
  60. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.d.ts.map +1 -1
  61. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +6 -4
  62. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
  63. package/dist/bigconsole/components/widgets/states/EmptyState.d.ts +1 -0
  64. package/dist/bigconsole/components/widgets/states/EmptyState.d.ts.map +1 -1
  65. package/dist/bigconsole/components/widgets/states/EmptyState.js +4 -4
  66. package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
  67. package/dist/bigconsole/components/workflow/WorkflowDesignPreview.d.ts +7 -0
  68. package/dist/bigconsole/components/workflow/WorkflowDesignPreview.d.ts.map +1 -0
  69. package/dist/bigconsole/components/workflow/WorkflowDesignPreview.js +94 -0
  70. package/dist/bigconsole/components/workflow/WorkflowDesignPreview.js.map +1 -0
  71. package/dist/bigconsole/components/workflow/WorkflowSinkLinkForm.d.ts +7 -0
  72. package/dist/bigconsole/components/workflow/WorkflowSinkLinkForm.d.ts.map +1 -0
  73. package/dist/bigconsole/components/workflow/WorkflowSinkLinkForm.js +101 -0
  74. package/dist/bigconsole/components/workflow/WorkflowSinkLinkForm.js.map +1 -0
  75. package/dist/bigconsole/hooks/useBigConsoleSettings.d.ts +16 -0
  76. package/dist/bigconsole/hooks/useBigConsoleSettings.d.ts.map +1 -0
  77. package/dist/bigconsole/hooks/useBigConsoleSettings.js +57 -0
  78. package/dist/bigconsole/hooks/useBigConsoleSettings.js.map +1 -0
  79. package/dist/bigconsole/hooks/useDashboardOperations.d.ts.map +1 -1
  80. package/dist/bigconsole/hooks/useDashboardOperations.js +102 -79
  81. package/dist/bigconsole/hooks/useDashboardOperations.js.map +1 -1
  82. package/dist/bigconsole/hooks/useExportDashboard.d.ts +3 -1
  83. package/dist/bigconsole/hooks/useExportDashboard.d.ts.map +1 -1
  84. package/dist/bigconsole/hooks/useExportDashboard.js +23 -13
  85. package/dist/bigconsole/hooks/useExportDashboard.js.map +1 -1
  86. package/dist/bigconsole/hooks/useFilterUrlSync.d.ts +18 -0
  87. package/dist/bigconsole/hooks/useFilterUrlSync.d.ts.map +1 -1
  88. package/dist/bigconsole/hooks/useFilterUrlSync.js +87 -57
  89. package/dist/bigconsole/hooks/useFilterUrlSync.js.map +1 -1
  90. package/dist/bigconsole/hooks/useGlobalFilters.d.ts.map +1 -1
  91. package/dist/bigconsole/hooks/useGlobalFilters.js +39 -29
  92. package/dist/bigconsole/hooks/useGlobalFilters.js.map +1 -1
  93. package/dist/bigconsole/hooks/usePageOperations.d.ts.map +1 -1
  94. package/dist/bigconsole/hooks/usePageOperations.js +1 -0
  95. package/dist/bigconsole/hooks/usePageOperations.js.map +1 -1
  96. package/dist/bigconsole/hooks/usePipelineOperations.d.ts.map +1 -1
  97. package/dist/bigconsole/hooks/usePipelineOperations.js +114 -112
  98. package/dist/bigconsole/hooks/usePipelineOperations.js.map +1 -1
  99. package/dist/bigconsole/hooks/useShareRecipients.d.ts +22 -0
  100. package/dist/bigconsole/hooks/useShareRecipients.d.ts.map +1 -0
  101. package/dist/bigconsole/hooks/useShareRecipients.js +198 -0
  102. package/dist/bigconsole/hooks/useShareRecipients.js.map +1 -0
  103. package/dist/bigconsole/pages/DashboardBuilderPage.d.ts.map +1 -1
  104. package/dist/bigconsole/pages/DashboardBuilderPage.js +198 -193
  105. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  106. package/dist/bigconsole/pages/DashboardViewPage.d.ts.map +1 -1
  107. package/dist/bigconsole/pages/DashboardViewPage.js +171 -167
  108. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  109. package/dist/bigconsole/pages/DashboardsPage.d.ts.map +1 -1
  110. package/dist/bigconsole/pages/DashboardsPage.js +313 -266
  111. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  112. package/dist/bigconsole/pages/DataSinkBuilderPage.d.ts.map +1 -1
  113. package/dist/bigconsole/pages/DataSinkBuilderPage.js +84 -79
  114. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  115. package/dist/bigconsole/pages/DataSinkViewPage.d.ts.map +1 -1
  116. package/dist/bigconsole/pages/DataSinkViewPage.js +267 -257
  117. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  118. package/dist/bigconsole/pages/InsightsPage.d.ts.map +1 -1
  119. package/dist/bigconsole/pages/InsightsPage.js +465 -402
  120. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  121. package/dist/bigconsole/pages/PipelineBuilderPage.d.ts.map +1 -1
  122. package/dist/bigconsole/pages/PipelineBuilderPage.js +169 -157
  123. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  124. package/dist/bigconsole/pages/PipelineViewPage.d.ts.map +1 -1
  125. package/dist/bigconsole/pages/PipelineViewPage.js +370 -230
  126. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  127. package/dist/bigconsole/pages/PipelinesPage.d.ts.map +1 -1
  128. package/dist/bigconsole/pages/PipelinesPage.js +181 -151
  129. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  130. package/dist/bigconsole/pages/SettingsPage.d.ts.map +1 -1
  131. package/dist/bigconsole/pages/SettingsPage.js +188 -208
  132. package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
  133. package/dist/bigconsole/pages/WidgetDemoPage.d.ts.map +1 -1
  134. package/dist/bigconsole/pages/WidgetDemoPage.js +134 -117
  135. package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
  136. package/dist/bigconsole/pages/WorkflowViewPage.d.ts.map +1 -1
  137. package/dist/bigconsole/pages/WorkflowViewPage.js +315 -267
  138. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  139. package/dist/bigconsole/pages/WorkflowsPage.d.ts.map +1 -1
  140. package/dist/bigconsole/pages/WorkflowsPage.js +4 -3
  141. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  142. package/dist/bigconsole/types/index.d.ts +4 -0
  143. package/dist/bigconsole/types/index.d.ts.map +1 -1
  144. package/dist/bigconsole/utils/drilldownParams.d.ts +3 -0
  145. package/dist/bigconsole/utils/drilldownParams.d.ts.map +1 -0
  146. package/dist/bigconsole/utils/drilldownParams.js +8 -0
  147. package/dist/bigconsole/utils/drilldownParams.js.map +1 -0
  148. package/dist/generated/wspace-operations.d.ts +148 -0
  149. package/dist/generated/wspace-operations.d.ts.map +1 -1
  150. package/dist/generated/wspace-operations.js +172 -133
  151. package/dist/generated/wspace-operations.js.map +1 -1
  152. package/dist/generated/wspace-types.d.ts +21 -0
  153. package/dist/generated/wspace-types.d.ts.map +1 -1
  154. package/dist/generated/wspace-types.js.map +1 -1
  155. package/dist/microfe-bigconsole.css +1 -1
  156. package/dist/translations/en.d.ts.map +1 -1
  157. package/package.json +2 -1
@@ -2,5 +2,5 @@ import { BigConsoleRootProps } from './types';
2
2
 
3
3
  /** Generate a new workflow builder path with a fresh UUID key. */
4
4
  export declare const newWorkflowPath: () => string;
5
- export declare function BigConsoleRoutes(_props: BigConsoleRootProps): import("react").JSX.Element;
5
+ export declare function BigConsoleRoutes(props: BigConsoleRootProps): import("react").JSX.Element;
6
6
  //# sourceMappingURL=BigConsoleRoutes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BigConsoleRoutes.d.ts","sourceRoot":"","sources":["../../src/bigconsole/BigConsoleRoutes.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAsDnD,kEAAkE;AAClE,eAAO,MAAM,eAAe,cAAwD,CAAC;AA4PrF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,+BAkE3D"}
1
+ {"version":3,"file":"BigConsoleRoutes.d.ts","sourceRoot":"","sources":["../../src/bigconsole/BigConsoleRoutes.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAsDnD,kEAAkE;AAClE,eAAO,MAAM,eAAe,cAAwD,CAAC;AA4PrF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,+BAgF1D"}
@@ -120,7 +120,13 @@ var J = o(function() {
120
120
  });
121
121
  });
122
122
  function Z(e) {
123
- return /* @__PURE__ */ _(i, {
123
+ return e.routePage === "workflow-feeds" ? /* @__PURE__ */ _(i, {
124
+ fallback: /* @__PURE__ */ _(G, {}),
125
+ children: /* @__PURE__ */ _(P, {})
126
+ }) : e.routePage === "workflow-detail" ? /* @__PURE__ */ _(i, {
127
+ fallback: /* @__PURE__ */ _(G, {}),
128
+ children: /* @__PURE__ */ _(F, {})
129
+ }) : /* @__PURE__ */ _(i, {
124
130
  fallback: /* @__PURE__ */ _(G, {}),
125
131
  children: /* @__PURE__ */ v(p, { children: [
126
132
  /* @__PURE__ */ _(f, {
@@ -207,6 +213,14 @@ function Z(e) {
207
213
  path: "/workflows",
208
214
  element: /* @__PURE__ */ _(P, {})
209
215
  }),
216
+ /* @__PURE__ */ _(f, {
217
+ path: "/workflows/feeds",
218
+ element: /* @__PURE__ */ _(P, {})
219
+ }),
220
+ /* @__PURE__ */ _(f, {
221
+ path: "/workflows/details/:workflowId",
222
+ element: /* @__PURE__ */ _(F, {})
223
+ }),
210
224
  /* @__PURE__ */ _(f, {
211
225
  path: "/workflows/list",
212
226
  element: /* @__PURE__ */ _(P, {})
@@ -1 +1 @@
1
- {"version":3,"file":"BigConsoleRoutes.js","names":[],"sources":["../../src/bigconsole/BigConsoleRoutes.tsx"],"sourcesContent":["import { lazy, Suspense, memo, useState, useMemo, useEffect, useRef } from 'react';\nimport { Route, Routes, Navigate, useParams } from 'react-router';\nimport { type BigConsoleRootProps } from './types';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { useApolloClient } from '@apollo/client/react';\nimport { useAppNavigate } from './contexts';\nimport { useWorkflowOperations } from './hooks/useWorkflowOperations';\nimport { GetWorkflowDocument } from '../generated/wspace-operations';\nimport { BOOTSTRAP_RETRY_DELAY_MS } from './constants';\n\n// Import FluidGrids SDK workflow components (EXACT same as microfe-workflows)\nimport {\n WorkflowBuilderPage as SDKWorkflowBuilderPage,\n ExecutionsListPage,\n ExecutionDetailPage,\n HistoryPage,\n TemplatesPage,\n NodesPage,\n SettingsPage as WorkflowSettingsPage,\n} from '@burdenoff/fluidgrids-fe-sdk';\n\n// Lazy-loaded pages\nconst OverviewPage = lazy(() => import('./pages/OverviewPage'));\nconst DashboardsPage = lazy(() => import('./pages/DashboardsPage'));\nconst DashboardViewPage = lazy(() => import('./pages/DashboardViewPage'));\nconst DashboardBuilderPage = lazy(() => import('./pages/DashboardBuilderPage'));\nconst DataSourcesPage = lazy(() => import('./pages/DataSourcesPage'));\nconst InsightsPage = lazy(() => import('./pages/InsightsPage'));\nconst SettingsPage = lazy(() => import('./pages/SettingsPage'));\nconst WidgetDemoPage = lazy(() => import('./pages/WidgetDemoPage'));\n// BigConsole-native workflow pages (query bigconsole-svc, not workflow-svc)\n// These use named exports (no default export), so we remap via .then()\nconst WorkflowsPage = lazy(() => import('./pages/WorkflowsPage').then((m) => ({ default: m.WorkflowsPage })));\nconst WorkflowViewPage = lazy(() => import('./pages/WorkflowViewPage').then((m) => ({ default: m.WorkflowViewPage })));\n// DataSink Pages\nconst DataSinksPage = lazy(() => import('./pages/DataSinksPage'));\nconst DataSinkViewPage = lazy(() => import('./pages/DataSinkViewPage'));\nconst DataSinkBuilderPage = lazy(() => import('./pages/DataSinkBuilderPage'));\n// Parser Pages\nconst DataParsersPage = lazy(() => import('./pages/DataParsersPage'));\nconst ParserViewPage = lazy(() => import('./pages/ParserViewPage'));\nconst ParserBuilderPage = lazy(() => import('./pages/ParserBuilderPage'));\n// Pipeline Pages\nconst PipelinesPage = lazy(() => import('./pages/PipelinesPage'));\nconst PipelineViewPage = lazy(() => import('./pages/PipelineViewPage'));\nconst PipelineBuilderPage = lazy(() => import('./pages/PipelineBuilderPage'));\n\n// Loading fallback component\nfunction PageLoader() {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Spinner className=\"h-8 w-8\" />\n </div>\n );\n}\n\n/** Generate a new workflow builder path with a fresh UUID key. */\nexport const newWorkflowPath = () => `/workflows/workflow/${crypto.randomUUID()}/v1`;\n\n/**\n * Redirect /workflows/new to a UUID-based URL.\n * Uses <Navigate> for synchronous redirect (no blank frame).\n */\nfunction WorkflowNewRedirect() {\n const path = useMemo(() => newWorkflowPath(), []);\n return <Navigate to={path} replace />;\n}\n\n/**\n * Bridge component: resolves a BigConsole workflow ID to its externalWorkflowId\n * and navigates to the SDK's visual builder route.\n *\n * Route: /workflows/:workflowId/edit\n * Redirects to: /workflows/workflow/{workflowKey}/v1\n */\nconst WorkflowEditBridge = memo(function WorkflowEditBridge() {\n const { workflowId } = useParams<{ workflowId: string }>();\n const navigate = useAppNavigate();\n const { fetchWorkflow } = useWorkflowOperations({ skipFetch: true });\n const [error, setError] = useState<string | null>(null);\n const retryCount = useRef(0);\n\n useEffect(() => {\n if (!workflowId) {\n setError('No workflow ID provided');\n return;\n }\n\n // Reset retry budget and error when workflowId changes so a\n // previous failed attempt doesn't consume the new workflow's retry.\n retryCount.current = 0;\n setError(null);\n let cancelled = false;\n\n const handleResult = (workflow: Awaited<ReturnType<typeof fetchWorkflow>>) => {\n if (cancelled) return;\n\n if (workflow?.key) {\n // Navigate to the SDK builder route using the workflow key (e.g. \"github_user_profile\")\n // and default version \"v1\". The FluidGrids SDK fetches the definition by workflowKey.\n // Replace history so the bridge doesn't trap the back button.\n navigate(`/workflows/workflow/${workflow.key}/v1`, { replace: true });\n } else if (workflow) {\n // Workflow exists but has no key — open SDK builder in create mode\n navigate(`/workflows/builder`, { replace: true });\n } else if (retryCount.current < 1) {\n // On full-page loads the auth/workspace context may not be bootstrapped yet,\n // causing a false null. Retry once after a short delay (same pattern as WorkflowViewPage).\n retryCount.current += 1;\n setTimeout(() => {\n if (!cancelled) {\n fetchWorkflow(workflowId)\n .then(handleResult)\n .catch((err) => {\n if (!cancelled) setError(err?.message ?? 'Failed to load workflow');\n });\n }\n }, BOOTSTRAP_RETRY_DELAY_MS);\n } else {\n setError('Workflow not found');\n }\n };\n\n fetchWorkflow(workflowId)\n .then(handleResult)\n .catch((err) => {\n if (!cancelled) setError(err?.message ?? 'Failed to load workflow');\n });\n\n return () => {\n cancelled = true;\n };\n }, [workflowId, fetchWorkflow, navigate]);\n\n if (error) {\n return (\n <div className=\"p-6 flex flex-col items-center justify-center min-h-[400px] text-center gap-4\">\n <p className=\"text-sm text-text-secondary\">{error}</p>\n <button\n type=\"button\"\n onClick={() => navigate('/workflows')}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken hover:bg-border-default rounded-md transition-colors\"\n >\n Back to Workflows\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Spinner className=\"h-8 w-8\" />\n </div>\n );\n});\n\n/**\n * Matches a canonical v4-style UUID. BigConsole workflow RECORD ids are UUIDs;\n * workflow KEYS are human slugs (e.g. \"users_analytics\"). New-workflow URLs also\n * use a fresh `crypto.randomUUID()` as the builder key. We only attempt record\n * resolution for UUID-shaped `:id`s — slugs are always real keys and skip the\n * lookup entirely (no extra round-trip, no spinner flash).\n */\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/** Minimal shape of the GetWorkflow query — the resolver only needs the key. */\ntype WorkflowKeyLookup = { workflow: { key: string | null } | null };\n\n/**\n * Guards the SDK visual builder route.\n *\n * The SDK builder loads its definition from workflow-svc using the URL `:id` as\n * the `workflowKey`. That only works when `:id` is the workflow KEY. When a\n * BigConsole workflow RECORD id (a UUID) reaches the builder — via the SDK\n * card's `navigate(\"../workflow/\" + workflow.workflow_key + ...)`, a bookmarked\n * record-id URL, etc. — no definition matches that key, so the canvas is empty\n * AND the SDK silently creates a phantom 0-node definition keyed by the UUID.\n *\n * This resolver closes that gap centrally (the same id→key resolution the\n * `/workflows/:workflowId/edit` `WorkflowEditBridge` does, but applied to the\n * builder route itself so EVERY entry point is covered):\n * - `:id` is a slug → it's already a key → render the builder as-is.\n * - `:id` is a UUID that maps to a BigConsole record with a different key →\n * redirect to `/workflows/workflow/<key>/<version>`.\n * - `:id` is a UUID that is NOT a record (a fresh new-workflow id) → render\n * the builder as-is (create mode).\n */\nconst WorkflowBuilderResolver = memo(function WorkflowBuilderResolver() {\n const { id, version } = useParams<{ id: string; version: string }>();\n const navigate = useAppNavigate();\n const client = useApolloClient();\n // Slugs (real keys) render the builder immediately (derived below); only\n // UUID-shaped ids need a record lookup first.\n const isUuid = !!id && UUID_RE.test(id);\n // A UUID is only safe to open in the SDK builder once the lookup POSITIVELY\n // confirms it is not a BigConsole record (a clean not-found — e.g. a fresh\n // new-workflow id). Both verdicts are keyed by the id they describe so that\n // navigating between workflows re-resolves instead of reusing a stale answer.\n const [confirmedAbsentId, setConfirmedAbsentId] = useState<string | null>(null);\n const [failedId, setFailedId] = useState<string | null>(null);\n // Bumped by the \"Try again\" button to re-run the lookup effect after a failure.\n const [retryNonce, setRetryNonce] = useState(0);\n const retryCount = useRef(0);\n\n useEffect(() => {\n if (!id || !isUuid) return;\n\n retryCount.current = 0;\n let cancelled = false;\n const targetVersion = version ?? 'v1';\n\n const attempt = () => {\n // Query directly (not via fetchWorkflow, which swallows Apollo errors and\n // returns null) so we can tell a genuine \"no such record\" apart from a\n // transient lookup failure. Treating a failure as not-found would re-open\n // the builder with the record id and recreate a phantom 0-node definition.\n client\n .query<WorkflowKeyLookup>({\n query: GetWorkflowDocument,\n variables: { id },\n fetchPolicy: 'network-only',\n })\n .then((result) => {\n if (cancelled) return;\n const record = result.data?.workflow;\n if (record) {\n // The UUID IS a BigConsole record.\n if (record.key && record.key !== id) {\n // Open the builder under its real key (where the definition + nodes\n // live). encodeURIComponent guards against URL-unsafe key chars.\n // Replace history so the resolver doesn't trap the back button.\n navigate(`/workflows/workflow/${encodeURIComponent(record.key)}/${targetVersion}`, {\n replace: true,\n });\n } else {\n // Record exists but has no usable key — open a blank builder rather\n // than reusing the record UUID as the key (which would phantom).\n navigate('/workflows/builder', { replace: true });\n }\n } else {\n // Query succeeded with no record → a genuine new-workflow id.\n setConfirmedAbsentId(id);\n }\n })\n .catch(() => {\n if (cancelled) return;\n if (retryCount.current < 1) {\n // On a cold full-page load the auth/workspace context may not be\n // bootstrapped yet. Retry once before giving up.\n retryCount.current += 1;\n setTimeout(() => {\n if (!cancelled) attempt();\n }, BOOTSTRAP_RETRY_DELAY_MS);\n } else {\n // Lookup failed — do NOT assume create mode (the id may be a record);\n // surface a retry instead of risking a phantom definition.\n setFailedId(id);\n }\n });\n };\n\n attempt();\n\n return () => {\n cancelled = true;\n };\n }, [id, isUuid, version, client, navigate, retryNonce]);\n\n // Slug keys, and UUIDs confirmed not to be records, render the builder.\n if (!isUuid || confirmedAbsentId === id) {\n return <SDKWorkflowBuilderPage />;\n }\n\n // A lookup that ultimately failed: surface a retry rather than silently\n // opening the builder with what may be a record id.\n if (failedId === id) {\n return (\n <div className=\"p-6 flex flex-col items-center justify-center min-h-[400px] text-center gap-4\">\n <p className=\"text-sm text-text-secondary\">Couldn&apos;t load this workflow. Please try again.</p>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n setFailedId(null);\n setRetryNonce((n) => n + 1);\n }}\n className=\"px-4 py-2 text-sm font-medium text-action-primary-fg bg-action-primary-bg hover:bg-action-primary-bgHover rounded-md transition-colors\"\n >\n Try again\n </button>\n <button\n type=\"button\"\n onClick={() => navigate('/workflows')}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken hover:bg-border-default rounded-md transition-colors\"\n >\n Back to Workflows\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Spinner className=\"h-8 w-8\" />\n </div>\n );\n});\n\nexport function BigConsoleRoutes(_props: BigConsoleRootProps) {\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route path=\"/\" element={<OverviewPage />} />\n <Route path=\"/dashboards\" element={<DashboardsPage />} />\n <Route path=\"/dashboards/:dashboardId\" element={<DashboardViewPage />} />\n <Route path=\"/dashboards/:dashboardId/builder\" element={<DashboardBuilderPage />} />\n <Route path=\"/datasources\" element={<DataSourcesPage />} />\n <Route path=\"/insights\" element={<InsightsPage />} />\n <Route path=\"/settings\" element={<SettingsPage />} />\n <Route path=\"/widgets/demo\" element={<WidgetDemoPage />} />\n {/* DataSink Routes */}\n <Route path=\"/datasinks\" element={<DataSinksPage />} />\n <Route path=\"/datasinks/new\" element={<DataSinkBuilderPage />} />\n <Route path=\"/datasinks/:dataSinkId\" element={<DataSinkViewPage />} />\n <Route path=\"/datasinks/:dataSinkId/edit\" element={<DataSinkBuilderPage />} />\n {/* Parser Routes */}\n <Route path=\"/parsers\" element={<DataParsersPage />} />\n <Route path=\"/parsers/new\" element={<ParserBuilderPage />} />\n <Route path=\"/parsers/:parserId\" element={<ParserViewPage />} />\n <Route path=\"/parsers/:parserId/edit\" element={<ParserBuilderPage />} />\n {/* Dashboard-scoped Parser Routes */}\n <Route path=\"/dashboards/:consoleId/parsers\" element={<DataParsersPage />} />\n <Route path=\"/dashboards/:consoleId/parsers/new\" element={<ParserBuilderPage />} />\n <Route path=\"/dashboards/:consoleId/parsers/:parserId\" element={<ParserViewPage />} />\n <Route path=\"/dashboards/:consoleId/parsers/:parserId/edit\" element={<ParserBuilderPage />} />\n {/* Workflow Routes — list/view use BigConsole-native pages (query bigconsole-svc).\n All static routes are grouped before the dynamic :workflowId catch-all.\n React Router v6 prioritizes static segments regardless of declaration order,\n but keeping them above the param routes makes intent unambiguous for maintainers. */}\n <Route path=\"/workflows\" element={<WorkflowsPage />} />\n <Route path=\"/workflows/list\" element={<WorkflowsPage />} />\n {/* New workflow — redirect to UUID-based URL (matches FluidGrids pattern) */}\n <Route path=\"/workflows/new\" element={<WorkflowNewRedirect />} />\n {/* SDK visual workflow builder — design existing workflows */}\n <Route path=\"/workflows/builder\" element={<SDKWorkflowBuilderPage />} />\n {/* All parameterised builder routes go through WorkflowBuilderResolver so a\n record-id `:id` is resolved to its workflow key first (slugs/new-workflow\n UUIDs pass straight through); otherwise the SDK opens an empty canvas and\n creates a phantom 0-node definition keyed by the record id. */}\n <Route path=\"/workflows/builder/:id/:version\" element={<WorkflowBuilderResolver />} />\n <Route path=\"/workflows/workflow/:id/:version\" element={<WorkflowBuilderResolver />} />\n {/* SDK sub-pages (runs, history, templates, nodes, settings) */}\n <Route path=\"/workflows/runs\" element={<ExecutionsListPage />} />\n <Route path=\"/workflows/runs/:runId\" element={<ExecutionDetailPage />} />\n <Route path=\"/workflows/history\" element={<HistoryPage />} />\n <Route path=\"/workflows/templates\" element={<TemplatesPage />} />\n <Route path=\"/workflows/nodes\" element={<NodesPage />} />\n <Route path=\"/workflows/settings\" element={<WorkflowSettingsPage />} />\n {/* Dynamic routes — :workflowId catch-all AFTER all static segments */}\n <Route path=\"/workflows/:workflowId\" element={<WorkflowViewPage />} />\n <Route path=\"/workflows/:workflowId/edit\" element={<WorkflowEditBridge />} />\n {/* Support SDK's navigation pattern (without /workflows/ prefix) — also\n resolves record-id → key via WorkflowBuilderResolver. */}\n <Route path=\"/workflow/:id/:version\" element={<WorkflowBuilderResolver />} />\n {/* Redirect /list to /workflows/list (SDK uses relative navigation) */}\n <Route path=\"/list\" element={<Navigate to=\"/bigconsole/workflows/list\" replace />} />\n {/* Pipeline Routes */}\n <Route path=\"/pipelines\" element={<PipelinesPage />} />\n <Route path=\"/pipelines/new\" element={<PipelineBuilderPage />} />\n <Route path=\"/pipelines/:pipelineId\" element={<PipelineViewPage />} />\n <Route path=\"/pipelines/:pipelineId/edit\" element={<PipelineBuilderPage />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"BigConsoleRoutes.js","names":[],"sources":["../../src/bigconsole/BigConsoleRoutes.tsx"],"sourcesContent":["import { lazy, Suspense, memo, useState, useMemo, useEffect, useRef } from 'react';\nimport { Route, Routes, Navigate, useParams } from 'react-router';\nimport { type BigConsoleRootProps } from './types';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { useApolloClient } from '@apollo/client/react';\nimport { useAppNavigate } from './contexts';\nimport { useWorkflowOperations } from './hooks/useWorkflowOperations';\nimport { GetWorkflowDocument } from '../generated/wspace-operations';\nimport { BOOTSTRAP_RETRY_DELAY_MS } from './constants';\n\n// Import FluidGrids SDK workflow components (EXACT same as microfe-workflows)\nimport {\n WorkflowBuilderPage as SDKWorkflowBuilderPage,\n ExecutionsListPage,\n ExecutionDetailPage,\n HistoryPage,\n TemplatesPage,\n NodesPage,\n SettingsPage as WorkflowSettingsPage,\n} from '@burdenoff/fluidgrids-fe-sdk';\n\n// Lazy-loaded pages\nconst OverviewPage = lazy(() => import('./pages/OverviewPage'));\nconst DashboardsPage = lazy(() => import('./pages/DashboardsPage'));\nconst DashboardViewPage = lazy(() => import('./pages/DashboardViewPage'));\nconst DashboardBuilderPage = lazy(() => import('./pages/DashboardBuilderPage'));\nconst DataSourcesPage = lazy(() => import('./pages/DataSourcesPage'));\nconst InsightsPage = lazy(() => import('./pages/InsightsPage'));\nconst SettingsPage = lazy(() => import('./pages/SettingsPage'));\nconst WidgetDemoPage = lazy(() => import('./pages/WidgetDemoPage'));\n// BigConsole-native workflow pages (query bigconsole-svc, not workflow-svc)\n// These use named exports (no default export), so we remap via .then()\nconst WorkflowsPage = lazy(() => import('./pages/WorkflowsPage').then((m) => ({ default: m.WorkflowsPage })));\nconst WorkflowViewPage = lazy(() => import('./pages/WorkflowViewPage').then((m) => ({ default: m.WorkflowViewPage })));\n// DataSink Pages\nconst DataSinksPage = lazy(() => import('./pages/DataSinksPage'));\nconst DataSinkViewPage = lazy(() => import('./pages/DataSinkViewPage'));\nconst DataSinkBuilderPage = lazy(() => import('./pages/DataSinkBuilderPage'));\n// Parser Pages\nconst DataParsersPage = lazy(() => import('./pages/DataParsersPage'));\nconst ParserViewPage = lazy(() => import('./pages/ParserViewPage'));\nconst ParserBuilderPage = lazy(() => import('./pages/ParserBuilderPage'));\n// Pipeline Pages\nconst PipelinesPage = lazy(() => import('./pages/PipelinesPage'));\nconst PipelineViewPage = lazy(() => import('./pages/PipelineViewPage'));\nconst PipelineBuilderPage = lazy(() => import('./pages/PipelineBuilderPage'));\n\n// Loading fallback component\nfunction PageLoader() {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Spinner className=\"h-8 w-8\" />\n </div>\n );\n}\n\n/** Generate a new workflow builder path with a fresh UUID key. */\nexport const newWorkflowPath = () => `/workflows/workflow/${crypto.randomUUID()}/v1`;\n\n/**\n * Redirect /workflows/new to a UUID-based URL.\n * Uses <Navigate> for synchronous redirect (no blank frame).\n */\nfunction WorkflowNewRedirect() {\n const path = useMemo(() => newWorkflowPath(), []);\n return <Navigate to={path} replace />;\n}\n\n/**\n * Bridge component: resolves a BigConsole workflow ID to its externalWorkflowId\n * and navigates to the SDK's visual builder route.\n *\n * Route: /workflows/:workflowId/edit\n * Redirects to: /workflows/workflow/{workflowKey}/v1\n */\nconst WorkflowEditBridge = memo(function WorkflowEditBridge() {\n const { workflowId } = useParams<{ workflowId: string }>();\n const navigate = useAppNavigate();\n const { fetchWorkflow } = useWorkflowOperations({ skipFetch: true });\n const [error, setError] = useState<string | null>(null);\n const retryCount = useRef(0);\n\n useEffect(() => {\n if (!workflowId) {\n setError('No workflow ID provided');\n return;\n }\n\n // Reset retry budget and error when workflowId changes so a\n // previous failed attempt doesn't consume the new workflow's retry.\n retryCount.current = 0;\n setError(null);\n let cancelled = false;\n\n const handleResult = (workflow: Awaited<ReturnType<typeof fetchWorkflow>>) => {\n if (cancelled) return;\n\n if (workflow?.key) {\n // Navigate to the SDK builder route using the workflow key (e.g. \"github_user_profile\")\n // and default version \"v1\". The FluidGrids SDK fetches the definition by workflowKey.\n // Replace history so the bridge doesn't trap the back button.\n navigate(`/workflows/workflow/${workflow.key}/v1`, { replace: true });\n } else if (workflow) {\n // Workflow exists but has no key — open SDK builder in create mode\n navigate(`/workflows/builder`, { replace: true });\n } else if (retryCount.current < 1) {\n // On full-page loads the auth/workspace context may not be bootstrapped yet,\n // causing a false null. Retry once after a short delay (same pattern as WorkflowViewPage).\n retryCount.current += 1;\n setTimeout(() => {\n if (!cancelled) {\n fetchWorkflow(workflowId)\n .then(handleResult)\n .catch((err) => {\n if (!cancelled) setError(err?.message ?? 'Failed to load workflow');\n });\n }\n }, BOOTSTRAP_RETRY_DELAY_MS);\n } else {\n setError('Workflow not found');\n }\n };\n\n fetchWorkflow(workflowId)\n .then(handleResult)\n .catch((err) => {\n if (!cancelled) setError(err?.message ?? 'Failed to load workflow');\n });\n\n return () => {\n cancelled = true;\n };\n }, [workflowId, fetchWorkflow, navigate]);\n\n if (error) {\n return (\n <div className=\"p-6 flex flex-col items-center justify-center min-h-[400px] text-center gap-4\">\n <p className=\"text-sm text-text-secondary\">{error}</p>\n <button\n type=\"button\"\n onClick={() => navigate('/workflows')}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken hover:bg-border-default rounded-md transition-colors\"\n >\n Back to Workflows\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Spinner className=\"h-8 w-8\" />\n </div>\n );\n});\n\n/**\n * Matches a canonical v4-style UUID. BigConsole workflow RECORD ids are UUIDs;\n * workflow KEYS are human slugs (e.g. \"users_analytics\"). New-workflow URLs also\n * use a fresh `crypto.randomUUID()` as the builder key. We only attempt record\n * resolution for UUID-shaped `:id`s — slugs are always real keys and skip the\n * lookup entirely (no extra round-trip, no spinner flash).\n */\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/** Minimal shape of the GetWorkflow query — the resolver only needs the key. */\ntype WorkflowKeyLookup = { workflow: { key: string | null } | null };\n\n/**\n * Guards the SDK visual builder route.\n *\n * The SDK builder loads its definition from workflow-svc using the URL `:id` as\n * the `workflowKey`. That only works when `:id` is the workflow KEY. When a\n * BigConsole workflow RECORD id (a UUID) reaches the builder — via the SDK\n * card's `navigate(\"../workflow/\" + workflow.workflow_key + ...)`, a bookmarked\n * record-id URL, etc. — no definition matches that key, so the canvas is empty\n * AND the SDK silently creates a phantom 0-node definition keyed by the UUID.\n *\n * This resolver closes that gap centrally (the same id→key resolution the\n * `/workflows/:workflowId/edit` `WorkflowEditBridge` does, but applied to the\n * builder route itself so EVERY entry point is covered):\n * - `:id` is a slug → it's already a key → render the builder as-is.\n * - `:id` is a UUID that maps to a BigConsole record with a different key →\n * redirect to `/workflows/workflow/<key>/<version>`.\n * - `:id` is a UUID that is NOT a record (a fresh new-workflow id) → render\n * the builder as-is (create mode).\n */\nconst WorkflowBuilderResolver = memo(function WorkflowBuilderResolver() {\n const { id, version } = useParams<{ id: string; version: string }>();\n const navigate = useAppNavigate();\n const client = useApolloClient();\n // Slugs (real keys) render the builder immediately (derived below); only\n // UUID-shaped ids need a record lookup first.\n const isUuid = !!id && UUID_RE.test(id);\n // A UUID is only safe to open in the SDK builder once the lookup POSITIVELY\n // confirms it is not a BigConsole record (a clean not-found — e.g. a fresh\n // new-workflow id). Both verdicts are keyed by the id they describe so that\n // navigating between workflows re-resolves instead of reusing a stale answer.\n const [confirmedAbsentId, setConfirmedAbsentId] = useState<string | null>(null);\n const [failedId, setFailedId] = useState<string | null>(null);\n // Bumped by the \"Try again\" button to re-run the lookup effect after a failure.\n const [retryNonce, setRetryNonce] = useState(0);\n const retryCount = useRef(0);\n\n useEffect(() => {\n if (!id || !isUuid) return;\n\n retryCount.current = 0;\n let cancelled = false;\n const targetVersion = version ?? 'v1';\n\n const attempt = () => {\n // Query directly (not via fetchWorkflow, which swallows Apollo errors and\n // returns null) so we can tell a genuine \"no such record\" apart from a\n // transient lookup failure. Treating a failure as not-found would re-open\n // the builder with the record id and recreate a phantom 0-node definition.\n client\n .query<WorkflowKeyLookup>({\n query: GetWorkflowDocument,\n variables: { id },\n fetchPolicy: 'network-only',\n })\n .then((result) => {\n if (cancelled) return;\n const record = result.data?.workflow;\n if (record) {\n // The UUID IS a BigConsole record.\n if (record.key && record.key !== id) {\n // Open the builder under its real key (where the definition + nodes\n // live). encodeURIComponent guards against URL-unsafe key chars.\n // Replace history so the resolver doesn't trap the back button.\n navigate(`/workflows/workflow/${encodeURIComponent(record.key)}/${targetVersion}`, {\n replace: true,\n });\n } else {\n // Record exists but has no usable key — open a blank builder rather\n // than reusing the record UUID as the key (which would phantom).\n navigate('/workflows/builder', { replace: true });\n }\n } else {\n // Query succeeded with no record → a genuine new-workflow id.\n setConfirmedAbsentId(id);\n }\n })\n .catch(() => {\n if (cancelled) return;\n if (retryCount.current < 1) {\n // On a cold full-page load the auth/workspace context may not be\n // bootstrapped yet. Retry once before giving up.\n retryCount.current += 1;\n setTimeout(() => {\n if (!cancelled) attempt();\n }, BOOTSTRAP_RETRY_DELAY_MS);\n } else {\n // Lookup failed — do NOT assume create mode (the id may be a record);\n // surface a retry instead of risking a phantom definition.\n setFailedId(id);\n }\n });\n };\n\n attempt();\n\n return () => {\n cancelled = true;\n };\n }, [id, isUuid, version, client, navigate, retryNonce]);\n\n // Slug keys, and UUIDs confirmed not to be records, render the builder.\n if (!isUuid || confirmedAbsentId === id) {\n return <SDKWorkflowBuilderPage />;\n }\n\n // A lookup that ultimately failed: surface a retry rather than silently\n // opening the builder with what may be a record id.\n if (failedId === id) {\n return (\n <div className=\"p-6 flex flex-col items-center justify-center min-h-[400px] text-center gap-4\">\n <p className=\"text-sm text-text-secondary\">Couldn&apos;t load this workflow. Please try again.</p>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n setFailedId(null);\n setRetryNonce((n) => n + 1);\n }}\n className=\"px-4 py-2 text-sm font-medium text-action-primary-fg bg-action-primary-bg hover:bg-action-primary-bgHover rounded-md transition-colors\"\n >\n Try again\n </button>\n <button\n type=\"button\"\n onClick={() => navigate('/workflows')}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken hover:bg-border-default rounded-md transition-colors\"\n >\n Back to Workflows\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Spinner className=\"h-8 w-8\" />\n </div>\n );\n});\n\nexport function BigConsoleRoutes(props: BigConsoleRootProps) {\n if (props.routePage === 'workflow-feeds')\n return (\n <Suspense fallback={<PageLoader />}>\n <WorkflowsPage />\n </Suspense>\n );\n if (props.routePage === 'workflow-detail')\n return (\n <Suspense fallback={<PageLoader />}>\n <WorkflowViewPage />\n </Suspense>\n );\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route path=\"/\" element={<OverviewPage />} />\n <Route path=\"/dashboards\" element={<DashboardsPage />} />\n <Route path=\"/dashboards/:dashboardId\" element={<DashboardViewPage />} />\n <Route path=\"/dashboards/:dashboardId/builder\" element={<DashboardBuilderPage />} />\n <Route path=\"/datasources\" element={<DataSourcesPage />} />\n <Route path=\"/insights\" element={<InsightsPage />} />\n <Route path=\"/settings\" element={<SettingsPage />} />\n <Route path=\"/widgets/demo\" element={<WidgetDemoPage />} />\n {/* DataSink Routes */}\n <Route path=\"/datasinks\" element={<DataSinksPage />} />\n <Route path=\"/datasinks/new\" element={<DataSinkBuilderPage />} />\n <Route path=\"/datasinks/:dataSinkId\" element={<DataSinkViewPage />} />\n <Route path=\"/datasinks/:dataSinkId/edit\" element={<DataSinkBuilderPage />} />\n {/* Parser Routes */}\n <Route path=\"/parsers\" element={<DataParsersPage />} />\n <Route path=\"/parsers/new\" element={<ParserBuilderPage />} />\n <Route path=\"/parsers/:parserId\" element={<ParserViewPage />} />\n <Route path=\"/parsers/:parserId/edit\" element={<ParserBuilderPage />} />\n {/* Dashboard-scoped Parser Routes */}\n <Route path=\"/dashboards/:consoleId/parsers\" element={<DataParsersPage />} />\n <Route path=\"/dashboards/:consoleId/parsers/new\" element={<ParserBuilderPage />} />\n <Route path=\"/dashboards/:consoleId/parsers/:parserId\" element={<ParserViewPage />} />\n <Route path=\"/dashboards/:consoleId/parsers/:parserId/edit\" element={<ParserBuilderPage />} />\n {/* Workflow Routes — list/view use BigConsole-native pages (query bigconsole-svc).\n All static routes are grouped before the dynamic :workflowId catch-all.\n React Router v6 prioritizes static segments regardless of declaration order,\n but keeping them above the param routes makes intent unambiguous for maintainers. */}\n <Route path=\"/workflows\" element={<WorkflowsPage />} />\n <Route path=\"/workflows/feeds\" element={<WorkflowsPage />} />\n <Route path=\"/workflows/details/:workflowId\" element={<WorkflowViewPage />} />\n <Route path=\"/workflows/list\" element={<WorkflowsPage />} />\n {/* New workflow — redirect to UUID-based URL (matches FluidGrids pattern) */}\n <Route path=\"/workflows/new\" element={<WorkflowNewRedirect />} />\n {/* SDK visual workflow builder — design existing workflows */}\n <Route path=\"/workflows/builder\" element={<SDKWorkflowBuilderPage />} />\n {/* All parameterised builder routes go through WorkflowBuilderResolver so a\n record-id `:id` is resolved to its workflow key first (slugs/new-workflow\n UUIDs pass straight through); otherwise the SDK opens an empty canvas and\n creates a phantom 0-node definition keyed by the record id. */}\n <Route path=\"/workflows/builder/:id/:version\" element={<WorkflowBuilderResolver />} />\n <Route path=\"/workflows/workflow/:id/:version\" element={<WorkflowBuilderResolver />} />\n {/* SDK sub-pages (runs, history, templates, nodes, settings) */}\n <Route path=\"/workflows/runs\" element={<ExecutionsListPage />} />\n <Route path=\"/workflows/runs/:runId\" element={<ExecutionDetailPage />} />\n <Route path=\"/workflows/history\" element={<HistoryPage />} />\n <Route path=\"/workflows/templates\" element={<TemplatesPage />} />\n <Route path=\"/workflows/nodes\" element={<NodesPage />} />\n <Route path=\"/workflows/settings\" element={<WorkflowSettingsPage />} />\n {/* Dynamic routes — :workflowId catch-all AFTER all static segments */}\n <Route path=\"/workflows/:workflowId\" element={<WorkflowViewPage />} />\n <Route path=\"/workflows/:workflowId/edit\" element={<WorkflowEditBridge />} />\n {/* Support SDK's navigation pattern (without /workflows/ prefix) — also\n resolves record-id → key via WorkflowBuilderResolver. */}\n <Route path=\"/workflow/:id/:version\" element={<WorkflowBuilderResolver />} />\n {/* Redirect /list to /workflows/list (SDK uses relative navigation) */}\n <Route path=\"/list\" element={<Navigate to=\"/bigconsole/workflows/list\" replace />} />\n {/* Pipeline Routes */}\n <Route path=\"/pipelines\" element={<PipelinesPage />} />\n <Route path=\"/pipelines/new\" element={<PipelineBuilderPage />} />\n <Route path=\"/pipelines/:pipelineId\" element={<PipelineViewPage />} />\n <Route path=\"/pipelines/:pipelineId/edit\" element={<PipelineBuilderPage />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DrilldownDashboardRenderer.d.ts","sourceRoot":"","sources":["../../../src/bigconsole/components/DrilldownDashboardRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,EAA6B,MAAM,OAAO,CAAC;AAa3D,MAAM,WAAW,+BAA+B;IAC9C,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AA8ED,eAAO,MAAM,0BAA0B,EAAE,EAAE,CAAC,+BAA+B,CAgQ1E,CAAC;AAmBF,eAAe,0BAA0B,CAAC"}
1
+ {"version":3,"file":"DrilldownDashboardRenderer.d.ts","sourceRoot":"","sources":["../../../src/bigconsole/components/DrilldownDashboardRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,EAA6B,MAAM,OAAO,CAAC;AAc3D,MAAM,WAAW,+BAA+B;IAC9C,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AA8ED,eAAO,MAAM,0BAA0B,EAAE,EAAE,CAAC,+BAA+B,CAgQ1E,CAAC;AAmBF,eAAe,0BAA0B,CAAC"}
@@ -4,11 +4,12 @@ import "./common/index.js";
4
4
  import { mapFromFederationWidgetType as i } from "../utils/widgetTypeMapping.js";
5
5
  import { MODAL_TARGET_PAGE_PARAM as a } from "../hooks/useDrilldown.js";
6
6
  import o from "./widgets/WidgetWrapper.js";
7
- import { memo as s, useEffect as c, useState as l } from "react";
8
- import { useApolloClient as u } from "@apollo/client/react";
9
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
7
+ import { getVisibleDrilldownParams as s } from "../utils/drilldownParams.js";
8
+ import { memo as c, useEffect as l, useState as u } from "react";
9
+ import { useApolloClient as d } from "@apollo/client/react";
10
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
10
11
  //#region src/bigconsole/components/DrilldownDashboardRenderer.tsx
11
- function p(e, t) {
12
+ function m(e, t) {
12
13
  let n = t * 4, r = {
13
14
  x: 0,
14
15
  y: n,
@@ -48,7 +49,7 @@ function p(e, t) {
48
49
  updatedAt: e.updatedAt || (/* @__PURE__ */ new Date()).toISOString()
49
50
  };
50
51
  }
51
- function m(e, t) {
52
+ function h(e, t) {
52
53
  let n = {
53
54
  x: 0,
54
55
  y: t * 4,
@@ -64,20 +65,20 @@ function m(e, t) {
64
65
  positionHeight: 4
65
66
  };
66
67
  }
67
- var h = s(function({ dashboardId: i, params: o, live: s = !1, refreshRevision: h = 0 }) {
68
- let _ = u(), [v, y] = l(!0), [b, x] = l(null), [S, C] = l(null), [w, T] = l([]);
69
- if (c(() => {
68
+ var g = c(function({ dashboardId: i, params: o, live: c = !1, refreshRevision: g = 0 }) {
69
+ let v = d(), [y, b] = u(!0), [x, S] = u(null), [C, w] = u(null), [T, E] = u([]);
70
+ if (l(() => {
70
71
  if (!i) {
71
- y(!1);
72
+ b(!1);
72
73
  return;
73
74
  }
74
75
  let n = !1, r = !1;
75
- y(!0);
76
+ b(!0);
76
77
  async function a() {
77
78
  if (!r) {
78
- r = !0, x(null);
79
+ r = !0, S(null);
79
80
  try {
80
- let r = await _.query({
81
+ let r = await v.query({
81
82
  query: e,
82
83
  variables: { id: i },
83
84
  fetchPolicy: "network-only"
@@ -85,35 +86,35 @@ var h = s(function({ dashboardId: i, params: o, live: s = !1, refreshRevision: h
85
86
  if (n) return;
86
87
  let a = r.data?.getDashboard;
87
88
  if (!a) {
88
- x("Dashboard not found"), y(!1);
89
+ S("Dashboard not found"), b(!1);
89
90
  return;
90
91
  }
91
92
  let o = a.pages?.edges?.map((e) => ({
92
93
  id: e.node.id,
93
94
  name: e.node.name || "Page 1"
94
95
  })) || [];
95
- C({
96
+ w({
96
97
  id: a.id,
97
98
  name: a.name,
98
99
  description: a.description,
99
100
  pages: o
100
101
  });
101
- let s = await _.query({
102
+ let s = await v.query({
102
103
  query: t,
103
104
  variables: { dashboardId: i },
104
105
  fetchPolicy: "network-only"
105
106
  });
106
107
  if (n) return;
107
- T((s.data?.listWidgetsByDashboard || []).map((e, t) => p(e, t)));
108
+ E((s.data?.listWidgetsByDashboard || []).map((e, t) => m(e, t)));
108
109
  } catch (e) {
109
- n || x(e instanceof Error ? e.message : "Failed to load dashboard");
110
+ n || S(e instanceof Error ? e.message : "Failed to load dashboard");
110
111
  } finally {
111
- r = !1, n || y(!1);
112
+ r = !1, n || b(!1);
112
113
  }
113
114
  }
114
115
  }
115
116
  a();
116
- let o = s ? window.setInterval(() => {
117
+ let o = c ? window.setInterval(() => {
117
118
  document.visibilityState === "visible" && a();
118
119
  }, 4e3) : void 0;
119
120
  return () => {
@@ -121,35 +122,35 @@ var h = s(function({ dashboardId: i, params: o, live: s = !1, refreshRevision: h
121
122
  };
122
123
  }, [
123
124
  i,
124
- _,
125
- s,
126
- h
127
- ]), v) return /* @__PURE__ */ d("div", {
125
+ v,
126
+ c,
127
+ g
128
+ ]), y) return /* @__PURE__ */ f("div", {
128
129
  className: "flex items-center justify-center h-full",
129
- children: /* @__PURE__ */ f("div", {
130
+ children: /* @__PURE__ */ p("div", {
130
131
  className: "flex flex-col items-center gap-3",
131
- children: [/* @__PURE__ */ d("div", { className: "w-8 h-8 border-2 border-action-primary-bg border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ d("p", {
132
+ children: [/* @__PURE__ */ f("div", { className: "w-8 h-8 border-2 border-action-primary-bg border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ f("p", {
132
133
  className: "text-sm text-text-secondary",
133
134
  children: "Loading dashboard..."
134
135
  })]
135
136
  })
136
137
  });
137
- if (b) return /* @__PURE__ */ d("div", {
138
+ if (x) return /* @__PURE__ */ f("div", {
138
139
  className: "flex h-full items-center justify-center",
139
140
  role: "alert",
140
- children: /* @__PURE__ */ d(n, {
141
+ children: /* @__PURE__ */ f(n, {
141
142
  headingLevel: 3,
142
143
  tone: "danger",
143
144
  className: "w-full max-w-md",
144
145
  "data-testid": "drilldown-error",
145
146
  title: "Could not load this dashboard",
146
- description: b,
147
- icon: /* @__PURE__ */ d("svg", {
147
+ description: x,
148
+ icon: /* @__PURE__ */ f("svg", {
148
149
  className: "h-icon-md w-icon-md",
149
150
  fill: "none",
150
151
  stroke: "currentColor",
151
152
  viewBox: "0 0 24 24",
152
- children: /* @__PURE__ */ d("path", {
153
+ children: /* @__PURE__ */ f("path", {
153
154
  strokeLinecap: "round",
154
155
  strokeLinejoin: "round",
155
156
  strokeWidth: 1.5,
@@ -158,69 +159,69 @@ var h = s(function({ dashboardId: i, params: o, live: s = !1, refreshRevision: h
158
159
  })
159
160
  })
160
161
  });
161
- if (!S || w.length === 0) return /* @__PURE__ */ d("div", {
162
+ if (!C || T.length === 0) return /* @__PURE__ */ f("div", {
162
163
  className: "flex items-center justify-center h-full",
163
- children: /* @__PURE__ */ f("div", {
164
+ children: /* @__PURE__ */ p("div", {
164
165
  className: "flex flex-col items-center gap-3 text-center",
165
- children: [/* @__PURE__ */ d("svg", {
166
+ children: [/* @__PURE__ */ f("svg", {
166
167
  className: "w-12 h-12 text-text-muted",
167
168
  fill: "none",
168
169
  stroke: "currentColor",
169
170
  viewBox: "0 0 24 24",
170
- children: /* @__PURE__ */ d("path", {
171
+ children: /* @__PURE__ */ f("path", {
171
172
  strokeLinecap: "round",
172
173
  strokeLinejoin: "round",
173
174
  strokeWidth: 1.5,
174
175
  d: "M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"
175
176
  })
176
- }), /* @__PURE__ */ d("p", {
177
+ }), /* @__PURE__ */ f("p", {
177
178
  className: "text-sm text-text-secondary",
178
- children: S ? "This dashboard has no widgets" : "Dashboard not found"
179
+ children: C ? "This dashboard has no widgets" : "Dashboard not found"
179
180
  })]
180
181
  })
181
182
  });
182
- let E = Object.entries(o).filter(([e]) => !e.startsWith("__")), D = o[a], O = S.pages.find((e) => e.id === D) ?? S.pages[0] ?? null, k = (O ? w.filter((e) => !e.pageId || e.pageId === O.id) : w).map((e, t) => m(e, t));
183
- return /* @__PURE__ */ f(r, {
183
+ let D = s(o), O = o[a], k = C.pages.find((e) => e.id === O) ?? C.pages[0] ?? null, A = (k ? T.filter((e) => !e.pageId || e.pageId === k.id) : T).map((e, t) => h(e, t));
184
+ return /* @__PURE__ */ p(r, {
184
185
  className: "w-full",
185
186
  children: [
186
- /* @__PURE__ */ d(n, {
187
+ /* @__PURE__ */ f(n, {
187
188
  emphasis: "bare",
188
189
  padding: "none",
189
190
  headingLevel: 3,
190
- title: S.name,
191
- description: S.pages.length > 1 && O ? /* @__PURE__ */ d("span", {
191
+ title: C.name,
192
+ description: C.pages.length > 1 && k ? /* @__PURE__ */ f("span", {
192
193
  "data-testid": "drilldown-dashboard-page",
193
- children: O.name
194
- }) : S.description,
194
+ children: k.name
195
+ }) : C.description,
195
196
  "data-testid": "drilldown-dashboard-header"
196
197
  }),
197
- E.length > 0 && /* @__PURE__ */ d(n, {
198
+ D.length > 0 && /* @__PURE__ */ f(n, {
198
199
  emphasis: "muted",
199
200
  padding: "compact",
200
201
  headingLevel: 3,
201
202
  title: "Filtered by",
202
203
  "data-testid": "drilldown-params",
203
204
  bodyClassName: "flex flex-wrap gap-control-gap",
204
- children: E.map(([e, t]) => /* @__PURE__ */ f("span", {
205
+ children: D.map(([e, t]) => /* @__PURE__ */ p("span", {
205
206
  className: "inline-flex items-center rounded-pill bg-bg-surface px-2 py-1 text-xs text-text-secondary",
206
- children: [/* @__PURE__ */ f("span", {
207
+ children: [/* @__PURE__ */ p("span", {
207
208
  className: "font-medium text-text-primary",
208
209
  children: [e, ":"]
209
- }), /* @__PURE__ */ d("span", {
210
+ }), /* @__PURE__ */ f("span", {
210
211
  className: "ml-1",
211
212
  children: typeof t == "object" && t ? JSON.stringify(t) : String(t)
212
213
  })]
213
214
  }, e))
214
215
  }),
215
- /* @__PURE__ */ f("div", {
216
+ /* @__PURE__ */ p("div", {
216
217
  className: "flex flex-col gap-form-gap",
217
- children: [k.length === 0 && /* @__PURE__ */ d("p", {
218
+ children: [A.length === 0 && /* @__PURE__ */ f("p", {
218
219
  className: "text-sm text-text-secondary",
219
220
  "data-testid": "drilldown-page-empty",
220
221
  children: "This page has no widgets"
221
- }), k.map((e) => {
222
+ }), A.map((e) => {
222
223
  let t = e.config?._internalWidgetType, n = e.type;
223
- return /* @__PURE__ */ d("div", {
224
+ return /* @__PURE__ */ f("div", {
224
225
  className: "min-w-0 overflow-hidden rounded-card border border-[var(--color-border-subtle)] bg-bg-surface",
225
226
  style: n === "LINE_CHART" || n === "chart" || t === "chart" || t === "funnel_chart" ? { height: "clamp(220px, 45vh, 350px)" } : n === "TABLE" || n === "table" || t === "table" || t === "list" || t === "pivot_table" ? {
226
227
  minHeight: "min(250px, 40vh)",
@@ -229,7 +230,7 @@ var h = s(function({ dashboardId: i, params: o, live: s = !1, refreshRevision: h
229
230
  minHeight: "min(120px, 25vh)",
230
231
  maxHeight: "min(300px, 50vh)"
231
232
  },
232
- children: /* @__PURE__ */ d(g, {
233
+ children: /* @__PURE__ */ f(_, {
233
234
  widget: e,
234
235
  filterValues: o
235
236
  })
@@ -238,10 +239,10 @@ var h = s(function({ dashboardId: i, params: o, live: s = !1, refreshRevision: h
238
239
  })
239
240
  ]
240
241
  });
241
- }), g = s(function({ widget: e, filterValues: t }) {
242
- return /* @__PURE__ */ d("div", {
242
+ }), _ = c(function({ widget: e, filterValues: t }) {
243
+ return /* @__PURE__ */ f("div", {
243
244
  className: "h-full [&_[data-widget-id]]:border-transparent [&_[data-widget-id]:hover]:border-transparent",
244
- children: /* @__PURE__ */ d(o, {
245
+ children: /* @__PURE__ */ f(o, {
245
246
  widget: e,
246
247
  isLoading: !1,
247
248
  error: null,
@@ -250,6 +251,6 @@ var h = s(function({ dashboardId: i, params: o, live: s = !1, refreshRevision: h
250
251
  });
251
252
  });
252
253
  //#endregion
253
- export { h as default };
254
+ export { g as default };
254
255
 
255
256
  //# sourceMappingURL=DrilldownDashboardRenderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DrilldownDashboardRenderer.js","names":[],"sources":["../../../src/bigconsole/components/DrilldownDashboardRenderer.tsx"],"sourcesContent":["/**\n * DrilldownDashboardRenderer Component\n *\n * Renders a dashboard inside the DrilldownModal.\n * Fetches dashboard data and displays the target page's widgets (the page named\n * by the drilldown, else the first page) with passed parameters (BOFF-7625).\n */\n\nimport { type FC, memo, useEffect, useState } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport type { Widget } from '../types';\nimport { WidgetWrapper } from './widgets/WidgetWrapper';\nimport { Section, SectionStack } from './common';\nimport { ListWidgetsByDashboardDocument, GetDashboardDocument } from '../../generated/wspace-operations';\nimport { mapFromFederationWidgetType } from '../utils/widgetTypeMapping';\nimport { MODAL_TARGET_PAGE_PARAM } from '../hooks/useDrilldown';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DrilldownDashboardRendererProps {\n /** Target dashboard ID to render */\n dashboardId: string;\n live?: boolean;\n refreshRevision?: number;\n /** Parameters passed from drilldown (can be used for filtering) */\n params: Record<string, unknown>;\n}\n\ninterface DashboardData {\n id: string;\n name: string;\n description?: string;\n pages: Array<{\n id: string;\n name: string;\n }>;\n}\n\n// ============================================================================\n// Helper: Normalize widget from GraphQL\n// ============================================================================\n\nfunction normalizeWidget(raw: Record<string, unknown>, index: number): Widget {\n // For drilldown modal, stack widgets vertically with compact sizing\n const posX = 0;\n const posY = index * 4; // Stack vertically, 4 row units per widget\n const posW = 12; // Full width\n const posH = 4; // Better height for widget content\n\n const position = { x: posX, y: posY, width: posW, height: posH };\n\n // Get the config object\n const config = (raw.config as Record<string, unknown>) || {};\n\n // Map widget type correctly: check _internalWidgetType first, then map from federation type\n // This is critical — federation types like 'KPI' must be mapped to internal types like 'metric_card'\n const internalType = config._internalWidgetType as string | undefined;\n const widgetType = internalType || mapFromFederationWidgetType((raw.type as string) || 'KPI');\n\n return {\n id: (raw.id as string) ?? '',\n pageId: (raw.pageId as string) || '',\n dashboardId: raw.dashboardId as string | undefined,\n type: widgetType,\n title: (raw.title as string) || 'Untitled Widget',\n renderer: raw.renderer || 'BIGCONSOLE',\n template: raw.template || null,\n dataSinkId: raw.dataSinkId || null,\n datasetId: raw.datasetId || null,\n parserId: raw.parserId || null,\n parserRules: raw.parserRules || null,\n config: config,\n position: position,\n positionX: posX,\n positionY: posY,\n positionWidth: posW,\n positionHeight: posH,\n positionResponsive: raw.positionResponsive as Widget['positionResponsive'],\n rowOrder: (raw.rowOrder as number | null) ?? null,\n refreshInterval: raw.refreshInterval,\n lastRefreshedAt: raw.lastRefreshedAt,\n cacheTTL: (raw.cacheTTL as number | null) ?? null,\n drilldown: raw.drilldown as Widget['drilldown'],\n actions: (raw.actions as Widget['actions']) || [],\n translations: (raw.translations as Widget['translations']) || [],\n metadata: raw.metadata as Record<string, unknown> | undefined,\n context: raw.context,\n // Include widget data from backend (critical for showing real data in modal)\n data: raw.data || null,\n createdAt: (raw.createdAt as string) || new Date().toISOString(),\n updatedAt: (raw.updatedAt as string) || new Date().toISOString(),\n } as Widget;\n}\n\n/** Place a widget at a given slot of the modal's single-column stack. */\nfunction normalizeStacking(widget: Widget, index: number): Widget {\n const position = { x: 0, y: index * 4, width: 12, height: 4 };\n return { ...widget, position, positionX: 0, positionY: position.y, positionWidth: 12, positionHeight: 4 };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const DrilldownDashboardRenderer: FC<DrilldownDashboardRendererProps> = memo(\n function DrilldownDashboardRenderer({ dashboardId, params, live = false, refreshRevision = 0 }) {\n const apolloClient = useApolloClient();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [dashboard, setDashboard] = useState<DashboardData | null>(null);\n const [widgets, setWidgets] = useState<Widget[]>([]);\n\n // Fetch dashboard and widgets — only when dashboardId is provided\n useEffect(() => {\n if (!dashboardId) {\n setLoading(false);\n return;\n }\n\n let cancelled = false;\n let fetching = false;\n setLoading(true);\n async function fetchData() {\n if (fetching) return;\n fetching = true;\n setError(null);\n\n try {\n // Fetch dashboard info\n interface DashboardQueryResult {\n getDashboard: {\n id: string;\n name: string;\n description?: string;\n pages?: {\n edges?: Array<{ node: { id: string; name?: string } }>;\n };\n } | null;\n }\n\n const dashboardResult = await apolloClient.query<DashboardQueryResult>({\n query: GetDashboardDocument,\n variables: { id: dashboardId },\n fetchPolicy: 'network-only',\n });\n\n if (cancelled) return;\n const dashboardData = dashboardResult.data?.getDashboard;\n if (!dashboardData) {\n setError('Dashboard not found');\n setLoading(false);\n return;\n }\n\n // Normalize dashboard\n const pages =\n dashboardData.pages?.edges?.map((edge) => ({\n id: edge.node.id,\n name: edge.node.name || 'Page 1',\n })) || [];\n\n setDashboard({\n id: dashboardData.id,\n name: dashboardData.name,\n description: dashboardData.description,\n pages,\n });\n\n // Fetch widgets for the dashboard\n const widgetsResult = await apolloClient.query<{ listWidgetsByDashboard: Record<string, unknown>[] }>({\n query: ListWidgetsByDashboardDocument,\n variables: { dashboardId },\n fetchPolicy: 'network-only',\n });\n\n if (cancelled) return;\n const widgetsList = widgetsResult.data?.listWidgetsByDashboard || [];\n setWidgets(widgetsList.map((w, i) => normalizeWidget(w, i)));\n } catch (err) {\n if (!cancelled) setError(err instanceof Error ? err.message : 'Failed to load dashboard');\n } finally {\n fetching = false;\n if (!cancelled) setLoading(false);\n }\n }\n\n void fetchData();\n const interval = live\n ? window.setInterval(() => {\n if (document.visibilityState === 'visible') void fetchData();\n }, 4000)\n : undefined;\n return () => {\n cancelled = true;\n if (interval !== undefined) window.clearInterval(interval);\n };\n }, [dashboardId, apolloClient, live, refreshRevision]);\n\n // Loading state\n if (loading) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"flex flex-col items-center gap-3\">\n <div className=\"w-8 h-8 border-2 border-action-primary-bg border-t-transparent rounded-full animate-spin\" />\n <p className=\"text-sm text-text-secondary\">Loading dashboard...</p>\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex h-full items-center justify-center\" role=\"alert\">\n <Section\n headingLevel={3}\n tone=\"danger\"\n className=\"w-full max-w-md\"\n data-testid=\"drilldown-error\"\n title=\"Could not load this dashboard\"\n description={error}\n icon={\n <svg className=\"h-icon-md w-icon-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n }\n />\n </div>\n );\n }\n\n // Empty state\n if (!dashboard || widgets.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"flex flex-col items-center gap-3 text-center\">\n <svg className=\"w-12 h-12 text-text-muted\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z\"\n />\n </svg>\n <p className=\"text-sm text-text-secondary\">\n {dashboard ? 'This dashboard has no widgets' : 'Dashboard not found'}\n </p>\n </div>\n </div>\n );\n }\n\n const visibleParams = Object.entries(params).filter(([key]) => !key.startsWith('__'));\n\n // Show one page: the drilldown's target page when it still exists, else the\n // first page. Widgets without a page id (older payloads) are always shown.\n const requestedPageId = params[MODAL_TARGET_PAGE_PARAM];\n const activePage = dashboard.pages.find((page) => page.id === requestedPageId) ?? dashboard.pages[0] ?? null;\n const pageWidgets = activePage\n ? widgets.filter((widget) => !widget.pageId || widget.pageId === activePage.id)\n : widgets;\n // Re-flow the page's widgets top to bottom (the stacking was computed over\n // the whole dashboard).\n const stackedWidgets = pageWidgets.map((widget, index) => normalizeStacking(widget, index));\n\n return (\n <SectionStack className=\"w-full\">\n {/* Which board you drilled into — identity, not content. */}\n <Section\n emphasis=\"bare\"\n padding=\"none\"\n headingLevel={3}\n title={dashboard.name}\n description={\n dashboard.pages.length > 1 && activePage ? (\n <span data-testid=\"drilldown-dashboard-page\">{activePage.name}</span>\n ) : (\n dashboard.description\n )\n }\n data-testid=\"drilldown-dashboard-header\"\n />\n\n {/* The filter context you arrived with: supporting detail, recessed. */}\n {visibleParams.length > 0 && (\n <Section\n emphasis=\"muted\"\n padding=\"compact\"\n headingLevel={3}\n title=\"Filtered by\"\n data-testid=\"drilldown-params\"\n bodyClassName=\"flex flex-wrap gap-control-gap\"\n >\n {visibleParams.map(([key, value]) => (\n <span\n key={key}\n className=\"inline-flex items-center rounded-pill bg-bg-surface px-2 py-1 text-xs text-text-secondary\"\n >\n <span className=\"font-medium text-text-primary\">{key}:</span>\n <span className=\"ml-1\">\n {typeof value === 'object' && value !== null ? JSON.stringify(value) : String(value)}\n </span>\n </span>\n ))}\n </Section>\n )}\n\n {/* Widgets List - simple vertical layout for modal */}\n <div className=\"flex flex-col gap-form-gap\">\n {stackedWidgets.length === 0 && (\n <p className=\"text-sm text-text-secondary\" data-testid=\"drilldown-page-empty\">\n This page has no widgets\n </p>\n )}\n {stackedWidgets.map((widget) => {\n // Chart widgets (LINE_CHART / chart) need explicit pixel height because\n // Recharts ResponsiveContainer height=\"100%\" requires a parent with\n // a definite height — minHeight alone doesn't work.\n const internalType = (widget.config as Record<string, unknown>)?._internalWidgetType as string | undefined;\n const widgetType = widget.type as string;\n const isChartWidget =\n widgetType === 'LINE_CHART' ||\n widgetType === 'chart' ||\n internalType === 'chart' ||\n internalType === 'funnel_chart';\n const isTableWidget =\n widgetType === 'TABLE' ||\n widgetType === 'table' ||\n internalType === 'table' ||\n internalType === 'list' ||\n internalType === 'pivot_table';\n\n // Charts need an explicit height (Recharts' ResponsiveContainer needs a\n // definite parent). Clamping against the viewport keeps a 350px chart\n // plus a 500px table from filling a phone screen twice over.\n const heightStyle = isChartWidget\n ? { height: 'clamp(220px, 45vh, 350px)' }\n : isTableWidget\n ? { minHeight: 'min(250px, 40vh)', maxHeight: 'min(500px, 65vh)' }\n : { minHeight: 'min(120px, 25vh)', maxHeight: 'min(300px, 50vh)' };\n\n return (\n <div\n key={widget.id}\n className=\"min-w-0 overflow-hidden rounded-card border border-[var(--color-border-subtle)] bg-bg-surface\"\n style={heightStyle}\n >\n <WidgetInModal widget={widget} filterValues={params} />\n </div>\n );\n })}\n </div>\n </SectionStack>\n );\n }\n);\n\n// ============================================================================\n// Widget In Modal Component\n// ============================================================================\n\ninterface WidgetInModalProps {\n widget: Widget;\n filterValues?: Record<string, unknown>;\n}\n\nconst WidgetInModal: FC<WidgetInModalProps> = memo(function WidgetInModal({ widget, filterValues }) {\n return (\n <div className=\"h-full [&_[data-widget-id]]:border-transparent [&_[data-widget-id]:hover]:border-transparent\">\n <WidgetWrapper widget={widget} isLoading={false} error={null} filterValues={filterValues} />\n </div>\n );\n});\n\nexport default DrilldownDashboardRenderer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"DrilldownDashboardRenderer.js","names":[],"sources":["../../../src/bigconsole/components/DrilldownDashboardRenderer.tsx"],"sourcesContent":["/**\n * DrilldownDashboardRenderer Component\n *\n * Renders a dashboard inside the DrilldownModal.\n * Fetches dashboard data and displays the target page's widgets (the page named\n * by the drilldown, else the first page) with passed parameters (BOFF-7625).\n */\n\nimport { type FC, memo, useEffect, useState } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport type { Widget } from '../types';\nimport { WidgetWrapper } from './widgets/WidgetWrapper';\nimport { Section, SectionStack } from './common';\nimport { ListWidgetsByDashboardDocument, GetDashboardDocument } from '../../generated/wspace-operations';\nimport { mapFromFederationWidgetType } from '../utils/widgetTypeMapping';\nimport { MODAL_TARGET_PAGE_PARAM } from '../hooks/useDrilldown';\nimport { getVisibleDrilldownParams } from '../utils/drilldownParams';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DrilldownDashboardRendererProps {\n /** Target dashboard ID to render */\n dashboardId: string;\n live?: boolean;\n refreshRevision?: number;\n /** Parameters passed from drilldown (can be used for filtering) */\n params: Record<string, unknown>;\n}\n\ninterface DashboardData {\n id: string;\n name: string;\n description?: string;\n pages: Array<{\n id: string;\n name: string;\n }>;\n}\n\n// ============================================================================\n// Helper: Normalize widget from GraphQL\n// ============================================================================\n\nfunction normalizeWidget(raw: Record<string, unknown>, index: number): Widget {\n // For drilldown modal, stack widgets vertically with compact sizing\n const posX = 0;\n const posY = index * 4; // Stack vertically, 4 row units per widget\n const posW = 12; // Full width\n const posH = 4; // Better height for widget content\n\n const position = { x: posX, y: posY, width: posW, height: posH };\n\n // Get the config object\n const config = (raw.config as Record<string, unknown>) || {};\n\n // Map widget type correctly: check _internalWidgetType first, then map from federation type\n // This is critical — federation types like 'KPI' must be mapped to internal types like 'metric_card'\n const internalType = config._internalWidgetType as string | undefined;\n const widgetType = internalType || mapFromFederationWidgetType((raw.type as string) || 'KPI');\n\n return {\n id: (raw.id as string) ?? '',\n pageId: (raw.pageId as string) || '',\n dashboardId: raw.dashboardId as string | undefined,\n type: widgetType,\n title: (raw.title as string) || 'Untitled Widget',\n renderer: raw.renderer || 'BIGCONSOLE',\n template: raw.template || null,\n dataSinkId: raw.dataSinkId || null,\n datasetId: raw.datasetId || null,\n parserId: raw.parserId || null,\n parserRules: raw.parserRules || null,\n config: config,\n position: position,\n positionX: posX,\n positionY: posY,\n positionWidth: posW,\n positionHeight: posH,\n positionResponsive: raw.positionResponsive as Widget['positionResponsive'],\n rowOrder: (raw.rowOrder as number | null) ?? null,\n refreshInterval: raw.refreshInterval,\n lastRefreshedAt: raw.lastRefreshedAt,\n cacheTTL: (raw.cacheTTL as number | null) ?? null,\n drilldown: raw.drilldown as Widget['drilldown'],\n actions: (raw.actions as Widget['actions']) || [],\n translations: (raw.translations as Widget['translations']) || [],\n metadata: raw.metadata as Record<string, unknown> | undefined,\n context: raw.context,\n // Include widget data from backend (critical for showing real data in modal)\n data: raw.data || null,\n createdAt: (raw.createdAt as string) || new Date().toISOString(),\n updatedAt: (raw.updatedAt as string) || new Date().toISOString(),\n } as Widget;\n}\n\n/** Place a widget at a given slot of the modal's single-column stack. */\nfunction normalizeStacking(widget: Widget, index: number): Widget {\n const position = { x: 0, y: index * 4, width: 12, height: 4 };\n return { ...widget, position, positionX: 0, positionY: position.y, positionWidth: 12, positionHeight: 4 };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const DrilldownDashboardRenderer: FC<DrilldownDashboardRendererProps> = memo(\n function DrilldownDashboardRenderer({ dashboardId, params, live = false, refreshRevision = 0 }) {\n const apolloClient = useApolloClient();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [dashboard, setDashboard] = useState<DashboardData | null>(null);\n const [widgets, setWidgets] = useState<Widget[]>([]);\n\n // Fetch dashboard and widgets — only when dashboardId is provided\n useEffect(() => {\n if (!dashboardId) {\n setLoading(false);\n return;\n }\n\n let cancelled = false;\n let fetching = false;\n setLoading(true);\n async function fetchData() {\n if (fetching) return;\n fetching = true;\n setError(null);\n\n try {\n // Fetch dashboard info\n interface DashboardQueryResult {\n getDashboard: {\n id: string;\n name: string;\n description?: string;\n pages?: {\n edges?: Array<{ node: { id: string; name?: string } }>;\n };\n } | null;\n }\n\n const dashboardResult = await apolloClient.query<DashboardQueryResult>({\n query: GetDashboardDocument,\n variables: { id: dashboardId },\n fetchPolicy: 'network-only',\n });\n\n if (cancelled) return;\n const dashboardData = dashboardResult.data?.getDashboard;\n if (!dashboardData) {\n setError('Dashboard not found');\n setLoading(false);\n return;\n }\n\n // Normalize dashboard\n const pages =\n dashboardData.pages?.edges?.map((edge) => ({\n id: edge.node.id,\n name: edge.node.name || 'Page 1',\n })) || [];\n\n setDashboard({\n id: dashboardData.id,\n name: dashboardData.name,\n description: dashboardData.description,\n pages,\n });\n\n // Fetch widgets for the dashboard\n const widgetsResult = await apolloClient.query<{ listWidgetsByDashboard: Record<string, unknown>[] }>({\n query: ListWidgetsByDashboardDocument,\n variables: { dashboardId },\n fetchPolicy: 'network-only',\n });\n\n if (cancelled) return;\n const widgetsList = widgetsResult.data?.listWidgetsByDashboard || [];\n setWidgets(widgetsList.map((w, i) => normalizeWidget(w, i)));\n } catch (err) {\n if (!cancelled) setError(err instanceof Error ? err.message : 'Failed to load dashboard');\n } finally {\n fetching = false;\n if (!cancelled) setLoading(false);\n }\n }\n\n void fetchData();\n const interval = live\n ? window.setInterval(() => {\n if (document.visibilityState === 'visible') void fetchData();\n }, 4000)\n : undefined;\n return () => {\n cancelled = true;\n if (interval !== undefined) window.clearInterval(interval);\n };\n }, [dashboardId, apolloClient, live, refreshRevision]);\n\n // Loading state\n if (loading) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"flex flex-col items-center gap-3\">\n <div className=\"w-8 h-8 border-2 border-action-primary-bg border-t-transparent rounded-full animate-spin\" />\n <p className=\"text-sm text-text-secondary\">Loading dashboard...</p>\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex h-full items-center justify-center\" role=\"alert\">\n <Section\n headingLevel={3}\n tone=\"danger\"\n className=\"w-full max-w-md\"\n data-testid=\"drilldown-error\"\n title=\"Could not load this dashboard\"\n description={error}\n icon={\n <svg className=\"h-icon-md w-icon-md\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n }\n />\n </div>\n );\n }\n\n // Empty state\n if (!dashboard || widgets.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"flex flex-col items-center gap-3 text-center\">\n <svg className=\"w-12 h-12 text-text-muted\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z\"\n />\n </svg>\n <p className=\"text-sm text-text-secondary\">\n {dashboard ? 'This dashboard has no widgets' : 'Dashboard not found'}\n </p>\n </div>\n </div>\n );\n }\n\n const visibleParams = getVisibleDrilldownParams(params);\n\n // Show one page: the drilldown's target page when it still exists, else the\n // first page. Widgets without a page id (older payloads) are always shown.\n const requestedPageId = params[MODAL_TARGET_PAGE_PARAM];\n const activePage = dashboard.pages.find((page) => page.id === requestedPageId) ?? dashboard.pages[0] ?? null;\n const pageWidgets = activePage\n ? widgets.filter((widget) => !widget.pageId || widget.pageId === activePage.id)\n : widgets;\n // Re-flow the page's widgets top to bottom (the stacking was computed over\n // the whole dashboard).\n const stackedWidgets = pageWidgets.map((widget, index) => normalizeStacking(widget, index));\n\n return (\n <SectionStack className=\"w-full\">\n {/* Which board you drilled into — identity, not content. */}\n <Section\n emphasis=\"bare\"\n padding=\"none\"\n headingLevel={3}\n title={dashboard.name}\n description={\n dashboard.pages.length > 1 && activePage ? (\n <span data-testid=\"drilldown-dashboard-page\">{activePage.name}</span>\n ) : (\n dashboard.description\n )\n }\n data-testid=\"drilldown-dashboard-header\"\n />\n\n {/* The filter context you arrived with: supporting detail, recessed. */}\n {visibleParams.length > 0 && (\n <Section\n emphasis=\"muted\"\n padding=\"compact\"\n headingLevel={3}\n title=\"Filtered by\"\n data-testid=\"drilldown-params\"\n bodyClassName=\"flex flex-wrap gap-control-gap\"\n >\n {visibleParams.map(([key, value]) => (\n <span\n key={key}\n className=\"inline-flex items-center rounded-pill bg-bg-surface px-2 py-1 text-xs text-text-secondary\"\n >\n <span className=\"font-medium text-text-primary\">{key}:</span>\n <span className=\"ml-1\">\n {typeof value === 'object' && value !== null ? JSON.stringify(value) : String(value)}\n </span>\n </span>\n ))}\n </Section>\n )}\n\n {/* Widgets List - simple vertical layout for modal */}\n <div className=\"flex flex-col gap-form-gap\">\n {stackedWidgets.length === 0 && (\n <p className=\"text-sm text-text-secondary\" data-testid=\"drilldown-page-empty\">\n This page has no widgets\n </p>\n )}\n {stackedWidgets.map((widget) => {\n // Chart widgets (LINE_CHART / chart) need explicit pixel height because\n // Recharts ResponsiveContainer height=\"100%\" requires a parent with\n // a definite height — minHeight alone doesn't work.\n const internalType = (widget.config as Record<string, unknown>)?._internalWidgetType as string | undefined;\n const widgetType = widget.type as string;\n const isChartWidget =\n widgetType === 'LINE_CHART' ||\n widgetType === 'chart' ||\n internalType === 'chart' ||\n internalType === 'funnel_chart';\n const isTableWidget =\n widgetType === 'TABLE' ||\n widgetType === 'table' ||\n internalType === 'table' ||\n internalType === 'list' ||\n internalType === 'pivot_table';\n\n // Charts need an explicit height (Recharts' ResponsiveContainer needs a\n // definite parent). Clamping against the viewport keeps a 350px chart\n // plus a 500px table from filling a phone screen twice over.\n const heightStyle = isChartWidget\n ? { height: 'clamp(220px, 45vh, 350px)' }\n : isTableWidget\n ? { minHeight: 'min(250px, 40vh)', maxHeight: 'min(500px, 65vh)' }\n : { minHeight: 'min(120px, 25vh)', maxHeight: 'min(300px, 50vh)' };\n\n return (\n <div\n key={widget.id}\n className=\"min-w-0 overflow-hidden rounded-card border border-[var(--color-border-subtle)] bg-bg-surface\"\n style={heightStyle}\n >\n <WidgetInModal widget={widget} filterValues={params} />\n </div>\n );\n })}\n </div>\n </SectionStack>\n );\n }\n);\n\n// ============================================================================\n// Widget In Modal Component\n// ============================================================================\n\ninterface WidgetInModalProps {\n widget: Widget;\n filterValues?: Record<string, unknown>;\n}\n\nconst WidgetInModal: FC<WidgetInModalProps> = memo(function WidgetInModal({ widget, filterValues }) {\n return (\n <div className=\"h-full [&_[data-widget-id]]:border-transparent [&_[data-widget-id]:hover]:border-transparent\">\n <WidgetWrapper widget={widget} isLoading={false} error={null} filterValues={filterValues} />\n </div>\n );\n});\n\nexport default DrilldownDashboardRenderer;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DrilldownModal.d.ts","sourceRoot":"","sources":["../../../src/bigconsole/components/DrilldownModal.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAgC,MAAM,OAAO,CAAC;AAQ9D,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5F,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAMD,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CA4IjD,CAAC;AAYH,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"DrilldownModal.d.ts","sourceRoot":"","sources":["../../../src/bigconsole/components/DrilldownModal.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,EAA6B,MAAM,OAAO,CAAC;AAe3D,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5F,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAMD,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAoHjD,CAAC;AAYH,eAAe,cAAc,CAAC"}