@quillsql/react 2.14.16 → 2.15.0

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 (253) hide show
  1. package/dist/cjs/Chart.d.ts.map +1 -1
  2. package/dist/cjs/Chart.js +12 -0
  3. package/dist/cjs/ChartBuilder.d.ts +3 -2
  4. package/dist/cjs/ChartBuilder.d.ts.map +1 -1
  5. package/dist/cjs/ChartBuilder.js +112 -18
  6. package/dist/cjs/ChartEditor.d.ts.map +1 -1
  7. package/dist/cjs/ChartEditor.js +2 -0
  8. package/dist/cjs/Context.d.ts +6 -2
  9. package/dist/cjs/Context.d.ts.map +1 -1
  10. package/dist/cjs/Context.js +160 -33
  11. package/dist/cjs/Dashboard.d.ts.map +1 -1
  12. package/dist/cjs/Dashboard.js +99 -19
  13. package/dist/cjs/QuillProvider.d.ts +38 -1
  14. package/dist/cjs/QuillProvider.d.ts.map +1 -1
  15. package/dist/cjs/QuillProvider.js +2 -2
  16. package/dist/cjs/ReportBuilder.d.ts +7 -2
  17. package/dist/cjs/ReportBuilder.d.ts.map +1 -1
  18. package/dist/cjs/ReportBuilder.js +104 -1271
  19. package/dist/cjs/SQLEditor.d.ts +9 -2
  20. package/dist/cjs/SQLEditor.d.ts.map +1 -1
  21. package/dist/cjs/SQLEditor.js +67 -10
  22. package/dist/cjs/Table.d.ts.map +1 -1
  23. package/dist/cjs/Table.js +12 -0
  24. package/dist/cjs/components/Chart/InternalChart.d.ts.map +1 -1
  25. package/dist/cjs/components/Chart/InternalChart.js +24 -1
  26. package/dist/cjs/components/Dashboard/DashboardTemplate.d.ts.map +1 -1
  27. package/dist/cjs/components/Dashboard/DashboardTemplate.js +2 -1
  28. package/dist/cjs/components/Dashboard/DataLoader.d.ts.map +1 -1
  29. package/dist/cjs/components/Dashboard/DataLoader.js +73 -2
  30. package/dist/cjs/components/Dashboard/util.d.ts +2 -1
  31. package/dist/cjs/components/Dashboard/util.d.ts.map +1 -1
  32. package/dist/cjs/components/Dashboard/util.js +12 -1
  33. package/dist/cjs/components/QuillTable.d.ts +2 -1
  34. package/dist/cjs/components/QuillTable.d.ts.map +1 -1
  35. package/dist/cjs/components/QuillTable.js +2 -2
  36. package/dist/cjs/components/ReportBuilder/AddColumnModal.d.ts +2 -1
  37. package/dist/cjs/components/ReportBuilder/AddColumnModal.d.ts.map +1 -1
  38. package/dist/cjs/components/ReportBuilder/AddColumnModal.js +28 -3
  39. package/dist/cjs/components/ReportBuilder/ColumnComponent.d.ts +49 -0
  40. package/dist/cjs/components/ReportBuilder/ColumnComponent.d.ts.map +1 -0
  41. package/dist/cjs/components/ReportBuilder/ColumnComponent.js +46 -0
  42. package/dist/cjs/components/ReportBuilder/FilterComponent.d.ts +65 -0
  43. package/dist/cjs/components/ReportBuilder/FilterComponent.d.ts.map +1 -0
  44. package/dist/cjs/components/ReportBuilder/FilterComponent.js +51 -0
  45. package/dist/cjs/components/ReportBuilder/LimitComponent.d.ts +42 -0
  46. package/dist/cjs/components/ReportBuilder/LimitComponent.d.ts.map +1 -0
  47. package/dist/cjs/components/ReportBuilder/LimitComponent.js +50 -0
  48. package/dist/cjs/components/ReportBuilder/PivotComponent.d.ts +66 -0
  49. package/dist/cjs/components/ReportBuilder/PivotComponent.d.ts.map +1 -0
  50. package/dist/cjs/components/ReportBuilder/PivotComponent.js +47 -0
  51. package/dist/cjs/components/ReportBuilder/SaveReport.d.ts +162 -0
  52. package/dist/cjs/components/ReportBuilder/SaveReport.d.ts.map +1 -0
  53. package/dist/cjs/components/ReportBuilder/SaveReport.js +31 -0
  54. package/dist/cjs/components/ReportBuilder/SortComponent.d.ts +42 -0
  55. package/dist/cjs/components/ReportBuilder/SortComponent.d.ts.map +1 -0
  56. package/dist/cjs/components/ReportBuilder/SortComponent.js +50 -0
  57. package/dist/cjs/components/ReportBuilder/TableComponent.d.ts +28 -0
  58. package/dist/cjs/components/ReportBuilder/TableComponent.d.ts.map +1 -0
  59. package/dist/cjs/components/ReportBuilder/TableComponent.js +24 -0
  60. package/dist/cjs/components/ReportBuilder/ui.d.ts.map +1 -1
  61. package/dist/cjs/components/ReportBuilder/ui.js +3 -1
  62. package/dist/cjs/components/UiComponents.d.ts +5 -2
  63. package/dist/cjs/components/UiComponents.d.ts.map +1 -1
  64. package/dist/cjs/components/UiComponents.js +7 -5
  65. package/dist/cjs/hooks/useAskQuill.d.ts.map +1 -1
  66. package/dist/cjs/hooks/useAskQuill.js +38 -0
  67. package/dist/cjs/hooks/useDashboard.d.ts +1 -1
  68. package/dist/cjs/hooks/useDashboard.d.ts.map +1 -1
  69. package/dist/cjs/hooks/useDashboard.js +62 -6
  70. package/dist/cjs/hooks/useExport.d.ts.map +1 -1
  71. package/dist/cjs/hooks/useExport.js +5 -2
  72. package/dist/cjs/hooks/useLongLoading.d.ts +13 -0
  73. package/dist/cjs/hooks/useLongLoading.d.ts.map +1 -0
  74. package/dist/cjs/hooks/useLongLoading.js +67 -0
  75. package/dist/cjs/hooks/useQuill.d.ts.map +1 -1
  76. package/dist/cjs/hooks/useQuill.js +25 -1
  77. package/dist/cjs/hooks/useReportBuilder.d.ts +178 -0
  78. package/dist/cjs/hooks/useReportBuilder.d.ts.map +1 -0
  79. package/dist/cjs/hooks/useReportBuilder.js +1495 -0
  80. package/dist/cjs/hooks/useVirtualTables.d.ts.map +1 -1
  81. package/dist/cjs/hooks/useVirtualTables.js +27 -2
  82. package/dist/cjs/index.d.ts +11 -0
  83. package/dist/cjs/index.d.ts.map +1 -1
  84. package/dist/cjs/index.js +17 -1
  85. package/dist/cjs/internals/ReportBuilder/PivotForm.d.ts +14 -1
  86. package/dist/cjs/internals/ReportBuilder/PivotForm.d.ts.map +1 -1
  87. package/dist/cjs/internals/ReportBuilder/PivotForm.js +86 -3
  88. package/dist/cjs/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  89. package/dist/cjs/internals/ReportBuilder/PivotList.js +3 -3
  90. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts +18 -2
  91. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  92. package/dist/cjs/internals/ReportBuilder/PivotModal.js +438 -147
  93. package/dist/cjs/models/Filter.d.ts +1 -1
  94. package/dist/cjs/models/Filter.d.ts.map +1 -1
  95. package/dist/cjs/models/Filter.js +3 -3
  96. package/dist/cjs/utils/astFilterProcessing.d.ts.map +1 -1
  97. package/dist/cjs/utils/astFilterProcessing.js +25 -4
  98. package/dist/cjs/utils/astProcessing.d.ts +4 -2
  99. package/dist/cjs/utils/astProcessing.d.ts.map +1 -1
  100. package/dist/cjs/utils/astProcessing.js +25 -2
  101. package/dist/cjs/utils/client.d.ts +2 -1
  102. package/dist/cjs/utils/client.d.ts.map +1 -1
  103. package/dist/cjs/utils/client.js +12 -1
  104. package/dist/cjs/utils/dashboard.d.ts +3 -1
  105. package/dist/cjs/utils/dashboard.d.ts.map +1 -1
  106. package/dist/cjs/utils/dashboard.js +44 -3
  107. package/dist/cjs/utils/filterProcessing.d.ts +2 -1
  108. package/dist/cjs/utils/filterProcessing.d.ts.map +1 -1
  109. package/dist/cjs/utils/filterProcessing.js +12 -1
  110. package/dist/cjs/utils/pivotConstructor.d.ts.map +1 -1
  111. package/dist/cjs/utils/pivotConstructor.js +15 -10
  112. package/dist/cjs/utils/pivotProcessing.d.ts.map +1 -1
  113. package/dist/cjs/utils/pivotProcessing.js +13 -3
  114. package/dist/cjs/utils/queryConstructor.d.ts.map +1 -1
  115. package/dist/cjs/utils/queryConstructor.js +30 -16
  116. package/dist/cjs/utils/report.d.ts +10 -5
  117. package/dist/cjs/utils/report.d.ts.map +1 -1
  118. package/dist/cjs/utils/report.js +55 -7
  119. package/dist/cjs/utils/reportBuilder.d.ts.map +1 -1
  120. package/dist/cjs/utils/reportBuilder.js +5 -2
  121. package/dist/cjs/utils/schema.d.ts +5 -2
  122. package/dist/cjs/utils/schema.d.ts.map +1 -1
  123. package/dist/cjs/utils/schema.js +14 -2
  124. package/dist/cjs/utils/tableProcessing.d.ts +17 -10
  125. package/dist/cjs/utils/tableProcessing.d.ts.map +1 -1
  126. package/dist/cjs/utils/tableProcessing.js +99 -17
  127. package/dist/esm/Chart.d.ts.map +1 -1
  128. package/dist/esm/Chart.js +13 -1
  129. package/dist/esm/ChartBuilder.d.ts +3 -2
  130. package/dist/esm/ChartBuilder.d.ts.map +1 -1
  131. package/dist/esm/ChartBuilder.js +114 -20
  132. package/dist/esm/ChartEditor.d.ts.map +1 -1
  133. package/dist/esm/ChartEditor.js +3 -1
  134. package/dist/esm/Context.d.ts +6 -2
  135. package/dist/esm/Context.d.ts.map +1 -1
  136. package/dist/esm/Context.js +159 -32
  137. package/dist/esm/Dashboard.d.ts.map +1 -1
  138. package/dist/esm/Dashboard.js +100 -20
  139. package/dist/esm/QuillProvider.d.ts +38 -1
  140. package/dist/esm/QuillProvider.d.ts.map +1 -1
  141. package/dist/esm/QuillProvider.js +2 -2
  142. package/dist/esm/ReportBuilder.d.ts +7 -2
  143. package/dist/esm/ReportBuilder.d.ts.map +1 -1
  144. package/dist/esm/ReportBuilder.js +107 -1271
  145. package/dist/esm/SQLEditor.d.ts +9 -2
  146. package/dist/esm/SQLEditor.d.ts.map +1 -1
  147. package/dist/esm/SQLEditor.js +68 -11
  148. package/dist/esm/Table.d.ts.map +1 -1
  149. package/dist/esm/Table.js +13 -1
  150. package/dist/esm/components/Chart/InternalChart.d.ts.map +1 -1
  151. package/dist/esm/components/Chart/InternalChart.js +25 -2
  152. package/dist/esm/components/Dashboard/DashboardTemplate.d.ts.map +1 -1
  153. package/dist/esm/components/Dashboard/DashboardTemplate.js +3 -2
  154. package/dist/esm/components/Dashboard/DataLoader.d.ts.map +1 -1
  155. package/dist/esm/components/Dashboard/DataLoader.js +74 -3
  156. package/dist/esm/components/Dashboard/util.d.ts +2 -1
  157. package/dist/esm/components/Dashboard/util.d.ts.map +1 -1
  158. package/dist/esm/components/Dashboard/util.js +12 -1
  159. package/dist/esm/components/QuillTable.d.ts +2 -1
  160. package/dist/esm/components/QuillTable.d.ts.map +1 -1
  161. package/dist/esm/components/QuillTable.js +2 -2
  162. package/dist/esm/components/ReportBuilder/AddColumnModal.d.ts +2 -1
  163. package/dist/esm/components/ReportBuilder/AddColumnModal.d.ts.map +1 -1
  164. package/dist/esm/components/ReportBuilder/AddColumnModal.js +29 -4
  165. package/dist/esm/components/ReportBuilder/ColumnComponent.d.ts +49 -0
  166. package/dist/esm/components/ReportBuilder/ColumnComponent.d.ts.map +1 -0
  167. package/dist/esm/components/ReportBuilder/ColumnComponent.js +39 -0
  168. package/dist/esm/components/ReportBuilder/FilterComponent.d.ts +65 -0
  169. package/dist/esm/components/ReportBuilder/FilterComponent.d.ts.map +1 -0
  170. package/dist/esm/components/ReportBuilder/FilterComponent.js +44 -0
  171. package/dist/esm/components/ReportBuilder/LimitComponent.d.ts +42 -0
  172. package/dist/esm/components/ReportBuilder/LimitComponent.d.ts.map +1 -0
  173. package/dist/esm/components/ReportBuilder/LimitComponent.js +46 -0
  174. package/dist/esm/components/ReportBuilder/PivotComponent.d.ts +66 -0
  175. package/dist/esm/components/ReportBuilder/PivotComponent.d.ts.map +1 -0
  176. package/dist/esm/components/ReportBuilder/PivotComponent.js +40 -0
  177. package/dist/esm/components/ReportBuilder/SaveReport.d.ts +162 -0
  178. package/dist/esm/components/ReportBuilder/SaveReport.d.ts.map +1 -0
  179. package/dist/esm/components/ReportBuilder/SaveReport.js +31 -0
  180. package/dist/esm/components/ReportBuilder/SortComponent.d.ts +42 -0
  181. package/dist/esm/components/ReportBuilder/SortComponent.d.ts.map +1 -0
  182. package/dist/esm/components/ReportBuilder/SortComponent.js +46 -0
  183. package/dist/esm/components/ReportBuilder/TableComponent.d.ts +28 -0
  184. package/dist/esm/components/ReportBuilder/TableComponent.d.ts.map +1 -0
  185. package/dist/esm/components/ReportBuilder/TableComponent.js +20 -0
  186. package/dist/esm/components/ReportBuilder/ui.d.ts.map +1 -1
  187. package/dist/esm/components/ReportBuilder/ui.js +4 -2
  188. package/dist/esm/components/UiComponents.d.ts +5 -2
  189. package/dist/esm/components/UiComponents.d.ts.map +1 -1
  190. package/dist/esm/components/UiComponents.js +7 -5
  191. package/dist/esm/hooks/useAskQuill.d.ts.map +1 -1
  192. package/dist/esm/hooks/useAskQuill.js +39 -1
  193. package/dist/esm/hooks/useDashboard.d.ts +1 -1
  194. package/dist/esm/hooks/useDashboard.d.ts.map +1 -1
  195. package/dist/esm/hooks/useDashboard.js +63 -7
  196. package/dist/esm/hooks/useExport.d.ts.map +1 -1
  197. package/dist/esm/hooks/useExport.js +6 -3
  198. package/dist/esm/hooks/useLongLoading.d.ts +13 -0
  199. package/dist/esm/hooks/useLongLoading.d.ts.map +1 -0
  200. package/dist/esm/hooks/useLongLoading.js +64 -0
  201. package/dist/esm/hooks/useQuill.d.ts.map +1 -1
  202. package/dist/esm/hooks/useQuill.js +26 -2
  203. package/dist/esm/hooks/useReportBuilder.d.ts +178 -0
  204. package/dist/esm/hooks/useReportBuilder.d.ts.map +1 -0
  205. package/dist/esm/hooks/useReportBuilder.js +1490 -0
  206. package/dist/esm/hooks/useVirtualTables.d.ts.map +1 -1
  207. package/dist/esm/hooks/useVirtualTables.js +28 -3
  208. package/dist/esm/index.d.ts +11 -0
  209. package/dist/esm/index.d.ts.map +1 -1
  210. package/dist/esm/index.js +8 -0
  211. package/dist/esm/internals/ReportBuilder/PivotForm.d.ts +14 -1
  212. package/dist/esm/internals/ReportBuilder/PivotForm.d.ts.map +1 -1
  213. package/dist/esm/internals/ReportBuilder/PivotForm.js +87 -4
  214. package/dist/esm/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  215. package/dist/esm/internals/ReportBuilder/PivotList.js +3 -3
  216. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts +18 -2
  217. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  218. package/dist/esm/internals/ReportBuilder/PivotModal.js +440 -149
  219. package/dist/esm/models/Filter.d.ts +1 -1
  220. package/dist/esm/models/Filter.d.ts.map +1 -1
  221. package/dist/esm/models/Filter.js +3 -3
  222. package/dist/esm/utils/astFilterProcessing.d.ts.map +1 -1
  223. package/dist/esm/utils/astFilterProcessing.js +25 -4
  224. package/dist/esm/utils/astProcessing.d.ts +4 -2
  225. package/dist/esm/utils/astProcessing.d.ts.map +1 -1
  226. package/dist/esm/utils/astProcessing.js +25 -2
  227. package/dist/esm/utils/client.d.ts +2 -1
  228. package/dist/esm/utils/client.d.ts.map +1 -1
  229. package/dist/esm/utils/client.js +12 -1
  230. package/dist/esm/utils/dashboard.d.ts +3 -1
  231. package/dist/esm/utils/dashboard.d.ts.map +1 -1
  232. package/dist/esm/utils/dashboard.js +44 -3
  233. package/dist/esm/utils/filterProcessing.d.ts +2 -1
  234. package/dist/esm/utils/filterProcessing.d.ts.map +1 -1
  235. package/dist/esm/utils/filterProcessing.js +12 -1
  236. package/dist/esm/utils/pivotConstructor.d.ts.map +1 -1
  237. package/dist/esm/utils/pivotConstructor.js +15 -10
  238. package/dist/esm/utils/pivotProcessing.d.ts.map +1 -1
  239. package/dist/esm/utils/pivotProcessing.js +13 -3
  240. package/dist/esm/utils/queryConstructor.d.ts.map +1 -1
  241. package/dist/esm/utils/queryConstructor.js +30 -16
  242. package/dist/esm/utils/report.d.ts +10 -5
  243. package/dist/esm/utils/report.d.ts.map +1 -1
  244. package/dist/esm/utils/report.js +55 -7
  245. package/dist/esm/utils/reportBuilder.d.ts.map +1 -1
  246. package/dist/esm/utils/reportBuilder.js +5 -2
  247. package/dist/esm/utils/schema.d.ts +5 -2
  248. package/dist/esm/utils/schema.d.ts.map +1 -1
  249. package/dist/esm/utils/schema.js +14 -2
  250. package/dist/esm/utils/tableProcessing.d.ts +17 -10
  251. package/dist/esm/utils/tableProcessing.d.ts.map +1 -1
  252. package/dist/esm/utils/tableProcessing.js +99 -17
  253. package/package.json +1 -1
@@ -0,0 +1,1495 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useReportBuilder = exports.useReportBuilderInternal = void 0;
4
+ const react_1 = require("react");
5
+ const Report_1 = require("../models/Report");
6
+ const report_1 = require("../utils/report");
7
+ const tableProcessing_1 = require("../utils/tableProcessing");
8
+ const ReportBuilder_1 = require("../models/ReportBuilder");
9
+ const Context_1 = require("../Context");
10
+ const constants_1 = require("../utils/constants");
11
+ const useDashboard_1 = require("./useDashboard");
12
+ const Filter_1 = require("../models/Filter");
13
+ const astProcessing_1 = require("../utils/astProcessing");
14
+ const dashboard_1 = require("../utils/dashboard");
15
+ const dataFetcher_1 = require("../utils/dataFetcher");
16
+ const filterProcessing_1 = require("../utils/filterProcessing");
17
+ const paginationProcessing_1 = require("../utils/paginationProcessing");
18
+ const pivotProcessing_1 = require("../utils/pivotProcessing");
19
+ const reportBuilder_1 = require("../utils/reportBuilder");
20
+ const schema_1 = require("../utils/schema");
21
+ const useLongLoading_1 = require("./useLongLoading");
22
+ const convert_1 = require("../components/ReportBuilder/convert");
23
+ const useReportBuilderInternal = ({ reportId, initialTableName, destinationDashboard, pivotRecommendationsEnabled, onSaveChanges, rowsPerPage, rowsPerRequest, }) => {
24
+ const { allReportsById } = (0, useDashboard_1.useAllReports)();
25
+ const [schemaData] = (0, react_1.useContext)(Context_1.SchemaDataContext);
26
+ const { dashboards } = (0, useDashboard_1.useDashboards)();
27
+ const { data, isLoading: dashboardIsLoading, reload, } = (0, useDashboard_1.useDashboardInternal)(destinationDashboard);
28
+ const { getToken } = (0, react_1.useContext)(Context_1.FetchContext);
29
+ const { eventTracking } = (0, react_1.useContext)(Context_1.EventTrackingContext);
30
+ const destinationDashboardConfig = (0, react_1.useMemo)(() => {
31
+ return dashboards?.find((d) => d.name === destinationDashboard);
32
+ }, [dashboards, destinationDashboard]);
33
+ const filteredSchema = (0, react_1.useMemo)(() => {
34
+ return schemaData.schemaWithCustomFields?.filter((table) => {
35
+ return (destinationDashboardConfig?.tenantKeys?.[0] === constants_1.SINGLE_TENANT ||
36
+ !table.ownerTenantFields ||
37
+ table.ownerTenantFields?.length === 0 ||
38
+ table.ownerTenantFields?.includes(destinationDashboardConfig?.tenantKeys?.[0] ?? ''));
39
+ });
40
+ }, [
41
+ schemaData.schemaWithCustomFields,
42
+ destinationDashboardConfig?.tenantKeys,
43
+ ]);
44
+ const { tenants } = (0, react_1.useContext)(Context_1.TenantContext);
45
+ const [client] = (0, react_1.useContext)(Context_1.ClientContext);
46
+ const _rowsPerRequest = rowsPerRequest ?? 100;
47
+ const _rowsPerPage = Math.min(rowsPerPage ?? 20, _rowsPerRequest);
48
+ // Consts
49
+ const REPORT_BUILDER_PAGINATION = {
50
+ page: 0,
51
+ rowsPerPage: _rowsPerPage,
52
+ rowsPerRequest: _rowsPerRequest,
53
+ };
54
+ // ReportBuilder UI States
55
+ const [openPopover, setOpenPopover] = (0, react_1.useState)(null);
56
+ const [aiPrompt, setAiPrompt] = (0, react_1.useState)('');
57
+ const [reportBuilderLoading, setReportBuilderLoading] = (0, react_1.useState)(false);
58
+ const [tableLoading, setTableLoading] = (0, react_1.useState)(false);
59
+ const [errorMessage, setErrorMessage] = (0, react_1.useState)('');
60
+ const [unresolvedReportMessage, setUnresolvedReportMessage] = (0, react_1.useState)('');
61
+ // Core Report states
62
+ // Table order matters for joins. For now, assumed to have one 'primary' table (the first one)
63
+ const [tables, setTables] = (0, react_1.useState)([]);
64
+ const [columns, setColumns] = (0, react_1.useState)([]);
65
+ const [filterStack, setFilterStack] = (0, react_1.useState)([]);
66
+ const [pivot, setPivot] = (0, react_1.useState)(null);
67
+ const [sort, setSort] = (0, react_1.useState)([]);
68
+ const [limit, setLimit] = (0, react_1.useState)(null);
69
+ const reportBuilderState = (0, react_1.useMemo)(() => {
70
+ return {
71
+ tables,
72
+ columns,
73
+ filterStack,
74
+ pivot,
75
+ sort,
76
+ limit,
77
+ };
78
+ }, [columns, filterStack, limit, pivot, sort, tables]);
79
+ // For undo/redo
80
+ const [stateStack, setStateStack] = (0, react_1.useState)([]);
81
+ const [poppedStateStack, setPoppedStateStack] = (0, react_1.useState)([]);
82
+ // Other Report states
83
+ const [activeQuery, setActiveQuery] = (0, react_1.useState)('');
84
+ const [queryOutOfSync, setQueryOutOfSync] = (0, react_1.useState)(false);
85
+ const [unfilteredUniqueValues, setUnfilteredUniqueValues] = (0, react_1.useState)({}); // unique values before filtering
86
+ const [unfilteredUniqueValuesIsLoading, setUnfilteredUniqueValuesIsLoading] = (0, react_1.useState)(false);
87
+ const [filteredUniqueValues, setFilteredUniqueValues] = (0, react_1.useState)(null); // unique values after filtering
88
+ const [filteredUniqueValuesIsLoading, setFilteredUniqueValuesIsLoading] = (0, react_1.useState)(false);
89
+ const [columnUniqueValues, setColumnUniqueValues] = (0, react_1.useState)({});
90
+ const [dateRanges, setDateRanges] = (0, react_1.useState)(null);
91
+ const [tempReport, setTempReport] = (0, react_1.useState)({
92
+ ...report_1.EMPTY_INTERNAL_REPORT,
93
+ pagination: REPORT_BUILDER_PAGINATION,
94
+ });
95
+ const [currentProcessing, setCurrentProcessing] = (0, react_1.useState)({
96
+ page: REPORT_BUILDER_PAGINATION,
97
+ });
98
+ const [previousPage, setPreviousPage] = (0, react_1.useState)(0);
99
+ // Table display states
100
+ const [reportColumns, setReportColumns] = (0, react_1.useState)([]);
101
+ const [reportRows, setReportRows] = (0, react_1.useState)([]);
102
+ const [formattedRows, setFormattedRows] = (0, react_1.useState)([]);
103
+ const [pivotData, setPivotData] = (0, react_1.useState)(null);
104
+ const [numberOfRows, setNumberOfRows] = (0, react_1.useState)(0);
105
+ const [rowCountIsLoading, setRowCountIsLoading] = (0, react_1.useState)(false);
106
+ const reportColumnsToStateColumns = (0, react_1.useMemo)(() => {
107
+ const positionMap = {};
108
+ columns.forEach((column, index) => {
109
+ positionMap[column.field] = index;
110
+ if (column.alias) {
111
+ positionMap[column.alias] = index;
112
+ }
113
+ });
114
+ // Sort reportColumns based on the position in columns
115
+ return [...reportColumns]
116
+ .filter((reportColumn) => positionMap[reportColumn.field] !== undefined)
117
+ .sort((a, b) => {
118
+ const posA = positionMap[a.field];
119
+ const posB = positionMap[b.field];
120
+ if (posA !== undefined && posB !== undefined) {
121
+ return posA - posB;
122
+ }
123
+ else {
124
+ return 0;
125
+ }
126
+ });
127
+ }, [columns, reportColumns]);
128
+ // Pivot form states
129
+ const [pivotRowField, setPivotRowField] = (0, react_1.useState)(undefined);
130
+ const [pivotColumnField, setPivotColumnField] = (0, react_1.useState)(undefined);
131
+ const [pivotAggregations, setPivotAggregations] = (0, react_1.useState)([]);
132
+ const [pivotLimit, setPivotLimit] = (0, react_1.useState)(undefined);
133
+ const [pivotSort, setPivotSort] = (0, react_1.useState)(undefined);
134
+ const [pivotHint, setPivotHint] = (0, react_1.useState)('');
135
+ const [pivotError, setPivotError] = (0, react_1.useState)('');
136
+ const [createdPivots, setCreatedPivots] = (0, react_1.useState)([]);
137
+ const [recommendedPivots, setRecommendedPivots] = (0, react_1.useState)([]);
138
+ const [pivotPopUpTitle, setPivotPopUpTitle] = (0, react_1.useState)('Add pivot');
139
+ const [showPivotPopover, setShowPivotPopover] = (0, react_1.useState)(false);
140
+ const [isEditingPivot, setIsEditingPivot] = (0, react_1.useState)(false);
141
+ const [selectedPivotIndex, setSelectedPivotIndex] = (0, react_1.useState)(-1);
142
+ const [pivotRecommendationsEnabledState, setPivotRecommendationsEnabledState,] = (0, react_1.useState)(pivotRecommendationsEnabled);
143
+ // Ask AI
144
+ const [askAILoading, setAskAILoading] = (0, react_1.useState)(false);
145
+ const loading = reportBuilderLoading || tableLoading;
146
+ (0, useLongLoading_1.useLongLoading)(reportBuilderLoading, {
147
+ origin: 'ReportBuilder',
148
+ loadDescription: 'Loading report builder',
149
+ });
150
+ (0, useLongLoading_1.useLongLoading)(tableLoading, {
151
+ origin: 'ReportBuilder',
152
+ loadDescription: 'Loading table',
153
+ });
154
+ (0, useLongLoading_1.useLongLoading)(askAILoading, {
155
+ origin: 'ReportBuilder',
156
+ loadDescription: 'Loading ask AI',
157
+ });
158
+ const isSelectStar = (0, react_1.useMemo)(() => {
159
+ if (tables.length === 1) {
160
+ // Check if all columns are selected
161
+ const totalColumnLength = tables.reduce((acc, table) => {
162
+ const tableColumns = filteredSchema.find((t) => t.name === table.name)?.columns.length ??
163
+ 0;
164
+ return acc + tableColumns;
165
+ }, 0);
166
+ return totalColumnLength === columns.length;
167
+ }
168
+ else {
169
+ // TODO: Implement this to work with joins
170
+ // SELECT * won't work if joined table has shared column name
171
+ return false;
172
+ }
173
+ }, [tables, columns, filteredSchema]);
174
+ const mssqlSortWarning = (0, react_1.useMemo)(() => {
175
+ if (!client || client?.databaseType !== 'mssql') {
176
+ return undefined;
177
+ }
178
+ else if (!pivot && !limit) {
179
+ return 'Please add a limit.';
180
+ }
181
+ }, [client, limit, pivot]);
182
+ const foreignKeyMap = (0, react_1.useMemo)(() => {
183
+ return (0, schema_1.getSchemaForeignKeyMapping)(filteredSchema);
184
+ }, [filteredSchema]);
185
+ // State changing functions
186
+ const clearAllState = (resetStateStack = true) => {
187
+ setActiveQuery('');
188
+ setQueryOutOfSync(false);
189
+ handleMultiStateChange({
190
+ state: ReportBuilder_1.EMPTY_REPORT_BUILDER_STATE,
191
+ fetchData: false,
192
+ updateStateStack: true,
193
+ });
194
+ if (resetStateStack) {
195
+ setStateStack([]);
196
+ setPoppedStateStack([]);
197
+ }
198
+ setFilteredUniqueValues(null);
199
+ setUnfilteredUniqueValues({});
200
+ setColumnUniqueValues({});
201
+ setDateRanges(null);
202
+ setTempReport({
203
+ ...report_1.EMPTY_INTERNAL_REPORT,
204
+ pagination: REPORT_BUILDER_PAGINATION,
205
+ });
206
+ resetProcessing();
207
+ setReportColumns([]);
208
+ setReportRows([]);
209
+ setFormattedRows([]);
210
+ setPivotData(null);
211
+ setNumberOfRows(0);
212
+ setRowCountIsLoading(false);
213
+ setPivotRowField(undefined);
214
+ setPivotColumnField(undefined);
215
+ setPivotAggregations([]);
216
+ setCreatedPivots([]);
217
+ setRecommendedPivots([]);
218
+ setSelectedPivotIndex(-1);
219
+ setAskAILoading(false);
220
+ setReportBuilderLoading(false);
221
+ setTableLoading(false);
222
+ setPivotError('');
223
+ setErrorMessage('');
224
+ setUnresolvedReportMessage('');
225
+ setPivotHint('');
226
+ };
227
+ const handleTablesChange = (newTables, updateStateStack = true) => {
228
+ setTables(newTables);
229
+ if (updateStateStack) {
230
+ setStateStack((prevStack) => [
231
+ ...prevStack,
232
+ { ...reportBuilderState, tables: newTables },
233
+ ]);
234
+ setPoppedStateStack([]);
235
+ }
236
+ };
237
+ const handleColumnsChange = (newColumns, fetchData, updateStateStack = true, bypassConfirmation = false) => {
238
+ if (newColumns.length > 0) {
239
+ eventTracking?.addBreadcrumb?.({
240
+ message: 'Changed columns in ReportBuilder',
241
+ data: {
242
+ columns: newColumns,
243
+ },
244
+ category: 'log',
245
+ level: 'info',
246
+ timestamp: Date.now(),
247
+ });
248
+ }
249
+ const validReportBuilderState = bypassConfirmation
250
+ ? { ...reportBuilderState, columns: newColumns }
251
+ : (0, reportBuilder_1.validatedReportBuilderState)({
252
+ ...reportBuilderState,
253
+ columns: newColumns,
254
+ }, foreignKeyMap);
255
+ if (validReportBuilderState.tables.length === 0 && !bypassConfirmation) {
256
+ if (!confirm('Removing all columns will clear all state. Are you sure you want to continue?')) {
257
+ return;
258
+ }
259
+ else {
260
+ handleMultiStateChange({
261
+ state: ReportBuilder_1.EMPTY_REPORT_BUILDER_STATE,
262
+ fetchData: false,
263
+ updateStateStack: true,
264
+ });
265
+ return;
266
+ }
267
+ }
268
+ const tablesAffected = tables.length - validReportBuilderState.tables.length >= 2;
269
+ const filtersAffected = validReportBuilderState.filterStack.length !== filterStack.length;
270
+ const deletedTables = tables
271
+ .filter((table) => {
272
+ return !validReportBuilderState.tables.some((t) => t.name === table.name);
273
+ })
274
+ .map((table) => table.name);
275
+ const deletedFilters = filterStack
276
+ .filter((filter) => filter.value)
277
+ .filter((filter) => {
278
+ return deletedTables.some((table) => table === filter.value.table);
279
+ })
280
+ .map((filter) => (0, filterProcessing_1.filterSentence)(filter.value));
281
+ if (tablesAffected && filtersAffected) {
282
+ if (!confirm(`Removing this column will remove the following table${deletedTables.length > 1 ? 's' : ''}:
283
+ ${deletedTables.join(', ')}.
284
+ It will also remove the following filter${deletedFilters.length > 1 ? 's' : ''}:
285
+ ${deletedFilters.join(', ')}.
286
+ Are you sure you want to continue?
287
+ `
288
+ .replace(/\s+/g, ' ')
289
+ .trim())) {
290
+ return;
291
+ }
292
+ }
293
+ else if (tablesAffected) {
294
+ if (!confirm(`Removing this column will remove the following table${deletedTables.length > 1 ? 's' : ''}:
295
+ ${deletedTables.join(', ')}.
296
+ Are you sure you want to continue?
297
+ `
298
+ .replace(/\s+/g, ' ')
299
+ .trim())) {
300
+ return;
301
+ }
302
+ }
303
+ else if (filtersAffected) {
304
+ if (!confirm(`Removing this column will remove the following filter${deletedFilters.length > 1 ? 's' : ''}:
305
+ ${deletedFilters.join(', ')}.
306
+ Are you sure you want to continue?
307
+ `
308
+ .replace(/\s+/g, ' ')
309
+ .trim())) {
310
+ return;
311
+ }
312
+ }
313
+ if (validReportBuilderState.tables.length !== tables.length) {
314
+ handleTablesChange(validReportBuilderState.tables, false);
315
+ fetchData = true;
316
+ }
317
+ if (validReportBuilderState.filterStack.length !== filterStack.length) {
318
+ handleFilterStackChange(validReportBuilderState.filterStack, false, false);
319
+ fetchData = true;
320
+ }
321
+ if (validReportBuilderState.sort.length !== sort.length) {
322
+ handleSortChange(validReportBuilderState.sort, false, false);
323
+ fetchData = true;
324
+ }
325
+ if (pivot && !validReportBuilderState.pivot) {
326
+ handlePivotChange(validReportBuilderState.pivot, false, false);
327
+ }
328
+ setColumns(validReportBuilderState.columns);
329
+ if (updateStateStack) {
330
+ setStateStack((prevStack) => [...prevStack, validReportBuilderState]);
331
+ setPoppedStateStack([]);
332
+ }
333
+ if (fetchData) {
334
+ fetchDataFromReportBuilderState({ state: validReportBuilderState });
335
+ }
336
+ else {
337
+ setQueryOutOfSync(true);
338
+ }
339
+ };
340
+ const handleFilterInsertion = (newFilter) => {
341
+ const newFilterStack = [...filterStack];
342
+ eventTracking?.addBreadcrumb?.({
343
+ message: 'Inserted filter in ReportBuilder',
344
+ data: {
345
+ filter: newFilter,
346
+ },
347
+ category: 'log',
348
+ level: 'info',
349
+ timestamp: Date.now(),
350
+ });
351
+ if (newFilterStack.length > 0) {
352
+ const tabNode = {
353
+ leaf: false,
354
+ operator: 'and',
355
+ leftNode: null,
356
+ rightNode: null,
357
+ };
358
+ newFilterStack.push(tabNode);
359
+ }
360
+ const newItem = {
361
+ leaf: true,
362
+ operator: null,
363
+ leftNode: null,
364
+ rightNode: null,
365
+ value: newFilter,
366
+ };
367
+ newFilterStack.push(newItem);
368
+ handleFilterStackChange(newFilterStack, true);
369
+ };
370
+ const handleFilterStackChange = (newFilterStack, fetchData, updateStateStack = true) => {
371
+ if (newFilterStack.length > 0 || filterStack.length > 0) {
372
+ eventTracking?.addBreadcrumb?.({
373
+ message: 'Changed filter stack in ReportBuilder',
374
+ data: {
375
+ filterStack: newFilterStack,
376
+ },
377
+ category: 'log',
378
+ level: 'info',
379
+ timestamp: Date.now(),
380
+ });
381
+ }
382
+ setFilterStack(newFilterStack);
383
+ if (newFilterStack.length === 0) {
384
+ setFilteredUniqueValues(null);
385
+ }
386
+ if (updateStateStack) {
387
+ setStateStack((prevStack) => [
388
+ ...prevStack,
389
+ { ...reportBuilderState, filterStack: newFilterStack },
390
+ ]);
391
+ setPoppedStateStack([]);
392
+ }
393
+ if (fetchData) {
394
+ fetchDataFromReportBuilderState({
395
+ state: {
396
+ ...reportBuilderState,
397
+ filterStack: newFilterStack,
398
+ },
399
+ filtersChanged: true,
400
+ });
401
+ }
402
+ };
403
+ const handlePivotChange = (newPivot, fetchData, updateStateStack = true) => {
404
+ if (newPivot || pivot) {
405
+ eventTracking?.addBreadcrumb?.({
406
+ message: 'Changed pivot in ReportBuilder',
407
+ data: {
408
+ pivot: newPivot,
409
+ },
410
+ category: 'log',
411
+ level: 'info',
412
+ timestamp: Date.now(),
413
+ });
414
+ }
415
+ setPivot(newPivot ? (0, reportBuilder_1.setTypesOnPivot)(newPivot, reportColumns) : null);
416
+ setPivotHint('');
417
+ setPivotError('');
418
+ if (!newPivot) {
419
+ setPivotData(null);
420
+ if (!fetchData) {
421
+ const formattedRows = (0, reportBuilder_1.formatRows)(reportRows, reportColumns, false);
422
+ setFormattedRows(formattedRows);
423
+ }
424
+ }
425
+ if (updateStateStack) {
426
+ setStateStack((prevStack) => [
427
+ ...prevStack,
428
+ {
429
+ ...reportBuilderState,
430
+ pivot: newPivot,
431
+ },
432
+ ]);
433
+ setPoppedStateStack([]);
434
+ }
435
+ if (fetchData) {
436
+ fetchDataFromReportBuilderState({
437
+ state: {
438
+ ...reportBuilderState,
439
+ pivot: newPivot,
440
+ },
441
+ });
442
+ }
443
+ };
444
+ const updatePivot = async (changeField, fieldKey) => {
445
+ if (!client || !pivot) {
446
+ return;
447
+ }
448
+ let newPivot = { ...pivot };
449
+ setPivotError('');
450
+ if (fieldKey === 'sort') {
451
+ if (changeField &&
452
+ typeof changeField === 'object' &&
453
+ 'sortField' in changeField &&
454
+ 'sortDirection' in changeField) {
455
+ newPivot.sort = true;
456
+ newPivot.sortField = changeField.sortField;
457
+ newPivot.sortDirection = changeField.sortDirection;
458
+ }
459
+ else {
460
+ newPivot.sort = false;
461
+ newPivot.sortField = undefined;
462
+ newPivot.sortDirection = undefined;
463
+ }
464
+ }
465
+ else {
466
+ // @ts-ignore
467
+ newPivot[fieldKey] = changeField;
468
+ }
469
+ if (fieldKey === 'rowField') {
470
+ if (changeField === '' || changeField === undefined) {
471
+ setPivotColumnField(undefined);
472
+ // set all percentage aggregations to undefined
473
+ setPivotAggregations(pivotAggregations.map((agg) => ({
474
+ ...agg,
475
+ aggregationType: agg.aggregationType === 'percentage'
476
+ ? undefined
477
+ : agg.aggregationType,
478
+ })));
479
+ }
480
+ }
481
+ newPivot = (0, reportBuilder_1.setTypesOnPivot)(newPivot, reportColumns);
482
+ if (newPivot.aggregations?.length === 0 ||
483
+ newPivot.aggregations?.some((agg) => !agg.aggregationType) ||
484
+ newPivot.aggregations?.some((agg) => !agg.valueField &&
485
+ agg.aggregationType !== 'count' &&
486
+ agg.aggregationType !== 'percentage')) {
487
+ return;
488
+ }
489
+ const { valid, reason } = (0, pivotProcessing_1.isValidPivot)(newPivot);
490
+ if (!valid) {
491
+ setPivotError(reason);
492
+ return;
493
+ }
494
+ handlePivotChange(newPivot, true);
495
+ };
496
+ const handleSortChange = (newSort, fetchData, updateStateStack = true) => {
497
+ if (newSort.length > 0 || sort.length > 0) {
498
+ eventTracking?.addBreadcrumb?.({
499
+ message: 'Changed sort in ReportBuilder',
500
+ data: {
501
+ sort: newSort,
502
+ },
503
+ category: 'log',
504
+ level: 'info',
505
+ timestamp: Date.now(),
506
+ });
507
+ }
508
+ setSort(newSort);
509
+ if (updateStateStack) {
510
+ setStateStack((prevStack) => [
511
+ ...prevStack,
512
+ { ...reportBuilderState, sort: newSort },
513
+ ]);
514
+ setPoppedStateStack([]);
515
+ }
516
+ if (fetchData) {
517
+ fetchDataFromReportBuilderState({
518
+ state: {
519
+ ...reportBuilderState,
520
+ sort: newSort,
521
+ },
522
+ });
523
+ }
524
+ };
525
+ const handleLimitChange = (newLimit, fetchData, updateStateStack = true) => {
526
+ if (newLimit || limit) {
527
+ eventTracking?.addBreadcrumb?.({
528
+ message: 'Changed limit in ReportBuilder',
529
+ data: {
530
+ limit: newLimit,
531
+ },
532
+ category: 'log',
533
+ level: 'info',
534
+ timestamp: Date.now(),
535
+ });
536
+ }
537
+ setLimit(newLimit);
538
+ if (updateStateStack) {
539
+ setStateStack((prevStack) => [
540
+ ...prevStack,
541
+ { ...reportBuilderState, limit: newLimit },
542
+ ]);
543
+ setPoppedStateStack([]);
544
+ }
545
+ if (fetchData) {
546
+ fetchDataFromReportBuilderState({
547
+ state: {
548
+ ...reportBuilderState,
549
+ limit: newLimit,
550
+ },
551
+ limitChanged: true,
552
+ });
553
+ }
554
+ };
555
+ const handleMultiStateChange = ({ state, fetchData, updateStateStack = true, report, skipPivotColumnFetch = false, }) => {
556
+ if (state.tables !== undefined) {
557
+ handleTablesChange(state.tables, false);
558
+ }
559
+ if (state.columns !== undefined) {
560
+ handleColumnsChange(state.columns, false, false, true);
561
+ }
562
+ if (state.filterStack !== undefined) {
563
+ handleFilterStackChange(state.filterStack, false, false);
564
+ }
565
+ if (state.pivot !== undefined) {
566
+ handlePivotChange(state.pivot, false, false);
567
+ }
568
+ if (state.sort !== undefined) {
569
+ handleSortChange(state.sort, false, false);
570
+ }
571
+ if (state.limit !== undefined) {
572
+ handleLimitChange(state.limit, false, false);
573
+ }
574
+ if (updateStateStack) {
575
+ setStateStack((prevStack) => [
576
+ ...prevStack,
577
+ { ...reportBuilderState, ...state },
578
+ ]);
579
+ setPoppedStateStack([]);
580
+ }
581
+ eventTracking?.addBreadcrumb?.({
582
+ message: 'Changed state in ReportBuilder',
583
+ data: {
584
+ state: { ...reportBuilderState, ...state },
585
+ },
586
+ category: 'log',
587
+ level: 'info',
588
+ timestamp: Date.now(),
589
+ });
590
+ if (fetchData) {
591
+ fetchDataFromReportBuilderState({
592
+ state: { ...reportBuilderState, ...state },
593
+ filtersChanged: !!state.filterStack,
594
+ limitChanged: !!state.limit,
595
+ tablesChanged: !!state.tables,
596
+ report,
597
+ skipPivotColumnFetch,
598
+ });
599
+ }
600
+ };
601
+ const handleUndo = () => {
602
+ if (stateStack.length <= 1) {
603
+ return;
604
+ }
605
+ const previousState = stateStack[stateStack.length - 2];
606
+ setPoppedStateStack((prevStack) => [
607
+ ...prevStack,
608
+ stateStack[stateStack.length - 1],
609
+ ]);
610
+ setStateStack((prevStack) => prevStack.slice(0, -1));
611
+ // Only fetch data if the previous state has columns
612
+ handleMultiStateChange({
613
+ state: previousState,
614
+ fetchData: previousState.columns.length > 0,
615
+ updateStateStack: false,
616
+ });
617
+ };
618
+ const handleRedo = () => {
619
+ if (poppedStateStack.length === 0) {
620
+ return;
621
+ }
622
+ const lastState = poppedStateStack[poppedStateStack.length - 1];
623
+ setStateStack((prevStack) => [...prevStack, lastState]);
624
+ setPoppedStateStack((prevStack) => prevStack.slice(0, -1));
625
+ // Only fetch data if the last state has columns
626
+ handleMultiStateChange({
627
+ state: lastState,
628
+ fetchData: lastState.columns.length > 0,
629
+ updateStateStack: false,
630
+ });
631
+ };
632
+ const fetchDataFromReportBuilderState = ({ state, filtersChanged, limitChanged, tablesChanged, report, skipPivotColumnFetch, }) => {
633
+ if (!client) {
634
+ return;
635
+ }
636
+ const ast = (0, reportBuilder_1.reportBuilderStateToAst)(state, client.databaseType?.toLowerCase() || 'postgresql');
637
+ fetchReportFromASTHelper({
638
+ ast,
639
+ pivot: state.pivot,
640
+ previousReport: report,
641
+ requiresNewFilteredUniqueValues: filtersChanged || limitChanged,
642
+ requiresNewUnfilteredUniqueValues: tablesChanged,
643
+ skipPivotColumnFetch,
644
+ });
645
+ };
646
+ const fetchReportFromASTHelper = async ({ ast, pivot, previousReport = tempReport, requiresNewFilteredUniqueValues = false, requiresNewUnfilteredUniqueValues = false, skipPivotColumnFetch = false, }) => {
647
+ let reportBuilderInfo = undefined;
648
+ setErrorMessage('');
649
+ const schema = filteredSchema;
650
+ try {
651
+ if (!client || reportBuilderLoading) {
652
+ return;
653
+ }
654
+ setReportBuilderLoading(true);
655
+ reportBuilderInfo = await (0, report_1.fetchReportBuilderDataFromAST)({
656
+ baseAst: ast,
657
+ schema,
658
+ client,
659
+ tenants,
660
+ pivot: pivot ?? undefined,
661
+ skipPivotColumnFetch,
662
+ previousRelevant: {
663
+ uniqueStringsByTable: unfilteredUniqueValues,
664
+ dateRanges: dateRanges ?? {},
665
+ uniqueStringsByColumn: requiresNewFilteredUniqueValues
666
+ ? {}
667
+ : columnUniqueValues,
668
+ },
669
+ requiresNewFilteredUniqueValues,
670
+ report: previousReport,
671
+ customFields: schemaData.customFields,
672
+ skipUniqueValues: true,
673
+ skipRowCount: true,
674
+ processing: { page: REPORT_BUILDER_PAGINATION },
675
+ dashboardName: destinationDashboard,
676
+ getToken,
677
+ eventTracking,
678
+ });
679
+ if (reportBuilderInfo.error) {
680
+ throw new Error(reportBuilderInfo.error);
681
+ }
682
+ }
683
+ catch (err) {
684
+ eventTracking?.logError?.({
685
+ type: 'bug', // TODO: determine type
686
+ severity: 'high',
687
+ message: 'Error fetching report',
688
+ errorMessage: err.message,
689
+ errorStack: err.stack,
690
+ errorData: {
691
+ caller: 'ReportBuilder',
692
+ function: 'fetchReportFromASTHelper',
693
+ },
694
+ });
695
+ if (err instanceof Error) {
696
+ setErrorMessage(err.message);
697
+ setReportBuilderLoading(false);
698
+ return { error: true, message: err.message, rows: [] };
699
+ }
700
+ setReportBuilderLoading(false);
701
+ setErrorMessage('Failed to fetch');
702
+ return { error: true, message: 'Failed to fetch', rows: [] };
703
+ }
704
+ if (!reportBuilderInfo) {
705
+ setReportBuilderLoading(false);
706
+ setErrorMessage('Failed to fetch');
707
+ return;
708
+ }
709
+ const cleanedReport = await (0, dashboard_1.cleanDashboardItem)({
710
+ item: reportBuilderInfo.report,
711
+ dashboardFilters: [],
712
+ getToken,
713
+ client,
714
+ customFields: schemaData.customFields,
715
+ skipPivotFetch: true,
716
+ tenants,
717
+ eventTracking,
718
+ });
719
+ // set tempReport
720
+ setTempReport({
721
+ ...cleanedReport,
722
+ pagination: REPORT_BUILDER_PAGINATION,
723
+ });
724
+ setActiveQuery(reportBuilderInfo.query);
725
+ setQueryOutOfSync(false);
726
+ // table data
727
+ fetchRowCountFromAST(ast, ast.where);
728
+ setReportRows(reportBuilderInfo.rows);
729
+ setFormattedRows(reportBuilderInfo.formattedRows);
730
+ resetProcessing();
731
+ if (!(client.databaseType?.toLowerCase() === 'bigquery') ||
732
+ (reportBuilderInfo.rows && reportBuilderInfo.rows.length > 0)) {
733
+ setReportColumns(reportBuilderInfo.columns);
734
+ }
735
+ setPivotData(reportBuilderInfo.pivotData);
736
+ if (reportBuilderInfo.pivot) {
737
+ setPivotRowField(reportBuilderInfo.pivot.rowField);
738
+ setPivotColumnField(reportBuilderInfo.pivot.columnField);
739
+ setPivotAggregations(reportBuilderInfo.pivot.aggregations ?? [
740
+ {
741
+ valueField: reportBuilderInfo.pivot.valueField,
742
+ valueField2: reportBuilderInfo.pivot.valueField2,
743
+ aggregationType: reportBuilderInfo.pivot.aggregationType,
744
+ },
745
+ ]);
746
+ setPivotLimit(reportBuilderInfo.pivot.rowLimit);
747
+ setPivotSort(reportBuilderInfo.pivot.sort &&
748
+ reportBuilderInfo.pivot.sortField &&
749
+ reportBuilderInfo.pivot.sortDirection
750
+ ? {
751
+ sortField: reportBuilderInfo.pivot.sortField,
752
+ sortDirection: reportBuilderInfo.pivot.sortDirection.toUpperCase(),
753
+ }
754
+ : undefined);
755
+ }
756
+ setPivot(reportBuilderInfo.pivot);
757
+ setPivotHint(reportBuilderInfo.pivotHint);
758
+ setDateRanges(reportBuilderInfo.dateRanges);
759
+ const tableNames = reportBuilderInfo.tables;
760
+ const columnInfo = tableNames.flatMap((table) => {
761
+ const tableInfo = schema.find((tableInfo) => tableInfo.name === table);
762
+ if (!tableInfo) {
763
+ return [];
764
+ }
765
+ return tableInfo.columns.map((col) => ({ ...col, table }));
766
+ });
767
+ setReportBuilderLoading(false);
768
+ // fetch unique values after everything else since it is the most expensive
769
+ try {
770
+ let uniqueStrings = filteredUniqueValues ?? unfilteredUniqueValues;
771
+ let uniqueValuesByColumn = columnUniqueValues;
772
+ if (requiresNewUnfilteredUniqueValues) {
773
+ fetchGlobalUniqueValues(columnInfo, tableNames);
774
+ }
775
+ if (requiresNewFilteredUniqueValues) {
776
+ if (reportBuilderInfo.pivot && !skipPivotColumnFetch) {
777
+ // if there's a pivot, these values would have had to been fetched
778
+ uniqueStrings = reportBuilderInfo.uniqueStringsByTable;
779
+ uniqueValuesByColumn = reportBuilderInfo.uniqueStringsByColumn;
780
+ }
781
+ else {
782
+ setFilteredUniqueValuesIsLoading(true);
783
+ const starQuery = await (0, dataFetcher_1.fetchSqlQuery)((0, astProcessing_1.createSelectStarFromAst)(ast), client, getToken);
784
+ uniqueStrings = await (0, tableProcessing_1.getUniqueStringValuesByTable)({
785
+ columns: columnInfo,
786
+ tables: tableNames,
787
+ client,
788
+ tenants,
789
+ customFields: schemaData.customFields ?? undefined,
790
+ withExceededColumns: true,
791
+ dashboardName: destinationDashboard,
792
+ queryTemplate: starQuery.query,
793
+ getToken,
794
+ eventTracking,
795
+ });
796
+ uniqueValuesByColumn = {};
797
+ reportBuilderInfo.reportBuilderColumns.forEach((col) => {
798
+ uniqueValuesByColumn[col.alias || col.field] =
799
+ uniqueStrings[col.table || '']?.[col.field] ?? [];
800
+ });
801
+ }
802
+ }
803
+ setFilteredUniqueValues(uniqueStrings);
804
+ setFilteredUniqueValuesIsLoading(false);
805
+ setColumnUniqueValues(uniqueValuesByColumn);
806
+ }
807
+ catch (err) {
808
+ eventTracking?.logError?.({
809
+ type: 'bug', // TODO: determine type
810
+ severity: 'high',
811
+ message: 'Error fetching unique values',
812
+ errorMessage: err.message,
813
+ errorStack: err.stack,
814
+ errorData: {
815
+ caller: 'ReportBuilder',
816
+ function: 'fetchReportFromASTHelper',
817
+ },
818
+ });
819
+ if (err instanceof Error) {
820
+ setErrorMessage(err.message);
821
+ return { error: true, message: err.message, rows: [] };
822
+ }
823
+ setErrorMessage('Failed to fetch unique values');
824
+ return {
825
+ error: true,
826
+ message: 'Failed to fetch unique values',
827
+ rows: [],
828
+ };
829
+ }
830
+ };
831
+ const fetchRowCountFromAST = async (ast, where) => {
832
+ setRowCountIsLoading(true);
833
+ if (!client) {
834
+ return;
835
+ }
836
+ const tableData = await (0, tableProcessing_1.fetchTableByAST)({ ...ast, where }, client, getToken, tenants, eventTracking, destinationDashboard, { page: REPORT_BUILDER_PAGINATION }, schemaData.customFields, false, true);
837
+ if (tableData.rowCount) {
838
+ setNumberOfRows(tableData.rowCount);
839
+ // @ts-ignore
840
+ setTempReport((tempReport) => ({
841
+ ...tempReport,
842
+ rowCount: tableData.rowCount,
843
+ }));
844
+ }
845
+ setRowCountIsLoading(false);
846
+ };
847
+ const fetchAstFromPromptHelper = async (overridePrompt) => {
848
+ let astInfo = {};
849
+ const prompt = overridePrompt || aiPrompt;
850
+ if (!client) {
851
+ return;
852
+ }
853
+ if (!prompt) {
854
+ setErrorMessage('Please supply a prompt.');
855
+ return;
856
+ }
857
+ try {
858
+ setReportBuilderLoading(true);
859
+ setAskAILoading(true);
860
+ setErrorMessage('');
861
+ astInfo = await (0, astProcessing_1.fetchAndProcessASTFromPrompt)({
862
+ aiPrompt: prompt,
863
+ schema: filteredSchema,
864
+ client,
865
+ prevPivot: pivot ?? undefined,
866
+ currentQuery: activeQuery,
867
+ prevTable: tables?.[0]?.name,
868
+ dashboardName: destinationDashboard,
869
+ tenants,
870
+ getToken,
871
+ eventTracking,
872
+ });
873
+ if (astInfo.error) {
874
+ throw new Error(astInfo.error);
875
+ }
876
+ }
877
+ catch (err) {
878
+ eventTracking?.logError?.({
879
+ type: 'bug', // TODO: determine type
880
+ severity: 'high',
881
+ message: 'Error fetching ast',
882
+ errorMessage: err.message,
883
+ errorStack: err.stack,
884
+ errorData: {
885
+ caller: 'ReportBuilder',
886
+ function: 'fetchAstFromPromptHelper',
887
+ },
888
+ });
889
+ if (err instanceof Error) {
890
+ setErrorMessage(err.message);
891
+ }
892
+ setReportBuilderLoading(false);
893
+ setAskAILoading(false);
894
+ return;
895
+ }
896
+ // check if pivot works with ReportBuilder constraints
897
+ if (Object.keys(columnUniqueValues).length > 0 &&
898
+ astInfo.pivot &&
899
+ !(0, reportBuilder_1.isValidPivotForReport)(astInfo.pivot, columnUniqueValues, reportColumns)) {
900
+ astInfo.pivot = null;
901
+ astInfo.ast.groupby = null;
902
+ }
903
+ setAskAILoading(false);
904
+ const newState = (0, reportBuilder_1.astToReportBuilderState)(astInfo.ast, client.databaseType || 'postgresql', filteredSchema);
905
+ handleMultiStateChange({
906
+ state: { ...newState, pivot: astInfo.pivot },
907
+ fetchData: true,
908
+ });
909
+ };
910
+ const fetchGlobalUniqueValues = async (columns, tables) => {
911
+ if (!client) {
912
+ return;
913
+ }
914
+ setUnfilteredUniqueValuesIsLoading(true);
915
+ const uniqueStrings = await (0, tableProcessing_1.getUniqueStringValuesByTable)({
916
+ columns,
917
+ tables,
918
+ client,
919
+ getToken,
920
+ eventTracking,
921
+ tenants,
922
+ customFields: schemaData.customFields ?? undefined,
923
+ withExceededColumns: true,
924
+ dashboardName: destinationDashboard,
925
+ });
926
+ setUnfilteredUniqueValues(uniqueStrings);
927
+ setUnfilteredUniqueValuesIsLoading(false);
928
+ };
929
+ const fetchQueryFromReportBuilderState = async (state) => {
930
+ if (!client) {
931
+ return '';
932
+ }
933
+ const ast = (0, reportBuilder_1.reportBuilderStateToAst)(state, client.databaseType?.toLowerCase() || 'postgresql');
934
+ const query = await (0, dataFetcher_1.fetchSqlQuery)(ast, client, getToken);
935
+ setActiveQuery(query.query);
936
+ return query.query;
937
+ };
938
+ const resetProcessing = () => {
939
+ setCurrentProcessing({ page: REPORT_BUILDER_PAGINATION });
940
+ setPreviousPage(0);
941
+ };
942
+ const handlePagination = async (processing) => {
943
+ try {
944
+ if (!client) {
945
+ return;
946
+ }
947
+ const isPivotPagination = !!(pivot && pivotData);
948
+ setErrorMessage('');
949
+ setTableLoading(true);
950
+ const tableInfo = await (0, tableProcessing_1.fetchResultsByQuery)({
951
+ query: isPivotPagination ? pivotData.pivotQuery : activeQuery,
952
+ comparisonQuery: pivot && pivotData ? pivotData.comparisonPivotQuery : undefined,
953
+ client,
954
+ tenants,
955
+ processing,
956
+ customFields: schemaData.customFields,
957
+ rowsOnly: true,
958
+ dashboardName: destinationDashboard,
959
+ pivot: pivot,
960
+ getPivotRowCount: false,
961
+ getToken,
962
+ eventTracking,
963
+ });
964
+ if (tableInfo.error) {
965
+ throw new Error(tableInfo.error);
966
+ }
967
+ else if (tableInfo.rows.length === 0) {
968
+ throw new Error('No data found');
969
+ }
970
+ if (!isPivotPagination) {
971
+ const tempRows = [...reportRows, ...tableInfo.rows];
972
+ setReportRows(tempRows);
973
+ setFormattedRows((0, report_1.formatRowsFromReport)({ rows: tempRows, columns: tableInfo.columns }));
974
+ setTempReport((tempReport) => ({
975
+ ...tempReport,
976
+ rows: tempRows,
977
+ rowCount: tableInfo.rowCount ?? tempReport.rowCount,
978
+ }));
979
+ }
980
+ else {
981
+ const tempRows = [...pivotData.rows, ...tableInfo.rows];
982
+ setPivotData((oldPivotData) => {
983
+ if (oldPivotData) {
984
+ return {
985
+ ...oldPivotData,
986
+ rows: tempRows,
987
+ columns: tableInfo.columns,
988
+ };
989
+ }
990
+ return null;
991
+ });
992
+ setFormattedRows((0, report_1.formatRowsFromReport)({ rows: tempRows, columns: tableInfo.columns }));
993
+ }
994
+ setTableLoading(false);
995
+ }
996
+ catch (e) {
997
+ eventTracking?.logError?.({
998
+ type: 'bug', // TODO: determine type
999
+ severity: 'high',
1000
+ message: 'Error fetching report',
1001
+ errorMessage: e.message,
1002
+ errorStack: e.stack,
1003
+ errorData: {
1004
+ caller: 'ReportBuilder',
1005
+ function: 'handlePagination',
1006
+ },
1007
+ });
1008
+ setTableLoading(false);
1009
+ setErrorMessage('Failed to run SQL query: ' + e.message);
1010
+ setReportRows([]);
1011
+ setReportColumns([]);
1012
+ return;
1013
+ }
1014
+ };
1015
+ const onPageChange = (page) => {
1016
+ const pagination = REPORT_BUILDER_PAGINATION;
1017
+ if (currentProcessing.page &&
1018
+ (0, paginationProcessing_1.shouldFetchMore)(pagination, page, previousPage, pivotData ? pivotData.rows.length : reportRows.length)) {
1019
+ const newPagination = { ...currentProcessing.page, page };
1020
+ const updatedProcessing = { ...currentProcessing, page: newPagination };
1021
+ setCurrentProcessing(updatedProcessing);
1022
+ handlePagination(updatedProcessing);
1023
+ }
1024
+ if (page > previousPage) {
1025
+ setPreviousPage(page);
1026
+ }
1027
+ };
1028
+ const onSortChange = (newSort, isPivotSort, isDelete) => {
1029
+ if (!newSort.field) {
1030
+ return;
1031
+ }
1032
+ if (pivot && isPivotSort) {
1033
+ let newPivot = null;
1034
+ if (isDelete) {
1035
+ newPivot = {
1036
+ ...pivot,
1037
+ sort: undefined,
1038
+ sortField: undefined,
1039
+ sortDirection: undefined,
1040
+ sortFieldType: undefined,
1041
+ };
1042
+ }
1043
+ else {
1044
+ newPivot = {
1045
+ ...pivot,
1046
+ sort: true,
1047
+ sortField: newSort.field,
1048
+ sortDirection: newSort.direction,
1049
+ sortFieldType: reportColumns.find((col) => col.field === newSort.field)?.fieldType,
1050
+ };
1051
+ }
1052
+ handlePivotChange(newPivot, true);
1053
+ }
1054
+ else {
1055
+ const updatedSort = [...sort];
1056
+ const existingSortIndex = updatedSort.findIndex((item) => item.field === newSort.field);
1057
+ if (isDelete) {
1058
+ if (existingSortIndex !== -1) {
1059
+ updatedSort.splice(existingSortIndex, 1);
1060
+ }
1061
+ }
1062
+ else if (existingSortIndex !== -1) {
1063
+ updatedSort[existingSortIndex] = {
1064
+ field: newSort.field,
1065
+ direction: newSort.direction,
1066
+ };
1067
+ }
1068
+ else {
1069
+ updatedSort.push({
1070
+ field: newSort.field,
1071
+ direction: newSort.direction,
1072
+ });
1073
+ }
1074
+ handleSortChange(updatedSort, true);
1075
+ }
1076
+ };
1077
+ const onLimitChange = (limit, isPivotLimit) => {
1078
+ if (limit) {
1079
+ if (pivot && isPivotLimit) {
1080
+ const newPivot = { ...pivot, rowLimit: limit };
1081
+ handlePivotChange(newPivot, true);
1082
+ }
1083
+ else {
1084
+ handleLimitChange({ value: limit }, true);
1085
+ }
1086
+ }
1087
+ else {
1088
+ if (pivot && isPivotLimit) {
1089
+ const newPivot = { ...pivot, rowLimit: undefined };
1090
+ handlePivotChange(newPivot, true);
1091
+ }
1092
+ else {
1093
+ handleLimitChange(null, true);
1094
+ }
1095
+ }
1096
+ };
1097
+ // Button events
1098
+ const onSaveQuery = async () => {
1099
+ let tempReportQuery = activeQuery;
1100
+ if (queryOutOfSync) {
1101
+ tempReportQuery =
1102
+ await fetchQueryFromReportBuilderState(reportBuilderState);
1103
+ }
1104
+ const tempReportColumns = columns
1105
+ .map((column) => {
1106
+ return reportColumnsToStateColumns.find((col) => col.field === (column.alias || column.field));
1107
+ })
1108
+ .filter((col) => col !== undefined);
1109
+ let customFieldColumns = [];
1110
+ if (client && isSelectStar && schemaData.customFields) {
1111
+ customFieldColumns = tables.flatMap((table) => {
1112
+ return (schemaData.customFields?.[table.name || ''] || []).map((field) => field.field);
1113
+ });
1114
+ }
1115
+ setTempReport({
1116
+ ...tempReport,
1117
+ ...(pivot
1118
+ ? (0, pivotProcessing_1.pivotFormData)(pivot, reportColumnsToStateColumns, tempReport, tempReport.chartType, pivotData ?? undefined)
1119
+ : {}),
1120
+ id: Report_1.TEMP_REPORT_ID,
1121
+ dashboardName: destinationDashboard,
1122
+ pivot: pivot,
1123
+ yAxisFields: tempReport?.pivot && !pivot ? [] : tempReport?.yAxisFields,
1124
+ columns: isSelectStar
1125
+ ? // if SELECT *, filter out custom fields from tabular view
1126
+ // so Automatic Custom Fields can be applied
1127
+ tempReportColumns.filter((col) => {
1128
+ return !customFieldColumns.includes(col.field);
1129
+ })
1130
+ : tempReportColumns,
1131
+ columnInternal: isSelectStar
1132
+ ? // if SELECT *, filter out custom fields from tabular view
1133
+ // so Automatic Custom Fields can be applied
1134
+ tempReportColumns.filter((col) => {
1135
+ return !customFieldColumns.includes(col.field);
1136
+ })
1137
+ : tempReportColumns,
1138
+ queryString: isSelectStar
1139
+ ? (0, convert_1.convertQueryToSelectStar)(tempReportQuery)
1140
+ : tempReportQuery,
1141
+ includeCustomFields: isSelectStar,
1142
+ rows: reportRows,
1143
+ pivotRows: pivotData?.rows,
1144
+ pivotColumns: pivotData?.columns,
1145
+ pivotRowCount: pivotData?.rowCount,
1146
+ pivotQuery: pivotData?.pivotQuery,
1147
+ comparisonPivotQuery: pivotData?.comparisonPivotQuery,
1148
+ flags: tempReport?.flags,
1149
+ chartType: 'table',
1150
+ });
1151
+ };
1152
+ const onSaveReport = async () => {
1153
+ let tempReportQuery = activeQuery;
1154
+ if (queryOutOfSync) {
1155
+ tempReportQuery =
1156
+ await fetchQueryFromReportBuilderState(reportBuilderState);
1157
+ }
1158
+ onSaveChanges && onSaveChanges();
1159
+ const tempReportColumns = columns
1160
+ .map((column) => {
1161
+ return reportColumnsToStateColumns.find((col) => col.field === (column.alias || column.field));
1162
+ })
1163
+ .filter((col) => col !== undefined);
1164
+ let customFieldColumns = [];
1165
+ if (client && isSelectStar && schemaData.customFields) {
1166
+ customFieldColumns = tables.flatMap((table) => {
1167
+ return (schemaData.customFields?.[table.name || ''] || []).map((field) => field.field);
1168
+ });
1169
+ }
1170
+ setTempReport({
1171
+ ...tempReport,
1172
+ ...(pivot
1173
+ ? (0, pivotProcessing_1.pivotFormData)(pivot, reportColumnsToStateColumns, tempReport, tempReport.chartType, pivotData ?? undefined)
1174
+ : {}),
1175
+ id: Report_1.TEMP_REPORT_ID,
1176
+ dashboardName: destinationDashboard,
1177
+ pivot: pivot,
1178
+ yAxisFields: tempReport?.pivot && !pivot ? [] : tempReport?.yAxisFields,
1179
+ columns: isSelectStar
1180
+ ? // if SELECT *, filter out custom fields from tabular view
1181
+ // so Automatic Custom Fields can be applied
1182
+ tempReportColumns.filter((col) => {
1183
+ return !customFieldColumns.includes(col.field);
1184
+ })
1185
+ : tempReportColumns,
1186
+ columnInternal: isSelectStar
1187
+ ? // if SELECT *, filter out custom fields from tabular view
1188
+ // so Automatic Custom Fields can be applied
1189
+ tempReportColumns.filter((col) => {
1190
+ return !customFieldColumns.includes(col.field);
1191
+ })
1192
+ : tempReportColumns,
1193
+ queryString: isSelectStar
1194
+ ? (0, convert_1.convertQueryToSelectStar)(tempReportQuery)
1195
+ : tempReportQuery,
1196
+ includeCustomFields: isSelectStar,
1197
+ rows: reportRows,
1198
+ pivotRows: pivotData?.rows,
1199
+ pivotColumns: pivotData?.columns,
1200
+ pivotRowCount: pivotData?.rowCount,
1201
+ pivotQuery: pivotData?.pivotQuery,
1202
+ comparisonPivotQuery: pivotData?.comparisonPivotQuery,
1203
+ flags: tempReport?.flags,
1204
+ });
1205
+ };
1206
+ (0, react_1.useEffect)(() => {
1207
+ if (!client) {
1208
+ return;
1209
+ }
1210
+ if (client.featureFlags?.['recommendedPivotsDisabled'] !== undefined) {
1211
+ setPivotRecommendationsEnabledState(!client.featureFlags?.['recommendedPivotsDisabled']);
1212
+ }
1213
+ if (!initialTableName && !reportId && client.publicKey) {
1214
+ clearAllState();
1215
+ }
1216
+ }, [client]);
1217
+ // Initialize ReportBuilder with a report
1218
+ (0, react_1.useEffect)(() => {
1219
+ const loadChart = async () => {
1220
+ let report;
1221
+ if (!client) {
1222
+ return;
1223
+ }
1224
+ try {
1225
+ if (!reportId) {
1226
+ throw new Error('Report ID is required');
1227
+ }
1228
+ report = allReportsById[reportId];
1229
+ if (!report) {
1230
+ console.log('no report');
1231
+ throw new Error('Report not found');
1232
+ }
1233
+ const { ast: newAst, pivot: newPivot } = await (0, astProcessing_1.fetchASTFromQuillReport)(report, client, filteredSchema, getToken, eventTracking);
1234
+ const initialState = (0, reportBuilder_1.astToReportBuilderState)(newAst, client.databaseType || 'postgresql', filteredSchema);
1235
+ setTempReport(report);
1236
+ handleMultiStateChange({
1237
+ state: {
1238
+ ...initialState,
1239
+ pivot: newPivot ?? null,
1240
+ },
1241
+ fetchData: true,
1242
+ report,
1243
+ skipPivotColumnFetch: true,
1244
+ });
1245
+ }
1246
+ catch (err) {
1247
+ console.error(err);
1248
+ eventTracking?.logError?.({
1249
+ type: 'bug', // TODO: determine type
1250
+ severity: 'high',
1251
+ message: 'Error fetching report',
1252
+ errorMessage: err.message,
1253
+ errorStack: err.stack,
1254
+ errorData: {
1255
+ caller: 'ReportBuilder',
1256
+ function: 'loadChart',
1257
+ },
1258
+ });
1259
+ setErrorMessage('Error when loading chart');
1260
+ }
1261
+ };
1262
+ if (reportId && client) {
1263
+ loadChart();
1264
+ }
1265
+ }, [allReportsById[reportId || ''], client]);
1266
+ (0, react_1.useEffect)(() => {
1267
+ if (initialTableName) {
1268
+ const tableColumns = filteredSchema.find((table) => {
1269
+ return table.name === initialTableName;
1270
+ })?.columns ?? [];
1271
+ if (tableColumns.length > 0) {
1272
+ handleMultiStateChange({
1273
+ state: {
1274
+ ...ReportBuilder_1.EMPTY_REPORT_BUILDER_STATE,
1275
+ tables: [{ name: initialTableName }],
1276
+ columns: tableColumns.map((col) => ({
1277
+ field: col.field,
1278
+ table: initialTableName,
1279
+ })),
1280
+ },
1281
+ fetchData: true,
1282
+ });
1283
+ }
1284
+ }
1285
+ }, [filteredSchema, initialTableName]);
1286
+ (0, react_1.useEffect)(() => {
1287
+ if (!data && !dashboardIsLoading) {
1288
+ // need dashboard to be in Context for filteredSchema
1289
+ reload();
1290
+ }
1291
+ }, [data, dashboardIsLoading]);
1292
+ return {
1293
+ // Core state
1294
+ columns,
1295
+ tables,
1296
+ sort,
1297
+ limit,
1298
+ filterStack,
1299
+ state: reportBuilderState,
1300
+ activeQuery,
1301
+ tempReport,
1302
+ stateStack,
1303
+ poppedStateStack,
1304
+ // UI state
1305
+ openPopover,
1306
+ setOpenPopover,
1307
+ errorMessage,
1308
+ unresolvedReportMessage,
1309
+ loading,
1310
+ tableLoading,
1311
+ askAILoading,
1312
+ rowCountIsLoading,
1313
+ unfilteredUniqueValuesIsLoading,
1314
+ filteredUniqueValuesIsLoading,
1315
+ mssqlSortWarning,
1316
+ // Data and results
1317
+ reportColumnsToStateColumns,
1318
+ reportRows,
1319
+ formattedRows,
1320
+ numberOfRows,
1321
+ unfilteredUniqueValues,
1322
+ filteredUniqueValues,
1323
+ columnUniqueValues,
1324
+ rowsPerPage: _rowsPerPage,
1325
+ rowsPerRequest: _rowsPerRequest,
1326
+ // Pivot state and handlers
1327
+ pivot,
1328
+ pivotData,
1329
+ pivotRowField,
1330
+ pivotColumnField,
1331
+ pivotAggregations,
1332
+ pivotLimit,
1333
+ pivotSort,
1334
+ pivotHint,
1335
+ pivotError,
1336
+ createdPivots,
1337
+ recommendedPivots,
1338
+ pivotPopUpTitle,
1339
+ showPivotPopover,
1340
+ isEditingPivot,
1341
+ selectedPivotIndex,
1342
+ pivotRecommendationsEnabledState,
1343
+ setCreatedPivots,
1344
+ setRecommendedPivots,
1345
+ setPivotPopUpTitle,
1346
+ setShowPivotPopover,
1347
+ setIsEditingPivot,
1348
+ setSelectedPivotIndex,
1349
+ setPivotRowField,
1350
+ setPivotColumnField,
1351
+ setPivotAggregations,
1352
+ setPivotLimit,
1353
+ setPivotSort,
1354
+ setPivotError,
1355
+ handlePivotChange,
1356
+ updatePivot,
1357
+ // Schema and client info
1358
+ filteredSchema,
1359
+ foreignKeyMap,
1360
+ schemaData,
1361
+ client,
1362
+ getToken,
1363
+ reportId,
1364
+ initialTableName,
1365
+ destinationDashboard,
1366
+ // AI features
1367
+ aiPrompt,
1368
+ setAiPrompt,
1369
+ fetchAstFromPromptHelper,
1370
+ // Action handlers
1371
+ clearAllState,
1372
+ handleMultiStateChange,
1373
+ handleTablesChange,
1374
+ handleColumnsChange,
1375
+ handleFilterInsertion,
1376
+ handleFilterStackChange,
1377
+ handleUndo,
1378
+ handleRedo,
1379
+ onSortChange,
1380
+ onLimitChange,
1381
+ handleSortChange,
1382
+ handleLimitChange,
1383
+ onPageChange,
1384
+ onSaveQuery,
1385
+ onSaveReport,
1386
+ };
1387
+ };
1388
+ exports.useReportBuilderInternal = useReportBuilderInternal;
1389
+ const useReportBuilder = ({ reportId, ownerDashboard, config, }) => {
1390
+ const reportBuilder = (0, exports.useReportBuilderInternal)({
1391
+ reportId,
1392
+ initialTableName: config?.initialTableName,
1393
+ destinationDashboard: ownerDashboard,
1394
+ pivotRecommendationsEnabled: config?.pivotRecommendationsEnabled,
1395
+ onSaveChanges: config?.onSaveChanges,
1396
+ rowsPerPage: config?.rowsPerPage,
1397
+ rowsPerRequest: config?.rowsPerRequest,
1398
+ });
1399
+ // Column selection actions
1400
+ const setColumns = (newColumns) => {
1401
+ reportBuilder.handleColumnsChange(newColumns.map((col) => ({
1402
+ field: col.field,
1403
+ table: col.table,
1404
+ })), true);
1405
+ };
1406
+ // // Filter actions
1407
+ const setFilters = (filters) => {
1408
+ const internalFilters = filters.map(Filter_1.convertCustomFilter);
1409
+ // Create a filter tree with all filters chained with AND
1410
+ const filterStack = internalFilters.reduce((stack, filter, index) => {
1411
+ // Create leaf node for current filter
1412
+ const filterNode = {
1413
+ leaf: true,
1414
+ operator: null,
1415
+ leftNode: null,
1416
+ rightNode: null,
1417
+ value: filter,
1418
+ };
1419
+ // If not first filter, add an AND node
1420
+ if (index > 0) {
1421
+ stack.push({
1422
+ leaf: false,
1423
+ operator: 'and',
1424
+ leftNode: null,
1425
+ rightNode: null,
1426
+ });
1427
+ }
1428
+ stack.push(filterNode);
1429
+ return stack;
1430
+ }, []);
1431
+ reportBuilder.handleFilterStackChange(filterStack, true);
1432
+ };
1433
+ // // Pivot actions
1434
+ const setPivot = (newPivot) => {
1435
+ reportBuilder.handlePivotChange(newPivot, true);
1436
+ };
1437
+ const setSort = (sort) => {
1438
+ reportBuilder.handleSortChange(sort, true);
1439
+ };
1440
+ // // Limit actions
1441
+ const setLimit = (limit) => {
1442
+ reportBuilder.handleLimitChange(limit, true);
1443
+ };
1444
+ // // AI actions
1445
+ const applyAIPrompt = async (prompt) => {
1446
+ reportBuilder.setAiPrompt(prompt);
1447
+ await reportBuilder.fetchAstFromPromptHelper(prompt);
1448
+ };
1449
+ const cleanedSchema = (0, react_1.useMemo)(() => {
1450
+ return reportBuilder.filteredSchema.reduce((acc, table) => {
1451
+ acc[table.name] = table.columns;
1452
+ return acc;
1453
+ }, {});
1454
+ }, [reportBuilder.filteredSchema]);
1455
+ const cleanedFilterStack = (0, react_1.useMemo)(() => {
1456
+ return reportBuilder.filterStack
1457
+ .map((filter) => {
1458
+ return filter.value
1459
+ ? (0, Filter_1.convertInternalFilterToFilter)(filter.value)
1460
+ : null;
1461
+ })
1462
+ .filter((filter) => filter !== null);
1463
+ }, [reportBuilder.filterStack]);
1464
+ return {
1465
+ reportBuilder,
1466
+ state: {
1467
+ schema: cleanedSchema,
1468
+ columns: reportBuilder.columns,
1469
+ filters: cleanedFilterStack,
1470
+ pivot: reportBuilder.pivot,
1471
+ sort: reportBuilder.sort,
1472
+ limit: reportBuilder.limit,
1473
+ reportBuilderLoading: reportBuilder.loading,
1474
+ tableLoading: reportBuilder.tableLoading,
1475
+ tableRows: reportBuilder.formattedRows,
1476
+ tableColumns: reportBuilder.pivot && reportBuilder.pivotData
1477
+ ? reportBuilder.pivotData.columns
1478
+ : reportBuilder.reportColumnsToStateColumns,
1479
+ tableRowsCount: reportBuilder.pivot && reportBuilder.pivotData
1480
+ ? reportBuilder.pivotData.rowCount
1481
+ : reportBuilder.numberOfRows,
1482
+ errorMessage: reportBuilder.errorMessage,
1483
+ },
1484
+ actions: {
1485
+ setColumns,
1486
+ setFilters,
1487
+ setPivot,
1488
+ setSort,
1489
+ setLimit,
1490
+ onPageChange: reportBuilder.onPageChange,
1491
+ applyAIPrompt,
1492
+ },
1493
+ };
1494
+ };
1495
+ exports.useReportBuilder = useReportBuilder;