@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
@@ -1,38 +1,23 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useContext, useEffect, useMemo, useRef, useState, } from 'react';
2
+ import { useContext, useEffect, useRef, useState, } from 'react';
3
3
  import { MemoizedButton, MemoizedDeleteButton, MemoizedHeader, MemoizedLabel, MemoizedSecondaryButton, MemoizedText, MemoizedPopover, QuillTabs, MemoizedModal, QuillChartBuilderInputRowContainer, QuillChartBuilderInputColumnContainer, MemoizedSubHeader, QuillErrorMessageComponent, QuillPivotRowContainer, QuillPivotColumnContainer, QuillColumnSearchEmptyState, QuillChartBuilderFormContainer, QuillLoadingComponent, QuillTableReportBuilderComponent, QuillChartBuilderCheckboxComponent, QuillToolTip, } from './components/UiComponents';
4
- import { ClientContext, FetchContext, SchemaDataContext, TenantContext, ThemeContext, } from './Context';
4
+ import { ThemeContext } from './Context';
5
5
  import { ChartBuilderWithModal } from './ChartBuilder';
6
6
  import { QuillTextInput } from './components/UiComponents';
7
7
  import { QuillSidebar, CustomContainer, QuillSelectColumn, QuillDraggableColumn, QuillSidebarHeading, QuillFilterPopover, QuillSortPopover, QuillLimitPopover, } from './components/ReportBuilder/ui';
8
- import { AddSortPopover, SortSentence, } from './components/ReportBuilder/AddSortPopover';
9
- import { PivotModal } from './internals/ReportBuilder/PivotModal';
10
- import { snakeAndCamelCaseToTitleCase } from './utils/textProcessing';
11
- import { AddLimitPopover, LimitSentence, } from './components/ReportBuilder/AddLimitPopover';
12
8
  import { updateFirstChildWidth } from './utils/width';
13
9
  import { QuillSelectComponent } from './components/QuillSelect';
14
10
  import { QuillCard } from './components/QuillCard';
15
- import { isValidPivot, pivotFormData } from './utils/pivotProcessing';
16
- import { fetchResultsByQuery, fetchTableByAST, getUniqueStringValuesByTable, } from './utils/tableProcessing';
17
- import { createSelectStarFromAst, fetchAndProcessASTFromPrompt, fetchASTFromQuillReport, } from './utils/astProcessing';
18
- import PivotForm from './internals/ReportBuilder/PivotForm';
19
- import FilterModal from './components/ReportBuilder/FilterModal';
20
11
  import { QuillMultiSelectComponentWithCombo } from './components/QuillMultiSelectWithCombo';
21
- import { DEFAULT_PAGINATION, shouldFetchMore, } from './utils/paginationProcessing';
22
- import { EMPTY_INTERNAL_REPORT, fetchReportBuilderDataFromAST, formatRowsFromReport, } from './utils/report';
23
- import { TEMP_REPORT_ID, } from './models/Report';
24
- import FilterStack from './components/ReportBuilder/FilterStack';
25
- import { SINGLE_TENANT, SAVED_QUERIES_DASHBOARD } from './utils/constants';
26
- import { convertQueryToSelectStar } from './components/ReportBuilder/convert';
27
- import { cleanDashboardItem } from './utils/dashboard';
28
- import { useAllReports, useDashboardInternal, useDashboards, } from './hooks/useDashboard';
29
- import { EMPTY_REPORT_BUILDER_STATE, } from './models/ReportBuilder';
30
- import DraggableColumns from './components/ReportBuilder/DraggableColumns';
31
- import AddColumnModal from './components/ReportBuilder/AddColumnModal';
32
- import { astToReportBuilderState, formatRows, isValidPivotForReport, reportBuilderStateToAst, setTypesOnPivot, validatedReportBuilderState, } from './utils/reportBuilder';
33
- import { fetchSqlQuery } from './utils/dataFetcher';
34
- import { getSchemaForeignKeyMapping } from './utils/schema';
35
- import { filterSentence } from './utils/filterProcessing';
12
+ import { SAVED_QUERIES_DASHBOARD } from './utils/constants';
13
+ import { useReportBuilderInternal } from './hooks/useReportBuilder';
14
+ import { AddColumns } from './components/ReportBuilder/ColumnComponent';
15
+ import { AddFilters } from './components/ReportBuilder/FilterComponent';
16
+ import { AddPivot } from './components/ReportBuilder/PivotComponent';
17
+ import { AddLimit } from './components/ReportBuilder/LimitComponent';
18
+ import { AddSort } from './components/ReportBuilder/SortComponent';
19
+ import { SaveReport } from './components/ReportBuilder/SaveReport';
20
+ import { ReportTable } from './components/ReportBuilder/TableComponent';
36
21
  /**
37
22
  * Quill Report Builder
38
23
  *
@@ -64,7 +49,7 @@ import { filterSentence } from './utils/filterProcessing';
64
49
  * ### Report Builder API
65
50
  * @see https://docs.quillsql.com/components/report-builder
66
51
  */
67
- export default function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void null, onSubmitCreateReport = () => void null, onSubmitSaveQuery = () => void null, onDiscardChanges = undefined, onSaveChanges = undefined, onCloseChartBuilder = undefined, destinationDashboard, destinationSection, chartBuilderTitle = undefined, organizationName = '', ButtonComponent = MemoizedButton, SecondaryButtonComponent = MemoizedSecondaryButton, DeleteButtonComponent = MemoizedDeleteButton, ModalComponent = MemoizedModal, TextInputComponent = QuillTextInput, SelectComponent = QuillSelectComponent, MultiSelectComponent = QuillMultiSelectComponentWithCombo, TableComponent = QuillTableReportBuilderComponent, PopoverComponent = MemoizedPopover, TabsComponent = QuillTabs, CheckboxComponent = QuillChartBuilderCheckboxComponent, SidebarComponent = QuillSidebar, ContainerComponent = CustomContainer, SelectColumnComponent = QuillSelectColumn, DraggableColumnComponent = QuillDraggableColumn, SidebarHeadingComponent = QuillSidebarHeading, FilterPopoverComponent = QuillFilterPopover, SortPopoverComponent = QuillSortPopover, LimitPopoverComponent = QuillLimitPopover, CardComponent = QuillCard, LabelComponent = MemoizedLabel, HeaderComponent = MemoizedHeader, SubHeaderComponent = MemoizedSubHeader, TextComponent = MemoizedText, ErrorMessageComponent = QuillErrorMessageComponent, ChartBuilderInputRowContainer = QuillChartBuilderInputRowContainer, ChartBuilderInputColumnContainer = QuillChartBuilderInputColumnContainer, PivotRowContainer = QuillPivotRowContainer, PivotColumnContainer = QuillPivotColumnContainer, LoadingComponent = QuillLoadingComponent, ColumnSearchEmptyState = QuillColumnSearchEmptyState, ChartBuilderFormContainer = QuillChartBuilderFormContainer, ChartBuilderModalComponent = MemoizedModal, isAdminEnabled = false, isAIEnabled = true, containerStyle, className, pivotRecommendationsEnabled = true, reportId, hideCopySQL = true, isChartBuilderHorizontalView = true, onClickChartElement, }) {
52
+ export default function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void null, onSubmitCreateReport = () => void null, onSubmitSaveQuery = () => void null, onDiscardChanges = undefined, onSaveChanges = undefined, onCloseChartBuilder = undefined, destinationDashboard, destinationSection, chartBuilderTitle = undefined, organizationName = '', ButtonComponent = MemoizedButton, SecondaryButtonComponent = MemoizedSecondaryButton, DeleteButtonComponent = MemoizedDeleteButton, ModalComponent = MemoizedModal, TextInputComponent = QuillTextInput, SelectComponent = QuillSelectComponent, MultiSelectComponent = QuillMultiSelectComponentWithCombo, TableComponent = QuillTableReportBuilderComponent, PopoverComponent = MemoizedPopover, TabsComponent = QuillTabs, CheckboxComponent = QuillChartBuilderCheckboxComponent, SidebarComponent = QuillSidebar, ContainerComponent = CustomContainer, SelectColumnComponent = QuillSelectColumn, DraggableColumnComponent = QuillDraggableColumn, SidebarHeadingComponent = QuillSidebarHeading, FilterPopoverComponent = QuillFilterPopover, SortPopoverComponent = QuillSortPopover, LimitPopoverComponent = QuillLimitPopover, CardComponent = QuillCard, LabelComponent = MemoizedLabel, HeaderComponent = MemoizedHeader, SubHeaderComponent = MemoizedSubHeader, TextComponent = MemoizedText, ErrorMessageComponent = QuillErrorMessageComponent, ChartBuilderInputRowContainer = QuillChartBuilderInputRowContainer, ChartBuilderInputColumnContainer = QuillChartBuilderInputColumnContainer, PivotRowContainer = QuillPivotRowContainer, PivotColumnContainer = QuillPivotColumnContainer, LoadingComponent = QuillLoadingComponent, ColumnSearchEmptyState = QuillColumnSearchEmptyState, ChartBuilderFormContainer = QuillChartBuilderFormContainer, ChartBuilderModalComponent = MemoizedModal, isAdminEnabled = false, isAIEnabled = true, containerStyle, className, pivotRecommendationsEnabled = true, reportId, hideCopySQL = true, isChartBuilderHorizontalView = true, onClickChartElement, onRequestAddVirtualTable, }) {
68
53
  /**
69
54
  * The state of the ReportBuilder is based off of an AST, which is a representation of a sql query
70
55
  * ASTs for the same query can vary between database types, so we create a layer of abstraction on top of it
@@ -104,928 +89,45 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
104
89
  // isChartBuilderHorizontalView: whether the chart builder is in horizontal view mode
105
90
  // onClickChartElement: a callback function triggered when a chart element is clicked
106
91
  // Contexts
107
- const { allReportsById } = useAllReports();
108
- const [schemaData] = useContext(SchemaDataContext);
109
- const { dashboards } = useDashboards();
110
- const { data, isLoading: dashboardIsLoading, reload, } = useDashboardInternal(destinationDashboard);
111
- const { getToken } = useContext(FetchContext);
112
- const destinationDashboardConfig = useMemo(() => {
113
- return dashboards?.find((d) => d.name === destinationDashboard);
114
- }, [dashboards, destinationDashboard]);
115
- const filteredSchema = useMemo(() => {
116
- return schemaData.schemaWithCustomFields?.filter((table) => {
117
- return (destinationDashboardConfig?.tenantKeys?.[0] === SINGLE_TENANT ||
118
- !table.ownerTenantFields ||
119
- table.ownerTenantFields?.length === 0 ||
120
- table.ownerTenantFields?.includes(destinationDashboardConfig?.tenantKeys?.[0] ?? ''));
121
- });
122
- }, [
123
- schemaData.schemaWithCustomFields,
124
- destinationDashboardConfig?.tenantKeys,
125
- ]);
126
- const { tenants } = useContext(TenantContext);
127
92
  const [theme] = useContext(ThemeContext);
128
- const [client] = useContext(ClientContext);
129
93
  // Refs
130
94
  const parentRef = useRef(null);
131
- // Consts
132
- const REPORT_BUILDER_PAGINATION = {
133
- page: 0,
134
- rowsPerPage: 20,
135
- rowsPerRequest: 100,
136
- };
137
- // ReportBuilder UI States
95
+ const askAIContainerRef = useRef(null);
96
+ const [askAIInputWidth, setAskAIInputWidth] = useState(-1);
97
+ // UI
98
+ const [isCopying, setIsCopying] = useState(false);
138
99
  const [isChartBuilderOpen, setIsChartBuilderOpen] = useState(false);
139
- const [filtersEnabled, setFiltersEnabled] = useState(!!reportId);
140
100
  const [isSaveQueryModalOpen, setIsSaveQueryModalOpen] = useState(false);
141
- const [openPopover, setOpenPopover] = useState(null);
142
- const [aiPrompt, setAiPrompt] = useState('');
143
- const [reportBuilderLoading, setReportBuilderLoading] = useState(false);
144
- const [tableLoading, setTableLoading] = useState(false);
145
- const [errorMessage, setErrorMessage] = useState('');
146
- const [unresolvedReportMessage, setUnresolvedReportMessage] = useState('');
147
- // Core Report states
148
- // Table order matters for joins. For now, assumed to have one 'primary' table (the first one)
149
- const [tables, setTables] = useState([]);
150
- const [columns, setColumns] = useState([]);
151
- const [filterStack, setFilterStack] = useState([]);
152
- const [pivot, setPivot] = useState(null);
153
- const [sort, setSort] = useState([]);
154
- const [limit, setLimit] = useState(null);
155
- const reportBuilderState = useMemo(() => {
156
- return {
157
- tables,
158
- columns,
159
- filterStack,
160
- pivot,
161
- sort,
162
- limit,
163
- };
164
- }, [columns, filterStack, limit, pivot, sort, tables]);
165
- // For undo/redo
166
- const [stateStack, setStateStack] = useState([]);
167
- const [poppedStateStack, setPoppedStateStack] = useState([]);
168
- // Other Report states
169
- const [activeQuery, setActiveQuery] = useState('');
170
- const [queryOutOfSync, setQueryOutOfSync] = useState(false);
171
- const [unfilteredUniqueValues, setUnfilteredUniqueValues] = useState({}); // unique values before filtering
172
- const [unfilteredUniqueValuesIsLoading, setUnfilteredUniqueValuesIsLoading] = useState(false);
173
- const [filteredUniqueValues, setFilteredUniqueValues] = useState(null); // unique values after filtering
174
- const [filteredUniqueValuesIsLoading, setFilteredUniqueValuesIsLoading] = useState(false);
175
- const [columnUniqueValues, setColumnUniqueValues] = useState({});
176
- const [dateRanges, setDateRanges] = useState(null);
177
- const [tempReport, setTempReport] = useState({
178
- ...EMPTY_INTERNAL_REPORT,
179
- pagination: REPORT_BUILDER_PAGINATION,
180
- });
181
- const [currentProcessing, setCurrentProcessing] = useState({
182
- page: REPORT_BUILDER_PAGINATION,
101
+ // Main
102
+ const reportBuilder = useReportBuilderInternal({
103
+ reportId,
104
+ initialTableName,
105
+ destinationDashboard,
106
+ pivotRecommendationsEnabled,
107
+ onSaveChanges,
183
108
  });
184
- const [previousPage, setPreviousPage] = useState(0);
185
- const [isCopying, setIsCopying] = useState(false);
186
- const [sortOrLimitWasReset, setSortOrLimitWasReset] = useState(false);
187
- // Table display states
188
- const [reportColumns, setReportColumns] = useState([]);
189
- const [reportRows, setReportRows] = useState([]);
190
- const [formattedRows, setFormattedRows] = useState([]);
191
- const [pivotData, setPivotData] = useState(null);
192
- const [numberOfRows, setNumberOfRows] = useState(0);
193
- const [rowCountIsLoading, setRowCountIsLoading] = useState(false);
194
- const reportColumnsToStateColumns = useMemo(() => {
195
- const positionMap = {};
196
- columns.forEach((column, index) => {
197
- positionMap[column.field] = index;
198
- if (column.alias) {
199
- positionMap[column.alias] = index;
200
- }
201
- });
202
- // Sort reportColumns based on the position in columns
203
- return [...reportColumns]
204
- .filter((reportColumn) => positionMap[reportColumn.field] !== undefined)
205
- .sort((a, b) => {
206
- const posA = positionMap[a.field];
207
- const posB = positionMap[b.field];
208
- if (posA !== undefined && posB !== undefined) {
209
- return posA - posB;
210
- }
211
- else {
212
- return 0;
213
- }
214
- });
215
- }, [columns, reportColumns]);
216
- // Pivot form states
217
- const [pivotRowField, setPivotRowField] = useState(undefined);
218
- const [pivotColumnField, setPivotColumnField] = useState(undefined);
219
- const [pivotAggregations, setPivotAggregations] = useState([]);
220
- const [pivotHint, setPivotHint] = useState('');
221
- const [pivotError, setPivotError] = useState('');
222
- const [createdPivots, setCreatedPivots] = useState([]);
223
- const [recommendedPivots, setRecommendedPivots] = useState([]);
224
- const [pivotPopUpTitle, setPivotPopUpTitle] = useState('Add pivot');
225
- const [showPivotPopover, setShowPivotPopover] = useState(false);
226
- const [isEditingPivot, setIsEditingPivot] = useState(false);
227
- const [selectedPivotIndex, setSelectedPivotIndex] = useState(-1);
228
- const [pivotRecommendationsEnabledState, setPivotRecommendationsEnabledState,] = useState(pivotRecommendationsEnabled);
229
- // Ask AI
230
- const [askAILoading, setAskAILoading] = useState(false);
231
- const askAIContainerRef = useRef(null);
232
- const [askAIInputWidth, setAskAIInputWidth] = useState(-1);
233
- const loading = reportBuilderLoading || tableLoading;
234
- const isSelectStar = useMemo(() => {
235
- if (tables.length === 1) {
236
- // Check if all columns are selected
237
- const totalColumnLength = tables.reduce((acc, table) => {
238
- const tableColumns = filteredSchema.find((t) => t.name === table.name)?.columns.length ??
239
- 0;
240
- return acc + tableColumns;
241
- }, 0);
242
- return totalColumnLength === columns.length;
243
- }
244
- else {
245
- // TODO: Implement this to work with joins
246
- // SELECT * won't work if joined table has shared column name
247
- return false;
248
- }
249
- }, [tables, columns, filteredSchema]);
250
- const mssqlSortWarning = useMemo(() => {
251
- if (!client || client?.databaseType !== 'mssql') {
252
- return undefined;
253
- }
254
- else if (!pivot && !limit) {
255
- return 'Please add a limit.';
256
- }
257
- }, [client, limit, pivot]);
258
- const foreignKeyMap = useMemo(() => {
259
- return getSchemaForeignKeyMapping(filteredSchema);
260
- }, [filteredSchema]);
261
- // State changing functions
262
- const clearAllState = (resetStateStack = true) => {
263
- setActiveQuery('');
264
- setQueryOutOfSync(false);
265
- handleMultiStateChange({
266
- state: EMPTY_REPORT_BUILDER_STATE,
267
- fetchData: false,
268
- updateStateStack: true,
269
- });
270
- if (resetStateStack) {
271
- setStateStack([]);
272
- setPoppedStateStack([]);
273
- }
274
- setFilteredUniqueValues(null);
275
- setUnfilteredUniqueValues({});
276
- setColumnUniqueValues({});
277
- setDateRanges(null);
278
- setTempReport({
279
- ...EMPTY_INTERNAL_REPORT,
280
- pagination: REPORT_BUILDER_PAGINATION,
281
- });
282
- resetProcessing();
283
- setReportColumns([]);
284
- setReportRows([]);
285
- setFormattedRows([]);
286
- setPivotData(null);
287
- setNumberOfRows(0);
288
- setRowCountIsLoading(false);
289
- setPivotRowField(undefined);
290
- setPivotColumnField(undefined);
291
- setPivotAggregations([]);
292
- setCreatedPivots([]);
293
- setRecommendedPivots([]);
294
- setSelectedPivotIndex(-1);
295
- setAskAILoading(false);
296
- setReportBuilderLoading(false);
297
- setTableLoading(false);
298
- setPivotError('');
299
- setErrorMessage('');
300
- setUnresolvedReportMessage('');
301
- setPivotHint('');
302
- };
109
+ const {
110
+ // Core state
111
+ columns, tables, activeQuery, tempReport, stateStack, poppedStateStack,
112
+ // UI state
113
+ errorMessage, unresolvedReportMessage, loading, tableLoading, askAILoading,
114
+ // Pivot state and handlers
115
+ pivot, pivotData, pivotError,
116
+ // Schema and client info
117
+ // foreignKeyMap,
118
+ // AI features
119
+ aiPrompt, setAiPrompt, fetchAstFromPromptHelper,
120
+ // Action handlers
121
+ clearAllState,
122
+ // handleMultiStateChange,
123
+ // handleColumnsChange,
124
+ handleUndo, handleRedo, onSaveQuery, onSaveReport, } = reportBuilder;
303
125
  const copySQLToClipboard = () => {
304
126
  const query = pivot && pivotData ? pivotData.pivotQuery : activeQuery;
305
127
  setIsCopying(true);
306
128
  navigator.clipboard.writeText(query);
307
129
  setTimeout(() => setIsCopying(false), 800);
308
130
  };
309
- const handleTablesChange = (newTables, updateStateStack = true) => {
310
- setTables(newTables);
311
- if (updateStateStack) {
312
- setStateStack((prevStack) => [
313
- ...prevStack,
314
- { ...reportBuilderState, tables: newTables },
315
- ]);
316
- setPoppedStateStack([]);
317
- }
318
- };
319
- const handleColumnsChange = (newColumns, fetchData, updateStateStack = true, bypassConfirmation = false) => {
320
- const validReportBuilderState = bypassConfirmation
321
- ? { ...reportBuilderState, columns: newColumns }
322
- : validatedReportBuilderState({
323
- ...reportBuilderState,
324
- columns: newColumns,
325
- }, foreignKeyMap);
326
- if (validReportBuilderState.tables.length === 0 && !bypassConfirmation) {
327
- if (!confirm('Removing all columns will clear all state. Are you sure you want to continue?')) {
328
- return;
329
- }
330
- else {
331
- handleMultiStateChange({
332
- state: EMPTY_REPORT_BUILDER_STATE,
333
- fetchData: false,
334
- updateStateStack: true,
335
- });
336
- return;
337
- }
338
- }
339
- const tablesAffected = tables.length - validReportBuilderState.tables.length >= 2;
340
- const filtersAffected = validReportBuilderState.filterStack.length !== filterStack.length;
341
- const deletedTables = tables
342
- .filter((table) => {
343
- return !validReportBuilderState.tables.some((t) => t.name === table.name);
344
- })
345
- .map((table) => table.name);
346
- const deletedFilters = filterStack
347
- .filter((filter) => filter.value)
348
- .filter((filter) => {
349
- return deletedTables.some((table) => table === filter.value.table);
350
- })
351
- .map((filter) => filterSentence(filter.value));
352
- if (tablesAffected && filtersAffected) {
353
- if (!confirm(`Removing this column will remove the following table${deletedTables.length > 1 ? 's' : ''}:
354
- ${deletedTables.join(', ')}.
355
- It will also remove the following filter${deletedFilters.length > 1 ? 's' : ''}:
356
- ${deletedFilters.join(', ')}.
357
- Are you sure you want to continue?
358
- `
359
- .replace(/\s+/g, ' ')
360
- .trim())) {
361
- return;
362
- }
363
- }
364
- else if (tablesAffected) {
365
- if (!confirm(`Removing this column will remove the following table${deletedTables.length > 1 ? 's' : ''}:
366
- ${deletedTables.join(', ')}.
367
- Are you sure you want to continue?
368
- `
369
- .replace(/\s+/g, ' ')
370
- .trim())) {
371
- return;
372
- }
373
- }
374
- else if (filtersAffected) {
375
- if (!confirm(`Removing this column will remove the following filter${deletedFilters.length > 1 ? 's' : ''}:
376
- ${deletedFilters.join(', ')}.
377
- Are you sure you want to continue?
378
- `
379
- .replace(/\s+/g, ' ')
380
- .trim())) {
381
- return;
382
- }
383
- }
384
- if (validReportBuilderState.tables.length !== tables.length) {
385
- handleTablesChange(validReportBuilderState.tables, false);
386
- fetchData = true;
387
- }
388
- if (validReportBuilderState.filterStack.length !== filterStack.length) {
389
- handleFilterStackChange(validReportBuilderState.filterStack, false, false);
390
- fetchData = true;
391
- }
392
- if (validReportBuilderState.sort.length !== sort.length) {
393
- handleSortChange(validReportBuilderState.sort, false, false);
394
- fetchData = true;
395
- }
396
- if (pivot && !validReportBuilderState.pivot) {
397
- handlePivotChange(validReportBuilderState.pivot, false, false);
398
- }
399
- setColumns(validReportBuilderState.columns);
400
- if (updateStateStack) {
401
- setStateStack((prevStack) => [...prevStack, validReportBuilderState]);
402
- setPoppedStateStack([]);
403
- }
404
- if (fetchData) {
405
- fetchDataFromReportBuilderState(validReportBuilderState);
406
- }
407
- else {
408
- setQueryOutOfSync(true);
409
- }
410
- };
411
- const handleFilterInsertion = (newFilter) => {
412
- const newFilterStack = [...filterStack];
413
- if (newFilterStack.length > 0) {
414
- const tabNode = {
415
- leaf: false,
416
- operator: 'and',
417
- leftNode: null,
418
- rightNode: null,
419
- };
420
- newFilterStack.push(tabNode);
421
- }
422
- const newItem = {
423
- leaf: true,
424
- operator: null,
425
- leftNode: null,
426
- rightNode: null,
427
- value: newFilter,
428
- };
429
- newFilterStack.push(newItem);
430
- handleFilterStackChange(newFilterStack, true);
431
- };
432
- const handleFilterStackChange = (newFilterStack, fetchData, updateStateStack = true) => {
433
- setFilterStack(newFilterStack);
434
- if (newFilterStack.length === 0) {
435
- setFilteredUniqueValues(null);
436
- }
437
- if (updateStateStack) {
438
- setStateStack((prevStack) => [
439
- ...prevStack,
440
- { ...reportBuilderState, filterStack: newFilterStack },
441
- ]);
442
- setPoppedStateStack([]);
443
- }
444
- if (fetchData) {
445
- fetchDataFromReportBuilderState({
446
- ...reportBuilderState,
447
- filterStack: newFilterStack,
448
- }, true);
449
- }
450
- };
451
- const handlePivotChange = (newPivot, fetchData, updateStateStack = true) => {
452
- setPivot(newPivot ? setTypesOnPivot(newPivot, reportColumns) : null);
453
- setPivotHint('');
454
- setPivotError('');
455
- if (!newPivot) {
456
- setPivotData(null);
457
- if (!fetchData) {
458
- const formattedRows = formatRows(reportRows, reportColumns, false);
459
- setFormattedRows(formattedRows);
460
- }
461
- }
462
- let resetSortAndLimit = false;
463
- if (!pivot && newPivot && (sort.length > 0 || limit)) {
464
- setSort([]);
465
- setLimit(null);
466
- resetSortAndLimit = true;
467
- }
468
- setSortOrLimitWasReset(resetSortAndLimit);
469
- if (updateStateStack) {
470
- setStateStack((prevStack) => [
471
- ...prevStack,
472
- {
473
- ...reportBuilderState,
474
- pivot: newPivot,
475
- sort: resetSortAndLimit ? [] : sort,
476
- limit: resetSortAndLimit ? null : limit,
477
- },
478
- ]);
479
- setPoppedStateStack([]);
480
- }
481
- if (fetchData) {
482
- fetchDataFromReportBuilderState({
483
- ...reportBuilderState,
484
- pivot: newPivot,
485
- sort: resetSortAndLimit ? [] : sort,
486
- limit: resetSortAndLimit ? null : limit,
487
- }, false, resetSortAndLimit);
488
- }
489
- };
490
- const updatePivot = async (changeField, fieldKey) => {
491
- if (!client || !pivot) {
492
- return;
493
- }
494
- let newPivot = { ...pivot };
495
- setPivotError('');
496
- // @ts-ignore
497
- newPivot[fieldKey] = changeField;
498
- newPivot.rowLimit = undefined;
499
- newPivot.sort = undefined;
500
- newPivot.sortDirection = undefined;
501
- newPivot.sortField = undefined;
502
- newPivot.sortFieldType = undefined;
503
- if (fieldKey === 'rowField') {
504
- if (changeField === '' || changeField === undefined) {
505
- setPivotColumnField(undefined);
506
- // set all percentage aggregations to undefined
507
- setPivotAggregations(pivotAggregations.map((agg) => ({
508
- ...agg,
509
- aggregationType: agg.aggregationType === 'percentage'
510
- ? undefined
511
- : agg.aggregationType,
512
- })));
513
- }
514
- }
515
- newPivot = setTypesOnPivot(newPivot, reportColumns);
516
- if (newPivot.aggregations?.length === 0 ||
517
- newPivot.aggregations?.some((agg) => !agg.aggregationType) ||
518
- newPivot.aggregations?.some((agg) => !agg.valueField && agg.aggregationType !== 'count')) {
519
- return;
520
- }
521
- const { valid, reason } = isValidPivot(newPivot);
522
- if (!valid) {
523
- setPivotError(reason);
524
- return;
525
- }
526
- handlePivotChange(newPivot, true);
527
- };
528
- const handleSortChange = (newSort, fetchData, updateStateStack = true) => {
529
- setSort(newSort);
530
- if (updateStateStack) {
531
- setStateStack((prevStack) => [
532
- ...prevStack,
533
- { ...reportBuilderState, sort: newSort },
534
- ]);
535
- setPoppedStateStack([]);
536
- }
537
- if (fetchData) {
538
- fetchDataFromReportBuilderState({
539
- ...reportBuilderState,
540
- sort: newSort,
541
- });
542
- }
543
- };
544
- const handleLimitChange = (newLimit, fetchData, updateStateStack = true) => {
545
- setLimit(newLimit);
546
- if (updateStateStack) {
547
- setStateStack((prevStack) => [
548
- ...prevStack,
549
- { ...reportBuilderState, limit: newLimit },
550
- ]);
551
- setPoppedStateStack([]);
552
- }
553
- if (fetchData) {
554
- fetchDataFromReportBuilderState({
555
- ...reportBuilderState,
556
- limit: newLimit,
557
- }, false, true);
558
- }
559
- };
560
- const handleMultiStateChange = ({ state, fetchData, updateStateStack = true, report, skipPivotColumnFetch = false, }) => {
561
- if (state.tables !== undefined) {
562
- handleTablesChange(state.tables, false);
563
- }
564
- if (state.columns !== undefined) {
565
- handleColumnsChange(state.columns, false, false, true);
566
- }
567
- if (state.filterStack !== undefined) {
568
- handleFilterStackChange(state.filterStack, false, false);
569
- }
570
- if (state.pivot !== undefined) {
571
- handlePivotChange(state.pivot, false, false);
572
- }
573
- if (state.sort !== undefined) {
574
- handleSortChange(state.sort, false, false);
575
- }
576
- if (state.limit !== undefined) {
577
- handleLimitChange(state.limit, false, false);
578
- }
579
- if (updateStateStack) {
580
- setStateStack((prevStack) => [
581
- ...prevStack,
582
- { ...reportBuilderState, ...state },
583
- ]);
584
- setPoppedStateStack([]);
585
- }
586
- if (fetchData) {
587
- fetchDataFromReportBuilderState({ ...reportBuilderState, ...state }, !!state.filterStack, !!state.limit, !!state.tables, report, skipPivotColumnFetch);
588
- }
589
- };
590
- const handleUndo = () => {
591
- if (stateStack.length <= 1) {
592
- return;
593
- }
594
- const previousState = stateStack[stateStack.length - 2];
595
- setPoppedStateStack((prevStack) => [
596
- ...prevStack,
597
- stateStack[stateStack.length - 1],
598
- ]);
599
- setStateStack((prevStack) => prevStack.slice(0, -1));
600
- // Only fetch data if the previous state has columns
601
- handleMultiStateChange({
602
- state: previousState,
603
- fetchData: previousState.columns.length > 0,
604
- updateStateStack: false,
605
- });
606
- };
607
- const handleRedo = () => {
608
- if (poppedStateStack.length === 0) {
609
- return;
610
- }
611
- const lastState = poppedStateStack[poppedStateStack.length - 1];
612
- setStateStack((prevStack) => [...prevStack, lastState]);
613
- setPoppedStateStack((prevStack) => prevStack.slice(0, -1));
614
- // Only fetch data if the last state has columns
615
- handleMultiStateChange({
616
- state: lastState,
617
- fetchData: lastState.columns.length > 0,
618
- updateStateStack: false,
619
- });
620
- };
621
- const fetchDataFromReportBuilderState = (state, filtersChanged, limitChanged, tablesChanged, report, skipPivotColumnFetch) => {
622
- if (!client) {
623
- return;
624
- }
625
- const ast = reportBuilderStateToAst(state, client.databaseType?.toLowerCase() || 'postgresql');
626
- fetchReportFromASTHelper({
627
- ast,
628
- pivot: state.pivot,
629
- previousReport: report,
630
- requiresNewFilteredUniqueValues: filtersChanged || limitChanged,
631
- requiresNewUnfilteredUniqueValues: tablesChanged,
632
- skipPivotColumnFetch,
633
- });
634
- };
635
- const fetchReportFromASTHelper = async ({ ast, pivot, previousReport = tempReport, requiresNewFilteredUniqueValues = false, requiresNewUnfilteredUniqueValues = false, skipPivotColumnFetch = false, }) => {
636
- let reportBuilderInfo = undefined;
637
- setErrorMessage('');
638
- const schema = filteredSchema;
639
- try {
640
- if (!client || reportBuilderLoading) {
641
- return;
642
- }
643
- setReportBuilderLoading(true);
644
- reportBuilderInfo = await fetchReportBuilderDataFromAST({
645
- baseAst: ast,
646
- schema,
647
- client,
648
- tenants,
649
- pivot: pivot ?? undefined,
650
- skipPivotColumnFetch,
651
- previousRelevant: {
652
- uniqueStringsByTable: unfilteredUniqueValues,
653
- dateRanges: dateRanges ?? {},
654
- uniqueStringsByColumn: requiresNewFilteredUniqueValues
655
- ? {}
656
- : columnUniqueValues,
657
- },
658
- requiresNewFilteredUniqueValues,
659
- report: previousReport,
660
- customFields: schemaData.customFields,
661
- skipUniqueValues: true,
662
- skipRowCount: true,
663
- processing: { page: REPORT_BUILDER_PAGINATION },
664
- dashboardName: destinationDashboard,
665
- getToken,
666
- });
667
- if (reportBuilderInfo.error) {
668
- throw new Error(reportBuilderInfo.error);
669
- }
670
- }
671
- catch (err) {
672
- if (err instanceof Error) {
673
- setErrorMessage(err.message);
674
- setReportBuilderLoading(false);
675
- return { error: true, message: err.message, rows: [] };
676
- }
677
- setReportBuilderLoading(false);
678
- setErrorMessage('Failed to fetch');
679
- return { error: true, message: 'Failed to fetch', rows: [] };
680
- }
681
- if (!reportBuilderInfo) {
682
- setReportBuilderLoading(false);
683
- setErrorMessage('Failed to fetch');
684
- return;
685
- }
686
- const cleanedReport = await cleanDashboardItem({
687
- item: reportBuilderInfo.report,
688
- dashboardFilters: [],
689
- getToken,
690
- client,
691
- customFields: schemaData.customFields,
692
- skipPivotFetch: true,
693
- tenants,
694
- });
695
- // set tempReport
696
- setTempReport({
697
- ...cleanedReport,
698
- pagination: REPORT_BUILDER_PAGINATION,
699
- });
700
- setActiveQuery(reportBuilderInfo.query);
701
- setQueryOutOfSync(false);
702
- // table data
703
- fetchRowCountFromAST(ast, ast.where);
704
- setReportRows(reportBuilderInfo.rows);
705
- setFormattedRows(reportBuilderInfo.formattedRows);
706
- resetProcessing();
707
- if (!(client.databaseType?.toLowerCase() === 'bigquery') ||
708
- (reportBuilderInfo.rows && reportBuilderInfo.rows.length > 0)) {
709
- setReportColumns(reportBuilderInfo.columns);
710
- }
711
- setPivotData(reportBuilderInfo.pivotData);
712
- if (reportBuilderInfo.pivot) {
713
- setPivotRowField(reportBuilderInfo.pivot.rowField);
714
- setPivotColumnField(reportBuilderInfo.pivot.columnField);
715
- setPivotAggregations(reportBuilderInfo.pivot.aggregations ?? [
716
- {
717
- valueField: reportBuilderInfo.pivot.valueField,
718
- valueField2: reportBuilderInfo.pivot.valueField2,
719
- aggregationType: reportBuilderInfo.pivot.aggregationType,
720
- },
721
- ]);
722
- }
723
- setPivot(reportBuilderInfo.pivot);
724
- setPivotHint(reportBuilderInfo.pivotHint);
725
- setDateRanges(reportBuilderInfo.dateRanges);
726
- const tableNames = reportBuilderInfo.tables;
727
- const columnInfo = tableNames.flatMap((table) => {
728
- const tableInfo = schema.find((tableInfo) => tableInfo.name === table);
729
- if (!tableInfo) {
730
- return [];
731
- }
732
- return tableInfo.columns.map((col) => ({ ...col, table }));
733
- });
734
- setReportBuilderLoading(false);
735
- // fetch unique values after everything else since it is the most expensive
736
- try {
737
- let uniqueStrings = filteredUniqueValues ?? unfilteredUniqueValues;
738
- let uniqueValuesByColumn = columnUniqueValues;
739
- if (requiresNewUnfilteredUniqueValues) {
740
- fetchGlobalUniqueValues(columnInfo, tableNames);
741
- }
742
- if (requiresNewFilteredUniqueValues) {
743
- if (reportBuilderInfo.pivot) {
744
- // if there's a pivot, these values would have had to been fetched
745
- uniqueStrings = reportBuilderInfo.uniqueStringsByTable;
746
- uniqueValuesByColumn = reportBuilderInfo.uniqueStringsByColumn;
747
- }
748
- else {
749
- setFilteredUniqueValuesIsLoading(true);
750
- const starQuery = await fetchSqlQuery(createSelectStarFromAst(ast), client, getToken);
751
- uniqueStrings = await getUniqueStringValuesByTable({
752
- columns: columnInfo,
753
- tables: tableNames,
754
- client,
755
- tenants,
756
- customFields: schemaData.customFields ?? undefined,
757
- withExceededColumns: true,
758
- dashboardName: destinationDashboard,
759
- queryTemplate: starQuery.query,
760
- getToken,
761
- });
762
- uniqueValuesByColumn = {};
763
- reportBuilderInfo.reportBuilderColumns.forEach((col) => {
764
- uniqueValuesByColumn[col.alias || col.field] =
765
- uniqueStrings[col.table || '']?.[col.field] ?? [];
766
- });
767
- }
768
- }
769
- setFilteredUniqueValues(uniqueStrings);
770
- setFilteredUniqueValuesIsLoading(false);
771
- setColumnUniqueValues(uniqueValuesByColumn);
772
- }
773
- catch (err) {
774
- if (err instanceof Error) {
775
- setErrorMessage(err.message);
776
- return { error: true, message: err.message, rows: [] };
777
- }
778
- setErrorMessage('Failed to fetch unique values');
779
- return {
780
- error: true,
781
- message: 'Failed to fetch unique values',
782
- rows: [],
783
- };
784
- }
785
- };
786
- const fetchRowCountFromAST = async (ast, where) => {
787
- setRowCountIsLoading(true);
788
- if (!client) {
789
- return;
790
- }
791
- const tableData = await fetchTableByAST({ ...ast, where }, client, getToken, tenants, destinationDashboard, { page: REPORT_BUILDER_PAGINATION }, schemaData.customFields, false, true);
792
- if (tableData.rowCount) {
793
- setNumberOfRows(tableData.rowCount);
794
- // @ts-ignore
795
- setTempReport((tempReport) => ({
796
- ...tempReport,
797
- rowCount: tableData.rowCount,
798
- }));
799
- }
800
- setRowCountIsLoading(false);
801
- };
802
- const fetchAstFromPromptHelper = async (overridePrompt) => {
803
- let astInfo = {};
804
- const prompt = overridePrompt || aiPrompt;
805
- if (!client) {
806
- return;
807
- }
808
- if (!prompt) {
809
- setErrorMessage('Please supply a prompt.');
810
- return;
811
- }
812
- try {
813
- setReportBuilderLoading(true);
814
- setAskAILoading(true);
815
- setErrorMessage('');
816
- astInfo = await fetchAndProcessASTFromPrompt({
817
- aiPrompt: prompt,
818
- schema: filteredSchema,
819
- client,
820
- prevPivot: pivot ?? undefined,
821
- currentQuery: activeQuery,
822
- prevTable: tables?.[0]?.name,
823
- dashboardName: destinationDashboard,
824
- tenants,
825
- getToken,
826
- });
827
- if (astInfo.error) {
828
- throw new Error(astInfo.error);
829
- }
830
- }
831
- catch (err) {
832
- if (err instanceof Error) {
833
- setErrorMessage(err.message);
834
- }
835
- setReportBuilderLoading(false);
836
- setAskAILoading(false);
837
- return;
838
- }
839
- // check if pivot works with ReportBuilder constraints
840
- if (Object.keys(columnUniqueValues).length > 0 &&
841
- astInfo.pivot &&
842
- !isValidPivotForReport(astInfo.pivot, columnUniqueValues, reportColumns)) {
843
- astInfo.pivot = null;
844
- astInfo.ast.groupby = null;
845
- }
846
- setAskAILoading(false);
847
- const newState = astToReportBuilderState(astInfo.ast, client.databaseType || 'postgresql', filteredSchema);
848
- handleMultiStateChange({
849
- state: { ...newState, pivot: astInfo.pivot },
850
- fetchData: true,
851
- });
852
- };
853
- const fetchGlobalUniqueValues = async (columns, tables) => {
854
- if (!client) {
855
- return;
856
- }
857
- setUnfilteredUniqueValuesIsLoading(true);
858
- const uniqueStrings = await getUniqueStringValuesByTable({
859
- columns,
860
- tables,
861
- client,
862
- getToken,
863
- tenants,
864
- customFields: schemaData.customFields ?? undefined,
865
- withExceededColumns: true,
866
- dashboardName: destinationDashboard,
867
- });
868
- setUnfilteredUniqueValues(uniqueStrings);
869
- setUnfilteredUniqueValuesIsLoading(false);
870
- };
871
- const fetchQueryFromReportBuilderState = async (state) => {
872
- if (!client) {
873
- return '';
874
- }
875
- const ast = reportBuilderStateToAst(state, client.databaseType?.toLowerCase() || 'postgresql');
876
- const query = await fetchSqlQuery(ast, client, getToken);
877
- setActiveQuery(query.query);
878
- return query.query;
879
- };
880
- const resetProcessing = () => {
881
- setCurrentProcessing({ page: REPORT_BUILDER_PAGINATION });
882
- setPreviousPage(0);
883
- };
884
- const handlePagination = async (processing) => {
885
- try {
886
- if (!client) {
887
- return;
888
- }
889
- const isPivotPagination = !!(pivot && pivotData);
890
- setErrorMessage('');
891
- setTableLoading(true);
892
- const tableInfo = await fetchResultsByQuery({
893
- query: isPivotPagination ? pivotData.pivotQuery : activeQuery,
894
- comparisonQuery: pivot && pivotData ? pivotData.comparisonPivotQuery : undefined,
895
- client,
896
- tenants,
897
- processing,
898
- customFields: schemaData.customFields,
899
- rowsOnly: true,
900
- dashboardName: destinationDashboard,
901
- pivot: pivot,
902
- getPivotRowCount: false,
903
- getToken,
904
- });
905
- if (tableInfo.error) {
906
- throw new Error(tableInfo.error);
907
- }
908
- else if (tableInfo.rows.length === 0) {
909
- throw new Error('No data found');
910
- }
911
- if (!isPivotPagination) {
912
- const tempRows = [...reportRows, ...tableInfo.rows];
913
- setReportRows(tempRows);
914
- setFormattedRows(formatRowsFromReport({ rows: tempRows, columns: tableInfo.columns }));
915
- setTempReport((tempReport) => ({
916
- ...tempReport,
917
- rows: tempRows,
918
- rowCount: tableInfo.rowCount ?? tempReport.rowCount,
919
- }));
920
- }
921
- else {
922
- const tempRows = [...pivotData.rows, ...tableInfo.rows];
923
- setPivotData((oldPivotData) => {
924
- if (oldPivotData) {
925
- return {
926
- ...oldPivotData,
927
- rows: tempRows,
928
- columns: tableInfo.columns,
929
- };
930
- }
931
- return null;
932
- });
933
- setFormattedRows(formatRowsFromReport({ rows: tempRows, columns: tableInfo.columns }));
934
- }
935
- setTableLoading(false);
936
- }
937
- catch (e) {
938
- setTableLoading(false);
939
- setErrorMessage('Failed to run SQL query: ' + e.message);
940
- setReportRows([]);
941
- setReportColumns([]);
942
- return;
943
- }
944
- };
945
- const onPageChange = (page, initiator = 'ReportBuilder') => {
946
- const pagination = initiator === 'ReportBuilder'
947
- ? REPORT_BUILDER_PAGINATION
948
- : DEFAULT_PAGINATION;
949
- if (currentProcessing.page &&
950
- shouldFetchMore(pagination, page, previousPage, pivotData ? pivotData.rows.length : reportRows.length)) {
951
- const newPagination = { ...currentProcessing.page, page };
952
- const updatedProcessing = { ...currentProcessing, page: newPagination };
953
- setCurrentProcessing(updatedProcessing);
954
- handlePagination(updatedProcessing);
955
- }
956
- if (page > previousPage) {
957
- setPreviousPage(page);
958
- }
959
- };
960
- const onSortChange = (newSort, isDelete) => {
961
- if (!newSort.field) {
962
- return;
963
- }
964
- if (pivot) {
965
- let newPivot = null;
966
- if (isDelete) {
967
- newPivot = {
968
- ...pivot,
969
- sort: undefined,
970
- sortField: undefined,
971
- sortDirection: undefined,
972
- sortFieldType: undefined,
973
- };
974
- }
975
- else {
976
- newPivot = {
977
- ...pivot,
978
- sort: true,
979
- sortField: newSort.field,
980
- sortDirection: newSort.direction,
981
- sortFieldType: reportColumns.find((col) => col.field === newSort.field)?.fieldType,
982
- };
983
- }
984
- handlePivotChange(newPivot, true);
985
- }
986
- else {
987
- const updatedSort = [...sort];
988
- const existingSortIndex = updatedSort.findIndex((item) => item.field === newSort.field);
989
- if (isDelete) {
990
- if (existingSortIndex !== -1) {
991
- updatedSort.splice(existingSortIndex, 1);
992
- }
993
- }
994
- else if (existingSortIndex !== -1) {
995
- updatedSort[existingSortIndex] = {
996
- field: newSort.field,
997
- direction: newSort.direction,
998
- };
999
- }
1000
- else {
1001
- updatedSort.push({
1002
- field: newSort.field,
1003
- direction: newSort.direction,
1004
- });
1005
- }
1006
- handleSortChange(updatedSort, true);
1007
- }
1008
- };
1009
- const onLimitChange = (limit) => {
1010
- if (limit) {
1011
- if (pivot) {
1012
- const newPivot = { ...pivot, rowLimit: limit };
1013
- handlePivotChange(newPivot, true);
1014
- }
1015
- else {
1016
- handleLimitChange({ value: limit }, true);
1017
- }
1018
- }
1019
- else {
1020
- if (pivot) {
1021
- const newPivot = { ...pivot, rowLimit: undefined };
1022
- handlePivotChange(newPivot, true);
1023
- }
1024
- else {
1025
- handleLimitChange(null, true);
1026
- }
1027
- }
1028
- };
1029
131
  useEffect(() => {
1030
132
  // Since the TextInput component takes a required numeric width parameter,
1031
133
  // we dynamically calculate the width of this component here.
@@ -1038,81 +140,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1038
140
  window.removeEventListener('resize', handleResize);
1039
141
  };
1040
142
  }, []);
1041
- useEffect(() => {
1042
- if (!client) {
1043
- return;
1044
- }
1045
- if (client.featureFlags?.['recommendedPivotsDisabled'] !== undefined) {
1046
- setPivotRecommendationsEnabledState(!client.featureFlags?.['recommendedPivotsDisabled']);
1047
- }
1048
- if (!initialTableName && !reportId && client.publicKey) {
1049
- clearAllState();
1050
- }
1051
- }, [client]);
1052
- // Initialize ReportBuilder with a report
1053
- useEffect(() => {
1054
- const loadChart = async () => {
1055
- let report;
1056
- if (!client) {
1057
- return;
1058
- }
1059
- try {
1060
- if (!reportId) {
1061
- throw new Error('Report ID is required');
1062
- }
1063
- report = allReportsById[reportId];
1064
- if (!report) {
1065
- console.log('no report');
1066
- throw new Error('Report not found');
1067
- }
1068
- const { ast: newAst, pivot: newPivot } = await fetchASTFromQuillReport(report, client, filteredSchema, getToken);
1069
- const initialState = astToReportBuilderState(newAst, client.databaseType || 'postgresql', filteredSchema);
1070
- setTempReport(report);
1071
- handleMultiStateChange({
1072
- state: {
1073
- ...initialState,
1074
- pivot: newPivot ?? null,
1075
- },
1076
- fetchData: true,
1077
- report,
1078
- skipPivotColumnFetch: true,
1079
- });
1080
- }
1081
- catch (err) {
1082
- console.error(err);
1083
- setErrorMessage('Error when loading chart');
1084
- }
1085
- };
1086
- if (reportId && client) {
1087
- loadChart();
1088
- }
1089
- }, [allReportsById[reportId || ''], client]);
1090
- useEffect(() => {
1091
- if (initialTableName) {
1092
- const tableColumns = filteredSchema.find((table) => {
1093
- return table.name === initialTableName;
1094
- })?.columns ?? [];
1095
- if (tableColumns.length > 0) {
1096
- handleMultiStateChange({
1097
- state: {
1098
- ...EMPTY_REPORT_BUILDER_STATE,
1099
- tables: [{ name: initialTableName }],
1100
- columns: tableColumns.map((col) => ({
1101
- field: col.field,
1102
- table: initialTableName,
1103
- })),
1104
- },
1105
- fetchData: true,
1106
- });
1107
- }
1108
- }
1109
- }, [filteredSchema, initialTableName]);
1110
- useEffect(() => {
1111
- if (!data && !dashboardIsLoading) {
1112
- // need dashboard to be in Context for filteredSchema
1113
- reload();
1114
- }
1115
- }, [data, dashboardIsLoading]);
1116
143
  useEffect(() => {
1117
144
  if (isChartBuilderOpen === false) {
1118
145
  onCloseChartBuilder && onCloseChartBuilder();
@@ -1129,136 +156,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1129
156
  : '100%',
1130
157
  overscrollBehavior: 'none',
1131
158
  ...containerStyle,
1132
- }, className: className, children: [_jsxs(SidebarComponent, { children: [_jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Columns" }), _jsx(DraggableColumns, { columns: columns, DraggableColumnComponent: DraggableColumnComponent, onColumnOrderChange: handleColumnsChange, loading: loading }), _jsx(SecondaryButtonComponent, { onClick: () => {
1133
- if (!openPopover) {
1134
- setOpenPopover('AddColumnModal');
1135
- }
1136
- }, label: "Select columns", disabled: loading }), _jsx(ModalComponent, { isOpen: openPopover === 'AddColumnModal', setIsOpen: (isOpen) => {
1137
- if (!isOpen) {
1138
- // delay onClose callback so onClick no-ops
1139
- setTimeout(() => {
1140
- setOpenPopover(null);
1141
- }, 100);
1142
- }
1143
- }, title: "Select columns", children: _jsx(AddColumnModal, { onSave: (tables, columns) => {
1144
- handleMultiStateChange({
1145
- state: {
1146
- ...EMPTY_REPORT_BUILDER_STATE,
1147
- tables,
1148
- columns,
1149
- },
1150
- fetchData: true,
1151
- });
1152
- setOpenPopover(null);
1153
- }, selectedTables: tables, selectedColumns: columns, schema: filteredSchema, foreignKeyMap: foreignKeyMap, schemaLoading: schemaData.isSchemaLoading, TextInputComponent: TextInputComponent, SelectColumn: SelectColumnComponent, SecondaryButton: SecondaryButtonComponent, Button: ButtonComponent, ColumnSearchEmptyState: ColumnSearchEmptyState, LoadingComponent: LoadingComponent }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Filters" }), filterStack.length > 0 && (_jsx("div", { style: {
1154
- display: 'flex',
1155
- flexDirection: 'column',
1156
- gap: 8,
1157
- marginBottom: 12,
1158
- }, children: _jsx(FilterStack, { client: client, filterStack: filterStack, handleFilterStackChange: handleFilterStackChange, schemaData: schemaData, uniqueValues: unfilteredUniqueValues, uniqueValuesIsLoading: unfilteredUniqueValuesIsLoading, tables: tables, TabsComponent: TabsComponent, FilterPopoverComponent: FilterPopoverComponent, FilterModal: FilterModal, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, MultiSelectComponent: MultiSelectComponent, actionsEnabled: !loading, dashboardName: destinationDashboard, getToken: getToken, reportBuilderColumns: columns }) })), _jsxs("div", { style: {
1159
- display: 'flex',
1160
- flexDirection: 'column',
1161
- alignItems: 'flex-start',
1162
- }, children: [_jsx(SecondaryButtonComponent, { disabled: columns.length === 0 || loading, onClick: () => {
1163
- if (!openPopover) {
1164
- setOpenPopover('AddFilterPopover');
1165
- }
1166
- }, label: 'Add filter' }), _jsx("div", { style: {
1167
- position: 'relative',
1168
- ...(openPopover === 'AddFilterPopover' && { top: 12 }),
1169
- }, children: _jsx(PopoverComponent, { isOpen: openPopover === 'AddFilterPopover', setIsOpen: (isOpen) => {
1170
- if (!isOpen) {
1171
- setOpenPopover(null);
1172
- }
1173
- }, popoverTitle: "Add filter", popoverChildren: _jsx(FilterModal, { schema: filteredSchema, tables: tables.map((table) => table.name), fieldValuesMap: filteredUniqueValues ?? unfilteredUniqueValues, fieldValuesMapIsLoading: filteredUniqueValuesIsLoading ||
1174
- unfilteredUniqueValuesIsLoading, onSubmitFilter: (filter) => {
1175
- setOpenPopover(null);
1176
- handleFilterInsertion(filter);
1177
- }, hideTableName: tables.length === 1, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, MultiSelectComponent: MultiSelectComponent, reportBuilderColumns: columns }) }) })] })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Pivot" }), _jsx(PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotAggregations: pivotAggregations, setPivotAggregations: setPivotAggregations, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, SubheaderComponent: SubHeaderComponent, DeleteButtonComponent: DeleteButtonComponent, SelectComponent: SelectComponent, ButtonComponent: ButtonComponent, CardComponent: CardComponent, SecondaryButtonComponent: SecondaryButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, LoadingComponent: LoadingComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEditingPivot, setShowUpdatePivot: setIsEditingPivot, parentRef: parentRef, data: reportRows, columns: reportColumnsToStateColumns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
1178
- handlePivotChange(null, sortOrLimitWasReset);
1179
- }, selectPivot: async (selectedPivot) => {
1180
- if (!selectedPivot)
1181
- return;
1182
- handlePivotChange(selectedPivot, true);
1183
- }, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: LabelComponent, HeaderComponent: HeaderComponent, dateRange: undefined, pivotCountRequest: 4, query: activeQuery, initialUniqueValues: columnUniqueValues, uniqueValuesIsLoading: filteredUniqueValuesIsLoading ||
1184
- unfilteredUniqueValuesIsLoading, disabled: !columns.length || tableLoading || loading, pivotRecommendationsEnabled: pivotRecommendationsEnabledState, report: tempReport, dashboardName: destinationDashboard }), pivot && (_jsx(PivotForm, { columns: reportColumnsToStateColumns, uniqueValues: columnUniqueValues, uniqueValuesIsLoading: filteredUniqueValuesIsLoading ||
1185
- unfilteredUniqueValuesIsLoading, setPivotRowField: (value) => {
1186
- setPivotRowField(value);
1187
- updatePivot(value, 'rowField');
1188
- }, setPivotColumnField: (value) => {
1189
- setPivotColumnField(value);
1190
- updatePivot(value, 'columnField');
1191
- }, setPivotAggregations: (value) => {
1192
- setPivotAggregations(value);
1193
- updatePivot(value, 'aggregations');
1194
- }, onDelete: () => {
1195
- handlePivotChange(null, sortOrLimitWasReset);
1196
- }, isLoading: tableLoading || loading, pivotRowField: pivotRowField, pivotColumnField: pivotColumnField, pivotAggregations: pivotAggregations, SecondaryButtonComponent: SecondaryButtonComponent, SelectComponent: SelectComponent, PivotColumnContainer: PivotColumnContainer, DeleteButtonComponent: DeleteButtonComponent, pivotHint: pivotHint }))] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Sort" }), pivot && pivot.sort && pivot.sortField && (_jsx("div", { style: {
1197
- display: 'flex',
1198
- flexDirection: 'column',
1199
- gap: 8,
1200
- marginBottom: 12,
1201
- }, children: _jsx(SortSentence, { sortField: pivot.sortField, sortDirection: pivot.sortDirection || 'ASC', columns: pivotData?.columns ?? [], setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: async () => {
1202
- onSortChange({
1203
- field: pivot.sortField ?? '',
1204
- direction: pivot.sortDirection ?? 'ASC',
1205
- }, true);
1206
- }, onSave: async (column, direction) => {
1207
- onSortChange({ field: column, direction });
1208
- }, Select: SelectComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent, disabled: tableLoading || loading }, `sort-sentence-pivot`) })), sort && sort.length > 0 && (_jsx("div", { style: {
1209
- display: 'flex',
1210
- flexDirection: 'column',
1211
- gap: 8,
1212
- marginBottom: 12,
1213
- }, children: sort.map((sortData, id) => (_jsx(SortSentence, { sortField: sortData.field, sortDirection: sortData.direction, columns: reportColumnsToStateColumns, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
1214
- onSortChange(sortData, true);
1215
- }, onSave: (column, direction) => {
1216
- onSortChange({ field: column, direction });
1217
- }, Select: SelectComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent, disabled: tableLoading || loading }, `sort-sentence-${id}`))) })), _jsx(SecondaryButtonComponent, { disabled: columns.length === 0 ||
1218
- loading ||
1219
- tableLoading ||
1220
- !!mssqlSortWarning, onClick: () => {
1221
- if (!openPopover) {
1222
- setOpenPopover('AddSortPopover');
1223
- }
1224
- }, label: 'Add sort', tooltipText: mssqlSortWarning }), _jsx("div", { style: {
1225
- position: 'relative',
1226
- ...(openPopover === 'AddSortPopover' && { top: 12 }),
1227
- }, children: _jsx(PopoverComponent, { isOpen: openPopover === 'AddSortPopover', setIsOpen: (isOpen) => {
1228
- if (!isOpen) {
1229
- setOpenPopover(null);
1230
- }
1231
- }, popoverTitle: "Sort by", popoverChildren: _jsx(AddSortPopover, { columns: pivotData
1232
- ? pivotData.columns
1233
- : reportColumnsToStateColumns, Select: SelectComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent, onSave: async (column, direction) => {
1234
- onSortChange({ field: column, direction });
1235
- setOpenPopover(null);
1236
- } }) }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Limit" }), limit || pivot?.rowLimit ? (_jsx("div", { style: {
1237
- display: 'flex',
1238
- flexDirection: 'column',
1239
- gap: 8,
1240
- marginBottom: 12,
1241
- }, children: _jsx(LimitSentence, { limit: limit?.value || pivot?.rowLimit || 0, setOpenPopover: setOpenPopover, LimitPopover: LimitPopoverComponent, EditPopover: AddLimitPopover, handleDelete: () => {
1242
- onLimitChange(null);
1243
- setOpenPopover(null);
1244
- }, onSave: (limit) => {
1245
- onLimitChange(limit);
1246
- setOpenPopover(null);
1247
- }, TextInput: TextInputComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent, disabled: tableLoading || loading }) })) : (_jsxs(_Fragment, { children: [_jsx(SecondaryButtonComponent, { disabled: columns.length === 0 || loading || tableLoading, onClick: () => {
1248
- if (!openPopover) {
1249
- setOpenPopover('AddLimitPopover');
1250
- }
1251
- }, label: 'Add limit' }), _jsx("div", { style: {
1252
- position: 'relative',
1253
- ...(openPopover === 'AddLimitPopover' && { top: 12 }),
1254
- }, children: _jsx(PopoverComponent, { isOpen: openPopover === 'AddLimitPopover', setIsOpen: (isOpen) => {
1255
- if (!isOpen) {
1256
- setOpenPopover(null);
1257
- }
1258
- }, popoverTitle: "Add limit", popoverChildren: _jsx(AddLimitPopover, { TextInputComponent: TextInputComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent, onSave: (limit) => {
1259
- onLimitChange(limit);
1260
- setOpenPopover(null);
1261
- } }) }) })] }))] }), _jsx("div", { style: { width: '100%', minHeight: '30vh' } })] }), _jsxs(ContainerComponent, { children: [isAIEnabled && (_jsx("form", { ref: askAIContainerRef, onSubmit: (event) => {
159
+ }, className: className, children: [_jsxs(SidebarComponent, { children: [_jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Columns" }), _jsx(AddColumns, { reportBuilder: reportBuilder, ModalComponent: ModalComponent, ButtonComponent: ButtonComponent, DraggableColumnComponent: DraggableColumnComponent, TextInputComponent: TextInputComponent, SelectColumnComponent: SelectColumnComponent, SecondaryButtonComponent: SecondaryButtonComponent, ColumnSearchEmptyState: ColumnSearchEmptyState, LoadingComponent: LoadingComponent, onRequestAddVirtualTable: onRequestAddVirtualTable })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Filters" }), _jsx(AddFilters, { reportBuilder: reportBuilder, TabsComponent: TabsComponent, FilterPopoverComponent: FilterPopoverComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, MultiSelectComponent: MultiSelectComponent, PopoverComponent: PopoverComponent })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Pivot" }), _jsx(AddPivot, { reportBuilder: reportBuilder, parentRef: parentRef, SubHeaderComponent: SubHeaderComponent, DeleteButtonComponent: DeleteButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, CardComponent: CardComponent, SecondaryButtonComponent: SecondaryButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, LoadingComponent: LoadingComponent, LabelComponent: LabelComponent, HeaderComponent: HeaderComponent })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Sort" }), _jsx(AddSort, { reportBuilder: reportBuilder, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, SelectComponent: SelectComponent, PopoverComponent: PopoverComponent, SortPopoverComponent: SortPopoverComponent })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Limit" }), _jsx(AddLimit, { reportBuilder: reportBuilder, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, TextInputComponent: TextInputComponent, PopoverComponent: PopoverComponent, LimitPopoverComponent: LimitPopoverComponent })] }), _jsx("div", { style: { width: '100%', minHeight: '30vh' } })] }), _jsxs(ContainerComponent, { children: [isAIEnabled && (_jsx("form", { ref: askAIContainerRef, onSubmit: (event) => {
1262
160
  event.preventDefault();
1263
161
  }, style: {
1264
162
  display: 'flex',
@@ -1274,18 +172,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1274
172
  if (tables.length <= 1) {
1275
173
  fetchAstFromPromptHelper();
1276
174
  }
1277
- }, isLoading: askAILoading && columns.length === 0, label: 'Ask AI' }) }), !reportId && (_jsx(SecondaryButtonComponent, { label: 'New report', onClick: () => clearAllState(false), disabled: columns.length === 0 || loading }))] }) })), columns.length > 0 && (_jsx(TableComponent, { isLoading: tableLoading || (loading && errorMessage.length === 0), rows: formattedRows, rowCount: pivot ? pivotData?.rowCount : numberOfRows, rowCountIsLoading: rowCountIsLoading, rowsPerPage: 20, columns: pivot
1278
- ? pivotData?.columns || []
1279
- : reportColumnsToStateColumns.map((col) => {
1280
- return {
1281
- field: col.field,
1282
- label: snakeAndCamelCaseToTitleCase(col.field),
1283
- };
1284
- }), onPageChange: onPageChange, onSortChange: (sort) => {
1285
- onSortChange(sort);
1286
- }, disableSort: !!mssqlSortWarning, containerStyle: {
1287
- maxHeight: Math.max(window.innerHeight - 290, 75 + Math.min(Math.max(10, reportRows.length), 20) * 37),
1288
- } })), _jsxs("div", { style: {
175
+ }, isLoading: askAILoading && columns.length === 0, label: 'Ask AI' }) }), !reportId && (_jsx(SecondaryButtonComponent, { label: 'New report', onClick: () => clearAllState(false), disabled: columns.length === 0 || loading }))] }) })), columns.length > 0 && (_jsx(ReportTable, { reportBuilder: reportBuilder, TableComponent: TableComponent })), _jsxs("div", { style: {
1289
176
  display: 'flex',
1290
177
  flexDirection: 'row',
1291
178
  gap: '12px',
@@ -1302,132 +189,81 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1302
189
  }, children: [_jsx(ErrorMessageComponent, { errorMessage: errorMessage || pivotError }), aiPrompt.trim().length > 500 && (_jsx(SecondaryButtonComponent, { onClick: () => {
1303
190
  fetchAstFromPromptHelper();
1304
191
  }, label: 'Retry' })), _jsx(SecondaryButtonComponent, { onClick: () => clearAllState(false), label: 'Reset' })] })) : (_jsx("div", { style: { width: '100%' } })), stateStack.length > 0 && (_jsx(SecondaryButtonComponent, { onClick: handleUndo, label: "", icon: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "size-6", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 15 3 9m0 0 6-6M3 9h12a6 6 0 0 1 0 12h-3" }) }), disabled: stateStack.length <= 1 || loading })), stateStack.length > 0 && (_jsx(SecondaryButtonComponent, { onClick: handleRedo, label: "", icon: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "size-6", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m15 15 6-6m0 0-6-6m6 6H9a6 6 0 0 0 0 12h3" }) }), disabled: poppedStateStack.length < 1 || loading })), columns.length > 0 && activeQuery && (_jsxs(_Fragment, { children: [onDiscardChanges && (_jsx(SecondaryButtonComponent, { onClick: onDiscardChanges, label: "Discard changes" })), !hideCopySQL && (_jsx(SecondaryButtonComponent, { label: isCopying ? 'Copied' : 'Copy SQL', onClick: () => copySQLToClipboard() })), !isAdminEnabled || reportId ? null : (_jsx(SecondaryButtonComponent, { onClick: async () => {
1305
- let tempReportQuery = activeQuery;
1306
- if (queryOutOfSync) {
1307
- tempReportQuery =
1308
- await fetchQueryFromReportBuilderState(reportBuilderState);
1309
- }
1310
- const tempReportColumns = columns
1311
- .map((column) => {
1312
- return reportColumnsToStateColumns.find((col) => col.field === (column.alias || column.field));
1313
- })
1314
- .filter((col) => col !== undefined);
1315
- let customFieldColumns = [];
1316
- if (client && isSelectStar && schemaData.customFields) {
1317
- customFieldColumns = tables.flatMap((table) => {
1318
- return (schemaData.customFields?.[table.name || ''] || []).map((field) => field.field);
1319
- });
1320
- }
1321
- setTempReport({
1322
- ...tempReport,
1323
- ...(pivot
1324
- ? pivotFormData(pivot, reportColumnsToStateColumns, tempReport, tempReport.chartType, pivotData ?? undefined)
1325
- : {}),
1326
- id: TEMP_REPORT_ID,
1327
- dashboardName: destinationDashboard,
1328
- pivot: pivot,
1329
- yAxisFields: tempReport?.pivot && !pivot
1330
- ? []
1331
- : tempReport?.yAxisFields,
1332
- columns: isSelectStar
1333
- ? // if SELECT *, filter out custom fields from tabular view
1334
- // so Automatic Custom Fields can be applied
1335
- tempReportColumns.filter((col) => {
1336
- return !customFieldColumns.includes(col.field);
1337
- })
1338
- : tempReportColumns,
1339
- columnInternal: isSelectStar
1340
- ? // if SELECT *, filter out custom fields from tabular view
1341
- // so Automatic Custom Fields can be applied
1342
- tempReportColumns.filter((col) => {
1343
- return !customFieldColumns.includes(col.field);
1344
- })
1345
- : tempReportColumns,
1346
- queryString: isSelectStar
1347
- ? convertQueryToSelectStar(tempReportQuery)
1348
- : tempReportQuery,
1349
- includeCustomFields: isSelectStar,
1350
- rows: reportRows,
1351
- pivotRows: pivotData?.rows,
1352
- pivotColumns: pivotData?.columns,
1353
- pivotRowCount: pivotData?.rowCount,
1354
- pivotQuery: pivotData?.pivotQuery,
1355
- comparisonPivotQuery: pivotData?.comparisonPivotQuery,
1356
- flags: tempReport?.flags,
1357
- chartType: 'table',
1358
- });
192
+ onSaveQuery();
1359
193
  setIsSaveQueryModalOpen(true);
1360
194
  }, disabled: !!errorMessage ||
1361
195
  !!pivotError ||
1362
196
  tableLoading ||
1363
197
  loading ||
1364
198
  !!unresolvedReportMessage, label: 'Save query', tooltipText: unresolvedReportMessage })), _jsx(ButtonComponent, { onClick: async () => {
1365
- let tempReportQuery = activeQuery;
1366
- if (queryOutOfSync) {
1367
- tempReportQuery =
1368
- await fetchQueryFromReportBuilderState(reportBuilderState);
1369
- }
1370
- onSaveChanges && onSaveChanges();
1371
- const tempReportColumns = columns
1372
- .map((column) => {
1373
- return reportColumnsToStateColumns.find((col) => col.field === (column.alias || column.field));
1374
- })
1375
- .filter((col) => col !== undefined);
1376
- let customFieldColumns = [];
1377
- if (client && isSelectStar && schemaData.customFields) {
1378
- customFieldColumns = tables.flatMap((table) => {
1379
- return (schemaData.customFields?.[table.name || ''] || []).map((field) => field.field);
1380
- });
1381
- }
1382
- setTempReport({
1383
- ...tempReport,
1384
- ...(pivot
1385
- ? pivotFormData(pivot, reportColumnsToStateColumns, tempReport, tempReport.chartType, pivotData ?? undefined)
1386
- : {}),
1387
- id: TEMP_REPORT_ID,
1388
- dashboardName: destinationDashboard,
1389
- pivot: pivot,
1390
- yAxisFields: tempReport?.pivot && !pivot
1391
- ? []
1392
- : tempReport?.yAxisFields,
1393
- columns: isSelectStar
1394
- ? // if SELECT *, filter out custom fields from tabular view
1395
- // so Automatic Custom Fields can be applied
1396
- tempReportColumns.filter((col) => {
1397
- return !customFieldColumns.includes(col.field);
1398
- })
1399
- : tempReportColumns,
1400
- columnInternal: isSelectStar
1401
- ? // if SELECT *, filter out custom fields from tabular view
1402
- // so Automatic Custom Fields can be applied
1403
- tempReportColumns.filter((col) => {
1404
- return !customFieldColumns.includes(col.field);
1405
- })
1406
- : tempReportColumns,
1407
- queryString: isSelectStar
1408
- ? convertQueryToSelectStar(tempReportQuery)
1409
- : tempReportQuery,
1410
- includeCustomFields: isSelectStar,
1411
- rows: reportRows,
1412
- pivotRows: pivotData?.rows,
1413
- pivotColumns: pivotData?.columns,
1414
- pivotRowCount: pivotData?.rowCount,
1415
- pivotQuery: pivotData?.pivotQuery,
1416
- comparisonPivotQuery: pivotData?.comparisonPivotQuery,
1417
- flags: tempReport?.flags,
1418
- });
199
+ onSaveReport();
1419
200
  setIsChartBuilderOpen(true);
1420
201
  }, disabled: !!errorMessage ||
1421
202
  !!pivotError ||
1422
203
  tableLoading ||
1423
204
  loading ||
1424
- !!unresolvedReportMessage, label: reportId ? 'Save changes' : 'Add to dashboard', tooltipText: unresolvedReportMessage })] }))] })] }), _jsx("style", { children: `body{margin:0;}` })] })), (!isChartBuilderHorizontalView || isChartBuilderOpen) && (_jsx(ChartBuilderWithModal, { tempReport: tempReport, reportId: reportId, isAdmin: isAdminEnabled, title: chartBuilderTitle
1425
- ? chartBuilderTitle
1426
- : reportId
1427
- ? 'Save changes'
1428
- : 'Add to dashboard', isHorizontalView: true, isOpen: isChartBuilderOpen, setIsOpen: setIsChartBuilderOpen, onAddToDashboardComplete: reportId ? onSubmitEditReport : onSubmitCreateReport, destinationDashboard: destinationDashboard, destinationSection: destinationSection, organizationName: organizationName, initialUniqueValues: columnUniqueValues, initialUniqueValuesIsLoading: filteredUniqueValuesIsLoading || unfilteredUniqueValuesIsLoading, pivotRecommendationsEnabled: pivotRecommendationsEnabledState, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, HeaderComponent: HeaderComponent, SubHeaderComponent: SubHeaderComponent, LabelComponent: LabelComponent, TextComponent: TextComponent, CardComponent: CardComponent, ModalComponent: ChartBuilderModalComponent, PopoverComponent: PopoverComponent, TableComponent: TableComponent, DeleteButtonComponent: DeleteButtonComponent, LoadingComponent: LoadingComponent, ChartBuilderInputRowContainer: ChartBuilderInputRowContainer, ChartBuilderInputColumnContainer: ChartBuilderInputColumnContainer, CheckboxComponent: CheckboxComponent, FormContainer: ChartBuilderFormContainer, hideDateRangeFilter: true, hideDeleteButton: true, buttonLabel: !!reportId ? 'Save changes' : 'Add to dashboard', onClickChartElement: onClickChartElement, filtersEnabled: filtersEnabled, onFiltersEnabledChanged: (enabled) => {
1429
- setFiltersEnabled(enabled);
1430
- }, isEditingMode: true, runQueryOnMount: filtersEnabled })), isSaveQueryModalOpen && (_jsx(ChartBuilderWithModal, { isHorizontalView: false, hideTableView: true, hideChartView: true, hidePivotForm: true, hideChartType: true, isOpen: isSaveQueryModalOpen, setIsOpen: setIsSaveQueryModalOpen, onAddToDashboardComplete: onSubmitSaveQuery, destinationDashboard: SAVED_QUERIES_DASHBOARD, destinationSection: destinationSection, isAdmin: false, title: 'Save query', buttonLabel: 'Save query', tempReport: tempReport, reportId: reportId, organizationName: organizationName, CardComponent: CardComponent, TableComponent: TableComponent, ModalComponent: ModalComponent, ButtonComponent: ButtonComponent, TextInputComponent: TextInputComponent, SelectComponent: SelectComponent, SecondaryButtonComponent: SecondaryButtonComponent, HeaderComponent: HeaderComponent, SubHeaderComponent: SubHeaderComponent, LabelComponent: LabelComponent, TextComponent: TextComponent, PopoverComponent: PopoverComponent, DeleteButtonComponent: DeleteButtonComponent, LoadingComponent: LoadingComponent, ChartBuilderInputRowContainer: ChartBuilderInputRowContainer, ChartBuilderInputColumnContainer: ChartBuilderInputColumnContainer, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, FormContainer: ChartBuilderFormContainer, CheckboxComponent: CheckboxComponent, hideDateRangeFilter: true, hideDeleteButton: true, hideDiscardChanges: true, hideSQLQuery: false, onClickChartElement: onClickChartElement,
1431
- // hide filters table, make it a table chart etc
1432
- filtersEnabled: filtersEnabled, onFiltersEnabledChanged: (enabled) => setFiltersEnabled(enabled), isEditingMode: true }))] }));
205
+ !!unresolvedReportMessage, label: reportId ? 'Save changes' : 'Add to dashboard', tooltipText: unresolvedReportMessage })] }))] })] }), _jsx("style", { children: `body{margin:0;}` })] })), (!isChartBuilderHorizontalView || isChartBuilderOpen) && (_jsx(SaveReport
206
+ // The reason this isn't just using the default trigger and
207
+ // directly replacing the Add To Dashboard button above is because
208
+ // that button is in a div with overflow: hidden
209
+ , {
210
+ // The reason this isn't just using the default trigger and
211
+ // directly replacing the Add To Dashboard button above is because
212
+ // that button is in a div with overflow: hidden
213
+ SaveTrigger: null, reportBuilder: reportBuilder, isOpen: isChartBuilderOpen, setIsOpen: setIsChartBuilderOpen, isAdminEnabled: isAdminEnabled, chartBuilderTitle: chartBuilderTitle, onSubmitEditReport: onSubmitEditReport, onSubmitCreateReport: onSubmitCreateReport, destinationSection: destinationSection, ModalComponent: ChartBuilderModalComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, HeaderComponent: HeaderComponent, SubHeaderComponent: SubHeaderComponent, LabelComponent: LabelComponent, TextComponent: TextComponent, CardComponent: CardComponent, PopoverComponent: PopoverComponent, TableComponent: TableComponent, DeleteButtonComponent: DeleteButtonComponent, LoadingComponent: LoadingComponent, ChartBuilderInputRowContainer: ChartBuilderInputRowContainer, ChartBuilderInputColumnContainer: ChartBuilderInputColumnContainer, CheckboxComponent: CheckboxComponent, ChartBuilderFormContainer: ChartBuilderFormContainer, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, onClickChartElement: onClickChartElement })
214
+ // <ChartBuilderWithModal
215
+ // tempReport={tempReport}
216
+ // reportId={reportId}
217
+ // isAdmin={isAdminEnabled}
218
+ // title={
219
+ // chartBuilderTitle
220
+ // ? chartBuilderTitle
221
+ // : reportId
222
+ // ? 'Save changes'
223
+ // : 'Add to dashboard'
224
+ // }
225
+ // isHorizontalView={true}
226
+ // isOpen={isChartBuilderOpen}
227
+ // setIsOpen={setIsChartBuilderOpen}
228
+ // onAddToDashboardComplete={
229
+ // reportId ? onSubmitEditReport : onSubmitCreateReport
230
+ // }
231
+ // destinationDashboard={destinationDashboard}
232
+ // destinationSection={destinationSection}
233
+ // organizationName={organizationName}
234
+ // initialUniqueValues={columnUniqueValues}
235
+ // initialUniqueValuesIsLoading={
236
+ // filteredUniqueValuesIsLoading || unfilteredUniqueValuesIsLoading
237
+ // }
238
+ // pivotRecommendationsEnabled={pivotRecommendationsEnabled}
239
+ // SelectComponent={SelectComponent}
240
+ // TextInputComponent={TextInputComponent}
241
+ // ButtonComponent={ButtonComponent}
242
+ // SecondaryButtonComponent={SecondaryButtonComponent}
243
+ // HeaderComponent={HeaderComponent}
244
+ // SubHeaderComponent={SubHeaderComponent}
245
+ // LabelComponent={LabelComponent}
246
+ // TextComponent={TextComponent}
247
+ // CardComponent={CardComponent}
248
+ // ModalComponent={ChartBuilderModalComponent}
249
+ // PopoverComponent={PopoverComponent}
250
+ // TableComponent={TableComponent}
251
+ // DeleteButtonComponent={DeleteButtonComponent}
252
+ // LoadingComponent={LoadingComponent}
253
+ // ChartBuilderInputRowContainer={ChartBuilderInputRowContainer}
254
+ // ChartBuilderInputColumnContainer={ChartBuilderInputColumnContainer}
255
+ // CheckboxComponent={CheckboxComponent}
256
+ // FormContainer={ChartBuilderFormContainer}
257
+ // hideDateRangeFilter={true}
258
+ // hideDeleteButton={true}
259
+ // buttonLabel={!!reportId ? 'Save changes' : 'Add to dashboard'}
260
+ // onClickChartElement={onClickChartElement}
261
+ // filtersEnabled={filtersEnabled}
262
+ // onFiltersEnabledChanged={(enabled: boolean) => {
263
+ // setFiltersEnabled(enabled);
264
+ // }}
265
+ // isEditingMode={true}
266
+ // runQueryOnMount={filtersEnabled}
267
+ // />
268
+ ), isSaveQueryModalOpen && (_jsx(ChartBuilderWithModal, { isHorizontalView: false, hideTableView: true, hideChartView: true, hidePivotForm: true, hideChartType: true, isOpen: isSaveQueryModalOpen, setIsOpen: setIsSaveQueryModalOpen, onAddToDashboardComplete: onSubmitSaveQuery, destinationDashboard: SAVED_QUERIES_DASHBOARD, destinationSection: destinationSection, isAdmin: false, title: 'Save query', buttonLabel: 'Save query', tempReport: tempReport, reportId: reportId, organizationName: organizationName, CardComponent: CardComponent, TableComponent: TableComponent, ModalComponent: ModalComponent, ButtonComponent: ButtonComponent, TextInputComponent: TextInputComponent, SelectComponent: SelectComponent, SecondaryButtonComponent: SecondaryButtonComponent, HeaderComponent: HeaderComponent, SubHeaderComponent: SubHeaderComponent, LabelComponent: LabelComponent, TextComponent: TextComponent, PopoverComponent: PopoverComponent, DeleteButtonComponent: DeleteButtonComponent, LoadingComponent: LoadingComponent, ChartBuilderInputRowContainer: ChartBuilderInputRowContainer, ChartBuilderInputColumnContainer: ChartBuilderInputColumnContainer, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, FormContainer: ChartBuilderFormContainer, CheckboxComponent: CheckboxComponent, hideDateRangeFilter: true, hideDeleteButton: true, hideDiscardChanges: true, hideSQLQuery: false, onClickChartElement: onClickChartElement, isEditingMode: true }))] }));
1433
269
  }