drizzle-cube 0.2.11 → 0.2.13

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 (76) hide show
  1. package/dist/adapters/compiler-CMwSRhTS.cjs +22 -0
  2. package/dist/adapters/{compiler-gcKytLwd.js → compiler-DrkCCzf0.js} +16 -11
  3. package/dist/adapters/express/index.cjs +1 -1
  4. package/dist/adapters/express/index.js +8 -8
  5. package/dist/adapters/fastify/index.cjs +1 -1
  6. package/dist/adapters/fastify/index.js +9 -9
  7. package/dist/adapters/hono/index.cjs +1 -1
  8. package/dist/adapters/hono/index.js +11 -11
  9. package/dist/adapters/nextjs/index.cjs +1 -1
  10. package/dist/adapters/nextjs/index.js +59 -59
  11. package/dist/client/charts.js +11 -11
  12. package/dist/client/chunks/{chart-activitygridchart-D17Fxiuf.js → chart-activitygridchart-CUGN9Xq9.js} +3 -2
  13. package/dist/client/chunks/chart-activitygridchart-CUGN9Xq9.js.map +1 -0
  14. package/dist/client/chunks/{chart-areachart-udSbAzl1.js → chart-areachart-B4tknnsY.js} +25 -25
  15. package/dist/client/chunks/{chart-areachart-udSbAzl1.js.map → chart-areachart-B4tknnsY.js.map} +1 -1
  16. package/dist/client/chunks/{chart-axisformatcontrols-DqSa245M.js → chart-axisformatcontrols-Ch_IYF94.js} +18 -18
  17. package/dist/client/chunks/chart-axisformatcontrols-Ch_IYF94.js.map +1 -0
  18. package/dist/client/chunks/{chart-barchart-CDIpqCKS.js → chart-barchart-D_op06r-.js} +6 -6
  19. package/dist/client/chunks/{chart-barchart-CDIpqCKS.js.map → chart-barchart-D_op06r-.js.map} +1 -1
  20. package/dist/client/chunks/{chart-bubblechart-CivK_yfh.js → chart-bubblechart-BsaIXUbS.js} +3 -3
  21. package/dist/client/chunks/chart-bubblechart-BsaIXUbS.js.map +1 -0
  22. package/dist/client/chunks/{chart-charttooltip-BVEdz4Q-.js → chart-charttooltip-Bx3I8jQv.js} +2 -2
  23. package/dist/client/chunks/{chart-charttooltip-BVEdz4Q-.js.map → chart-charttooltip-Bx3I8jQv.js.map} +1 -1
  24. package/dist/client/chunks/{chart-datatable-NHE7BTMr.js → chart-datatable-C7MS9q4Y.js} +2 -2
  25. package/dist/client/chunks/{chart-datatable-NHE7BTMr.js.map → chart-datatable-C7MS9q4Y.js.map} +1 -1
  26. package/dist/client/chunks/{chart-kpidelta-D-FR2o4V.js → chart-kpidelta-7-KOmb3w.js} +62 -60
  27. package/dist/client/chunks/chart-kpidelta-7-KOmb3w.js.map +1 -0
  28. package/dist/client/chunks/{chart-kpinumber-DSH8RJxb.js → chart-kpinumber-HOPfcK2N.js} +4 -4
  29. package/dist/client/chunks/{chart-kpinumber-DSH8RJxb.js.map → chart-kpinumber-HOPfcK2N.js.map} +1 -1
  30. package/dist/client/chunks/{chart-kpitext-Z9oh0bJq.js → chart-kpitext-BZkC9u3A.js} +24 -24
  31. package/dist/client/chunks/{chart-kpitext-Z9oh0bJq.js.map → chart-kpitext-BZkC9u3A.js.map} +1 -1
  32. package/dist/client/chunks/{chart-linechart-D4r0uD1j.js → chart-linechart-DqFmLbRe.js} +7 -7
  33. package/dist/client/chunks/{chart-linechart-D4r0uD1j.js.map → chart-linechart-DqFmLbRe.js.map} +1 -1
  34. package/dist/client/chunks/chart-markdownchart-9n_TemoB.js +256 -0
  35. package/dist/client/chunks/chart-markdownchart-9n_TemoB.js.map +1 -0
  36. package/dist/client/chunks/{chart-piechart-BhttUWuH.js → chart-piechart-CrXFd9pE.js} +6 -6
  37. package/dist/client/chunks/{chart-piechart-BhttUWuH.js.map → chart-piechart-CrXFd9pE.js.map} +1 -1
  38. package/dist/client/chunks/{chart-radarchart-DnqlfoGr.js → chart-radarchart-tar2GBkO.js} +5 -5
  39. package/dist/client/chunks/{chart-radarchart-DnqlfoGr.js.map → chart-radarchart-tar2GBkO.js.map} +1 -1
  40. package/dist/client/chunks/{chart-radialbarchart-BFxxiqLw.js → chart-radialbarchart-ab8Swtal.js} +5 -5
  41. package/dist/client/chunks/{chart-radialbarchart-BFxxiqLw.js.map → chart-radialbarchart-ab8Swtal.js.map} +1 -1
  42. package/dist/client/chunks/{chart-scatterchart-MN4SM-w7.js → chart-scatterchart-BP06BeU5.js} +5 -5
  43. package/dist/client/chunks/{chart-scatterchart-MN4SM-w7.js.map → chart-scatterchart-BP06BeU5.js.map} +1 -1
  44. package/dist/client/chunks/{chart-treemapchart-Nozh2m26.js → chart-treemapchart-DAiixITm.js} +31 -31
  45. package/dist/client/chunks/{chart-treemapchart-Nozh2m26.js.map → chart-treemapchart-DAiixITm.js.map} +1 -1
  46. package/dist/client/chunks/{charts-BSDHSv4l.js → charts-CHzWeaY1.js} +26 -26
  47. package/dist/client/chunks/charts-CHzWeaY1.js.map +1 -0
  48. package/dist/client/chunks/{components-CbDovlG-.js → components-DnM9CCUS.js} +2453 -2445
  49. package/dist/client/chunks/components-DnM9CCUS.js.map +1 -0
  50. package/dist/client/chunks/{index-th92_8oL.js → index-DlsvcKXf.js} +135 -135
  51. package/dist/client/chunks/index-DlsvcKXf.js.map +1 -0
  52. package/dist/client/components/AnalysisBuilder/AnalysisAxisDropZone.d.ts +5 -5
  53. package/dist/client/components/AnalysisBuilder/SectionHeading.d.ts +2 -7
  54. package/dist/client/components/AnalysisBuilder/types.d.ts +8 -8
  55. package/dist/client/components.js +2 -2
  56. package/dist/client/hooks/useResponsiveDashboard.d.ts +2 -8
  57. package/dist/client/hooks.js +2 -2
  58. package/dist/client/hooks.js.map +1 -1
  59. package/dist/client/icons/types.d.ts +2 -2
  60. package/dist/client/index.js +3 -3
  61. package/dist/client/providers.js +1 -1
  62. package/dist/client/styles.css +1 -1
  63. package/dist/client-bundle-stats.html +1 -1
  64. package/dist/server/index.cjs +2 -2
  65. package/dist/server/index.js +16 -11
  66. package/package.json +3 -3
  67. package/dist/adapters/compiler-DP1pPIcg.cjs +0 -22
  68. package/dist/client/chunks/chart-activitygridchart-D17Fxiuf.js.map +0 -1
  69. package/dist/client/chunks/chart-axisformatcontrols-DqSa245M.js.map +0 -1
  70. package/dist/client/chunks/chart-bubblechart-CivK_yfh.js.map +0 -1
  71. package/dist/client/chunks/chart-kpidelta-D-FR2o4V.js.map +0 -1
  72. package/dist/client/chunks/chart-markdownchart-C3FAQFuO.js +0 -254
  73. package/dist/client/chunks/chart-markdownchart-C3FAQFuO.js.map +0 -1
  74. package/dist/client/chunks/charts-BSDHSv4l.js.map +0 -1
  75. package/dist/client/chunks/components-CbDovlG-.js.map +0 -1
  76. package/dist/client/chunks/index-th92_8oL.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components-DnM9CCUS.js","sources":["../../../node_modules/react-intersection-observer/dist/index.mjs","../../../src/client/components/ChartErrorBoundary.tsx","../../../src/client/utils/filterUtils.ts","../../../src/client/components/AnalyticsPortlet.tsx","../../../src/client/components/DebugModal.tsx","../../../src/client/components/DashboardPortletCard.tsx","../../../src/client/components/RowManagedLayout.tsx","../../../src/client/components/Modal.tsx","../../../src/client/utils/measureIcons.tsx","../../../src/client/components/QueryBuilder/CubeMetaExplorer.tsx","../../../src/client/shared/types.ts","../../../src/client/components/QueryBuilder/FilterValueSelector.tsx","../../../src/client/components/QueryBuilder/utils.ts","../../../src/client/components/QueryBuilder/FilterItem.tsx","../../../src/client/components/QueryBuilder/FilterGroup.tsx","../../../src/client/components/QueryBuilder/FilterBuilder.tsx","../../../src/client/components/QueryBuilder/DateRangeSelector.tsx","../../../src/client/components/QueryBuilder/DateRangeFilter.tsx","../../../src/client/components/QueryBuilder/QueryAnalysisPanel.tsx","../../../src/client/components/QueryBuilder/QueryPanel.tsx","../../../src/client/charts/chartConfigRegistry.ts","../../../src/client/components/ChartTypeSelector.tsx","../../../src/client/components/AxisDropZone.tsx","../../../src/client/components/ChartConfigPanel.tsx","../../../src/client/components/QueryBuilder/ResultsPanel.tsx","../../../src/client/components/QueryBuilder/SetupPanel.tsx","../../../src/client/components/AIAssistant/constants.ts","../../../src/client/components/AIAssistant/utils.ts","../../../src/client/components/AIAssistant/AIAssistantModal.tsx","../../../node_modules/lz-string/libs/lz-string.js","../../../src/client/components/QueryBuilder/shareUtils.ts","../../../src/client/components/QueryBuilder/ShareWarningModal.tsx","../../../src/client/components/QueryBuilder/index.tsx","../../../src/client/components/PortletEditModal.tsx","../../../src/client/components/AnalysisBuilder/utils.ts","../../../src/client/components/AnalysisBuilder/FieldSearchItem.tsx","../../../src/client/components/AnalysisBuilder/FieldDetailPanel.tsx","../../../src/client/components/AnalysisBuilder/FieldSearchModal.tsx","../../../src/client/shared/utils.ts","../../../src/client/shared/components/QueryAnalysisPanel.tsx","../../../src/client/shared/chartDefaults.ts","../../../src/client/utils/colorPalettes.ts","../../../src/client/components/ColorPaletteSelector.tsx","../../../src/client/components/AnalysisBuilder/AnalysisResultsPanel.tsx","../../../src/client/components/AnalysisBuilder/MetricItemCard.tsx","../../../src/client/components/AnalysisBuilder/MetricsSection.tsx","../../../src/client/components/AnalysisBuilder/types.ts","../../../src/client/components/AnalysisBuilder/BreakdownItemCard.tsx","../../../src/client/components/AnalysisBuilder/BreakdownSection.tsx","../../../src/client/components/AnalysisBuilder/AnalysisFilterItem.tsx","../../../src/client/components/AnalysisBuilder/AnalysisFilterGroup.tsx","../../../src/client/components/AnalysisBuilder/AnalysisFilterSection.tsx","../../../src/client/components/AnalysisBuilder/AnalysisAxisDropZone.tsx","../../../src/client/components/AnalysisBuilder/AnalysisChartConfigPanel.tsx","../../../src/client/components/AnalysisBuilder/AnalysisDisplayConfigPanel.tsx","../../../src/client/components/AnalysisBuilder/AnalysisQueryPanel.tsx","../../../src/client/components/AnalysisBuilder/AnalysisAIPanel.tsx","../../../src/client/components/AnalysisBuilder/index.tsx","../../../src/client/components/PortletAnalysisModal.tsx","../../../src/client/components/PortletFilterConfigModal.tsx","../../../src/client/components/DashboardFilters/FilterEditModal.tsx","../../../src/client/components/DashboardFilters/ReadOnlyFilterList.tsx","../../../src/client/components/DashboardFilters/EditModeFilterList.tsx","../../../src/client/components/DashboardFilterPanel.tsx","../../../src/client/components/ScaledGridWrapper.tsx","../../../src/client/components/MobileStackedLayout.tsx","../../../src/client/components/DashboardGrid.tsx","../../../src/client/components/AnalyticsDashboard.tsx","../../../src/client/components/PortletContainer.tsx","../../../src/client/components/DashboardEditModal.tsx"],"sourcesContent":["\"use client\";\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n\n// src/InView.tsx\nimport * as React from \"react\";\n\n// src/observe.ts\nvar observerMap = /* @__PURE__ */ new Map();\nvar RootIds = /* @__PURE__ */ new WeakMap();\nvar rootId = 0;\nvar unsupportedValue;\nfunction defaultFallbackInView(inView) {\n unsupportedValue = inView;\n}\nfunction getRootId(root) {\n if (!root) return \"0\";\n if (RootIds.has(root)) return RootIds.get(root);\n rootId += 1;\n RootIds.set(root, rootId.toString());\n return RootIds.get(root);\n}\nfunction optionsToId(options) {\n return Object.keys(options).sort().filter(\n (key) => options[key] !== void 0\n ).map((key) => {\n return `${key}_${key === \"root\" ? getRootId(options.root) : options[key]}`;\n }).toString();\n}\nfunction createObserver(options) {\n const id = optionsToId(options);\n let instance = observerMap.get(id);\n if (!instance) {\n const elements = /* @__PURE__ */ new Map();\n let thresholds;\n const observer = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n var _a2;\n const inView = entry.isIntersecting && thresholds.some((threshold) => entry.intersectionRatio >= threshold);\n if (options.trackVisibility && typeof entry.isVisible === \"undefined\") {\n entry.isVisible = inView;\n }\n (_a2 = elements.get(entry.target)) == null ? void 0 : _a2.forEach((callback) => {\n callback(inView, entry);\n });\n });\n }, options);\n thresholds = observer.thresholds || (Array.isArray(options.threshold) ? options.threshold : [options.threshold || 0]);\n instance = {\n id,\n observer,\n elements\n };\n observerMap.set(id, instance);\n }\n return instance;\n}\nfunction observe(element, callback, options = {}, fallbackInView = unsupportedValue) {\n if (typeof window.IntersectionObserver === \"undefined\" && fallbackInView !== void 0) {\n const bounds = element.getBoundingClientRect();\n callback(fallbackInView, {\n isIntersecting: fallbackInView,\n target: element,\n intersectionRatio: typeof options.threshold === \"number\" ? options.threshold : 0,\n time: 0,\n boundingClientRect: bounds,\n intersectionRect: bounds,\n rootBounds: bounds\n });\n return () => {\n };\n }\n const { id, observer, elements } = createObserver(options);\n const callbacks = elements.get(element) || [];\n if (!elements.has(element)) {\n elements.set(element, callbacks);\n }\n callbacks.push(callback);\n observer.observe(element);\n return function unobserve() {\n callbacks.splice(callbacks.indexOf(callback), 1);\n if (callbacks.length === 0) {\n elements.delete(element);\n observer.unobserve(element);\n }\n if (elements.size === 0) {\n observer.disconnect();\n observerMap.delete(id);\n }\n };\n}\n\n// src/InView.tsx\nfunction isPlainChildren(props) {\n return typeof props.children !== \"function\";\n}\nvar InView = class extends React.Component {\n constructor(props) {\n super(props);\n __publicField(this, \"node\", null);\n __publicField(this, \"_unobserveCb\", null);\n __publicField(this, \"lastInView\");\n __publicField(this, \"handleNode\", (node) => {\n if (this.node) {\n this.unobserve();\n if (!node && !this.props.triggerOnce && !this.props.skip) {\n this.setState({ inView: !!this.props.initialInView, entry: void 0 });\n this.lastInView = this.props.initialInView;\n }\n }\n this.node = node ? node : null;\n this.observeNode();\n });\n __publicField(this, \"handleChange\", (inView, entry) => {\n const previousInView = this.lastInView;\n this.lastInView = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n if (inView && this.props.triggerOnce) {\n this.unobserve();\n }\n if (!isPlainChildren(this.props)) {\n this.setState({ inView, entry });\n }\n if (this.props.onChange) {\n this.props.onChange(inView, entry);\n }\n });\n this.state = {\n inView: !!props.initialInView,\n entry: void 0\n };\n this.lastInView = props.initialInView;\n }\n componentDidMount() {\n this.unobserve();\n this.observeNode();\n }\n componentDidUpdate(prevProps) {\n if (prevProps.rootMargin !== this.props.rootMargin || prevProps.root !== this.props.root || prevProps.threshold !== this.props.threshold || prevProps.skip !== this.props.skip || prevProps.trackVisibility !== this.props.trackVisibility || prevProps.delay !== this.props.delay) {\n this.unobserve();\n this.observeNode();\n }\n }\n componentWillUnmount() {\n this.unobserve();\n }\n observeNode() {\n if (!this.node || this.props.skip) return;\n const {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n fallbackInView\n } = this.props;\n if (this.lastInView === void 0) {\n this.lastInView = this.props.initialInView;\n }\n this._unobserveCb = observe(\n this.node,\n this.handleChange,\n {\n threshold,\n root,\n rootMargin,\n // @ts-expect-error\n trackVisibility,\n delay\n },\n fallbackInView\n );\n }\n unobserve() {\n if (this._unobserveCb) {\n this._unobserveCb();\n this._unobserveCb = null;\n }\n }\n render() {\n const { children } = this.props;\n if (typeof children === \"function\") {\n const { inView, entry } = this.state;\n return children({ inView, entry, ref: this.handleNode });\n }\n const {\n as,\n triggerOnce,\n threshold,\n root,\n rootMargin,\n onChange,\n skip,\n trackVisibility,\n delay,\n initialInView,\n fallbackInView,\n ...props\n } = this.props;\n return React.createElement(\n as || \"div\",\n { ref: this.handleNode, ...props },\n children\n );\n }\n};\n\n// src/useInView.tsx\nimport * as React2 from \"react\";\nfunction useInView({\n threshold,\n delay,\n trackVisibility,\n rootMargin,\n root,\n triggerOnce,\n skip,\n initialInView,\n fallbackInView,\n onChange\n} = {}) {\n var _a2;\n const [ref, setRef] = React2.useState(null);\n const callback = React2.useRef(onChange);\n const lastInViewRef = React2.useRef(initialInView);\n const [state, setState] = React2.useState({\n inView: !!initialInView,\n entry: void 0\n });\n callback.current = onChange;\n React2.useEffect(\n () => {\n if (lastInViewRef.current === void 0) {\n lastInViewRef.current = initialInView;\n }\n if (skip || !ref) return;\n let unobserve;\n unobserve = observe(\n ref,\n (inView, entry) => {\n const previousInView = lastInViewRef.current;\n lastInViewRef.current = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n setState({\n inView,\n entry\n });\n if (callback.current) callback.current(inView, entry);\n if (entry.isIntersecting && triggerOnce && unobserve) {\n unobserve();\n unobserve = void 0;\n }\n },\n {\n root,\n rootMargin,\n threshold,\n // @ts-expect-error\n trackVisibility,\n delay\n },\n fallbackInView\n );\n return () => {\n if (unobserve) {\n unobserve();\n }\n };\n },\n // We break the rule here, because we aren't including the actual `threshold` variable\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n // If the threshold is an array, convert it to a string, so it won't change between renders.\n Array.isArray(threshold) ? threshold.toString() : threshold,\n ref,\n root,\n rootMargin,\n triggerOnce,\n skip,\n trackVisibility,\n fallbackInView,\n delay\n ]\n );\n const entryTarget = (_a2 = state.entry) == null ? void 0 : _a2.target;\n const previousEntryTarget = React2.useRef(void 0);\n if (!ref && entryTarget && !triggerOnce && !skip && previousEntryTarget.current !== entryTarget) {\n previousEntryTarget.current = entryTarget;\n setState({\n inView: !!initialInView,\n entry: void 0\n });\n lastInViewRef.current = initialInView;\n }\n const result = [setRef, state.inView, state.entry];\n result.ref = result[0];\n result.inView = result[1];\n result.entry = result[2];\n return result;\n}\n\n// src/useOnInView.tsx\nimport * as React3 from \"react\";\nvar _a, _b;\nvar useSyncEffect = (_b = (_a = React3.useInsertionEffect) != null ? _a : React3.useLayoutEffect) != null ? _b : React3.useEffect;\nvar useOnInView = (onIntersectionChange, {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n triggerOnce,\n skip\n} = {}) => {\n const onIntersectionChangeRef = React3.useRef(onIntersectionChange);\n const observedElementRef = React3.useRef(null);\n const observerCleanupRef = React3.useRef(void 0);\n const lastInViewRef = React3.useRef(void 0);\n useSyncEffect(() => {\n onIntersectionChangeRef.current = onIntersectionChange;\n }, [onIntersectionChange]);\n return React3.useCallback(\n (element) => {\n const cleanupExisting = () => {\n if (observerCleanupRef.current) {\n const cleanup = observerCleanupRef.current;\n observerCleanupRef.current = void 0;\n cleanup();\n }\n };\n if (element === observedElementRef.current) {\n return observerCleanupRef.current;\n }\n if (!element || skip) {\n cleanupExisting();\n observedElementRef.current = null;\n lastInViewRef.current = void 0;\n return;\n }\n cleanupExisting();\n observedElementRef.current = element;\n let destroyed = false;\n const destroyObserver = observe(\n element,\n (inView, entry) => {\n const previousInView = lastInViewRef.current;\n lastInViewRef.current = inView;\n if (previousInView === void 0 && !inView) {\n return;\n }\n onIntersectionChangeRef.current(\n inView,\n entry\n );\n if (triggerOnce && inView) {\n stopObserving();\n }\n },\n {\n threshold,\n root,\n rootMargin,\n trackVisibility,\n delay\n }\n );\n function stopObserving() {\n if (destroyed) return;\n destroyed = true;\n destroyObserver();\n observedElementRef.current = null;\n observerCleanupRef.current = void 0;\n lastInViewRef.current = void 0;\n }\n observerCleanupRef.current = stopObserving;\n return observerCleanupRef.current;\n },\n [\n Array.isArray(threshold) ? threshold.toString() : threshold,\n root,\n rootMargin,\n trackVisibility,\n delay,\n triggerOnce,\n skip\n ]\n );\n};\nexport {\n InView,\n defaultFallbackInView,\n observe,\n useInView,\n useOnInView\n};\n//# sourceMappingURL=index.mjs.map","import React, { Component, ReactNode } from 'react'\nimport { getIcon } from '../icons'\n\nconst RefreshIcon = getIcon('refresh')\n\ninterface Props {\n children: ReactNode\n fallback?: ReactNode\n portletTitle?: string\n portletConfig?: any\n cubeQuery?: string\n}\n\ninterface State {\n hasError: boolean\n error: Error | null\n errorInfo: string | null\n}\n\nexport default class ChartErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props)\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null\n }\n }\n\n static getDerivedStateFromError(error: Error): State {\n // Update state so the next render will show the fallback UI\n return {\n hasError: true,\n error,\n errorInfo: null\n }\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n // Update state with error details\n this.setState({\n error,\n errorInfo: errorInfo.componentStack || null\n })\n\n // Log the error for debugging\n console.error('Chart Error Boundary caught a rendering error:', error, errorInfo)\n }\n\n handleReset = () => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null\n })\n }\n\n render() {\n if (this.state.hasError) {\n // Custom fallback UI\n if (this.props.fallback) {\n return this.props.fallback\n }\n\n // Default error display\n return (\n <div className=\"flex flex-col items-center justify-center w-full h-full p-6 text-center border border-dashed rounded-lg\"\n style={{ borderColor: 'var(--dc-border)', backgroundColor: 'var(--dc-surface)' }}>\n <div className=\"h-12 w-12 mb-4 text-dc-text-muted\">⚠️</div>\n <h3 className=\"text-lg font-semibold mb-2 text-dc-text\">\n {this.props.portletTitle ? `Unable to render ${this.props.portletTitle}` : 'Unable to render chart'}\n </h3>\n <p className=\"text-sm text-dc-text-secondary mb-4 max-w-md\">\n There was an error rendering this chart component. The error details are shown below.\n </p>\n\n {/* Error details */}\n <div className=\"w-full max-w-2xl mb-4\">\n <div className=\"bg-dc-surface-secondary rounded-lg p-3 text-left\">\n <div className=\"text-xs font-mono mb-2 text-dc-text\">\n <strong>Error:</strong> {this.state.error?.message}\n </div>\n {this.state.error?.name && (\n <div className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <strong>Type:</strong> {this.state.error.name}\n </div>\n )}\n\n {/* Portlet Config Debug Info */}\n {this.props.portletConfig && (\n <details className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <summary className=\"cursor-pointer\">Portlet Configuration</summary>\n <pre className=\"mt-2 whitespace-pre-wrap p-2 rounded-sm overflow-auto max-h-32\"\n style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.1)' }}>\n {JSON.stringify(this.props.portletConfig, null, 2)}\n </pre>\n </details>\n )}\n\n {/* Cube Query Debug Info */}\n {this.props.cubeQuery && (\n <details className=\"text-xs font-mono text-dc-text-secondary mb-2\">\n <summary className=\"cursor-pointer\">Cube Query</summary>\n <pre className=\"mt-2 whitespace-pre-wrap p-2 rounded-sm overflow-auto max-h-32\"\n style={{ backgroundColor: '#d1fae5' }}>\n {typeof this.props.cubeQuery === 'string' \n ? JSON.stringify(JSON.parse(this.props.cubeQuery), null, 2)\n : JSON.stringify(this.props.cubeQuery, null, 2)\n }\n </pre>\n </details>\n )}\n\n {this.state.errorInfo && (\n <details className=\"text-xs font-mono text-dc-text-secondary\">\n <summary className=\"cursor-pointer\">Component Stack</summary>\n <pre className=\"mt-2 whitespace-pre-wrap\">{this.state.errorInfo}</pre>\n </details>\n )}\n </div>\n </div>\n\n {/* Reset button */}\n <button\n onClick={this.handleReset}\n className=\"px-3 py-1 text-white rounded-sm text-sm hover:opacity-90 transition-opacity\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n <RefreshIcon style={{ width: '16px', height: '16px', display: 'inline', marginRight: '4px' }} />Try Again\n </button>\n </div>\n )\n }\n\n return this.props.children\n }\n}","/**\n * Filter utility functions for dashboard-level filtering\n */\n\nimport type { Filter, DashboardFilter, CubeMeta, GroupFilter, DashboardConfig, SimpleFilter } from '../types'\n\n/**\n * Check if a filter should be included in the query (has valid values or doesn't require values)\n * @param filter - The filter to check\n * @returns true if the filter should be included, false otherwise\n */\nfunction shouldIncludeFilter(filter: Filter): boolean {\n // Handle SimpleFilter\n if ('member' in filter && 'operator' in filter) {\n const simpleFilter = filter as SimpleFilter\n\n // Operators that don't require values\n const noValueOperators = ['set', 'notSet', 'isEmpty', 'isNotEmpty']\n if (noValueOperators.includes(simpleFilter.operator)) {\n return true\n }\n\n // For inDateRange, check if dateRange is provided as alternative to values\n if (simpleFilter.operator === 'inDateRange' && simpleFilter.dateRange) {\n return true\n }\n\n // For other operators, check if values exist and are non-empty\n return !!(simpleFilter.values && simpleFilter.values.length > 0)\n }\n\n // Handle GroupFilter - recursively check nested filters\n if ('type' in filter && 'filters' in filter) {\n const groupFilter = filter as GroupFilter\n // Include group filter if at least one nested filter is valid\n const validFilters = groupFilter.filters.filter(f => shouldIncludeFilter(f))\n return validFilters.length > 0\n }\n\n return false\n}\n\n/**\n * Get dashboard filters that should be applied to a portlet based on its mapping configuration\n * @param dashboardFilters - All available dashboard filters\n * @param filterMapping - Array of filter IDs that apply to this portlet\n * @returns Array of filters that should be applied to the portlet\n */\nexport function getApplicableDashboardFilters(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined\n): Filter[] {\n if (!dashboardFilters || !dashboardFilters.length) {\n return []\n }\n\n // If no mapping is specified, no dashboard filters apply\n if (!filterMapping || !filterMapping.length) {\n return []\n }\n\n // Return filters that are in the mapping AND have valid values\n return dashboardFilters\n .filter(df => filterMapping.includes(df.id))\n .filter(df => shouldIncludeFilter(df.filter))\n .map(df => df.filter)\n}\n\n/**\n * Merge dashboard filters with portlet filters using AND logic\n * Dashboard filters are combined with portlet filters so both sets of filters apply\n * @param dashboardFilters - Filters from dashboard-level configuration\n * @param portletFilters - Filters from portlet query\n * @returns Merged filter array with AND logic\n */\n/**\n * Convert GroupFilter format to server format\n * GroupFilter: { type: 'and', filters: [...] }\n * Server format: { and: [...] } or { or: [...] }\n */\nfunction convertToServerFormat(filter: Filter): any {\n // Handle GroupFilter format\n if ('type' in filter && 'filters' in filter) {\n const groupFilter = filter as GroupFilter\n const convertedFilters = groupFilter.filters.map(convertToServerFormat)\n\n if (groupFilter.type === 'and') {\n return { and: convertedFilters }\n } else {\n return { or: convertedFilters }\n }\n }\n\n // Simple filter - return as-is\n return filter\n}\n\nexport function mergeDashboardAndPortletFilters(\n dashboardFilters: Filter[],\n portletFilters: Filter[] | undefined\n): Filter[] | undefined {\n // If no dashboard filters, return portlet filters as-is\n if (!dashboardFilters || dashboardFilters.length === 0) {\n return portletFilters\n }\n\n // If no portlet filters, return dashboard filters\n if (!portletFilters || portletFilters.length === 0) {\n return dashboardFilters\n }\n\n // Both exist - need to merge with AND logic\n // We need to combine them in a way that both sets of filters apply\n\n // Flatten both filter arrays and convert to server format\n const allFilters = [...dashboardFilters, ...portletFilters].map(convertToServerFormat)\n\n // Wrap all filters in a single AND group using server format\n return [{\n and: allFilters\n } as any]\n}\n\n/**\n * Check if a filter field exists in the cube metadata\n * This helps identify filters that might not apply to a specific portlet's data\n * @param filter - The filter to validate\n * @param cubeMeta - Cube metadata to validate against\n * @returns true if the filter field exists in any cube's measures or dimensions\n */\nexport function validateFilterForCube(\n filter: Filter,\n cubeMeta: CubeMeta | null\n): boolean {\n if (!cubeMeta || !cubeMeta.cubes) {\n // If no metadata available, assume filter is valid (fail open)\n return true\n }\n\n // Extract member names from filter recursively\n const memberNames = extractMemberNamesFromFilter(filter)\n\n // Check if any of the member names exist in cube metadata\n return memberNames.some(memberName => {\n return cubeMeta.cubes.some(cube => {\n // Check measures\n const inMeasures = cube.measures?.some(m => m.name === memberName) ?? false\n // Check dimensions\n const inDimensions = cube.dimensions?.some(d => d.name === memberName) ?? false\n\n return inMeasures || inDimensions\n })\n })\n}\n\n/**\n * Extract all member names from a filter (handles nested group filters)\n * @param filter - The filter to extract members from\n * @returns Array of member names\n */\nfunction extractMemberNamesFromFilter(filter: Filter): string[] {\n if ('member' in filter) {\n // SimpleFilter\n return [filter.member]\n } else if ('type' in filter && 'filters' in filter) {\n // GroupFilter - recursively extract from nested filters\n return filter.filters.flatMap(f => extractMemberNamesFromFilter(f))\n }\n\n return []\n}\n\n/**\n * Validate that all dashboard filters in a portlet's mapping exist and are valid\n * @param dashboardFilters - All available dashboard filters\n * @param filterMapping - The portlet's filter mapping\n * @param cubeMeta - Cube metadata for validation\n * @returns Object with validation result and list of invalid filter IDs\n */\nexport function validatePortletFilterMapping(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined,\n cubeMeta: CubeMeta | null\n): { isValid: boolean; invalidFilterIds: string[]; missingFilterIds: string[] } {\n if (!filterMapping || !filterMapping.length) {\n return { isValid: true, invalidFilterIds: [], missingFilterIds: [] }\n }\n\n if (!dashboardFilters || !dashboardFilters.length) {\n // Mapping references filters that don't exist\n return {\n isValid: false,\n invalidFilterIds: [],\n missingFilterIds: filterMapping\n }\n }\n\n const invalidFilterIds: string[] = []\n const missingFilterIds: string[] = []\n\n filterMapping.forEach(filterId => {\n const dashboardFilter = dashboardFilters.find(df => df.id === filterId)\n\n if (!dashboardFilter) {\n // Filter ID in mapping doesn't exist in dashboard filters\n missingFilterIds.push(filterId)\n } else {\n // Check if filter is valid for the cube metadata\n const isValid = validateFilterForCube(dashboardFilter.filter, cubeMeta)\n if (!isValid) {\n invalidFilterIds.push(filterId)\n }\n }\n })\n\n return {\n isValid: invalidFilterIds.length === 0 && missingFilterIds.length === 0,\n invalidFilterIds,\n missingFilterIds\n }\n}\n\n/**\n * Extract all unique measures, dimensions, and timeDimensions used across all portlets in a dashboard\n * This helps create a filtered schema view showing only fields relevant to the dashboard\n * @param dashboardConfig - Dashboard configuration\n * @returns Object with unique measures, dimensions, and timeDimensions\n */\nexport function extractDashboardFields(\n dashboardConfig: DashboardConfig\n): { measures: Set<string>; dimensions: Set<string>; timeDimensions: Set<string> } {\n const measures = new Set<string>()\n const dimensions = new Set<string>()\n const timeDimensions = new Set<string>()\n\n // Iterate through all portlets\n dashboardConfig.portlets.forEach(portlet => {\n try {\n // Parse the query JSON\n const query = JSON.parse(portlet.query)\n\n // Extract measures\n if (query.measures && Array.isArray(query.measures)) {\n query.measures.forEach((measure: string) => measures.add(measure))\n }\n\n // Extract dimensions\n if (query.dimensions && Array.isArray(query.dimensions)) {\n query.dimensions.forEach((dimension: string) => dimensions.add(dimension))\n }\n\n // Extract timeDimensions\n if (query.timeDimensions && Array.isArray(query.timeDimensions)) {\n query.timeDimensions.forEach((td: any) => {\n if (td.dimension) {\n timeDimensions.add(td.dimension)\n }\n })\n }\n\n // Also extract from filters to catch any filtered fields\n if (query.filters) {\n extractFieldsFromFilters(query.filters).forEach(field => {\n // Try to determine if it's a measure, dimension, or timeDimension\n // by checking cube metadata or convention (add to dimensions by default)\n dimensions.add(field)\n })\n }\n } catch (e) {\n // Skip portlets with invalid query JSON\n console.warn('Failed to parse portlet query:', portlet.id, e)\n }\n })\n\n return { measures, dimensions, timeDimensions }\n}\n\n/**\n * Extract field names from filters recursively\n * @param filters - Filter array\n * @returns Array of unique field names\n */\nfunction extractFieldsFromFilters(filters: Filter[]): string[] {\n const fields: string[] = []\n\n filters.forEach(filter => {\n if ('member' in filter) {\n // SimpleFilter\n fields.push(filter.member)\n } else if ('type' in filter && 'filters' in filter) {\n // GroupFilter - recurse\n fields.push(...extractFieldsFromFilters(filter.filters))\n }\n })\n\n return [...new Set(fields)] // Return unique fields\n}\n\n/**\n * Time dimension type from CubeQuery\n */\ntype TimeDimension = {\n dimension: string\n granularity?: string\n dateRange?: string[] | string\n}\n\n/**\n * Helper to get date range from a SimpleFilter (backward compatible)\n * Reads from both dateRange and values for compatibility\n * Handles both:\n * - Preset ranges: [\"this quarter\"], [\"last 7 days\"] (single string value)\n * - Custom ranges: [\"2024-01-01\", \"2024-12-31\"] (two date values)\n */\nfunction getDateRangeFromFilter(filter: SimpleFilter): string[] | string | undefined {\n // Prefer dateRange for backward compatibility, fall back to values\n if (filter.dateRange) {\n return filter.dateRange\n }\n if (filter.values && filter.values.length > 0) {\n // Single value = preset like \"this quarter\", return as string\n // Multiple values = custom date range, return as array\n return filter.values.length === 1 ? filter.values[0] : filter.values\n }\n return undefined\n}\n\n/**\n * Apply universal time filters to a portlet's timeDimensions\n * Universal time filters apply their dateRange to ALL time dimensions in the portlet\n *\n * @param dashboardFilters - All dashboard filters\n * @param filterMapping - Filter IDs that apply to this portlet\n * @param portletTimeDimensions - The portlet's existing timeDimensions array\n * @returns Updated timeDimensions array with date ranges applied\n */\nexport function applyUniversalTimeFilters(\n dashboardFilters: DashboardFilter[] | undefined,\n filterMapping: string[] | undefined,\n portletTimeDimensions: TimeDimension[] | undefined\n): TimeDimension[] | undefined {\n // Return as-is if no time dimensions in portlet (skip silently)\n if (!portletTimeDimensions || portletTimeDimensions.length === 0) {\n return portletTimeDimensions\n }\n\n // If no mapping specified, no filters apply\n if (!filterMapping || filterMapping.length === 0) {\n return portletTimeDimensions\n }\n\n // Find applicable universal time filters that have valid date ranges\n const universalTimeFilters = dashboardFilters\n ?.filter(df => df.isUniversalTime && filterMapping.includes(df.id))\n ?.filter(df => {\n // Must be a SimpleFilter with a valid dateRange\n if (!('member' in df.filter)) return false\n const simpleFilter = df.filter as SimpleFilter\n const dateRange = getDateRangeFromFilter(simpleFilter)\n return dateRange !== undefined\n })\n\n if (!universalTimeFilters || universalTimeFilters.length === 0) {\n return portletTimeDimensions\n }\n\n // Use the first universal time filter's dateRange (typically only one)\n const timeFilter = universalTimeFilters[0]\n const simpleFilter = timeFilter.filter as SimpleFilter\n const dateRange = getDateRangeFromFilter(simpleFilter)\n\n // Apply dateRange to ALL time dimensions (dashboard wins - overrides portlet dateRange)\n return portletTimeDimensions.map(td => ({\n ...td,\n dateRange: dateRange\n }))\n}\n","/**\n * Analytics Portlet Component\n * Simplified version with minimal dependencies\n */\n\nimport { useMemo, useState, forwardRef, useImperativeHandle, useEffect, useRef } from 'react'\nimport { useInView } from 'react-intersection-observer'\nimport { useCubeQuery } from '../hooks/useCubeQuery'\nimport { useScrollContainer } from '../providers/ScrollContainerContext'\nimport ChartErrorBoundary from './ChartErrorBoundary'\nimport LoadingIndicator from './LoadingIndicator'\nimport { LazyChart, isValidChartType } from '../charts/ChartLoader'\nimport { useChartConfig } from '../charts/lazyChartConfigRegistry'\nimport type { AnalyticsPortletProps } from '../types'\nimport { getApplicableDashboardFilters, mergeDashboardAndPortletFilters, applyUniversalTimeFilters } from '../utils/filterUtils'\n\n\ninterface AnalyticsPortletRef {\n refresh: () => void\n}\n\nconst AnalyticsPortlet = forwardRef<AnalyticsPortletRef, AnalyticsPortletProps>(({\n query,\n chartType,\n chartConfig,\n displayConfig,\n dashboardFilters,\n dashboardFilterMapping,\n eagerLoad = false,\n isVisible: _isVisible, // Deprecated - visibility now handled internally via useInView\n height = 300,\n title: _title,\n colorPalette,\n loadingComponent,\n onDebugDataReady\n}, ref) => {\n const [refreshCounter, setRefreshCounter] = useState(0)\n const onDebugDataReadyRef = useRef(onDebugDataReady)\n\n // Lazy loading: Use IntersectionObserver to detect when portlet is visible\n // Get scroll container from context (null = viewport, element = container scroll)\n const scrollContainer = useScrollContainer()\n const { ref: inViewRef, inView } = useInView({\n root: scrollContainer,\n rootMargin: '200px', // Start loading 200px before entering viewport\n triggerOnce: true, // Once visible, stay \"visible\" (don't unload data)\n initialInView: false, // Start as not visible, let observer determine actual state\n skip: eagerLoad // Skip observation entirely if eagerLoad is true\n })\n\n // Effective visibility: eagerLoad forces visible, otherwise use inView from IntersectionObserver\n // Note: Batching is handled by BatchCoordinator which collects queries for 100ms before flushing\n const isVisible = eagerLoad || inView\n\n // Update ref when callback changes\n useEffect(() => {\n onDebugDataReadyRef.current = onDebugDataReady\n }, [onDebugDataReady])\n\n // Check if this chart type skips queries (using lazy-loaded config)\n const { config: chartTypeConfig } = useChartConfig(chartType)\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Parse query from JSON string, merge dashboard filters, and include refresh counter to force re-query\n const queryObject = useMemo(() => {\n // Skip query parsing for charts that don't need queries\n if (shouldSkipQuery) {\n return null\n }\n\n try {\n const parsed = JSON.parse(query)\n\n // Get applicable dashboard filters (excluding universal time filters - they apply to timeDimensions)\n const regularFilters = dashboardFilters?.filter(df => !df.isUniversalTime)\n const applicableFilters = getApplicableDashboardFilters(regularFilters, dashboardFilterMapping)\n\n // Merge dashboard filters with portlet filters\n const mergedFilters = mergeDashboardAndPortletFilters(applicableFilters, parsed.filters)\n\n // Apply universal time filters to timeDimensions (dashboard wins over portlet dateRange)\n const mergedTimeDimensions = applyUniversalTimeFilters(\n dashboardFilters,\n dashboardFilterMapping,\n parsed.timeDimensions\n )\n\n return {\n ...parsed,\n filters: mergedFilters,\n timeDimensions: mergedTimeDimensions,\n __refresh_counter: refreshCounter\n }\n } catch (e) {\n console.error('AnalyticsPortlet: Invalid query JSON:', e)\n return null\n }\n }, [query, refreshCounter, shouldSkipQuery, dashboardFilters, dashboardFilterMapping])\n\n // Use the cube React hook (skip for charts that don't need queries or not visible for lazy loading)\n // Priority: shouldSkipQuery (chart type) > eagerLoad override > isVisible (lazy loading)\n const shouldSkip = !queryObject || shouldSkipQuery || (!eagerLoad && !isVisible)\n\n const { resultSet, isLoading, error } = useCubeQuery(queryObject, {\n skip: shouldSkip,\n resetResultSetOnChange: true\n })\n\n // Expose refresh function through ref\n useImperativeHandle(ref, () => ({\n refresh: () => {\n setRefreshCounter(prev => prev + 1)\n }\n }), [])\n\n\n // Send debug data to parent when ready (must be before any returns)\n useEffect(() => {\n if (onDebugDataReadyRef.current && chartConfig && queryObject && resultSet && !error) {\n const getData = () => {\n switch (chartType) {\n case 'pie':\n case 'table':\n return resultSet.tablePivot()\n default:\n return resultSet.rawData()\n }\n }\n const data = getData()\n \n if (data) {\n onDebugDataReadyRef.current({\n chartConfig: chartConfig || {},\n displayConfig: displayConfig || {},\n queryObject,\n data,\n chartType\n })\n }\n }\n }, [chartConfig, displayConfig, queryObject, resultSet, chartType, error]) // Use ref for callback to prevent infinite loops\n\n // Validate that chartConfig is provided when required (not required for skipQuery charts)\n // Check if any dropZones are mandatory for this chart type\n const hasMandatoryFields = !shouldSkipQuery && chartTypeConfig.dropZones.some(zone => zone.mandatory === true)\n \n if (!chartConfig && hasMandatoryFields) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Required</div>\n <div className=\"text-xs text-dc-text-secondary\">Please configure this chart</div>\n </div>\n </div>\n )\n }\n\n // Show placeholder for lazy-loaded portlets that aren't visible yet\n if (!shouldSkipQuery && !eagerLoad && !isVisible) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"w-8 h-8 mx-auto mb-2 rounded-full bg-dc-surface-secondary animate-pulse\" />\n <div className=\"text-xs text-dc-text-secondary\">Scroll to load</div>\n </div>\n </div>\n )\n }\n\n // Skip loading and error handling for charts that don't need queries\n if (!shouldSkipQuery) {\n if (isLoading || (queryObject && !resultSet && !error)) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full\" style={{ height }}>\n {loadingComponent || <LoadingIndicator size=\"md\" />}\n </div>\n )\n }\n\n if (error) {\n return (\n <div ref={inViewRef} className=\"p-4 border rounded-sm\" style={{ height, borderColor: 'var(--dc-border)', backgroundColor: 'var(--dc-surface)' }}>\n <div className=\"mb-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium text-sm\" style={{ color: 'var(--dc-text)' }}>⚠️ Query Error</span>\n <button\n onClick={() => setRefreshCounter(prev => prev + 1)}\n className=\"px-2 py-1 text-white rounded-sm text-xs\"\n style={{ backgroundColor: 'var(--dc-primary)' }}\n >\n Retry\n </button>\n </div>\n </div>\n\n <div className=\"mb-3\">\n <div className=\"text-xs p-2 rounded-sm border\" style={{ color: 'var(--dc-text-secondary)', backgroundColor: 'var(--dc-surface)', borderColor: 'var(--dc-border)' }}>\n {error.message || error.toString()}\n </div>\n </div>\n\n <div className=\"space-y-2 text-xs\">\n <details>\n <summary className=\"cursor-pointer font-medium\" style={{ color: 'var(--dc-text-secondary)' }}>Query (with filters applied)</summary>\n <pre className=\"mt-1 p-2 rounded-sm text-xs overflow-auto max-h-20\" style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.1)' }}>\n {queryObject ? JSON.stringify(queryObject, null, 2) : query}\n </pre>\n </details>\n\n <details>\n <summary className=\"cursor-pointer font-medium\" style={{ color: 'var(--dc-text-secondary)' }}>Chart Config</summary>\n <pre className=\"mt-1 p-2 rounded-sm text-xs overflow-auto max-h-20\" style={{ backgroundColor: 'rgba(var(--dc-primary-rgb), 0.05)' }}>\n {JSON.stringify({\n chartType,\n chartConfig,\n displayConfig: displayConfig\n }, null, 2)}\n </pre>\n </details>\n </div>\n </div>\n )\n }\n\n if (!resultSet || !queryObject) {\n return (\n <div ref={inViewRef} className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs\">Invalid query or no results</div>\n </div>\n </div>\n )\n }\n }\n\n // Get data based on chart type needs\n const getData = () => {\n // Return empty array for charts that don't use query data\n if (shouldSkipQuery) {\n return []\n }\n \n // Return empty array if no resultSet\n if (!resultSet) {\n return []\n }\n \n switch (chartType) {\n case 'pie':\n case 'table':\n return resultSet.tablePivot()\n default:\n return resultSet.rawData()\n }\n }\n\n const data = getData()\n\n // Render appropriate chart component using lazy loading\n // Each chart type is dynamically imported for code splitting\n const renderChart = () => {\n try {\n const chartHeight = height\n\n // Handle unsupported chart types\n if (!isValidChartType(chartType)) {\n return (\n <div className=\"flex items-center justify-center w-full\" style={{ height }}>\n <div className=\"text-center text-dc-text-muted\">\n <div className=\"text-sm font-semibold mb-1\">Unsupported chart type</div>\n <div className=\"text-xs\">{chartType}</div>\n </div>\n </div>\n )\n }\n\n // For markdown chart, use empty data array\n const chartData = chartType === 'markdown' ? [] : data\n\n return (\n <LazyChart\n chartType={chartType}\n data={chartData}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n queryObject={queryObject ?? undefined}\n height={chartHeight}\n colorPalette={colorPalette}\n fallback={\n <div\n className=\"flex items-center justify-center w-full\"\n style={{ height: typeof chartHeight === 'number' ? `${chartHeight}px` : chartHeight }}\n >\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full min-h-[100px]\" />\n </div>\n }\n />\n )\n } catch (error) {\n console.error('Chart rendering error:', error)\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted p-4\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Unable to render chart</div>\n <div className=\"text-xs text-dc-text-secondary\">{error instanceof Error ? error.message : 'Unknown error'}</div>\n </div>\n </div>\n )\n }\n }\n\n return (\n <div ref={inViewRef} className=\"w-full h-full\">\n <ChartErrorBoundary\n portletTitle={_title}\n portletConfig={{\n chartType,\n chartConfig,\n displayConfig,\n height\n }}\n cubeQuery={query}\n >\n <div className=\"w-full h-full flex flex-col flex-1\" style={{ minHeight: '200px' }}>\n {renderChart()}\n </div>\n </ChartErrorBoundary>\n </div>\n )\n})\n\nAnalyticsPortlet.displayName = 'AnalyticsPortlet'\n\nexport default AnalyticsPortlet","import { useState, useEffect } from 'react'\n\ninterface DebugModalProps {\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n}\n\nexport default function DebugModal({ \n chartConfig, \n displayConfig, \n queryObject, \n data, \n chartType \n}: DebugModalProps) {\n const [isOpen, setIsOpen] = useState(false)\n\n // Handle ESC key to close modal\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && isOpen) {\n setIsOpen(false)\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [isOpen])\n\n // Trigger Prism highlighting when modal opens and content is rendered\n useEffect(() => {\n if (isOpen && typeof window !== 'undefined' && (window as any).Prism) {\n // Small delay to ensure DOM is updated\n const timer = setTimeout(() => {\n (window as any).Prism.highlightAll()\n }, 10)\n \n return () => clearTimeout(timer)\n }\n }, [isOpen])\n\n\n if (!isOpen) {\n return (\n <button\n onClick={() => setIsOpen(true)}\n className=\"p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors\"\n title=\"Debug chart configuration\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\n </svg>\n </button>\n )\n }\n\n return (\n <div\n className=\"absolute inset-0 bg-dc-surface border border-dc-border rounded-lg z-50 overflow-auto\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"p-4 h-full flex flex-col\">\n <div className=\"flex justify-between items-center mb-4 shrink-0\">\n <h2 className=\"text-lg font-semibold text-dc-text\">Chart Debug Information</h2>\n <button\n onClick={() => setIsOpen(false)}\n className=\"p-2 text-dc-text-muted hover:text-dc-text-secondary hover:bg-dc-surface-secondary rounded-sm\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4 flex-1 overflow-auto\">\n <div>\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Chart Type</h3>\n <div className=\"bg-dc-surface-secondary p-2 rounded-sm text-sm font-mono border border-dc-border\">\n {chartType}\n </div>\n </div>\n\n <div>\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Field Analysis</h3>\n <div className=\"bg-dc-surface-secondary p-2 rounded-sm text-xs space-y-1 border border-dc-border\">\n <div>\n <strong>xAxis:</strong> {Array.isArray(chartConfig?.xAxis) ? `Array: [${chartConfig.xAxis.join(', ')}]` : `String: \"${chartConfig?.xAxis}\"`}\n </div>\n <div>\n <strong>yAxis:</strong> {Array.isArray(chartConfig?.yAxis) ? `Array: [${chartConfig.yAxis.join(', ')}]` : `String: \"${chartConfig?.yAxis}\"`}\n </div>\n <div>\n <strong>series:</strong> {Array.isArray(chartConfig?.series) ? `Array: [${chartConfig.series.join(', ')}]` : `String: \"${chartConfig?.series}\"`}\n </div>\n {chartConfig?.sizeField && (\n <div>\n <strong>sizeField:</strong> {Array.isArray(chartConfig?.sizeField) ? `Array: [${chartConfig.sizeField.join(', ')}]` : `String: \"${chartConfig?.sizeField}\"`}\n </div>\n )}\n {chartConfig?.colorField && (\n <div>\n <strong>colorField:</strong> {Array.isArray(chartConfig?.colorField) ? `Array: [${chartConfig.colorField.join(', ')}]` : `String: \"${chartConfig?.colorField}\"`}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Chart Config</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(chartConfig, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Display Config</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(displayConfig, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Query Object</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(queryObject, null, 2)}</code>\n </pre>\n </div>\n\n <div className=\"lg:col-span-2\">\n <h3 className=\"text-sm font-medium text-dc-text-secondary mb-2\">Data Sample (first 3 rows)</h3>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border\" style={{ fontSize: '10px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(data?.slice(0, 3) || [], null, 2)}</code>\n </pre>\n </div>\n </div>\n\n <div className=\"mt-4 pt-2 border-t border-dc-border text-xs text-dc-text-muted shrink-0\">\n Press <kbd className=\"px-1 py-0.5 bg-dc-surface-secondary rounded-sm text-xs\">ESC</kbd> to close\n </div>\n </div>\n </div>\n )\n}","import { type HTMLAttributes, type ReactNode, type CSSProperties, type ComponentType } from 'react'\nimport type { DashboardFilter, PortletConfig } from '../types'\nimport AnalyticsPortlet from './AnalyticsPortlet'\nimport DebugModal from './DebugModal'\nimport type { ColorPalette } from '../utils/colorPalettes'\n\ninterface DashboardPortletCardProps {\n portlet: PortletConfig\n editable: boolean\n isEditMode: boolean\n selectedFilterId: string | null\n debugData?: {\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n }\n dashboardFilters?: DashboardFilter[]\n configEagerLoad?: boolean\n loadingComponent?: ReactNode\n colorPalette?: ColorPalette\n containerProps?: HTMLAttributes<HTMLDivElement>\n headerProps?: HTMLAttributes<HTMLDivElement>\n onToggleFilter: (portletId: string, filterId: string) => void\n onRefresh: (portletId: string) => void\n onDuplicate: (portletId: string) => void\n onEdit: (portlet: PortletConfig) => void\n onDelete: (portletId: string) => void\n onOpenFilterConfig: (portlet: PortletConfig) => void\n onDebugDataReady: (portletId: string, data: {\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n }) => void\n setPortletRef: (portletId: string, element: HTMLDivElement | null) => void\n setPortletComponentRef: (portletId: string, element: { refresh: () => void } | null) => void\n icons: {\n RefreshIcon: ComponentType<{ className?: string; style?: CSSProperties }>\n EditIcon: ComponentType<{ className?: string; style?: CSSProperties }>\n DeleteIcon: ComponentType<{ className?: string; style?: CSSProperties }>\n CopyIcon: ComponentType<{ className?: string; style?: CSSProperties }>\n FilterIcon: ComponentType<{ className?: string; style?: CSSProperties }>\n }\n}\n\nexport default function DashboardPortletCard({\n portlet,\n editable,\n isEditMode,\n selectedFilterId,\n debugData,\n dashboardFilters,\n configEagerLoad,\n loadingComponent,\n colorPalette,\n containerProps,\n headerProps,\n onToggleFilter,\n onRefresh,\n onDuplicate,\n onEdit,\n onDelete,\n onOpenFilterConfig,\n onDebugDataReady,\n setPortletRef,\n setPortletComponentRef,\n icons\n}: DashboardPortletCardProps) {\n const hasSelectedFilter = selectedFilterId\n ? (portlet.dashboardFilterMapping || []).includes(selectedFilterId)\n : false\n const isInSelectionMode = !!selectedFilterId\n\n const mergedContainerClassName = [\n 'bg-dc-surface border rounded-lg flex flex-col h-full transition-all',\n isInSelectionMode ? 'cursor-pointer' : '',\n containerProps?.className\n ]\n .filter(Boolean)\n .join(' ')\n\n const mergedHeaderClassName = [\n 'flex items-center justify-between px-3 py-1.5 md:px-4 md:py-1 border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg portlet-drag-handle',\n isEditMode ? 'cursor-move' : 'cursor-default',\n headerProps?.className\n ]\n .filter(Boolean)\n .join(' ')\n\n const {\n onClick: containerOnClick,\n className: _containerClassName,\n style: containerStyle,\n ...restContainerProps\n } = containerProps ?? {}\n\n const {\n onClick: headerOnClick,\n className: _headerClassName,\n style: headerStyle,\n ...restHeaderProps\n } = headerProps ?? {}\n\n return (\n <div\n data-portlet-id={portlet.id}\n ref={el => setPortletRef(portlet.id, el)}\n className={mergedContainerClassName}\n style={{\n boxShadow: 'var(--dc-shadow-sm)',\n borderColor: isInSelectionMode && hasSelectedFilter\n ? 'var(--dc-primary)'\n : 'var(--dc-border)',\n borderWidth: isInSelectionMode && hasSelectedFilter ? '2px' : '1px',\n backgroundColor: isInSelectionMode && hasSelectedFilter\n ? 'rgba(var(--dc-primary-rgb), 0.05)'\n : 'var(--dc-surface)',\n opacity: isInSelectionMode && !hasSelectedFilter ? '0.5' : '1',\n ...containerStyle\n }}\n onClick={(event) => {\n if (isInSelectionMode && selectedFilterId) {\n event.stopPropagation()\n onToggleFilter(portlet.id, selectedFilterId)\n }\n containerOnClick?.(event)\n }}\n {...restContainerProps}\n >\n {(!portlet.displayConfig?.hideHeader || isEditMode) && (\n <div\n className={mergedHeaderClassName}\n style={headerStyle}\n onClick={(event) => {\n headerOnClick?.(event)\n }}\n {...restHeaderProps}\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <h3 className=\"font-semibold text-sm text-dc-text truncate\">{portlet.title}</h3>\n {editable && isEditMode && debugData && (\n <div\n onMouseDown={(event) => event.stopPropagation()}\n onClick={(event) => event.stopPropagation()}\n onTouchStart={(event) => event.stopPropagation()}\n onTouchEnd={(event) => event.stopPropagation()}\n >\n <DebugModal\n chartConfig={debugData.chartConfig}\n displayConfig={debugData.displayConfig}\n queryObject={debugData.queryObject}\n data={debugData.data}\n chartType={debugData.chartType}\n />\n </div>\n )}\n </div>\n <div\n className=\"flex items-center gap-1 shrink-0 ml-4 -mr-2\"\n onMouseDown={(event) => event.stopPropagation()}\n onClick={(event) => event.stopPropagation()}\n onTouchStart={(event) => event.stopPropagation()}\n onTouchEnd={(event) => event.stopPropagation()}\n >\n <button\n onClick={(event) => {\n event.stopPropagation()\n onRefresh(portlet.id)\n }}\n onTouchEnd={(event) => {\n event.stopPropagation()\n event.preventDefault()\n onRefresh(portlet.id)\n }}\n disabled={isInSelectionMode}\n className={`p-1 bg-transparent border-none rounded-sm text-dc-text-secondary transition-colors ${\n isInSelectionMode ? 'cursor-not-allowed opacity-50' : 'cursor-pointer hover:bg-dc-surface-hover'\n }`}\n title=\"Refresh portlet data\"\n >\n <icons.RefreshIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n\n {editable && isEditMode && !isInSelectionMode && (\n <>\n <button\n onClick={(event) => {\n event.stopPropagation()\n onOpenFilterConfig(portlet)\n }}\n onTouchEnd={(event) => {\n event.stopPropagation()\n event.preventDefault()\n onOpenFilterConfig(portlet)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm cursor-pointer hover:bg-dc-surface-hover transition-colors relative\"\n title={`Configure dashboard filters${portlet.dashboardFilterMapping && portlet.dashboardFilterMapping.length > 0 ? ` (${portlet.dashboardFilterMapping.length} active)` : ''}`}\n style={{\n color: portlet.dashboardFilterMapping && portlet.dashboardFilterMapping.length > 0\n ? 'var(--dc-primary)'\n : 'var(--dc-text-secondary)'\n }}\n >\n <icons.FilterIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n\n <button\n onClick={(event) => {\n event.stopPropagation()\n onDuplicate(portlet.id)\n }}\n onTouchEnd={(event) => {\n event.stopPropagation()\n event.preventDefault()\n onDuplicate(portlet.id)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Duplicate portlet\"\n >\n <icons.CopyIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n <button\n onClick={(event) => {\n event.stopPropagation()\n onEdit(portlet)\n }}\n onTouchEnd={(event) => {\n event.stopPropagation()\n event.preventDefault()\n onEdit(portlet)\n }}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Edit portlet\"\n >\n <icons.EditIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n <button\n onClick={(event) => {\n event.stopPropagation()\n onDelete(portlet.id)\n }}\n onTouchEnd={(event) => {\n event.stopPropagation()\n event.preventDefault()\n onDelete(portlet.id)\n }}\n className=\"p-1 mr-0.5 bg-transparent border-none rounded-sm cursor-pointer hover:bg-dc-danger-bg text-dc-danger transition-colors\"\n title=\"Delete portlet\"\n >\n <icons.DeleteIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n </>\n )}\n </div>\n </div>\n )}\n\n <div className=\"flex-1 px-2 py-3 md:px-4 md:py-4 min-h-0 overflow-visible flex flex-col\">\n <AnalyticsPortlet\n ref={el => setPortletComponentRef(portlet.id, el)}\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n dashboardFilters={dashboardFilters}\n dashboardFilterMapping={portlet.dashboardFilterMapping}\n eagerLoad={portlet.eagerLoad ?? configEagerLoad ?? false}\n title={portlet.title}\n height=\"100%\"\n colorPalette={colorPalette}\n loadingComponent={loadingComponent}\n onDebugDataReady={(data) => onDebugDataReady(portlet.id, data)}\n />\n </div>\n </div>\n )\n}\n","import { useState, type HTMLAttributes, type ReactNode, type MouseEvent, type DragEvent } from 'react'\nimport type { DashboardGridSettings, PortletConfig, RowLayout } from '../types'\n\ninterface RowManagedLayoutProps {\n rows: RowLayout[]\n portlets: PortletConfig[]\n gridSettings: DashboardGridSettings\n gridWidth: number\n canEdit: boolean\n isDragging: boolean\n onRowResize: (rowIndex: number, event: MouseEvent<HTMLDivElement>) => void\n onColumnResize: (rowIndex: number, columnIndex: number, event: MouseEvent<HTMLDivElement>) => void\n onPortletDragStart: (rowIndex: number, columnIndex: number, portletId: string, event: DragEvent<HTMLDivElement>) => void\n onPortletDragEnd: () => void\n onRowDrop: (rowIndex: number, insertIndex: number | null) => void\n onNewRowDrop: (insertIndex: number) => void\n renderPortlet: (portlet: PortletConfig, containerProps?: HTMLAttributes<HTMLDivElement>, headerProps?: HTMLAttributes<HTMLDivElement>) => ReactNode\n}\n\nconst COLUMN_GAP = 16\n\nexport default function RowManagedLayout({\n rows,\n portlets,\n gridSettings,\n gridWidth,\n canEdit,\n isDragging,\n onRowResize,\n onColumnResize,\n onPortletDragStart,\n onPortletDragEnd,\n onRowDrop,\n onNewRowDrop,\n renderPortlet\n}: RowManagedLayoutProps) {\n const portletMap = new Map(portlets.map(portlet => [portlet.id, portlet]))\n const [activeDropKey, setActiveDropKey] = useState<string | null>(null)\n\n const setDropActive = (key: string | null) => {\n setActiveDropKey(key)\n }\n\n const isDragActive = isDragging || activeDropKey !== null\n\n const topDropActive = activeDropKey === 'row-insert-0'\n const bottomDropActive = activeDropKey === 'row-bottom'\n\n return (\n <div\n className={`dc-row-layout${canEdit ? ' dc-row-layout-editable' : ''}${isDragActive ? ' dc-row-layout-dragging' : ''}`}\n style={{\n ['--dc-row-gap' as string]: '24px',\n ['--dc-column-gap' as string]: `${COLUMN_GAP}px`,\n ['--dc-top-drop-space' as string]: topDropActive ? '24px' : '0px',\n ['--dc-bottom-drop-space' as string]: bottomDropActive ? '24px' : '0px'\n }}\n >\n {canEdit && (\n <div\n className={`dc-row-boundary-drop dc-row-boundary-drop-top dc-split-handle${activeDropKey === 'row-insert-0' ? ' dc-drop-zone-active' : ''}`}\n onDragOver={(event) => {\n event.preventDefault()\n setDropActive('row-insert-0')\n }}\n onDragLeave={() => setDropActive(null)}\n onDrop={(event) => {\n event.preventDefault()\n setDropActive(null)\n onNewRowDrop(0)\n }}\n />\n )}\n {rows.map((row, rowIndex) => {\n const rowHeight = row.h * gridSettings.rowHeight\n const safeGridWidth = gridWidth || gridSettings.cols * gridSettings.rowHeight\n const paddingLeft = activeDropKey === `row-${rowIndex}-insert-0` ? COLUMN_GAP : 0\n const paddingRight = activeDropKey === `row-${rowIndex}-insert-${row.columns.length}` ? COLUMN_GAP : 0\n const rowContentWidth = safeGridWidth - (row.columns.length - 1) * COLUMN_GAP - paddingLeft - paddingRight\n const unitWidth = rowContentWidth / gridSettings.cols\n\n return (\n <div key={row.id} className=\"dc-row-layout-row-wrapper\">\n <div\n className=\"dc-row-layout-row\"\n style={{ height: rowHeight, paddingLeft, paddingRight }}\n >\n {row.columns.map((column, columnIndex) => {\n const portlet = portletMap.get(column.portletId)\n if (!portlet) return null\n const width = column.w * unitWidth\n\n const containerProps: HTMLAttributes<HTMLDivElement> = {\n draggable: canEdit,\n onDragStart: (event) => onPortletDragStart(rowIndex, columnIndex, portlet.id, event),\n onDragEnd: () => {\n setDropActive(null)\n onPortletDragEnd()\n },\n className: 'dc-row-layout-column'\n }\n\n return (\n <div\n key={portlet.id}\n className=\"dc-row-layout-column-wrapper\"\n style={{\n flex: `0 0 ${width}px`,\n maxWidth: `${width}px`\n }}\n >\n {renderPortlet(portlet, containerProps)}\n {columnIndex < row.columns.length - 1 && (\n <div\n className={`dc-column-resize-handle dc-split-handle${activeDropKey === `row-${rowIndex}-insert-${columnIndex + 1}` ? ' dc-drop-zone-active' : ''}`}\n onMouseDown={(event) => onColumnResize(rowIndex, columnIndex, event)}\n onDragOver={(event) => {\n if (!canEdit) return\n event.preventDefault()\n setDropActive(`row-${rowIndex}-insert-${columnIndex + 1}`)\n }}\n onDragLeave={() => setDropActive(null)}\n onDrop={(event) => {\n if (!canEdit) return\n event.preventDefault()\n event.stopPropagation()\n setDropActive(null)\n onRowDrop(rowIndex, columnIndex + 1)\n }}\n />\n )}\n </div>\n )\n })}\n </div>\n {canEdit && (\n <>\n <div\n className={`dc-row-edge-drop dc-row-edge-drop-left dc-split-handle${activeDropKey === `row-${rowIndex}-insert-0` ? ' dc-drop-zone-active' : ''}`}\n onDragOver={(event) => {\n event.preventDefault()\n setDropActive(`row-${rowIndex}-insert-0`)\n }}\n onDragLeave={() => {\n setDropActive(null)\n }}\n onDrop={(event) => {\n event.preventDefault()\n setDropActive(null)\n onRowDrop(rowIndex, 0)\n }}\n />\n <div\n className={`dc-row-edge-drop dc-row-edge-drop-right dc-split-handle${activeDropKey === `row-${rowIndex}-insert-${row.columns.length}` ? ' dc-drop-zone-active' : ''}`}\n onDragOver={(event) => {\n event.preventDefault()\n setDropActive(`row-${rowIndex}-insert-${row.columns.length}`)\n }}\n onDragLeave={() => {\n setDropActive(null)\n }}\n onDrop={(event) => {\n event.preventDefault()\n setDropActive(null)\n onRowDrop(rowIndex, row.columns.length)\n }}\n />\n </>\n )}\n {canEdit && (\n <div\n className={`dc-row-resize-handle dc-split-handle${activeDropKey === `row-insert-${rowIndex + 1}` ? ' dc-drop-zone-active' : ''}`}\n onMouseDown={(event) => onRowResize(rowIndex, event)}\n onDragOver={(event) => {\n event.preventDefault()\n setDropActive(`row-insert-${rowIndex + 1}`)\n }}\n onDragLeave={() => setDropActive(null)}\n onDrop={(event) => {\n event.preventDefault()\n setDropActive(null)\n onNewRowDrop(rowIndex + 1)\n }}\n />\n )}\n </div>\n )\n })}\n {canEdit && (\n <div\n className={`dc-row-boundary-drop dc-row-boundary-drop-bottom dc-split-handle${activeDropKey === 'row-bottom' ? ' dc-drop-zone-active' : ''}`}\n onDragOver={(event) => {\n event.preventDefault()\n setDropActive('row-bottom')\n }}\n onDragLeave={() => setDropActive(null)}\n onDrop={(event) => {\n event.preventDefault()\n setDropActive(null)\n onNewRowDrop(rows.length)\n }}\n />\n )}\n </div>\n )\n}\n","import React, { useEffect, useCallback } from 'react'\n\nexport interface ModalProps {\n isOpen: boolean\n onClose: () => void\n title?: string\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'full' | 'fullscreen' | 'fullscreen-mobile'\n closeOnBackdropClick?: boolean\n closeOnEscape?: boolean\n showCloseButton?: boolean\n className?: string\n children: React.ReactNode\n footer?: React.ReactNode\n noPadding?: boolean\n}\n\nconst Modal: React.FC<ModalProps> = ({\n isOpen,\n onClose,\n title,\n size = 'md',\n closeOnBackdropClick = true,\n closeOnEscape = true,\n showCloseButton = true,\n children,\n footer,\n noPadding = false\n}) => {\n // Handle ESC key press\n const handleEscapeKey = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape' && closeOnEscape) {\n onClose()\n }\n }, [closeOnEscape, onClose])\n\n\n // Manage ESC key listener and body scroll\n useEffect(() => {\n if (isOpen) {\n // Add ESC key listener\n if (closeOnEscape) {\n document.addEventListener('keydown', handleEscapeKey)\n }\n\n // Prevent body scroll when modal is open\n document.body.style.overflow = 'hidden'\n } else {\n // Restore body scroll\n document.body.style.overflow = 'unset'\n }\n\n // Cleanup\n return () => {\n document.removeEventListener('keydown', handleEscapeKey)\n document.body.style.overflow = 'unset'\n }\n }, [isOpen, closeOnEscape, handleEscapeKey])\n\n\n if (!isOpen) return null\n\n const getSizeClasses = () => {\n switch (size) {\n case 'sm':\n return 'max-w-md'\n case 'md':\n return 'max-w-lg'\n case 'lg':\n return 'max-w-2xl'\n case 'xl':\n return 'max-w-6xl'\n case 'xxl':\n return 'max-w-[1400px]' // Good for retina/mac displays\n case 'full':\n return 'max-w-7xl'\n case 'fullscreen':\n return 'w-[90vw] h-[90vh] max-w-none'\n case 'fullscreen-mobile':\n return 'w-full h-full md:w-[min(90vw,1400px)] md:h-[90vh]'\n default:\n return 'max-w-lg'\n }\n }\n\n return (\n <div\n className={`fixed inset-0 z-50 backdrop-blur-md ${size === 'fullscreen-mobile' ? 'flex md:flex md:items-center md:justify-center' : 'flex items-center justify-center'}`}\n style={{ backgroundColor: 'var(--dc-overlay)' }}\n onClick={closeOnBackdropClick ? onClose : undefined}\n >\n <div\n className={`relative bg-dc-surface border border-dc-border ${size === 'fullscreen-mobile' ? 'rounded-none md:rounded-lg' : 'rounded-lg'} ${size === 'fullscreen' || size === 'fullscreen-mobile' ? '' : 'mx-4'} ${getSizeClasses()} ${size === 'fullscreen' || size === 'fullscreen-mobile' ? '' : 'max-h-[90vh]'} flex flex-col`}\n style={{ boxShadow: 'var(--dc-shadow-2xl)' }}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? 'modal-title' : undefined}\n >\n {/* Header */}\n {(title || showCloseButton) && (\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-dc-border\">\n {title && (\n <h2 id=\"modal-title\" className=\"text-xl font-semibold text-dc-text\">\n {title}\n </h2>\n )}\n {showCloseButton && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-dc-text-muted hover:text-dc-text-secondary transition-colors p-2 -mr-2\"\n aria-label=\"Close modal\"\n >\n <svg width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n )}\n\n {/* Content */}\n <div className={`flex-1 overflow-y-auto ${noPadding ? '' : 'px-6 py-4'}`}>\n {children}\n </div>\n\n {/* Footer */}\n {footer && (\n <div className=\"flex items-center justify-end space-x-3 px-6 py-4 border-t border-dc-border bg-dc-surface-secondary\">\n {footer}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default Modal","import React from 'react'\nimport { getMeasureTypeIcon } from '../icons'\n\n/**\n * Get the appropriate icon component for a given measure type\n * All icons use amber coloring for consistency\n */\nexport function getMeasureIcon(\n measureType: string | undefined,\n className: string = 'w-4 h-4'\n): React.ReactElement {\n const IconComponent = getMeasureTypeIcon(measureType)\n return <IconComponent className={className} />\n}\n\n/**\n * Get all available measure type icons\n * Useful for documentation or UI that shows all measure types\n */\nexport function getAllMeasureIcons(): Record<string, React.ReactElement> {\n const types = ['count', 'countDistinct', 'countDistinctApprox', 'sum', 'avg', 'min', 'max', 'runningTotal', 'calculated', 'number']\n const icons: Record<string, React.ReactElement> = {}\n\n for (const type of types) {\n const IconComponent = getMeasureTypeIcon(type)\n icons[type] = <IconComponent className=\"w-4 h-4\" />\n }\n\n return icons\n}\n","/**\n * CubeMetaExplorer Component\n * \n * Displays the cube schema in a collapsible tree view.\n * Users can click on dimensions, measures, and time dimensions to add them to their query.\n */\n\nimport React, { useState, Suspense, lazy, memo } from 'react'\nimport type { CubeMetaExplorerProps, MetaCube, MetaField } from './types'\nimport { getMeasureIcon } from '../../utils/measureIcons'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport { getIcon } from '../../icons'\n\n// Lazy load the relationship diagram (imports reactflow which is large)\nconst CubeRelationshipDiagram = lazy(() =>\n import('../CubeRelationshipDiagram').then(mod => ({ default: mod.CubeRelationshipDiagram }))\n)\n\ntype SchemaViewType = 'tree' | 'diagram'\n\nconst CubeMetaExplorer: React.FC<CubeMetaExplorerProps> = ({\n schema,\n schemaStatus,\n schemaError,\n selectedFields,\n onFieldSelect,\n onFieldDeselect,\n onRetrySchema,\n onOpenSettings,\n onViewTypeChange,\n isExpanded = false\n}) => {\n // Get icons\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronRightIcon = getIcon('chevronRight')\n const WarningIcon = getIcon('warning')\n const RefreshIcon = getIcon('refresh')\n const SettingsIcon = getIcon('settings')\n const MeasureIcon = getIcon('measure')\n const DimensionIcon = getIcon('dimension')\n const TimeDimensionIcon = getIcon('timeDimension')\n const SegmentIcon = getIcon('segment')\n const MenuIcon = getIcon('menu')\n\n // Get features from context to check if schema diagram is enabled\n const { features } = useCubeContext()\n const showSchemaDiagram = features?.showSchemaDiagram === true\n\n const [expandedCubes, setExpandedCubes] = useState<Set<string>>(new Set())\n const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set())\n const [searchTerm, setSearchTerm] = useState('')\n const [viewType, setViewType] = useState<SchemaViewType>('tree')\n\n // Track the original expansion state before search\n const [preSearchExpandedCubes, setPreSearchExpandedCubes] = useState<Set<string> | null>(null)\n const [preSearchExpandedSections, setPreSearchExpandedSections] = useState<Set<string> | null>(null)\n\n // Auto-switch to diagram view when expanded (only if schema diagram is enabled)\n React.useEffect(() => {\n if (isExpanded && showSchemaDiagram) {\n setViewType('diagram')\n }\n }, [isExpanded, showSchemaDiagram])\n\n\n // Auto-expand cubes and sections that contain search matches\n React.useEffect(() => {\n if (!schema) {\n return\n }\n\n const hasSearchTerm = searchTerm.trim().length > 0\n\n if (hasSearchTerm) {\n // Save current state before expanding for search (only if not already saved)\n if (preSearchExpandedCubes === null) {\n setPreSearchExpandedCubes(new Set(expandedCubes))\n setPreSearchExpandedSections(new Set(expandedSections))\n }\n\n const newExpandedCubes = new Set<string>()\n const newExpandedSections = new Set<string>()\n\n schema.cubes.forEach((cube: MetaCube) => {\n let cubeHasMatches = false\n\n // Check measures\n const matchingMeasures = cube.measures.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingMeasures.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-measures`)\n }\n\n // Check regular dimensions\n const regularDimensions = cube.dimensions.filter(d => d.type !== 'time')\n const matchingDimensions = regularDimensions.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingDimensions.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-dimensions`)\n }\n\n // Check time dimensions\n const timeDimensions = cube.dimensions.filter(d => d.type === 'time')\n const matchingTimeDimensions = timeDimensions.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n if (matchingTimeDimensions.length > 0) {\n cubeHasMatches = true\n newExpandedSections.add(`${cube.name}-timeDimensions`)\n }\n\n // If cube has any matches, expand it\n if (cubeHasMatches) {\n newExpandedCubes.add(cube.name)\n }\n })\n\n // Combine pre-search state with search expansions\n const combinedCubes = new Set([...(preSearchExpandedCubes || []), ...newExpandedCubes])\n const combinedSections = new Set([...(preSearchExpandedSections || []), ...newExpandedSections])\n \n setExpandedCubes(combinedCubes)\n setExpandedSections(combinedSections)\n } else {\n // No search term - restore original state if we have it saved\n if (preSearchExpandedCubes !== null && preSearchExpandedSections !== null) {\n setExpandedCubes(preSearchExpandedCubes)\n setExpandedSections(preSearchExpandedSections)\n setPreSearchExpandedCubes(null)\n setPreSearchExpandedSections(null)\n }\n }\n }, [schema, searchTerm, preSearchExpandedCubes, preSearchExpandedSections])\n\n // Loading state\n if (schemaStatus === 'loading') {\n return (\n <div className=\"h-full flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 mx-auto mb-3\" style={{ borderBottomColor: 'var(--dc-primary)' }}></div>\n <div className=\"text-sm font-semibold mb-1\">Loading Schema...</div>\n <div className=\"text-xs\">Fetching cube metadata</div>\n </div>\n </div>\n )\n }\n\n // Error state\n if (schemaStatus === 'error') {\n const isCorsError = schemaError?.toLowerCase().includes('cors') || \n schemaError?.toLowerCase().includes('fetch')\n \n return (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center max-w-sm p-6\">\n <WarningIcon className=\"w-12 h-12 mx-auto text-dc-error mb-4\" />\n <div className=\"text-sm font-semibold text-dc-text mb-2\">\n Failed to Load Schema\n </div>\n <div className=\"text-xs text-dc-text-secondary mb-4\">\n {isCorsError ? (\n <>\n CORS error detected. The API endpoint may be incorrect or not accessible.\n </>\n ) : (\n <>\n {schemaError || 'Unable to connect to the Cube.js API'}\n </>\n )}\n </div>\n \n <div className=\"space-y-2\">\n {onRetrySchema && (\n <button\n onClick={onRetrySchema}\n className=\"w-full flex items-center justify-center space-x-2 px-3 py-2 text-sm font-medium text-dc-accent bg-dc-accent-bg border border-dc-accent rounded-md hover:bg-dc-accent-bg focus:outline-hidden focus:ring-2 focus:ring-dc-accent\"\n >\n <RefreshIcon className=\"w-4 h-4\" />\n <span>Retry</span>\n </button>\n )}\n\n {onOpenSettings && (\n <button\n onClick={onOpenSettings}\n className=\"w-full flex items-center justify-center space-x-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-dc-accent\"\n >\n <SettingsIcon className=\"w-4 h-4\" />\n <span>Check API Settings</span>\n </button>\n )}\n </div>\n \n {isCorsError && (\n <div className=\"mt-4 p-3 bg-dc-warning-bg border border-dc-warning rounded-md\">\n <div className=\"text-xs text-dc-warning\">\n <div className=\"font-medium mb-1\">Common solutions:</div>\n <ul className=\"list-disc list-inside space-y-1\">\n <li>Verify the Base API URL is correct</li>\n <li>Ensure the server supports CORS</li>\n <li>Check if authentication is required</li>\n </ul>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n }\n\n // No schema loaded yet\n if (!schema) {\n return (\n <div className=\"h-full flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No Schema</div>\n <div className=\"text-xs\">Schema not loaded</div>\n </div>\n </div>\n )\n }\n\n const toggleCubeExpansion = (cubeName: string) => {\n const newExpanded = new Set(expandedCubes)\n if (newExpanded.has(cubeName)) {\n newExpanded.delete(cubeName)\n } else {\n newExpanded.add(cubeName)\n }\n setExpandedCubes(newExpanded)\n \n // If we're in search mode, also update the pre-search state\n if (preSearchExpandedCubes !== null) {\n const newPreSearchExpanded = new Set(preSearchExpandedCubes)\n if (newPreSearchExpanded.has(cubeName)) {\n newPreSearchExpanded.delete(cubeName)\n } else {\n newPreSearchExpanded.add(cubeName)\n }\n setPreSearchExpandedCubes(newPreSearchExpanded)\n }\n }\n\n const toggleSectionExpansion = (sectionKey: string) => {\n const newExpanded = new Set(expandedSections)\n if (newExpanded.has(sectionKey)) {\n newExpanded.delete(sectionKey)\n } else {\n newExpanded.add(sectionKey)\n }\n setExpandedSections(newExpanded)\n \n // If we're in search mode, also update the pre-search state\n if (preSearchExpandedSections !== null) {\n const newPreSearchExpanded = new Set(preSearchExpandedSections)\n if (newPreSearchExpanded.has(sectionKey)) {\n newPreSearchExpanded.delete(sectionKey)\n } else {\n newPreSearchExpanded.add(sectionKey)\n }\n setPreSearchExpandedSections(newPreSearchExpanded)\n }\n }\n\n const handleFieldClick = (field: MetaField, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n const isSelected = (() => {\n switch (fieldType) {\n case 'measures':\n return selectedFields.measures.includes(field.name)\n case 'dimensions':\n return selectedFields.dimensions.includes(field.name)\n case 'timeDimensions':\n return selectedFields.timeDimensions.includes(field.name)\n default:\n return false\n }\n })()\n\n if (isSelected) {\n onFieldDeselect(field.name, fieldType)\n } else {\n onFieldSelect(field.name, fieldType)\n }\n }\n\n const filterFields = (fields: MetaField[]): MetaField[] => {\n if (!searchTerm) return fields\n return fields.filter(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n }\n\n const cubeHasMatches = (cube: MetaCube): boolean => {\n if (!searchTerm.trim()) return true\n \n const measureMatches = cube.measures.some(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n \n const dimensionMatches = cube.dimensions.some(field => \n field.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n field.title.toLowerCase().includes(searchTerm.toLowerCase())\n )\n \n return measureMatches || dimensionMatches\n }\n\n const FieldItem: React.FC<{ \n field: MetaField\n fieldType: 'measures' | 'dimensions' | 'timeDimensions'\n icon: React.ReactNode\n }> = ({ field, fieldType, icon }) => {\n const isSelected = (() => {\n switch (fieldType) {\n case 'measures':\n return selectedFields.measures.includes(field.name)\n case 'dimensions':\n return selectedFields.dimensions.includes(field.name)\n case 'timeDimensions':\n return selectedFields.timeDimensions.includes(field.name)\n default:\n return false\n }\n })()\n\n const getSelectedStyles = () => {\n if (!isSelected) return 'hover:bg-dc-surface-hover text-dc-text-secondary'\n\n switch (fieldType) {\n case 'measures':\n return 'bg-dc-warning-bg text-dc-warning border border-dc-warning'\n case 'dimensions':\n return 'bg-dc-success-bg text-dc-success border border-dc-success'\n case 'timeDimensions':\n return 'bg-dc-accent-bg text-dc-accent border border-dc-accent'\n default:\n return 'bg-dc-accent-bg text-dc-accent border border-dc-accent'\n }\n }\n\n const getIconColor = () => {\n if (!isSelected) return 'text-dc-text-muted'\n \n switch (fieldType) {\n case 'measures':\n return 'text-dc-warning'\n case 'dimensions':\n return 'text-dc-success'\n case 'timeDimensions':\n return 'text-dc-accent'\n default:\n return 'text-dc-accent'\n }\n }\n\n const getCheckmarkColor = () => {\n switch (fieldType) {\n case 'measures':\n return 'text-dc-warning'\n case 'dimensions':\n return 'text-dc-success'\n case 'timeDimensions':\n return 'text-dc-accent'\n default:\n return 'text-dc-accent'\n }\n }\n\n return (\n <div\n className={`flex items-center px-2 py-1.5 text-xs cursor-pointer rounded-md transition-colors ${getSelectedStyles()}`}\n onClick={() => handleFieldClick(field, fieldType)}\n title={field.description || field.title}\n >\n <div className={`mr-1.5 ${getIconColor()}`}>\n {React.cloneElement(icon as React.ReactElement, { className: 'w-4 h-4' })}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium truncate text-xs\">{field.shortTitle}</div>\n <div className=\"text-xs text-dc-text-muted truncate\">{field.name}</div>\n </div>\n {isSelected && (\n <div className={`ml-1.5 ${getCheckmarkColor()}`}>\n <svg className=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clipRule=\"evenodd\" />\n </svg>\n </div>\n )}\n </div>\n )\n }\n\n const SectionHeader: React.FC<{\n title: string\n count: number\n sectionKey: string\n icon: React.ReactNode\n }> = ({ title, count, sectionKey, icon }) => {\n const isExpanded = expandedSections.has(sectionKey)\n \n // Get section type from sectionKey to apply consistent colors\n const getSectionType = (): 'dimensions' | 'timeDimensions' | 'measures' => {\n if (sectionKey.includes('-dimensions') && !sectionKey.includes('-timeDimensions')) {\n return 'dimensions'\n } else if (sectionKey.includes('-timeDimensions')) {\n return 'timeDimensions'\n } else {\n return 'measures'\n }\n }\n \n const getSectionColorClasses = () => {\n const sectionType = getSectionType()\n switch (sectionType) {\n case 'dimensions':\n return 'text-dc-success'\n case 'timeDimensions':\n return 'text-dc-accent'\n case 'measures':\n return 'text-dc-warning'\n default:\n return 'text-dc-text-secondary'\n }\n }\n \n return (\n <div\n className={`flex items-center px-2 py-1 text-sm font-semibold cursor-pointer hover:bg-dc-surface-hover rounded-md ${getSectionColorClasses()}`}\n onClick={() => toggleSectionExpansion(sectionKey)}\n >\n <div className=\"mr-1.5\">\n {isExpanded ? (\n <ChevronDownIcon className=\"w-3 h-3\" />\n ) : (\n <ChevronRightIcon className=\"w-3 h-3\" />\n )}\n </div>\n <div className=\"mr-1.5\">\n {icon}\n </div>\n <span className=\"flex-1\">{title}</span>\n <span className=\"text-xs text-dc-text-muted bg-dc-surface-secondary px-1.5 py-0.5 rounded-full\">\n {count}\n </span>\n </div>\n )\n }\n\n const NoMatchesMessage: React.FC = () => (\n <div className=\"flex items-center justify-center py-8 text-center\">\n <div className=\"max-w-sm\">\n <div className=\"text-dc-text-muted mb-2\">\n <svg className=\"w-12 h-12 mx-auto\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n </div>\n <div className=\"text-sm font-medium text-dc-text mb-1\">No matches found</div>\n <div className=\"text-xs text-dc-text-muted mb-3\">\n No fields match your search term \"{searchTerm}\"\n </div>\n <button\n onClick={() => setSearchTerm('')}\n className=\"inline-flex items-center px-3 py-1.5 text-xs font-medium text-dc-accent bg-dc-accent-bg border border-dc-accent rounded-md hover:bg-dc-accent-bg focus:outline-hidden focus:ring-2 focus:ring-dc-accent\"\n >\n Clear search\n </button>\n </div>\n </div>\n )\n\n return (\n <div className=\"flex-1 flex flex-col bg-dc-surface border border-dc-border rounded-lg min-h-0\">\n {/* Header */}\n <div className=\"border-b border-dc-border\">\n <div className=\"p-3 pb-0\">\n <div className=\"flex items-center justify-between mb-3\">\n <div>\n <h3 className=\"text-base font-semibold text-dc-text\">\n {viewType === 'diagram' ? 'Schema Diagram' : 'Schema Explorer'}\n </h3>\n </div>\n <div className=\"flex items-center space-x-2\">\n {onOpenSettings && (\n <button\n onClick={onOpenSettings}\n className=\"p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors\"\n title=\"Open settings\"\n >\n <SettingsIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n\n {/* View Type Tabs and Search */}\n <div className=\"flex items-center gap-3 mb-3\">\n {showSchemaDiagram ? (\n <div className=\"flex space-x-1 bg-dc-surface-secondary p-1 rounded-md\">\n <button\n onClick={() => {\n setViewType('tree')\n onViewTypeChange?.('tree')\n }}\n className={`\n flex items-center px-3 py-1.5 rounded text-xs font-medium transition-colors\n ${viewType === 'tree'\n ? 'bg-dc-surface text-dc-text shadow-xs'\n : 'text-dc-text-secondary hover:text-dc-text'\n }\n `}\n >\n <MenuIcon className=\"w-3 h-3 mr-1.5\" />\n Fields\n </button>\n <button\n onClick={() => {\n setViewType('diagram')\n onViewTypeChange?.('diagram')\n }}\n className={`\n flex items-center px-3 py-1.5 rounded text-xs font-medium transition-colors\n ${viewType === 'diagram'\n ? 'bg-dc-surface text-dc-text shadow-xs'\n : 'text-dc-text-secondary hover:text-dc-text'\n }\n `}\n >\n <SegmentIcon className=\"w-3 h-3 mr-1.5\" />\n Schema\n </button>\n </div>\n ) : null}\n\n {/* Search input - visible for both views */}\n <div className=\"flex-1 relative min-w-0\">\n <input\n type=\"text\"\n placeholder=\"Search fields...\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n className=\"w-full px-2 py-1.5 border border-dc-border rounded-md text-sm bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n <div className=\"absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none\">\n <svg className=\"h-4 w-4 text-dc-text-muted\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n </div>\n </div>\n </div>\n </div>\n\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {viewType === 'diagram' && showSchemaDiagram ? (\n /* Diagram View - schema relationship diagram (only when enabled) */\n <div className=\"h-full\">\n <Suspense fallback={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"animate-pulse text-dc-text-muted\">Loading diagram...</div>\n </div>\n }>\n <CubeRelationshipDiagram\n className=\"h-full\"\n onCubeClick={(cubeName) => {\n if (!isExpanded) {\n // Auto-expand the clicked cube in tree view\n setExpandedCubes(prev => new Set([...prev, cubeName]))\n // Switch to tree view to show the expanded cube\n setViewType('tree')\n }\n }}\n onFieldClick={(cubeName, fieldName, fieldType) => {\n // Convert field type to QueryBuilder expected type and determine if time dimension\n let qbFieldType: 'measures' | 'dimensions' | 'timeDimensions'\n \n if (fieldType === 'measure') {\n qbFieldType = 'measures'\n } else {\n // For dimensions, check if it's a time dimension by looking at the schema\n const cube = schema?.cubes.find(c => c.name === cubeName)\n const dimension = cube?.dimensions.find(d => \n d.name === `${cubeName}.${fieldName}` || d.name === fieldName\n )\n \n qbFieldType = dimension?.type === 'time' ? 'timeDimensions' : 'dimensions'\n }\n \n const fullFieldName = `${cubeName}.${fieldName}`\n \n // Check if field is already selected\n const isSelected = selectedFields[qbFieldType].includes(fullFieldName)\n \n if (isSelected) {\n // Remove the field from the query\n onFieldDeselect(fullFieldName, qbFieldType)\n } else {\n // Add the field to the query\n onFieldSelect(fullFieldName, qbFieldType)\n }\n }}\n highlightedCubes={[\n ...selectedFields.measures.map(field => field.split('.')[0]),\n ...selectedFields.dimensions.map(field => field.split('.')[0]),\n ...selectedFields.timeDimensions.map(field => field.split('.')[0])\n ].filter((cube, index, arr) => arr.indexOf(cube) === index)} // Remove duplicates\n highlightedFields={[\n ...selectedFields.measures,\n ...selectedFields.dimensions,\n ...selectedFields.timeDimensions\n ]}\n searchTerm={searchTerm}\n />\n </Suspense>\n </div>\n ) : (\n /* Tree View - existing field list */\n <div className=\"h-full p-3 space-y-2 overflow-y-auto\">\n {(() => {\n // Filter cubes to only show those with matches (when searching)\n const filteredCubes = schema.cubes.filter(cubeHasMatches)\n \n // Show \"No matches\" message if searching but no cubes have matches\n if (searchTerm.trim() && filteredCubes.length === 0) {\n return <NoMatchesMessage />\n }\n \n return filteredCubes.map((cube: MetaCube) => {\n const isExpanded = expandedCubes.has(cube.name)\n const timeDimensions = cube.dimensions.filter(d => d.type === 'time')\n const regularDimensions = cube.dimensions.filter(d => d.type !== 'time')\n\n return (\n <div key={cube.name} className=\"border border-dc-border rounded-lg\">\n {/* Cube Header */}\n <div\n className=\"flex items-center px-3 py-2 cursor-pointer hover:bg-dc-surface-hover rounded-t-lg\"\n onClick={() => toggleCubeExpansion(cube.name)}\n >\n <div className=\"mr-2\">\n {isExpanded ? (\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-secondary\" />\n ) : (\n <ChevronRightIcon className=\"w-4 h-4 text-dc-text-secondary\" />\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"font-medium text-sm text-dc-text\">{cube.title}</div>\n <div className=\"text-xs text-dc-text-muted\">{cube.description}</div>\n </div>\n </div>\n\n {/* Cube Content */}\n {isExpanded && (\n <div className=\"border-t border-dc-border p-2 space-y-1\">\n {/* Dimensions - First (matching QueryPanel order) */}\n {regularDimensions.length > 0 && filterFields(regularDimensions).length > 0 && (\n <div>\n <SectionHeader\n title=\"Dimensions\"\n count={filterFields(regularDimensions).length}\n sectionKey={`${cube.name}-dimensions`}\n icon={<DimensionIcon className=\"w-4 h-4 text-dc-success\" />}\n />\n {expandedSections.has(`${cube.name}-dimensions`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(regularDimensions).map(dimension => (\n <FieldItem\n key={dimension.name}\n field={dimension}\n fieldType=\"dimensions\"\n icon={<DimensionIcon className=\"w-4 h-4\" />}\n />\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Time Dimensions - Second (matching QueryPanel order) */}\n {timeDimensions.length > 0 && filterFields(timeDimensions).length > 0 && (\n <div>\n <SectionHeader\n title=\"Time Dimensions\"\n count={filterFields(timeDimensions).length}\n sectionKey={`${cube.name}-timeDimensions`}\n icon={<TimeDimensionIcon className=\"w-4 h-4 text-dc-accent\" />}\n />\n {expandedSections.has(`${cube.name}-timeDimensions`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(timeDimensions).map(timeDimension => (\n <FieldItem\n key={timeDimension.name}\n field={timeDimension}\n fieldType=\"timeDimensions\"\n icon={<TimeDimensionIcon className=\"w-4 h-4\" />}\n />\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Measures - Third (matching QueryPanel order) */}\n {cube.measures.length > 0 && filterFields(cube.measures).length > 0 && (\n <div>\n <SectionHeader\n title=\"Measures\"\n count={filterFields(cube.measures).length}\n sectionKey={`${cube.name}-measures`}\n icon={<MeasureIcon className=\"w-4 h-4 text-dc-warning\" />}\n />\n {expandedSections.has(`${cube.name}-measures`) && (\n <div className=\"ml-5 space-y-1 mt-1\">\n {filterFields(cube.measures).map(measure => (\n <FieldItem\n key={measure.name}\n field={measure}\n fieldType=\"measures\"\n icon={getMeasureIcon(measure.type, 'w-4 h-4')}\n />\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n )\n })\n })()}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default memo(CubeMetaExplorer)\n","/**\n * Shared type definitions used across QueryBuilder and AnalysisBuilder\n */\n\nimport type { CubeQuery, FilterOperator } from '../types'\n\n// ============================================================================\n// Meta endpoint response types\n// ============================================================================\n\nexport interface MetaField {\n name: string // e.g., \"Employees.count\"\n title: string // e.g., \"Total Employees\"\n shortTitle: string // e.g., \"Total Employees\"\n type: string // e.g., \"count\", \"string\", \"time\", \"number\"\n description?: string // Optional description\n}\n\nexport interface MetaCube {\n name: string // e.g., \"Employees\"\n title: string // e.g., \"Employee Analytics\"\n description: string // e.g., \"Employee data and metrics\"\n measures: MetaField[] // e.g., \"Employees.count\"\n dimensions: MetaField[] // e.g., \"Employees.name\"\n segments: MetaField[] // Currently empty in examples\n}\n\nexport interface MetaResponse {\n cubes: MetaCube[]\n}\n\n// ============================================================================\n// Query analysis types for debugging transparency\n// ============================================================================\n\nexport type PrimaryCubeSelectionReason =\n | 'most_dimensions'\n | 'most_connected'\n | 'alphabetical_fallback'\n | 'single_cube'\n\nexport interface PrimaryCubeCandidate {\n cubeName: string\n dimensionCount: number\n joinCount: number\n canReachAll: boolean\n}\n\nexport interface PrimaryCubeAnalysis {\n selectedCube: string\n reason: PrimaryCubeSelectionReason\n explanation: string\n candidates?: PrimaryCubeCandidate[]\n}\n\nexport interface JoinPathStep {\n fromCube: string\n toCube: string\n relationship: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany'\n joinType: 'inner' | 'left' | 'right' | 'full'\n joinColumns: Array<{\n sourceColumn: string\n targetColumn: string\n }>\n junctionTable?: {\n tableName: string\n sourceColumns: string[]\n targetColumns: string[]\n }\n}\n\nexport interface JoinPathAnalysis {\n targetCube: string\n pathFound: boolean\n path?: JoinPathStep[]\n pathLength?: number\n error?: string\n visitedCubes?: string[]\n}\n\nexport interface PreAggregationAnalysis {\n cubeName: string\n cteAlias: string\n reason: string\n measures: string[]\n joinKeys: Array<{\n sourceColumn: string\n targetColumn: string\n }>\n}\n\nexport interface QuerySummary {\n queryType: 'single_cube' | 'multi_cube_join' | 'multi_cube_cte'\n joinCount: number\n cteCount: number\n hasPreAggregation: boolean\n}\n\nexport interface QueryAnalysis {\n timestamp: string\n cubeCount: number\n cubesInvolved: string[]\n primaryCube: PrimaryCubeAnalysis\n joinPaths: JoinPathAnalysis[]\n preAggregations: PreAggregationAnalysis[]\n querySummary: QuerySummary\n warnings?: string[]\n}\n\n// ============================================================================\n// Validation response from /dry-run endpoint\n// ============================================================================\n\nexport interface ValidationResult {\n valid?: boolean // Our custom property (may not be present in official Cube.js)\n error?: string\n query?: CubeQuery\n sql?: {\n sql: string[]\n params: any[]\n }\n queryType?: string // Always present in successful Cube.js responses\n normalizedQueries?: any[]\n queryOrder?: string[]\n transformedQueries?: any[]\n pivotQuery?: any\n complexity?: string\n cubesUsed?: string[]\n joinType?: string\n // Query analysis for debugging transparency\n analysis?: QueryAnalysis\n}\n\n// ============================================================================\n// Filter operator metadata\n// ============================================================================\n\nexport interface FilterOperatorMeta {\n label: string\n description: string\n requiresValues: boolean\n supportsMultipleValues: boolean\n valueType: 'string' | 'number' | 'date' | 'boolean' | 'any'\n fieldTypes: string[] // Which field types support this operator\n}\n\nexport const FILTER_OPERATORS: Record<FilterOperator, FilterOperatorMeta> = {\n // String operators\n equals: {\n label: 'equals',\n description: 'Exact match',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean', 'time']\n },\n notEquals: {\n label: 'not equals',\n description: 'Does not match',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean', 'time']\n },\n contains: {\n label: 'contains',\n description: 'Contains text (case insensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notContains: {\n label: 'not contains',\n description: 'Does not contain text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n startsWith: {\n label: 'starts with',\n description: 'Starts with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notStartsWith: {\n label: 'not starts with',\n description: 'Does not start with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n endsWith: {\n label: 'ends with',\n description: 'Ends with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notEndsWith: {\n label: 'not ends with',\n description: 'Does not end with text',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n like: {\n label: 'like',\n description: 'SQL LIKE pattern matching (case sensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notLike: {\n label: 'not like',\n description: 'SQL NOT LIKE pattern matching (case sensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n ilike: {\n label: 'ilike',\n description: 'SQL ILIKE pattern matching (case insensitive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // Numeric operators\n gt: {\n label: 'greater than',\n description: 'Greater than value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n gte: {\n label: 'greater than or equal',\n description: 'Greater than or equal to value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n lt: {\n label: 'less than',\n description: 'Less than value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n lte: {\n label: 'less than or equal',\n description: 'Less than or equal to value',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n between: {\n label: 'between',\n description: 'Between two values (inclusive)',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n notBetween: {\n label: 'not between',\n description: 'Not between two values',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'number',\n fieldTypes: ['number', 'count', 'sum', 'avg', 'min', 'max']\n },\n // Array operators\n in: {\n label: 'in',\n description: 'Matches any of the provided values',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean']\n },\n notIn: {\n label: 'not in',\n description: 'Does not match any of the provided values',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'boolean']\n },\n // Null/Empty operators\n set: {\n label: 'is set',\n description: 'Is not null/empty',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'time', 'boolean']\n },\n notSet: {\n label: 'is not set',\n description: 'Is null/empty',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'any',\n fieldTypes: ['string', 'number', 'time', 'boolean']\n },\n isEmpty: {\n label: 'is empty',\n description: 'Is empty string or null',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n isNotEmpty: {\n label: 'is not empty',\n description: 'Is not empty string and not null',\n requiresValues: false,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // Date operators\n inDateRange: {\n label: 'in date range',\n description: 'Between two dates',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n beforeDate: {\n label: 'before date',\n description: 'Before specified date',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n afterDate: {\n label: 'after date',\n description: 'After specified date',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'date',\n fieldTypes: ['time']\n },\n // Regex operators\n regex: {\n label: 'matches regex',\n description: 'Matches regular expression pattern',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n notRegex: {\n label: 'not matches regex',\n description: 'Does not match regular expression pattern',\n requiresValues: true,\n supportsMultipleValues: false,\n valueType: 'string',\n fieldTypes: ['string']\n },\n // PostgreSQL array operators\n arrayContains: {\n label: 'array contains all',\n description: 'Array field contains all specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n },\n arrayOverlaps: {\n label: 'array contains any',\n description: 'Array field contains any of the specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n },\n arrayContained: {\n label: 'array values in',\n description: 'All array field values are within specified values (PostgreSQL only)',\n requiresValues: true,\n supportsMultipleValues: true,\n valueType: 'string',\n fieldTypes: ['string']\n }\n}\n\n// ============================================================================\n// Date range types\n// ============================================================================\n\nexport type DateRangeType =\n | 'custom'\n | 'today'\n | 'yesterday'\n | 'this_week'\n | 'this_month'\n | 'this_quarter'\n | 'this_year'\n | 'last_7_days'\n | 'last_30_days'\n | 'last_week'\n | 'last_month'\n | 'last_quarter'\n | 'last_year'\n | 'last_12_months'\n | 'last_n_days'\n | 'last_n_weeks'\n | 'last_n_months'\n | 'last_n_quarters'\n | 'last_n_years'\n\nexport interface DateRangeOption {\n value: DateRangeType\n label: string\n}\n\nexport const DATE_RANGE_OPTIONS: DateRangeOption[] = [\n { value: 'custom', label: 'Custom' },\n { value: 'today', label: 'Today' },\n { value: 'yesterday', label: 'Yesterday' },\n { value: 'this_week', label: 'This week' },\n { value: 'this_month', label: 'This month' },\n { value: 'this_quarter', label: 'This quarter' },\n { value: 'this_year', label: 'This year' },\n { value: 'last_7_days', label: 'Last 7 days' },\n { value: 'last_30_days', label: 'Last 30 days' },\n { value: 'last_n_days', label: 'Last N days' },\n { value: 'last_week', label: 'Last week' },\n { value: 'last_n_weeks', label: 'Last N weeks' },\n { value: 'last_month', label: 'Last month' },\n { value: 'last_12_months', label: 'Last 12 months' },\n { value: 'last_n_months', label: 'Last N months' },\n { value: 'last_quarter', label: 'Last quarter' },\n { value: 'last_n_quarters', label: 'Last N quarters' },\n { value: 'last_year', label: 'Last year' },\n { value: 'last_n_years', label: 'Last N years' }\n] as const\n\n// ============================================================================\n// Time dimension granularity options\n// ============================================================================\n\nexport const TIME_GRANULARITIES = [\n { value: 'hour', label: 'Hour' },\n { value: 'day', label: 'Day' },\n { value: 'week', label: 'Week' },\n { value: 'month', label: 'Month' },\n { value: 'quarter', label: 'Quarter' },\n { value: 'year', label: 'Year' }\n] as const\n\nexport type TimeGranularity = typeof TIME_GRANULARITIES[number]['value']\n","/**\n * FilterValueSelector Component\n * \n * Smart input component that adapts to operator type:\n * - Combo box for equals/notEquals with API-fetched values\n * - Number input for numeric operators\n * - Date picker for date operators\n * - No input for set/notSet operators\n */\n\nimport React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'\nimport { getIcon } from '../../icons'\nimport { useFilterValues } from '../../hooks/useFilterValues'\nimport { useDebounce } from '../../hooks/useDebounce'\nimport type { FilterValueSelectorProps } from './types'\nimport { FILTER_OPERATORS } from './types'\n\nconst ChevronDownIcon = getIcon('chevronDown')\nconst CloseIcon = getIcon('close')\n\nconst FilterValueSelector: React.FC<FilterValueSelectorProps> = ({\n fieldName,\n operator,\n values,\n onValuesChange,\n schema\n}) => {\n const operatorMeta = FILTER_OPERATORS[operator]\n const [isOpen, setIsOpen] = useState(false)\n const [searchText, setSearchText] = useState('')\n const [hasLoadedInitial, setHasLoadedInitial] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n const lastSearchedTerm = useRef<string>('')\n \n // Debounce the search text\n const debouncedSearchText = useDebounce(searchText, 300)\n \n // Check if the field is a dimension (not a measure)\n const isDimension = useMemo(() => schema ? schema.cubes.some(cube => \n cube.dimensions.some(dim => dim.name === fieldName)\n ) : false, [schema, fieldName])\n \n // Check if the field is a time dimension\n const isTimeDimension = useMemo(() => schema ? schema.cubes.some(cube => \n cube.dimensions.some(dim => dim.name === fieldName && dim.type === 'time')\n ) : false, [schema, fieldName])\n \n // Fetch distinct values for combo box (only for equals/notEquals/in/notIn on non-time dimensions)\n const shouldFetchValues = useMemo(() => \n (['equals', 'notEquals', 'in', 'notIn'].includes(operator)) && isDimension && !isTimeDimension,\n [operator, isDimension, isTimeDimension]\n )\n const shouldShowComboBox = shouldFetchValues\n \n const { \n values: distinctValues, \n loading: valuesLoading, \n error: valuesError,\n searchValues\n } = useFilterValues(fieldName, shouldFetchValues)\n \n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n \n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n \n // Load initial values when dropdown opens\n useEffect(() => {\n if (isOpen && shouldFetchValues && searchValues) {\n searchValues('', true) // Force load with empty search\n setHasLoadedInitial(true)\n lastSearchedTerm.current = ''\n }\n }, [isOpen, shouldFetchValues, searchValues])\n \n // Trigger search when debounced search text changes\n useEffect(() => {\n if (hasLoadedInitial && shouldFetchValues && searchValues && debouncedSearchText !== lastSearchedTerm.current) {\n lastSearchedTerm.current = debouncedSearchText\n searchValues(debouncedSearchText)\n }\n }, [debouncedSearchText, hasLoadedInitial, shouldFetchValues, searchValues])\n \n // Handle dropdown toggle\n const handleDropdownToggle = useCallback(() => {\n const newIsOpen = !isOpen\n setIsOpen(newIsOpen)\n \n // Reset search when closing dropdown\n if (!newIsOpen) {\n setSearchText('')\n lastSearchedTerm.current = ''\n }\n }, [isOpen])\n \n // Handle search input change\n const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const newSearchText = e.target.value\n setSearchText(newSearchText)\n }, [])\n \n // Handle value selection for combo box\n const handleValueSelect = useCallback((value: any) => {\n if (operatorMeta.supportsMultipleValues) {\n // Add to selection if not already selected\n if (!values.includes(value)) {\n onValuesChange([...values, value])\n }\n } else {\n // Replace current value\n onValuesChange([value])\n setIsOpen(false)\n }\n // Clear search after selection\n setSearchText('')\n }, [operatorMeta.supportsMultipleValues, values, onValuesChange])\n \n // Handle value removal for multi-select\n const handleValueRemove = useCallback((valueToRemove: any) => {\n onValuesChange(values.filter(v => v !== valueToRemove))\n }, [values, onValuesChange])\n \n // Handle direct text input for non-combo operators\n const handleDirectInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n if (operatorMeta.valueType === 'number') {\n const numValue = parseFloat(value)\n // Accept valid numbers including zero\n if (!isNaN(numValue)) {\n onValuesChange([numValue])\n } else if (value === '' || value === '-') {\n // Allow empty string or just a minus sign for negative numbers being typed\n onValuesChange([])\n }\n } else {\n onValuesChange(value ? [value] : [])\n }\n }, [operatorMeta.valueType, onValuesChange])\n \n // Handle date input\n const handleDateInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n if (operator === 'inDateRange') {\n // For date range, we need two values\n const currentValues = values.length >= 2 ? values : ['', '']\n onValuesChange([value, currentValues[1]])\n } else {\n // Single date value\n onValuesChange(value ? [value] : [])\n }\n }, [operator, values, onValuesChange])\n \n const handleDateRangeEndInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n const currentValues = values.length >= 2 ? values : ['', '']\n onValuesChange([currentValues[0], value])\n }, [values, onValuesChange])\n\n // Handle between/notBetween range inputs (must be defined at top level, not inside conditionals)\n const handleBetweenStartInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = parseFloat(e.target.value)\n const currentValues = values.length >= 2 ? values : ['', '']\n const newValues = [!isNaN(value) ? value : e.target.value === '' ? '' : currentValues[0], currentValues[1]]\n onValuesChange(newValues.filter(v => v !== ''))\n }, [values, onValuesChange])\n\n const handleBetweenEndInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const value = parseFloat(e.target.value)\n const currentValues = values.length >= 2 ? values : ['', '']\n const newValues = [currentValues[0], !isNaN(value) ? value : e.target.value === '' ? '' : currentValues[1]]\n onValuesChange(newValues.filter(v => v !== ''))\n }, [values, onValuesChange])\n\n // Render based on operator type\n if (!operatorMeta.requiresValues) {\n // No input needed for set/notSet\n return (\n <div className=\"text-sm text-dc-text-muted italic\">\n No value required\n </div>\n )\n }\n \n if (operator === 'inDateRange') {\n // Date range picker\n return (\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n <span className=\"text-sm text-dc-text-muted\">to</span>\n <input\n type=\"date\"\n value={values[1] || ''}\n onChange={handleDateRangeEndInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n </div>\n )\n }\n \n if (operator === 'between' || operator === 'notBetween') {\n // Between range picker (for numbers)\n return (\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"number\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleBetweenStartInput}\n placeholder=\"Min\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n <span className=\"text-sm text-dc-text-muted\">to</span>\n <input\n type=\"number\"\n value={values[1] !== undefined && values[1] !== null ? values[1] : ''}\n onChange={handleBetweenEndInput}\n placeholder=\"Max\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n </div>\n )\n }\n \n if (operatorMeta.valueType === 'date') {\n // Single date picker\n return (\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n )\n }\n \n if (operatorMeta.valueType === 'number') {\n // Number input\n return (\n <input\n type=\"number\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleDirectInput}\n placeholder=\"Enter number\"\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n )\n }\n \n // Time dimension with equals/notEquals/in/notIn - use date picker\n if (isTimeDimension && (['equals', 'notEquals', 'in', 'notIn'].includes(operator))) {\n if (operatorMeta.supportsMultipleValues) {\n // Multi-select date picker (for notEquals that supports multiple values)\n return (\n <div className=\"space-y-2\">\n {/* Selected dates display */}\n {values.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {values.map((value, index) => (\n <div\n key={index}\n className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\"\n >\n <span className=\"mr-1\">{String(value)}</span>\n <button\n onClick={() => handleValueRemove(value)}\n className=\"text-dc-accent hover:text-dc-accent focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n \n {/* Add new date */}\n <input\n type=\"date\"\n onChange={(e) => {\n if (e.target.value && !values.includes(e.target.value)) {\n onValuesChange([...values, e.target.value])\n e.target.value = '' // Clear the input\n }\n }}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n placeholder=\"Add date...\"\n />\n </div>\n )\n } else {\n // Single date picker\n return (\n <input\n type=\"date\"\n value={values[0] || ''}\n onChange={handleDateInput}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n )\n }\n }\n \n if (shouldShowComboBox) {\n // Combo box with API-fetched values\n return (\n <div className=\"relative\" ref={dropdownRef}>\n {/* Selected values display (for multi-select) */}\n {operatorMeta.supportsMultipleValues && values.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mb-2\">\n {values.map((value, index) => (\n <div\n key={index}\n className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\"\n >\n <span className=\"mr-1\">{String(value)}</span>\n <button\n onClick={() => handleValueRemove(value)}\n className=\"text-dc-accent hover:text-dc-accent focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n \n {/* Single value display (for single-select) */}\n {!operatorMeta.supportsMultipleValues && values.length > 0 && (\n <div className=\"mb-2\">\n <div className=\"inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension\">\n <span className=\"mr-1\">{String(values[0])}</span>\n <button\n onClick={() => onValuesChange([])}\n className=\"text-dc-accent hover:text-dc-accent focus:outline-hidden\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n </div>\n )}\n \n {/* Dropdown trigger */}\n <button\n onClick={handleDropdownToggle}\n className=\"w-full text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent flex items-center justify-between min-w-0\"\n >\n <span className=\"text-dc-text-muted truncate\">\n {valuesLoading && !hasLoadedInitial ? 'Loading values...' : 'Select value...'}\n </span>\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-muted\" />\n </button>\n\n {/* Dropdown menu */}\n {isOpen && (\n <div className=\"absolute z-30 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {/* Search input */}\n <div className=\"p-2 border-b border-dc-border\">\n <input\n type=\"text\"\n value={searchText}\n onChange={handleSearchChange}\n placeholder=\"Search values...\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n autoFocus\n />\n </div>\n\n {/* Values list */}\n <div className=\"max-h-48 overflow-y-auto\">\n {valuesLoading ? (\n <div className=\"p-2 text-sm text-dc-text-muted\">\n {searchText ? 'Searching...' : 'Loading values...'}\n </div>\n ) : valuesError ? (\n <div className=\"p-2 text-sm text-dc-error\">\n Error loading values: {valuesError}\n </div>\n ) : distinctValues.length === 0 ? (\n <div className=\"p-2 text-sm text-dc-text-muted\">\n {searchText ? 'No matching values' : 'No values available'}\n </div>\n ) : (\n distinctValues.map((value, index) => {\n const isSelected = values.includes(value)\n\n return (\n <button\n key={`${value}-${index}`}\n onClick={() => handleValueSelect(value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n isSelected ? 'bg-dc-accent-bg text-dc-accent' : 'text-dc-text-secondary'\n }`}\n >\n {String(value)}\n {isSelected && (\n <span className=\"float-right text-dc-accent\">✓</span>\n )}\n </button>\n )\n })\n )}\n </div>\n </div>\n )}\n </div>\n )\n }\n \n // Fallback to text input\n return (\n <input\n type=\"text\"\n value={values[0] !== undefined && values[0] !== null ? values[0] : ''}\n onChange={handleDirectInput}\n placeholder={`Enter ${operatorMeta.valueType} value`}\n className=\"text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n )\n}\n\nexport default FilterValueSelector","/**\n * Utility functions for QueryBuilder components\n */\n\nimport type { CubeQuery, Filter, SimpleFilter, GroupFilter } from '../../types'\nimport type { MetaField, MetaResponse } from './types'\nimport { FILTER_OPERATORS } from './types'\n\n/**\n * Check if a field is selected in the current query\n */\nexport function isFieldSelected(\n fieldName: string, \n fieldType: 'measures' | 'dimensions' | 'timeDimensions',\n query: CubeQuery\n): boolean {\n switch (fieldType) {\n case 'measures':\n return query.measures?.includes(fieldName) || false\n case 'dimensions':\n return query.dimensions?.includes(fieldName) || false\n case 'timeDimensions':\n return query.timeDimensions?.some(td => td.dimension === fieldName) || false\n default:\n return false\n }\n}\n\n/**\n * Get all time dimension fields from schema\n */\nexport function getTimeDimensionFields(schema: MetaResponse): MetaField[] {\n const timeDimensions: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.dimensions.forEach(dimension => {\n if (dimension.type === 'time') {\n timeDimensions.push(dimension)\n }\n })\n })\n \n return timeDimensions\n}\n\n/**\n * Get all non-time dimension fields from schema\n */\nexport function getRegularDimensionFields(schema: MetaResponse): MetaField[] {\n const dimensions: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.dimensions.forEach(dimension => {\n if (dimension.type !== 'time') {\n dimensions.push(dimension)\n }\n })\n })\n \n return dimensions\n}\n\n/**\n * Get all measure fields from schema\n */\nexport function getMeasureFields(schema: MetaResponse): MetaField[] {\n const measures: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n cube.measures.forEach(measure => {\n measures.push(measure)\n })\n })\n \n return measures\n}\n\n/**\n * Check if query has any content (measures, dimensions, or timeDimensions)\n */\nexport function hasQueryContent(query: CubeQuery): boolean {\n return Boolean(\n (query.measures && query.measures.length > 0) ||\n (query.dimensions && query.dimensions.length > 0) ||\n (query.timeDimensions && query.timeDimensions.length > 0)\n )\n}\n\n/**\n * Get count of selected fields across all types\n */\nexport function getSelectedFieldsCount(query: CubeQuery): number {\n let count = 0\n if (query.measures) count += query.measures.length\n if (query.dimensions) count += query.dimensions.length\n if (query.timeDimensions) count += query.timeDimensions.length\n return count\n}\n\n/**\n * Get cube name from field name (e.g., \"Employees.count\" -> \"Employees\")\n */\nexport function getCubeNameFromField(fieldName: string): string {\n return fieldName.split('.')[0]\n}\n\n/**\n * Group fields by cube name\n */\nexport function groupFieldsByCube(fields: MetaField[]): Record<string, MetaField[]> {\n return fields.reduce((groups, field) => {\n const cubeName = getCubeNameFromField(field.name)\n if (!groups[cubeName]) {\n groups[cubeName] = []\n }\n groups[cubeName].push(field)\n return groups\n }, {} as Record<string, MetaField[]>)\n}\n\n/**\n * Clean query object by removing empty arrays\n */\nexport function cleanQuery(query: CubeQuery): CubeQuery {\n const cleanedQuery: CubeQuery = {}\n \n if (query.measures && query.measures.length > 0) {\n cleanedQuery.measures = query.measures\n }\n \n if (query.dimensions && query.dimensions.length > 0) {\n cleanedQuery.dimensions = query.dimensions\n }\n \n if (query.timeDimensions && query.timeDimensions.length > 0) {\n cleanedQuery.timeDimensions = query.timeDimensions\n }\n \n if (query.filters && query.filters.length > 0) {\n cleanedQuery.filters = query.filters\n }\n \n if (query.order) {\n cleanedQuery.order = query.order\n }\n \n if (query.limit) {\n cleanedQuery.limit = query.limit\n }\n \n if (query.offset) {\n cleanedQuery.offset = query.offset\n }\n \n if (query.segments && query.segments.length > 0) {\n cleanedQuery.segments = query.segments\n }\n \n return cleanedQuery\n}\n\n/**\n * Clean a query and transform filters for server compatibility\n * This version transforms GroupFilter to legacy and/or format\n */\nexport function cleanQueryForServer(query: CubeQuery): CubeQuery {\n const cleanedQuery = cleanQuery(query)\n \n // Apply server transformation to filters\n if (cleanedQuery.filters && cleanedQuery.filters.length > 0) {\n cleanedQuery.filters = transformFiltersForServer(cleanedQuery.filters) as any\n }\n \n return cleanedQuery\n}\n\n/**\n * Create an empty query object\n */\nexport function createEmptyQuery(): CubeQuery {\n return {}\n}\n\n/**\n * Filter utility functions\n */\n\n/**\n * Check if a filter is a simple filter\n */\nexport function isSimpleFilter(filter: Filter): filter is SimpleFilter {\n return 'member' in filter && 'operator' in filter && 'values' in filter\n}\n\n/**\n * Check if a filter is a group filter\n */\nexport function isGroupFilter(filter: Filter): filter is GroupFilter {\n return 'type' in filter && 'filters' in filter\n}\n\n/**\n * Check if a filter is an AND filter\n */\nexport function isAndFilter(filter: Filter): filter is GroupFilter {\n return isGroupFilter(filter) && filter.type === 'and'\n}\n\n/**\n * Check if a filter is an OR filter\n */\nexport function isOrFilter(filter: Filter): filter is GroupFilter {\n return isGroupFilter(filter) && filter.type === 'or'\n}\n\n/**\n * Flatten all simple filters from a hierarchical filter structure\n */\nexport function flattenFilters(filters: Filter[]): SimpleFilter[] {\n const simple: SimpleFilter[] = []\n \n const flatten = (filter: Filter) => {\n if (isSimpleFilter(filter)) {\n simple.push(filter)\n } else if (isGroupFilter(filter)) {\n filter.filters.forEach(flatten)\n }\n }\n \n filters.forEach(flatten)\n return simple\n}\n\n/**\n * Get all filterable fields from schema (measures, dimensions, and time dimensions)\n * Returns ALL fields if no query provided, or only query fields if query provided\n */\nexport function getFilterableFields(schema: MetaResponse, query?: CubeQuery): MetaField[] {\n const allFields: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n allFields.push(...cube.measures)\n allFields.push(...cube.dimensions)\n })\n \n // If no query provided, return all fields\n if (!query) {\n return allFields.sort((a, b) => a.name.localeCompare(b.name))\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Filter to only include selected fields\n const filterableFields = allFields.filter(field => selectedFields.has(field.name))\n \n return filterableFields.sort((a, b) => a.name.localeCompare(b.name))\n}\n\n/**\n * Get ALL filterable fields from schema, regardless of query selection\n */\nexport function getAllFilterableFields(schema: MetaResponse): MetaField[] {\n const allFields: MetaField[] = []\n \n schema.cubes.forEach(cube => {\n allFields.push(...cube.measures)\n allFields.push(...cube.dimensions)\n })\n \n return allFields.sort((a, b) => a.name.localeCompare(b.name))\n}\n\n/**\n * Get organized filter field options with query fields prioritized at top\n */\nexport function getOrganizedFilterFields(schema: MetaResponse, query?: CubeQuery): {\n queryFields: MetaField[]\n allFields: MetaField[]\n} {\n const allFields = getAllFilterableFields(schema)\n \n if (!query) {\n return {\n queryFields: [],\n allFields\n }\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Split fields into query fields and other fields\n const queryFields = allFields.filter(field => selectedFields.has(field.name))\n \n return {\n queryFields,\n allFields\n }\n}\n\n/**\n * Get available operators for a field type\n */\nexport function getAvailableOperators(fieldType: string): Array<{operator: string, label: string}> {\n const operators: Array<{operator: string, label: string}> = []\n \n for (const [operator, meta] of Object.entries(FILTER_OPERATORS)) {\n if (meta.fieldTypes.includes(fieldType)) {\n operators.push({\n operator,\n label: meta.label\n })\n }\n }\n \n return operators\n}\n\n/**\n * Get field type from schema\n */\nexport function getFieldType(fieldName: string, schema: MetaResponse): string {\n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find(m => m.name === fieldName)\n if (measure) return measure.type\n \n // Check dimensions\n const dimension = cube.dimensions.find(d => d.name === fieldName)\n if (dimension) return dimension.type\n }\n \n return 'string' // Default fallback\n}\n\n/**\n * Validate a filter\n */\nexport function validateFilter(filter: SimpleFilter, schema: MetaResponse): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n \n // Check if field exists\n const fields = getFilterableFields(schema)\n const fieldExists = fields.some(f => f.name === filter.member)\n \n if (!fieldExists) {\n errors.push(`Field \"${filter.member}\" does not exist`)\n }\n \n // Check if operator is valid for field type\n if (fieldExists) {\n const fieldType = getFieldType(filter.member, schema)\n const operatorMeta = FILTER_OPERATORS[filter.operator]\n \n if (!operatorMeta) {\n errors.push(`Invalid operator \"${filter.operator}\"`)\n } else if (!operatorMeta.fieldTypes.includes(fieldType)) {\n errors.push(`Operator \"${filter.operator}\" is not valid for field type \"${fieldType}\"`)\n } else {\n // Check values\n if (operatorMeta.requiresValues && (!filter.values || filter.values.length === 0)) {\n errors.push(`Operator \"${filter.operator}\" requires values`)\n }\n \n if (!operatorMeta.supportsMultipleValues && filter.values && filter.values.length > 1) {\n errors.push(`Operator \"${filter.operator}\" does not support multiple values`)\n }\n }\n }\n \n return {\n isValid: errors.length === 0,\n errors\n }\n}\n\n/**\n * Count total filters in hierarchical structure\n */\nexport function countFilters(filters: Filter[]): number {\n let count = 0\n \n const countFilter = (filter: Filter) => {\n if (isSimpleFilter(filter)) {\n count++\n } else if (isGroupFilter(filter)) {\n filter.filters.forEach(countFilter)\n }\n }\n \n filters.forEach(countFilter)\n return count\n}\n\n/**\n * Create a new simple filter\n */\nexport function createSimpleFilter(member: string, operator: string = 'equals', values: any[] = []): SimpleFilter {\n return {\n member,\n operator: operator as any,\n values\n }\n}\n\n/**\n * Create a new AND filter group\n */\nexport function createAndFilter(filters: Filter[] = []): GroupFilter {\n return {\n type: 'and',\n filters\n }\n}\n\n/**\n * Create a new OR filter group\n */\nexport function createOrFilter(filters: Filter[] = []): GroupFilter {\n return {\n type: 'or',\n filters\n }\n}\n\n/**\n * Clean up filters by removing any that reference fields not in the current query\n * @deprecated This function is no longer used as we now support filtering on any schema field\n */\nexport function cleanupFilters(filters: Filter[], _query?: CubeQuery): Filter[] {\n // Return filters unchanged - we now support filtering on any field\n return filters || []\n}\n\n/**\n * Clean up filters by removing any that reference fields not in the current query (legacy)\n * Only used for backward compatibility - filters on non-query fields are now supported\n */\nexport function cleanupFiltersLegacy(filters: Filter[], query: CubeQuery): Filter[] {\n if (!filters || filters.length === 0) {\n return []\n }\n \n // Get currently selected fields from the query\n const selectedFields = new Set<string>()\n \n // Add measures\n if (query.measures) {\n query.measures.forEach(measure => selectedFields.add(measure))\n }\n \n // Add dimensions\n if (query.dimensions) {\n query.dimensions.forEach(dimension => selectedFields.add(dimension))\n }\n \n // Add time dimensions\n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => selectedFields.add(td.dimension))\n }\n \n // Recursively clean filters\n const cleanFilter = (filter: Filter): Filter | null => {\n if (isSimpleFilter(filter)) {\n // Remove filter if its field is not selected\n return selectedFields.has(filter.member) ? filter : null\n } else if (isGroupFilter(filter)) {\n // Clean group recursively\n const cleanedFilters = filter.filters.map(cleanFilter).filter(f => f !== null) as Filter[]\n return cleanedFilters.length > 0 ? { type: filter.type, filters: cleanedFilters } : null\n }\n return null\n }\n \n // Clean all filters and remove nulls\n const cleanedFilters = filters.map(cleanFilter).filter(f => f !== null) as Filter[]\n \n return cleanedFilters\n}\n\n/**\n * Transform filters from new GroupFilter format to legacy server format\n * Server expects { and: [...] } and { or: [...] } instead of { type: 'and', filters: [...] }\n */\nexport function transformFiltersForServer(filters: Filter[]): any[] {\n const transformFilter = (filter: Filter): any => {\n if (isSimpleFilter(filter)) {\n return filter\n } else if (isGroupFilter(filter)) {\n const transformedSubFilters = filter.filters.map(transformFilter)\n \n if (filter.type === 'and') {\n return { and: transformedSubFilters }\n } else {\n return { or: transformedSubFilters }\n }\n }\n return filter\n }\n \n return filters.map(transformFilter)\n}\n\n/**\n * Date range utility functions\n */\n\n/**\n * Convert DateRangeType to Cube.js compatible date range format\n */\nexport function convertDateRangeTypeToValue(rangeType: string, number?: number): string {\n const typeMap: Record<string, string> = {\n 'today': 'today',\n 'yesterday': 'yesterday',\n 'this_week': 'this week',\n 'this_month': 'this month',\n 'this_quarter': 'this quarter',\n 'this_year': 'this year',\n 'last_7_days': 'last 7 days',\n 'last_30_days': 'last 30 days',\n 'last_week': 'last week',\n 'last_month': 'last month',\n 'last_quarter': 'last quarter',\n 'last_year': 'last year',\n 'last_12_months': 'last 12 months'\n }\n \n // Handle dynamic ranges with number input\n if (rangeType.startsWith('last_n_') && number !== undefined && number > 0) {\n const unit = rangeType.replace('last_n_', '')\n const unitSingular = unit.slice(0, -1) // Remove 's' for singular form\n return number === 1 ? `last ${unitSingular}` : `last ${number} ${unit}`\n }\n \n return typeMap[rangeType] || rangeType\n}\n\n/**\n * Check if a date range type requires a number input\n */\nexport function requiresNumberInput(rangeType: string): boolean {\n return rangeType.startsWith('last_n_')\n}\n\n/**\n * Format date for Cube.js (YYYY-MM-DD)\n */\nexport function formatDateForCube(date: Date): string {\n return date.toISOString().split('T')[0]\n}\n\n/**\n * Get the time dimensions that have date ranges applied\n */\nexport function getTimeDimensionsWithDateRanges(query: CubeQuery): Record<string, string | string[]> {\n const dateRanges: Record<string, string | string[]> = {}\n \n if (query.timeDimensions) {\n query.timeDimensions.forEach(td => {\n if (td.dateRange) {\n dateRanges[td.dimension] = td.dateRange\n }\n })\n }\n \n return dateRanges\n}\n\n/**\n * Check if a query has any time dimensions\n */\nexport function hasTimeDimensions(query: CubeQuery): boolean {\n return Boolean(query.timeDimensions && query.timeDimensions.length > 0)\n}\n\n/**\n * Transform a Cube.js query from external format to UI internal format\n * This handles format differences between server/API queries and QueryBuilder state\n */\nexport function transformQueryForUI(query: any): CubeQuery {\n if (!query || typeof query !== 'object') {\n return {}\n }\n \n const transformed: CubeQuery = {}\n \n // Copy simple fields if they exist\n if (query.measures) transformed.measures = Array.isArray(query.measures) ? query.measures : []\n if (query.dimensions) transformed.dimensions = Array.isArray(query.dimensions) ? query.dimensions : []\n if (query.timeDimensions) transformed.timeDimensions = Array.isArray(query.timeDimensions) ? query.timeDimensions : []\n if (query.order) transformed.order = query.order\n if (query.limit) transformed.limit = query.limit\n if (query.offset) transformed.offset = query.offset\n if (query.segments) transformed.segments = Array.isArray(query.segments) ? query.segments : []\n \n // Transform filters from server format to UI format\n if (query.filters && Array.isArray(query.filters)) {\n transformed.filters = transformFiltersFromServer(query.filters)\n }\n \n return cleanQuery(transformed)\n}\n\n/**\n * Transform filters from server/API format to UI format\n * Converts {and: [...]} and {or: [...]} to {type: 'and', filters: [...]} format\n */\nfunction transformFiltersFromServer(filters: any[]): Filter[] {\n return filters.map(filter => {\n if (!filter || typeof filter !== 'object') {\n return filter\n }\n \n // Handle legacy {and: [...]} format\n if ('and' in filter && Array.isArray(filter.and)) {\n return {\n type: 'and',\n filters: transformFiltersFromServer(filter.and)\n } as GroupFilter\n }\n \n // Handle legacy {or: [...]} format\n if ('or' in filter && Array.isArray(filter.or)) {\n return {\n type: 'or',\n filters: transformFiltersFromServer(filter.or)\n } as GroupFilter\n }\n \n // Handle new format {type: 'and', filters: [...]} - process recursively\n if ('type' in filter && 'filters' in filter && Array.isArray(filter.filters)) {\n return {\n type: filter.type,\n filters: transformFiltersFromServer(filter.filters)\n } as GroupFilter\n }\n \n // Simple filter - pass through\n return filter as SimpleFilter\n }).filter(Boolean) // Remove any null/undefined values\n}\n\n/**\n * Sorting utility functions\n */\n\n/**\n * Get field title from schema metadata, falling back to field name\n */\nexport function getFieldTitle(fieldName: string, schema: MetaResponse | null): string {\n if (!schema) return fieldName\n \n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find(m => m.name === fieldName)\n if (measure) return measure.title || measure.shortTitle || fieldName\n \n // Check dimensions\n const dimension = cube.dimensions.find(d => d.name === fieldName)\n if (dimension) return dimension.title || dimension.shortTitle || fieldName\n }\n \n return fieldName // Fallback to field name if not found\n}\n\n/**\n * Clean up order object by removing fields that are no longer in the query\n */\nexport function cleanupOrder(order: Record<string, 'asc' | 'desc'> | undefined, query: CubeQuery): Record<string, 'asc' | 'desc'> | undefined {\n if (!order) return undefined\n \n const allFields = [\n ...(query.measures || []),\n ...(query.dimensions || []),\n ...(query.timeDimensions || []).map(td => td.dimension)\n ]\n \n const cleanedOrder: Record<string, 'asc' | 'desc'> = {}\n for (const [field, direction] of Object.entries(order)) {\n if (allFields.includes(field)) {\n cleanedOrder[field] = direction\n }\n }\n \n return Object.keys(cleanedOrder).length > 0 ? cleanedOrder : undefined\n}\n\n/**\n * Get sort direction for a field from the order object\n */\nexport function getSortDirection(fieldName: string, order: Record<string, 'asc' | 'desc'> | undefined): 'asc' | 'desc' | null {\n return order?.[fieldName] || null\n}\n\n/**\n * Get tooltip text for sort button based on current direction\n */\nexport function getSortTooltip(direction: 'asc' | 'desc' | null): string {\n switch (direction) {\n case 'asc':\n return 'Sorted ascending (click for descending)'\n case 'desc':\n return 'Sorted descending (click to remove)'\n default:\n return 'Click to sort ascending'\n }\n}\n\n/**\n * Get next sort direction in the cycle: null -> asc -> desc -> null\n */\nexport function getNextSortDirection(current: 'asc' | 'desc' | null): 'asc' | 'desc' | null {\n switch (current) {\n case null:\n return 'asc'\n case 'asc':\n return 'desc'\n case 'desc':\n return null\n default:\n return 'asc'\n }\n}","/**\n * FilterItem Component\n * \n * Renders a single filter with field selection, operator selection, and value input.\n * Handles all the logic for individual filter management.\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterValueSelector from './FilterValueSelector'\nimport type { FilterItemProps, MetaField, DateRangeType } from './types'\nimport { getAllFilterableFields, getOrganizedFilterFields, getFieldType, getAvailableOperators, convertDateRangeTypeToValue, formatDateForCube, requiresNumberInput } from './utils'\nimport { getMeasureIcon } from '../../utils/measureIcons'\nimport { DATE_RANGE_OPTIONS } from './types'\n\nconst CloseIcon = getIcon('close')\nconst FilterIcon = getIcon('filter')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst SearchIcon = getIcon('search')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\n\nconst FilterItem: React.FC<FilterItemProps> = ({\n filter,\n index,\n onFilterChange,\n onFilterRemove,\n schema,\n query,\n hideFieldSelector = false,\n hideOperatorSelector = false,\n hideRemoveButton = false\n}) => {\n const [isFieldDropdownOpen, setIsFieldDropdownOpen] = useState(false)\n const [isOperatorDropdownOpen, setIsOperatorDropdownOpen] = useState(false)\n const [isDateRangeDropdownOpen, setIsDateRangeDropdownOpen] = useState(false)\n const [fieldSearchTerm, setFieldSearchTerm] = useState('')\n const containerRef = useRef<HTMLDivElement>(null)\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n // Date range state - always initialized with defaults (must be before any early returns)\n const [rangeType, setRangeType] = useState<DateRangeType>('this_month')\n const [customDates, setCustomDates] = useState({\n startDate: formatDateForCube(new Date()),\n endDate: formatDateForCube(new Date())\n })\n const [numberValue, setNumberValue] = useState<number>(1)\n\n // Close dropdowns when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsFieldDropdownOpen(false)\n setIsOperatorDropdownOpen(false)\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n // Close other dropdowns when opening one\n const handleFieldDropdownToggle = () => {\n setIsOperatorDropdownOpen(false)\n const newOpen = !isFieldDropdownOpen\n setIsFieldDropdownOpen(newOpen)\n setFieldSearchTerm('') // Reset search when toggling\n\n // Focus search input when opening\n if (newOpen) {\n setTimeout(() => searchInputRef.current?.focus(), 50)\n }\n }\n\n const handleOperatorDropdownToggle = () => {\n setIsFieldDropdownOpen(false)\n setIsOperatorDropdownOpen(!isOperatorDropdownOpen)\n }\n\n // Get field info (safe defaults if schema not loaded)\n const allFields = schema ? getAllFilterableFields(schema) : []\n const { queryFields } = schema ? getOrganizedFilterFields(schema, query) : { queryFields: [] }\n const selectedField = allFields.find(f => f.name === filter.member)\n const fieldType = selectedField ? selectedField.type : 'string'\n const availableOperators = getAvailableOperators(fieldType)\n\n // Determine if we should show date range selector (for time fields with inDateRange operator)\n const shouldShowDateRangeSelector = fieldType === 'time' && filter.operator === 'inDateRange'\n\n // Update date range state when filter.dateRange changes (must be before early return)\n useEffect(() => {\n if (!shouldShowDateRangeSelector || !filter.dateRange) return\n\n // Update rangeType\n if (Array.isArray(filter.dateRange)) {\n setRangeType('custom')\n setCustomDates({\n startDate: filter.dateRange[0] || '',\n endDate: filter.dateRange[1] || filter.dateRange[0] || ''\n })\n } else {\n // Check for flexible range patterns\n const flexibleRangeMatch = filter.dateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n const [, num, unit] = flexibleRangeMatch\n const unitPlural = unit === 'days' ? 'days' : unit === 'weeks' ? 'weeks' : unit === 'months' ? 'months' : unit === 'quarters' ? 'quarters' : 'years'\n setRangeType(`last_n_${unitPlural}` as DateRangeType)\n setNumberValue(parseInt(num) || 1)\n } else {\n // Check for predefined ranges\n let found = false\n for (const option of DATE_RANGE_OPTIONS) {\n if (option.value !== 'custom' && !requiresNumberInput(option.value) && convertDateRangeTypeToValue(option.value) === filter.dateRange) {\n setRangeType(option.value)\n found = true\n break\n }\n }\n if (!found) {\n setRangeType('custom')\n }\n }\n }\n }, [filter.dateRange, shouldShowDateRangeSelector])\n\n // Early return AFTER all hooks\n if (!schema) {\n return (\n <div className=\"text-sm text-dc-text-muted\">\n Schema not loaded\n </div>\n )\n }\n \n // Filter fields based on search term\n const filterFieldsBySearch = (fields: MetaField[]) => {\n if (!fieldSearchTerm) return fields\n const searchTerm = fieldSearchTerm.toLowerCase()\n return fields.filter(field => \n field.name.toLowerCase().includes(searchTerm) ||\n field.title.toLowerCase().includes(searchTerm) ||\n field.shortTitle.toLowerCase().includes(searchTerm)\n )\n }\n \n const filteredQueryFields = filterFieldsBySearch(queryFields)\n const filteredAllFields = filterFieldsBySearch(allFields)\n \n // Helper function to get field type icon\n const getFieldTypeIcon = (field: MetaField) => {\n if (field.type === 'time') {\n return <TimeDimensionIcon className=\"w-3 h-3 text-dc-accent\" />\n } else if (['count', 'sum', 'avg', 'min', 'max', 'countDistinct', 'countDistinctApprox', 'runningTotal', 'calculated', 'number'].includes(field.type)) {\n // Use dynamic icon based on measure type, with amber color\n const icon = getMeasureIcon(field.type, 'w-3 h-3 text-dc-warning')\n return icon\n } else {\n return <DimensionIcon className=\"w-3 h-3 text-dc-success\" />\n }\n }\n\n // Helper function to get field type badge\n const getFieldTypeBadge = (field: MetaField) => {\n if (field.type === 'time') {\n return <span className=\"text-xs bg-dc-time-dimension text-dc-time-dimension px-1.5 py-0.5 rounded-sm\">T</span>\n } else if (['count', 'sum', 'avg', 'min', 'max', 'countDistinct', 'number'].includes(field.type)) {\n return <span className=\"text-xs bg-dc-measure text-dc-measure px-1.5 py-0.5 rounded-sm\">M</span>\n } else {\n return <span className=\"text-xs bg-dc-dimension text-dc-dimension px-1.5 py-0.5 rounded-sm\">D</span>\n }\n }\n\n const handleFieldChange = (fieldName: string) => {\n // When field changes, reset operator and values\n const newFieldType = getFieldType(fieldName, schema)\n const newAvailableOperators = getAvailableOperators(newFieldType)\n const defaultOperator = newAvailableOperators[0]?.operator || 'equals'\n\n onFilterChange(index, {\n member: fieldName,\n operator: defaultOperator as any,\n values: [],\n dateRange: undefined // Reset dateRange when field changes\n })\n setIsFieldDropdownOpen(false)\n }\n \n const handleOperatorChange = (operator: string) => {\n onFilterChange(index, {\n ...filter,\n operator: operator as any,\n values: [], // Reset values when operator changes\n dateRange: undefined // Reset dateRange when operator changes\n })\n setIsOperatorDropdownOpen(false)\n }\n \n const handleValuesChange = (values: any[]) => {\n onFilterChange(index, {\n ...filter,\n values\n })\n }\n\n // Date range handlers for time dimension filters\n const handleDateRangeChange = (dateRange: string | string[]) => {\n onFilterChange(index, {\n ...filter,\n dateRange\n })\n }\n\n const handleRangeTypeChange = (newRangeType: DateRangeType) => {\n setIsDateRangeDropdownOpen(false)\n\n if (newRangeType === 'custom') {\n // For custom, use current custom dates or default to today\n if (customDates.startDate && customDates.endDate) {\n const dateRange = customDates.startDate === customDates.endDate\n ? customDates.startDate\n : [customDates.startDate, customDates.endDate]\n handleDateRangeChange(dateRange)\n }\n } else if (requiresNumberInput(newRangeType)) {\n // For number-based ranges, use the number value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType, numberValue)\n handleDateRangeChange(cubeRangeValue)\n } else {\n // For predefined ranges, use the converted value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType)\n handleDateRangeChange(cubeRangeValue)\n }\n\n setRangeType(newRangeType)\n }\n\n const handleCustomDateChange = (field: 'startDate' | 'endDate', value: string) => {\n const newCustomDates = { ...customDates, [field]: value }\n setCustomDates(newCustomDates)\n\n if (rangeType === 'custom' && newCustomDates.startDate) {\n const dateRange = !newCustomDates.endDate || newCustomDates.startDate === newCustomDates.endDate\n ? newCustomDates.startDate\n : [newCustomDates.startDate, newCustomDates.endDate]\n handleDateRangeChange(dateRange)\n }\n }\n\n const handleNumberChange = (value: number) => {\n setNumberValue(value)\n\n if (requiresNumberInput(rangeType)) {\n const cubeRangeValue = convertDateRangeTypeToValue(rangeType, value)\n handleDateRangeChange(cubeRangeValue)\n }\n }\n\n const selectedRangeLabel = DATE_RANGE_OPTIONS.find(opt => opt.value === rangeType)?.label || 'Custom'\n\n return (\n <div ref={containerRef} className=\"bg-dc-surface border border-dc-border rounded-lg p-3\">\n {/* Responsive layout - stacks on mobile, single row on desktop */}\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 min-w-0\">\n {/* Row 1 on mobile: Filter icon and field selection - conditionally hidden */}\n {!hideFieldSelector && (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <FilterIcon className=\"w-4 h-4 text-dc-text-muted shrink-0\" />\n\n {/* Field selection */}\n <div className=\"relative flex-1 min-w-0\">\n <button\n onClick={handleFieldDropdownToggle}\n className=\"w-full flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent min-w-0\"\n >\n <span className=\"truncate\">\n {selectedField ? (\n <span className=\"font-medium\">{selectedField.name}</span>\n ) : (\n <span className=\"text-dc-text-muted\">Select field...</span>\n )}\n </span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isFieldDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isFieldDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-80 overflow-hidden\">\n {/* Search input */}\n <div className=\"p-2 border-b border-dc-border\">\n <div className=\"relative\">\n <SearchIcon className=\"w-4 h-4 absolute left-2 top-1/2 transform -translate-y-1/2 text-dc-text-muted\" />\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder=\"Search fields...\"\n value={fieldSearchTerm}\n onChange={(e) => setFieldSearchTerm(e.target.value)}\n className=\"w-full pl-8 pr-3 py-1.5 text-sm border border-dc-border rounded-sm bg-dc-surface text-dc-text focus:ring-1 focus:ring-dc-accent focus:border-dc-accent\"\n />\n </div>\n </div>\n\n {/* Fields list */}\n <div className=\"max-h-60 overflow-y-auto\">\n {/* Query fields section */}\n {filteredQueryFields.length > 0 && (\n <div>\n <div className=\"px-3 py-1.5 text-xs font-medium text-dc-text-muted bg-dc-surface-secondary border-b border-dc-border\">\n Fields in Query ({filteredQueryFields.length})\n </div>\n {filteredQueryFields.map((field) => (\n <button\n key={`query-${field.name}`}\n onClick={() => handleFieldChange(field.name)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n field.name === filter.member ? 'bg-dc-accent-bg text-dc-accent' : 'text-dc-text-secondary'\n }`}\n >\n <div className=\"flex items-center gap-2\">\n {getFieldTypeIcon(field)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium truncate\">{field.name}</span>\n {getFieldTypeBadge(field)}\n </div>\n {field.title !== field.name && (\n <div className=\"text-xs text-dc-text-muted truncate\">{field.title}</div>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n\n {/* All fields section */}\n <div>\n {filteredQueryFields.length > 0 && (\n <div className=\"px-3 py-1.5 text-xs font-medium text-dc-text-muted bg-dc-surface-secondary border-b border-dc-border\">\n All Available Fields ({filteredAllFields.length})\n </div>\n )}\n {filteredAllFields.map((field) => (\n <button\n key={`all-${field.name}`}\n onClick={() => handleFieldChange(field.name)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n field.name === filter.member ? 'bg-dc-accent-bg text-dc-accent' : 'text-dc-text-secondary'\n }`}\n >\n <div className=\"flex items-center gap-2\">\n {getFieldTypeIcon(field)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium truncate\">{field.name}</span>\n {getFieldTypeBadge(field)}\n </div>\n {field.title !== field.name && (\n <div className=\"text-xs text-dc-text-muted truncate\">{field.title}</div>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n\n {/* No results message */}\n {filteredAllFields.length === 0 && (\n <div className=\"px-3 py-4 text-sm text-dc-text-muted text-center\">\n No fields found matching \"{fieldSearchTerm}\"\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Row 2 on mobile: Operator and Value selection */}\n {selectedField && (\n <div className=\"flex items-center gap-2 flex-1 sm:flex-initial min-w-0\">\n {/* Operator selection - conditionally hidden */}\n {!hideOperatorSelector && (\n <div className=\"relative shrink-0\">\n <button\n onClick={handleOperatorDropdownToggle}\n className=\"w-full sm:w-32 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n >\n <span className=\"truncate\">\n {availableOperators.find(op => op.operator === filter.operator)?.label || filter.operator}\n </span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isOperatorDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isOperatorDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {availableOperators.map((operator) => (\n <button\n key={operator.operator}\n onClick={() => handleOperatorChange(operator.operator)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n operator.operator === filter.operator ? 'bg-dc-accent-bg text-dc-accent' : 'text-dc-text-secondary'\n }`}\n >\n {operator.label}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Value input or Date Range Selector */}\n <div className=\"flex-1 min-w-0\">\n {shouldShowDateRangeSelector ? (\n /* Date Range Selector for time dimensions with inDateRange */\n <div className=\"flex items-center gap-2\">\n {/* Range type selector */}\n <div className=\"relative shrink-0\">\n <button\n onClick={() => {\n setIsOperatorDropdownOpen(false)\n setIsDateRangeDropdownOpen(!isDateRangeDropdownOpen)\n }}\n className=\"w-full sm:w-40 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n >\n <span className=\"truncate\">{selectedRangeLabel}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isDateRangeDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isDateRangeDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {DATE_RANGE_OPTIONS.map((option) => (\n <button\n key={option.value}\n onClick={() => handleRangeTypeChange(option.value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${\n option.value === rangeType ? 'bg-dc-accent-bg text-dc-accent' : 'text-dc-text-secondary'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Custom date inputs or number input */}\n {rangeType === 'custom' ? (\n <>\n <input\n type=\"date\"\n value={customDates.startDate}\n onChange={(e) => handleCustomDateChange('startDate', e.target.value)}\n placeholder=\"Start date\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n <input\n type=\"date\"\n value={customDates.endDate}\n onChange={(e) => handleCustomDateChange('endDate', e.target.value)}\n placeholder=\"End date\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n </>\n ) : requiresNumberInput(rangeType) ? (\n <>\n <input\n type=\"number\"\n min=\"1\"\n max=\"1000\"\n value={numberValue}\n onChange={(e) => handleNumberChange(Math.max(1, parseInt(e.target.value) || 1))}\n placeholder=\"Number\"\n className=\"flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n <div className=\"shrink-0 text-sm text-dc-text-secondary\">\n {rangeType.replace('last_n_', '').replace('_', ' ')}\n </div>\n </>\n ) : null}\n </div>\n ) : (\n /* Regular FilterValueSelector for non-dateRange filters */\n <FilterValueSelector\n fieldName={filter.member}\n operator={filter.operator}\n values={filter.values}\n onValuesChange={handleValuesChange}\n schema={schema}\n />\n )}\n </div>\n </div>\n )}\n \n {/* Row 3 on mobile: Remove button - conditionally hidden */}\n {!hideRemoveButton && (\n <div className=\"flex justify-end sm:justify-start\">\n <button\n onClick={() => onFilterRemove(index)}\n className=\"text-dc-text-muted hover:text-dc-error focus:outline-none shrink-0\"\n title=\"Remove filter\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default FilterItem","/**\n * FilterGroup Component\n * \n * Handles AND/OR logical groups with support for infinite nesting.\n * Renders child filters with proper indentation and group controls.\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from './FilterItem'\nimport type { FilterGroupProps } from './types'\nimport type { SimpleFilter, GroupFilter } from '../../types'\nimport {\n isSimpleFilter,\n isGroupFilter,\n createSimpleFilter,\n createAndFilter,\n createOrFilter,\n getFilterableFields\n} from './utils'\n\nconst CloseIcon = getIcon('close')\nconst AddIcon = getIcon('add')\n\nconst FilterGroup: React.FC<FilterGroupProps> = ({\n group,\n index,\n onGroupChange,\n onGroupChangeWithUnwrap,\n onGroupRemove,\n schema,\n query,\n depth = 0\n}) => {\n const [showAddMenu, setShowAddMenu] = useState(false)\n \n const isAndGroup = group.type === 'and'\n const groupType = isAndGroup ? 'AND' : 'OR'\n const filters = group.filters\n \n // Style based on depth for visual nesting\n const indentClass = depth > 0 ? `ml-${Math.min(depth * 4, 16)}` : ''\n const borderColor = 'border-dc-border'\n const bgColor = 'bg-dc-bg-secondary'\n const textColor = 'text-dc-text-secondary'\n \n const handleGroupTypeToggle = () => {\n if (isAndGroup) {\n const newGroup = createOrFilter(filters)\n onGroupChange(index, newGroup)\n } else {\n const newGroup = createAndFilter(filters)\n onGroupChange(index, newGroup)\n }\n }\n \n const handleAddSimpleFilter = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newFilter = createSimpleFilter(defaultField, 'equals', [])\n const newFilters = [...filters, newFilter]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleAddAndGroup = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newGroup = createAndFilter([createSimpleFilter(defaultField, 'equals', [])])\n const newFilters = [...filters, newGroup]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleAddOrGroup = () => {\n if (!schema) return\n \n // Get the first available field as default\n const filterableFields = getFilterableFields(schema, query)\n const defaultField = filterableFields[0]?.name || ''\n const newGroup = createOrFilter([createSimpleFilter(defaultField, 'equals', [])])\n const newFilters = [...filters, newGroup]\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n setShowAddMenu(false)\n }\n \n const handleFilterChange = (filterIndex: number, newFilter: SimpleFilter) => {\n const newFilters = [...filters]\n newFilters[filterIndex] = newFilter\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n }\n \n const handleFilterRemove = (filterIndex: number) => {\n const newFilters = filters.filter((_, i) => i !== filterIndex)\n \n // If no filters left, remove the entire group\n if (newFilters.length === 0) {\n onGroupRemove(index)\n return\n }\n \n // If only one filter left, use unwrapping handler if available\n if (newFilters.length === 1) {\n const newGroup = group.type === 'and' ? createAndFilter(newFilters) : createOrFilter(newFilters)\n \n if (onGroupChangeWithUnwrap) {\n // Use the unwrapping handler for removal scenarios\n onGroupChangeWithUnwrap(index, newGroup)\n } else {\n // Fallback to regular handler (for nested groups)\n onGroupChange(index, newGroup)\n }\n return\n }\n \n // Otherwise, update the group with remaining filters (preserve the group type)\n const updatedGroup = group.type === 'and' ? createAndFilter(newFilters) : createOrFilter(newFilters)\n onGroupChange(index, updatedGroup)\n }\n \n const handleNestedGroupChange = (filterIndex: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n newFilters[filterIndex] = newGroup\n \n if (isAndGroup) {\n onGroupChange(index, createAndFilter(newFilters))\n } else {\n onGroupChange(index, createOrFilter(newFilters))\n }\n }\n \n const handleNestedGroupRemove = (filterIndex: number) => {\n handleFilterRemove(filterIndex)\n }\n \n return (\n <div className={`${indentClass} ${borderColor} border-2 ${bgColor} rounded-lg p-4 space-y-3`}>\n {/* Group header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-2\">\n <button\n onClick={handleGroupTypeToggle}\n className={`px-3 py-1 rounded-sm text-sm font-semibold ${textColor} border border-current hover:bg-dc-surface hover:bg-opacity-20 focus:outline-hidden focus:ring-2 focus:ring-current focus:ring-opacity-50`}\n >\n {groupType}\n </button>\n <span className=\"text-sm text-dc-text-secondary\">\n {filters.length} condition{filters.length !== 1 ? 's' : ''}\n </span>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Add menu */}\n <div className=\"relative\">\n <button\n onClick={() => setShowAddMenu(!showAddMenu)}\n className=\"text-dc-text-muted hover:text-dc-text-secondary focus:outline-hidden\"\n title=\"Add condition\"\n >\n <AddIcon className=\"w-4 h-4\" />\n </button>\n\n {showAddMenu && (\n <div className=\"absolute right-0 mt-1 w-48 bg-dc-surface border border-dc-border rounded-md shadow-lg z-30\">\n <button\n onClick={handleAddSimpleFilter}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add Filter\n </button>\n <button\n onClick={handleAddAndGroup}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add AND Group\n </button>\n <button\n onClick={handleAddOrGroup}\n className=\"w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover\"\n >\n Add OR Group\n </button>\n </div>\n )}\n </div>\n\n {/* Remove group button */}\n <button\n onClick={() => onGroupRemove(index)}\n className=\"text-dc-text-muted hover:text-dc-error focus:outline-hidden\"\n title=\"Remove group\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n \n {/* Group content */}\n <div className=\"space-y-3\">\n {filters.map((filter, filterIndex) => {\n if (isSimpleFilter(filter)) {\n return (\n <FilterItem\n key={filterIndex}\n filter={filter}\n index={filterIndex}\n onFilterChange={handleFilterChange}\n onFilterRemove={handleFilterRemove}\n schema={schema}\n query={query}\n />\n )\n } else if (isGroupFilter(filter)) {\n return (\n <FilterGroup\n key={filterIndex}\n group={filter}\n index={filterIndex}\n onGroupChange={handleNestedGroupChange}\n onGroupRemove={handleNestedGroupRemove}\n schema={schema}\n query={query}\n depth={depth + 1}\n />\n )\n }\n return null\n })}\n \n {/* Empty state */}\n {filters.length === 0 && (\n <div className=\"text-center py-4 text-dc-text-muted text-sm\">\n No conditions in this group.\n <button\n onClick={handleAddSimpleFilter}\n className=\"ml-2 text-dc-accent hover:text-dc-accent focus:outline-hidden underline\"\n >\n Add a filter\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default FilterGroup","/**\n * FilterBuilder Component\n * \n * Main component for managing all filters in the query.\n * Handles the top-level filter state and provides controls for adding new filters and groups.\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from './FilterItem'\nimport FilterGroup from './FilterGroup'\nimport type { FilterBuilderProps } from './types'\nimport type { SimpleFilter, GroupFilter } from '../../types'\nimport {\n isSimpleFilter,\n isGroupFilter,\n isAndFilter,\n isOrFilter,\n createSimpleFilter,\n createAndFilter,\n createOrFilter,\n countFilters,\n getAllFilterableFields\n} from './utils'\n\nconst AddIcon = getIcon('add')\nconst FilterIcon = getIcon('filter')\n\nconst FilterBuilder: React.FC<FilterBuilderProps> = ({\n filters,\n schema,\n query,\n onFiltersChange,\n hideFieldSelector = false\n}) => {\n \n \n const totalFilterCount = countFilters(filters)\n \n // Get all filterable fields from schema\n const allFilterableFields = schema ? getAllFilterableFields(schema) : []\n const hasFilterableFields = allFilterableFields.length > 0\n \n const handleAddSimpleFilter = () => {\n if (!hasFilterableFields) return\n \n // Use the first available field as default\n const defaultField = allFilterableFields[0]?.name || ''\n const newFilter = createSimpleFilter(defaultField, 'equals', [])\n \n // Smart filter grouping logic:\n // - First filter: add as simple filter\n // - Second filter: create AND group with first filter + new filter\n // - Additional filters: add to existing group (AND or OR, respecting current type)\n \n if (filters.length === 0) {\n // First filter - add as simple filter\n onFiltersChange([newFilter])\n } else if (filters.length === 1 && isSimpleFilter(filters[0])) {\n // Second filter - create AND group with existing filter + new filter\n const andGroup = createAndFilter([filters[0], newFilter])\n onFiltersChange([andGroup])\n } else if (filters.length === 1 && isAndFilter(filters[0])) {\n // Additional filter - add to existing AND group\n const existingAndGroup = filters[0]\n const updatedAndGroup = createAndFilter([...existingAndGroup.filters, newFilter])\n onFiltersChange([updatedAndGroup])\n } else if (filters.length === 1 && isOrFilter(filters[0])) {\n // Additional filter - add to existing OR group\n const existingOrGroup = filters[0]\n const updatedOrGroup = createOrFilter([...existingOrGroup.filters, newFilter])\n onFiltersChange([updatedOrGroup])\n } else {\n // Fallback: just add to the end (shouldn't happen with new logic)\n onFiltersChange([...filters, newFilter])\n }\n }\n \n \n const handleFilterChange = (index: number, newFilter: SimpleFilter) => {\n const newFilters = [...filters]\n newFilters[index] = newFilter\n onFiltersChange(newFilters)\n }\n \n const handleFilterRemove = (index: number) => {\n // Simple case: just remove the filter\n // The handleGroupChange method will automatically handle unwrapping if needed\n const newFilters = filters.filter((_, i) => i !== index)\n onFiltersChange(newFilters)\n }\n \n const handleGroupChange = (index: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n newFilters[index] = newGroup\n onFiltersChange(newFilters)\n }\n \n const handleGroupChangeWithUnwrap = (index: number, newGroup: GroupFilter) => {\n const newFilters = [...filters]\n \n // Check if the group has been reduced to a single filter and should be unwrapped\n // This is only used during filter removal operations\n if (newGroup.filters.length === 1 && isSimpleFilter(newGroup.filters[0])) {\n // Unwrap the single filter from the group\n newFilters[index] = newGroup.filters[0]\n } else {\n newFilters[index] = newGroup\n }\n \n onFiltersChange(newFilters)\n }\n \n const handleGroupRemove = () => {\n // When removing an AND group, we should remove all filters\n onFiltersChange([])\n }\n \n const handleClearAllFilters = () => {\n onFiltersChange([])\n }\n \n return (\n <div className=\"space-y-4 bg-dc-surface-secondary rounded-lg p-4\">\n {/* Header - hidden for universal time filters */}\n {!hideFieldSelector && (\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center\">\n <FilterIcon className=\"w-4 h-4 text-dc-text-muted mr-2\" />\n <h4 className=\"text-sm font-semibold text-dc-text-secondary\">\n Filters ({totalFilterCount})\n </h4>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Clear all button */}\n {filters.length > 0 && (\n <button\n onClick={handleClearAllFilters}\n className=\"text-xs text-dc-text-muted hover:text-dc-error focus:outline-hidden underline\"\n >\n Clear all\n </button>\n )}\n\n {/* Add Filter button */}\n <button\n onClick={handleAddSimpleFilter}\n disabled={!hasFilterableFields}\n className={`flex items-center space-x-1 px-2 py-1 text-xs font-medium rounded focus:outline-hidden focus:ring-2 ${\n hasFilterableFields\n ? 'text-dc-accent bg-dc-accent-bg border border-dc-accent hover:bg-dc-accent-bg focus:ring-dc-accent'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n >\n <AddIcon className=\"w-3 h-3\" />\n <span>Add Filter</span>\n </button>\n </div>\n </div>\n )}\n \n {/* Filters list */}\n {filters.length > 0 && (\n <div className=\"space-y-3\">\n {filters.map((filter, index) => {\n \n if (isSimpleFilter(filter)) {\n return (\n <FilterItem\n key={index}\n filter={filter}\n index={index}\n onFilterChange={handleFilterChange}\n onFilterRemove={handleFilterRemove}\n schema={schema}\n query={query}\n hideFieldSelector={hideFieldSelector}\n hideRemoveButton={hideFieldSelector}\n />\n )\n } else if (isGroupFilter(filter)) {\n return (\n <FilterGroup\n key={index}\n group={filter}\n index={index}\n onGroupChange={handleGroupChange}\n onGroupChangeWithUnwrap={handleGroupChangeWithUnwrap}\n onGroupRemove={handleGroupRemove}\n schema={schema}\n query={query}\n depth={0}\n />\n )\n }\n return null\n })}\n </div>\n )}\n \n </div>\n )\n}\n\nexport default FilterBuilder","/**\n * DateRangeSelector Component\n * \n * Individual date range selector for a specific time dimension\n * Styled to match FilterItem component exactly\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\nimport { getIcon } from '../../icons'\nimport { DATE_RANGE_OPTIONS, type DateRangeType } from './types'\nimport { convertDateRangeTypeToValue, formatDateForCube, requiresNumberInput } from './utils'\n\nconst CloseIcon = getIcon('close')\nconst CalendarIcon = getIcon('timeDimension')\nconst ChevronDownIcon = getIcon('chevronDown')\n\ninterface DateRangeSelectorProps {\n timeDimension: string\n availableTimeDimensions: string[]\n currentDateRange?: string | string[]\n onDateRangeChange: (timeDimension: string, dateRange: string | string[]) => void\n onTimeDimensionChange: (oldTimeDimension: string, newTimeDimension: string) => void\n onRemove: (timeDimension: string) => void\n hideFieldSelector?: boolean // Hide the time dimension field selector (for read-only filters)\n hideRemoveButton?: boolean // Hide the remove button (for read-only filters)\n}\n\nconst DateRangeSelector: React.FC<DateRangeSelectorProps> = ({\n timeDimension,\n availableTimeDimensions,\n currentDateRange,\n onDateRangeChange,\n onTimeDimensionChange,\n onRemove,\n hideFieldSelector = false,\n hideRemoveButton = false\n}) => {\n // Parse current date range to determine the type and custom dates\n const getCurrentRangeType = (): DateRangeType => {\n if (!currentDateRange) return 'this_month'\n \n if (Array.isArray(currentDateRange)) {\n return 'custom'\n }\n \n // Check if it's a flexible range with number (e.g., \"last 9 weeks\")\n const flexibleRangeMatch = currentDateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n const [, , unit] = flexibleRangeMatch\n const unitPlural = unit === 'days' ? 'days' : unit === 'weeks' ? 'weeks' : unit === 'months' ? 'months' : unit === 'quarters' ? 'quarters' : 'years'\n return `last_n_${unitPlural}` as DateRangeType\n }\n \n // Find matching predefined range\n for (const option of DATE_RANGE_OPTIONS) {\n if (option.value !== 'custom' && !requiresNumberInput(option.value) && convertDateRangeTypeToValue(option.value) === currentDateRange) {\n return option.value\n }\n }\n \n return 'custom'\n }\n\n const getCurrentDates = (): { startDate: string; endDate: string } => {\n if (Array.isArray(currentDateRange) && currentDateRange.length >= 1) {\n return {\n startDate: currentDateRange[0] || '',\n endDate: currentDateRange[1] || currentDateRange[0] || ''\n }\n }\n \n // Default to today for custom ranges\n const today = formatDateForCube(new Date())\n return { startDate: today, endDate: today }\n }\n\n const getCurrentNumber = (): number => {\n if (!currentDateRange || Array.isArray(currentDateRange)) return 1\n \n // Check if it's a flexible range with number (e.g., \"last 9 weeks\")\n const flexibleRangeMatch = currentDateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexibleRangeMatch) {\n return parseInt(flexibleRangeMatch[1]) || 1\n }\n \n return 1\n }\n\n const [rangeType, setRangeType] = useState<DateRangeType>(getCurrentRangeType())\n const [customDates, setCustomDates] = useState(getCurrentDates())\n const [numberValue, setNumberValue] = useState<number>(getCurrentNumber())\n const [isRangeDropdownOpen, setIsRangeDropdownOpen] = useState(false)\n const [isTimeDimensionDropdownOpen, setIsTimeDimensionDropdownOpen] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n \n // Close dropdowns when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsRangeDropdownOpen(false)\n setIsTimeDimensionDropdownOpen(false)\n }\n }\n \n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n // Close other dropdowns when opening one\n const handleTimeDimensionDropdownToggle = () => {\n setIsRangeDropdownOpen(false)\n setIsTimeDimensionDropdownOpen(!isTimeDimensionDropdownOpen)\n }\n \n const handleRangeDropdownToggle = () => {\n setIsTimeDimensionDropdownOpen(false)\n setIsRangeDropdownOpen(!isRangeDropdownOpen)\n }\n\n const handleRangeTypeChange = (newRangeType: DateRangeType) => {\n setRangeType(newRangeType)\n setIsRangeDropdownOpen(false)\n \n if (newRangeType === 'custom') {\n // For custom, use current custom dates or default to today\n if (customDates.startDate && customDates.endDate) {\n const dateRange = customDates.startDate === customDates.endDate \n ? customDates.startDate\n : [customDates.startDate, customDates.endDate]\n onDateRangeChange(timeDimension, dateRange)\n }\n } else if (requiresNumberInput(newRangeType)) {\n // For number-based ranges, use the number value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType, numberValue)\n onDateRangeChange(timeDimension, cubeRangeValue)\n } else {\n // For predefined ranges, use the converted value\n const cubeRangeValue = convertDateRangeTypeToValue(newRangeType)\n onDateRangeChange(timeDimension, cubeRangeValue)\n }\n }\n\n const handleCustomDateChange = (field: 'startDate' | 'endDate', value: string) => {\n const newCustomDates = { ...customDates, [field]: value }\n setCustomDates(newCustomDates)\n \n if (rangeType === 'custom' && newCustomDates.startDate) {\n const dateRange = !newCustomDates.endDate || newCustomDates.startDate === newCustomDates.endDate\n ? newCustomDates.startDate\n : [newCustomDates.startDate, newCustomDates.endDate]\n onDateRangeChange(timeDimension, dateRange)\n }\n }\n\n const handleNumberChange = (value: number) => {\n setNumberValue(value)\n \n if (requiresNumberInput(rangeType)) {\n const cubeRangeValue = convertDateRangeTypeToValue(rangeType, value)\n onDateRangeChange(timeDimension, cubeRangeValue)\n }\n }\n\n const handleTimeDimensionChange = (newTimeDimension: string) => {\n setIsTimeDimensionDropdownOpen(false)\n onTimeDimensionChange(timeDimension, newTimeDimension)\n }\n\n const selectedRangeLabel = DATE_RANGE_OPTIONS.find(opt => opt.value === rangeType)?.label || 'Custom'\n\n return (\n <div ref={containerRef} className=\"bg-dc-surface border border-dc-border rounded-lg p-3\">\n {/* Responsive layout - stacks on mobile, single row on desktop */}\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 min-w-0\">\n {/* Row 1: Filter icon and time dimension field - conditionally hidden */}\n {!hideFieldSelector && (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <CalendarIcon className=\"w-4 h-4 text-dc-text-muted shrink-0\" />\n\n {/* Time dimension field selector */}\n <div className=\"relative flex-1 min-w-0\">\n <button\n onClick={handleTimeDimensionDropdownToggle}\n className=\"w-full flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent min-w-0\"\n >\n <span className=\"truncate\">{timeDimension}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 transition-transform ${\n isTimeDimensionDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isTimeDimensionDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {availableTimeDimensions.map((td) => (\n <button\n key={td}\n onClick={() => handleTimeDimensionChange(td)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n td === timeDimension ? 'bg-dc-accent-bg dark:bg-dc-accent-bg text-dc-accent dark:text-dc-accent' : 'text-dc-text-secondary'\n }`}\n >\n {td}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Row 2: Date range selector */}\n <div className=\"flex items-center gap-2 flex-1 sm:flex-initial min-w-0\">\n {/* Range type selector with custom dropdown */}\n <div className=\"relative shrink-0\">\n <button\n onClick={handleRangeDropdownToggle}\n className=\"w-full sm:w-40 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n >\n <span className=\"truncate\">{selectedRangeLabel}</span>\n <ChevronDownIcon className={`w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isRangeDropdownOpen ? 'transform rotate-180' : ''\n }`} />\n </button>\n\n {isRangeDropdownOpen && (\n <div className=\"absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto\">\n {DATE_RANGE_OPTIONS.map((option) => (\n <button\n key={option.value}\n onClick={() => handleRangeTypeChange(option.value)}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n option.value === rangeType ? 'bg-dc-accent-bg dark:bg-dc-accent-bg text-dc-accent dark:text-dc-accent' : 'text-dc-text-secondary'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Row 3: Custom date inputs, number input, or remove button */}\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {rangeType === 'custom' ? (\n <>\n {/* Start date */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"date\"\n value={customDates.startDate}\n onChange={(e) => handleCustomDateChange('startDate', e.target.value)}\n placeholder=\"dd/mm/yyyy\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n </div>\n\n {/* End date (optional) */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"date\"\n value={customDates.endDate}\n onChange={(e) => handleCustomDateChange('endDate', e.target.value)}\n placeholder=\"dd/mm/yyyy\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n </div>\n </>\n ) : requiresNumberInput(rangeType) ? (\n <>\n {/* Number input for flexible ranges */}\n <div className=\"flex-1 min-w-0\">\n <input\n type=\"number\"\n min=\"1\"\n max=\"1000\"\n value={numberValue}\n onChange={(e) => handleNumberChange(Math.max(1, parseInt(e.target.value) || 1))}\n placeholder=\"Number\"\n className=\"w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n />\n </div>\n\n {/* Unit display */}\n <div className=\"shrink-0 text-sm text-dc-text-secondary\">\n {rangeType.replace('last_n_', '').replace('_', ' ')}\n </div>\n </>\n ) : (\n // Empty placeholder to maintain layout consistency\n <div className=\"flex-1\"></div>\n )}\n\n {/* Remove button - conditionally hidden */}\n {!hideRemoveButton && (\n <button\n onClick={() => onRemove(timeDimension)}\n className=\"text-dc-text-muted hover:text-dc-error focus:outline-hidden shrink-0 p-1\"\n title=\"Remove date range\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nexport default DateRangeSelector","/**\n * DateRangeFilter Component\n * \n * Container component for managing date ranges on time dimensions.\n * Shows all time dimensions with date ranges and provides controls for adding new ones.\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport DateRangeSelector from './DateRangeSelector'\nimport type { DateRangeFilterProps } from './types'\nimport { getTimeDimensionsWithDateRanges } from './utils'\n\nconst AddIcon = getIcon('add')\nconst CalendarIcon = getIcon('timeDimension')\n\nconst DateRangeFilter: React.FC<DateRangeFilterProps> = ({\n timeDimensions,\n onDateRangeChange,\n onDateRangeRemove\n}) => {\n // Get current date ranges from time dimensions\n const currentDateRanges = getTimeDimensionsWithDateRanges({ timeDimensions })\n \n // Get time dimensions that don't have date ranges yet\n const availableTimeDimensions = timeDimensions.filter(td => !td.dateRange)\n \n // Count of time dimensions with date ranges\n const dateRangeCount = Object.keys(currentDateRanges).length\n\n const handleAddDateRange = () => {\n if (availableTimeDimensions.length === 0) return\n \n // Add date range to the first available time dimension with default \"this month\"\n const firstAvailable = availableTimeDimensions[0]\n onDateRangeChange(firstAvailable.dimension, 'this month')\n }\n\n const handleClearAllDateRanges = () => {\n // Remove all date ranges\n Object.keys(currentDateRanges).forEach(timeDimension => {\n onDateRangeRemove(timeDimension)\n })\n }\n\n // Don't render if there are no time dimensions\n if (!timeDimensions || timeDimensions.length === 0) {\n return null\n }\n\n return (\n <div className=\"space-y-4 bg-dc-surface-secondary rounded-lg p-4\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center\">\n <CalendarIcon className=\"w-4 h-4 text-dc-text-muted mr-2\" />\n <h4 className=\"text-sm font-semibold text-dc-text-secondary\">\n Date Ranges ({dateRangeCount})\n </h4>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n {/* Clear all button */}\n {dateRangeCount > 0 && (\n <button\n onClick={handleClearAllDateRanges}\n className=\"text-xs text-dc-text-muted hover:text-dc-error focus:outline-hidden underline\"\n >\n Clear all\n </button>\n )}\n \n {/* Add Date Range button */}\n <button\n onClick={handleAddDateRange}\n disabled={availableTimeDimensions.length === 0}\n className={`flex items-center space-x-1 px-2 py-1 text-xs font-medium rounded focus:outline-hidden focus:ring-2 ${\n availableTimeDimensions.length > 0\n ? 'text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg focus:ring-dc-accent'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n title={availableTimeDimensions.length === 0 ? 'All time dimensions already have date ranges' : 'Add date range'}\n >\n <AddIcon className=\"w-3 h-3\" />\n <span>Add Date Range</span>\n </button>\n </div>\n </div>\n \n {/* Date Range List */}\n {dateRangeCount > 0 && (\n <div className=\"space-y-3\">\n {timeDimensions.map(td => {\n if (!td.dateRange) return null\n \n const allTimeDimensions = timeDimensions.map(t => t.dimension)\n \n return (\n <DateRangeSelector\n key={td.dimension}\n timeDimension={td.dimension}\n availableTimeDimensions={allTimeDimensions}\n currentDateRange={td.dateRange}\n onDateRangeChange={onDateRangeChange}\n onTimeDimensionChange={(oldTd, newTd) => {\n // Remove date range from old time dimension and add it to new one\n onDateRangeRemove(oldTd)\n onDateRangeChange(newTd, td.dateRange!)\n }}\n onRemove={onDateRangeRemove}\n />\n )\n })}\n </div>\n )}\n \n </div>\n )\n}\n\nexport default DateRangeFilter","/**\n * QueryAnalysisPanel Component\n * Displays query planning analysis for debugging and transparency\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport type { QueryAnalysis } from './types'\n\ninterface QueryAnalysisPanelProps {\n analysis: QueryAnalysis\n}\n\n/**\n * Format reason string for display\n */\nfunction formatReason(reason: string): string {\n return reason.replace(/_/g, ' ')\n}\n\n/**\n * Get badge color based on reason\n */\nfunction getReasonBadgeClasses(reason: string): string {\n switch (reason) {\n case 'most_dimensions':\n return 'bg-dc-accent-bg dark:bg-dc-accent-bg text-dc-accent dark:text-dc-accent'\n case 'most_connected':\n return 'bg-dc-accent-bg dark:bg-dc-accent-bg text-dc-accent dark:text-dc-accent'\n case 'alphabetical_fallback':\n return 'bg-dc-warning-bg dark:bg-dc-warning-bg text-dc-warning dark:text-dc-warning'\n case 'single_cube':\n return 'bg-dc-success-bg dark:bg-dc-success-bg text-dc-success dark:text-dc-success'\n default:\n return 'bg-dc-bg-secondary dark:bg-dc-bg-secondary text-dc-text-secondary dark:text-dc-text-muted'\n }\n}\n\nconst QueryAnalysisPanel: React.FC<QueryAnalysisPanelProps> = ({ analysis }) => {\n const InfoIcon = getIcon('info')\n const ArrowRightIcon = getIcon('chevronRight')\n const WarningIcon = getIcon('warning')\n const TableIcon = getIcon('table')\n const LinkIcon = getIcon('link')\n const SuccessIcon = getIcon('success')\n const ErrorIcon = getIcon('error')\n\n return (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4 space-y-4\">\n {/* Query Summary Section */}\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <InfoIcon className=\"w-4 h-4 mr-2\" />\n Query Summary\n </h4>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-2 text-xs\">\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Type:</span>\n <span className=\"ml-1 font-medium text-dc-text\">\n {formatReason(analysis.querySummary.queryType)}\n </span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Cubes:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.cubeCount}</span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Joins:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.querySummary.joinCount}</span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">CTEs:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.querySummary.cteCount}</span>\n </div>\n </div>\n </div>\n\n {/* Primary Cube Section */}\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <TableIcon className=\"w-4 h-4 mr-2\" />\n Primary Cube (FROM table)\n </h4>\n <div className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-2 flex-wrap\">\n <span className=\"font-mono font-medium text-dc-primary\">\n {analysis.primaryCube.selectedCube}\n </span>\n <span className={`text-xs px-2 py-0.5 rounded ${getReasonBadgeClasses(analysis.primaryCube.reason)}`}>\n {formatReason(analysis.primaryCube.reason)}\n </span>\n </div>\n <p className=\"text-dc-text-secondary text-xs\">\n {analysis.primaryCube.explanation}\n </p>\n {analysis.primaryCube.candidates && analysis.primaryCube.candidates.length > 1 && (\n <details className=\"mt-2\">\n <summary className=\"text-xs text-dc-text-muted cursor-pointer hover:text-dc-text\">\n Show candidates ({analysis.primaryCube.candidates.length})\n </summary>\n <div className=\"mt-2 space-y-1 ml-2\">\n {analysis.primaryCube.candidates.map((c, i) => (\n <div key={i} className=\"text-xs flex items-center gap-2 flex-wrap\">\n <span className={`font-mono ${c.cubeName === analysis.primaryCube.selectedCube ? 'font-bold text-dc-primary' : 'text-dc-text-muted'}`}>\n {c.cubeName}\n </span>\n <span className=\"text-dc-text-muted\">\n dims: {c.dimensionCount}, joins: {c.joinCount}\n </span>\n {c.canReachAll ? (\n <span className=\"text-dc-success dark:text-dc-success flex items-center gap-0.5\">\n <SuccessIcon className=\"w-3 h-3\" />\n reachable\n </span>\n ) : (\n <span className=\"text-dc-error dark:text-dc-error flex items-center gap-0.5\">\n <ErrorIcon className=\"w-3 h-3\" />\n cannot reach all\n </span>\n )}\n </div>\n ))}\n </div>\n </details>\n )}\n </div>\n </div>\n\n {/* Join Paths Section */}\n {analysis.joinPaths.length > 0 && (\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <LinkIcon className=\"w-4 h-4 mr-2\" />\n Join Paths\n </h4>\n <div className=\"space-y-2\">\n {analysis.joinPaths.map((jp, idx) => (\n <div key={idx} className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-2 flex-wrap\">\n <span className=\"font-mono text-dc-text-secondary\">{analysis.primaryCube.selectedCube}</span>\n <ArrowRightIcon className=\"w-4 h-4 text-dc-text-muted\" />\n <span className=\"font-mono font-medium text-dc-text\">{jp.targetCube}</span>\n {jp.pathFound ? (\n <span className=\"text-xs px-2 py-0.5 bg-dc-success-bg dark:bg-dc-success-bg text-dc-success dark:text-dc-success rounded\">\n {jp.pathLength} step{jp.pathLength !== 1 ? 's' : ''}\n </span>\n ) : (\n <span className=\"text-xs px-2 py-0.5 bg-dc-danger-bg dark:bg-dc-danger-bg text-dc-error dark:text-dc-error rounded\">\n No path\n </span>\n )}\n </div>\n {jp.pathFound && jp.path && jp.path.length > 0 && (\n <div className=\"space-y-1 ml-2\">\n {jp.path.map((step, stepIdx) => (\n <div key={stepIdx} className=\"flex items-center gap-1 text-xs flex-wrap\">\n <span className=\"font-mono text-dc-text-secondary\">{step.fromCube}</span>\n <ArrowRightIcon className=\"w-3 h-3 text-dc-text-muted\" />\n <span className=\"font-mono text-dc-text\">{step.toCube}</span>\n <span className=\"text-dc-text-muted\">\n ({step.relationship}, {step.joinType} join)\n </span>\n {step.joinColumns.length > 0 && (\n <span className=\"text-dc-text-muted\">\n on {step.joinColumns.map(jc => `${jc.sourceColumn}=${jc.targetColumn}`).join(', ')}\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n {!jp.pathFound && jp.error && (\n <p className=\"text-xs text-dc-error dark:text-dc-error mt-1\">{jp.error}</p>\n )}\n {jp.visitedCubes && jp.visitedCubes.length > 0 && !jp.pathFound && (\n <details className=\"mt-1\">\n <summary className=\"text-xs text-dc-text-muted cursor-pointer hover:text-dc-text\">\n Cubes visited during search ({jp.visitedCubes.length})\n </summary>\n <div className=\"mt-1 text-xs text-dc-text-muted ml-2\">\n {jp.visitedCubes.join(' → ')}\n </div>\n </details>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Pre-Aggregations Section */}\n {analysis.preAggregations.length > 0 && (\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <TableIcon className=\"w-4 h-4 mr-2\" />\n Pre-Aggregation CTEs\n </h4>\n <div className=\"space-y-2\">\n {analysis.preAggregations.map((pa, idx) => (\n <div key={idx} className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-1 flex-wrap\">\n <span className=\"font-mono font-medium text-dc-text\">{pa.cubeName}</span>\n <span className=\"text-xs text-dc-text-muted\">as</span>\n <code className=\"text-xs bg-dc-surface-secondary px-1 rounded font-mono\">{pa.cteAlias}</code>\n </div>\n <p className=\"text-xs text-dc-text-secondary\">{pa.reason}</p>\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n <span className=\"font-medium\">Measures:</span> {pa.measures.join(', ')}\n </div>\n {pa.joinKeys.length > 0 && (\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n <span className=\"font-medium\">Join keys:</span> {pa.joinKeys.map(jk => `${jk.sourceColumn}=${jk.targetColumn}`).join(', ')}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Warnings Section */}\n {analysis.warnings && analysis.warnings.length > 0 && (\n <div>\n <h4 className=\"text-sm font-semibold text-dc-warning dark:text-dc-warning mb-2 flex items-center\">\n <WarningIcon className=\"w-4 h-4 mr-2\" />\n Warnings\n </h4>\n <ul className=\"list-disc list-inside text-xs text-dc-warning dark:text-dc-warning space-y-1\">\n {analysis.warnings.map((w, i) => (\n <li key={i}>{w}</li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Cubes Involved */}\n {analysis.cubesInvolved.length > 0 && (\n <div className=\"text-xs text-dc-text-muted pt-2 border-t border-dc-border\">\n <span className=\"font-medium\">Cubes involved:</span> {analysis.cubesInvolved.join(', ')}\n </div>\n )}\n </div>\n )\n}\n\nexport default QueryAnalysisPanel\n","/**\n * QueryPanel Component\n * \n * Displays the current query being built, with sections for measures, dimensions, and time dimensions.\n * Includes validation status, JSON preview, and action buttons.\n */\n\nimport React, { useState, useEffect, memo, useMemo, useRef, useCallback } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterBuilder from './FilterBuilder'\nimport DateRangeFilter from './DateRangeFilter'\nimport QueryAnalysisPanel from './QueryAnalysisPanel'\nimport type { QueryPanelProps } from './types'\nimport { TIME_GRANULARITIES } from './types'\nimport { hasQueryContent, getSelectedFieldsCount, cleanQueryForServer, hasTimeDimensions, getFieldTitle, getSortDirection, getSortTooltip, getNextSortDirection, getFieldType } from './utils'\nimport { getMeasureIcon } from '../../utils/measureIcons'\n\ntype IconComponent = React.ComponentType<{ className?: string }>\n\ninterface QueryPanelHeaderProps {\n hasContent: boolean\n selectedCount: number\n copyButtonState: 'idle' | 'copied'\n shareButtonState: QueryPanelProps['shareButtonState']\n canShare: boolean\n onShareClick?: () => void\n onClearQuery?: () => void\n onSettingsClick?: () => void\n onAIAssistantClick?: () => void\n onSchemaClick?: () => void\n showSettings?: boolean\n handleCopyQuery: () => void\n icons: {\n SettingsIcon: ReturnType<typeof getIcon>\n CopyIcon: ReturnType<typeof getIcon>\n ShareIcon: ReturnType<typeof getIcon>\n CheckIcon: ReturnType<typeof getIcon>\n DeleteIcon: ReturnType<typeof getIcon>\n SparklesIcon: ReturnType<typeof getIcon>\n }\n}\n\nconst QueryPanelHeader = memo(({\n hasContent,\n selectedCount,\n copyButtonState,\n shareButtonState,\n canShare,\n onShareClick,\n onClearQuery,\n onSettingsClick,\n onAIAssistantClick,\n onSchemaClick,\n showSettings,\n handleCopyQuery,\n icons\n}: QueryPanelHeaderProps) => {\n const {\n SettingsIcon,\n CopyIcon,\n ShareIcon,\n CheckIcon,\n DeleteIcon,\n SparklesIcon\n } = icons\n\n return (\n <div className=\"p-3 sm:p-4 border-b border-dc-border\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-1 sm:gap-2 min-w-0\">\n <h3 className=\"text-sm sm:text-lg font-semibold text-dc-text truncate\">Query Builder</h3>\n {onSchemaClick && (\n <button\n onClick={onSchemaClick}\n className=\"flex items-center gap-1 px-3 py-2 text-xs font-medium text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent rounded-lg hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg focus:outline-hidden focus:ring-2 focus:ring-dc-accent transition-all duration-200 shrink-0\"\n title=\"Schema Explorer - View cube relationships and fields\"\n >\n <svg className=\"w-3 h-3 sm:w-4 sm:h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z\" clipRule=\"evenodd\" />\n </svg>\n <span>Schema</span>\n </button>\n )}\n {onAIAssistantClick && (\n <button\n onClick={onAIAssistantClick}\n className=\"flex items-center gap-1 px-3 py-2 text-xs font-medium text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent rounded-lg hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg focus:outline-hidden focus:ring-2 focus:ring-dc-accent transition-all duration-200 shrink-0\"\n title=\"AI Assistant - Generate queries with AI\"\n >\n <SparklesIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n <span>AI Assistant</span>\n </button>\n )}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">\n <span className=\"hidden lg:inline text-xs text-dc-text-muted mr-1\">\n {selectedCount} field{selectedCount !== 1 ? 's' : ''} selected\n </span>\n <button\n onClick={handleCopyQuery}\n className={`flex items-center gap-1 px-3 py-2 text-xs font-medium rounded-sm focus:outline-hidden focus:ring-2 ${\n hasContent\n ? 'text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg focus:ring-dc-accent'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n title={copyButtonState === 'idle' ? 'Copy query to clipboard' : 'Copied!'}\n disabled={!hasContent}\n >\n {copyButtonState === 'idle' ? (\n <>\n <CopyIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copy Query</span>\n </>\n ) : (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n </>\n )}\n </button>\n {onShareClick && (\n <button\n onClick={onShareClick}\n className={`flex items-center gap-1 px-3 py-2 text-xs font-medium rounded-sm focus:outline-hidden focus:ring-2 transition-colors ${\n shareButtonState === 'idle' && canShare\n ? 'text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg focus:ring-dc-accent'\n : shareButtonState !== 'idle'\n ? 'text-dc-success dark:text-dc-success bg-dc-success-bg dark:bg-dc-success-bg border border-dc-success dark:border-dc-success focus:ring-dc-success'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n title={shareButtonState === 'idle' ? 'Share this analysis' : 'Link copied!'}\n disabled={!canShare || shareButtonState !== 'idle'}\n >\n {shareButtonState === 'idle' ? (\n <>\n <ShareIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Share</span>\n </>\n ) : shareButtonState === 'copied' ? (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n </>\n ) : (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n <span className=\"hidden lg:inline text-[10px] opacity-75\">(no chart)</span>\n </>\n )}\n </button>\n )}\n {onClearQuery && (\n <button\n onClick={onClearQuery}\n className={`p-2 focus:outline-hidden ${\n hasContent ? 'text-dc-text-muted hover:text-dc-error' : 'text-dc-text-muted opacity-40 cursor-not-allowed'\n }`}\n title=\"Clear all fields\"\n disabled={!hasContent}\n >\n <DeleteIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n </button>\n )}\n {showSettings && onSettingsClick && (\n <button\n onClick={onSettingsClick}\n className=\"text-dc-text-muted hover:text-dc-text-secondary focus:outline-hidden p-2\"\n title=\"API Configuration\"\n >\n <SettingsIcon className=\"w-3 h-3 sm:w-4 sm:h-4\" />\n </button>\n )}\n </div>\n </div>\n </div>\n )\n})\n\ninterface RemovableChipProps {\n fieldName: string\n fieldType: 'measures' | 'dimensions' | 'timeDimensions'\n schema: QueryPanelProps['schema']\n icon: React.ReactNode\n hasFilters: boolean\n sortDirection: 'asc' | 'desc' | null\n sortTooltip: string\n onAddFilter: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onToggleSort: (fieldName: string) => void\n onRemoveField: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n FilterIcon: IconComponent\n ChevronUpIcon: IconComponent\n ChevronDownIcon: IconComponent\n ChevronUpDownIcon: IconComponent\n CloseIcon: IconComponent\n}\n\nconst RemovableChip = memo(({\n fieldName,\n fieldType,\n schema,\n icon,\n hasFilters,\n sortDirection,\n sortTooltip,\n onAddFilter,\n onToggleSort,\n onRemoveField,\n FilterIcon,\n ChevronUpIcon,\n ChevronDownIcon,\n ChevronUpDownIcon,\n CloseIcon\n}: RemovableChipProps) => {\n const getChipClasses = () => {\n switch (fieldType) {\n case 'measures':\n return 'bg-dc-measure text-dc-measure border-dc-measure'\n case 'dimensions':\n return 'bg-dc-dimension text-dc-dimension border-dc-dimension'\n case 'timeDimensions':\n return 'bg-dc-time-dimension text-dc-time-dimension border-dc-time-dimension'\n default:\n return 'bg-dc-time-dimension text-dc-time-dimension border-dc-time-dimension'\n }\n }\n\n const getSortIcon = () => {\n switch (sortDirection) {\n case 'asc':\n return <ChevronUpIcon className=\"w-4 h-4 stroke-3\" />\n case 'desc':\n return <ChevronDownIcon className=\"w-4 h-4 stroke-3\" />\n default:\n return <ChevronUpDownIcon className=\"w-4 h-4\" />\n }\n }\n\n const getSortButtonClasses = () => {\n const baseClasses = 'focus:outline-hidden shrink-0 p-0.5 transition-colors'\n if (sortDirection) {\n switch (fieldType) {\n case 'measures':\n return `${baseClasses} text-dc-measure hover:opacity-80`\n case 'dimensions':\n return `${baseClasses} text-dc-dimension hover:opacity-80`\n case 'timeDimensions':\n return `${baseClasses} text-dc-time-dimension hover:opacity-80`\n default:\n return `${baseClasses} text-dc-time-dimension hover:opacity-80`\n }\n }\n return `${baseClasses} text-dc-text-muted hover:text-dc-text-secondary`\n }\n\n const filterColorClasses = () => {\n switch (fieldType) {\n case 'measures':\n return 'text-dc-measure hover:opacity-80'\n case 'dimensions':\n return 'text-dc-dimension hover:opacity-80'\n case 'timeDimensions':\n return 'text-dc-time-dimension hover:opacity-80'\n default:\n return 'text-dc-time-dimension hover:opacity-80'\n }\n }\n\n return (\n <div className={`inline-flex items-center text-sm px-3 py-2 rounded-lg border w-full ${getChipClasses()}`}>\n <div className=\"mr-2 shrink-0\">\n {icon}\n </div>\n <span className=\"flex-1 flex flex-col min-w-0\">\n <span className=\"text-xs font-medium truncate\">{getFieldTitle(fieldName, schema)}</span>\n <span className=\"text-[10px] text-dc-text-muted truncate\">{fieldName}</span>\n </span>\n <div className=\"flex items-center gap-2 ml-2\">\n <div className=\"flex flex-col items-center\">\n <button\n onClick={() => onAddFilter(fieldName, fieldType)}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${\n hasFilters\n ? filterColorClasses()\n : 'text-dc-text-muted hover:text-dc-text-secondary'\n }`}\n title={fieldType === 'timeDimensions' ? 'Add date range' : 'Add filter'}\n >\n <FilterIcon className={`w-4 h-4 ${hasFilters ? 'stroke-3' : ''}`} />\n </button>\n <button\n onClick={() => onToggleSort(fieldName)}\n className={getSortButtonClasses()}\n title={sortTooltip}\n >\n {getSortIcon()}\n </button>\n </div>\n <button\n onClick={() => onRemoveField(fieldName, fieldType)}\n className=\"text-dc-text-secondary hover:text-dc-error focus:outline-hidden shrink-0\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n )\n})\n\ninterface TimeDimensionChipProps {\n timeDimension: { dimension: string; granularity?: string }\n schema: QueryPanelProps['schema']\n hasDateRange: boolean\n sortDirection: 'asc' | 'desc' | null\n sortTooltip: string\n onAddFilter: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onToggleSort: (fieldName: string) => void\n onRemoveField: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void\n onGranularityChange: (dimensionName: string, granularity: string) => void\n TimeDimensionIcon: IconComponent\n FilterIcon: IconComponent\n ChevronUpIcon: IconComponent\n ChevronDownIcon: IconComponent\n ChevronUpDownIcon: IconComponent\n CloseIcon: IconComponent\n}\n\nconst TimeDimensionChip = memo(({\n timeDimension,\n schema,\n hasDateRange,\n sortDirection,\n sortTooltip,\n onAddFilter,\n onToggleSort,\n onRemoveField,\n onGranularityChange,\n TimeDimensionIcon,\n FilterIcon,\n ChevronUpIcon,\n ChevronDownIcon,\n ChevronUpDownIcon,\n CloseIcon\n}: TimeDimensionChipProps) => {\n const getSortIcon = () => {\n switch (sortDirection) {\n case 'asc':\n return <ChevronUpIcon className=\"w-4 h-4 stroke-3\" />\n case 'desc':\n return <ChevronDownIcon className=\"w-4 h-4 stroke-3\" />\n default:\n return <ChevronUpDownIcon className=\"w-4 h-4\" />\n }\n }\n\n const getSortButtonClasses = () => {\n const baseClasses = 'focus:outline-hidden shrink-0 p-0.5 transition-colors'\n if (sortDirection) {\n return `${baseClasses} text-dc-time-dimension hover:opacity-80`\n }\n return `${baseClasses} text-dc-text-muted hover:text-dc-text-secondary`\n }\n\n return (\n <div className=\"bg-dc-time-dimension text-dc-time-dimension text-sm px-3 py-2 rounded-lg border border-dc-time-dimension w-full\">\n <div className=\"flex items-center mb-1\">\n <div className=\"mr-2\">\n <TimeDimensionIcon className=\"w-4 h-4\" />\n </div>\n <span className=\"flex-1 flex flex-col min-w-0\">\n <span className=\"text-xs font-medium truncate\">{getFieldTitle(timeDimension.dimension, schema)}</span>\n <span className=\"text-[10px] text-dc-text-muted truncate\">{timeDimension.dimension}</span>\n </span>\n <div className=\"flex items-center gap-2 ml-2\">\n <div className=\"flex flex-col items-center\">\n <button\n onClick={() => onAddFilter(timeDimension.dimension, 'timeDimensions')}\n className={`focus:outline-hidden shrink-0 p-0.5 transition-colors ${\n hasDateRange\n ? 'text-dc-time-dimension hover:opacity-80'\n : 'text-dc-text-muted hover:text-dc-text-secondary'\n }`}\n title=\"Add date range\"\n >\n <FilterIcon className={`w-4 h-4 ${hasDateRange ? 'stroke-3' : ''}`} />\n </button>\n <button\n onClick={() => onToggleSort(timeDimension.dimension)}\n className={getSortButtonClasses()}\n title={sortTooltip}\n >\n {getSortIcon()}\n </button>\n </div>\n <button\n onClick={() => onRemoveField(timeDimension.dimension, 'timeDimensions')}\n className=\"text-dc-text-secondary hover:text-dc-error focus:outline-hidden\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n <div className=\"ml-6 flex items-center\">\n <span className=\"text-xs text-dc-time-dimension mr-2\">Granularity:</span>\n <select\n value={timeDimension.granularity || 'month'}\n onChange={(e) => onGranularityChange(timeDimension.dimension, e.target.value)}\n className=\"bg-dc-time-dimension border-none text-dc-time-dimension text-xs rounded-sm focus:ring-2 focus:ring-dc-accent flex-1\"\n onClick={(e) => e.stopPropagation()}\n >\n {TIME_GRANULARITIES.map(granularity => (\n <option key={granularity.value} value={granularity.value}>\n {granularity.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n )\n})\n\nconst QueryPanel: React.FC<QueryPanelProps> = ({\n query,\n schema,\n validationStatus,\n validationError,\n validationSql,\n validationAnalysis,\n onExecute,\n onRemoveField,\n onTimeDimensionGranularityChange,\n onFiltersChange,\n onDateRangeChange,\n onDateRangeRemove,\n onOrderChange,\n onClearQuery,\n showSettings,\n onSettingsClick,\n onAIAssistantClick,\n onSchemaClick,\n onShareClick,\n canShare = false,\n shareButtonState = 'idle',\n isViewingShared = false\n}) => {\n const [showJsonPreview, setShowJsonPreview] = useState(false)\n const [showSqlPreview, setShowSqlPreview] = useState(false)\n const [showAnalysisPreview, setShowAnalysisPreview] = useState(false)\n const [copyButtonState, setCopyButtonState] = useState<'idle' | 'copied'>('idle')\n const queryRef = useRef(query)\n\n useEffect(() => {\n queryRef.current = query\n }, [query])\n\n // Trigger Prism highlighting when preview content changes\n useEffect(() => {\n if ((showJsonPreview || showSqlPreview) && typeof window !== 'undefined' && (window as any).Prism) {\n // Use setTimeout to ensure DOM is updated before highlighting\n setTimeout(() => {\n try {\n ;(window as any).Prism.highlightAll()\n } catch {\n // Silently fail if Prism is not available or encounters an error\n }\n }, 0)\n }\n }, [showJsonPreview, showSqlPreview, query, validationSql])\n\n const hasContent = hasQueryContent(query)\n const selectedCount = getSelectedFieldsCount(query)\n\n const CloseIcon = useMemo(() => getIcon('close'), [])\n const ErrorIcon = useMemo(() => getIcon('error'), [])\n const DeleteIcon = useMemo(() => getIcon('delete'), [])\n const CopyIcon = useMemo(() => getIcon('copy'), [])\n const SettingsIcon = useMemo(() => getIcon('settings'), [])\n const FilterIcon = useMemo(() => getIcon('filter'), [])\n const SparklesIcon = useMemo(() => getIcon('sparkles'), [])\n const ChevronUpIcon = useMemo(() => getIcon('chevronUp'), [])\n const ChevronDownIcon = useMemo(() => getIcon('chevronDown'), [])\n const ChevronUpDownIcon = useMemo(() => getIcon('chevronUpDown'), [])\n const ShareIcon = useMemo(() => getIcon('share'), [])\n const MeasureIcon = useMemo(() => getIcon('measure'), [])\n const DimensionIcon = useMemo(() => getIcon('dimension'), [])\n const TimeDimensionIcon = useMemo(() => getIcon('timeDimension'), [])\n const RunIcon = useMemo(() => getIcon('run'), [])\n const CheckIcon = useMemo(() => getIcon('check'), [])\n\n const handleCopyQuery = useCallback(async () => {\n const cleanedQuery = cleanQueryForServer(queryRef.current)\n try {\n await navigator.clipboard.writeText(JSON.stringify(cleanedQuery, null, 2))\n // You could add a toast notification here if desired\n } catch {\n // Failed to copy query\n // Fallback for older browsers\n const textArea = document.createElement('textarea')\n textArea.value = JSON.stringify(cleanedQuery, null, 2)\n document.body.appendChild(textArea)\n textArea.select()\n document.execCommand('copy')\n document.body.removeChild(textArea)\n }\n setCopyButtonState('copied')\n setTimeout(() => {\n setCopyButtonState('idle')\n }, 1500)\n }, [])\n\n // Helper function to check if a field has filters applied\n const hasFiltersApplied = useCallback((fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions'): boolean => {\n if (fieldType === 'timeDimensions') {\n // Check if time dimension has a date range\n return Boolean(query.timeDimensions?.some(td => td.dimension === fieldName && td.dateRange))\n } else {\n // Check if field has regular filters applied\n const currentFilters = query.filters || []\n \n const hasFieldInFilters = (filters: any[]): boolean => {\n return filters.some(filter => {\n if ('member' in filter) {\n // Simple filter\n return filter.member === fieldName\n } else if ('type' in filter && 'filters' in filter) {\n // Group filter - check recursively\n return hasFieldInFilters(filter.filters)\n }\n return false\n })\n }\n \n return hasFieldInFilters(currentFilters)\n }\n }, [query.timeDimensions, query.filters])\n\n const handleAddFilterFromField = useCallback((fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n if (fieldType === 'timeDimensions') {\n // For time dimensions, add a date range instead of a regular filter\n onDateRangeChange(fieldName, 'this month')\n } else {\n // For measures and dimensions, add a regular filter\n // Get current filters and add a new one\n const currentFilters = query.filters || []\n const newFilter = {\n member: fieldName,\n operator: 'equals' as const,\n values: []\n }\n \n // Use the same smart grouping logic as FilterBuilder\n if (currentFilters.length === 0) {\n onFiltersChange([newFilter])\n } else if (currentFilters.length === 1 && 'member' in currentFilters[0]) {\n // Create AND group with existing filter + new filter\n const andGroup = {\n type: 'and' as const,\n filters: [currentFilters[0], newFilter]\n }\n onFiltersChange([andGroup])\n } else if (currentFilters.length === 1 && 'type' in currentFilters[0] && currentFilters[0].type === 'and') {\n // Add to existing AND group\n const existingAndGroup = currentFilters[0]\n const updatedAndGroup = {\n type: 'and' as const,\n filters: [...existingAndGroup.filters, newFilter]\n }\n onFiltersChange([updatedAndGroup])\n } else if (currentFilters.length === 1 && 'type' in currentFilters[0] && currentFilters[0].type === 'or') {\n // Add to existing OR group\n const existingOrGroup = currentFilters[0]\n const updatedOrGroup = {\n type: 'or' as const,\n filters: [...existingOrGroup.filters, newFilter]\n }\n onFiltersChange([updatedOrGroup])\n } else {\n // Fallback: just add to the end\n onFiltersChange([...currentFilters, newFilter])\n }\n }\n }, [onDateRangeChange, onFiltersChange, query.filters])\n\n const handleToggleSort = useCallback((fieldName: string) => {\n const current = getSortDirection(fieldName, query.order)\n const next = getNextSortDirection(current)\n onOrderChange(fieldName, next)\n }, [query.order, onOrderChange])\n\n const headerIcons = useMemo(() => ({\n SettingsIcon,\n CopyIcon,\n ShareIcon,\n CheckIcon,\n DeleteIcon,\n SparklesIcon\n }), [SettingsIcon, CopyIcon, ShareIcon, CheckIcon, DeleteIcon, SparklesIcon])\n\n return (\n <div className=\"flex flex-col bg-dc-surface border border-dc-border rounded-lg\">\n <QueryPanelHeader\n hasContent={hasContent}\n selectedCount={selectedCount}\n copyButtonState={copyButtonState}\n shareButtonState={shareButtonState}\n canShare={canShare}\n onShareClick={onShareClick}\n onClearQuery={onClearQuery}\n onSettingsClick={onSettingsClick}\n onAIAssistantClick={onAIAssistantClick}\n onSchemaClick={onSchemaClick}\n showSettings={showSettings}\n handleCopyQuery={handleCopyQuery}\n icons={headerIcons}\n />\n\n {/* Viewing Shared Indicator */}\n {isViewingShared && (\n <div className=\"px-4 py-2 bg-dc-accent-bg dark:bg-dc-accent-bg border-b border-dc-accent dark:border-dc-accent flex items-center gap-2 text-sm text-dc-accent dark:text-dc-accent\">\n <ShareIcon className=\"w-4 h-4\" />\n <span>Viewing shared analysis</span>\n </div>\n )}\n\n {/* Content */}\n <div className=\"p-4\">\n {!hasContent ? (\n <div className=\"py-8 flex items-center justify-center text-dc-text-muted\">\n <div className=\"text-center\">\n <MeasureIcon className=\"w-12 h-12 mx-auto text-dc-text-muted mb-3\" />\n <div className=\"text-sm font-semibold mb-1\">No fields selected</div>\n <div className=\"text-xs\">Select measures, dimensions, or time dimensions from the schema explorer</div>\n </div>\n </div>\n ) : (\n <div className=\"space-y-6\">\n {/* Responsive Layout Grid */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n {/* Dimensions Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-dimension mb-3 flex items-center\">\n <DimensionIcon className=\"w-4 h-4 mr-2\" />\n Dimensions ({(query.dimensions || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.dimensions || []).map(dimension => (\n <RemovableChip\n key={dimension}\n fieldName={dimension}\n fieldType=\"dimensions\"\n schema={schema}\n icon={<DimensionIcon className=\"w-4 h-4\" />}\n hasFilters={hasFiltersApplied(dimension, 'dimensions')}\n sortDirection={getSortDirection(dimension, query.order)}\n sortTooltip={getSortTooltip(getSortDirection(dimension, query.order))}\n onAddFilter={handleAddFilterFromField}\n onToggleSort={handleToggleSort}\n onRemoveField={onRemoveField}\n FilterIcon={FilterIcon}\n ChevronUpIcon={ChevronUpIcon}\n ChevronDownIcon={ChevronDownIcon}\n ChevronUpDownIcon={ChevronUpDownIcon}\n CloseIcon={CloseIcon}\n />\n ))}\n </div>\n </div>\n\n {/* Time Dimensions Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-time-dimension mb-3 flex items-center\">\n <TimeDimensionIcon className=\"w-4 h-4 mr-2\" />\n Time Dimensions ({(query.timeDimensions || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.timeDimensions || []).map(timeDimension => (\n <TimeDimensionChip\n key={timeDimension.dimension}\n timeDimension={timeDimension}\n schema={schema}\n hasDateRange={hasFiltersApplied(timeDimension.dimension, 'timeDimensions')}\n sortDirection={getSortDirection(timeDimension.dimension, query.order)}\n sortTooltip={getSortTooltip(getSortDirection(timeDimension.dimension, query.order))}\n onAddFilter={handleAddFilterFromField}\n onToggleSort={handleToggleSort}\n onRemoveField={onRemoveField}\n onGranularityChange={onTimeDimensionGranularityChange}\n TimeDimensionIcon={TimeDimensionIcon}\n FilterIcon={FilterIcon}\n ChevronUpIcon={ChevronUpIcon}\n ChevronDownIcon={ChevronDownIcon}\n ChevronUpDownIcon={ChevronUpDownIcon}\n CloseIcon={CloseIcon}\n />\n ))}\n </div>\n </div>\n\n {/* Measures Column */}\n <div className=\"min-h-24\">\n <h4 className=\"text-sm font-semibold text-dc-measure mb-3 flex items-center\">\n <MeasureIcon className=\"w-4 h-4 mr-2\" />\n Measures ({(query.measures || []).length})\n </h4>\n <div className=\"flex flex-col gap-2\">\n {(query.measures || []).map(measure => {\n const measureType = schema ? getFieldType(measure, schema) : undefined\n return (\n <RemovableChip\n key={measure}\n fieldName={measure}\n fieldType=\"measures\"\n schema={schema}\n icon={getMeasureIcon(measureType, 'w-4 h-4')}\n hasFilters={hasFiltersApplied(measure, 'measures')}\n sortDirection={getSortDirection(measure, query.order)}\n sortTooltip={getSortTooltip(getSortDirection(measure, query.order))}\n onAddFilter={handleAddFilterFromField}\n onToggleSort={handleToggleSort}\n onRemoveField={onRemoveField}\n FilterIcon={FilterIcon}\n ChevronUpIcon={ChevronUpIcon}\n ChevronDownIcon={ChevronDownIcon}\n ChevronUpDownIcon={ChevronUpDownIcon}\n CloseIcon={CloseIcon}\n />\n )\n })}\n </div>\n </div>\n </div>\n\n {/* Date Range Section */}\n {hasTimeDimensions(query) && (\n <div className=\"mt-6\">\n <DateRangeFilter\n timeDimensions={query.timeDimensions || []}\n onDateRangeChange={onDateRangeChange}\n onDateRangeRemove={onDateRangeRemove}\n />\n </div>\n )}\n\n {/* Filters Section */}\n <div className=\"mt-6\">\n <FilterBuilder\n filters={query.filters || []}\n schema={schema}\n query={query}\n onFiltersChange={onFiltersChange}\n />\n </div>\n\n {/* Validation Error */}\n {validationError && (\n <div className=\"bg-dc-danger-bg border border-dc-error rounded-lg p-4\">\n <div className=\"flex items-start\">\n <ErrorIcon className=\"w-5 h-5 text-dc-error mr-2 mt-0.5\" />\n <div>\n <h5 className=\"text-sm font-semibold text-dc-error\">Validation Error</h5>\n <p className=\"text-sm text-dc-error mt-1\">{validationError}</p>\n </div>\n </div>\n </div>\n )}\n\n {/* Preview Toggles */}\n <div className=\"space-y-3\">\n <div className=\"flex space-x-4 flex-wrap gap-y-2\">\n <button\n onClick={() => {\n const newJsonState = !showJsonPreview\n setShowJsonPreview(newJsonState)\n if (newJsonState) {\n setShowSqlPreview(false)\n setShowAnalysisPreview(false)\n }\n }}\n className=\"text-sm text-dc-text-secondary hover:text-dc-text focus:outline-hidden focus:underline\"\n >\n {showJsonPreview ? 'Hide' : 'Show'} JSON Query\n </button>\n <button\n onClick={() => {\n if (!validationSql) return\n const newSqlState = !showSqlPreview\n setShowSqlPreview(newSqlState)\n if (newSqlState) {\n setShowJsonPreview(false)\n setShowAnalysisPreview(false)\n }\n }}\n className={`text-sm focus:outline-hidden focus:underline ${\n validationSql\n ? 'text-dc-text-secondary hover:text-dc-text'\n : 'text-dc-text-muted cursor-not-allowed'\n }`}\n disabled={!validationSql}\n title={validationSql ? 'Toggle SQL preview' : 'Run a query to view SQL'}\n >\n {showSqlPreview ? 'Hide' : 'Show'} SQL Generated\n </button>\n <button\n onClick={() => {\n if (!validationAnalysis) return\n const newAnalysisState = !showAnalysisPreview\n setShowAnalysisPreview(newAnalysisState)\n if (newAnalysisState) {\n setShowJsonPreview(false)\n setShowSqlPreview(false)\n }\n }}\n className={`text-sm focus:outline-hidden focus:underline ${\n validationAnalysis\n ? 'text-dc-text-secondary hover:text-dc-text'\n : 'text-dc-text-muted cursor-not-allowed'\n }`}\n disabled={!validationAnalysis}\n title={validationAnalysis ? 'Toggle analysis preview' : 'Run a query to view analysis'}\n >\n {showAnalysisPreview ? 'Hide' : 'Show'} Query Analysis\n </button>\n </div>\n\n {showJsonPreview && (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4\">\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2\">JSON Query:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(cleanQueryForServer(query), null, 2)}</code>\n </pre>\n </div>\n )}\n\n {showSqlPreview && validationSql && (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4\">\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Generated SQL:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto whitespace-pre-wrap font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-sql\">{validationSql.sql.join(';\\n\\n')}</code>\n </pre>\n {validationSql.params && validationSql.params.length > 0 && (\n <>\n <div className=\"text-xs font-semibold text-dc-text-secondary mb-2 mt-4\">Parameters:</div>\n <pre className=\"text-dc-text-secondary overflow-x-auto font-mono\" style={{ fontSize: '12px', lineHeight: '1.4' }}>\n <code className=\"language-json\">{JSON.stringify(validationSql.params, null, 2)}</code>\n </pre>\n </>\n )}\n </div>\n )}\n\n {showAnalysisPreview && validationAnalysis && (\n <QueryAnalysisPanel analysis={validationAnalysis} />\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* Actions */}\n {hasContent && (\n <div className=\"border-t border-dc-border p-4\">\n <div className=\"flex\">\n <button\n onClick={onExecute}\n disabled={validationStatus === 'validating' || !hasContent}\n className={`flex-1 flex items-center justify-center px-4 py-2 text-sm font-medium rounded-md transition-colors ${\n validationStatus === 'validating' || !hasContent\n ? 'bg-dc-surface-secondary text-dc-text-muted cursor-not-allowed border border-dc-border'\n : 'text-white border border-dc-success hover:bg-dc-success focus:ring-2 focus:ring-dc-success'\n }`}\n style={!hasContent || validationStatus === 'validating' ? undefined : { backgroundColor: 'var(--dc-primary)' }}\n >\n <RunIcon className=\"w-4 h-4 mr-2\" />\n Run Query\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default memo(QueryPanel)\n","import { barChartConfig } from '../components/charts/BarChart.config'\nimport { lineChartConfig } from '../components/charts/LineChart.config'\nimport { areaChartConfig } from '../components/charts/AreaChart.config'\nimport { pieChartConfig } from '../components/charts/PieChart.config'\nimport { scatterChartConfig } from '../components/charts/ScatterChart.config'\nimport { bubbleChartConfig } from '../components/charts/BubbleChart.config'\nimport { radarChartConfig } from '../components/charts/RadarChart.config'\nimport { radialBarChartConfig } from '../components/charts/RadialBarChart.config'\nimport { treemapChartConfig } from '../components/charts/TreeMapChart.config'\nimport { dataTableConfig } from '../components/charts/DataTable.config'\nimport { activityGridChartConfig } from '../components/charts/ActivityGridChart.config'\nimport { kpiNumberConfig } from '../components/charts/KpiNumber.config'\nimport { kpiDeltaConfig } from '../components/charts/KpiDelta.config'\nimport { kpiTextConfig } from '../components/charts/KpiText.config'\nimport { markdownConfig } from '../components/charts/MarkdownChart.config'\nimport type { ChartConfigRegistry } from './chartConfigs'\n\n/**\n * Registry of all chart type configurations\n */\nexport const chartConfigRegistry: ChartConfigRegistry = {\n bar: barChartConfig,\n line: lineChartConfig,\n area: areaChartConfig,\n pie: pieChartConfig,\n scatter: scatterChartConfig,\n bubble: bubbleChartConfig,\n radar: radarChartConfig,\n radialBar: radialBarChartConfig,\n treemap: treemapChartConfig,\n table: dataTableConfig,\n activityGrid: activityGridChartConfig,\n kpiNumber: kpiNumberConfig,\n kpiDelta: kpiDeltaConfig,\n kpiText: kpiTextConfig,\n markdown: markdownConfig\n}","import { useState } from 'react'\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport type { ChartType } from '../types'\nimport type { ChartAvailabilityMap } from '../shared/chartDefaults'\n\ninterface ChartTypeSelectorProps {\n selectedType: ChartType\n onTypeChange: (type: ChartType) => void\n className?: string\n /** Compact mode for narrow containers - uses 2 columns and constrains width */\n compact?: boolean\n /** Map of chart type availability - when provided, unavailable charts are disabled */\n availability?: ChartAvailabilityMap\n}\n\n// Chart type display names (defined outside component to avoid recreation)\nconst chartTypeLabels: Record<ChartType, string> = {\n activityGrid: 'Activity Grid',\n area: 'Area Chart',\n bar: 'Bar Chart',\n bubble: 'Bubble Chart',\n kpiDelta: 'KPI Delta',\n kpiNumber: 'KPI Number',\n kpiText: 'KPI Text',\n line: 'Line Chart',\n markdown: 'Markdown',\n pie: 'Pie Chart',\n radar: 'Radar Chart',\n radialBar: 'Radial Bar Chart',\n scatter: 'Scatter Plot',\n table: 'Data Table',\n treemap: 'TreeMap'\n}\n\nexport default function ChartTypeSelector({\n selectedType,\n onTypeChange,\n className = '',\n compact = false,\n availability\n}: ChartTypeSelectorProps) {\n const [isOpen, setIsOpen] = useState(false)\n\n // Get chart types and sort alphabetically by label\n const chartTypes = (Object.entries(chartConfigRegistry) as [ChartType, typeof chartConfigRegistry[keyof typeof chartConfigRegistry]][])\n .sort((a, b) => {\n const labelA = chartTypeLabels[a[0]] || a[0]\n const labelB = chartTypeLabels[b[0]] || b[0]\n return labelA.localeCompare(labelB)\n })\n\n const selectedConfig = chartConfigRegistry[selectedType]\n const SelectedIcon = selectedConfig?.icon\n const selectedLabel = chartTypeLabels[selectedType]\n\n return (\n <div className={`${className} relative`}>\n {/* Dropdown Button */}\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"w-full flex items-center justify-between px-3 py-2 border border-dc-border rounded-md bg-dc-surface hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-dc-accent focus:border-dc-accent\"\n >\n <div className=\"flex items-center space-x-2\">\n {SelectedIcon && (\n <SelectedIcon className=\"h-5 w-5 text-dc-text-secondary\" />\n )}\n <span className=\"text-sm font-medium text-dc-text\">{selectedLabel}</span>\n </div>\n <svg\n className={`h-4 w-4 text-dc-text-muted transform transition-transform ${isOpen ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {/* Dropdown Menu - Grid Layout */}\n {isOpen && (\n <div className={`absolute z-10 mt-1 w-full bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-80 overflow-auto ${compact ? '' : 'min-w-max'}`}>\n <div className=\"p-2\">\n <div className={`grid gap-1.5 ${compact ? 'grid-cols-2' : 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-4'}`}>\n {chartTypes.map(([type, config]) => {\n const IconComponent = config.icon\n const label = chartTypeLabels[type]\n const isSelected = selectedType === type\n const description = config.description\n const useCase = config.useCase\n\n // Check availability if provided\n const chartAvailability = availability?.[type]\n const isAvailable = chartAvailability?.available ?? true\n const unavailableReason = chartAvailability?.reason\n\n // Build tooltip text - show unavailable reason if not available, otherwise show description\n const tooltipText = !isAvailable && unavailableReason\n ? unavailableReason\n : [description, useCase].filter(Boolean).join('. ')\n\n return (\n <button\n key={type}\n type=\"button\"\n onClick={() => {\n if (!isAvailable) return // Don't allow clicking disabled charts\n onTypeChange(type)\n setIsOpen(false)\n }}\n disabled={!isAvailable}\n className={`\n relative p-1.5 rounded border transition-colors duration-150\n text-left group min-h-[30px] flex items-center justify-start\n ${!isAvailable\n ? 'opacity-50 cursor-not-allowed bg-dc-surface'\n : isSelected\n ? 'bg-dc-surface-secondary'\n : 'bg-dc-surface hover:bg-dc-surface-hover'\n }\n `}\n style={{\n borderColor: isSelected && isAvailable ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n title={tooltipText}\n >\n <div className=\"flex items-center space-x-1.5\">\n {/* Icon */}\n {IconComponent && (\n <IconComponent\n className={`h-4 w-4 shrink-0 ${\n !isAvailable\n ? 'text-dc-text-muted'\n : isSelected\n ? 'text-dc-text'\n : 'text-dc-text-secondary'\n }`}\n />\n )}\n\n {/* Chart name */}\n <span className={`text-xs font-medium leading-tight truncate ${\n !isAvailable\n ? 'text-dc-text-muted'\n : isSelected\n ? ''\n : 'text-dc-text'\n }`}\n style={isSelected && isAvailable ? { color: 'var(--dc-primary)' } : undefined}>\n {label}\n </span>\n </div>\n\n {/* Selected indicator - smaller dot */}\n {isSelected && isAvailable && (\n <div className=\"absolute top-0.5 right-0.5\">\n <div className=\"w-1.5 h-1.5 rounded-full\" style={{ backgroundColor: 'var(--dc-primary)' }}></div>\n </div>\n )}\n </button>\n )\n })}\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}","import React, { useState } from 'react'\nimport { getIcon } from '../icons'\nimport type { AxisDropZoneConfig } from '../charts/chartConfigs'\n\nconst CloseIcon = getIcon('close')\n\ninterface FieldStyling {\n IconComponent: React.ComponentType<{ className?: string }>\n baseClasses: string\n hoverClasses: string\n}\n\ninterface AxisDropZoneProps {\n config: AxisDropZoneConfig\n fields: string[]\n onDrop: (e: React.DragEvent<HTMLDivElement>, toKey: string) => void\n onRemove: (field: string, fromKey: string) => void\n onDragStart: (e: React.DragEvent<HTMLDivElement>, field: string, fromKey: string, fromIndex?: number) => void\n onDragEnd?: (e: React.DragEvent<HTMLDivElement>) => void\n onDragOver: (e: React.DragEvent<HTMLDivElement>) => void\n getFieldStyling: (field: string) => FieldStyling\n onReorder?: (fromIndex: number, toIndex: number, axisKey: string) => void\n draggedItem?: { field: string; fromAxis: string; fromIndex?: number } | null\n}\n\nexport default function AxisDropZone({\n config,\n fields,\n onDrop,\n onRemove,\n onDragStart,\n onDragEnd,\n onDragOver,\n getFieldStyling,\n onReorder,\n draggedItem\n}: AxisDropZoneProps) {\n const { key, label, description, mandatory, maxItems, emptyText, icon: IconComponent } = config\n const [dragOverIndex, setDragOverIndex] = useState<number | null>(null)\n const [isDraggedOver, setIsDraggedOver] = useState(false)\n const [isReorderDraggedOver, setIsReorderDraggedOver] = useState(false)\n \n // Calculate acceptance considering what's being dragged\n const getCanAcceptMore = () => {\n let effectiveCount = fields.length\n \n // If we're dragging FROM this axis, we effectively have one less item\n if (draggedItem && draggedItem.fromAxis === key) {\n effectiveCount = Math.max(0, fields.length - 1)\n }\n \n return !maxItems || effectiveCount < maxItems\n }\n \n const getIsFull = () => {\n let effectiveCount = fields.length\n \n // If we're dragging FROM this axis, we effectively have one less item\n if (draggedItem && draggedItem.fromAxis === key) {\n effectiveCount = Math.max(0, fields.length - 1)\n }\n \n return maxItems && effectiveCount >= maxItems\n }\n \n const canAcceptMore = getCanAcceptMore()\n const isFull = getIsFull()\n \n\n // Add a global drag end listener to reset visual state\n React.useEffect(() => {\n const handleGlobalDragEnd = () => {\n setDragOverIndex(null)\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n\n document.addEventListener('dragend', handleGlobalDragEnd)\n return () => {\n document.removeEventListener('dragend', handleGlobalDragEnd)\n }\n }, [])\n\n // Clear states when transitioning between different drag operations\n React.useEffect(() => {\n if (draggedItem) {\n // If we have a dragged item but it's not from this axis, clear reorder state\n if (draggedItem.fromAxis !== key) {\n setIsReorderDraggedOver(false)\n setDragOverIndex(null)\n }\n // If we have a dragged item from this axis, clear regular drag state\n else if (draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n setIsDraggedOver(false)\n }\n } else {\n // No dragged item, clear all states\n setDragOverIndex(null)\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n }, [draggedItem, key])\n\n const handleReorderDragOver = (e: React.DragEvent<HTMLDivElement>, targetIndex: number) => {\n // Check if this is a reorder operation (same axis) using the draggedItem prop\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n e.preventDefault()\n e.stopPropagation()\n setDragOverIndex(targetIndex)\n setIsReorderDraggedOver(true)\n }\n }\n\n const handleReorderDragLeave = () => {\n // Clear the individual item drag over index\n setDragOverIndex(null)\n // Note: Don't clear isReorderDraggedOver here as it causes flickering\n // Let the global drag end handler clear it when the drag is truly complete\n }\n\n const handleReorderDrop = (e: React.DragEvent<HTMLDivElement>, targetIndex: number) => {\n e.preventDefault()\n e.stopPropagation()\n setDragOverIndex(null)\n setIsReorderDraggedOver(false)\n \n // Handle reordering using either drag data or the draggedItem prop\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined && onReorder) {\n onReorder(draggedItem.fromIndex, targetIndex, key)\n return\n }\n \n // Fallback to parsing drag data\n try {\n const data = JSON.parse(e.dataTransfer.getData('text/plain'))\n if (data.fromAxis === key && onReorder && data.fromIndex !== undefined) {\n onReorder(data.fromIndex, targetIndex, key)\n }\n } catch {\n // If we can't parse the data, ignore\n }\n }\n \n return (\n <div className=\"mb-2\">\n <div className=\"flex items-center gap-2 mb-1\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary flex items-center\">\n {IconComponent && <IconComponent className=\"w-3 h-3 mr-1 text-dc-text-muted\" />}\n {label}\n {mandatory && <span className=\"text-dc-error ml-1\">*</span>}\n {maxItems && (\n <span className=\"text-dc-text-muted ml-1 font-normal\">\n ({fields.length}/{maxItems})\n </span>\n )}\n </h4>\n {description && (\n <span className=\"text-xs text-dc-text-muted\">\n {description}\n </span>\n )}\n </div>\n \n <div\n data-axis-container={key}\n className={`min-h-[40px] sm:min-h-[32px] border-2 border-dashed rounded-lg p-3 sm:p-1.5 transition-all duration-300 flex items-center ${\n (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'shadow-lg scale-110 border-solid animate-pulse'\n : isFull\n ? 'bg-dc-surface-secondary'\n : 'bg-dc-surface-secondary hover:bg-dc-surface-hover'\n }`}\n style={{\n borderColor: (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'var(--dc-primary)'\n : 'var(--dc-border)',\n backgroundColor: (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'rgba(var(--dc-primary-rgb), 0.1)'\n : undefined\n }}\n onDragOver={(e) => {\n // Check if this is a reorder operation (same axis) - if so, don't interfere\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n return\n }\n \n // Simple acceptance check - either we have space OR it's a single-item replacement\n const canAccept = canAcceptMore || (maxItems === 1)\n \n if (canAccept) {\n setIsDraggedOver(true)\n onDragOver(e)\n } else {\n e.preventDefault()\n e.dataTransfer.dropEffect = 'none'\n }\n }}\n onDragLeave={(e) => {\n // Check if we're truly leaving the container\n const rect = e.currentTarget.getBoundingClientRect()\n const isLeavingContainer = (\n e.clientX < rect.left || \n e.clientX > rect.right || \n e.clientY < rect.top || \n e.clientY > rect.bottom\n )\n \n // Also check if the related target is outside this container\n const relatedTarget = e.relatedTarget as Element | null\n const isRelatedTargetOutside = relatedTarget && !e.currentTarget.contains(relatedTarget)\n \n if (isLeavingContainer || isRelatedTargetOutside || e.currentTarget === e.target) {\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n }}\n onDrop={(e) => {\n // Check if this is a reorder operation (same axis) - if so, don't interfere\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n return\n }\n \n // Simple acceptance check - either we have space OR it's a single-item replacement\n const shouldAcceptDrop = canAcceptMore || (maxItems === 1)\n \n if (shouldAcceptDrop) {\n onDrop(e, key)\n } else {\n e.preventDefault()\n }\n \n // Reset drag state on drop\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }}\n >\n {fields.length === 0 ? (\n <div className=\"text-xs text-dc-text-muted text-center w-full\">\n {isFull ? 'Maximum items reached' : (emptyText || `Drop fields here`)}\n </div>\n ) : (\n <div className=\"flex flex-wrap gap-1\">\n {fields.map((field, index) => {\n const { IconComponent: FieldIcon, baseClasses, hoverClasses } = getFieldStyling(field)\n const isDragOver = dragOverIndex === index\n const isBeingDragged = draggedItem && draggedItem.field === field && draggedItem.fromAxis === key\n \n return (\n <div\n key={`${field}-${index}`}\n className={`relative ${isDragOver ? 'transform scale-105' : ''}`}\n >\n {/* Drop indicator line for reordering */}\n {isDragOver && (\n <div className=\"absolute -left-1 top-0 bottom-0 w-1 rounded-full z-10\" style={{ backgroundColor: 'var(--dc-primary)' }} />\n )}\n \n <div\n draggable\n onDragStart={(e) => {\n // Let parent handle drag data with index\n onDragStart(e, field, key, index)\n }}\n onDragEnd={onDragEnd}\n onDragOver={(e) => handleReorderDragOver(e, index)}\n onDragLeave={handleReorderDragLeave}\n onDrop={(e) => handleReorderDrop(e, index)}\n className={`rounded text-xs cursor-move px-3 py-0.5 sm:px-2 sm:py-1 flex items-center transition-transform h-[28px] sm:h-auto ${baseClasses} ${hoverClasses} ${\n isDragOver ? 'bg-opacity-75' : ''\n } ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n >\n <FieldIcon className=\"w-3 h-3 mr-1 shrink-0\" />\n <span className=\"leading-none\">{field}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(field, key)}\n className=\"text-dc-text-secondary hover:text-dc-danger ml-1.5 leading-none\"\n title={`Remove from ${label}`}\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n </div>\n )\n })}\n </div>\n )}\n </div>\n \n {mandatory && fields.length === 0 && (\n <div className=\"text-xs text-dc-error mt-0.5\">\n This field is required\n </div>\n )}\n </div>\n )\n}","import React, { useMemo, useEffect, useState } from 'react'\nimport { getIcon } from '../icons'\nimport AxisDropZone from './AxisDropZone'\n\nconst MeasureIcon = getIcon('measure')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport { getChartConfig } from '../charts/chartConfigs'\nimport type { ChartType, ChartAxisConfig, ChartDisplayConfig, ColorPalette } from '../types'\n\ninterface ChartConfigPanelProps {\n chartType: ChartType\n chartConfig: ChartAxisConfig\n displayConfig: ChartDisplayConfig\n availableFields: {\n dimensions: string[]\n timeDimensions: string[]\n measures: string[]\n } | null\n colorPalette?: ColorPalette\n onChartConfigChange: (config: ChartAxisConfig) => void\n onDisplayConfigChange: (config: ChartDisplayConfig) => void\n}\n\nexport default function ChartConfigPanel({\n chartType,\n chartConfig,\n displayConfig,\n availableFields,\n colorPalette,\n onChartConfigChange,\n onDisplayConfigChange\n}: ChartConfigPanelProps) {\n \n // Track currently dragging item for immediate state updates\n const [draggedItem, setDraggedItem] = useState<{\n field: string\n fromAxis: string\n fromIndex?: number\n } | null>(null)\n \n // Get configuration for current chart type\n const chartTypeConfig = useMemo(() => \n getChartConfig(chartType, chartConfigRegistry),\n [chartType]\n )\n \n // Check if this chart type skips queries\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Get fields for each drop zone\n const getFieldsForDropZone = (key: string): string[] => {\n const value = chartConfig[key as keyof ChartAxisConfig]\n const result = Array.isArray(value) ? value : (typeof value === 'string' ? [value] : [])\n return result\n }\n\n // Clean up chart config when available fields change\n useEffect(() => {\n if (!availableFields) return\n\n const allAvailableFields = [\n ...availableFields.dimensions,\n ...availableFields.timeDimensions,\n ...availableFields.measures\n ]\n\n let hasChanges = false\n const newConfig = { ...chartConfig }\n\n // Check each axis and remove fields that are no longer available\n chartTypeConfig.dropZones.forEach(dropZone => {\n const currentFields = getFieldsForDropZone(dropZone.key)\n const validFields = currentFields.filter(field => allAvailableFields.includes(field))\n \n if (validFields.length !== currentFields.length) {\n hasChanges = true\n if (validFields.length === 0) {\n // Remove the axis property entirely if no valid fields remain\n delete newConfig[dropZone.key as keyof ChartAxisConfig]\n } else if (dropZone.maxItems === 1) {\n // Single field axis - always store as string\n newConfig[dropZone.key as keyof ChartAxisConfig] = validFields[0] as any\n } else {\n // Multi-field axis - always store as array\n newConfig[dropZone.key as keyof ChartAxisConfig] = validFields as any\n }\n }\n })\n\n if (hasChanges) {\n onChartConfigChange(newConfig)\n }\n }, [availableFields, chartConfig, chartTypeConfig.dropZones, onChartConfigChange])\n\n // Helper to determine field type and styling\n const getFieldType = (field: string): 'dimension' | 'timeDimension' | 'measure' => {\n if (!availableFields) return 'dimension'\n if (availableFields.measures.includes(field)) return 'measure'\n if (availableFields.timeDimensions.includes(field)) return 'timeDimension'\n return 'dimension'\n }\n\n const getFieldStyling = (field: string) => {\n const fieldType = getFieldType(field)\n\n switch (fieldType) {\n case 'measure':\n return {\n IconComponent: MeasureIcon,\n baseClasses: 'bg-dc-measure text-dc-measure border border-dc-measure',\n hoverClasses: 'hover:opacity-80'\n }\n case 'timeDimension':\n return {\n IconComponent: TimeDimensionIcon,\n baseClasses: 'bg-dc-time-dimension text-dc-time-dimension border border-dc-time-dimension',\n hoverClasses: 'hover:opacity-80'\n }\n default:\n return {\n IconComponent: DimensionIcon,\n baseClasses: 'bg-dc-dimension text-dc-dimension border border-dc-dimension',\n hoverClasses: 'hover:opacity-80'\n }\n }\n }\n\n // Drag and drop handlers\n const handleDragStart = (e: React.DragEvent<HTMLDivElement>, field: string, fromAxis: string, fromIndex?: number) => {\n e.dataTransfer.setData('text/plain', JSON.stringify({ field, fromAxis, fromIndex }))\n \n // Just track the dragged item - don't remove it yet\n setDraggedItem({ field, fromAxis, fromIndex })\n }\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n }\n\n const handleDragEnd = () => {\n // Just clear the dragged item tracking - no need to restore since we didn't remove it\n setDraggedItem(null)\n }\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>, toAxis: string) => {\n e.preventDefault()\n const data = JSON.parse(e.dataTransfer.getData('text/plain'))\n const { field, fromAxis } = data\n \n const newConfig = { ...chartConfig }\n \n // Remove from old location if moving between axes\n if (fromAxis !== 'available' && fromAxis !== toAxis) {\n const fromValue = newConfig[fromAxis as keyof ChartAxisConfig]\n if (Array.isArray(fromValue)) {\n const filteredValue = fromValue.filter(f => f !== field)\n if (filteredValue.length === 0) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n } else {\n newConfig[fromAxis as keyof ChartAxisConfig] = filteredValue as any\n }\n } else if (fromValue === field) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n }\n }\n \n // Add to new location\n const toValue = newConfig[toAxis as keyof ChartAxisConfig]\n const dropZoneConfig = chartTypeConfig.dropZones.find(dz => dz.key === toAxis)\n \n if (dropZoneConfig?.maxItems === 1) {\n // Single field - always store as string\n newConfig[toAxis as keyof ChartAxisConfig] = field as any\n } else {\n // Multiple fields - always store as array\n if (Array.isArray(toValue)) {\n if (!toValue.includes(field)) {\n newConfig[toAxis as keyof ChartAxisConfig] = [...toValue, field] as any\n }\n } else {\n newConfig[toAxis as keyof ChartAxisConfig] = [field] as any\n }\n }\n \n // Clear the dragged item tracking\n setDraggedItem(null)\n onChartConfigChange(newConfig)\n }\n\n const handleRemoveFromAxis = (field: string, fromAxis: string) => {\n const newConfig = { ...chartConfig }\n const value = newConfig[fromAxis as keyof ChartAxisConfig]\n \n if (Array.isArray(value)) {\n const filteredValue = value.filter(f => f !== field)\n if (filteredValue.length === 0) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n } else {\n newConfig[fromAxis as keyof ChartAxisConfig] = filteredValue as any\n }\n } else if (value === field) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n }\n \n onChartConfigChange(newConfig)\n }\n\n const handleReorder = (fromIndex: number, toIndex: number, axisKey: string) => {\n const newConfig = { ...chartConfig }\n const value = newConfig[axisKey as keyof ChartAxisConfig]\n \n // Only reorder if we have an array with multiple items\n if (Array.isArray(value) && value.length > 1 && fromIndex !== toIndex) {\n const newArray = [...value]\n const [movedItem] = newArray.splice(fromIndex, 1)\n newArray.splice(toIndex, 0, movedItem)\n newConfig[axisKey as keyof ChartAxisConfig] = newArray as any\n \n // Clear the dragged item tracking\n setDraggedItem(null)\n onChartConfigChange(newConfig)\n }\n }\n\n // Get unassigned fields\n const getUnassignedFields = () => {\n if (!availableFields) return { dimensions: [], timeDimensions: [], measures: [] }\n \n const assignedFields = new Set<string>()\n chartTypeConfig.dropZones.forEach(dz => {\n getFieldsForDropZone(dz.key).forEach(field => assignedFields.add(field))\n })\n \n // Exclude the currently dragged field only if it's being dragged FROM a configured axis\n // (not from available fields, where it should remain visible)\n if (draggedItem && draggedItem.fromAxis !== 'available') {\n assignedFields.add(draggedItem.field)\n }\n \n return {\n dimensions: availableFields.dimensions.filter(f => !assignedFields.has(f)),\n timeDimensions: availableFields.timeDimensions.filter(f => !assignedFields.has(f)),\n measures: availableFields.measures.filter(f => !assignedFields.has(f))\n }\n }\n\n const unassignedFields = getUnassignedFields()\n\n\n return (\n <div>\n {/* Available Fields - Hidden for skipQuery charts */}\n {!shouldSkipQuery && availableFields && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Available Fields</h4>\n <div className=\"border border-dc-border rounded-lg p-2 bg-dc-surface-secondary\">\n {(unassignedFields.dimensions.length > 0 ||\n unassignedFields.timeDimensions.length > 0 ||\n unassignedFields.measures.length > 0) ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-2 sm:gap-2 gap-y-4 sm:gap-y-2\">\n {/* Dimensions Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <DimensionIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Dimensions\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.dimensions.map(dim => {\n const isBeingDragged = draggedItem && draggedItem.field === dim && draggedItem.fromAxis === 'available'\n return (\n <div\n key={dim}\n draggable\n onDragStart={(e) => handleDragStart(e, dim, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-dimension text-dc-dimension border border-dc-dimension hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={dim}\n >\n {dim}\n </div>\n )\n })}\n {unassignedFields.dimensions.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n \n {/* Time Dimensions Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <TimeDimensionIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Time Dimensions\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.timeDimensions.map(dim => {\n const isBeingDragged = draggedItem && draggedItem.field === dim && draggedItem.fromAxis === 'available'\n return (\n <div\n key={dim}\n draggable\n onDragStart={(e) => handleDragStart(e, dim, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-time-dimension text-dc-time-dimension border border-dc-time-dimension hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={dim}\n >\n {dim}\n </div>\n )\n })}\n {unassignedFields.timeDimensions.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n \n {/* Measures Column */}\n <div className=\"pb-2 sm:pb-0\">\n <div className=\"text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center\">\n <MeasureIcon className=\"w-3 h-3 mr-1 text-dc-text-muted\" />\n Measures\n </div>\n <div className=\"space-y-1\">\n {unassignedFields.measures.map(measure => {\n const isBeingDragged = draggedItem && draggedItem.field === measure && draggedItem.fromAxis === 'available'\n return (\n <div\n key={measure}\n draggable\n onDragStart={(e) => handleDragStart(e, measure, 'available')}\n onDragEnd={handleDragEnd}\n className={`bg-dc-measure text-dc-measure border border-dc-measure hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={measure}\n >\n {measure}\n </div>\n )\n })}\n {unassignedFields.measures.length === 0 && (\n <div className=\"text-xs text-dc-text-muted italic\">None</div>\n )}\n </div>\n </div>\n </div>\n ) : (\n <div className=\"text-xs text-dc-text-muted text-center py-2\">\n All fields have been assigned\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Chart Axis Configuration - Dynamic Drop Zones, Hidden for skipQuery charts */}\n {!shouldSkipQuery && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Chart Configuration</h4>\n <div className=\"space-y-1\">\n {chartTypeConfig.dropZones.map(dropZone => (\n <AxisDropZone\n key={dropZone.key}\n config={dropZone}\n fields={getFieldsForDropZone(dropZone.key)}\n onDrop={handleDrop}\n onRemove={handleRemoveFromAxis}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n getFieldStyling={getFieldStyling}\n onReorder={handleReorder}\n draggedItem={draggedItem}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Display Options */}\n {((chartTypeConfig.displayOptions && chartTypeConfig.displayOptions.length > 0) ||\n (chartTypeConfig.displayOptionsConfig && chartTypeConfig.displayOptionsConfig.length > 0)) && (\n <div className=\"mb-4\">\n <h4 className=\"text-xs font-semibold text-dc-text-secondary mb-2\">Display Options</h4>\n <div className=\"space-y-2\">\n {/* Backward compatibility: Simple boolean display options */}\n {chartTypeConfig.displayOptions?.includes('showLegend') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showLegend ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showLegend: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Legend</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('showGrid') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showGrid ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showGrid: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Grid</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('showTooltip') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showTooltip ?? true}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n showTooltip: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Tooltip</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('stacked') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.stacked ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n stacked: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Stacked</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('hideHeader') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.hideHeader ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n hideHeader: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Hide Header</span>\n </label>\n )}\n\n {/* New structured display options */}\n {chartTypeConfig.displayOptionsConfig?.map((option) => (\n <div key={option.key} className=\"space-y-1\">\n {option.type === 'boolean' && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? false}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.checked\n })}\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">{option.label}</span>\n </label>\n )}\n\n {option.type === 'string' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">\n {option.label}\n {option.key === 'content' && (\n <span className=\"text-xs text-dc-text-muted ml-1\">(only headers, lists and links)</span>\n )}\n </label>\n {option.key === 'content' ? (\n <textarea\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder}\n rows={8}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent font-mono resize-y bg-dc-surface text-dc-text\"\n />\n ) : (\n <input\n type=\"text\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n )}\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'paletteColor' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <div className=\"flex flex-wrap gap-2\">\n {colorPalette?.colors.map((color, index) => {\n const isSelected = (displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? 0) === index\n return (\n <button\n key={index}\n type=\"button\"\n onClick={() => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: index\n })}\n className={`w-8 h-8 rounded border-2 transition-all duration-200 hover:scale-110 focus:outline-hidden focus:ring-2 focus:ring-dc-accent focus:ring-offset-1 ${\n isSelected\n ? 'ring-2 ring-offset-1 scale-110'\n : 'hover:border-dc-text-muted'\n }`}\n style={{\n backgroundColor: color,\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n title={`Color ${index + 1}: ${color}`}\n />\n )\n }) || [\n // Fallback if no palette available\n <button\n key={0}\n type=\"button\"\n onClick={() => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: 0\n })}\n className=\"w-8 h-8 rounded-sm border-2 ring-2 ring-offset-1\"\n style={{\n backgroundColor: '#8884d8',\n borderColor: 'var(--dc-primary)',\n boxShadow: '0 0 0 2px var(--dc-primary)'\n }}\n title=\"Default Color\"\n />\n ]}\n </div>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'number' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <input\n type=\"number\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? 0}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value === '' ? undefined : Number(e.target.value)\n })}\n placeholder={option.placeholder}\n min={option.min}\n max={option.max}\n step={option.step}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'select' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <select\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? ''}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n >\n {option.options?.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'color' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"color\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? '#8884d8'}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n className=\"w-12 h-8 border border-dc-border rounded-sm cursor-pointer\"\n />\n <input\n type=\"text\"\n value={displayConfig[option.key as keyof ChartDisplayConfig] ?? option.defaultValue ?? '#8884d8'}\n onChange={(e) => onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })}\n placeholder={option.placeholder || '#8884d8'}\n className=\"flex-1 px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n </div>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}","/**\n * ResultsPanel Component\n *\n * Displays query execution results, loading states, and errors.\n * Supports both table and chart visualization with configurable chart types.\n */\n\nimport React, { useState } from 'react'\nimport { LazyChart, isValidChartType } from '../../charts/ChartLoader'\nimport ChartTypeSelector from '../ChartTypeSelector'\nimport ChartConfigPanel from '../ChartConfigPanel'\nimport type { ResultsPanelProps } from './types'\nimport { getIcon } from '../../icons'\n\nconst ResultsPanel: React.FC<ResultsPanelProps> = ({\n executionStatus,\n executionResults,\n executionError,\n resultsStale = false,\n query,\n displayLimit = 10,\n onDisplayLimitChange,\n totalRowCount,\n totalRowCountStatus,\n // Chart visualization props\n chartType = 'table',\n chartConfig = {},\n displayConfig = {},\n availableFields,\n onChartTypeChange,\n onChartConfigChange,\n onDisplayConfigChange,\n // View state props\n activeView: activeViewProp = 'table',\n onActiveViewChange\n}) => {\n // Get icons\n const ErrorIcon = getIcon('error')\n const TimeIcon = getIcon('timeDimension')\n const SuccessIcon = getIcon('success')\n const WarningIcon = getIcon('warning')\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronUpIcon = getIcon('chevronUp')\n const TableIcon = getIcon('table')\n const MeasureIcon = getIcon('measure')\n const AdjustmentsIcon = getIcon('adjustments')\n\n // Use prop if provided, otherwise use local state for backwards compatibility\n const [localActiveView, setLocalActiveView] = useState<'table' | 'chart'>('table')\n const activeView = onActiveViewChange ? activeViewProp : localActiveView\n const setActiveView = onActiveViewChange || setLocalActiveView\n\n // Local state for config panel visibility\n const [showChartConfig, setShowChartConfig] = useState(false)\n\n const LoadingState = () => (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4\" style={{ borderBottomColor: 'var(--dc-primary)' }}></div>\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">Executing Query...</div>\n <div className=\"text-xs text-dc-text-muted\">Running your query against the cube API</div>\n </div>\n </div>\n )\n\n const ErrorState = () => (\n <div className=\"h-full flex items-center justify-center p-4\">\n <div className=\"text-center max-w-md\">\n <ErrorIcon className=\"w-12 h-12 mx-auto text-dc-error mb-4\" />\n <div className=\"text-sm font-semibold text-dc-text mb-2\">Query Execution Failed</div>\n <div className=\"text-sm text-dc-text-secondary mb-4\">\n There was an error executing your query. Please check the query and try again.\n </div>\n {executionError && (\n <div className=\"bg-dc-danger-bg border border-dc-error rounded-lg p-3 text-left\">\n <div className=\"text-xs font-mono text-dc-error break-words\">\n {executionError}\n </div>\n </div>\n )}\n </div>\n </div>\n )\n\n const OverlaySpinner = () => (\n <div className=\"absolute inset-0 flex items-center justify-center bg-dc-surface-secondary bg-opacity-80\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-10 w-10 border-b-2 mx-auto mb-2\" style={{ borderBottomColor: 'var(--dc-primary)' }}></div>\n <div className=\"text-xs text-dc-text-secondary\">Refreshing results...</div>\n </div>\n </div>\n )\n\n const OverlayError = () => (\n <div className=\"absolute inset-x-4 top-4 bg-dc-danger-bg border border-dc-error rounded-lg p-3 text-left shadow\">\n <div className=\"flex items-start gap-2\">\n <ErrorIcon className=\"w-4 h-4 text-dc-error mt-0.5\" />\n <div className=\"text-xs text-dc-error\">\n {executionError || 'Query execution failed'}\n </div>\n </div>\n </div>\n )\n\n const EmptyState = () => (\n <div className=\"h-full flex items-center justify-center pt-6\">\n <div className=\"text-center mb-16\">\n <TimeIcon className=\"w-12 h-12 mx-auto text-dc-text-muted mb-3\" />\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">No Results Yet</div>\n <div className=\"text-xs text-dc-text-muted\">Build and run a query to see results here</div>\n </div>\n </div>\n )\n\n // Render the appropriate chart component using lazy loading\n const renderChart = () => {\n if (!executionResults || executionResults.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <MeasureIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">No data to display</div>\n <div className=\"text-xs\">Run a query to see chart visualization</div>\n </div>\n </div>\n )\n }\n\n const chartHeight = 400\n const data = executionResults\n\n try {\n // Check if it's a valid chart type for lazy loading\n if (!isValidChartType(chartType)) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <WarningIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">Unsupported chart type</div>\n <div className=\"text-xs\">{chartType}</div>\n </div>\n </div>\n )\n }\n\n // For markdown chart, use empty data array\n const chartData = chartType === 'markdown' ? [] : data\n\n return (\n <LazyChart\n chartType={chartType}\n data={chartData}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n queryObject={query}\n height={chartHeight}\n fallback={\n <div className=\"flex items-center justify-center\" style={{ height: chartHeight }}>\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full\" />\n </div>\n }\n />\n )\n } catch (error) {\n console.error('Chart rendering error:', error)\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted p-4\">\n <div className=\"text-center\">\n <ErrorIcon className=\"w-12 h-12 mx-auto mb-3 text-dc-error\" />\n <div className=\"text-sm font-semibold mb-1\">Unable to render chart</div>\n <div className=\"text-xs text-dc-text-secondary\">{error instanceof Error ? error.message : 'Unknown error'}</div>\n </div>\n </div>\n )\n }\n }\n\n const SuccessState = () => {\n if (!executionResults || executionResults.length === 0) {\n return (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <SuccessIcon className=\"w-12 h-12 mx-auto text-dc-success mb-3\" />\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">Query Successful</div>\n <div className=\"text-xs text-dc-text-muted\">No data returned from the query</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"h-full flex flex-col\">\n {/* Results Header with Chart Controls */}\n <div className=\"p-4 border-b border-dc-border bg-dc-surface-secondary\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n {/* Left side: Status and row count */}\n <div className=\"flex items-center\">\n {executionStatus === 'refreshing' ? (\n <div\n className=\"w-5 h-5 mr-2 rounded-full border-b-2 animate-spin\"\n style={{ borderBottomColor: 'var(--dc-primary)' }}\n />\n ) : (\n <SuccessIcon className=\"w-5 h-5 text-dc-success mr-2\" />\n )}\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-semibold text-dc-text-secondary\">\n Query Results ({executionResults.length} row{executionResults.length !== 1 ? 's' : ''} shown)\n </span>\n {resultsStale && (\n <span className=\"text-xs text-dc-text-muted\">Showing previous results while updating.</span>\n )}\n {totalRowCountStatus === 'success' && totalRowCount !== null && totalRowCount !== undefined && (\n <span className=\"text-xs text-dc-text-muted\">\n Total: {totalRowCount.toLocaleString()} row{totalRowCount !== 1 ? 's' : ''}\n </span>\n )}\n {totalRowCountStatus === 'loading' && (\n <span className=\"text-xs text-dc-text-muted\">\n Counting total rows...\n </span>\n )}\n </div>\n </div>\n\n {/* Right side: View tabs and display limit */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n {/* View Toggle Tabs */}\n <div className=\"flex items-center bg-dc-surface border border-dc-border rounded-md overflow-hidden\">\n <button\n onClick={() => setActiveView('table')}\n className={`flex items-center gap-1 px-3 py-1.5 text-xs font-medium transition-colors ${\n activeView === 'table'\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary hover:bg-dc-surface-hover'\n }`}\n >\n <TableIcon className=\"w-3.5 h-3.5\" />\n Table\n </button>\n <button\n onClick={() => setActiveView('chart')}\n className={`flex items-center gap-1 px-3 py-1.5 text-xs font-medium transition-colors ${\n activeView === 'chart'\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary hover:bg-dc-surface-hover'\n }`}\n >\n <MeasureIcon className=\"w-3.5 h-3.5\" />\n Chart\n </button>\n </div>\n\n {/* Display Limit (only show for table view) */}\n {activeView === 'table' && onDisplayLimitChange && (\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-dc-text-secondary\">Show:</label>\n <select\n value={displayLimit}\n onChange={(e) => onDisplayLimitChange(Number(e.target.value))}\n className=\"text-xs border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:outline-hidden focus:ring-1 focus:ring-dc-accent\"\n >\n <option value={10}>10 rows</option>\n <option value={50}>50 rows</option>\n <option value={100}>100 rows</option>\n </select>\n </div>\n )}\n </div>\n </div>\n\n {/* Chart Controls Row (only show when chart view is active) */}\n {activeView === 'chart' && onChartTypeChange && (\n <div className=\"mt-3 pt-3 border-t border-dc-border flex items-center justify-between gap-3 flex-wrap\">\n {/* Chart Type Selector */}\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-dc-text-secondary whitespace-nowrap\">Chart Type:</label>\n <ChartTypeSelector\n selectedType={chartType}\n onTypeChange={onChartTypeChange}\n />\n </div>\n\n {/* Configure Chart Button (only show for non-table chart types) */}\n {chartType !== 'table' && onChartConfigChange && onDisplayConfigChange && (\n <button\n onClick={() => setShowChartConfig(!showChartConfig)}\n className={`flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md transition-colors ${\n showChartConfig\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary bg-dc-surface hover:bg-dc-surface-hover border border-dc-border'\n }`}\n >\n <AdjustmentsIcon className=\"w-4 h-4\" />\n {showChartConfig ? 'Hide Config' : 'Configure'}\n {showChartConfig ? (\n <ChevronUpIcon className=\"w-3.5 h-3.5\" />\n ) : (\n <ChevronDownIcon className=\"w-3.5 h-3.5\" />\n )}\n </button>\n )}\n </div>\n )}\n\n {/* Performance Warning */}\n {totalRowCountStatus === 'success' && totalRowCount !== null && totalRowCount !== undefined && totalRowCount > 500 && (\n <div className=\"mt-3 bg-dc-warning-bg border border-dc-warning rounded-lg p-3 flex items-start\">\n <WarningIcon className=\"w-5 h-5 text-dc-warning mr-2 shrink-0 mt-0.5\" />\n <div className=\"text-sm text-dc-warning\">\n <span className=\"font-semibold\">Performance Warning:</span> This query returns {totalRowCount.toLocaleString()} rows,\n which may impact performance. Consider adding filters to reduce the dataset size.\n </div>\n </div>\n )}\n </div>\n\n {/* Collapsible Chart Config Panel (only when chart view is active) */}\n {activeView === 'chart' && showChartConfig && chartType !== 'table' && onChartConfigChange && onDisplayConfigChange && (\n <div className=\"border-b border-dc-border bg-dc-surface-tertiary p-4\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields || null}\n onChartConfigChange={onChartConfigChange}\n onDisplayConfigChange={onDisplayConfigChange}\n />\n </div>\n )}\n\n {/* Results Content - Table or Chart based on active view */}\n <div className=\"flex-1 min-h-0\">\n {activeView === 'table' ? (\n <LazyChart\n chartType=\"table\"\n data={executionResults}\n queryObject={query}\n height=\"100%\"\n fallback={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full\" />\n </div>\n }\n />\n ) : (\n <div className=\"p-4 h-full overflow-auto\">\n {renderChart()}\n </div>\n )}\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"flex-1 flex flex-col bg-dc-surface border border-dc-border rounded-lg min-h-0\">\n {/* Header */}\n <div className=\"px-4 py-3 border-b border-dc-border bg-dc-surface-secondary\">\n <h3 className=\"text-sm font-semibold text-dc-text\">Query Results</h3>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-h-0 relative\">\n {executionStatus === 'idle' && <EmptyState />}\n {(executionStatus === 'loading' || executionStatus === 'refreshing') && executionResults === null && (\n <LoadingState />\n )}\n {executionStatus === 'error' && executionResults === null && <ErrorState />}\n {(executionStatus === 'success' || executionResults !== null) && <SuccessState />}\n {(executionStatus === 'loading' || executionStatus === 'refreshing') && executionResults !== null && (\n <OverlaySpinner />\n )}\n {executionStatus === 'error' && executionResults !== null && <OverlayError />}\n </div>\n </div>\n )\n}\n\nexport default ResultsPanel\n","/**\n * SetupPanel Component\n * \n * Provides configuration options for API endpoint and authentication.\n * Only shown in standalone QueryBuilder mode, not in modal contexts.\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport type { ApiConfig } from './types'\n\nconst ChevronDownIcon = getIcon('chevronDown')\nconst ChevronUpIcon = getIcon('chevronUp')\nconst SettingsIcon = getIcon('settings')\nconst RefreshIcon = getIcon('refresh')\n\ninterface SetupPanelProps {\n isOpen: boolean\n onToggle: () => void\n config: ApiConfig\n onConfigChange: (config: ApiConfig) => void\n onReset: () => void\n}\n\nconst SetupPanel: React.FC<SetupPanelProps> = ({\n isOpen,\n onToggle,\n config,\n onConfigChange,\n onReset\n}) => {\n const [localConfig, setLocalConfig] = useState<ApiConfig>(config)\n\n const handleApply = () => {\n onConfigChange(localConfig)\n }\n\n const handleReset = () => {\n const defaultConfig = {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n setLocalConfig(defaultConfig)\n onConfigChange(defaultConfig)\n onReset()\n }\n\n const handleInputChange = (field: keyof ApiConfig, value: string) => {\n setLocalConfig(prev => ({\n ...prev,\n [field]: value\n }))\n }\n\n const hasChanges = JSON.stringify(localConfig) !== JSON.stringify(config)\n const isUsingDefaults = config.baseApiUrl === '/cubejs-api/v1' && config.apiToken === ''\n\n return (\n <div className=\"bg-dc-surface border border-dc-border rounded-lg mb-4\">\n {/* Header */}\n <button\n onClick={onToggle}\n className=\"w-full px-4 py-3 flex items-center justify-between text-left bg-dc-surface-secondary rounded-t-lg hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-dc-accent\"\n >\n <div className=\"flex items-center space-x-2\">\n <SettingsIcon className=\"w-5 h-5 text-dc-text-secondary\" />\n <h3 className=\"text-sm font-semibold text-dc-text\">API Configuration</h3>\n {!isUsingDefaults && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-dc-info text-dc-text\">\n Custom\n </span>\n )}\n </div>\n {isOpen ? (\n <ChevronUpIcon className=\"w-4 h-4 text-dc-text-muted\" />\n ) : (\n <ChevronDownIcon className=\"w-4 h-4 text-dc-text-muted\" />\n )}\n </button>\n\n {/* Expandable Content */}\n {isOpen && (\n <div className=\"p-4 border-t border-dc-border\">\n <div className=\"space-y-4\">\n {/* Base API URL */}\n <div>\n <label className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Base API URL\n </label>\n <input\n type=\"text\"\n value={localConfig.baseApiUrl}\n onChange={(e) => handleInputChange('baseApiUrl', e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-hidden focus:ring-2 focus:ring-dc-accent focus:border-dc-accent text-sm\"\n placeholder=\"/cubejs-api/v1\"\n />\n <p className=\"text-xs text-dc-text-muted mt-1\">\n The base URL for the Cube.js API endpoints\n </p>\n </div>\n\n {/* API Token */}\n <div>\n <label className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n API Token\n </label>\n <input\n type=\"password\"\n value={localConfig.apiToken}\n onChange={(e) => handleInputChange('apiToken', e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-hidden focus:ring-2 focus:ring-dc-accent focus:border-dc-accent text-sm\"\n placeholder=\"Leave empty for no authentication\"\n />\n <p className=\"text-xs text-dc-text-muted mt-1\">\n Optional bearer token for API authentication\n </p>\n </div>\n\n {/* Status Indicator */}\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-md p-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h4 className=\"text-xs font-medium text-dc-text-secondary\">Current Configuration</h4>\n <p className=\"text-xs text-dc-text-secondary mt-1\">\n URL: <span className=\"font-mono\">{config.baseApiUrl}</span>\n </p>\n <p className=\"text-xs text-dc-text-secondary\">\n Token: {config.apiToken ? (\n <span className=\"text-dc-success\">Configured</span>\n ) : (\n <span className=\"text-dc-text-muted\">Not set</span>\n )}\n </p>\n </div>\n {!isUsingDefaults && (\n <button\n onClick={handleReset}\n className=\"flex items-center space-x-1 px-2 py-1 text-xs font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-sm hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-dc-accent\"\n title=\"Reset to defaults\"\n >\n <RefreshIcon className=\"w-3 h-3\" />\n <span>Reset</span>\n </button>\n )}\n </div>\n </div>\n\n {/* Action Buttons */}\n {hasChanges && (\n <div className=\"flex justify-end space-x-2 pt-2 border-t border-dc-border\">\n <button\n onClick={() => setLocalConfig(config)}\n className=\"px-3 py-1.5 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-dc-accent\"\n >\n Cancel\n </button>\n <button\n onClick={handleApply}\n className=\"px-3 py-1.5 text-sm font-medium text-white border border-transparent rounded-md focus:outline-hidden focus:ring-2 focus:ring-dc-accent\"\n style={{ backgroundColor: 'var(--dc-primary)' }}\n >\n Apply Changes\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default SetupPanel","/**\n * Constants for AI Assistant\n */\n\nexport const AI_PROXY_BASE_URL = '/api/ai'\nexport const GEMINI_MODEL = 'gemini-2.0-flash'\n\nexport const DEFAULT_SYSTEM_PROMPT_TEMPLATE = `You are a SQL query builder assistant for a semantic layer using Cube.js format.\n\nAvailable cube schema (JSON):\n{CUBE_SCHEMA}\n\nA valid Cube schema can contain things such as below (this is only an example of possible options):\n\n{\n \"measures\": [\"stories.count\"],\n \"dimensions\": [\"stories.category\"],\n \"filters\": [\n {\n \"member\": \"stories.isDraft\",\n \"operator\": \"equals\",\n \"values\": [\"No\"]\n }\n ],\n \"timeDimensions\": [\n {\n \"dimension\": \"stories.time\",\n \"dateRange\": [\"2015-01-01\", \"2015-12-31\"],\n \"granularity\": \"month\"\n }\n ],\n \"limit\": 100,\n \"offset\": 50,\n \"order\": {\n \"stories.time\": \"asc\",\n \"stories.count\": \"desc\"\n }\n}\n\nUser request: {USER_PROMPT}\n\nCRITICAL: You MUST only use field names that exist in the schema above. Do NOT create or invent field names.\n\nGenerate a JSON query object with this structure:\n{\n \"measures\": [\"CubeName.measureName\"],\n \"dimensions\": [\"CubeName.dimensionName\"], \n \"timeDimensions\": [{\n \"dimension\": \"CubeName.timeDimensionName\",\n \"granularity\": \"hour|day|week|month|quarter|year\",\n \"dateRange\": \"last 30 days\"\n }],\n \"filters\": [{\n \"member\": \"CubeName.fieldName\",\n \"operator\": \"equals|contains|gt|gte|lt|lte|inDateRange\",\n \"values\": [\"value1\", \"value2\"]\n }]\n}\n\nRules:\n1. Only use cube names, measure names, and dimension names from the schema\n2. All field references must be in \"CubeName.fieldName\" format\n3. Verify every field exists in the provided schema before using it\n\nRespond with only the JSON query object, no explanation, no markdown formatting, no code blocks, no backtick wrapper.`\n\nexport const AI_STORAGE_KEY = 'drizzle-cube-ai-config'\n\nexport const DEFAULT_AI_CONFIG = {\n provider: 'gemini' as const,\n apiKey: ''\n}","/**\n * Utility functions for AI Assistant\n */\n\nimport type { \n AIQueryRequest,\n AIQueryResponse,\n AIConfig\n} from './types'\nimport { \n AI_STORAGE_KEY,\n DEFAULT_AI_CONFIG\n} from './constants'\n\n/**\n * Send a user prompt to AI proxy (server builds system prompt)\n */\nexport async function sendGeminiMessage(\n apiKey: string,\n userPrompt: string,\n endpoint: string = '/api/ai/generate'\n): Promise<AIQueryResponse> {\n const requestBody: AIQueryRequest = {\n text: userPrompt // Send only the user's prompt, server handles system prompt\n }\n\n // Only add API key header if provided (allow empty string for server key)\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n }\n \n if (apiKey && apiKey.trim()) {\n headers['X-API-Key'] = apiKey\n }\n\n console.log('🤖 Client: Sending user prompt to AI proxy')\n console.log(' URL:', endpoint)\n console.log(' Headers:', headers)\n console.log(' User prompt length:', userPrompt.length)\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody)\n })\n\n console.log('📥 Client: Proxy response')\n console.log(' Status:', response.status)\n console.log(' Status Text:', response.statusText)\n\n if (!response.ok) {\n let errorMessage = `Failed to generate content: ${response.status} ${response.statusText}`\n \n try {\n // Try to parse JSON error response first\n const errorData = await response.json()\n console.error('❌ Client: Proxy error:', errorData)\n \n // Handle rate limit errors specially\n if (response.status === 429 && errorData.error === 'Daily quota exceeded') {\n throw new Error(\n `${errorData.message}\\n\\n${errorData.suggestion || 'Add your own Gemini API key for unlimited access.'}`\n )\n }\n \n // Handle other structured errors\n if (errorData.error) {\n errorMessage = errorData.message || errorData.error\n if (errorData.suggestion) {\n errorMessage += `\\n\\n💡 ${errorData.suggestion}`\n }\n }\n } catch {\n // Fallback to text if JSON parsing fails\n try {\n const errorText = await response.text()\n console.error('❌ Client: Proxy text error:', errorText)\n errorMessage = errorText || errorMessage\n } catch {\n console.error('❌ Client: Could not parse error response')\n }\n }\n \n throw new Error(errorMessage)\n }\n\n const data = await response.json()\n console.log('✅ Client: Successfully generated content')\n return data\n}\n\n// Removed: buildSystemPrompt and formatCubeSchemaForPrompt \n// These functions are now handled server-side for better security\n\n/**\n * Save AI configuration to localStorage\n */\nexport function saveAIConfig(config: AIConfig): void {\n try {\n localStorage.setItem(AI_STORAGE_KEY, JSON.stringify(config))\n } catch (error) {\n console.warn('Failed to save AI config to localStorage:', error)\n }\n}\n\n/**\n * Load AI configuration from localStorage\n */\nexport function loadAIConfig(): AIConfig {\n try {\n const saved = localStorage.getItem(AI_STORAGE_KEY)\n if (saved) {\n const parsed = JSON.parse(saved)\n return { ...DEFAULT_AI_CONFIG, ...parsed }\n }\n } catch (error) {\n console.warn('Failed to load AI config from localStorage:', error)\n }\n return { ...DEFAULT_AI_CONFIG }\n}\n\n/**\n * Extract query text from simplified AI response and clean up formatting\n */\nexport function extractTextFromResponse(response: AIQueryResponse): string {\n const rawText = response.query || ''\n\n // Clean up common markdown formatting that might appear\n return rawText\n .replace(/```json\\s*/g, '') // Remove ```json\n .replace(/```\\s*/g, '') // Remove ```\n .replace(/^\\s*```.*\\n/gm, '') // Remove any remaining code block markers\n .trim()\n}","/**\n * AI Assistant Modal Component\n * \n * Multi-step modal for AI-powered query generation\n * Step 1: API Key input\n * Step 2: Model selection \n * Step 3: Query input and response\n */\n\nimport React, { useState } from 'react'\nimport { getIcon } from '../../icons'\nimport Modal from '../Modal'\n\nconst ErrorIcon = getIcon('error')\nconst SuccessIcon = getIcon('success')\nconst SparklesIcon = getIcon('sparkles')\nimport type { AIAssistantState } from './types'\nimport {\n sendGeminiMessage,\n loadAIConfig,\n extractTextFromResponse\n} from './utils'\nimport { DEFAULT_SYSTEM_PROMPT_TEMPLATE } from './constants'\n\ninterface AIAssistantModalProps {\n isOpen: boolean\n onClose: () => void\n schema?: any\n onQueryLoad?: (query: any) => void\n aiEndpoint?: string\n}\n\nconst AIAssistantModal: React.FC<AIAssistantModalProps> = ({\n isOpen,\n onClose,\n onQueryLoad,\n aiEndpoint = '/api/ai'\n}) => {\n const [state, setState] = useState<AIAssistantState>(() => {\n const savedConfig = loadAIConfig()\n return {\n step: 'query', // Skip API key step and go straight to query\n apiKey: savedConfig.apiKey || '',\n systemPromptTemplate: DEFAULT_SYSTEM_PROMPT_TEMPLATE,\n userPrompt: '',\n isSubmitting: false,\n response: null,\n responseError: null,\n isValidating: false,\n validationResult: null,\n validationError: null\n }\n })\n\n\n const handleQuerySubmit = async (e?: React.FormEvent) => {\n e?.preventDefault()\n if (!state.userPrompt.trim()) return\n\n setState(prev => ({ \n ...prev, \n isSubmitting: true, \n response: null, \n responseError: null,\n validationResult: null,\n validationError: null,\n isValidating: false\n }))\n\n try {\n // Send only the user prompt - server will handle system prompt building\n const response = await sendGeminiMessage(\n state.apiKey,\n state.userPrompt,\n aiEndpoint\n )\n\n const responseText = extractTextFromResponse(response)\n setState(prev => ({ \n ...prev, \n isSubmitting: false, \n response: responseText \n }))\n \n // Automatically validate after successful generation\n setTimeout(() => {\n validateResponse(responseText)\n }, 500)\n } catch (error) {\n setState(prev => ({\n ...prev,\n isSubmitting: false,\n responseError: error instanceof Error ? error.message : 'Failed to process query'\n }))\n }\n }\n\n // Validate a specific response text (used for auto-validation)\n const validateResponse = async (responseText: string) => {\n if (!responseText) {\n console.log('AI Modal: No response text to validate')\n return\n }\n\n console.log('AI Modal: Starting validation with response:', responseText.substring(0, 100) + '...')\n \n setState(prev => ({\n ...prev,\n isValidating: true,\n validationResult: null,\n validationError: null\n }))\n\n try {\n const query = JSON.parse(responseText)\n console.log('AI Modal: Parsed query:', query)\n \n const response = await fetch('/cubejs-api/v1/load', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(query)\n })\n\n console.log('AI Modal: Validation response status:', response.status)\n\n if (response.ok) {\n console.log('AI Modal: Validation SUCCESS')\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'valid'\n }))\n } else {\n const errorData = await response.text()\n console.log('AI Modal: Validation FAILED:', errorData)\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'invalid',\n validationError: errorData || `HTTP ${response.status}: ${response.statusText}`\n }))\n }\n } catch (error) {\n console.log('AI Modal: Validation ERROR:', error)\n setState(prev => ({\n ...prev,\n isValidating: false,\n validationResult: 'invalid',\n validationError: error instanceof Error ? error.message : 'Failed to validate query'\n }))\n }\n }\n\n const handleValidate = async () => {\n if (!state.response) return\n await validateResponse(state.response)\n }\n\n const handleUseQuery = () => {\n if (!state.response || !onQueryLoad) return\n\n try {\n const query = JSON.parse(state.response)\n onQueryLoad(query)\n handleClose()\n } catch {\n setState(prev => ({\n ...prev,\n validationError: 'Invalid JSON format'\n }))\n }\n }\n\n const handleClose = () => {\n setState(prev => ({\n ...prev,\n response: null,\n responseError: null,\n validationResult: null,\n validationError: null\n }))\n onClose()\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n handleQuerySubmit()\n }\n }\n\n\n\n const renderQueryStep = () => (\n <div className=\"flex flex-col space-y-4\">\n {/* Top: Config Panel - Full Width */}\n <div className=\"shrink-0 p-3 bg-dc-surface-secondary border border-dc-border rounded-md\">\n <div className=\"text-sm text-dc-text-muted\">\n Using: <span className=\"font-medium\">AI Query Generation</span>\n <span className=\"ml-2 px-2 py-1 bg-dc-accent-bg text-dc-accent text-xs rounded-sm\">\n Server-provided AI (Rate Limited)\n </span>\n </div>\n </div>\n \n {/* Middle: Input/Output Row - Takes remaining space */}\n <div className=\"flex flex-col md:flex-row gap-6 flex-1 min-h-0\">\n {/* Left: Query Input */}\n <div className=\"w-full md:w-1/2 flex flex-col\">\n <label htmlFor=\"user-prompt\" className=\"block text-sm font-medium text-dc-text-secondary mb-2\">\n Describe your query in natural language\n </label>\n <textarea\n id=\"user-prompt\"\n value={state.userPrompt}\n onChange={(e) => setState(prev => ({ ...prev, userPrompt: e.target.value }))}\n onKeyDown={handleKeyDown}\n placeholder=\"e.g., Show me the total revenue by month for the last year (Press Enter to generate, Shift+Enter for new line)\"\n className=\"flex-1 w-full px-3 py-2 border border-dc-border rounded-md shadow-xs focus:outline-none focus:ring-dc-accent focus:border-dc-accent resize-none bg-dc-surface text-dc-text\"\n required\n />\n </div>\n \n {/* Right: Output Query */}\n <div className=\"w-full md:w-1/2 flex flex-col\">\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center space-x-2\">\n {state.response ? (\n <>\n <SuccessIcon className=\"w-5 h-5 text-dc-success\" />\n <span className=\"text-sm font-medium text-dc-success\">AI Generated Query</span>\n </>\n ) : (\n <span className=\"text-sm font-medium text-dc-text-muted\">Generated Query</span>\n )}\n </div>\n {state.response && (\n <button\n onClick={handleValidate}\n disabled={state.isValidating}\n className=\"text-xs text-dc-accent hover:text-dc-accent disabled:opacity-50\"\n title=\"Click to re-validate query\"\n >\n {state.isValidating ? 'Validating...' : 'Re-validate'}\n </button>\n )}\n </div>\n\n {state.response ? (\n <div className=\"flex-1 bg-dc-success-bg border border-dc-success rounded-md p-3\">\n <pre className=\"text-sm text-dc-text whitespace-pre-wrap overflow-auto bg-dc-surface p-3 rounded-sm border h-full\">\n {state.response}\n </pre>\n </div>\n ) : (\n <div className=\"flex-1 flex items-center justify-center text-dc-text-muted border-2 border-dashed border-dc-border rounded-md p-8 min-h-64\">\n <div className=\"text-center\">\n <SparklesIcon className=\"w-12 h-12 mx-auto text-dc-text-muted\" />\n </div>\n </div>\n )}\n </div>\n </div>\n \n {/* Status Messages - Fixed height */}\n <div className=\"shrink-0\">\n {state.responseError && (\n <div className=\"flex items-start space-x-2 p-3 bg-dc-danger-bg border border-dc-error rounded-md\">\n <ErrorIcon className=\"w-5 h-5 text-dc-error mt-0.5 shrink-0\" />\n <div className=\"text-sm text-dc-error\">{state.responseError}</div>\n </div>\n )}\n \n {state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-dc-accent-bg border border-dc-accent rounded-md\">\n <div className=\"animate-spin rounded-full h-5 w-5 border-b-2 border-dc-accent mt-0.5 shrink-0\"></div>\n <div className=\"text-sm text-dc-accent\">Validating query...</div>\n </div>\n )}\n \n {state.validationResult === 'valid' && !state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-dc-success-bg border border-dc-success rounded-md\">\n <SuccessIcon className=\"w-5 h-5 text-dc-success mt-0.5 shrink-0\" />\n <div className=\"text-sm text-dc-success\">Query is valid and ready to use!</div>\n </div>\n )}\n \n {state.validationResult === 'invalid' && !state.isValidating && (\n <div className=\"flex items-start space-x-2 p-3 bg-dc-danger-bg border border-dc-error rounded-md\">\n <ErrorIcon className=\"w-5 h-5 text-dc-error mt-0.5 shrink-0\" />\n <div className=\"text-sm text-dc-error\">\n <div className=\"font-medium mb-1\">Query validation failed:</div>\n <div className=\"text-xs\">{state.validationError}</div>\n </div>\n </div>\n )}\n </div>\n \n {/* Bottom: Action Buttons - Right Aligned */}\n <div className=\"shrink-0 flex justify-end space-x-3 pt-3\">\n <button\n type=\"submit\"\n disabled={!state.userPrompt.trim() || state.isSubmitting}\n onClick={handleQuerySubmit}\n className=\"px-4 py-2 text-white text-sm rounded-md hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-dc-accent focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed flex items-center\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n {state.isSubmitting ? (\n <>\n <div className=\"animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2\"></div>\n Generating...\n </>\n ) : (\n <>\n <SparklesIcon className=\"w-4 h-4 mr-2\" />\n Generate\n </>\n )}\n </button>\n\n {/* Validation happens automatically after generation */}\n\n <button\n onClick={handleUseQuery}\n disabled={!state.response || !onQueryLoad}\n className=\"px-4 py-2 bg-dc-success text-white text-sm rounded-md hover:bg-dc-success focus:outline-none focus:ring-2 focus:ring-dc-success focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed flex items-center\"\n >\n <SuccessIcon className=\"w-4 h-4 mr-2\" />\n Use Query\n </button>\n </div>\n </div>\n )\n\n const getTitle = () => {\n return 'AI Assistant - Generate Query'\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={getTitle()}\n size=\"fullscreen-mobile\"\n >\n {renderQueryStep()}\n </Modal>\n )\n}\n\nexport default AIAssistantModal","// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>\n// This work is free. You can redistribute it and/or modify it\n// under the terms of the WTFPL, Version 2\n// For more information see LICENSE.txt or http://www.wtfpl.net/\n//\n// For more information, the home page:\n// http://pieroxy.net/blog/pages/lz-string/testing.html\n//\n// LZ-based compression algorithm, version 1.4.5\nvar LZString = (function() {\n\n// private property\nvar f = String.fromCharCode;\nvar keyStrBase64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\nvar keyStrUriSafe = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$\";\nvar baseReverseDic = {};\n\nfunction getBaseValue(alphabet, character) {\n if (!baseReverseDic[alphabet]) {\n baseReverseDic[alphabet] = {};\n for (var i=0 ; i<alphabet.length ; i++) {\n baseReverseDic[alphabet][alphabet.charAt(i)] = i;\n }\n }\n return baseReverseDic[alphabet][character];\n}\n\nvar LZString = {\n compressToBase64 : function (input) {\n if (input == null) return \"\";\n var res = LZString._compress(input, 6, function(a){return keyStrBase64.charAt(a);});\n switch (res.length % 4) { // To produce valid Base64\n default: // When could this happen ?\n case 0 : return res;\n case 1 : return res+\"===\";\n case 2 : return res+\"==\";\n case 3 : return res+\"=\";\n }\n },\n\n decompressFromBase64 : function (input) {\n if (input == null) return \"\";\n if (input == \"\") return null;\n return LZString._decompress(input.length, 32, function(index) { return getBaseValue(keyStrBase64, input.charAt(index)); });\n },\n\n compressToUTF16 : function (input) {\n if (input == null) return \"\";\n return LZString._compress(input, 15, function(a){return f(a+32);}) + \" \";\n },\n\n decompressFromUTF16: function (compressed) {\n if (compressed == null) return \"\";\n if (compressed == \"\") return null;\n return LZString._decompress(compressed.length, 16384, function(index) { return compressed.charCodeAt(index) - 32; });\n },\n\n //compress into uint8array (UCS-2 big endian format)\n compressToUint8Array: function (uncompressed) {\n var compressed = LZString.compress(uncompressed);\n var buf=new Uint8Array(compressed.length*2); // 2 bytes per character\n\n for (var i=0, TotalLen=compressed.length; i<TotalLen; i++) {\n var current_value = compressed.charCodeAt(i);\n buf[i*2] = current_value >>> 8;\n buf[i*2+1] = current_value % 256;\n }\n return buf;\n },\n\n //decompress from uint8array (UCS-2 big endian format)\n decompressFromUint8Array:function (compressed) {\n if (compressed===null || compressed===undefined){\n return LZString.decompress(compressed);\n } else {\n var buf=new Array(compressed.length/2); // 2 bytes per character\n for (var i=0, TotalLen=buf.length; i<TotalLen; i++) {\n buf[i]=compressed[i*2]*256+compressed[i*2+1];\n }\n\n var result = [];\n buf.forEach(function (c) {\n result.push(f(c));\n });\n return LZString.decompress(result.join(''));\n\n }\n\n },\n\n\n //compress into a string that is already URI encoded\n compressToEncodedURIComponent: function (input) {\n if (input == null) return \"\";\n return LZString._compress(input, 6, function(a){return keyStrUriSafe.charAt(a);});\n },\n\n //decompress from an output of compressToEncodedURIComponent\n decompressFromEncodedURIComponent:function (input) {\n if (input == null) return \"\";\n if (input == \"\") return null;\n input = input.replace(/ /g, \"+\");\n return LZString._decompress(input.length, 32, function(index) { return getBaseValue(keyStrUriSafe, input.charAt(index)); });\n },\n\n compress: function (uncompressed) {\n return LZString._compress(uncompressed, 16, function(a){return f(a);});\n },\n _compress: function (uncompressed, bitsPerChar, getCharFromInt) {\n if (uncompressed == null) return \"\";\n var i, value,\n context_dictionary= {},\n context_dictionaryToCreate= {},\n context_c=\"\",\n context_wc=\"\",\n context_w=\"\",\n context_enlargeIn= 2, // Compensate for the first entry which should not count\n context_dictSize= 3,\n context_numBits= 2,\n context_data=[],\n context_data_val=0,\n context_data_position=0,\n ii;\n\n for (ii = 0; ii < uncompressed.length; ii += 1) {\n context_c = uncompressed.charAt(ii);\n if (!Object.prototype.hasOwnProperty.call(context_dictionary,context_c)) {\n context_dictionary[context_c] = context_dictSize++;\n context_dictionaryToCreate[context_c] = true;\n }\n\n context_wc = context_w + context_c;\n if (Object.prototype.hasOwnProperty.call(context_dictionary,context_wc)) {\n context_w = context_wc;\n } else {\n if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) {\n if (context_w.charCodeAt(0)<256) {\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<8 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n } else {\n value = 1;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | value;\n if (context_data_position ==bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = 0;\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<16 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n delete context_dictionaryToCreate[context_w];\n } else {\n value = context_dictionary[context_w];\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n // Add wc to the dictionary.\n context_dictionary[context_wc] = context_dictSize++;\n context_w = String(context_c);\n }\n }\n\n // Output the code for w.\n if (context_w !== \"\") {\n if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) {\n if (context_w.charCodeAt(0)<256) {\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<8 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n } else {\n value = 1;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | value;\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = 0;\n }\n value = context_w.charCodeAt(0);\n for (i=0 ; i<16 ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n delete context_dictionaryToCreate[context_w];\n } else {\n value = context_dictionary[context_w];\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n\n }\n context_enlargeIn--;\n if (context_enlargeIn == 0) {\n context_enlargeIn = Math.pow(2, context_numBits);\n context_numBits++;\n }\n }\n\n // Mark the end of the stream\n value = 2;\n for (i=0 ; i<context_numBits ; i++) {\n context_data_val = (context_data_val << 1) | (value&1);\n if (context_data_position == bitsPerChar-1) {\n context_data_position = 0;\n context_data.push(getCharFromInt(context_data_val));\n context_data_val = 0;\n } else {\n context_data_position++;\n }\n value = value >> 1;\n }\n\n // Flush the last char\n while (true) {\n context_data_val = (context_data_val << 1);\n if (context_data_position == bitsPerChar-1) {\n context_data.push(getCharFromInt(context_data_val));\n break;\n }\n else context_data_position++;\n }\n return context_data.join('');\n },\n\n decompress: function (compressed) {\n if (compressed == null) return \"\";\n if (compressed == \"\") return null;\n return LZString._decompress(compressed.length, 32768, function(index) { return compressed.charCodeAt(index); });\n },\n\n _decompress: function (length, resetValue, getNextValue) {\n var dictionary = [],\n next,\n enlargeIn = 4,\n dictSize = 4,\n numBits = 3,\n entry = \"\",\n result = [],\n i,\n w,\n bits, resb, maxpower, power,\n c,\n data = {val:getNextValue(0), position:resetValue, index:1};\n\n for (i = 0; i < 3; i += 1) {\n dictionary[i] = i;\n }\n\n bits = 0;\n maxpower = Math.pow(2,2);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n switch (next = bits) {\n case 0:\n bits = 0;\n maxpower = Math.pow(2,8);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n c = f(bits);\n break;\n case 1:\n bits = 0;\n maxpower = Math.pow(2,16);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n c = f(bits);\n break;\n case 2:\n return \"\";\n }\n dictionary[3] = c;\n w = c;\n result.push(c);\n while (true) {\n if (data.index > length) {\n return \"\";\n }\n\n bits = 0;\n maxpower = Math.pow(2,numBits);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n switch (c = bits) {\n case 0:\n bits = 0;\n maxpower = Math.pow(2,8);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n\n dictionary[dictSize++] = f(bits);\n c = dictSize-1;\n enlargeIn--;\n break;\n case 1:\n bits = 0;\n maxpower = Math.pow(2,16);\n power=1;\n while (power!=maxpower) {\n resb = data.val & data.position;\n data.position >>= 1;\n if (data.position == 0) {\n data.position = resetValue;\n data.val = getNextValue(data.index++);\n }\n bits |= (resb>0 ? 1 : 0) * power;\n power <<= 1;\n }\n dictionary[dictSize++] = f(bits);\n c = dictSize-1;\n enlargeIn--;\n break;\n case 2:\n return result.join('');\n }\n\n if (enlargeIn == 0) {\n enlargeIn = Math.pow(2, numBits);\n numBits++;\n }\n\n if (dictionary[c]) {\n entry = dictionary[c];\n } else {\n if (c === dictSize) {\n entry = w + w.charAt(0);\n } else {\n return null;\n }\n }\n result.push(entry);\n\n // Add w+entry[0] to the dictionary.\n dictionary[dictSize++] = w + entry.charAt(0);\n enlargeIn--;\n\n w = entry;\n\n if (enlargeIn == 0) {\n enlargeIn = Math.pow(2, numBits);\n numBits++;\n }\n\n }\n }\n};\n return LZString;\n})();\n\nif (typeof define === 'function' && define.amd) {\n define(function () { return LZString; });\n} else if( typeof module !== 'undefined' && module != null ) {\n module.exports = LZString\n} else if( typeof angular !== 'undefined' && angular != null ) {\n angular.module('LZString', [])\n .factory('LZString', function () {\n return LZString;\n });\n}\n","/**\n * Share utilities for QueryBuilder\n *\n * Handles compression, encoding, and URL generation for sharing analysis state.\n * Uses LZ-String for compression which produces URL-safe output.\n */\n\nimport { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from 'lz-string'\nimport type { CubeQuery, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\n\n/**\n * State that can be shared via URL\n * Query is required, chart config is optional (may be dropped if too large)\n */\nexport interface ShareableState {\n query: CubeQuery\n chartType?: ChartType\n chartConfig?: ChartAxisConfig\n displayConfig?: ChartDisplayConfig\n activeView?: 'table' | 'chart'\n}\n\n/**\n * Result of compression with fallback\n */\nexport interface CompressionResult {\n encoded: string | null\n queryOnly: boolean\n}\n\n// Max safe URL hash length (conservative for browser compatibility)\nconst MAX_HASH_LENGTH = 1800\nconst SHARE_PREFIX = 'share='\n\n/**\n * Compress state to URL-safe encoded string\n */\nexport function compressAndEncode(state: ShareableState): string {\n const json = JSON.stringify(state)\n return compressToEncodedURIComponent(json)\n}\n\n/**\n * Decompress URL-safe encoded string back to state\n * Returns null if decompression or parsing fails\n */\nexport function decodeAndDecompress(encoded: string): ShareableState | null {\n try {\n const json = decompressFromEncodedURIComponent(encoded)\n if (!json) return null\n\n const state = JSON.parse(json) as ShareableState\n\n // Validate required field\n if (!state.query || typeof state.query !== 'object') {\n return null\n }\n\n return state\n } catch {\n return null\n }\n}\n\n/**\n * Check if compressed state fits within URL length limit\n */\nexport function isShareableSize(state: ShareableState): { ok: boolean; size: number; maxSize: number } {\n const encoded = compressAndEncode(state)\n return {\n ok: encoded.length <= MAX_HASH_LENGTH,\n size: encoded.length,\n maxSize: MAX_HASH_LENGTH\n }\n}\n\n/**\n * Compress state with automatic fallback\n * If full state is too large, tries with query only\n * Returns null encoded if even query-only is too large\n */\nexport function compressWithFallback(state: ShareableState): CompressionResult {\n // Try full state first\n const fullEncoded = compressAndEncode(state)\n if (fullEncoded.length <= MAX_HASH_LENGTH) {\n return { encoded: fullEncoded, queryOnly: false }\n }\n\n // Fall back to query only\n const queryOnlyState: ShareableState = { query: state.query }\n const queryOnlyEncoded = compressAndEncode(queryOnlyState)\n\n if (queryOnlyEncoded.length <= MAX_HASH_LENGTH) {\n return { encoded: queryOnlyEncoded, queryOnly: true }\n }\n\n // Even query-only is too large\n return { encoded: null, queryOnly: true }\n}\n\n/**\n * Generate full share URL with compressed state in hash\n */\nexport function generateShareUrl(state: ShareableState): string | null {\n const { encoded } = compressWithFallback(state)\n if (!encoded) return null\n\n return `${window.location.origin}${window.location.pathname}#${SHARE_PREFIX}${encoded}`\n}\n\n/**\n * Parse share hash from current URL\n * Returns encoded string if #share= is present, null otherwise\n */\nexport function parseShareHash(): string | null {\n if (typeof window === 'undefined') return null\n\n const hash = window.location.hash\n if (!hash || !hash.startsWith(`#${SHARE_PREFIX}`)) {\n return null\n }\n\n return hash.slice(SHARE_PREFIX.length + 1) // +1 for the #\n}\n\n/**\n * Clear share hash from URL without page reload\n */\nexport function clearShareHash(): void {\n if (typeof window === 'undefined') return\n\n const url = new URL(window.location.href)\n url.hash = ''\n window.history.replaceState(null, '', url.toString())\n}\n\n/**\n * Get the maximum allowed hash length\n */\nexport function getMaxHashLength(): number {\n return MAX_HASH_LENGTH\n}\n","/**\n * ShareWarningModal Component\n *\n * Displayed when the query is too large to share via URL,\n * even after dropping chart configuration.\n */\n\nimport React from 'react'\nimport Modal from '../Modal'\nimport { getIcon } from '../../icons'\n\nexport interface ShareWarningModalProps {\n isOpen: boolean\n onClose: () => void\n size: number\n maxSize: number\n}\n\nconst ShareWarningModal: React.FC<ShareWarningModalProps> = ({\n isOpen,\n onClose,\n size,\n maxSize\n}) => {\n const percentUsed = Math.min(Math.round((size / maxSize) * 100), 100)\n\n const WarningIcon = getIcon('warning')\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title=\"Query Too Large to Share\"\n size=\"sm\"\n >\n <div className=\"space-y-4\">\n {/* Warning icon and message */}\n <div className=\"flex items-start gap-3\">\n <div className=\"shrink-0 p-2 bg-dc-warning-bg dark:bg-dc-warning-bg rounded-full\">\n <WarningIcon className=\"w-5 h-5 text-dc-warning dark:text-dc-warning\" />\n </div>\n <div className=\"text-sm text-dc-text-secondary\">\n Your query is too large to fit in a shareable URL. Even after removing chart settings,\n the compressed query exceeds the safe URL length limit.\n </div>\n </div>\n\n {/* Size indicator */}\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-xs text-dc-text-muted\">\n <span>Compressed size</span>\n <span className=\"text-dc-error dark:text-dc-error font-medium\">\n {size.toLocaleString()} / {maxSize.toLocaleString()} chars\n </span>\n </div>\n <div className=\"h-2 bg-dc-surface-secondary rounded-full overflow-hidden\">\n <div\n className=\"h-full bg-dc-danger-bg0 dark:bg-dc-error transition-all duration-300\"\n style={{ width: `${percentUsed}%` }}\n />\n </div>\n </div>\n\n {/* Suggestions */}\n <div className=\"border-t border-dc-border pt-4\">\n <p className=\"text-xs font-medium text-dc-text mb-2\">\n To make your query shareable, try:\n </p>\n <ul className=\"text-xs text-dc-text-secondary space-y-1.5\">\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Remove some filters, especially complex nested filter groups</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Reduce the number of dimensions or measures</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Simplify date range filters</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <span className=\"text-dc-text-muted\">-</span>\n <span>Use the &quot;Copy Query&quot; button to copy the raw JSON instead</span>\n </li>\n </ul>\n </div>\n\n {/* Close button */}\n <div className=\"flex justify-end pt-2\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-sm font-medium text-white bg-dc-primary hover:bg-dc-primary-hover rounded-md transition-colors\"\n >\n Got it\n </button>\n </div>\n </div>\n </Modal>\n )\n}\n\nexport default ShareWarningModal\n","/**\n * QueryBuilder Component\n * \n * Main component that orchestrates the query building experience.\n * Manages state and coordinates between the meta explorer, query panel, and results panel.\n */\n\nimport { useState, useEffect, useCallback, useRef, forwardRef, useImperativeHandle, useMemo } from 'react'\nimport { getIcon } from '../../icons'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport CubeMetaExplorer from './CubeMetaExplorer'\nimport QueryPanel from './QueryPanel'\nimport ResultsPanel from './ResultsPanel'\nimport SetupPanel from './SetupPanel'\nimport AIAssistantModal from '../AIAssistant/AIAssistantModal'\nimport type {\n QueryBuilderProps,\n QueryBuilderRef,\n QueryBuilderState,\n MetaResponse,\n ValidationResult,\n ApiConfig,\n ShareButtonState\n} from './types'\nimport type { Filter, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\nimport { createEmptyQuery, hasQueryContent, cleanQuery, cleanQueryForServer, cleanupFilters, transformQueryForUI } from './utils'\nimport { parseShareHash, clearShareHash, decodeAndDecompress, compressWithFallback, getMaxHashLength, type ShareableState } from './shareUtils'\nimport ShareWarningModal from './ShareWarningModal'\n\nconst STORAGE_KEY = 'drizzle-cube-query-builder-state'\nconst API_CONFIG_STORAGE_KEY = 'drizzle-cube-api-config'\n\nconst QueryBuilder = forwardRef<QueryBuilderRef, QueryBuilderProps>(({\n className = '',\n initialQuery,\n disableLocalStorage = false,\n hideSettings = false,\n enableSharing = false,\n onShare\n}, ref) => {\n // Get cube client, update function, and features from context\n const { cubeApi, updateApiConfig, features, meta, metaLoading, metaError, refetchMeta } = useCubeContext()\n \n // Load initial API configuration from localStorage\n const getInitialApiConfig = (): ApiConfig => {\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(API_CONFIG_STORAGE_KEY)\n if (saved) {\n return JSON.parse(saved)\n }\n } catch {\n // Failed to load API config from localStorage\n }\n }\n return {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n }\n\n // Load initial state from localStorage if available, or use provided initialQuery\n const getInitialState = (): QueryBuilderState => {\n // If initialQuery is provided, use it instead of localStorage\n if (initialQuery) {\n return {\n query: transformQueryForUI(initialQuery),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle',\n resultsStale: false\n }\n }\n\n // Only check localStorage if not disabled\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n const parsedState = JSON.parse(saved)\n return {\n query: transformQueryForUI(parsedState.query) || createEmptyQuery(),\n validationStatus: 'idle', // Reset validation status\n validationError: null,\n validationSql: null,\n executionStatus: 'idle', // Reset execution status\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle',\n resultsStale: false\n }\n }\n } catch {\n // Failed to load query from localStorage\n }\n }\n\n return {\n query: createEmptyQuery(),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle',\n resultsStale: false\n }\n }\n\n const [state, setState] = useState<QueryBuilderState>(getInitialState())\n \n // Separate state for display limit (doesn't affect the actual query object)\n const [displayLimit, setDisplayLimit] = useState<number>(10)\n\n // Load initial chart configuration from localStorage\n const getInitialChartState = () => {\n if (!disableLocalStorage) {\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n const parsed = JSON.parse(saved)\n return {\n chartType: parsed.chartType || 'table',\n chartConfig: parsed.chartConfig || {},\n displayConfig: parsed.displayConfig || { showLegend: true, showGrid: true, showTooltip: true },\n activeView: parsed.activeView || 'table'\n }\n }\n } catch {\n // Failed to load chart config from localStorage\n }\n }\n return {\n chartType: 'table' as ChartType,\n chartConfig: {} as ChartAxisConfig,\n displayConfig: { showLegend: true, showGrid: true, showTooltip: true } as ChartDisplayConfig,\n activeView: 'table' as 'table' | 'chart'\n }\n }\n\n // Chart visualization state\n const initialChartState = getInitialChartState()\n const [chartType, setChartType] = useState<ChartType>(initialChartState.chartType)\n const [chartConfig, setChartConfig] = useState<ChartAxisConfig>(initialChartState.chartConfig)\n const [displayConfig, setDisplayConfig] = useState<ChartDisplayConfig>(initialChartState.displayConfig)\n const [activeView, setActiveView] = useState<'table' | 'chart'>(initialChartState.activeView)\n\n // API configuration state\n const [apiConfig, setApiConfig] = useState<ApiConfig>(getInitialApiConfig())\n const [showSetupPanel, setShowSetupPanel] = useState(false)\n const [showSchemaMobile, setShowSchemaMobile] = useState(false)\n const [schemaViewType, setSchemaViewType] = useState<'tree' | 'diagram'>('tree')\n \n // AI Assistant modal state\n const [showAIAssistant, setShowAIAssistant] = useState(false)\n\n // Share functionality state\n const [shareButtonState, setShareButtonState] = useState<ShareButtonState>('idle')\n const [showShareWarning, setShowShareWarning] = useState(false)\n const [shareWarningData, setShareWarningData] = useState({ size: 0, maxSize: 0 })\n const [isViewingShared, setIsViewingShared] = useState(false)\n\n // Update query when initialQuery prop changes (for modal usage)\n useEffect(() => {\n if (initialQuery && JSON.stringify(initialQuery) !== JSON.stringify(state.query)) {\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(initialQuery),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle',\n resultsStale: false\n }))\n }\n }, [initialQuery])\n\n // Track the last validated query to avoid resetting validation on unrelated updates\n const lastValidatedQueryRef = useRef<string>('')\n\n // Note: API configuration is kept for backward compatibility but not used \n // since we now use the CubeClient from context\n\n // Store the full validation result for access via ref\n const [fullValidationResult, setFullValidationResult] = useState<ValidationResult | null>(null)\n\n // Expose query and validation state to parent via ref (only called when Apply is clicked)\n useImperativeHandle(ref, () => ({\n getCurrentQuery: () => cleanQueryForServer(state.query),\n getValidationState: () => ({\n status: state.validationStatus,\n result: state.validationStatus === 'valid' ? {\n valid: true,\n sql: state.validationSql || undefined\n } : state.validationStatus === 'invalid' ? {\n valid: false,\n error: state.validationError || undefined\n } : undefined\n }),\n getValidationResult: () => fullValidationResult\n }), [state.query, state.validationStatus, state.validationError, state.validationSql, fullValidationResult])\n\n // Save query and chart config to localStorage whenever they change (if not disabled)\n useEffect(() => {\n if (!disableLocalStorage) {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify({\n query: state.query,\n chartType,\n chartConfig,\n displayConfig,\n activeView\n }))\n } catch {\n // Failed to save state to localStorage\n }\n }\n }, [state.query, chartType, chartConfig, displayConfig, activeView, disableLocalStorage])\n\n // Save API config to localStorage whenever it changes (if not disabled)\n useEffect(() => {\n if (!disableLocalStorage) {\n try {\n localStorage.setItem(API_CONFIG_STORAGE_KEY, JSON.stringify(apiConfig))\n } catch {\n // Failed to save API config to localStorage\n }\n }\n }, [apiConfig, disableLocalStorage])\n\n // Track if we need to auto-run after loading shared analysis\n const pendingSharedExecution = useRef(false)\n\n // Parse URL hash for shared analysis on mount (when sharing is enabled)\n useEffect(() => {\n if (!enableSharing) return\n\n const encoded = parseShareHash()\n if (!encoded) return\n\n const decoded = decodeAndDecompress(encoded)\n if (decoded) {\n // Apply query (required)\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(decoded.query),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle',\n resultsStale: false\n }))\n\n // Apply chart config if present, otherwise use defaults\n if (decoded.chartType) setChartType(decoded.chartType)\n if (decoded.chartConfig) setChartConfig(decoded.chartConfig)\n if (decoded.displayConfig) setDisplayConfig(decoded.displayConfig)\n if (decoded.activeView) setActiveView(decoded.activeView)\n\n setIsViewingShared(true)\n pendingSharedExecution.current = true\n }\n\n // Clear hash from URL\n clearShareHash()\n }, [enableSharing])\n\n // Auto re-run query when displayLimit or activeView changes\n useEffect(() => {\n if (state.executionStatus === 'success' && hasQueryContent(state.query)) {\n handleExecuteQuery()\n }\n }, [displayLimit, activeView]) // Re-run on limit or view change\n\n\n const updateQuery = useCallback((updater: (prev: typeof state.query) => typeof state.query) => {\n setState(prev => {\n const newQuery = updater(prev.query)\n \n // Clean up filters to remove any that reference fields no longer in the query\n const cleanedQuery = {\n ...newQuery,\n filters: newQuery.filters ? cleanupFilters(newQuery.filters, newQuery) : undefined\n }\n \n const queryChanged = JSON.stringify(cleanedQuery) !== JSON.stringify(prev.query)\n const shouldMarkStale = queryChanged && !!prev.executionResults\n \n return {\n ...prev,\n query: cleanedQuery,\n // Only reset validation if query actually changed\n validationStatus: queryChanged ? 'idle' : prev.validationStatus,\n validationError: queryChanged ? null : prev.validationError,\n validationSql: queryChanged ? null : prev.validationSql,\n executionStatus: queryChanged\n ? (prev.executionResults ? 'success' : 'idle')\n : prev.executionStatus,\n executionError: queryChanged ? null : prev.executionError,\n resultsStale: shouldMarkStale ? true : prev.resultsStale\n }\n })\n }, [])\n\n const handleFieldSelect = useCallback((fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n updateQuery(prev => {\n const newQuery = { ...prev }\n \n switch (fieldType) {\n case 'measures':\n // Only add if not already present\n if (!(prev.measures || []).includes(fieldName)) {\n newQuery.measures = [...(prev.measures || []), fieldName]\n }\n break\n case 'dimensions':\n // Only add if not already present\n if (!(prev.dimensions || []).includes(fieldName)) {\n newQuery.dimensions = [...(prev.dimensions || []), fieldName]\n }\n break\n case 'timeDimensions':\n // Only add if not already present\n if (!(prev.timeDimensions || []).some(td => td.dimension === fieldName)) {\n newQuery.timeDimensions = [...(prev.timeDimensions || []), { \n dimension: fieldName, \n granularity: 'month' \n }]\n }\n break\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleFieldDeselect = useCallback((fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => {\n updateQuery(prev => {\n const newQuery = { ...prev }\n \n switch (fieldType) {\n case 'measures':\n newQuery.measures = (prev.measures || []).filter(m => m !== fieldName)\n break\n case 'dimensions':\n newQuery.dimensions = (prev.dimensions || []).filter(d => d !== fieldName)\n break\n case 'timeDimensions':\n newQuery.timeDimensions = (prev.timeDimensions || []).filter(td => td.dimension !== fieldName)\n break\n }\n \n // Clean up order if field was sorted\n if (newQuery.order && newQuery.order[fieldName]) {\n const newOrder = { ...newQuery.order }\n delete newOrder[fieldName]\n newQuery.order = Object.keys(newOrder).length > 0 ? newOrder : undefined\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleTimeDimensionGranularityChange = useCallback((dimensionName: string, granularity: string) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === dimensionName \n ? { ...td, granularity }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleFiltersChange = useCallback((filters: Filter[]) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n filters\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleDateRangeChange = useCallback((timeDimension: string, dateRange: string | string[]) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === timeDimension \n ? { ...td, dateRange }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleDateRangeRemove = useCallback((timeDimension: string) => {\n updateQuery(prev => {\n const newQuery = {\n ...prev,\n timeDimensions: (prev.timeDimensions || []).map(td => \n td.dimension === timeDimension \n ? { ...td, dateRange: undefined }\n : td\n )\n }\n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const handleOrderChange = useCallback((fieldName: string, direction: 'asc' | 'desc' | null) => {\n updateQuery(prev => {\n const newOrder = { ...(prev.order || {}) }\n \n if (direction === null) {\n delete newOrder[fieldName]\n } else {\n newOrder[fieldName] = direction\n }\n \n const newQuery = {\n ...prev,\n order: Object.keys(newOrder).length > 0 ? newOrder : undefined\n }\n \n return cleanQuery(newQuery)\n })\n }, [updateQuery])\n\n const validateQuery = useCallback(async (silent: boolean) => {\n if (!hasQueryContent(state.query)) return null\n\n const queryToValidate = cleanQueryForServer(state.query)\n const queryStr = JSON.stringify(queryToValidate)\n\n if (!silent) {\n setState(prev => ({\n ...prev,\n validationStatus: 'validating',\n validationError: null,\n validationSql: null\n }))\n }\n\n try {\n const result: ValidationResult = await cubeApi.dryRun(queryToValidate)\n const isValid = !result.error && result.queryType && (result.valid !== false)\n\n if (isValid) {\n lastValidatedQueryRef.current = queryStr\n }\n\n if (silent) {\n if (!isValid) {\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: result.error || 'Validation failed',\n validationSql: result.sql || null\n }))\n } else {\n setState(prev => ({\n ...prev,\n validationError: null,\n validationSql: result.sql || null\n }))\n }\n setFullValidationResult(result)\n } else {\n if (!isValid) {\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: result.error || 'Validation failed',\n validationSql: result.sql || null\n }))\n } else {\n setState(prev => ({\n ...prev,\n validationStatus: 'valid',\n validationError: null,\n validationSql: result.sql || null\n }))\n }\n setFullValidationResult(result)\n }\n\n return isValid ? result : null\n } catch (error) {\n setFullValidationResult(null)\n if (!silent) {\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: error instanceof Error ? error.message : 'Network error during validation',\n validationSql: null\n }))\n } else {\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: error instanceof Error ? error.message : 'Network error during validation',\n validationSql: null\n }))\n }\n return null\n }\n }, [state.query, cubeApi])\n\n // Auto re-validate query when query changes (silent, no UI updates)\n useEffect(() => {\n if (!hasQueryContent(state.query)) {\n return\n }\n\n const debounceTimer = setTimeout(() => {\n validateQuery(true)\n }, 200) // 200ms debounce - fast but prevents excessive API calls\n\n return () => clearTimeout(debounceTimer)\n }, [state.query, validateQuery])\n\n const handleExecuteQuery = useCallback(async () => {\n if (!hasQueryContent(state.query)) return\n\n const cleanedQuery = cleanQueryForServer(state.query)\n const queryStr = JSON.stringify(cleanedQuery)\n\n if (lastValidatedQueryRef.current !== queryStr) {\n const result = await validateQuery(false)\n if (!result) {\n return\n }\n }\n\n setState(prev => ({\n ...prev,\n executionStatus: prev.executionResults ? 'refreshing' : 'loading',\n executionError: null,\n totalRowCountStatus: 'loading'\n }))\n\n try {\n // Run both queries in parallel: one with limit and one without for total count\n // Chart view: no limit (show all data for visualization)\n // Table view: apply displayLimit for pagination\n const effectiveLimit = activeView === 'chart' ? undefined : displayLimit\n\n const [limitedResultSet, totalResultSet] = await Promise.all([\n cubeApi.load(effectiveLimit ? { ...cleanedQuery, limit: effectiveLimit } : cleanedQuery),\n cubeApi.load(cleanedQuery) // No limit for total count\n ])\n\n const limitedData = limitedResultSet.tablePivot()\n const totalData = totalResultSet.tablePivot()\n const totalCount = totalData.length\n\n setState(prev => ({\n ...prev,\n executionStatus: 'success',\n executionResults: limitedData,\n executionError: null,\n totalRowCount: totalCount,\n totalRowCountStatus: 'success',\n resultsStale: false\n }))\n lastExecutedQueryRef.current = queryStr\n if (lastAutoRunQueryRef.current === queryStr) {\n lastAutoRunQueryRef.current = ''\n }\n } catch (error) {\n // Query execution error\n setState(prev => ({\n ...prev,\n executionStatus: 'error',\n executionError: error instanceof Error ? error.message : 'Query execution failed',\n totalRowCountStatus: prev.totalRowCount !== null ? 'success' : 'error'\n }))\n }\n }, [state.query, cubeApi, displayLimit, activeView, validateQuery])\n\n useEffect(() => {\n if (!state.executionResults) return\n if (!hasQueryContent(state.query)) return\n\n const cleanedQuery = cleanQueryForServer(state.query)\n const queryStr = JSON.stringify(cleanedQuery)\n\n if (queryStr === lastExecutedQueryRef.current || queryStr === lastAutoRunQueryRef.current) {\n return\n }\n\n if (autoRunTimerRef.current) {\n clearTimeout(autoRunTimerRef.current)\n }\n\n lastAutoRunQueryRef.current = queryStr\n autoRunTimerRef.current = setTimeout(() => {\n handleExecuteQuery()\n }, 250)\n\n return () => {\n if (autoRunTimerRef.current) {\n clearTimeout(autoRunTimerRef.current)\n }\n }\n }, [state.query, state.executionResults, handleExecuteQuery])\n\n // Auto-execute query after loading from shared link once validation succeeds\n useEffect(() => {\n if (pendingSharedExecution.current && state.executionStatus === 'idle') {\n pendingSharedExecution.current = false\n handleExecuteQuery()\n }\n }, [state.executionStatus, handleExecuteQuery])\n\n const handleClearQuery = useCallback(() => {\n setState(prev => ({\n ...prev,\n query: createEmptyQuery(),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle',\n resultsStale: false\n }))\n }, [])\n\n const shareStateRef = useRef<ShareableState>({\n query: cleanQueryForServer(state.query),\n chartType,\n chartConfig,\n displayConfig,\n activeView\n })\n const onShareRef = useRef<typeof onShare>(onShare)\n\n useEffect(() => {\n shareStateRef.current = {\n query: cleanQueryForServer(state.query),\n chartType,\n chartConfig,\n displayConfig,\n activeView\n }\n }, [state.query, chartType, chartConfig, displayConfig, activeView])\n\n useEffect(() => {\n onShareRef.current = onShare\n }, [onShare])\n\n const handleShare = useCallback(async () => {\n if (!enableSharing) return\n\n const shareableState = shareStateRef.current\n\n // Try full state first, fall back to query-only if too large\n const { encoded, queryOnly } = compressWithFallback(shareableState)\n\n // If even query-only is too large, show warning modal\n if (!encoded) {\n const queryOnlyState: ShareableState = { query: shareableState.query }\n const queryOnlySize = JSON.stringify(queryOnlyState).length\n setShareWarningData({ size: queryOnlySize, maxSize: getMaxHashLength() })\n setShowShareWarning(true)\n return\n }\n\n const url = `${window.location.origin}${window.location.pathname}#share=${encoded}`\n\n try {\n await navigator.clipboard.writeText(url)\n } catch {\n // Fallback for older browsers\n const textArea = document.createElement('textarea')\n textArea.value = url\n document.body.appendChild(textArea)\n textArea.select()\n document.execCommand('copy')\n document.body.removeChild(textArea)\n }\n\n // Update button state\n setShareButtonState(queryOnly ? 'copied-no-chart' : 'copied')\n\n // Call onShare callback if provided\n onShareRef.current?.(url)\n\n // Reset button state after 2 seconds\n setTimeout(() => {\n setShareButtonState('idle')\n }, 2000)\n }, [enableSharing])\n\n const handleApiConfigChange = useCallback((newConfig: ApiConfig) => {\n setApiConfig(newConfig)\n \n // Update the CubeProvider's client with new configuration\n updateApiConfig(\n { apiUrl: newConfig.baseApiUrl },\n newConfig.apiToken || undefined\n )\n \n // Reset query-related state when API config changes\n setState(prev => ({\n ...prev,\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle',\n resultsStale: false\n }))\n }, [updateApiConfig])\n\n const handleResetApiConfig = useCallback(() => {\n const defaultConfig = {\n baseApiUrl: '/cubejs-api/v1',\n apiToken: ''\n }\n setApiConfig(defaultConfig)\n \n // Update the CubeProvider's client with reset configuration\n updateApiConfig(\n { apiUrl: defaultConfig.baseApiUrl },\n undefined\n )\n }, [updateApiConfig])\n\n const handleRetrySchema = useCallback(() => {\n refetchMeta()\n }, [refetchMeta])\n\n const selectedFields = useMemo(() => ({\n measures: state.query.measures || [],\n dimensions: state.query.dimensions || [],\n timeDimensions: (state.query.timeDimensions || []).map(td => td.dimension)\n }), [state.query.measures, state.query.dimensions, state.query.timeDimensions])\n\n const schemaStatus = metaLoading ? 'loading' : metaError ? 'error' : meta ? 'success' : 'idle'\n const schema = meta ? (meta as unknown as MetaResponse) : null\n const schemaError = metaError\n\n const availableFields = useMemo(() => {\n const sourceQuery = fullValidationResult?.pivotQuery?.query ?? state.query\n return {\n dimensions: sourceQuery.dimensions || [],\n timeDimensions: sourceQuery.timeDimensions?.map((td: { dimension: string }) => td.dimension) || [],\n measures: sourceQuery.measures || []\n }\n }, [fullValidationResult, state.query])\n\n const handleToggleSetupPanel = useCallback(() => {\n setShowSetupPanel(prev => !prev)\n }, [])\n\n const handleOpenAIAssistant = useCallback(() => {\n setShowAIAssistant(true)\n }, [])\n\n const handleViewTypeChange = useCallback((viewType: 'tree' | 'diagram') => {\n setSchemaViewType(viewType)\n }, [])\n\n const lastExecutedQueryRef = useRef<string>('')\n const lastAutoRunQueryRef = useRef<string>('')\n const autoRunTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const MenuIcon = getIcon('menu')\n const CloseIcon = getIcon('close')\n\n return (\n <div className={`h-full flex flex-col ${className}`} style={{ minHeight: '100%' }}>\n {/* Setup Panel - only show when not in modal and not hidden */}\n {!hideSettings && (\n <div className=\"shrink-0 p-4 pb-0\">\n <SetupPanel\n isOpen={showSetupPanel}\n onToggle={handleToggleSetupPanel}\n config={apiConfig}\n onConfigChange={handleApiConfigChange}\n onReset={handleResetApiConfig}\n />\n </div>\n )}\n\n {/* Mobile Schema Toggle Button */}\n <div className=\"md:hidden shrink-0 px-4 pb-2\">\n <button\n onClick={() => setShowSchemaMobile(!showSchemaMobile)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface-secondary hover:bg-dc-surface-hover rounded-md transition-colors\"\n >\n {showSchemaMobile ? (\n <><CloseIcon className=\"w-4 h-4\" /> Hide Schema</>\n ) : (\n <><MenuIcon className=\"w-4 h-4\" /> Show Schema</>\n )}\n </button>\n </div>\n\n {/* Mobile Schema Panel Overlay */}\n {showSchemaMobile && (\n <div className=\"md:hidden fixed inset-0 z-50 bg-black bg-opacity-50 flex\">\n <div className=\"w-full max-w-md sm:max-w-lg bg-dc-surface h-full overflow-y-auto\">\n <div className=\"p-4 border-b border-dc-border\">\n <button\n onClick={() => setShowSchemaMobile(false)}\n className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface-secondary hover:bg-dc-surface-hover rounded-md transition-colors\"\n >\n <CloseIcon className=\"w-4 h-4\" /> Close Schema\n </button>\n </div>\n <div className=\"p-4\">\n <CubeMetaExplorer\n schema={schema}\n schemaStatus={schemaStatus}\n schemaError={schemaError}\n selectedFields={selectedFields}\n onFieldSelect={(field, type) => {\n handleFieldSelect(field, type)\n setShowSchemaMobile(false)\n }}\n onFieldDeselect={handleFieldDeselect}\n onRetrySchema={handleRetrySchema}\n onOpenSettings={!hideSettings ? () => setShowSetupPanel(true) : undefined}\n onExpandSchema={(expanded) => {\n if (expanded) setShowSchemaMobile(false)\n }}\n />\n </div>\n </div>\n <div className=\"flex-1\" onClick={() => setShowSchemaMobile(false)}></div>\n </div>\n )}\n\n <div className=\"flex-1 flex flex-col md:flex-row gap-4 p-4 min-h-0\" style={{ paddingTop: hideSettings ? '1rem' : '0rem' }}>\n {/* Schema Explorer with dynamic width based on view type */}\n <div className={`hidden md:flex shrink-0 flex-col min-w-0 ${schemaViewType === 'diagram' ? 'w-full' : 'md:w-1/3 max-w-[500px]'}`}>\n <CubeMetaExplorer\n schema={schema}\n schemaStatus={schemaStatus}\n schemaError={schemaError}\n selectedFields={selectedFields}\n onFieldSelect={handleFieldSelect}\n onFieldDeselect={handleFieldDeselect}\n onRetrySchema={handleRetrySchema}\n onOpenSettings={!hideSettings ? () => setShowSetupPanel(true) : undefined}\n onExpandSchema={undefined} // No expand/collapse needed\n onViewTypeChange={handleViewTypeChange}\n isExpanded={false} // Always false, handled by tab switching\n />\n </div>\n\n {/* Main Content - Query Builder + Results (hide when diagram is selected) */}\n {schemaViewType === 'tree' && (\n <div className=\"flex-1 flex flex-col gap-4 min-w-0 min-h-0\">\n {/* Query Builder */}\n <div className=\"shrink-0\">\n <QueryPanel\n query={state.query}\n schema={schema}\n validationStatus={state.validationStatus}\n validationError={state.validationError}\n validationSql={state.validationSql}\n validationAnalysis={fullValidationResult?.analysis}\n onExecute={handleExecuteQuery}\n onRemoveField={handleFieldDeselect}\n onTimeDimensionGranularityChange={handleTimeDimensionGranularityChange}\n onFiltersChange={handleFiltersChange}\n onDateRangeChange={handleDateRangeChange}\n onDateRangeRemove={handleDateRangeRemove}\n onOrderChange={handleOrderChange}\n onClearQuery={handleClearQuery}\n showSettings={!hideSettings}\n onSettingsClick={handleToggleSetupPanel}\n onAIAssistantClick={features?.enableAI !== false ? handleOpenAIAssistant : undefined}\n onShareClick={enableSharing ? handleShare : undefined}\n canShare={enableSharing && hasQueryContent(state.query)}\n shareButtonState={shareButtonState}\n isViewingShared={isViewingShared}\n />\n </div>\n\n {/* Results Panel */}\n <div className=\"flex-1 min-h-0\">\n <ResultsPanel\n executionStatus={state.executionStatus}\n executionResults={state.executionResults}\n executionError={state.executionError}\n resultsStale={state.resultsStale}\n query={state.query}\n displayLimit={displayLimit}\n onDisplayLimitChange={setDisplayLimit}\n totalRowCount={state.totalRowCount}\n totalRowCountStatus={state.totalRowCountStatus}\n // Chart visualization props\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields}\n onChartTypeChange={setChartType}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n // View state props\n activeView={activeView}\n onActiveViewChange={setActiveView}\n />\n </div>\n </div>\n )}\n </div>\n \n {/* AI Assistant Modal - only render if AI is enabled */}\n {features?.enableAI !== false && (\n <AIAssistantModal\n isOpen={showAIAssistant}\n onClose={() => setShowAIAssistant(false)}\n schema={schema}\n aiEndpoint={features?.aiEndpoint}\n onQueryLoad={(query) => {\n // Update the query in the builder\n setState(prev => ({\n ...prev,\n query: transformQueryForUI(query),\n validationStatus: 'idle',\n validationError: null,\n validationSql: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n totalRowCountStatus: 'idle',\n resultsStale: false\n }))\n \n // Auto-validate the loaded query after a short delay\n setTimeout(async () => {\n // We need to access handleValidateQuery through a ref or recreate the validation logic\n // For now, let's trigger validation by updating the state to force a validation\n const queryToValidate = cleanQueryForServer(transformQueryForUI(query))\n \n try {\n const result = await cubeApi.dryRun(queryToValidate)\n const isValid = !result.error && result.queryType && (result.valid !== false)\n \n setState(prev => ({\n ...prev,\n validationStatus: isValid ? 'valid' : 'invalid',\n validationError: result.error || null,\n validationSql: result.sql || null\n }))\n \n setFullValidationResult(result)\n } catch (error) {\n // Auto-validation error\n setState(prev => ({\n ...prev,\n validationStatus: 'invalid',\n validationError: error instanceof Error ? error.message : 'Validation failed',\n validationSql: null\n }))\n setFullValidationResult(null)\n }\n }, 200)\n }}\n />\n )}\n\n {/* Share Warning Modal - shown when query is too large to share */}\n <ShareWarningModal\n isOpen={showShareWarning}\n onClose={() => setShowShareWarning(false)}\n size={shareWarningData.size}\n maxSize={shareWarningData.maxSize}\n />\n\n </div>\n )\n})\n\nQueryBuilder.displayName = 'QueryBuilder'\n\nexport default QueryBuilder\n","import React, { useState, useEffect, useRef } from 'react'\nimport Modal from './Modal'\nimport QueryBuilder from './QueryBuilder'\nimport ChartConfigPanel from './ChartConfigPanel'\nimport ChartTypeSelector from './ChartTypeSelector'\nimport { useCubeContext } from '../providers/CubeProvider'\nimport { chartConfigRegistry } from '../charts/chartConfigRegistry'\nimport { getChartConfig } from '../charts/chartConfigs'\nimport type { PortletConfig, ChartAxisConfig, ChartDisplayConfig, ChartType, ColorPalette } from '../types'\n\ninterface PortletEditModalProps {\n isOpen: boolean\n onClose: () => void\n onSave: (portlet: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => void\n portlet?: PortletConfig | null\n title: string\n submitText: string\n colorPalette?: ColorPalette\n}\n\n\nconst SAMPLE_QUERIES = [\n {\n name: 'Employee Count by Department',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Employees.count\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Employee Hiring Trends',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\"],\n \"timeDimensions\": [{\n \"dimension\": \"Employees.createdAt\",\n \"granularity\": \"month\"\n }],\n \"order\": { \"Employees.createdAt\": \"asc\" }\n }, null, 2)\n },\n {\n name: 'Department Budget Analysis',\n query: JSON.stringify({\n \"measures\": [\"Departments.totalBudget\", \"Departments.avgBudget\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Departments.totalBudget\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Daily Productivity Trends',\n query: JSON.stringify({\n \"measures\": [\"Productivity.avgLinesOfCode\", \"Productivity.totalPullRequests\"],\n \"timeDimensions\": [{\n \"dimension\": \"Productivity.date\",\n \"granularity\": \"day\"\n }],\n \"order\": { \"Productivity.date\": \"asc\" }\n }, null, 2)\n },\n {\n name: 'Happiness by Department',\n query: JSON.stringify({\n \"measures\": [\"Productivity.avgHappinessIndex\", \"Productivity.workingDaysCount\"],\n \"dimensions\": [\"Departments.name\"],\n \"order\": { \"Productivity.avgHappinessIndex\": \"desc\" }\n }, null, 2)\n },\n {\n name: 'Employee Salary Overview',\n query: JSON.stringify({\n \"measures\": [\"Employees.count\", \"Employees.avgSalary\", \"Employees.totalSalary\"],\n \"dimensions\": [\"Employees.isActive\"],\n \"order\": { \"Employees.avgSalary\": \"desc\" }\n }, null, 2)\n }\n]\n\nexport default function PortletEditModal({\n isOpen,\n onClose,\n onSave,\n portlet,\n title,\n submitText,\n colorPalette\n}: PortletEditModalProps) {\n // Get cube client from context\n const { cubeApi } = useCubeContext()\n const [formTitle, setFormTitle] = useState('')\n const [query, setQuery] = useState('')\n const [chartType, setChartType] = useState<ChartType>('bar')\n const [dashboardFilterMapping, setDashboardFilterMapping] = useState<string[]>([])\n const [isValidating, setIsValidating] = useState(false)\n const [validationResult, setValidationResult] = useState<{ isValid: boolean; message: string } | null>(null)\n const [lastValidatedQuery, setLastValidatedQuery] = useState<string>('')\n const [dryRunData, setDryRunData] = useState<any>(null)\n const [chartConfig, setChartConfig] = useState<ChartAxisConfig>({ xAxis: [], yAxis: [], series: [] })\n const [displayConfig, setDisplayConfig] = useState<ChartDisplayConfig>({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n const [showQueryBuilder, setShowQueryBuilder] = useState(false)\n const [queryBuilderInitialQuery, setQueryBuilderInitialQuery] = useState<any>(null)\n const queryBuilderRef = useRef<any>(null)\n\n // Check if current chart type skips queries\n const chartTypeConfig = getChartConfig(chartType, chartConfigRegistry)\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Validation only - no automatic chart config changes\n const autoPopulateChartConfig = (_result: any) => {\n // Do nothing - let the chart configuration panel handle all axis assignments manually\n // This preserves any existing user configuration and doesn't auto-assign fields\n }\n \n // Sensible defaults: slightly larger than 1/3 width with good aspect ratio\n const defaultWidth = 5\n const defaultHeight = 4\n\n\n // Initialize form values when modal opens or portlet changes\n useEffect(() => {\n if (isOpen) {\n if (portlet) {\n // Edit mode - populate with existing data\n setFormTitle(portlet.title)\n const formattedQuery = (() => {\n try {\n return JSON.stringify(JSON.parse(portlet.query), null, 2)\n } catch {\n return portlet.query\n }\n })()\n setQuery(formattedQuery)\n setChartType(portlet.chartType)\n setChartConfig(portlet.chartConfig || { xAxis: [], yAxis: [], series: [] })\n setDisplayConfig(portlet.displayConfig || {})\n setDashboardFilterMapping(portlet.dashboardFilterMapping || [])\n setLastValidatedQuery(formattedQuery)\n setValidationResult({ isValid: true, message: 'Loaded query (assumed valid)' })\n setDryRunData(null)\n\n // Auto-run dry-run validation for edit mode to enable chart configuration (skip for skipQuery charts)\n if (!shouldSkipQuery) {\n setTimeout(() => {\n runDryRunValidation(formattedQuery, true, true)\n }, 100)\n }\n } else {\n // Create mode - clear form\n setFormTitle('')\n setQuery('')\n setChartType('bar')\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n setDisplayConfig({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n setDashboardFilterMapping([])\n setLastValidatedQuery('')\n setValidationResult(null)\n setDryRunData(null)\n }\n setIsValidating(false)\n }\n }, [isOpen, portlet])\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault()\n \n // For skipQuery charts, only validate title\n if (shouldSkipQuery) {\n if (!formTitle.trim()) {\n return\n }\n } else {\n // For normal charts, validate both title and query\n if (!formTitle.trim() || !query.trim()) {\n return\n }\n\n // Require validation before saving only if query has changed\n if (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')) {\n alert('Please validate your query before saving.')\n return\n }\n\n // Validate JSON\n try {\n JSON.parse(query)\n } catch {\n alert('Invalid JSON in query. Please check your syntax.')\n return\n }\n }\n\n // Prepare query - use minimal query for skipQuery charts\n const queryToSave = shouldSkipQuery ? '{\"measures\":[]}' : query.trim()\n\n if (portlet) {\n // Edit mode - return full portlet config\n onSave({\n ...portlet,\n title: formTitle.trim(),\n query: queryToSave,\n chartType,\n chartConfig: Object.keys(chartConfig).length > 0 ? chartConfig : undefined,\n displayConfig: displayConfig,\n dashboardFilterMapping: dashboardFilterMapping.length > 0 ? dashboardFilterMapping : undefined,\n w: portlet.w || defaultWidth,\n h: portlet.h || defaultHeight\n })\n } else {\n // Create mode - return partial config\n onSave({\n title: formTitle.trim(),\n query: queryToSave,\n chartType,\n chartConfig: Object.keys(chartConfig).length > 0 ? chartConfig : undefined,\n displayConfig: displayConfig,\n dashboardFilterMapping: dashboardFilterMapping.length > 0 ? dashboardFilterMapping : undefined,\n w: defaultWidth,\n h: defaultHeight\n })\n }\n }\n\n const handleSampleQuery = (sampleQuery: string) => {\n setQuery(sampleQuery)\n setValidationResult(null)\n setLastValidatedQuery('')\n setDryRunData(null)\n // Sample queries always clear chart config since they're completely different\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n }\n\n const handleQueryChange = (value: string) => {\n setQuery(value)\n setValidationResult(null)\n setDryRunData(null)\n // Only clear chart config for new portlets, preserve existing config for edits\n if (!portlet) {\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n }\n }\n\n const runDryRunValidation = async (queryToValidate: string, silent = false, isEditModeLoad = false) => {\n if (!queryToValidate.trim()) {\n if (!silent) {\n setValidationResult({ isValid: false, message: 'Query cannot be empty' })\n }\n return\n }\n\n let parsedQuery\n try {\n parsedQuery = JSON.parse(queryToValidate)\n } catch {\n if (!silent) {\n setValidationResult({ isValid: false, message: 'Invalid JSON syntax' })\n }\n return\n }\n\n if (!silent) {\n setIsValidating(true)\n setValidationResult(null)\n }\n\n try {\n const result = await cubeApi.dryRun(parsedQuery)\n\n // Check if validation is successful:\n // 1. Must have queryType (always present in successful Cube.js responses) \n // 2. Must not have an error\n const isValid = !result.error && result.queryType\n \n if (isValid) {\n setDryRunData(result)\n \n if (!silent) {\n const details = []\n \n if (result.pivotQuery?.query) {\n if (result.pivotQuery.query.measures?.length > 0) {\n details.push(`${result.pivotQuery.query.measures.length} measure${result.pivotQuery.query.measures.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.dimensions?.length > 0) {\n details.push(`${result.pivotQuery.query.dimensions.length} dimension${result.pivotQuery.query.dimensions.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.filters?.length > 0) {\n details.push(`${result.pivotQuery.query.filters.length} filter${result.pivotQuery.query.filters.length > 1 ? 's' : ''}`)\n }\n if (result.pivotQuery.query.timeDimensions?.length > 0) {\n details.push(`${result.pivotQuery.query.timeDimensions.length} time dimension${result.pivotQuery.query.timeDimensions.length > 1 ? 's' : ''}`)\n }\n }\n\n if (result.complexity) {\n details.push(`${result.complexity} complexity`)\n }\n if (result.sql?.sql) {\n details.push('SQL generated')\n }\n if (result.cubesUsed?.length > 0) {\n details.push(`Cubes: ${result.cubesUsed.join(', ')}`)\n }\n \n const message = details.length > 0 ? `Query validated successfully (${details.join(', ')})` : 'Query validated successfully'\n setValidationResult({ isValid: true, message })\n setLastValidatedQuery(queryToValidate)\n }\n\n // Auto-populate chart config with sensible defaults on successful validation\n if (!isEditModeLoad) {\n autoPopulateChartConfig(result)\n }\n } else {\n if (!silent) {\n const errorMsg = result.error || 'Query validation failed'\n const details = result.details ? ` - ${Array.isArray(result.details) ? result.details.join(', ') : result.details}` : ''\n setValidationResult({ \n isValid: false, \n message: errorMsg + details\n })\n setLastValidatedQuery(queryToValidate)\n }\n }\n } catch (error) {\n if (!silent) {\n setValidationResult({ \n isValid: false, \n message: error instanceof Error ? error.message : 'Network error during validation' \n })\n setLastValidatedQuery(queryToValidate)\n }\n } finally {\n if (!silent) {\n setIsValidating(false)\n }\n }\n }\n\n const handleValidateQuery = async () => {\n await runDryRunValidation(query)\n }\n\n const handleOpenQueryBuilder = () => {\n // Parse the current query and set it as the initial query for QueryBuilder\n const initialQuery = query ? (() => {\n try {\n return JSON.parse(query)\n } catch {\n return {}\n }\n })() : {}\n \n setQueryBuilderInitialQuery(initialQuery)\n setShowQueryBuilder(true)\n }\n\n\n const handleApplyQueryBuilderQuery = (e?: React.MouseEvent) => {\n e?.preventDefault()\n e?.stopPropagation()\n \n if (!queryBuilderRef.current) return\n \n // Get current query and validation state from QueryBuilder\n const currentQuery = queryBuilderRef.current.getCurrentQuery()\n const validationState = queryBuilderRef.current.getValidationState()\n const validationResult = queryBuilderRef.current.getValidationResult()\n \n // Apply the query to the form\n const formattedQuery = JSON.stringify(currentQuery, null, 2)\n setQuery(formattedQuery)\n \n // If QueryBuilder had a valid query, transfer the validation state and dry-run data\n if (validationState?.status === 'valid' && validationResult) {\n setValidationResult({ \n isValid: true, \n message: 'Query validated in Query Builder' \n })\n setLastValidatedQuery(formattedQuery)\n \n // Transfer the dry-run data from QueryBuilder validation result\n setDryRunData(validationResult)\n \n // Auto-populate chart config using the same logic as form validation\n autoPopulateChartConfig(validationResult)\n } else {\n // Reset validation state if query wasn't validated in QueryBuilder\n setValidationResult(null)\n setLastValidatedQuery('')\n setDryRunData(null)\n }\n \n // Return to form view to continue editing\n setShowQueryBuilder(false)\n }\n\n const handleBackToForm = () => {\n setShowQueryBuilder(false)\n setQueryBuilderInitialQuery(null)\n }\n\n const handleClose = () => {\n setFormTitle('')\n setQuery('')\n setChartType('bar')\n setChartConfig({ xAxis: [], yAxis: [], series: [] })\n setDisplayConfig({ showLegend: true, showGrid: true, showTooltip: true, stacked: false })\n setValidationResult(null)\n setIsValidating(false)\n setLastValidatedQuery('')\n setDryRunData(null)\n setShowQueryBuilder(false)\n setQueryBuilderInitialQuery(null)\n onClose()\n }\n\n const isEditMode = !!portlet\n const hasQueryChanged = query.trim() !== lastValidatedQuery.trim() && lastValidatedQuery !== ''\n const isQueryValidAndCurrent = validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n\n\n const availableFields = dryRunData?.pivotQuery?.query ? {\n dimensions: dryRunData.pivotQuery.query.dimensions || [],\n timeDimensions: dryRunData.pivotQuery.query.timeDimensions?.map((td: any) => td.dimension) || [],\n measures: dryRunData.pivotQuery.query.measures || []\n } : null\n\n\n const footer = showQueryBuilder ? (\n <>\n <button\n type=\"button\"\n onClick={handleBackToForm}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-none focus:ring-2 focus:ring-dc-primary\"\n >\n Back to Form\n </button>\n <button\n type=\"button\"\n onClick={handleApplyQueryBuilderQuery}\n className=\"px-4 py-2 text-sm font-medium border border-transparent rounded-md focus:outline-none focus:ring-2 focus:ring-dc-accent\"\n style={{ backgroundColor: 'var(--dc-primary)', color: '#ffffff' }}\n title=\"Apply query to form\"\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary)'}\n >\n Apply Query\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n onClick={handleClose}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-none focus:ring-2 focus:ring-dc-primary\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n form=\"portlet-form\"\n className=\"px-4 py-2 text-sm font-medium border border-transparent rounded-md disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-dc-accent\"\n style={{ backgroundColor: 'var(--dc-primary)', color: '#ffffff' }}\n disabled={shouldSkipQuery ? !formTitle.trim() : (!formTitle.trim() || !query.trim() || (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')))}\n title={!shouldSkipQuery && (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '')) ? \"Please validate your query before saving\" : \"\"}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-primary)'}\n >\n {submitText}\n </button>\n </>\n )\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={showQueryBuilder ? \"Query Builder\" : title}\n size=\"fullscreen-mobile\"\n footer={footer}\n noPadding={showQueryBuilder}\n >\n {showQueryBuilder ? (\n <QueryBuilder\n ref={queryBuilderRef}\n initialQuery={queryBuilderInitialQuery}\n disableLocalStorage={true}\n hideSettings={true}\n className=\"flex-1 w-full\"\n />\n ) : (\n <form id=\"portlet-form\" onSubmit={handleSubmit} className=\"space-y-4\">\n {/* Main layout - Responsive: single column on mobile, two columns on desktop */}\n <div className=\"flex flex-col lg:flex-row gap-4\">\n {/* Left side - Title, Chart Type, Query */}\n <div className=\"flex-1 flex flex-col gap-4\">\n {/* Title */}\n <div>\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-1\">\n Title\n </label>\n <input\n type=\"text\"\n value={formTitle}\n onChange={(e) => setFormTitle(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter portlet title...\"\n required\n />\n </div>\n\n {/* Chart Type */}\n <div>\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-3\">\n Chart Type\n </label>\n <ChartTypeSelector\n selectedType={chartType}\n onTypeChange={setChartType}\n />\n </div>\n\n\n {/* Query Editor - Hidden for skipQuery charts */}\n {!shouldSkipQuery && (\n <div className=\"flex-1 flex flex-col\">\n <div className=\"flex justify-between items-center mb-1\">\n <label className=\"block text-sm font-semibold text-dc-text-secondary\">\n Cube.js Query (JSON)\n </label>\n <div className=\"flex items-center space-x-2\">\n <button\n type=\"button\"\n onClick={handleOpenQueryBuilder}\n className=\"text-xs px-2 py-1 text-dc-accent bg-dc-surface hover:bg-dc-accent-bg rounded-sm border border-dc-accent hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-dc-accent\"\n >\n Edit in Query Builder\n </button>\n </div>\n </div>\n <textarea\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n className=\"flex-1 w-full min-h-64 px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary font-mono text-xs resize-y\"\n placeholder={`{\n \"measures\": [\"People.count\"],\n \"dimensions\": [\"People.active\"]\n}`}\n required\n />\n </div>\n )}\n </div>\n\n {/* Right side - Chart Configuration */}\n <div className=\"flex-1 flex flex-col\">\n <label className=\"block text-sm font-semibold text-dc-text-secondary mb-1\">\n {shouldSkipQuery ? 'Chart Configuration' : 'Chart Axis Configuration'}\n </label>\n\n {shouldSkipQuery ? (\n <div className=\"rounded-lg bg-dc-surface p-3 border border-dc-border\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={null}\n colorPalette={colorPalette}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n />\n </div>\n ) : (!dryRunData || !isQueryValidAndCurrent) ? (\n <div className=\"flex-1 flex items-center justify-center border-2 border-dashed border-dc-border rounded-lg bg-dc-surface-secondary\">\n <div className=\"text-center text-dc-text-muted\">\n <svg className=\"h-8 w-8 mx-auto mb-2\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" />\n </svg>\n <p className=\"text-sm\">Validate query first to configure chart axes</p>\n </div>\n </div>\n ) : (\n <div className=\"rounded-lg bg-dc-surface p-3 border border-dc-border\">\n <ChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n availableFields={availableFields}\n colorPalette={colorPalette}\n onChartConfigChange={setChartConfig}\n onDisplayConfigChange={setDisplayConfig}\n />\n </div>\n )}\n </div>\n </div>\n\n {/* Validation section - Hidden for skipQuery charts */}\n {!shouldSkipQuery && (hasQueryChanged || (lastValidatedQuery === '' && query.trim() !== '') || (validationResult && query.trim() === lastValidatedQuery.trim() && validationResult.message !== 'Loaded query (assumed valid)')) && (\n <div className={`rounded-lg p-4 ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-dc-success-bg'\n : validationResult && !validationResult.isValid\n ? 'bg-dc-error-bg'\n : hasQueryChanged\n ? 'bg-dc-warning-bg'\n : 'bg-dc-surface-secondary'\n }`}>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-3\">\n <div className={`w-2 h-2 rounded-full ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-dc-success'\n : validationResult && !validationResult.isValid\n ? 'bg-dc-error'\n : hasQueryChanged\n ? 'bg-dc-warning'\n : 'bg-dc-muted'\n }`}></div>\n <div>\n <h3 className={`text-sm font-medium ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'text-dc-success'\n : validationResult && !validationResult.isValid\n ? 'text-dc-error'\n : hasQueryChanged\n ? 'text-dc-warning'\n : 'text-dc-text-secondary'\n }`}>\n {validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'Query validated successfully'\n : validationResult && !validationResult.isValid\n ? 'Query validation failed'\n : hasQueryChanged\n ? 'Query modified - validation required'\n : 'Query validation required'\n }\n </h3>\n {validationResult && (\n <p className={`text-xs mt-1 ${\n validationResult.isValid ? 'text-dc-success' : 'text-dc-error'\n }`}>\n {validationResult.message}\n </p>\n )}\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={handleValidateQuery}\n disabled={isValidating || !query.trim()}\n className={`px-3 py-1.5 text-sm font-medium rounded-md transition-colors flex items-center space-x-1.5 ${\n validationResult?.isValid && query.trim() === lastValidatedQuery.trim()\n ? 'bg-dc-success text-white hover:opacity-80'\n : validationResult && !validationResult.isValid\n ? 'bg-dc-error text-white hover:opacity-80'\n : 'bg-dc-primary text-white hover:bg-dc-primary-hover'\n } disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-dc-primary`}\n >\n {isValidating ? (\n <>\n <svg className=\"animate-spin h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span>Validating</span>\n </>\n ) : validationResult?.isValid && query.trim() === lastValidatedQuery.trim() ? (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <span>Validated</span>\n </>\n ) : (\n <>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <span>Validate</span>\n </>\n )}\n </button>\n </div>\n </div>\n )}\n\n {/* Sample Queries - only show for create mode */}\n {!isEditMode && (\n <div>\n <label className=\"block text-sm text-dc-text-muted mb-2\">Sample Queries (click to use)</label>\n <div className=\"flex flex-wrap gap-2 mb-2\">\n {SAMPLE_QUERIES.map((sample, index) => (\n <button\n key={index}\n type=\"button\"\n onClick={() => handleSampleQuery(sample.query)}\n className=\"px-2 py-1 text-xs text-dc-text-secondary bg-dc-surface-secondary border border-dc-border rounded-sm cursor-pointer transition-all duration-200 ease-in-out hover:bg-dc-surface-hover hover:border-dc-border m-0.5\"\n >\n {sample.name}\n </button>\n ))}\n </div>\n </div>\n )}\n </form>\n )}\n </Modal>\n )\n}","/**\n * Utility functions for PortletBuilder component\n */\n\nimport type {\n MetricItem,\n BreakdownItem,\n FieldOption,\n FieldType,\n RecentFieldsStorage\n} from './types'\nimport type { MetaResponse, MetaField } from '../../shared/types'\nimport type { CubeQuery, Filter } from '../../types'\n\n// ============================================================================\n// ID Generation\n// ============================================================================\n\n/**\n * Generate a unique ID for items\n */\nexport function generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * Generate letter label for metrics (A, B, C, ..., AA, AB, ...)\n */\nexport function generateMetricLabel(index: number): string {\n let label = ''\n let n = index\n do {\n label = String.fromCharCode(65 + (n % 26)) + label\n n = Math.floor(n / 26) - 1\n } while (n >= 0)\n return label\n}\n\n// ============================================================================\n// Query Building\n// ============================================================================\n\n/**\n * Convert metrics and breakdowns to CubeQuery format\n */\nexport function buildCubeQuery(\n metrics: MetricItem[],\n breakdowns: BreakdownItem[],\n filters: Filter[]\n): CubeQuery {\n const query: CubeQuery = {\n measures: metrics.map((m) => m.field),\n dimensions: breakdowns.filter((b) => !b.isTimeDimension).map((b) => b.field),\n timeDimensions: breakdowns\n .filter((b) => b.isTimeDimension)\n .map((b) => ({\n dimension: b.field,\n granularity: b.granularity || 'day'\n })),\n filters: filters.length > 0 ? filters : undefined\n }\n\n // Clean up empty arrays\n if (query.measures?.length === 0) delete query.measures\n if (query.dimensions?.length === 0) delete query.dimensions\n if (query.timeDimensions?.length === 0) delete query.timeDimensions\n\n return query\n}\n\n/**\n * Check if a query has any content\n */\nexport function hasQueryContent(\n metrics: MetricItem[],\n breakdowns: BreakdownItem[],\n filters: Filter[]\n): boolean {\n return metrics.length > 0 || breakdowns.length > 0 || filters.length > 0\n}\n\n// ============================================================================\n// Field Utilities\n// ============================================================================\n\n/**\n * Get cube name from a field name (e.g., \"Employees.count\" -> \"Employees\")\n */\nexport function getCubeNameFromField(fieldName: string): string {\n return fieldName.split('.')[0]\n}\n\n/**\n * Get field short name from full name (e.g., \"Employees.count\" -> \"count\")\n */\nexport function getFieldShortName(fieldName: string): string {\n const parts = fieldName.split('.')\n return parts.length > 1 ? parts.slice(1).join('.') : fieldName\n}\n\n/**\n * Find field metadata from schema\n */\nexport function findFieldInSchema(\n fieldName: string,\n schema: MetaResponse | null\n): { field: MetaField; cubeName: string; fieldType: FieldType } | null {\n if (!schema) return null\n\n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find((m) => m.name === fieldName)\n if (measure) {\n return { field: measure, cubeName: cube.name, fieldType: 'measure' }\n }\n\n // Check dimensions\n const dimension = cube.dimensions.find((d) => d.name === fieldName)\n if (dimension) {\n return {\n field: dimension,\n cubeName: cube.name,\n fieldType: dimension.type === 'time' ? 'timeDimension' : 'dimension'\n }\n }\n }\n\n return null\n}\n\n/**\n * Get display title for a field\n */\nexport function getFieldTitle(fieldName: string, schema: MetaResponse | null): string {\n const found = findFieldInSchema(fieldName, schema)\n if (found) {\n return found.field.title || found.field.shortTitle || fieldName\n }\n return fieldName\n}\n\n/**\n * Determine field type from metadata\n */\nexport function getFieldType(field: MetaField): FieldType {\n if (field.type === 'time') return 'timeDimension'\n // Measures typically have aggregation types\n if (['count', 'countDistinct', 'sum', 'avg', 'min', 'max', 'runningTotal', 'countDistinctApprox'].includes(field.type)) {\n return 'measure'\n }\n return 'dimension'\n}\n\n// ============================================================================\n// Field Search & Filtering\n// ============================================================================\n\n/**\n * Convert schema to flat list of field options\n */\nexport function schemaToFieldOptions(\n schema: MetaResponse | null,\n mode: 'metrics' | 'breakdown' | 'filter'\n): FieldOption[] {\n if (!schema) return []\n\n const options: FieldOption[] = []\n\n for (const cube of schema.cubes) {\n if (mode === 'metrics') {\n // Add measures only\n for (const measure of cube.measures) {\n options.push({\n name: measure.name,\n title: measure.title || measure.shortTitle || measure.name,\n shortTitle: measure.shortTitle || measure.title || measure.name,\n type: measure.type,\n description: measure.description,\n cubeName: cube.name,\n fieldType: 'measure'\n })\n }\n } else if (mode === 'breakdown') {\n // Add dimensions only (both regular and time)\n for (const dimension of cube.dimensions) {\n const isTime = dimension.type === 'time'\n options.push({\n name: dimension.name,\n title: dimension.title || dimension.shortTitle || dimension.name,\n shortTitle: dimension.shortTitle || dimension.title || dimension.name,\n type: dimension.type,\n description: dimension.description,\n cubeName: cube.name,\n fieldType: isTime ? 'timeDimension' : 'dimension'\n })\n }\n } else {\n // 'filter' mode - add BOTH measures AND dimensions\n // Add measures first\n for (const measure of cube.measures) {\n options.push({\n name: measure.name,\n title: measure.title || measure.shortTitle || measure.name,\n shortTitle: measure.shortTitle || measure.title || measure.name,\n type: measure.type,\n description: measure.description,\n cubeName: cube.name,\n fieldType: 'measure'\n })\n }\n // Add dimensions (both regular and time)\n for (const dimension of cube.dimensions) {\n const isTime = dimension.type === 'time'\n options.push({\n name: dimension.name,\n title: dimension.title || dimension.shortTitle || dimension.name,\n shortTitle: dimension.shortTitle || dimension.title || dimension.name,\n type: dimension.type,\n description: dimension.description,\n cubeName: cube.name,\n fieldType: isTime ? 'timeDimension' : 'dimension'\n })\n }\n }\n }\n\n return options\n}\n\n/**\n * Filter field options by search term\n */\nexport function filterFieldOptions(\n options: FieldOption[],\n searchTerm: string,\n selectedCube?: string | null\n): FieldOption[] {\n let filtered = options\n\n // Filter by cube if selected\n if (selectedCube && selectedCube !== 'all') {\n filtered = filtered.filter((opt) => opt.cubeName === selectedCube)\n }\n\n // Filter by search term\n if (searchTerm.trim()) {\n const term = searchTerm.toLowerCase()\n filtered = filtered.filter(\n (opt) =>\n opt.name.toLowerCase().includes(term) ||\n opt.title.toLowerCase().includes(term) ||\n (opt.description?.toLowerCase().includes(term) ?? false)\n )\n }\n\n return filtered\n}\n\n/**\n * Group field options by cube\n */\nexport function groupFieldsByCube(options: FieldOption[]): Map<string, FieldOption[]> {\n const grouped = new Map<string, FieldOption[]>()\n\n for (const option of options) {\n const existing = grouped.get(option.cubeName) || []\n existing.push(option)\n grouped.set(option.cubeName, existing)\n }\n\n return grouped\n}\n\n// ============================================================================\n// Recent Fields Storage\n// ============================================================================\n\nconst RECENT_FIELDS_KEY = 'drizzle-cube-recent-fields'\nconst MAX_RECENT_FIELDS = 10\n\n/**\n * Get recent fields from localStorage\n */\nexport function getRecentFields(): RecentFieldsStorage {\n try {\n const stored = localStorage.getItem(RECENT_FIELDS_KEY)\n if (stored) {\n return JSON.parse(stored)\n }\n } catch {\n // Ignore errors\n }\n return { metrics: [], breakdowns: [] }\n}\n\n/**\n * Add a field to recent fields\n */\nexport function addRecentField(fieldName: string, mode: 'metrics' | 'breakdowns'): void {\n try {\n const recent = getRecentFields()\n const list = recent[mode]\n\n // Remove if already exists\n const filtered = list.filter((f) => f !== fieldName)\n\n // Add to front\n filtered.unshift(fieldName)\n\n // Limit size\n recent[mode] = filtered.slice(0, MAX_RECENT_FIELDS)\n\n localStorage.setItem(RECENT_FIELDS_KEY, JSON.stringify(recent))\n } catch {\n // Ignore errors\n }\n}\n\n/**\n * Get recent field options from schema\n */\nexport function getRecentFieldOptions(\n schema: MetaResponse | null,\n mode: 'metrics' | 'breakdown' | 'filter',\n recentFieldNames: string[]\n): FieldOption[] {\n if (!schema || recentFieldNames.length === 0) return []\n\n const allOptions = schemaToFieldOptions(schema, mode)\n const recentOptions: FieldOption[] = []\n\n for (const fieldName of recentFieldNames) {\n const option = allOptions.find((opt) => opt.name === fieldName)\n if (option) {\n recentOptions.push(option)\n }\n }\n\n return recentOptions\n}\n\n// ============================================================================\n// Cube List Utilities\n// ============================================================================\n\n/**\n * Get list of cube names from schema\n */\nexport function getCubeNames(schema: MetaResponse | null): string[] {\n if (!schema) return []\n return schema.cubes.map((cube) => cube.name)\n}\n\n/**\n * Get cube title by name\n */\nexport function getCubeTitle(cubeName: string, schema: MetaResponse | null): string {\n if (!schema) return cubeName\n const cube = schema.cubes.find((c) => c.name === cubeName)\n return cube?.title || cubeName\n}\n\n// ============================================================================\n// State Persistence\n// ============================================================================\n\nconst STORAGE_KEY = 'drizzle-cube-portlet-builder-state'\n\n/**\n * Save state to localStorage\n */\nexport function saveStateToStorage(state: {\n metrics: MetricItem[]\n breakdowns: BreakdownItem[]\n filters: Filter[]\n chartType: string\n chartConfig: object\n displayConfig: object\n activeView: string\n}): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(state))\n } catch {\n // Ignore errors\n }\n}\n\n/**\n * Load state from localStorage\n */\nexport function loadStateFromStorage(): {\n metrics: MetricItem[]\n breakdowns: BreakdownItem[]\n filters: Filter[]\n chartType: string\n chartConfig: object\n displayConfig: object\n activeView: string\n} | null {\n try {\n const stored = localStorage.getItem(STORAGE_KEY)\n if (stored) {\n return JSON.parse(stored)\n }\n } catch {\n // Ignore errors\n }\n return null\n}\n\n/**\n * Clear state from localStorage\n */\nexport function clearStateFromStorage(): void {\n try {\n localStorage.removeItem(STORAGE_KEY)\n } catch {\n // Ignore errors\n }\n}\n","/**\n * FieldSearchItem Component\n *\n * A single field item in the search results list.\n * Shows field icon, title, type badge, and selection state.\n */\n\nimport { memo } from 'react'\nimport { getIcon, getMeasureTypeIcon, getFieldTypeIcon } from '../../icons'\nimport type { FieldSearchItemProps } from './types'\n\nconst CheckIcon = getIcon('check')\n\nfunction FieldSearchItem({\n field,\n isSelected,\n isFocused,\n onClick,\n onMouseEnter,\n ...props\n}: FieldSearchItemProps & { 'data-field-index'?: number }) {\n // Get appropriate icon based on field type\n const getFieldIcon = () => {\n if (field.fieldType === 'measure') {\n const Icon = getMeasureTypeIcon(field.type)\n return Icon ? <Icon className=\"w-4 h-4\" /> : null\n } else if (field.fieldType === 'timeDimension') {\n const Icon = getFieldTypeIcon('time')\n return Icon ? <Icon className=\"w-4 h-4\" /> : null\n } else {\n const Icon = getFieldTypeIcon('dimension')\n return Icon ? <Icon className=\"w-4 h-4\" /> : null\n }\n }\n\n // Get badge color based on field type\n const getBadgeStyle = () => {\n if (field.fieldType === 'measure') {\n return 'bg-dc-measure text-dc-measure-text'\n } else if (field.fieldType === 'timeDimension') {\n return 'bg-dc-time-dimension text-dc-time-dimension-text'\n } else {\n return 'bg-dc-dimension text-dc-dimension-text'\n }\n }\n\n // Get short type label\n const getTypeLabel = () => {\n if (field.fieldType === 'measure') {\n return field.type.charAt(0).toUpperCase() + field.type.slice(1)\n } else if (field.fieldType === 'timeDimension') {\n return 'Time'\n } else {\n return 'Dim'\n }\n }\n\n return (\n <button\n onClick={onClick}\n onMouseEnter={onMouseEnter}\n className={`w-full text-left px-3 py-2 rounded-lg flex items-center gap-3 transition-colors group ${\n isFocused\n ? 'bg-dc-primary/10 ring-1 ring-dc-primary'\n : isSelected\n ? 'bg-dc-success/10'\n : 'hover:bg-dc-surface-hover'\n }`}\n {...props}\n >\n {/* Icon */}\n <span\n className={`shrink-0 w-8 h-8 flex items-center justify-center rounded-md ${\n field.fieldType === 'measure'\n ? 'bg-dc-measure text-dc-measure-text'\n : field.fieldType === 'timeDimension'\n ? 'bg-dc-time-dimension text-dc-time-dimension-text'\n : 'bg-dc-dimension text-dc-dimension-text'\n }`}\n >\n {getFieldIcon()}\n </span>\n\n {/* Title and name */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-dc-text truncate\">\n {field.title}\n </div>\n <div className=\"text-xs text-dc-text-muted truncate\">{field.name}</div>\n </div>\n\n {/* Type badge */}\n <span\n className={`shrink-0 px-2 py-0.5 rounded text-xs font-medium ${getBadgeStyle()}`}\n >\n {getTypeLabel()}\n </span>\n\n {/* Selection indicator */}\n {isSelected && (\n <span className=\"shrink-0 w-5 h-5 flex items-center justify-center rounded-full bg-dc-success text-white\">\n <CheckIcon className=\"w-3 h-3\" />\n </span>\n )}\n </button>\n )\n}\n\nexport default memo(FieldSearchItem)\n","/**\n * FieldDetailPanel Component\n *\n * Shows detailed information about the currently focused/hovered field.\n * Displays: icon, title, description, type, cube name, and technical name.\n */\n\nimport { memo } from 'react'\nimport { getMeasureTypeIcon, getFieldTypeIcon } from '../../icons'\nimport type { FieldDetailPanelProps } from './types'\n\nfunction FieldDetailPanel({ field }: FieldDetailPanelProps) {\n if (!field) {\n return (\n <div className=\"p-6 text-center text-dc-text-muted\">\n <p className=\"text-sm\">Hover over a field to see details</p>\n </div>\n )\n }\n\n // Get appropriate icon based on field type\n const getFieldIcon = () => {\n if (field.fieldType === 'measure') {\n const Icon = getMeasureTypeIcon(field.type)\n return Icon ? <Icon className=\"w-6 h-6\" /> : null\n } else if (field.fieldType === 'timeDimension') {\n const Icon = getFieldTypeIcon('time')\n return Icon ? <Icon className=\"w-6 h-6\" /> : null\n } else {\n const Icon = getFieldTypeIcon('dimension')\n return Icon ? <Icon className=\"w-6 h-6\" /> : null\n }\n }\n\n // Get icon background color - use field type specific colors for consistency\n const getIconBgStyle = () => {\n if (field.fieldType === 'measure') {\n return 'bg-dc-measure text-dc-measure-text'\n } else if (field.fieldType === 'timeDimension') {\n return 'bg-dc-time-dimension text-dc-time-dimension-text'\n } else {\n return 'bg-dc-dimension text-dc-dimension-text'\n }\n }\n\n // Get type display name\n const getTypeDisplay = () => {\n if (field.fieldType === 'measure') {\n const typeMap: Record<string, string> = {\n count: 'Count',\n countDistinct: 'Count Distinct',\n countDistinctApprox: 'Count Distinct (Approx)',\n sum: 'Sum',\n avg: 'Average',\n min: 'Minimum',\n max: 'Maximum',\n runningTotal: 'Running Total',\n number: 'Number'\n }\n return typeMap[field.type] || field.type\n } else if (field.fieldType === 'timeDimension') {\n return 'Time Dimension'\n } else {\n const typeMap: Record<string, string> = {\n string: 'Text',\n number: 'Number',\n boolean: 'Boolean',\n geo: 'Geographic'\n }\n return typeMap[field.type] || 'Dimension'\n }\n }\n\n return (\n <div className=\"p-4\">\n {/* Header with icon and title */}\n <div className=\"flex items-start gap-3 mb-4\">\n <span\n className={`shrink-0 w-12 h-12 flex items-center justify-center rounded-lg ${getIconBgStyle()}`}\n >\n {getFieldIcon()}\n </span>\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-base font-semibold text-dc-text leading-tight\">\n {field.title}\n </h3>\n <p className=\"text-xs text-dc-text-muted mt-0.5 truncate\">\n {field.name}\n </p>\n </div>\n </div>\n\n {/* Description */}\n {field.description && (\n <div className=\"mb-4\">\n <p className=\"text-sm text-dc-text-secondary leading-relaxed\">\n {field.description}\n </p>\n </div>\n )}\n\n {/* Metadata */}\n <div className=\"space-y-3 pt-4 border-t border-dc-border\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-dc-text-muted\">Type</span>\n <span className=\"text-sm text-dc-text font-medium\">{getTypeDisplay()}</span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-dc-text-muted\">Cube</span>\n <span className=\"text-sm text-dc-text font-medium\">{field.cubeName}</span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-dc-text-muted\">Category</span>\n <span\n className={`text-xs px-2 py-0.5 rounded font-medium ${\n field.fieldType === 'measure'\n ? 'bg-dc-measure text-dc-measure-text'\n : field.fieldType === 'timeDimension'\n ? 'bg-dc-time-dimension text-dc-time-dimension-text'\n : 'bg-dc-dimension text-dc-dimension-text'\n }`}\n >\n {field.fieldType === 'measure'\n ? 'Measure'\n : field.fieldType === 'timeDimension'\n ? 'Time Dimension'\n : 'Dimension'}\n </span>\n </div>\n </div>\n\n {/* Usage hint */}\n <div className=\"mt-6 p-3 bg-dc-surface rounded-lg\">\n <p className=\"text-xs text-dc-text-muted\">\n Press <kbd className=\"px-1 py-0.5 bg-dc-surface-tertiary rounded text-xs\">Enter</kbd> or click to add this field to your query.\n </p>\n </div>\n </div>\n )\n}\n\nexport default memo(FieldDetailPanel)\n","/**\n * FieldSearchModal Component\n *\n * A full-screen search modal for selecting cube fields (measures/dimensions).\n * Features:\n * - Real-time search filtering\n * - Cube-based category filtering\n * - Three-column layout: Categories | Results | Details\n * - Keyboard navigation support\n * - Recent fields tracking\n */\n\nimport { useState, useMemo, useCallback, useEffect, useRef, KeyboardEvent } from 'react'\nimport { getIcon } from '../../icons'\nimport type { FieldSearchModalProps, FieldOption } from './types'\nimport type { MetaField } from '../../shared/types'\nimport {\n schemaToFieldOptions,\n filterFieldOptions,\n groupFieldsByCube,\n getCubeNames,\n getCubeTitle,\n getRecentFields,\n addRecentField,\n getRecentFieldOptions\n} from './utils'\nimport FieldSearchItem from './FieldSearchItem'\nimport FieldDetailPanel from './FieldDetailPanel'\n\nconst SearchIcon = getIcon('search')\nconst CloseIcon = getIcon('close')\n\nexport default function FieldSearchModal({\n isOpen,\n onClose,\n onSelect,\n mode,\n schema,\n selectedFields,\n recentFields: externalRecentFields\n}: FieldSearchModalProps) {\n // State\n const [searchTerm, setSearchTerm] = useState('')\n const [selectedCube, setSelectedCube] = useState<string | null>(null)\n const [focusedField, setFocusedField] = useState<FieldOption | null>(null)\n const [focusedIndex, setFocusedIndex] = useState(-1)\n const [lastSelectedIndex, setLastSelectedIndex] = useState<number | null>(null)\n\n // Refs\n const searchInputRef = useRef<HTMLInputElement>(null)\n const resultsContainerRef = useRef<HTMLDivElement>(null)\n\n // Get recent fields from localStorage or props\n const recentFieldNames = useMemo(() => {\n if (externalRecentFields) return externalRecentFields\n const stored = getRecentFields()\n return mode === 'metrics' ? stored.metrics : stored.breakdowns\n }, [externalRecentFields, mode])\n\n // Map mode to field options mode\n const fieldOptionsMode = mode\n\n // Get all field options for current mode\n const allFieldOptions = useMemo(() => {\n return schemaToFieldOptions(schema, fieldOptionsMode)\n }, [schema, fieldOptionsMode])\n\n // Get cube names for category filter\n const cubeNames = useMemo(() => {\n return getCubeNames(schema)\n }, [schema])\n\n // Filter fields by search and cube\n const filteredFields = useMemo(() => {\n return filterFieldOptions(allFieldOptions, searchTerm, selectedCube)\n }, [allFieldOptions, searchTerm, selectedCube])\n\n // Group filtered fields by cube\n const groupedFields = useMemo(() => {\n return groupFieldsByCube(filteredFields)\n }, [filteredFields])\n\n // Get recent field options (only when not searching)\n const recentOptions = useMemo(() => {\n if (searchTerm.trim()) return []\n return getRecentFieldOptions(schema, fieldOptionsMode, recentFieldNames).filter(\n (f) => !selectedCube || f.cubeName === selectedCube\n )\n }, [schema, fieldOptionsMode, recentFieldNames, searchTerm, selectedCube])\n\n // Flat list of visible fields for keyboard navigation\n const flatFieldsList = useMemo(() => {\n const list: FieldOption[] = [...recentOptions]\n groupedFields.forEach((fields) => {\n list.push(...fields)\n })\n return list\n }, [recentOptions, groupedFields])\n\n // Focus search input when modal opens\n useEffect(() => {\n if (isOpen && searchInputRef.current) {\n searchInputRef.current.focus()\n }\n }, [isOpen])\n\n // Reset state when modal closes\n useEffect(() => {\n if (!isOpen) {\n setSearchTerm('')\n setSelectedCube(null)\n setFocusedField(null)\n setFocusedIndex(-1)\n setLastSelectedIndex(null)\n }\n }, [isOpen])\n\n // Handle single field selection\n const selectSingleField = useCallback(\n (field: FieldOption, keepOpen: boolean = false) => {\n // Add to recent fields\n addRecentField(field.name, mode === 'metrics' ? 'metrics' : 'breakdowns')\n\n // Create MetaField object for callback\n const metaField: MetaField = {\n name: field.name,\n title: field.title,\n shortTitle: field.shortTitle,\n type: field.type,\n description: field.description\n }\n\n onSelect(metaField, field.fieldType, field.cubeName, keepOpen)\n },\n [mode, onSelect]\n )\n\n // Handle field selection with shift-click support for range selection\n const handleSelectField = useCallback(\n (field: FieldOption, fieldIndex: number, shiftKey: boolean = false) => {\n // Shift-click for range selection - keep modal open\n if (shiftKey && lastSelectedIndex !== null && lastSelectedIndex !== fieldIndex) {\n const startIndex = Math.min(lastSelectedIndex, fieldIndex)\n const endIndex = Math.max(lastSelectedIndex, fieldIndex)\n\n // Select all fields in the range, keep modal open for all\n for (let i = startIndex; i <= endIndex; i++) {\n const rangeField = flatFieldsList[i]\n if (rangeField && !selectedFields.includes(rangeField.name)) {\n selectSingleField(rangeField, true) // Keep modal open\n }\n }\n } else if (shiftKey) {\n // Shift-click on single item - select but keep modal open\n selectSingleField(field, true)\n } else {\n // Normal single selection - close modal after\n selectSingleField(field, false)\n }\n\n // Update last selected index for next shift-click\n setLastSelectedIndex(fieldIndex)\n },\n [flatFieldsList, lastSelectedIndex, selectSingleField, selectedFields]\n )\n\n // Keyboard navigation\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (flatFieldsList.length === 0) return\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n setFocusedIndex((prev) => {\n const next = Math.min(prev + 1, flatFieldsList.length - 1)\n setFocusedField(flatFieldsList[next])\n return next\n })\n break\n\n case 'ArrowUp':\n e.preventDefault()\n setFocusedIndex((prev) => {\n const next = Math.max(prev - 1, 0)\n setFocusedField(flatFieldsList[next])\n return next\n })\n break\n\n case 'Enter':\n e.preventDefault()\n if (focusedIndex >= 0 && flatFieldsList[focusedIndex]) {\n handleSelectField(flatFieldsList[focusedIndex], focusedIndex, e.shiftKey)\n }\n break\n\n case 'Escape':\n e.preventDefault()\n onClose()\n break\n }\n },\n [flatFieldsList, focusedIndex, handleSelectField, onClose]\n )\n\n // Scroll focused item into view\n useEffect(() => {\n if (focusedIndex >= 0 && resultsContainerRef.current) {\n const focusedElement = resultsContainerRef.current.querySelector(\n `[data-field-index=\"${focusedIndex}\"]`\n )\n if (focusedElement) {\n focusedElement.scrollIntoView({ block: 'nearest', behavior: 'smooth' })\n }\n }\n }, [focusedIndex])\n\n if (!isOpen) return null\n\n const searchPlaceholder =\n mode === 'metrics' ? 'Search metrics...' : mode === 'filter' ? 'Search fields to filter...' : 'Search dimensions...'\n\n const modalTitle = mode === 'metrics' ? 'Select a Metric' : mode === 'filter' ? 'Select a Field to Filter' : 'Select a Dimension'\n const focusedFieldId = focusedIndex >= 0 && flatFieldsList[focusedIndex]\n ? `field-option-${flatFieldsList[focusedIndex].name.replace(/\\./g, '-')}`\n : undefined\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n style={{ backgroundColor: 'var(--dc-overlay)' }}\n onClick={onClose}\n role=\"presentation\"\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={modalTitle}\n className=\"bg-dc-surface shadow-xl w-full h-full md:rounded-lg md:w-[900px] md:max-w-[900px] md:h-[80vh] md:max-h-[700px] flex flex-col overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={handleKeyDown}\n >\n {/* Header with Search */}\n <div className=\"shrink-0 border-b border-dc-border\">\n <div className=\"flex items-center px-4 py-3 gap-3\">\n <SearchIcon className=\"w-5 h-5 text-dc-text-muted\" aria-hidden={true} />\n <input\n ref={searchInputRef}\n type=\"text\"\n value={searchTerm}\n onChange={(e) => {\n setSearchTerm(e.target.value)\n setFocusedIndex(-1)\n }}\n placeholder={searchPlaceholder}\n className=\"flex-1 bg-transparent border-none outline-none text-dc-text placeholder-dc-text-muted text-lg\"\n aria-label={searchPlaceholder}\n aria-controls=\"field-search-results\"\n aria-activedescendant={focusedFieldId}\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-autocomplete=\"list\"\n />\n <button\n onClick={onClose}\n className=\"p-1 text-dc-text-secondary hover:text-dc-text rounded\"\n aria-label=\"Close dialog\"\n >\n <CloseIcon className=\"w-5 h-5\" aria-hidden={true} />\n </button>\n </div>\n {/* Mobile cube filter - shown only on mobile */}\n {cubeNames.length > 1 && (\n <div className=\"md:hidden px-4 pb-3\">\n <select\n value={selectedCube || ''}\n onChange={(e) => setSelectedCube(e.target.value || null)}\n className=\"w-full px-3 py-2 bg-dc-surface border border-dc-border rounded-lg text-sm text-dc-text focus:outline-none focus:ring-1 focus:ring-dc-primary\"\n aria-label=\"Filter by cube\"\n >\n <option value=\"\">All Cubes</option>\n {cubeNames.map((cubeName) => (\n <option key={cubeName} value={cubeName}>\n {getCubeTitle(cubeName, schema)}\n </option>\n ))}\n </select>\n </div>\n )}\n </div>\n\n {/* Three Column Layout - Single column on mobile */}\n <div className=\"flex-1 flex overflow-hidden\">\n {/* Left Column - Categories (hidden on mobile) */}\n <nav\n className=\"hidden md:block w-48 shrink-0 border-r border-dc-border overflow-y-auto bg-dc-surface-secondary\"\n aria-label=\"Filter by cube\"\n >\n <div className=\"p-2\" role=\"group\" aria-label=\"Cube categories\">\n <button\n onClick={() => setSelectedCube(null)}\n className={`w-full text-left px-3 py-2 rounded-md text-sm transition-colors ${\n selectedCube === null\n ? 'bg-dc-primary/10 text-dc-primary font-medium'\n : 'text-dc-text hover:bg-dc-surface-hover'\n }`}\n aria-pressed={selectedCube === null}\n >\n All\n </button>\n {cubeNames.map((cubeName) => (\n <button\n key={cubeName}\n onClick={() => setSelectedCube(cubeName)}\n className={`w-full text-left px-3 py-2 rounded-md text-sm transition-colors truncate ${\n selectedCube === cubeName\n ? 'bg-dc-primary/10 text-dc-primary font-medium'\n : 'text-dc-text hover:bg-dc-surface-hover'\n }`}\n title={getCubeTitle(cubeName, schema)}\n aria-pressed={selectedCube === cubeName}\n >\n {getCubeTitle(cubeName, schema)}\n </button>\n ))}\n </div>\n </nav>\n\n {/* Middle Column - Results */}\n <div\n id=\"field-search-results\"\n ref={resultsContainerRef}\n className=\"flex-1 overflow-y-auto p-4\"\n role=\"listbox\"\n aria-label=\"Available fields\"\n >\n {filteredFields.length === 0 && recentOptions.length === 0 ? (\n <div className=\"text-center py-12 text-dc-text-muted\">\n <p className=\"text-lg mb-2\">No fields found</p>\n <p className=\"text-sm\">\n {searchTerm\n ? `No ${mode === 'metrics' ? 'metrics' : 'dimensions'} match \"${searchTerm}\"`\n : `No ${mode === 'metrics' ? 'metrics' : 'dimensions'} available`}\n </p>\n </div>\n ) : (\n <div className=\"space-y-6\">\n {/* Recent Fields */}\n {recentOptions.length > 0 && (\n <div>\n <h3 className=\"text-xs font-semibold text-dc-text-muted uppercase tracking-wider mb-2\">\n Recents\n </h3>\n <div className=\"space-y-1\">\n {recentOptions.map((field, idx) => (\n <FieldSearchItem\n key={`recent-${field.name}`}\n field={field}\n isSelected={selectedFields.includes(field.name)}\n isFocused={focusedIndex === idx}\n onClick={(e) => handleSelectField(field, idx, e.shiftKey)}\n onMouseEnter={() => {\n setFocusedField(field)\n setFocusedIndex(idx)\n }}\n data-field-index={idx}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Grouped by Cube */}\n {Array.from(groupedFields.entries()).map(([cubeName, fields]) => (\n <div key={cubeName}>\n <h3 className=\"text-xs font-semibold text-dc-text-muted uppercase tracking-wider mb-2\">\n {getCubeTitle(cubeName, schema)}\n </h3>\n <div className=\"space-y-1\">\n {fields.map((field) => {\n const fieldIndex =\n recentOptions.length +\n Array.from(groupedFields.entries())\n .slice(\n 0,\n Array.from(groupedFields.keys()).indexOf(cubeName)\n )\n .reduce((sum, [, f]) => sum + f.length, 0) +\n fields.indexOf(field)\n\n return (\n <FieldSearchItem\n key={field.name}\n field={field}\n isSelected={selectedFields.includes(field.name)}\n isFocused={focusedIndex === fieldIndex}\n onClick={(e) => handleSelectField(field, fieldIndex, e.shiftKey)}\n onMouseEnter={() => {\n setFocusedField(field)\n setFocusedIndex(fieldIndex)\n }}\n data-field-index={fieldIndex}\n />\n )\n })}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Right Column - Field Details (hidden on mobile) */}\n <div className=\"hidden md:block w-72 shrink-0 border-l border-dc-border bg-dc-surface-secondary overflow-y-auto\">\n <FieldDetailPanel field={focusedField} />\n </div>\n </div>\n\n {/* Footer */}\n <div className=\"shrink-0 border-t border-dc-border px-4 py-3 flex items-center justify-between text-sm text-dc-text-muted\">\n <div>\n <span className=\"text-dc-text-secondary\">{filteredFields.length}</span>{' '}\n {mode === 'metrics' ? 'metrics' : mode === 'filter' ? 'fields' : 'dimensions'} available\n </div>\n {/* Keyboard shortcuts - hidden on mobile */}\n <div className=\"hidden md:flex items-center gap-4\">\n <span>\n <kbd className=\"px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs\">↑↓</kbd> Navigate\n </span>\n <span>\n <kbd className=\"px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs\">Enter</kbd> Select\n </span>\n <span>\n <kbd className=\"px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs\">Shift</kbd>+Click Multi-select\n </span>\n <span>\n <kbd className=\"px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs\">Esc</kbd> Close\n </span>\n </div>\n </div>\n </div>\n </div>\n )\n}\n","/**\n * Shared utility functions used across QueryBuilder and AnalysisBuilder\n */\n\nimport type { CubeQuery, Filter, SimpleFilter, GroupFilter } from '../types'\nimport type { MetaField, MetaResponse } from './types'\nimport { FILTER_OPERATORS } from './types'\n\n// ============================================================================\n// Filter type guards\n// ============================================================================\n\n/**\n * Check if a filter is a simple filter\n */\nexport function isSimpleFilter(filter: Filter): filter is SimpleFilter {\n return 'member' in filter && 'operator' in filter && 'values' in filter\n}\n\n/**\n * Check if a filter is a group filter\n */\nexport function isGroupFilter(filter: Filter): filter is GroupFilter {\n return 'type' in filter && 'filters' in filter\n}\n\n/**\n * Check if a filter is an AND filter\n */\nexport function isAndFilter(filter: Filter): filter is GroupFilter {\n return isGroupFilter(filter) && filter.type === 'and'\n}\n\n/**\n * Check if a filter is an OR filter\n */\nexport function isOrFilter(filter: Filter): filter is GroupFilter {\n return isGroupFilter(filter) && filter.type === 'or'\n}\n\n// ============================================================================\n// Filter manipulation functions\n// ============================================================================\n\n/**\n * Flatten all simple filters from a hierarchical filter structure\n */\nexport function flattenFilters(filters: Filter[]): SimpleFilter[] {\n const simple: SimpleFilter[] = []\n\n const flatten = (filter: Filter) => {\n if (isSimpleFilter(filter)) {\n simple.push(filter)\n } else if (isGroupFilter(filter)) {\n filter.filters.forEach(flatten)\n }\n }\n\n filters.forEach(flatten)\n return simple\n}\n\n/**\n * Count total filters in hierarchical structure\n */\nexport function countFilters(filters: Filter[]): number {\n let count = 0\n\n const countFilter = (filter: Filter) => {\n if (isSimpleFilter(filter)) {\n count++\n } else if (isGroupFilter(filter)) {\n filter.filters.forEach(countFilter)\n }\n }\n\n filters.forEach(countFilter)\n return count\n}\n\n/**\n * Create a new simple filter\n */\nexport function createSimpleFilter(member: string, operator: string = 'equals', values: any[] = []): SimpleFilter {\n return {\n member,\n operator: operator as any,\n values\n }\n}\n\n/**\n * Create a new AND filter group\n */\nexport function createAndFilter(filters: Filter[] = []): GroupFilter {\n return {\n type: 'and',\n filters\n }\n}\n\n/**\n * Create a new OR filter group\n */\nexport function createOrFilter(filters: Filter[] = []): GroupFilter {\n return {\n type: 'or',\n filters\n }\n}\n\n// ============================================================================\n// Filter transformation functions\n// ============================================================================\n\n/**\n * Transform filters from new GroupFilter format to legacy server format\n * Server expects { and: [...] } and { or: [...] } instead of { type: 'and', filters: [...] }\n */\nexport function transformFiltersForServer(filters: Filter[]): any[] {\n const transformFilter = (filter: Filter): any => {\n if (isSimpleFilter(filter)) {\n return filter\n } else if (isGroupFilter(filter)) {\n const transformedSubFilters = filter.filters.map(transformFilter)\n\n if (filter.type === 'and') {\n return { and: transformedSubFilters }\n } else {\n return { or: transformedSubFilters }\n }\n }\n return filter\n }\n\n return filters.map(transformFilter)\n}\n\n/**\n * Transform filters from server/API format to UI format\n * Converts {and: [...]} and {or: [...]} to {type: 'and', filters: [...]} format\n */\nexport function transformFiltersFromServer(filters: any[]): Filter[] {\n return filters.map(filter => {\n if (!filter || typeof filter !== 'object') {\n return filter\n }\n\n // Handle legacy {and: [...]} format\n if ('and' in filter && Array.isArray(filter.and)) {\n return {\n type: 'and',\n filters: transformFiltersFromServer(filter.and)\n } as GroupFilter\n }\n\n // Handle legacy {or: [...]} format\n if ('or' in filter && Array.isArray(filter.or)) {\n return {\n type: 'or',\n filters: transformFiltersFromServer(filter.or)\n } as GroupFilter\n }\n\n // Handle new format {type: 'and', filters: [...]} - process recursively\n if ('type' in filter && 'filters' in filter && Array.isArray(filter.filters)) {\n return {\n type: filter.type,\n filters: transformFiltersFromServer(filter.filters)\n } as GroupFilter\n }\n\n // Simple filter - pass through\n return filter as SimpleFilter\n }).filter(Boolean) // Remove any null/undefined values\n}\n\n// ============================================================================\n// Query utility functions\n// ============================================================================\n\n/**\n * Check if query has any content (measures, dimensions, or timeDimensions)\n */\nexport function hasQueryContent(query: CubeQuery): boolean {\n return Boolean(\n (query.measures && query.measures.length > 0) ||\n (query.dimensions && query.dimensions.length > 0) ||\n (query.timeDimensions && query.timeDimensions.length > 0)\n )\n}\n\n/**\n * Clean query object by removing empty arrays\n */\nexport function cleanQuery(query: CubeQuery): CubeQuery {\n const cleanedQuery: CubeQuery = {}\n\n if (query.measures && query.measures.length > 0) {\n cleanedQuery.measures = query.measures\n }\n\n if (query.dimensions && query.dimensions.length > 0) {\n cleanedQuery.dimensions = query.dimensions\n }\n\n if (query.timeDimensions && query.timeDimensions.length > 0) {\n cleanedQuery.timeDimensions = query.timeDimensions\n }\n\n if (query.filters && query.filters.length > 0) {\n cleanedQuery.filters = query.filters\n }\n\n if (query.order) {\n cleanedQuery.order = query.order\n }\n\n if (query.limit) {\n cleanedQuery.limit = query.limit\n }\n\n if (query.offset) {\n cleanedQuery.offset = query.offset\n }\n\n if (query.segments && query.segments.length > 0) {\n cleanedQuery.segments = query.segments\n }\n\n return cleanedQuery\n}\n\n/**\n * Clean a query and transform filters for server compatibility\n * This version transforms GroupFilter to legacy and/or format\n */\nexport function cleanQueryForServer(query: CubeQuery): CubeQuery {\n const cleanedQuery = cleanQuery(query)\n\n // Apply server transformation to filters\n if (cleanedQuery.filters && cleanedQuery.filters.length > 0) {\n cleanedQuery.filters = transformFiltersForServer(cleanedQuery.filters) as any\n }\n\n return cleanedQuery\n}\n\n/**\n * Transform a Cube.js query from external format to UI internal format\n * This handles format differences between server/API queries and QueryBuilder state\n */\nexport function transformQueryForUI(query: any): CubeQuery {\n if (!query || typeof query !== 'object') {\n return {}\n }\n\n const transformed: CubeQuery = {}\n\n // Copy simple fields if they exist\n if (query.measures) transformed.measures = Array.isArray(query.measures) ? query.measures : []\n if (query.dimensions) transformed.dimensions = Array.isArray(query.dimensions) ? query.dimensions : []\n if (query.timeDimensions) transformed.timeDimensions = Array.isArray(query.timeDimensions) ? query.timeDimensions : []\n if (query.order) transformed.order = query.order\n if (query.limit) transformed.limit = query.limit\n if (query.offset) transformed.offset = query.offset\n if (query.segments) transformed.segments = Array.isArray(query.segments) ? query.segments : []\n\n // Transform filters from server format to UI format\n if (query.filters && Array.isArray(query.filters)) {\n transformed.filters = transformFiltersFromServer(query.filters)\n }\n\n return cleanQuery(transformed)\n}\n\n// ============================================================================\n// Schema utility functions\n// ============================================================================\n\n/**\n * Get cube name from field name (e.g., \"Employees.count\" -> \"Employees\")\n */\nexport function getCubeNameFromField(fieldName: string): string {\n return fieldName.split('.')[0]\n}\n\n/**\n * Get field type from schema\n */\nexport function getFieldType(fieldName: string, schema: MetaResponse): string {\n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find(m => m.name === fieldName)\n if (measure) return measure.type\n\n // Check dimensions\n const dimension = cube.dimensions.find(d => d.name === fieldName)\n if (dimension) return dimension.type\n }\n\n return 'string' // Default fallback\n}\n\n/**\n * Get field title from schema metadata, falling back to field name\n */\nexport function getFieldTitle(fieldName: string, schema: MetaResponse | null): string {\n if (!schema) return fieldName\n\n for (const cube of schema.cubes) {\n // Check measures\n const measure = cube.measures.find(m => m.name === fieldName)\n if (measure) return measure.title || measure.shortTitle || fieldName\n\n // Check dimensions\n const dimension = cube.dimensions.find(d => d.name === fieldName)\n if (dimension) return dimension.title || dimension.shortTitle || fieldName\n }\n\n return fieldName // Fallback to field name if not found\n}\n\n/**\n * Get available operators for a field type\n */\nexport function getAvailableOperators(fieldType: string): Array<{operator: string, label: string}> {\n const operators: Array<{operator: string, label: string}> = []\n\n for (const [operator, meta] of Object.entries(FILTER_OPERATORS)) {\n if (meta.fieldTypes.includes(fieldType)) {\n operators.push({\n operator,\n label: meta.label\n })\n }\n }\n\n return operators\n}\n\n/**\n * Get ALL filterable fields from schema\n */\nexport function getAllFilterableFields(schema: MetaResponse): MetaField[] {\n const allFields: MetaField[] = []\n\n schema.cubes.forEach(cube => {\n allFields.push(...cube.measures)\n allFields.push(...cube.dimensions)\n })\n\n return allFields.sort((a, b) => a.name.localeCompare(b.name))\n}\n\n// ============================================================================\n// Date range utility functions\n// ============================================================================\n\n/**\n * Convert DateRangeType to Cube.js compatible date range format\n */\nexport function convertDateRangeTypeToValue(rangeType: string, number?: number): string {\n const typeMap: Record<string, string> = {\n 'today': 'today',\n 'yesterday': 'yesterday',\n 'this_week': 'this week',\n 'this_month': 'this month',\n 'this_quarter': 'this quarter',\n 'this_year': 'this year',\n 'last_7_days': 'last 7 days',\n 'last_30_days': 'last 30 days',\n 'last_week': 'last week',\n 'last_month': 'last month',\n 'last_quarter': 'last quarter',\n 'last_year': 'last year',\n 'last_12_months': 'last 12 months'\n }\n\n // Handle dynamic ranges with number input\n if (rangeType.startsWith('last_n_') && number !== undefined && number > 0) {\n const unit = rangeType.replace('last_n_', '')\n const unitSingular = unit.slice(0, -1) // Remove 's' for singular form\n return number === 1 ? `last ${unitSingular}` : `last ${number} ${unit}`\n }\n\n return typeMap[rangeType] || rangeType\n}\n\n/**\n * Check if a date range type requires a number input\n */\nexport function requiresNumberInput(rangeType: string): boolean {\n return rangeType.startsWith('last_n_')\n}\n\n/**\n * Format date for Cube.js (YYYY-MM-DD)\n */\nexport function formatDateForCube(date: Date): string {\n return date.toISOString().split('T')[0]\n}\n","/**\n * QueryAnalysisPanel Component\n * Displays query planning analysis for debugging and transparency\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport type { QueryAnalysis } from '../types'\n\ninterface QueryAnalysisPanelProps {\n analysis: QueryAnalysis\n}\n\n/**\n * Format reason string for display\n */\nfunction formatReason(reason: string): string {\n return reason.replace(/_/g, ' ')\n}\n\n/**\n * Get badge color based on reason\n */\nfunction getReasonBadgeClasses(reason: string): string {\n switch (reason) {\n case 'most_dimensions':\n return 'bg-dc-info-bg text-dc-info'\n case 'most_connected':\n return 'bg-dc-accent-bg text-dc-accent'\n case 'alphabetical_fallback':\n return 'bg-dc-warning-bg text-dc-warning'\n case 'single_cube':\n return 'bg-dc-success-bg text-dc-success'\n default:\n return 'bg-dc-muted-bg text-dc-muted'\n }\n}\n\nconst QueryAnalysisPanel: React.FC<QueryAnalysisPanelProps> = ({ analysis }) => {\n const InfoIcon = getIcon('info')\n const ArrowRightIcon = getIcon('chevronRight')\n const WarningIcon = getIcon('warning')\n const TableIcon = getIcon('table')\n const LinkIcon = getIcon('link')\n const SuccessIcon = getIcon('success')\n const ErrorIcon = getIcon('error')\n\n return (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded-lg p-4 space-y-4\">\n {/* Query Summary Section */}\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <InfoIcon className=\"w-4 h-4 mr-2\" />\n Query Summary\n </h4>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-2 text-xs\">\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Type:</span>\n <span className=\"ml-1 font-medium text-dc-text\">\n {formatReason(analysis.querySummary.queryType)}\n </span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Cubes:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.cubeCount}</span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">Joins:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.querySummary.joinCount}</span>\n </div>\n <div className=\"bg-dc-surface p-2 rounded\">\n <span className=\"text-dc-text-muted\">CTEs:</span>\n <span className=\"ml-1 font-medium text-dc-text\">{analysis.querySummary.cteCount}</span>\n </div>\n </div>\n </div>\n\n {/* Primary Cube Section */}\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <TableIcon className=\"w-4 h-4 mr-2\" />\n Primary Cube (FROM table)\n </h4>\n <div className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-2 flex-wrap\">\n <span className=\"font-mono font-medium text-dc-primary\">\n {analysis.primaryCube.selectedCube}\n </span>\n <span className={`text-xs px-2 py-0.5 rounded ${getReasonBadgeClasses(analysis.primaryCube.reason)}`}>\n {formatReason(analysis.primaryCube.reason)}\n </span>\n </div>\n <p className=\"text-dc-text-secondary text-xs\">\n {analysis.primaryCube.explanation}\n </p>\n {analysis.primaryCube.candidates && analysis.primaryCube.candidates.length > 1 && (\n <details className=\"mt-2\">\n <summary className=\"text-xs text-dc-text-muted cursor-pointer hover:text-dc-text\">\n Show candidates ({analysis.primaryCube.candidates.length})\n </summary>\n <div className=\"mt-2 space-y-1 ml-2\">\n {analysis.primaryCube.candidates.map((c, i) => (\n <div key={i} className=\"text-xs flex items-center gap-2 flex-wrap\">\n <span className={`font-mono ${c.cubeName === analysis.primaryCube.selectedCube ? 'font-bold text-dc-primary' : 'text-dc-text-muted'}`}>\n {c.cubeName}\n </span>\n <span className=\"text-dc-text-muted\">\n dims: {c.dimensionCount}, joins: {c.joinCount}\n </span>\n {c.canReachAll ? (\n <span className=\"text-dc-success flex items-center gap-0.5\">\n <SuccessIcon className=\"w-3 h-3\" />\n reachable\n </span>\n ) : (\n <span className=\"text-dc-error flex items-center gap-0.5\">\n <ErrorIcon className=\"w-3 h-3\" />\n cannot reach all\n </span>\n )}\n </div>\n ))}\n </div>\n </details>\n )}\n </div>\n </div>\n\n {/* Join Paths Section */}\n {analysis.joinPaths.length > 0 && (\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <LinkIcon className=\"w-4 h-4 mr-2\" />\n Join Paths\n </h4>\n <div className=\"space-y-2\">\n {analysis.joinPaths.map((jp, idx) => (\n <div key={idx} className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-2 flex-wrap\">\n <span className=\"font-mono text-dc-text-secondary\">{analysis.primaryCube.selectedCube}</span>\n <ArrowRightIcon className=\"w-4 h-4 text-dc-text-muted\" />\n <span className=\"font-mono font-medium text-dc-text\">{jp.targetCube}</span>\n {jp.pathFound ? (\n <span className=\"text-xs px-2 py-0.5 bg-dc-success-bg text-dc-success rounded\">\n {jp.pathLength} step{jp.pathLength !== 1 ? 's' : ''}\n </span>\n ) : (\n <span className=\"text-xs px-2 py-0.5 bg-dc-error-bg text-dc-error rounded\">\n No path\n </span>\n )}\n </div>\n {jp.pathFound && jp.path && jp.path.length > 0 && (\n <div className=\"space-y-1 ml-2\">\n {jp.path.map((step, stepIdx) => (\n <div key={stepIdx} className=\"flex items-center gap-1 text-xs flex-wrap\">\n <span className=\"font-mono text-dc-text-secondary\">{step.fromCube}</span>\n <ArrowRightIcon className=\"w-3 h-3 text-dc-text-muted\" />\n <span className=\"font-mono text-dc-text\">{step.toCube}</span>\n <span className=\"text-dc-text-muted\">\n ({step.relationship}, {step.joinType} join)\n </span>\n {step.joinColumns.length > 0 && (\n <span className=\"text-dc-text-muted\">\n on {step.joinColumns.map(jc => `${jc.sourceColumn}=${jc.targetColumn}`).join(', ')}\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n {!jp.pathFound && jp.error && (\n <p className=\"text-xs text-dc-error mt-1\">{jp.error}</p>\n )}\n {jp.visitedCubes && jp.visitedCubes.length > 0 && !jp.pathFound && (\n <details className=\"mt-1\">\n <summary className=\"text-xs text-dc-text-muted cursor-pointer hover:text-dc-text\">\n Cubes visited during search ({jp.visitedCubes.length})\n </summary>\n <div className=\"mt-1 text-xs text-dc-text-muted ml-2\">\n {jp.visitedCubes.join(' → ')}\n </div>\n </details>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Pre-Aggregations Section */}\n {analysis.preAggregations.length > 0 && (\n <div className=\"border-b border-dc-border pb-3\">\n <h4 className=\"text-sm font-semibold text-dc-text mb-2 flex items-center\">\n <TableIcon className=\"w-4 h-4 mr-2\" />\n Pre-Aggregation CTEs\n </h4>\n <div className=\"space-y-2\">\n {analysis.preAggregations.map((pa, idx) => (\n <div key={idx} className=\"bg-dc-surface p-3 rounded text-sm\">\n <div className=\"flex items-center gap-2 mb-1 flex-wrap\">\n <span className=\"font-mono font-medium text-dc-text\">{pa.cubeName}</span>\n <span className=\"text-xs text-dc-text-muted\">as</span>\n <code className=\"text-xs bg-dc-surface-secondary px-1 rounded font-mono\">{pa.cteAlias}</code>\n </div>\n <p className=\"text-xs text-dc-text-secondary\">{pa.reason}</p>\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n <span className=\"font-medium\">Measures:</span> {pa.measures.join(', ')}\n </div>\n {pa.joinKeys.length > 0 && (\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n <span className=\"font-medium\">Join keys:</span> {pa.joinKeys.map(jk => `${jk.sourceColumn}=${jk.targetColumn}`).join(', ')}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Warnings Section */}\n {analysis.warnings && analysis.warnings.length > 0 && (\n <div>\n <h4 className=\"text-sm font-semibold text-dc-warning mb-2 flex items-center\">\n <WarningIcon className=\"w-4 h-4 mr-2\" />\n Warnings\n </h4>\n <ul className=\"list-disc list-inside text-xs text-dc-warning space-y-1\">\n {analysis.warnings.map((w, i) => (\n <li key={i}>{w}</li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Cubes Involved */}\n {analysis.cubesInvolved.length > 0 && (\n <div className=\"text-xs text-dc-text-muted pt-2 border-t border-dc-border\">\n <span className=\"font-medium\">Cubes involved:</span> {analysis.cubesInvolved.join(', ')}\n </div>\n )}\n </div>\n )\n}\n\nexport default QueryAnalysisPanel\n","/**\n * Smart Chart Defaulting System\n *\n * Provides intelligent chart type selection and configuration based on\n * the user's current metrics and breakdowns selection.\n */\n\nimport type { ChartType, ChartAxisConfig } from '../types'\nimport type { MetricItem, BreakdownItem } from '../components/AnalysisBuilder/types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of smart chart defaults calculation\n */\nexport interface SmartChartDefaults {\n /** The recommended chart type */\n chartType: ChartType\n /** The auto-configured chart axis settings */\n chartConfig: ChartAxisConfig\n}\n\n/**\n * Availability status for a chart type\n */\nexport interface ChartAvailability {\n /** Whether the chart type can be used with current selections */\n available: boolean\n /** Reason why the chart is unavailable (for tooltip) */\n reason?: string\n}\n\n/**\n * Map of chart type availability statuses\n */\nexport type ChartAvailabilityMap = Record<ChartType, ChartAvailability>\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if a breakdown is a time dimension\n */\nfunction isTimeDimension(breakdown: BreakdownItem): boolean {\n return breakdown.isTimeDimension\n}\n\n/**\n * Get the first time dimension from breakdowns, if any\n */\nfunction getFirstTimeDimension(breakdowns: BreakdownItem[]): BreakdownItem | undefined {\n return breakdowns.find(isTimeDimension)\n}\n\n/**\n * Get the first non-time dimension from breakdowns, if any\n */\nfunction getFirstDimension(breakdowns: BreakdownItem[]): BreakdownItem | undefined {\n return breakdowns.find((b) => !b.isTimeDimension)\n}\n\n/**\n * Get all non-time dimensions\n */\nfunction getDimensions(breakdowns: BreakdownItem[]): BreakdownItem[] {\n return breakdowns.filter((b) => !b.isTimeDimension)\n}\n\n/**\n * Get all time dimensions\n */\nfunction getTimeDimensions(breakdowns: BreakdownItem[]): BreakdownItem[] {\n return breakdowns.filter(isTimeDimension)\n}\n\n// ============================================================================\n// Chart Availability\n// ============================================================================\n\n/**\n * Check if a specific chart type is available given current selections\n */\nexport function getChartAvailability(\n chartType: ChartType,\n metrics: MetricItem[],\n breakdowns: BreakdownItem[]\n): ChartAvailability {\n const measureCount = metrics.length\n const dimensionCount = getDimensions(breakdowns).length\n const timeDimensionCount = getTimeDimensions(breakdowns).length\n const totalBreakdowns = breakdowns.length\n\n switch (chartType) {\n // Always available charts\n case 'table':\n case 'markdown':\n return { available: true }\n\n // Measure-only charts (KPI Number, KPI Text)\n case 'kpiNumber':\n case 'kpiText':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n return { available: true }\n\n // Bar chart - needs dimension for categories + measure for values\n case 'bar':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n if (totalBreakdowns < 1) {\n return { available: false, reason: 'Requires at least 1 breakdown for categories' }\n }\n return { available: true }\n\n // KPI Delta - needs dimension for ordering + measure for values\n case 'kpiDelta':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n if (totalBreakdowns < 1) {\n return { available: false, reason: 'Requires at least 1 breakdown for ordering' }\n }\n return { available: true }\n\n // Line and area charts - need dimension/time + measure\n case 'line':\n case 'area':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n if (totalBreakdowns < 1) {\n return { available: false, reason: 'Requires a breakdown (dimension or time)' }\n }\n return { available: true }\n\n // Pie chart - needs dimension (not time) + measure\n case 'pie':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires 1 measure' }\n }\n if (dimensionCount < 1) {\n return { available: false, reason: 'Requires 1 dimension (not time dimension)' }\n }\n return { available: true }\n\n // Scatter - needs measure + any breakdown\n case 'scatter':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n // Scatter can work with just measures (x and y from different measures)\n // or with dimension + measure\n if (measureCount < 2 && totalBreakdowns < 1) {\n return { available: false, reason: 'Requires 2 measures or 1 measure + 1 breakdown' }\n }\n return { available: true }\n\n // Bubble - needs 2+ measures and 1+ breakdown (dimension or time dimension for series)\n case 'bubble':\n if (measureCount < 2) {\n return { available: false, reason: 'Requires at least 2 measures' }\n }\n if (totalBreakdowns < 1) {\n return { available: false, reason: 'Requires at least 1 breakdown for series grouping' }\n }\n return { available: true }\n\n // Radar - needs dimension + measure\n case 'radar':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n if (dimensionCount < 1) {\n return { available: false, reason: 'Requires at least 1 dimension' }\n }\n return { available: true }\n\n // Radial Bar - needs dimension + measure\n case 'radialBar':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n if (dimensionCount < 1) {\n return { available: false, reason: 'Requires at least 1 dimension' }\n }\n return { available: true }\n\n // Treemap - needs dimension + measure\n case 'treemap':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n if (dimensionCount < 1) {\n return { available: false, reason: 'Requires at least 1 dimension' }\n }\n return { available: true }\n\n // Activity Grid - needs time dimension + measure\n case 'activityGrid':\n if (measureCount < 1) {\n return { available: false, reason: 'Requires at least 1 measure' }\n }\n if (timeDimensionCount < 1) {\n return { available: false, reason: 'Requires a time dimension' }\n }\n return { available: true }\n\n default:\n // Unknown chart type - assume available\n return { available: true }\n }\n}\n\n/**\n * Get availability for all chart types\n */\nexport function getAllChartAvailability(\n metrics: MetricItem[],\n breakdowns: BreakdownItem[]\n): ChartAvailabilityMap {\n // Chart types in alphabetical order (matching ChartTypeSelector display)\n const chartTypes: ChartType[] = [\n 'activityGrid',\n 'area',\n 'bar',\n 'bubble',\n 'kpiDelta',\n 'kpiNumber',\n 'kpiText',\n 'line',\n 'markdown',\n 'pie',\n 'radar',\n 'radialBar',\n 'scatter',\n 'table',\n 'treemap'\n ]\n\n const availability: Partial<ChartAvailabilityMap> = {}\n for (const chartType of chartTypes) {\n availability[chartType] = getChartAvailability(chartType, metrics, breakdowns)\n }\n\n return availability as ChartAvailabilityMap\n}\n\n// ============================================================================\n// Smart Chart Type Selection\n// ============================================================================\n\n/**\n * Select the best chart type based on current metrics and breakdowns\n *\n * Priority order:\n * 1. If current chart type is still valid, keep it (preserve user intent)\n * 2. If current chart becomes invalid, switch to best alternative:\n * - Has time dimension → line\n * - Has dimension + measure → bar\n * - Has measures only → bar (or kpiNumber if single measure + no breakdowns)\n * - No fields → keep current\n */\nexport function selectBestChartType(\n metrics: MetricItem[],\n breakdowns: BreakdownItem[],\n currentChartType: ChartType\n): ChartType {\n // Check if current chart type is still valid\n const currentAvailability = getChartAvailability(currentChartType, metrics, breakdowns)\n if (currentAvailability.available) {\n return currentChartType\n }\n\n // No fields selected - keep current\n if (metrics.length === 0 && breakdowns.length === 0) {\n return currentChartType\n }\n\n const hasTimeDimension = getTimeDimensions(breakdowns).length > 0\n const hasDimension = getDimensions(breakdowns).length > 0\n const hasMeasure = metrics.length > 0\n\n // Priority selection logic\n if (hasTimeDimension && hasMeasure) {\n // Time series data → line chart\n return 'line'\n }\n\n if (hasDimension && hasMeasure) {\n // Categorical data with measures → bar chart\n return 'bar'\n }\n\n if (hasMeasure && !hasDimension && !hasTimeDimension) {\n // Measures only, no breakdowns → KPI number (works with just measures)\n return 'kpiNumber'\n }\n\n // Fallback to table as most versatile (works with any combination)\n return 'table'\n}\n\n// ============================================================================\n// Smart Chart Config Defaults\n// ============================================================================\n\n/**\n * Get smart default chart configuration based on chart type and selections\n */\nexport function getSmartChartDefaults(\n metrics: MetricItem[],\n breakdowns: BreakdownItem[],\n currentChartType: ChartType\n): SmartChartDefaults {\n // First, determine the best chart type\n const chartType = selectBestChartType(metrics, breakdowns, currentChartType)\n\n // Then, auto-configure the chart axes based on chart type\n const chartConfig = buildChartConfig(chartType, metrics, breakdowns)\n\n return { chartType, chartConfig }\n}\n\n/**\n * Build optimal chart configuration for a given chart type\n */\nfunction buildChartConfig(\n chartType: ChartType,\n metrics: MetricItem[],\n breakdowns: BreakdownItem[]\n): ChartAxisConfig {\n const timeDimension = getFirstTimeDimension(breakdowns)\n const dimension = getFirstDimension(breakdowns)\n const dimensions = getDimensions(breakdowns)\n const allBreakdowns = breakdowns\n\n switch (chartType) {\n case 'line':\n case 'area':\n // Line/Area: xAxis = first time dimension (prefer) or dimension\n // yAxis = all measures, series = optional second dimension\n return {\n xAxis: timeDimension\n ? [timeDimension.field]\n : dimension\n ? [dimension.field]\n : [],\n yAxis: metrics.map((m) => m.field),\n series:\n dimensions.length > 1\n ? [dimensions[1].field]\n : dimension && timeDimension\n ? [dimension.field]\n : []\n }\n\n case 'bar':\n // Bar: xAxis = first dimension (prefer non-time), yAxis = all measures\n return {\n xAxis: dimension\n ? [dimension.field]\n : timeDimension\n ? [timeDimension.field]\n : [],\n yAxis: metrics.map((m) => m.field),\n series:\n dimensions.length > 1\n ? [dimensions[1].field]\n : timeDimension && dimension\n ? [timeDimension.field]\n : []\n }\n\n case 'pie':\n // Pie: xAxis = first dimension (exactly 1), yAxis = first measure (exactly 1)\n return {\n xAxis: dimension ? [dimension.field] : [],\n yAxis: metrics.length > 0 ? [metrics[0].field] : []\n }\n\n case 'scatter':\n // Scatter: xAxis = first dimension or measure, yAxis = first/second measure\n if (metrics.length >= 2) {\n return {\n xAxis: [metrics[0].field],\n yAxis: [metrics[1].field],\n series: dimension ? [dimension.field] : []\n }\n }\n return {\n xAxis: allBreakdowns.length > 0 ? [allBreakdowns[0].field] : [],\n yAxis: metrics.length > 0 ? [metrics[0].field] : [],\n series: dimensions.length > 1 ? [dimensions[1].field] : []\n }\n\n case 'bubble':\n // Bubble: xAxis = first measure, yAxis = second measure, sizeField = third measure (or second if only 2)\n // series = first breakdown (dimension or time dimension) for grouping/coloring\n return {\n xAxis: metrics.length > 0 ? [metrics[0].field] : [],\n yAxis: metrics.length > 1 ? [metrics[1].field] : [],\n sizeField: metrics.length > 2 ? metrics[2].field : metrics.length > 1 ? metrics[1].field : undefined,\n series: dimension ? [dimension.field] : timeDimension ? [timeDimension.field] : []\n }\n\n case 'radar':\n case 'radialBar':\n case 'treemap':\n // These all use dimension for categories and measure for values\n return {\n xAxis: dimension ? [dimension.field] : [],\n yAxis: metrics.length > 0 ? [metrics[0].field] : []\n }\n\n case 'activityGrid':\n // Activity Grid: dateField = time dimension, valueField = measure\n return {\n dateField: timeDimension ? [timeDimension.field] : [],\n valueField: metrics.length > 0 ? [metrics[0].field] : []\n }\n\n case 'kpiNumber':\n case 'kpiDelta':\n case 'kpiText':\n // KPI charts: just need the measure\n return {\n yAxis: metrics.length > 0 ? [metrics[0].field] : []\n }\n\n case 'table':\n // Table: include all fields\n return {\n xAxis: [\n ...breakdowns.map((b) => b.field),\n ...metrics.map((m) => m.field)\n ]\n }\n\n case 'markdown':\n // Markdown doesn't need chart config\n return {}\n\n default:\n // Default fallback - x = first breakdown, y = all measures\n return {\n xAxis: allBreakdowns.length > 0 ? [allBreakdowns[0].field] : [],\n yAxis: metrics.map((m) => m.field)\n }\n }\n}\n\n// ============================================================================\n// Update Logic for AnalysisBuilder\n// ============================================================================\n\n/**\n * Determine if chart type should be auto-switched based on selections change\n *\n * Returns the new chart type if a switch is recommended, or null if no change needed.\n *\n * @param metrics - Current metrics selection\n * @param breakdowns - Current breakdowns selection\n * @param currentChartType - Current chart type\n * @param userManuallySelected - Whether user manually selected the current chart type\n */\nexport function shouldAutoSwitchChartType(\n metrics: MetricItem[],\n breakdowns: BreakdownItem[],\n currentChartType: ChartType,\n userManuallySelected: boolean\n): ChartType | null {\n // If user manually selected this chart type, only switch if it becomes invalid\n if (userManuallySelected) {\n const availability = getChartAvailability(currentChartType, metrics, breakdowns)\n if (availability.available) {\n return null // Keep user's choice\n }\n }\n\n // Check if a better chart type should be used\n const recommendedType = selectBestChartType(metrics, breakdowns, currentChartType)\n\n // Only suggest switch if recommended type is different\n if (recommendedType !== currentChartType) {\n return recommendedType\n }\n\n return null\n}\n\n/**\n * Check if a chart config field references valid fields from metrics/breakdowns\n */\nfunction isValidConfigField(\n fieldValue: string | string[] | undefined,\n validFields: Set<string>\n): boolean {\n if (!fieldValue) return false\n if (Array.isArray(fieldValue)) {\n return fieldValue.length > 0 && fieldValue.every((f) => validFields.has(f))\n }\n return validFields.has(fieldValue)\n}\n\n/**\n * Merge existing chart config with smart defaults\n * Only fills in missing or invalid fields, preserves valid existing config\n */\nexport function mergeChartConfigWithDefaults(\n existingConfig: ChartAxisConfig,\n smartDefaults: ChartAxisConfig,\n metrics: MetricItem[],\n breakdowns: BreakdownItem[]\n): ChartAxisConfig {\n // Build set of valid field names\n const validFields = new Set<string>([\n ...metrics.map((m) => m.field),\n ...breakdowns.map((b) => b.field)\n ])\n\n const result: ChartAxisConfig = {}\n\n // For each key in smart defaults, use existing value if valid, otherwise use default\n const allKeys = new Set([\n ...Object.keys(existingConfig),\n ...Object.keys(smartDefaults)\n ]) as Set<keyof ChartAxisConfig>\n\n for (const key of allKeys) {\n const existingValue = existingConfig[key]\n const defaultValue = smartDefaults[key]\n\n // Check if existing value is valid\n if (isValidConfigField(existingValue as string | string[] | undefined, validFields)) {\n // Keep existing valid config\n result[key] = existingValue as any\n } else if (defaultValue !== undefined) {\n // Use smart default\n result[key] = defaultValue as any\n }\n // If neither exists or is valid, leave undefined\n }\n\n return result\n}\n","/**\n * Unified Color Palette System\n * Each palette contains coordinated series and gradient colors that work well together\n */\n\nexport interface ColorPalette {\n name: string\n label: string\n colors: string[] // For series-based charts (bar, line, pie, area, scatter, radar, etc.)\n gradient: string[] // For gradient-based charts (bubble, activity grid)\n}\n\n// Predefined color palettes with visually coordinated series and gradient colors\nexport const COLOR_PALETTES: ColorPalette[] = [\n {\n name: 'default',\n label: 'Default',\n colors: [\n '#3b82f6', // blue\n '#10b981', // green\n '#f59e0b', // yellow\n '#ef4444', // red\n '#8b5cf6', // purple\n '#f97316', // orange\n '#06b6d4', // cyan\n '#84cc16', // lime\n ],\n gradient: [\n '#440154', // dark purple\n '#414487', // purple-blue\n '#2a788e', // teal\n '#22a884', // green-teal \n '#7ad151', // green\n '#fde725', // yellow\n ]\n },\n {\n name: 'ocean',\n label: 'Ocean',\n colors: [\n '#1e3a8a', // deep blue\n '#1e40af', // blue\n '#2563eb', // bright blue\n '#3b82f6', // light blue\n '#06b6d4', // cyan\n '#0891b2', // dark cyan\n '#0e7490', // teal\n '#0f766e', // dark teal\n ],\n gradient: [\n '#0c4a6e', // very dark blue\n '#075985', // dark blue\n '#0369a1', // medium blue\n '#0284c7', // bright blue\n '#0ea5e9', // light blue\n '#38bdf8', // cyan blue\n ]\n },\n {\n name: 'sunset',\n label: 'Sunset',\n colors: [\n '#dc2626', // red\n '#ea580c', // orange-red\n '#f59e0b', // orange\n '#eab308', // yellow-orange\n '#d97706', // amber\n '#b45309', // dark amber\n '#92400e', // brown\n '#7c2d12', // dark brown\n ],\n gradient: [\n '#7c2d12', // dark brown\n '#92400e', // brown\n '#b45309', // dark amber\n '#d97706', // amber\n '#f59e0b', // orange\n '#fbbf24', // light orange\n ]\n },\n {\n name: 'forest',\n label: 'Forest',\n colors: [\n '#166534', // dark green\n '#15803d', // green\n '#16a34a', // bright green\n '#22c55e', // light green\n '#4ade80', // lighter green\n '#65a30d', // lime green\n '#84cc16', // lime\n '#a3e635', // light lime\n ],\n gradient: [\n '#14532d', // very dark green\n '#166534', // dark green\n '#15803d', // green\n '#16a34a', // bright green\n '#22c55e', // light green\n '#4ade80', // lighter green\n ]\n },\n {\n name: 'purple',\n label: 'Purple',\n colors: [\n '#581c87', // dark purple\n '#7c3aed', // purple\n '#8b5cf6', // bright purple\n '#a855f7', // light purple\n '#c084fc', // lighter purple\n '#e879f9', // magenta\n '#f0abfc', // light magenta\n '#fbbf24', // accent yellow\n ],\n gradient: [\n '#4c1d95', // very dark purple\n '#581c87', // dark purple\n '#6d28d9', // medium purple\n '#7c3aed', // purple\n '#8b5cf6', // bright purple\n '#a855f7', // light purple\n ]\n },\n {\n name: 'monochrome',\n label: 'Monochrome',\n colors: [\n '#1f2937', // very dark gray\n '#374151', // dark gray\n '#4b5563', // medium gray\n '#6b7280', // gray\n '#9ca3af', // light gray\n '#d1d5db', // lighter gray\n '#e5e7eb', // very light gray\n '#f3f4f6', // almost white\n ],\n gradient: [\n '#111827', // black\n '#1f2937', // very dark gray\n '#374151', // dark gray\n '#4b5563', // medium gray\n '#6b7280', // gray\n '#9ca3af', // light gray\n ]\n },\n {\n name: 'pastel',\n label: 'Pastel',\n colors: [\n '#93c5fd', // light blue\n '#86efac', // light green\n '#fde047', // light yellow\n '#fca5a5', // light red\n '#c4b5fd', // light purple\n '#fdba74', // light orange\n '#67e8f9', // light cyan\n '#bef264', // light lime\n ],\n gradient: [\n '#bfdbfe', // very light blue\n '#a7f3d0', // very light green\n '#fef08a', // very light yellow\n '#fecaca', // very light red\n '#ddd6fe', // very light purple\n '#fed7aa', // very light orange\n ]\n },\n {\n name: 'vibrant',\n label: 'Vibrant',\n colors: [\n '#0000ff', // pure blue\n '#00ff00', // pure green\n '#ffff00', // pure yellow\n '#ff0000', // pure red\n '#ff00ff', // pure magenta\n '#ff8000', // pure orange\n '#00ffff', // pure cyan\n '#8000ff', // pure violet\n ],\n gradient: [\n '#4000ff', // blue-violet\n '#0080ff', // blue\n '#00ffff', // cyan\n '#00ff80', // green\n '#80ff00', // lime\n '#ffff00', // yellow\n ]\n },\n {\n name: 'd3Category10',\n label: 'D3 Category 10',\n colors: [\n '#1f77b4', // blue\n '#ff7f0e', // orange\n '#2ca02c', // green\n '#d62728', // red\n '#9467bd', // purple\n '#8c564b', // brown\n '#e377c2', // pink\n '#7f7f7f', // gray\n '#bcbd22', // olive\n '#17becf', // cyan\n ],\n gradient: [\n '#1f77b4', // blue\n '#2ca02c', // green\n '#bcbd22', // olive\n '#ff7f0e', // orange\n '#d62728', // red\n '#9467bd', // purple\n ]\n },\n {\n name: 'd3Tableau10',\n label: 'D3 Tableau 10',\n colors: [\n '#4e79a7', // blue\n '#f28e2c', // orange\n '#e15759', // red\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc949', // yellow\n '#af7aa1', // purple\n '#ff9da7', // pink\n '#9c755f', // brown\n '#bab0ab', // gray\n ],\n gradient: [\n '#4e79a7', // blue\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc949', // yellow\n '#f28e2c', // orange\n '#e15759', // red\n ]\n },\n {\n name: 'colorBrewerSet1',\n label: 'ColorBrewer Set 1',\n colors: [\n '#e41a1c', // red\n '#377eb8', // blue\n '#4daf4a', // green\n '#984ea3', // purple\n '#ff7f00', // orange\n '#ffff33', // yellow\n '#a65628', // brown\n '#f781bf', // pink\n '#999999', // gray\n ],\n gradient: [\n '#377eb8', // blue\n '#4daf4a', // green\n '#ffff33', // yellow\n '#ff7f00', // orange\n '#e41a1c', // red\n '#984ea3', // purple\n ]\n },\n {\n name: 'colorBrewerSet2',\n label: 'ColorBrewer Set 2',\n colors: [\n '#66c2a5', // teal\n '#fc8d62', // orange\n '#8da0cb', // blue\n '#e78ac3', // pink\n '#a6d854', // lime\n '#ffd92f', // yellow\n '#e5c494', // tan\n '#b3b3b3', // gray\n ],\n gradient: [\n '#8da0cb', // blue\n '#66c2a5', // teal\n '#a6d854', // lime\n '#ffd92f', // yellow\n '#fc8d62', // orange\n '#e78ac3', // pink\n ]\n },\n {\n name: 'colorBrewerDark2',\n label: 'ColorBrewer Dark 2',\n colors: [\n '#1b9e77', // dark teal\n '#d95f02', // dark orange\n '#7570b3', // dark blue\n '#e7298a', // dark pink\n '#66a61e', // dark green\n '#e6ab02', // dark yellow\n '#a6761d', // dark brown\n '#666666', // dark gray\n ],\n gradient: [\n '#7570b3', // dark blue\n '#1b9e77', // dark teal\n '#66a61e', // dark green\n '#e6ab02', // dark yellow\n '#d95f02', // dark orange\n '#e7298a', // dark pink\n ]\n },\n {\n name: 'colorBrewerPaired',\n label: 'ColorBrewer Paired',\n colors: [\n '#a6cee3', // light blue\n '#1f78b4', // blue\n '#b2df8a', // light green\n '#33a02c', // green\n '#fb9a99', // light red\n '#e31a1c', // red\n '#fdbf6f', // light orange\n '#ff7f00', // orange\n '#cab2d6', // light purple\n '#6a3d9a', // purple\n '#ffff99', // light yellow\n '#b15928', // brown\n ],\n gradient: [\n '#1f78b4', // blue\n '#33a02c', // green\n '#ffff99', // light yellow\n '#ff7f00', // orange\n '#e31a1c', // red\n '#6a3d9a', // purple\n ]\n },\n {\n name: 'viridis',\n label: 'Viridis',\n colors: [\n '#440154', // dark purple\n '#482677', // purple\n '#3f4a8a', // blue-purple\n '#31678e', // blue\n '#26838f', // teal\n '#1f9d8a', // green-teal\n '#6cce5a', // green\n '#b6de2b', // yellow-green\n ],\n gradient: [\n '#440154', // dark purple\n '#482677', // purple\n '#3f4a8a', // blue-purple\n '#31678e', // blue\n '#26838f', // teal\n '#1f9d8a', // green-teal\n '#6cce5a', // green\n '#b6de2b', // yellow-green\n ]\n },\n {\n name: 'plasma',\n label: 'Plasma',\n colors: [\n '#0c0786', // dark blue\n '#5c01a6', // purple\n '#900da4', // magenta\n '#bf3984', // pink\n '#e16462', // coral\n '#f99b45', // orange\n '#fcce25', // yellow\n '#f0f921', // bright yellow\n ],\n gradient: [\n '#0c0786', // dark blue\n '#5c01a6', // purple\n '#900da4', // magenta\n '#bf3984', // pink\n '#e16462', // coral\n '#f99b45', // orange\n '#fcce25', // yellow\n '#f0f921', // bright yellow\n ]\n },\n {\n name: 'inferno',\n label: 'Inferno',\n colors: [\n '#000003', // black\n '#1f0c47', // dark blue\n '#550f6d', // purple\n '#88226a', // magenta\n '#a83655', // red\n '#cc4f39', // orange-red\n '#e6862a', // orange\n '#fec228', // yellow\n ],\n gradient: [\n '#000003', // black\n '#1f0c47', // dark blue\n '#550f6d', // purple\n '#88226a', // magenta\n '#a83655', // red\n '#cc4f39', // orange-red\n '#e6862a', // orange\n '#fec228', // yellow\n ]\n },\n {\n name: 'magma',\n label: 'Magma',\n colors: [\n '#000003', // black\n '#140b34', // dark purple\n '#3b0f6f', // purple\n '#641a80', // magenta\n '#8b2981', // pink\n '#b63679', // coral\n '#de4968', // red\n '#fd9f6c', // orange\n ],\n gradient: [\n '#000003', // black\n '#140b34', // dark purple\n '#3b0f6f', // purple\n '#641a80', // magenta\n '#8b2981', // pink\n '#b63679', // coral\n '#de4968', // red\n '#fd9f6c', // orange\n ]\n },\n {\n name: 'cividis',\n label: 'Cividis',\n colors: [\n '#00204c', // dark blue\n '#003f5c', // blue\n '#2c4b7a', // blue\n '#51576f', // blue-gray\n '#7f6874', // gray\n '#a8786e', // brown\n '#d2906d', // orange\n '#ffb570', // yellow\n ],\n gradient: [\n '#00204c', // dark blue\n '#003f5c', // blue\n '#2c4b7a', // blue\n '#51576f', // blue-gray\n '#7f6874', // gray\n '#a8786e', // brown\n '#d2906d', // orange\n '#ffb570', // yellow\n ]\n },\n {\n name: 'turbo',\n label: 'Turbo',\n colors: [\n '#30123b', // purple\n '#4454c4', // blue\n '#1dd3c0', // cyan\n '#42f465', // green\n '#b2df22', // lime\n '#faba39', // yellow\n '#f66c19', // orange\n '#c42e02', // red\n ],\n gradient: [\n '#30123b', // purple\n '#4454c4', // blue\n '#1dd3c0', // cyan\n '#42f465', // green\n '#b2df22', // lime\n '#faba39', // yellow\n '#f66c19', // orange\n '#c42e02', // red\n ]\n },\n {\n name: 'warm',\n label: 'Warm',\n colors: [\n '#8b0000', // dark red\n '#b22222', // red\n '#cd5c5c', // light red\n '#ff6347', // tomato\n '#ff8c00', // dark orange\n '#ffa500', // orange\n '#ffd700', // gold\n '#ffff00', // yellow\n ],\n gradient: [\n '#8b0000', // dark red\n '#b22222', // red\n '#ff6347', // tomato\n '#ff8c00', // dark orange\n '#ffa500', // orange\n '#ffd700', // gold\n ]\n },\n {\n name: 'cool',\n label: 'Cool',\n colors: [\n '#000080', // navy\n '#0000ff', // blue\n '#4169e1', // royal blue\n '#00bfff', // deep sky blue\n '#00ffff', // cyan\n '#40e0d0', // turquoise\n '#20b2aa', // light sea green\n '#008b8b', // dark cyan\n ],\n gradient: [\n '#000080', // navy\n '#0000ff', // blue\n '#4169e1', // royal blue\n '#00bfff', // deep sky blue\n '#00ffff', // cyan\n '#40e0d0', // turquoise\n ]\n },\n {\n name: 'earth',\n label: 'Earth',\n colors: [\n '#8b4513', // saddle brown\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#d2691e', // chocolate\n '#bc8f8f', // rosy brown\n '#f4a460', // sandy brown\n '#deb887', // burlywood\n ],\n gradient: [\n '#8b4513', // saddle brown\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#d2691e', // chocolate\n '#f4a460', // sandy brown\n ]\n },\n {\n name: 'autumn',\n label: 'Autumn',\n colors: [\n '#8b0000', // dark red\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#ff8c00', // dark orange\n '#ff4500', // orange red\n '#dc143c', // crimson\n '#b22222', // fire brick\n ],\n gradient: [\n '#8b0000', // dark red\n '#a0522d', // sienna\n '#cd853f', // peru\n '#daa520', // goldenrod\n '#ff8c00', // dark orange\n '#ff4500', // orange red\n ]\n },\n {\n name: 'spring',\n label: 'Spring',\n colors: [\n '#32cd32', // lime green\n '#98fb98', // pale green\n '#90ee90', // light green\n '#ffb6c1', // light pink\n '#ffc0cb', // pink\n '#ffffe0', // light yellow\n '#f0fff0', // honeydew\n '#e0ffff', // light cyan\n ],\n gradient: [\n '#32cd32', // lime green\n '#98fb98', // pale green\n '#ffffe0', // light yellow\n '#ffb6c1', // light pink\n '#ffc0cb', // pink\n '#e0ffff', // light cyan\n ]\n },\n {\n name: 'winter',\n label: 'Winter',\n colors: [\n '#191970', // midnight blue\n '#4682b4', // steel blue\n '#87ceeb', // sky blue\n '#b0e0e6', // powder blue\n '#e0ffff', // light cyan\n '#f0f8ff', // alice blue\n '#c0c0c0', // silver\n '#708090', // slate gray\n ],\n gradient: [\n '#191970', // midnight blue\n '#4682b4', // steel blue\n '#87ceeb', // sky blue\n '#b0e0e6', // powder blue\n '#e0ffff', // light cyan\n '#f0f8ff', // alice blue\n ]\n },\n {\n name: 'neon',\n label: 'Neon',\n colors: [\n '#ff0080', // neon pink\n '#00ff80', // neon green\n '#8000ff', // neon purple\n '#ff8000', // neon orange\n '#0080ff', // neon blue\n '#80ff00', // neon lime\n '#ff0040', // neon red\n '#40ff00', // bright green\n ],\n gradient: [\n '#8000ff', // neon purple\n '#0080ff', // neon blue\n '#00ff80', // neon green\n '#80ff00', // neon lime\n '#ff8000', // neon orange\n '#ff0080', // neon pink\n ]\n },\n {\n name: 'retro',\n label: 'Retro',\n colors: [\n '#ff69b4', // hot pink\n '#ffd700', // gold\n '#32cd32', // lime green\n '#00ced1', // dark turquoise\n '#ff6347', // tomato\n '#9370db', // medium purple\n '#ffa500', // orange\n '#20b2aa', // light sea green\n ],\n gradient: [\n '#9370db', // medium purple\n '#ff69b4', // hot pink\n '#ff6347', // tomato\n '#ffd700', // gold\n '#32cd32', // lime green\n '#00ced1', // dark turquoise\n ]\n },\n {\n name: 'corporate',\n label: 'Corporate',\n colors: [\n '#003366', // dark blue\n '#0066cc', // blue\n '#336699', // steel blue\n '#6699cc', // light blue\n '#4d4d4d', // dark gray\n '#808080', // gray\n '#b3b3b3', // light gray\n '#cccccc', // very light gray\n ],\n gradient: [\n '#003366', // dark blue\n '#0066cc', // blue\n '#336699', // steel blue\n '#6699cc', // light blue\n '#808080', // gray\n '#b3b3b3', // light gray\n ]\n },\n {\n name: 'material',\n label: 'Material Design',\n colors: [\n '#f44336', // red\n '#e91e63', // pink\n '#9c27b0', // purple\n '#673ab7', // deep purple\n '#3f51b5', // indigo\n '#2196f3', // blue\n '#03a9f4', // light blue\n '#00bcd4', // cyan\n ],\n gradient: [\n '#673ab7', // deep purple\n '#3f51b5', // indigo\n '#2196f3', // blue\n '#00bcd4', // cyan\n '#03a9f4', // light blue\n '#e91e63', // pink\n ]\n }\n]\n\n/**\n * Get a color palette by name, with fallback to default\n */\nexport function getColorPalette(paletteName?: string): ColorPalette {\n if (!paletteName) {\n return COLOR_PALETTES[0] // default palette\n }\n \n const palette = COLOR_PALETTES.find(p => p.name === paletteName)\n return palette || COLOR_PALETTES[0] // fallback to default\n}\n\n/**\n * Get just the series colors for a palette\n */\nexport function getSeriesColors(paletteName?: string): string[] {\n return getColorPalette(paletteName).colors\n}\n\n/**\n * Get just the gradient colors for a palette\n */\nexport function getGradientColors(paletteName?: string): string[] {\n return getColorPalette(paletteName).gradient\n}\n\n/**\n * Chart types that use series colors (discrete categories)\n */\nexport const SERIES_CHART_TYPES = [\n 'bar', 'line', 'area', 'pie', 'scatter', 'radar', 'radialBar', 'treeMap'\n] as const\n\n/**\n * Chart types that use gradient colors (continuous values)\n */\nexport const GRADIENT_CHART_TYPES = [\n 'bubble', 'activityGrid'\n] as const\n\n/**\n * Determine if a chart type uses gradient colors\n */\nexport function usesGradientColors(chartType: string): boolean {\n return GRADIENT_CHART_TYPES.includes(chartType as any)\n}","/**\n * Color Palette Selector Component\n * Allows users to select from predefined color palettes for their dashboard\n */\n\nimport { useState, useRef, useEffect } from 'react'\nimport { COLOR_PALETTES, getColorPalette } from '../utils/colorPalettes'\nimport { getIcon } from '../icons'\n\nconst ChevronDownIcon = getIcon('chevronDown')\n\ninterface ColorPaletteSelectorProps {\n currentPalette?: string\n onPaletteChange: (paletteName: string) => void\n className?: string\n}\n\nexport default function ColorPaletteSelector({\n currentPalette = 'default',\n onPaletteChange,\n className = ''\n}: ColorPaletteSelectorProps) {\n const [isOpen, setIsOpen] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n \n const currentPaletteObj = getColorPalette(currentPalette)\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n const handlePaletteSelect = (paletteName: string) => {\n onPaletteChange(paletteName)\n setIsOpen(false)\n }\n\n return (\n <div className={`relative ${className}`} ref={dropdownRef}>\n {/* Trigger Button */}\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"inline-flex items-center gap-2 px-3 py-1.5 bg-dc-surface border border-dc-border rounded-md shadow-xs text-sm font-medium text-dc-text-secondary hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-dc-accent\"\n >\n {/* Current Palette Preview - Hidden on mobile */}\n <div className=\"hidden md:flex items-center gap-1.5\">\n <div className=\"flex gap-0.5\">\n {currentPaletteObj.colors.slice(0, 4).map((color, index) => (\n <div\n key={index}\n className=\"w-3 h-3 rounded-xs border border-dc-border\"\n style={{ backgroundColor: color }}\n title={`Series Color ${index + 1}`}\n />\n ))}\n </div>\n <span className=\"text-xs text-dc-text-secondary\">|</span>\n <div className=\"flex gap-0.5\">\n {currentPaletteObj.gradient.slice(0, 3).map((color, index) => (\n <div\n key={index}\n className=\"w-2 h-3 border-r first:rounded-l-sm last:rounded-r-sm last:border-r-0\"\n style={{\n backgroundColor: color,\n borderColor: 'var(--dc-border)'\n }}\n title={`Gradient Color ${index + 1}`}\n />\n ))}\n </div>\n </div>\n <span>{currentPaletteObj.label}</span>\n <ChevronDownIcon \n className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`} \n />\n </button>\n\n {/* Dropdown Menu - Responsive width */}\n {isOpen && (\n <div className=\"absolute top-full left-0 mt-1 w-72 md:w-80 lg:w-96 bg-dc-surface border border-dc-border rounded-md shadow-lg z-50 max-h-80 overflow-y-auto\">\n <div className=\"py-1\">\n {COLOR_PALETTES.slice().sort((a, b) => a.label.localeCompare(b.label)).map((palette) => (\n <button\n key={palette.name}\n type=\"button\"\n onClick={() => handlePaletteSelect(palette.name)}\n className={`w-full px-3 py-2 text-left text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${\n palette.name === currentPalette ? 'bg-dc-surface-secondary' : 'text-dc-text-secondary'\n }`}\n style={palette.name === currentPalette ? { color: 'var(--dc-primary)' } : undefined}\n >\n <div className=\"flex items-center gap-3\">\n {/* Palette Preview - Hidden on mobile */}\n <div className=\"hidden md:flex items-center gap-2\">\n {/* Series Colors */}\n <div className=\"flex gap-0.5\">\n {palette.colors.slice(0, 6).map((color, index) => (\n <div\n key={`series-${index}`}\n className=\"w-3 h-3 rounded-xs border border-dc-border\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n\n {/* Separator */}\n <div className=\"w-px h-4 bg-dc-border\" />\n \n {/* Gradient Colors */}\n <div className=\"flex\">\n {palette.gradient.map((color, index) => (\n <div\n key={`gradient-${index}`}\n className=\"w-2 h-4 first:rounded-l-sm last:rounded-r-sm\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n </div>\n \n {/* Palette Name */}\n <span className=\"font-medium\">{palette.label}</span>\n \n {/* Current Indicator */}\n {palette.name === currentPalette && (\n <div className=\"ml-auto\">\n <div className=\"w-2 h-2 rounded-full\" style={{ backgroundColor: 'var(--dc-primary)' }}></div>\n </div>\n )}\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}","/**\n * AnalysisResultsPanel Component\n *\n * Displays query execution results with chart and table views.\n * Used in the left panel of AnalysisBuilder.\n */\n\nimport { useState, useEffect, memo } from 'react'\nimport type { AnalysisResultsPanelProps } from './types'\nimport { LazyChart, isValidChartType } from '../../charts/ChartLoader'\nimport { getIcon } from '../../icons'\nimport { QueryAnalysisPanel } from '../../shared'\nimport ColorPaletteSelector from '../ColorPaletteSelector'\n\n/**\n * AnalysisResultsPanel displays query results with chart/table toggle.\n *\n * Features:\n * - Chart visualization with LazyChart\n * - Table view with DataTable\n * - Loading, error, and empty states\n * - Stale results indicator\n * - Display limit control for tables\n */\nconst AnalysisResultsPanel = memo(function AnalysisResultsPanel({\n executionStatus,\n executionResults,\n executionError,\n totalRowCount,\n resultsStale = false,\n chartType = 'line',\n chartConfig = {},\n displayConfig = {},\n colorPalette,\n currentPaletteName,\n onColorPaletteChange,\n query,\n activeView = 'chart',\n onActiveViewChange,\n displayLimit = 100,\n onDisplayLimitChange,\n hasMetrics = false,\n // Debug props\n debugQuery,\n debugSql,\n debugAnalysis,\n debugLoading,\n debugError,\n // Share props\n onShareClick,\n canShare = false,\n shareButtonState = 'idle',\n // Clear functionality\n onClearClick,\n canClear = false,\n // AI functionality\n enableAI = false,\n isAIOpen = false,\n onAIToggle\n}: AnalysisResultsPanelProps) {\n // Debug view toggle state\n const [showDebug, setShowDebug] = useState(false)\n // Force table view when no metrics are selected\n useEffect(() => {\n if (!hasMetrics && activeView === 'chart') {\n onActiveViewChange('table')\n }\n }, [hasMetrics, activeView, onActiveViewChange])\n // Icons\n const SuccessIcon = getIcon('success')\n const ErrorIcon = getIcon('error')\n const WarningIcon = getIcon('warning')\n const TableIcon = getIcon('table')\n const ChartIcon = getIcon('measure')\n const CodeIcon = getIcon('codeBracket')\n const ShareIcon = getIcon('share')\n const CheckIcon = getIcon('check')\n const TrashIcon = getIcon('delete')\n const SparklesIcon = getIcon('sparkles')\n\n // Loading state - initial load\n const renderLoading = () => (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <div\n className=\"animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4\"\n style={{ borderBottomColor: 'var(--dc-primary)' }}\n />\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">\n Executing Query...\n </div>\n <div className=\"text-xs text-dc-text-muted\">\n Running your query against the cube API\n </div>\n </div>\n </div>\n )\n\n // Error state - no previous results\n const renderError = () => (\n <div className=\"h-full flex items-center justify-center p-4\">\n <div className=\"text-center max-w-md\">\n <ErrorIcon className=\"w-12 h-12 mx-auto text-dc-error mb-4\" />\n <div className=\"text-sm font-semibold text-dc-text mb-2\">\n Query Execution Failed\n </div>\n <div className=\"text-sm text-dc-text-secondary mb-4\">\n There was an error executing your query. Please check the query and try again.\n </div>\n {executionError && (\n <div className=\"bg-dc-danger-bg border border-dc-error rounded-lg p-3 text-left\">\n <div className=\"text-xs font-mono text-dc-error break-words\">\n {executionError}\n </div>\n </div>\n )}\n </div>\n </div>\n )\n\n // Check if query has any content (pending execution)\n const hasQueryContent = !!(\n (query.measures && query.measures.length > 0) ||\n (query.dimensions && query.dimensions.length > 0) ||\n (query.timeDimensions && query.timeDimensions.length > 0)\n )\n\n // Waiting state - query built but not yet executed (debounce period)\n const renderWaiting = () => (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <div\n className=\"animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4\"\n style={{ borderBottomColor: 'var(--dc-primary)' }}\n />\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">\n Preparing Query...\n </div>\n <div className=\"text-xs text-dc-text-muted\">\n Your query will execute shortly\n </div>\n </div>\n </div>\n )\n\n // Empty state - no query built yet\n const renderEmpty = () => (\n <div className=\"h-full flex items-center justify-center pt-6\">\n <div className=\"text-center mb-16\">\n <ChartIcon className=\"w-12 h-12 mx-auto text-dc-text-muted mb-3\" />\n <div className=\"text-sm font-semibold text-dc-text-secondary mb-1\">\n No Results Yet\n </div>\n <div className=\"text-xs text-dc-text-muted mb-4\">\n Add metrics or breakdowns from the panel on the right to see results\n </div>\n {/* Prominent AI button when enabled */}\n {enableAI && onAIToggle && (\n <button\n onClick={onAIToggle}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-dc-accent hover:bg-dc-accent rounded-lg transition-colors shadow-sm\"\n >\n <SparklesIcon className=\"w-4 h-4\" />\n Analyse with AI\n </button>\n )}\n </div>\n </div>\n )\n\n // No data returned state\n const renderNoData = () => (\n <div className=\"h-full flex items-center justify-center\">\n <div className=\"text-center\">\n <SuccessIcon className=\"w-12 h-12 mx-auto text-dc-success mb-3\" />\n <div className=\"text-sm font-semibold text-dc-text mb-1\">\n Query Successful\n </div>\n <div className=\"text-xs text-dc-text-muted\">\n No data returned from the query\n </div>\n </div>\n </div>\n )\n\n // Render chart\n const renderChart = () => {\n if (!executionResults || executionResults.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <ChartIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">No data to display</div>\n <div className=\"text-xs\">Run a query to see chart visualization</div>\n </div>\n </div>\n )\n }\n\n if (!isValidChartType(chartType)) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <WarningIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">Unsupported chart type</div>\n <div className=\"text-xs\">{chartType}</div>\n </div>\n </div>\n )\n }\n\n return (\n <LazyChart\n chartType={chartType}\n data={executionResults}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n colorPalette={colorPalette}\n queryObject={query}\n height=\"100%\"\n fallback={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full\" />\n </div>\n }\n />\n )\n }\n\n // Render debug view\n const renderDebug = () => (\n <div className=\"p-4 space-y-4 overflow-auto h-full\">\n {/* Execution Error Banner (if any) */}\n {executionError && (\n <div className=\"bg-dc-danger-bg dark:bg-dc-danger-bg border border-dc-error dark:border-dc-error rounded p-3\">\n <h4 className=\"text-sm font-semibold text-dc-error dark:text-dc-error mb-1\">\n Execution Error\n </h4>\n <p className=\"text-sm text-dc-error dark:text-dc-error\">{executionError}</p>\n </div>\n )}\n\n {/* JSON Query and SQL Query in 2 columns */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {/* JSON Query */}\n <div>\n <h4 className=\"text-sm font-semibold text-dc-text mb-2\">JSON Query</h4>\n <pre className=\"bg-dc-surface-secondary border border-dc-border rounded p-3 text-xs overflow-auto max-h-64 text-dc-text-secondary\">\n {debugQuery ? JSON.stringify(debugQuery, null, 2) : 'No query'}\n </pre>\n </div>\n\n {/* Generated SQL */}\n <div>\n <h4 className=\"text-sm font-semibold text-dc-text mb-2\">Generated SQL</h4>\n {debugLoading ? (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm\">\n Loading...\n </div>\n ) : debugError ? (\n <div className=\"text-dc-error text-sm bg-dc-danger-bg dark:bg-dc-danger-bg p-3 rounded border border-dc-error dark:border-dc-error\">\n {debugError}\n </div>\n ) : debugSql ? (\n <pre className=\"bg-dc-surface-secondary border border-dc-border rounded p-3 text-xs overflow-auto max-h-64 text-dc-text-secondary font-mono whitespace-pre-wrap\">\n {debugSql.sql}\n {debugSql.params && debugSql.params.length > 0 && (\n <>\n {'\\n\\n-- Parameters:\\n'}\n {JSON.stringify(debugSql.params, null, 2)}\n </>\n )}\n </pre>\n ) : (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm\">\n Add metrics to generate SQL\n </div>\n )}\n </div>\n </div>\n\n {/* Query Analysis - full width */}\n <div>\n <h4 className=\"text-sm font-semibold text-dc-text mb-2\">Query Analysis</h4>\n {debugLoading ? (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm\">\n Loading...\n </div>\n ) : debugAnalysis ? (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded p-3\">\n <QueryAnalysisPanel analysis={debugAnalysis} />\n </div>\n ) : (\n <div className=\"bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm\">\n {debugError ? 'Analysis unavailable due to error' : 'Add metrics to see analysis'}\n </div>\n )}\n </div>\n </div>\n )\n\n // Render table\n const renderTable = () => {\n if (!executionResults || executionResults.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full text-dc-text-muted\">\n <div className=\"text-center\">\n <TableIcon className=\"w-12 h-12 mx-auto mb-3 opacity-50\" />\n <div className=\"text-sm font-semibold mb-1\">No data to display</div>\n <div className=\"text-xs\">Run a query to see table data</div>\n </div>\n </div>\n )\n }\n\n // Apply display limit\n const limitedData = executionResults.slice(0, displayLimit)\n\n return (\n <LazyChart\n chartType=\"table\"\n data={limitedData}\n colorPalette={colorPalette}\n queryObject={query}\n height=\"100%\"\n fallback={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"animate-pulse bg-dc-surface-secondary rounded w-full h-full\" />\n </div>\n }\n />\n )\n }\n\n // Overlay spinner for refreshing\n const renderOverlaySpinner = () => (\n <div className=\"absolute inset-0 flex items-center justify-center bg-dc-surface bg-opacity-75 z-10\">\n <div className=\"text-center\">\n <div\n className=\"animate-spin rounded-full h-10 w-10 border-b-2 mx-auto mb-2\"\n style={{ borderBottomColor: 'var(--dc-primary)' }}\n />\n <div className=\"text-xs text-dc-text-secondary\">Refreshing results...</div>\n </div>\n </div>\n )\n\n // Success state with data\n const renderSuccess = () => {\n if (!executionResults || executionResults.length === 0) {\n return renderNoData()\n }\n\n return (\n <div className=\"h-full flex flex-col\">\n {/* Results Header - Compact status bar */}\n <div className=\"px-4 py-2 border-b border-dc-border bg-dc-surface-secondary flex-shrink-0\">\n <div className=\"flex items-center justify-between\">\n {/* Left side: Status and row count */}\n <div className=\"flex items-center\">\n {executionStatus === 'refreshing' ? (\n <div\n className=\"w-4 h-4 mr-2 rounded-full border-b-2 animate-spin\"\n style={{ borderBottomColor: 'var(--dc-primary)' }}\n />\n ) : (\n <SuccessIcon className=\"w-4 h-4 text-dc-success mr-2\" />\n )}\n <span className=\"text-sm text-dc-text-secondary\">\n {executionResults.length} row{executionResults.length !== 1 ? 's' : ''}\n {totalRowCount !== null && totalRowCount > executionResults.length && (\n <span className=\"text-dc-text-muted\"> of {totalRowCount.toLocaleString()}</span>\n )}\n {resultsStale && (\n <span className=\"text-dc-warning ml-2\">• Results may be outdated</span>\n )}\n </span>\n </div>\n\n {/* Right side: Display limit (table only) and Debug toggle */}\n <div className=\"flex items-center gap-2\">\n {/* Display Limit (only for table view) */}\n {activeView === 'table' && !showDebug && onDisplayLimitChange && (\n <select\n value={displayLimit}\n onChange={(e) => onDisplayLimitChange(Number(e.target.value))}\n className=\"text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text focus:outline-none focus:ring-1 focus:ring-dc-primary\"\n >\n <option value={50}>50 rows</option>\n <option value={100}>100 rows</option>\n <option value={250}>250 rows</option>\n <option value={500}>500 rows</option>\n </select>\n )}\n\n {/* AI Button - positioned before palette selector */}\n {enableAI && onAIToggle && (\n <button\n onClick={onAIToggle}\n className={`flex items-center gap-1 px-2 py-1.5 text-xs font-medium rounded transition-colors ${\n isAIOpen\n ? 'text-white bg-dc-accent border border-dc-accent'\n : 'text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg'\n }`}\n title={isAIOpen ? 'Close AI assistant' : 'Analyse with AI'}\n >\n <SparklesIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Analyse with AI</span>\n </button>\n )}\n\n {/* Color Palette Selector (only when callback is provided, i.e., standalone mode) */}\n {onColorPaletteChange && (\n <ColorPaletteSelector\n currentPalette={currentPaletteName || 'default'}\n onPaletteChange={onColorPaletteChange}\n />\n )}\n\n {/* Share Button */}\n {onShareClick && (\n <button\n onClick={onShareClick}\n className={`flex items-center gap-1 px-2 py-1.5 text-xs font-medium rounded transition-colors ${\n shareButtonState === 'idle' && canShare\n ? 'text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg'\n : shareButtonState !== 'idle'\n ? 'text-dc-success dark:text-dc-success bg-dc-success-bg dark:bg-dc-success-bg border border-dc-success dark:border-dc-success'\n : 'text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed'\n }`}\n title={shareButtonState === 'idle' ? 'Share this analysis' : 'Link copied!'}\n disabled={!canShare || shareButtonState !== 'idle'}\n >\n {shareButtonState === 'idle' ? (\n <>\n <ShareIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Share</span>\n </>\n ) : shareButtonState === 'copied' ? (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n </>\n ) : (\n <>\n <CheckIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Copied!</span>\n <span className=\"hidden lg:inline text-[10px] opacity-75\">(no chart)</span>\n </>\n )}\n </button>\n )}\n\n {/* Clear Button */}\n {onClearClick && canClear && (\n <button\n onClick={onClearClick}\n className=\"flex items-center gap-1 px-2 py-1.5 text-xs font-medium text-dc-text-secondary hover:text-dc-text bg-dc-surface hover:bg-dc-surface-hover border border-dc-border rounded transition-colors\"\n title=\"Clear all query data\"\n >\n <TrashIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">Clear</span>\n </button>\n )}\n\n {/* Debug Toggle Button */}\n <button\n onClick={() => setShowDebug(!showDebug)}\n className={`p-1.5 rounded transition-colors relative ${\n showDebug\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary hover:text-dc-text hover:bg-dc-surface-hover'\n }`}\n title={showDebug ? 'Hide debug info' : 'Show debug info'}\n >\n <CodeIcon className=\"w-4 h-4\" />\n {/* Error indicator dot */}\n {(executionError || debugError) && !showDebug && (\n <span className=\"absolute -top-0.5 -right-0.5 w-2 h-2 bg-dc-danger-bg0 rounded-full\" />\n )}\n </button>\n </div>\n </div>\n\n {/* Performance Warning */}\n {totalRowCount !== null && totalRowCount > 1000 && (\n <div className=\"mt-2 bg-dc-warning-bg border border-dc-warning rounded-lg p-2 flex items-start\">\n <WarningIcon className=\"w-4 h-4 text-dc-warning mr-2 shrink-0 mt-0.5\" />\n <div className=\"text-xs text-dc-warning\">\n <span className=\"font-semibold\">Large dataset:</span> {totalRowCount.toLocaleString()} rows.\n Consider adding filters to improve performance.\n </div>\n </div>\n )}\n </div>\n\n {/* Results Content */}\n <div className=\"flex-1 min-h-0 relative overflow-auto\">\n {showDebug ? (\n renderDebug()\n ) : activeView === 'chart' ? (\n <div className=\"p-4 h-full\">{renderChart()}</div>\n ) : (\n <div className=\"h-full\">{renderTable()}</div>\n )}\n </div>\n\n {/* View Toggle - Below content, centered */}\n {!showDebug && (\n <div className=\"px-4 py-3 border-t border-dc-border bg-dc-surface flex justify-center flex-shrink-0\">\n <div className=\"flex items-center bg-dc-surface-secondary border border-dc-border rounded-md overflow-hidden\">\n <button\n onClick={() => hasMetrics && onActiveViewChange('chart')}\n disabled={!hasMetrics}\n className={`flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium transition-colors ${\n activeView === 'chart'\n ? 'bg-dc-primary text-white'\n : !hasMetrics\n ? 'text-dc-text-disabled bg-dc-surface-tertiary cursor-not-allowed'\n : 'text-dc-text-secondary hover:bg-dc-surface-hover'\n }`}\n title={hasMetrics ? 'Chart view' : 'Add metrics to enable chart view'}\n >\n <ChartIcon className=\"w-4 h-4\" />\n Chart\n </button>\n <button\n onClick={() => onActiveViewChange('table')}\n className={`flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium transition-colors ${\n activeView === 'table'\n ? 'bg-dc-primary text-white'\n : 'text-dc-text-secondary hover:bg-dc-surface-hover'\n }`}\n title=\"Table view\"\n >\n <TableIcon className=\"w-4 h-4\" />\n Table\n </button>\n </div>\n </div>\n )}\n </div>\n )\n }\n\n // Determine what to render based on execution status\n const hasResults = executionResults !== null\n\n // Don't show results if we're in idle state with no query content (cleared state)\n const shouldShowResults = hasResults && (executionStatus !== 'idle' || hasQueryContent)\n\n return (\n <div className=\"h-full min-h-[400px] flex flex-col bg-dc-surface relative\">\n {/* Main content */}\n {executionStatus === 'idle' && !hasQueryContent && renderEmpty()}\n {executionStatus === 'idle' && hasQueryContent && !hasResults && renderWaiting()}\n {executionStatus === 'loading' && !hasResults && renderLoading()}\n {executionStatus === 'error' && !hasResults && renderError()}\n {(executionStatus === 'success' || shouldShowResults) && renderSuccess()}\n\n {/* Overlay states */}\n {(executionStatus === 'loading' || executionStatus === 'refreshing') && hasResults && renderOverlaySpinner()}\n </div>\n )\n})\n\nexport default AnalysisResultsPanel\n","/**\n * MetricItemCard Component\n *\n * Displays a single metric item with remove button.\n */\n\nimport { memo } from 'react'\nimport type { MetricItemCardProps } from './types'\nimport { getIcon, getMeasureTypeIcon } from '../../icons'\n\n/**\n * MetricItemCard displays a selected metric with:\n * - Field icon based on measure type\n * - Field title or full name\n * - Sort toggle button (visible on hover, or always visible when sorted)\n * - Remove button (visible on hover)\n * - Drag handle for reordering\n */\nconst MetricItemCard = memo(function MetricItemCard({\n metric,\n fieldMeta,\n onRemove,\n sortDirection,\n sortPriority,\n onToggleSort,\n index,\n isDragging,\n onDragStart,\n onDragEnd\n}: MetricItemCardProps) {\n const CloseIcon = getIcon('close')\n const ChevronUpIcon = getIcon('chevronUp')\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronUpDownIcon = getIcon('chevronUpDown')\n\n // Get the appropriate icon based on measure type\n const measureType = fieldMeta?.type || 'count'\n const MeasureIcon = getMeasureTypeIcon(measureType) || getIcon('measure')\n\n // Get display title - prefer shortTitle, then title, then field name\n const displayTitle = fieldMeta?.shortTitle || fieldMeta?.title || metric.field.split('.').pop() || metric.field\n\n // Get the cube name from the field\n const cubeName = metric.field.split('.')[0]\n\n // Get sort icon based on direction\n const getSortIcon = () => {\n switch (sortDirection) {\n case 'asc':\n return ChevronUpIcon ? <ChevronUpIcon className=\"w-4 h-4\" /> : '↑'\n case 'desc':\n return ChevronDownIcon ? <ChevronDownIcon className=\"w-4 h-4\" /> : '↓'\n default:\n return ChevronUpDownIcon ? <ChevronUpDownIcon className=\"w-4 h-4\" /> : '⇅'\n }\n }\n\n // Get sort tooltip\n const getSortTooltip = () => {\n switch (sortDirection) {\n case 'asc':\n return 'Sorted ascending (click for descending)'\n case 'desc':\n return 'Sorted descending (click to remove)'\n default:\n return 'Click to sort ascending'\n }\n }\n\n // Check if drag/drop is enabled\n const isDraggable = typeof index === 'number' && onDragStart && onDragEnd\n\n return (\n <div\n className={`flex items-center gap-2 p-2 bg-dc-surface-secondary rounded-lg group hover:bg-dc-surface-tertiary transition-all duration-150 ${\n isDraggable ? 'cursor-grab active:cursor-grabbing' : ''\n } ${isDragging ? 'opacity-30' : ''}`}\n draggable={isDraggable ? true : undefined}\n onDragStart={isDraggable ? (e) => onDragStart(e, index) : undefined}\n onDragEnd={isDraggable ? onDragEnd : undefined}\n >\n {/* Icon - colored background matching field selector */}\n <span className=\"w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0\">\n {MeasureIcon && <MeasureIcon className=\"w-4 h-4\" />}\n </span>\n\n {/* Field Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm text-dc-text truncate\" title={metric.field}>\n {displayTitle}\n </div>\n <div className=\"text-xs text-dc-text-muted truncate\">\n {cubeName}\n </div>\n </div>\n\n {/* Sort Button */}\n {onToggleSort && (\n <button\n onClick={onToggleSort}\n className={`p-1 transition-opacity flex-shrink-0 flex items-center gap-0.5 ${\n sortDirection\n ? 'opacity-100 text-dc-primary'\n : 'opacity-100 sm:opacity-0 sm:group-hover:opacity-100 text-dc-text-muted hover:text-dc-primary'\n }`}\n title={getSortTooltip()}\n >\n {getSortIcon()}\n {sortDirection && sortPriority && (\n <span className=\"text-xs font-medium\">({sortPriority})</span>\n )}\n </button>\n )}\n\n {/* Remove Button */}\n <button\n onClick={onRemove}\n className=\"p-1 text-dc-text-muted hover:text-dc-danger opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity flex-shrink-0\"\n title=\"Remove metric\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n )\n})\n\nexport default MetricItemCard\n","/**\n * MetricsSection Component\n *\n * Displays the Metrics section in the query panel with expandable list of metrics.\n */\n\nimport { useMemo, useState, useCallback, useRef, memo, DragEvent } from 'react'\nimport type { MetricsSectionProps } from './types'\nimport type { MetaField } from '../../shared/types'\nimport MetricItemCard from './MetricItemCard'\nimport SectionHeading from './SectionHeading'\nimport { getIcon } from '../../icons'\n\n// Get icon once at module level to avoid recreating\nconst AddIcon = getIcon('add')\n\n/**\n * Find field metadata by field name\n */\nfunction findFieldMeta(fieldName: string, schema: MetricsSectionProps['schema']): MetaField | null {\n if (!schema?.cubes) return null\n\n const [cubeName] = fieldName.split('.')\n const cube = schema.cubes.find((c) => c.name === cubeName)\n if (!cube) return null\n\n return cube.measures?.find((m) => m.name === fieldName) || null\n}\n\n/**\n * Get next sort direction in the cycle: null -> asc -> desc -> null\n */\nfunction getNextSortDirection(current: 'asc' | 'desc' | null): 'asc' | 'desc' | null {\n switch (current) {\n case null:\n return 'asc'\n case 'asc':\n return 'desc'\n case 'desc':\n return null\n default:\n return 'asc'\n }\n}\n\n/**\n * MetricsSection displays a collapsible section with:\n * - Header with title and add button\n * - List of selected metrics (using MetricItemCard)\n * - Drag/drop reordering support\n */\nconst MetricsSection = memo(function MetricsSection({\n metrics,\n schema,\n onAdd,\n onRemove,\n order,\n onOrderChange,\n onReorder\n}: MetricsSectionProps) {\n\n // Drag/drop state\n const [draggedIndex, setDraggedIndex] = useState<number | null>(null)\n const [dropTargetIndex, setDropTargetIndex] = useState<number | null>(null) // Index where item will be inserted\n\n // Use refs to track current values for use in drop handler (avoids stale closure issues)\n const draggedIndexRef = useRef<number | null>(null)\n const dropTargetIndexRef = useRef<number | null>(null)\n\n // Get the ordered keys to calculate priority\n const orderKeys = useMemo(() => order ? Object.keys(order) : [], [order])\n\n // Resolve field metadata for all metrics with sort info\n const metricsWithMeta = useMemo(() => {\n return metrics.map((metric, index) => {\n const sortDirection = order?.[metric.field] || null\n const sortPriority = sortDirection ? orderKeys.indexOf(metric.field) + 1 : undefined\n return {\n metric,\n fieldMeta: findFieldMeta(metric.field, schema),\n sortDirection,\n sortPriority,\n index\n }\n })\n }, [metrics, schema, order, orderKeys])\n\n // Track drag clone for cleanup\n const dragCloneRef = useRef<HTMLElement | null>(null)\n\n // Drag handlers\n const handleDragStart = useCallback((e: DragEvent, index: number) => {\n setDraggedIndex(index)\n draggedIndexRef.current = index\n e.dataTransfer.effectAllowed = 'move'\n e.dataTransfer.setData('text/plain', JSON.stringify({ type: 'metric', index, field: metrics[index].field }))\n\n // Create a semi-transparent, slightly tilted drag image\n const target = e.currentTarget as HTMLElement\n const clone = target.cloneNode(true) as HTMLElement\n clone.style.cssText = `\n position: absolute;\n top: -9999px;\n left: -9999px;\n width: ${target.offsetWidth}px;\n opacity: 0.7;\n transform: rotate(2deg);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n pointer-events: none;\n `\n document.body.appendChild(clone)\n dragCloneRef.current = clone\n\n // Calculate offset from click position\n const rect = target.getBoundingClientRect()\n const offsetX = e.clientX - rect.left\n const offsetY = e.clientY - rect.top\n e.dataTransfer.setDragImage(clone, offsetX, offsetY)\n }, [metrics])\n\n const handleDragEnd = useCallback(() => {\n setDraggedIndex(null)\n setDropTargetIndex(null)\n draggedIndexRef.current = null\n dropTargetIndexRef.current = null\n // Clean up the drag clone\n if (dragCloneRef.current) {\n document.body.removeChild(dragCloneRef.current)\n dragCloneRef.current = null\n }\n }, [])\n\n // Handle drag over an item - determine drop position based on mouse position\n const handleItemDragOver = useCallback((e: DragEvent, itemIndex: number) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Only process if we're dragging from this section\n const currentDraggedIndex = draggedIndexRef.current\n if (currentDraggedIndex === null) return\n\n // Determine if we're in the top or bottom half of the item\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseY = e.clientY - rect.top\n const isTopHalf = mouseY < rect.height / 2\n\n // Calculate target index based on position\n let targetIndex = isTopHalf ? itemIndex : itemIndex + 1\n\n // Don't set drop target if it would result in no movement\n if (targetIndex === currentDraggedIndex || targetIndex === currentDraggedIndex + 1) {\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n } else {\n setDropTargetIndex(targetIndex)\n dropTargetIndexRef.current = targetIndex\n }\n }, [])\n\n // Handle drop on an item\n const handleItemDrop = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Use refs to get current values (avoids stale closure issues)\n const currentDraggedIndex = draggedIndexRef.current\n const currentDropTargetIndex = dropTargetIndexRef.current\n\n // Reset visual state immediately\n setDraggedIndex(null)\n setDropTargetIndex(null)\n draggedIndexRef.current = null\n dropTargetIndexRef.current = null\n\n // Validate and reorder - use refs directly, no dataTransfer parsing needed\n if (currentDraggedIndex === null || currentDropTargetIndex === null || !onReorder) {\n return\n }\n\n // Adjust target index when dragging down (after splice, indices shift)\n const adjustedTarget = currentDropTargetIndex > currentDraggedIndex\n ? currentDropTargetIndex - 1\n : currentDropTargetIndex\n\n if (adjustedTarget !== currentDraggedIndex) {\n onReorder(currentDraggedIndex, adjustedTarget)\n }\n }, [onReorder])\n\n // Clear drop target when leaving the section\n const handleSectionDragLeave = useCallback((e: DragEvent) => {\n const relatedTarget = e.relatedTarget as HTMLElement | null\n if (!relatedTarget || !e.currentTarget.contains(relatedTarget)) {\n setDropTargetIndex(null)\n }\n }, [])\n\n // Calculate if an item should be shifted to make room for the drop\n const getItemTransform = useCallback((itemIndex: number): string => {\n if (draggedIndex === null || dropTargetIndex === null) return ''\n\n // Gap size in pixels\n const gapSize = 40\n\n // If this is the dragged item, no transform needed (it's already faded)\n if (itemIndex === draggedIndex) return ''\n\n // Items at or after drop target need to shift down\n // But we need to account for the dragged item's position\n if (draggedIndex < dropTargetIndex) {\n // Dragging down: items between dragged+1 and dropTarget-1 shift up\n if (itemIndex > draggedIndex && itemIndex < dropTargetIndex) {\n return '' // No gap needed, item stays in place\n }\n // Item at dropTarget-1 position should show gap after it\n if (itemIndex === dropTargetIndex - 1) {\n return `translateY(-${gapSize / 2}px)` // Shift up to make room\n }\n if (itemIndex >= dropTargetIndex) {\n return `translateY(${gapSize / 2}px)` // Shift down\n }\n } else {\n // Dragging up: items from dropTarget to draggedIndex-1 shift down\n if (itemIndex >= dropTargetIndex && itemIndex < draggedIndex) {\n return `translateY(${gapSize / 2}px)` // Shift down to make room\n }\n }\n\n return ''\n }, [draggedIndex, dropTargetIndex])\n\n // Determine if gap indicator should show at a position\n const shouldShowGapIndicator = useCallback((itemIndex: number): boolean => {\n if (draggedIndex === null || dropTargetIndex === null) return false\n\n // Show indicator before the item that matches dropTargetIndex\n return itemIndex === dropTargetIndex\n }, [draggedIndex, dropTargetIndex])\n\n return (\n <div>\n {/* Section Header - entire row is clickable */}\n <button\n onClick={onAdd}\n className=\"flex items-center justify-between mb-3 w-full py-1 px-2 -ml-2 rounded-lg hover:bg-dc-primary/10 transition-colors group\"\n title=\"Add metric\"\n >\n <SectionHeading>Metrics</SectionHeading>\n <AddIcon className=\"w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors\" />\n </button>\n\n {/* Metrics List */}\n <div\n className=\"space-y-2\"\n onDragLeave={onReorder ? handleSectionDragLeave : undefined}\n onDragOver={onReorder ? (e) => e.preventDefault() : undefined}\n onDrop={onReorder ? handleItemDrop : undefined}\n >\n {metricsWithMeta.map(({ metric, fieldMeta, sortDirection, sortPriority, index }) => {\n const transform = getItemTransform(index)\n const showGapBefore = shouldShowGapIndicator(index)\n\n return (\n <div\n key={metric.id}\n className=\"relative\"\n style={{\n transform,\n transition: draggedIndex !== null ? 'transform 0.15s ease-out' : 'none'\n }}\n onDragOver={onReorder ? (e) => handleItemDragOver(e, index) : undefined}\n onDrop={onReorder ? handleItemDrop : undefined}\n >\n {/* Gap indicator line - shows where item will be inserted */}\n {showGapBefore && (\n <div className=\"absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10\">\n <div className=\"h-0.5 w-full bg-dc-primary rounded-full\" />\n </div>\n )}\n <MetricItemCard\n metric={metric}\n fieldMeta={fieldMeta}\n onRemove={() => onRemove(metric.id)}\n sortDirection={sortDirection}\n sortPriority={sortPriority}\n onToggleSort={onOrderChange ? () => {\n const nextDirection = getNextSortDirection(sortDirection)\n onOrderChange(metric.field, nextDirection)\n } : undefined}\n index={index}\n isDragging={draggedIndex === index}\n onDragStart={onReorder ? handleDragStart : undefined}\n onDragEnd={onReorder ? handleDragEnd : undefined}\n />\n </div>\n )\n })}\n {/* Gap indicator after the last item - shows when dropping at end */}\n {onReorder && draggedIndex !== null && dropTargetIndex === metrics.length && (\n <div className=\"relative h-2\">\n <div className=\"absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10\">\n <div className=\"h-0.5 w-full bg-dc-primary rounded-full\" />\n </div>\n </div>\n )}\n {/* Handle drop at the end of the list */}\n {onReorder && metrics.length > 0 && draggedIndex !== null && (\n <div\n className=\"h-8\"\n onDragOver={(e) => {\n e.preventDefault()\n // Set drop target to end of list\n const lastIndex = metrics.length\n const currentDraggedIndex = draggedIndexRef.current\n if (dropTargetIndexRef.current !== lastIndex && currentDraggedIndex !== lastIndex - 1) {\n setDropTargetIndex(lastIndex)\n dropTargetIndexRef.current = lastIndex\n }\n }}\n onDrop={handleItemDrop}\n />\n )}\n </div>\n </div>\n )\n})\n\nexport default MetricsSection\n","/**\n * Type definitions for AnalysisBuilder components\n *\n * AnalysisBuilder is a redesigned query builder with:\n * - Results panel on the left (large)\n * - Query builder panel on the right\n * - Search-based field selection via modal\n * - Sections: Metrics (measures), Breakdown (dimensions), Filters\n */\n\nimport type { MouseEvent, DragEvent } from 'react'\nimport type {\n CubeQuery,\n Filter,\n ChartType,\n ChartAxisConfig,\n ChartDisplayConfig\n} from '../../types'\nimport type { ColorPalette } from '../../utils/colorPalettes'\nimport type { MetaResponse, MetaField, MetaCube, QueryAnalysis } from '../../shared/types'\nimport type { ChartAvailabilityMap } from '../../shared/chartDefaults'\n\n// Re-export types from shared for convenience\nexport type { MetaResponse, MetaField, MetaCube, QueryAnalysis }\n\n// ============================================================================\n// Metric and Breakdown Items\n// ============================================================================\n\n/**\n * A selected metric (measure) with a letter label (A, B, C, ...)\n */\nexport interface MetricItem {\n /** Unique identifier for this metric selection */\n id: string\n /** Full field name, e.g., \"Employees.count\" */\n field: string\n /** Display label (A, B, C, ...) */\n label: string\n}\n\n/**\n * A selected breakdown (dimension or time dimension)\n */\nexport interface BreakdownItem {\n /** Unique identifier for this breakdown selection */\n id: string\n /** Full field name, e.g., \"Employees.departmentName\" */\n field: string\n /** Granularity for time dimensions (day, week, month, quarter, year) */\n granularity?: string\n /** Whether this is a time dimension */\n isTimeDimension: boolean\n}\n\n// ============================================================================\n// State Types\n// ============================================================================\n\n/** Validation status for query building */\nexport type ValidationStatus = 'idle' | 'validating' | 'valid' | 'invalid'\n\n/** Execution status for query results */\nexport type ExecutionStatus = 'idle' | 'loading' | 'refreshing' | 'success' | 'error'\n\n/**\n * Main state for the AnalysisBuilder component\n */\nexport interface AnalysisBuilderState {\n /** Selected metrics (measures) */\n metrics: MetricItem[]\n /** Selected breakdowns (dimensions and time dimensions) */\n breakdowns: BreakdownItem[]\n /** Applied filters */\n filters: Filter[]\n\n // Validation state\n validationStatus: ValidationStatus\n validationError: string | null\n\n // Execution state\n executionStatus: ExecutionStatus\n executionResults: any[] | null\n executionError: string | null\n totalRowCount: number | null\n\n // Stale indicator (query changed since last execution)\n resultsStale: boolean\n}\n\n/**\n * State for the AI query generation panel\n */\nexport interface AIState {\n /** Whether the AI panel is open */\n isOpen: boolean\n /** User's natural language prompt */\n userPrompt: string\n /** Whether a query is being generated */\n isGenerating: boolean\n /** Error message from generation */\n error: string | null\n /** Whether the AI has generated a query that's been loaded */\n hasGeneratedQuery: boolean\n /** Snapshot of state before AI was opened (for undo) */\n previousState: {\n metrics: MetricItem[]\n breakdowns: BreakdownItem[]\n filters: Filter[]\n chartType: ChartType\n chartConfig: ChartAxisConfig\n displayConfig: ChartDisplayConfig\n } | null\n}\n\n// ============================================================================\n// Field Search Modal Types\n// ============================================================================\n\n/**\n * Mode for the field search modal - determines which field types are shown\n */\nexport type FieldSearchMode = 'metrics' | 'breakdown' | 'filter'\n\n/**\n * Field type categorization\n */\nexport type FieldType = 'measure' | 'dimension' | 'timeDimension'\n\n/**\n * A field option for display in the search modal\n */\nexport interface FieldOption {\n /** Full field name, e.g., \"Employees.count\" */\n name: string\n /** Display title */\n title: string\n /** Short title for compact display */\n shortTitle: string\n /** Field type (count, sum, avg, string, time, number, etc.) */\n type: string\n /** Optional description */\n description?: string\n /** Parent cube name */\n cubeName: string\n /** Categorized field type */\n fieldType: FieldType\n}\n\n/**\n * Props for the FieldSearchModal component\n */\nexport interface FieldSearchModalProps {\n /** Whether the modal is open */\n isOpen: boolean\n /** Callback to close the modal */\n onClose: () => void\n /** Callback when a field is selected. keepOpen=true when shift-click multi-selecting */\n onSelect: (field: MetaField, fieldType: FieldType, cubeName: string, keepOpen?: boolean) => void\n /** Mode determines which field types to show */\n mode: FieldSearchMode\n /** Schema metadata */\n schema: MetaResponse | null\n /** Already selected field names (to show checkmarks) */\n selectedFields: string[]\n /** Recently used field names */\n recentFields?: string[]\n}\n\n/**\n * Props for the FieldSearchItem component\n */\nexport interface FieldSearchItemProps {\n /** Field data */\n field: FieldOption\n /** Whether this field is selected */\n isSelected: boolean\n /** Whether this field is focused/highlighted */\n isFocused: boolean\n /** Click handler - receives mouse event for shift-click multi-select */\n onClick: (e: MouseEvent) => void\n /** Mouse enter handler (for detail panel) */\n onMouseEnter: () => void\n}\n\n/**\n * Props for the FieldDetailPanel component\n */\nexport interface FieldDetailPanelProps {\n /** Field to display details for */\n field: FieldOption | null\n}\n\n// ============================================================================\n// Panel Component Props\n// ============================================================================\n\n/**\n * Tab options for the query panel\n */\nexport type QueryPanelTab = 'query' | 'chart' | 'display'\n\n/**\n * Props for the AnalysisQueryPanel component\n */\nexport interface AnalysisQueryPanelProps {\n /** Selected metrics */\n metrics: MetricItem[]\n /** Selected breakdowns */\n breakdowns: BreakdownItem[]\n /** Applied filters */\n filters: Filter[]\n /** Schema metadata */\n schema: MetaResponse | null\n\n /** Currently active tab */\n activeTab: QueryPanelTab\n /** Callback when active tab changes */\n onActiveTabChange: (tab: QueryPanelTab) => void\n\n // Metric actions\n onAddMetric: () => void\n onRemoveMetric: (id: string) => void\n onReorderMetrics?: (fromIndex: number, toIndex: number) => void\n\n // Breakdown actions\n onAddBreakdown: () => void\n onRemoveBreakdown: (id: string) => void\n onBreakdownGranularityChange: (id: string, granularity: string) => void\n onReorderBreakdowns?: (fromIndex: number, toIndex: number) => void\n\n // Filter actions\n onFiltersChange: (filters: Filter[]) => void\n onDropFieldToFilter?: (field: string) => void\n\n // Sorting\n /** Current sort order */\n order?: Record<string, 'asc' | 'desc'>\n /** Callback when sort order changes */\n onOrderChange: (fieldName: string, direction: 'asc' | 'desc' | null) => void\n\n // Chart configuration\n chartType: ChartType\n chartConfig: ChartAxisConfig\n displayConfig: ChartDisplayConfig\n /** Color palette for display config options */\n colorPalette?: ColorPalette\n /** Map of chart type availability for disabling unavailable chart types */\n chartAvailability?: ChartAvailabilityMap\n onChartTypeChange: (type: ChartType) => void\n onChartConfigChange: (config: ChartAxisConfig) => void\n onDisplayConfigChange: (config: ChartDisplayConfig) => void\n\n // Validation state (for showing errors)\n validationStatus: ValidationStatus\n validationError: string | null\n}\n\n/**\n * Props for the AnalysisResultsPanel component\n */\nexport interface AnalysisResultsPanelProps {\n /** Current execution status */\n executionStatus: ExecutionStatus\n /** Execution results (raw data) */\n executionResults: any[] | null\n /** Execution error message */\n executionError: string | null\n /** Total row count (before limit) */\n totalRowCount: number | null\n /** Whether results are stale (query changed) */\n resultsStale: boolean\n\n /** Chart type for visualization */\n chartType: ChartType\n /** Chart axis configuration */\n chartConfig: ChartAxisConfig\n /** Chart display configuration */\n displayConfig: ChartDisplayConfig\n /** Color palette for charts */\n colorPalette?: ColorPalette\n /** Current palette name (for selector) */\n currentPaletteName?: string\n /** Callback when color palette changes (shows selector when provided) */\n onColorPaletteChange?: (paletteName: string) => void\n\n /** Current query object (for annotation/metadata) */\n query: CubeQuery\n /** Schema metadata */\n schema: MetaResponse | null\n\n /** Active view (table or chart) */\n activeView: 'table' | 'chart'\n /** Callback when active view changes */\n onActiveViewChange: (view: 'table' | 'chart') => void\n\n /** Display limit for table */\n displayLimit: number\n /** Callback when display limit changes */\n onDisplayLimitChange: (limit: number) => void\n\n /** Whether the query has metrics (measures) - needed to enable/disable chart view */\n hasMetrics: boolean\n\n // Debug information (from dry-run)\n debugQuery?: CubeQuery | null\n debugSql?: { sql: string; params: any[] } | null\n debugAnalysis?: QueryAnalysis | null\n debugLoading?: boolean\n debugError?: string | null\n\n // Share functionality\n onShareClick?: () => void\n canShare?: boolean\n shareButtonState?: 'idle' | 'copied' | 'copied-no-chart'\n\n // Clear functionality\n onClearClick?: () => void\n canClear?: boolean\n\n // AI functionality\n enableAI?: boolean\n isAIOpen?: boolean\n onAIToggle?: () => void\n}\n\n// ============================================================================\n// Section Component Props\n// ============================================================================\n\n/**\n * Props for the MetricsSection component\n */\nexport interface MetricsSectionProps {\n /** Selected metrics */\n metrics: MetricItem[]\n /** Schema for resolving field titles */\n schema: MetaResponse | null\n /** Add metric handler */\n onAdd: () => void\n /** Remove metric handler */\n onRemove: (id: string) => void\n /** Whether the section is expanded */\n isExpanded?: boolean\n /** Toggle expansion */\n onToggleExpanded?: () => void\n /** Current sort order */\n order?: Record<string, 'asc' | 'desc'>\n /** Callback when sort order changes */\n onOrderChange?: (fieldName: string, direction: 'asc' | 'desc' | null) => void\n /** Callback when metrics are reordered via drag/drop */\n onReorder?: (fromIndex: number, toIndex: number) => void\n /** Callback when a metric is dragged to the filter section */\n onDragToFilter?: (field: string) => void\n}\n\n/**\n * Props for the BreakdownSection component\n */\nexport interface BreakdownSectionProps {\n /** Selected breakdowns */\n breakdowns: BreakdownItem[]\n /** Schema for resolving field titles */\n schema: MetaResponse | null\n /** Add breakdown handler */\n onAdd: () => void\n /** Remove breakdown handler */\n onRemove: (id: string) => void\n /** Change granularity for time dimension */\n onGranularityChange: (id: string, granularity: string) => void\n /** Whether the section is expanded */\n isExpanded?: boolean\n /** Toggle expansion */\n onToggleExpanded?: () => void\n /** Current sort order */\n order?: Record<string, 'asc' | 'desc'>\n /** Callback when sort order changes */\n onOrderChange?: (fieldName: string, direction: 'asc' | 'desc' | null) => void\n /** Callback when breakdowns are reordered via drag/drop */\n onReorder?: (fromIndex: number, toIndex: number) => void\n /** Callback when a breakdown is dragged to the filter section */\n onDragToFilter?: (field: string) => void\n}\n\n/**\n * Props for MetricItemCard component\n */\nexport interface MetricItemCardProps {\n /** Metric item data */\n metric: MetricItem\n /** Field metadata (for title, description) */\n fieldMeta: MetaField | null\n /** Remove handler */\n onRemove: () => void\n /** Current sort direction for this field */\n sortDirection?: 'asc' | 'desc' | null\n /** Sort priority (1, 2, 3...) if sorted */\n sortPriority?: number\n /** Toggle sort handler */\n onToggleSort?: () => void\n /** Index in the list (for drag/drop) */\n index?: number\n /** Whether this item is being dragged */\n isDragging?: boolean\n /** Whether dragging over this item */\n isDragOver?: boolean\n /** Drag start handler */\n onDragStart?: (e: DragEvent, index: number) => void\n /** Drag over handler */\n onDragOver?: (e: DragEvent, index: number) => void\n /** Drop handler */\n onDrop?: (e: DragEvent, index: number) => void\n /** Drag end handler */\n onDragEnd?: () => void\n}\n\n/**\n * Props for BreakdownItemCard component\n */\nexport interface BreakdownItemCardProps {\n /** Breakdown item data */\n breakdown: BreakdownItem\n /** Field metadata (for title, description) */\n fieldMeta: MetaField | null\n /** Remove handler */\n onRemove: () => void\n /** Granularity change handler (for time dimensions) */\n onGranularityChange?: (granularity: string) => void\n /** Current sort direction for this field */\n sortDirection?: 'asc' | 'desc' | null\n /** Sort priority (1, 2, 3...) if sorted */\n sortPriority?: number\n /** Toggle sort handler */\n onToggleSort?: () => void\n /** Index in the list (for drag/drop) */\n index?: number\n /** Whether this item is being dragged */\n isDragging?: boolean\n /** Whether dragging over this item */\n isDragOver?: boolean\n /** Drag start handler */\n onDragStart?: (e: DragEvent, index: number) => void\n /** Drag over handler */\n onDragOver?: (e: DragEvent, index: number) => void\n /** Drop handler */\n onDrop?: (e: DragEvent, index: number) => void\n /** Drag end handler */\n onDragEnd?: () => void\n}\n\n// ============================================================================\n// Main Component Props\n// ============================================================================\n\n/**\n * Props for the main AnalysisBuilder component\n */\nexport interface AnalysisBuilderProps {\n /** Additional CSS classes */\n className?: string\n /** Maximum height for the component (e.g., '800px', '100vh', 'calc(100vh - 64px)') */\n maxHeight?: string\n /** Initial query to load */\n initialQuery?: CubeQuery\n /** Initial chart configuration (for editing existing portlets) */\n initialChartConfig?: {\n chartType?: ChartType\n chartConfig?: ChartAxisConfig\n displayConfig?: ChartDisplayConfig\n }\n /** Initial data to display (avoids re-fetching when editing existing portlets) */\n initialData?: any[]\n /** Color palette for chart visualization */\n colorPalette?: ColorPalette\n /** Disable localStorage persistence */\n disableLocalStorage?: boolean\n /** Hide settings button */\n hideSettings?: boolean\n /** Callback when query changes (for modal integration) */\n onQueryChange?: (query: CubeQuery) => void\n /** Callback when chart config changes */\n onChartConfigChange?: (config: { chartType: ChartType; chartConfig: ChartAxisConfig; displayConfig: ChartDisplayConfig }) => void\n}\n\n/**\n * Ref interface for AnalysisBuilder (for external access)\n */\nexport interface AnalysisBuilderRef {\n /** Get the current query object */\n getCurrentQuery: () => CubeQuery\n /** Get current chart configuration */\n getChartConfig: () => { chartType: ChartType; chartConfig: ChartAxisConfig; displayConfig: ChartDisplayConfig }\n /** Execute the current query */\n executeQuery: () => void\n /** Clear the current query */\n clearQuery: () => void\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\n/**\n * Local storage state shape for persistence\n */\nexport interface AnalysisBuilderStorageState {\n metrics: MetricItem[]\n breakdowns: BreakdownItem[]\n filters: Filter[]\n order?: Record<string, 'asc' | 'desc'>\n chartType: ChartType\n chartConfig: ChartAxisConfig\n displayConfig: ChartDisplayConfig\n activeView: 'table' | 'chart'\n}\n\n/**\n * Recent fields storage shape\n */\nexport interface RecentFieldsStorage {\n metrics: string[]\n breakdowns: string[]\n}\n\n/**\n * Time granularity options\n */\nexport const TIME_GRANULARITIES = [\n { value: 'hour', label: 'Hour' },\n { value: 'day', label: 'Day' },\n { value: 'week', label: 'Week' },\n { value: 'month', label: 'Month' },\n { value: 'quarter', label: 'Quarter' },\n { value: 'year', label: 'Year' }\n] as const\n\nexport type TimeGranularity = typeof TIME_GRANULARITIES[number]['value']\n","/**\n * BreakdownItemCard Component\n *\n * Displays a single breakdown (dimension) item with optional granularity selector.\n */\n\nimport { memo } from 'react'\nimport type { BreakdownItemCardProps, TimeGranularity } from './types'\nimport { TIME_GRANULARITIES } from './types'\nimport { getIcon } from '../../icons'\n\n/**\n * BreakdownItemCard displays a selected breakdown with:\n * - Field icon (dimension or time dimension)\n * - Field title or full name\n * - Granularity dropdown (for time dimensions)\n * - Sort toggle button (visible on hover, or always visible when sorted)\n * - Remove button (visible on hover)\n * - Drag handle for reordering\n */\nconst BreakdownItemCard = memo(function BreakdownItemCard({\n breakdown,\n fieldMeta,\n onRemove,\n onGranularityChange,\n sortDirection,\n sortPriority,\n onToggleSort,\n index,\n isDragging,\n onDragStart,\n onDragEnd\n}: BreakdownItemCardProps) {\n const DimensionIcon = getIcon('dimension')\n const TimeIcon = getIcon('timeDimension')\n const CloseIcon = getIcon('close')\n const ChevronUpIcon = getIcon('chevronUp')\n const ChevronDownIcon = getIcon('chevronDown')\n const ChevronUpDownIcon = getIcon('chevronUpDown')\n\n // Get display title - prefer shortTitle, then title, then field name\n const displayTitle = fieldMeta?.shortTitle || fieldMeta?.title || breakdown.field.split('.').pop() || breakdown.field\n\n // Get the cube name from the field\n const cubeName = breakdown.field.split('.')[0]\n\n // Choose icon based on dimension type\n const Icon = breakdown.isTimeDimension ? TimeIcon : DimensionIcon\n\n // Get sort icon based on direction\n const getSortIcon = () => {\n switch (sortDirection) {\n case 'asc':\n return ChevronUpIcon ? <ChevronUpIcon className=\"w-4 h-4\" /> : '↑'\n case 'desc':\n return ChevronDownIcon ? <ChevronDownIcon className=\"w-4 h-4\" /> : '↓'\n default:\n return ChevronUpDownIcon ? <ChevronUpDownIcon className=\"w-4 h-4\" /> : '⇅'\n }\n }\n\n // Get sort tooltip\n const getSortTooltip = () => {\n switch (sortDirection) {\n case 'asc':\n return 'Sorted ascending (click for descending)'\n case 'desc':\n return 'Sorted descending (click to remove)'\n default:\n return 'Click to sort ascending'\n }\n }\n\n // Check if drag/drop is enabled\n const isDraggable = typeof index === 'number' && onDragStart && onDragEnd\n\n return (\n <div\n className={`flex items-center gap-2 p-2 bg-dc-surface-secondary rounded-lg group hover:bg-dc-surface-tertiary transition-all duration-150 ${\n isDraggable ? 'cursor-grab active:cursor-grabbing' : ''\n } ${isDragging ? 'opacity-30' : ''}`}\n draggable={isDraggable ? true : undefined}\n onDragStart={isDraggable ? (e) => onDragStart(e, index) : undefined}\n onDragEnd={isDraggable ? onDragEnd : undefined}\n >\n {/* Icon - colored background matching field selector */}\n <span className={`w-6 h-6 flex items-center justify-center rounded flex-shrink-0 ${\n breakdown.isTimeDimension\n ? 'bg-dc-time-dimension text-dc-time-dimension-text'\n : 'bg-dc-dimension text-dc-dimension-text'\n }`}>\n <Icon className=\"w-4 h-4\" />\n </span>\n\n {/* Field Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm text-dc-text truncate\" title={breakdown.field}>\n {displayTitle}\n </div>\n <div className=\"text-xs text-dc-text-muted truncate\">\n {cubeName}\n </div>\n </div>\n\n {/* Granularity Selector (for time dimensions) */}\n {breakdown.isTimeDimension && onGranularityChange && (\n <select\n value={breakdown.granularity || 'day'}\n onChange={(e) => onGranularityChange(e.target.value as TimeGranularity)}\n onClick={(e) => e.stopPropagation()}\n className=\"text-xs bg-dc-surface border border-dc-border rounded px-2 py-1 text-dc-text focus:outline-none focus:ring-1 focus:ring-dc-primary flex-shrink-0\"\n >\n {TIME_GRANULARITIES.map((g) => (\n <option key={g.value} value={g.value}>\n {g.label}\n </option>\n ))}\n </select>\n )}\n\n {/* Sort Button */}\n {onToggleSort && (\n <button\n onClick={onToggleSort}\n className={`p-1 transition-opacity flex-shrink-0 flex items-center gap-0.5 ${\n sortDirection\n ? 'opacity-100 text-dc-primary'\n : 'opacity-100 sm:opacity-0 sm:group-hover:opacity-100 text-dc-text-muted hover:text-dc-primary'\n }`}\n title={getSortTooltip()}\n >\n {getSortIcon()}\n {sortDirection && sortPriority && (\n <span className=\"text-xs font-medium\">({sortPriority})</span>\n )}\n </button>\n )}\n\n {/* Remove Button */}\n <button\n onClick={onRemove}\n className=\"p-1 text-dc-text-muted hover:text-dc-danger opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity flex-shrink-0\"\n title=\"Remove breakdown\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n )\n})\n\nexport default BreakdownItemCard\n","/**\n * BreakdownSection Component\n *\n * Displays the Breakdown section in the query panel with expandable list of breakdowns.\n */\n\nimport { useMemo, useState, useCallback, useRef, memo, DragEvent } from 'react'\nimport type { BreakdownSectionProps } from './types'\nimport type { MetaField } from '../../shared/types'\nimport BreakdownItemCard from './BreakdownItemCard'\nimport SectionHeading from './SectionHeading'\nimport { getIcon } from '../../icons'\n\n// Get icon once at module level to avoid recreating\nconst AddIcon = getIcon('add')\n\n/**\n * Find field metadata by field name\n */\nfunction findFieldMeta(fieldName: string, schema: BreakdownSectionProps['schema']): MetaField | null {\n if (!schema?.cubes) return null\n\n const [cubeName] = fieldName.split('.')\n const cube = schema.cubes.find((c) => c.name === cubeName)\n if (!cube) return null\n\n // Check dimensions first, then try to find in other arrays\n return cube.dimensions?.find((d) => d.name === fieldName) || null\n}\n\n/**\n * Get next sort direction in the cycle: null -> asc -> desc -> null\n */\nfunction getNextSortDirection(current: 'asc' | 'desc' | null): 'asc' | 'desc' | null {\n switch (current) {\n case null:\n return 'asc'\n case 'asc':\n return 'desc'\n case 'desc':\n return null\n default:\n return 'asc'\n }\n}\n\n/**\n * BreakdownSection displays a collapsible section with:\n * - Header with title and add button\n * - List of selected breakdowns (using BreakdownItemCard)\n * - Drag/drop reordering support\n */\nconst BreakdownSection = memo(function BreakdownSection({\n breakdowns,\n schema,\n onAdd,\n onRemove,\n onGranularityChange,\n order,\n onOrderChange,\n onReorder\n}: BreakdownSectionProps) {\n\n // Drag/drop state\n const [draggedIndex, setDraggedIndex] = useState<number | null>(null)\n const [dropTargetIndex, setDropTargetIndex] = useState<number | null>(null) // Index where item will be inserted\n\n // Use refs to track current values for use in drop handler (avoids stale closure issues)\n const draggedIndexRef = useRef<number | null>(null)\n const dropTargetIndexRef = useRef<number | null>(null)\n\n // Get the ordered keys to calculate priority\n const orderKeys = useMemo(() => order ? Object.keys(order) : [], [order])\n\n // Resolve field metadata for all breakdowns with sort info\n const breakdownsWithMeta = useMemo(() => {\n return breakdowns.map((breakdown, index) => {\n const sortDirection = order?.[breakdown.field] || null\n const sortPriority = sortDirection ? orderKeys.indexOf(breakdown.field) + 1 : undefined\n return {\n breakdown,\n fieldMeta: findFieldMeta(breakdown.field, schema),\n sortDirection,\n sortPriority,\n index\n }\n })\n }, [breakdowns, schema, order, orderKeys])\n\n // Track drag clone for cleanup\n const dragCloneRef = useRef<HTMLElement | null>(null)\n\n // Drag handlers\n const handleDragStart = useCallback((e: DragEvent, index: number) => {\n setDraggedIndex(index)\n draggedIndexRef.current = index\n e.dataTransfer.effectAllowed = 'move'\n e.dataTransfer.setData('text/plain', JSON.stringify({ type: 'breakdown', index, field: breakdowns[index].field }))\n\n // Create a semi-transparent, slightly tilted drag image\n const target = e.currentTarget as HTMLElement\n const clone = target.cloneNode(true) as HTMLElement\n clone.style.cssText = `\n position: absolute;\n top: -9999px;\n left: -9999px;\n width: ${target.offsetWidth}px;\n opacity: 0.7;\n transform: rotate(2deg);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n pointer-events: none;\n `\n document.body.appendChild(clone)\n dragCloneRef.current = clone\n\n // Calculate offset from click position\n const rect = target.getBoundingClientRect()\n const offsetX = e.clientX - rect.left\n const offsetY = e.clientY - rect.top\n e.dataTransfer.setDragImage(clone, offsetX, offsetY)\n }, [breakdowns])\n\n const handleDragEnd = useCallback(() => {\n setDraggedIndex(null)\n setDropTargetIndex(null)\n draggedIndexRef.current = null\n dropTargetIndexRef.current = null\n // Clean up the drag clone\n if (dragCloneRef.current) {\n document.body.removeChild(dragCloneRef.current)\n dragCloneRef.current = null\n }\n }, [])\n\n // Handle drag over an item - determine drop position based on mouse position\n const handleItemDragOver = useCallback((e: DragEvent, itemIndex: number) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Only process if we're dragging from this section\n const currentDraggedIndex = draggedIndexRef.current\n if (currentDraggedIndex === null) return\n\n // Determine if we're in the top or bottom half of the item\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseY = e.clientY - rect.top\n const isTopHalf = mouseY < rect.height / 2\n\n // Calculate target index based on position\n let targetIndex = isTopHalf ? itemIndex : itemIndex + 1\n\n // Don't set drop target if it would result in no movement\n if (targetIndex === currentDraggedIndex || targetIndex === currentDraggedIndex + 1) {\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n } else {\n setDropTargetIndex(targetIndex)\n dropTargetIndexRef.current = targetIndex\n }\n }, [])\n\n // Handle drop on an item\n const handleItemDrop = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Use refs to get current values (avoids stale closure issues)\n const currentDraggedIndex = draggedIndexRef.current\n const currentDropTargetIndex = dropTargetIndexRef.current\n\n // Reset visual state immediately\n setDraggedIndex(null)\n setDropTargetIndex(null)\n draggedIndexRef.current = null\n dropTargetIndexRef.current = null\n\n // Validate and reorder - use refs directly, no dataTransfer parsing needed\n if (currentDraggedIndex === null || currentDropTargetIndex === null || !onReorder) {\n return\n }\n\n // Adjust target index when dragging down (after splice, indices shift)\n const adjustedTarget = currentDropTargetIndex > currentDraggedIndex\n ? currentDropTargetIndex - 1\n : currentDropTargetIndex\n\n if (adjustedTarget !== currentDraggedIndex) {\n onReorder(currentDraggedIndex, adjustedTarget)\n }\n }, [onReorder])\n\n // Clear drop target when leaving the section\n const handleSectionDragLeave = useCallback((e: DragEvent) => {\n const relatedTarget = e.relatedTarget as HTMLElement | null\n if (!relatedTarget || !e.currentTarget.contains(relatedTarget)) {\n setDropTargetIndex(null)\n }\n }, [])\n\n // Calculate if an item should be shifted to make room for the drop\n const getItemTransform = useCallback((itemIndex: number): string => {\n if (draggedIndex === null || dropTargetIndex === null) return ''\n\n // Gap size in pixels\n const gapSize = 40\n\n // If this is the dragged item, no transform needed (it's already faded)\n if (itemIndex === draggedIndex) return ''\n\n // Items at or after drop target need to shift down\n // But we need to account for the dragged item's position\n if (draggedIndex < dropTargetIndex) {\n // Dragging down: items between dragged+1 and dropTarget-1 shift up\n if (itemIndex > draggedIndex && itemIndex < dropTargetIndex) {\n return '' // No gap needed, item stays in place\n }\n // Item at dropTarget-1 position should show gap after it\n if (itemIndex === dropTargetIndex - 1) {\n return `translateY(-${gapSize / 2}px)` // Shift up to make room\n }\n if (itemIndex >= dropTargetIndex) {\n return `translateY(${gapSize / 2}px)` // Shift down\n }\n } else {\n // Dragging up: items from dropTarget to draggedIndex-1 shift down\n if (itemIndex >= dropTargetIndex && itemIndex < draggedIndex) {\n return `translateY(${gapSize / 2}px)` // Shift down to make room\n }\n }\n\n return ''\n }, [draggedIndex, dropTargetIndex])\n\n // Determine if gap indicator should show at a position\n const shouldShowGapIndicator = useCallback((itemIndex: number): boolean => {\n if (draggedIndex === null || dropTargetIndex === null) return false\n\n // Show indicator before the item that matches dropTargetIndex\n return itemIndex === dropTargetIndex\n }, [draggedIndex, dropTargetIndex])\n\n return (\n <div>\n {/* Section Header - entire row is clickable */}\n <button\n onClick={onAdd}\n className=\"flex items-center justify-between mb-3 w-full py-1 px-2 -ml-2 rounded-lg hover:bg-dc-primary/10 transition-colors group\"\n title=\"Add breakdown\"\n >\n <SectionHeading>Breakdown</SectionHeading>\n <AddIcon className=\"w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors\" />\n </button>\n\n {/* Breakdowns List */}\n <div\n className=\"space-y-2\"\n onDragLeave={onReorder ? handleSectionDragLeave : undefined}\n onDragOver={onReorder ? (e) => e.preventDefault() : undefined}\n onDrop={onReorder ? handleItemDrop : undefined}\n >\n {breakdownsWithMeta.map(({ breakdown, fieldMeta, sortDirection, sortPriority, index }) => {\n const transform = getItemTransform(index)\n const showGapBefore = shouldShowGapIndicator(index)\n\n return (\n <div\n key={breakdown.id}\n className=\"relative\"\n style={{\n transform,\n transition: draggedIndex !== null ? 'transform 0.15s ease-out' : 'none'\n }}\n onDragOver={onReorder ? (e) => handleItemDragOver(e, index) : undefined}\n onDrop={onReorder ? handleItemDrop : undefined}\n >\n {/* Gap indicator line - shows where item will be inserted */}\n {showGapBefore && (\n <div className=\"absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10\">\n <div className=\"h-0.5 w-full bg-dc-primary rounded-full\" />\n </div>\n )}\n <BreakdownItemCard\n breakdown={breakdown}\n fieldMeta={fieldMeta}\n onRemove={() => onRemove(breakdown.id)}\n onGranularityChange={\n breakdown.isTimeDimension\n ? (granularity) => onGranularityChange(breakdown.id, granularity)\n : undefined\n }\n sortDirection={sortDirection}\n sortPriority={sortPriority}\n onToggleSort={onOrderChange ? () => {\n const nextDirection = getNextSortDirection(sortDirection)\n onOrderChange(breakdown.field, nextDirection)\n } : undefined}\n index={index}\n isDragging={draggedIndex === index}\n onDragStart={onReorder ? handleDragStart : undefined}\n onDragEnd={onReorder ? handleDragEnd : undefined}\n />\n </div>\n )\n })}\n {/* Gap indicator after the last item - shows when dropping at end */}\n {onReorder && draggedIndex !== null && dropTargetIndex === breakdowns.length && (\n <div className=\"relative h-2\">\n <div className=\"absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10\">\n <div className=\"h-0.5 w-full bg-dc-primary rounded-full\" />\n </div>\n </div>\n )}\n {/* Handle drop at the end of the list */}\n {onReorder && breakdowns.length > 0 && draggedIndex !== null && (\n <div\n className=\"h-8\"\n onDragOver={(e) => {\n e.preventDefault()\n // Set drop target to end of list\n const lastIndex = breakdowns.length\n const currentDraggedIndex = draggedIndexRef.current\n if (dropTargetIndexRef.current !== lastIndex && currentDraggedIndex !== lastIndex - 1) {\n setDropTargetIndex(lastIndex)\n dropTargetIndexRef.current = lastIndex\n }\n }}\n onDrop={handleItemDrop}\n />\n )}\n </div>\n </div>\n )\n})\n\nexport default BreakdownSection\n","/**\n * AnalysisFilterItem Component\n *\n * Compact filter item for the AnalysisBuilder's narrow column layout.\n * Features:\n * - Display name for field (not just shortName)\n * - Operator + value on same row\n * - API-fetched combo box with search for dimension values\n * - Multi-value support with tags for in/notIn operators\n * - Date range selector with predefined options\n */\n\nimport { useState, useRef, useEffect, useCallback, useMemo, ChangeEvent } from 'react'\nimport { getIcon } from '../../icons'\nimport type { SimpleFilter, FilterOperator } from '../../types'\nimport type { MetaResponse, DateRangeType } from '../../shared/types'\nimport {\n FILTER_OPERATORS,\n DATE_RANGE_OPTIONS\n} from '../../shared/types'\nimport {\n getAvailableOperators,\n convertDateRangeTypeToValue,\n requiresNumberInput\n} from '../../shared/utils'\nimport { findFieldInSchema, getFieldTitle } from './utils'\nimport { useFilterValues } from '../../hooks/useFilterValues'\nimport { useDebounce } from '../../hooks/useDebounce'\n\nconst CloseIcon = getIcon('close')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\nconst MeasureIcon = getIcon('measure')\n\ninterface AnalysisFilterItemProps {\n /** The filter to display */\n filter: SimpleFilter\n /** Schema for field metadata */\n schema: MetaResponse | null\n /** Callback to remove this filter */\n onRemove: () => void\n /** Callback to update this filter */\n onUpdate: (filter: SimpleFilter) => void\n /** Optional depth for nested styling */\n depth?: number\n}\n\nexport default function AnalysisFilterItem({\n filter,\n schema,\n onRemove,\n onUpdate,\n depth = 0\n}: AnalysisFilterItemProps) {\n const [isOperatorDropdownOpen, setIsOperatorDropdownOpen] = useState(false)\n const [isValueDropdownOpen, setIsValueDropdownOpen] = useState(false)\n const [isDateRangeDropdownOpen, setIsDateRangeDropdownOpen] = useState(false)\n const [rangeType, setRangeType] = useState<DateRangeType>('this_month')\n const [numberValue, setNumberValue] = useState(1)\n const [searchText, setSearchText] = useState('')\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Debounce search text for API calls\n const debouncedSearchText = useDebounce(searchText, 300)\n\n // Get field info\n const fieldInfo = findFieldInSchema(filter.member, schema)\n const fieldType = fieldInfo?.field.type || 'string'\n const isTimeField = fieldType === 'time'\n const isMeasureField = fieldInfo?.fieldType === 'measure'\n const isDimensionField = fieldInfo?.fieldType === 'dimension'\n\n // Get display title for field\n const fieldTitle = getFieldTitle(filter.member, schema)\n\n // Get operator metadata\n const operatorMeta = FILTER_OPERATORS[filter.operator]\n\n // Get available operators for this field type\n const availableOperators = getAvailableOperators(fieldType)\n\n // Should show date range selector\n const shouldShowDateRange = isTimeField && filter.operator === 'inDateRange'\n\n // Should use combo box for value selection\n const shouldShowComboBox = useMemo(() => {\n const comboOperators = ['equals', 'notEquals', 'in', 'notIn']\n return comboOperators.includes(filter.operator) && isDimensionField && !isTimeField\n }, [filter.operator, isDimensionField, isTimeField])\n\n // Fetch distinct values for combo box\n const {\n values: distinctValues,\n loading: valuesLoading,\n error: valuesError,\n searchValues\n } = useFilterValues(filter.member, shouldShowComboBox)\n\n // Close dropdowns when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOperatorDropdownOpen(false)\n setIsValueDropdownOpen(false)\n setIsDateRangeDropdownOpen(false)\n }\n }\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n // Load values when dropdown opens\n useEffect(() => {\n if (isValueDropdownOpen && shouldShowComboBox && searchValues) {\n searchValues('', true)\n }\n }, [isValueDropdownOpen, shouldShowComboBox, searchValues])\n\n // Search when debounced text changes\n useEffect(() => {\n if (isValueDropdownOpen && shouldShowComboBox && searchValues && debouncedSearchText !== undefined) {\n searchValues(debouncedSearchText)\n }\n }, [debouncedSearchText, isValueDropdownOpen, shouldShowComboBox, searchValues])\n\n // Sync rangeType state with filter.dateRange\n useEffect(() => {\n if (!shouldShowDateRange || !filter.dateRange) return\n\n if (Array.isArray(filter.dateRange)) {\n setRangeType('custom')\n } else {\n // Find matching range type\n const flexMatch = filter.dateRange.match(/^last (\\d+) (days|weeks|months|quarters|years)$/)\n if (flexMatch) {\n const [, num, unit] = flexMatch\n setRangeType(`last_n_${unit}` as DateRangeType)\n setNumberValue(parseInt(num) || 1)\n } else {\n // Check predefined ranges\n let found = false\n for (const option of DATE_RANGE_OPTIONS) {\n if (option.value !== 'custom' && !requiresNumberInput(option.value)) {\n if (convertDateRangeTypeToValue(option.value) === filter.dateRange) {\n setRangeType(option.value)\n found = true\n break\n }\n }\n }\n if (!found) setRangeType('custom')\n }\n }\n }, [filter.dateRange, shouldShowDateRange])\n\n // Handle operator change\n const handleOperatorChange = useCallback((operator: FilterOperator) => {\n const newFilter: SimpleFilter = {\n member: filter.member,\n operator,\n values: []\n }\n onUpdate(newFilter)\n setIsOperatorDropdownOpen(false)\n }, [filter.member, onUpdate])\n\n // Handle value selection from combo box\n const handleValueSelect = useCallback((value: unknown) => {\n const values = filter.values || []\n if (operatorMeta?.supportsMultipleValues) {\n if (!values.includes(value)) {\n onUpdate({ ...filter, values: [...values, value] })\n }\n } else {\n onUpdate({ ...filter, values: [value] })\n setIsValueDropdownOpen(false)\n }\n setSearchText('')\n }, [filter, operatorMeta?.supportsMultipleValues, onUpdate])\n\n // Handle value removal\n const handleValueRemove = useCallback((valueToRemove: unknown) => {\n const values = (filter.values || []).filter(v => v !== valueToRemove)\n onUpdate({ ...filter, values })\n }, [filter, onUpdate])\n\n // Handle direct text/number input\n const handleDirectInput = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n if (operatorMeta?.valueType === 'number') {\n const numValue = parseFloat(value)\n if (!isNaN(numValue)) {\n onUpdate({ ...filter, values: [numValue] })\n } else if (value === '' || value === '-') {\n onUpdate({ ...filter, values: [] })\n }\n } else {\n onUpdate({ ...filter, values: value ? [value] : [] })\n }\n }, [filter, operatorMeta?.valueType, onUpdate])\n\n // Handle between range inputs\n const handleBetweenStartInput = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const value = parseFloat(e.target.value)\n const currentValues = filter.values?.length >= 2 ? filter.values : ['', '']\n const newValues = [!isNaN(value) ? value : '', currentValues[1]].filter(v => v !== '')\n onUpdate({ ...filter, values: newValues })\n }, [filter, onUpdate])\n\n const handleBetweenEndInput = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const value = parseFloat(e.target.value)\n const currentValues = filter.values?.length >= 2 ? filter.values : ['', '']\n const newValues = [currentValues[0], !isNaN(value) ? value : ''].filter(v => v !== '')\n onUpdate({ ...filter, values: newValues })\n }, [filter, onUpdate])\n\n // Handle date input\n const handleDateInput = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n onUpdate({ ...filter, values: value ? [value] : [] })\n }, [filter, onUpdate])\n\n // Handle date range type change\n const handleRangeTypeChange = useCallback((newRangeType: DateRangeType) => {\n setRangeType(newRangeType)\n setIsDateRangeDropdownOpen(false)\n\n let dateRange: string | string[]\n if (newRangeType === 'custom') {\n const today = new Date().toISOString().split('T')[0]\n dateRange = [today, today]\n } else if (requiresNumberInput(newRangeType)) {\n dateRange = convertDateRangeTypeToValue(newRangeType, numberValue)\n } else {\n dateRange = convertDateRangeTypeToValue(newRangeType)\n }\n\n onUpdate({ ...filter, dateRange } as SimpleFilter)\n }, [filter, numberValue, onUpdate])\n\n // Handle number value change for \"last N days/weeks/etc\"\n const handleNumberValueChange = useCallback((value: number) => {\n setNumberValue(value)\n if (requiresNumberInput(rangeType)) {\n const dateRange = convertDateRangeTypeToValue(rangeType, value)\n onUpdate({ ...filter, dateRange } as SimpleFilter)\n }\n }, [filter, rangeType, onUpdate])\n\n // Handle custom date range inputs\n const handleCustomStartDate = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const start = e.target.value\n const currentRange = Array.isArray(filter.dateRange) ? filter.dateRange : [filter.dateRange || '', '']\n const end = currentRange[1] || start\n onUpdate({ ...filter, dateRange: [start, end] } as SimpleFilter)\n }, [filter, onUpdate])\n\n const handleCustomEndDate = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const end = e.target.value\n const currentRange = Array.isArray(filter.dateRange) ? filter.dateRange : ['', filter.dateRange || '']\n const start = currentRange[0] || end\n onUpdate({ ...filter, dateRange: [start, end] } as SimpleFilter)\n }, [filter, onUpdate])\n\n // Get current operator label\n const operatorLabel = availableOperators.find(op => op.operator === filter.operator)?.label || filter.operator\n\n // Get current date range label\n const dateRangeLabel = DATE_RANGE_OPTIONS.find(opt => opt.value === rangeType)?.label || 'Select range'\n\n // Get icon for field type\n const FieldIcon = isTimeField ? TimeDimensionIcon : isMeasureField ? MeasureIcon : DimensionIcon\n const iconColor = isTimeField ? 'text-dc-time-dimension-text' : isMeasureField ? 'text-dc-measure-text' : 'text-dc-dimension-text'\n\n // Render value input based on operator type\n const renderValueInput = () => {\n // No value required for set/notSet\n if (!operatorMeta?.requiresValues) {\n return (\n <div className=\"text-xs text-dc-text-muted italic py-1\">\n No value required\n </div>\n )\n }\n\n // Date range selector for inDateRange on time fields\n if (shouldShowDateRange) {\n return (\n <div className=\"space-y-1.5\">\n {/* Range type dropdown */}\n <div className=\"relative\">\n <button\n onClick={() => {\n setIsOperatorDropdownOpen(false)\n setIsValueDropdownOpen(false)\n setIsDateRangeDropdownOpen(!isDateRangeDropdownOpen)\n }}\n className=\"w-full flex items-center justify-between text-left text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover\"\n >\n <span className=\"truncate\">{dateRangeLabel}</span>\n <ChevronDownIcon className={`w-3 h-3 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isDateRangeDropdownOpen ? 'rotate-180' : ''\n }`} />\n </button>\n\n {isDateRangeDropdownOpen && (\n <div className=\"absolute z-30 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded shadow-lg max-h-40 overflow-y-auto\">\n {DATE_RANGE_OPTIONS.map((option) => (\n <button\n key={option.value}\n onClick={() => handleRangeTypeChange(option.value)}\n className={`w-full text-left px-2 py-1.5 text-xs hover:bg-dc-surface-hover ${\n option.value === rangeType ? 'bg-dc-primary/10 text-dc-primary' : 'text-dc-text'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Number input for \"last N\" ranges */}\n {requiresNumberInput(rangeType) && (\n <div className=\"flex items-center gap-1.5\">\n <input\n type=\"number\"\n min=\"1\"\n max=\"1000\"\n value={numberValue}\n onChange={(e) => handleNumberValueChange(Math.max(1, parseInt(e.target.value) || 1))}\n className=\"flex-1 text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text w-16\"\n />\n <span className=\"text-xs text-dc-text-muted\">\n {rangeType.replace('last_n_', '')}\n </span>\n </div>\n )}\n\n {/* Custom date inputs */}\n {rangeType === 'custom' && (\n <div className=\"flex items-center gap-1.5\">\n <input\n type=\"date\"\n value={Array.isArray(filter.dateRange) ? filter.dateRange[0] : ''}\n onChange={handleCustomStartDate}\n className=\"flex-1 text-xs border border-dc-border rounded px-1.5 py-1 bg-dc-surface text-dc-text\"\n />\n <span className=\"text-xs text-dc-text-muted\">to</span>\n <input\n type=\"date\"\n value={Array.isArray(filter.dateRange) ? filter.dateRange[1] : ''}\n onChange={handleCustomEndDate}\n className=\"flex-1 text-xs border border-dc-border rounded px-1.5 py-1 bg-dc-surface text-dc-text\"\n />\n </div>\n )}\n </div>\n )\n }\n\n // Between/notBetween range inputs\n if (filter.operator === 'between' || filter.operator === 'notBetween') {\n return (\n <div className=\"flex items-center gap-1.5\">\n <input\n type=\"number\"\n value={filter.values?.[0] ?? ''}\n onChange={handleBetweenStartInput}\n placeholder=\"Min\"\n className=\"flex-1 text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text\"\n />\n <span className=\"text-xs text-dc-text-muted\">to</span>\n <input\n type=\"number\"\n value={filter.values?.[1] ?? ''}\n onChange={handleBetweenEndInput}\n placeholder=\"Max\"\n className=\"flex-1 text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text\"\n />\n </div>\n )\n }\n\n // Date picker for date operators\n if (operatorMeta?.valueType === 'date') {\n return (\n <input\n type=\"date\"\n value={filter.values?.[0] || ''}\n onChange={handleDateInput}\n className=\"w-full text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text\"\n />\n )\n }\n\n // Number input\n if (operatorMeta?.valueType === 'number') {\n return (\n <input\n type=\"number\"\n value={filter.values?.[0] ?? ''}\n onChange={handleDirectInput}\n placeholder=\"Enter number\"\n className=\"w-full text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text\"\n />\n )\n }\n\n // Combo box for equals/notEquals/in/notIn on dimensions\n if (shouldShowComboBox) {\n return (\n <div className=\"space-y-1.5\">\n {/* Selected values as tags */}\n {filter.values && filter.values.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {filter.values.map((value, index) => (\n <span\n key={index}\n className=\"inline-flex items-center gap-0.5 bg-dc-primary/10 text-dc-primary text-xs px-1.5 py-0.5 rounded\"\n >\n <span className=\"max-w-[100px] truncate\">{String(value)}</span>\n <button\n onClick={() => handleValueRemove(value)}\n className=\"hover:text-dc-danger\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </span>\n ))}\n </div>\n )}\n\n {/* Dropdown trigger */}\n <div className=\"relative\">\n <button\n onClick={() => {\n setIsOperatorDropdownOpen(false)\n setIsDateRangeDropdownOpen(false)\n setIsValueDropdownOpen(!isValueDropdownOpen)\n }}\n className=\"w-full flex items-center justify-between text-left text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover\"\n >\n <span className=\"text-dc-text-muted truncate\">\n {valuesLoading ? 'Loading...' : 'Select value...'}\n </span>\n <ChevronDownIcon className={`w-3 h-3 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isValueDropdownOpen ? 'rotate-180' : ''\n }`} />\n </button>\n\n {isValueDropdownOpen && (\n <div className=\"absolute z-30 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded shadow-lg max-h-48 overflow-hidden\">\n {/* Search input */}\n <div className=\"p-1.5 border-b border-dc-border\">\n <input\n type=\"text\"\n value={searchText}\n onChange={(e) => setSearchText(e.target.value)}\n placeholder=\"Search...\"\n className=\"w-full text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text\"\n autoFocus\n />\n </div>\n\n {/* Values list */}\n <div className=\"max-h-36 overflow-y-auto\">\n {valuesLoading ? (\n <div className=\"px-2 py-2 text-xs text-dc-text-muted\">Loading...</div>\n ) : valuesError ? (\n <div className=\"px-2 py-2 text-xs text-dc-error\">Error: {valuesError}</div>\n ) : distinctValues.length === 0 ? (\n <div className=\"px-2 py-2 text-xs text-dc-text-muted\">No values found</div>\n ) : (\n distinctValues.map((value, index) => {\n const isSelected = filter.values?.includes(value)\n return (\n <button\n key={`${value}-${index}`}\n onClick={() => handleValueSelect(value)}\n className={`w-full text-left px-2 py-1.5 text-xs hover:bg-dc-surface-hover ${\n isSelected ? 'bg-dc-primary/10 text-dc-primary' : 'text-dc-text'\n }`}\n >\n {String(value)}\n {isSelected && <span className=\"float-right\">✓</span>}\n </button>\n )\n })\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n )\n }\n\n // Default: text input\n return (\n <input\n type=\"text\"\n value={filter.values?.[0] ?? ''}\n onChange={handleDirectInput}\n placeholder=\"Enter value...\"\n className=\"w-full text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text placeholder-dc-text-muted\"\n />\n )\n }\n\n return (\n <div\n ref={containerRef}\n className={`bg-dc-surface border border-dc-border rounded-lg p-2 ${depth > 0 ? 'ml-3' : ''}`}\n >\n {/* Header: Field name and remove button */}\n <div className=\"flex items-center justify-between mb-1.5\">\n <div className=\"flex items-center gap-1.5 min-w-0\">\n <FieldIcon className={`w-3.5 h-3.5 ${iconColor} shrink-0`} />\n <span className=\"text-xs font-medium text-dc-text truncate\" title={filter.member}>\n {fieldTitle}\n </span>\n </div>\n <button\n onClick={onRemove}\n className=\"text-dc-text-muted hover:text-dc-danger transition-colors shrink-0 p-0.5\"\n title=\"Remove filter\"\n >\n <CloseIcon className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n\n {/* Operator selector */}\n <div className=\"relative mb-1.5\">\n <button\n onClick={() => {\n setIsValueDropdownOpen(false)\n setIsDateRangeDropdownOpen(false)\n setIsOperatorDropdownOpen(!isOperatorDropdownOpen)\n }}\n className=\"w-full flex items-center justify-between text-left text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover\"\n >\n <span className=\"truncate\">{operatorLabel}</span>\n <ChevronDownIcon className={`w-3 h-3 text-dc-text-muted shrink-0 ml-1 transition-transform ${\n isOperatorDropdownOpen ? 'rotate-180' : ''\n }`} />\n </button>\n\n {isOperatorDropdownOpen && (\n <div className=\"absolute z-30 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded shadow-lg max-h-40 overflow-y-auto\">\n {availableOperators.map((op) => (\n <button\n key={op.operator}\n onClick={() => handleOperatorChange(op.operator as FilterOperator)}\n className={`w-full text-left px-2 py-1.5 text-xs hover:bg-dc-surface-hover ${\n op.operator === filter.operator ? 'bg-dc-primary/10 text-dc-primary' : 'text-dc-text'\n }`}\n >\n {op.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Value input */}\n {renderValueInput()}\n </div>\n )\n}\n","/**\n * AnalysisFilterGroup Component\n *\n * Renders a group of filters with AND/OR logic.\n * Supports infinite nesting for complex filter conditions.\n * Compact design for the AnalysisBuilder's narrow column.\n */\n\nimport { useState, useRef, useEffect, useCallback } from 'react'\nimport { getIcon } from '../../icons'\nimport type { Filter, SimpleFilter, GroupFilter } from '../../types'\nimport type { MetaResponse } from '../../shared/types'\nimport AnalysisFilterItem from './AnalysisFilterItem'\n\nconst AddIcon = getIcon('add')\nconst CloseIcon = getIcon('close')\n\ninterface AnalysisFilterGroupProps {\n /** The group filter to render */\n group: GroupFilter\n /** Schema for field metadata */\n schema: MetaResponse | null\n /** Callback when group changes */\n onUpdate: (group: GroupFilter) => void\n /** Callback to remove this group */\n onRemove: () => void\n /** Callback to add a new filter - receives path relative to this group */\n onAddFilter: (relativePath?: number[]) => void\n /** Depth level for styling */\n depth?: number\n /** Whether to hide the remove button (for top-level groups) */\n hideRemoveButton?: boolean\n}\n\n/**\n * Check if a filter is a simple filter\n */\nfunction isSimpleFilter(filter: Filter): filter is SimpleFilter {\n return 'member' in filter && typeof (filter as SimpleFilter).member === 'string'\n}\n\n/**\n * Check if a filter is a group filter\n */\nfunction isGroupFilter(filter: Filter): filter is GroupFilter {\n return 'type' in filter && ((filter as GroupFilter).type === 'and' || (filter as GroupFilter).type === 'or')\n}\n\nexport default function AnalysisFilterGroup({\n group,\n schema,\n onUpdate,\n onRemove,\n onAddFilter,\n depth = 0,\n hideRemoveButton = false\n}: AnalysisFilterGroupProps) {\n const [isAddMenuOpen, setIsAddMenuOpen] = useState(false)\n const addMenuRef = useRef<HTMLDivElement>(null)\n\n // Close add menu when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (addMenuRef.current && !addMenuRef.current.contains(event.target as Node)) {\n setIsAddMenuOpen(false)\n }\n }\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n // Toggle group type (AND <-> OR)\n const handleToggleType = useCallback(() => {\n const newType = group.type === 'and' ? 'or' : 'and'\n onUpdate({ ...group, type: newType })\n }, [group, onUpdate])\n\n // Update a nested filter at a specific index\n const handleUpdateFilter = useCallback((index: number, newFilter: Filter) => {\n const newFilters = [...group.filters]\n newFilters[index] = newFilter\n onUpdate({ ...group, filters: newFilters })\n }, [group, onUpdate])\n\n // Remove a filter at a specific index\n const handleRemoveFilter = useCallback((index: number) => {\n const newFilters = group.filters.filter((_, i) => i !== index)\n\n // If only one filter remains, we might want to unwrap\n // But for now, just update with remaining filters\n if (newFilters.length === 0) {\n // If group is empty, remove the group itself\n onRemove()\n } else if (newFilters.length === 1 && depth > 0) {\n // Unwrap single-filter groups at non-root level by updating parent\n // This is handled by the parent component\n onUpdate({ ...group, filters: newFilters })\n } else {\n onUpdate({ ...group, filters: newFilters })\n }\n }, [group, onUpdate, onRemove, depth])\n\n // Add a nested group at a specific index\n const handleAddNestedGroup = useCallback((type: 'and' | 'or') => {\n const newGroup: GroupFilter = { type, filters: [] }\n onUpdate({ ...group, filters: [...group.filters, newGroup] })\n setIsAddMenuOpen(false)\n }, [group, onUpdate])\n\n // Handle add filter button - add to this group\n const handleAddFilterClick = useCallback(() => {\n onAddFilter([]) // Empty path means add to this group\n setIsAddMenuOpen(false)\n }, [onAddFilter])\n\n // Create handler for nested group to add filters\n const createNestedAddFilterHandler = useCallback((nestedIndex: number) => {\n return (relativePath: number[] = []) => {\n // Prepend this nested index to the relative path\n onAddFilter([nestedIndex, ...relativePath])\n }\n }, [onAddFilter])\n\n // Get border color based on depth\n const getBorderColor = () => {\n if (depth % 2 === 0) {\n return 'border-dc-border'\n }\n return 'border-dc-border dark:border-dc-border'\n }\n\n // Get background color based on group type\n const getGroupBgColor = () => {\n return group.type === 'and' ? 'bg-dc-info-bg/50' : 'bg-dc-warning-bg/50'\n }\n\n const conditionCount = group.filters.length\n const conditionLabel = conditionCount === 1 ? 'condition' : 'conditions'\n\n return (\n <div className={`border ${getBorderColor()} rounded-lg ${getGroupBgColor()} ${depth > 0 ? 'ml-3' : ''}`}>\n {/* Group Header */}\n <div className=\"flex items-center justify-between px-2 py-1.5 border-b border-dc-border/50\">\n <div className=\"flex items-center gap-2\">\n {/* AND/OR Toggle Button */}\n <button\n onClick={handleToggleType}\n className={`px-2 py-0.5 text-xs font-semibold rounded transition-colors ${\n group.type === 'and'\n ? 'bg-dc-info-bg text-dc-info hover:opacity-80'\n : 'bg-dc-warning-bg text-dc-warning hover:opacity-80'\n }`}\n title={`Click to switch to ${group.type === 'and' ? 'OR' : 'AND'}`}\n >\n {group.type.toUpperCase()}\n </button>\n\n {/* Condition Count */}\n <span className=\"text-xs text-dc-text-muted\">\n {conditionCount} {conditionLabel}\n </span>\n </div>\n\n <div className=\"flex items-center gap-1\">\n {/* Add Button with Dropdown */}\n <div className=\"relative\" ref={addMenuRef}>\n <button\n onClick={() => setIsAddMenuOpen(!isAddMenuOpen)}\n className=\"p-1 text-dc-text-secondary hover:text-dc-primary hover:bg-dc-surface-hover rounded transition-colors\"\n title=\"Add condition\"\n >\n <AddIcon className=\"w-4 h-4\" />\n </button>\n\n {isAddMenuOpen && (\n <div className=\"absolute right-0 mt-1 z-40 bg-dc-surface border border-dc-border rounded shadow-lg py-1 min-w-[120px]\">\n <button\n onClick={handleAddFilterClick}\n className=\"w-full text-left px-3 py-1.5 text-xs text-dc-text hover:bg-dc-surface-hover\"\n >\n Add Filter\n </button>\n <button\n onClick={() => handleAddNestedGroup('and')}\n className=\"w-full text-left px-3 py-1.5 text-xs text-dc-text hover:bg-dc-surface-hover\"\n >\n Add AND Group\n </button>\n <button\n onClick={() => handleAddNestedGroup('or')}\n className=\"w-full text-left px-3 py-1.5 text-xs text-dc-text hover:bg-dc-surface-hover\"\n >\n Add OR Group\n </button>\n </div>\n )}\n </div>\n\n {/* Remove Group Button */}\n {!hideRemoveButton && (\n <button\n onClick={onRemove}\n className=\"p-1 text-dc-text-muted hover:text-dc-danger transition-colors\"\n title=\"Remove group\"\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n\n {/* Group Body - Filter List */}\n <div className=\"p-2 space-y-2\">\n {group.filters.length === 0 ? (\n <div className=\"text-center py-3\">\n <p className=\"text-xs text-dc-text-muted mb-1\">No conditions in this group</p>\n <button\n onClick={() => onAddFilter([])}\n className=\"text-xs text-dc-primary hover:underline\"\n >\n Add a filter\n </button>\n </div>\n ) : (\n group.filters.map((filter, index) => {\n if (isSimpleFilter(filter)) {\n return (\n <AnalysisFilterItem\n key={`filter-${index}`}\n filter={filter}\n schema={schema}\n onUpdate={(newFilter) => handleUpdateFilter(index, newFilter)}\n onRemove={() => handleRemoveFilter(index)}\n depth={depth + 1}\n />\n )\n } else if (isGroupFilter(filter)) {\n return (\n <AnalysisFilterGroup\n key={`group-${index}`}\n group={filter}\n schema={schema}\n onUpdate={(newGroup) => handleUpdateFilter(index, newGroup)}\n onRemove={() => handleRemoveFilter(index)}\n onAddFilter={createNestedAddFilterHandler(index)}\n depth={depth + 1}\n />\n )\n }\n return null\n })\n )}\n </div>\n </div>\n )\n}\n","/**\n * AnalysisFilterSection Component\n *\n * Compact filter section for the AnalysisBuilder's narrow column layout.\n * Renders hierarchical filter structure with AND/OR groups.\n * Uses FieldSearchModal for field selection.\n */\n\nimport { useState, useCallback, useRef, DragEvent } from 'react'\nimport { getIcon } from '../../icons'\nimport SectionHeading from './SectionHeading'\nimport type { Filter, SimpleFilter, GroupFilter } from '../../types'\nimport type { MetaResponse, MetaField } from '../../shared/types'\nimport FieldSearchModal from './FieldSearchModal'\nimport AnalysisFilterItem from './AnalysisFilterItem'\nimport AnalysisFilterGroup from './AnalysisFilterGroup'\nimport { convertDateRangeTypeToValue } from '../../shared/utils'\n\nconst AddIcon = getIcon('add')\n\ninterface AnalysisFilterSectionProps {\n /** Current filters */\n filters: Filter[]\n /** Schema for field metadata */\n schema: MetaResponse | null\n /** Callback when filters change */\n onFiltersChange: (filters: Filter[]) => void\n /** Callback when a field is dropped from another section */\n onFieldDropped?: (field: string) => void\n}\n\n/**\n * Check if a filter is a simple filter (has member property)\n */\nfunction isSimpleFilter(filter: Filter): filter is SimpleFilter {\n return 'member' in filter && typeof (filter as SimpleFilter).member === 'string'\n}\n\n/**\n * Check if a filter is a group filter\n */\nfunction isGroupFilter(filter: Filter): filter is GroupFilter {\n return 'type' in filter && ((filter as GroupFilter).type === 'and' || (filter as GroupFilter).type === 'or')\n}\n\n/**\n * Count all simple filters in a filter tree\n */\nfunction countFilters(filters: Filter[]): number {\n let count = 0\n for (const filter of filters) {\n if (isSimpleFilter(filter)) {\n count++\n } else if (isGroupFilter(filter)) {\n count += countFilters(filter.filters)\n }\n }\n return count\n}\n\n/**\n * Get all simple filter member names from a filter tree\n */\nfunction getSelectedFields(filters: Filter[]): string[] {\n const fields: string[] = []\n for (const filter of filters) {\n if (isSimpleFilter(filter)) {\n fields.push(filter.member)\n } else if (isGroupFilter(filter)) {\n fields.push(...getSelectedFields(filter.filters))\n }\n }\n return fields\n}\n\n/**\n * Add a filter at a specific path in the filter tree\n * Path is an array of indices, e.g., [0, 2] means filters[0].filters[2]\n */\nfunction addFilterAtPath(filters: Filter[], path: number[], newFilter: SimpleFilter): Filter[] {\n if (path.length === 0) {\n // Add to root level\n if (filters.length === 0) {\n return [newFilter]\n } else if (filters.length === 1 && isSimpleFilter(filters[0])) {\n // Wrap in AND group\n return [{ type: 'and', filters: [filters[0], newFilter] }]\n } else if (filters.length === 1 && isGroupFilter(filters[0])) {\n // Add to existing group\n return [{\n ...filters[0],\n filters: [...filters[0].filters, newFilter]\n }]\n } else {\n // Wrap all in AND group\n return [{ type: 'and', filters: [...filters, newFilter] }]\n }\n }\n\n // Navigate to the target group and add\n const [firstIndex, ...restPath] = path\n const newFilters = [...filters]\n const targetFilter = newFilters[firstIndex]\n\n if (isGroupFilter(targetFilter)) {\n if (restPath.length === 0) {\n // Add to this group\n newFilters[firstIndex] = {\n ...targetFilter,\n filters: [...targetFilter.filters, newFilter]\n }\n } else {\n // Recurse deeper\n newFilters[firstIndex] = {\n ...targetFilter,\n filters: addFilterAtPath(targetFilter.filters, restPath, newFilter)\n }\n }\n }\n\n return newFilters\n}\n\nexport default function AnalysisFilterSection({\n filters,\n schema,\n onFiltersChange,\n onFieldDropped\n}: AnalysisFilterSectionProps) {\n const [showFieldModal, setShowFieldModal] = useState(false)\n const [isDragOver, setIsDragOver] = useState(false)\n // Track which group we're adding a filter to (path of indices, empty = root)\n const pendingAddPath = useRef<number[]>([])\n\n // Get total filter count for display\n const totalFilterCount = countFilters(filters)\n\n // Handle drag over for drop zone\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(true)\n }, [])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n try {\n const data = JSON.parse(e.dataTransfer.getData('text/plain'))\n if (data.field && onFieldDropped) {\n onFieldDropped(data.field)\n }\n } catch {\n // Ignore invalid drop data\n }\n }, [onFieldDropped])\n\n // Get selected field names for the modal\n const selectedFields = getSelectedFields(filters)\n\n // Handle adding a new filter via field selection\n const handleFieldSelected = useCallback(\n (field: MetaField, _fieldType: 'measure' | 'dimension' | 'timeDimension', _cubeName: string) => {\n // Determine default operator based on field type\n const isTime = field.type === 'time'\n const defaultOperator = isTime ? 'inDateRange' : 'equals'\n\n // Create new filter with appropriate defaults\n const newFilter: SimpleFilter = {\n member: field.name,\n operator: defaultOperator,\n values: []\n }\n\n // For time fields with inDateRange, set a default dateRange so the filter is immediately active\n if (isTime && defaultOperator === 'inDateRange') {\n (newFilter as any).dateRange = convertDateRangeTypeToValue('this_month')\n }\n\n // Add filter at the pending path\n const updatedFilters = addFilterAtPath(filters, pendingAddPath.current, newFilter)\n onFiltersChange(updatedFilters)\n\n setShowFieldModal(false)\n pendingAddPath.current = []\n },\n [filters, onFiltersChange]\n )\n\n // Handle updating a top-level filter\n const handleUpdateTopLevelFilter = useCallback(\n (index: number, newFilter: Filter) => {\n const newFilters = [...filters]\n newFilters[index] = newFilter\n onFiltersChange(newFilters)\n },\n [filters, onFiltersChange]\n )\n\n // Handle removing a top-level filter\n const handleRemoveTopLevelFilter = useCallback(\n (index: number) => {\n const newFilters = filters.filter((_, i) => i !== index)\n\n // If we have a single group with one filter, unwrap it\n if (newFilters.length === 1 && isGroupFilter(newFilters[0])) {\n const group = newFilters[0]\n if (group.filters.length === 1) {\n onFiltersChange([group.filters[0]])\n return\n }\n }\n\n onFiltersChange(newFilters)\n },\n [filters, onFiltersChange]\n )\n\n // Handle clearing all filters\n const handleClearAll = useCallback(() => {\n onFiltersChange([])\n }, [onFiltersChange])\n\n // Handle add filter button at root level\n const handleAddFilterClick = useCallback(() => {\n pendingAddPath.current = []\n setShowFieldModal(true)\n }, [])\n\n // Create a handler for adding filters at a specific path\n // The handler receives an optional relativePath from nested groups\n const createAddFilterHandler = useCallback((basePath: number[]) => {\n return (relativePath: number[] = []) => {\n pendingAddPath.current = [...basePath, ...relativePath]\n setShowFieldModal(true)\n }\n }, [])\n\n // Render a single filter (SimpleFilter or GroupFilter)\n const renderFilter = (filter: Filter, index: number, parentPath: number[] = []) => {\n const currentPath = [...parentPath, index]\n\n if (isSimpleFilter(filter)) {\n return (\n <AnalysisFilterItem\n key={`filter-${currentPath.join('-')}`}\n filter={filter}\n schema={schema}\n onUpdate={(newFilter) => handleUpdateTopLevelFilter(index, newFilter)}\n onRemove={() => handleRemoveTopLevelFilter(index)}\n />\n )\n } else if (isGroupFilter(filter)) {\n return (\n <AnalysisFilterGroup\n key={`group-${currentPath.join('-')}`}\n group={filter}\n schema={schema}\n onUpdate={(newGroup) => handleUpdateTopLevelFilter(index, newGroup)}\n onRemove={() => handleRemoveTopLevelFilter(index)}\n onAddFilter={createAddFilterHandler(currentPath)}\n hideRemoveButton={filters.length === 1}\n />\n )\n }\n return null\n }\n\n return (\n <div>\n {/* Header - entire row is clickable to add filter */}\n <button\n onClick={handleAddFilterClick}\n className=\"flex items-center justify-between mb-3 w-full py-1 px-2 -ml-2 rounded-lg hover:bg-dc-primary/10 transition-colors group\"\n title=\"Add filter\"\n >\n <SectionHeading>\n Filter\n {totalFilterCount > 0 && (\n <span className=\"ml-1.5 text-xs font-normal text-dc-text-muted normal-case tracking-normal\">\n ({totalFilterCount})\n </span>\n )}\n </SectionHeading>\n <div className=\"flex items-center gap-2\">\n {totalFilterCount > 0 && (\n <span\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation()\n handleClearAll()\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.stopPropagation()\n handleClearAll()\n }\n }}\n className=\"text-xs text-dc-text-muted hover:text-dc-error underline cursor-pointer\"\n >\n Clear all\n </span>\n )}\n <AddIcon className=\"w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors\" />\n </div>\n </button>\n\n {/* Drop Zone Container - Only wraps content, not header */}\n <div\n onDragOver={onFieldDropped ? handleDragOver : undefined}\n onDragLeave={onFieldDropped ? handleDragLeave : undefined}\n onDrop={onFieldDropped ? handleDrop : undefined}\n className={`p-2 -mx-2 rounded-lg border-2 border-dashed transition-all ${\n isDragOver\n ? 'border-dc-primary bg-dc-primary/5'\n : 'border-transparent'\n }`}\n >\n {/* Filter List - Hierarchical Rendering */}\n {filters.length === 0 ? (\n <p className={`text-sm ${isDragOver ? 'text-dc-primary font-medium' : 'text-dc-text-muted'}`}>\n {isDragOver ? 'Drop to add filter' : 'No filters applied'}\n </p>\n ) : (\n <div className=\"space-y-2\">\n {filters.map((filter, index) => renderFilter(filter, index))}\n </div>\n )}\n </div>\n\n {/* Field Search Modal - mode 'filter' shows all fields (measures + dimensions) */}\n <FieldSearchModal\n isOpen={showFieldModal}\n onClose={() => {\n setShowFieldModal(false)\n pendingAddPath.current = []\n }}\n onSelect={handleFieldSelected}\n mode=\"filter\"\n schema={schema}\n selectedFields={selectedFields}\n />\n </div>\n )\n}\n","/**\n * AnalysisAxisDropZone Component\n *\n * A styled version of AxisDropZone that matches the Query Panel card styling.\n * Used in the Analysis Builder's Chart tab for configuring chart axes.\n *\n * Key differences from AxisDropZone:\n * - Vertical card layout instead of inline chips\n * - Two-line display (title + cube name)\n * - Colored icon boxes for measures, plain icons for dimensions\n * - Hidden-on-hover remove buttons\n */\n\nimport { useState, useCallback, useRef, useEffect, DragEvent } from 'react'\nimport { getIcon, getMeasureTypeIcon } from '../../icons'\nimport type { AxisDropZoneConfig } from '../../charts/chartConfigs'\n\nconst CloseIcon = getIcon('close')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\nconst MeasureIcon = getIcon('measure')\n\ninterface FieldMeta {\n title?: string\n shortTitle?: string\n cubeName: string\n type: 'measure' | 'dimension' | 'timeDimension'\n measureType?: string\n}\n\ninterface AnalysisAxisDropZoneProps {\n config: AxisDropZoneConfig\n fields: string[]\n onDrop: (e: DragEvent<HTMLDivElement>, toKey: string) => void\n onRemove: (field: string, fromKey: string) => void\n onDragStart: (\n e: DragEvent<HTMLDivElement>,\n field: string,\n fromKey: string,\n fromIndex?: number\n ) => void\n onDragEnd?: (e: DragEvent<HTMLDivElement>) => void\n onDragOver: (e: DragEvent<HTMLDivElement>) => void\n onReorder?: (fromIndex: number, toIndex: number, axisKey: string) => void\n draggedItem?: { field: string; fromAxis: string; fromIndex?: number } | null\n getFieldMeta?: (field: string) => FieldMeta\n // Dual Y-axis support\n yAxisAssignment?: Record<string, 'left' | 'right'>\n onYAxisAssignmentChange?: (field: string, axis: 'left' | 'right') => void\n}\n\nexport default function AnalysisAxisDropZone({\n config,\n fields,\n onDrop,\n onRemove,\n onDragStart,\n onDragEnd,\n onDragOver,\n onReorder,\n draggedItem,\n getFieldMeta,\n yAxisAssignment,\n onYAxisAssignmentChange\n}: AnalysisAxisDropZoneProps) {\n const { key, label, description, mandatory, maxItems, emptyText } = config\n const [dropTargetIndex, setDropTargetIndex] = useState<number | null>(null)\n const [isDraggedOver, setIsDraggedOver] = useState(false)\n const [isReorderDraggedOver, setIsReorderDraggedOver] = useState(false)\n\n // Track the field being dragged from this axis for drag-out-to-remove\n const draggingFieldRef = useRef<string | null>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n // Keep fields in a ref to avoid stale closure issues\n const fieldsRef = useRef(fields)\n fieldsRef.current = fields\n // Keep dropTargetIndex in a ref to avoid stale closure issues in drop handler\n const dropTargetIndexRef = useRef<number | null>(null)\n\n // Calculate acceptance considering what's being dragged\n const getCanAcceptMore = () => {\n let effectiveCount = fields.length\n\n // If we're dragging FROM this axis, we effectively have one less item\n if (draggedItem && draggedItem.fromAxis === key) {\n effectiveCount = Math.max(0, fields.length - 1)\n }\n\n return !maxItems || effectiveCount < maxItems\n }\n\n const getIsFull = () => {\n let effectiveCount = fields.length\n\n // If we're dragging FROM this axis, we effectively have one less item\n if (draggedItem && draggedItem.fromAxis === key) {\n effectiveCount = Math.max(0, fields.length - 1)\n }\n\n return maxItems && effectiveCount >= maxItems\n }\n\n const canAcceptMore = getCanAcceptMore()\n const isFull = getIsFull()\n\n // Add a global drag end listener to reset visual state\n useEffect(() => {\n const handleGlobalDragEnd = () => {\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n draggingFieldRef.current = null\n }\n\n document.addEventListener('dragend', handleGlobalDragEnd)\n return () => {\n document.removeEventListener('dragend', handleGlobalDragEnd)\n }\n }, [])\n\n // Clear states when transitioning between different drag operations\n useEffect(() => {\n if (draggedItem) {\n // If we have a dragged item but it's not from this axis, clear reorder state\n if (draggedItem.fromAxis !== key) {\n setIsReorderDraggedOver(false)\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n }\n // If we have a dragged item from this axis, clear regular drag state\n else if (draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n setIsDraggedOver(false)\n }\n } else {\n // No dragged item, clear all states\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n }, [draggedItem, key])\n\n // Handle drag over an item - determine drop position based on mouse position\n const handleItemDragOver = useCallback((e: DragEvent<HTMLDivElement>, itemIndex: number) => {\n // Check if this is a reorder operation (same axis)\n if (!draggedItem || draggedItem.fromAxis !== key || draggedItem.fromIndex === undefined) return\n\n e.preventDefault()\n e.stopPropagation()\n\n // Determine if we're in the top or bottom half of the item\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseY = e.clientY - rect.top\n const isTopHalf = mouseY < rect.height / 2\n\n // Calculate target index based on position\n const fromIndex = draggedItem.fromIndex\n let targetIndex = isTopHalf ? itemIndex : itemIndex + 1\n\n // Don't set drop target if it would result in no movement\n if (targetIndex === fromIndex || targetIndex === fromIndex + 1) {\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n } else {\n setDropTargetIndex(targetIndex)\n dropTargetIndexRef.current = targetIndex\n setIsReorderDraggedOver(true)\n }\n }, [draggedItem, key])\n\n // Handle drop on an item for reordering\n const handleItemDrop = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n // DON'T stopPropagation here yet - only stop if this is a reorder operation\n\n // Use ref to get current dropTargetIndex (avoids stale closure)\n const currentDropTargetIndex = dropTargetIndexRef.current\n\n // Check if this is a reorder operation (same axis with valid indices)\n const isReorderOperation = draggedItem &&\n draggedItem.fromAxis === key &&\n draggedItem.fromIndex !== undefined &&\n currentDropTargetIndex !== null\n\n if (!isReorderOperation) {\n // Let the event bubble up to container for external drops\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n setIsReorderDraggedOver(false)\n return // Don't stop propagation - container will handle external drops\n }\n\n // This IS a reorder operation - stop propagation and handle it\n e.stopPropagation()\n\n // Adjust target index when dragging down (after splice, indices shift)\n const fromIndex = draggedItem!.fromIndex!\n const adjustedTarget = currentDropTargetIndex > fromIndex\n ? currentDropTargetIndex - 1\n : currentDropTargetIndex\n\n if (onReorder && adjustedTarget !== fromIndex) {\n onReorder(fromIndex, adjustedTarget, key)\n }\n\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n setIsReorderDraggedOver(false)\n }, [draggedItem, key, onReorder])\n\n // Handle drag end - check if dropped outside container to remove\n const handleFieldDragEnd = useCallback((e: DragEvent<HTMLDivElement>, field: string) => {\n const container = containerRef.current\n if (container && draggingFieldRef.current === field) {\n const rect = container.getBoundingClientRect()\n const isInside =\n e.clientX >= rect.left &&\n e.clientX <= rect.right &&\n e.clientY >= rect.top &&\n e.clientY <= rect.bottom\n\n // If dropped outside the container\n if (!isInside) {\n // Use a small delay to let other drop handlers fire first\n // Then check if the field is still in this axis (wasn't moved elsewhere)\n setTimeout(() => {\n // Check using ref to get current fields, avoiding stale closure\n if (fieldsRef.current.includes(field)) {\n onRemove(field, key)\n }\n }, 0)\n }\n }\n\n draggingFieldRef.current = null\n setDropTargetIndex(null)\n dropTargetIndexRef.current = null\n setIsReorderDraggedOver(false)\n\n onDragEnd?.(e)\n }, [key, onRemove, onDragEnd])\n\n // Calculate transform for gap animation\n const getItemTransform = useCallback((itemIndex: number): string => {\n if (!draggedItem || draggedItem.fromAxis !== key || draggedItem.fromIndex === undefined || dropTargetIndex === null) {\n return ''\n }\n\n const fromIndex = draggedItem.fromIndex\n const gapSize = 40\n\n // If this is the dragged item, no transform needed\n if (itemIndex === fromIndex) return ''\n\n if (fromIndex < dropTargetIndex) {\n // Dragging down\n if (itemIndex >= dropTargetIndex) {\n return `translateY(${gapSize / 2}px)`\n }\n } else {\n // Dragging up\n if (itemIndex >= dropTargetIndex && itemIndex < fromIndex) {\n return `translateY(${gapSize / 2}px)`\n }\n }\n\n return ''\n }, [draggedItem, key, dropTargetIndex])\n\n // Determine if gap indicator should show\n const shouldShowGapIndicator = useCallback((itemIndex: number): boolean => {\n if (!draggedItem || draggedItem.fromAxis !== key || dropTargetIndex === null) return false\n return itemIndex === dropTargetIndex\n }, [draggedItem, key, dropTargetIndex])\n\n // Get default field meta from field name\n const getDefaultFieldMeta = (field: string): FieldMeta => {\n const parts = field.split('.')\n const cubeName = parts[0] || field\n const fieldName = parts[1] || field\n\n return {\n title: fieldName,\n shortTitle: fieldName,\n cubeName,\n type: 'dimension' // Default assumption\n }\n }\n\n // Render icon based on field type\n const renderFieldIcon = (meta: FieldMeta) => {\n if (meta.type === 'measure') {\n // Measures get colored icon box with type-specific icon\n const IconComponent = getMeasureTypeIcon(meta.measureType || 'count') || MeasureIcon\n return (\n <span className=\"w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0\">\n <IconComponent className=\"w-4 h-4\" />\n </span>\n )\n } else if (meta.type === 'timeDimension') {\n // Time dimensions get colored background matching field selector\n return (\n <span className=\"w-6 h-6 flex items-center justify-center rounded bg-dc-time-dimension text-dc-time-dimension-text flex-shrink-0\">\n <TimeDimensionIcon className=\"w-4 h-4\" />\n </span>\n )\n } else {\n // Regular dimensions get colored background matching field selector\n return (\n <span className=\"w-6 h-6 flex items-center justify-center rounded bg-dc-dimension text-dc-dimension-text flex-shrink-0\">\n <DimensionIcon className=\"w-4 h-4\" />\n </span>\n )\n }\n }\n\n return (\n <div className=\"mb-3\">\n {/* Header */}\n <div className=\"mb-2\">\n <h4 className=\"text-sm font-medium text-dc-text flex items-center\">\n {label}\n {mandatory && <span className=\"text-dc-error ml-1\">*</span>}\n </h4>\n {description && <div className=\"text-xs text-dc-text-muted mt-0.5\">{description}</div>}\n </div>\n\n {/* Drop Zone Container */}\n <div\n ref={containerRef}\n data-axis-container={key}\n className={`min-h-[48px] border-2 border-dashed rounded-lg p-2 transition-all duration-200 ${\n (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'shadow-sm border-solid'\n : isFull\n ? 'bg-dc-surface-secondary'\n : 'bg-dc-surface-secondary hover:bg-dc-surface-hover'\n }`}\n style={{\n borderColor:\n (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'var(--dc-primary)'\n : 'var(--dc-border)',\n backgroundColor:\n (isDraggedOver && (canAcceptMore || maxItems === 1)) || isReorderDraggedOver\n ? 'rgba(var(--dc-primary-rgb), 0.1)'\n : undefined\n }}\n onDragOver={(e) => {\n // Check if this is a reorder operation (same axis) - if so, don't interfere\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n return\n }\n\n // Simple acceptance check - either we have space OR it's a single-item replacement\n const canAccept = canAcceptMore || maxItems === 1\n\n if (canAccept) {\n setIsDraggedOver(true)\n onDragOver(e)\n } else {\n e.preventDefault()\n e.dataTransfer.dropEffect = 'none'\n }\n }}\n onDragLeave={(e) => {\n // Check if we're truly leaving the container\n const rect = e.currentTarget.getBoundingClientRect()\n const isLeavingContainer =\n e.clientX < rect.left ||\n e.clientX > rect.right ||\n e.clientY < rect.top ||\n e.clientY > rect.bottom\n\n // Also check if the related target is outside this container\n const relatedTarget = e.relatedTarget as Element | null\n const isRelatedTargetOutside = relatedTarget && !e.currentTarget.contains(relatedTarget)\n\n if (isLeavingContainer || isRelatedTargetOutside || e.currentTarget === e.target) {\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }\n }}\n onDrop={(e) => {\n // Check if this is a reorder operation (same axis) - if so, don't interfere\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n return\n }\n\n // Simple acceptance check - either we have space OR it's a single-item replacement\n const shouldAcceptDrop = canAcceptMore || maxItems === 1\n\n if (shouldAcceptDrop) {\n onDrop(e, key)\n } else {\n e.preventDefault()\n }\n\n // Reset drag state on drop\n setIsDraggedOver(false)\n setIsReorderDraggedOver(false)\n }}\n >\n {fields.length === 0 ? (\n <div className=\"text-sm text-dc-text-muted text-center py-2\">\n {isFull ? 'Maximum items reached' : emptyText || `Drop fields here`}\n </div>\n ) : (\n <div\n className=\"space-y-2\"\n onDragOver={(e) => {\n // Allow dropping for reorder operations\n if (draggedItem && draggedItem.fromAxis === key) {\n e.preventDefault()\n }\n }}\n onDrop={(e) => {\n // Handle reorder drops at container level\n if (draggedItem && draggedItem.fromAxis === key && draggedItem.fromIndex !== undefined) {\n handleItemDrop(e)\n }\n }}\n >\n {fields.map((field, index) => {\n const meta = getFieldMeta ? getFieldMeta(field) : getDefaultFieldMeta(field)\n const isBeingDragged =\n draggedItem && draggedItem.field === field && draggedItem.fromAxis === key\n const transform = getItemTransform(index)\n const showGapBefore = shouldShowGapIndicator(index)\n\n return (\n <div\n key={`${field}-${index}`}\n className=\"relative\"\n style={{\n transform,\n transition: draggedItem && draggedItem.fromAxis === key ? 'transform 0.15s ease-out' : 'none'\n }}\n >\n {/* Gap indicator line - shows where item will be inserted */}\n {showGapBefore && (\n <div className=\"absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10\">\n <div className=\"h-0.5 w-full bg-dc-primary rounded-full\" />\n </div>\n )}\n\n <div\n draggable\n onDragStart={(e) => {\n draggingFieldRef.current = field\n onDragStart(e, field, key, index)\n }}\n onDragEnd={(e) => handleFieldDragEnd(e, field)}\n onDragOver={(e) => handleItemDragOver(e, index)}\n onDrop={handleItemDrop}\n className={`flex items-center gap-2 p-2 bg-dc-surface rounded-lg group hover:bg-dc-surface-tertiary transition-colors cursor-move ${\n isBeingDragged ? 'opacity-30 cursor-grabbing' : ''\n }`}\n >\n {/* Icon */}\n {renderFieldIcon(meta)}\n\n {/* Field Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm text-dc-text truncate\" title={field}>\n {meta.shortTitle || meta.title || field.split('.').pop()}\n </div>\n <div className=\"text-xs text-dc-text-muted truncate\">{meta.cubeName}</div>\n </div>\n\n {/* L/R Axis Toggle - only for yAxis with dual axis enabled */}\n {config.enableDualAxis && onYAxisAssignmentChange && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n const currentAxis = yAxisAssignment?.[field] || 'left'\n onYAxisAssignmentChange(field, currentAxis === 'left' ? 'right' : 'left')\n }}\n className={`px-1.5 py-0.5 text-xs font-medium rounded transition-colors flex-shrink-0 ${\n (yAxisAssignment?.[field] || 'left') === 'left'\n ? 'bg-dc-info-bg text-dc-info hover:opacity-80'\n : 'bg-dc-accent-bg text-dc-accent hover:opacity-80'\n }`}\n title={`Y-Axis: ${(yAxisAssignment?.[field] || 'left') === 'left' ? 'Left' : 'Right'} (click to toggle)`}\n >\n {(yAxisAssignment?.[field] || 'left') === 'left' ? 'L' : 'R'}\n </button>\n )}\n\n {/* Remove Button - hidden until hover */}\n <button\n type=\"button\"\n onClick={() => onRemove(field, key)}\n className=\"p-1 text-dc-text-muted hover:text-dc-danger opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0\"\n title={`Remove from ${label}`}\n >\n <CloseIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n )\n })}\n {/* Gap indicator after the last item - shows when dropping at end */}\n {draggedItem && draggedItem.fromAxis === key && dropTargetIndex === fields.length && (\n <div className=\"relative h-2\">\n <div className=\"absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10\">\n <div className=\"h-0.5 w-full bg-dc-primary rounded-full\" />\n </div>\n </div>\n )}\n {/* Handle drop at the end of the list for reordering */}\n {draggedItem && draggedItem.fromAxis === key && fields.length > 1 && (\n <div\n className=\"h-6\"\n onDragOver={(e) => {\n if (draggedItem.fromIndex !== undefined) {\n e.preventDefault()\n const lastIndex = fields.length\n if (dropTargetIndexRef.current !== lastIndex && draggedItem.fromIndex !== lastIndex - 1) {\n setDropTargetIndex(lastIndex)\n dropTargetIndexRef.current = lastIndex\n setIsReorderDraggedOver(true)\n }\n }\n }}\n onDrop={handleItemDrop}\n />\n )}\n </div>\n )}\n </div>\n\n {mandatory && fields.length === 0 && (\n <div className=\"text-xs text-dc-error mt-1\">This field is required</div>\n )}\n </div>\n )\n}\n","/**\n * AnalysisChartConfigPanel Component\n *\n * A single-column chart configuration panel for the AnalysisBuilder.\n * Uses fields from the Query tab (metrics/breakdowns) as available fields.\n * Renders axis drop zones and display options based on chart type.\n */\n\nimport { useMemo, useEffect, useState, useCallback, DragEvent } from 'react'\nimport { getIcon, getMeasureTypeIcon } from '../../icons'\nimport SectionHeading from './SectionHeading'\nimport AnalysisAxisDropZone from './AnalysisAxisDropZone'\nimport ChartTypeSelector from '../ChartTypeSelector'\nimport { chartConfigRegistry } from '../../charts/chartConfigRegistry'\nimport { getChartConfig } from '../../charts/chartConfigs'\nimport type { ChartType, ChartAxisConfig } from '../../types'\nimport type { MetricItem, BreakdownItem } from './types'\nimport type { ChartAvailabilityMap } from '../../shared/chartDefaults'\nimport type { MetaResponse } from '../../shared/types'\n\nconst MeasureIcon = getIcon('measure')\nconst DimensionIcon = getIcon('dimension')\nconst TimeDimensionIcon = getIcon('timeDimension')\n\ninterface AnalysisChartConfigPanelProps {\n chartType: ChartType\n chartConfig: ChartAxisConfig\n metrics: MetricItem[]\n breakdowns: BreakdownItem[]\n /** Schema metadata for resolving field titles */\n schema?: MetaResponse | null\n /** Map of chart type availability for disabling unavailable chart types */\n chartAvailability?: ChartAvailabilityMap\n onChartTypeChange: (type: ChartType) => void\n onChartConfigChange: (config: ChartAxisConfig) => void\n}\n\nexport default function AnalysisChartConfigPanel({\n chartType,\n chartConfig,\n metrics,\n breakdowns,\n schema,\n chartAvailability,\n onChartTypeChange,\n onChartConfigChange\n}: AnalysisChartConfigPanelProps) {\n // Track currently dragging item for immediate state updates\n const [draggedItem, setDraggedItem] = useState<{\n field: string\n fromAxis: string\n fromIndex?: number\n } | null>(null)\n\n // Derive available fields from metrics and breakdowns\n const availableFields = useMemo(\n () => ({\n measures: metrics.map((m) => m.field),\n dimensions: breakdowns.filter((b) => !b.isTimeDimension).map((b) => b.field),\n timeDimensions: breakdowns.filter((b) => b.isTimeDimension).map((b) => b.field)\n }),\n [metrics, breakdowns]\n )\n\n // Get configuration for current chart type\n const chartTypeConfig = useMemo(\n () => getChartConfig(chartType, chartConfigRegistry),\n [chartType]\n )\n\n // Check if this chart type skips queries\n const shouldSkipQuery = chartTypeConfig.skipQuery === true\n\n // Get fields for each drop zone\n const getFieldsForDropZone = (key: string): string[] => {\n const value = chartConfig[key as keyof ChartAxisConfig]\n const result = Array.isArray(value)\n ? value\n : typeof value === 'string'\n ? [value]\n : []\n return result\n }\n\n // Clean up chart config when available fields change\n useEffect(() => {\n const allAvailableFields = [\n ...availableFields.dimensions,\n ...availableFields.timeDimensions,\n ...availableFields.measures\n ]\n\n let hasChanges = false\n const newConfig = { ...chartConfig }\n\n // Check each axis and remove fields that are no longer available\n chartTypeConfig.dropZones.forEach((dropZone) => {\n const currentFields = getFieldsForDropZone(dropZone.key)\n const validFields = currentFields.filter((field) => allAvailableFields.includes(field))\n\n if (validFields.length !== currentFields.length) {\n hasChanges = true\n if (validFields.length === 0) {\n // Remove the axis property entirely if no valid fields remain\n delete newConfig[dropZone.key as keyof ChartAxisConfig]\n } else if (dropZone.maxItems === 1) {\n // Single field axis - always store as string\n newConfig[dropZone.key as keyof ChartAxisConfig] = validFields[0] as any\n } else {\n // Multi-field axis - always store as array\n newConfig[dropZone.key as keyof ChartAxisConfig] = validFields as any\n }\n }\n })\n\n if (hasChanges) {\n onChartConfigChange(newConfig)\n }\n }, [availableFields, chartConfig, chartTypeConfig.dropZones, onChartConfigChange])\n\n // Helper to determine field type and styling\n const getFieldType = (field: string): 'dimension' | 'timeDimension' | 'measure' => {\n if (availableFields.measures.includes(field)) return 'measure'\n if (availableFields.timeDimensions.includes(field)) return 'timeDimension'\n return 'dimension'\n }\n\n // Helper to find field metadata from schema\n const findFieldMeta = (fieldName: string) => {\n if (!schema?.cubes) return null\n\n const [cubeName] = fieldName.split('.')\n const cube = schema.cubes.find((c) => c.name === cubeName)\n if (!cube) return null\n\n // Check measures first, then dimensions\n const measure = cube.measures?.find((m) => m.name === fieldName)\n if (measure) return { ...measure, fieldType: 'measure' as const }\n\n const dimension = cube.dimensions?.find((d) => d.name === fieldName)\n if (dimension) return { ...dimension, fieldType: dimension.type === 'time' ? 'timeDimension' as const : 'dimension' as const }\n\n return null\n }\n\n // Get field metadata for display in AnalysisAxisDropZone\n const getFieldMeta = (field: string) => {\n const fieldType = getFieldType(field)\n const parts = field.split('.')\n const cubeName = parts[0] || field\n const fieldName = parts[1] || field\n\n // Look up field metadata from schema\n const schemaMeta = findFieldMeta(field)\n\n // Try to find the field in breakdowns for isTimeDimension flag\n const breakdownItem = breakdowns.find((b) => b.field === field)\n\n if (schemaMeta) {\n return {\n title: schemaMeta.title || fieldName,\n shortTitle: schemaMeta.shortTitle || schemaMeta.title || fieldName,\n cubeName,\n type: schemaMeta.fieldType,\n measureType: schemaMeta.fieldType === 'measure' ? schemaMeta.type : undefined\n }\n }\n\n // Fallback when schema lookup fails\n if (breakdownItem) {\n return {\n title: fieldName,\n shortTitle: fieldName,\n cubeName,\n type: breakdownItem.isTimeDimension ? ('timeDimension' as const) : ('dimension' as const)\n }\n }\n\n return {\n title: fieldName,\n shortTitle: fieldName,\n cubeName,\n type: fieldType\n }\n }\n\n // Drag and drop handlers\n const handleDragStart = (\n e: DragEvent<HTMLDivElement>,\n field: string,\n fromAxis: string,\n fromIndex?: number\n ) => {\n e.dataTransfer.setData('text/plain', JSON.stringify({ field, fromAxis, fromIndex }))\n setDraggedItem({ field, fromAxis, fromIndex })\n }\n\n const handleDragOver = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n }\n\n const handleDragEnd = () => {\n setDraggedItem(null)\n }\n\n const handleDrop = (e: DragEvent<HTMLDivElement>, toAxis: string) => {\n e.preventDefault()\n const data = JSON.parse(e.dataTransfer.getData('text/plain'))\n const { field, fromAxis } = data\n\n const newConfig = { ...chartConfig }\n\n // Remove from old location if moving between axes\n if (fromAxis !== 'available' && fromAxis !== toAxis) {\n const fromValue = newConfig[fromAxis as keyof ChartAxisConfig]\n if (Array.isArray(fromValue)) {\n const filteredValue = fromValue.filter((f) => f !== field)\n if (filteredValue.length === 0) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n } else {\n newConfig[fromAxis as keyof ChartAxisConfig] = filteredValue as any\n }\n } else if (fromValue === field) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n }\n }\n\n // Add to new location\n const toValue = newConfig[toAxis as keyof ChartAxisConfig]\n const dropZoneConfig = chartTypeConfig.dropZones.find((dz) => dz.key === toAxis)\n\n if (dropZoneConfig?.maxItems === 1) {\n // Single field - always store as string\n newConfig[toAxis as keyof ChartAxisConfig] = field as any\n } else {\n // Multiple fields - always store as array\n if (Array.isArray(toValue)) {\n if (!toValue.includes(field)) {\n newConfig[toAxis as keyof ChartAxisConfig] = [...toValue, field] as any\n }\n } else {\n newConfig[toAxis as keyof ChartAxisConfig] = [field] as any\n }\n }\n\n // Apply default yAxisAssignment when adding to yAxis with dual axis enabled\n if (toAxis === 'yAxis' && dropZoneConfig?.enableDualAxis) {\n const currentYAxisFields = Array.isArray(newConfig.yAxis) ? newConfig.yAxis : [field]\n const fieldIndex = currentYAxisFields.indexOf(field)\n // Default: 1st field = left, 2nd field = right, 3rd+ = left\n if (!newConfig.yAxisAssignment?.[field]) {\n newConfig.yAxisAssignment = {\n ...newConfig.yAxisAssignment,\n [field]: fieldIndex === 1 ? 'right' : 'left'\n }\n }\n }\n\n setDraggedItem(null)\n onChartConfigChange(newConfig)\n }\n\n const handleRemoveFromAxis = (field: string, fromAxis: string) => {\n const newConfig = { ...chartConfig }\n const value = newConfig[fromAxis as keyof ChartAxisConfig]\n\n if (Array.isArray(value)) {\n const filteredValue = value.filter((f) => f !== field)\n if (filteredValue.length === 0) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n } else {\n newConfig[fromAxis as keyof ChartAxisConfig] = filteredValue as any\n }\n } else if (value === field) {\n delete newConfig[fromAxis as keyof ChartAxisConfig]\n }\n\n // Clean up yAxisAssignment when removing from yAxis\n if (fromAxis === 'yAxis' && newConfig.yAxisAssignment?.[field]) {\n const { [field]: _removed, ...rest } = newConfig.yAxisAssignment\n newConfig.yAxisAssignment = Object.keys(rest).length > 0 ? rest : undefined\n }\n\n onChartConfigChange(newConfig)\n }\n\n const handleReorder = (fromIndex: number, toIndex: number, axisKey: string) => {\n const newConfig = { ...chartConfig }\n const value = newConfig[axisKey as keyof ChartAxisConfig]\n\n // Only reorder if we have an array with multiple items\n if (Array.isArray(value) && value.length > 1 && fromIndex !== toIndex) {\n const newArray = [...value]\n const [movedItem] = newArray.splice(fromIndex, 1)\n newArray.splice(toIndex, 0, movedItem)\n newConfig[axisKey as keyof ChartAxisConfig] = newArray as any\n\n setDraggedItem(null)\n onChartConfigChange(newConfig)\n }\n }\n\n // Handler for Y-axis assignment changes (dual Y-axis support)\n const handleYAxisAssignmentChange = useCallback(\n (field: string, axis: 'left' | 'right') => {\n onChartConfigChange({\n ...chartConfig,\n yAxisAssignment: {\n ...chartConfig.yAxisAssignment,\n [field]: axis\n }\n })\n },\n [chartConfig, onChartConfigChange]\n )\n\n // Get unassigned fields (fields selected in Query tab but not yet assigned to chart axes)\n const getUnassignedFields = () => {\n const assignedFields = new Set<string>()\n chartTypeConfig.dropZones.forEach((dz) => {\n getFieldsForDropZone(dz.key).forEach((field) => assignedFields.add(field))\n })\n\n // Exclude the currently dragged field only if it's being dragged FROM a configured axis\n if (draggedItem && draggedItem.fromAxis !== 'available') {\n assignedFields.add(draggedItem.field)\n }\n\n return {\n dimensions: availableFields.dimensions.filter((f) => !assignedFields.has(f)),\n timeDimensions: availableFields.timeDimensions.filter((f) => !assignedFields.has(f)),\n measures: availableFields.measures.filter((f) => !assignedFields.has(f))\n }\n }\n\n const unassignedFields = getUnassignedFields()\n const hasUnassignedFields =\n unassignedFields.dimensions.length > 0 ||\n unassignedFields.timeDimensions.length > 0 ||\n unassignedFields.measures.length > 0\n\n return (\n <div className=\"space-y-6\">\n {/* Chart Type Selector */}\n <div>\n <SectionHeading className=\"mb-2\">Chart Type</SectionHeading>\n <ChartTypeSelector\n selectedType={chartType}\n onTypeChange={onChartTypeChange}\n availability={chartAvailability}\n compact\n />\n </div>\n\n {/* Chart Axis Configuration - Dynamic Drop Zones */}\n {!shouldSkipQuery && chartTypeConfig.dropZones.length > 0 && (\n <div>\n <SectionHeading className=\"mb-2\">\n Chart Configuration\n </SectionHeading>\n <div className=\"space-y-1\">\n {chartTypeConfig.dropZones.map((dropZone) => (\n <AnalysisAxisDropZone\n key={dropZone.key}\n config={dropZone}\n fields={getFieldsForDropZone(dropZone.key)}\n onDrop={handleDrop}\n onRemove={handleRemoveFromAxis}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n onReorder={handleReorder}\n draggedItem={draggedItem}\n getFieldMeta={getFieldMeta}\n yAxisAssignment={chartConfig.yAxisAssignment}\n onYAxisAssignmentChange={\n dropZone.enableDualAxis ? handleYAxisAssignmentChange : undefined\n }\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Unassigned Fields - Show fields from Query tab that haven't been assigned yet */}\n {!shouldSkipQuery && hasUnassignedFields && (\n <div>\n <div className=\"mb-2\">\n <SectionHeading>Unassigned Fields</SectionHeading>\n <div className=\"text-xs text-dc-text-muted mt-0.5\">\n Drag fields to chart axes above\n </div>\n </div>\n <div className=\"border-2 border-dashed border-dc-border rounded-lg p-2 bg-dc-surface-secondary\">\n <div className=\"space-y-2\">\n {/* Measures */}\n {unassignedFields.measures.map((field) => {\n const meta = getFieldMeta(field)\n const isBeingDragged =\n draggedItem && draggedItem.field === field && draggedItem.fromAxis === 'available'\n const IconComponent = getMeasureTypeIcon(meta.measureType || 'count') || MeasureIcon\n return (\n <div\n key={field}\n draggable\n onDragStart={(e) => handleDragStart(e, field, 'available')}\n onDragEnd={handleDragEnd}\n className={`flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={field}\n >\n <span className=\"w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0\">\n <IconComponent className=\"w-4 h-4\" />\n </span>\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm text-dc-text truncate\">{meta.shortTitle}</div>\n <div className=\"text-xs text-dc-text-muted truncate\">{meta.cubeName}</div>\n </div>\n </div>\n )\n })}\n\n {/* Dimensions */}\n {unassignedFields.dimensions.map((field) => {\n const meta = getFieldMeta(field)\n const isBeingDragged =\n draggedItem && draggedItem.field === field && draggedItem.fromAxis === 'available'\n return (\n <div\n key={field}\n draggable\n onDragStart={(e) => handleDragStart(e, field, 'available')}\n onDragEnd={handleDragEnd}\n className={`flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={field}\n >\n <span className=\"w-6 h-6 flex items-center justify-center rounded bg-dc-dimension text-dc-dimension-text flex-shrink-0\">\n <DimensionIcon className=\"w-4 h-4\" />\n </span>\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm text-dc-text truncate\">{meta.shortTitle}</div>\n <div className=\"text-xs text-dc-text-muted truncate\">{meta.cubeName}</div>\n </div>\n </div>\n )\n })}\n\n {/* Time Dimensions */}\n {unassignedFields.timeDimensions.map((field) => {\n const meta = getFieldMeta(field)\n const isBeingDragged =\n draggedItem && draggedItem.field === field && draggedItem.fromAxis === 'available'\n return (\n <div\n key={field}\n draggable\n onDragStart={(e) => handleDragStart(e, field, 'available')}\n onDragEnd={handleDragEnd}\n className={`flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${isBeingDragged ? 'opacity-50 cursor-grabbing' : ''}`}\n title={field}\n >\n <span className=\"w-6 h-6 flex items-center justify-center rounded bg-dc-time-dimension text-dc-time-dimension-text flex-shrink-0\">\n <TimeDimensionIcon className=\"w-4 h-4\" />\n </span>\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm text-dc-text truncate\">{meta.shortTitle}</div>\n <div className=\"text-xs text-dc-text-muted truncate\">{meta.cubeName}</div>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n </div>\n )}\n\n {/* Help text when no fields are available */}\n {!shouldSkipQuery &&\n availableFields.measures.length === 0 &&\n availableFields.dimensions.length === 0 &&\n availableFields.timeDimensions.length === 0 && (\n <div className=\"text-center text-dc-text-muted text-sm py-4\">\n <p>Add metrics and breakdowns in the Query tab to configure your chart.</p>\n </div>\n )}\n </div>\n )\n}\n","/**\n * AnalysisDisplayConfigPanel Component\n *\n * A panel for configuring chart display options (legend, grid, tooltip, etc.)\n * Extracted from AnalysisChartConfigPanel to be shown in its own tab.\n */\n\nimport { useMemo } from 'react'\nimport SectionHeading from './SectionHeading'\nimport { chartConfigRegistry } from '../../charts/chartConfigRegistry'\nimport { getChartConfig } from '../../charts/chartConfigs'\nimport type { ChartType, ChartDisplayConfig, ColorPalette, AxisFormatConfig } from '../../types'\nimport { AxisFormatControls } from '../charts/AxisFormatControls'\n\ninterface AnalysisDisplayConfigPanelProps {\n chartType: ChartType\n displayConfig: ChartDisplayConfig\n colorPalette?: ColorPalette\n onDisplayConfigChange: (config: ChartDisplayConfig) => void\n}\n\nexport default function AnalysisDisplayConfigPanel({\n chartType,\n displayConfig,\n colorPalette,\n onDisplayConfigChange\n}: AnalysisDisplayConfigPanelProps) {\n // Get configuration for current chart type\n const chartTypeConfig = useMemo(\n () => getChartConfig(chartType, chartConfigRegistry),\n [chartType]\n )\n\n // Check if we have any display options to show\n const hasDisplayOptions =\n (chartTypeConfig.displayOptions && chartTypeConfig.displayOptions.length > 0) ||\n (chartTypeConfig.displayOptionsConfig && chartTypeConfig.displayOptionsConfig.length > 0)\n\n if (!hasDisplayOptions) {\n return (\n <div className=\"text-center text-dc-text-muted text-sm py-4\">\n <p>No display options available for this chart type.</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-6\">\n <div>\n <SectionHeading className=\"mb-2\">Display Options</SectionHeading>\n <div className=\"space-y-2\">\n {/* Backward compatibility: Simple boolean display options */}\n {chartTypeConfig.displayOptions?.includes('showLegend') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showLegend ?? true}\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n showLegend: e.target.checked\n })\n }\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Legend</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('showGrid') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showGrid ?? true}\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n showGrid: e.target.checked\n })\n }\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Grid</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('showTooltip') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.showTooltip ?? true}\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n showTooltip: e.target.checked\n })\n }\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Show Tooltip</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('stacked') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.stacked ?? false}\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n stacked: e.target.checked\n })\n }\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Stacked</span>\n </label>\n )}\n\n {chartTypeConfig.displayOptions?.includes('hideHeader') && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={displayConfig.hideHeader ?? false}\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n hideHeader: e.target.checked\n })\n }\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">Hide Header</span>\n </label>\n )}\n\n {/* New structured display options */}\n {chartTypeConfig.displayOptionsConfig?.map((option) => (\n <div key={option.key} className={`space-y-1 ${option.type === 'axisFormat' ? 'mt-6 pt-2' : ''}`}>\n {option.type === 'boolean' && (\n <label className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={\n (displayConfig[option.key as keyof ChartDisplayConfig] as boolean) ??\n option.defaultValue ??\n false\n }\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.checked\n })\n }\n className=\"rounded border-dc-border focus:ring-dc-accent\"\n style={{ color: 'var(--dc-primary)' }}\n />\n <span className=\"text-sm text-dc-text\">{option.label}</span>\n </label>\n )}\n\n {option.type === 'string' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">\n {option.label}\n {option.key === 'content' && (\n <span className=\"text-xs text-dc-text-muted ml-1\">\n (only headers, lists and links)\n </span>\n )}\n </label>\n {option.key === 'content' ? (\n <textarea\n value={\n (displayConfig[option.key as keyof ChartDisplayConfig] as string) ??\n option.defaultValue ??\n ''\n }\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })\n }\n placeholder={option.placeholder}\n rows={8}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent font-mono resize-y bg-dc-surface text-dc-text\"\n />\n ) : (\n <input\n type=\"text\"\n value={\n (displayConfig[option.key as keyof ChartDisplayConfig] as string) ??\n option.defaultValue ??\n ''\n }\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })\n }\n placeholder={option.placeholder}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n )}\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'paletteColor' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <div className=\"flex flex-wrap gap-2\">\n {colorPalette?.colors.map((color, index) => {\n const isSelected =\n ((displayConfig[option.key as keyof ChartDisplayConfig] as number) ??\n option.defaultValue ??\n 0) === index\n return (\n <button\n key={index}\n type=\"button\"\n onClick={() =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: index\n })\n }\n className={`w-8 h-8 rounded border-2 transition-all duration-200 hover:scale-110 focus:outline-hidden focus:ring-2 focus:ring-dc-accent focus:ring-offset-1 ${\n isSelected\n ? 'ring-2 ring-offset-1 scale-110'\n : 'hover:border-dc-text-muted'\n }`}\n style={{\n backgroundColor: color,\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n title={`Color ${index + 1}: ${color}`}\n />\n )\n }) || [\n // Fallback if no palette available\n <button\n key={0}\n type=\"button\"\n onClick={() =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: 0\n })\n }\n className=\"w-8 h-8 rounded-sm border-2 ring-2 ring-offset-1\"\n style={{\n backgroundColor: '#8884d8',\n borderColor: 'var(--dc-primary)',\n boxShadow: '0 0 0 2px var(--dc-primary)'\n }}\n title=\"Default Color\"\n />\n ]}\n </div>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'number' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <input\n type=\"number\"\n value={\n (displayConfig[option.key as keyof ChartDisplayConfig] as number) ??\n option.defaultValue ??\n 0\n }\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value === '' ? undefined : Number(e.target.value)\n })\n }\n placeholder={option.placeholder}\n min={option.min}\n max={option.max}\n step={option.step}\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'select' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <select\n value={\n (displayConfig[option.key as keyof ChartDisplayConfig] as string) ??\n option.defaultValue ??\n ''\n }\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })\n }\n className=\"w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n >\n {option.options?.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'color' && (\n <div className=\"space-y-1\">\n <label className=\"text-sm text-dc-text-secondary\">{option.label}</label>\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"color\"\n value={\n (displayConfig[option.key as keyof ChartDisplayConfig] as string) ??\n option.defaultValue ??\n '#8884d8'\n }\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })\n }\n className=\"w-12 h-8 border border-dc-border rounded-sm cursor-pointer\"\n />\n <input\n type=\"text\"\n value={\n (displayConfig[option.key as keyof ChartDisplayConfig] as string) ??\n option.defaultValue ??\n '#8884d8'\n }\n onChange={(e) =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: e.target.value\n })\n }\n placeholder={option.placeholder || '#8884d8'}\n className=\"flex-1 px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n </div>\n {option.description && (\n <p className=\"text-xs text-dc-text-muted\">{option.description}</p>\n )}\n </div>\n )}\n\n {option.type === 'axisFormat' && (\n <AxisFormatControls\n axisLabel={option.label}\n value={(displayConfig[option.key as keyof ChartDisplayConfig] as AxisFormatConfig) || {}}\n onChange={(config) =>\n onDisplayConfigChange({\n ...displayConfig,\n [option.key]: Object.keys(config).length > 0 ? config : undefined\n })\n }\n />\n )}\n </div>\n ))}\n </div>\n </div>\n </div>\n )\n}\n","/**\n * AnalysisQueryPanel Component\n *\n * Right-side panel containing Query and Chart tabs with sections for\n * Metrics, Filters, and Breakdowns.\n */\n\nimport { useEffect, memo } from 'react'\nimport type { AnalysisQueryPanelProps } from './types'\nimport MetricsSection from './MetricsSection'\nimport BreakdownSection from './BreakdownSection'\nimport AnalysisFilterSection from './AnalysisFilterSection'\nimport AnalysisChartConfigPanel from './AnalysisChartConfigPanel'\nimport AnalysisDisplayConfigPanel from './AnalysisDisplayConfigPanel'\n\n/**\n * AnalysisQueryPanel displays the right-side query builder with:\n * - Query/Chart tab switcher\n * - Metrics section (measures)\n * - Filter section\n * - Breakdown section (dimensions)\n * - Chart configuration (in Chart tab)\n */\nconst AnalysisQueryPanel = memo(function AnalysisQueryPanel({\n metrics,\n breakdowns,\n filters,\n schema,\n activeTab,\n onActiveTabChange,\n onAddMetric,\n onRemoveMetric,\n onReorderMetrics,\n onAddBreakdown,\n onRemoveBreakdown,\n onBreakdownGranularityChange,\n onReorderBreakdowns,\n onFiltersChange,\n onDropFieldToFilter,\n // Sorting\n order,\n onOrderChange,\n // Chart configuration\n chartType,\n chartConfig,\n displayConfig,\n colorPalette,\n chartAvailability,\n onChartTypeChange,\n onChartConfigChange,\n onDisplayConfigChange\n}: AnalysisQueryPanelProps) {\n // Force query tab when no metrics are selected\n useEffect(() => {\n if (metrics.length === 0 && (activeTab === 'chart' || activeTab === 'display')) {\n onActiveTabChange('query')\n }\n }, [metrics.length, activeTab, onActiveTabChange])\n\n return (\n <div className=\"h-full flex flex-col bg-dc-surface\">\n {/* Tab Bar */}\n <div className=\"flex border-b border-dc-border flex-shrink-0\">\n <button\n onClick={() => onActiveTabChange('query')}\n className={`flex-1 px-4 py-3 text-sm font-medium transition-colors ${\n activeTab === 'query'\n ? 'text-dc-primary border-b-2 border-dc-primary'\n : 'text-dc-text-secondary hover:text-dc-text'\n }`}\n >\n Query\n </button>\n <button\n onClick={() => metrics.length > 0 && onActiveTabChange('chart')}\n disabled={metrics.length === 0}\n className={`flex-1 px-4 py-3 text-sm font-medium transition-colors ${\n activeTab === 'chart'\n ? 'text-dc-primary border-b-2 border-dc-primary'\n : metrics.length === 0\n ? 'text-dc-text-muted cursor-not-allowed opacity-50'\n : 'text-dc-text-secondary hover:text-dc-text'\n }`}\n title={metrics.length === 0 ? 'Add metrics to configure chart' : 'Chart configuration'}\n >\n Chart\n </button>\n <button\n onClick={() => metrics.length > 0 && onActiveTabChange('display')}\n disabled={metrics.length === 0}\n className={`flex-1 px-4 py-3 text-sm font-medium transition-colors ${\n activeTab === 'display'\n ? 'text-dc-primary border-b-2 border-dc-primary'\n : metrics.length === 0\n ? 'text-dc-text-muted cursor-not-allowed opacity-50'\n : 'text-dc-text-secondary hover:text-dc-text'\n }`}\n title={metrics.length === 0 ? 'Add metrics to configure display' : 'Display options'}\n >\n Display\n </button>\n </div>\n\n {/* Tab Content */}\n <div className=\"flex-1 overflow-auto p-4\">\n {activeTab === 'query' ? (\n <div className=\"space-y-6\">\n {/* Metrics Section */}\n <MetricsSection\n metrics={metrics}\n schema={schema}\n onAdd={onAddMetric}\n onRemove={onRemoveMetric}\n order={order}\n onOrderChange={onOrderChange}\n onReorder={onReorderMetrics}\n />\n\n {/* Breakdown Section */}\n <BreakdownSection\n breakdowns={breakdowns}\n schema={schema}\n onAdd={onAddBreakdown}\n onRemove={onRemoveBreakdown}\n onGranularityChange={onBreakdownGranularityChange}\n order={order}\n onOrderChange={onOrderChange}\n onReorder={onReorderBreakdowns}\n />\n\n {/* Filter Section */}\n <AnalysisFilterSection\n filters={filters}\n schema={schema}\n onFiltersChange={onFiltersChange}\n onFieldDropped={onDropFieldToFilter}\n />\n </div>\n ) : activeTab === 'chart' ? (\n /* Chart Tab Content */\n <AnalysisChartConfigPanel\n chartType={chartType}\n chartConfig={chartConfig}\n metrics={metrics}\n breakdowns={breakdowns}\n schema={schema}\n chartAvailability={chartAvailability}\n onChartTypeChange={onChartTypeChange}\n onChartConfigChange={onChartConfigChange}\n />\n ) : activeTab === 'display' ? (\n /* Display Tab Content */\n <AnalysisDisplayConfigPanel\n chartType={chartType}\n displayConfig={displayConfig}\n colorPalette={colorPalette}\n onDisplayConfigChange={onDisplayConfigChange}\n />\n ) : null}\n </div>\n </div>\n )\n})\n\nexport default AnalysisQueryPanel\n","/**\n * AnalysisAIPanel Component\n *\n * A collapsible panel for AI-powered query generation.\n * Appears above the results panel when activated.\n */\n\nimport { useCallback, KeyboardEvent } from 'react'\nimport { getIcon } from '../../icons'\n\nconst SparklesIcon = getIcon('sparkles')\nconst ErrorIcon = getIcon('error')\n\nexport interface AnalysisAIPanelProps {\n /** User's natural language prompt */\n userPrompt: string\n /** Callback when prompt changes */\n onPromptChange: (prompt: string) => void\n /** Whether a query is being generated */\n isGenerating: boolean\n /** Error message from generation */\n error: string | null\n /** Whether the AI has generated a query */\n hasGeneratedQuery: boolean\n /** Callback to generate query */\n onGenerate: () => void\n /** Callback to accept the generated query */\n onAccept: () => void\n /** Callback to cancel and restore previous state */\n onCancel: () => void\n}\n\nexport default function AnalysisAIPanel({\n userPrompt,\n onPromptChange,\n isGenerating,\n error,\n hasGeneratedQuery,\n onGenerate,\n onAccept,\n onCancel\n}: AnalysisAIPanelProps) {\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n onGenerate()\n }\n },\n [onGenerate]\n )\n\n return (\n <div\n className=\"border-b border-dc-border\"\n style={{ background: 'linear-gradient(to right, var(--dc-ai-gradient-start), var(--dc-ai-gradient-end))' }}\n >\n {/* Header */}\n <div className=\"px-4 py-2 flex items-center justify-between border-b border-dc-border bg-dc-surface-secondary\">\n <div className=\"flex items-center gap-2\">\n <SparklesIcon className=\"w-4 h-4 text-dc-accent\" />\n <span className=\"text-sm font-medium text-dc-text\">AI Query Generator</span>\n {isGenerating && (\n <span className=\"text-xs text-dc-accent animate-pulse\">\n Generating...\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n {hasGeneratedQuery && (\n <button\n onClick={onAccept}\n className=\"px-3 py-1 text-xs font-medium text-white bg-dc-success hover:opacity-80 rounded transition-colors\"\n >\n Accept\n </button>\n )}\n <button\n onClick={onCancel}\n className=\"px-3 py-1 text-xs font-medium text-dc-text-secondary hover:text-dc-text bg-dc-surface hover:bg-dc-surface-hover border border-dc-border rounded transition-colors\"\n >\n {hasGeneratedQuery ? 'Cancel' : 'Close'}\n </button>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n <div className=\"flex gap-3\">\n {/* Prompt input */}\n <div className=\"flex-1\">\n <textarea\n value={userPrompt}\n onChange={(e) => onPromptChange(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Describe your query in natural language... (e.g., 'Show total sales by month for the last year')\"\n className=\"w-full px-3 py-2 text-sm border border-dc-border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-dc-accent focus:border-dc-accent resize-none bg-dc-surface text-dc-text placeholder-dc-text-muted\"\n rows={2}\n disabled={isGenerating}\n />\n <div className=\"mt-1 text-xs text-dc-text-muted\">\n Press Enter to generate, Shift+Enter for new line\n </div>\n </div>\n\n {/* Generate button */}\n <div className=\"flex-shrink-0\">\n <button\n onClick={onGenerate}\n disabled={isGenerating || !userPrompt.trim()}\n className={`px-4 py-2 text-sm font-medium rounded-md transition-colors flex items-center gap-2 ${\n isGenerating || !userPrompt.trim()\n ? 'bg-dc-surface-tertiary text-dc-text-disabled cursor-not-allowed'\n : 'bg-dc-accent hover:bg-dc-accent-hover text-white'\n }`}\n >\n {isGenerating ? (\n <>\n <div className=\"w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin\" />\n <span>Generating...</span>\n </>\n ) : (\n <>\n <SparklesIcon className=\"w-4 h-4\" />\n <span>Generate</span>\n </>\n )}\n </button>\n </div>\n </div>\n\n {/* Error message */}\n {error && (\n <div className=\"mt-3 flex items-start gap-2 p-3 bg-dc-error-bg border border-dc-error-border rounded-md\">\n <ErrorIcon className=\"w-4 h-4 text-dc-error mt-0.5 flex-shrink-0\" />\n <div className=\"text-sm text-dc-error\">{error}</div>\n </div>\n )}\n\n {/* Success message */}\n {hasGeneratedQuery && !error && (\n <div className=\"mt-3 p-3 bg-dc-success-bg border border-dc-success-border rounded-md\">\n <div className=\"text-sm text-dc-success\">\n Query generated and loaded! Check the results below, then click{' '}\n <strong>Accept</strong> to keep or <strong>Cancel</strong> to revert.\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n","/**\n * AnalysisBuilder Component\n *\n * A redesigned query builder with a modern UX:\n * - Results panel on the left (large)\n * - Query builder panel on the right\n * - Search-based field selection via modal\n * - Sections: Metrics (measures), Breakdown (dimensions), Filters\n * - Auto-execute queries on field changes\n */\n\nimport { useState, useCallback, useEffect, useRef, useMemo, forwardRef, useImperativeHandle } from 'react'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport { useCubeQuery } from '../../hooks/useCubeQuery'\nimport type {\n AnalysisBuilderProps,\n AnalysisBuilderRef,\n AnalysisBuilderState,\n AIState,\n MetricItem,\n BreakdownItem,\n QueryPanelTab,\n ExecutionStatus,\n AnalysisBuilderStorageState,\n QueryAnalysis\n} from './types'\nimport type { CubeQuery, Filter, ChartType, ChartAxisConfig, ChartDisplayConfig } from '../../types'\nimport FieldSearchModal from './FieldSearchModal'\nimport AnalysisResultsPanel from './AnalysisResultsPanel'\nimport AnalysisQueryPanel from './AnalysisQueryPanel'\nimport type { MetaField, MetaResponse } from '../../shared/types'\nimport { cleanQueryForServer } from '../../shared/utils'\nimport { getAllChartAvailability, getSmartChartDefaults, shouldAutoSwitchChartType } from '../../shared/chartDefaults'\nimport { compressWithFallback, parseShareHash, decodeAndDecompress, clearShareHash } from '../QueryBuilder/shareUtils'\nimport { getColorPalette } from '../../utils/colorPalettes'\nimport { sendGeminiMessage, extractTextFromResponse } from '../AIAssistant/utils'\nimport AnalysisAIPanel from './AnalysisAIPanel'\n\n// Storage key for localStorage persistence\nconst STORAGE_KEY = 'drizzle-cube-analysis-builder-state'\n\n// Debounce delay for auto-execute (ms)\nconst AUTO_EXECUTE_DELAY = 300\n\n/**\n * Generate a unique ID for items\n */\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * Generate letter label for metrics (A, B, C, ..., AA, AB, ...)\n */\nfunction generateMetricLabel(index: number): string {\n let label = ''\n let n = index\n do {\n label = String.fromCharCode(65 + (n % 26)) + label\n n = Math.floor(n / 26) - 1\n } while (n >= 0)\n return label\n}\n\n/**\n * Convert metrics and breakdowns to CubeQuery format\n */\nfunction buildCubeQuery(\n metrics: MetricItem[],\n breakdowns: BreakdownItem[],\n filters: Filter[],\n order?: Record<string, 'asc' | 'desc'>\n): CubeQuery {\n const query: CubeQuery = {\n measures: metrics.map((m) => m.field),\n dimensions: breakdowns.filter((b) => !b.isTimeDimension).map((b) => b.field),\n timeDimensions: breakdowns\n .filter((b) => b.isTimeDimension)\n .map((b) => ({\n dimension: b.field,\n granularity: b.granularity || 'day'\n })),\n filters: filters.length > 0 ? filters : undefined,\n order: order && Object.keys(order).length > 0 ? order : undefined\n }\n\n // Clean up empty arrays\n if (query.measures?.length === 0) delete query.measures\n if (query.dimensions?.length === 0) delete query.dimensions\n if (query.timeDimensions?.length === 0) delete query.timeDimensions\n\n return query\n}\n\n/**\n * Create initial empty state\n */\nfunction createInitialState(): AnalysisBuilderState {\n return {\n metrics: [],\n breakdowns: [],\n filters: [],\n validationStatus: 'idle',\n validationError: null,\n executionStatus: 'idle',\n executionResults: null,\n executionError: null,\n totalRowCount: null,\n resultsStale: false\n }\n}\n\n/**\n * Load all state from localStorage once (to avoid repeated parsing)\n */\nfunction loadInitialStateFromStorage(\n disableLocalStorage: boolean\n): AnalysisBuilderStorageState | null {\n if (disableLocalStorage) return null\n\n try {\n const saved = localStorage.getItem(STORAGE_KEY)\n if (saved) {\n return JSON.parse(saved) as AnalysisBuilderStorageState\n }\n } catch {\n // Ignore parse errors\n }\n return null\n}\n\nconst AnalysisBuilder = forwardRef<AnalysisBuilderRef, AnalysisBuilderProps>(\n (\n {\n className = '',\n maxHeight,\n initialQuery,\n initialChartConfig,\n initialData,\n colorPalette: externalColorPalette,\n disableLocalStorage: disableLocalStorageProp = false,\n hideSettings: _hideSettings = false,\n onQueryChange,\n onChartConfigChange\n },\n ref\n ) => {\n // Mark unused props for future use\n void _hideSettings\n\n // Disable localStorage when initialQuery is provided (parent manages state)\n const disableLocalStorage = disableLocalStorageProp || !!initialQuery\n\n // Get context - metaLoading and metaError used by FieldSearchModal internally\n const { meta, cubeApi } = useCubeContext()\n\n // Load localStorage once on mount (before useState calls) to avoid repeated parsing\n const cachedStorage = useMemo(\n () => loadInitialStateFromStorage(disableLocalStorageProp),\n [] // Only run once on mount\n )\n\n // Load initial state from localStorage or initialQuery\n const [state, setState] = useState<AnalysisBuilderState>(() => {\n // If initialQuery is provided, parse it to metrics/breakdowns\n if (initialQuery) {\n return {\n ...createInitialState(),\n metrics: (initialQuery.measures || []).map((field, index) => ({\n id: generateId(),\n field,\n label: generateMetricLabel(index)\n })),\n breakdowns: [\n ...(initialQuery.dimensions || []).map((field) => ({\n id: generateId(),\n field,\n isTimeDimension: false\n })),\n ...(initialQuery.timeDimensions || []).map((td) => ({\n id: generateId(),\n field: td.dimension,\n granularity: td.granularity,\n isTimeDimension: true\n }))\n ],\n filters: initialQuery.filters || []\n }\n }\n\n // Use cached localStorage data if available\n if (cachedStorage) {\n return {\n ...createInitialState(),\n metrics: cachedStorage.metrics || [],\n breakdowns: cachedStorage.breakdowns || [],\n filters: cachedStorage.filters || []\n }\n }\n\n return createInitialState()\n })\n\n // Chart configuration state - load from initialChartConfig, cached localStorage, or defaults\n const [chartType, setChartType] = useState<ChartType>(() => {\n // Priority: initialChartConfig > cached localStorage > default\n if (initialChartConfig?.chartType) {\n return initialChartConfig.chartType\n }\n if (!initialQuery && cachedStorage?.chartType) {\n return cachedStorage.chartType\n }\n return 'line'\n })\n\n const [chartConfig, setChartConfig] = useState<ChartAxisConfig>(() => {\n // Priority: initialChartConfig > cached localStorage > default\n if (initialChartConfig?.chartConfig) {\n return initialChartConfig.chartConfig\n }\n if (!initialQuery && cachedStorage?.chartConfig) {\n return cachedStorage.chartConfig\n }\n return {}\n })\n\n const [displayConfig, setDisplayConfig] = useState<ChartDisplayConfig>(() => {\n // Priority: initialChartConfig > cached localStorage > default\n if (initialChartConfig?.displayConfig) {\n return initialChartConfig.displayConfig\n }\n if (!initialQuery && cachedStorage?.displayConfig) {\n return cachedStorage.displayConfig\n }\n return { showLegend: true, showGrid: true, showTooltip: true }\n })\n\n // Local color palette state (only used when externalColorPalette is not provided)\n const [localPaletteName, setLocalPaletteName] = useState<string>('default')\n\n // Compute effective color palette\n const effectiveColorPalette = useMemo(() => {\n if (externalColorPalette) return externalColorPalette\n return getColorPalette(localPaletteName)\n }, [externalColorPalette, localPaletteName])\n\n // Sort order state\n const [order, setOrder] = useState<Record<string, 'asc' | 'desc'> | undefined>(() => {\n // Load from initialQuery if provided\n if (initialQuery?.order) {\n return initialQuery.order\n }\n // Use cached localStorage data if available\n if (!initialQuery && cachedStorage?.order) {\n return cachedStorage.order\n }\n return undefined\n })\n\n // UI state\n const [activeTab, setActiveTab] = useState<QueryPanelTab>('query')\n const [activeView, setActiveView] = useState<'table' | 'chart'>(() => {\n if (!initialQuery && cachedStorage?.activeView) {\n return cachedStorage.activeView\n }\n return 'chart'\n })\n const [displayLimit, setDisplayLimit] = useState<number>(100)\n\n // Track whether user manually selected a chart type (vs auto-selection)\n // If initialChartConfig is provided, treat it as a manual selection to prevent auto-switching\n const [userManuallySelectedChart, setUserManuallySelectedChart] = useState(\n () => !!initialChartConfig?.chartType\n )\n\n // Debug data state (from dry-run API)\n const [debugData, setDebugData] = useState<{\n sql: { sql: string; params: any[] } | null\n analysis: QueryAnalysis | null\n loading: boolean\n error: string | null\n }>({ sql: null, analysis: null, loading: false, error: null })\n\n // Field search modal state\n const [showFieldModal, setShowFieldModal] = useState(false)\n const [fieldModalMode, setFieldModalMode] = useState<'metrics' | 'breakdown'>('metrics')\n\n // Share state\n const [shareButtonState, setShareButtonState] = useState<'idle' | 'copied' | 'copied-no-chart'>('idle')\n\n // AI state\n const { features } = useCubeContext()\n const [aiState, setAIState] = useState<AIState>({\n isOpen: false,\n userPrompt: '',\n isGenerating: false,\n error: null,\n hasGeneratedQuery: false,\n previousState: null\n })\n\n // Load shared state from URL on mount\n useEffect(() => {\n // Skip if initialQuery is provided (parent manages state)\n if (initialQuery) return\n\n const encoded = parseShareHash()\n if (!encoded) return\n\n const sharedState = decodeAndDecompress(encoded)\n if (!sharedState || !sharedState.query) return\n\n const query = sharedState.query\n\n // Set metrics and breakdowns from shared query\n setState({\n ...createInitialState(),\n metrics: (query.measures || []).map((field, index) => ({\n id: generateId(),\n field,\n label: generateMetricLabel(index)\n })),\n breakdowns: [\n ...(query.dimensions || []).map((field) => ({\n id: generateId(),\n field,\n isTimeDimension: false\n })),\n ...(query.timeDimensions || []).map((td) => ({\n id: generateId(),\n field: td.dimension,\n granularity: td.granularity,\n isTimeDimension: true\n }))\n ],\n filters: query.filters || []\n })\n\n // Set order if present\n if (query.order) {\n setOrder(query.order)\n }\n\n // Apply chart config if present\n if (sharedState.chartType) {\n setChartType(sharedState.chartType)\n setUserManuallySelectedChart(true)\n }\n if (sharedState.chartConfig) {\n setChartConfig(sharedState.chartConfig)\n }\n if (sharedState.displayConfig) {\n setDisplayConfig(sharedState.displayConfig)\n }\n if (sharedState.activeView) {\n setActiveView(sharedState.activeView)\n }\n\n // Clear the share hash from URL\n clearShareHash()\n }, []) // Run once on mount\n\n // Build current query - memoized to prevent infinite loops\n const currentQuery = useMemo(\n () => buildCubeQuery(state.metrics, state.breakdowns, state.filters, order),\n [state.metrics, state.breakdowns, state.filters, order]\n )\n\n // Serialize query for comparison (prevents object reference issues)\n const currentQueryString = useMemo(() => JSON.stringify(currentQuery), [currentQuery])\n\n // Debounced query for auto-execution\n const [debouncedQuery, setDebouncedQuery] = useState<CubeQuery | null>(null)\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const lastQueryStringRef = useRef<string>('')\n\n // Track if we should skip the first auto-execute (when initialData is provided)\n const hasInitialDataRef = useRef<boolean>(!!initialData && initialData.length > 0)\n const initialQueryStringRef = useRef<string>(initialQuery ? JSON.stringify(initialQuery) : '')\n\n // Track previous metrics/breakdowns for smart chart defaulting (avoid re-runs when chartConfig changes)\n const prevMetricsBreakdownsRef = useRef<string>('')\n const chartConfigRef = useRef<ChartAxisConfig>(chartConfig)\n\n // Determine if query is valid (has at least one measure OR one dimension)\n const isValidQuery =\n (currentQuery.measures && currentQuery.measures.length > 0) ||\n (currentQuery.dimensions && currentQuery.dimensions.length > 0) ||\n (currentQuery.timeDimensions && currentQuery.timeDimensions.length > 0)\n\n // Debounce query changes - use string comparison to avoid infinite loops\n useEffect(() => {\n // Skip if query hasn't actually changed\n if (currentQueryString === lastQueryStringRef.current) {\n return\n }\n\n // Skip initial auto-execution if initialData was provided and query hasn't changed from initial\n // This prevents re-fetching data that was already provided\n if (hasInitialDataRef.current && currentQueryString === initialQueryStringRef.current) {\n // Mark the query as \"seen\" so we don't skip future executions\n lastQueryStringRef.current = currentQueryString\n // Clear the flag so subsequent changes will execute\n hasInitialDataRef.current = false\n return\n }\n\n // Clear existing timer\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current)\n }\n\n // Only debounce if we have a valid query\n if (isValidQuery) {\n debounceTimerRef.current = setTimeout(() => {\n lastQueryStringRef.current = currentQueryString\n setDebouncedQuery(currentQuery)\n }, AUTO_EXECUTE_DELAY)\n } else {\n // Clear debounced query if no valid query\n lastQueryStringRef.current = currentQueryString\n setDebouncedQuery(null)\n }\n\n return () => {\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current)\n }\n }\n }, [currentQueryString, currentQuery, isValidQuery])\n\n // Transform debounced query to server format (converts filter groups)\n const serverQuery = useMemo(() => {\n if (!debouncedQuery) return null\n return cleanQueryForServer(debouncedQuery)\n }, [debouncedQuery])\n\n // Execute query using useCubeQuery hook\n // Reset resultSet when query changes to avoid showing stale data after clearing\n const { resultSet, isLoading, error } = useCubeQuery(serverQuery, {\n skip: !serverQuery,\n resetResultSetOnChange: true\n })\n\n // Derive execution status - show success with initialData even before first query\n const executionStatus: ExecutionStatus = useMemo(() => {\n // If we have initialData and haven't started querying yet, show success\n if (initialData && initialData.length > 0 && !debouncedQuery && !resultSet) {\n return 'success'\n }\n if (!debouncedQuery) return 'idle'\n if (isLoading && !resultSet) return 'loading'\n if (isLoading && resultSet) return 'refreshing'\n if (error) return 'error'\n if (resultSet) return 'success'\n return 'idle'\n }, [debouncedQuery, isLoading, error, resultSet, initialData])\n\n // Get execution results - use initialData if no resultSet yet\n const executionResults = useMemo(() => {\n if (resultSet) {\n try {\n return resultSet.rawData()\n } catch {\n return null\n }\n }\n // Use initialData if provided and no resultSet yet\n if (initialData && initialData.length > 0) {\n return initialData\n }\n return null\n }, [resultSet, initialData])\n\n // Note: We pass executionStatus, executionResults, error directly to PortletResultsPanel\n // instead of storing in state, to avoid render loops\n\n // Compute chart availability based on current metrics and breakdowns\n const chartAvailability = useMemo(\n () => getAllChartAvailability(state.metrics, state.breakdowns),\n [state.metrics, state.breakdowns]\n )\n\n // Helper to check if chart config is completely empty (no axes configured)\n const isChartConfigEmpty = useCallback((config: ChartAxisConfig): boolean => {\n const keys: (keyof ChartAxisConfig)[] = ['xAxis', 'yAxis', 'series', 'sizeField', 'colorField', 'dateField', 'valueField']\n return keys.every(key => {\n const val = config[key]\n if (val === undefined || val === null) return true\n if (Array.isArray(val)) return val.length === 0\n if (typeof val === 'string') return val === ''\n return false\n })\n }, [])\n\n // Keep chartConfigRef in sync with chartConfig state\n chartConfigRef.current = chartConfig\n\n // Smart chart defaulting - auto-configure chart type and axes when debouncedQuery changes\n // This runs AFTER the debounce fires, so chart config changes are synchronized with data updates\n // This prevents the \"double refresh\" visual where chart updates before data arrives\n useEffect(() => {\n // Only run when we have a debounced query (after debounce timer fires)\n if (!debouncedQuery) {\n return\n }\n\n if (state.metrics.length === 0 && state.breakdowns.length === 0) {\n return // Nothing to configure\n }\n\n // Create a key from metrics/breakdowns fields to detect actual changes\n const currentKey = JSON.stringify({\n metrics: state.metrics.map(m => m.field),\n breakdowns: state.breakdowns.map(b => ({ field: b.field, isTime: b.isTimeDimension }))\n })\n\n // Skip if metrics/breakdowns haven't actually changed\n if (currentKey === prevMetricsBreakdownsRef.current) {\n return\n }\n prevMetricsBreakdownsRef.current = currentKey\n\n // Check if we should auto-switch chart type\n const newChartType = shouldAutoSwitchChartType(\n state.metrics,\n state.breakdowns,\n chartType,\n userManuallySelectedChart\n )\n\n if (newChartType) {\n // Chart type is changing - get smart defaults for the new chart type\n const { chartConfig: newChartConfig } = getSmartChartDefaults(\n state.metrics,\n state.breakdowns,\n newChartType\n )\n setChartType(newChartType)\n setChartConfig(newChartConfig)\n // Reset user selection flag since we auto-switched\n setUserManuallySelectedChart(false)\n } else if (state.metrics.length > 0 || state.breakdowns.length > 0) {\n // Only apply smart defaults if the chart config is COMPLETELY empty\n // Once user has configured ANY axis, don't auto-fill (respects user removals)\n // Use ref to get current value without adding to dependencies\n if (isChartConfigEmpty(chartConfigRef.current)) {\n const { chartConfig: smartDefaults } = getSmartChartDefaults(\n state.metrics,\n state.breakdowns,\n chartType\n )\n setChartConfig(smartDefaults)\n }\n }\n }, [debouncedQuery, state.metrics, state.breakdowns, chartType, userManuallySelectedChart, isChartConfigEmpty])\n\n // Save state to localStorage whenever it changes (if not disabled)\n // Deferred to avoid blocking renders\n useEffect(() => {\n if (disableLocalStorage) return\n\n // Defer to next tick to avoid blocking renders\n const timeoutId = setTimeout(() => {\n try {\n const storageState: AnalysisBuilderStorageState = {\n metrics: state.metrics,\n breakdowns: state.breakdowns,\n filters: state.filters,\n order,\n chartType,\n chartConfig,\n displayConfig,\n activeView\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(storageState))\n } catch {\n // Failed to save to localStorage\n }\n }, 0)\n\n return () => clearTimeout(timeoutId)\n }, [\n state.metrics,\n state.breakdowns,\n state.filters,\n order,\n chartType,\n chartConfig,\n displayConfig,\n activeView,\n disableLocalStorage\n ])\n\n // Call onQueryChange callback when query changes\n useEffect(() => {\n if (onQueryChange && isValidQuery) {\n onQueryChange(currentQuery)\n }\n }, [currentQuery, isValidQuery, onQueryChange])\n\n // Call onChartConfigChange callback when chart config changes\n useEffect(() => {\n if (onChartConfigChange) {\n onChartConfigChange({ chartType, chartConfig, displayConfig })\n }\n }, [chartType, chartConfig, displayConfig, onChartConfigChange])\n\n // Fetch dry-run data for debug tab\n useEffect(() => {\n // Clear debug data if no valid query\n if (!isValidQuery || !serverQuery) {\n setDebugData({ sql: null, analysis: null, loading: false, error: null })\n return\n }\n\n let isCancelled = false\n\n const fetchDebugData = async () => {\n setDebugData((prev) => ({ ...prev, loading: true, error: null }))\n try {\n const result = await cubeApi.dryRun(serverQuery)\n if (!isCancelled) {\n setDebugData({\n sql: result.sql,\n analysis: result.analysis,\n loading: false,\n error: null\n })\n }\n } catch (err) {\n if (!isCancelled) {\n setDebugData({\n sql: null,\n analysis: null,\n loading: false,\n error: err instanceof Error ? err.message : 'Failed to fetch debug info'\n })\n }\n }\n }\n\n fetchDebugData()\n\n return () => {\n isCancelled = true\n }\n }, [serverQuery, cubeApi, isValidQuery])\n\n // ========================================================================\n // Metric Handlers\n // ========================================================================\n\n const handleAddMetric = useCallback(() => {\n setFieldModalMode('metrics')\n setShowFieldModal(true)\n }, [])\n\n const handleRemoveMetric = useCallback((id: string) => {\n // Find the field name before removing\n const fieldToRemove = state.metrics.find((m) => m.id === id)?.field\n\n setState((prev) => ({\n ...prev,\n metrics: prev.metrics.filter((m) => m.id !== id),\n resultsStale: true\n }))\n\n // Clean up any sort order for the removed field\n if (fieldToRemove) {\n setOrder((prevOrder) => {\n if (!prevOrder || !prevOrder[fieldToRemove]) return prevOrder\n const newOrder = { ...prevOrder }\n delete newOrder[fieldToRemove]\n return Object.keys(newOrder).length > 0 ? newOrder : undefined\n })\n }\n }, [state.metrics])\n\n const handleFieldSelected = useCallback(\n (field: MetaField, fieldType: 'measure' | 'dimension' | 'timeDimension', _cubeName: string, keepOpen?: boolean) => {\n if (fieldModalMode === 'metrics' && fieldType === 'measure') {\n // Toggle metric - add if not present, remove if already added\n setState((prev) => {\n const existingIndex = prev.metrics.findIndex((m) => m.field === field.name)\n if (existingIndex >= 0) {\n // Remove existing metric\n return {\n ...prev,\n metrics: prev.metrics.filter((_, i) => i !== existingIndex),\n resultsStale: true\n }\n }\n // Add new metric\n const newMetric: MetricItem = {\n id: generateId(),\n field: field.name,\n label: generateMetricLabel(prev.metrics.length)\n }\n return {\n ...prev,\n metrics: [...prev.metrics, newMetric],\n resultsStale: true\n }\n })\n } else if (fieldModalMode === 'breakdown') {\n // Toggle breakdown - add if not present, remove if already added\n const isTimeDimension = fieldType === 'timeDimension'\n setState((prev) => {\n const existingIndex = prev.breakdowns.findIndex((b) => b.field === field.name)\n if (existingIndex >= 0) {\n // Remove existing breakdown\n return {\n ...prev,\n breakdowns: prev.breakdowns.filter((_, i) => i !== existingIndex),\n resultsStale: true\n }\n }\n\n // Check if we already have a time dimension breakdown (only allow one)\n if (isTimeDimension) {\n const hasExistingTimeDimension = prev.breakdowns.some((b) => b.isTimeDimension)\n if (hasExistingTimeDimension) {\n // Don't add - already have a time dimension breakdown\n // Could show a notification here in the future\n return prev\n }\n }\n\n // Add new breakdown\n const newBreakdown: BreakdownItem = {\n id: generateId(),\n field: field.name,\n isTimeDimension,\n granularity: isTimeDimension ? 'month' : undefined\n }\n return {\n ...prev,\n breakdowns: [...prev.breakdowns, newBreakdown],\n resultsStale: true\n }\n })\n }\n // Only close modal if not doing shift-click multi-select\n if (!keepOpen) {\n setShowFieldModal(false)\n }\n },\n [fieldModalMode]\n )\n\n // ========================================================================\n // Breakdown Handlers\n // ========================================================================\n\n const handleAddBreakdown = useCallback(() => {\n setFieldModalMode('breakdown')\n setShowFieldModal(true)\n }, [])\n\n const handleRemoveBreakdown = useCallback((id: string) => {\n // Find the field name before removing\n const fieldToRemove = state.breakdowns.find((b) => b.id === id)?.field\n\n setState((prev) => ({\n ...prev,\n breakdowns: prev.breakdowns.filter((b) => b.id !== id),\n resultsStale: true\n }))\n\n // Clean up any sort order for the removed field\n if (fieldToRemove) {\n setOrder((prevOrder) => {\n if (!prevOrder || !prevOrder[fieldToRemove]) return prevOrder\n const newOrder = { ...prevOrder }\n delete newOrder[fieldToRemove]\n return Object.keys(newOrder).length > 0 ? newOrder : undefined\n })\n }\n }, [state.breakdowns])\n\n const handleBreakdownGranularityChange = useCallback(\n (id: string, granularity: string) => {\n setState((prev) => ({\n ...prev,\n breakdowns: prev.breakdowns.map((b) =>\n b.id === id ? { ...b, granularity } : b\n ),\n resultsStale: true\n }))\n },\n []\n )\n\n // ========================================================================\n // Reorder Handlers\n // ========================================================================\n\n const handleReorderMetrics = useCallback(\n (fromIndex: number, toIndex: number) => {\n setState((prev) => {\n const newMetrics = [...prev.metrics]\n const [movedItem] = newMetrics.splice(fromIndex, 1)\n newMetrics.splice(toIndex, 0, movedItem)\n return {\n ...prev,\n metrics: newMetrics,\n resultsStale: true\n }\n })\n },\n []\n )\n\n const handleReorderBreakdowns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setState((prev) => {\n const newBreakdowns = [...prev.breakdowns]\n const [movedItem] = newBreakdowns.splice(fromIndex, 1)\n newBreakdowns.splice(toIndex, 0, movedItem)\n return {\n ...prev,\n breakdowns: newBreakdowns,\n resultsStale: true\n }\n })\n },\n []\n )\n\n // ========================================================================\n // Filter Handlers\n // ========================================================================\n\n // Filter change handler - connected to PortletQueryPanel\n const handleFiltersChange = useCallback((filters: Filter[]) => {\n setState((prev) => ({\n ...prev,\n filters,\n resultsStale: true\n }))\n }, [])\n\n // Handle dropping a field from metrics/breakdowns onto the filter section\n const handleDropFieldToFilter = useCallback((field: string) => {\n // Create a new filter with 'set' operator (checks if field exists/is not null)\n const newFilter: Filter = {\n member: field,\n operator: 'set',\n values: []\n }\n\n setState((prev) => {\n // Add to existing filters or create new array\n const existingFilters = prev.filters || []\n\n // Check if we already have a filter for this field\n const hasFilterForField = existingFilters.some((f) =>\n 'member' in f && f.member === field\n )\n\n if (hasFilterForField) {\n // Don't add duplicate filter\n return prev\n }\n\n // If we have existing filters, wrap in an AND group or add to existing group\n let updatedFilters: Filter[]\n if (existingFilters.length === 0) {\n updatedFilters = [newFilter]\n } else if (existingFilters.length === 1 && 'type' in existingFilters[0]) {\n // Already a group, add to it\n const group = existingFilters[0] as { type: 'and' | 'or'; filters: Filter[] }\n updatedFilters = [{\n ...group,\n filters: [...group.filters, newFilter]\n }]\n } else {\n // Wrap all in AND group\n updatedFilters = [{\n type: 'and' as const,\n filters: [...existingFilters, newFilter]\n }]\n }\n\n return {\n ...prev,\n filters: updatedFilters,\n resultsStale: true\n }\n })\n }, [])\n\n // ========================================================================\n // Order Handlers\n // ========================================================================\n\n const handleOrderChange = useCallback(\n (fieldName: string, direction: 'asc' | 'desc' | null) => {\n setOrder((prev) => {\n const newOrder = { ...(prev || {}) }\n\n if (direction === null) {\n // Remove sort for this field\n delete newOrder[fieldName]\n } else {\n // Set or update sort direction\n newOrder[fieldName] = direction\n }\n\n // Return undefined if empty, otherwise return the new order\n return Object.keys(newOrder).length > 0 ? newOrder : undefined\n })\n },\n []\n )\n\n // ========================================================================\n // Clear Query\n // ========================================================================\n\n const handleClearQuery = useCallback(() => {\n setState(createInitialState())\n setOrder(undefined)\n setUserManuallySelectedChart(false)\n // Also reset chart type, config, and display config\n setChartType('line')\n setChartConfig({})\n setDisplayConfig({ showLegend: true, showGrid: true, showTooltip: true })\n // Clear the debounced query immediately to stop showing old results\n setDebouncedQuery(null)\n // Also clear any pending debounce timer\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current)\n debounceTimerRef.current = null\n }\n }, [])\n\n // ========================================================================\n // AI Query Generation\n // ========================================================================\n\n const handleOpenAI = useCallback(() => {\n // Snapshot current state for undo\n setAIState({\n isOpen: true,\n userPrompt: '',\n isGenerating: false,\n error: null,\n hasGeneratedQuery: false,\n previousState: {\n metrics: [...state.metrics],\n breakdowns: [...state.breakdowns],\n filters: [...state.filters],\n chartType,\n chartConfig: { ...chartConfig },\n displayConfig: { ...displayConfig }\n }\n })\n }, [state.metrics, state.breakdowns, state.filters, chartType, chartConfig, displayConfig])\n\n const handleCloseAI = useCallback(() => {\n setAIState(prev => ({\n ...prev,\n isOpen: false,\n userPrompt: '',\n error: null,\n hasGeneratedQuery: false\n }))\n }, [])\n\n const handleAIPromptChange = useCallback((prompt: string) => {\n setAIState(prev => ({ ...prev, userPrompt: prompt }))\n }, [])\n\n const handleGenerateAI = useCallback(async () => {\n if (!aiState.userPrompt.trim()) return\n\n setAIState(prev => ({ ...prev, isGenerating: true, error: null }))\n\n try {\n const response = await sendGeminiMessage(\n '', // API key not needed for server-side AI\n aiState.userPrompt,\n features?.aiEndpoint || '/api/ai'\n )\n\n const responseText = extractTextFromResponse(response)\n const parsed = JSON.parse(responseText) as {\n query?: CubeQuery\n chartType?: ChartType\n chartConfig?: ChartAxisConfig\n } | CubeQuery\n\n // Support both new format (with query/chartType/chartConfig) and legacy format (just query)\n const query = ('query' in parsed && parsed.query) ? parsed.query : parsed as CubeQuery\n const aiChartType = ('chartType' in parsed) ? parsed.chartType : undefined\n const aiChartConfig = ('chartConfig' in parsed) ? parsed.chartConfig : undefined\n\n // Load query into builder state (same pattern as initialQuery)\n setState(prev => ({\n ...prev,\n metrics: (query.measures || []).map((field, index) => ({\n id: generateId(),\n field,\n label: generateMetricLabel(index)\n })),\n breakdowns: [\n ...(query.dimensions || []).map((field) => ({\n id: generateId(),\n field,\n isTimeDimension: false\n })),\n ...(query.timeDimensions || []).map((td) => ({\n id: generateId(),\n field: td.dimension,\n granularity: td.granularity,\n isTimeDimension: true\n }))\n ],\n filters: query.filters || []\n }))\n\n // Apply chart type if provided by AI\n if (aiChartType) {\n setChartType(aiChartType)\n setUserManuallySelectedChart(true) // Prevent auto-switching\n }\n\n // Apply chart config if provided by AI\n if (aiChartConfig) {\n setChartConfig(aiChartConfig)\n }\n\n // Switch to chart view so user can see the visualization\n setActiveView('chart')\n\n setAIState(prev => ({\n ...prev,\n isGenerating: false,\n hasGeneratedQuery: true\n }))\n } catch (error) {\n setAIState(prev => ({\n ...prev,\n isGenerating: false,\n error: error instanceof Error ? error.message : 'Failed to generate query'\n }))\n }\n }, [aiState.userPrompt, features?.aiEndpoint])\n\n const handleAcceptAI = useCallback(() => {\n // Close panel and clear previous state (keep the changes)\n setAIState({\n isOpen: false,\n userPrompt: '',\n isGenerating: false,\n error: null,\n hasGeneratedQuery: false,\n previousState: null\n })\n }, [])\n\n const handleCancelAI = useCallback(() => {\n // Restore previous state\n if (aiState.previousState) {\n setState(prev => ({\n ...prev,\n metrics: aiState.previousState!.metrics,\n breakdowns: aiState.previousState!.breakdowns,\n filters: aiState.previousState!.filters\n }))\n setChartType(aiState.previousState.chartType)\n setChartConfig(aiState.previousState.chartConfig)\n setDisplayConfig(aiState.previousState.displayConfig)\n }\n\n // Close panel\n setAIState({\n isOpen: false,\n userPrompt: '',\n isGenerating: false,\n error: null,\n hasGeneratedQuery: false,\n previousState: null\n })\n }, [aiState.previousState])\n\n // Handle chart type change - track that user manually selected this\n const handleChartTypeChange = useCallback((type: ChartType) => {\n setChartType(type)\n setUserManuallySelectedChart(true)\n\n // Update chart config for the new chart type\n const { chartConfig: newChartConfig } = getSmartChartDefaults(\n state.metrics,\n state.breakdowns,\n type\n )\n setChartConfig(newChartConfig)\n // Switch to chart view so user can see the changes\n setActiveView('chart')\n }, [state.metrics, state.breakdowns])\n\n // Handle chart config change - also switch to chart view\n const handleChartConfigChange = useCallback((config: ChartAxisConfig) => {\n setChartConfig(config)\n // Switch to chart view so user can see the changes\n setActiveView('chart')\n }, [])\n\n // Handle display config change - also switch to chart view\n const handleDisplayConfigChange = useCallback((config: ChartDisplayConfig) => {\n setDisplayConfig(config)\n // Switch to chart view so user can see the changes\n setActiveView('chart')\n }, [])\n\n // ========================================================================\n // Share Handler\n // ========================================================================\n\n const handleShare = useCallback(async () => {\n if (!isValidQuery || !serverQuery) return\n\n const shareableState = {\n query: serverQuery,\n chartType,\n chartConfig,\n displayConfig,\n activeView\n }\n\n // Try full state first, fall back to query-only if too large\n const { encoded, queryOnly } = compressWithFallback(shareableState)\n\n // If even query-only is too large, don't share\n if (!encoded) {\n return\n }\n\n const url = `${window.location.origin}${window.location.pathname}#share=${encoded}`\n\n try {\n await navigator.clipboard.writeText(url)\n } catch {\n // Fallback for older browsers\n const textArea = document.createElement('textarea')\n textArea.value = url\n document.body.appendChild(textArea)\n textArea.select()\n document.execCommand('copy')\n document.body.removeChild(textArea)\n }\n\n // Update button state\n setShareButtonState(queryOnly ? 'copied-no-chart' : 'copied')\n\n // Reset button state after 2 seconds\n setTimeout(() => {\n setShareButtonState('idle')\n }, 2000)\n }, [isValidQuery, serverQuery, chartType, chartConfig, displayConfig, activeView])\n\n // ========================================================================\n // Expose API via ref\n // ========================================================================\n\n useImperativeHandle(\n ref,\n () => ({\n getCurrentQuery: () => currentQuery,\n getChartConfig: () => ({ chartType, chartConfig, displayConfig }),\n executeQuery: () => {\n // TODO: Implement manual execute\n },\n clearQuery: handleClearQuery\n }),\n [currentQuery, chartType, chartConfig, displayConfig, handleClearQuery]\n )\n\n // ========================================================================\n // Render\n // ========================================================================\n\n return (\n <div\n className={`flex flex-col lg:flex-row bg-dc-surface border-x border-b border-dc-border ${maxHeight ? 'lg:h-[var(--dc-max-h)] lg:max-h-[var(--dc-max-h)] lg:overflow-hidden' : 'lg:h-full'} ${className}`}\n style={maxHeight ? { ['--dc-max-h' as string]: maxHeight } : undefined}\n >\n {/* Top/Left Panel - Results */}\n <div className=\"h-[60vh] lg:h-auto lg:flex-1 min-w-0 border-b lg:border-b-0 lg:border-r border-dc-border overflow-auto flex flex-col\">\n {/* AI Panel - expands above results when open */}\n {aiState.isOpen && (\n <AnalysisAIPanel\n userPrompt={aiState.userPrompt}\n onPromptChange={handleAIPromptChange}\n isGenerating={aiState.isGenerating}\n error={aiState.error}\n hasGeneratedQuery={aiState.hasGeneratedQuery}\n onGenerate={handleGenerateAI}\n onAccept={handleAcceptAI}\n onCancel={handleCancelAI}\n />\n )}\n\n {/* Results Panel */}\n <div className=\"flex-1 overflow-auto\">\n <AnalysisResultsPanel\n executionStatus={executionStatus}\n executionResults={executionResults}\n executionError={error?.message || null}\n totalRowCount={null}\n resultsStale={isLoading && executionResults !== null}\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n colorPalette={effectiveColorPalette}\n // Only show palette selector in standalone mode (not when editing portlet)\n currentPaletteName={!externalColorPalette ? localPaletteName : undefined}\n onColorPaletteChange={!externalColorPalette ? setLocalPaletteName : undefined}\n query={currentQuery}\n schema={meta as MetaResponse | null}\n activeView={activeView}\n onActiveViewChange={setActiveView}\n displayLimit={displayLimit}\n onDisplayLimitChange={setDisplayLimit}\n hasMetrics={state.metrics.length > 0}\n // Debug props (serverQuery is the cleaned/transformed version sent to server)\n debugQuery={serverQuery}\n debugSql={debugData.sql}\n debugAnalysis={debugData.analysis}\n debugLoading={debugData.loading}\n debugError={debugData.error}\n // Share props\n onShareClick={handleShare}\n canShare={isValidQuery}\n shareButtonState={shareButtonState}\n // Clear props\n onClearClick={handleClearQuery}\n canClear={state.metrics.length > 0 || state.breakdowns.length > 0 || state.filters.length > 0}\n // AI props\n enableAI={features?.enableAI !== false}\n isAIOpen={aiState.isOpen}\n onAIToggle={aiState.isOpen ? handleCloseAI : handleOpenAI}\n />\n </div>\n </div>\n\n {/* Bottom/Right Panel - Query Builder */}\n <div className=\"w-full lg:w-96 flex-shrink-0 lg:h-full overflow-auto lg:overflow-hidden\">\n <AnalysisQueryPanel\n metrics={state.metrics}\n breakdowns={state.breakdowns}\n filters={state.filters}\n schema={meta as MetaResponse | null}\n activeTab={activeTab}\n onActiveTabChange={setActiveTab}\n onAddMetric={handleAddMetric}\n onRemoveMetric={handleRemoveMetric}\n onReorderMetrics={handleReorderMetrics}\n onAddBreakdown={handleAddBreakdown}\n onRemoveBreakdown={handleRemoveBreakdown}\n onBreakdownGranularityChange={handleBreakdownGranularityChange}\n onReorderBreakdowns={handleReorderBreakdowns}\n onFiltersChange={handleFiltersChange}\n onDropFieldToFilter={handleDropFieldToFilter}\n order={order}\n onOrderChange={handleOrderChange}\n chartType={chartType}\n chartConfig={chartConfig}\n displayConfig={displayConfig}\n colorPalette={effectiveColorPalette}\n chartAvailability={chartAvailability}\n onChartTypeChange={handleChartTypeChange}\n onChartConfigChange={handleChartConfigChange}\n onDisplayConfigChange={handleDisplayConfigChange}\n validationStatus={state.validationStatus}\n validationError={state.validationError}\n />\n </div>\n\n {/* Field Search Modal */}\n <FieldSearchModal\n isOpen={showFieldModal}\n onClose={() => setShowFieldModal(false)}\n onSelect={handleFieldSelected}\n mode={fieldModalMode}\n schema={meta as MetaResponse | null}\n selectedFields={[\n ...state.metrics.map((m) => m.field),\n ...state.breakdowns.map((b) => b.field)\n ]}\n />\n </div>\n )\n }\n)\n\nAnalysisBuilder.displayName = 'AnalysisBuilder'\n\nexport default AnalysisBuilder\n","import React, { useState, useEffect, useRef, useCallback } from 'react'\nimport Modal from './Modal'\nimport AnalysisBuilder from './AnalysisBuilder'\nimport type { AnalysisBuilderRef } from './AnalysisBuilder/types'\nimport type { PortletConfig, ColorPalette, CubeQuery } from '../types'\n\ninterface PortletAnalysisModalProps {\n isOpen: boolean\n onClose: () => void\n onSave: (portlet: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => void\n portlet?: PortletConfig | null\n /** Initial data to display (avoids re-fetching when editing) */\n initialData?: any[]\n title: string\n submitText: string\n colorPalette?: ColorPalette\n}\n\n/**\n * PortletAnalysisModal - A modal wrapper around AnalysisBuilder for portlet editing\n *\n * This replaces PortletEditModal with the modern AnalysisBuilder interface.\n * Features:\n * - Two-panel layout with results and query builder\n * - Auto-execution of queries\n * - Smart chart defaults\n * - Title input in header\n * - Initial data support (no re-fetch when editing)\n */\nexport default function PortletAnalysisModal({\n isOpen,\n onClose,\n onSave,\n portlet,\n initialData,\n title: modalTitle,\n submitText,\n colorPalette\n}: PortletAnalysisModalProps) {\n\n // Ref to AnalysisBuilder for getting current query and chart config\n const builderRef = useRef<AnalysisBuilderRef>(null)\n\n // Title state\n const [formTitle, setFormTitle] = useState('')\n\n // Parse initial query from portlet\n const initialQuery = React.useMemo<CubeQuery | undefined>(() => {\n if (!portlet?.query) return undefined\n try {\n return JSON.parse(portlet.query)\n } catch {\n return undefined\n }\n }, [portlet?.query])\n\n // Initial chart config from portlet\n const initialChartConfig = React.useMemo(() => {\n if (!portlet) return undefined\n return {\n chartType: portlet.chartType,\n chartConfig: portlet.chartConfig,\n displayConfig: portlet.displayConfig\n }\n }, [portlet])\n\n // Reset form state when modal opens/closes or portlet changes\n useEffect(() => {\n if (isOpen) {\n setFormTitle(portlet?.title || '')\n }\n }, [isOpen, portlet])\n\n // Handle save\n const handleSave = useCallback(() => {\n if (!formTitle.trim()) {\n alert('Please enter a title for the portlet.')\n return\n }\n\n // Get current query and chart config from AnalysisBuilder\n const currentQuery = builderRef.current?.getCurrentQuery()\n const chartConfig = builderRef.current?.getChartConfig()\n\n if (!currentQuery) {\n alert('Please configure a query before saving.')\n return\n }\n\n // Check if query has at least one measure or dimension\n const hasContent =\n (currentQuery.measures && currentQuery.measures.length > 0) ||\n (currentQuery.dimensions && currentQuery.dimensions.length > 0) ||\n (currentQuery.timeDimensions && currentQuery.timeDimensions.length > 0)\n\n if (!hasContent) {\n alert('Please add at least one metric or breakdown to your query.')\n return\n }\n\n // Build portlet config\n const portletData: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'> = {\n ...(portlet || {}),\n title: formTitle.trim(),\n query: JSON.stringify(currentQuery),\n chartType: chartConfig?.chartType || 'line',\n chartConfig: chartConfig?.chartConfig || {},\n displayConfig: chartConfig?.displayConfig || {},\n // Preserve existing position or use defaults for new portlets\n w: portlet?.w || 5,\n h: portlet?.h || 4\n } as PortletConfig\n\n onSave(portletData)\n onClose()\n }, [formTitle, portlet, onSave, onClose])\n\n // Handle cancel\n const handleCancel = useCallback(() => {\n onClose()\n }, [onClose])\n\n // Footer with save/cancel buttons\n const footer = (\n <>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary hover:text-dc-text bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\n className=\"px-4 py-2 text-sm font-medium text-white bg-dc-accent hover:bg-dc-accent-hover rounded-md transition-colors\"\n >\n {submitText}\n </button>\n </>\n )\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={modalTitle}\n size=\"fullscreen-mobile\"\n showCloseButton={true}\n closeOnBackdropClick={false}\n closeOnEscape={true}\n noPadding={true}\n footer={footer}\n >\n {/* Custom content with title input */}\n <div className=\"flex flex-col h-full\">\n {/* Title input section */}\n <div className=\"shrink-0 px-4 py-3 border-b border-dc-border bg-dc-surface-secondary\">\n <div className=\"flex items-center gap-3\">\n <label htmlFor=\"portlet-title\" className=\"text-sm font-medium text-dc-text-secondary shrink-0\">\n Title\n </label>\n <input\n id=\"portlet-title\"\n type=\"text\"\n value={formTitle}\n onChange={(e) => setFormTitle(e.target.value)}\n placeholder=\"Enter portlet title...\"\n autoComplete=\"off\"\n className=\"flex-1 px-3 py-1.5 text-sm bg-dc-surface border border-dc-border rounded-md text-dc-text placeholder-dc-text-muted focus:outline-none focus:ring-2 focus:ring-dc-accent focus:border-transparent\"\n autoFocus\n />\n </div>\n </div>\n\n {/* AnalysisBuilder content */}\n <div className=\"flex-1 min-h-0\">\n <AnalysisBuilder\n ref={builderRef}\n maxHeight=\"100%\"\n initialQuery={initialQuery}\n initialChartConfig={initialChartConfig}\n initialData={initialData}\n colorPalette={colorPalette}\n disableLocalStorage={true}\n className=\"h-full\"\n />\n </div>\n </div>\n </Modal>\n )\n}\n","/**\n * Portlet Filter Configuration Modal\n * Allows users to configure which dashboard filters apply to a specific portlet\n */\n\nimport { useState, useEffect } from 'react'\nimport type { DashboardFilter } from '../types'\n\ninterface PortletFilterConfigModalProps {\n isOpen: boolean\n onClose: () => void\n dashboardFilters: DashboardFilter[]\n currentMapping: string[]\n onSave: (mapping: string[]) => void\n portletTitle: string\n}\n\nexport default function PortletFilterConfigModal({\n isOpen,\n onClose,\n dashboardFilters = [],\n currentMapping = [],\n onSave,\n portletTitle\n}: PortletFilterConfigModalProps) {\n const [selectedFilters, setSelectedFilters] = useState<string[]>(currentMapping)\n\n // Update local state when props change\n useEffect(() => {\n setSelectedFilters(currentMapping)\n }, [currentMapping, isOpen])\n\n const handleToggleFilter = (filterId: string) => {\n setSelectedFilters(prev => {\n if (prev.includes(filterId)) {\n return prev.filter(id => id !== filterId)\n } else {\n return [...prev, filterId]\n }\n })\n }\n\n const handleSave = () => {\n onSave(selectedFilters)\n onClose()\n }\n\n const handleCancel = () => {\n setSelectedFilters(currentMapping) // Reset to original\n onClose()\n }\n\n // Format filter preview text\n const formatFilterPreview = (filter: DashboardFilter): string => {\n if (!filter.filter) return ''\n\n // Handle simple filters\n if ('member' in filter.filter && filter.filter.member) {\n const values = filter.filter.values || []\n const valuesText = values.length > 0 ? values.join(', ') : 'no value'\n return `${filter.filter.member} ${filter.filter.operator} ${valuesText}`\n }\n\n // Handle group filters (AND/OR)\n if ('type' in filter.filter && filter.filter.type) {\n const filterCount = filter.filter.filters?.length || 0\n return `${filter.filter.type.toUpperCase()} group with ${filterCount} filter${filterCount !== 1 ? 's' : ''}`\n }\n\n return 'Complex filter'\n }\n\n if (!isOpen) return null\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50\" onClick={handleCancel}>\n <div\n className=\"bg-dc-surface border border-dc-border rounded-lg max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col\"\n style={{ boxShadow: 'var(--dc-shadow-lg)' }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"px-6 py-4 border-b border-dc-border bg-dc-surface-secondary rounded-t-lg\">\n <h2 className=\"text-lg font-semibold text-dc-text\">Configure Dashboard Filters</h2>\n <p className=\"text-sm text-dc-text-secondary mt-1\">\n Choose which dashboard filters apply to \"{portletTitle}\"\n </p>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">\n {dashboardFilters.length === 0 ? (\n <div className=\"text-center py-8 text-dc-text-muted\">\n <svg\n className=\"mx-auto h-12 w-12 mb-3\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\"\n />\n </svg>\n <p className=\"text-sm font-medium\">No dashboard filters available</p>\n <p className=\"text-xs mt-1\">Add filters at the dashboard level first</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between mb-4 pb-2 border-b border-dc-border\">\n <span className=\"text-sm font-medium text-dc-text\">Available Filters</span>\n <span className=\"text-xs text-dc-text-secondary\">\n {selectedFilters.length} of {dashboardFilters.length} selected\n </span>\n </div>\n\n {dashboardFilters.map(filter => {\n const isSelected = selectedFilters.includes(filter.id)\n\n return (\n <label\n key={filter.id}\n className={`flex items-start p-3 rounded-md border cursor-pointer transition-colors ${\n isSelected\n ? 'border-dc-primary bg-dc-surface-secondary'\n : 'border-dc-border hover:bg-dc-surface-hover'\n }`}\n >\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={() => handleToggleFilter(filter.id)}\n className=\"mt-0.5 mr-3 h-4 w-4 rounded border-dc-border focus:ring-2 focus:ring-dc-primary\"\n style={{\n accentColor: 'var(--dc-primary)'\n }}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm text-dc-text truncate\">\n {filter.label}\n </span>\n {isSelected && (\n <span\n className=\"px-2 py-0.5 text-xs rounded-full\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n Applied\n </span>\n )}\n </div>\n <div className=\"mt-1 text-xs text-dc-text-secondary break-words\">\n {formatFilterPreview(filter)}\n </div>\n </div>\n </label>\n )\n })}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"px-6 py-4 border-t border-dc-border bg-dc-surface-secondary rounded-b-lg flex justify-end gap-3\">\n <button\n onClick={handleCancel}\n className=\"px-4 py-2 text-sm font-medium rounded-md border border-dc-border bg-dc-surface hover:bg-dc-surface-hover transition-colors text-dc-text\"\n >\n Cancel\n </button>\n <button\n onClick={handleSave}\n className=\"px-4 py-2 text-sm font-medium rounded-md text-white transition-colors\"\n style={{\n backgroundColor: 'var(--dc-primary)'\n }}\n >\n Apply Filters\n </button>\n </div>\n </div>\n </div>\n )\n}\n","/**\n * FilterEditModal Component\n *\n * Modal for editing dashboard filter details including label, field, operator, and values\n *\n * Pattern: Self-contained modal with local state (matches PortletEditModal pattern)\n * - All editing state is local to the modal\n * - Changes only propagate on \"Done\" button click via onSave callback\n * - Cancel/close resets local state without saving\n */\n\nimport React, { useState, useCallback, useMemo, useEffect } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterBuilder from '../QueryBuilder/FilterBuilder'\n\nconst CloseIcon = getIcon('close')\nconst EyeIcon = getIcon('eye')\nconst EyeOffIcon = getIcon('eyeOff')\nimport DateRangeSelector from '../QueryBuilder/DateRangeSelector'\nimport CubeMetaExplorer from '../QueryBuilder/CubeMetaExplorer'\nimport { extractDashboardFields } from '../../utils/filterUtils'\nimport type { DashboardFilter, CubeMeta, Filter, DashboardConfig, SimpleFilter } from '../../types'\nimport type { MetaResponse } from '../QueryBuilder/types'\n\ninterface FilterEditModalProps {\n filter: DashboardFilter\n schema: CubeMeta | null\n dashboardConfig: DashboardConfig\n isOpen: boolean\n onSave: (filter: DashboardFilter) => void | Promise<void>\n onClose: () => void\n onDelete: () => void\n convertToMetaResponse: (cubeMeta: CubeMeta | null) => MetaResponse | null\n}\n\nconst FilterEditModal: React.FC<FilterEditModalProps> = ({\n filter,\n schema,\n dashboardConfig,\n isOpen,\n onSave,\n onClose,\n onDelete,\n convertToMetaResponse\n}) => {\n // Local state for editing - all changes stay local until \"Done\"\n const [localLabel, setLocalLabel] = useState(filter.label)\n const [localFilter, setLocalFilter] = useState(filter.filter)\n const [showAllFields, setShowAllFields] = useState(false)\n\n // Sync local state when filter prop changes or modal opens\n useEffect(() => {\n if (isOpen) {\n setLocalLabel(filter.label)\n setLocalFilter(filter.filter)\n }\n }, [filter, isOpen])\n\n // Extract fields used in dashboard\n const dashboardFields = useMemo(() => {\n return extractDashboardFields(dashboardConfig)\n }, [dashboardConfig])\n\n // Create filtered schema showing only dashboard fields\n const filteredSchema = useMemo<MetaResponse | null>(() => {\n if (!schema) return null\n\n if (showAllFields) {\n return convertToMetaResponse(schema)\n }\n\n const filteredCubes = schema.cubes\n .map(cube => {\n const cubeName = cube.name\n\n const filteredMeasures = cube.measures.filter(measure => {\n const fullName = measure.name.includes('.')\n ? measure.name\n : `${cubeName}.${measure.name}`\n return dashboardFields.measures.has(fullName)\n })\n\n const filteredDimensions = cube.dimensions.filter(dimension => {\n const fullName = dimension.name.includes('.')\n ? dimension.name\n : `${cubeName}.${dimension.name}`\n return dashboardFields.dimensions.has(fullName) ||\n dashboardFields.timeDimensions.has(fullName)\n })\n\n if (filteredMeasures.length > 0 || filteredDimensions.length > 0) {\n return {\n ...cube,\n measures: filteredMeasures,\n dimensions: filteredDimensions\n }\n }\n\n return null\n })\n .filter((cube): cube is NonNullable<typeof cube> => cube !== null)\n\n const filteredCubeMeta: CubeMeta = {\n ...schema,\n cubes: filteredCubes\n }\n\n return convertToMetaResponse(filteredCubeMeta)\n }, [schema, dashboardFields, showAllFields, convertToMetaResponse])\n\n // Extract the currently selected field to highlight it in the schema\n const selectedFieldInFilter = useMemo(() => {\n if ('member' in localFilter && localFilter.member) {\n return localFilter.member\n }\n return null\n }, [localFilter])\n\n // Handle label change - updates local state only\n const handleLabelChange = useCallback((newLabel: string) => {\n setLocalLabel(newLabel)\n }, [])\n\n // Handle filter changes from FilterBuilder - updates local state only\n const handleFilterBuilderChange = useCallback((filters: Filter[]) => {\n setLocalFilter(filters[0] || localFilter)\n }, [localFilter])\n\n // Handle field selection from schema explorer - updates local state only\n const handleFieldSelect = useCallback((fieldName: string) => {\n if ('member' in localFilter) {\n setLocalFilter({\n ...localFilter,\n member: fieldName,\n values: [] // Reset values when changing field\n })\n }\n }, [localFilter])\n\n // Handle date range change for universal time filters\n const handleDateRangeChange = useCallback((_timeDim: string, dateRange: string | string[]) => {\n if ('member' in localFilter) {\n setLocalFilter({\n ...localFilter,\n values: Array.isArray(dateRange) ? dateRange : [dateRange]\n } as SimpleFilter)\n }\n }, [localFilter])\n\n // Validate filter before saving\n const validateFilter = useCallback((): { isValid: boolean; message?: string } => {\n if (!localLabel.trim()) {\n return { isValid: false, message: 'Filter label is required' }\n }\n\n // Skip member validation for universal time filters (member is placeholder)\n if (!filter.isUniversalTime && 'member' in localFilter && !localFilter.member) {\n return { isValid: false, message: 'Please select a field for the filter' }\n }\n\n return { isValid: true }\n }, [localLabel, localFilter, filter.isUniversalTime])\n\n // Handle save - validate then call onSave with complete filter data\n const handleSave = useCallback(async () => {\n const validation = validateFilter()\n if (!validation.isValid) {\n alert(validation.message)\n return\n }\n\n const updatedFilter: DashboardFilter = {\n id: filter.id,\n label: localLabel,\n filter: localFilter,\n // Preserve isUniversalTime flag if present\n ...(filter.isUniversalTime && { isUniversalTime: true })\n }\n\n try {\n await onSave(updatedFilter)\n onClose()\n } catch (error) {\n console.error('Failed to save filter:', error)\n alert('Failed to save filter. Please try again.')\n }\n }, [filter.id, filter.isUniversalTime, localLabel, localFilter, validateFilter, onSave, onClose])\n\n // Handle cancel/close - reset local state\n const handleCancel = useCallback(() => {\n setLocalLabel(filter.label)\n setLocalFilter(filter.filter)\n onClose()\n }, [filter, onClose])\n\n return (\n <div\n className=\"fixed inset-0 z-50 backdrop-blur-md flex items-center justify-center p-2\"\n style={{ backgroundColor: 'var(--dc-overlay)' }}\n >\n <div\n className=\"rounded-lg max-w-7xl w-full h-[95vh] overflow-hidden flex flex-col bg-dc-surface border border-dc-border\"\n style={{ boxShadow: 'var(--dc-shadow-2xl)' }}\n >\n {/* Modal Header */}\n <div className=\"px-6 py-4 border-b border-dc-border flex items-center justify-between\">\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium mb-2 text-dc-text\">\n Filter Label\n </label>\n <input\n type=\"text\"\n value={localLabel}\n onChange={(e) => handleLabelChange(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md text-sm bg-dc-surface-secondary text-dc-text\"\n placeholder=\"Enter filter label\"\n />\n </div>\n <button\n onClick={handleCancel}\n className=\"ml-4 p-2 hover:bg-dc-surface-hover rounded-md transition-colors text-dc-text-secondary\"\n >\n <CloseIcon className=\"w-5 h-5\" />\n </button>\n </div>\n\n {/* Modal Body - Two Column Layout (or single column for universal time filters) */}\n <div className=\"flex-1 overflow-hidden flex\">\n {/* Left Column - Schema Explorer (hidden for universal time filters) */}\n {!filter.isUniversalTime && (\n <div className=\"w-80 border-r border-dc-border bg-dc-surface overflow-auto\">\n <div className=\"p-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-semibold text-dc-text\">\n Available Fields\n </h3>\n <button\n onClick={() => setShowAllFields(!showAllFields)}\n className=\"flex items-center gap-1 text-xs px-2 py-1 rounded hover:bg-dc-surface-hover text-dc-text-muted\"\n title={showAllFields ? 'Show dashboard fields only' : 'Show all fields'}\n >\n {showAllFields ? (\n <>\n <EyeOffIcon className=\"w-3.5 h-3.5\" />\n <span>Dashboard</span>\n </>\n ) : (\n <>\n <EyeIcon className=\"w-3.5 h-3.5\" />\n <span>All</span>\n </>\n )}\n </button>\n </div>\n\n {!showAllFields && (\n <div className=\"text-xs text-dc-info mb-3 p-2 bg-dc-info-bg rounded border border-dc-info-border\">\n Showing only fields used in this dashboard\n </div>\n )}\n\n {filteredSchema && filteredSchema.cubes.length > 0 ? (\n <CubeMetaExplorer\n schema={filteredSchema}\n schemaStatus=\"success\"\n schemaError={null}\n selectedFields={{\n measures: selectedFieldInFilter ? [selectedFieldInFilter] : [],\n dimensions: selectedFieldInFilter ? [selectedFieldInFilter] : [],\n timeDimensions: selectedFieldInFilter ? [selectedFieldInFilter] : []\n }}\n onFieldSelect={(fieldName) => handleFieldSelect(fieldName)}\n onFieldDeselect={() => {}}\n />\n ) : (\n <div className=\"text-center py-8 text-dc-text-muted text-sm\">\n {showAllFields ? (\n <div>\n <p className=\"mb-2\">No schema available</p>\n <p className=\"text-xs\">Check your API connection</p>\n </div>\n ) : (\n <div>\n <p className=\"mb-2\">No fields used in dashboard</p>\n <p className=\"text-xs\">Add portlets to the dashboard first, or toggle to show all fields</p>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Right Column - Filter Builder or Date Range Selector */}\n <div className=\"flex-1 overflow-auto px-6 py-4 bg-dc-surface-secondary\">\n {filter.isUniversalTime ? (\n /* Universal time filter - show DateRangeSelector */\n <div>\n <div className=\"mb-4 p-3 rounded-md bg-dc-info-bg border border-dc-info-border\">\n <div className=\"text-sm font-medium text-dc-info mb-1\">\n Universal Time Filter\n </div>\n <div className=\"text-xs text-dc-text-secondary\">\n This filter applies to all time dimensions in portlets it&apos;s mapped to.\n Select a date range below to filter data across all time-based charts.\n </div>\n </div>\n <div className=\"mt-4\">\n <DateRangeSelector\n timeDimension=\"__universal_time__\"\n availableTimeDimensions={['__universal_time__']}\n currentDateRange={(() => {\n // Handle both dateRange property and values array\n const simpleFilter = localFilter as SimpleFilter\n if (simpleFilter.dateRange) return simpleFilter.dateRange\n if (simpleFilter.values) {\n // Single string value (preset like \"last 30 days\") - pass as string\n if (Array.isArray(simpleFilter.values) && simpleFilter.values.length === 1 && typeof simpleFilter.values[0] === 'string') {\n return simpleFilter.values[0]\n }\n return simpleFilter.values\n }\n return undefined\n })()}\n onDateRangeChange={handleDateRangeChange}\n onTimeDimensionChange={() => {}}\n onRemove={() => {}}\n hideFieldSelector={true}\n hideRemoveButton={true}\n />\n </div>\n </div>\n ) : (\n /* Regular filter - show FilterBuilder */\n <FilterBuilder\n filters={[localFilter]}\n schema={convertToMetaResponse(schema)}\n query={{}} // Empty query object - not needed for standalone filter editing\n onFiltersChange={handleFilterBuilderChange}\n />\n )}\n </div>\n </div>\n\n {/* Modal Footer */}\n <div className=\"px-6 py-4 border-t border-dc-border flex items-center justify-between bg-dc-surface\">\n <button\n onClick={onDelete}\n className=\"px-4 py-2 text-sm font-medium text-dc-danger hover:bg-dc-danger-bg rounded-md transition-colors\"\n >\n Delete Filter\n </button>\n <button\n onClick={handleSave}\n className=\"px-4 py-2 text-sm font-medium rounded-md transition-colors bg-dc-primary hover:bg-dc-primary-hover text-dc-primary-content\"\n >\n Done\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default FilterEditModal\n","/**\n * ReadOnlyFilterList Component\n *\n * Displays filters in read-only mode with interactive value selectors\n */\n\nimport React, { useCallback } from 'react'\nimport { getIcon } from '../../icons'\nimport FilterItem from '../QueryBuilder/FilterItem'\n\nconst FilterIcon = getIcon('filter')\nconst ClockIcon = getIcon('timeDimension')\nimport DateRangeSelector from '../QueryBuilder/DateRangeSelector'\nimport type { DashboardFilter, CubeMeta, SimpleFilter } from '../../types'\nimport type { MetaResponse } from '../QueryBuilder/types'\n\ninterface ReadOnlyFilterListProps {\n dashboardFilters: DashboardFilter[]\n schema: CubeMeta | null\n onFilterChange: (filterId: string, updatedFilter: DashboardFilter) => void\n onDateRangeChange: (filterId: string, dateRange: string | string[]) => void\n convertToMetaResponse: (cubeMeta: CubeMeta | null) => MetaResponse | null\n isTimeDimensionField: (fieldName: string) => boolean\n}\n\nconst ReadOnlyFilterList: React.FC<ReadOnlyFilterListProps> = ({\n dashboardFilters,\n schema,\n onFilterChange,\n onDateRangeChange,\n convertToMetaResponse,\n isTimeDimensionField\n}) => {\n // Render individual read-only filter\n const renderReadOnlyFilter = useCallback((dashboardFilter: DashboardFilter) => {\n const { id, label, filter, isUniversalTime } = dashboardFilter\n\n // Only render SimpleFilter in read-only mode (skip GroupFilters for now)\n if (!('member' in filter)) {\n return null\n }\n\n const simpleFilter = filter as SimpleFilter\n const isTimeDim = isTimeDimensionField(simpleFilter.member)\n\n // For universal time filters OR time dimensions with inDateRange, use DateRangeSelector\n if (isUniversalTime || (isTimeDim && simpleFilter.operator === 'inDateRange')) {\n // Get date range - handle both dateRange property and values array\n // If values is a single-element array with a preset string, use that string directly\n let dateRangeValue: string | string[] | undefined = simpleFilter.dateRange\n if (!dateRangeValue && simpleFilter.values) {\n if (Array.isArray(simpleFilter.values) && simpleFilter.values.length === 1 && typeof simpleFilter.values[0] === 'string') {\n // Single string value (preset like \"last 30 days\") - pass as string\n dateRangeValue = simpleFilter.values[0]\n } else {\n dateRangeValue = simpleFilter.values\n }\n }\n\n return (\n <div key={id} className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center gap-1.5 px-1\">\n {isUniversalTime && (\n <ClockIcon className=\"w-3.5 h-3.5 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n )}\n <label\n className=\"text-xs font-semibold uppercase tracking-wide truncate\"\n style={{ color: 'var(--dc-text-secondary)' }}\n title={isUniversalTime ? `${label} (applies to all time dimensions)` : label}\n >\n {label}\n </label>\n </div>\n <DateRangeSelector\n timeDimension={isUniversalTime ? '__universal_time__' : simpleFilter.member}\n availableTimeDimensions={isUniversalTime ? ['__universal_time__'] : [simpleFilter.member]}\n currentDateRange={dateRangeValue}\n onDateRangeChange={(_timeDim, dateRange) => onDateRangeChange(id, dateRange)}\n onTimeDimensionChange={() => {}} // Not editable in read-only mode\n onRemove={() => {}} // Not removable in read-only mode\n hideFieldSelector={true}\n hideRemoveButton={true}\n />\n </div>\n )\n }\n\n // For regular filters, use FilterItem\n return (\n <div key={id} className=\"flex flex-col gap-1.5\">\n <label\n className=\"text-xs font-semibold uppercase tracking-wide truncate px-1\"\n style={{ color: 'var(--dc-text-secondary)' }}\n title={label}\n >\n {label}\n </label>\n <FilterItem\n filter={simpleFilter}\n index={0} // Not used in read-only mode\n onFilterChange={(_index, updatedFilter) => {\n onFilterChange(id, {\n ...dashboardFilter,\n filter: updatedFilter\n })\n }}\n onFilterRemove={() => {}} // Not removable in read-only mode\n schema={convertToMetaResponse(schema)}\n query={{}} // Empty query object for read-only mode\n hideFieldSelector={true}\n hideOperatorSelector={true}\n hideRemoveButton={true}\n />\n </div>\n )\n }, [schema, convertToMetaResponse, isTimeDimensionField, onFilterChange, onDateRangeChange])\n\n if (dashboardFilters.length === 0) {\n return null\n }\n\n return (\n <div className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2 mb-3\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {dashboardFilters.map(renderReadOnlyFilter)}\n </div>\n </div>\n )\n}\n\nexport default ReadOnlyFilterList\n","/**\n * EditModeFilterList Component\n *\n * Displays filters in edit mode with chips showing filter labels and edit/delete actions\n */\n\nimport React from 'react'\nimport { getIcon } from '../../icons'\nimport type { DashboardFilter } from '../../types'\n\nconst FilterIcon = getIcon('filter')\nconst AddIcon = getIcon('add')\nconst CloseIcon = getIcon('close')\nconst EditIcon = getIcon('edit')\nconst ChevronDownIcon = getIcon('chevronDown')\nconst ClockIcon = getIcon('timeDimension')\n\ninterface EditModeFilterListProps {\n dashboardFilters: DashboardFilter[]\n onAddFilter: () => void\n onAddTimeFilter: () => void\n onEditFilter: (filterId: string) => void\n onRemoveFilter: (filterId: string) => void\n selectedFilterId?: string | null\n onFilterSelect?: (filterId: string) => void\n}\n\nconst EditModeFilterList: React.FC<EditModeFilterListProps> = ({\n dashboardFilters,\n onAddFilter,\n onAddTimeFilter,\n onEditFilter,\n onRemoveFilter,\n selectedFilterId,\n onFilterSelect\n}) => {\n const [isCollapsed, setIsCollapsed] = React.useState(false)\n\n // Render compact filter chip - just label + edit + delete\n const renderFilterChip = (dashboardFilter: DashboardFilter) => {\n const { id, label, isUniversalTime } = dashboardFilter\n const isSelected = selectedFilterId === id\n\n // Use calendar icon for universal time filters, funnel for regular filters\n const IconComponent = isUniversalTime ? ClockIcon : FilterIcon\n\n return (\n <div\n key={id}\n className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md border text-xs transition-all ${\n 'cursor-pointer hover:shadow-md'\n }`}\n style={{\n backgroundColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-surface)',\n borderColor: isSelected ? 'var(--dc-primary)' : 'var(--dc-border)',\n borderWidth: isSelected ? '2px' : '1px',\n color: isSelected ? 'white' : 'var(--dc-text)',\n boxShadow: isSelected ? '0 0 0 3px rgba(var(--dc-primary-rgb), 0.1)' : 'none'\n }}\n onClick={() => {\n if (onFilterSelect) {\n onFilterSelect(id)\n }\n }}\n >\n <IconComponent\n className=\"w-3.5 h-3.5 shrink-0\"\n style={{ color: isSelected ? 'white' : 'var(--dc-primary)' }}\n />\n <span className=\"font-medium truncate\">{label}</span>\n\n {!isSelected && (\n <div className=\"flex items-center gap-0.5 ml-1\" onClick={(e) => e.stopPropagation()}>\n <button\n onClick={() => onEditFilter(id)}\n className=\"p-0.5 hover:bg-dc-hover rounded transition-colors\"\n title=\"Edit filter\"\n >\n <EditIcon className=\"w-3 h-3\" />\n </button>\n <button\n onClick={() => onRemoveFilter(id)}\n className=\"p-0.5 hover:bg-dc-danger-bg hover:text-dc-danger rounded transition-colors\"\n title=\"Remove filter\"\n >\n <CloseIcon className=\"w-3 h-3\" />\n </button>\n </div>\n )}\n </div>\n )\n }\n\n return (\n <>\n {/* Mobile: Header + collapsible content */}\n <div className=\"md:hidden\">\n {/* Header - clickable to toggle */}\n <div\n className=\"px-4 py-2 flex items-center justify-between cursor-pointer\"\n onClick={() => setIsCollapsed(!isCollapsed)}\n >\n <div className=\"flex items-center gap-2\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n <ChevronDownIcon\n className={`w-4 h-4 transition-transform ${isCollapsed ? '' : 'rotate-180'}`}\n style={{ color: 'var(--dc-text-secondary)' }}\n />\n </div>\n\n <div className=\"flex items-center gap-1\">\n {/* Only show Date Range button if no universal time filter exists */}\n {!dashboardFilters.some(f => f.isUniversalTime) && (\n <button\n onClick={(e) => {\n e.stopPropagation()\n onAddTimeFilter()\n }}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-surface)',\n color: 'var(--dc-primary)',\n border: '1px solid var(--dc-border)'\n }}\n title=\"Add date range filter (applies to all time dimensions)\"\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <ClockIcon className=\"w-3.5 h-3.5\" />\n </button>\n )}\n <button\n onClick={(e) => {\n e.stopPropagation()\n onAddFilter()\n }}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n </div>\n\n {/* Mobile Filter Chips - Collapsible */}\n {dashboardFilters.length > 0 && !isCollapsed && (\n <div className=\"px-4 pb-2 flex flex-col gap-2\">\n {dashboardFilters.map(renderFilterChip)}\n </div>\n )}\n\n {/* Mobile Empty State */}\n {dashboardFilters.length === 0 && !isCollapsed && (\n <div className=\"px-4 pb-2\">\n <div\n className=\"text-xs p-2 rounded-md text-center\"\n style={{\n backgroundColor: 'var(--dc-surface-secondary)',\n color: 'var(--dc-text-secondary)'\n }}\n >\n No filters configured. Click \"Add\" to create one.\n </div>\n </div>\n )}\n </div>\n\n {/* Desktop: Single row layout */}\n <div className=\"hidden md:flex md:items-center md:gap-3 px-4 py-2\">\n {/* Header Section */}\n <div className=\"flex items-center gap-2 shrink-0\">\n <FilterIcon className=\"w-4 h-4 shrink-0\" style={{ color: 'var(--dc-primary)' }} />\n <h3 className=\"text-sm font-semibold whitespace-nowrap\" style={{ color: 'var(--dc-text)' }}>\n Filters\n </h3>\n {dashboardFilters.length > 0 && (\n <span\n className=\"px-1.5 py-0.5 rounded-full text-xs font-medium\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n {dashboardFilters.length}\n </span>\n )}\n </div>\n\n {/* Filter Chips Section - grows to fill space */}\n {dashboardFilters.length > 0 ? (\n <div className=\"flex flex-wrap gap-2 flex-1 min-w-0\">\n {dashboardFilters.map(renderFilterChip)}\n </div>\n ) : (\n <div className=\"flex-1 min-w-0\">\n <div\n className=\"text-xs px-3 py-1 rounded-md inline-block\"\n style={{\n backgroundColor: 'var(--dc-surface-secondary)',\n color: 'var(--dc-text-secondary)'\n }}\n >\n No filters configured. Click \"Add\" to create one.\n </div>\n </div>\n )}\n\n {/* Add Button Section */}\n <div className=\"flex items-center gap-1 shrink-0\">\n {/* Only show Date Range button if no universal time filter exists */}\n {!dashboardFilters.some(f => f.isUniversalTime) && (\n <button\n onClick={onAddTimeFilter}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-surface)',\n color: 'var(--dc-primary)',\n border: '1px solid var(--dc-border)'\n }}\n title=\"Add date range filter (applies to all time dimensions)\"\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <span>Date Range</span>\n </button>\n )}\n <button\n onClick={onAddFilter}\n className=\"inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <AddIcon className=\"w-3.5 h-3.5\" />\n <span>Filter</span>\n </button>\n </div>\n </div>\n </>\n )\n}\n\nexport default EditModeFilterList\n","/**\n * DashboardFilterPanel Component\n *\n * Orchestrates dashboard-level filtering UI\n * - Edit mode: Shows filter chips with edit/delete actions\n * - View mode: Shows interactive read-only filters\n *\n * Pattern: Simplified coordination layer (matches portlet editing pattern)\n * - No local editing state (modal owns all edit state)\n * - Just tracks which filter is being edited and modal visibility\n * - Delegates to FilterEditModal for all editing logic\n */\n\nimport React, { useState, useCallback } from 'react'\nimport FilterEditModal from './DashboardFilters/FilterEditModal'\nimport ReadOnlyFilterList from './DashboardFilters/ReadOnlyFilterList'\nimport EditModeFilterList from './DashboardFilters/EditModeFilterList'\nimport type { DashboardFilter, CubeMeta, DashboardConfig } from '../types'\nimport type { MetaResponse } from './QueryBuilder/types'\n\ninterface DashboardFilterPanelProps {\n dashboardFilters: DashboardFilter[]\n editable: boolean\n schema: CubeMeta | null\n dashboardConfig: DashboardConfig\n onDashboardFiltersChange: (filters: DashboardFilter[]) => void\n onSaveFilters?: (filters: DashboardFilter[]) => void | Promise<void>\n selectedFilterId?: string | null\n onFilterSelect?: (filterId: string) => void\n isEditMode?: boolean\n}\n\nconst DashboardFilterPanel: React.FC<DashboardFilterPanelProps> = ({\n dashboardFilters,\n editable,\n schema,\n dashboardConfig,\n onDashboardFiltersChange,\n onSaveFilters,\n selectedFilterId,\n onFilterSelect,\n isEditMode = false\n}) => {\n // Track which filter is being edited and modal visibility (no local editing state)\n const [editingFilter, setEditingFilter] = useState<DashboardFilter | null>(null)\n const [showFilterBuilder, setShowFilterBuilder] = useState(false)\n\n // Convert CubeMeta to MetaResponse (QueryBuilder type)\n const convertToMetaResponse = useCallback((cubeMeta: CubeMeta | null): MetaResponse | null => {\n if (!cubeMeta) return null\n\n return {\n cubes: cubeMeta.cubes.map(cube => ({\n name: cube.name,\n title: cube.title || cube.name,\n description: cube.description || '',\n measures: cube.measures.map(m => ({\n name: m.name,\n title: m.title,\n type: m.type,\n description: '',\n shortTitle: m.shortTitle\n })),\n dimensions: cube.dimensions.map(d => ({\n name: d.name,\n title: d.title,\n type: d.type,\n description: '',\n shortTitle: d.shortTitle\n })),\n segments: cube.segments?.map(s => ({\n name: s.name,\n title: s.title,\n type: s.type,\n description: '',\n shortTitle: s.shortTitle\n })) || []\n }))\n }\n }, [])\n\n // Generate unique ID for new filters\n const generateFilterId = useCallback(() => {\n return `df_${Date.now()}_${Math.random().toString(36).substring(7)}`\n }, [])\n\n // Handle adding a new filter - create temporary filter for modal\n const handleAddFilter = useCallback(() => {\n const newFilter: DashboardFilter = {\n id: generateFilterId(),\n label: `Filter ${dashboardFilters.length + 1}`,\n filter: {\n member: '',\n operator: 'equals',\n values: []\n }\n }\n setEditingFilter(newFilter)\n setShowFilterBuilder(true)\n }, [dashboardFilters.length, generateFilterId])\n\n // Handle adding a universal time filter - applies to all time dimensions\n // Creates filter directly without opening modal (fixed name, user just sets date range in view mode)\n const handleAddTimeFilter = useCallback(() => {\n const newFilter: DashboardFilter = {\n id: generateFilterId(),\n label: 'Date Range Filter',\n isUniversalTime: true,\n filter: {\n member: '__universal_time__', // Placeholder, not used in merge logic\n operator: 'inDateRange',\n values: ['last 30 days']\n }\n }\n // Add directly to filters without opening modal\n const updatedFilters = [...dashboardFilters, newFilter]\n onDashboardFiltersChange(updatedFilters)\n }, [generateFilterId, dashboardFilters, onDashboardFiltersChange])\n\n // Handle editing an existing filter - just open modal with filter\n const handleEditFilter = useCallback((filterId: string) => {\n const filterToEdit = dashboardFilters.find(df => df.id === filterId)\n if (filterToEdit) {\n setEditingFilter(filterToEdit)\n setShowFilterBuilder(true)\n }\n }, [dashboardFilters])\n\n // Handle removing a filter - simple filter list update\n const handleRemoveFilter = useCallback((filterId: string) => {\n const updatedFilters = dashboardFilters.filter(df => df.id !== filterId)\n onDashboardFiltersChange(updatedFilters)\n\n // Close modal if we're deleting the filter being edited\n if (editingFilter?.id === filterId) {\n setEditingFilter(null)\n setShowFilterBuilder(false)\n }\n }, [dashboardFilters, editingFilter, onDashboardFiltersChange])\n\n // Handle save from modal - update or add filter and save\n const handleSaveFilter = useCallback(async (filterData: DashboardFilter) => {\n // Check if this is a new filter (not in current list) or an update\n const existingFilterIndex = dashboardFilters.findIndex(f => f.id === filterData.id)\n\n let updatedFilters: DashboardFilter[]\n if (existingFilterIndex >= 0) {\n // Update existing filter\n updatedFilters = dashboardFilters.map(f =>\n f.id === filterData.id ? filterData : f\n )\n } else {\n // Add new filter\n updatedFilters = [...dashboardFilters, filterData]\n }\n\n // Update dashboard state\n onDashboardFiltersChange(updatedFilters)\n\n // Trigger save if callback provided\n if (onSaveFilters) {\n try {\n await onSaveFilters(updatedFilters)\n } catch (error) {\n console.error('Failed to save filters:', error)\n throw error // Re-throw so modal can handle it\n }\n }\n }, [dashboardFilters, onDashboardFiltersChange, onSaveFilters])\n\n // Handle modal close - just clean up state\n const handleCloseFilterBuilder = useCallback(() => {\n setEditingFilter(null)\n setShowFilterBuilder(false)\n }, [])\n\n // Handle date range change in read-only mode\n const handleFilterDateRangeChange = useCallback((filterId: string, dateRange: string | string[]) => {\n const updatedFilters = dashboardFilters.map(df => {\n if (df.id === filterId) {\n const filter = df.filter\n if ('member' in filter) {\n return {\n ...df,\n filter: {\n ...filter,\n dateRange,\n values: Array.isArray(dateRange) ? dateRange : [dateRange]\n }\n }\n }\n }\n return df\n })\n onDashboardFiltersChange(updatedFilters)\n }, [dashboardFilters, onDashboardFiltersChange])\n\n // Handle filter change in read-only mode\n const handleReadOnlyFilterChange = useCallback((filterId: string, updatedFilter: DashboardFilter) => {\n const updatedFilters = dashboardFilters.map(df =>\n df.id === filterId ? updatedFilter : df\n )\n onDashboardFiltersChange(updatedFilters)\n }, [dashboardFilters, onDashboardFiltersChange])\n\n // Check if a field is a time dimension\n const isTimeDimensionField = useCallback((fieldName: string): boolean => {\n if (!schema) return false\n return schema.cubes.some(cube =>\n cube.dimensions.some(dim => dim.name === fieldName && dim.type === 'time')\n )\n }, [schema])\n\n // Hide filter panel completely when not editable (fully embedded mode without filter support)\n if (!editable) {\n return null\n }\n\n // Hide if no filters exist and not in edit mode (nothing to show)\n if (!isEditMode && dashboardFilters.length === 0) {\n return null\n }\n\n return (\n <div\n className=\"mb-4 border rounded-lg\"\n style={{\n borderColor: 'var(--dc-border)',\n backgroundColor: 'var(--dc-surface)',\n boxShadow: 'var(--dc-shadow-sm)'\n }}\n >\n {/* Edit Mode - Filter chips with edit/delete actions */}\n {isEditMode ? (\n <EditModeFilterList\n dashboardFilters={dashboardFilters}\n onAddFilter={handleAddFilter}\n onAddTimeFilter={handleAddTimeFilter}\n onEditFilter={handleEditFilter}\n onRemoveFilter={handleRemoveFilter}\n selectedFilterId={selectedFilterId}\n onFilterSelect={onFilterSelect}\n />\n ) : (\n /* View Mode - Read-only interactive filters */\n <ReadOnlyFilterList\n dashboardFilters={dashboardFilters}\n schema={schema}\n onFilterChange={handleReadOnlyFilterChange}\n onDateRangeChange={handleFilterDateRangeChange}\n convertToMetaResponse={convertToMetaResponse}\n isTimeDimensionField={isTimeDimensionField}\n />\n )}\n\n {/* Filter Edit Modal */}\n {editable && showFilterBuilder && editingFilter && (\n <FilterEditModal\n filter={editingFilter}\n schema={schema}\n dashboardConfig={dashboardConfig}\n isOpen={showFilterBuilder}\n onSave={handleSaveFilter}\n onClose={handleCloseFilterBuilder}\n onDelete={() => handleRemoveFilter(editingFilter.id)}\n convertToMetaResponse={convertToMetaResponse}\n />\n )}\n </div>\n )\n}\n\nexport default DashboardFilterPanel\n","/**\n * ScaledGridWrapper component\n * Applies CSS transform scaling to the dashboard grid for intermediate screen sizes\n * Maintains the exact desktop layout appearance, just proportionally smaller\n */\n\nimport React, { useState, useEffect, useRef } from 'react'\n\ninterface ScaledGridWrapperProps {\n scaleFactor: number\n designWidth: number\n children: React.ReactNode\n}\n\n/**\n * Wrapper component that scales the grid using CSS transform\n * Handles height compensation to prevent overflow/whitespace issues\n */\nexport default function ScaledGridWrapper({\n scaleFactor,\n designWidth,\n children\n}: ScaledGridWrapperProps) {\n const [actualHeight, setActualHeight] = useState(0)\n const innerRef = useRef<HTMLDivElement>(null)\n\n // Measure actual grid height to calculate visible height\n useEffect(() => {\n if (!innerRef.current) return\n\n const observer = new ResizeObserver((entries) => {\n setActualHeight(entries[0]?.contentRect.height ?? 0)\n })\n\n observer.observe(innerRef.current)\n\n // Set initial height\n setActualHeight(innerRef.current.offsetHeight || 0)\n\n return () => observer.disconnect()\n }, [])\n\n // The scaled visual height\n const visualHeight = actualHeight * scaleFactor\n\n return (\n <div\n className=\"scaled-grid-container\"\n style={{\n height: visualHeight > 0 ? visualHeight : 'auto',\n overflow: 'hidden',\n width: '100%'\n }}\n >\n <div\n ref={innerRef}\n className=\"scaled-grid-inner\"\n style={{\n transform: `scale(${scaleFactor})`,\n transformOrigin: 'top left',\n width: designWidth\n }}\n >\n {children}\n </div>\n </div>\n )\n}\n","/**\n * MobileStackedLayout component\n * Simple vertical stack layout for mobile screens (<768px)\n * Read-only view with portlets sorted by grid position\n */\n\nimport { useMemo, useRef, useState, useCallback } from 'react'\nimport { getIcon } from '../icons'\nimport AnalyticsPortlet from './AnalyticsPortlet'\n\nconst RefreshIcon = getIcon('refresh')\nimport { ScrollContainerProvider } from '../providers/ScrollContainerContext'\nimport type { DashboardFilter, DashboardConfig } from '../types'\nimport type { ColorPalette } from '../utils/colorPalettes'\n\n/**\n * Finds the nearest scrollable ancestor of an element.\n */\nfunction findScrollableAncestor(element: HTMLElement | null): HTMLElement | null {\n if (!element) return null\n\n let current = element.parentElement\n\n while (current) {\n const style = window.getComputedStyle(current)\n const overflowY = style.overflowY\n const overflowX = style.overflowX\n\n const hasScrollableOverflow =\n overflowY === 'auto' || overflowY === 'scroll' ||\n overflowX === 'auto' || overflowX === 'scroll'\n\n const hasScrollContent =\n current.scrollHeight > current.clientHeight ||\n current.scrollWidth > current.clientWidth\n\n if (hasScrollableOverflow && hasScrollContent) {\n return current\n }\n\n if (current === document.body) break\n current = current.parentElement\n }\n\n return null\n}\n\ninterface MobileStackedLayoutProps {\n config: DashboardConfig\n colorPalette?: ColorPalette\n dashboardFilters?: DashboardFilter[]\n onPortletRefresh?: (portletId: string) => void\n}\n\n/**\n * Mobile-optimized stacked layout for dashboard portlets\n * Renders portlets in a single column, sorted by grid position\n */\nexport default function MobileStackedLayout({\n config,\n colorPalette,\n dashboardFilters,\n onPortletRefresh\n}: MobileStackedLayoutProps) {\n const portletComponentRefs = useRef<{ [key: string]: { refresh: () => void } | null }>({})\n\n // Scroll container detection for lazy loading\n const [scrollContainer, setScrollContainer] = useState<HTMLElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n\n const setContainerRef = useCallback((node: HTMLDivElement | null) => {\n containerRef.current = node\n if (node) {\n setScrollContainer(findScrollableAncestor(node))\n }\n }, [])\n\n // Sort portlets by y position, then x position (top-to-bottom, left-to-right)\n const sortedPortlets = useMemo(() => {\n return [...config.portlets].sort((a, b) => {\n if (a.y !== b.y) return a.y - b.y\n return a.x - b.x\n })\n }, [config.portlets])\n\n const handlePortletRefresh = (portletId: string) => {\n // Refresh the specific portlet component\n portletComponentRefs.current[portletId]?.refresh()\n // Also call external handler if provided\n onPortletRefresh?.(portletId)\n }\n\n return (\n <ScrollContainerProvider value={scrollContainer}>\n <div ref={setContainerRef} className=\"mobile-stacked-layout space-y-4 px-2\">\n {sortedPortlets.map(portlet => {\n // Calculate height: use stored h * rowHeight (80px), with minimum\n const portletHeight = Math.max(300, portlet.h * 80)\n // Header is approximately 40px when shown\n const headerHeight = portlet.displayConfig?.hideHeader ? 0 : 40\n // Content height = total - header - padding (py-3 = 24px)\n const contentHeight = portletHeight - headerHeight - 24\n\n return (\n <div\n key={portlet.id}\n data-portlet-id={portlet.id}\n className=\"bg-dc-surface border border-dc-border rounded-lg flex flex-col\"\n style={{\n height: portletHeight,\n boxShadow: 'var(--dc-shadow-sm)'\n }}\n >\n {/* Portlet Header - Simplified for mobile (no edit controls) */}\n {!portlet.displayConfig?.hideHeader && (\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg\">\n <h3 className=\"font-semibold text-sm text-dc-text truncate flex-1\">\n {portlet.title}\n </h3>\n <div className=\"flex items-center gap-1 shrink-0 ml-2\">\n <button\n onClick={() => handlePortletRefresh(portlet.id)}\n className=\"p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors\"\n title=\"Refresh portlet data\"\n >\n <RefreshIcon style={{ width: '16px', height: '16px', color: 'currentColor' }} />\n </button>\n </div>\n </div>\n )}\n\n {/* Portlet Content - explicit height for charts to render */}\n <div\n className=\"px-2 py-3 overflow-visible flex flex-col\"\n style={{ height: contentHeight }}\n >\n <AnalyticsPortlet\n ref={el => { portletComponentRefs.current[portlet.id] = el }}\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n dashboardFilters={dashboardFilters}\n dashboardFilterMapping={portlet.dashboardFilterMapping}\n eagerLoad={portlet.eagerLoad ?? config.eagerLoad ?? false}\n title={portlet.title}\n height={contentHeight}\n colorPalette={colorPalette}\n />\n </div>\n </div>\n )\n })}\n </div>\n </ScrollContainerProvider>\n )\n}\n","/**\n * Dashboard Grid Component\n * Uses react-grid-layout for responsive grid layout\n * Simplified version without app-specific dependencies\n */\n\nimport {\n useCallback,\n useRef,\n useState,\n useEffect,\n useMemo,\n type ReactNode,\n type HTMLAttributes,\n type DragEvent,\n type MouseEvent,\n type Ref\n} from 'react'\nimport ReactGridLayout, { verticalCompactor, type LayoutItem, type Layout } from 'react-grid-layout'\nimport { getIcon } from '../icons'\nimport DashboardPortletCard from './DashboardPortletCard'\nimport RowManagedLayout from './RowManagedLayout'\n\nconst ChartBarIcon = getIcon('measure')\nconst RefreshIcon = getIcon('refresh')\nconst EditIcon = getIcon('edit')\nconst DeleteIcon = getIcon('delete')\nconst AddIcon = getIcon('add')\nconst CopyIcon = getIcon('copy')\nconst FilterIcon = getIcon('filter')\nconst DesktopIcon = getIcon('desktop')\nconst GridIcon = getIcon('segment')\nconst RowsIcon = getIcon('table')\nimport PortletEditModal from './PortletEditModal'\nimport PortletAnalysisModal from './PortletAnalysisModal'\nimport PortletFilterConfigModal from './PortletFilterConfigModal'\nimport { useCubeContext } from '../providers/CubeProvider'\nimport ColorPaletteSelector from './ColorPaletteSelector'\nimport DashboardFilterPanel from './DashboardFilterPanel'\nimport ScaledGridWrapper from './ScaledGridWrapper'\nimport MobileStackedLayout from './MobileStackedLayout'\nimport { useResponsiveDashboard } from '../hooks/useResponsiveDashboard'\nimport { ScrollContainerProvider } from '../providers/ScrollContainerContext'\nimport type { ColorPalette } from '../utils/colorPalettes'\n\n/**\n * Finds the nearest scrollable ancestor of an element.\n * Used to detect scroll container for lazy loading IntersectionObserver.\n */\nfunction findScrollableAncestor(element: HTMLElement | null): HTMLElement | null {\n if (!element) return null\n\n let current = element.parentElement\n\n while (current) {\n const style = window.getComputedStyle(current)\n const overflowY = style.overflowY\n const overflowX = style.overflowX\n\n const hasScrollableOverflow =\n overflowY === 'auto' || overflowY === 'scroll' ||\n overflowX === 'auto' || overflowX === 'scroll'\n\n const hasScrollContent =\n current.scrollHeight > current.clientHeight ||\n current.scrollWidth > current.clientWidth\n\n if (hasScrollableOverflow && hasScrollContent) {\n return current\n }\n\n if (current === document.body) break\n current = current.parentElement\n }\n\n return null // Use viewport\n}\nimport type {\n DashboardConfig,\n PortletConfig,\n DashboardFilter,\n CubeMeta,\n DashboardLayoutMode,\n DashboardGridSettings,\n RowLayout,\n RowLayoutColumn\n} from '../types'\n\n// CSS for react-grid-layout should be imported by the consuming app\n// import 'react-grid-layout/css/styles.css'\n\ninterface DashboardGridProps {\n config: DashboardConfig\n editable?: boolean\n dashboardFilters?: DashboardFilter[] // Dashboard-level filters to apply to portlets\n loadingComponent?: ReactNode // Custom loading indicator for all portlets\n onConfigChange?: (config: DashboardConfig) => void\n onPortletRefresh?: (portletId: string) => void\n onSave?: (config: DashboardConfig) => Promise<void> | void\n colorPalette?: ColorPalette // Complete palette with both colors and gradient\n schema?: CubeMeta | null // Cube metadata for filter panel\n onDashboardFiltersChange?: (filters: DashboardFilter[]) => void // Handler for filter changes\n dashboardModes?: DashboardLayoutMode[]\n}\n\nconst DEFAULT_GRID_SETTINGS: DashboardGridSettings = {\n cols: 12,\n rowHeight: 80,\n minW: 2,\n minH: 2\n}\n\nconst createRowId = () => `row-${Date.now()}`\n\nconst getGridSettings = (config: DashboardConfig): DashboardGridSettings => ({\n cols: config.grid?.cols ?? DEFAULT_GRID_SETTINGS.cols,\n rowHeight: config.grid?.rowHeight ?? DEFAULT_GRID_SETTINGS.rowHeight,\n minW: config.grid?.minW ?? DEFAULT_GRID_SETTINGS.minW,\n minH: config.grid?.minH ?? DEFAULT_GRID_SETTINGS.minH\n})\n\nconst equalizeRowColumns = (\n portletIds: string[],\n gridSettings: DashboardGridSettings\n): RowLayoutColumn[] => {\n const count = portletIds.length\n if (count === 0) return []\n\n const { cols, minW } = gridSettings\n const minTotal = minW * count\n\n if (minTotal > cols) {\n const base = Math.floor(cols / count)\n const remainder = cols % count\n return portletIds.map((id, index) => ({\n portletId: id,\n w: base + (index < remainder ? 1 : 0)\n }))\n }\n\n const remaining = cols - minTotal\n const extra = Math.floor(remaining / count)\n const remainder = remaining % count\n\n return portletIds.map((id, index) => ({\n portletId: id,\n w: minW + extra + (index < remainder ? 1 : 0)\n }))\n}\n\nconst adjustRowWidths = (\n columns: RowLayoutColumn[],\n gridSettings: DashboardGridSettings\n): RowLayoutColumn[] => {\n if (columns.length === 0) return []\n\n const { cols, minW } = gridSettings\n const adjusted = columns.map(column => ({\n ...column,\n w: Math.max(minW, column.w)\n }))\n\n let total = adjusted.reduce((sum, column) => sum + column.w, 0)\n if (total === cols) return adjusted\n\n if (total < cols) {\n let remaining = cols - total\n let index = 0\n while (remaining > 0) {\n adjusted[index % adjusted.length].w += 1\n remaining -= 1\n index += 1\n }\n return adjusted\n }\n\n let overflow = total - cols\n for (let index = adjusted.length - 1; index >= 0 && overflow > 0; index -= 1) {\n const column = adjusted[index]\n const reducible = Math.max(0, column.w - minW)\n if (reducible === 0) continue\n const delta = Math.min(reducible, overflow)\n column.w -= delta\n overflow -= delta\n }\n\n return adjusted\n}\n\nconst convertPortletsToRows = (\n portlets: PortletConfig[],\n gridSettings: DashboardGridSettings\n): RowLayout[] => {\n if (portlets.length === 0) return []\n\n const sorted = [...portlets].sort((a, b) => {\n if (a.y !== b.y) return a.y - b.y\n return a.x - b.x\n })\n\n const rowsByY = new Map<number, PortletConfig[]>()\n sorted.forEach(portlet => {\n const row = rowsByY.get(portlet.y) ?? []\n row.push(portlet)\n rowsByY.set(portlet.y, row)\n })\n\n return Array.from(rowsByY.entries())\n .sort(([a], [b]) => a - b)\n .map(([rowY, rowPortlets]) => {\n const rowHeight = Math.max(\n gridSettings.minH,\n ...rowPortlets.map(portlet => portlet.h)\n )\n const portletIds = rowPortlets.map(portlet => portlet.id)\n return {\n id: `row-${rowY}`,\n h: rowHeight,\n columns: equalizeRowColumns(portletIds, gridSettings)\n }\n })\n}\n\nconst normalizeRows = (\n rows: RowLayout[],\n portlets: PortletConfig[],\n gridSettings: DashboardGridSettings\n): RowLayout[] => {\n const portletIds = new Set(portlets.map(portlet => portlet.id))\n return rows\n .map(row => ({\n ...row,\n h: Math.max(gridSettings.minH, row.h),\n columns: adjustRowWidths(\n row.columns.filter(column => portletIds.has(column.portletId)),\n gridSettings\n )\n }))\n .filter(row => row.columns.length > 0)\n}\n\nconst convertRowsToPortlets = (\n rows: RowLayout[],\n portlets: PortletConfig[]\n): PortletConfig[] => {\n const portletMap = new Map(portlets.map(portlet => [portlet.id, portlet]))\n let currentY = 0\n\n const updated: PortletConfig[] = []\n rows.forEach(row => {\n let currentX = 0\n row.columns.forEach(column => {\n const portlet = portletMap.get(column.portletId)\n if (!portlet) return\n updated.push({\n ...portlet,\n x: currentX,\n y: currentY,\n w: column.w,\n h: row.h\n })\n currentX += column.w\n })\n currentY += row.h\n })\n\n const updatedIds = new Set(updated.map(portlet => portlet.id))\n portlets.forEach(portlet => {\n if (!updatedIds.has(portlet.id)) {\n updated.push(portlet)\n }\n })\n\n return updated\n}\n\nexport default function DashboardGrid({\n config,\n editable = false,\n dashboardFilters,\n loadingComponent,\n onConfigChange,\n onPortletRefresh,\n onSave,\n colorPalette,\n schema,\n onDashboardFiltersChange,\n dashboardModes\n}: DashboardGridProps) {\n // Get features from context for conditional modal rendering\n const { features } = useCubeContext()\n\n // Responsive dashboard hook for three-tier layout strategy\n const {\n containerRef,\n containerWidth,\n displayMode,\n scaleFactor,\n isEditable: isResponsiveEditable,\n designWidth\n } = useResponsiveDashboard()\n\n const allowedModes: DashboardLayoutMode[] = dashboardModes && dashboardModes.length > 0\n ? dashboardModes\n : ['rows', 'grid']\n const fallbackMode: DashboardLayoutMode = allowedModes.includes('rows') ? 'rows' : allowedModes[0] ?? 'grid'\n const configMode = config.layoutMode ?? 'grid'\n const layoutMode: DashboardLayoutMode = allowedModes.includes(configMode)\n ? configMode\n : fallbackMode\n const gridSettings = useMemo(() => getGridSettings(config), [config])\n\n // Scroll container detection for lazy loading\n // Null = viewport, element = scrolling container\n const [scrollContainer, setScrollContainer] = useState<HTMLElement | null>(null)\n const containerElementRef = useRef<HTMLDivElement | null>(null)\n\n // Detect scroll container after mount\n useEffect(() => {\n if (containerElementRef.current) {\n setScrollContainer(findScrollableAncestor(containerElementRef.current))\n }\n }, [])\n\n // Combined ref for container\n const combinedContainerRef = useCallback((node: HTMLDivElement | null) => {\n containerElementRef.current = node\n containerRef(node)\n if (node) {\n setScrollContainer(findScrollableAncestor(node))\n }\n }, [containerRef])\n\n // Calculate grid width based on display mode\n // Desktop: use actual container width (allows wider than 1200px)\n // Scaled: use design width (1200px) and apply CSS scaling\n const gridWidth = displayMode === 'desktop' ? containerWidth : designWidth\n const [draftRows, setDraftRows] = useState<RowLayout[] | null>(null)\n const draftRowsRef = useRef<RowLayout[] | null>(null)\n const dragStateRef = useRef<{ rowIndex: number; colIndex: number; portletId: string } | null>(null)\n const [isDraggingPortlet, setIsDraggingPortlet] = useState(false)\n\n // Refs to store portlet refs for refresh functionality\n const portletRefs = useRef<{ [key: string]: HTMLDivElement | null }>({})\n const portletComponentRefs = useRef<{ [key: string]: { refresh: () => void } | null }>({})\n\n // Track if component has been initialized to prevent saves during initial load\n const [isInitialized, setIsInitialized] = useState(false)\n const [lastKnownLayout, setLastKnownLayout] = useState<any[]>([])\n\n // Edit mode state - dashboard is readonly by default\n const [isEditMode, setIsEditMode] = useState(false)\n\n // Filter selection mode state\n const [selectedFilterId, setSelectedFilterId] = useState<string | null>(null)\n\n // Determine if editing is allowed (only in desktop mode)\n const canEdit = editable && isEditMode && isResponsiveEditable && !selectedFilterId\n const canChangeLayoutMode = editable && isEditMode && isResponsiveEditable && !selectedFilterId && allowedModes.length > 1\n\n // Exit filter selection mode when leaving edit mode or when switching to non-desktop mode\n useEffect(() => {\n if ((!isEditMode || !isResponsiveEditable) && selectedFilterId) {\n setSelectedFilterId(null)\n }\n }, [isEditMode, isResponsiveEditable, selectedFilterId])\n\n // Exit edit mode when switching to non-desktop view\n useEffect(() => {\n if (!isResponsiveEditable && isEditMode) {\n setIsEditMode(false)\n }\n }, [isResponsiveEditable, isEditMode])\n\n // Track scroll state for sticky header\n const [isScrolled, setIsScrolled] = useState(false)\n\n // Modal states\n const [isPortletModalOpen, setIsPortletModalOpen] = useState(false)\n const [editingPortlet, setEditingPortlet] = useState<PortletConfig | null>(null)\n const [isFilterConfigModalOpen, setIsFilterConfigModalOpen] = useState(false)\n const [filterConfigPortlet, setFilterConfigPortlet] = useState<PortletConfig | null>(null)\n\n // Debug data state - keyed by portlet ID\n const [debugData, setDebugData] = useState<{ [portletId: string]: {\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n } }>({})\n\n useEffect(() => {\n draftRowsRef.current = draftRows\n }, [draftRows])\n\n const resolvedRows = useMemo(() => {\n if (layoutMode !== 'rows') return []\n const baseRows = draftRows ?? config.rows ?? convertPortletsToRows(config.portlets, gridSettings)\n return normalizeRows(baseRows, config.portlets, gridSettings)\n }, [layoutMode, draftRows, config.rows, config.portlets, gridSettings])\n\n const updateRowLayout = useCallback(async (\n rows: RowLayout[],\n save = true,\n portletsOverride?: PortletConfig[]\n ) => {\n if (!onConfigChange) return\n const portlets = portletsOverride ?? config.portlets\n const normalizedRows = normalizeRows(rows, portlets, gridSettings)\n const updatedPortlets = convertRowsToPortlets(normalizedRows, portlets)\n const updatedConfig = {\n ...config,\n layoutMode: 'rows' as const,\n rows: normalizedRows,\n portlets: updatedPortlets\n }\n\n setDraftRows(null)\n onConfigChange(updatedConfig)\n\n if (save && onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed after row layout change:', error)\n }\n }\n }, [config, gridSettings, onConfigChange, onSave])\n\n // Set up initialization tracking\n useEffect(() => {\n // Mark as initialized after first render to prevent saves during load/resize\n const timer = setTimeout(() => {\n setIsInitialized(true)\n // Store initial layout for comparison\n const initialLayout = config.portlets.map(portlet => ({\n i: portlet.id,\n x: portlet.x,\n y: portlet.y,\n w: portlet.w,\n h: portlet.h\n }))\n setLastKnownLayout(initialLayout)\n }, 200) // Slightly longer delay to ensure responsive grid is fully settled\n\n return () => clearTimeout(timer)\n }, [config.portlets])\n\n // Set up scroll listener for sticky header\n useEffect(() => {\n const handleScroll = () => {\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop\n setIsScrolled(scrollTop > 20) // Add sticky styling after scrolling 20px\n }\n\n window.addEventListener('scroll', handleScroll, { passive: true })\n\n // Check initial scroll position\n handleScroll()\n\n return () => {\n window.removeEventListener('scroll', handleScroll)\n }\n }, [])\n\n // Set up ESC key listener for filter selection mode\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && selectedFilterId) {\n setSelectedFilterId(null)\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [selectedFilterId])\n\n // Helper function to check if layout actually changed (not just reordered due to responsive changes)\n const hasLayoutActuallyChanged = useCallback((newLayout: any[]) => {\n if (!isInitialized || lastKnownLayout.length === 0) return false\n \n // Compare each item's position and size\n for (const newItem of newLayout) {\n const oldItem = lastKnownLayout.find(item => item.i === newItem.i)\n if (!oldItem) continue // New item, this is a change\n \n if (oldItem.x !== newItem.x || oldItem.y !== newItem.y || \n oldItem.w !== newItem.w || oldItem.h !== newItem.h) {\n return true\n }\n }\n return false\n }, [isInitialized, lastKnownLayout])\n\n const handleLayoutChange = useCallback((_layout: Layout) => {\n // This function is called for ALL layout changes\n // We should NOT save here - only update internal state if needed\n // Actual saving only happens in handleDragStop and handleResizeStop for explicit user actions\n\n // Note: We don't call onConfigChange here to prevent saving intermediate layout changes\n // The layout changes are handled by react-grid-layout internally\n }, []) // No dependencies since we're not doing anything\n\n // Handle drag stop - save when user finishes dragging (only if layout actually changed)\n const handleDragStop = useCallback(async (layout: Layout, _oldItem: LayoutItem | null, _newItem: LayoutItem | null, _placeholder: LayoutItem | null, _e: Event, _element: HTMLElement | undefined) => {\n if (!editable || !isEditMode || !onSave || !isInitialized) return\n\n // Only save if the layout actually changed from user interaction\n // Convert readonly Layout to mutable array for comparison\n const mutableLayout = [...layout]\n if (!hasLayoutActuallyChanged(mutableLayout)) {\n return // No actual change, don't save\n }\n\n // Get the current updated config (only called in desktop mode)\n const updatedPortlets = config.portlets.map(portlet => {\n const layoutItem = mutableLayout.find(item => item.i === portlet.id)\n if (layoutItem) {\n return {\n ...portlet,\n x: layoutItem.x,\n y: layoutItem.y,\n w: layoutItem.w,\n h: layoutItem.h\n }\n }\n return portlet\n })\n\n // Preserve existing responsive layouts, only update with new lg layout\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets,\n layouts: {\n ...config.layouts,\n lg: mutableLayout // Only save the large layout, let RGL handle responsive adjustments\n }\n }\n\n // Update our tracking of the last known layout\n setLastKnownLayout(mutableLayout)\n\n // Update config state first\n onConfigChange?.(updatedConfig)\n\n // Auto-save after drag operation\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed after drag:', error)\n }\n }, [config.portlets, config.layouts, editable, isEditMode, onConfigChange, onSave, isInitialized, hasLayoutActuallyChanged])\n\n // Handle resize stop - update config and save (resize is user interaction)\n const handleResizeStop = useCallback(async (layout: Layout, _oldItem: LayoutItem | null, _newItem: LayoutItem | null, _placeholder: LayoutItem | null, _e: Event, _element: HTMLElement | undefined) => {\n if (!editable || !isEditMode || !onConfigChange || !isInitialized) return\n\n // Only proceed if the layout actually changed from user interaction\n // Convert readonly Layout to mutable array for comparison\n const mutableLayout = [...layout]\n if (!hasLayoutActuallyChanged(mutableLayout)) {\n return // No actual change, don't save\n }\n\n // Get the current updated config (only called in desktop mode)\n const updatedPortlets = config.portlets.map(portlet => {\n const layoutItem = mutableLayout.find(item => item.i === portlet.id)\n if (layoutItem) {\n return {\n ...portlet,\n x: layoutItem.x,\n y: layoutItem.y,\n w: layoutItem.w,\n h: layoutItem.h\n }\n }\n return portlet\n })\n\n // Preserve existing responsive layouts, only update with new lg layout\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets,\n layouts: {\n ...config.layouts,\n lg: mutableLayout // Only save the large layout, let RGL handle responsive adjustments\n }\n }\n\n // Update our tracking of the last known layout\n setLastKnownLayout(mutableLayout)\n\n // Update config state\n onConfigChange(updatedConfig)\n\n // Auto-save after resize operation (user deliberately resized)\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed after resize:', error)\n }\n }\n }, [config.portlets, config.layouts, editable, isEditMode, onConfigChange, onSave, isInitialized, hasLayoutActuallyChanged])\n\n const handleLayoutModeChange = useCallback(async (mode: DashboardLayoutMode) => {\n if (!onConfigChange || mode === layoutMode || !canChangeLayoutMode || !allowedModes.includes(mode)) return\n\n const baseRows = normalizeRows(\n config.rows && config.rows.length > 0\n ? config.rows\n : convertPortletsToRows(config.portlets, gridSettings),\n config.portlets,\n gridSettings\n )\n\n const updatedPortlets = convertRowsToPortlets(baseRows, config.portlets)\n const updatedConfig = {\n ...config,\n layoutMode: mode,\n rows: baseRows,\n portlets: updatedPortlets\n }\n\n setDraftRows(null)\n onConfigChange(updatedConfig)\n\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed after layout mode switch:', error)\n }\n }\n }, [allowedModes, canChangeLayoutMode, config, gridSettings, layoutMode, onConfigChange, onSave])\n\n const startRowResize = useCallback((rowIndex: number, event: MouseEvent<HTMLDivElement>) => {\n if (!canEdit) return\n event.preventDefault()\n\n const startY = event.clientY\n const startRows = resolvedRows.map(row => ({\n ...row,\n columns: row.columns.map(column => ({ ...column }))\n }))\n\n const handleMouseMove = (moveEvent: globalThis.MouseEvent) => {\n const delta = moveEvent.clientY - startY\n const deltaUnits = Math.round(delta / gridSettings.rowHeight)\n const nextRows = startRows.map((row, index) => {\n if (index !== rowIndex) return row\n return {\n ...row,\n h: Math.max(gridSettings.minH, row.h + deltaUnits)\n }\n })\n setDraftRows(nextRows)\n }\n\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove)\n document.removeEventListener('mouseup', handleMouseUp)\n const finalRows = draftRowsRef.current ?? startRows\n updateRowLayout(finalRows)\n }\n\n document.addEventListener('mousemove', handleMouseMove)\n document.addEventListener('mouseup', handleMouseUp)\n }, [canEdit, gridSettings, resolvedRows, updateRowLayout])\n\n const startColumnResize = useCallback((rowIndex: number, columnIndex: number, event: MouseEvent<HTMLDivElement>) => {\n if (!canEdit) return\n event.preventDefault()\n\n const startX = event.clientX\n const startRows = resolvedRows.map(row => ({\n ...row,\n columns: row.columns.map(column => ({ ...column }))\n }))\n\n const row = startRows[rowIndex]\n const leftColumn = row?.columns[columnIndex]\n const rightColumn = row?.columns[columnIndex + 1]\n if (!row || !leftColumn || !rightColumn) return\n\n const columnGap = 16\n const rowContentWidth = gridWidth - (row.columns.length - 1) * columnGap\n const unitWidth = rowContentWidth / gridSettings.cols\n\n const handleMouseMove = (moveEvent: globalThis.MouseEvent) => {\n const delta = moveEvent.clientX - startX\n const deltaUnits = Math.round(delta / unitWidth)\n if (deltaUnits === 0) {\n setDraftRows(startRows)\n return\n }\n\n let nextLeft = leftColumn.w + deltaUnits\n let nextRight = rightColumn.w - deltaUnits\n\n if (nextLeft < gridSettings.minW) {\n const diff = gridSettings.minW - nextLeft\n nextLeft = gridSettings.minW\n nextRight -= diff\n }\n\n if (nextRight < gridSettings.minW) {\n const diff = gridSettings.minW - nextRight\n nextRight = gridSettings.minW\n nextLeft -= diff\n }\n\n if (nextLeft < gridSettings.minW || nextRight < gridSettings.minW) return\n\n const nextRows = startRows.map((rowItem, index) => {\n if (index !== rowIndex) return rowItem\n const nextColumns = rowItem.columns.map((column, colIndex) => {\n if (colIndex === columnIndex) {\n return { ...column, w: nextLeft }\n }\n if (colIndex === columnIndex + 1) {\n return { ...column, w: nextRight }\n }\n return column\n })\n return {\n ...rowItem,\n columns: adjustRowWidths(nextColumns, gridSettings)\n }\n })\n setDraftRows(nextRows)\n }\n\n const handleMouseUp = () => {\n document.removeEventListener('mousemove', handleMouseMove)\n document.removeEventListener('mouseup', handleMouseUp)\n const finalRows = draftRowsRef.current ?? startRows\n updateRowLayout(finalRows)\n }\n\n document.addEventListener('mousemove', handleMouseMove)\n document.addEventListener('mouseup', handleMouseUp)\n }, [canEdit, gridSettings, gridWidth, resolvedRows, updateRowLayout])\n\n const handlePortletDragStart = useCallback((rowIndex: number, colIndex: number, portletId: string, event: DragEvent<HTMLDivElement>) => {\n if (!canEdit) return\n dragStateRef.current = { rowIndex, colIndex, portletId }\n setIsDraggingPortlet(true)\n event.dataTransfer.effectAllowed = 'move'\n event.dataTransfer.setData('text/plain', portletId)\n }, [canEdit])\n\n const handlePortletDragEnd = useCallback(() => {\n dragStateRef.current = null\n setIsDraggingPortlet(false)\n }, [])\n\n const handleRowDrop = useCallback((rowIndex: number, insertIndex: number | null) => {\n const dragState = dragStateRef.current\n if (!dragState) return\n\n const nextRows = resolvedRows.map(row => ({\n ...row,\n columns: row.columns.map(column => ({ ...column }))\n }))\n\n const sourceRowIndex = dragState.rowIndex\n const sourceRow = nextRows[sourceRowIndex]\n if (!sourceRow) return\n\n const [movedColumn] = sourceRow.columns.splice(dragState.colIndex, 1)\n let sourceRowRemoved = false\n if (sourceRow.columns.length === 0) {\n nextRows.splice(sourceRowIndex, 1)\n sourceRowRemoved = true\n }\n\n let targetRowIndex = rowIndex\n if (sourceRowRemoved && sourceRowIndex < rowIndex) {\n targetRowIndex -= 1\n }\n\n const targetRow = nextRows[targetRowIndex]\n if (!targetRow) return\n\n let targetIndex = insertIndex ?? targetRow.columns.length\n if (!sourceRowRemoved && sourceRowIndex === targetRowIndex && insertIndex !== null) {\n if (insertIndex > dragState.colIndex) {\n targetIndex -= 1\n }\n }\n targetRow.columns.splice(targetIndex, 0, movedColumn)\n\n const movedBetweenRows = sourceRowIndex !== targetRowIndex || sourceRowRemoved\n if (movedBetweenRows) {\n if (!sourceRowRemoved) {\n nextRows[sourceRowIndex] = {\n ...nextRows[sourceRowIndex],\n columns: equalizeRowColumns(\n nextRows[sourceRowIndex].columns.map(column => column.portletId),\n gridSettings\n )\n }\n }\n nextRows[targetRowIndex] = {\n ...nextRows[targetRowIndex],\n columns: equalizeRowColumns(\n nextRows[targetRowIndex].columns.map(column => column.portletId),\n gridSettings\n )\n }\n }\n\n updateRowLayout(nextRows)\n }, [gridSettings, resolvedRows, updateRowLayout])\n\n const handleNewRowDrop = useCallback((insertIndex: number) => {\n const dragState = dragStateRef.current\n if (!dragState) return\n\n const nextRows = resolvedRows.map(row => ({\n ...row,\n columns: row.columns.map(column => ({ ...column }))\n }))\n\n const sourceRow = nextRows[dragState.rowIndex]\n if (!sourceRow) return\n\n const [movedColumn] = sourceRow.columns.splice(dragState.colIndex, 1)\n if (sourceRow.columns.length === 0) {\n nextRows.splice(dragState.rowIndex, 1)\n } else {\n sourceRow.columns = equalizeRowColumns(\n sourceRow.columns.map(column => column.portletId),\n gridSettings\n )\n }\n\n const newRow: RowLayout = {\n id: createRowId(),\n h: Math.max(gridSettings.minH, 5),\n columns: equalizeRowColumns([movedColumn.portletId], gridSettings)\n }\n nextRows.splice(insertIndex, 0, newRow)\n\n updateRowLayout(nextRows)\n }, [gridSettings, resolvedRows, updateRowLayout])\n\n // Handle portlet refresh\n const handlePortletRefresh = useCallback((portletId: string) => {\n const portletComponent = portletComponentRefs.current[portletId]\n if (portletComponent && portletComponent.refresh) {\n portletComponent.refresh()\n }\n if (onPortletRefresh) {\n onPortletRefresh(portletId)\n }\n }, [onPortletRefresh])\n\n // Handle adding new portlet\n const handleAddPortlet = useCallback(() => {\n setEditingPortlet(null)\n setIsPortletModalOpen(true)\n }, [])\n\n // Handle editing existing portlet\n const handleEditPortlet = useCallback((portlet: PortletConfig) => {\n setEditingPortlet(portlet)\n setIsPortletModalOpen(true)\n }, [])\n\n // Handle portlet save\n const handlePortletSave = useCallback(async (portletData: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => {\n if (!onConfigChange) return\n\n let updatedPortlets = [...config.portlets]\n let isNewPortlet = false\n let newPortletId: string | null = null\n\n if (editingPortlet) {\n // Editing existing portlet\n const index = updatedPortlets.findIndex(p => p.id === editingPortlet.id)\n if (index !== -1) {\n updatedPortlets[index] = portletData as PortletConfig\n }\n } else {\n // Adding new portlet\n isNewPortlet = true\n const newPortlet: PortletConfig = {\n ...portletData,\n id: `portlet-${Date.now()}`,\n x: 0,\n y: 0\n } as PortletConfig\n\n newPortletId = newPortlet.id\n\n // Find the best position for the new portlet\n const gridLayout = updatedPortlets.map(p => ({ i: p.id, x: p.x, y: p.y, w: p.w, h: p.h }))\n let maxY = 0\n gridLayout.forEach(item => {\n if (item.y + item.h > maxY) {\n maxY = item.y + item.h\n }\n })\n newPortlet.y = maxY\n\n updatedPortlets.push(newPortlet)\n }\n\n if (layoutMode === 'rows') {\n const baseRows = resolvedRows.length > 0\n ? resolvedRows.map(row => ({\n ...row,\n columns: row.columns.map(column => ({ ...column }))\n }))\n : normalizeRows(\n config.rows ?? convertPortletsToRows(config.portlets, gridSettings),\n updatedPortlets,\n gridSettings\n )\n\n const nextRows = isNewPortlet && newPortletId\n ? [\n ...baseRows,\n {\n id: createRowId(),\n h: Math.max(gridSettings.minH, 5),\n columns: equalizeRowColumns([newPortletId], gridSettings)\n }\n ]\n : baseRows\n\n await updateRowLayout(nextRows, true, updatedPortlets)\n } else {\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }\n\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n\n // Scroll to the new portlet after DOM update\n if (isNewPortlet && newPortletId) {\n setTimeout(() => {\n const scrollToPortlet = () => {\n // Try both the ref and DOM query selector\n let portletElement: HTMLElement | null = portletRefs.current[newPortletId!]\n if (!portletElement) {\n portletElement = document.querySelector(`[data-portlet-id=\"${newPortletId}\"]`)\n }\n \n if (portletElement) {\n portletElement.scrollIntoView({ \n behavior: 'smooth', \n block: 'center',\n inline: 'nearest'\n })\n return true\n }\n return false\n }\n \n // Try multiple times with increasing delays\n if (!scrollToPortlet()) {\n setTimeout(() => {\n if (!scrollToPortlet()) {\n setTimeout(() => {\n scrollToPortlet()\n }, 300)\n }\n }, 200)\n }\n }, 200)\n }\n }, [config, editingPortlet, gridSettings, layoutMode, onConfigChange, onSave, resolvedRows, updateRowLayout])\n\n // Handle deleting portlet\n const handleDeletePortlet = useCallback(async (portletId: string) => {\n if (!onConfigChange) return\n \n if (window.confirm('Are you sure you want to delete this portlet?')) {\n const updatedPortlets = config.portlets.filter(p => p.id !== portletId)\n\n if (layoutMode === 'rows') {\n const nextRows = resolvedRows\n .map(row => ({\n ...row,\n columns: row.columns.filter(column => column.portletId !== portletId)\n }))\n .filter(row => row.columns.length > 0)\n .map(row => ({\n ...row,\n columns: equalizeRowColumns(\n row.columns.map(column => column.portletId),\n gridSettings\n )\n }))\n\n await updateRowLayout(nextRows, true, updatedPortlets)\n } else {\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n \n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }\n }\n }, [config, gridSettings, layoutMode, onConfigChange, onSave, resolvedRows, updateRowLayout])\n\n // Handle duplicating portlet\n const handleDuplicatePortlet = useCallback(async (portletId: string) => {\n if (!onConfigChange) return\n \n const originalPortlet = config.portlets.find(p => p.id === portletId)\n if (!originalPortlet) return\n\n // Create duplicated portlet with new ID and updated title\n const duplicatedPortlet: PortletConfig = {\n ...originalPortlet,\n id: `portlet-${Date.now()}`,\n title: `${originalPortlet.title} Duplicated`,\n x: 0,\n y: 0\n }\n\n // Find the best position for the duplicated portlet\n const gridLayout = config.portlets.map(p => ({ i: p.id, x: p.x, y: p.y, w: p.w, h: p.h }))\n let maxY = 0\n gridLayout.forEach(item => {\n if (item.y + item.h > maxY) {\n maxY = item.y + item.h\n }\n })\n duplicatedPortlet.y = maxY\n\n const updatedPortlets = [...config.portlets, duplicatedPortlet]\n if (layoutMode === 'rows') {\n const baseRows = resolvedRows.map(row => ({\n ...row,\n columns: row.columns.map(column => ({ ...column }))\n }))\n const nextRows = [\n ...baseRows,\n {\n id: createRowId(),\n h: Math.max(gridSettings.minH, 5),\n columns: equalizeRowColumns([duplicatedPortlet.id], gridSettings)\n }\n ]\n await updateRowLayout(nextRows, true, updatedPortlets)\n } else {\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n \n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }\n\n // Scroll to the duplicated portlet after DOM update\n setTimeout(() => {\n const scrollToPortlet = () => {\n // Try both the ref and DOM query selector\n let portletElement: HTMLElement | null = portletRefs.current[duplicatedPortlet.id]\n if (!portletElement) {\n portletElement = document.querySelector(`[data-portlet-id=\"${duplicatedPortlet.id}\"]`)\n }\n \n if (portletElement) {\n portletElement.scrollIntoView({ \n behavior: 'smooth', \n block: 'center',\n inline: 'nearest'\n })\n return true\n }\n return false\n }\n \n // Try multiple times with increasing delays\n if (!scrollToPortlet()) {\n setTimeout(() => {\n if (!scrollToPortlet()) {\n setTimeout(() => {\n scrollToPortlet()\n }, 300)\n }\n }, 200)\n }\n }, 200)\n }, [config, gridSettings, layoutMode, onConfigChange, onSave, resolvedRows, updateRowLayout])\n\n // Handle color palette changes\n const handlePaletteChange = useCallback(async (paletteName: string) => {\n if (!onConfigChange) return\n\n const updatedConfig = {\n ...config,\n colorPalette: paletteName\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Handle opening filter config modal\n const handleOpenFilterConfig = useCallback((portlet: PortletConfig) => {\n setFilterConfigPortlet(portlet)\n setIsFilterConfigModalOpen(true)\n }, [])\n\n // Handle saving filter configuration\n const handleSaveFilterConfig = useCallback(async (mapping: string[]) => {\n if (!onConfigChange || !filterConfigPortlet) return\n\n const updatedPortlets = config.portlets.map(p => {\n if (p.id === filterConfigPortlet.id) {\n return {\n ...p,\n dashboardFilterMapping: mapping\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, filterConfigPortlet, onConfigChange, onSave])\n\n // Handle toggling filter for a portlet (used in filter selection mode)\n const handleToggleFilterForPortlet = useCallback(async (portletId: string, filterId: string) => {\n if (!onConfigChange) return\n\n const updatedPortlets = config.portlets.map(p => {\n if (p.id === portletId) {\n const currentMapping = p.dashboardFilterMapping || []\n const hasFilter = currentMapping.includes(filterId)\n\n return {\n ...p,\n dashboardFilterMapping: hasFilter\n ? currentMapping.filter(id => id !== filterId)\n : [...currentMapping, filterId]\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Handle filter selection (click on filter chip)\n const handleFilterSelect = useCallback((filterId: string) => {\n // Toggle selection: if already selected, deselect\n setSelectedFilterId(prev => prev === filterId ? null : filterId)\n }, [])\n\n // Handle select all - apply current filter to all portlets\n const handleSelectAllForFilter = useCallback(async (filterId: string) => {\n if (!onConfigChange) return\n\n const updatedPortlets = config.portlets.map(p => {\n const currentMapping = p.dashboardFilterMapping || []\n // Add the filter if it's not already in the mapping\n if (!currentMapping.includes(filterId)) {\n return {\n ...p,\n dashboardFilterMapping: [...currentMapping, filterId]\n }\n }\n return p\n })\n\n const updatedConfig = {\n ...config,\n portlets: updatedPortlets\n }\n\n onConfigChange(updatedConfig)\n\n // Auto-save if handler is provided\n if (onSave) {\n try {\n await onSave(updatedConfig)\n } catch (error) {\n console.error('Auto-save failed:', error)\n }\n }\n }, [config, onConfigChange, onSave])\n\n // Get the selected filter object\n const selectedFilter = selectedFilterId\n ? dashboardFilters?.find(f => f.id === selectedFilterId)\n : null\n\n if (!config.portlets || config.portlets.length === 0) {\n return (\n <>\n <div className=\"flex justify-center items-center min-h-[50vh]\">\n <div className=\"text-center\">\n <ChartBarIcon style={{ width: '64px', height: '64px', color: 'var(--dc-text-muted)', margin: '0 auto 16px auto' }} />\n <h3 className=\"text-lg font-semibold mb-2 text-dc-text\">No Portlets</h3>\n <p className=\"text-sm text-dc-text-secondary mb-4\">Add your first portlet to start visualizing your data</p>\n {editable && (\n <button\n onClick={handleAddPortlet}\n className=\"inline-flex items-center px-4 py-2 border border-dc-border bg-dc-surface rounded-md focus:outline-hidden focus:ring-2\"\n style={{\n color: 'var(--dc-primary)',\n borderColor: 'var(--dc-primary)'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-surface-hover)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-surface)'}\n >\n <AddIcon className=\"w-5 h-5 mr-2\" />\n Add Portlet\n </button>\n )}\n </div>\n </div>\n \n {/* Portlet Modal - conditionally render new or old modal based on feature flag */}\n {features.useAnalysisBuilder ? (\n <PortletAnalysisModal\n isOpen={isPortletModalOpen}\n onClose={() => {\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n }}\n onSave={handlePortletSave}\n portlet={editingPortlet}\n title={editingPortlet ? 'Edit Portlet' : 'Add New Portlet'}\n submitText={editingPortlet ? 'Update Portlet' : 'Add Portlet'}\n colorPalette={colorPalette}\n />\n ) : (\n <PortletEditModal\n isOpen={isPortletModalOpen}\n onClose={() => {\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n }}\n onSave={handlePortletSave}\n portlet={editingPortlet}\n title={editingPortlet ? 'Edit Portlet' : 'Add New Portlet'}\n submitText={editingPortlet ? 'Update Portlet' : 'Add Portlet'}\n colorPalette={colorPalette}\n />\n )}\n </>\n )\n }\n\n // Generate grid layout from portlets - only use for lg (desktop) breakpoint\n // Let react-grid-layout handle responsive adjustments automatically\n const baseLayout: LayoutItem[] = config.portlets.map(portlet => ({\n i: portlet.id,\n x: portlet.x,\n y: portlet.y,\n w: portlet.w,\n h: portlet.h,\n minW: gridSettings.minW,\n minH: gridSettings.minH, // 2 rows at 80px = 160px minimum\n // Only enable drag/resize in edit mode\n isDraggable: canEdit,\n isResizable: canEdit,\n ...(canEdit ? { resizeHandles: ['s', 'w', 'e', 'n', 'se', 'sw', 'ne', 'nw'] as const } : {})\n }))\n\n const renderPortletCard = (\n portlet: PortletConfig,\n containerProps?: HTMLAttributes<HTMLDivElement>,\n headerProps?: HTMLAttributes<HTMLDivElement>\n ) => (\n <DashboardPortletCard\n portlet={portlet}\n editable={editable}\n isEditMode={isEditMode}\n selectedFilterId={selectedFilterId}\n debugData={debugData[portlet.id]}\n dashboardFilters={dashboardFilters}\n configEagerLoad={config.eagerLoad}\n loadingComponent={loadingComponent}\n colorPalette={colorPalette}\n containerProps={containerProps}\n headerProps={headerProps}\n onToggleFilter={handleToggleFilterForPortlet}\n onRefresh={handlePortletRefresh}\n onDuplicate={handleDuplicatePortlet}\n onEdit={handleEditPortlet}\n onDelete={handleDeletePortlet}\n onOpenFilterConfig={handleOpenFilterConfig}\n onDebugDataReady={(portletId, data) => {\n setDebugData(prev => ({\n ...prev,\n [portletId]: data\n }))\n }}\n setPortletRef={(portletId, element) => {\n portletRefs.current[portletId] = element\n }}\n setPortletComponentRef={(portletId, element) => {\n portletComponentRefs.current[portletId] = element\n }}\n icons={{ RefreshIcon, EditIcon, DeleteIcon, CopyIcon, FilterIcon }}\n />\n )\n\n // Render the portlet grid content (shared between desktop and scaled modes)\n const renderGridContent = () => (\n <ReactGridLayout\n className=\"layout\"\n layout={baseLayout}\n onLayoutChange={handleLayoutChange}\n onDragStop={handleDragStop}\n onResizeStop={handleResizeStop}\n width={gridWidth}\n gridConfig={{\n cols: gridSettings.cols,\n rowHeight: gridSettings.rowHeight,\n margin: [16, 16],\n containerPadding: [0, 0]\n }}\n dragConfig={{\n enabled: canEdit,\n handle: '.portlet-drag-handle'\n }}\n resizeConfig={{\n enabled: canEdit,\n handles: ['s', 'w', 'e', 'n', 'se', 'sw', 'ne', 'nw'],\n // Invisible but functional resize handles\n handleComponent: (axis, ref) => (\n <div\n ref={ref as Ref<HTMLDivElement>}\n className={`react-resizable-handle react-resizable-handle-${axis}`}\n style={{ opacity: 0 }}\n />\n )\n }}\n compactor={verticalCompactor}\n >\n {config.portlets.map(portlet => (\n <div key={portlet.id}>\n {renderPortletCard(portlet)}\n </div>\n ))}\n </ReactGridLayout>\n )\n\n const renderRowContent = () => (\n <RowManagedLayout\n rows={resolvedRows}\n portlets={config.portlets}\n gridSettings={gridSettings}\n gridWidth={gridWidth}\n canEdit={canEdit}\n isDragging={isDraggingPortlet}\n onRowResize={startRowResize}\n onColumnResize={startColumnResize}\n onPortletDragStart={handlePortletDragStart}\n onPortletDragEnd={handlePortletDragEnd}\n onRowDrop={handleRowDrop}\n onNewRowDrop={handleNewRowDrop}\n renderPortlet={renderPortletCard}\n />\n )\n\n const renderActiveLayout = layoutMode === 'rows' ? renderRowContent() : renderGridContent()\n const editModeHint = 'Drag • Resize • Auto-save'\n\n return (\n <ScrollContainerProvider value={scrollContainer}>\n <div ref={combinedContainerRef} className=\"dashboard-grid-container w-full\" style={{ maxWidth: '100%', overflow: 'hidden' }}>\n {editable && (\n <div\n className={`mb-4 flex justify-between items-center sticky top-0 z-10 px-4 py-4 bg-dc-surface-tertiary border border-dc-border rounded-lg transition-all duration-200 ${\n isScrolled ? 'border-b' : ''\n }`}\n style={{\n boxShadow: isScrolled ? 'var(--dc-shadow-md)' : 'var(--dc-shadow-sm)'\n }}\n >\n <div className=\"flex items-center gap-4\">\n <button\n onClick={() => isResponsiveEditable && setIsEditMode(!isEditMode)}\n disabled={!isResponsiveEditable}\n className={`inline-flex items-center px-4 py-2 text-sm font-medium rounded-md transition-colors focus:outline-hidden focus:ring-2 focus:ring-offset-2 ${\n !isResponsiveEditable\n ? 'opacity-50 cursor-not-allowed bg-dc-surface-secondary border border-dc-border'\n : isEditMode\n ? 'bg-dc-surface-secondary border border-dc-border hover:bg-dc-surface-hover'\n : 'bg-dc-surface border border-dc-border hover:bg-dc-surface-hover'\n }`}\n style={{\n color: !isResponsiveEditable ? 'var(--dc-text-muted)' : 'var(--dc-primary)',\n borderColor: !isResponsiveEditable ? 'var(--dc-border)' : isEditMode ? 'var(--dc-border)' : 'var(--dc-primary)'\n }}\n >\n <EditIcon className=\"w-4 h-4 mr-1.5\" />\n {isEditMode ? 'Finished Editing' : 'Edit'}\n </button>\n {isEditMode && allowedModes.length > 1 && (\n <div className=\"inline-flex rounded-md border border-dc-border overflow-hidden whitespace-nowrap\">\n <button\n onClick={() => handleLayoutModeChange('grid')}\n disabled={!canChangeLayoutMode}\n className={`inline-flex items-center gap-2 whitespace-nowrap px-3 py-1.5 text-sm font-medium transition-colors ${\n layoutMode === 'grid'\n ? 'bg-dc-surface-secondary text-dc-text shadow-inner'\n : 'bg-dc-surface text-dc-text-secondary hover:bg-dc-surface-hover'\n } ${!canChangeLayoutMode ? 'cursor-not-allowed opacity-50' : ''}`}\n >\n <GridIcon className=\"w-4 h-4 shrink-0\" />\n Grid\n </button>\n <button\n onClick={() => handleLayoutModeChange('rows')}\n disabled={!canChangeLayoutMode}\n className={`inline-flex items-center gap-2 whitespace-nowrap px-3 py-1.5 text-sm font-medium transition-colors ${\n layoutMode === 'rows'\n ? 'bg-dc-surface-secondary text-dc-text shadow-inner'\n : 'bg-dc-surface text-dc-text-secondary hover:bg-dc-surface-hover'\n } ${!canChangeLayoutMode ? 'cursor-not-allowed opacity-50' : ''}`}\n >\n <RowsIcon className=\"w-4 h-4 shrink-0\" />\n Rows\n </button>\n </div>\n )}\n {!isResponsiveEditable && (\n <div className=\"flex items-center gap-2 text-sm text-dc-text-secondary\">\n <DesktopIcon className=\"w-4 h-4\" />\n <span>Desktop view required for editing</span>\n </div>\n )}\n {isEditMode && isResponsiveEditable && (\n <p className=\"hidden md:block text-sm text-dc-text-secondary\">\n {editModeHint}\n </p>\n )}\n </div>\n\n {/* Color Palette Selector - Only show in edit mode */}\n <div className=\"flex items-center gap-3\">\n {isEditMode && (\n <ColorPaletteSelector\n currentPalette={config.colorPalette}\n onPaletteChange={handlePaletteChange}\n className=\"shrink-0\"\n />\n )}\n\n <button\n onClick={handleAddPortlet}\n disabled={!isEditMode}\n className={`inline-flex items-center px-4 py-2 text-sm font-medium border rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 ${\n isEditMode\n ? 'border-dc-border bg-dc-surface hover:bg-dc-surface-hover'\n : 'border-dc-border bg-dc-surface-secondary cursor-not-allowed'\n }`}\n style={{\n color: isEditMode ? 'var(--dc-primary)' : 'var(--dc-text-muted)',\n borderColor: isEditMode ? 'var(--dc-primary)' : 'var(--dc-border)'\n }}\n >\n <AddIcon className=\"w-5 h-5 mr-2\" />\n Add Portlet\n </button>\n </div>\n </div>\n )}\n\n {/* Dashboard Filter Panel - Always visible below toolbar */}\n <DashboardFilterPanel\n dashboardFilters={dashboardFilters || []}\n editable={editable}\n schema={schema || null}\n dashboardConfig={config}\n onDashboardFiltersChange={onDashboardFiltersChange || (() => {})}\n onSaveFilters={onSave ? async (filters: DashboardFilter[]) => {\n const updatedConfig = {\n ...config,\n filters\n }\n await onSave(updatedConfig)\n } : undefined}\n selectedFilterId={selectedFilterId}\n onFilterSelect={handleFilterSelect}\n isEditMode={isEditMode}\n />\n\n {/* Filter Selection Mode Banner */}\n {selectedFilterId && selectedFilter && (\n <div\n className=\"mb-4 px-4 py-3 rounded-md border-2 transition-all\"\n style={{\n backgroundColor: 'var(--dc-primary)',\n borderColor: 'var(--dc-primary)',\n color: 'white'\n }}\n >\n <div className=\"flex items-center justify-between flex-wrap gap-2\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <FilterIcon className=\"w-5 h-5 shrink-0\" />\n <span className=\"font-medium\">\n Filter Selection Mode - Click portlets to toggle '{selectedFilter.label}'\n </span>\n <span className=\"text-sm opacity-90 hidden sm:inline\">• Press ESC to exit</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => handleSelectAllForFilter(selectedFilterId)}\n className=\"px-3 py-1 rounded-md transition-colors text-sm font-medium\"\n style={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: 'white'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'}\n >\n Select All\n </button>\n <button\n onClick={() => setSelectedFilterId(null)}\n className=\"px-3 py-1 rounded-md transition-colors text-sm font-medium\"\n style={{\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n color: 'white'\n }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'}\n >\n Exit\n </button>\n </div>\n </div>\n </div>\n )}\n \n {/* Render layout based on display mode */}\n {displayMode === 'mobile' ? (\n <MobileStackedLayout\n config={config}\n colorPalette={colorPalette}\n dashboardFilters={dashboardFilters}\n onPortletRefresh={handlePortletRefresh}\n />\n ) : displayMode === 'scaled' ? (\n <ScaledGridWrapper scaleFactor={scaleFactor} designWidth={designWidth}>\n {renderActiveLayout}\n </ScaledGridWrapper>\n ) : (\n renderActiveLayout\n )}\n \n {/* Portlet Modal - conditionally render new or old modal based on feature flag */}\n {features.useAnalysisBuilder ? (\n <PortletAnalysisModal\n isOpen={isPortletModalOpen}\n onClose={() => {\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n }}\n onSave={handlePortletSave}\n portlet={editingPortlet}\n title={editingPortlet ? 'Edit Portlet' : 'Add New Portlet'}\n submitText={editingPortlet ? 'Update Portlet' : 'Add Portlet'}\n colorPalette={colorPalette}\n />\n ) : (\n <PortletEditModal\n isOpen={isPortletModalOpen}\n onClose={() => {\n setIsPortletModalOpen(false)\n setEditingPortlet(null)\n }}\n onSave={handlePortletSave}\n portlet={editingPortlet}\n title={editingPortlet ? 'Edit Portlet' : 'Add New Portlet'}\n submitText={editingPortlet ? 'Update Portlet' : 'Add Portlet'}\n colorPalette={colorPalette}\n />\n )}\n\n {/* Filter Configuration Modal */}\n <PortletFilterConfigModal\n isOpen={isFilterConfigModalOpen}\n onClose={() => {\n setIsFilterConfigModalOpen(false)\n setFilterConfigPortlet(null)\n }}\n dashboardFilters={dashboardFilters || []}\n currentMapping={filterConfigPortlet?.dashboardFilterMapping || []}\n onSave={handleSaveFilterConfig}\n portletTitle={filterConfigPortlet?.title || ''}\n />\n </div>\n </ScrollContainerProvider>\n )\n}\n","/**\n * Analytics Dashboard Component\n * Main dashboard container that uses CubeProvider context\n * Minimal dependencies, designed to be embedded in existing apps\n */\n\nimport { useCallback, useRef, useMemo } from 'react'\nimport DashboardGrid from './DashboardGrid'\nimport { useCubeContext } from '../providers/CubeProvider'\nimport { getColorPalette } from '../utils/colorPalettes'\nimport type { AnalyticsDashboardProps, DashboardConfig, DashboardFilter } from '../types'\n\nexport default function AnalyticsDashboard({\n config,\n editable = false,\n dashboardFilters: propDashboardFilters,\n loadingComponent,\n onConfigChange,\n onSave,\n onDirtyStateChange\n}: AnalyticsDashboardProps) {\n // Get cube metadata for filter building\n const { meta, dashboardModes } = useCubeContext()\n\n // Track initial config to prevent saves during initial load\n const initialConfigRef = useRef(config)\n const hasConfigChangedFromInitial = useRef(false)\n\n // Merge programmatic filters (props) with config filters by ID\n // Config provides structure/metadata, props provide value overrides\n const mergedDashboardFilters = useMemo<DashboardFilter[]>(() => {\n const configFilters = config.filters || []\n const propFilters = propDashboardFilters || []\n\n // If no prop filters, use config filters as-is\n if (propFilters.length === 0) {\n return configFilters\n }\n\n // If no config filters, use prop filters as-is\n if (configFilters.length === 0) {\n return propFilters\n }\n\n // Merge by ID: config filters provide structure, prop filters provide values\n const mergedFilters: DashboardFilter[] = configFilters.map(configFilter => {\n // Find matching prop filter by ID\n const propFilter = propFilters.find(pf => pf.id === configFilter.id)\n\n if (propFilter) {\n // Merge: preserve config metadata, use prop filter values\n return {\n ...configFilter, // Preserve id, label, isUniversalTime from config\n filter: propFilter.filter // Use filter values from prop override\n }\n }\n\n // No override for this filter, use config as-is\n return configFilter\n })\n\n // Add any prop filters that don't exist in config (new filters)\n const configIds = new Set(configFilters.map(cf => cf.id))\n const newFilters = propFilters.filter(pf => !configIds.has(pf.id))\n\n return [...mergedFilters, ...newFilters]\n }, [config.filters, propDashboardFilters])\n\n // Enhanced save handler that tracks dirty state and prevents saves during initial load\n const handleSaveWithDirtyTracking = useCallback(async (config: DashboardConfig) => {\n // Don't save if this config hasn't actually changed from the initial load\n if (!hasConfigChangedFromInitial.current) {\n return // Prevent saves during initial load/responsive changes\n }\n \n if (onDirtyStateChange) {\n onDirtyStateChange(true) // Mark as dirty when save starts\n }\n \n try {\n if (onSave) {\n await onSave(config)\n }\n \n // Update our reference point after successful save\n initialConfigRef.current = config\n \n // Mark as clean after successful save\n if (onDirtyStateChange) {\n onDirtyStateChange(false)\n }\n } catch (error) {\n // Keep dirty state if save failed\n console.error('Save failed:', error)\n throw error\n }\n }, [onSave, onDirtyStateChange])\n\n // Enhanced config change handler that marks as dirty (only after initial load)\n const handleConfigChangeWithDirtyTracking = useCallback((config: DashboardConfig) => {\n if (onConfigChange) {\n onConfigChange(config)\n }\n \n // Check if this is a meaningful change from the initial config\n const configString = JSON.stringify(config)\n const initialConfigString = JSON.stringify(initialConfigRef.current)\n \n if (configString !== initialConfigString) {\n hasConfigChangedFromInitial.current = true\n \n if (onDirtyStateChange) {\n onDirtyStateChange(true)\n }\n }\n }, [onConfigChange, onDirtyStateChange])\n\n // Handle dashboard filter changes\n const handleDashboardFiltersChange = useCallback((filters: DashboardFilter[]) => {\n // Only update config if we're not using programmatic filters\n if (!propDashboardFilters || propDashboardFilters.length === 0) {\n const updatedConfig = {\n ...config,\n filters\n }\n handleConfigChangeWithDirtyTracking(updatedConfig)\n } else {\n console.warn('Dashboard filters are controlled via props - config changes ignored')\n }\n }, [config, propDashboardFilters, handleConfigChangeWithDirtyTracking])\n\n // Resolve complete palette object based on config\n const colorPalette = useMemo(() => {\n const paletteName = config.colorPalette\n return getColorPalette(paletteName)\n }, [config.colorPalette])\n\n return (\n <div className=\"w-full\">\n {/* Dashboard Grid (now includes filter panel) */}\n <DashboardGrid\n config={config}\n editable={editable}\n dashboardFilters={mergedDashboardFilters}\n loadingComponent={loadingComponent}\n onConfigChange={handleConfigChangeWithDirtyTracking}\n onSave={handleSaveWithDirtyTracking}\n colorPalette={colorPalette}\n schema={meta}\n dashboardModes={dashboardModes}\n onDashboardFiltersChange={handleDashboardFiltersChange}\n />\n </div>\n )\n}\n","/**\n * Portlet Container Component\n * Simple wrapper for individual portlets\n */\n\nimport { useState } from 'react'\nimport AnalyticsPortlet from './AnalyticsPortlet'\nimport DebugModal from './DebugModal'\nimport type { PortletConfig } from '../types'\n\ninterface PortletContainerProps {\n portlet: PortletConfig\n editable?: boolean\n onEdit?: (portlet: PortletConfig) => void\n onDelete?: (portletId: string) => void\n onRefresh?: (portletId: string) => void\n}\n\nexport default function PortletContainer({ \n portlet, \n editable = false,\n onEdit,\n onDelete,\n onRefresh\n}: PortletContainerProps) {\n const [debugData, setDebugData] = useState<{\n chartConfig: any\n displayConfig: any\n queryObject: any\n data: any[]\n chartType: string\n } | null>(null)\n\n return (\n <div className=\"bg-dc-surface border border-dc-border rounded-lg flex flex-col h-full\" style={{ boxShadow: 'var(--dc-shadow-sm)' }}>\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg px-3 py-2 md:px-6 md:py-3\">\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <h3 className=\"font-semibold text-sm truncate text-dc-text\">{portlet.title}</h3>\n {/* Debug button - right next to title */}\n {debugData && (\n <DebugModal\n chartConfig={debugData.chartConfig}\n displayConfig={debugData.displayConfig}\n queryObject={debugData.queryObject}\n data={debugData.data}\n chartType={debugData.chartType}\n />\n )}\n </div>\n\n <div className=\"flex items-center gap-2 ml-4\">\n\n {editable && (\n <>\n <button\n onClick={() => onRefresh?.(portlet.id)}\n className=\"p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary\"\n title=\"Refresh\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\" />\n </svg>\n </button>\n <button\n onClick={() => onEdit?.(portlet)}\n className=\"p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary\"\n title=\"Edit\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\" />\n </svg>\n </button>\n <button\n onClick={() => onDelete?.(portlet.id)}\n className=\"p-1.5 rounded-sm text-dc-danger\"\n style={{ backgroundColor: 'transparent' }}\n onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--dc-danger-bg)'}\n onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'transparent'}\n title=\"Delete\"\n >\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\" />\n </svg>\n </button>\n </>\n )}\n </div>\n </div>\n\n {/* Content */}\n <div className=\"px-2 py-3 md:px-4 md:pt-6 md:pb-4 flex-1 min-h-0\">\n <AnalyticsPortlet\n query={portlet.query}\n chartType={portlet.chartType}\n chartConfig={portlet.chartConfig}\n displayConfig={portlet.displayConfig}\n title={portlet.title}\n height=\"100%\"\n onDebugDataReady={(data) => {\n setDebugData(data)\n }}\n />\n </div>\n </div>\n )\n}","import React, { useState, useEffect } from 'react'\nimport Modal from './Modal'\n\ninterface DashboardEditModalProps {\n isOpen: boolean\n onClose: () => void\n onSave: (data: { name: string; description?: string }) => Promise<void> | void\n title: string\n submitText: string\n initialName?: string\n initialDescription?: string\n}\n\nexport default function DashboardEditModal({\n isOpen,\n onClose,\n onSave,\n title,\n submitText,\n initialName = '',\n initialDescription = ''\n}: DashboardEditModalProps) {\n const [name, setName] = useState('')\n const [description, setDescription] = useState('')\n const [isSaving, setIsSaving] = useState(false)\n\n // Initialize form values when modal opens\n useEffect(() => {\n if (isOpen) {\n setName(initialName)\n setDescription(initialDescription)\n }\n }, [isOpen, initialName, initialDescription])\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n \n if (!name.trim()) {\n return\n }\n\n setIsSaving(true)\n \n try {\n await onSave({\n name: name.trim(),\n description: description.trim() || undefined\n })\n handleClose()\n } catch {\n // Failed to save dashboard\n // Don't close modal on error so user can retry\n } finally {\n setIsSaving(false)\n }\n }\n\n const handleClose = () => {\n setName('')\n setDescription('')\n setIsSaving(false)\n onClose()\n }\n\n const footer = (\n <>\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={isSaving}\n className=\"px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n form=\"dashboard-form\"\n disabled={isSaving || !name.trim()}\n className=\"px-4 py-2 text-sm font-medium text-white bg-dc-primary border border-transparent rounded-md hover:bg-dc-primary-hover disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isSaving ? 'Saving...' : submitText}\n </button>\n </>\n )\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n size=\"fullscreen-mobile\"\n footer={footer}\n >\n <form id=\"dashboard-form\" onSubmit={handleSubmit} className=\"space-y-4 w-full\">\n <div>\n <label htmlFor=\"dashboard-name\" className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Dashboard Name\n </label>\n <input\n type=\"text\"\n id=\"dashboard-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter dashboard name...\"\n required\n autoFocus\n />\n </div>\n\n <div>\n <label htmlFor=\"dashboard-description\" className=\"block text-sm font-medium text-dc-text-secondary mb-1\">\n Description (optional)\n </label>\n <textarea\n id=\"dashboard-description\"\n rows={3}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n className=\"w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary\"\n placeholder=\"Enter description...\"\n />\n </div>\n </form>\n </Modal>\n )\n}"],"names":["observerMap","RootIds","rootId","unsupportedValue","getRootId","root","optionsToId","options","key","createObserver","id","instance","elements","thresholds","observer","entries","entry","_a2","inView","threshold","callback","observe","element","fallbackInView","bounds","callbacks","useInView","delay","trackVisibility","rootMargin","triggerOnce","skip","initialInView","onChange","ref","setRef","React2","lastInViewRef","state","setState","unobserve","previousInView","entryTarget","previousEntryTarget","result","RefreshIcon","getIcon","ChartErrorBoundary","Component","props","error","errorInfo","jsxs","jsx","shouldIncludeFilter","filter","simpleFilter","f","getApplicableDashboardFilters","dashboardFilters","filterMapping","df","convertToServerFormat","groupFilter","convertedFilters","mergeDashboardAndPortletFilters","portletFilters","extractDashboardFields","dashboardConfig","measures","dimensions","timeDimensions","portlet","query","measure","dimension","td","extractFieldsFromFilters","field","e","filters","fields","getDateRangeFromFilter","applyUniversalTimeFilters","portletTimeDimensions","universalTimeFilters","dateRange","AnalyticsPortlet","forwardRef","chartType","chartConfig","displayConfig","dashboardFilterMapping","eagerLoad","_isVisible","height","_title","colorPalette","loadingComponent","onDebugDataReady","refreshCounter","setRefreshCounter","useState","onDebugDataReadyRef","useRef","scrollContainer","useScrollContainer","inViewRef","isVisible","useEffect","chartTypeConfig","useChartConfig","shouldSkipQuery","queryObject","useMemo","parsed","regularFilters","applicableFilters","mergedFilters","mergedTimeDimensions","shouldSkip","resultSet","isLoading","useCubeQuery","useImperativeHandle","prev","data","getData","hasMandatoryFields","zone","LoadingIndicator","chartHeight","isValidChartType","LazyChart","DebugModal","isOpen","setIsOpen","handleKeyDown","event","timer","DashboardPortletCard","editable","isEditMode","selectedFilterId","debugData","configEagerLoad","containerProps","headerProps","onToggleFilter","onRefresh","onDuplicate","onEdit","onDelete","onOpenFilterConfig","setPortletRef","setPortletComponentRef","icons","hasSelectedFilter","isInSelectionMode","mergedContainerClassName","mergedHeaderClassName","containerOnClick","_containerClassName","containerStyle","restContainerProps","headerOnClick","_headerClassName","headerStyle","restHeaderProps","el","Fragment","COLUMN_GAP","RowManagedLayout","rows","portlets","gridSettings","gridWidth","canEdit","isDragging","onRowResize","onColumnResize","onPortletDragStart","onPortletDragEnd","onRowDrop","onNewRowDrop","renderPortlet","portletMap","activeDropKey","setActiveDropKey","setDropActive","isDragActive","topDropActive","bottomDropActive","row","rowIndex","rowHeight","safeGridWidth","paddingLeft","paddingRight","unitWidth","column","columnIndex","width","Modal","onClose","title","size","closeOnBackdropClick","closeOnEscape","showCloseButton","children","footer","noPadding","handleEscapeKey","useCallback","getMeasureIcon","measureType","className","IconComponent","getMeasureTypeIcon","CubeRelationshipDiagram","lazy","mod","CubeMetaExplorer","schema","schemaStatus","schemaError","selectedFields","onFieldSelect","onFieldDeselect","onRetrySchema","onOpenSettings","onViewTypeChange","isExpanded","ChevronDownIcon","ChevronRightIcon","WarningIcon","SettingsIcon","MeasureIcon","DimensionIcon","TimeDimensionIcon","SegmentIcon","MenuIcon","features","useCubeContext","showSchemaDiagram","expandedCubes","setExpandedCubes","expandedSections","setExpandedSections","searchTerm","setSearchTerm","viewType","setViewType","preSearchExpandedCubes","setPreSearchExpandedCubes","preSearchExpandedSections","setPreSearchExpandedSections","React","newExpandedCubes","newExpandedSections","cube","cubeHasMatches","d","combinedCubes","combinedSections","isCorsError","toggleCubeExpansion","cubeName","newExpanded","newPreSearchExpanded","toggleSectionExpansion","sectionKey","handleFieldClick","fieldType","filterFields","measureMatches","dimensionMatches","FieldItem","icon","isSelected","getSelectedStyles","getIconColor","getCheckmarkColor","SectionHeader","count","getSectionType","NoMatchesMessage","Suspense","fieldName","qbFieldType","c","fullFieldName","index","arr","filteredCubes","regularDimensions","timeDimension","CubeMetaExplorer$1","memo","FILTER_OPERATORS","DATE_RANGE_OPTIONS","TIME_GRANULARITIES","CloseIcon","FilterValueSelector","operator","values","onValuesChange","operatorMeta","searchText","setSearchText","hasLoadedInitial","setHasLoadedInitial","dropdownRef","lastSearchedTerm","debouncedSearchText","useDebounce","isDimension","dim","isTimeDimension","shouldFetchValues","shouldShowComboBox","distinctValues","valuesLoading","valuesError","searchValues","useFilterValues","handleClickOutside","handleDropdownToggle","newIsOpen","handleSearchChange","newSearchText","handleValueSelect","value","handleValueRemove","valueToRemove","v","handleDirectInput","numValue","handleDateInput","currentValues","handleDateRangeEndInput","handleBetweenStartInput","newValues","handleBetweenEndInput","hasQueryContent","getSelectedFieldsCount","cleanQuery","cleanedQuery","cleanQueryForServer","transformFiltersForServer","createEmptyQuery","isSimpleFilter","isGroupFilter","isAndFilter","isOrFilter","getFilterableFields","allFields","a","b","getAllFilterableFields","getOrganizedFilterFields","getAvailableOperators","operators","meta","getFieldType","m","countFilters","countFilter","createSimpleFilter","member","createAndFilter","createOrFilter","cleanupFilters","_query","transformFilter","transformedSubFilters","convertDateRangeTypeToValue","rangeType","number","typeMap","unit","unitSingular","requiresNumberInput","formatDateForCube","date","getTimeDimensionsWithDateRanges","dateRanges","hasTimeDimensions","transformQueryForUI","transformed","transformFiltersFromServer","getFieldTitle","getSortDirection","order","getSortTooltip","direction","getNextSortDirection","current","FilterIcon","SearchIcon","FilterItem","onFilterChange","onFilterRemove","hideFieldSelector","hideOperatorSelector","hideRemoveButton","isFieldDropdownOpen","setIsFieldDropdownOpen","isOperatorDropdownOpen","setIsOperatorDropdownOpen","isDateRangeDropdownOpen","setIsDateRangeDropdownOpen","fieldSearchTerm","setFieldSearchTerm","containerRef","searchInputRef","setRangeType","customDates","setCustomDates","numberValue","setNumberValue","handleFieldDropdownToggle","newOpen","handleOperatorDropdownToggle","queryFields","selectedField","availableOperators","shouldShowDateRangeSelector","flexibleRangeMatch","num","found","option","filterFieldsBySearch","filteredQueryFields","filteredAllFields","getFieldTypeIcon","getFieldTypeBadge","handleFieldChange","newFieldType","defaultOperator","handleOperatorChange","handleValuesChange","handleDateRangeChange","handleRangeTypeChange","newRangeType","cubeRangeValue","handleCustomDateChange","newCustomDates","handleNumberChange","selectedRangeLabel","opt","op","AddIcon","FilterGroup","group","onGroupChange","onGroupChangeWithUnwrap","onGroupRemove","depth","showAddMenu","setShowAddMenu","isAndGroup","groupType","indentClass","borderColor","bgColor","textColor","handleGroupTypeToggle","newGroup","handleAddSimpleFilter","defaultField","newFilter","newFilters","handleAddAndGroup","handleAddOrGroup","handleFilterChange","filterIndex","handleFilterRemove","_","i","updatedGroup","handleNestedGroupChange","handleNestedGroupRemove","FilterBuilder","onFiltersChange","totalFilterCount","allFilterableFields","hasFilterableFields","andGroup","existingAndGroup","updatedAndGroup","existingOrGroup","updatedOrGroup","handleGroupChange","handleGroupChangeWithUnwrap","handleGroupRemove","handleClearAllFilters","CalendarIcon","DateRangeSelector","availableTimeDimensions","currentDateRange","onDateRangeChange","onTimeDimensionChange","onRemove","getCurrentRangeType","getCurrentDates","today","getCurrentNumber","isRangeDropdownOpen","setIsRangeDropdownOpen","isTimeDimensionDropdownOpen","setIsTimeDimensionDropdownOpen","handleTimeDimensionDropdownToggle","handleRangeDropdownToggle","handleTimeDimensionChange","newTimeDimension","DateRangeFilter","onDateRangeRemove","currentDateRanges","dateRangeCount","handleAddDateRange","firstAvailable","handleClearAllDateRanges","allTimeDimensions","t","oldTd","newTd","formatReason","reason","getReasonBadgeClasses","QueryAnalysisPanel","analysis","InfoIcon","ArrowRightIcon","TableIcon","LinkIcon","SuccessIcon","ErrorIcon","jp","idx","step","stepIdx","jc","pa","jk","w","QueryPanelHeader","hasContent","selectedCount","copyButtonState","shareButtonState","canShare","onShareClick","onClearQuery","onSettingsClick","onAIAssistantClick","onSchemaClick","showSettings","handleCopyQuery","CopyIcon","ShareIcon","CheckIcon","DeleteIcon","SparklesIcon","RemovableChip","hasFilters","sortDirection","sortTooltip","onAddFilter","onToggleSort","onRemoveField","ChevronUpIcon","ChevronUpDownIcon","getChipClasses","getSortIcon","getSortButtonClasses","baseClasses","filterColorClasses","TimeDimensionChip","hasDateRange","onGranularityChange","granularity","QueryPanel","validationStatus","validationError","validationSql","validationAnalysis","onExecute","onTimeDimensionGranularityChange","onOrderChange","isViewingShared","showJsonPreview","setShowJsonPreview","showSqlPreview","setShowSqlPreview","showAnalysisPreview","setShowAnalysisPreview","setCopyButtonState","queryRef","RunIcon","textArea","hasFiltersApplied","currentFilters","hasFieldInFilters","handleAddFilterFromField","handleToggleSort","next","headerIcons","newJsonState","newSqlState","newAnalysisState","QueryPanel$1","chartConfigRegistry","barChartConfig","lineChartConfig","areaChartConfig","pieChartConfig","scatterChartConfig","bubbleChartConfig","radarChartConfig","radialBarChartConfig","treemapChartConfig","dataTableConfig","activityGridChartConfig","kpiNumberConfig","kpiDeltaConfig","kpiTextConfig","markdownConfig","chartTypeLabels","ChartTypeSelector","selectedType","onTypeChange","compact","availability","chartTypes","labelA","labelB","SelectedIcon","selectedLabel","type","config","label","description","useCase","chartAvailability","isAvailable","unavailableReason","tooltipText","AxisDropZone","onDrop","onDragStart","onDragEnd","onDragOver","getFieldStyling","onReorder","draggedItem","mandatory","maxItems","emptyText","dragOverIndex","setDragOverIndex","isDraggedOver","setIsDraggedOver","isReorderDraggedOver","setIsReorderDraggedOver","getCanAcceptMore","effectiveCount","getIsFull","canAcceptMore","isFull","handleGlobalDragEnd","handleReorderDragOver","targetIndex","handleReorderDragLeave","handleReorderDrop","rect","isLeavingContainer","relatedTarget","isRelatedTargetOutside","FieldIcon","hoverClasses","isDragOver","isBeingDragged","ChartConfigPanel","availableFields","onChartConfigChange","onDisplayConfigChange","setDraggedItem","getChartConfig","getFieldsForDropZone","allAvailableFields","hasChanges","newConfig","dropZone","currentFields","validFields","handleDragStart","fromAxis","fromIndex","handleDragOver","handleDragEnd","handleDrop","toAxis","fromValue","filteredValue","toValue","dz","handleRemoveFromAxis","handleReorder","toIndex","axisKey","newArray","movedItem","unassignedFields","assignedFields","color","ResultsPanel","executionStatus","executionResults","executionError","resultsStale","displayLimit","onDisplayLimitChange","totalRowCount","totalRowCountStatus","onChartTypeChange","activeViewProp","onActiveViewChange","TimeIcon","AdjustmentsIcon","localActiveView","setLocalActiveView","activeView","setActiveView","showChartConfig","setShowChartConfig","LoadingState","ErrorState","OverlaySpinner","OverlayError","EmptyState","renderChart","SetupPanel","onToggle","onConfigChange","onReset","localConfig","setLocalConfig","handleApply","handleReset","defaultConfig","handleInputChange","isUsingDefaults","DEFAULT_SYSTEM_PROMPT_TEMPLATE","AI_STORAGE_KEY","DEFAULT_AI_CONFIG","sendGeminiMessage","apiKey","userPrompt","endpoint","requestBody","headers","response","errorMessage","errorData","errorText","loadAIConfig","saved","extractTextFromResponse","AIAssistantModal","onQueryLoad","aiEndpoint","handleQuerySubmit","responseText","validateResponse","handleValidate","handleUseQuery","handleClose","LZString","keyStrBase64","keyStrUriSafe","baseReverseDic","getBaseValue","alphabet","character","input","res","compressed","uncompressed","buf","TotalLen","current_value","bitsPerChar","getCharFromInt","context_dictionary","context_dictionaryToCreate","context_c","context_wc","context_w","context_enlargeIn","context_dictSize","context_numBits","context_data","context_data_val","context_data_position","ii","length","resetValue","getNextValue","dictionary","enlargeIn","dictSize","numBits","bits","resb","maxpower","power","module","MAX_HASH_LENGTH","SHARE_PREFIX","compressAndEncode","json","compressToEncodedURIComponent","decodeAndDecompress","encoded","decompressFromEncodedURIComponent","compressWithFallback","fullEncoded","queryOnlyState","queryOnlyEncoded","parseShareHash","hash","clearShareHash","url","getMaxHashLength","ShareWarningModal","maxSize","percentUsed","STORAGE_KEY","API_CONFIG_STORAGE_KEY","QueryBuilder","initialQuery","disableLocalStorage","hideSettings","enableSharing","onShare","cubeApi","updateApiConfig","metaLoading","metaError","refetchMeta","getInitialApiConfig","getInitialState","parsedState","setDisplayLimit","initialChartState","setChartType","setChartConfig","setDisplayConfig","apiConfig","setApiConfig","showSetupPanel","setShowSetupPanel","showSchemaMobile","setShowSchemaMobile","schemaViewType","setSchemaViewType","showAIAssistant","setShowAIAssistant","setShareButtonState","showShareWarning","setShowShareWarning","shareWarningData","setShareWarningData","setIsViewingShared","lastValidatedQueryRef","fullValidationResult","setFullValidationResult","pendingSharedExecution","decoded","handleExecuteQuery","updateQuery","updater","newQuery","queryChanged","shouldMarkStale","handleFieldSelect","handleFieldDeselect","newOrder","handleTimeDimensionGranularityChange","dimensionName","handleFiltersChange","handleDateRangeRemove","handleOrderChange","validateQuery","silent","queryToValidate","queryStr","isValid","debounceTimer","effectiveLimit","limitedResultSet","totalResultSet","limitedData","totalCount","lastExecutedQueryRef","lastAutoRunQueryRef","autoRunTimerRef","handleClearQuery","shareStateRef","onShareRef","handleShare","shareableState","queryOnly","queryOnlySize","handleApiConfigChange","handleResetApiConfig","handleRetrySchema","sourceQuery","handleToggleSetupPanel","handleOpenAIAssistant","handleViewTypeChange","expanded","SAMPLE_QUERIES","PortletEditModal","onSave","submitText","formTitle","setFormTitle","setQuery","setDashboardFilterMapping","isValidating","setIsValidating","validationResult","setValidationResult","lastValidatedQuery","setLastValidatedQuery","dryRunData","setDryRunData","showQueryBuilder","setShowQueryBuilder","queryBuilderInitialQuery","setQueryBuilderInitialQuery","queryBuilderRef","autoPopulateChartConfig","_result","defaultWidth","defaultHeight","formattedQuery","runDryRunValidation","handleSubmit","hasQueryChanged","queryToSave","handleSampleQuery","sampleQuery","handleQueryChange","isEditModeLoad","parsedQuery","details","message","errorMsg","handleValidateQuery","handleOpenQueryBuilder","handleApplyQueryBuilderQuery","currentQuery","validationState","handleBackToForm","isQueryValidAndCurrent","sample","findFieldInSchema","schemaToFieldOptions","mode","isTime","filterFieldOptions","selectedCube","filtered","term","groupFieldsByCube","grouped","existing","RECENT_FIELDS_KEY","MAX_RECENT_FIELDS","getRecentFields","stored","addRecentField","recent","getRecentFieldOptions","recentFieldNames","allOptions","recentOptions","getCubeNames","getCubeTitle","FieldSearchItem","isFocused","onClick","onMouseEnter","getFieldIcon","Icon","getBadgeStyle","getTypeLabel","FieldSearchItem$1","FieldDetailPanel","getIconBgStyle","getTypeDisplay","FieldDetailPanel$1","FieldSearchModal","onSelect","externalRecentFields","setSelectedCube","focusedField","setFocusedField","focusedIndex","setFocusedIndex","lastSelectedIndex","setLastSelectedIndex","resultsContainerRef","fieldOptionsMode","allFieldOptions","cubeNames","filteredFields","groupedFields","flatFieldsList","list","selectSingleField","keepOpen","metaField","handleSelectField","fieldIndex","shiftKey","startIndex","endIndex","rangeField","focusedElement","searchPlaceholder","modalTitle","focusedFieldId","sum","breakdown","getFirstTimeDimension","breakdowns","getFirstDimension","getDimensions","getTimeDimensions","getChartAvailability","metrics","measureCount","dimensionCount","timeDimensionCount","totalBreakdowns","getAllChartAvailability","selectBestChartType","currentChartType","hasTimeDimension","hasDimension","hasMeasure","getSmartChartDefaults","buildChartConfig","allBreakdowns","shouldAutoSwitchChartType","userManuallySelected","recommendedType","COLOR_PALETTES","getColorPalette","paletteName","p","ColorPaletteSelector","currentPalette","onPaletteChange","currentPaletteObj","handlePaletteSelect","palette","AnalysisResultsPanel","currentPaletteName","onColorPaletteChange","hasMetrics","debugQuery","debugSql","debugAnalysis","debugLoading","debugError","onClearClick","canClear","enableAI","isAIOpen","onAIToggle","showDebug","setShowDebug","ChartIcon","CodeIcon","TrashIcon","renderLoading","renderError","renderWaiting","renderEmpty","renderNoData","renderDebug","renderTable","renderOverlaySpinner","renderSuccess","hasResults","shouldShowResults","MetricItemCard","metric","fieldMeta","sortPriority","displayTitle","isDraggable","findFieldMeta","MetricsSection","onAdd","draggedIndex","setDraggedIndex","dropTargetIndex","setDropTargetIndex","draggedIndexRef","dropTargetIndexRef","orderKeys","metricsWithMeta","dragCloneRef","target","clone","offsetX","offsetY","handleItemDragOver","itemIndex","currentDraggedIndex","handleItemDrop","currentDropTargetIndex","adjustedTarget","handleSectionDragLeave","getItemTransform","gapSize","shouldShowGapIndicator","SectionHeading","transform","showGapBefore","nextDirection","lastIndex","BreakdownItemCard","g","BreakdownSection","breakdownsWithMeta","AnalysisFilterItem","onUpdate","isValueDropdownOpen","setIsValueDropdownOpen","fieldInfo","isTimeField","isMeasureField","isDimensionField","fieldTitle","shouldShowDateRange","flexMatch","handleNumberValueChange","handleCustomStartDate","start","end","handleCustomEndDate","operatorLabel","dateRangeLabel","iconColor","renderValueInput","AnalysisFilterGroup","isAddMenuOpen","setIsAddMenuOpen","addMenuRef","handleToggleType","newType","handleUpdateFilter","handleRemoveFilter","handleAddNestedGroup","handleAddFilterClick","createNestedAddFilterHandler","nestedIndex","relativePath","getBorderColor","getGroupBgColor","conditionCount","conditionLabel","getSelectedFields","addFilterAtPath","path","firstIndex","restPath","targetFilter","AnalysisFilterSection","onFieldDropped","showFieldModal","setShowFieldModal","setIsDragOver","pendingAddPath","handleDragLeave","handleFieldSelected","_fieldType","_cubeName","updatedFilters","handleUpdateTopLevelFilter","handleRemoveTopLevelFilter","handleClearAll","createAddFilterHandler","basePath","renderFilter","parentPath","currentPath","AnalysisAxisDropZone","getFieldMeta","yAxisAssignment","onYAxisAssignmentChange","draggingFieldRef","fieldsRef","isTopHalf","handleFieldDragEnd","container","getDefaultFieldMeta","parts","renderFieldIcon","currentAxis","AnalysisChartConfigPanel","schemaMeta","breakdownItem","dropZoneConfig","_removed","rest","handleYAxisAssignmentChange","axis","hasUnassignedFields","AnalysisDisplayConfigPanel","AxisFormatControls","AnalysisQueryPanel","activeTab","onActiveTabChange","onAddMetric","onRemoveMetric","onReorderMetrics","onAddBreakdown","onRemoveBreakdown","onBreakdownGranularityChange","onReorderBreakdowns","onDropFieldToFilter","AnalysisAIPanel","onPromptChange","isGenerating","hasGeneratedQuery","onGenerate","onAccept","onCancel","AUTO_EXECUTE_DELAY","generateId","generateMetricLabel","buildCubeQuery","createInitialState","loadInitialStateFromStorage","AnalysisBuilder","maxHeight","initialChartConfig","initialData","externalColorPalette","disableLocalStorageProp","_hideSettings","onQueryChange","cachedStorage","localPaletteName","setLocalPaletteName","effectiveColorPalette","setOrder","setActiveTab","userManuallySelectedChart","setUserManuallySelectedChart","setDebugData","fieldModalMode","setFieldModalMode","aiState","setAIState","sharedState","currentQueryString","debouncedQuery","setDebouncedQuery","debounceTimerRef","lastQueryStringRef","hasInitialDataRef","initialQueryStringRef","prevMetricsBreakdownsRef","chartConfigRef","isValidQuery","serverQuery","isChartConfigEmpty","val","currentKey","newChartType","newChartConfig","smartDefaults","timeoutId","storageState","isCancelled","err","handleAddMetric","handleRemoveMetric","fieldToRemove","prevOrder","existingIndex","newMetric","newBreakdown","handleAddBreakdown","handleRemoveBreakdown","handleBreakdownGranularityChange","handleReorderMetrics","newMetrics","handleReorderBreakdowns","newBreakdowns","handleDropFieldToFilter","existingFilters","handleOpenAI","handleCloseAI","handleAIPromptChange","prompt","handleGenerateAI","aiChartType","aiChartConfig","handleAcceptAI","handleCancelAI","handleChartTypeChange","handleChartConfigChange","handleDisplayConfigChange","PortletAnalysisModal","builderRef","handleSave","portletData","handleCancel","PortletFilterConfigModal","currentMapping","portletTitle","selectedFilters","setSelectedFilters","handleToggleFilter","filterId","formatFilterPreview","valuesText","filterCount","EyeIcon","EyeOffIcon","FilterEditModal","convertToMetaResponse","localLabel","setLocalLabel","localFilter","setLocalFilter","showAllFields","setShowAllFields","dashboardFields","filteredSchema","filteredMeasures","fullName","filteredDimensions","filteredCubeMeta","selectedFieldInFilter","handleLabelChange","newLabel","handleFilterBuilderChange","_timeDim","validateFilter","validation","updatedFilter","ClockIcon","ReadOnlyFilterList","isTimeDimensionField","renderReadOnlyFilter","dashboardFilter","isUniversalTime","isTimeDim","dateRangeValue","_index","EditIcon","EditModeFilterList","onAddTimeFilter","onEditFilter","onRemoveFilter","onFilterSelect","isCollapsed","setIsCollapsed","renderFilterChip","DashboardFilterPanel","onDashboardFiltersChange","onSaveFilters","editingFilter","setEditingFilter","showFilterBuilder","setShowFilterBuilder","cubeMeta","s","generateFilterId","handleAddFilter","handleAddTimeFilter","handleEditFilter","filterToEdit","handleSaveFilter","filterData","existingFilterIndex","handleCloseFilterBuilder","handleFilterDateRangeChange","handleReadOnlyFilterChange","ScaledGridWrapper","scaleFactor","designWidth","actualHeight","setActualHeight","innerRef","visualHeight","findScrollableAncestor","style","overflowY","overflowX","hasScrollableOverflow","hasScrollContent","MobileStackedLayout","onPortletRefresh","portletComponentRefs","setScrollContainer","setContainerRef","node","sortedPortlets","handlePortletRefresh","portletId","ScrollContainerProvider","portletHeight","headerHeight","contentHeight","ChartBarIcon","DesktopIcon","GridIcon","RowsIcon","DEFAULT_GRID_SETTINGS","createRowId","getGridSettings","equalizeRowColumns","portletIds","cols","minW","minTotal","base","remainder","remaining","extra","adjustRowWidths","columns","adjusted","total","overflow","reducible","delta","convertPortletsToRows","sorted","rowsByY","rowY","rowPortlets","normalizeRows","convertRowsToPortlets","currentY","updated","currentX","updatedIds","DashboardGrid","dashboardModes","containerWidth","displayMode","isResponsiveEditable","useResponsiveDashboard","allowedModes","fallbackMode","configMode","layoutMode","containerElementRef","combinedContainerRef","draftRows","setDraftRows","draftRowsRef","dragStateRef","isDraggingPortlet","setIsDraggingPortlet","portletRefs","isInitialized","setIsInitialized","lastKnownLayout","setLastKnownLayout","setIsEditMode","setSelectedFilterId","canChangeLayoutMode","isScrolled","setIsScrolled","isPortletModalOpen","setIsPortletModalOpen","editingPortlet","setEditingPortlet","isFilterConfigModalOpen","setIsFilterConfigModalOpen","filterConfigPortlet","setFilterConfigPortlet","resolvedRows","baseRows","updateRowLayout","save","portletsOverride","normalizedRows","updatedPortlets","updatedConfig","initialLayout","handleScroll","scrollTop","hasLayoutActuallyChanged","newLayout","newItem","oldItem","item","handleLayoutChange","_layout","handleDragStop","layout","_oldItem","_newItem","_placeholder","_e","_element","mutableLayout","layoutItem","handleResizeStop","handleLayoutModeChange","startRowResize","startY","startRows","handleMouseMove","moveEvent","deltaUnits","nextRows","handleMouseUp","finalRows","startColumnResize","startX","leftColumn","rightColumn","nextLeft","nextRight","diff","rowItem","nextColumns","colIndex","handlePortletDragStart","handlePortletDragEnd","handleRowDrop","insertIndex","dragState","sourceRowIndex","sourceRow","movedColumn","sourceRowRemoved","targetRowIndex","targetRow","handleNewRowDrop","newRow","portletComponent","handleAddPortlet","handleEditPortlet","handlePortletSave","isNewPortlet","newPortletId","newPortlet","gridLayout","maxY","scrollToPortlet","portletElement","handleDeletePortlet","handleDuplicatePortlet","originalPortlet","duplicatedPortlet","handlePaletteChange","handleOpenFilterConfig","handleSaveFilterConfig","mapping","handleToggleFilterForPortlet","hasFilter","handleFilterSelect","handleSelectAllForFilter","selectedFilter","baseLayout","renderPortletCard","renderActiveLayout","ReactGridLayout","verticalCompactor","AnalyticsDashboard","propDashboardFilters","onDirtyStateChange","initialConfigRef","hasConfigChangedFromInitial","mergedDashboardFilters","configFilters","propFilters","configFilter","propFilter","pf","configIds","cf","handleSaveWithDirtyTracking","handleConfigChangeWithDirtyTracking","configString","initialConfigString","handleDashboardFiltersChange","PortletContainer","DashboardEditModal","initialName","initialDescription","name","setName","setDescription","isSaving","setIsSaving"],"mappings":"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","x_google_ignoreList":[0,29]}