drizzle-cube 0.3.13 → 0.3.15

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 (182) hide show
  1. package/dist/adapters/{compiler-DTOU8IsK.js → compiler-DdcGVWIl.js} +7429 -4165
  2. package/dist/adapters/compiler-mAJDpIQx.cjs +214 -0
  3. package/dist/adapters/express/index.cjs +1 -1
  4. package/dist/adapters/express/index.d.ts +1 -1
  5. package/dist/adapters/express/index.js +1 -1
  6. package/dist/adapters/fastify/index.cjs +1 -1
  7. package/dist/adapters/fastify/index.d.ts +1 -1
  8. package/dist/adapters/fastify/index.js +1 -1
  9. package/dist/adapters/hono/index.cjs +1 -1
  10. package/dist/adapters/hono/index.d.ts +1 -1
  11. package/dist/adapters/hono/index.js +1 -1
  12. package/dist/adapters/nextjs/index.cjs +1 -1
  13. package/dist/adapters/nextjs/index.d.ts +1 -1
  14. package/dist/adapters/nextjs/index.js +1 -1
  15. package/dist/adapters/utils.d.ts +29 -0
  16. package/dist/client/adapters/index.d.ts +2 -0
  17. package/dist/client/adapters/retentionModeAdapter.d.ts +3 -0
  18. package/dist/client/charts.js +12 -12
  19. package/dist/client/chunks/RetentionCombinedChart-CqMAkdcR.js +256 -0
  20. package/dist/client/chunks/RetentionCombinedChart-CqMAkdcR.js.map +1 -0
  21. package/dist/client/chunks/RetentionCombinedChart.config-C-ILIaEb.js +47 -0
  22. package/dist/client/chunks/RetentionCombinedChart.config-C-ILIaEb.js.map +1 -0
  23. package/dist/client/chunks/RetentionHeatmap-Bofadstm.js +178 -0
  24. package/dist/client/chunks/RetentionHeatmap-Bofadstm.js.map +1 -0
  25. package/dist/client/chunks/RetentionHeatmap.config-CIvhc-GT.js +28 -0
  26. package/dist/client/chunks/RetentionHeatmap.config-CIvhc-GT.js.map +1 -0
  27. package/dist/client/chunks/analysis-builder-D0MIKiKS.js +6939 -0
  28. package/dist/client/chunks/analysis-builder-D0MIKiKS.js.map +1 -0
  29. package/dist/client/chunks/analysis-builder-shared-gS0TDC6Y.js +2779 -0
  30. package/dist/client/chunks/analysis-builder-shared-gS0TDC6Y.js.map +1 -0
  31. package/dist/client/chunks/{chart-activity-grid-CuPARsr1.js → chart-activity-grid-B37W8fcE.js} +11 -11
  32. package/dist/client/chunks/{chart-activity-grid-CuPARsr1.js.map → chart-activity-grid-B37W8fcE.js.map} +1 -1
  33. package/dist/client/chunks/{chart-area-cPrJnhLj.js → chart-area-DZcxSVB1.js} +2 -2
  34. package/dist/client/chunks/{chart-area-cPrJnhLj.js.map → chart-area-DZcxSVB1.js.map} +1 -1
  35. package/dist/client/chunks/{chart-bar-D68HFPpa.js → chart-bar-BFAdRj-E.js} +2 -2
  36. package/dist/client/chunks/{chart-bar-D68HFPpa.js.map → chart-bar-BFAdRj-E.js.map} +1 -1
  37. package/dist/client/chunks/{chart-bubble-CquyYfNO.js → chart-bubble-eoCCbl3h.js} +2 -2
  38. package/dist/client/chunks/{chart-bubble-CquyYfNO.js.map → chart-bubble-eoCCbl3h.js.map} +1 -1
  39. package/dist/client/chunks/{chart-config-activity-grid-Bkvx0F-G.js → chart-config-activity-grid-BBSNCbkb.js} +2 -2
  40. package/dist/client/chunks/{chart-config-activity-grid-Bkvx0F-G.js.map → chart-config-activity-grid-BBSNCbkb.js.map} +1 -1
  41. package/dist/client/chunks/{chart-config-area-OApsRaYC.js → chart-config-area-CyyJOO2T.js} +2 -2
  42. package/dist/client/chunks/{chart-config-area-OApsRaYC.js.map → chart-config-area-CyyJOO2T.js.map} +1 -1
  43. package/dist/client/chunks/{chart-config-bar-Dy21oaIA.js → chart-config-bar-BJKGnfLt.js} +2 -2
  44. package/dist/client/chunks/{chart-config-bar-Dy21oaIA.js.map → chart-config-bar-BJKGnfLt.js.map} +1 -1
  45. package/dist/client/chunks/{chart-config-bubble-Chv0SoFm.js → chart-config-bubble-CuSsCHZ4.js} +2 -2
  46. package/dist/client/chunks/{chart-config-bubble-Chv0SoFm.js.map → chart-config-bubble-CuSsCHZ4.js.map} +1 -1
  47. package/dist/client/chunks/{chart-config-data-table-DTIdC35a.js → chart-config-data-table-BhgqwoqT.js} +2 -2
  48. package/dist/client/chunks/{chart-config-data-table-DTIdC35a.js.map → chart-config-data-table-BhgqwoqT.js.map} +1 -1
  49. package/dist/client/chunks/{chart-config-funnel-f17Livgr.js → chart-config-funnel-BlSQYng0.js} +4 -4
  50. package/dist/client/chunks/{chart-config-funnel-f17Livgr.js.map → chart-config-funnel-BlSQYng0.js.map} +1 -1
  51. package/dist/client/chunks/{chart-config-heat-map-DPhNICha.js → chart-config-heat-map-DHQGFZhX.js} +2 -2
  52. package/dist/client/chunks/{chart-config-heat-map-DPhNICha.js.map → chart-config-heat-map-DHQGFZhX.js.map} +1 -1
  53. package/dist/client/chunks/{chart-config-kpi-delta-CCl1d-St.js → chart-config-kpi-delta-yTA5ug_l.js} +2 -2
  54. package/dist/client/chunks/{chart-config-kpi-delta-CCl1d-St.js.map → chart-config-kpi-delta-yTA5ug_l.js.map} +1 -1
  55. package/dist/client/chunks/{chart-config-kpi-number-DkE3eSwH.js → chart-config-kpi-number-nVAwDXzq.js} +2 -2
  56. package/dist/client/chunks/{chart-config-kpi-number-DkE3eSwH.js.map → chart-config-kpi-number-nVAwDXzq.js.map} +1 -1
  57. package/dist/client/chunks/{chart-config-kpi-text-BMbgdxZm.js → chart-config-kpi-text-DZjqsx-b.js} +2 -2
  58. package/dist/client/chunks/{chart-config-kpi-text-BMbgdxZm.js.map → chart-config-kpi-text-DZjqsx-b.js.map} +1 -1
  59. package/dist/client/chunks/{chart-config-line-BnLlRUQE.js → chart-config-line-DR0ThxZy.js} +2 -2
  60. package/dist/client/chunks/{chart-config-line-BnLlRUQE.js.map → chart-config-line-DR0ThxZy.js.map} +1 -1
  61. package/dist/client/chunks/{chart-config-markdown-DIaMFC0Z.js → chart-config-markdown-DZxdGNVQ.js} +2 -2
  62. package/dist/client/chunks/{chart-config-markdown-DIaMFC0Z.js.map → chart-config-markdown-DZxdGNVQ.js.map} +1 -1
  63. package/dist/client/chunks/{chart-config-pie-O9y_T0BQ.js → chart-config-pie-BM5lgH-w.js} +2 -2
  64. package/dist/client/chunks/{chart-config-pie-O9y_T0BQ.js.map → chart-config-pie-BM5lgH-w.js.map} +1 -1
  65. package/dist/client/chunks/{chart-config-radar-CXa0354h.js → chart-config-radar-BBAVIF0S.js} +2 -2
  66. package/dist/client/chunks/{chart-config-radar-CXa0354h.js.map → chart-config-radar-BBAVIF0S.js.map} +1 -1
  67. package/dist/client/chunks/{chart-config-radial-bar-BppJU8-Q.js → chart-config-radial-bar-CTwjDRnB.js} +2 -2
  68. package/dist/client/chunks/{chart-config-radial-bar-BppJU8-Q.js.map → chart-config-radial-bar-CTwjDRnB.js.map} +1 -1
  69. package/dist/client/chunks/{chart-config-sankey-BfBHgL4x.js → chart-config-sankey-CNAgsMQ4.js} +2 -2
  70. package/dist/client/chunks/{chart-config-sankey-BfBHgL4x.js.map → chart-config-sankey-CNAgsMQ4.js.map} +1 -1
  71. package/dist/client/chunks/{chart-config-scatter-BTt8a10R.js → chart-config-scatter-CWvN2E-X.js} +2 -2
  72. package/dist/client/chunks/{chart-config-scatter-BTt8a10R.js.map → chart-config-scatter-CWvN2E-X.js.map} +1 -1
  73. package/dist/client/chunks/{chart-config-sunburst-DNmQpIIx.js → chart-config-sunburst-W_SKwaj0.js} +4 -4
  74. package/dist/client/chunks/{chart-config-sunburst-DNmQpIIx.js.map → chart-config-sunburst-W_SKwaj0.js.map} +1 -1
  75. package/dist/client/chunks/{chart-config-tree-map-HVgG4oa0.js → chart-config-tree-map-CLmRvvMR.js} +2 -2
  76. package/dist/client/chunks/{chart-config-tree-map-HVgG4oa0.js.map → chart-config-tree-map-CLmRvvMR.js.map} +1 -1
  77. package/dist/client/chunks/{chart-data-table-D4WDqbM0.js → chart-data-table-kudRwZxJ.js} +4 -4
  78. package/dist/client/chunks/{chart-data-table-D4WDqbM0.js.map → chart-data-table-kudRwZxJ.js.map} +1 -1
  79. package/dist/client/chunks/{chart-funnel-Csdn4FbN.js → chart-funnel-CA0XJkfh.js} +2 -2
  80. package/dist/client/chunks/{chart-funnel-Csdn4FbN.js.map → chart-funnel-CA0XJkfh.js.map} +1 -1
  81. package/dist/client/chunks/{chart-heat-map-v1afxnjq.js → chart-heat-map-DUy9_pWM.js} +2 -2
  82. package/dist/client/chunks/{chart-heat-map-v1afxnjq.js.map → chart-heat-map-DUy9_pWM.js.map} +1 -1
  83. package/dist/client/chunks/chart-kpi-delta-MIGGCpkG.js +351 -0
  84. package/dist/client/chunks/chart-kpi-delta-MIGGCpkG.js.map +1 -0
  85. package/dist/client/chunks/chart-kpi-number-DM0Brd91.js +473 -0
  86. package/dist/client/chunks/chart-kpi-number-DM0Brd91.js.map +1 -0
  87. package/dist/client/chunks/{chart-kpi-text-CRp8QWYG.js → chart-kpi-text-BAb28V4X.js} +3 -3
  88. package/dist/client/chunks/{chart-kpi-text-CRp8QWYG.js.map → chart-kpi-text-BAb28V4X.js.map} +1 -1
  89. package/dist/client/chunks/{chart-line-DqqE7ky9.js → chart-line-e3h8sa1R.js} +5 -5
  90. package/dist/client/chunks/{chart-line-DqqE7ky9.js.map → chart-line-e3h8sa1R.js.map} +1 -1
  91. package/dist/client/chunks/{chart-pie-B5WBzIRH.js → chart-pie-CFoHYqDB.js} +2 -2
  92. package/dist/client/chunks/{chart-pie-B5WBzIRH.js.map → chart-pie-CFoHYqDB.js.map} +1 -1
  93. package/dist/client/chunks/{chart-radar-DL_dvhA-.js → chart-radar-CPPwkfxj.js} +2 -2
  94. package/dist/client/chunks/{chart-radar-DL_dvhA-.js.map → chart-radar-CPPwkfxj.js.map} +1 -1
  95. package/dist/client/chunks/{chart-radial-bar-DDRo6nz-.js → chart-radial-bar-BdEOM-P1.js} +2 -2
  96. package/dist/client/chunks/{chart-radial-bar-DDRo6nz-.js.map → chart-radial-bar-BdEOM-P1.js.map} +1 -1
  97. package/dist/client/chunks/{chart-sankey-C_bgIfg-.js → chart-sankey-Bbady-8g.js} +2 -2
  98. package/dist/client/chunks/{chart-sankey-C_bgIfg-.js.map → chart-sankey-Bbady-8g.js.map} +1 -1
  99. package/dist/client/chunks/{chart-scatter-DjmJRlK0.js → chart-scatter-JFu0Pv3a.js} +15 -15
  100. package/dist/client/chunks/{chart-scatter-DjmJRlK0.js.map → chart-scatter-JFu0Pv3a.js.map} +1 -1
  101. package/dist/client/chunks/{chart-sunburst-CbMEnaes.js → chart-sunburst-sayxze15.js} +2 -2
  102. package/dist/client/chunks/{chart-sunburst-CbMEnaes.js.map → chart-sunburst-sayxze15.js.map} +1 -1
  103. package/dist/client/chunks/{chart-tree-map-DEfJtJVC.js → chart-tree-map-Ks2xev8b.js} +30 -30
  104. package/dist/client/chunks/{chart-tree-map-DEfJtJVC.js.map → chart-tree-map-Ks2xev8b.js.map} +1 -1
  105. package/dist/client/chunks/chartConfigRegistry-BumUIPw4.js +44 -0
  106. package/dist/client/chunks/{chartConfigRegistry-CiOq-PqX.js.map → chartConfigRegistry-BumUIPw4.js.map} +1 -1
  107. package/dist/client/chunks/charts-_yZ9gBJU.js +230 -0
  108. package/dist/client/chunks/charts-_yZ9gBJU.js.map +1 -0
  109. package/dist/client/chunks/{charts-core-CXrhEEVF.js → charts-core-Bzu9PzMd.js} +10 -10
  110. package/dist/client/chunks/{charts-core-CXrhEEVF.js.map → charts-core-Bzu9PzMd.js.map} +1 -1
  111. package/dist/client/chunks/{charts-loader-BtsnUO4Q.js → charts-loader-cMtx4zHx.js} +30 -28
  112. package/dist/client/chunks/charts-loader-cMtx4zHx.js.map +1 -0
  113. package/dist/client/chunks/{components-BDrlf9Er.js → components-DQuPThfA.js} +3575 -3208
  114. package/dist/client/chunks/components-DQuPThfA.js.map +1 -0
  115. package/dist/client/chunks/{core-B8zw0qRf.js → core-DwOXVb87.js} +2 -2
  116. package/dist/client/chunks/{core-B8zw0qRf.js.map → core-DwOXVb87.js.map} +1 -1
  117. package/dist/client/chunks/hooks-DPRv1Xhb.js +150 -0
  118. package/dist/client/chunks/{hooks-B8Zw5PfL.js.map → hooks-DPRv1Xhb.js.map} +1 -1
  119. package/dist/client/chunks/{icons-NzFHtqeM.js → icons-DRreo6m8.js} +128 -112
  120. package/dist/client/chunks/{icons-NzFHtqeM.js.map → icons-DRreo6m8.js.map} +1 -1
  121. package/dist/client/chunks/{providers-CqCiJTEj.js → providers-BW8D7Wso.js} +2 -2
  122. package/dist/client/chunks/{providers-CqCiJTEj.js.map → providers-BW8D7Wso.js.map} +1 -1
  123. package/dist/client/chunks/retention-CzCo8262.js +120 -0
  124. package/dist/client/chunks/retention-CzCo8262.js.map +1 -0
  125. package/dist/client/chunks/{useDirtyStateTracking-C_mitVwh.js → useDirtyStateTracking-Yu_qQXb-.js} +101 -99
  126. package/dist/client/chunks/useDirtyStateTracking-Yu_qQXb-.js.map +1 -0
  127. package/dist/client/chunks/{vendor-DzzxS7Ay.js → vendor-BSkQZgtm.js} +548 -540
  128. package/dist/client/chunks/vendor-BSkQZgtm.js.map +1 -0
  129. package/dist/client/components/AnalysisBuilder/AnalysisTypeSelector.d.ts +3 -1
  130. package/dist/client/components/AnalysisBuilder/RetentionConfigPanel.d.ts +36 -0
  131. package/dist/client/components/AnalysisBuilder/RetentionModeContent.d.ts +71 -0
  132. package/dist/client/components/AnalysisBuilder/types.d.ts +99 -0
  133. package/dist/client/components/DebugModal.d.ts +2 -1
  134. package/dist/client/components/charts/RetentionCombinedChart.config.d.ts +2 -0
  135. package/dist/client/components/charts/RetentionCombinedChart.d.ts +14 -0
  136. package/dist/client/components/charts/RetentionHeatmap.config.d.ts +2 -0
  137. package/dist/client/components/charts/RetentionHeatmap.d.ts +7 -0
  138. package/dist/client/components.js +2 -2
  139. package/dist/client/hooks/queries/index.d.ts +2 -1
  140. package/dist/client/hooks/queries/useDryRunQuery.d.ts +26 -0
  141. package/dist/client/hooks/queries/useExplainQuery.d.ts +3 -1
  142. package/dist/client/hooks/queries/useFlowQuery.d.ts +5 -0
  143. package/dist/client/hooks/queries/useRetentionQuery.d.ts +67 -0
  144. package/dist/client/hooks/useAnalysisBuilderHook.d.ts +61 -0
  145. package/dist/client/hooks/useAnalysisQueryExecution.d.ts +42 -1
  146. package/dist/client/hooks.js +3 -3
  147. package/dist/client/icons/customIcons.d.ts +7 -0
  148. package/dist/client/icons/types.d.ts +1 -0
  149. package/dist/client/icons.js +1 -1
  150. package/dist/client/index.js +11 -11
  151. package/dist/client/providers.js +1 -1
  152. package/dist/client/stores/analysisBuilderStore.d.ts +86 -1
  153. package/dist/client/stores/dashboardStore.d.ts +2 -1
  154. package/dist/client/stores/slices/index.d.ts +2 -0
  155. package/dist/client/stores/slices/retentionSlice.d.ts +66 -0
  156. package/dist/client/styles.css +1 -1
  157. package/dist/client/types/analysisConfig.d.ts +29 -4
  158. package/dist/client/types/funnel.d.ts +5 -0
  159. package/dist/client/types/retention.d.ts +301 -0
  160. package/dist/client/types.d.ts +6 -3
  161. package/dist/client-bundle-stats.html +1 -1
  162. package/dist/server/index.cjs +76 -54
  163. package/dist/server/index.d.ts +217 -0
  164. package/dist/server/index.js +7363 -4152
  165. package/package.json +5 -2
  166. package/dist/adapters/compiler-CO13DaEb.cjs +0 -192
  167. package/dist/client/chunks/analysis-builder-Dc9NrG_N.js +0 -6013
  168. package/dist/client/chunks/analysis-builder-Dc9NrG_N.js.map +0 -1
  169. package/dist/client/chunks/analysis-builder-shared-B3-UWqQ2.js +0 -2540
  170. package/dist/client/chunks/analysis-builder-shared-B3-UWqQ2.js.map +0 -1
  171. package/dist/client/chunks/chart-kpi-delta-Bs5R5xr4.js +0 -435
  172. package/dist/client/chunks/chart-kpi-delta-Bs5R5xr4.js.map +0 -1
  173. package/dist/client/chunks/chart-kpi-number-Cf4Pgkm9.js +0 -392
  174. package/dist/client/chunks/chart-kpi-number-Cf4Pgkm9.js.map +0 -1
  175. package/dist/client/chunks/chartConfigRegistry-CiOq-PqX.js +0 -44
  176. package/dist/client/chunks/charts-loader-BtsnUO4Q.js.map +0 -1
  177. package/dist/client/chunks/charts-xNubY0vm.js +0 -226
  178. package/dist/client/chunks/charts-xNubY0vm.js.map +0 -1
  179. package/dist/client/chunks/components-BDrlf9Er.js.map +0 -1
  180. package/dist/client/chunks/hooks-B8Zw5PfL.js +0 -123
  181. package/dist/client/chunks/useDirtyStateTracking-C_mitVwh.js.map +0 -1
  182. package/dist/client/chunks/vendor-DzzxS7Ay.js.map +0 -1
@@ -1,2540 +0,0 @@
1
- import { useContext as Le, createContext as Ht, useRef as re, useMemo as T, useCallback as B, useEffect as ee, useState as Ot } from "react";
2
- import { f as Gt } from "./providers-CqCiJTEj.js";
3
- import { jsx as jt } from "react/jsx-runtime";
4
- import { c as Wt, d as Fe, e as Me, s as Ae, p as zt, f as Jt, l as Pe } from "./vendor-DzzxS7Ay.js";
5
- import { H as E, I as te, J as K, K as N, L as Yt, N as $e, u as Xt, f as Zt, O as en } from "./components-BDrlf9Er.js";
6
- import { F as xe, b as qe } from "./flow-utils-CjQZG5qq.js";
7
- import { h as tn, u as nn, a as rn } from "./useDirtyStateTracking-C_mitVwh.js";
8
- import { c as sn, a as Ke } from "./funnel-utils-CyonoNeC.js";
9
- import { b as an, c as on, d as ln } from "./hooks-B8Zw5PfL.js";
10
- function un(n) {
11
- const i = /* @__PURE__ */ new Date(), e = n.toLowerCase().trim(), t = i.getUTCFullYear(), r = i.getUTCMonth(), s = i.getUTCDate(), a = i.getUTCDay();
12
- if (e === "today") {
13
- const g = new Date(i);
14
- g.setUTCHours(0, 0, 0, 0);
15
- const u = new Date(i);
16
- return u.setUTCHours(23, 59, 59, 999), { start: g, end: u };
17
- }
18
- if (e === "yesterday") {
19
- const g = new Date(i);
20
- g.setUTCDate(s - 1), g.setUTCHours(0, 0, 0, 0);
21
- const u = new Date(i);
22
- return u.setUTCDate(s - 1), u.setUTCHours(23, 59, 59, 999), { start: g, end: u };
23
- }
24
- if (e === "this week") {
25
- const g = a === 0 ? -6 : 1 - a, u = new Date(i);
26
- u.setUTCDate(s + g), u.setUTCHours(0, 0, 0, 0);
27
- const m = new Date(u);
28
- return m.setUTCDate(u.getUTCDate() + 6), m.setUTCHours(23, 59, 59, 999), { start: u, end: m };
29
- }
30
- if (e === "this month") {
31
- const g = new Date(Date.UTC(t, r, 1, 0, 0, 0, 0)), u = new Date(Date.UTC(t, r + 1, 0, 23, 59, 59, 999));
32
- return { start: g, end: u };
33
- }
34
- if (e === "this quarter") {
35
- const g = Math.floor(r / 3), u = new Date(Date.UTC(t, g * 3, 1, 0, 0, 0, 0)), m = new Date(Date.UTC(t, g * 3 + 3, 0, 23, 59, 59, 999));
36
- return { start: u, end: m };
37
- }
38
- if (e === "this year") {
39
- const g = new Date(Date.UTC(t, 0, 1, 0, 0, 0, 0)), u = new Date(Date.UTC(t, 11, 31, 23, 59, 59, 999));
40
- return { start: g, end: u };
41
- }
42
- const l = e.match(/^last\s+(\d+)\s+days?$/);
43
- if (l) {
44
- const g = parseInt(l[1], 10), u = new Date(i);
45
- u.setUTCDate(s - g + 1), u.setUTCHours(0, 0, 0, 0);
46
- const m = new Date(i);
47
- return m.setUTCHours(23, 59, 59, 999), { start: u, end: m };
48
- }
49
- const c = e.match(/^last\s+(\d+)\s+weeks?$/);
50
- if (c) {
51
- const u = parseInt(c[1], 10) * 7, m = new Date(i);
52
- m.setUTCDate(s - u + 1), m.setUTCHours(0, 0, 0, 0);
53
- const p = new Date(i);
54
- return p.setUTCHours(23, 59, 59, 999), { start: m, end: p };
55
- }
56
- if (e === "last week") {
57
- const g = a === 0 ? -13 : -6 - a, u = new Date(i);
58
- u.setUTCDate(s + g), u.setUTCHours(0, 0, 0, 0);
59
- const m = new Date(u);
60
- return m.setUTCDate(u.getUTCDate() + 6), m.setUTCHours(23, 59, 59, 999), { start: u, end: m };
61
- }
62
- if (e === "last month") {
63
- const g = new Date(Date.UTC(t, r - 1, 1, 0, 0, 0, 0)), u = new Date(Date.UTC(t, r, 0, 23, 59, 59, 999));
64
- return { start: g, end: u };
65
- }
66
- if (e === "last quarter") {
67
- const g = Math.floor(r / 3), u = g === 0 ? 3 : g - 1, m = g === 0 ? t - 1 : t, p = new Date(Date.UTC(m, u * 3, 1, 0, 0, 0, 0)), v = new Date(Date.UTC(m, u * 3 + 3, 0, 23, 59, 59, 999));
68
- return { start: p, end: v };
69
- }
70
- if (e === "last year") {
71
- const g = new Date(Date.UTC(t - 1, 0, 1, 0, 0, 0, 0)), u = new Date(Date.UTC(t - 1, 11, 31, 23, 59, 59, 999));
72
- return { start: g, end: u };
73
- }
74
- if (e === "last 12 months") {
75
- const g = new Date(Date.UTC(t, r - 11, 1, 0, 0, 0, 0)), u = new Date(i);
76
- return u.setUTCHours(23, 59, 59, 999), { start: g, end: u };
77
- }
78
- const f = e.match(/^last\s+(\d+)\s+months?$/);
79
- if (f) {
80
- const g = parseInt(f[1], 10), u = new Date(Date.UTC(t, r - g + 1, 1, 0, 0, 0, 0)), m = new Date(i);
81
- return m.setUTCHours(23, 59, 59, 999), { start: u, end: m };
82
- }
83
- const y = e.match(/^last\s+(\d+)\s+years?$/);
84
- if (y) {
85
- const g = parseInt(y[1], 10), u = new Date(Date.UTC(t - g, 0, 1, 0, 0, 0, 0)), m = new Date(i);
86
- return m.setUTCHours(23, 59, 59, 999), { start: u, end: m };
87
- }
88
- return null;
89
- }
90
- function cn(n) {
91
- if (Array.isArray(n)) {
92
- if (n.length < 2) return null;
93
- const i = new Date(n[0]), e = new Date(n[1]);
94
- return isNaN(i.getTime()) || isNaN(e.getTime()) ? null : (e.setUTCHours(23, 59, 59, 999), { start: i, end: e });
95
- }
96
- return un(n);
97
- }
98
- function Z(n) {
99
- return n.toISOString().split("T")[0];
100
- }
101
- function fn(n, i) {
102
- const e = i.getTime() - n.getTime(), t = Math.ceil(e / (1e3 * 60 * 60 * 24)), r = new Date(n);
103
- r.setUTCDate(r.getUTCDate() - 1), r.setUTCHours(23, 59, 59, 999);
104
- const s = new Date(r);
105
- return s.setUTCDate(s.getUTCDate() - t + 1), s.setUTCHours(0, 0, 0, 0), { start: s, end: r };
106
- }
107
- function Ne(n, i) {
108
- for (const e of n)
109
- if ("type" in e && "filters" in e) {
110
- const r = Ne(e.filters, i);
111
- if (r) return r;
112
- } else if ("member" in e) {
113
- const t = e;
114
- if (t.member === i && t.operator === "inDateRange" && t.dateRange)
115
- return { dateRange: t.dateRange };
116
- }
117
- }
118
- function He(n, i) {
119
- const e = Ne(i, n);
120
- if (!e?.dateRange) return;
121
- const t = cn(e.dateRange);
122
- if (!t) return;
123
- const r = fn(t.start, t.end);
124
- return [
125
- [Z(t.start), Z(t.end)],
126
- [Z(r.start), Z(r.end)]
127
- ];
128
- }
129
- function Oe(n, i) {
130
- return n.reduce((e, t) => {
131
- if ("type" in t && "filters" in t) {
132
- const r = t, s = Oe(r.filters, i);
133
- s.length > 0 && e.push({ type: r.type, filters: s });
134
- } else if ("member" in t) {
135
- const r = t;
136
- r.member === i && r.operator === "inDateRange" || e.push(t);
137
- } else
138
- e.push(t);
139
- return e;
140
- }, []);
141
- }
142
- function ne(n, i, e, t, r = !1) {
143
- const s = i.filter((c) => c.isTimeDimension && c.enableComparison).map((c) => c.field);
144
- let a = e;
145
- if (!r)
146
- for (const c of s)
147
- a = Oe(a, c);
148
- const l = {
149
- measures: n.map((c) => c.field),
150
- dimensions: i.filter((c) => !c.isTimeDimension).map((c) => c.field),
151
- timeDimensions: i.filter((c) => c.isTimeDimension).map((c) => {
152
- const f = {
153
- dimension: c.field,
154
- granularity: c.granularity || "day"
155
- };
156
- if (c.enableComparison) {
157
- const y = He(c.field, e);
158
- y && (f.compareDateRange = y);
159
- }
160
- return f;
161
- }),
162
- filters: a.length > 0 ? a : void 0,
163
- order: t && Object.keys(t).length > 0 ? t : void 0
164
- };
165
- return l.measures?.length === 0 && delete l.measures, l.dimensions?.length === 0 && delete l.dimensions, l.timeDimensions?.length === 0 && delete l.timeDimensions, l;
166
- }
167
- const dn = "drizzle-cube-analysis-builder-v3";
168
- function D() {
169
- return {
170
- metrics: [],
171
- breakdowns: [],
172
- filters: [],
173
- order: void 0,
174
- validationStatus: "idle",
175
- validationError: null
176
- };
177
- }
178
- function Ie() {
179
- return {
180
- metrics: [],
181
- breakdowns: [],
182
- filters: [],
183
- order: void 0,
184
- validationStatus: "idle",
185
- validationError: null
186
- };
187
- }
188
- function yn(n) {
189
- return n.map((i) => i.field);
190
- }
191
- function gn(n, i) {
192
- const e = [], t = [];
193
- for (const r of n)
194
- if (r.isTimeDimension) {
195
- const s = {
196
- dimension: r.field,
197
- granularity: r.granularity || "day"
198
- };
199
- if (r.enableComparison) {
200
- const a = He(r.field, i);
201
- a && (s.compareDateRange = a);
202
- }
203
- t.push(s);
204
- } else
205
- e.push(r.field);
206
- return { dimensions: e, timeDimensions: t };
207
- }
208
- function mn(n) {
209
- const { dimensions: i, timeDimensions: e } = gn(
210
- n.breakdowns,
211
- n.filters
212
- ), t = {
213
- measures: yn(n.metrics),
214
- dimensions: i
215
- };
216
- return e.length > 0 && (t.timeDimensions = e), n.filters.length > 0 && (t.filters = n.filters), n.order && Object.keys(n.order).length > 0 && (t.order = n.order), t;
217
- }
218
- function hn(n) {
219
- return n.map((i, e) => ({
220
- id: E(),
221
- field: i,
222
- label: te(e)
223
- }));
224
- }
225
- function pn(n) {
226
- const i = [];
227
- if (n.dimensions)
228
- for (const e of n.dimensions)
229
- i.push({
230
- id: E(),
231
- field: e,
232
- isTimeDimension: !1
233
- });
234
- if (n.timeDimensions)
235
- for (const e of n.timeDimensions) {
236
- const t = !!(e.compareDateRange && e.compareDateRange.length > 0);
237
- i.push({
238
- id: E(),
239
- field: e.dimension,
240
- granularity: e.granularity,
241
- isTimeDimension: !0,
242
- enableComparison: t
243
- });
244
- }
245
- return i;
246
- }
247
- function ke(n) {
248
- return {
249
- metrics: hn(n.measures || []),
250
- breakdowns: pn(n),
251
- filters: n.filters || [],
252
- order: n.order,
253
- validationStatus: "idle",
254
- validationError: null
255
- };
256
- }
257
- function Sn(n) {
258
- return typeof n == "object" && n !== null && "queries" in n && Array.isArray(n.queries);
259
- }
260
- const U = {
261
- type: "query",
262
- createInitial() {
263
- return {
264
- queryStates: [Ie()],
265
- activeQueryIndex: 0,
266
- mergeStrategy: "concat"
267
- };
268
- },
269
- extractState(n) {
270
- return {
271
- queryStates: n.queryStates,
272
- activeQueryIndex: n.activeQueryIndex,
273
- mergeStrategy: n.mergeStrategy
274
- };
275
- },
276
- canLoad(n) {
277
- if (!n || typeof n != "object") return !1;
278
- const i = n;
279
- return !(i.version !== 1 || i.analysisType !== "query" || !i.query || typeof i.query != "object");
280
- },
281
- load(n) {
282
- if (n.analysisType !== "query")
283
- throw new Error(
284
- `Cannot load ${n.analysisType} config with query adapter`
285
- );
286
- const i = n;
287
- if (Sn(i.query)) {
288
- const e = i.query, t = e.queries.map(ke);
289
- return t.length === 0 && t.push(Ie()), {
290
- queryStates: t,
291
- activeQueryIndex: 0,
292
- mergeStrategy: e.mergeStrategy || "concat"
293
- };
294
- }
295
- return {
296
- queryStates: [ke(i.query)],
297
- activeQueryIndex: 0,
298
- mergeStrategy: "concat"
299
- };
300
- },
301
- save(n, i, e) {
302
- const t = n.queryStates.map(mn), s = t.length === 1 && n.mergeStrategy === "concat" ? t[0] : {
303
- queries: t,
304
- mergeStrategy: n.mergeStrategy
305
- };
306
- return {
307
- version: 1,
308
- analysisType: "query",
309
- activeView: e,
310
- charts: {
311
- query: i.query || this.getDefaultChartConfig()
312
- },
313
- query: s
314
- };
315
- },
316
- validate(n) {
317
- const i = [], e = [];
318
- if (n.queryStates.some((r) => r.metrics.length > 0) || i.push("At least one metric is required"), n.queryStates.forEach((r, s) => {
319
- const a = n.queryStates.length > 1 ? `Query ${s + 1}: ` : "";
320
- r.metrics.length === 0 && r.breakdowns.length === 0 && e.push(`${a}Query is empty`);
321
- }), n.queryStates.length > 1 && n.mergeStrategy === "merge") {
322
- const r = n.queryStates[0].breakdowns.map(
323
- (a) => a.field
324
- );
325
- n.queryStates.every((a) => {
326
- const l = a.breakdowns.map((c) => c.field);
327
- return l.length === r.length && l.every((c) => r.includes(c));
328
- }) || e.push(
329
- "Queries have different breakdowns - merge results may be unexpected"
330
- );
331
- }
332
- return {
333
- isValid: i.length === 0,
334
- errors: i,
335
- warnings: e
336
- };
337
- },
338
- clear(n) {
339
- return this.createInitial();
340
- },
341
- getDefaultChartConfig() {
342
- return {
343
- chartType: "bar",
344
- chartConfig: {},
345
- displayConfig: { showLegend: !0, showGrid: !0, showTooltip: !0 }
346
- };
347
- }
348
- }, R = /* @__PURE__ */ new Map();
349
- let ye = !1;
350
- function fe() {
351
- ye || (R.has("query") || R.set("query", U), R.has("funnel") || R.set("funnel", K), R.has("flow") || R.set("flow", N), ye = !0);
352
- }
353
- const _ = {
354
- /**
355
- * Register an adapter for a specific analysis type.
356
- * Should be called once at app initialization.
357
- *
358
- * @param adapter - The adapter to register
359
- */
360
- register(n) {
361
- R.has(n.type) && console.warn(
362
- `[adapterRegistry] Overwriting existing adapter for type: ${n.type}`
363
- ), R.set(n.type, n);
364
- },
365
- /**
366
- * Get the adapter for a specific analysis type.
367
- * Built-in adapters (query, funnel) are initialized automatically.
368
- *
369
- * @param type - The analysis type to get adapter for
370
- * @returns The registered adapter
371
- * @throws Error if no adapter is registered for the type
372
- */
373
- get(n) {
374
- fe();
375
- const i = R.get(n);
376
- if (!i)
377
- throw new Error(
378
- `[adapterRegistry] No adapter registered for type: ${n}. Available types: ${Array.from(R.keys()).join(", ") || "none"}`
379
- );
380
- return i;
381
- },
382
- /**
383
- * Check if an adapter is registered for a specific type.
384
- * Built-in adapters (query, funnel) are initialized automatically.
385
- *
386
- * @param type - The analysis type to check
387
- * @returns True if an adapter is registered
388
- */
389
- has(n) {
390
- return fe(), R.has(n);
391
- },
392
- /**
393
- * Get all registered analysis types.
394
- * Built-in adapters (query, funnel) are initialized automatically.
395
- *
396
- * @returns Array of registered types
397
- */
398
- getRegisteredTypes() {
399
- return fe(), Array.from(R.keys());
400
- },
401
- /**
402
- * Clear all registered adapters.
403
- * Primarily useful for testing.
404
- * Note: Built-in adapters will be re-initialized on next access.
405
- */
406
- clear() {
407
- R.clear(), ye = !1;
408
- }
409
- }, Ge = () => ({
410
- analysisType: "query",
411
- // Use adapter defaults as single source of truth for chart configuration
412
- charts: {
413
- query: U.getDefaultChartConfig(),
414
- funnel: K.getDefaultChartConfig(),
415
- flow: N.getDefaultChartConfig()
416
- },
417
- // Per-mode active view preference
418
- activeViews: {
419
- query: "chart",
420
- funnel: "chart",
421
- flow: "chart"
422
- },
423
- userManuallySelectedChart: !1,
424
- localPaletteName: "default"
425
- }), Cn = (n, i) => ({
426
- ...Ge(),
427
- setAnalysisType: (e) => {
428
- n((t) => {
429
- const r = { ...t.charts };
430
- if (!r[e]) {
431
- const a = _.get(e);
432
- r[e] = a.getDefaultChartConfig();
433
- }
434
- const s = { ...t.activeViews };
435
- return s[e] || (s[e] = "chart"), {
436
- analysisType: e,
437
- charts: r,
438
- activeViews: s,
439
- activeView: s[e] ?? "chart"
440
- };
441
- });
442
- },
443
- setChartType: (e) => {
444
- n((t) => {
445
- const r = t.analysisType, s = t.charts[r] || {
446
- chartType: e,
447
- chartConfig: {},
448
- displayConfig: {}
449
- };
450
- return {
451
- charts: {
452
- ...t.charts,
453
- [r]: { ...s, chartType: e }
454
- }
455
- };
456
- });
457
- },
458
- setChartTypeManual: (e) => {
459
- n((t) => {
460
- const r = t.analysisType, s = t.charts[r] || {
461
- chartType: e,
462
- chartConfig: {},
463
- displayConfig: {}
464
- };
465
- return {
466
- charts: {
467
- ...t.charts,
468
- [r]: { ...s, chartType: e }
469
- },
470
- userManuallySelectedChart: !0,
471
- activeView: "chart",
472
- activeViews: {
473
- ...t.activeViews,
474
- [r]: "chart"
475
- }
476
- };
477
- });
478
- },
479
- setChartConfig: (e) => {
480
- n((t) => {
481
- const r = t.analysisType, s = t.charts[r] || {
482
- chartType: "bar",
483
- chartConfig: e,
484
- displayConfig: {}
485
- };
486
- return {
487
- charts: {
488
- ...t.charts,
489
- [r]: { ...s, chartConfig: e }
490
- },
491
- activeView: "chart",
492
- activeViews: {
493
- ...t.activeViews,
494
- [r]: "chart"
495
- }
496
- };
497
- });
498
- },
499
- setDisplayConfig: (e) => {
500
- n((t) => {
501
- const r = t.analysisType, s = t.charts[r] || {
502
- chartType: "bar",
503
- chartConfig: {},
504
- displayConfig: e
505
- };
506
- return {
507
- charts: {
508
- ...t.charts,
509
- [r]: { ...s, displayConfig: e }
510
- },
511
- activeView: "chart",
512
- activeViews: {
513
- ...t.activeViews,
514
- [r]: "chart"
515
- }
516
- };
517
- });
518
- },
519
- setLocalPaletteName: (e) => n({ localPaletteName: e }),
520
- setUserManuallySelectedChart: (e) => n({ userManuallySelectedChart: e }),
521
- // @deprecated - Use setChartType() instead
522
- // Kept for backward compatibility
523
- setFunnelChartType: (e) => {
524
- n((t) => {
525
- const r = t.charts.funnel || {
526
- chartType: e,
527
- chartConfig: {},
528
- displayConfig: {}
529
- };
530
- return {
531
- charts: {
532
- ...t.charts,
533
- funnel: { ...r, chartType: e }
534
- }
535
- };
536
- });
537
- },
538
- // @deprecated - Use setChartConfig() instead
539
- // Kept for backward compatibility
540
- setFunnelChartConfig: (e) => {
541
- n((t) => {
542
- const r = t.charts.funnel || {
543
- chartType: "funnel",
544
- chartConfig: e,
545
- displayConfig: {}
546
- };
547
- return {
548
- charts: {
549
- ...t.charts,
550
- funnel: { ...r, chartConfig: e }
551
- }
552
- };
553
- });
554
- },
555
- // @deprecated - Use setDisplayConfig() instead
556
- // Kept for backward compatibility
557
- setFunnelDisplayConfig: (e) => {
558
- n((t) => {
559
- const r = t.charts.funnel || {
560
- chartType: "funnel",
561
- chartConfig: {},
562
- displayConfig: e
563
- };
564
- return {
565
- charts: {
566
- ...t.charts,
567
- funnel: { ...r, displayConfig: e }
568
- }
569
- };
570
- });
571
- },
572
- save: () => {
573
- const e = i(), t = _.get(e.analysisType), r = t.extractState(e), s = e.activeViews[e.analysisType] ?? e.activeView ?? "chart";
574
- return t.save(r, e.charts, s);
575
- },
576
- load: (e) => {
577
- const t = _.get(e.analysisType);
578
- if (!t.canLoad(e)) {
579
- console.warn("[coreSlice] Invalid config, cannot load");
580
- return;
581
- }
582
- const r = t.load(e), s = i(), a = {
583
- ...s.charts,
584
- ...e.charts
585
- };
586
- a[e.analysisType] || (a[e.analysisType] = t.getDefaultChartConfig());
587
- const l = {
588
- ...s.activeViews,
589
- [e.analysisType]: e.activeView
590
- };
591
- n({
592
- analysisType: e.analysisType,
593
- charts: a,
594
- activeView: e.activeView,
595
- activeViews: l,
596
- // Mode-specific state from adapter
597
- ...r
598
- });
599
- },
600
- saveWorkspace: () => {
601
- const e = i(), t = e, r = _.get("query"), s = r.extractState(t), a = e.activeViews.query ?? e.activeView ?? "chart", l = r.save(
602
- s,
603
- e.charts,
604
- a
605
- ), c = _.get("funnel"), f = c.extractState(t), y = e.activeViews.funnel ?? e.activeView ?? "chart", g = c.save(
606
- f,
607
- e.charts,
608
- y
609
- ), u = _.get("flow"), m = u.extractState(t), p = e.activeViews.flow ?? e.activeView ?? "chart", v = u.save(
610
- m,
611
- e.charts,
612
- p
613
- );
614
- return {
615
- version: 1,
616
- activeType: e.analysisType,
617
- modes: {
618
- query: l,
619
- funnel: g,
620
- flow: v
621
- }
622
- };
623
- },
624
- loadWorkspace: (e) => {
625
- const t = _.get("query"), r = _.get("funnel"), s = _.get("flow");
626
- let a = {}, l = {}, c = {}, f = { ...i().charts }, y = { ...i().activeViews };
627
- e.modes.query && t.canLoad(e.modes.query) && (a = t.load(e.modes.query), f = { ...f, ...e.modes.query.charts }, y.query = e.modes.query.activeView ?? "chart"), e.modes.funnel && r.canLoad(e.modes.funnel) && (l = r.load(e.modes.funnel), f = { ...f, ...e.modes.funnel.charts }, y.funnel = e.modes.funnel.activeView ?? "chart"), e.modes.flow && s.canLoad(e.modes.flow) && (c = s.load(e.modes.flow), f = { ...f, ...e.modes.flow.charts }, y.flow = e.modes.flow.activeView ?? "chart");
628
- const u = e.modes[e.activeType]?.activeView ?? "chart";
629
- n({
630
- analysisType: e.activeType,
631
- charts: f,
632
- activeViews: y,
633
- activeView: u,
634
- ...a,
635
- ...l,
636
- ...c
637
- });
638
- }
639
- }), ge = () => ({
640
- queryStates: [D()],
641
- activeQueryIndex: 0,
642
- mergeStrategy: "concat"
643
- }), wn = (n, i) => ({
644
- ...ge(),
645
- // ==========================================================================
646
- // Query State Management
647
- // ==========================================================================
648
- setQueryStates: (e) => n({ queryStates: e }),
649
- updateQueryState: (e, t) => n((r) => {
650
- const s = [...r.queryStates];
651
- return s[e] = t(s[e] || D()), { queryStates: s };
652
- }),
653
- setActiveQueryIndex: (e) => n({ activeQueryIndex: e }),
654
- setMergeStrategy: (e) => n({ mergeStrategy: e }),
655
- // ==========================================================================
656
- // Multi-Query Actions
657
- // ==========================================================================
658
- addQuery: () => n((e) => {
659
- const t = e.queryStates[e.activeQueryIndex] || D(), r = {
660
- ...D(),
661
- metrics: [...t.metrics],
662
- breakdowns: [...t.breakdowns],
663
- filters: [...t.filters]
664
- };
665
- return {
666
- queryStates: [...e.queryStates, r],
667
- activeQueryIndex: e.queryStates.length
668
- };
669
- }),
670
- removeQuery: (e) => n((t) => {
671
- if (t.queryStates.length <= 1) return t;
672
- const r = t.queryStates.filter((a, l) => l !== e);
673
- let s = t.activeQueryIndex;
674
- return e === t.activeQueryIndex ? s = Math.max(0, t.activeQueryIndex - 1) : e < t.activeQueryIndex && (s = t.activeQueryIndex - 1), { queryStates: r, activeQueryIndex: s };
675
- }),
676
- // ==========================================================================
677
- // Metrics Actions
678
- // ==========================================================================
679
- addMetric: (e, t) => n((r) => {
680
- const s = r.activeQueryIndex, a = [...r.queryStates], l = a[s] || D(), c = {
681
- id: E(),
682
- field: e,
683
- label: t || te(l.metrics.length)
684
- };
685
- return a[s] = {
686
- ...l,
687
- metrics: [...l.metrics, c]
688
- }, { queryStates: a };
689
- }),
690
- removeMetric: (e) => n((t) => {
691
- const r = t.activeQueryIndex, s = [...t.queryStates], a = s[r] || D(), l = a.metrics.find((y) => y.id === e)?.field, c = a.metrics.filter((y) => y.id !== e);
692
- let f = a.order;
693
- return l && f && f[l] && (f = { ...f }, delete f[l], Object.keys(f).length === 0 && (f = void 0)), s[r] = {
694
- ...a,
695
- metrics: c,
696
- order: f
697
- }, { queryStates: s };
698
- }),
699
- toggleMetric: (e) => n((t) => {
700
- const r = t.activeQueryIndex, s = [...t.queryStates], a = s[r] || D(), l = a.metrics.findIndex((c) => c.field === e);
701
- if (l >= 0)
702
- s[r] = {
703
- ...a,
704
- metrics: a.metrics.filter((c, f) => f !== l)
705
- };
706
- else {
707
- const c = {
708
- id: E(),
709
- field: e,
710
- label: te(a.metrics.length)
711
- };
712
- s[r] = {
713
- ...a,
714
- metrics: [...a.metrics, c]
715
- };
716
- }
717
- return { queryStates: s };
718
- }),
719
- reorderMetrics: (e, t) => n((r) => {
720
- const s = r.activeQueryIndex, a = [...r.queryStates], l = a[s] || D(), c = [...l.metrics], [f] = c.splice(e, 1);
721
- return c.splice(t, 0, f), a[s] = {
722
- ...l,
723
- metrics: c
724
- }, { queryStates: a };
725
- }),
726
- // ==========================================================================
727
- // Breakdowns Actions
728
- // ==========================================================================
729
- addBreakdown: (e, t, r) => n((s) => {
730
- const a = s.activeQueryIndex, l = [...s.queryStates], c = l[a] || D();
731
- if (t && c.breakdowns.some((g) => g.isTimeDimension))
732
- return s;
733
- const f = {
734
- id: E(),
735
- field: e,
736
- isTimeDimension: t,
737
- granularity: t ? r || "month" : void 0
738
- };
739
- return l[a] = {
740
- ...c,
741
- breakdowns: [...c.breakdowns, f]
742
- }, { queryStates: l };
743
- }),
744
- removeBreakdown: (e) => n((t) => {
745
- const r = t.activeQueryIndex, s = [...t.queryStates], a = s[r] || D(), l = a.breakdowns.find((y) => y.id === e)?.field, c = a.breakdowns.filter((y) => y.id !== e);
746
- let f = a.order;
747
- return l && f && f[l] && (f = { ...f }, delete f[l], Object.keys(f).length === 0 && (f = void 0)), s[r] = {
748
- ...a,
749
- breakdowns: c,
750
- order: f
751
- }, { queryStates: s };
752
- }),
753
- toggleBreakdown: (e, t, r) => n((s) => {
754
- const a = s.activeQueryIndex, l = [...s.queryStates], c = l[a] || D(), f = c.breakdowns.findIndex((y) => y.field === e);
755
- if (f >= 0)
756
- l[a] = {
757
- ...c,
758
- breakdowns: c.breakdowns.filter((y, g) => g !== f)
759
- };
760
- else {
761
- if (t && c.breakdowns.some((u) => u.isTimeDimension))
762
- return s;
763
- const y = {
764
- id: E(),
765
- field: e,
766
- isTimeDimension: t,
767
- granularity: t ? r || "month" : void 0
768
- };
769
- l[a] = {
770
- ...c,
771
- breakdowns: [...c.breakdowns, y]
772
- };
773
- }
774
- return { queryStates: l };
775
- }),
776
- setBreakdownGranularity: (e, t) => n((r) => {
777
- const { mergeStrategy: s, activeQueryIndex: a, queryStates: l } = r, c = [...l], f = s === "merge" && a > 0 ? 0 : a;
778
- return c[f] = {
779
- ...c[f],
780
- breakdowns: c[f].breakdowns.map(
781
- (y) => y.id === e ? { ...y, granularity: t } : y
782
- )
783
- }, { queryStates: c };
784
- }),
785
- toggleBreakdownComparison: (e) => n((t) => {
786
- const { mergeStrategy: r, activeQueryIndex: s, queryStates: a, charts: l, analysisType: c } = t, f = [...a], y = r === "merge" && s > 0 ? 0 : s, g = f[y].breakdowns.find((v) => v.id === e), u = g && !g.enableComparison, m = f[y].breakdowns.map((v) => v.id === e ? { ...v, enableComparison: !v.enableComparison } : v.isTimeDimension && v.enableComparison ? { ...v, enableComparison: !1 } : v);
787
- f[y] = {
788
- ...f[y],
789
- breakdowns: m
790
- };
791
- const p = { queryStates: f };
792
- if (u && g?.isTimeDimension && g.field) {
793
- const v = f[y].filters || [];
794
- if (!v.some((h) => {
795
- if ("member" in h) {
796
- const C = h;
797
- return C.member === g.field && C.operator === "inDateRange";
798
- }
799
- return !1;
800
- })) {
801
- const h = {
802
- member: g.field,
803
- operator: "inDateRange",
804
- values: [],
805
- dateRange: tn("last_n_months", 3)
806
- };
807
- f[y] = {
808
- ...f[y],
809
- filters: [...v, h]
810
- }, p.queryStates = f;
811
- }
812
- const q = l[c];
813
- q && q.chartType !== "line" && (p.charts = {
814
- ...l,
815
- [c]: {
816
- ...q,
817
- chartType: "line"
818
- }
819
- }, p.userManuallySelectedChart = !1, p.activeView = "chart", p.activeViews = {
820
- ...t.activeViews,
821
- [c]: "chart"
822
- });
823
- }
824
- return p;
825
- }),
826
- reorderBreakdowns: (e, t) => n((r) => {
827
- const s = r.activeQueryIndex, a = [...r.queryStates], l = a[s] || D(), c = [...l.breakdowns], [f] = c.splice(e, 1);
828
- return c.splice(t, 0, f), a[s] = {
829
- ...l,
830
- breakdowns: c
831
- }, { queryStates: a };
832
- }),
833
- // ==========================================================================
834
- // Filters Actions
835
- // ==========================================================================
836
- setFilters: (e) => n((t) => {
837
- const r = t.activeQueryIndex, s = [...t.queryStates];
838
- return s[r] = {
839
- ...s[r],
840
- filters: e
841
- }, { queryStates: s };
842
- }),
843
- dropFieldToFilter: (e) => n((t) => {
844
- const r = t.activeQueryIndex, s = [...t.queryStates], a = s[r] || D(), l = a.filters || [];
845
- if (l.some((g) => "member" in g && g.member === e)) return t;
846
- const f = {
847
- member: e,
848
- operator: "set",
849
- values: []
850
- };
851
- let y;
852
- if (l.length === 0)
853
- y = [f];
854
- else if (l.length === 1 && "type" in l[0]) {
855
- const g = l[0];
856
- y = [{ ...g, filters: [...g.filters, f] }];
857
- } else
858
- y = [{ type: "and", filters: [...l, f] }];
859
- return s[r] = {
860
- ...a,
861
- filters: y
862
- }, { queryStates: s };
863
- }),
864
- setOrder: (e, t) => n((r) => {
865
- const s = r.activeQueryIndex, a = [...r.queryStates], l = a[s] || D(), c = { ...l.order || {} };
866
- return t === null ? delete c[e] : c[e] = t, a[s] = {
867
- ...l,
868
- order: Object.keys(c).length > 0 ? c : void 0
869
- }, { queryStates: a };
870
- }),
871
- // ==========================================================================
872
- // Utility Actions
873
- // ==========================================================================
874
- getCurrentState: () => {
875
- const e = i();
876
- return e.queryStates[e.activeQueryIndex] || D();
877
- },
878
- getMergeKeys: () => {
879
- const e = i();
880
- if (e.mergeStrategy !== "merge" || e.queryStates.length === 0)
881
- return;
882
- const t = e.queryStates[0].breakdowns;
883
- if (t.length !== 0)
884
- return t.map((r) => r.field);
885
- },
886
- isMultiQueryMode: () => {
887
- const e = i();
888
- return e.queryStates.length <= 1 ? !1 : e.queryStates.filter(
889
- (r) => r.metrics.length > 0 || r.breakdowns.length > 0
890
- ).length > 1;
891
- },
892
- buildCurrentQuery: () => {
893
- const e = i(), t = e.queryStates[e.activeQueryIndex] || D();
894
- return ne(t.metrics, t.breakdowns, t.filters, t.order);
895
- },
896
- buildAllQueries: () => {
897
- const e = i(), t = e.queryStates[0]?.breakdowns || [];
898
- return e.queryStates.map((r, s) => {
899
- const a = e.mergeStrategy === "merge" && s > 0 ? t : r.breakdowns;
900
- return ne(r.metrics, a, r.filters, r.order);
901
- });
902
- },
903
- buildMultiQueryConfig: () => {
904
- const e = i();
905
- if (!i().isMultiQueryMode()) return null;
906
- const r = i().buildAllQueries().filter((s) => s.measures && s.measures.length > 0 || s.dimensions && s.dimensions.length > 0 || s.timeDimensions && s.timeDimensions.length > 0);
907
- return r.length < 2 ? null : {
908
- queries: r,
909
- mergeStrategy: e.mergeStrategy,
910
- mergeKeys: i().getMergeKeys(),
911
- queryLabels: r.map((s, a) => `Q${a + 1}`)
912
- };
913
- }
914
- }), me = () => ({
915
- funnelCube: null,
916
- funnelSteps: [],
917
- activeFunnelStepIndex: 0,
918
- funnelTimeDimension: null,
919
- funnelBindingKey: null,
920
- stepTimeToConvert: []
921
- // Deprecated - kept for backward compat
922
- }), vn = (n, i) => ({
923
- ...me(),
924
- addFunnelStep: () => n((e) => {
925
- const t = e.funnelSteps[e.funnelSteps.length - 1], r = {
926
- id: E(),
927
- name: `Step ${e.funnelSteps.length + 1}`,
928
- cube: e.funnelCube || "",
929
- // Deep copy filters from previous step, or empty array if first step
930
- filters: t?.filters ? JSON.parse(JSON.stringify(t.filters)) : [],
931
- // Copy timeToConvert from previous step
932
- timeToConvert: t?.timeToConvert
933
- };
934
- return {
935
- funnelSteps: [...e.funnelSteps, r],
936
- activeFunnelStepIndex: e.funnelSteps.length
937
- };
938
- }),
939
- removeFunnelStep: (e) => n((t) => {
940
- if (t.funnelSteps.length <= 1) return t;
941
- const r = t.funnelSteps.filter((a, l) => l !== e), s = Math.min(t.activeFunnelStepIndex, r.length - 1);
942
- return {
943
- funnelSteps: r,
944
- activeFunnelStepIndex: s
945
- };
946
- }),
947
- updateFunnelStep: (e, t) => n((r) => {
948
- const s = [...r.funnelSteps];
949
- return s[e] && (s[e] = { ...s[e], ...t }), { funnelSteps: s };
950
- }),
951
- setActiveFunnelStepIndex: (e) => n({ activeFunnelStepIndex: e }),
952
- reorderFunnelSteps: (e, t) => n((r) => {
953
- const s = [...r.funnelSteps], [a] = s.splice(e, 1);
954
- return s.splice(t, 0, a), { funnelSteps: s };
955
- }),
956
- setFunnelTimeDimension: (e) => n({ funnelTimeDimension: e }),
957
- setFunnelBindingKey: (e) => n({ funnelBindingKey: e }),
958
- setFunnelCube: (e) => n((t) => {
959
- const r = t.funnelSteps.map((s) => ({
960
- ...s,
961
- cube: e || ""
962
- }));
963
- return {
964
- funnelCube: e,
965
- // Clear binding key and time dimension since they may not exist in new cube
966
- funnelBindingKey: null,
967
- funnelTimeDimension: null,
968
- funnelSteps: r
969
- };
970
- }),
971
- // Deprecated: no-op - legacy queryStates-based funnels are no longer supported
972
- // Use updateFunnelStep with timeToConvert instead
973
- setStepTimeToConvert: () => {
974
- },
975
- // Deprecated: always returns null - legacy queryStates-based funnels are no longer supported
976
- // Use buildFunnelQueryFromSteps instead
977
- buildFunnelConfig: () => null,
978
- // New: Build ServerFunnelQuery from dedicated funnelSteps
979
- buildFunnelQueryFromSteps: () => {
980
- const e = i();
981
- if (e.analysisType !== "funnel" || !e.funnelBindingKey || !e.funnelTimeDimension || e.funnelSteps.length < 2) return null;
982
- const t = e.funnelSteps.filter((r) => r.cube && r.name);
983
- return t.length < 2 ? null : {
984
- funnel: {
985
- bindingKey: e.funnelBindingKey.dimension,
986
- timeDimension: e.funnelTimeDimension,
987
- steps: t.map((r) => ({
988
- name: r.name,
989
- cube: r.cube,
990
- filter: r.filters.length > 0 ? r.filters : void 0,
991
- timeToConvert: r.timeToConvert
992
- })),
993
- includeTimeMetrics: !0
994
- }
995
- };
996
- },
997
- isFunnelMode: () => i().analysisType === "funnel",
998
- isFunnelModeEnabled: () => {
999
- const e = i();
1000
- return e.analysisType !== "funnel" || !e.funnelBindingKey || !e.funnelTimeDimension || e.funnelSteps.length < 2 ? !1 : e.funnelSteps.filter((r) => r.cube && r.name).length >= 2;
1001
- }
1002
- }), he = () => ({
1003
- flowCube: null,
1004
- flowBindingKey: null,
1005
- flowTimeDimension: null,
1006
- startingStep: {
1007
- name: "",
1008
- filters: []
1009
- },
1010
- stepsBefore: 3,
1011
- stepsAfter: 3,
1012
- eventDimension: null,
1013
- joinStrategy: "auto"
1014
- }), bn = (n, i) => ({
1015
- ...he(),
1016
- setFlowCube: (e) => n(() => ({
1017
- flowCube: e,
1018
- // Clear binding key and time dimension since they may not exist in new cube
1019
- flowBindingKey: null,
1020
- flowTimeDimension: null,
1021
- eventDimension: null,
1022
- // Reset starting step filters when cube changes
1023
- startingStep: {
1024
- name: "",
1025
- filters: []
1026
- }
1027
- })),
1028
- setFlowBindingKey: (e) => n({ flowBindingKey: e }),
1029
- setFlowTimeDimension: (e) => n({ flowTimeDimension: e }),
1030
- setEventDimension: (e) => n({ eventDimension: e }),
1031
- setStartingStepName: (e) => n((t) => ({
1032
- startingStep: {
1033
- ...t.startingStep,
1034
- name: e
1035
- }
1036
- })),
1037
- setStartingStepFilters: (e) => n((t) => ({
1038
- startingStep: {
1039
- ...t.startingStep,
1040
- filters: e
1041
- }
1042
- })),
1043
- addStartingStepFilter: (e) => n((t) => ({
1044
- startingStep: {
1045
- ...t.startingStep,
1046
- filters: [...t.startingStep.filters, e]
1047
- }
1048
- })),
1049
- removeStartingStepFilter: (e) => n((t) => ({
1050
- startingStep: {
1051
- ...t.startingStep,
1052
- filters: t.startingStep.filters.filter((r, s) => s !== e)
1053
- }
1054
- })),
1055
- updateStartingStepFilter: (e, t) => n((r) => {
1056
- const s = [...r.startingStep.filters];
1057
- return s[e] && (s[e] = t), {
1058
- startingStep: {
1059
- ...r.startingStep,
1060
- filters: s
1061
- }
1062
- };
1063
- }),
1064
- setStepsBefore: (e) => n({
1065
- stepsBefore: Math.max(xe, Math.min(qe, e))
1066
- }),
1067
- setStepsAfter: (e) => n({
1068
- stepsAfter: Math.max(xe, Math.min(qe, e))
1069
- }),
1070
- setJoinStrategy: (e) => n(() => ({
1071
- joinStrategy: e
1072
- })),
1073
- isFlowMode: () => i().analysisType === "flow",
1074
- isFlowModeEnabled: () => {
1075
- const e = i();
1076
- return !(e.analysisType !== "flow" || !e.flowCube || !e.flowBindingKey?.dimension || !e.flowTimeDimension || !e.eventDimension || e.startingStep.filters.length === 0);
1077
- },
1078
- buildFlowQuery: () => {
1079
- const e = i();
1080
- if (e.analysisType !== "flow" || !e.flowBindingKey?.dimension || !e.flowTimeDimension || !e.eventDimension || e.startingStep.filters.length === 0) return null;
1081
- let t;
1082
- if (typeof e.flowBindingKey.dimension == "string")
1083
- t = e.flowBindingKey.dimension;
1084
- else if (Array.isArray(e.flowBindingKey.dimension))
1085
- t = e.flowBindingKey.dimension.map((c) => ({
1086
- cube: c.cube,
1087
- dimension: c.dimension
1088
- }));
1089
- else
1090
- return null;
1091
- const r = e.startingStep.filters.length === 1 ? e.startingStep.filters[0] : e.startingStep.filters, a = e.charts?.flow?.chartType === "sunburst" ? "sunburst" : "sankey", l = a === "sunburst" ? 0 : e.stepsBefore;
1092
- return {
1093
- flow: {
1094
- bindingKey: t,
1095
- timeDimension: e.flowTimeDimension,
1096
- startingStep: {
1097
- name: e.startingStep.name || "Starting Step",
1098
- filter: r
1099
- },
1100
- stepsBefore: l,
1101
- stepsAfter: e.stepsAfter,
1102
- eventDimension: e.eventDimension,
1103
- outputMode: a,
1104
- joinStrategy: e.joinStrategy
1105
- }
1106
- };
1107
- }
1108
- }), je = {
1109
- isOpen: !1,
1110
- userPrompt: "",
1111
- isGenerating: !1,
1112
- error: null,
1113
- hasGeneratedQuery: !1,
1114
- previousState: null
1115
- }, Dn = () => ({
1116
- activeTab: "query",
1117
- activeView: "chart",
1118
- displayLimit: 100,
1119
- showFieldModal: !1,
1120
- fieldModalMode: "metrics",
1121
- aiState: je
1122
- }), Tn = (n, i) => ({
1123
- ...Dn(),
1124
- // ==========================================================================
1125
- // Tab/View Actions
1126
- // ==========================================================================
1127
- setActiveTab: (e) => n({ activeTab: e }),
1128
- setActiveView: (e) => n((t) => ({
1129
- activeView: e,
1130
- activeViews: {
1131
- ...t.activeViews,
1132
- [t.analysisType]: e
1133
- }
1134
- })),
1135
- setDisplayLimit: (e) => n({ displayLimit: e }),
1136
- // ==========================================================================
1137
- // Field Modal Actions
1138
- // ==========================================================================
1139
- openMetricsModal: () => n({ showFieldModal: !0, fieldModalMode: "metrics" }),
1140
- openBreakdownsModal: () => n({ showFieldModal: !0, fieldModalMode: "breakdown" }),
1141
- closeFieldModal: () => n({ showFieldModal: !1 }),
1142
- // ==========================================================================
1143
- // AI Actions
1144
- // ==========================================================================
1145
- openAI: () => n((e) => ({
1146
- aiState: { ...e.aiState, isOpen: !0 }
1147
- })),
1148
- closeAI: () => n((e) => ({
1149
- aiState: { ...e.aiState, isOpen: !1 }
1150
- })),
1151
- setAIPrompt: (e) => n((t) => ({
1152
- aiState: { ...t.aiState, userPrompt: e }
1153
- })),
1154
- setAIGenerating: (e) => n((t) => ({
1155
- aiState: { ...t.aiState, isGenerating: e }
1156
- })),
1157
- setAIError: (e) => n((t) => ({
1158
- aiState: { ...t.aiState, error: e }
1159
- })),
1160
- setAIHasGeneratedQuery: (e) => n((t) => ({
1161
- aiState: { ...t.aiState, hasGeneratedQuery: e }
1162
- })),
1163
- saveAIPreviousState: () => n((e) => {
1164
- const t = e.queryStates[e.activeQueryIndex], r = e.charts[e.analysisType] || {
1165
- chartType: "bar",
1166
- chartConfig: {},
1167
- displayConfig: { showLegend: !0, showGrid: !0, showTooltip: !0 }
1168
- };
1169
- return {
1170
- aiState: {
1171
- ...e.aiState,
1172
- previousState: t ? {
1173
- metrics: [...t.metrics],
1174
- breakdowns: [...t.breakdowns],
1175
- filters: [...t.filters],
1176
- chartType: r.chartType,
1177
- chartConfig: { ...r.chartConfig },
1178
- displayConfig: { ...r.displayConfig }
1179
- } : null
1180
- }
1181
- };
1182
- }),
1183
- restoreAIPreviousState: () => n((e) => {
1184
- const t = e.aiState.previousState;
1185
- if (!t) return e;
1186
- const r = e.activeQueryIndex, s = [...e.queryStates];
1187
- return s[r] = {
1188
- ...s[r] || D(),
1189
- metrics: t.metrics,
1190
- breakdowns: t.breakdowns,
1191
- filters: t.filters
1192
- }, {
1193
- queryStates: s,
1194
- charts: {
1195
- ...e.charts,
1196
- [e.analysisType]: {
1197
- chartType: t.chartType,
1198
- chartConfig: t.chartConfig,
1199
- displayConfig: t.displayConfig
1200
- }
1201
- },
1202
- aiState: { ...je }
1203
- };
1204
- })
1205
- });
1206
- function Be(n) {
1207
- const i = n.filters ? [...n.filters] : [], e = n.timeDimensions || [], t = [
1208
- ...(n.dimensions || []).map((s) => ({
1209
- id: E(),
1210
- field: s,
1211
- isTimeDimension: !1
1212
- })),
1213
- ...e.map((s) => ({
1214
- id: E(),
1215
- field: s.dimension,
1216
- granularity: s.granularity,
1217
- isTimeDimension: !0,
1218
- enableComparison: !!(s.compareDateRange && s.compareDateRange.length > 0)
1219
- }))
1220
- ];
1221
- let r = i;
1222
- for (const s of e) {
1223
- if (!s.compareDateRange || s.compareDateRange.length === 0) continue;
1224
- const a = r.some(
1225
- (f) => "member" in f && f.member === s.dimension && f.operator === "inDateRange"
1226
- ), l = s.compareDateRange[0], c = Array.isArray(l) || typeof l == "string" ? l : void 0;
1227
- if (c) {
1228
- if (!a) {
1229
- r = [
1230
- ...r,
1231
- {
1232
- member: s.dimension,
1233
- operator: "inDateRange",
1234
- values: [],
1235
- dateRange: c
1236
- }
1237
- ];
1238
- continue;
1239
- }
1240
- r = r.map((f) => "member" in f && f.member === s.dimension && f.operator === "inDateRange" && !f.dateRange ? { ...f, dateRange: c } : f);
1241
- }
1242
- }
1243
- return {
1244
- ...D(),
1245
- metrics: (n.measures || []).map((s, a) => ({
1246
- id: E(),
1247
- field: s,
1248
- label: te(a)
1249
- })),
1250
- breakdowns: t,
1251
- filters: r,
1252
- order: n.order
1253
- };
1254
- }
1255
- function Qn(n) {
1256
- return "queries" in n && Array.isArray(n.queries);
1257
- }
1258
- function Fn(n) {
1259
- if (n.initialAnalysisType === "funnel" && n.initialFunnelState) {
1260
- const i = K.getDefaultChartConfig(), e = {
1261
- chartType: n.initialChartConfig?.chartType || i.chartType,
1262
- chartConfig: n.initialChartConfig?.chartConfig || i.chartConfig,
1263
- displayConfig: n.initialChartConfig?.displayConfig || i.displayConfig
1264
- }, t = {
1265
- funnelCube: n.initialFunnelState.funnelCube ?? null,
1266
- funnelSteps: n.initialFunnelState.funnelSteps || [],
1267
- activeFunnelStepIndex: 0,
1268
- funnelTimeDimension: n.initialFunnelState.funnelTimeDimension ?? null,
1269
- funnelBindingKey: n.initialFunnelState.funnelBindingKey ?? null
1270
- };
1271
- return K.save(
1272
- t,
1273
- { funnel: e },
1274
- n.initialActiveView || "chart"
1275
- );
1276
- }
1277
- if (n.initialAnalysisType === "flow" && n.initialFlowState) {
1278
- const i = N.getDefaultChartConfig(), e = {
1279
- chartType: n.initialChartConfig?.chartType || i.chartType,
1280
- chartConfig: n.initialChartConfig?.chartConfig || i.chartConfig,
1281
- displayConfig: n.initialChartConfig?.displayConfig || i.displayConfig
1282
- }, t = {
1283
- flowCube: n.initialFlowState.flowCube ?? null,
1284
- flowBindingKey: n.initialFlowState.flowBindingKey ?? null,
1285
- flowTimeDimension: n.initialFlowState.flowTimeDimension ?? null,
1286
- startingStep: n.initialFlowState.startingStep || { name: "", filters: [] },
1287
- stepsBefore: n.initialFlowState.stepsBefore ?? 3,
1288
- stepsAfter: n.initialFlowState.stepsAfter ?? 3,
1289
- eventDimension: n.initialFlowState.eventDimension ?? null,
1290
- joinStrategy: n.initialFlowState.joinStrategy ?? "auto"
1291
- };
1292
- return N.save(
1293
- t,
1294
- { flow: e },
1295
- n.initialActiveView || "chart"
1296
- );
1297
- }
1298
- if (n.initialQuery) {
1299
- const i = n.initialQuery;
1300
- let e, t = "concat";
1301
- Qn(i) ? (e = i.queries.map(Be), i.mergeStrategy && (t = i.mergeStrategy)) : e = [Be(i)];
1302
- const r = U.getDefaultChartConfig(), s = {
1303
- chartType: n.initialChartConfig?.chartType || r.chartType,
1304
- chartConfig: n.initialChartConfig?.chartConfig || r.chartConfig,
1305
- displayConfig: n.initialChartConfig?.displayConfig || r.displayConfig
1306
- };
1307
- return U.save(
1308
- { queryStates: e, activeQueryIndex: 0, mergeStrategy: t },
1309
- { query: s },
1310
- n.initialActiveView || "chart"
1311
- );
1312
- }
1313
- if (n.initialChartConfig) {
1314
- const i = U.getDefaultChartConfig(), e = {
1315
- chartType: n.initialChartConfig.chartType || i.chartType,
1316
- chartConfig: n.initialChartConfig.chartConfig || i.chartConfig,
1317
- displayConfig: n.initialChartConfig.displayConfig || i.displayConfig
1318
- };
1319
- return U.save(
1320
- { queryStates: [D()], activeQueryIndex: 0, mergeStrategy: "concat" },
1321
- { query: e },
1322
- n.initialActiveView || "chart"
1323
- );
1324
- }
1325
- return n.initialActiveView ? U.save(
1326
- { queryStates: [D()], activeQueryIndex: 0, mergeStrategy: "concat" },
1327
- { query: U.getDefaultChartConfig() },
1328
- n.initialActiveView
1329
- ) : null;
1330
- }
1331
- function Mn(n, i) {
1332
- return {
1333
- reset: () => {
1334
- n({
1335
- ...Ge(),
1336
- ...ge(),
1337
- ...me(),
1338
- ...he(),
1339
- // Apply adapter defaults for charts (may differ from slice defaults)
1340
- charts: {
1341
- query: U.getDefaultChartConfig(),
1342
- funnel: K.getDefaultChartConfig(),
1343
- flow: N.getDefaultChartConfig()
1344
- },
1345
- activeViews: {
1346
- query: "chart",
1347
- funnel: "chart",
1348
- flow: "chart"
1349
- }
1350
- });
1351
- },
1352
- clearCurrentMode: () => n((e) => {
1353
- switch (e.analysisType) {
1354
- case "funnel":
1355
- return {
1356
- ...me(),
1357
- charts: {
1358
- ...e.charts,
1359
- funnel: K.getDefaultChartConfig()
1360
- }
1361
- };
1362
- case "flow":
1363
- return {
1364
- ...he(),
1365
- charts: {
1366
- ...e.charts,
1367
- flow: N.getDefaultChartConfig()
1368
- }
1369
- };
1370
- default:
1371
- return {
1372
- ...ge(),
1373
- userManuallySelectedChart: !1,
1374
- charts: {
1375
- ...e.charts,
1376
- query: U.getDefaultChartConfig()
1377
- }
1378
- };
1379
- }
1380
- }),
1381
- clearQuery: () => n((e) => {
1382
- const t = [...e.queryStates];
1383
- return t[e.activeQueryIndex] = D(), {
1384
- queryStates: t,
1385
- userManuallySelectedChart: !1,
1386
- charts: {
1387
- ...e.charts,
1388
- query: U.getDefaultChartConfig()
1389
- }
1390
- };
1391
- }),
1392
- getValidation: () => {
1393
- const e = i(), t = _.get(e.analysisType), r = t.extractState(e);
1394
- return t.validate(r);
1395
- }
1396
- };
1397
- }
1398
- function An(n = {}) {
1399
- const i = Fn(n), e = (t, r, s) => ({
1400
- // Compose slices - they provide default state and actions
1401
- ...Cn(t, r),
1402
- ...wn(t, r),
1403
- ...vn(t, r),
1404
- ...bn(t, r),
1405
- ...Tn(t),
1406
- // Cross-slice actions
1407
- ...Mn(t, r)
1408
- });
1409
- if (n.disableLocalStorage) {
1410
- const t = Fe()(
1411
- Me(Ae(e), {
1412
- name: "AnalysisBuilderStore (no-persist)"
1413
- })
1414
- );
1415
- return i && t.getState().load(i), t;
1416
- }
1417
- return Fe()(
1418
- Me(
1419
- Ae(
1420
- zt(e, {
1421
- name: dn,
1422
- // Use workspace format to preserve ALL modes' state
1423
- partialize: (t) => t.saveWorkspace(),
1424
- merge: (t, r) => t && Yt(t) ? {
1425
- ...r,
1426
- _persistedWorkspace: t
1427
- } : t && $e(t) ? {
1428
- ...r,
1429
- _persistedConfig: t
1430
- } : i ? {
1431
- ...r,
1432
- _initialConfig: i
1433
- } : r,
1434
- onRehydrateStorage: () => (t) => {
1435
- if (t) {
1436
- if (t._persistedWorkspace) {
1437
- const r = t._persistedWorkspace;
1438
- delete t._persistedWorkspace, delete t._persistedConfig, delete t._initialConfig, t.loadWorkspace(r);
1439
- } else if (t._persistedConfig) {
1440
- const r = t._persistedConfig;
1441
- delete t._persistedConfig, delete t._initialConfig, t.load(r);
1442
- } else if (t._initialConfig) {
1443
- const r = t._initialConfig;
1444
- delete t._initialConfig, t.load(r);
1445
- }
1446
- }
1447
- }
1448
- })
1449
- ),
1450
- { name: "AnalysisBuilderStore" }
1451
- )
1452
- );
1453
- }
1454
- const pe = Ht(null);
1455
- function cr({
1456
- children: n,
1457
- initialQuery: i,
1458
- initialChartConfig: e,
1459
- disableLocalStorage: t,
1460
- initialAnalysisType: r,
1461
- initialFunnelState: s,
1462
- initialFlowState: a,
1463
- initialActiveView: l
1464
- }) {
1465
- const c = re(null);
1466
- return c.current || (c.current = An({
1467
- initialQuery: i,
1468
- initialChartConfig: e,
1469
- disableLocalStorage: t,
1470
- initialAnalysisType: r,
1471
- initialFunnelState: s,
1472
- initialFlowState: a,
1473
- initialActiveView: l
1474
- })), /* @__PURE__ */ jt(pe.Provider, { value: c.current, children: n });
1475
- }
1476
- function d(n) {
1477
- const i = Le(pe);
1478
- if (!i)
1479
- throw new Error("useAnalysisBuilderStore must be used within AnalysisBuilderStoreProvider");
1480
- return Wt(i, n);
1481
- }
1482
- function xn() {
1483
- const n = Le(pe);
1484
- if (!n)
1485
- throw new Error("useAnalysisBuilderStoreApi must be used within AnalysisBuilderStoreProvider");
1486
- return n;
1487
- }
1488
- const Se = (n) => n.queryStates[n.activeQueryIndex] || D(), fr = (n) => Se(n).metrics, dr = (n) => Se(n).breakdowns, yr = (n) => Se(n).filters, qn = (n) => {
1489
- const i = n.charts[n.analysisType];
1490
- return i ? {
1491
- chartType: i.chartType,
1492
- chartConfig: i.chartConfig,
1493
- displayConfig: i.displayConfig
1494
- } : {
1495
- chartType: "bar",
1496
- chartConfig: {},
1497
- displayConfig: { showLegend: !0, showGrid: !0, showTooltip: !0 }
1498
- };
1499
- }, gr = (n) => ({
1500
- activeTab: n.activeTab,
1501
- activeView: n.activeView,
1502
- displayLimit: n.displayLimit,
1503
- showFieldModal: n.showFieldModal,
1504
- fieldModalMode: n.fieldModalMode
1505
- }), mr = (n) => ({
1506
- queryStates: n.queryStates,
1507
- activeQueryIndex: n.activeQueryIndex,
1508
- mergeStrategy: n.mergeStrategy,
1509
- // Multi-query mode is when we have more than one query in 'query' analysis type
1510
- isMultiQueryMode: n.analysisType === "query" && n.queryStates.length > 1
1511
- }), hr = (n) => ({
1512
- funnelCube: n.funnelCube,
1513
- funnelSteps: n.funnelSteps,
1514
- activeFunnelStepIndex: n.activeFunnelStepIndex,
1515
- funnelTimeDimension: n.funnelTimeDimension,
1516
- funnelBindingKey: n.funnelBindingKey,
1517
- isFunnelMode: n.analysisType === "funnel",
1518
- // Deprecated field kept for backward compat
1519
- stepTimeToConvert: n.stepTimeToConvert
1520
- });
1521
- function Re(n) {
1522
- return n.timeDimensions || [];
1523
- }
1524
- function In(n) {
1525
- const i = [];
1526
- if (n.length < 2) return i;
1527
- const e = Re(n[0]);
1528
- if (e.length === 0) return i;
1529
- for (let t = 1; t < n.length; t++) {
1530
- const r = Re(n[t]);
1531
- if (r.length === 0 && e.length > 0) {
1532
- i.push({
1533
- type: "missing_time_dimension",
1534
- queryIndex: t,
1535
- message: `Query ${t + 1} is missing time dimension "${e[0].dimension}"`,
1536
- details: { field: e[0].dimension }
1537
- });
1538
- continue;
1539
- }
1540
- for (const s of e) {
1541
- const a = r.find((l) => l.dimension === s.dimension);
1542
- a && a.granularity !== s.granularity && i.push({
1543
- type: "granularity_mismatch",
1544
- queryIndex: t,
1545
- message: `Query ${t + 1} uses "${a.granularity}" granularity but Query 1 uses "${s.granularity}"`,
1546
- details: {
1547
- field: s.dimension,
1548
- expectedGranularity: s.granularity,
1549
- actualGranularity: a.granularity
1550
- }
1551
- });
1552
- }
1553
- }
1554
- return i;
1555
- }
1556
- function kn(n, i) {
1557
- const e = [];
1558
- if (n.length < 2 || i.length === 0) return e;
1559
- for (let t = 0; t < n.length; t++) {
1560
- const r = n[t], s = /* @__PURE__ */ new Set([
1561
- ...r.dimensions || [],
1562
- ...r.timeDimensions?.map((a) => a.dimension) || []
1563
- ]);
1564
- for (const a of i)
1565
- s.has(a) || e.push({
1566
- type: "missing_merge_key",
1567
- queryIndex: t,
1568
- message: `Query ${t + 1} is missing merge dimension "${a}"`,
1569
- details: { field: a }
1570
- });
1571
- }
1572
- return e;
1573
- }
1574
- function Bn(n) {
1575
- const i = [];
1576
- if (n.length < 2) return i;
1577
- const e = /* @__PURE__ */ new Map();
1578
- n.forEach((s, a) => {
1579
- s.measures?.forEach((l) => {
1580
- e.has(l) || e.set(l, []), e.get(l).push(a);
1581
- });
1582
- });
1583
- const t = [], r = /* @__PURE__ */ new Set();
1584
- return e.forEach((s, a) => {
1585
- s.length > 1 && (t.push(a), s.forEach((l) => r.add(l)));
1586
- }), t.length > 0 && i.push({
1587
- type: "measure_collision",
1588
- queryIndices: Array.from(r).sort(),
1589
- message: `Measure${t.length > 1 ? "s" : ""} "${t.join('", "')}" appear${t.length === 1 ? "s" : ""} in multiple queries - first value will be used`,
1590
- affectedMeasures: t
1591
- }), i;
1592
- }
1593
- function Rn(n) {
1594
- const i = [];
1595
- if (n.length < 2) return i;
1596
- const e = n.map((r) => r.timeDimensions?.[0]?.dateRange);
1597
- return new Set(e.map((r) => JSON.stringify(r))).size > 1 && i.push({
1598
- type: "asymmetric_date_range",
1599
- queryIndices: n.map((r, s) => s),
1600
- message: "Queries have different date ranges - some data points may be missing in merged results"
1601
- }), i;
1602
- }
1603
- function Vn(n, i, e = []) {
1604
- const t = [], r = [];
1605
- return n.length < 2 ? { isValid: !0, errors: t, warnings: r } : (r.push(...Bn(n)), r.push(...Rn(n)), i === "merge" && (t.push(...In(n)), e.length > 0 && t.push(...kn(n, e))), {
1606
- isValid: t.length === 0,
1607
- errors: t,
1608
- warnings: r
1609
- });
1610
- }
1611
- function pr(n) {
1612
- return n.filter(
1613
- (i) => (i.measures?.length || 0) + (i.dimensions?.length || 0) + (i.timeDimensions?.length || 0) > 0
1614
- ).length >= 2;
1615
- }
1616
- function Sr(n) {
1617
- if (n.isValid && n.warnings.length === 0)
1618
- return "Configuration is valid";
1619
- const i = [];
1620
- return n.errors.length > 0 && i.push(`${n.errors.length} error${n.errors.length > 1 ? "s" : ""}`), n.warnings.length > 0 && i.push(`${n.warnings.length} warning${n.warnings.length > 1 ? "s" : ""}`), i.join(", ");
1621
- }
1622
- function Un() {
1623
- const n = d((h) => h.queryStates), i = d((h) => h.activeQueryIndex), e = d((h) => h.mergeStrategy), t = d((h) => h.setActiveQueryIndex), r = d((h) => h.setMergeStrategy), s = d((h) => h.addQuery), a = d((h) => h.removeQuery), l = d((h) => h.getCurrentState), c = d((h) => h.getMergeKeys), f = d((h) => h.isMultiQueryMode), y = l(), g = f(), u = c(), m = T(() => {
1624
- const h = n[i] || y;
1625
- return ne(h.metrics, h.breakdowns, h.filters, h.order);
1626
- }, [n, i, y]), p = T(() => {
1627
- const h = n[0]?.breakdowns || [];
1628
- return n.map((C, w) => {
1629
- const b = e === "merge" && w > 0 ? h : C.breakdowns;
1630
- return ne(C.metrics, b, C.filters, C.order);
1631
- });
1632
- }, [n, e]), v = T(() => {
1633
- if (n.length <= 1) return null;
1634
- const h = p.filter((C) => C.measures && C.measures.length > 0 || C.dimensions && C.dimensions.length > 0 || C.timeDimensions && C.timeDimensions.length > 0);
1635
- return h.length < 2 ? null : {
1636
- queries: h,
1637
- mergeStrategy: e,
1638
- mergeKeys: u,
1639
- queryLabels: h.map((C, w) => `Q${w + 1}`)
1640
- };
1641
- }, [p, n.length, e, u]), V = T(() => g ? Vn(p, e, u || []) : null, [g, p, e, u]), q = T(() => m.measures && m.measures.length > 0 || m.dimensions && m.dimensions.length > 0 || m.timeDimensions && m.timeDimensions.length > 0, [m]);
1642
- return {
1643
- queryState: y,
1644
- queryStates: n,
1645
- activeQueryIndex: i,
1646
- mergeStrategy: e,
1647
- isMultiQueryMode: g,
1648
- mergeKeys: u,
1649
- currentQuery: m,
1650
- allQueries: p,
1651
- multiQueryConfig: v,
1652
- multiQueryValidation: V,
1653
- isValidQuery: q,
1654
- // Actions
1655
- setActiveQueryIndex: t,
1656
- setMergeStrategy: r,
1657
- addQuery: s,
1658
- removeQuery: a
1659
- };
1660
- }
1661
- function En(n) {
1662
- const { queryState: i, queryStates: e, isMultiQueryMode: t, mergeStrategy: r, activeQueryIndex: s } = n, a = T(() => {
1663
- if (!t) return i.metrics;
1664
- const f = /* @__PURE__ */ new Set(), y = [];
1665
- for (let g = 0; g < e.length; g++) {
1666
- const u = e[g];
1667
- for (const m of u.metrics) {
1668
- const p = `Q${g + 1}:${m.field}`;
1669
- f.has(p) || (f.add(p), y.push({
1670
- ...m,
1671
- label: `${m.label} (Q${g + 1})`
1672
- }));
1673
- }
1674
- }
1675
- return y;
1676
- }, [t, e, i.metrics]), l = T(() => {
1677
- if (!t) return i.breakdowns;
1678
- const f = /* @__PURE__ */ new Set(), y = [];
1679
- for (const g of e)
1680
- for (const u of g.breakdowns)
1681
- f.has(u.field) || (f.add(u.field), y.push(u));
1682
- return y;
1683
- }, [t, e, i.breakdowns]), c = T(() => r === "merge" && s > 0 ? e[0]?.breakdowns || [] : i.breakdowns, [r, s, e, i.breakdowns]);
1684
- return {
1685
- combinedMetrics: a,
1686
- combinedBreakdowns: l,
1687
- effectiveBreakdowns: c
1688
- };
1689
- }
1690
- function _n(n) {
1691
- const {
1692
- currentQuery: i,
1693
- allQueries: e,
1694
- multiQueryConfig: t,
1695
- isMultiQueryMode: r,
1696
- isValidQuery: s,
1697
- initialData: a,
1698
- // Unused - legacy mergeStrategy === 'funnel' is no longer supported
1699
- funnelBindingKey: l,
1700
- isFunnelModeEnabled: c,
1701
- analysisType: f,
1702
- serverFunnelQuery: y,
1703
- serverFlowQuery: g
1704
- } = n, u = f === "funnel" || c, m = f === "flow", p = f === "query" && r, v = f === "query" && !r, V = f === "funnel" && !!y, q = T(() => V || !u || !l || e.length < 2 ? null : sn(e, l), [V, u, l, e]), h = nn(i, {
1705
- skip: !s || !v,
1706
- debounceMs: 300
1707
- }), C = rn(t, {
1708
- skip: !t || !p,
1709
- debounceMs: 300
1710
- }), w = Xt(q, {
1711
- skip: !u || !q && !y,
1712
- debounceMs: 300,
1713
- prebuiltServerQuery: V ? y : void 0
1714
- }), b = Zt(g ?? null, {
1715
- skip: !m || !g,
1716
- debounceMs: 300
1717
- }), P = an({
1718
- queries: r ? e : [i],
1719
- isMultiQueryMode: r,
1720
- skip: !s || u || m
1721
- }), $ = on(
1722
- w.serverQuery,
1723
- { skip: !u || !w.serverQuery }
1724
- ), L = ln(
1725
- b.serverQuery,
1726
- { skip: !m || !b.serverQuery }
1727
- ), S = m ? b.isLoading || b.isDebouncing : u ? w.isExecuting || w.isDebouncing : p ? C.isLoading : h.isLoading, I = m ? b.isFetching : u ? w.isExecuting : p ? C.isFetching : h.isFetching, A = m ? b.error : u ? w.error : p ? C.error : h.error, H = !!(h.debouncedQuery || C.debouncedConfig || !w.isDebouncing || // Funnel has debounced when not debouncing
1728
- !b.isDebouncing), ie = B((k) => {
1729
- m ? b.refetch(k) : u ? w.execute(k) : p ? C.refetch(k) : h.refetch(k);
1730
- }, [m, u, p, b, w, C, h]), J = T(() => {
1731
- const k = m ? b.data : u ? w.chartData : p ? C.data : h.rawData;
1732
- return a && a.length > 0 && !k ? "success" : s ? S && !k ? "loading" : I && k ? "refreshing" : A ? "error" : k ? "success" : "idle" : "idle";
1733
- }, [s, S, I, A, h.rawData, C.data, w.chartData, b.data, a, p, u, m]), O = T(() => m && b.data ? [b.data] : u && w.chartData ? w.chartData : p && C.data ? C.data : h.rawData ? h.rawData : a && a.length > 0 ? a : null, [h.rawData, C.data, w.chartData, b.data, a, p, u, m]), Y = T(() => u && w.stepResults ? w.stepResults.map((k) => k.data) : !p || !C.perQueryData ? null : C.perQueryData, [p, u, C.perQueryData, w.stepResults]), G = u && w.executedQueries?.length > 0 ? w.executedQueries : null, j = u ? w.serverQuery : null, M = u ? $.debugData : null, Q = m ? b.serverQuery : null, F = m ? b.data : null, se = m ? L.debugData : null;
1734
- return {
1735
- executionStatus: J,
1736
- executionResults: O,
1737
- perQueryResults: Y,
1738
- isLoading: S,
1739
- isFetching: I,
1740
- error: A,
1741
- debugDataPerQuery: P.debugDataPerQuery,
1742
- hasDebounced: H,
1743
- refetch: ie,
1744
- funnelExecutedQueries: G,
1745
- funnelServerQuery: j,
1746
- funnelDebugData: M,
1747
- flowServerQuery: Q,
1748
- flowChartData: F,
1749
- flowDebugData: se
1750
- };
1751
- }
1752
- function We(n) {
1753
- return n.isTimeDimension;
1754
- }
1755
- function Ln(n) {
1756
- return n.find(We);
1757
- }
1758
- function Pn(n) {
1759
- return n.find((i) => !i.isTimeDimension);
1760
- }
1761
- function Ce(n) {
1762
- return n.filter((i) => !i.isTimeDimension);
1763
- }
1764
- function ze(n) {
1765
- return n.filter(We);
1766
- }
1767
- function we(n, i, e) {
1768
- const t = i.length, r = Ce(e).length, s = ze(e).length, a = e.length;
1769
- switch (n) {
1770
- // Always available charts
1771
- case "table":
1772
- case "markdown":
1773
- return { available: !0 };
1774
- // Measure-only charts (KPI Number, KPI Text)
1775
- case "kpiNumber":
1776
- case "kpiText":
1777
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : { available: !0 };
1778
- // Bar chart - needs dimension for categories + measure for values
1779
- case "bar":
1780
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : a < 1 ? { available: !1, reason: "Requires at least 1 breakdown for categories" } : { available: !0 };
1781
- // KPI Delta - needs dimension for ordering + measure for values
1782
- case "kpiDelta":
1783
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : a < 1 ? { available: !1, reason: "Requires at least 1 breakdown for ordering" } : { available: !0 };
1784
- // Line and area charts - need dimension/time + measure
1785
- case "line":
1786
- case "area":
1787
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : a < 1 ? { available: !1, reason: "Requires a breakdown (dimension or time)" } : { available: !0 };
1788
- // Pie chart - needs dimension (not time) + measure
1789
- case "pie":
1790
- return t < 1 ? { available: !1, reason: "Requires 1 measure" } : r < 1 ? { available: !1, reason: "Requires 1 dimension (not time dimension)" } : { available: !0 };
1791
- // Scatter - needs measure + any breakdown
1792
- case "scatter":
1793
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : t < 2 && a < 1 ? { available: !1, reason: "Requires 2 measures or 1 measure + 1 breakdown" } : { available: !0 };
1794
- // Bubble - needs 2+ measures and 1+ breakdown (dimension or time dimension for series)
1795
- case "bubble":
1796
- return t < 2 ? { available: !1, reason: "Requires at least 2 measures" } : a < 1 ? { available: !1, reason: "Requires at least 1 breakdown for series grouping" } : { available: !0 };
1797
- // Radar - needs dimension + measure
1798
- case "radar":
1799
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : r < 1 ? { available: !1, reason: "Requires at least 1 dimension" } : { available: !0 };
1800
- // Radial Bar - needs dimension + measure
1801
- case "radialBar":
1802
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : r < 1 ? { available: !1, reason: "Requires at least 1 dimension" } : { available: !0 };
1803
- // Treemap - needs dimension + measure
1804
- case "treemap":
1805
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : r < 1 ? { available: !1, reason: "Requires at least 1 dimension" } : { available: !0 };
1806
- // Activity Grid - needs time dimension + measure
1807
- case "activityGrid":
1808
- return t < 1 ? { available: !1, reason: "Requires at least 1 measure" } : s < 1 ? { available: !1, reason: "Requires a time dimension" } : { available: !0 };
1809
- default:
1810
- return { available: !0 };
1811
- }
1812
- }
1813
- function $n(n, i) {
1814
- const e = [
1815
- "activityGrid",
1816
- "area",
1817
- "bar",
1818
- "bubble",
1819
- "kpiDelta",
1820
- "kpiNumber",
1821
- "kpiText",
1822
- "line",
1823
- "markdown",
1824
- "pie",
1825
- "radar",
1826
- "radialBar",
1827
- "scatter",
1828
- "table",
1829
- "treemap"
1830
- ], t = {};
1831
- for (const r of e)
1832
- t[r] = we(r, n, i);
1833
- return t;
1834
- }
1835
- function Je(n, i, e) {
1836
- if (we(e, n, i).available || n.length === 0 && i.length === 0)
1837
- return e;
1838
- const r = ze(i).length > 0, s = Ce(i).length > 0, a = n.length > 0;
1839
- return r && a ? "line" : s && a ? "bar" : a && !s && !r ? "kpiNumber" : "table";
1840
- }
1841
- function de(n, i, e) {
1842
- const t = Je(n, i, e), r = Kn(t, n, i);
1843
- return { chartType: t, chartConfig: r };
1844
- }
1845
- function Kn(n, i, e) {
1846
- const t = Ln(e), r = Pn(e), s = Ce(e), a = e;
1847
- switch (n) {
1848
- case "line":
1849
- case "area":
1850
- return {
1851
- xAxis: t ? [t.field] : r ? [r.field] : [],
1852
- yAxis: i.map((l) => l.field),
1853
- series: s.length > 1 ? [s[1].field] : r && t ? [r.field] : []
1854
- };
1855
- case "bar":
1856
- return {
1857
- xAxis: r ? [r.field] : t ? [t.field] : [],
1858
- yAxis: i.map((l) => l.field),
1859
- series: s.length > 1 ? [s[1].field] : t && r ? [t.field] : []
1860
- };
1861
- case "pie":
1862
- return {
1863
- xAxis: r ? [r.field] : [],
1864
- yAxis: i.length > 0 ? [i[0].field] : []
1865
- };
1866
- case "scatter":
1867
- return i.length >= 2 ? {
1868
- xAxis: [i[0].field],
1869
- yAxis: [i[1].field],
1870
- series: r ? [r.field] : []
1871
- } : {
1872
- xAxis: a.length > 0 ? [a[0].field] : [],
1873
- yAxis: i.length > 0 ? [i[0].field] : [],
1874
- series: s.length > 1 ? [s[1].field] : []
1875
- };
1876
- case "bubble":
1877
- return {
1878
- xAxis: i.length > 0 ? [i[0].field] : [],
1879
- yAxis: i.length > 1 ? [i[1].field] : [],
1880
- sizeField: i.length > 2 ? i[2].field : i.length > 1 ? i[1].field : void 0,
1881
- series: r ? [r.field] : t ? [t.field] : []
1882
- };
1883
- case "radar":
1884
- case "radialBar":
1885
- case "treemap":
1886
- return {
1887
- xAxis: r ? [r.field] : [],
1888
- yAxis: i.length > 0 ? [i[0].field] : []
1889
- };
1890
- case "activityGrid":
1891
- return {
1892
- dateField: t ? [t.field] : [],
1893
- valueField: i.length > 0 ? [i[0].field] : []
1894
- };
1895
- case "kpiNumber":
1896
- case "kpiDelta":
1897
- case "kpiText":
1898
- return {
1899
- yAxis: i.length > 0 ? [i[0].field] : []
1900
- };
1901
- case "table":
1902
- return {
1903
- xAxis: [
1904
- ...e.map((l) => l.field),
1905
- ...i.map((l) => l.field)
1906
- ]
1907
- };
1908
- case "markdown":
1909
- return {};
1910
- default:
1911
- return {
1912
- xAxis: a.length > 0 ? [a[0].field] : [],
1913
- yAxis: i.map((l) => l.field)
1914
- };
1915
- }
1916
- }
1917
- function Nn(n, i, e, t) {
1918
- if (t && we(e, n, i).available)
1919
- return null;
1920
- const r = Je(n, i, e);
1921
- return r !== e ? r : null;
1922
- }
1923
- function Hn(n) {
1924
- const { externalColorPalette: i, combinedMetrics: e, combinedBreakdowns: t, hasDebounced: r } = n, s = d((S) => S.analysisType), { chartType: a, chartConfig: l, displayConfig: c } = d(Jt(qn)), f = d((S) => S.userManuallySelectedChart), y = d((S) => S.localPaletteName), g = d((S) => S.setChartTypeManual), u = d((S) => S.setChartConfig), m = d((S) => S.setDisplayConfig), p = d((S) => S.setFunnelChartType), v = d((S) => S.setFunnelChartConfig), V = d((S) => S.setFunnelDisplayConfig), q = d((S) => S.setLocalPaletteName), h = d((S) => S.setUserManuallySelectedChart), C = B(
1925
- (S) => {
1926
- if (s === "funnel")
1927
- p(S);
1928
- else {
1929
- g(S);
1930
- const { chartConfig: I } = de(
1931
- e,
1932
- t,
1933
- S
1934
- );
1935
- u(I);
1936
- }
1937
- },
1938
- [
1939
- s,
1940
- e,
1941
- t,
1942
- p,
1943
- g,
1944
- u
1945
- ]
1946
- ), w = B(
1947
- (S) => {
1948
- s === "funnel" ? v(S) : u(S);
1949
- },
1950
- [s, v, u]
1951
- ), b = B(
1952
- (S) => {
1953
- s === "funnel" ? V(S) : m(S);
1954
- },
1955
- [s, V, m]
1956
- ), P = T(
1957
- () => $n(e, t),
1958
- [e, t]
1959
- ), $ = T(() => i ? Array.isArray(i) && typeof i[0] == "string" ? {
1960
- name: "custom",
1961
- label: "Custom",
1962
- colors: i,
1963
- gradient: i
1964
- } : i : en(y), [i, y]), L = re("");
1965
- return ee(() => {
1966
- if (!r || e.length === 0 && t.length === 0) return;
1967
- const S = JSON.stringify({
1968
- metrics: e.map((A) => A.field),
1969
- breakdowns: t.map((A) => ({ field: A.field, isTime: A.isTimeDimension }))
1970
- });
1971
- if (S === L.current) return;
1972
- L.current = S;
1973
- const I = Nn(
1974
- e,
1975
- t,
1976
- a,
1977
- f
1978
- );
1979
- if (I) {
1980
- const { chartConfig: A } = de(
1981
- e,
1982
- t,
1983
- I
1984
- );
1985
- C(I), w(A), h(!1);
1986
- } else if ((e.length > 0 || t.length > 0) && !l.xAxis?.length && !l.yAxis?.length && !l.series?.length) {
1987
- const { chartConfig: H } = de(
1988
- e,
1989
- t,
1990
- a
1991
- );
1992
- w(H);
1993
- }
1994
- }, [
1995
- r,
1996
- e,
1997
- t,
1998
- a,
1999
- f,
2000
- l,
2001
- C,
2002
- w,
2003
- h
2004
- ]), {
2005
- chartType: a,
2006
- chartConfig: l,
2007
- displayConfig: c,
2008
- colorPalette: $,
2009
- localPaletteName: y,
2010
- chartAvailability: P,
2011
- userManuallySelectedChart: f,
2012
- // Actions - mode-aware setters route to appropriate store fields
2013
- setChartType: C,
2014
- setChartConfig: w,
2015
- setDisplayConfig: b,
2016
- setLocalPaletteName: q
2017
- };
2018
- }
2019
- function On() {
2020
- const n = d((u) => u.activeTab), i = d((u) => u.activeView), e = d((u) => u.displayLimit), t = d((u) => u.showFieldModal), r = d((u) => u.fieldModalMode), s = d((u) => u.userManuallySelectedChart), a = d((u) => u.setActiveTab), l = d((u) => u.setActiveView), c = d((u) => u.setDisplayLimit), f = d((u) => u.closeFieldModal), [y, g] = Ot(0);
2021
- return {
2022
- // State
2023
- activeTab: n,
2024
- activeView: i,
2025
- displayLimit: e,
2026
- showFieldModal: t,
2027
- fieldModalMode: r,
2028
- activeTableIndex: y,
2029
- userManuallySelectedChart: s,
2030
- // Actions
2031
- setActiveTab: a,
2032
- setActiveView: l,
2033
- setDisplayLimit: c,
2034
- closeFieldModal: f,
2035
- setActiveTableIndex: g
2036
- };
2037
- }
2038
- const Ve = 1800, Ue = "share=";
2039
- function Ee(n) {
2040
- const i = JSON.stringify(n);
2041
- return Pe.compressToEncodedURIComponent(i);
2042
- }
2043
- function Gn(n) {
2044
- try {
2045
- const i = Pe.decompressFromEncodedURIComponent(n);
2046
- if (!i) return null;
2047
- const e = JSON.parse(i);
2048
- return $e(e) ? e : (console.warn("[shareUtils] Invalid AnalysisConfig in share URL"), null);
2049
- } catch {
2050
- return null;
2051
- }
2052
- }
2053
- function Cr(n) {
2054
- const i = Ee(n);
2055
- if (i.length <= Ve)
2056
- return { encoded: i, queryOnly: !1 };
2057
- const e = {
2058
- version: n.version,
2059
- analysisType: n.analysisType,
2060
- activeView: n.activeView,
2061
- charts: {},
2062
- // Drop chart config to save space
2063
- query: n.query
2064
- }, t = Ee(e);
2065
- return t.length <= Ve ? { encoded: t, queryOnly: !0 } : { encoded: null, queryOnly: !0 };
2066
- }
2067
- function jn() {
2068
- if (typeof window > "u") return null;
2069
- const n = window.location.hash;
2070
- return !n || !n.startsWith(`#${Ue}`) ? null : n.slice(Ue.length + 1);
2071
- }
2072
- function Wn() {
2073
- if (typeof window > "u") return;
2074
- const n = new URL(window.location.href);
2075
- n.hash = "", window.history.replaceState(null, "", n.toString());
2076
- }
2077
- function zn() {
2078
- const n = jn();
2079
- return n ? Gn(n) : null;
2080
- }
2081
- function Jn(n) {
2082
- const {
2083
- currentQuery: i,
2084
- isValidQuery: e,
2085
- chartType: t,
2086
- chartConfig: r,
2087
- displayConfig: s,
2088
- onQueryChange: a,
2089
- onChartConfigChange: l
2090
- } = n, c = d((y) => y.load), f = re(!1);
2091
- ee(() => {
2092
- if (f.current) return;
2093
- f.current = !0;
2094
- const y = zn();
2095
- y && (c(y), Wn());
2096
- }, [c]), ee(() => {
2097
- a && e && a(i);
2098
- }, [i, e, a]), ee(() => {
2099
- l && l({
2100
- chartType: t,
2101
- chartConfig: r,
2102
- displayConfig: s
2103
- });
2104
- }, [t, r, s, l]);
2105
- }
2106
- function wr(n = {}) {
2107
- const { initialData: i, externalColorPalette: e, onQueryChange: t, onChartConfigChange: r } = n, { features: s } = Gt(), a = xn(), l = Un(), c = En({
2108
- queryState: l.queryState,
2109
- queryStates: l.queryStates,
2110
- isMultiQueryMode: l.isMultiQueryMode,
2111
- mergeStrategy: l.mergeStrategy,
2112
- activeQueryIndex: l.activeQueryIndex
2113
- }), f = d((o) => o.funnelBindingKey), y = d((o) => o.analysisType), g = d((o) => o.funnelCube), u = d((o) => o.funnelSteps), m = d((o) => o.activeFunnelStepIndex), p = d((o) => o.funnelTimeDimension), v = T(() => y !== "funnel" || !f?.dimension || !p || !u || u.length < 2 ? !1 : u.every((o) => o.filters.length > 0), [y, f, p, u]), V = d((o) => o.charts.funnel?.chartType) || "funnel", q = d((o) => o.charts.funnel?.chartConfig), h = T(() => q || {}, [q]), C = d((o) => o.flowCube), w = d((o) => o.flowBindingKey), b = d((o) => o.flowTimeDimension), P = d((o) => o.eventDimension), $ = d((o) => o.startingStep), L = d((o) => o.stepsBefore), S = d((o) => o.stepsAfter), I = d((o) => o.joinStrategy), A = d((o) => o.charts.flow?.displayConfig), H = T(
2114
- () => A || { showLegend: !0, showGrid: !0, showTooltip: !0 },
2115
- [A]
2116
- ), ie = d((o) => o.charts.flow?.chartType) || "sankey", J = d((o) => o.buildFunnelQueryFromSteps), O = T(() => y !== "funnel" ? null : J(), [y, J, u]), Y = d((o) => o.buildFlowQuery), G = T(() => y !== "flow" ? null : Y(), [y, Y, C, w, b, P, $, L, S, ie, I]), j = T(() => y === "flow" ? G !== null : y === "funnel" ? O !== null : l.isValidQuery ?? !1, [y, G, O, l.isValidQuery]), M = _n({
2117
- currentQuery: l.currentQuery,
2118
- allQueries: l.allQueries,
2119
- multiQueryConfig: l.multiQueryConfig,
2120
- isMultiQueryMode: l.isMultiQueryMode,
2121
- isValidQuery: j,
2122
- initialData: i,
2123
- funnelBindingKey: f,
2124
- isFunnelModeEnabled: v,
2125
- // New: pass analysisType and serverFunnelQuery for explicit mode routing
2126
- analysisType: y,
2127
- serverFunnelQuery: O,
2128
- // Flow mode: pass serverFlowQuery
2129
- serverFlowQuery: G
2130
- }), Q = Hn({
2131
- externalColorPalette: e,
2132
- combinedMetrics: c.combinedMetrics,
2133
- combinedBreakdowns: c.combinedBreakdowns,
2134
- hasDebounced: M.hasDebounced
2135
- }), F = On();
2136
- Jn({
2137
- currentQuery: l.currentQuery,
2138
- isValidQuery: l.isValidQuery ?? !1,
2139
- chartType: Q.chartType,
2140
- chartConfig: Q.chartConfig,
2141
- displayConfig: Q.displayConfig,
2142
- onQueryChange: t,
2143
- onChartConfigChange: r
2144
- });
2145
- const se = d((o) => o.openMetricsModal), k = d((o) => o.addMetric), Ye = d((o) => o.removeMetric), ae = d((o) => o.toggleMetric), Xe = d((o) => o.reorderMetrics), Ze = d((o) => o.openBreakdownsModal), et = d((o) => o.addBreakdown), tt = d((o) => o.removeBreakdown), oe = d((o) => o.toggleBreakdown), nt = d((o) => o.setBreakdownGranularity), rt = d((o) => o.toggleBreakdownComparison), it = d((o) => o.reorderBreakdowns), st = d((o) => o.setFilters), at = d((o) => o.dropFieldToFilter), ot = d((o) => o.setOrder), lt = d((o) => o.clearQuery), ut = d((o) => o.clearCurrentMode), ct = d((o) => o.setFunnelBindingKey), ft = d((o) => o.setAnalysisType), dt = d((o) => o.setFunnelCube), yt = d((o) => o.addFunnelStep), gt = d((o) => o.removeFunnelStep), mt = d((o) => o.updateFunnelStep), ht = d((o) => o.setActiveFunnelStepIndex), pt = d((o) => o.reorderFunnelSteps), St = d((o) => o.setFunnelTimeDimension), ve = d((o) => o.charts.funnel?.displayConfig), Ct = T(
2146
- () => ve || { showLegend: !0, showGrid: !0, showTooltip: !0 },
2147
- [ve]
2148
- ), wt = d((o) => o.setFunnelDisplayConfig), vt = d((o) => o.setFlowCube), bt = d((o) => o.setFlowBindingKey), Dt = d((o) => o.setFlowTimeDimension), Tt = d((o) => o.setEventDimension), Qt = d((o) => o.setStartingStepName), Ft = d((o) => o.setStartingStepFilters), Mt = d((o) => o.setStepsBefore), At = d((o) => o.setStepsAfter), xt = d((o) => o.setJoinStrategy), qt = B(
2149
- (o) => {
2150
- a.setState((x) => ({
2151
- charts: {
2152
- ...x.charts,
2153
- flow: {
2154
- ...x.charts.flow || { chartType: "sankey", chartConfig: {}, displayConfig: {} },
2155
- displayConfig: o
2156
- }
2157
- }
2158
- }));
2159
- },
2160
- [a]
2161
- ), W = d((o) => o.aiState), It = d((o) => o.openAI), z = d((o) => o.closeAI), kt = d((o) => o.setAIPrompt), le = d((o) => o.setAIGenerating), ue = d((o) => o.setAIError), X = d((o) => o.setAIHasGeneratedQuery), be = d((o) => o.saveAIPreviousState), De = d((o) => o.restoreAIPreviousState), ce = re("idle"), Bt = j, Te = d((o) => o.getValidation), Rt = T(
2162
- () => Te(),
2163
- // eslint-disable-next-line react-hooks/exhaustive-deps
2164
- [
2165
- Te,
2166
- l.queryStates,
2167
- y,
2168
- // Funnel deps
2169
- u,
2170
- f,
2171
- p,
2172
- // Flow deps
2173
- C,
2174
- w,
2175
- b,
2176
- P,
2177
- $,
2178
- L,
2179
- S,
2180
- I
2181
- ]
2182
- ), Vt = B(
2183
- (o, x, Qe, Nt) => {
2184
- F.fieldModalMode === "metrics" && x === "measure" ? ae(o.name) : F.fieldModalMode === "breakdown" && oe(o.name, x === "timeDimension"), Nt || F.closeFieldModal();
2185
- },
2186
- [F, ae, oe]
2187
- ), Ut = B(async () => {
2188
- if (s?.aiEndpoint) {
2189
- be(), le(!0), ue(null);
2190
- try {
2191
- await new Promise((o) => setTimeout(o, 1e3)), X(!0);
2192
- } catch (o) {
2193
- ue(o instanceof Error ? o.message : "Failed to generate query");
2194
- } finally {
2195
- le(!1);
2196
- }
2197
- }
2198
- }, [s?.aiEndpoint, be, le, ue, X]), Et = B(() => {
2199
- z(), X(!1);
2200
- }, [z, X]), _t = B(() => {
2201
- De(), z();
2202
- }, [De, z]), Lt = B(async () => {
2203
- ce.current = "copied", setTimeout(() => {
2204
- ce.current = "idle";
2205
- }, 2e3);
2206
- }, []), Pt = B(() => {
2207
- const o = a.getState();
2208
- if (o.analysisType === "funnel") {
2209
- const x = o.buildFunnelQueryFromSteps();
2210
- return x || o.buildCurrentQuery();
2211
- }
2212
- return o.queryStates.length > 1 ? {
2213
- queries: o.buildAllQueries(),
2214
- mergeStrategy: o.mergeStrategy,
2215
- mergeKeys: o.getMergeKeys(),
2216
- queryLabels: o.queryStates.map((x, Qe) => `Q${Qe + 1}`),
2217
- // Include funnel-specific config when in funnel mode
2218
- funnelBindingKey: o.funnelBindingKey,
2219
- stepTimeToConvert: o.stepTimeToConvert
2220
- } : o.buildCurrentQuery();
2221
- }, [a]), $t = B(() => {
2222
- const o = a.getState(), x = o.charts[o.analysisType];
2223
- return x ? {
2224
- chartType: x.chartType,
2225
- chartConfig: x.chartConfig,
2226
- displayConfig: x.displayConfig
2227
- } : {
2228
- chartType: Q.chartType,
2229
- chartConfig: Q.chartConfig,
2230
- displayConfig: Q.displayConfig
2231
- };
2232
- }, [a, Q.chartType, Q.chartConfig, Q.displayConfig]), Kt = B(() => a.getState().analysisType, [a]);
2233
- return {
2234
- // Query state (from queryBuilder)
2235
- queryState: l.queryState,
2236
- queryStates: l.queryStates,
2237
- activeQueryIndex: l.activeQueryIndex,
2238
- mergeStrategy: l.mergeStrategy,
2239
- isMultiQueryMode: l.isMultiQueryMode,
2240
- mergeKeys: l.mergeKeys,
2241
- currentQuery: l.currentQuery,
2242
- allQueries: l.allQueries,
2243
- multiQueryConfig: l.multiQueryConfig,
2244
- multiQueryValidation: l.multiQueryValidation,
2245
- // Funnel state (legacy)
2246
- funnelBindingKey: f,
2247
- isFunnelModeEnabled: v,
2248
- // Analysis Type state (new)
2249
- analysisType: y,
2250
- funnelCube: g,
2251
- funnelSteps: u,
2252
- activeFunnelStepIndex: m,
2253
- funnelTimeDimension: p,
2254
- funnelChartType: V,
2255
- funnelChartConfig: h,
2256
- funnelDisplayConfig: Ct,
2257
- // Flow state (new)
2258
- flowCube: C,
2259
- flowBindingKey: w,
2260
- flowTimeDimension: b,
2261
- eventDimension: P,
2262
- startingStep: $,
2263
- stepsBefore: L,
2264
- stepsAfter: S,
2265
- joinStrategy: I,
2266
- flowDisplayConfig: H,
2267
- // Data fetching (from queryExecution)
2268
- executionStatus: M.executionStatus,
2269
- executionResults: M.executionResults,
2270
- perQueryResults: M.perQueryResults,
2271
- isLoading: M.isLoading,
2272
- isFetching: M.isFetching,
2273
- error: M.error,
2274
- isValidQuery: j,
2275
- debugDataPerQuery: M.debugDataPerQuery,
2276
- funnelExecutedQueries: M.funnelExecutedQueries,
2277
- funnelServerQuery: M.funnelServerQuery,
2278
- funnelDebugData: M.funnelDebugData,
2279
- flowServerQuery: M.flowServerQuery,
2280
- flowDebugData: M.flowDebugData,
2281
- // Chart configuration (from chartDefaults)
2282
- // Note: Funnel chart type is determined by analysisType === 'funnel', not mergeStrategy
2283
- chartType: Q.chartType,
2284
- chartConfig: Q.chartConfig,
2285
- displayConfig: Q.displayConfig,
2286
- colorPalette: Q.colorPalette,
2287
- localPaletteName: Q.localPaletteName,
2288
- chartAvailability: Q.chartAvailability,
2289
- combinedMetrics: c.combinedMetrics,
2290
- combinedBreakdowns: c.combinedBreakdowns,
2291
- effectiveBreakdowns: c.effectiveBreakdowns,
2292
- // UI state (from uiState)
2293
- activeTab: F.activeTab,
2294
- activeView: F.activeView,
2295
- displayLimit: F.displayLimit,
2296
- showFieldModal: F.showFieldModal,
2297
- fieldModalMode: F.fieldModalMode,
2298
- activeTableIndex: F.activeTableIndex,
2299
- userManuallySelectedChart: F.userManuallySelectedChart,
2300
- // AI state
2301
- aiState: {
2302
- isOpen: W.isOpen,
2303
- userPrompt: W.userPrompt,
2304
- isGenerating: W.isGenerating,
2305
- error: W.error,
2306
- hasGeneratedQuery: W.hasGeneratedQuery
2307
- },
2308
- // Share state
2309
- shareButtonState: ce.current,
2310
- canShare: Bt,
2311
- // Adapter validation (NEW - Phase 5)
2312
- adapterValidation: Rt,
2313
- // Actions
2314
- actions: {
2315
- // Query state (from queryBuilder)
2316
- setActiveQueryIndex: l.setActiveQueryIndex,
2317
- setMergeStrategy: l.setMergeStrategy,
2318
- // Metrics
2319
- openMetricsModal: se,
2320
- addMetric: k,
2321
- removeMetric: Ye,
2322
- toggleMetric: ae,
2323
- reorderMetrics: Xe,
2324
- // Breakdowns
2325
- openBreakdownsModal: Ze,
2326
- addBreakdown: et,
2327
- removeBreakdown: tt,
2328
- toggleBreakdown: oe,
2329
- setBreakdownGranularity: nt,
2330
- toggleBreakdownComparison: rt,
2331
- reorderBreakdowns: it,
2332
- // Filters
2333
- setFilters: st,
2334
- dropFieldToFilter: at,
2335
- setOrder: ot,
2336
- // Multi-query (from queryBuilder)
2337
- addQuery: l.addQuery,
2338
- removeQuery: l.removeQuery,
2339
- // Funnel (legacy)
2340
- setFunnelBindingKey: ct,
2341
- // Analysis Type (new)
2342
- setAnalysisType: ft,
2343
- // Funnel Mode (new dedicated state)
2344
- setFunnelCube: dt,
2345
- addFunnelStep: yt,
2346
- removeFunnelStep: gt,
2347
- updateFunnelStep: mt,
2348
- setActiveFunnelStepIndex: ht,
2349
- reorderFunnelSteps: pt,
2350
- setFunnelTimeDimension: St,
2351
- setFunnelDisplayConfig: wt,
2352
- // Flow Mode actions
2353
- setFlowCube: vt,
2354
- setFlowBindingKey: bt,
2355
- setFlowTimeDimension: Dt,
2356
- setEventDimension: Tt,
2357
- setStartingStepName: Qt,
2358
- setStartingStepFilters: Ft,
2359
- setStepsBefore: Mt,
2360
- setStepsAfter: At,
2361
- setJoinStrategy: xt,
2362
- setFlowDisplayConfig: qt,
2363
- // Chart (from chartDefaults)
2364
- setChartType: Q.setChartType,
2365
- setChartConfig: Q.setChartConfig,
2366
- setDisplayConfig: Q.setDisplayConfig,
2367
- setLocalPaletteName: Q.setLocalPaletteName,
2368
- // UI (from uiState)
2369
- setActiveTab: F.setActiveTab,
2370
- setActiveView: F.setActiveView,
2371
- setDisplayLimit: F.setDisplayLimit,
2372
- closeFieldModal: F.closeFieldModal,
2373
- setActiveTableIndex: F.setActiveTableIndex,
2374
- // AI
2375
- openAI: It,
2376
- closeAI: z,
2377
- setAIPrompt: kt,
2378
- generateAI: Ut,
2379
- acceptAI: Et,
2380
- cancelAI: _t,
2381
- // Share
2382
- share: Lt,
2383
- // Utility
2384
- clearQuery: lt,
2385
- clearCurrentMode: ut,
2386
- refetch: M.refetch,
2387
- handleFieldSelected: Vt
2388
- },
2389
- // Refs
2390
- getQueryConfig: Pt,
2391
- getChartConfig: $t,
2392
- getAnalysisType: Kt
2393
- };
2394
- }
2395
- function Yn(n, i) {
2396
- const e = [];
2397
- if (!i?.cubes)
2398
- return e;
2399
- if (typeof n.dimension == "string") {
2400
- const [t, r] = n.dimension.split("."), s = i.cubes.find((a) => a.name === t);
2401
- s ? s.dimensions?.find((l) => l.name === n.dimension) || e.push({
2402
- type: "binding_key",
2403
- message: `Dimension "${r}" not found in cube "${t}"`
2404
- }) : e.push({
2405
- type: "binding_key",
2406
- message: `Cube "${t}" not found for binding key`
2407
- });
2408
- } else
2409
- for (const t of n.dimension) {
2410
- const r = i.cubes.find((s) => s.name === t.cube);
2411
- r ? r.dimensions?.find((a) => a.name === t.dimension) || e.push({
2412
- type: "cross_cube",
2413
- message: `Dimension "${t.dimension}" not found in cube "${t.cube}"`
2414
- }) : e.push({
2415
- type: "cross_cube",
2416
- message: `Cube "${t.cube}" not found for binding key mapping`
2417
- });
2418
- }
2419
- return e;
2420
- }
2421
- function Xn(n) {
2422
- const i = [];
2423
- for (let e = 0; e < n.length; e++) {
2424
- const t = n[e], r = t.query;
2425
- r.measures && r.measures.length > 0 || r.dimensions && r.dimensions.length > 0 || r.timeDimensions && r.timeDimensions.length > 0 || i.push({
2426
- type: "step_query",
2427
- message: `Step ${e + 1} "${t.name}" has no measures, dimensions, or time dimensions`,
2428
- stepIndex: e
2429
- });
2430
- }
2431
- return i;
2432
- }
2433
- function Zn(n, i) {
2434
- if (typeof n.dimension == "string")
2435
- return !0;
2436
- const e = Ke(i);
2437
- return e ? n.dimension.some((t) => t.cube === e) : !1;
2438
- }
2439
- function er(n, i) {
2440
- const e = [];
2441
- for (let t = 0; t < i.length; t++) {
2442
- const r = i[t];
2443
- if (!Zn(n, r.query)) {
2444
- const s = Ke(r.query) || "unknown";
2445
- e.push({
2446
- type: "cross_cube",
2447
- message: `Step ${t + 1} uses cube "${s}" but no binding key mapping exists for it`,
2448
- stepIndex: t
2449
- });
2450
- }
2451
- }
2452
- return e;
2453
- }
2454
- function _e(n) {
2455
- return n ? /^P(?:\d+Y)?(?:\d+M)?(?:\d+W)?(?:\d+D)?(?:T(?:\d+H)?(?:\d+M)?(?:\d+S)?)?$/.test(n) ? null : {
2456
- type: "time_window",
2457
- message: `Invalid time window format "${n}". Expected ISO 8601 duration (e.g., P7D, PT1H)`
2458
- } : null;
2459
- }
2460
- function vr(n, i) {
2461
- const e = [], t = [];
2462
- n.steps.length < 2 && e.push({
2463
- type: "general",
2464
- message: "Funnel requires at least 2 steps"
2465
- }), n.bindingKey?.dimension ? (e.push(...Yn(n.bindingKey, i)), e.push(...er(n.bindingKey, n.steps))) : e.push({
2466
- type: "binding_key",
2467
- message: "Binding key dimension is required"
2468
- }), e.push(...Xn(n.steps));
2469
- for (let s = 0; s < n.steps.length; s++) {
2470
- const a = n.steps[s], l = _e(a.timeToConvert);
2471
- l && (l.stepIndex = s, e.push(l));
2472
- }
2473
- const r = _e(n.globalTimeWindow);
2474
- return r && e.push(r), n.steps.length > 5 && t.push({
2475
- type: "general",
2476
- message: "Funnels with more than 5 steps may have reduced performance"
2477
- }), {
2478
- isValid: e.length === 0,
2479
- errors: e,
2480
- warnings: t
2481
- };
2482
- }
2483
- function br(n, i) {
2484
- return i < 2 ? { isValid: !1, message: "Add at least 2 steps for funnel" } : n?.dimension ? typeof n.dimension == "string" && !n.dimension ? { isValid: !1, message: "Select a binding key dimension" } : Array.isArray(n.dimension) && n.dimension.length === 0 ? { isValid: !1, message: "Select a binding key dimension" } : { isValid: !0 } : { isValid: !1, message: "Select a binding key dimension" };
2485
- }
2486
- function Dr(n) {
2487
- if (!n?.cubes) return [];
2488
- const i = [];
2489
- for (const e of n.cubes)
2490
- if (e.dimensions)
2491
- for (const t of e.dimensions)
2492
- (t.type === "string" || t.type === "number") && i.push({
2493
- cube: e.name,
2494
- dimension: t.name,
2495
- label: t.title || t.shortTitle || t.name.split(".")[1] || t.name
2496
- });
2497
- return i;
2498
- }
2499
- function Tr(n) {
2500
- if (!n?.dimension) return "Select binding key...";
2501
- if (typeof n.dimension == "string")
2502
- return n.dimension.split(".")[1] || n.dimension;
2503
- if (n.dimension.length > 0) {
2504
- const i = n.dimension[0];
2505
- return `${i.dimension.split(".")[1] || i.dimension} (${n.dimension.length} cubes)`;
2506
- }
2507
- return "Select binding key...";
2508
- }
2509
- export {
2510
- Gn as A,
2511
- cr as B,
2512
- xn as C,
2513
- d as a,
2514
- fr as b,
2515
- dr as c,
2516
- yr as d,
2517
- qn as e,
2518
- gr as f,
2519
- mr as g,
2520
- hr as h,
2521
- In as i,
2522
- kn as j,
2523
- Bn as k,
2524
- Rn as l,
2525
- pr as m,
2526
- Sr as n,
2527
- vr as o,
2528
- Yn as p,
2529
- Xn as q,
2530
- er as r,
2531
- Se as s,
2532
- br as t,
2533
- wr as u,
2534
- Vn as v,
2535
- Dr as w,
2536
- Tr as x,
2537
- Cr as y,
2538
- jn as z
2539
- };
2540
- //# sourceMappingURL=analysis-builder-shared-B3-UWqQ2.js.map