@quillsql/react 2.14.13 → 2.14.14

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