@quillsql/react 2.12.29 → 2.12.31

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 (530) hide show
  1. package/dist/cjs/Chart.d.ts +29 -46
  2. package/dist/cjs/Chart.d.ts.map +1 -1
  3. package/dist/cjs/Chart.js +187 -468
  4. package/dist/cjs/ChartBuilder.d.ts +30 -61
  5. package/dist/cjs/ChartBuilder.d.ts.map +1 -1
  6. package/dist/cjs/ChartBuilder.js +190 -131
  7. package/dist/cjs/ChartEditor.d.ts +14 -2
  8. package/dist/cjs/ChartEditor.d.ts.map +1 -1
  9. package/dist/cjs/ChartEditor.js +70 -125
  10. package/dist/cjs/Context.d.ts +4 -1
  11. package/dist/cjs/Context.d.ts.map +1 -1
  12. package/dist/cjs/Context.js +52 -6
  13. package/dist/cjs/Dashboard.d.ts +74 -118
  14. package/dist/cjs/Dashboard.d.ts.map +1 -1
  15. package/dist/cjs/Dashboard.js +273 -47
  16. package/dist/cjs/DateRangePicker/Calendar.d.ts.map +1 -1
  17. package/dist/cjs/DateRangePicker/Calendar.js +3 -6
  18. package/dist/cjs/DateRangePicker/DateRangePicker.d.ts.map +1 -1
  19. package/dist/cjs/DateRangePicker/DateRangePicker.js +2 -29
  20. package/dist/cjs/DateRangePicker/DateRangePickerButton.d.ts +1 -2
  21. package/dist/cjs/DateRangePicker/DateRangePickerButton.d.ts.map +1 -1
  22. package/dist/cjs/DateRangePicker/DateRangePickerButton.js +2 -4
  23. package/dist/cjs/DateRangePicker/QuillDateRangePicker.d.ts +2 -1
  24. package/dist/cjs/DateRangePicker/QuillDateRangePicker.d.ts.map +1 -1
  25. package/dist/cjs/DateRangePicker/QuillDateRangePicker.js +4 -4
  26. package/dist/cjs/DateRangePicker/dateRangePickerUtils.d.ts +1 -1
  27. package/dist/cjs/DateRangePicker/dateRangePickerUtils.d.ts.map +1 -1
  28. package/dist/cjs/DateRangePicker/dateRangePickerUtils.js +1 -15
  29. package/dist/cjs/ReportBuilder.d.ts +18 -6
  30. package/dist/cjs/ReportBuilder.d.ts.map +1 -1
  31. package/dist/cjs/ReportBuilder.js +477 -489
  32. package/dist/cjs/SQLEditor.d.ts +4 -11
  33. package/dist/cjs/SQLEditor.d.ts.map +1 -1
  34. package/dist/cjs/SQLEditor.js +76 -88
  35. package/dist/cjs/Table.d.ts +19 -3
  36. package/dist/cjs/Table.d.ts.map +1 -1
  37. package/dist/cjs/Table.js +130 -114
  38. package/dist/cjs/TableChart.d.ts.map +1 -1
  39. package/dist/cjs/TableChart.js +0 -1
  40. package/dist/cjs/assets/ArrowDownHeadIcon.d.ts.map +1 -1
  41. package/dist/cjs/assets/ArrowDownIcon.d.ts.map +1 -1
  42. package/dist/cjs/assets/ArrowDownRightIcon.d.ts.map +1 -1
  43. package/dist/cjs/assets/ArrowLeftHeadIcon.d.ts.map +1 -1
  44. package/dist/cjs/assets/ArrowRightHeadIcon.d.ts.map +1 -1
  45. package/dist/cjs/assets/ArrowRightIcon.d.ts.map +1 -1
  46. package/dist/cjs/assets/ArrowUpHeadIcon.d.ts.map +1 -1
  47. package/dist/cjs/assets/ArrowUpIcon.d.ts.map +1 -1
  48. package/dist/cjs/assets/ArrowUpRightIcon.d.ts.map +1 -1
  49. package/dist/cjs/assets/CalendarIcon.d.ts.map +1 -1
  50. package/dist/cjs/assets/DoubleArrowLeftHeadIcon.d.ts.map +1 -1
  51. package/dist/cjs/assets/DoubleArrowRightHeadIcon.d.ts.map +1 -1
  52. package/dist/cjs/assets/ExclamationFilledIcon.d.ts.map +1 -1
  53. package/dist/cjs/assets/LoadingSpinner.d.ts.map +1 -1
  54. package/dist/cjs/assets/SearchIcon.d.ts.map +1 -1
  55. package/dist/cjs/assets/XCircleIcon.d.ts.map +1 -1
  56. package/dist/cjs/components/Banner/index.d.ts +1 -1
  57. package/dist/cjs/components/Banner/index.d.ts.map +1 -1
  58. package/dist/cjs/components/Banner/index.js +1 -1
  59. package/dist/cjs/components/BigModal/BigModal.d.ts.map +1 -1
  60. package/dist/cjs/components/BigModal/BigModal.js +6 -12
  61. package/dist/cjs/components/Chart/BarChart.d.ts.map +1 -1
  62. package/dist/cjs/components/Chart/BarChart.js +12 -1
  63. package/dist/cjs/components/Chart/BarList.d.ts.map +1 -1
  64. package/dist/cjs/components/Chart/BarList.js +21 -14
  65. package/dist/cjs/components/Chart/ChartError.d.ts +8 -1
  66. package/dist/cjs/components/Chart/ChartError.d.ts.map +1 -1
  67. package/dist/cjs/components/Chart/ChartError.js +40 -5
  68. package/dist/cjs/components/Chart/ChartTooltip.d.ts.map +1 -1
  69. package/dist/cjs/components/Chart/ChartTooltip.js +8 -2
  70. package/dist/cjs/components/Chart/LineChart.d.ts +2 -1
  71. package/dist/cjs/components/Chart/LineChart.d.ts.map +1 -1
  72. package/dist/cjs/components/Chart/LineChart.js +27 -3
  73. package/dist/cjs/components/Chart/PieChart.d.ts.map +1 -1
  74. package/dist/cjs/components/Chart/PieChart.js +1 -3
  75. package/dist/cjs/components/Dashboard/ChartComponent.d.ts +1 -1
  76. package/dist/cjs/components/Dashboard/ChartComponent.d.ts.map +1 -1
  77. package/dist/cjs/components/Dashboard/ChartComponent.js +1 -1
  78. package/dist/cjs/components/Dashboard/DashboardFilter.d.ts +5 -1
  79. package/dist/cjs/components/Dashboard/DashboardFilter.d.ts.map +1 -1
  80. package/dist/cjs/components/Dashboard/DashboardFilter.js +10 -5
  81. package/dist/cjs/components/Dashboard/DataLoader.d.ts +8 -12
  82. package/dist/cjs/components/Dashboard/DataLoader.d.ts.map +1 -1
  83. package/dist/cjs/components/Dashboard/DataLoader.js +137 -194
  84. package/dist/cjs/components/Dashboard/MetricComponent.d.ts.map +1 -1
  85. package/dist/cjs/components/Dashboard/MetricComponent.js +11 -45
  86. package/dist/cjs/components/Dashboard/TableComponent.d.ts +2 -5
  87. package/dist/cjs/components/Dashboard/TableComponent.d.ts.map +1 -1
  88. package/dist/cjs/components/Dashboard/TableComponent.js +3 -32
  89. package/dist/cjs/components/Dropdown/Dropdown.d.ts.map +1 -1
  90. package/dist/cjs/components/Dropdown/Dropdown.js +1 -3
  91. package/dist/cjs/components/Dropdown/DropdownItem.d.ts.map +1 -1
  92. package/dist/cjs/components/Dropdown/DropdownItem.js +3 -8
  93. package/dist/cjs/components/Dropdown/index.d.ts +2 -2
  94. package/dist/cjs/components/Modal/Modal.d.ts.map +1 -1
  95. package/dist/cjs/components/Modal/Modal.js +2 -3
  96. package/dist/cjs/components/Modal/index.d.ts +1 -1
  97. package/dist/cjs/components/QuillMultiSelect.d.ts.map +1 -1
  98. package/dist/cjs/components/QuillMultiSelect.js +18 -3
  99. package/dist/cjs/components/QuillMultiSelectWithCombo.d.ts.map +1 -1
  100. package/dist/cjs/components/QuillMultiSelectWithCombo.js +18 -3
  101. package/dist/cjs/components/QuillSelect.js +1 -1
  102. package/dist/cjs/components/QuillSelectWithCombo.d.ts.map +1 -1
  103. package/dist/cjs/components/QuillSelectWithCombo.js +6 -3
  104. package/dist/cjs/components/QuillTable.d.ts +1 -4
  105. package/dist/cjs/components/QuillTable.d.ts.map +1 -1
  106. package/dist/cjs/components/QuillTable.js +5 -11
  107. package/dist/cjs/components/ReportBuilder/AddColumnModal.d.ts +3 -1
  108. package/dist/cjs/components/ReportBuilder/AddColumnModal.d.ts.map +1 -1
  109. package/dist/cjs/components/ReportBuilder/AddColumnModal.js +5 -8
  110. package/dist/cjs/components/ReportBuilder/AddLimitPopover.d.ts.map +1 -1
  111. package/dist/cjs/components/ReportBuilder/AddLimitPopover.js +1 -3
  112. package/dist/cjs/components/ReportBuilder/AddSortPopover.d.ts.map +1 -1
  113. package/dist/cjs/components/ReportBuilder/AddSortPopover.js +12 -1
  114. package/dist/cjs/components/ReportBuilder/FilterModal.d.ts +30 -0
  115. package/dist/cjs/components/ReportBuilder/FilterModal.d.ts.map +1 -0
  116. package/dist/cjs/components/ReportBuilder/FilterModal.js +579 -0
  117. package/dist/cjs/components/ReportBuilder/ast.d.ts +2 -1
  118. package/dist/cjs/components/ReportBuilder/ast.d.ts.map +1 -1
  119. package/dist/cjs/components/ReportBuilder/ast.js +33 -6
  120. package/dist/cjs/components/ReportBuilder/constants.d.ts +18 -3
  121. package/dist/cjs/components/ReportBuilder/constants.d.ts.map +1 -1
  122. package/dist/cjs/components/ReportBuilder/constants.js +24 -3
  123. package/dist/cjs/components/ReportBuilder/convert.d.ts +18 -16
  124. package/dist/cjs/components/ReportBuilder/convert.d.ts.map +1 -1
  125. package/dist/cjs/components/ReportBuilder/convert.js +378 -494
  126. package/dist/cjs/components/ReportBuilder/operators.d.ts +24 -4
  127. package/dist/cjs/components/ReportBuilder/operators.d.ts.map +1 -1
  128. package/dist/cjs/components/ReportBuilder/operators.js +32 -4
  129. package/dist/cjs/components/ReportBuilder/ui.d.ts +20 -0
  130. package/dist/cjs/components/ReportBuilder/ui.d.ts.map +1 -1
  131. package/dist/cjs/components/ReportBuilder/ui.js +15 -5
  132. package/dist/cjs/components/ReportBuilder/util.d.ts +3 -11
  133. package/dist/cjs/components/ReportBuilder/util.d.ts.map +1 -1
  134. package/dist/cjs/components/ReportBuilder/util.js +15 -18
  135. package/dist/cjs/components/UiComponents.d.ts +36 -8
  136. package/dist/cjs/components/UiComponents.d.ts.map +1 -1
  137. package/dist/cjs/components/UiComponents.js +106 -12
  138. package/dist/cjs/components/selectUtils.d.ts +0 -1
  139. package/dist/cjs/components/selectUtils.d.ts.map +1 -1
  140. package/dist/cjs/components/selectUtils.js +1 -22
  141. package/dist/cjs/hooks/index.d.ts +4 -4
  142. package/dist/cjs/hooks/useAstToFilterTree.d.ts +11 -0
  143. package/dist/cjs/hooks/useAstToFilterTree.d.ts.map +1 -0
  144. package/dist/cjs/hooks/useAstToFilterTree.js +26 -0
  145. package/dist/cjs/hooks/useDashboard.d.ts.map +1 -1
  146. package/dist/cjs/hooks/useDashboard.js +5 -1
  147. package/dist/cjs/hooks/useExport.d.ts.map +1 -1
  148. package/dist/cjs/hooks/useExport.js +3 -1
  149. package/dist/cjs/hooks/useOnClickOutside.js +4 -4
  150. package/dist/cjs/hooks/useOnWindowResize.d.ts.map +1 -1
  151. package/dist/cjs/hooks/useOnWindowResize.js +2 -2
  152. package/dist/cjs/hooks/useQuill.d.ts +10 -27
  153. package/dist/cjs/hooks/useQuill.d.ts.map +1 -1
  154. package/dist/cjs/hooks/useQuill.js +133 -85
  155. package/dist/cjs/hooks/useSelectOnKeyDown.d.ts.map +1 -1
  156. package/dist/cjs/hooks/useSelectOnKeyDown.js +4 -4
  157. package/dist/cjs/hooks/useTheme.js +1 -1
  158. package/dist/cjs/index.d.ts +3 -1
  159. package/dist/cjs/index.d.ts.map +1 -1
  160. package/dist/cjs/index.js +3 -1
  161. package/dist/cjs/internals/ReportBuilder/PivotForm.d.ts.map +1 -1
  162. package/dist/cjs/internals/ReportBuilder/PivotForm.js +8 -1
  163. package/dist/cjs/internals/ReportBuilder/PivotList.d.ts +2 -2
  164. package/dist/cjs/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  165. package/dist/cjs/internals/ReportBuilder/PivotList.js +2 -2
  166. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts +2 -1
  167. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  168. package/dist/cjs/internals/ReportBuilder/PivotModal.js +8 -21
  169. package/dist/cjs/lib/utils.js +2 -2
  170. package/dist/cjs/models/Columns.d.ts +2 -1
  171. package/dist/cjs/models/Columns.d.ts.map +1 -1
  172. package/dist/cjs/models/Filter.d.ts +115 -4
  173. package/dist/cjs/models/Filter.d.ts.map +1 -1
  174. package/dist/cjs/models/Filter.js +99 -0
  175. package/dist/cjs/models/Pagination.d.ts +10 -0
  176. package/dist/cjs/models/Pagination.d.ts.map +1 -0
  177. package/dist/cjs/models/Pagination.js +2 -0
  178. package/dist/cjs/models/Report.d.ts +103 -0
  179. package/dist/cjs/models/Report.d.ts.map +1 -0
  180. package/dist/cjs/models/Report.js +2 -0
  181. package/dist/cjs/utils/aggregate.js +1 -1
  182. package/dist/cjs/utils/astFilterProcessing.d.ts +36 -0
  183. package/dist/cjs/utils/astFilterProcessing.d.ts.map +1 -0
  184. package/dist/cjs/utils/astFilterProcessing.js +8091 -0
  185. package/dist/cjs/utils/astProcessing.d.ts.map +1 -1
  186. package/dist/cjs/utils/astProcessing.js +4 -3
  187. package/dist/cjs/utils/axisFormatter.js +0 -71
  188. package/dist/cjs/utils/color.js +9 -87
  189. package/dist/cjs/utils/columnProcessing.d.ts +2 -0
  190. package/dist/cjs/utils/columnProcessing.d.ts.map +1 -1
  191. package/dist/cjs/utils/columnProcessing.js +54 -1
  192. package/dist/cjs/utils/csv.d.ts.map +1 -1
  193. package/dist/cjs/utils/dashboard.d.ts +1 -1
  194. package/dist/cjs/utils/dashboard.d.ts.map +1 -1
  195. package/dist/cjs/utils/dashboard.js +6 -59
  196. package/dist/cjs/utils/dataFetcher.d.ts.map +1 -1
  197. package/dist/cjs/utils/dataFetcher.js +63 -1
  198. package/dist/cjs/utils/dataProcessing.d.ts +10 -0
  199. package/dist/cjs/utils/dataProcessing.d.ts.map +1 -0
  200. package/dist/cjs/utils/dataProcessing.js +144 -0
  201. package/dist/cjs/utils/dates.d.ts +2 -1
  202. package/dist/cjs/utils/dates.d.ts.map +1 -1
  203. package/dist/cjs/utils/dates.js +23 -1
  204. package/dist/cjs/utils/error.d.ts +5 -0
  205. package/dist/cjs/utils/error.d.ts.map +1 -0
  206. package/dist/cjs/utils/error.js +12 -0
  207. package/dist/cjs/utils/filterConstants.d.ts +34 -0
  208. package/dist/cjs/utils/filterConstants.d.ts.map +1 -0
  209. package/dist/cjs/utils/filterConstants.js +36 -0
  210. package/dist/cjs/utils/filterProcessing.d.ts +7 -1
  211. package/dist/cjs/utils/filterProcessing.d.ts.map +1 -1
  212. package/dist/cjs/utils/filterProcessing.js +104 -17
  213. package/dist/cjs/utils/logging.d.ts.map +1 -1
  214. package/dist/cjs/utils/logging.js +1 -0
  215. package/dist/cjs/utils/merge.js +0 -21
  216. package/dist/cjs/utils/{monacoAutocomplete.d.ts → monacoConfig.d.ts} +3 -2
  217. package/dist/cjs/utils/monacoConfig.d.ts.map +1 -0
  218. package/dist/cjs/utils/monacoConfig.js +324 -0
  219. package/dist/cjs/utils/paginationProcessing.d.ts +5 -0
  220. package/dist/cjs/utils/paginationProcessing.d.ts.map +1 -0
  221. package/dist/cjs/utils/paginationProcessing.js +30 -0
  222. package/dist/cjs/utils/pivotConstructor.d.ts +2 -1
  223. package/dist/cjs/utils/pivotConstructor.d.ts.map +1 -1
  224. package/dist/cjs/utils/pivotConstructor.js +16 -1
  225. package/dist/cjs/utils/pivotProcessing.d.ts.map +1 -1
  226. package/dist/cjs/utils/pivotProcessing.js +12 -6
  227. package/dist/cjs/utils/queryConstructor.d.ts.map +1 -1
  228. package/dist/cjs/utils/queryConstructor.js +4 -3
  229. package/dist/cjs/utils/report.d.ts +10 -0
  230. package/dist/cjs/utils/report.d.ts.map +1 -0
  231. package/dist/cjs/utils/report.js +180 -0
  232. package/dist/cjs/utils/schema.d.ts.map +1 -1
  233. package/dist/cjs/utils/schema.js +35 -6
  234. package/dist/cjs/utils/styles.d.ts +1 -1
  235. package/dist/cjs/utils/styles.d.ts.map +1 -1
  236. package/dist/cjs/utils/tableProcessing.d.ts +22 -8
  237. package/dist/cjs/utils/tableProcessing.d.ts.map +1 -1
  238. package/dist/cjs/utils/tableProcessing.js +116 -35
  239. package/dist/cjs/utils/textProcessing.js +3 -3
  240. package/dist/cjs/utils/validation.d.ts +9 -0
  241. package/dist/cjs/utils/validation.d.ts.map +1 -0
  242. package/dist/cjs/utils/validation.js +24 -0
  243. package/dist/cjs/utils/valueFormatter.d.ts.map +1 -1
  244. package/dist/cjs/utils/valueFormatter.js +8 -4
  245. package/dist/esm/Chart.d.ts +29 -46
  246. package/dist/esm/Chart.d.ts.map +1 -1
  247. package/dist/esm/Chart.js +189 -471
  248. package/dist/esm/ChartBuilder.d.ts +30 -61
  249. package/dist/esm/ChartBuilder.d.ts.map +1 -1
  250. package/dist/esm/ChartBuilder.js +191 -129
  251. package/dist/esm/ChartEditor.d.ts +14 -2
  252. package/dist/esm/ChartEditor.d.ts.map +1 -1
  253. package/dist/esm/ChartEditor.js +71 -126
  254. package/dist/esm/Context.d.ts +4 -1
  255. package/dist/esm/Context.d.ts.map +1 -1
  256. package/dist/esm/Context.js +51 -5
  257. package/dist/esm/Dashboard.d.ts +74 -118
  258. package/dist/esm/Dashboard.d.ts.map +1 -1
  259. package/dist/esm/Dashboard.js +275 -49
  260. package/dist/esm/DateRangePicker/Calendar.d.ts.map +1 -1
  261. package/dist/esm/DateRangePicker/Calendar.js +5 -8
  262. package/dist/esm/DateRangePicker/DateRangePicker.d.ts.map +1 -1
  263. package/dist/esm/DateRangePicker/DateRangePicker.js +2 -29
  264. package/dist/esm/DateRangePicker/DateRangePickerButton.d.ts +1 -2
  265. package/dist/esm/DateRangePicker/DateRangePickerButton.d.ts.map +1 -1
  266. package/dist/esm/DateRangePicker/DateRangePickerButton.js +2 -4
  267. package/dist/esm/DateRangePicker/QuillDateRangePicker.d.ts +2 -1
  268. package/dist/esm/DateRangePicker/QuillDateRangePicker.d.ts.map +1 -1
  269. package/dist/esm/DateRangePicker/QuillDateRangePicker.js +4 -4
  270. package/dist/esm/DateRangePicker/dateRangePickerUtils.d.ts +1 -1
  271. package/dist/esm/DateRangePicker/dateRangePickerUtils.d.ts.map +1 -1
  272. package/dist/esm/DateRangePicker/dateRangePickerUtils.js +1 -15
  273. package/dist/esm/ReportBuilder.d.ts +18 -6
  274. package/dist/esm/ReportBuilder.d.ts.map +1 -1
  275. package/dist/esm/ReportBuilder.js +484 -496
  276. package/dist/esm/SQLEditor.d.ts +4 -11
  277. package/dist/esm/SQLEditor.d.ts.map +1 -1
  278. package/dist/esm/SQLEditor.js +75 -87
  279. package/dist/esm/Table.d.ts +19 -3
  280. package/dist/esm/Table.d.ts.map +1 -1
  281. package/dist/esm/Table.js +132 -116
  282. package/dist/esm/TableChart.d.ts.map +1 -1
  283. package/dist/esm/TableChart.js +0 -1
  284. package/dist/esm/assets/ArrowDownHeadIcon.d.ts.map +1 -1
  285. package/dist/esm/assets/ArrowDownIcon.d.ts.map +1 -1
  286. package/dist/esm/assets/ArrowDownRightIcon.d.ts.map +1 -1
  287. package/dist/esm/assets/ArrowLeftHeadIcon.d.ts.map +1 -1
  288. package/dist/esm/assets/ArrowRightHeadIcon.d.ts.map +1 -1
  289. package/dist/esm/assets/ArrowRightIcon.d.ts.map +1 -1
  290. package/dist/esm/assets/ArrowUpHeadIcon.d.ts.map +1 -1
  291. package/dist/esm/assets/ArrowUpIcon.d.ts.map +1 -1
  292. package/dist/esm/assets/ArrowUpRightIcon.d.ts.map +1 -1
  293. package/dist/esm/assets/CalendarIcon.d.ts.map +1 -1
  294. package/dist/esm/assets/DoubleArrowLeftHeadIcon.d.ts.map +1 -1
  295. package/dist/esm/assets/DoubleArrowRightHeadIcon.d.ts.map +1 -1
  296. package/dist/esm/assets/ExclamationFilledIcon.d.ts.map +1 -1
  297. package/dist/esm/assets/LoadingSpinner.d.ts.map +1 -1
  298. package/dist/esm/assets/SearchIcon.d.ts.map +1 -1
  299. package/dist/esm/assets/XCircleIcon.d.ts.map +1 -1
  300. package/dist/esm/components/Banner/index.d.ts +1 -1
  301. package/dist/esm/components/Banner/index.d.ts.map +1 -1
  302. package/dist/esm/components/Banner/index.js +1 -1
  303. package/dist/esm/components/BigModal/BigModal.d.ts.map +1 -1
  304. package/dist/esm/components/BigModal/BigModal.js +7 -13
  305. package/dist/esm/components/Chart/BarChart.d.ts.map +1 -1
  306. package/dist/esm/components/Chart/BarChart.js +13 -2
  307. package/dist/esm/components/Chart/BarList.d.ts.map +1 -1
  308. package/dist/esm/components/Chart/BarList.js +21 -14
  309. package/dist/esm/components/Chart/ChartError.d.ts +8 -1
  310. package/dist/esm/components/Chart/ChartError.d.ts.map +1 -1
  311. package/dist/esm/components/Chart/ChartError.js +39 -6
  312. package/dist/esm/components/Chart/ChartTooltip.d.ts.map +1 -1
  313. package/dist/esm/components/Chart/ChartTooltip.js +8 -2
  314. package/dist/esm/components/Chart/LineChart.d.ts +2 -1
  315. package/dist/esm/components/Chart/LineChart.d.ts.map +1 -1
  316. package/dist/esm/components/Chart/LineChart.js +28 -4
  317. package/dist/esm/components/Chart/PieChart.d.ts.map +1 -1
  318. package/dist/esm/components/Chart/PieChart.js +1 -3
  319. package/dist/esm/components/Dashboard/ChartComponent.d.ts +1 -1
  320. package/dist/esm/components/Dashboard/ChartComponent.d.ts.map +1 -1
  321. package/dist/esm/components/Dashboard/ChartComponent.js +1 -1
  322. package/dist/esm/components/Dashboard/DashboardFilter.d.ts +5 -1
  323. package/dist/esm/components/Dashboard/DashboardFilter.d.ts.map +1 -1
  324. package/dist/esm/components/Dashboard/DashboardFilter.js +10 -5
  325. package/dist/esm/components/Dashboard/DataLoader.d.ts +8 -12
  326. package/dist/esm/components/Dashboard/DataLoader.d.ts.map +1 -1
  327. package/dist/esm/components/Dashboard/DataLoader.js +137 -194
  328. package/dist/esm/components/Dashboard/MetricComponent.d.ts.map +1 -1
  329. package/dist/esm/components/Dashboard/MetricComponent.js +11 -45
  330. package/dist/esm/components/Dashboard/TableComponent.d.ts +2 -5
  331. package/dist/esm/components/Dashboard/TableComponent.d.ts.map +1 -1
  332. package/dist/esm/components/Dashboard/TableComponent.js +3 -32
  333. package/dist/esm/components/Dropdown/Dropdown.d.ts.map +1 -1
  334. package/dist/esm/components/Dropdown/Dropdown.js +2 -4
  335. package/dist/esm/components/Dropdown/DropdownItem.d.ts.map +1 -1
  336. package/dist/esm/components/Dropdown/DropdownItem.js +4 -9
  337. package/dist/esm/components/Dropdown/index.d.ts +2 -2
  338. package/dist/esm/components/Dropdown/index.js +2 -2
  339. package/dist/esm/components/Modal/Modal.d.ts.map +1 -1
  340. package/dist/esm/components/Modal/Modal.js +2 -3
  341. package/dist/esm/components/Modal/index.d.ts +1 -1
  342. package/dist/esm/components/Modal/index.js +1 -1
  343. package/dist/esm/components/QuillMultiSelect.d.ts.map +1 -1
  344. package/dist/esm/components/QuillMultiSelect.js +18 -3
  345. package/dist/esm/components/QuillMultiSelectWithCombo.d.ts.map +1 -1
  346. package/dist/esm/components/QuillMultiSelectWithCombo.js +18 -3
  347. package/dist/esm/components/QuillSelect.js +1 -1
  348. package/dist/esm/components/QuillSelectWithCombo.d.ts.map +1 -1
  349. package/dist/esm/components/QuillSelectWithCombo.js +7 -4
  350. package/dist/esm/components/QuillTable.d.ts +1 -4
  351. package/dist/esm/components/QuillTable.d.ts.map +1 -1
  352. package/dist/esm/components/QuillTable.js +5 -11
  353. package/dist/esm/components/ReportBuilder/AddColumnModal.d.ts +3 -1
  354. package/dist/esm/components/ReportBuilder/AddColumnModal.d.ts.map +1 -1
  355. package/dist/esm/components/ReportBuilder/AddColumnModal.js +8 -11
  356. package/dist/esm/components/ReportBuilder/AddLimitPopover.d.ts.map +1 -1
  357. package/dist/esm/components/ReportBuilder/AddLimitPopover.js +2 -4
  358. package/dist/esm/components/ReportBuilder/AddSortPopover.d.ts.map +1 -1
  359. package/dist/esm/components/ReportBuilder/AddSortPopover.js +12 -1
  360. package/dist/esm/components/ReportBuilder/FilterModal.d.ts +30 -0
  361. package/dist/esm/components/ReportBuilder/FilterModal.d.ts.map +1 -0
  362. package/dist/esm/components/ReportBuilder/FilterModal.js +576 -0
  363. package/dist/esm/components/ReportBuilder/ast.d.ts +2 -1
  364. package/dist/esm/components/ReportBuilder/ast.d.ts.map +1 -1
  365. package/dist/esm/components/ReportBuilder/ast.js +31 -5
  366. package/dist/esm/components/ReportBuilder/constants.d.ts +18 -3
  367. package/dist/esm/components/ReportBuilder/constants.d.ts.map +1 -1
  368. package/dist/esm/components/ReportBuilder/constants.js +24 -3
  369. package/dist/esm/components/ReportBuilder/convert.d.ts +18 -16
  370. package/dist/esm/components/ReportBuilder/convert.d.ts.map +1 -1
  371. package/dist/esm/components/ReportBuilder/convert.js +375 -493
  372. package/dist/esm/components/ReportBuilder/convert.uspec.d.ts +2 -0
  373. package/dist/esm/components/ReportBuilder/convert.uspec.d.ts.map +1 -0
  374. package/dist/esm/components/ReportBuilder/convert.uspec.js +1419 -0
  375. package/dist/esm/components/ReportBuilder/operators.d.ts +24 -4
  376. package/dist/esm/components/ReportBuilder/operators.d.ts.map +1 -1
  377. package/dist/esm/components/ReportBuilder/operators.js +32 -4
  378. package/dist/esm/components/ReportBuilder/ui.d.ts +20 -0
  379. package/dist/esm/components/ReportBuilder/ui.d.ts.map +1 -1
  380. package/dist/esm/components/ReportBuilder/ui.js +13 -4
  381. package/dist/esm/components/ReportBuilder/util.d.ts +3 -11
  382. package/dist/esm/components/ReportBuilder/util.d.ts.map +1 -1
  383. package/dist/esm/components/ReportBuilder/util.js +16 -19
  384. package/dist/esm/components/UiComponents.d.ts +36 -8
  385. package/dist/esm/components/UiComponents.d.ts.map +1 -1
  386. package/dist/esm/components/UiComponents.js +104 -11
  387. package/dist/esm/components/selectUtils.d.ts +0 -1
  388. package/dist/esm/components/selectUtils.d.ts.map +1 -1
  389. package/dist/esm/components/selectUtils.js +0 -20
  390. package/dist/esm/hooks/index.d.ts +4 -4
  391. package/dist/esm/hooks/index.js +4 -4
  392. package/dist/esm/hooks/useAstToFilterTree.d.ts +11 -0
  393. package/dist/esm/hooks/useAstToFilterTree.d.ts.map +1 -0
  394. package/dist/esm/hooks/useAstToFilterTree.js +24 -0
  395. package/dist/esm/hooks/useDashboard.d.ts.map +1 -1
  396. package/dist/esm/hooks/useDashboard.js +5 -1
  397. package/dist/esm/hooks/useExport.d.ts.map +1 -1
  398. package/dist/esm/hooks/useExport.js +4 -2
  399. package/dist/esm/hooks/useOnClickOutside.js +5 -5
  400. package/dist/esm/hooks/useOnWindowResize.d.ts.map +1 -1
  401. package/dist/esm/hooks/useOnWindowResize.js +3 -3
  402. package/dist/esm/hooks/useQuill.d.ts +10 -27
  403. package/dist/esm/hooks/useQuill.d.ts.map +1 -1
  404. package/dist/esm/hooks/useQuill.js +133 -85
  405. package/dist/esm/hooks/useSelectOnKeyDown.d.ts.map +1 -1
  406. package/dist/esm/hooks/useSelectOnKeyDown.js +5 -5
  407. package/dist/esm/hooks/useTheme.js +1 -1
  408. package/dist/esm/index.d.ts +3 -1
  409. package/dist/esm/index.d.ts.map +1 -1
  410. package/dist/esm/index.js +1 -0
  411. package/dist/esm/internals/ReportBuilder/PivotForm.d.ts.map +1 -1
  412. package/dist/esm/internals/ReportBuilder/PivotForm.js +9 -2
  413. package/dist/esm/internals/ReportBuilder/PivotList.d.ts +2 -2
  414. package/dist/esm/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  415. package/dist/esm/internals/ReportBuilder/PivotList.js +3 -3
  416. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts +2 -1
  417. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  418. package/dist/esm/internals/ReportBuilder/PivotModal.js +11 -24
  419. package/dist/esm/lib/utils.js +2 -2
  420. package/dist/esm/models/Columns.d.ts +2 -1
  421. package/dist/esm/models/Columns.d.ts.map +1 -1
  422. package/dist/esm/models/Filter.d.ts +115 -4
  423. package/dist/esm/models/Filter.d.ts.map +1 -1
  424. package/dist/esm/models/Filter.js +98 -1
  425. package/dist/esm/models/Pagination.d.ts +10 -0
  426. package/dist/esm/models/Pagination.d.ts.map +1 -0
  427. package/dist/esm/models/Pagination.js +1 -0
  428. package/dist/esm/models/Report.d.ts +103 -0
  429. package/dist/esm/models/Report.d.ts.map +1 -0
  430. package/dist/esm/models/Report.js +1 -0
  431. package/dist/esm/test-utils/constants.d.ts +56 -0
  432. package/dist/esm/test-utils/constants.d.ts.map +1 -0
  433. package/dist/esm/test-utils/constants.js +271 -0
  434. package/dist/esm/test-utils/generators.d.ts +4 -0
  435. package/dist/esm/test-utils/generators.d.ts.map +1 -0
  436. package/dist/esm/test-utils/generators.js +37 -0
  437. package/dist/esm/utils/aggregate.js +1 -1
  438. package/dist/esm/utils/astFilterProcessing.d.ts +36 -0
  439. package/dist/esm/utils/astFilterProcessing.d.ts.map +1 -0
  440. package/dist/esm/utils/astFilterProcessing.js +8084 -0
  441. package/dist/esm/utils/astFilterProcessing.uspec.d.ts +2 -0
  442. package/dist/esm/utils/astFilterProcessing.uspec.d.ts.map +1 -0
  443. package/dist/esm/utils/astFilterProcessing.uspec.js +2877 -0
  444. package/dist/esm/utils/astProcessing.d.ts.map +1 -1
  445. package/dist/esm/utils/astProcessing.js +4 -3
  446. package/dist/esm/utils/axisFormatter.js +0 -71
  447. package/dist/esm/utils/color.js +9 -87
  448. package/dist/esm/utils/columnProcessing.d.ts +2 -0
  449. package/dist/esm/utils/columnProcessing.d.ts.map +1 -1
  450. package/dist/esm/utils/columnProcessing.js +52 -0
  451. package/dist/esm/utils/columnProcessing.uspec.d.ts +2 -0
  452. package/dist/esm/utils/columnProcessing.uspec.d.ts.map +1 -0
  453. package/dist/esm/utils/columnProcessing.uspec.js +65 -0
  454. package/dist/esm/utils/csv.d.ts.map +1 -1
  455. package/dist/esm/utils/dashboard.d.ts +1 -1
  456. package/dist/esm/utils/dashboard.d.ts.map +1 -1
  457. package/dist/esm/utils/dashboard.js +6 -59
  458. package/dist/esm/utils/dataFetcher.d.ts.map +1 -1
  459. package/dist/esm/utils/dataFetcher.js +63 -1
  460. package/dist/esm/utils/dataProcessing.d.ts +10 -0
  461. package/dist/esm/utils/dataProcessing.d.ts.map +1 -0
  462. package/dist/esm/utils/dataProcessing.js +138 -0
  463. package/dist/esm/utils/dataProcessing.uspec.d.ts +2 -0
  464. package/dist/esm/utils/dataProcessing.uspec.d.ts.map +1 -0
  465. package/dist/esm/utils/dataProcessing.uspec.js +205 -0
  466. package/dist/esm/utils/dates.d.ts +2 -1
  467. package/dist/esm/utils/dates.d.ts.map +1 -1
  468. package/dist/esm/utils/dates.js +21 -0
  469. package/dist/esm/utils/error.d.ts +5 -0
  470. package/dist/esm/utils/error.d.ts.map +1 -0
  471. package/dist/esm/utils/error.js +8 -0
  472. package/dist/esm/utils/filterConstants.d.ts +34 -0
  473. package/dist/esm/utils/filterConstants.d.ts.map +1 -0
  474. package/dist/esm/utils/filterConstants.js +33 -0
  475. package/dist/esm/utils/filterProcessing.d.ts +7 -1
  476. package/dist/esm/utils/filterProcessing.d.ts.map +1 -1
  477. package/dist/esm/utils/filterProcessing.js +101 -16
  478. package/dist/esm/utils/filterProcessing.uspec.d.ts +2 -0
  479. package/dist/esm/utils/filterProcessing.uspec.d.ts.map +1 -0
  480. package/dist/esm/utils/filterProcessing.uspec.js +245 -0
  481. package/dist/esm/utils/logging.d.ts.map +1 -1
  482. package/dist/esm/utils/logging.js +1 -0
  483. package/dist/esm/utils/merge.js +0 -21
  484. package/dist/esm/utils/{monacoAutocomplete.d.ts → monacoConfig.d.ts} +3 -2
  485. package/dist/esm/utils/monacoConfig.d.ts.map +1 -0
  486. package/dist/esm/utils/monacoConfig.js +319 -0
  487. package/dist/esm/utils/paginationProcessing.d.ts +5 -0
  488. package/dist/esm/utils/paginationProcessing.d.ts.map +1 -0
  489. package/dist/esm/utils/paginationProcessing.js +25 -0
  490. package/dist/esm/utils/pivotConstructor.d.ts +2 -1
  491. package/dist/esm/utils/pivotConstructor.d.ts.map +1 -1
  492. package/dist/esm/utils/pivotConstructor.js +16 -1
  493. package/dist/esm/utils/pivotProcessing.d.ts.map +1 -1
  494. package/dist/esm/utils/pivotProcessing.js +12 -6
  495. package/dist/esm/utils/queryConstructor.d.ts.map +1 -1
  496. package/dist/esm/utils/queryConstructor.js +4 -3
  497. package/dist/esm/utils/queryConstructor.uspec.js +21 -21
  498. package/dist/esm/utils/report.d.ts +10 -0
  499. package/dist/esm/utils/report.d.ts.map +1 -0
  500. package/dist/esm/utils/report.ispec.d.ts +2 -0
  501. package/dist/esm/utils/report.ispec.d.ts.map +1 -0
  502. package/dist/esm/utils/report.ispec.js +46 -0
  503. package/dist/esm/utils/report.js +174 -0
  504. package/dist/esm/utils/report.uspec.d.ts +2 -0
  505. package/dist/esm/utils/report.uspec.d.ts.map +1 -0
  506. package/dist/esm/utils/report.uspec.js +66 -0
  507. package/dist/esm/utils/schema.d.ts.map +1 -1
  508. package/dist/esm/utils/schema.js +35 -6
  509. package/dist/esm/utils/styles.d.ts +1 -1
  510. package/dist/esm/utils/styles.d.ts.map +1 -1
  511. package/dist/esm/utils/tableProcessing.d.ts +22 -8
  512. package/dist/esm/utils/tableProcessing.d.ts.map +1 -1
  513. package/dist/esm/utils/tableProcessing.ispec.d.ts +2 -0
  514. package/dist/esm/utils/tableProcessing.ispec.d.ts.map +1 -0
  515. package/dist/esm/utils/tableProcessing.ispec.js +61 -0
  516. package/dist/esm/utils/tableProcessing.js +112 -33
  517. package/dist/esm/utils/textProcessing.js +3 -3
  518. package/dist/esm/utils/validation.d.ts +9 -0
  519. package/dist/esm/utils/validation.d.ts.map +1 -0
  520. package/dist/esm/utils/validation.js +20 -0
  521. package/dist/esm/utils/valueFormatter.d.ts.map +1 -1
  522. package/dist/esm/utils/valueFormatter.js +8 -4
  523. package/package.json +1 -1
  524. package/dist/cjs/utils/monacoAutocomplete.d.ts.map +0 -1
  525. package/dist/cjs/utils/monacoAutocomplete.js +0 -145
  526. package/dist/cjs/utils/queryConstructor.uspec.d.ts +0 -2
  527. package/dist/cjs/utils/queryConstructor.uspec.d.ts.map +0 -1
  528. package/dist/cjs/utils/queryConstructor.uspec.js +0 -225
  529. package/dist/esm/utils/monacoAutocomplete.d.ts.map +0 -1
  530. package/dist/esm/utils/monacoAutocomplete.js +0 -140
@@ -1,26 +1,24 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- /* eslint-disable no-unused-vars */
3
2
  import { useContext, useEffect, useRef, useState, } from 'react';
4
3
  import { DEFAULT_TAB_OPTIONS, MemoizedButton, MemoizedCheckbox, MemoizedDeleteButton, MemoizedHeader, MemoizedLabel, MemoizedSecondaryButton, MemoizedText, MemoizedPopover, QuillTabs, MemoizedModal, QuillChartBuilderInputRowContainer, QuillChartBuilderInputColumnContainer, MemoizedSubHeader, QuillErrorMessageComponent, QuillPivotRowContainer, QuillPivotColumnContainer, QuillColumnSearchEmptyState, QuillChartBuilderFormContainer, QuillLoadingComponent, QuillTableSQLEditorComponent, } from './components/UiComponents';
5
4
  import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, } from '@dnd-kit/core';
6
5
  import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, useSortable, } from '@dnd-kit/sortable';
7
6
  import { CSS as DND_CSS } from '@dnd-kit/utilities';
8
- import { getQuarter } from 'date-fns';
9
7
  import { ClientContext, CustomFieldContext, SchemaContext, ThemeContext, } from './Context';
10
- import { getTableAliases, getTableNames, isBoolColumnType, isDateishColumnType, isNumericColumnType, isTextColumnType, } from './components/ReportBuilder/ast';
8
+ import { extractColumnish, getTableAliases, getTableNames, isBoolColumnType, isDateishColumnType, isNumericColumnType, isTextColumnType, } from './components/ReportBuilder/ast';
11
9
  import { ChartBuilderWithModal, createInitialFormData } from './ChartBuilder';
12
10
  import { QuillTextInput } from './components/UiComponents';
13
- import { QuillSidebar, CustomContainer, QuillSelectColumn, QuillDraggableColumn, QuillSidebarHeading, QuillFilterPopover, QuillSortPopover, TagWrapper, EditPopover, AddFilterPopover, QuillLimitPopover, } from './components/ReportBuilder/ui';
11
+ import { QuillSidebar, CustomContainer, QuillSelectColumn, QuillDraggableColumn, QuillSidebarHeading, QuillFilterPopover, QuillSortPopover, QuillLimitPopover, FilterPopoverWrapper, } from './components/ReportBuilder/ui';
14
12
  import { generateCurrentPeriodPostgres, generateEqualsPostgres, generateLastNPeriodsPostgres, generatePreviousPeriodPostgres, } from './components/ReportBuilder/postgres';
15
- import { convertBigQuery, convertGroupBy, convertRemoveSimpleParentheses, convertStringComparison, convertWildcardColumns, } from './components/ReportBuilder/convert';
16
- import { deepCopy, formatDateComparisonNode, getDateFilterInfo, getPostgresBasicType, isColumnComparison, isDateTruncEquals, isInTheLastInterval, isNodeEmptyCollection, isTheCurrentInterval, isThePreviousInterval, isTopLevelBoolean, showNodeAsRow, tryConvertDateEquality, removeNonSelectedTableReferences, getCustomSentence, isEquals, } from './components/ReportBuilder/util';
13
+ import { convertBigQuery, convertGroupBy, convertRemoveSimpleParentheses, convertStringComparison, convertWildcardColumns, convertUnaryToBinary, } from './components/ReportBuilder/convert';
14
+ import { deepCopy, formatDateComparisonNode, getDateFilterInfo, isColumnComparison, isDateTruncEquals, isInTheLastInterval, isNodeEmptyCollection, isTheCurrentInterval, isThePreviousInterval, showNodeAsRow, removeNonSelectedTableReferences, isEquals, } from './components/ReportBuilder/util';
17
15
  import { getDefaultOperatorSubtrees, OPERATOR_GROUPS, } from './components/ReportBuilder/operators';
18
16
  import { hashCode } from './utils/crypto';
19
- import { DATE_FMT, DAY_OF_WEEK, defaultAST, defaultBoolComparison, defaultColumn, defaultEntry, defaultNumericComparison, defaultTable, defaultVariant, MONTH_OF_YEAR, } from './components/ReportBuilder/constants';
17
+ import { defaultAST, defaultBoolComparison, defaultColumn, defaultEntry, defaultNumericComparison, defaultTable, defaultVariant, } from './components/ReportBuilder/constants';
20
18
  import AddColumnModal from './components/ReportBuilder/AddColumnModal';
21
19
  import { AddSortPopover, SortSentence, } from './components/ReportBuilder/AddSortPopover';
22
20
  import { PivotModal, generatePivotTable, } from './internals/ReportBuilder/PivotModal';
23
- import { snakeAndCamelCaseToTitleCase, } from './utils/textProcessing';
21
+ import { snakeAndCamelCaseToTitleCase } from './utils/textProcessing';
24
22
  import { AddLimitPopover, LimitSentence, } from './components/ReportBuilder/AddLimitPopover';
25
23
  import { updateFirstChildWidth } from './utils/width';
26
24
  import { QuillSelectComponent } from './components/QuillSelect';
@@ -28,15 +26,21 @@ import { QuillCard } from './components/QuillCard';
28
26
  import { getData } from './utils/dataFetcher';
29
27
  import { DATE_FORMAT_TYPES, quillFormat } from './utils/valueFormatter';
30
28
  import { getPossiblePivotFieldOptions, pivotToSql, } from './utils/pivotProcessing';
31
- import { getUniqueValuesByColumns, getDateRangeByColumns, getCountsByColumns, } from './utils/tableProcessing';
29
+ import { getUniqueValuesByColumns, getDateRangeByColumns, getCountsByColumns, fetchTableByQuery, } from './utils/tableProcessing';
32
30
  import { useQuill } from './hooks/useQuill';
33
31
  import { getDataFromCloud } from './utils/dataFetcher';
34
32
  import { convertColumnInfoToColumnInternal, convertPostgresColumn, } from './utils/columnProcessing';
35
33
  import { getSelectFromAST, processApostrophe, processStarColumn, } from './utils/astProcessing';
36
34
  import PivotForm from './internals/ReportBuilder/PivotForm';
37
35
  import { getSchemaInfoWithCustomFields } from './utils/schema';
38
- import { MAX_COLUMN_ROWS_LIMIT } from './utils/constants';
39
36
  import { getDateBucketFromRange } from './utils/dates';
37
+ import FilterModal from './components/ReportBuilder/FilterModal';
38
+ import { filterToAst, filterTreeToAst, } from './utils/astFilterProcessing';
39
+ import useAstToFilterTree from './hooks/useAstToFilterTree';
40
+ import { filterSentence } from './utils/filterProcessing';
41
+ import { QuillMultiSelectComponentWithCombo } from './components/QuillMultiSelectWithCombo';
42
+ import { shouldFetchMore, DEFAULT_PAGINATION, shouldSortInMemory, } from './utils/paginationProcessing';
43
+ import { EMPTY_REPORT, formatRowsFromReport } from './utils/report';
40
44
  export const QUILL_SERVER = (typeof process !== 'undefined' && process?.env?.QUILL_SERVER_HOST) ||
41
45
  'https://quill-344421.uc.r.appspot.com';
42
46
  /**
@@ -70,7 +74,7 @@ export const QUILL_SERVER = (typeof process !== 'undefined' && process?.env?.QUI
70
74
  * ### Report Builder API
71
75
  * @see https://docs.quillsql.com/components/report-builder
72
76
  */
73
- export default function ReportBuilder({ initialTableName = '', onSubmitEditReport = (_) => void null, onSubmitCreateReport = (_) => void null, destinationDashboard = undefined, organizationName = '', ButtonComponent = MemoizedButton, SecondaryButtonComponent = MemoizedSecondaryButton, DeleteButtonComponent = MemoizedDeleteButton, ModalComponent = MemoizedModal, TextInputComponent = QuillTextInput, SelectComponent = QuillSelectComponent, TableComponent = QuillTableSQLEditorComponent, PopoverComponent = MemoizedPopover, TabsComponent = QuillTabs, CheckboxComponent = MemoizedCheckbox, 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, showChartBuilderTableFormatOptions = true, containerStyle, className, pivotRecommendationsEnabled = true, reportId, hideCopySQL = true, isChartBuilderHorizontalView = true, onClickChartElement, }) {
77
+ export default function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void null, onSubmitCreateReport = () => void null, destinationDashboard = undefined, organizationName = '', ButtonComponent = MemoizedButton, SecondaryButtonComponent = MemoizedSecondaryButton, DeleteButtonComponent = MemoizedDeleteButton, ModalComponent = MemoizedModal, TextInputComponent = QuillTextInput, SelectComponent = QuillSelectComponent, MultiSelectComponent = QuillMultiSelectComponentWithCombo, TableComponent = QuillTableSQLEditorComponent, PopoverComponent = MemoizedPopover, TabsComponent = QuillTabs, CheckboxComponent = MemoizedCheckbox, 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, showChartBuilderTableFormatOptions = true, containerStyle, className, pivotRecommendationsEnabled = true, reportId, hideCopySQL = true, isChartBuilderHorizontalView = true, onClickChartElement, }) {
74
78
  const { data: report } = useQuill(reportId || '');
75
79
  const [aiPrompt, setAiPrompt] = useState('');
76
80
  const [errorMessage, setErrorMessage] = useState('');
@@ -93,9 +97,8 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
93
97
  const [rows, setRows] = useState([]);
94
98
  const [formattedRows, setFormattedRows] = useState([]);
95
99
  const [columns, setColumns] = useState([]);
96
- const [tempReport, setTempReport] = useState({});
100
+ const [tempReport, setTempReport] = useState(EMPTY_REPORT);
97
101
  const [topLevelBinaryOperator, setTopLevelBinaryOperator] = useState('AND');
98
- const [editPopoverKey, setEditPopoverKey] = useState(null);
99
102
  const [uniqueValues, setUniqueValues] = useState({});
100
103
  const [pivot, setPivot] = useState(null);
101
104
  const [pivotData, setPivotData] = useState(null);
@@ -103,8 +106,8 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
103
106
  const [recommendedPivots, setRecommendedPivots] = useState([]);
104
107
  const [pivotPopUpTitle, setPivotPopUpTitle] = useState('Add pivot');
105
108
  const [showPivotPopover, setShowPivotPopover] = useState(false);
106
- const [isEdittingPivot, setIsEdittingPivot] = useState(false);
107
- const [initalChartLoad, setInitalChartLoad] = useState(false);
109
+ const [isEditingPivot, setIsEditingPivot] = useState(false);
110
+ const [initialChartLoad, setInitialChartLoad] = useState(false);
108
111
  const [askedAQuestion, setAskedAQuestion] = useState(false);
109
112
  const [selectedPivotIndex, setSelectedPivotIndex] = useState(-1);
110
113
  const [initialLoad, setInitialLoad] = useState(!!initialTableName || !!reportId);
@@ -120,11 +123,12 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
120
123
  const [pivotValueField, setPivotValueField] = useState(undefined);
121
124
  const [pivotAggregation, setPivotAggregation] = useState(undefined);
122
125
  const [dateRanges, setDateRanges] = useState(null);
123
- // eslint-disable-next-line no-unused-vars
124
- const [client, _setClient] = useContext(ClientContext);
126
+ const [client] = useContext(ClientContext);
125
127
  // JANK: This is temp and stupid
126
128
  const [overrideRecommendations, setOverrideRecommendations] = useState(true);
127
129
  const [customFields, setCustomFields] = useContext(CustomFieldContext);
130
+ const [fieldValuesMap, setFieldValuesMap] = useState({}); // Mapping of unique values per field, used in string filter 'in' and 'not in'
131
+ const filterTree = useAstToFilterTree(formData, client); // Stores the state of filters
128
132
  useEffect(() => {
129
133
  if (!client) {
130
134
  return;
@@ -140,6 +144,21 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
140
144
  updateFirstChildWidth(askAIContainerRef, setAskAIInputWidth, { gap: 12 });
141
145
  updateFirstChildWidth(askAILoadingContainerRef, setAskAILoadingContainerWidth, { gap: 12 });
142
146
  }, [dataDisplayed]);
147
+ // Whenever unique values changes, update the fieldValuesMap, used in FilterModals
148
+ useEffect(() => {
149
+ const tables = getTableNames(baseAst);
150
+ const table = tables.length === 1 ? tables[0] : initialTableName;
151
+ const newFieldValues = {};
152
+ if (uniqueValues[table]) {
153
+ for (const field of Object.keys(uniqueValues[table])) {
154
+ newFieldValues[field] = [];
155
+ for (const value of Object.keys(uniqueValues[table][field])) {
156
+ newFieldValues[field]?.push(value);
157
+ }
158
+ }
159
+ }
160
+ setFieldValuesMap(newFieldValues);
161
+ }, [uniqueValues]);
143
162
  useEffect(() => {
144
163
  // Since the TextInput component takes a required numeric width parameter,
145
164
  // we dynamically calculate the width of this component here.
@@ -178,7 +197,17 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
178
197
  if (tempDateRange) {
179
198
  dateBucket = getDateBucketFromRange(tempDateRange.dateRange);
180
199
  }
181
- const pivotedData = await generatePivotTable(pivot, rows, undefined, false, -1, undefined, dateBucket, tempReport, client, uniqueValues[currentTable]);
200
+ let distinctValuesForQuery = {};
201
+ if (pivot.columnField) {
202
+ distinctValuesForQuery = await getUniqueValuesByColumns([
203
+ {
204
+ field: pivot.columnField,
205
+ label: pivot.columnField,
206
+ format: 'string',
207
+ },
208
+ ], activeQuery, [], client, customFields);
209
+ }
210
+ const pivotedData = await generatePivotTable(pivot, rows, undefined, false, -1, undefined, dateBucket, tempReport, client, distinctValuesForQuery);
182
211
  setPivotData(pivotedData || []);
183
212
  const formattedRows = formatRows(pivotedData.rows, columns, true, newPivot.aggregationType);
184
213
  setPivot(newPivot);
@@ -218,7 +247,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
218
247
  setRows([]);
219
248
  setColumns([]);
220
249
  setTopLevelBinaryOperator('AND');
221
- setEditPopoverKey(null);
222
250
  setErrorMessage('');
223
251
  setFormattedRows([]);
224
252
  // setUniqueValues({});
@@ -246,8 +274,8 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
246
274
  if (pivot) {
247
275
  const formattedRows = copiedRows.map((row) => {
248
276
  const formattedRow = row;
249
- Object.keys(row).forEach((key, index) => {
250
- let column = columns.find((c) => c.field === key);
277
+ Object.keys(row).forEach((key) => {
278
+ const column = columns.find((c) => c.field === key);
251
279
  let format = 'string';
252
280
  if (!column) {
253
281
  format =
@@ -307,42 +335,20 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
307
335
  navigator.clipboard.writeText(query);
308
336
  setTimeout(() => setIsCopying(false), 800);
309
337
  };
310
- const copyToClipboard = (str) => {
311
- setIsCopying(true);
312
- navigator.clipboard.writeText(str);
313
- setTimeout(() => setIsCopying(false), 800);
314
- };
315
338
  const clearCheckboxes = () => {
316
339
  const checkboxes = uniqueValues;
317
340
  const newValues = {};
318
- for (let table of Object.keys(checkboxes)) {
341
+ for (const table of Object.keys(checkboxes)) {
319
342
  newValues[table] = {};
320
- for (let column of Object.keys(checkboxes[table])) {
343
+ for (const column of Object.keys(checkboxes[table])) {
321
344
  newValues[table][column] = {};
322
- for (let variant of Object.keys(checkboxes[table][column])) {
345
+ for (const variant of Object.keys(checkboxes[table][column])) {
323
346
  newValues[table][column][variant] = false;
324
347
  }
325
348
  }
326
349
  }
327
350
  setUniqueValues(newValues);
328
351
  };
329
- const setCheckboxes = (node) => {
330
- if (!['IN', 'NOT IN'].includes(node.operator))
331
- return;
332
- const selectedItems = node.right.value.flatMap((v) => v.args.value.map((x) => x.value.toLowerCase()));
333
- const checkboxes = uniqueValues;
334
- const newValues = {};
335
- for (let table of Object.keys(checkboxes)) {
336
- newValues[table] = {};
337
- for (let column of Object.keys(checkboxes[table])) {
338
- newValues[table][column] = {};
339
- for (let variant of Object.keys(checkboxes[table][column])) {
340
- newValues[table][column][variant] = selectedItems.includes(variant.toLowerCase());
341
- }
342
- }
343
- }
344
- setUniqueValues(newValues);
345
- };
346
352
  const fetchSqlQuery = async (ast, formData, fetchData = true) => {
347
353
  if (fetchData) {
348
354
  setLoading(true);
@@ -358,6 +364,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
358
364
  body: JSON.stringify({
359
365
  ast: { ...ast, where },
360
366
  publicKey: client.publicKey,
367
+ useNewNodeSql: true, // new flag
361
368
  }),
362
369
  });
363
370
  const data = await response.json();
@@ -365,6 +372,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
365
372
  if (fetchData) {
366
373
  fetchUponChange(ast, formData);
367
374
  }
375
+ return data.query;
368
376
  }
369
377
  catch (error) {
370
378
  setLoading(false);
@@ -489,83 +497,102 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
489
497
  };
490
498
  useEffect(() => {
491
499
  const loadChart = async () => {
492
- setInitalChartLoad(true);
500
+ setInitialChartLoad(true);
501
+ // @ts-ignore THIS PROCESS SHOULD BE UPDATED TO NOT USE USEQUILL
493
502
  if (!report || report.referencedTables.length !== 1) {
494
- setInitalChartLoad(false);
495
- return;
496
- }
497
- const tableName = report.referencedTables[0];
498
- if (!tableName) {
499
- return;
500
- }
501
- const resp = await getDataFromCloud(client, `astify`, {
502
- query: report.queryString,
503
- });
504
- if (resp.success === false) {
505
- setErrorMessage('Error: ' + resp.message);
503
+ setInitialChartLoad(false);
506
504
  return;
507
505
  }
508
- const ast = getSelectFromAST(resp.ast);
509
- let convertedAst = processStarColumn(ast, report.columns);
510
- processApostrophe(convertedAst, ['type', 'value']);
511
- convertedAst = convertBigQuery(convertedAst);
512
- let schemaInfo = schema.length !== 0 ? schema : await fetchSchema();
513
- let newAst, groupByPivot;
514
- ({ ast: newAst, pivot: groupByPivot } = convertGroupBy(convertedAst,
515
- // @ts-ignore
516
- report.pivot, schemaInfo));
517
- if (convertedAst.where) {
518
- setFormData(deepCopy(convertedAst.where));
519
- }
520
- setActiveQuery(report.queryString);
521
- newAst = groupByPivot ? newAst : convertedAst;
522
- setBaseAst(newAst);
523
- const initialRows = await fetchUponChange(newAst, undefined);
524
- const tableInfo = schemaInfo.find((table) => table.name === tableName);
525
- let newUniqueValues = undefined;
526
- let dateRangesTemp = undefined;
527
- if (tableName) {
528
- newUniqueValues = await getUniqueStringValues(tableInfo.columns, tableName);
529
- setUniqueValues(newUniqueValues);
530
- dateRangesTemp = await getDateRanges(tableInfo.columns, tableName);
531
- setDateRanges(dateRangesTemp);
532
- }
533
- if (groupByPivot) {
534
- // @ts-ignore
535
- setPivotRowField(groupByPivot.rowField);
536
- // @ts-ignore
537
- setPivotAggregation(groupByPivot.aggregationType);
538
- // @ts-ignore
539
- setPivotColumnField(groupByPivot.columnField);
540
- // @ts-ignore
541
- setPivotValueField(groupByPivot.valueField);
542
- setPivot(groupByPivot);
543
- let dateBucket = undefined;
544
- const tempDateRange = dateRangesTemp &&
545
- groupByPivot.rowField &&
546
- dateRangesTemp[groupByPivot.rowField];
547
- if (tempDateRange) {
548
- dateBucket = getDateBucketFromRange(tempDateRange.dateRange);
549
- }
550
- const pivotedData = await generatePivotTable(
551
- // @ts-ignore
552
- groupByPivot, initialRows, tempDateRange, false, -1, undefined, dateBucket, report, client, newUniqueValues[tableName]);
553
- setPivotData(pivotedData || []);
554
- const formattedRows = formatRows(pivotedData.rows, report.columns, true,
506
+ try {
507
+ // @ts-ignore THIS PROCESS SHOULD BE UPDATED TO NOT USE USEQUILL
508
+ const tableName = report.referencedTables[0];
509
+ if (!tableName) {
510
+ return;
511
+ }
512
+ const resp = await getDataFromCloud(client, `astify`, {
513
+ // @ts-ignore THIS PROCESS SHOULD BE UPDATED TO NOT USE USEQUILL
514
+ query: report.queryString,
515
+ useNewNodeSql: true,
516
+ });
517
+ if (resp.success === false) {
518
+ setErrorMessage(resp.message);
519
+ return;
520
+ }
521
+ const ast = getSelectFromAST(resp.ast);
522
+ let convertedAst = processStarColumn(ast, report.columns);
523
+ processApostrophe(convertedAst, ['type', 'value']);
524
+ convertedAst = convertBigQuery(convertedAst);
525
+ const schemaInfo = schema.length !== 0 ? schema : await fetchSchema();
526
+ let newAst;
527
+ let groupByPivot = {};
528
+ ({ ast: newAst, pivot: groupByPivot } = convertGroupBy(convertedAst,
555
529
  // @ts-ignore
556
- groupByPivot.aggregationType);
557
- setFormattedRows(formattedRows);
530
+ report.pivot, schemaInfo));
531
+ if (convertedAst.where) {
532
+ setFormData(deepCopy(convertedAst.where));
533
+ }
534
+ // @ts-ignore THIS PROCESS SHOULD BE UPDATED TO NOT USE USEQUILL
535
+ setActiveQuery(report.queryString);
536
+ newAst = groupByPivot ? newAst : convertedAst;
537
+ const initialRows = await fetchUponChange(newAst, undefined);
538
+ if (initialRows.error) {
539
+ setBaseAst(null);
540
+ setErrorMessage(initialRows.message);
541
+ setInitialChartLoad(false);
542
+ return;
543
+ }
544
+ setBaseAst(newAst);
545
+ const tableInfo = schemaInfo.find((table) => table.name === tableName);
546
+ let newUniqueValues = undefined;
547
+ let dateRangesTemp = undefined;
548
+ if (tableName) {
549
+ newUniqueValues = await getUniqueStringValues(tableInfo.columns, tableName);
550
+ setUniqueValues(newUniqueValues);
551
+ dateRangesTemp = await getDateRanges(tableInfo.columns, tableName);
552
+ setDateRanges(dateRangesTemp);
553
+ }
554
+ if (groupByPivot) {
555
+ // @ts-ignore
556
+ setPivotRowField(groupByPivot.rowField);
557
+ // @ts-ignore
558
+ setPivotAggregation(groupByPivot.aggregationType);
559
+ // @ts-ignore
560
+ setPivotColumnField(groupByPivot.columnField);
561
+ // @ts-ignore
562
+ setPivotValueField(groupByPivot.valueField);
563
+ setPivot(groupByPivot);
564
+ let dateBucket = undefined;
565
+ const tempDateRange = dateRangesTemp &&
566
+ groupByPivot.rowField &&
567
+ dateRangesTemp[groupByPivot.rowField];
568
+ if (tempDateRange) {
569
+ dateBucket = getDateBucketFromRange(tempDateRange.dateRange);
570
+ }
571
+ const pivotedData = await generatePivotTable(
572
+ // @ts-ignore
573
+ groupByPivot, initialRows, tempDateRange, false, -1, undefined, dateBucket, report, client, newUniqueValues[tableName]);
574
+ setPivotData(pivotedData || []);
575
+ const formattedRows = formatRows(pivotedData.rows, report.columns, true,
576
+ // @ts-ignore
577
+ groupByPivot.aggregationType);
578
+ setFormattedRows(formattedRows);
579
+ }
580
+ else {
581
+ const formattedRows = formatRows(report.rows, report.columns);
582
+ setFormattedRows(formattedRows);
583
+ }
584
+ setCurrentTable(tableName);
558
585
  }
559
- else {
560
- const formattedRows = formatRows(report.rows, report.columns);
561
- setFormattedRows(formattedRows);
586
+ catch (error) {
587
+ console.error(error);
588
+ setErrorMessage('Error loading report');
562
589
  }
563
- setCurrentTable(tableName);
564
590
  // This handles a flashing issue
565
591
  setTimeout(() => {
566
- setInitalChartLoad(false);
592
+ setInitialChartLoad(false);
567
593
  }, 500);
568
594
  };
595
+ // @ts-ignore THIS PROCESS SHOULD BE UPDATED TO NOT USE USEQUILL
569
596
  if (report && report.referencedTables.length === 1) {
570
597
  loadChart();
571
598
  }
@@ -891,10 +918,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
891
918
  isReplaceSubtree: true,
892
919
  });
893
920
  };
894
- // Function to handle the deletion of expressions
895
- const handleDelete = (key) => {
896
- updateFormData([{ path: key, value: null }], { isDeletion: true });
897
- };
898
921
  // Function to handle the insertion of expressions
899
922
  const handleInsertion = (value, op = 'OR', isCondition = undefined) => {
900
923
  updateFormData([{ path: '', value }], {
@@ -959,84 +982,60 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
959
982
  };
960
983
  const [previousPage, setPreviousPage] = useState(0);
961
984
  const [currentProcessing, setCurrentProcessing] = useState({
962
- page: { currentPage: 0, rowsPerPage: 20 },
985
+ page: DEFAULT_PAGINATION,
963
986
  });
964
987
  const [numberOfRows, setNumberOfRows] = useState(0);
965
988
  const [tableLoading, setTableLoading] = useState(false);
966
989
  const onPageChange = (page) => {
967
- if (pivot) {
968
- return;
990
+ if (currentProcessing.page &&
991
+ shouldFetchMore(DEFAULT_PAGINATION, page, previousPage)) {
992
+ const newPagination = { ...currentProcessing.page, page };
993
+ const updatedProcessing = { ...currentProcessing, page: newPagination };
994
+ setCurrentProcessing(updatedProcessing);
995
+ handleRunQuery(updatedProcessing);
969
996
  }
970
- if ((previousPage < page.currentPage &&
971
- (page.currentPage * page.rowsPerPage) % MAX_COLUMN_ROWS_LIMIT === 0) ||
972
- (previousPage > page.currentPage &&
973
- (previousPage * page.rowsPerPage) % MAX_COLUMN_ROWS_LIMIT === 0)) {
974
- handleRunQuery({ ...currentProcessing, page });
997
+ if (page > previousPage) {
998
+ setPreviousPage(page);
975
999
  }
976
- setPreviousPage(page.currentPage);
977
1000
  };
978
1001
  const onSortChange = (sort) => {
979
- if (pivot) {
1002
+ if (shouldSortInMemory(DEFAULT_PAGINATION, numberOfRows, !!pivot)) {
980
1003
  return;
981
1004
  }
982
- handleRunQuery({ sort, page: { currentPage: 0, rowsPerPage: 20 } });
1005
+ const updatedProcessing = { page: DEFAULT_PAGINATION, sort };
1006
+ handleRunQuery(updatedProcessing, true);
1007
+ setCurrentProcessing(updatedProcessing);
983
1008
  setPreviousPage(0);
984
1009
  };
985
- const handleRunQuery = async (processing) => {
1010
+ const handleRunQuery = async (processing, resetRows = false) => {
986
1011
  try {
987
1012
  setErrorMessage('');
988
1013
  setTableLoading(true);
989
- const hostedBody = {
990
- metadata: {
991
- query: activeQuery,
992
- task: 'query',
993
- orgId: client.customerId || '*',
994
- clientId: client.publicKey,
995
- databaseType: client?.databaseType,
996
- getCustomFields: !client.customerId || client.customerId === '*' ? false : true,
997
- customFieldsByTable: customFields,
998
- additionalProcessing: processing,
999
- useUpdatedDataGathering: true,
1000
- },
1001
- };
1002
- const cloudBody = { activeQuery };
1003
- const resp = await getData(client, 'dashquery', 'same-origin', hostedBody, cloudBody);
1004
- if (resp && resp.errorMessage) {
1005
- setTableLoading(false);
1006
- setErrorMessage('Failed to run SQL query: ' + resp.errorMessage);
1007
- setRows([]);
1008
- setColumns([]);
1009
- return;
1014
+ const tableInfo = await fetchTableByQuery(activeQuery, client, processing, customFields);
1015
+ if (tableInfo.error) {
1016
+ throw new Error(tableInfo.error);
1010
1017
  }
1011
- if (resp.rowCount) {
1012
- setNumberOfRows(resp.rowCount);
1018
+ else if (tableInfo.rows.length === 0) {
1019
+ throw new Error('No data found');
1020
+ }
1021
+ if (tableInfo.rowCount) {
1022
+ setNumberOfRows(tableInfo.rowCount);
1013
1023
  }
1014
- setErrorMessage('');
1015
1024
  setCurrentProcessing(processing);
1016
- if (resp.rows.length === 0) {
1017
- setErrorMessage('No data found');
1025
+ let tempRows = [...rows, ...tableInfo.rows];
1026
+ if (resetRows) {
1027
+ tempRows = tableInfo.rows;
1018
1028
  }
1019
- const temp_rows = resp.rows && resp.rows.length ? resp.rows : [];
1020
- const processedFields = resp.fields.map((elem) => convertPostgresColumn(elem));
1021
- setRows(temp_rows);
1022
- // setNumberOfRows(resp.compareRows[0]?.count || temp_rows.length);
1023
- setFormattedRows(temp_rows.map((row) => {
1024
- return processedFields.reduce((formattedRow, column) => {
1025
- // Apply the format function to each field in the row
1026
- const formattedValue = quillFormat({
1027
- value: row[column.field],
1028
- format: column.format,
1029
- });
1030
- formattedRow[column.field] = formattedValue;
1031
- return formattedRow;
1032
- }, {});
1033
- }));
1034
- setColumns(processedFields);
1029
+ setRows(tempRows);
1030
+ setFormattedRows(formatRowsFromReport({ rows: tempRows, columns: tableInfo.columns }));
1031
+ setColumns(tableInfo.columns);
1035
1032
  setTableLoading(false);
1036
1033
  }
1037
1034
  catch (e) {
1038
1035
  setTableLoading(false);
1039
- console.log('ERROR: ', e);
1036
+ setErrorMessage('Failed to run SQL query: ' + e.message);
1037
+ setRows([]);
1038
+ setColumns([]);
1040
1039
  return;
1041
1040
  }
1042
1041
  };
@@ -1055,10 +1054,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1055
1054
  case 'binary_expr':
1056
1055
  if (dateComparisonPartialMatch ||
1057
1056
  (isDateTruncEquals(node) && client.databaseType !== 'BigQuery')) {
1058
- const { dateColumn,
1059
- // see onChange callback handleChange
1060
- // eslint-disable-next-line no-unused-vars
1061
- dateColumnPath, dateFilterType, intervalCount, intervalType, intervalPaths, } = getDateFilterInfo(node);
1057
+ const { dateColumn, dateFilterType, intervalCount, intervalType, intervalPaths, } = getDateFilterInfo(node);
1062
1058
  const isPlural = intervalCount !== 1 && dateFilterType !== 'in the current'
1063
1059
  ? 's'
1064
1060
  : '';
@@ -1206,7 +1202,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1206
1202
  } }))] }));
1207
1203
  }
1208
1204
  else if (isInTheLastInterval(node, client.databaseType)) {
1209
- const { dateColumn, dateFilterType, intervalCount, intervalType } = getDateFilterInfo(node);
1205
+ const { dateColumn } = getDateFilterInfo(node);
1210
1206
  const options = getAllPossibleColumns().map((column) => ({
1211
1207
  label: snakeAndCamelCaseToTitleCase(column.displayName),
1212
1208
  value: column.name,
@@ -1267,7 +1263,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1267
1263
  ], width: 200 }) })] }));
1268
1264
  }
1269
1265
  else if (isTheCurrentInterval(node, client.databaseType)) {
1270
- const { dateFilterType } = getDateFilterInfo(node);
1271
1266
  const options = getAllPossibleColumns().map((column) => ({
1272
1267
  label: snakeAndCamelCaseToTitleCase(column.displayName),
1273
1268
  value: column.name,
@@ -1326,7 +1321,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1326
1321
  { label: `week`, value: 'WEEK' },
1327
1322
  ], width: 200 })] }));
1328
1323
  }
1329
- else if (isThePreviousInterval(node, client.databaseType)) {
1324
+ else if (isThePreviousInterval(node)) {
1330
1325
  const options = getAllPossibleColumns().map((column) => ({
1331
1326
  label: snakeAndCamelCaseToTitleCase(column.displayName),
1332
1327
  value: column.name,
@@ -1473,7 +1468,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1473
1468
  .find((tableInfo) => tableInfo.name === table)
1474
1469
  ?.columns.find((col) => col.name === leftChildValue);
1475
1470
  const columnType = column?.fieldType;
1476
- let operatorOptions = [
1471
+ const operatorOptions = [
1477
1472
  ...(isNumericColumnType(columnType)
1478
1473
  ? [
1479
1474
  { label: 'equal to', value: '=' },
@@ -1714,112 +1709,180 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1714
1709
  }
1715
1710
  return validPivot;
1716
1711
  };
1717
- const renderSentence = (formData, node, keyPrefix = '',
1718
- // @depreciated TODO: remove next update
1719
- // eslint-disable-next-line no-unused-vars
1720
- isTopLevel = false,
1721
- // @depreciated TODO: remove next update
1722
- // eslint-disable-next-line no-unused-vars
1723
- isTopLevelAnd = false, isParentRow = false) => {
1724
- const uniqueSentence = getCustomSentence(node, client.databaseType);
1725
- let dateComparisonPartialMatch = null;
1726
- let dateEqualityPartialMatch = null;
1727
- if (client.databaseType !== 'BigQuery') {
1728
- dateComparisonPartialMatch = formatDateComparisonNode(node);
1729
- dateEqualityPartialMatch = tryConvertDateEquality(node, client.databaseType);
1712
+ /**
1713
+ * @param filterTree
1714
+ * Returns a list of filters to be displayed
1715
+ * Replaces the functionality of renderNodes in the context of filters
1716
+ */
1717
+ const renderFilters = (filterTree) => {
1718
+ let tree = filterTree;
1719
+ let filterStack = [];
1720
+ /**
1721
+ * Function that takes in a FilterTree and flattens it into an array using in order traversal
1722
+ */
1723
+ function traverseTree(node) {
1724
+ if (!node) {
1725
+ return;
1726
+ }
1727
+ if (node.leaf) {
1728
+ filterStack.push(node);
1729
+ }
1730
+ else {
1731
+ traverseTree(node.leftNode);
1732
+ filterStack.push(node);
1733
+ traverseTree(node.rightNode);
1734
+ }
1730
1735
  }
1731
- const isRow = !isTopLevelBoolean(node);
1732
- const isCard = isRow && !isParentRow;
1733
- const OPS = {
1734
- AND: 'and',
1735
- OR: 'or',
1736
- LIKE: 'is exactly',
1737
- BETWEEN: 'is between',
1738
- IN: 'is',
1739
- 'NOT IN': 'is not',
1740
- 'NOT LIKE': 'is not exactly',
1741
- '!=': 'is not exactly',
1742
- '=': 'is',
1743
- '<': 'is less than',
1744
- '>': 'is greater than',
1745
- '<=': 'is less than or equal to',
1746
- '>=': 'is greater than or equal to',
1747
- '<>': 'is not',
1748
- '-': 'minus',
1749
- 'IS NOT': 'is not',
1750
- IS: 'is',
1751
- };
1752
- switch (node.type) {
1753
- case 'binary_expr':
1754
- return (_jsx(TagWrapper, { keyPrefix: keyPrefix, formData: formData, activeEditItem: activeEditItem, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setCheckboxes: setCheckboxes, handleReplaceSubtree: handleReplaceSubtree, FilterPopover: FilterPopoverComponent, setActivePath: setActivePath, setOpenPopover: setOpenPopover, setIsPending: setIsPending, clearCheckboxes: clearCheckboxes, handleDelete: handleDelete, editPopoverKey: editPopoverKey, isCard: isCard, isRow: isRow, getByKey: getByKey, EditPopover: EditPopover, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent, renderNode: renderNode, children: dateComparisonPartialMatch ??
1755
- dateEqualityPartialMatch ??
1756
- uniqueSentence ?? (_jsxs(_Fragment, { children: [node.left &&
1757
- renderSentence(formData, node.left, keyPrefix + 'left.', false, false, isRow), isRow ? (' ' + OPS[node.operator] + ' ') : isTopLevel || topLevelBinaryOperator === 'OR' ? (_jsx(TopLevelBooleanSwitch, { node: node, keyPrefix: keyPrefix, handleOperatorChange: handleOperatorChange, Select: SelectComponent })) : null, node.right &&
1758
- renderSentence(formData, node.right, keyPrefix + 'right.', false, false, isRow)] })) }));
1759
- case 'column_ref':
1760
- return snakeAndCamelCaseToTitleCase(node.column);
1761
- case 'expr_list':
1762
- if (node.value.length === 1) {
1763
- const subQuery = renderSentence(formData, node.value[0]);
1764
- if (subQuery) {
1765
- return `${subQuery}`;
1766
- }
1767
- return '()';
1768
- }
1769
- return `${node.value
1770
- .map((elem) => renderSentence(formData, elem))
1771
- .join(', ')}`;
1772
- case 'single_quote_string':
1773
- return node.value.replaceAll('%', '');
1774
- case 'double_quote_string':
1775
- case 'number':
1776
- return node.value;
1777
- case 'null':
1778
- return 'null';
1779
- case 'bool':
1780
- return node.value.toString();
1781
- case 'interval':
1782
- if (node.unit) {
1783
- // eg. `INTERVAL '90' DAY` -> "90 days"
1784
- return `${node.expr.value} ${node.unit}s`;
1785
- }
1786
- return node.expr.value;
1787
- case 'function':
1788
- if (node.name.toLowerCase() === 'lower' ||
1789
- node.name.toLowerCase() === 'upper') {
1790
- // how many transactions were above 20 and not fuel or made in the last 90 days (hint: use lower)
1791
- if (node.args.value.length < 1)
1792
- return null;
1793
- if (node.args.value[0].value) {
1794
- if (node.args.value[0].type === 'single_quote_string') {
1795
- return node.args.value[0].value.replaceAll('%', '');
1796
- }
1797
- return snakeAndCamelCaseToTitleCase(node.args.value[0].value.replaceAll('%', ''));
1798
- }
1799
- if (node.args.value[0].column)
1800
- return snakeAndCamelCaseToTitleCase(node.args.value[0].column.replaceAll('%', ''));
1736
+ /**
1737
+ * Given an array of Filters (presumed to be in in-order state), generate
1738
+ * the corresponding Filter tree. Essentially the reverse of what traverseTree does
1739
+ */
1740
+ function filterStackToFilterTree(stack) {
1741
+ function buildTree(i) {
1742
+ const newNode = {
1743
+ leaf: false,
1744
+ operator: null,
1745
+ leftNode: null,
1746
+ rightNode: null,
1747
+ };
1748
+ if (i >= stack.length) {
1801
1749
  return null;
1802
1750
  }
1803
- if (node.name.toLowerCase() === 'current_date' ||
1804
- node.name.toLowerCase() === 'now') {
1805
- return 'today';
1806
- }
1807
- if (node.name.toLowerCase() === 'date_trunc') {
1808
- // eg. date_trunc('month', now())
1809
- if (!node.args)
1810
- return null;
1811
- if (node.args.type !== 'expr_list')
1812
- return null;
1813
- if (node.args.value?.length !== 2)
1814
- return null;
1815
- const interval = renderSentence(formData, node.args.value[0]);
1816
- const timestamp = renderSentence(formData, node.args.value[1]);
1817
- return `start of the ${interval} of ${timestamp}`;
1751
+ else if (stack[i].leaf) {
1752
+ if (i < stack.length - 1) {
1753
+ // more nodes later
1754
+ newNode.operator = stack[i + 1].operator;
1755
+ newNode.leftNode = {
1756
+ leaf: true,
1757
+ leftNode: null,
1758
+ rightNode: null,
1759
+ operator: null,
1760
+ value: stack[i].value,
1761
+ };
1762
+ newNode.rightNode = buildTree(i + 2);
1763
+ }
1764
+ else {
1765
+ newNode.leaf = true;
1766
+ newNode.value = stack[i].value;
1767
+ }
1818
1768
  }
1819
- return null;
1820
- default:
1821
- return null;
1769
+ return newNode;
1770
+ }
1771
+ return buildTree(0);
1822
1772
  }
1773
+ traverseTree(tree);
1774
+ // Remove null (invalid) filters from filter stack
1775
+ filterStack = filterStack.filter((filter) => {
1776
+ return ((!filter.leaf &&
1777
+ filter.rightNode &&
1778
+ (!filter.rightNode.leaf || filter.rightNode.value)) ||
1779
+ (filter.leaf && filter.value));
1780
+ });
1781
+ // Render filterStack
1782
+ return (_jsx("div", { style: {
1783
+ display: 'flex',
1784
+ flexDirection: 'column',
1785
+ }, children: filterStack.map((item, index) => {
1786
+ if (!item.leaf &&
1787
+ (item.operator === 'and' || item.operator === 'or')) {
1788
+ return (_jsx("div", { style: {
1789
+ width: 'fit-content',
1790
+ marginBottom: '8px',
1791
+ marginTop: '8px',
1792
+ }, children: _jsx(TabsComponent, { value: item.operator.toUpperCase(), options: DEFAULT_TAB_OPTIONS, onChange: () => {
1793
+ if (item.operator === 'and') {
1794
+ item.operator = 'or';
1795
+ }
1796
+ else {
1797
+ item.operator = 'and';
1798
+ }
1799
+ let newFormData = null;
1800
+ if (tree) {
1801
+ newFormData = filterTreeToAst(tree, client.databaseType.toLowerCase());
1802
+ }
1803
+ const newAst = deepCopy({
1804
+ ...defaultAST,
1805
+ ...baseAst,
1806
+ ...(!baseAst?.columns && {
1807
+ columns: getAllPossibleColumns().map((c) => {
1808
+ const newColumn = deepCopy(defaultColumn);
1809
+ newColumn.expr.column = c.name;
1810
+ return newColumn;
1811
+ }),
1812
+ }),
1813
+ ...(!baseAst?.from && {
1814
+ from: [{ ...defaultTable, table: initialTableName }],
1815
+ }),
1816
+ where: newFormData,
1817
+ });
1818
+ setBaseAst(newAst);
1819
+ setFormData(newFormData);
1820
+ fetchSqlQuery(newAst, newFormData);
1821
+ } }) }, index));
1822
+ }
1823
+ else {
1824
+ return (_jsx(FilterPopoverWrapper, { schema: schema.find((s) => s.name === currentTable || s.displayName === currentTable) ?? schema[0], filter: item.value, filterLabel: item.value ? filterSentence(item.value) : '', index: index, FilterTagComponent: FilterPopoverComponent, FilterModal: FilterModal, fieldValuesMap: fieldValuesMap, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, MultiSelectComponent: MultiSelectComponent, handleFilterSave: (filter) => {
1825
+ item.value = filter;
1826
+ let newFormData = null;
1827
+ if (tree) {
1828
+ newFormData = filterTreeToAst(tree, client.databaseType.toLowerCase());
1829
+ }
1830
+ const newAst = deepCopy({
1831
+ ...defaultAST,
1832
+ ...baseAst,
1833
+ ...(!baseAst?.columns && {
1834
+ columns: getAllPossibleColumns().map((c) => {
1835
+ const newColumn = deepCopy(defaultColumn);
1836
+ newColumn.expr.column = c.name;
1837
+ return newColumn;
1838
+ }),
1839
+ }),
1840
+ ...(!baseAst?.from && {
1841
+ from: [{ ...defaultTable, table: initialTableName }],
1842
+ }),
1843
+ where: newFormData,
1844
+ });
1845
+ setBaseAst(newAst);
1846
+ setFormData(newFormData);
1847
+ fetchSqlQuery(newAst, newFormData);
1848
+ }, handleFilterDelete: (i) => {
1849
+ if (i > 0) {
1850
+ filterStack.splice(i - 1, 2);
1851
+ }
1852
+ else {
1853
+ if (filterStack.length > 1) {
1854
+ filterStack.splice(i, 2);
1855
+ }
1856
+ else {
1857
+ filterStack.splice(i, 1);
1858
+ }
1859
+ }
1860
+ tree = filterStackToFilterTree(filterStack);
1861
+ let newFormData = null;
1862
+ if (tree) {
1863
+ newFormData = filterTreeToAst(tree, client.databaseType.toLowerCase());
1864
+ }
1865
+ const newAst = deepCopy({
1866
+ ...defaultAST,
1867
+ ...baseAst,
1868
+ ...(!baseAst?.columns && {
1869
+ columns: getAllPossibleColumns().map((c) => {
1870
+ const newColumn = deepCopy(defaultColumn);
1871
+ newColumn.expr.column = c.name;
1872
+ return newColumn;
1873
+ }),
1874
+ }),
1875
+ ...(!baseAst?.from && {
1876
+ from: [{ ...defaultTable, table: initialTableName }],
1877
+ }),
1878
+ where: newFormData,
1879
+ });
1880
+ setBaseAst(newAst);
1881
+ setFormData(newFormData);
1882
+ fetchSqlQuery(newAst, newFormData);
1883
+ } }, 'filter' + index));
1884
+ }
1885
+ }) }));
1823
1886
  };
1824
1887
  const getAllPossibleColumns = () => {
1825
1888
  if (!baseAst || !baseAst.from) {
@@ -1861,7 +1924,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1861
1924
  if (selectedColumns.length < 1)
1862
1925
  return false;
1863
1926
  const allColumns = orderedColumnNames.filter((row) => {
1864
- const [table, _] = row.split('.');
1927
+ const [table] = row.split('.');
1865
1928
  const selectedTable = selectedColumns[0].split('.')[0];
1866
1929
  return selectedTable === table;
1867
1930
  });
@@ -1907,23 +1970,16 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1907
1970
  customFields,
1908
1971
  additionalProcessing: { page: { currentPage: 0, rowsPerPage: 20 } },
1909
1972
  useUpdatedDataGathering: true,
1973
+ useNewNodeSql: true, // new flag
1910
1974
  },
1911
1975
  };
1912
- const cloudBody = {};
1913
- const data2 = await getData(client, 'dashquery', 'same-origin', hostedBody, cloudBody);
1914
- if (data2.success === false) {
1915
- throw new Error(data2.errorMessage);
1916
- }
1917
- rows = data2.rows;
1918
- if (data2.rowCount) {
1919
- setNumberOfRows(data2.rowCount);
1920
- }
1921
1976
  const tables = getTableNames(baseAst);
1922
1977
  const table = tables.length >= 1 ? tables[0] : initialTableName;
1923
1978
  let newUniqueValues = uniqueValues;
1924
1979
  let dateRangesTemp = dateRanges;
1925
- let curReport = undefined;
1926
- if (table !== currentTable) {
1980
+ let curReport = tempReport;
1981
+ if ((newUniqueValues && Object.keys(newUniqueValues).length === 0) ||
1982
+ table !== currentTable) {
1927
1983
  const tableInfo = schema.find((tableInfo) => tableInfo.name === table);
1928
1984
  if (tableInfo) {
1929
1985
  newUniqueValues = await getUniqueStringValues(tableInfo.columns, table);
@@ -1935,6 +1991,15 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1935
1991
  }
1936
1992
  setCurrentTable(table);
1937
1993
  }
1994
+ const cloudBody = {};
1995
+ const data2 = await getData(client, 'dashquery', 'same-origin', hostedBody, cloudBody);
1996
+ if (data2.success === false) {
1997
+ throw new Error(data2.errorMessage);
1998
+ }
1999
+ rows = data2.rows;
2000
+ if (data2.rowCount) {
2001
+ setNumberOfRows(data2.rowCount);
2002
+ }
1938
2003
  if (data2.rows && data2.rows.length) {
1939
2004
  if (pivot) {
1940
2005
  // check if any of the pivot fields aren't in the data2.fields array
@@ -1964,13 +2029,14 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1964
2029
  setFormattedRows(formattedRows);
1965
2030
  return;
1966
2031
  }
2032
+ curReport = {
2033
+ ...formData,
2034
+ itemQuery: data2.itemQuery,
2035
+ rowCount: data2.rowCount,
2036
+ filtersApplied: [],
2037
+ rows: data2.rows,
2038
+ };
1967
2039
  // Do all of this to make sure we have the right unique columns when applying a pivot
1968
- let uniqueFormatted = {};
1969
- const uniqueRecords = Array.from(new Set(data2.rows.map((row) => row[pivot.columnField]))).reduce((acc, curr) => {
1970
- acc[curr] = false;
1971
- return acc;
1972
- }, {});
1973
- uniqueFormatted[pivot.columnField] = uniqueRecords;
1974
2040
  let dateBucket = undefined;
1975
2041
  const tempDateRange = dateRangesTemp &&
1976
2042
  pivot.rowField &&
@@ -1978,9 +2044,20 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
1978
2044
  if (tempDateRange) {
1979
2045
  dateBucket = getDateBucketFromRange(tempDateRange.dateRange);
1980
2046
  }
2047
+ let distinctValuesForQuery = {};
2048
+ if (pivot.columnField) {
2049
+ const sqlQuery = await fetchSqlQuery({ ...baseAst, where: curFormData }, null, false);
2050
+ distinctValuesForQuery = await getUniqueValuesByColumns([
2051
+ {
2052
+ field: pivot.columnField,
2053
+ label: pivot.columnField,
2054
+ format: 'string',
2055
+ },
2056
+ ], sqlQuery, [], client, customFields);
2057
+ }
1981
2058
  const pivotedData = await generatePivotTable(
1982
2059
  // @ts-ignore
1983
- pivot, data2.rows, undefined, false, -1, undefined, dateBucket, curReport, client, uniqueFormatted[pivot.columnField]);
2060
+ pivot, data2.rows, undefined, false, -1, undefined, dateBucket, curReport, client, distinctValuesForQuery ? distinctValuesForQuery : undefined);
1984
2061
  console.info(`%c[Pivot]: ${JSON.stringify(pivot)}`, 'color: dimgray');
1985
2062
  const processedFields = data2.fields.map((elem) => convertPostgresColumn(elem));
1986
2063
  setPivotData(pivotedData);
@@ -2042,105 +2119,22 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2042
2119
  setFormattedRows([]);
2043
2120
  setPivotData(null);
2044
2121
  }
2122
+ setLoading(false);
2123
+ setDataDisplayed(true);
2124
+ return rows;
2045
2125
  }
2046
2126
  catch (e) {
2047
- console.error(e);
2048
2127
  setErrorMessage(e.message);
2049
- }
2050
- finally {
2051
2128
  setLoading(false);
2052
2129
  setDataDisplayed(true);
2053
- return rows;
2130
+ setRows([]);
2131
+ setColumns([]);
2132
+ setFormattedRows([]);
2133
+ setPivotData(null);
2134
+ return { error: true, message: e.message };
2054
2135
  }
2055
2136
  }
2056
2137
  };
2057
- // Convert an array of columns to a map where the name is the
2058
- // key and the value is the column node.
2059
- const columnArrayToMap = (columns) => {
2060
- const columnMap = {};
2061
- for (const col of columns) {
2062
- const key = col.expr?.value ?? col.expr?.column ?? col.as;
2063
- columnMap[key] = col;
2064
- }
2065
- return columnMap;
2066
- };
2067
- const applyFormatting = (response, columns) => {
2068
- const columnFormatters = {};
2069
- const columnMap = columnArrayToMap(columns);
2070
- response.fields.forEach((field) => {
2071
- // TODO: columnMap[field.name] silently breaks for columnField columns
2072
- const formatType = getPostgresBasicType(field);
2073
- if (formatType === 'date') {
2074
- columnFormatters[field.name] = (x) => {
2075
- const d = new Date(x);
2076
- // check if d is a valid date
2077
- if (isNaN(d.getTime())) {
2078
- return 'Invalid Date';
2079
- }
2080
- d.setMinutes(d.getMinutes() + d.getTimezoneOffset()); // TZ adjust
2081
- if (columnMap[field.name]?.expr.type === 'function' &&
2082
- columnMap[field.name]?.expr.name.toLowerCase() === 'date_trunc' &&
2083
- columnMap[field.name]?.expr.args.value[0].value.toLowerCase() ===
2084
- 'month') {
2085
- return d.toLocaleString('default', {
2086
- month: 'short',
2087
- year: 'numeric',
2088
- });
2089
- }
2090
- else if (columnMap[field.name]?.expr.type === 'function' &&
2091
- columnMap[field.name]?.expr.name.toLowerCase() === 'date_trunc' &&
2092
- columnMap[field.name]?.expr.args.value[0].value.toLowerCase() ===
2093
- 'quarter') {
2094
- return `Q${getQuarter(d)} ${d.getFullYear()}`;
2095
- }
2096
- else if (columnMap[field.name]?.expr.type === 'function' &&
2097
- columnMap[field.name]?.expr.name.toLowerCase() === 'date_trunc' &&
2098
- columnMap[field.name]?.expr.args.value[0].value.toLowerCase() ===
2099
- 'year') {
2100
- return d.toLocaleString('default', {
2101
- year: 'numeric',
2102
- });
2103
- }
2104
- return DATE_FMT.format(d);
2105
- };
2106
- }
2107
- else if (formatType === 'number') {
2108
- columnFormatters[field.name] = (x) => {
2109
- if (columnMap[field.name]?.expr.type === 'extract' &&
2110
- columnMap[field.name]?.expr.args.field.toLowerCase() === 'dow') {
2111
- return DAY_OF_WEEK[x];
2112
- }
2113
- else if (columnMap[field.name]?.expr.type === 'extract' &&
2114
- columnMap[field.name]?.expr.args.field.toLowerCase() === 'month') {
2115
- return MONTH_OF_YEAR[x - 1];
2116
- }
2117
- else if (`${x}`.includes('.')) {
2118
- // return MONEY_FMT.format(Number(x ?? 0.0));
2119
- return Number(x ?? 0.0).toFixed(2);
2120
- }
2121
- return x ?? 0.0;
2122
- };
2123
- }
2124
- else if (formatType === 'boolean') {
2125
- columnFormatters[field.name] = (x) => {
2126
- if (x) {
2127
- return 'True';
2128
- }
2129
- return 'False';
2130
- };
2131
- }
2132
- else {
2133
- columnFormatters[field.name] = (x) => x;
2134
- }
2135
- });
2136
- return response.rows.map((row) => {
2137
- const newRow = {};
2138
- Object.keys(row).forEach((key) => (newRow[key] = columnFormatters[key]
2139
- ? columnFormatters[key](row[key])
2140
- : row[key]));
2141
- return newRow;
2142
- });
2143
- };
2144
2138
  // Returns whether a where-clause contains a nested subquery.
2145
2139
  const isSubquery = (node) => {
2146
2140
  if (!node)
@@ -2164,7 +2158,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2164
2158
  return;
2165
2159
  }
2166
2160
  try {
2167
- let errored = false;
2168
2161
  setLoading(true);
2169
2162
  setAskedAQuestion(true);
2170
2163
  setErrorMessage('');
@@ -2184,6 +2177,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2184
2177
  body: JSON.stringify({
2185
2178
  initialQuestion: aiPrompt || overridePrompt,
2186
2179
  publicKey: client.publicKey,
2180
+ useNewNodeSql: true, // new flag
2187
2181
  }),
2188
2182
  });
2189
2183
  }
@@ -2195,6 +2189,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2195
2189
  sqlQuery: activeQuery,
2196
2190
  initialQuestion: aiPrompt,
2197
2191
  publicKey: client.publicKey,
2192
+ useNewNodeSql: true, // new flag
2198
2193
  }),
2199
2194
  });
2200
2195
  }
@@ -2212,31 +2207,34 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2212
2207
  setErrorMessage("Error: Couldn't process your request, please re-word your prompt.");
2213
2208
  return;
2214
2209
  }
2210
+ let currentSchema = schema;
2211
+ if (currentSchema && currentSchema.length === 0) {
2212
+ currentSchema = await fetchSchema();
2213
+ }
2215
2214
  let newAst, groupByPivot;
2216
2215
  if (ast) {
2217
2216
  // Unwrap the ast object, supporting many possible types
2218
2217
  ast = ast.length ? ast[0] : ast;
2219
2218
  newAst = convertBigQuery(ast);
2220
- newAst = convertWildcardColumns(newAst, schema); // must go before groupby
2221
- ({ ast: newAst, pivot: groupByPivot } = convertGroupBy(newAst, pivot, schema));
2222
- if (groupByPivot && !groupByPivot?.valueField) {
2223
- setErrorMessage("Error: Couldn't process your request, please re-word your prompt.");
2224
- return;
2225
- }
2219
+ newAst = convertWildcardColumns(newAst, currentSchema); // must go before groupby
2220
+ ({ ast: newAst, pivot: groupByPivot } = convertGroupBy(newAst, pivot, currentSchema));
2226
2221
  newAst = convertStringComparison(newAst, client.databaseType);
2227
2222
  newAst = convertRemoveSimpleParentheses(newAst);
2228
2223
  const table = getTableNames(newAst)[0] ?? initialTableName;
2229
2224
  const tableAlias = getTableAliases(newAst)[0] ?? initialTableName;
2225
+ newAst = convertUnaryToBinary(newAst);
2230
2226
  newAst = removeNonSelectedTableReferences(newAst, tableAlias ?? table, getAllPossibleColumns().map((col) => col.name));
2231
- setSelectedColumns(deepCopy(newAst).columns?.map((column) => {
2227
+ const procesedColumns = deepCopy(newAst).columns?.map((column) => {
2232
2228
  if (column.expr.type === 'column_ref') {
2233
- return `${table}.${column.expr.column}`;
2229
+ const columnName = extractColumnish(column.expr);
2230
+ return `${table}.${columnName}`;
2234
2231
  }
2235
2232
  else if (column.as) {
2236
2233
  return `${table}.${column.as}`;
2237
2234
  }
2238
2235
  return `${table}.${column.expr.value}`;
2239
- }));
2236
+ });
2237
+ setSelectedColumns(procesedColumns);
2240
2238
  if (groupByPivot) {
2241
2239
  setBaseAst(deepCopy({ ...newAst, orderby: null, limit: null }));
2242
2240
  newAst = deepCopy({ ...newAst, orderby: null, limit: null });
@@ -2252,7 +2250,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2252
2250
  ast = newAst; // so we fetch data for newAst later.
2253
2251
  fetchSqlQuery(ast, undefined, false);
2254
2252
  const table = getTableNames(newAst)[0] ?? initialTableName;
2255
- const tableAlias = getTableAliases(newAst)[0] ?? initialTableName;
2256
2253
  const hostedBody = {
2257
2254
  metadata: {
2258
2255
  clientId: client.publicKey,
@@ -2263,19 +2260,19 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2263
2260
  additionalProcessing: { page: { currentPage: 0, rowsPerPage: 20 } },
2264
2261
  useUpdatedDataGathering: true,
2265
2262
  pivot: groupByPivot,
2263
+ useNewNodeSql: true, // new flag
2266
2264
  },
2267
2265
  };
2268
- const cloudBody = {};
2269
- const data2 = await getData(client, 'patterns', 'same-origin', hostedBody, cloudBody);
2270
- if (data2.status === 'error') {
2271
- throw new Error('Error querying data from patterns');
2272
- }
2273
2266
  let currentUniqueValues = uniqueValues;
2274
2267
  let dateRangesTemp = dateRanges;
2275
- if (table !== currentTable) {
2276
- const tableInfo = schema.find((tableInfo) => tableInfo.name === table);
2268
+ if ((currentUniqueValues &&
2269
+ currentUniqueValues[table] &&
2270
+ Object.keys(currentUniqueValues[table]).length === 0) ||
2271
+ table !== currentTable) {
2272
+ const tableInfo = currentSchema.find((tableInfo) => tableInfo.name === table);
2277
2273
  if (tableInfo) {
2278
2274
  const newUniqueValues = await getUniqueStringValues(tableInfo.columns, table);
2275
+ currentUniqueValues = newUniqueValues;
2279
2276
  if (hashCode(uniqueValues) !== hashCode(newUniqueValues)) {
2280
2277
  setUniqueValues(newUniqueValues);
2281
2278
  }
@@ -2284,8 +2281,22 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2284
2281
  }
2285
2282
  setCurrentTable(table);
2286
2283
  }
2284
+ const cloudBody = {};
2285
+ const data2 = await getData(client, 'patterns', 'same-origin', hostedBody, cloudBody);
2286
+ if (!data2 || data2.status === 'error') {
2287
+ throw new Error('Error querying data from patterns');
2288
+ }
2287
2289
  if (data2.rows && data2.rows.length) {
2288
- const processedFields = data2.fields.map((elem) => convertPostgresColumn(elem));
2290
+ const processedFields = data2.fields
2291
+ .map((elem) => convertPostgresColumn(elem))
2292
+ .map((elem) => {
2293
+ const tableInfo = currentSchema.find((t) => t.name === table);
2294
+ const columnInfo = tableInfo?.columns.find((column) => column.name === elem.field);
2295
+ return columnInfo
2296
+ ? convertColumnInfoToColumnInternal(columnInfo)
2297
+ : null;
2298
+ })
2299
+ .filter((elem) => elem);
2289
2300
  let possiblePivot = true;
2290
2301
  const possibleColumns = getPossiblePivotFieldOptions(processedFields, currentUniqueValues[table]);
2291
2302
  if (groupByPivot &&
@@ -2299,7 +2310,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2299
2310
  let errorMessageEnding = '';
2300
2311
  if (groupByPivot.columnField &&
2301
2312
  !possibleColumns.columnFields.includes(groupByPivot?.columnField || '')) {
2302
- if (currentUniqueValues[table][groupByPivot?.columnField || '']) {
2313
+ if (currentUniqueValues[table]?.[groupByPivot?.columnField || '']) {
2303
2314
  errorMessageEnding = `The column ${groupByPivot?.columnField} has more than 24 unique values to pivot on.`;
2304
2315
  }
2305
2316
  else {
@@ -2308,7 +2319,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2308
2319
  }
2309
2320
  else if (groupByPivot.rowField &&
2310
2321
  !possibleColumns.rowFields.includes(groupByPivot?.rowField || '')) {
2311
- if (currentUniqueValues[table][groupByPivot?.rowField || '']) {
2322
+ if (currentUniqueValues[table]?.[groupByPivot?.rowField || '']) {
2312
2323
  errorMessageEnding = `The column ${groupByPivot?.rowField} has more than 36 unique values to pivot on.`;
2313
2324
  }
2314
2325
  else {
@@ -2320,7 +2331,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2320
2331
  errorMessageEnding = `The column ${groupByPivot?.valueField} is not a proper value field.`;
2321
2332
  }
2322
2333
  setErrorMessage(`The requested pivot is not supported. ${errorMessageEnding}`);
2323
- errored = true;
2324
2334
  }
2325
2335
  if (groupByPivot && possiblePivot) {
2326
2336
  let curReport = report ? report : undefined;
@@ -2397,7 +2407,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2397
2407
  setActiveQuery('');
2398
2408
  }
2399
2409
  if (data2.errorMessage) {
2400
- setErrorMessage(`Error: ${data2.errorMessage}`);
2410
+ setErrorMessage(`Error: Couldn't process your request, please re-word your prompt.`);
2401
2411
  }
2402
2412
  }
2403
2413
  catch (e) {
@@ -2417,7 +2427,8 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2417
2427
  setSelectedColumns((selectedColumns) => selectedColumns.filter((column) => !column.endsWith(name)));
2418
2428
  const columns = baseAst.columns.filter((col) => {
2419
2429
  if (col.expr.type === 'column_ref') {
2420
- return col.expr.column !== name;
2430
+ return (col.expr.column !== name &&
2431
+ (!col.expr.column.expr || col.expr.column.expr.value !== name));
2421
2432
  }
2422
2433
  else if (col.as) {
2423
2434
  return col.as !== name;
@@ -2432,14 +2443,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2432
2443
  setBaseAst(newAst);
2433
2444
  fetchSqlQuery(newAst);
2434
2445
  };
2435
- function TopLevelBooleanSwitch({ node, keyPrefix, handleOperatorChange, }) {
2436
- return (_jsx("div", { style: { width: 'fit-content' }, children: _jsx(TabsComponent, { value: node.operator, options: DEFAULT_TAB_OPTIONS, onChange: (event) => {
2437
- if (loading) {
2438
- return;
2439
- }
2440
- handleOperatorChange(event.target.value, node, keyPrefix);
2441
- } }) }));
2442
- }
2443
2446
  const DraggableItem = ({ id, label, onDelete }) => {
2444
2447
  const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: id });
2445
2448
  const style = {
@@ -2466,7 +2469,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2466
2469
  setOrderedColumnNames(newOrder);
2467
2470
  const orderedSelectedColumns = [];
2468
2471
  for (const value of newOrder) {
2469
- const [_, column] = value.split('.');
2472
+ const column = value.split('.')[1];
2470
2473
  if (selectedColumns.includes(value)) {
2471
2474
  orderedSelectedColumns.push(column);
2472
2475
  }
@@ -2490,12 +2493,23 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2490
2493
  fetchSqlQuery(newAst, undefined, false);
2491
2494
  }
2492
2495
  }
2493
- const columnNamesInAst = baseAst?.columns.map((col) => {
2494
- if (col.expr.type === 'column_ref') {
2495
- return col.expr.column;
2496
+ const columnNamesInAst = baseAst?.columns
2497
+ .map((col) => {
2498
+ if (col.expr.type === 'column_ref' && col.expr.column) {
2499
+ if (typeof col.expr.column === 'string') {
2500
+ return col.expr.column;
2501
+ }
2502
+ else {
2503
+ return col.expr.column.expr.value;
2504
+ }
2496
2505
  }
2497
2506
  else if (col.as) {
2498
- return col.as;
2507
+ if (typeof col.as === 'string') {
2508
+ return col.as;
2509
+ }
2510
+ else {
2511
+ return col.as.expr?.value;
2512
+ }
2499
2513
  }
2500
2514
  else if (col.expr && col.expr.type === 'aggr_func') {
2501
2515
  if (col.expr.args) {
@@ -2504,22 +2518,23 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2504
2518
  return col.expr.name;
2505
2519
  }
2506
2520
  return col.expr.value;
2507
- }) ?? [];
2521
+ })
2522
+ .filter(
2523
+ // remove duplicate entries
2524
+ (value, index, self) => value && self.indexOf(value) === index) ?? [];
2508
2525
  return (_jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: columnNamesInAst, strategy: verticalListSortingStrategy, children: _jsxs("div", { style: {
2509
2526
  display: 'flex',
2510
2527
  flexDirection: 'column',
2511
2528
  gap: 8,
2512
2529
  }, children: [columnNamesInAst.map((name) => (_jsx(DraggableItem, { id: name, label: name, onDelete: () => handleDeleteColumn(name) }, name))), columnNamesInAst?.length > 0 && _jsx("div", { style: { height: 6 } })] }) }) }));
2513
2530
  }
2514
- if (loading || initalChartLoad) {
2531
+ if (loading || initialChartLoad) {
2515
2532
  return (_jsxs("div", { style: {
2516
2533
  display: 'flex',
2517
2534
  flexDirection: 'row',
2518
2535
  height: '100%',
2519
2536
  ...containerStyle,
2520
2537
  }, className: className, ref: parentRef, children: [_jsxs(SidebarComponent, { children: [_jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Columns" }), _jsx(DraggableColumns, {}), _jsx(SecondaryButtonComponent, { onClick: () => {
2521
- if (loadingSchema)
2522
- return;
2523
2538
  if (!openPopover) {
2524
2539
  setOpenPopover('AddColumnModal');
2525
2540
  }
@@ -2540,12 +2555,12 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2540
2555
  }, orderedColumnNames: orderedColumnNames, setOrderedColumnNames: setOrderedColumnNames, selectedColumns: selectedColumns, setSelectedColumns: setSelectedColumns, isSelectedAllColumns: isSelectedAllColumns, clearAllState: clearAllState, nameToColumn: nameToColumn, baseAst: baseAst, setBaseAst: (ast) => {
2541
2556
  setBaseAst(ast);
2542
2557
  fetchSqlQuery(ast);
2543
- }, pivot: pivot, initialTableName: initialTableName, defaultAST: defaultAST, defaultTable: defaultTable, setPivot: setPivot, TextInput: TextInputComponent, SelectColumn: SelectColumnComponent, SecondaryButton: SecondaryButtonComponent, Button: ButtonComponent, ColumnSearchEmptyState: ColumnSearchEmptyState }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Filters" }), formData && (_jsx("div", { style: {
2558
+ }, pivot: pivot, initialTableName: initialTableName, defaultAST: defaultAST, defaultTable: defaultTable, setPivot: setPivot, TextInput: TextInputComponent, SelectColumn: SelectColumnComponent, SecondaryButton: SecondaryButtonComponent, Button: ButtonComponent, ColumnSearchEmptyState: ColumnSearchEmptyState, LoadingComponent: LoadingComponent }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Filters" }), formData && (_jsx("div", { style: {
2544
2559
  display: 'flex',
2545
2560
  flexDirection: 'column',
2546
2561
  gap: 8,
2547
2562
  marginBottom: 12,
2548
- }, children: renderSentence(formData, formData, '', true) })), _jsxs("div", { style: {
2563
+ }, children: filterTree && renderFilters(filterTree) })), _jsxs("div", { style: {
2549
2564
  display: 'flex',
2550
2565
  flexDirection: 'column',
2551
2566
  alignItems: 'flex-start',
@@ -2557,7 +2572,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2557
2572
  }
2558
2573
  if (!openPopover) {
2559
2574
  const value = orderedColumnNames[0];
2560
- const [_table, column] = value.split('.');
2575
+ const column = value.split('.')[1];
2561
2576
  const columnType = getColumnTypeByName(column);
2562
2577
  if (isNumericColumnType(columnType)) {
2563
2578
  const newSubtree = deepCopy(defaultNumericComparison);
@@ -2586,27 +2601,15 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2586
2601
  setActiveEditItem(null);
2587
2602
  }, 300);
2588
2603
  }
2589
- }, popoverTitle: 'Add filter', popoverChildren: _jsx(AddFilterPopover, { onSave: () => {
2590
- if (isNodeEmptyCollection(activeEditItem)) {
2591
- setIsPending(false);
2592
- setActivePath(null);
2593
- setOpenPopover(null);
2594
- setTimeout(() => {
2595
- clearCheckboxes();
2596
- setActiveEditItem(null);
2597
- }, 300);
2598
- }
2599
- else {
2600
- setIsPending(false);
2601
- handleInsertion(activeEditItem, 'AND', false);
2602
- setActivePath(null);
2603
- setOpenPopover(null);
2604
- setTimeout(() => {
2605
- clearCheckboxes();
2606
- setActiveEditItem(null);
2607
- }, 300);
2608
- }
2609
- }, Button: ButtonComponent, renderNode: renderNode, activeEditItem: activeEditItem }) }) }), baseAst?.where &&
2604
+ }, popoverTitle: 'Add filter', popoverChildren: _jsx(FilterModal, { schema: schema.find((s) => s.name === currentTable ||
2605
+ s.displayName === currentTable) ?? schema[0], fieldValuesMap: uniqueValues[getTableNames(baseAst).length === 1
2606
+ ? getTableNames(baseAst)[0]
2607
+ : initialTableName], onSubmitFilter: (filter) => {
2608
+ setOpenPopover(null);
2609
+ setIsPending(false);
2610
+ const item = filterToAst(filter, client.databaseType.toLowerCase());
2611
+ handleInsertion(item, 'AND', false);
2612
+ }, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, SecondaryButtonComponent: SecondaryButtonComponent, MultiSelectComponent: MultiSelectComponent }) }) }), baseAst?.where &&
2610
2613
  false && ( // temp removed the AddConditionPopover
2611
2614
  _jsxs(_Fragment, { children: [_jsx(SecondaryButtonComponent, { onClick: () => {
2612
2615
  if (!openPopover) {
@@ -2645,14 +2648,14 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2645
2648
  setActivePath(null);
2646
2649
  setOpenPopover(null);
2647
2650
  }
2648
- } }) })] }))] })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Pivot" }), _jsx(PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, CardComponent: CardComponent, SelectComponent: SelectComponent, ButtonComponent: ButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, LoadingComponent: LoadingComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEdittingPivot, setShowUpdatePivot: setIsEdittingPivot, parentRef: parentRef, data: rows, columns: columns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
2651
+ } }) })] }))] })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Pivot" }), _jsx(PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, CardComponent: CardComponent, SelectComponent: SelectComponent, ButtonComponent: ButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, LoadingComponent: LoadingComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEditingPivot, setShowUpdatePivot: setIsEditingPivot, parentRef: parentRef, data: rows, columns: columns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
2649
2652
  setPivot(null);
2650
2653
  setPivotData(null);
2651
2654
  const formattedRows = formatRows(rows, columns, false);
2652
2655
  setFormattedRows(formattedRows);
2653
2656
  },
2654
2657
  // TODOs
2655
- selectPivot: (pivot) => {
2658
+ selectPivot: () => {
2656
2659
  return;
2657
2660
  }, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: LabelComponent, HeaderComponent: HeaderComponent, dateRange: undefined, pivotCountRequest: 4, SecondaryButtonComponent: SecondaryButtonComponent, query: activeQuery, initialUniqueValues: uniqueValues[currentTable], disabled: !loading && (!baseAst || !dataDisplayed), pivotRecommendationsEnabled: pivotRecommendationsEnabled && overrideRecommendations, report: tempReport ?? report }), pivot && (_jsx(PivotForm, { columns: columns, uniqueValues: uniqueValues[currentTable], setPivotRowField: (value) => {
2658
2661
  setPivotRowField(value);
@@ -2669,7 +2672,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2669
2672
  }, children: _jsx(SortSentence, { sortData: {
2670
2673
  type: pivot.sortDirection,
2671
2674
  expr: { type: 'column_ref', column: pivot.sortField },
2672
- }, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
2675
+ }, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: () => { }, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
2673
2676
  setPivot({ ...pivot, sort: false });
2674
2677
  setBaseAst(deepCopy(baseAst));
2675
2678
  if (!pivot) {
@@ -2718,7 +2721,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2718
2721
  if (!pivot) {
2719
2722
  fetchSqlQuery(newAst);
2720
2723
  }
2721
- }, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
2724
+ }, setIsPending: setIsPending, setEditPopoverKey: () => { }, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
2722
2725
  const newAst = { ...baseAst };
2723
2726
  newAst.orderby.splice(id, 1);
2724
2727
  setBaseAst(deepCopy(newAst));
@@ -2741,7 +2744,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2741
2744
  setActivePath(null);
2742
2745
  setOpenPopover(null);
2743
2746
  }
2744
- }, popoverTitle: "Sort by", popoverChildren: _jsx(AddSortPopover, { columns: selectedColumns, Select: SelectComponent, Button: ButtonComponent, onSave: () => { } }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Limit" }), baseAst && baseAst.limit ? (_jsx("div", { style: {
2747
+ }, popoverTitle: "Sort by", popoverChildren: _jsx(AddSortPopover, { columns: selectedColumns, Select: SelectComponent, Button: ButtonComponent, onSave: () => { } }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Limit" }), baseAst && baseAst.limit && baseAst.limit.value?.length > 0 ? (_jsx("div", { style: {
2745
2748
  display: 'flex',
2746
2749
  flexDirection: 'column',
2747
2750
  gap: 8,
@@ -2796,7 +2799,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2796
2799
  ? askAIInputWidth
2797
2800
  : askAILoadingContainerWidth, value: aiPrompt, onChange: () => { } }), _jsx(ButtonComponent, { onClick: () => { }, label: "Ask AI" }), ((baseAst && dataDisplayed) ||
2798
2801
  initialLoad ||
2799
- initalChartLoad) && (_jsx(SecondaryButtonComponent, { onClick: () => { }, label: "New report" }))] }) })), _jsxs(_Fragment, { children: [_jsx(TableComponent, { isLoading: true, rows: [], columns: [] }), baseAst && dataDisplayed && !initalChartLoad && (_jsxs("div", { style: {
2802
+ initialChartLoad) && (_jsx(SecondaryButtonComponent, { onClick: () => { }, label: "New report" }))] }) })), _jsxs(_Fragment, { children: [_jsx(TableComponent, { isLoading: true, rows: [], columns: [] }), baseAst && dataDisplayed && !initialChartLoad && (_jsxs("div", { style: {
2800
2803
  display: 'flex',
2801
2804
  flexDirection: 'row',
2802
2805
  gap: '12px',
@@ -2811,8 +2814,6 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2811
2814
  boxSizing: 'border-box',
2812
2815
  ...containerStyle,
2813
2816
  }, className: className, children: [_jsxs(SidebarComponent, { children: [_jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Columns" }), _jsx(DraggableColumns, {}), _jsx(SecondaryButtonComponent, { onClick: () => {
2814
- if (loadingSchema)
2815
- return;
2816
2817
  if (!orderedColumnNames) {
2817
2818
  return;
2818
2819
  }
@@ -2836,12 +2837,12 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2836
2837
  }, orderedColumnNames: orderedColumnNames, setOrderedColumnNames: setOrderedColumnNames, selectedColumns: selectedColumns, setSelectedColumns: setSelectedColumns, isSelectedAllColumns: isSelectedAllColumns, clearAllState: clearAllState, nameToColumn: nameToColumn, baseAst: baseAst, setBaseAst: (ast) => {
2837
2838
  setBaseAst(ast);
2838
2839
  fetchSqlQuery(ast);
2839
- }, pivot: pivot, initialTableName: initialTableName, defaultAST: defaultAST, defaultTable: defaultTable, setPivot: setPivot, TextInput: TextInputComponent, SelectColumn: SelectColumnComponent, SecondaryButton: SecondaryButtonComponent, Button: ButtonComponent, ColumnSearchEmptyState: ColumnSearchEmptyState }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Filters" }), formData && (_jsx("div", { style: {
2840
+ }, pivot: pivot, initialTableName: initialTableName, defaultAST: defaultAST, defaultTable: defaultTable, schemaLoading: loadingSchema, setPivot: setPivot, TextInput: TextInputComponent, SelectColumn: SelectColumnComponent, SecondaryButton: SecondaryButtonComponent, Button: ButtonComponent, ColumnSearchEmptyState: ColumnSearchEmptyState, LoadingComponent: LoadingComponent }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Filters" }), formData && (_jsx("div", { style: {
2840
2841
  display: 'flex',
2841
2842
  flexDirection: 'column',
2842
2843
  gap: 8,
2843
2844
  marginBottom: 12,
2844
- }, children: renderSentence(formData, formData, '', true) })), _jsxs("div", { style: {
2845
+ }, children: filterTree && renderFilters(filterTree) })), _jsxs("div", { style: {
2845
2846
  display: 'flex',
2846
2847
  flexDirection: 'column',
2847
2848
  alignItems: 'flex-start',
@@ -2853,7 +2854,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2853
2854
  }
2854
2855
  if (!openPopover) {
2855
2856
  const value = orderedColumnNames[0];
2856
- const [_table, column] = value.split('.');
2857
+ const column = value.split('.')[1];
2857
2858
  const columnType = getColumnTypeByName(column);
2858
2859
  if (isNumericColumnType(columnType)) {
2859
2860
  const newSubtree = deepCopy(defaultNumericComparison);
@@ -2883,27 +2884,13 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2883
2884
  setActiveEditItem(null);
2884
2885
  }, 300);
2885
2886
  }
2886
- }, popoverTitle: "Add filter", popoverChildren: _jsx(AddFilterPopover, { onSave: () => {
2887
- if (isNodeEmptyCollection(activeEditItem)) {
2888
- setOpenPopover(null);
2889
- clearCheckboxes();
2890
- setIsPending(false);
2891
- setTimeout(() => {
2892
- setActivePath(null);
2893
- setActiveEditItem(null);
2894
- }, 300);
2895
- }
2896
- else {
2897
- setOpenPopover(null);
2898
- setIsPending(false);
2899
- handleInsertion(activeEditItem, 'AND', false);
2900
- setActivePath(null);
2901
- setTimeout(() => {
2902
- clearCheckboxes();
2903
- setActiveEditItem(null);
2904
- }, 300);
2905
- }
2906
- }, Button: ButtonComponent, renderNode: renderNode, activeEditItem: activeEditItem }) }) }), baseAst?.where &&
2887
+ }, popoverTitle: "Add filter", popoverChildren: _jsx(FilterModal, { schema: schema.find((s) => s.name === currentTable ||
2888
+ s.displayName === currentTable) ?? schema[0], fieldValuesMap: fieldValuesMap, onSubmitFilter: (filter) => {
2889
+ setOpenPopover(null);
2890
+ setIsPending(false);
2891
+ const item = filterToAst(filter, client.databaseType.toLowerCase());
2892
+ handleInsertion(item, 'AND', false);
2893
+ }, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, MultiSelectComponent: MultiSelectComponent }) }) }), baseAst?.where &&
2907
2894
  false && ( // temp removed the AddConditionPopover
2908
2895
  _jsxs(_Fragment, { children: [_jsx(SecondaryButtonComponent, { onClick: () => {
2909
2896
  if (!openPopover) {
@@ -2943,7 +2930,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
2943
2930
  setOpenPopover(null);
2944
2931
  clearCheckboxes();
2945
2932
  }
2946
- } }) })] }))] })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Pivot" }), _jsx(PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, 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: isEdittingPivot, setShowUpdatePivot: setIsEdittingPivot, parentRef: parentRef, data: rows, columns: columns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
2933
+ } }) })] }))] })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Pivot" }), _jsx(PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, 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: rows, columns: columns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
2947
2934
  setPivot(null);
2948
2935
  setPivotData(null);
2949
2936
  const formattedRows = formatRows(rows, columns, false);
@@ -3002,7 +2989,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
3002
2989
  `.${pivot.rowField}`,
3003
2990
  `.${pivot.valueField || 'count'}`,
3004
2991
  ]
3005
- : selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: async () => {
2992
+ : selectedColumns, setIsPending: setIsPending, setEditPopoverKey: () => { }, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: async () => {
3006
2993
  if (pivot) {
3007
2994
  const tempPivot = { ...pivot, sort: false };
3008
2995
  let dateBucket = undefined;
@@ -3057,7 +3044,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
3057
3044
  flexDirection: 'column',
3058
3045
  gap: 8,
3059
3046
  marginBottom: 12,
3060
- }, children: baseAst.orderby.map((sortData, id) => (_jsx(SortSentence, { sortData: sortData, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
3047
+ }, children: baseAst.orderby.map((sortData, id) => (_jsx(SortSentence, { sortData: sortData, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: () => { }, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
3061
3048
  if (pivot) {
3062
3049
  setPivot({ ...pivot, sort: false });
3063
3050
  return;
@@ -3167,7 +3154,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
3167
3154
  setOpenPopover(null);
3168
3155
  setBaseAst(deepCopy(newAst));
3169
3156
  fetchSqlQuery(deepCopy(newAst));
3170
- } }) }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Limit" }), baseAst && baseAst.limit ? (_jsx("div", { style: {
3157
+ } }) }) })] }), _jsxs("div", { style: { width: '100%' }, children: [_jsx(SidebarHeadingComponent, { label: "Limit" }), baseAst && baseAst.limit && baseAst.limit.value?.length > 0 ? (_jsx("div", { style: {
3171
3158
  display: 'flex',
3172
3159
  flexDirection: 'column',
3173
3160
  gap: 8,
@@ -3240,7 +3227,7 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
3240
3227
  ? 'Ask a follow-up question...'
3241
3228
  : 'Ask a question...' }), _jsx(ButtonComponent, { onClick: handleAsk, label: 'Ask AI' }), ((baseAst && dataDisplayed) || initialLoad) && (_jsx(SecondaryButtonComponent, { label: 'New report', onClick: clearAllState }))] }) })), baseAst && (_jsx(TableComponent, { isLoading: tableLoading ||
3242
3229
  (loading && errorMessage.length === 0) ||
3243
- initalChartLoad, rows: formattedRows, rowCount: pivot ? undefined : numberOfRows, columns: pivot
3230
+ initialChartLoad, rows: formattedRows, rowCount: pivot ? undefined : numberOfRows, columns: pivot
3244
3231
  ? pivotData?.columns || emptyPivotColumns()
3245
3232
  : enforceOrderOnColumns(Object.keys(rows[0] ?? {})).map((c) => {
3246
3233
  return {
@@ -3258,9 +3245,10 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
3258
3245
  overflow: 'hidden',
3259
3246
  width: '100%',
3260
3247
  gap: 12,
3261
- }, children: [_jsx(ErrorMessageComponent, { errorMessage: errorMessage }), _jsx(SecondaryButtonComponent, { onClick: handleAsk, label: 'Retry' })] })) : (_jsx("div", { style: { width: '100%' } })), baseAst && dataDisplayed && !initalChartLoad && (_jsxs(_Fragment, { children: [!hideCopySQL && (_jsx(SecondaryButtonComponent, { label: isCopying ? '✅ Copied' : 'Copy SQL', onClick: () => copySQLToClipboard() })), _jsx(ButtonComponent, { onClick: () => {
3248
+ alignItems: 'center',
3249
+ }, children: [_jsx(ErrorMessageComponent, { errorMessage: errorMessage }), _jsx(SecondaryButtonComponent, { onClick: handleAsk, label: 'Retry' })] })) : (_jsx("div", { style: { width: '100%' } })), baseAst && dataDisplayed && !initialChartLoad && (_jsxs(_Fragment, { children: [!hideCopySQL && (_jsx(SecondaryButtonComponent, { label: isCopying ? '✅ Copied' : 'Copy SQL', onClick: () => copySQLToClipboard() })), _jsx(ButtonComponent, { onClick: () => {
3262
3250
  setIsChartBuilderOpen(true);
3263
- }, label: report ? 'Save changes' : 'Add to dashboard' })] }))] })] }), _jsx("style", { children: `body{margin:0;}` })] })), (!isChartBuilderHorizontalView || isChartBuilderOpen) && (_jsx(ChartBuilderWithModal, { report: report
3251
+ }, disabled: !!errorMessage, label: report ? 'Save changes' : 'Add to dashboard' })] }))] })] }), _jsx("style", { children: `body{margin:0;}` })] })), (!isChartBuilderHorizontalView || isChartBuilderOpen) && (_jsx(ChartBuilderWithModal, { report: report
3264
3252
  ? {
3265
3253
  ...report,
3266
3254
  ...tempReport,
@@ -3274,5 +3262,5 @@ export default function ReportBuilder({ initialTableName = '', onSubmitEditRepor
3274
3262
  queryString: activeQuery,
3275
3263
  rows: rows,
3276
3264
  }
3277
- : tempReport, rows: rows, columns: columns, pivot: pivot, query: activeQuery, showTableFormatOptions: showChartBuilderTableFormatOptions, showDateFieldOptions: isAdminEnabled, showAccessControlOptions: isAdminEnabled, title: report ? 'Save changes' : 'Add to dashboard', isHorizontalView: true, isOpen: isChartBuilderOpen, setIsOpen: setIsChartBuilderOpen, onAddToDashboardComplete: report ? onSubmitEditReport : onSubmitCreateReport, destinationDashboard: destinationDashboard, organizationName: organizationName, pivotData: pivotData, initialUniqueValues: uniqueValues[currentTable], pivotRecommendationsEnabled: pivotRecommendationsEnabled && overrideRecommendations, 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, FormContainer: ChartBuilderFormContainer, hideDateRangeFilter: true, buttonLabel: report ? 'Save changes' : 'Add to dashboard', onClickChartElement: onClickChartElement }))] }));
3265
+ : tempReport, rows: rows, columns: columns, pivot: pivot, query: activeQuery, showTableFormatOptions: showChartBuilderTableFormatOptions, showDateFieldOptions: isAdminEnabled, showAccessControlOptions: isAdminEnabled, title: report ? 'Save changes' : 'Add to dashboard', isHorizontalView: true, isOpen: isChartBuilderOpen, setIsOpen: setIsChartBuilderOpen, onAddToDashboardComplete: report ? onSubmitEditReport : onSubmitCreateReport, destinationDashboard: destinationDashboard, organizationName: organizationName, pivotData: pivotData, initialUniqueValues: uniqueValues[currentTable], pivotRecommendationsEnabled: pivotRecommendationsEnabled && overrideRecommendations, 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, FormContainer: ChartBuilderFormContainer, hideDateRangeFilter: true, buttonLabel: report ? 'Save changes' : 'Add to dashboard', onClickChartElement: onClickChartElement, rowCount: numberOfRows, onPageChange: onPageChange, onSortChange: onSortChange, isLoading: tableLoading }))] }));
3278
3266
  }