@quillsql/react 2.11.15 → 2.11.17

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 (209) hide show
  1. package/dist/cjs/Chart.d.ts +117 -42
  2. package/dist/cjs/Chart.d.ts.map +1 -1
  3. package/dist/cjs/Chart.js +44 -18
  4. package/dist/cjs/ChartBuilder.d.ts +195 -28
  5. package/dist/cjs/ChartBuilder.d.ts.map +1 -1
  6. package/dist/cjs/ChartBuilder.js +124 -63
  7. package/dist/cjs/ChartEditor.d.ts +114 -18
  8. package/dist/cjs/ChartEditor.d.ts.map +1 -1
  9. package/dist/cjs/ChartEditor.js +47 -15
  10. package/dist/cjs/Dashboard.d.ts +148 -90
  11. package/dist/cjs/Dashboard.d.ts.map +1 -1
  12. package/dist/cjs/Dashboard.js +46 -152
  13. package/dist/cjs/DateRangePicker/QuillDateRangePicker.d.ts +21 -1
  14. package/dist/cjs/DateRangePicker/QuillDateRangePicker.d.ts.map +1 -1
  15. package/dist/cjs/DateRangePicker/QuillDateRangePicker.js +5 -2
  16. package/dist/cjs/DateRangePicker/dateRangePickerUtils.js +1 -1
  17. package/dist/cjs/QuillProvider.d.ts +105 -2
  18. package/dist/cjs/QuillProvider.d.ts.map +1 -1
  19. package/dist/cjs/QuillProvider.js +59 -0
  20. package/dist/cjs/ReportBuilder.d.ts +188 -34
  21. package/dist/cjs/ReportBuilder.d.ts.map +1 -1
  22. package/dist/cjs/ReportBuilder.js +551 -426
  23. package/dist/cjs/SQLEditor.d.ts +158 -29
  24. package/dist/cjs/SQLEditor.d.ts.map +1 -1
  25. package/dist/cjs/SQLEditor.js +52 -32
  26. package/dist/cjs/Table.d.ts +119 -15
  27. package/dist/cjs/Table.d.ts.map +1 -1
  28. package/dist/cjs/Table.js +37 -6
  29. package/dist/cjs/TableChart.d.ts.map +1 -1
  30. package/dist/cjs/TableChart.js +0 -194
  31. package/dist/cjs/{BarList.d.ts → components/Chart/BarList.d.ts} +1 -1
  32. package/dist/cjs/components/Chart/BarList.d.ts.map +1 -0
  33. package/dist/cjs/{BarList.js → components/Chart/BarList.js} +1 -1
  34. package/dist/cjs/components/Chart/LineChart.d.ts +2 -3
  35. package/dist/cjs/components/Chart/LineChart.d.ts.map +1 -1
  36. package/dist/cjs/components/Chart/LineChart.js +3 -3
  37. package/dist/cjs/components/Chart/PieChart.d.ts.map +1 -0
  38. package/dist/cjs/{PieChart.js → components/Chart/PieChart.js} +1 -1
  39. package/dist/cjs/components/Dashboard/ChartComponent.d.ts +2 -1
  40. package/dist/cjs/components/Dashboard/ChartComponent.d.ts.map +1 -1
  41. package/dist/cjs/components/Dashboard/ChartComponent.js +6 -7
  42. package/dist/cjs/components/Dashboard/DashboardFilter.d.ts +22 -0
  43. package/dist/cjs/components/Dashboard/DashboardFilter.d.ts.map +1 -0
  44. package/dist/cjs/components/Dashboard/DashboardFilter.js +75 -0
  45. package/dist/cjs/components/Dashboard/DataLoader.d.ts +1 -1
  46. package/dist/cjs/components/Dashboard/DataLoader.d.ts.map +1 -1
  47. package/dist/cjs/components/Dashboard/DataLoader.js +1 -1
  48. package/dist/cjs/components/Dashboard/MetricComponent.d.ts +2 -12
  49. package/dist/cjs/components/Dashboard/MetricComponent.d.ts.map +1 -1
  50. package/dist/cjs/components/Dashboard/MetricComponent.js +39 -17
  51. package/dist/cjs/components/Dashboard/TableComponent.d.ts +2 -1
  52. package/dist/cjs/components/Dashboard/TableComponent.d.ts.map +1 -1
  53. package/dist/cjs/components/Dashboard/TableComponent.js +6 -9
  54. package/dist/cjs/components/QuillSelect.d.ts +4 -1
  55. package/dist/cjs/components/QuillSelect.d.ts.map +1 -1
  56. package/dist/cjs/components/QuillSelect.js +13 -8
  57. package/dist/cjs/components/QuillTable.d.ts +16 -2
  58. package/dist/cjs/components/QuillTable.d.ts.map +1 -1
  59. package/dist/cjs/components/QuillTable.js +4 -4
  60. package/dist/cjs/components/ReportBuilder/AddColumnPopover.d.ts +30 -1
  61. package/dist/cjs/components/ReportBuilder/AddColumnPopover.d.ts.map +1 -1
  62. package/dist/cjs/components/ReportBuilder/AddColumnPopover.js +33 -14
  63. package/dist/cjs/components/ReportBuilder/AddLimitPopover.d.ts +25 -2
  64. package/dist/cjs/components/ReportBuilder/AddLimitPopover.d.ts.map +1 -1
  65. package/dist/cjs/components/ReportBuilder/AddLimitPopover.js +19 -19
  66. package/dist/cjs/components/ReportBuilder/AddSortPopover.d.ts +22 -2
  67. package/dist/cjs/components/ReportBuilder/AddSortPopover.d.ts.map +1 -1
  68. package/dist/cjs/components/ReportBuilder/AddSortPopover.js +18 -20
  69. package/dist/cjs/components/ReportBuilder/bigDateMap.js +1 -1
  70. package/dist/cjs/components/ReportBuilder/convert.d.ts +2 -1
  71. package/dist/cjs/components/ReportBuilder/convert.d.ts.map +1 -1
  72. package/dist/cjs/components/ReportBuilder/convert.js +40 -20
  73. package/dist/cjs/components/ReportBuilder/pivot.d.ts +2 -1
  74. package/dist/cjs/components/ReportBuilder/pivot.d.ts.map +1 -1
  75. package/dist/cjs/components/ReportBuilder/ui.d.ts +83 -19
  76. package/dist/cjs/components/ReportBuilder/ui.d.ts.map +1 -1
  77. package/dist/cjs/components/ReportBuilder/ui.js +68 -121
  78. package/dist/cjs/components/ReportBuilder/util.d.ts +3 -1
  79. package/dist/cjs/components/ReportBuilder/util.d.ts.map +1 -1
  80. package/dist/cjs/components/ReportBuilder/util.js +34 -8
  81. package/dist/cjs/components/UiComponents.d.ts +98 -97
  82. package/dist/cjs/components/UiComponents.d.ts.map +1 -1
  83. package/dist/cjs/components/UiComponents.js +132 -112
  84. package/dist/cjs/hooks/index.d.ts +1 -0
  85. package/dist/cjs/hooks/index.d.ts.map +1 -1
  86. package/dist/cjs/hooks/index.js +3 -1
  87. package/dist/cjs/hooks/useTheme.d.ts +7 -0
  88. package/dist/cjs/hooks/useTheme.d.ts.map +1 -0
  89. package/dist/cjs/hooks/useTheme.js +12 -0
  90. package/dist/cjs/index.d.ts +10 -2
  91. package/dist/cjs/index.d.ts.map +1 -1
  92. package/dist/cjs/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  93. package/dist/cjs/internals/ReportBuilder/PivotList.js +10 -10
  94. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts +29 -14
  95. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  96. package/dist/cjs/internals/ReportBuilder/PivotModal.js +73 -49
  97. package/dist/cjs/utils/dataFetcher.d.ts.map +1 -1
  98. package/dist/cjs/utils/dataFetcher.js +2 -0
  99. package/dist/cjs/utils/width.d.ts +12 -0
  100. package/dist/cjs/utils/width.d.ts.map +1 -0
  101. package/dist/cjs/utils/width.js +25 -0
  102. package/dist/esm/Chart.d.ts +117 -42
  103. package/dist/esm/Chart.d.ts.map +1 -1
  104. package/dist/esm/Chart.js +45 -19
  105. package/dist/esm/ChartBuilder.d.ts +195 -28
  106. package/dist/esm/ChartBuilder.d.ts.map +1 -1
  107. package/dist/esm/ChartBuilder.js +124 -63
  108. package/dist/esm/ChartEditor.d.ts +114 -18
  109. package/dist/esm/ChartEditor.d.ts.map +1 -1
  110. package/dist/esm/ChartEditor.js +51 -19
  111. package/dist/esm/Dashboard.d.ts +148 -90
  112. package/dist/esm/Dashboard.d.ts.map +1 -1
  113. package/dist/esm/Dashboard.js +49 -153
  114. package/dist/esm/DateRangePicker/QuillDateRangePicker.d.ts +21 -1
  115. package/dist/esm/DateRangePicker/QuillDateRangePicker.d.ts.map +1 -1
  116. package/dist/esm/DateRangePicker/QuillDateRangePicker.js +6 -3
  117. package/dist/esm/DateRangePicker/dateRangePickerUtils.js +1 -1
  118. package/dist/esm/QuillProvider.d.ts +105 -2
  119. package/dist/esm/QuillProvider.d.ts.map +1 -1
  120. package/dist/esm/QuillProvider.js +59 -0
  121. package/dist/esm/ReportBuilder.d.ts +188 -34
  122. package/dist/esm/ReportBuilder.d.ts.map +1 -1
  123. package/dist/esm/ReportBuilder.js +553 -428
  124. package/dist/esm/SQLEditor.d.ts +158 -29
  125. package/dist/esm/SQLEditor.d.ts.map +1 -1
  126. package/dist/esm/SQLEditor.js +53 -33
  127. package/dist/esm/Table.d.ts +119 -15
  128. package/dist/esm/Table.d.ts.map +1 -1
  129. package/dist/esm/Table.js +38 -7
  130. package/dist/esm/TableChart.d.ts.map +1 -1
  131. package/dist/esm/TableChart.js +0 -194
  132. package/dist/esm/{BarList.d.ts → components/Chart/BarList.d.ts} +1 -1
  133. package/dist/esm/components/Chart/BarList.d.ts.map +1 -0
  134. package/dist/esm/{BarList.js → components/Chart/BarList.js} +1 -1
  135. package/dist/esm/components/Chart/LineChart.d.ts +2 -3
  136. package/dist/esm/components/Chart/LineChart.d.ts.map +1 -1
  137. package/dist/esm/components/Chart/LineChart.js +3 -3
  138. package/dist/esm/components/Chart/PieChart.d.ts.map +1 -0
  139. package/dist/esm/{PieChart.js → components/Chart/PieChart.js} +1 -1
  140. package/dist/esm/components/Dashboard/ChartComponent.d.ts +2 -1
  141. package/dist/esm/components/Dashboard/ChartComponent.d.ts.map +1 -1
  142. package/dist/esm/components/Dashboard/ChartComponent.js +5 -6
  143. package/dist/esm/components/Dashboard/DashboardFilter.d.ts +22 -0
  144. package/dist/esm/components/Dashboard/DashboardFilter.d.ts.map +1 -0
  145. package/dist/esm/components/Dashboard/DashboardFilter.js +71 -0
  146. package/dist/esm/components/Dashboard/DataLoader.d.ts +1 -1
  147. package/dist/esm/components/Dashboard/DataLoader.d.ts.map +1 -1
  148. package/dist/esm/components/Dashboard/DataLoader.js +1 -1
  149. package/dist/esm/components/Dashboard/MetricComponent.d.ts +2 -12
  150. package/dist/esm/components/Dashboard/MetricComponent.d.ts.map +1 -1
  151. package/dist/esm/components/Dashboard/MetricComponent.js +39 -17
  152. package/dist/esm/components/Dashboard/TableComponent.d.ts +2 -1
  153. package/dist/esm/components/Dashboard/TableComponent.d.ts.map +1 -1
  154. package/dist/esm/components/Dashboard/TableComponent.js +6 -9
  155. package/dist/esm/components/QuillSelect.d.ts +4 -1
  156. package/dist/esm/components/QuillSelect.d.ts.map +1 -1
  157. package/dist/esm/components/QuillSelect.js +14 -9
  158. package/dist/esm/components/QuillTable.d.ts +16 -2
  159. package/dist/esm/components/QuillTable.d.ts.map +1 -1
  160. package/dist/esm/components/QuillTable.js +4 -4
  161. package/dist/esm/components/ReportBuilder/AddColumnPopover.d.ts +30 -1
  162. package/dist/esm/components/ReportBuilder/AddColumnPopover.d.ts.map +1 -1
  163. package/dist/esm/components/ReportBuilder/AddColumnPopover.js +34 -15
  164. package/dist/esm/components/ReportBuilder/AddLimitPopover.d.ts +25 -2
  165. package/dist/esm/components/ReportBuilder/AddLimitPopover.d.ts.map +1 -1
  166. package/dist/esm/components/ReportBuilder/AddLimitPopover.js +20 -20
  167. package/dist/esm/components/ReportBuilder/AddSortPopover.d.ts +22 -2
  168. package/dist/esm/components/ReportBuilder/AddSortPopover.d.ts.map +1 -1
  169. package/dist/esm/components/ReportBuilder/AddSortPopover.js +20 -22
  170. package/dist/esm/components/ReportBuilder/bigDateMap.js +1 -1
  171. package/dist/esm/components/ReportBuilder/convert.d.ts +2 -1
  172. package/dist/esm/components/ReportBuilder/convert.d.ts.map +1 -1
  173. package/dist/esm/components/ReportBuilder/convert.js +33 -13
  174. package/dist/esm/components/ReportBuilder/pivot.d.ts +2 -1
  175. package/dist/esm/components/ReportBuilder/pivot.d.ts.map +1 -1
  176. package/dist/esm/components/ReportBuilder/ui.d.ts +83 -19
  177. package/dist/esm/components/ReportBuilder/ui.d.ts.map +1 -1
  178. package/dist/esm/components/ReportBuilder/ui.js +67 -119
  179. package/dist/esm/components/ReportBuilder/util.d.ts +3 -1
  180. package/dist/esm/components/ReportBuilder/util.d.ts.map +1 -1
  181. package/dist/esm/components/ReportBuilder/util.js +31 -7
  182. package/dist/esm/components/UiComponents.d.ts +98 -97
  183. package/dist/esm/components/UiComponents.d.ts.map +1 -1
  184. package/dist/esm/components/UiComponents.js +125 -110
  185. package/dist/esm/hooks/index.d.ts +1 -0
  186. package/dist/esm/hooks/index.d.ts.map +1 -1
  187. package/dist/esm/hooks/index.js +1 -0
  188. package/dist/esm/hooks/useTheme.d.ts +7 -0
  189. package/dist/esm/hooks/useTheme.d.ts.map +1 -0
  190. package/dist/esm/hooks/useTheme.js +10 -0
  191. package/dist/esm/index.d.ts +10 -2
  192. package/dist/esm/index.d.ts.map +1 -1
  193. package/dist/esm/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  194. package/dist/esm/internals/ReportBuilder/PivotList.js +10 -10
  195. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts +29 -14
  196. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  197. package/dist/esm/internals/ReportBuilder/PivotModal.js +73 -49
  198. package/dist/esm/utils/dataFetcher.d.ts.map +1 -1
  199. package/dist/esm/utils/dataFetcher.js +2 -0
  200. package/dist/esm/utils/width.d.ts +12 -0
  201. package/dist/esm/utils/width.d.ts.map +1 -0
  202. package/dist/esm/utils/width.js +21 -0
  203. package/package.json +1 -1
  204. package/dist/cjs/BarList.d.ts.map +0 -1
  205. package/dist/cjs/PieChart.d.ts.map +0 -1
  206. package/dist/esm/BarList.d.ts.map +0 -1
  207. package/dist/esm/PieChart.d.ts.map +0 -1
  208. /package/dist/cjs/{PieChart.d.ts → components/Chart/PieChart.d.ts} +0 -0
  209. /package/dist/esm/{PieChart.d.ts → components/Chart/PieChart.d.ts} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /* eslint-disable no-unused-vars */
2
3
  import { useContext, useEffect, useRef, useState, } from 'react';
3
- import { MemoizedButton, MemoizedCheckbox, MemoizedHeader, MemoizedLabel, MemoizedPopover, MemoizedSecondaryButton, MemoizedText, } from './components/UiComponents';
4
+ import { DEFAULT_TAB_OPTIONS, MemoizedButton, MemoizedCheckbox, MemoizedDeleteButton, MemoizedHeader, MemoizedLabel, MemoizedSecondaryButton, MemoizedText, MemoizedPopover, QuillTableComponent, QuillTabs, MemoizedModal, } from './components/UiComponents';
4
5
  import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, } from '@dnd-kit/core';
5
6
  import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, useSortable, } from '@dnd-kit/sortable';
6
7
  import { CSS as DND_CSS } from '@dnd-kit/utilities';
@@ -8,7 +9,8 @@ import { getQuarter } from 'date-fns';
8
9
  import { ClientContext, ThemeContext } from './Context';
9
10
  import { getTableAliases, getTableNames, isDateishColumnType, isNumericColumnType, isTextColumnType, } from './components/ReportBuilder/ast';
10
11
  import { ChartBuilderWithModal } from './ChartBuilder';
11
- import { QuillPopover, QuillTabs, QuillTextInput, QuillSidebar, CustomContainer, QuillHandleButton, QuillSelectColumn, QuillDraggableColumn, QuillButtonLoadingState, QuillTableLoadingState, QuillSidebarHeading, QuillSidebarSubHeading, QuillFilterPopover, QuillSortPopover, DEFAULT_TAB_OPTIONS, TagWrapper, EditPopover, AddFilterPopover, } from './components/ReportBuilder/ui';
12
+ import { QuillTextInput } from './components/UiComponents';
13
+ import { QuillSidebar, CustomContainer, QuillSelectColumn, QuillDraggableColumn, QuillSidebarHeading, QuillFilterPopover, QuillSortPopover, TagWrapper, EditPopover, AddFilterPopover, QuillLimitPopover, } from './components/ReportBuilder/ui';
12
14
  import { generateCurrentPeriodPostgres, generateEqualsPostgres, generateLastNPeriodsPostgres, generatePreviousPeriodPostgres, } from './components/ReportBuilder/postgres';
13
15
  import { convertBigQuery, convertGroupBy, convertRemoveSimpleParentheses, convertStringComparison, convertWildcardColumns, } from './components/ReportBuilder/convert';
14
16
  import { deepCopy, formatDateComparisonNode, getDateFilterInfo, getInTheCurrentIntervalSentence, getInTheLastIntervalSentence, getInThePreviousIntervalSentence, getPostgresBasicType, isColumnComparison, isDateTruncEquals, isInTheLastInterval, isNodeEmptyCollection, isTheCurrentInterval, isThePreviousInterval, isTopLevelBoolean, showNodeAsRow, tryConvertDateEquality, removeNonSelectedTableReferences, } from './components/ReportBuilder/util';
@@ -19,10 +21,10 @@ import AddColumnPopover from './components/ReportBuilder/AddColumnPopover';
19
21
  import { AddSortPopover, SortSentence, } from './components/ReportBuilder/AddSortPopover';
20
22
  import { PivotModal, generatePivotTable, } from './internals/ReportBuilder/PivotModal';
21
23
  import { PivotCard } from './internals/ReportBuilder/PivotList';
22
- import QuillTable from './components/QuillTable';
23
- import { QuillSelectComponent } from './components/QuillSelect';
24
24
  import { snakeCaseToTitleCase } from './utils/textProcessing';
25
25
  import { AddLimitPopover, LimitSentence, } from './components/ReportBuilder/AddLimitPopover';
26
+ import { updateFirstChildWidth } from './utils/width';
27
+ import { QuillSelectComponent } from './components/QuillSelect';
26
28
  /**
27
29
  * Quill Report Builder
28
30
  *
@@ -30,8 +32,31 @@ import { AddLimitPopover, LimitSentence, } from './components/ReportBuilder/AddL
30
32
  * then edit them on the fly. Once users have constructed a query they like,
31
33
  * they can click a button and add that report to their dashboard or export it
32
34
  * as a CSV.
35
+ *
36
+ * @example
37
+ * ```js
38
+ * // Usage without custom components
39
+ * <ReportBuilder />
40
+ * ```
41
+ *
42
+ * @example
43
+ * ```js
44
+ * // You can also pass your own components
45
+ * <ReportBuilder
46
+ * initialTableName="transactions"
47
+ * TableComponent={MyTable}
48
+ * SelectComponent={MySelect}
49
+ * ButtonComponent={MyButton}
50
+ * PopoverComponent={MyPopover}
51
+ * TextInputComponent={MyTextInput}
52
+ * containerStyle={{ backgroundColor: 'white', padding: '10px' }}
53
+ * />
54
+ * ```
55
+ *
56
+ * ### Report Builder API
57
+ * @see https://docs.quillsql.com/components/report-builder
33
58
  */
34
- export default function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () => void null, destinationDashboard = undefined, organizationName = '', Button = MemoizedButton, SecondaryButton = MemoizedSecondaryButton, TextInput = QuillTextInput, Select = QuillSelectComponent, Table = QuillTable, Popover = QuillPopover, Tabs = QuillTabs, Checkbox = MemoizedCheckbox, Sidebar = QuillSidebar, Container = CustomContainer, HandleButton = QuillHandleButton, SelectColumn = QuillSelectColumn, DraggableColumn = QuillDraggableColumn, ButtonLoadingState = QuillButtonLoadingState, TableLoadingState = QuillTableLoadingState, SidebarHeading = QuillSidebarHeading, SidebarSubHeading = QuillSidebarSubHeading, FilterPopover = QuillFilterPopover, SortPopover = QuillSortPopover, Label = MemoizedLabel, Header = MemoizedHeader, Text = MemoizedText, PivotPopover = MemoizedPopover, admin = false, hideAi = false, containerStyle, }) {
59
+ export default function ReportBuilder({ initialTableName = '', onSubmitChartBuilder = () => void null, destinationDashboard = undefined, organizationName = '', ButtonComponent = MemoizedButton, SecondaryButtonComponent = MemoizedSecondaryButton, DeleteButtonComponent = MemoizedDeleteButton, ModalComponent = MemoizedModal, TextInputComponent = QuillTextInput, SelectComponent = QuillSelectComponent, TableComponent = QuillTableComponent, PopoverComponent = MemoizedPopover, TabsComponent = QuillTabs, CheckboxComponent = MemoizedCheckbox, SidebarComponent = QuillSidebar, ContainerComponent = CustomContainer, SelectColumnComponent = QuillSelectColumn, DraggableColumnComponent = QuillDraggableColumn, SidebarHeadingComponent = QuillSidebarHeading, FilterPopoverComponent = QuillFilterPopover, SortPopoverComponent = QuillSortPopover, LimitPopoverComponent = QuillLimitPopover, LabelComponent = MemoizedLabel, HeaderComponent = MemoizedHeader, TextComponent = MemoizedText, isAdminEnabled = false, isAIEnabled = true, containerStyle, }) {
35
60
  const [aiPrompt, setAiPrompt] = useState('');
36
61
  const [errorMessage, setErrorMessage] = useState('');
37
62
  const [baseAst, setBaseAst] = useState(null);
@@ -44,6 +69,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
44
69
  const [activePath, setActivePath] = useState(null);
45
70
  const [openPopover, setOpenPopover] = useState(null);
46
71
  const [loading, setLoading] = useState(false);
72
+ const [loadingSchema, setLoadingSchema] = useState(false);
47
73
  const [isChartBuilderOpen, setIsChartBuilderOpen] = useState(false);
48
74
  const [isPending, setIsPending] = useState(false);
49
75
  const [isCopying, setIsCopying] = useState(false);
@@ -63,6 +89,10 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
63
89
  const [initialLoad, setInitialLoad] = useState(true);
64
90
  const [currentTable, setCurrentTable] = useState(initialTableName || '');
65
91
  const parentRef = useRef(null);
92
+ const askAIContainerRef = useRef(null);
93
+ const askAILoadingContainerRef = useRef(null);
94
+ const [askAIInputWidth, setAskAIInputWidth] = useState(200);
95
+ const [askAILoadingContainerWidth, setAskAILoadingContainerWidth] = useState(200);
66
96
  const [theme] = useContext(ThemeContext);
67
97
  const [pivotRowField, setPivotRowField] = useState(undefined);
68
98
  const [pivotColumnField, setPivotColumnField] = useState(undefined);
@@ -70,6 +100,19 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
70
100
  const [pivotAggregation, setPivotAggregation] = useState(undefined);
71
101
  // eslint-disable-next-line no-unused-vars
72
102
  const [client, _setClient] = useContext(ClientContext);
103
+ useEffect(() => {
104
+ // Since the TextInput component takes a required numeric width parameter,
105
+ // we dynamically calculate the width of this component here.
106
+ function handleResize() {
107
+ updateFirstChildWidth(askAIContainerRef, setAskAIInputWidth, { gap: 12 });
108
+ updateFirstChildWidth(askAILoadingContainerRef, setAskAILoadingContainerWidth, { gap: 12 });
109
+ }
110
+ handleResize();
111
+ window.addEventListener('resize', handleResize);
112
+ return () => {
113
+ window.removeEventListener('resize', handleResize);
114
+ };
115
+ }, [baseAst, loading]);
73
116
  const enforceOrderOnColumns = (columnNames) => {
74
117
  if (pivot) {
75
118
  const rowName = pivot.rowField;
@@ -105,9 +148,9 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
105
148
  setAiPrompt('');
106
149
  setBaseAst(null);
107
150
  setFormData(null);
108
- setOrderedColumnNames([]);
109
151
  setSelectedColumns([]);
110
152
  setSchemaTables([]);
153
+ setOrderedColumnNames([]);
111
154
  setActiveQuery('');
112
155
  setActiveEditItem(null);
113
156
  setActivePath(null);
@@ -118,6 +161,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
118
161
  setFields([]);
119
162
  setTopLevelBinaryOperator('AND');
120
163
  setEditPopoverKey(null);
164
+ setErrorMessage('');
121
165
  // setUniqueValues({});
122
166
  setPivot(null);
123
167
  setPivotData(null);
@@ -217,7 +261,9 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
217
261
  const result = [];
218
262
  const table = tables[0];
219
263
  const { valueField, rowField, columnField } = pivot;
220
- if (columnField && uniqueValues[table][columnField]) {
264
+ if (columnField &&
265
+ uniqueValues[table] &&
266
+ uniqueValues[table][columnField]) {
221
267
  result.push(...Object.keys(uniqueValues[table][columnField]));
222
268
  }
223
269
  result.push(valueField, rowField);
@@ -255,8 +301,29 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
255
301
  }
256
302
  };
257
303
  useEffect(() => {
304
+ const loadTable = async (tables) => {
305
+ if (!tables)
306
+ return;
307
+ setLoading(true);
308
+ await getDistinctValues(initialTableName, tables);
309
+ const columnsForTable = tables
310
+ .find((t) => t.name === initialTableName)
311
+ ?.columns.map((c) => c.name)
312
+ .sort((a, b) => {
313
+ const aIsId = a.endsWith('.id') || a.endsWith('_id') || a.endsWith('Id');
314
+ const bIsId = b.endsWith('.id') || b.endsWith('_id') || b.endsWith('Id');
315
+ if (aIsId && !bIsId)
316
+ return 1;
317
+ if (bIsId && !aIsId)
318
+ return -1;
319
+ return 0;
320
+ });
321
+ await handleAsk(`get ${columnsForTable} from ${initialTableName}`);
322
+ setInitialLoad(false);
323
+ };
258
324
  const fetchSchema = async () => {
259
325
  try {
326
+ setLoadingSchema(true);
260
327
  const response = await fetch(`${client.queryEndpoint}`, {
261
328
  method: 'POST',
262
329
  headers: {
@@ -279,8 +346,8 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
279
346
  setOrderedColumnNames((tables ?? []).flatMap((table) => table.columns
280
347
  .map((c) => `${table.name}.${c.name}`)
281
348
  .sort((a, b) => {
282
- const aIsId = a.endsWith('.id') || a.endsWith('_id');
283
- const bIsId = b.endsWith('.id') || b.endsWith('_id');
349
+ const aIsId = a.endsWith('.id') || a.endsWith('_id') || a.endsWith('Id');
350
+ const bIsId = b.endsWith('.id') || b.endsWith('_id') || b.endsWith('Id');
284
351
  if (aIsId && !bIsId)
285
352
  return 1;
286
353
  if (bIsId && !aIsId)
@@ -288,14 +355,9 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
288
355
  return 0;
289
356
  })));
290
357
  if (initialTableName && initialLoad) {
291
- setInitialLoad(false);
292
- setLoading(true);
293
- await getDistinctValues(initialTableName, tables);
294
- const columnsForTable = tables
295
- .find((t) => t.name === initialTableName)
296
- ?.columns.map((c) => c.name);
297
- await handleAsk(`get ${columnsForTable} from ${initialTableName}`);
358
+ await loadTable(tables);
298
359
  }
360
+ setLoadingSchema(false);
299
361
  }
300
362
  catch (error) {
301
363
  console.error(error);
@@ -304,7 +366,10 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
304
366
  if (schemaTables.length === 0) {
305
367
  fetchSchema();
306
368
  }
307
- }, [schemaTables]);
369
+ else if (initialLoad && initialTableName) {
370
+ loadTable(schemaTables);
371
+ }
372
+ }, [schemaTables, initialTableName]);
308
373
  const updateFormData = (updates, { isDeletion = false, isInsertion = false, isReplaceSubtree = false, isAddVariant = false, isDeleteVariant = false, topLevelBinOp = 'OR', isCondition = undefined, }) => {
309
374
  // Function to immutably update or delete nodes based on their path
310
375
  // TODO: fix the following horible code
@@ -711,7 +776,9 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
711
776
  // see onChange callback handleChange
712
777
  // eslint-disable-next-line no-unused-vars
713
778
  dateColumnPath, dateFilterType, intervalCount, intervalType, intervalPaths, } = getDateFilterInfo(node);
714
- const isPlural = intervalCount && intervalCount > 1 ? 's' : '';
779
+ const isPlural = intervalCount !== 1 && dateFilterType !== 'in the current'
780
+ ? 's'
781
+ : '';
715
782
  // Pull off the string literal date for "equals" comparisons
716
783
  const rawDateStringEquals = node.right?.value ??
717
784
  node.right?.args?.value[1]?.column ??
@@ -721,50 +788,50 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
721
788
  'node.right.args.value.1.column') ??
722
789
  (node.right?.args?.value[1]?.value &&
723
790
  'node.right.args.value.1.value');
724
- return (_jsxs("div", { style: { display: 'flex', gap: 20 }, children: [_jsx(Select, { theme: theme, value: dateColumn, onChange: (value) => {
725
- const columnType = getColumnTypeByName(value);
791
+ return (_jsxs("div", { style: { display: 'flex', gap: 20 }, children: [_jsx(SelectComponent, { value: dateColumn, onChange: (event) => {
792
+ const columnType = getColumnTypeByName(event.target.value);
726
793
  if (isDateishColumnType(columnType)) {
727
794
  // handleChange(value, keyPrefix + dateColumnPath, "text");
728
- handleOperatorChange('IN_THE_LAST', node, keyPrefix, value);
795
+ handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
729
796
  }
730
797
  else if (isNumericColumnType(columnType)) {
731
798
  const newSubtree = deepCopy(defaultNumericComparison);
732
- newSubtree.left.column = value;
799
+ newSubtree.left.column = event.target.value;
733
800
  handleReplaceSubtree(keyPrefix, newSubtree);
734
801
  }
735
802
  else {
736
803
  const newSubtree = deepCopy(defaultEntry);
737
- newSubtree.left.args.value[0].column = value;
804
+ newSubtree.left.args.value[0].column = event.target.value;
738
805
  handleReplaceSubtree(keyPrefix, newSubtree);
739
806
  }
740
807
  }, options: getAllPossibleColumns().map((column) => ({
741
808
  label: snakeCaseToTitleCase(column.displayName),
742
809
  value: column.name,
743
- })) }), _jsx(Select, { theme: theme, value: dateFilterType, onChange: (value) => {
744
- if (value === dateFilterType)
810
+ })) }), _jsx(SelectComponent, { value: dateFilterType, onChange: (event) => {
811
+ if (event.target.value === dateFilterType)
745
812
  return null;
746
813
  let newSubtree = {};
747
814
  // TODO: implement one for each database type (eg. pg, snowflake, etc.)
748
- if (value === 'in the last') {
815
+ if (event.target.value === 'in the last') {
749
816
  newSubtree = generateLastNPeriodsPostgres({
750
817
  dateField: dateColumn,
751
818
  intervalPeriod: `${intervalCount ?? 1} ${intervalType}`,
752
819
  });
753
820
  }
754
- else if (value === 'in the previous') {
821
+ else if (event.target.value === 'in the previous') {
755
822
  newSubtree = generatePreviousPeriodPostgres({
756
823
  dateField: dateColumn,
757
824
  intervalPeriod: `${intervalCount ?? 1} ${intervalType}`,
758
825
  currentPeriod: intervalType,
759
826
  });
760
827
  }
761
- else if (value === 'in the current') {
828
+ else if (event.target.value === 'in the current') {
762
829
  newSubtree = generateCurrentPeriodPostgres({
763
830
  dateField: dateColumn,
764
831
  currentPeriod: intervalType,
765
832
  });
766
833
  }
767
- else if (value === 'equals') {
834
+ else if (event.target.value === 'equals') {
768
835
  newSubtree = generateEqualsPostgres({
769
836
  dateField: dateColumn,
770
837
  currentPeriod: intervalType,
@@ -778,21 +845,25 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
778
845
  { label: 'in the previous', value: 'in the previous' },
779
846
  { label: 'in the current', value: 'in the current' },
780
847
  { label: 'equals', value: 'equals' },
781
- ] }), !['in the current', 'equals'].includes(dateFilterType) && (_jsx(TextInput, { value: intervalCount, type: "number", style: { width: '70px' }, onChange: (e) => {
782
- const isPluralNow = e.target.value > 1 ? 's' : '';
848
+ ] }), !['in the current', 'equals'].includes(dateFilterType) && (_jsx(TextInputComponent, { id: "date_filter_interval_count", value: intervalCount?.toString() ?? '', width: 70, onChange: (e) => {
849
+ if (Number.isNaN(parseFloat(e.target.value || '0'))) {
850
+ alert('Please input a number.');
851
+ return;
852
+ }
853
+ const isPluralNow = parseFloat(e.target.value || '0') !== 1 ? 's' : '';
783
854
  intervalPaths.forEach((intervalPath) => handleChangeText([
784
855
  {
785
- value: `${e.target.value} ${intervalType}${isPluralNow}`,
856
+ value: `${e.target.value || 0} ${intervalType}${isPluralNow}`,
786
857
  path: keyPrefix + intervalPath,
787
858
  },
788
859
  ]));
789
- } })), _jsx(Select, { theme: theme, value: intervalType, onChange: (value) => {
860
+ } })), _jsx(SelectComponent, { value: intervalType, onChange: (event) => {
790
861
  if (intervalPaths.length === 1) {
791
862
  handleChangeText([
792
863
  {
793
864
  value: intervalCount !== null
794
- ? `${intervalCount} ${value}${isPlural}`
795
- : value,
865
+ ? `${intervalCount} ${event.target.value}${isPlural}`
866
+ : event.target.value,
796
867
  path: keyPrefix + intervalPaths[0],
797
868
  },
798
869
  ]);
@@ -802,14 +873,14 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
802
873
  if (dateFilterType === 'equals') {
803
874
  newSubtree = generateEqualsPostgres({
804
875
  dateField: dateColumn,
805
- currentPeriod: value,
876
+ currentPeriod: event.target.value,
806
877
  timestamp: rawDateStringEquals,
807
878
  });
808
879
  }
809
880
  else {
810
881
  newSubtree = generateCurrentPeriodPostgres({
811
882
  dateField: dateColumn,
812
- currentPeriod: value,
883
+ currentPeriod: event.target.value,
813
884
  });
814
885
  }
815
886
  handleReplaceSubtree(keyPrefix, newSubtree);
@@ -820,7 +891,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
820
891
  { label: `week${isPlural}`, value: 'week' },
821
892
  { label: `day${isPlural}`, value: 'day' },
822
893
  { label: `hour${isPlural}`, value: 'hour' },
823
- ] }), dateFilterType === 'equals' && (_jsx(TextInput, { value: rawDateStringEquals, type: "text", style: { width: '120px' }, onChange: (e) => {
894
+ ] }), dateFilterType === 'equals' && (_jsx(TextInputComponent, { id: "date_filter_equals_raw_date", value: rawDateStringEquals, width: 120, onChange: (e) => {
824
895
  handleChangeText([
825
896
  {
826
897
  value: e.target.value,
@@ -835,44 +906,49 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
835
906
  label: snakeCaseToTitleCase(column.displayName),
836
907
  value: column.name,
837
908
  }));
838
- const plural = node.right.args.value[1].expr.value > 1 ? 's' : '';
909
+ const plural = node.right.args.value[1].expr.value !== 1 ? 's' : '';
839
910
  return (_jsxs("div", { style: {
840
911
  display: 'flex',
841
912
  flexDirection: 'row',
842
913
  alignItems: 'center',
843
914
  gap: 20,
844
- }, children: [_jsx("div", { children: _jsx(Select, { theme: theme, value: node.left.column, onChange: (value) => {
845
- const columnType = getColumnTypeByName(value);
846
- if (isDateishColumnType(columnType)) {
847
- // handleChange(value, keyPrefix + dateColumnPath, "text");
848
- handleOperatorChange('IN_THE_LAST', node, keyPrefix, value);
849
- }
850
- else if (isNumericColumnType(columnType)) {
851
- const newSubtree = deepCopy(defaultNumericComparison);
852
- newSubtree.left.column = value;
853
- handleReplaceSubtree(keyPrefix, newSubtree);
854
- }
855
- else {
856
- const newSubtree = deepCopy(defaultEntry);
857
- newSubtree.left.args.value[0].column = value;
858
- handleReplaceSubtree(keyPrefix, newSubtree);
859
- }
860
- }, options: options }) }), _jsx(Select, { theme: theme, value: dateFilterType, onChange: (value) => {
861
- handleOperatorChange(value, node, keyPrefix, dateColumn);
915
+ }, children: [_jsx(SelectComponent, { value: node.left.column, onChange: (event) => {
916
+ const columnType = getColumnTypeByName(event.target.value);
917
+ if (isDateishColumnType(columnType)) {
918
+ // handleChange(value, keyPrefix + dateColumnPath, "text");
919
+ handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
920
+ }
921
+ else if (isNumericColumnType(columnType)) {
922
+ const newSubtree = deepCopy(defaultNumericComparison);
923
+ newSubtree.left.column = event.target.value;
924
+ handleReplaceSubtree(keyPrefix, newSubtree);
925
+ }
926
+ else {
927
+ const newSubtree = deepCopy(defaultEntry);
928
+ newSubtree.left.args.value[0].column = event.target.value;
929
+ handleReplaceSubtree(keyPrefix, newSubtree);
930
+ }
931
+ }, options: options }), _jsx(SelectComponent, { value: 'IN_THE_LAST', onChange: (event) => {
932
+ handleOperatorChange(event.target.value, node, keyPrefix, dateColumn);
862
933
  }, options: [
863
934
  { label: 'in the last', value: 'IN_THE_LAST' },
864
935
  { label: 'in the previous', value: 'IN_THE_PREVIOUS' },
865
936
  { label: 'in the current', value: 'IN_THE_CURRENT' },
937
+ { label: 'is not null', value: 'IS NOT' },
938
+ { label: 'is null', value: 'IS' },
866
939
  // { label: 'equals', value: 'equals' },
867
- ] }), _jsx(TextInput, { defaultValue: node.right.args.value[1].expr.value, type: "number", style: { width: '120px', height: '42px' }, min: 0, onBlur: (e) => {
940
+ ] }), _jsx(TextInputComponent, { id: 'date_window_interval_count', value: node.right.args.value[1].expr.value, width: 120, onChange: (e) => {
868
941
  handleChange([
869
942
  {
870
943
  value: e.target.value,
871
944
  path: keyPrefix + 'right.args.value||1.expr.value',
872
945
  },
873
946
  ]);
874
- } }), _jsx("div", { children: _jsx(Select, { theme: theme, value: node.right.args.value[1].unit, onChange: (value) => handleChange([
875
- { value, path: keyPrefix + 'right.args.value||1.unit' },
947
+ } }), _jsx("div", { children: _jsx(SelectComponent, { value: node.right.args.value[1].unit, onChange: (event) => handleChange([
948
+ {
949
+ value: event.target.value,
950
+ path: keyPrefix + 'right.args.value||1.unit',
951
+ },
876
952
  ]), options: [
877
953
  { label: `year${plural}`, value: '* 365 DAY' },
878
954
  { label: `month${plural}`, value: '* 30 DAY' },
@@ -891,33 +967,41 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
891
967
  flexDirection: 'row',
892
968
  alignItems: 'center',
893
969
  gap: 20,
894
- }, children: [_jsx(Select, { theme: theme, value: node.left.column, onChange: (value) => {
895
- const columnType = getColumnTypeByName(value);
970
+ }, children: [_jsx(SelectComponent, { value: node.left.column, onChange: (event) => {
971
+ const columnType = getColumnTypeByName(event.target.value);
896
972
  if (isDateishColumnType(columnType)) {
897
973
  // handleChange(value, keyPrefix + dateColumnPath, "text");
898
- handleOperatorChange('IN_THE_LAST', node, keyPrefix, value);
974
+ handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
899
975
  }
900
976
  else if (isNumericColumnType(columnType)) {
901
977
  const newSubtree = deepCopy(defaultNumericComparison);
902
- newSubtree.left.column = value;
978
+ newSubtree.left.column = event.target.value;
903
979
  handleReplaceSubtree(keyPrefix, newSubtree);
904
980
  }
905
981
  else {
906
982
  const newSubtree = deepCopy(defaultEntry);
907
- newSubtree.left.args.value[0].column = value;
983
+ newSubtree.left.args.value[0].column = event.target.value;
908
984
  handleReplaceSubtree(keyPrefix, newSubtree);
909
985
  }
910
- }, options: options }), _jsx(Select, { theme: theme, value: 'IN_THE_CURRENT', onChange: (value) => {
911
- handleOperatorChange(value, node, keyPrefix, node.left.column);
986
+ }, options: options }), _jsx(SelectComponent, { value: 'IN_THE_CURRENT', onChange: (event) => {
987
+ handleOperatorChange(event.target.value, node, keyPrefix, node.left.column);
912
988
  }, options: [
913
989
  { label: 'in the last', value: 'IN_THE_LAST' },
914
990
  { label: 'in the previous', value: 'IN_THE_PREVIOUS' },
915
991
  { label: 'in the current', value: 'IN_THE_CURRENT' },
992
+ { label: 'is not null', value: 'IS NOT' },
993
+ { label: 'is null', value: 'IS' },
916
994
  // { label: 'equals', value: 'equals' },
917
- ] }), _jsx(Select, { theme: theme, value: node.left.args.value[1].column, onChange: (value) => {
995
+ ] }), _jsx(SelectComponent, { value: node.left.args.value[1].column, onChange: (event) => {
918
996
  handleChange([
919
- { value, path: 'right.args.value||1.column' },
920
- { value, path: 'left.args.value||1.column' },
997
+ {
998
+ value: event.target.value,
999
+ path: 'right.args.value||1.column',
1000
+ },
1001
+ {
1002
+ value: event.target.value,
1003
+ path: 'left.args.value||1.column',
1004
+ },
921
1005
  ]);
922
1006
  }, options: [
923
1007
  { label: `year`, value: 'YEAR' },
@@ -936,30 +1020,32 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
936
1020
  flexDirection: 'row',
937
1021
  alignItems: 'center',
938
1022
  gap: 20,
939
- }, children: [_jsx(Select, { theme: theme, value: node.left.column, onChange: (value) => {
940
- const columnType = getColumnTypeByName(value);
1023
+ }, children: [_jsx(SelectComponent, { value: node.left.column, onChange: (event) => {
1024
+ const columnType = getColumnTypeByName(event.target.value);
941
1025
  if (isDateishColumnType(columnType)) {
942
1026
  // handleChange(value, keyPrefix + dateColumnPath, "text");
943
- handleOperatorChange('IN_THE_LAST', node, keyPrefix, value);
1027
+ handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
944
1028
  }
945
1029
  else if (isNumericColumnType(columnType)) {
946
1030
  const newSubtree = deepCopy(defaultNumericComparison);
947
- newSubtree.left.column = value;
1031
+ newSubtree.left.column = event.target.value;
948
1032
  handleReplaceSubtree(keyPrefix, newSubtree);
949
1033
  }
950
1034
  else {
951
1035
  const newSubtree = deepCopy(defaultEntry);
952
- newSubtree.left.args.value[0].column = value;
1036
+ newSubtree.left.args.value[0].column = event.target.value;
953
1037
  handleReplaceSubtree(keyPrefix, newSubtree);
954
1038
  }
955
- }, opt: true, options: options }), _jsx(Select, { theme: theme, value: 'IN_THE_PREVIOUS', onChange: (value) => {
956
- handleOperatorChange(value, node, keyPrefix, node.left.column);
1039
+ }, options: options }), _jsx(SelectComponent, { value: 'IN_THE_PREVIOUS', onChange: (event) => {
1040
+ handleOperatorChange(event.target.value, node, keyPrefix, node.left.column);
957
1041
  }, options: [
958
1042
  { label: 'in the last', value: 'IN_THE_LAST' },
959
1043
  { label: 'in the previous', value: 'IN_THE_PREVIOUS' },
960
1044
  { label: 'in the current', value: 'IN_THE_CURRENT' },
1045
+ { label: 'is not null', value: 'IS NOT' },
1046
+ { label: 'is null', value: 'IS' },
961
1047
  // { label: 'equals', value: 'equals' },
962
- ] }), _jsx(Select, { theme: theme, value: node.left.args.value[1].column, onChange: (value) => {
1048
+ ] }), _jsx(SelectComponent, { value: node.left.args.value[1].column, onChange: (event) => {
963
1049
  const dayConversion = {
964
1050
  YEAR: 365,
965
1051
  QUARTER: 90,
@@ -968,15 +1054,15 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
968
1054
  };
969
1055
  handleChange([
970
1056
  {
971
- value,
1057
+ value: event.target.value,
972
1058
  path: 'left.args.value||1.column',
973
1059
  },
974
1060
  {
975
- value,
1061
+ value: event.target.value,
976
1062
  path: 'right.args.value||1.column',
977
1063
  },
978
1064
  {
979
- value: dayConversion[value] || 30,
1065
+ value: dayConversion[event.target.value] || 30,
980
1066
  path: 'right.args.value||0.args.value||1.expr.value',
981
1067
  },
982
1068
  ]);
@@ -1001,7 +1087,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1001
1087
  const tables = getTableNames(baseAst);
1002
1088
  const table = tables.length === 1 ? tables[0] : initialTableName;
1003
1089
  const columnType = column?.fieldType;
1004
- const operatorOptions = [
1090
+ let operatorOptions = [
1005
1091
  ...(isNumericColumnType(columnType)
1006
1092
  ? [
1007
1093
  { label: 'equal to', value: '=' },
@@ -1016,10 +1102,10 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1016
1102
  : []),
1017
1103
  ...(isTextColumnType(columnType)
1018
1104
  ? [
1019
- { label: 'is', value: 'LIKE' },
1020
- { label: 'is not', value: 'NOT LIKE' },
1021
- { label: 'is one of', value: 'IN' },
1022
- { label: 'is not one of', value: 'NOT IN' },
1105
+ { label: 'is exactly', value: 'LIKE' },
1106
+ { label: 'is not exactly', value: 'NOT LIKE' },
1107
+ { label: 'is', value: 'IN' },
1108
+ { label: 'is not', value: 'NOT IN' },
1023
1109
  { label: 'is not null', value: 'IS NOT' },
1024
1110
  { label: 'is null', value: 'IS' },
1025
1111
  ]
@@ -1038,6 +1124,10 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1038
1124
  ]
1039
1125
  : []),
1040
1126
  ];
1127
+ if (client.databaseType === 'BigQuery' &&
1128
+ isDateishColumnType(columnType)) {
1129
+ operatorOptions = operatorOptions.filter((option) => option.value !== 'equals');
1130
+ }
1041
1131
  return (_jsxs("div", { style: {
1042
1132
  display: 'flex',
1043
1133
  gap: 12,
@@ -1047,45 +1137,48 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1047
1137
  }, children: [_jsxs("div", { style: {
1048
1138
  display: 'flex',
1049
1139
  gap: 20,
1050
- // justifyContent: "space-between",
1051
1140
  flexDirection: showNodeAsRow(node, formData)
1052
1141
  ? 'row'
1053
1142
  : 'column',
1054
1143
  width: '100%',
1055
- }, children: [_jsx(Select, { theme: theme, style: { width: 'min-content' }, value: leftChildValue, onChange: (value) => {
1056
- const columnType = getColumnTypeByName(value);
1144
+ }, children: [_jsx(SelectComponent, { value: leftChildValue, onChange: (event) => {
1145
+ const columnType = getColumnTypeByName(event.target.value);
1057
1146
  if (isDateishColumnType(columnType)) {
1058
- handleOperatorChange('IN_THE_LAST', node, keyPrefix, value);
1147
+ handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
1059
1148
  }
1060
1149
  else if (isNumericColumnType(columnType)) {
1061
1150
  const newSubtree = deepCopy(defaultNumericComparison);
1062
- newSubtree.left.column = value;
1151
+ newSubtree.left.column = event.target.value;
1063
1152
  handleReplaceSubtree(keyPrefix, newSubtree);
1064
1153
  }
1065
1154
  else {
1066
1155
  const newSubtree = deepCopy(defaultEntry);
1067
- newSubtree.left.args.value[0].column = value;
1156
+ newSubtree.left.args.value[0].column = event.target.value;
1068
1157
  handleReplaceSubtree(keyPrefix, newSubtree);
1069
1158
  }
1070
- }, options: options }), operatorOptions.length > 0 && (_jsx(Select, { theme: theme, value: node.operator, onChange: (value) => {
1071
- handleOperatorChange(value, node, keyPrefix, leftChildValue);
1072
- }, style: { width: 'min-content' }, options: operatorOptions })), node.right &&
1159
+ }, options: options }), operatorOptions.length > 0 && (_jsx(SelectComponent, { value: node.operator, onChange: (event) => {
1160
+ handleOperatorChange(event.target.value, node, keyPrefix, leftChildValue);
1161
+ }, options: operatorOptions })), node.right &&
1073
1162
  node.right.type !== 'expr_list' &&
1074
1163
  renderNode(node.right, keyPrefix + 'right.')] }, keyPrefix), node.right && node.right.type === 'expr_list' && (_jsx("div", { style: {
1075
1164
  display: 'grid',
1076
1165
  gridTemplateColumns: 'repeat(2, 1fr)',
1077
1166
  gap: 12,
1078
- }, children: Object.keys(uniqueValues[table][leftChildValue] ?? {}).map((key) => (_jsxs("label", { style: { display: 'flex', gap: 2 }, children: [_jsx(Checkbox, { checked: uniqueValues[table][leftChildValue][key], onChange: (checked) => {
1079
- const newValues = deepCopy(uniqueValues);
1080
- newValues[table][leftChildValue][key] = checked;
1081
- setUniqueValues(newValues);
1082
- if (checked) {
1083
- handleInsertVariant(keyPrefix + 'right.' + 'value', key);
1084
- }
1085
- else {
1086
- handleDeleteVariant(keyPrefix + 'right.' + 'value', key);
1087
- }
1088
- } }), _jsx("span", { style: { fontFamily: theme.fontFamily }, children: key })] }, key))) }, keyPrefix + 'right.'))] }));
1167
+ }, children: uniqueValues[table] &&
1168
+ Object.keys(uniqueValues[table][leftChildValue] ?? {}).map((key) => (_jsxs("label", { style: { display: 'flex', gap: 4 }, children: [_jsx(CheckboxComponent, { isChecked: uniqueValues[table][leftChildValue][key], onChange: (event) => {
1169
+ const newValues = deepCopy(uniqueValues);
1170
+ newValues[table][leftChildValue][key] = event.target.checked;
1171
+ setUniqueValues(newValues);
1172
+ if (event.target.checked) {
1173
+ handleInsertVariant(keyPrefix + 'right.' + 'value', key);
1174
+ }
1175
+ else {
1176
+ handleDeleteVariant(keyPrefix + 'right.' + 'value', key);
1177
+ }
1178
+ } }), _jsx("span", { style: {
1179
+ fontFamily: theme.fontFamily,
1180
+ margin: 'auto 0',
1181
+ }, children: key })] }, key))) }, keyPrefix + 'right.'))] }));
1089
1182
  }
1090
1183
  else {
1091
1184
  const columnName = node.left.column;
@@ -1097,9 +1190,9 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1097
1190
  justifyContent: 'space-between',
1098
1191
  flexDirection: showNodeAsRow(node, formData) ? 'row' : 'column',
1099
1192
  width: '100%',
1100
- }, children: [node.left && renderNode(node.left, keyPrefix + 'left.'), _jsx(Select, { theme: theme, value: node.operator, onChange: (value) => {
1101
- handleOperatorChange(value, node, keyPrefix);
1102
- }, style: { width: `100%` }, options: [
1193
+ }, children: [node.left && renderNode(node.left, keyPrefix + 'left.'), _jsx(SelectComponent, { value: node.operator, onChange: (event) => {
1194
+ handleOperatorChange(event.target.value, node, keyPrefix);
1195
+ }, options: [
1103
1196
  // { label: `and`, value: "AND" },
1104
1197
  // { label: `or`, value: "OR" },
1105
1198
  ...(isNumericColumnType(columnType)
@@ -1116,10 +1209,10 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1116
1209
  : []),
1117
1210
  ...(isTextColumnType(columnType)
1118
1211
  ? [
1119
- { label: 'is', value: 'LIKE' },
1120
- { label: 'is not', value: 'NOT LIKE' },
1121
- { label: 'is one of', value: 'IN' },
1122
- { label: 'is not one of', value: 'NOT IN' },
1212
+ { label: 'is exactly', value: 'LIKE' },
1213
+ { label: 'is not exactly', value: 'NOT LIKE' },
1214
+ { label: 'is', value: 'IN' },
1215
+ { label: 'is not', value: 'NOT IN' },
1123
1216
  { label: 'is not null', value: 'IS NOT' },
1124
1217
  { label: 'is null', value: 'IS' },
1125
1218
  ]
@@ -1142,45 +1235,41 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1142
1235
  label: snakeCaseToTitleCase(column.displayName),
1143
1236
  value: column.name,
1144
1237
  }));
1145
- return (_jsx(Select, { theme: theme, style: { width: '120px' }, value: node.column ?? options[0]?.value, onChange: (value) => {
1146
- handleChange([{ value, path: keyPrefix + 'column' }]);
1238
+ return (_jsx(SelectComponent, { value: node.column ?? options[0]?.value, onChange: (event) => {
1239
+ handleChange([
1240
+ { value: event.target.value, path: keyPrefix + 'column' },
1241
+ ]);
1147
1242
  }, options: options }));
1148
1243
  }
1149
1244
  case 'expr_list': {
1150
1245
  const len = node.value.length;
1151
1246
  return (_jsxs("div", { style: { display: 'flex', flexDirection: 'row', gap: 12 }, children: [node.value.map((elem, index) => {
1152
1247
  if (elem.value) {
1153
- return (_jsx(TextInput, { type: elem.type === 'number' ? 'number' : 'text', defaultValue: elem.value, onBlur: (e) => handleChange([
1248
+ return (_jsx(TextInputComponent, { id: `expr_list_${index}`, width: 200, value: elem.value, onChange: (e) => handleChange([
1154
1249
  {
1155
- value: elem.type === 'number'
1156
- ? parseFloat(e.target.value)
1157
- : e.target.value,
1250
+ value: e.target.value,
1158
1251
  path: keyPrefix + `value.${index}.`,
1159
1252
  },
1160
1253
  ]) }, `input_${index}`));
1161
1254
  }
1162
1255
  return renderNode(elem, keyPrefix + `value.${index}.`);
1163
- }), len > 1 && (_jsx(SecondaryButton, { label: '-', onClick: () => handleDeleteVariant(keyPrefix + 'value') })), _jsx(SecondaryButton, { onClick: () => handleInsertVariant(keyPrefix + 'value'), label: '+' })] }, keyPrefix));
1256
+ }), len > 1 && (_jsx(SecondaryButtonComponent, { label: '-', onClick: () => handleDeleteVariant(keyPrefix + 'value') })), _jsx(SecondaryButtonComponent, { onClick: () => handleInsertVariant(keyPrefix + 'value'), label: '+' })] }, keyPrefix));
1164
1257
  }
1165
1258
  case 'double_quote_string':
1166
1259
  case 'single_quote_string':
1167
- return (_jsx(TextInput, { type: "text", defaultValue: node.value.replaceAll('%', ''), style: { width: '120px' }, onBlur: (e) => handleChange([
1260
+ return (_jsx(TextInputComponent, { id: 'quoted_string', value: node.value.replaceAll('%', ''), width: 120, onChange: (e) => handleChange([
1168
1261
  {
1169
- value: node.type === 'number'
1170
- ? parseFloat(e.target.value)
1171
- : e.target.value,
1262
+ value: e.target.value,
1172
1263
  path: keyPrefix + 'value',
1173
1264
  },
1174
1265
  ]) }));
1175
1266
  case 'null':
1176
1267
  return _jsx("div", {});
1177
1268
  case 'number':
1178
- return (_jsx(TextInput, { defaultValue: node.value, type: "number", style: { width: '120px' }, onBlur: (e) => {
1269
+ return (_jsx(TextInputComponent, { id: "quill_number_input", value: node.value, width: 120, onChange: (e) => {
1179
1270
  handleChange([
1180
1271
  {
1181
- value: node.type === 'number'
1182
- ? parseFloat(e.target.value)
1183
- : e.target.value,
1272
+ value: e.target.value,
1184
1273
  path: keyPrefix + 'value',
1185
1274
  },
1186
1275
  ]);
@@ -1207,6 +1296,22 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1207
1296
  return null;
1208
1297
  }
1209
1298
  };
1299
+ const isValidPivot = (fields) => {
1300
+ let validPivot = true;
1301
+ if (pivot.rowField &&
1302
+ !fields.find((field) => field.name === pivot.rowField)) {
1303
+ validPivot = false;
1304
+ }
1305
+ if (pivot.valueField &&
1306
+ !fields.find((field) => field.name === pivot.valueField)) {
1307
+ validPivot = false;
1308
+ }
1309
+ if (pivot.columnField &&
1310
+ !fields.find((field) => field.name === pivot.columnField)) {
1311
+ validPivot = false;
1312
+ }
1313
+ return validPivot;
1314
+ };
1210
1315
  const renderSentence = (formData, node, keyPrefix = '',
1211
1316
  // @depreciated TODO: remove next update
1212
1317
  // eslint-disable-next-line no-unused-vars
@@ -1234,13 +1339,13 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1234
1339
  const OPS = {
1235
1340
  AND: 'and',
1236
1341
  OR: 'or',
1237
- LIKE: 'is',
1342
+ LIKE: 'is exactly',
1238
1343
  BETWEEN: 'is between',
1239
- IN: 'is one of',
1240
- 'NOT IN': 'is not one of',
1241
- 'NOT LIKE': 'is not',
1242
- '!=': 'is not',
1243
- '=': 'is',
1344
+ IN: 'is',
1345
+ 'NOT IN': 'is not',
1346
+ 'NOT LIKE': 'is not exactly',
1347
+ '!=': 'is not exactly',
1348
+ '=': 'is exactly',
1244
1349
  '<': 'is less than',
1245
1350
  '>': 'is greater than',
1246
1351
  '<=': 'is less than or equal to',
@@ -1248,25 +1353,16 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1248
1353
  '<>': 'is not',
1249
1354
  '-': 'minus',
1250
1355
  'IS NOT': 'is not',
1251
- IS: 'is ',
1356
+ IS: 'is',
1252
1357
  };
1253
1358
  switch (node.type) {
1254
1359
  case 'binary_expr':
1255
- return (_jsx(TagWrapper, { keyPrefix: keyPrefix, formData: formData, activeEditItem: activeEditItem, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setCheckboxes: setCheckboxes, handleReplaceSubtree: handleReplaceSubtree, FilterPopover: FilterPopover, setActivePath: setActivePath, setOpenPopover: setOpenPopover, setIsPending: setIsPending, clearCheckboxes: clearCheckboxes, fetchSqlQuery: fetchSqlQuery, handleDelete: handleDelete, editPopoverKey: editPopoverKey, isCard: isCard, isRow: isRow, getByKey: getByKey, node: node, EditPopover: EditPopover, Button: Button, renderNode: renderNode, Popover: Popover, style: {
1256
- display: 'flex',
1257
- gap: 3,
1258
- flexDirection: isRow ? 'row' : 'column',
1259
- padding: '1px',
1260
- border: isCard ? '1px solid black' : 'none',
1261
- whiteSpace: 'nowrap',
1262
- overflow: 'hidden',
1263
- textOverflow: 'ellipsis',
1264
- }, children: dateComparisonPartialMatch ??
1360
+ 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, fetchSqlQuery: fetchSqlQuery, handleDelete: handleDelete, editPopoverKey: editPopoverKey, isCard: isCard, isRow: isRow, getByKey: getByKey, EditPopover: EditPopover, Button: ButtonComponent, renderNode: renderNode, children: dateComparisonPartialMatch ??
1265
1361
  dateEqualityPartialMatch ??
1266
1362
  isInTheCurrentIntervalSentence ??
1267
1363
  isInTheLastIntervalSentence ??
1268
1364
  isInThePreviousIntervalSentence ?? (_jsxs(_Fragment, { children: [node.left &&
1269
- 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: Select })) : null, node.right &&
1365
+ 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 &&
1270
1366
  renderSentence(formData, node.right, keyPrefix + 'right.', false, false, isRow)] })) }));
1271
1367
  case 'column_ref':
1272
1368
  return snakeCaseToTitleCase(node.column);
@@ -1301,6 +1397,9 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1301
1397
  if (node.args.value.length < 1)
1302
1398
  return null;
1303
1399
  if (node.args.value[0].value) {
1400
+ if (node.args.value[0].type === 'single_quote_string') {
1401
+ return node.args.value[0].value.replaceAll('%', '');
1402
+ }
1304
1403
  return snakeCaseToTitleCase(node.args.value[0].value.replaceAll('%', ''));
1305
1404
  }
1306
1405
  if (node.args.value[0].column)
@@ -1348,9 +1447,11 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1348
1447
  }))
1349
1448
  .sort((a, b) => {
1350
1449
  const aIsId = a.name.toLowerCase() === 'id' ||
1351
- a.name.toLowerCase().endsWith('_id');
1450
+ a.name.toLowerCase().endsWith('_id') ||
1451
+ a.name.endsWith('Id');
1352
1452
  const bIsId = b.name.toLowerCase() === 'id' ||
1353
- b.name.toLowerCase().endsWith('_id');
1453
+ b.name.toLowerCase().endsWith('_id') ||
1454
+ b.name.endsWith('Id');
1354
1455
  if (aIsId && !bIsId)
1355
1456
  return 1;
1356
1457
  if (bIsId && !aIsId)
@@ -1367,7 +1468,8 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1367
1468
  return false;
1368
1469
  const allColumns = orderedColumnNames.filter((row) => {
1369
1470
  const [table, _] = row.split('.');
1370
- return selectedColumns[0].startsWith(table);
1471
+ const selectedTable = selectedColumns[0].split('.')[0];
1472
+ return selectedTable === table;
1371
1473
  });
1372
1474
  return selectedColumns.length === allColumns.length;
1373
1475
  };
@@ -1386,12 +1488,12 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1386
1488
  fontSize: 18,
1387
1489
  margin: 0,
1388
1490
  textAlign: 'left',
1389
- }, children: "Add condition" }), _jsx(Tabs, { defaultValue: topLevelBinaryOperator, options: DEFAULT_TAB_OPTIONS, onValueChange: (value) => setTopLevelBinaryOperator(value) }), activeEditItem && renderNode(activeEditItem), _jsx("div", { style: {
1491
+ }, children: "Add condition" }), _jsx(TabsComponent, { value: topLevelBinaryOperator, options: DEFAULT_TAB_OPTIONS, onChange: (event) => setTopLevelBinaryOperator(event.target.value) }), activeEditItem && renderNode(activeEditItem), _jsx("div", { style: {
1390
1492
  display: 'flex',
1391
1493
  flexDirection: 'row',
1392
1494
  gap: 8,
1393
1495
  justifyContent: 'end',
1394
- }, children: _jsx(Button, { onClick: onSave, label: 'Add condition' }) })] }));
1496
+ }, children: _jsx(ButtonComponent, { onClick: onSave, label: 'Add condition' }) })] }));
1395
1497
  };
1396
1498
  const fetchUponChange = async (baseAst, newFormData) => {
1397
1499
  // if newFormData is null still use it
@@ -1410,26 +1512,24 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1410
1512
  orgId: client.customerId,
1411
1513
  }),
1412
1514
  });
1515
+ const tables = getTableNames(baseAst);
1516
+ const table = tables.length >= 1 ? tables[0] : initialTableName;
1517
+ if (table !== currentTable) {
1518
+ await getDistinctValues(table);
1519
+ setCurrentTable(table);
1520
+ }
1413
1521
  const data2 = await res2.json();
1414
1522
  if (data2.rows && data2.rows.length) {
1415
1523
  const tables = getTableNames(baseAst);
1416
- const table = tables.length >= 1 ? tables[0] : initialTableName;
1417
- if (table !== currentTable) {
1418
- getDistinctValues(table);
1419
- setCurrentTable(table);
1420
- }
1421
- const sortedFields = data2.fields.sort((a, b) => {
1422
- const aIsId = a.name.toLowerCase() === 'id' ||
1423
- a.name.toLowerCase().endsWith('_id');
1424
- const bIsId = b.name.toLowerCase() === 'id' ||
1425
- b.name.toLowerCase().endsWith('_id');
1426
- if (aIsId && !bIsId)
1427
- return 1;
1428
- if (bIsId && !aIsId)
1429
- return -1;
1430
- return 0;
1431
- });
1432
1524
  if (pivot) {
1525
+ // check if any of the pivot fields aren't in the data2.fields array
1526
+ if (!isValidPivot(data2.fields)) {
1527
+ setPivot(null);
1528
+ setPivotData(null);
1529
+ setRows(data2.rows);
1530
+ setFields(data2.fields);
1531
+ return;
1532
+ }
1433
1533
  // Do all of this to make sure we have the right unique columns when applying a pivot
1434
1534
  let uniqueFormatted = {};
1435
1535
  const uniqueRecords = Array.from(new Set(data2.rows.map((row) => row[pivot.columnField]))).reduce((acc, curr) => {
@@ -1654,11 +1754,10 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1654
1754
  newAst = convertRemoveSimpleParentheses(newAst);
1655
1755
  const table = getTableNames(newAst)[0] ?? initialTableName;
1656
1756
  const tableAlias = getTableAliases(newAst)[0] ?? initialTableName;
1657
- newAst = removeNonSelectedTableReferences(newAst, tableAlias ?? table);
1757
+ newAst = removeNonSelectedTableReferences(newAst, tableAlias ?? table, getAllPossibleColumns().map((col) => col.name));
1658
1758
  // newAst = convertDateComparison(newAst); // TODO
1659
- ast = newAst; // so we fetch data for newAst later.
1660
1759
  if (table !== currentTable) {
1661
- getDistinctValues(table);
1760
+ await getDistinctValues(table);
1662
1761
  setCurrentTable(table);
1663
1762
  }
1664
1763
  setPivotRowField(groupByPivot?.rowField);
@@ -1676,6 +1775,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1676
1775
  }));
1677
1776
  if (groupByPivot) {
1678
1777
  setBaseAst(deepCopy({ ...newAst, orderby: null, limit: null }));
1778
+ newAst = deepCopy({ ...newAst, orderby: null, limit: null });
1679
1779
  }
1680
1780
  else {
1681
1781
  setBaseAst(deepCopy({ ...newAst }));
@@ -1685,6 +1785,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1685
1785
  // @ts-ignore
1686
1786
  newAst?.where ? newAst?.where?.operator : 'AND');
1687
1787
  }
1788
+ ast = newAst; // so we fetch data for newAst later.
1688
1789
  const res2 = await fetch('https://quill-344421.uc.r.appspot.com/patterns', {
1689
1790
  method: 'POST',
1690
1791
  headers: {
@@ -1765,11 +1866,11 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1765
1866
  fetchSqlQuery(newAst);
1766
1867
  };
1767
1868
  function TopLevelBooleanSwitch({ node, keyPrefix, handleOperatorChange, }) {
1768
- return (_jsx("div", { style: { width: 'fit-content' }, children: _jsx(Tabs, { defaultValue: node.operator, options: DEFAULT_TAB_OPTIONS, onValueChange: (value) => {
1869
+ return (_jsx("div", { style: { width: 'fit-content' }, children: _jsx(TabsComponent, { value: node.operator, options: DEFAULT_TAB_OPTIONS, onChange: (event) => {
1769
1870
  if (loading) {
1770
1871
  return;
1771
1872
  }
1772
- handleOperatorChange(value, node, keyPrefix);
1873
+ handleOperatorChange(event.target.value, node, keyPrefix);
1773
1874
  } }) }));
1774
1875
  }
1775
1876
  const DraggableItem = ({ id, label, onDelete }) => {
@@ -1778,9 +1879,9 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1778
1879
  transform: DND_CSS.Transform.toString(transform),
1779
1880
  transition,
1780
1881
  };
1781
- return (_jsx("div", { style: { ...style }, ref: setNodeRef, children: _jsx(DraggableColumn, { label: snakeCaseToTitleCase(label), onDelete: onDelete, children: _jsx("div", { style: {
1882
+ return (_jsx("div", { style: { ...style }, ref: setNodeRef, children: _jsx(DraggableColumnComponent, { label: snakeCaseToTitleCase(label), onDelete: onDelete, DragHandle: (props) => (_jsx("div", { style: {
1782
1883
  cursor: 'grab',
1783
- }, ...attributes, ...listeners, children: _jsx(HandleButton, {}) }) }) }));
1884
+ }, ...attributes, ...listeners, children: _jsx(props.dragIcon, {}) })) }) }));
1784
1885
  };
1785
1886
  function DraggableColumns() {
1786
1887
  const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
@@ -1790,8 +1891,8 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1790
1891
  function handleDragEnd(event) {
1791
1892
  const { active, over } = event;
1792
1893
  if (active.id !== over.id) {
1793
- const oldIndex = orderedColumnNames.findIndex((c) => c.endsWith(active.id));
1794
- const newIndex = orderedColumnNames.findIndex((c) => c.endsWith(over.id));
1894
+ const oldIndex = orderedColumnNames.findIndex((c) => c.endsWith(`${currentTable}.${active.id}`));
1895
+ const newIndex = orderedColumnNames.findIndex((c) => c.endsWith(`${currentTable}.${over.id}`));
1795
1896
  const newOrder = arrayMove(orderedColumnNames, oldIndex, newIndex);
1796
1897
  setOrderedColumnNames(newOrder);
1797
1898
  const orderedSelectedColumns = [];
@@ -1846,23 +1947,27 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1846
1947
  flexDirection: 'row',
1847
1948
  height: '100%',
1848
1949
  ...containerStyle,
1849
- }, ref: parentRef, children: [_jsxs(Sidebar, { children: [_jsx(SidebarHeading, { label: "Columns" }), _jsx("div", { style: { height: 4, width: '100%' } }), _jsx(DraggableColumns, {}), _jsx(Popover, { isOpen: openPopover === 'AddColumnPopover', trigger: _jsx(SecondaryButton, { onClick: () => {
1850
- if (!openPopover) {
1851
- setOpenPopover('AddColumnPopover');
1852
- }
1853
- }, label: 'Select columns' }), label: "Select columns", onClose: () => {
1854
- setIsPending(false);
1855
- setActiveEditItem(null);
1856
- setActivePath(null);
1857
- setOpenPopover(null);
1858
- }, children: _jsx(AddColumnPopover, { onSave: () => {
1950
+ }, ref: parentRef, children: [_jsxs(SidebarComponent, { children: [_jsx(SidebarHeadingComponent, { label: "Columns" }), _jsx("div", { style: { height: 4, width: '100%' } }), _jsx(DraggableColumns, {}), _jsx(SecondaryButtonComponent, { onClick: () => {
1951
+ if (loadingSchema)
1952
+ return;
1953
+ if (!openPopover) {
1954
+ setOpenPopover('AddColumnPopover');
1955
+ }
1956
+ }, label: 'Select columns' }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddColumnPopover', setIsOpen: (isOpen) => {
1957
+ if (!isOpen) {
1958
+ setIsPending(false);
1959
+ setActiveEditItem(null);
1960
+ setActivePath(null);
1961
+ setOpenPopover(null);
1962
+ }
1963
+ }, popoverTitle: "Select columns", popoverChildren: _jsx(AddColumnPopover, { onSave: () => {
1859
1964
  setActiveEditItem(null);
1860
1965
  setActivePath(null);
1861
1966
  setOpenPopover(null);
1862
1967
  }, orderedColumnNames: orderedColumnNames, setOrderedColumnNames: setOrderedColumnNames, selectedColumns: selectedColumns, setSelectedColumns: setSelectedColumns, isSelectedAllColumns: isSelectedAllColumns, clearAllState: clearAllState, nameToColumn: nameToColumn, baseAst: baseAst, setBaseAst: (newAst) => {
1863
1968
  setBaseAst(newAst);
1864
1969
  fetchSqlQuery(newAst);
1865
- }, pivot: pivot, initialTableName: initialTableName, defaultAST: defaultAST, defaultTable: defaultTable, setPivot: setPivot, TextInput: TextInput, SelectColumn: SelectColumn, SecondaryButton: SecondaryButton, Button: Button, HandleButton: HandleButton }) }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeading, { label: "Filters" }), _jsx("div", { style: { height: 4, width: '100%' } }), formData && (_jsx("div", { style: {
1970
+ }, pivot: pivot, initialTableName: initialTableName, defaultAST: defaultAST, defaultTable: defaultTable, setPivot: setPivot, TextInput: TextInputComponent, SelectColumn: SelectColumnComponent, SecondaryButton: SecondaryButtonComponent, Button: ButtonComponent }) }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeadingComponent, { label: "Filters" }), _jsx("div", { style: { height: 4, width: '100%' } }), formData && (_jsx("div", { style: {
1866
1971
  display: 'flex',
1867
1972
  flexDirection: 'column',
1868
1973
  gap: 8,
@@ -1872,37 +1977,41 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1872
1977
  flexDirection: 'column',
1873
1978
  gap: 2.5,
1874
1979
  alignItems: 'flex-start',
1875
- }, children: [_jsx(Popover, { isOpen: openPopover === 'AddFilterPopover', title: 'Add filter', trigger: _jsx(SecondaryButton, { onClick: () => {
1876
- if (!selectedColumns || selectedColumns.length === 0) {
1877
- return;
1980
+ }, children: [_jsx(SecondaryButtonComponent, { onClick: () => {
1981
+ if (!selectedColumns ||
1982
+ selectedColumns.length === 0 ||
1983
+ loading) {
1984
+ return;
1985
+ }
1986
+ if (!openPopover) {
1987
+ const value = orderedColumnNames[0];
1988
+ const [_table, column] = value.split('.');
1989
+ const columnType = getColumnTypeByName(column);
1990
+ if (isNumericColumnType(columnType)) {
1991
+ const newSubtree = deepCopy(defaultNumericComparison);
1992
+ newSubtree.left.column = column;
1993
+ setActiveEditItem(newSubtree);
1878
1994
  }
1879
- if (!openPopover) {
1880
- const value = orderedColumnNames[0];
1881
- const [_table, column] = value.split('.');
1882
- const columnType = getColumnTypeByName(column);
1883
- if (isNumericColumnType(columnType)) {
1884
- const newSubtree = deepCopy(defaultNumericComparison);
1885
- newSubtree.left.column = column;
1886
- setActiveEditItem(newSubtree);
1887
- }
1888
- else {
1889
- const newSubtree = deepCopy(defaultEntry);
1890
- newSubtree.left.args.value[0].column = column;
1891
- setActiveEditItem(newSubtree);
1892
- }
1893
- setOpenPopover('AddFilterPopover');
1894
- setActivePath('');
1895
- setIsPending(true);
1995
+ else {
1996
+ const newSubtree = deepCopy(defaultEntry);
1997
+ newSubtree.left.args.value[0].column = column;
1998
+ setActiveEditItem(newSubtree);
1896
1999
  }
1897
- }, label: 'Add filter' }), onClose: () => {
1898
- setIsPending(false);
1899
- setActivePath(null);
1900
- setOpenPopover(null);
1901
- clearCheckboxes();
1902
- setTimeout(() => {
1903
- setActiveEditItem(null);
1904
- }, 300);
1905
- }, children: _jsx(AddFilterPopover, { onSave: () => {
2000
+ setOpenPopover('AddFilterPopover');
2001
+ setActivePath('');
2002
+ setIsPending(true);
2003
+ }
2004
+ }, label: 'Add filter' }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddFilterPopover', setIsOpen: (isOpen) => {
2005
+ if (!isOpen) {
2006
+ setIsPending(false);
2007
+ setActivePath(null);
2008
+ setOpenPopover(null);
2009
+ clearCheckboxes();
2010
+ setTimeout(() => {
2011
+ setActiveEditItem(null);
2012
+ }, 300);
2013
+ }
2014
+ }, popoverTitle: 'Add filter', popoverChildren: _jsx(AddFilterPopover, { onSave: () => {
1906
2015
  if (isNodeEmptyCollection(activeEditItem)) {
1907
2016
  setIsPending(false);
1908
2017
  setActivePath(null);
@@ -1922,44 +2031,46 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1922
2031
  setActiveEditItem(null);
1923
2032
  }, 300);
1924
2033
  }
1925
- }, Button: Button, renderNode: renderNode, activeEditItem: activeEditItem }) }), baseAst?.where &&
2034
+ }, Button: ButtonComponent, renderNode: renderNode, activeEditItem: activeEditItem }) }), baseAst?.where &&
1926
2035
  false && ( // temp removed the AddConditionPopover
1927
- _jsx(Popover, { isOpen: openPopover === 'AddConditionPopover', trigger: _jsx(SecondaryButton, { onClick: () => {
1928
- if (!openPopover) {
1929
- setActiveEditItem(deepCopy(defaultEntry));
1930
- setOpenPopover('AddConditionPopover');
1931
- setActivePath('');
1932
- setIsPending(true);
1933
- }
1934
- }, label: 'Add condition' }), onClose: () => {
1935
- setIsPending(false);
1936
- setTimeout(() => {
1937
- setActiveEditItem(null);
1938
- }, 300);
1939
- setActivePath(null);
1940
- setOpenPopover(null);
1941
- clearCheckboxes();
1942
- }, children: _jsx(AddConditionPopover, { onSave: () => {
1943
- if (isNodeEmptyCollection(activeEditItem)) {
1944
- setIsPending(false);
1945
- setTimeout(() => {
1946
- setActiveEditItem(null);
1947
- }, 300);
1948
- setActivePath(null);
1949
- setOpenPopover(null);
1950
- clearCheckboxes();
1951
- }
1952
- else {
1953
- setIsPending(false);
1954
- handleInsertion(activeEditItem, topLevelBinaryOperator, true);
1955
- setTimeout(() => {
1956
- setActiveEditItem(null);
1957
- }, 300);
1958
- setActivePath(null);
1959
- setOpenPopover(null);
1960
- clearCheckboxes();
1961
- }
1962
- } }) }))] }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeading, { label: "Pivot" }), _jsx("div", { style: { height: 4, width: '100%' } }), _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: Select, ButtonComponent: Button, PopoverComponent: PivotPopover, TextComponent: Text, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEdittingPivot, setShowUpdatePivot: setIsEdittingPivot, parentRef: parentRef, data: rows, columns: processColumnsForChartBuilder(Object.keys(rows[0] ?? {})), triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
2036
+ _jsxs(_Fragment, { children: [_jsx(SecondaryButtonComponent, { onClick: () => {
2037
+ if (!openPopover) {
2038
+ setActiveEditItem(deepCopy(defaultEntry));
2039
+ setOpenPopover('AddConditionPopover');
2040
+ setActivePath('');
2041
+ setIsPending(true);
2042
+ }
2043
+ }, label: "Add condition" }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddConditionPopover', setIsOpen: (isOpen) => {
2044
+ if (!isOpen) {
2045
+ setIsPending(false);
2046
+ setTimeout(() => {
2047
+ setActiveEditItem(null);
2048
+ }, 300);
2049
+ setActivePath(null);
2050
+ setOpenPopover(null);
2051
+ clearCheckboxes();
2052
+ }
2053
+ }, popoverTitle: "Add condition", popoverChildren: _jsx(AddConditionPopover, { onSave: () => {
2054
+ if (isNodeEmptyCollection(activeEditItem)) {
2055
+ setIsPending(false);
2056
+ setTimeout(() => {
2057
+ setActiveEditItem(null);
2058
+ }, 300);
2059
+ setActivePath(null);
2060
+ setOpenPopover(null);
2061
+ clearCheckboxes();
2062
+ }
2063
+ else {
2064
+ setIsPending(false);
2065
+ handleInsertion(activeEditItem, topLevelBinaryOperator, true);
2066
+ setTimeout(() => {
2067
+ setActiveEditItem(null);
2068
+ }, 300);
2069
+ setActivePath(null);
2070
+ setOpenPopover(null);
2071
+ clearCheckboxes();
2072
+ }
2073
+ } }) })] }))] }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeadingComponent, { label: "Pivot" }), _jsx("div", { style: { height: 4, width: '100%' } }), _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, PopoverComponent: PopoverComponent, TextComponent: TextComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEdittingPivot, setShowUpdatePivot: setIsEdittingPivot, parentRef: parentRef, data: rows, columns: processColumnsForChartBuilder(Object.keys(rows[0] ?? {})), triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
1963
2074
  setPivot(null);
1964
2075
  setPivotData(null);
1965
2076
  },
@@ -1973,7 +2084,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1973
2084
  setPivot(pivot);
1974
2085
  const pivotedData = generatePivotTable(pivot, rows, [null, null, null], false);
1975
2086
  setPivotData(pivotedData || []);
1976
- }, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: Label, HeaderComponent: Header, dateRange: [null, null, null], recommendPivotCount: 3, SecondaryButtonComponent: SecondaryButton }), pivot && (_jsx(PivotCard, { pivotTable: {
2087
+ }, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: LabelComponent, HeaderComponent: HeaderComponent, dateRange: [null, null, null], recommendPivotCount: 3, SecondaryButtonComponent: SecondaryButtonComponent }), pivot && (_jsx(PivotCard, { pivotTable: {
1977
2088
  pivot: pivot,
1978
2089
  rows: pivotData?.rows || [],
1979
2090
  columns: pivotData?.columns || [],
@@ -1985,11 +2096,11 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1985
2096
  setPivotValueField(pivot?.valueField);
1986
2097
  setPivotAggregation(pivot?.aggregationType);
1987
2098
  setPivotPopUpTitle('Edit Pivot');
1988
- }, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: Button, HeaderComponent: Header, showEdit: false, onClose: () => {
2099
+ }, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: ButtonComponent, HeaderComponent: HeaderComponent, showEdit: false, onClose: () => {
1989
2100
  setPivot(null);
1990
2101
  setPivotData(null);
1991
2102
  setBaseAst(deepCopy(baseAst)); // trigger refetch
1992
- }, minHeight: 180, LabelComponent: Label, TextComponent: Text })), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeading, { label: "Sort" }), _jsx("div", { style: { height: 4, width: '100%' } }), pivot && pivot.sort && (_jsx("div", { style: {
2103
+ }, minHeight: 180, LabelComponent: LabelComponent, TextComponent: TextComponent })), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeadingComponent, { label: "Sort" }), _jsx("div", { style: { height: 4, width: '100%' } }), pivot && pivot.sort && (_jsx("div", { style: {
1993
2104
  display: 'flex',
1994
2105
  flexDirection: 'column',
1995
2106
  gap: 8,
@@ -1997,7 +2108,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
1997
2108
  }, children: _jsx(SortSentence, { sortData: {
1998
2109
  type: pivot.sortDirection,
1999
2110
  expr: { type: 'column_ref', column: pivot.rowField },
2000
- }, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setOpenPopover: setOpenPopover, SortPopover: SortPopover, EditPopover: AddSortPopover, handleDelete: () => {
2111
+ }, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
2001
2112
  setPivot({ ...pivot, sort: false });
2002
2113
  setBaseAst(deepCopy(baseAst));
2003
2114
  if (!pivot) {
@@ -2010,7 +2121,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2010
2121
  if (!pivot) {
2011
2122
  fetchSqlQuery(baseAst);
2012
2123
  }
2013
- } }, `sort-sentence-pivot`) })), baseAst && baseAst.orderby && (_jsx("div", { style: {
2124
+ }, Select: SelectComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent }, `sort-sentence-pivot`) })), baseAst && baseAst.orderby && (_jsx("div", { style: {
2014
2125
  display: 'flex',
2015
2126
  flexDirection: 'column',
2016
2127
  gap: 8,
@@ -2037,31 +2148,33 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2037
2148
  if (!pivot) {
2038
2149
  fetchSqlQuery(newAst);
2039
2150
  }
2040
- }, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setOpenPopover: setOpenPopover, SortPopover: SortPopover, EditPopover: AddSortPopover, handleDelete: () => {
2151
+ }, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
2041
2152
  const newAst = { ...baseAst };
2042
2153
  newAst.orderby.splice(id, 1);
2043
2154
  setBaseAst(deepCopy(newAst));
2044
2155
  if (!pivot) {
2045
2156
  fetchSqlQuery(newAst);
2046
2157
  }
2047
- } }, `sort-sentence-${id}`))) })), _jsx(Popover, { isOpen: openPopover === 'AddSortPopover', setIsOpen: () => { }, trigger: _jsx(SecondaryButton, { onClick: () => {
2048
- if (!selectedColumns || selectedColumns.length === 0) {
2049
- return;
2050
- }
2051
- if (!openPopover) {
2052
- setOpenPopover('AddSortPopover');
2053
- }
2054
- }, label: 'Add sort' }), title: "Sort By", onClose: () => {
2055
- setIsPending(false);
2056
- setActiveEditItem(null);
2057
- setActivePath(null);
2058
- setOpenPopover(null);
2059
- }, children: _jsx(AddSortPopover, { columns: selectedColumns, Select: Select, Button: Button, onSave: () => { } }) }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeading, { label: "Limit" }), _jsx("div", { style: { height: 4, width: '100%' } }), baseAst && baseAst.limit ? (_jsx("div", { style: {
2158
+ }, Select: SelectComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent }, `sort-sentence-${id}`))) })), _jsx(SecondaryButtonComponent, { onClick: () => {
2159
+ if (!selectedColumns || selectedColumns.length === 0) {
2160
+ return;
2161
+ }
2162
+ if (!openPopover) {
2163
+ setOpenPopover('AddSortPopover');
2164
+ }
2165
+ }, label: "Add sort" }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddSortPopover', setIsOpen: (isOpen) => {
2166
+ if (!isOpen) {
2167
+ setIsPending(false);
2168
+ setActiveEditItem(null);
2169
+ setActivePath(null);
2170
+ setOpenPopover(null);
2171
+ }
2172
+ }, popoverTitle: "Sort by", popoverChildren: _jsx(AddSortPopover, { columns: selectedColumns, Select: SelectComponent, Button: ButtonComponent, onSave: () => { } }) }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeadingComponent, { label: "Limit" }), _jsx("div", { style: { height: 4, width: '100%' } }), baseAst && baseAst.limit ? (_jsx("div", { style: {
2060
2173
  display: 'flex',
2061
2174
  flexDirection: 'column',
2062
2175
  gap: 8,
2063
2176
  marginBottom: 12,
2064
- }, children: _jsx(LimitSentence, { limit: baseAst.limit, setOpenPopover: setOpenPopover, LimitPopover: SortPopover, EditPopover: AddLimitPopover, handleDelete: () => {
2177
+ }, children: _jsx(LimitSentence, { limit: baseAst.limit, setOpenPopover: setOpenPopover, LimitPopover: LimitPopoverComponent, EditPopover: AddLimitPopover, handleDelete: () => {
2065
2178
  const newAst = { ...baseAst };
2066
2179
  newAst.limit = null;
2067
2180
  setBaseAst(deepCopy(newAst));
@@ -2080,27 +2193,29 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2080
2193
  setOpenPopover(null);
2081
2194
  setBaseAst(deepCopy(newAst));
2082
2195
  fetchSqlQuery(newAst);
2083
- } }) })) : (_jsx(Popover, { isOpen: openPopover === 'AddLimitPopover', setIsOpen: () => { }, trigger: _jsx(SecondaryButton, { onClick: () => {
2084
- if (!openPopover) {
2085
- setOpenPopover('AddLimitPopover');
2086
- }
2087
- }, label: 'Add limit' }), title: "Limit", onClose: () => {
2088
- setIsPending(false);
2089
- setActiveEditItem(null);
2090
- setActivePath(null);
2091
- setOpenPopover(null);
2092
- }, children: _jsx(TextInput, { value: 0, type: "number", style: { width: 120, minHeight: 32 }, onChange: (e) => { } }) }))] }), _jsxs(Container, { children: [!hideAi && (_jsxs("form", { onSubmit: (event) => {
2196
+ }, TextInput: TextInputComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent }) })) : (_jsxs(_Fragment, { children: [_jsx(SecondaryButtonComponent, { onClick: () => {
2197
+ if (!openPopover) {
2198
+ setOpenPopover('AddLimitPopover');
2199
+ }
2200
+ }, label: 'Add limit' }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddLimitPopover', setIsOpen: (isOpen) => {
2201
+ if (!isOpen) {
2202
+ setIsPending(false);
2203
+ setActiveEditItem(null);
2204
+ setActivePath(null);
2205
+ setOpenPopover(null);
2206
+ }
2207
+ }, popoverTitle: "Limit", popoverChildren: _jsx(TextInputComponent, { id: "loading_input_limit", value: '0', width: 120, onChange: () => { } }) })] }))] }), _jsxs(ContainerComponent, { children: [isAIEnabled && (_jsxs("form", { ref: askAILoadingContainerRef, onSubmit: (event) => {
2093
2208
  event.preventDefault();
2094
2209
  }, style: {
2095
2210
  display: 'flex',
2096
2211
  flexDirection: 'row',
2097
2212
  gap: 12,
2098
2213
  padding: 1,
2099
- }, children: [_jsx(TextInput, { placeholder: baseAst ? 'Ask a follow-up question...' : 'Ask a question...', type: "text", style: { width: '100%', fontSize: 14 }, value: aiPrompt }), _jsx(Button, { onClick: () => { }, label: 'Ask AI' }), baseAst && (_jsx(SecondaryButton, { onClick: clearAllState, label: "New report" }))] })), _jsxs(_Fragment, { children: [_jsx(TableLoadingState, {}), _jsxs("div", { style: {
2214
+ }, children: [_jsx(TextInputComponent, { id: "ask_ai_loading_bar", placeholder: baseAst ? 'Ask a follow-up question...' : 'Ask a question...', width: askAILoadingContainerWidth, value: aiPrompt, onChange: () => { } }), _jsx(ButtonComponent, { onClick: () => { }, label: "Ask AI" }), baseAst && (_jsx(SecondaryButtonComponent, { onClick: clearAllState, label: "New report" }))] })), _jsxs(_Fragment, { children: [_jsx(TableComponent, { isLoading: true, rows: [], columns: [] }), _jsxs("div", { style: {
2100
2215
  display: 'flex',
2101
2216
  flexDirection: 'row',
2102
2217
  gap: '12px',
2103
- }, children: [_jsx("div", { style: { width: '100%' } }), _jsx(SecondaryButton, { onClick: () => copyToClipboard(activeQuery), label: isCopying ? '✅ Copied' : 'Copy SQL' }), _jsx(Button, { label: 'Add to dashboard', onClick: () => { } })] })] })] }), _jsx("style", { children: `body{margin:0;}` })] }));
2218
+ }, children: [_jsx("div", { style: { width: '100%' } }), _jsx(SecondaryButtonComponent, { onClick: () => copyToClipboard(activeQuery), label: isCopying ? '✅ Copied' : 'Copy SQL' }), _jsx(ButtonComponent, { label: 'Add to dashboard', onClick: () => { } })] })] })] }), _jsx("style", { children: `body{margin:0;}` })] }));
2104
2219
  }
2105
2220
  return (_jsxs("div", { ref: parentRef, style: {
2106
2221
  display: 'flex',
@@ -2109,26 +2224,28 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2109
2224
  overflowY: 'auto',
2110
2225
  boxSizing: 'border-box',
2111
2226
  ...containerStyle,
2112
- }, children: [_jsxs(Sidebar, { children: [_jsx(SidebarHeading, { label: "Columns" }), _jsx("div", { style: { height: 4, width: '100%' } }), _jsx(DraggableColumns, {}), _jsx(Popover, { isOpen: openPopover === 'AddColumnPopover', title: "Select columns", trigger: _jsx(SecondaryButton, { onClick: () => {
2113
- if (!openPopover) {
2114
- setOpenPopover('AddColumnPopover');
2115
- }
2116
- }, label: 'Select columns' }), onClose: () => {
2117
- // delay onClose callback so onClick no-ops
2118
- setTimeout(() => {
2119
- setIsPending(false);
2120
- setActiveEditItem(null);
2121
- setActivePath(null);
2122
- setOpenPopover(null);
2123
- }, 100);
2124
- }, children: _jsx(AddColumnPopover, { onSave: () => {
2227
+ }, children: [_jsxs(SidebarComponent, { children: [_jsx(SidebarHeadingComponent, { label: "Columns" }), _jsx("div", { style: { height: 4, width: '100%' } }), _jsx(DraggableColumns, {}), _jsx(SecondaryButtonComponent, { onClick: () => {
2228
+ if (!openPopover) {
2229
+ setOpenPopover('AddColumnPopover');
2230
+ }
2231
+ }, label: "Select columns" }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddColumnPopover', setIsOpen: (isOpen) => {
2232
+ if (!isOpen) {
2233
+ // delay onClose callback so onClick no-ops
2234
+ setTimeout(() => {
2235
+ setIsPending(false);
2236
+ setActiveEditItem(null);
2237
+ setActivePath(null);
2238
+ setOpenPopover(null);
2239
+ }, 100);
2240
+ }
2241
+ }, popoverTitle: "Select columns", popoverChildren: _jsx(AddColumnPopover, { onSave: () => {
2125
2242
  setActiveEditItem(null);
2126
2243
  setActivePath(null);
2127
2244
  setOpenPopover(null);
2128
2245
  }, orderedColumnNames: orderedColumnNames, setOrderedColumnNames: setOrderedColumnNames, selectedColumns: selectedColumns, setSelectedColumns: setSelectedColumns, isSelectedAllColumns: isSelectedAllColumns, clearAllState: clearAllState, nameToColumn: nameToColumn, baseAst: baseAst, setBaseAst: (ast) => {
2129
2246
  setBaseAst(ast);
2130
2247
  fetchSqlQuery(ast);
2131
- }, pivot: pivot, initialTableName: initialTableName, defaultAST: defaultAST, defaultTable: defaultTable, setPivot: setPivot, TextInput: TextInput, SelectColumn: SelectColumn, SecondaryButton: SecondaryButton, Button: Button, HandleButton: HandleButton }) }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeading, { label: "Filters" }), _jsx("div", { style: { height: 4, width: '100%' } }), formData && (_jsx("div", { style: {
2248
+ }, pivot: pivot, initialTableName: initialTableName, defaultAST: defaultAST, defaultTable: defaultTable, setPivot: setPivot, TextInput: TextInputComponent, SelectColumn: SelectColumnComponent, SecondaryButton: SecondaryButtonComponent, Button: ButtonComponent }) }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeadingComponent, { label: "Filters" }), _jsx("div", { style: { height: 4, width: '100%' } }), formData && (_jsx("div", { style: {
2132
2249
  display: 'flex',
2133
2250
  flexDirection: 'column',
2134
2251
  gap: 8,
@@ -2138,50 +2255,42 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2138
2255
  flexDirection: 'column',
2139
2256
  gap: 2.5,
2140
2257
  alignItems: 'flex-start',
2141
- }, children: [_jsx(Popover, { title: 'Add filter', isOpen: openPopover === 'AddFilterPopover', trigger: _jsx(SecondaryButton, { onClick: () => {
2142
- if (!selectedColumns || selectedColumns.length === 0) {
2143
- return;
2258
+ }, children: [_jsx(SecondaryButtonComponent, { onClick: () => {
2259
+ if (!selectedColumns || selectedColumns.length === 0 || loading) {
2260
+ return;
2261
+ }
2262
+ if (!openPopover) {
2263
+ const value = orderedColumnNames[0];
2264
+ const [_table, column] = value.split('.');
2265
+ const columnType = getColumnTypeByName(column);
2266
+ if (isNumericColumnType(columnType)) {
2267
+ const newSubtree = deepCopy(defaultNumericComparison);
2268
+ newSubtree.left.column = column;
2269
+ setActiveEditItem(newSubtree);
2144
2270
  }
2145
- if (!openPopover) {
2146
- const value = orderedColumnNames[0];
2147
- const [_table, column] = value.split('.');
2148
- const columnType = getColumnTypeByName(column);
2149
- if (isNumericColumnType(columnType)) {
2150
- const newSubtree = deepCopy(defaultNumericComparison);
2151
- newSubtree.left.column = column;
2152
- setActiveEditItem(newSubtree);
2153
- }
2154
- else {
2155
- const newSubtree = deepCopy(defaultEntry);
2156
- newSubtree.left.args.value[0].column = column;
2157
- setActiveEditItem(newSubtree);
2158
- }
2159
- setOpenPopover('AddFilterPopover');
2160
- setActivePath('');
2161
- setIsPending(true);
2271
+ else {
2272
+ const newSubtree = deepCopy(defaultEntry);
2273
+ newSubtree.left.args.value[0].column = column;
2274
+ setActiveEditItem(newSubtree);
2162
2275
  }
2163
- }, label: 'Add filter' }), onClose: () => {
2164
- // delay onClose callback so onClick no-ops
2165
- setTimeout(() => {
2166
- setIsPending(false);
2167
- setActivePath(null);
2168
- setOpenPopover(null);
2169
- clearCheckboxes();
2170
- setActiveEditItem(null);
2171
- }, 200);
2172
- }, children: _jsx(AddFilterPopover, { onSave: () => {
2173
- if (isNodeEmptyCollection(activeEditItem)) {
2276
+ setOpenPopover('AddFilterPopover');
2277
+ setActivePath('');
2278
+ setIsPending(true);
2279
+ }
2280
+ }, label: 'Add filter' }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddFilterPopover', setIsOpen: (isOpen) => {
2281
+ if (!isOpen) {
2282
+ // delay onClose callback so onClick no-ops
2283
+ setTimeout(() => {
2174
2284
  setIsPending(false);
2175
2285
  setActivePath(null);
2176
2286
  setOpenPopover(null);
2177
2287
  clearCheckboxes();
2178
- setTimeout(() => {
2179
- setActiveEditItem(null);
2180
- }, 300);
2181
- }
2182
- else {
2288
+ setActiveEditItem(null);
2289
+ }, 200);
2290
+ }
2291
+ }, popoverTitle: "Add filter", popoverChildren: _jsx(AddFilterPopover, { onSave: () => {
2292
+ if (isNodeEmptyCollection(activeEditItem)) {
2183
2293
  setIsPending(false);
2184
- handleInsertion(activeEditItem, 'AND', false);
2185
2294
  setActivePath(null);
2186
2295
  setOpenPopover(null);
2187
2296
  clearCheckboxes();
@@ -2189,45 +2298,57 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2189
2298
  setActiveEditItem(null);
2190
2299
  }, 300);
2191
2300
  }
2192
- }, Button: Button, renderNode: renderNode, activeEditItem: activeEditItem }) }), baseAst?.where &&
2193
- false && ( // temp removed the AddConditionPopover
2194
- _jsx(Popover, { isOpen: openPopover === 'AddConditionPopover', trigger: _jsx(SecondaryButton, { onClick: () => {
2195
- if (!openPopover) {
2196
- setActiveEditItem(deepCopy(defaultEntry));
2197
- setOpenPopover('AddConditionPopover');
2198
- setActivePath('');
2199
- setIsPending(true);
2200
- }
2201
- }, label: 'Add condition' }), onClose: () => {
2202
- // delay onClose callback so onClick no-ops
2203
- setTimeout(() => {
2204
- setIsPending(false);
2205
- setActiveEditItem(null);
2206
- setActivePath(null);
2207
- setOpenPopover(null);
2208
- clearCheckboxes();
2209
- }, 200);
2210
- }, children: _jsx(AddConditionPopover, { onSave: () => {
2211
- if (isNodeEmptyCollection(activeEditItem)) {
2301
+ else {
2212
2302
  setIsPending(false);
2213
- setTimeout(() => {
2214
- setActiveEditItem(null);
2215
- }, 300);
2303
+ handleInsertion(activeEditItem, 'AND', false);
2216
2304
  setActivePath(null);
2217
2305
  setOpenPopover(null);
2218
2306
  clearCheckboxes();
2219
- }
2220
- else {
2221
- setIsPending(false);
2222
- handleInsertion(activeEditItem, topLevelBinaryOperator, true);
2223
2307
  setTimeout(() => {
2224
2308
  setActiveEditItem(null);
2225
2309
  }, 300);
2226
- setActivePath(null);
2227
- setOpenPopover(null);
2228
- clearCheckboxes();
2229
2310
  }
2230
- } }) }))] }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeading, { label: "Pivot" }), _jsx("div", { style: { height: 4, width: '100%' } }), _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: Select, ButtonComponent: Button, SecondaryButtonComponent: SecondaryButton, PopoverComponent: PivotPopover, TextComponent: Text, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEdittingPivot, setShowUpdatePivot: setIsEdittingPivot, parentRef: parentRef, data: rows, columns: processColumnsForChartBuilder(Object.keys(rows[0] ?? {})), triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
2311
+ }, Button: ButtonComponent, renderNode: renderNode, activeEditItem: activeEditItem }) }), baseAst?.where &&
2312
+ false && ( // temp removed the AddConditionPopover
2313
+ _jsxs(_Fragment, { children: [_jsx(SecondaryButtonComponent, { onClick: () => {
2314
+ if (!openPopover) {
2315
+ setActiveEditItem(deepCopy(defaultEntry));
2316
+ setOpenPopover('AddConditionPopover');
2317
+ setActivePath('');
2318
+ setIsPending(true);
2319
+ }
2320
+ }, label: 'Add condition' }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddConditionPopover', setIsOpen: (isOpen) => {
2321
+ if (!isOpen) {
2322
+ // delay onClose callback so onClick no-ops
2323
+ setTimeout(() => {
2324
+ setIsPending(false);
2325
+ setActiveEditItem(null);
2326
+ setActivePath(null);
2327
+ setOpenPopover(null);
2328
+ clearCheckboxes();
2329
+ }, 200);
2330
+ }
2331
+ }, popoverChildren: _jsx(AddConditionPopover, { onSave: () => {
2332
+ if (isNodeEmptyCollection(activeEditItem)) {
2333
+ setIsPending(false);
2334
+ setTimeout(() => {
2335
+ setActiveEditItem(null);
2336
+ }, 300);
2337
+ setActivePath(null);
2338
+ setOpenPopover(null);
2339
+ clearCheckboxes();
2340
+ }
2341
+ else {
2342
+ setIsPending(false);
2343
+ handleInsertion(activeEditItem, topLevelBinaryOperator, true);
2344
+ setTimeout(() => {
2345
+ setActiveEditItem(null);
2346
+ }, 300);
2347
+ setActivePath(null);
2348
+ setOpenPopover(null);
2349
+ clearCheckboxes();
2350
+ }
2351
+ } }) })] }))] }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeadingComponent, { label: "Pivot" }), _jsx("div", { style: { height: 4, width: '100%' } }), _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, SecondaryButtonComponent: SecondaryButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEdittingPivot, setShowUpdatePivot: setIsEdittingPivot, parentRef: parentRef, data: rows, columns: processColumnsForChartBuilder(Object.keys(rows[0] ?? {})), triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
2231
2352
  setPivot(null);
2232
2353
  setPivotData(null);
2233
2354
  }, selectPivot: (pivot) => {
@@ -2243,7 +2364,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2243
2364
  setPivot(pivot);
2244
2365
  const pivotedData = generatePivotTable(pivot, rows, [null, null, null], false);
2245
2366
  setPivotData(pivotedData || []);
2246
- }, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: Label, HeaderComponent: Header, dateRange: [null, null, null], recommendPivotCount: 3 }), pivot && (_jsx(PivotCard, { pivotTable: {
2367
+ }, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: LabelComponent, HeaderComponent: HeaderComponent, dateRange: [null, null, null], recommendPivotCount: 3 }), pivot && (_jsx(PivotCard, { pivotTable: {
2247
2368
  pivot: pivot,
2248
2369
  rows: pivotData?.rows || [],
2249
2370
  columns: pivotData?.columns || [],
@@ -2255,11 +2376,11 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2255
2376
  setPivotValueField(pivot?.valueField);
2256
2377
  setPivotAggregation(pivot?.aggregationType);
2257
2378
  setPivotPopUpTitle('Edit Pivot');
2258
- }, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: Button, HeaderComponent: Header, showEdit: false, onClose: () => {
2379
+ }, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: ButtonComponent, HeaderComponent: HeaderComponent, showEdit: false, onClose: () => {
2259
2380
  setPivot(null);
2260
2381
  setPivotData(null);
2261
2382
  setBaseAst(deepCopy(baseAst));
2262
- }, minHeight: 180, LabelComponent: Label, TextComponent: Text })), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeading, { label: "Sort" }), _jsx("div", { style: { height: 4, width: '100%' } }), pivot && pivot.sort && (_jsx("div", { style: {
2383
+ }, minHeight: 180, LabelComponent: LabelComponent, TextComponent: TextComponent })), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeadingComponent, { label: "Sort" }), _jsx("div", { style: { height: 4, width: '100%' } }), pivot && pivot.sort && (_jsx("div", { style: {
2263
2384
  display: 'flex',
2264
2385
  flexDirection: 'column',
2265
2386
  gap: 8,
@@ -2267,7 +2388,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2267
2388
  }, children: _jsx(SortSentence, { sortData: {
2268
2389
  type: pivot.sortDirection,
2269
2390
  expr: { type: 'column_ref', column: pivot.rowField },
2270
- }, columns: pivot ? [`.${pivot.rowField}`] : selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setOpenPopover: setOpenPopover, SortPopover: SortPopover, EditPopover: AddSortPopover, handleDelete: () => {
2391
+ }, columns: pivot ? [`.${pivot.rowField}`] : selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setActivePath: setActivePath, setOpenPopover: setOpenPopover, SortPopover: SortPopoverComponent, EditPopover: AddSortPopover, handleDelete: () => {
2271
2392
  if (pivot) {
2272
2393
  setPivot({ ...pivot, sort: false });
2273
2394
  const pivotedData = generatePivotTable({ ...pivot, sort: false }, rows, [null, null, null], false);
@@ -2286,12 +2407,12 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2286
2407
  setOpenPopover(null);
2287
2408
  setBaseAst(deepCopy(baseAst));
2288
2409
  fetchSqlQuery(deepCopy(baseAst));
2289
- } }, `sort-sentence-pivot`) })), baseAst && baseAst.orderby && (_jsx("div", { style: {
2410
+ }, Select: SelectComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent }, `sort-sentence-pivot`) })), baseAst && baseAst.orderby && (_jsx("div", { style: {
2290
2411
  display: 'flex',
2291
2412
  flexDirection: 'column',
2292
2413
  gap: 8,
2293
2414
  marginBottom: 12,
2294
- }, children: baseAst.orderby.map((sortData, id) => (_jsx(SortSentence, { sortData: sortData, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setOpenPopover: setOpenPopover, SortPopover: SortPopover, EditPopover: AddSortPopover, handleDelete: () => {
2415
+ }, 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: () => {
2295
2416
  if (pivot) {
2296
2417
  setPivot({ ...pivot, sort: false });
2297
2418
  return;
@@ -2328,19 +2449,21 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2328
2449
  setOpenPopover(null);
2329
2450
  setBaseAst(deepCopy(newAst));
2330
2451
  fetchSqlQuery(deepCopy(newAst));
2331
- } }, `sort-sentence-${id}`))) })), _jsx(Popover, { isOpen: openPopover === 'AddSortPopover', trigger: _jsx(SecondaryButton, { onClick: () => {
2332
- if (!selectedColumns || selectedColumns.length === 0) {
2333
- return;
2334
- }
2335
- if (!openPopover) {
2336
- setOpenPopover('AddSortPopover');
2337
- }
2338
- }, label: 'Add sort' }), title: "Sort by", onClose: () => {
2339
- setIsPending(false);
2340
- setActiveEditItem(null);
2341
- setActivePath(null);
2342
- setOpenPopover(null);
2343
- }, children: _jsx(AddSortPopover, { columns: pivot ? [`.${pivot.rowField}`] : selectedColumns, Select: Select, Button: Button, onSave: (column, direction) => {
2452
+ }, Select: SelectComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent }, `sort-sentence-${id}`))) })), _jsx(SecondaryButtonComponent, { onClick: () => {
2453
+ if (!selectedColumns || selectedColumns.length === 0) {
2454
+ return;
2455
+ }
2456
+ if (!openPopover) {
2457
+ setOpenPopover('AddSortPopover');
2458
+ }
2459
+ }, label: 'Add sort' }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddSortPopover', setIsOpen: (isOpen) => {
2460
+ if (!isOpen) {
2461
+ setIsPending(false);
2462
+ setActiveEditItem(null);
2463
+ setActivePath(null);
2464
+ setOpenPopover(null);
2465
+ }
2466
+ }, popoverTitle: "Sort by", popoverChildren: _jsx(AddSortPopover, { columns: pivot ? [`.${pivot.rowField}`] : selectedColumns, Select: SelectComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent, onSave: (column, direction) => {
2344
2467
  if (column === '')
2345
2468
  return;
2346
2469
  if (pivot) {
@@ -2364,12 +2487,12 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2364
2487
  setOpenPopover(null);
2365
2488
  setBaseAst(deepCopy(newAst));
2366
2489
  fetchSqlQuery(deepCopy(newAst));
2367
- } }) }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeading, { label: "Limit" }), _jsx("div", { style: { height: 4, width: '100%' } }), baseAst && baseAst.limit ? (_jsx("div", { style: {
2490
+ } }) }), _jsx("div", { style: { height: 28, width: '100%' } }), _jsx(SidebarHeadingComponent, { label: "Limit" }), _jsx("div", { style: { height: 4, width: '100%' } }), baseAst && baseAst.limit ? (_jsx("div", { style: {
2368
2491
  display: 'flex',
2369
2492
  flexDirection: 'column',
2370
2493
  gap: 8,
2371
2494
  marginBottom: 12,
2372
- }, children: _jsx(LimitSentence, { limit: baseAst.limit, setOpenPopover: setOpenPopover, LimitPopover: SortPopover, EditPopover: AddLimitPopover, handleDelete: () => {
2495
+ }, children: _jsx(LimitSentence, { limit: baseAst.limit, setOpenPopover: setOpenPopover, LimitPopover: LimitPopoverComponent, EditPopover: AddLimitPopover, handleDelete: () => {
2373
2496
  const newAst = { ...baseAst };
2374
2497
  newAst.limit = null;
2375
2498
  setBaseAst(deepCopy(newAst));
@@ -2388,36 +2511,38 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2388
2511
  setOpenPopover(null);
2389
2512
  setBaseAst(deepCopy(newAst));
2390
2513
  fetchSqlQuery(deepCopy(newAst));
2391
- } }) })) : (_jsx(Popover, { isOpen: openPopover === 'AddLimitPopover', setIsOpen: () => { }, trigger: _jsx(SecondaryButton, { onClick: () => {
2392
- if (!selectedColumns || selectedColumns.length === 0) {
2393
- return;
2394
- }
2395
- if (!baseAst) {
2396
- return;
2397
- }
2398
- if (!openPopover) {
2399
- setOpenPopover('AddLimitPopover');
2400
- }
2401
- }, label: 'Add limit' }), title: "Limit", onClose: () => {
2402
- setIsPending(false);
2403
- setActiveEditItem(null);
2404
- setActivePath(null);
2405
- setOpenPopover(null);
2406
- }, children: _jsx(AddLimitPopover, { TextInput: TextInput, onSave: (limit) => {
2407
- const newAst = { ...baseAst };
2408
- newAst.limit = {
2409
- seperator: '',
2410
- value: [
2411
- {
2412
- type: 'number',
2413
- value: Number(limit),
2414
- },
2415
- ],
2416
- };
2417
- setOpenPopover(null);
2418
- setBaseAst(deepCopy(newAst));
2419
- fetchSqlQuery(deepCopy(newAst));
2420
- } }) }))] }), _jsxs(Container, { children: [!hideAi && (_jsxs("form", { onSubmit: (event) => {
2514
+ }, TextInput: TextInputComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent }) })) : (_jsxs(_Fragment, { children: [_jsx(SecondaryButtonComponent, { onClick: () => {
2515
+ if (!selectedColumns || selectedColumns.length === 0) {
2516
+ return;
2517
+ }
2518
+ if (!baseAst) {
2519
+ return;
2520
+ }
2521
+ if (!openPopover) {
2522
+ setOpenPopover('AddLimitPopover');
2523
+ }
2524
+ }, label: 'Add limit' }), _jsx(PopoverComponent, { isOpen: openPopover === 'AddLimitPopover', setIsOpen: (isOpen) => {
2525
+ if (!isOpen) {
2526
+ setIsPending(false);
2527
+ setActiveEditItem(null);
2528
+ setActivePath(null);
2529
+ setOpenPopover(null);
2530
+ }
2531
+ }, popoverTitle: "Limit", popoverChildren: _jsx(AddLimitPopover, { TextInput: TextInputComponent, Button: ButtonComponent, SecondaryButton: SecondaryButtonComponent, onSave: (limit) => {
2532
+ const newAst = { ...baseAst };
2533
+ newAst.limit = {
2534
+ seperator: '',
2535
+ value: [
2536
+ {
2537
+ type: 'number',
2538
+ value: Number(limit),
2539
+ },
2540
+ ],
2541
+ };
2542
+ setOpenPopover(null);
2543
+ setBaseAst(deepCopy(newAst));
2544
+ fetchSqlQuery(deepCopy(newAst));
2545
+ } }) })] }))] }), _jsxs(ContainerComponent, { children: [isAIEnabled && (_jsxs("form", { ref: askAIContainerRef, onSubmit: (event) => {
2421
2546
  event.preventDefault();
2422
2547
  handleAsk();
2423
2548
  }, style: {
@@ -2425,14 +2550,14 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2425
2550
  flexDirection: 'row',
2426
2551
  gap: 12,
2427
2552
  padding: 1,
2428
- }, children: [_jsx(TextInput, { type: "text", value: aiPrompt, style: { width: '100%', fontSize: 14 }, onChange: (e) => setAiPrompt(e.target.value), placeholder: baseAst ? 'Ask a follow-up question...' : 'Ask a question...' }), _jsx(Button, { onClick: handleAsk, label: 'Ask AI' }), baseAst && (_jsx(SecondaryButton, { label: 'New report', onClick: clearAllState }))] })), baseAst && (_jsx(_Fragment, { children: loading && errorMessage.length === 0 ? (_jsx(TableLoadingState, {})) : (_jsx(Table, { rows: applyFormatting({
2429
- rows: pivotData?.rows || rows,
2430
- fields: pivotData?.fields || fields,
2431
- }, baseAst?.columns ?? []), columns: pivot
2432
- ? pivotData?.columns || emptyPivotColumns()
2433
- : enforceOrderOnColumns(Object.keys(rows[0] ?? {})).map((c) => {
2434
- return { label: snakeCaseToTitleCase(c), field: c };
2435
- }), error: errorMessage, rowsPerPage: 20 })) })), _jsxs("div", { style: {
2553
+ }, children: [_jsx(TextInputComponent, { id: "ask_ai_input_bar", value: aiPrompt, width: askAIInputWidth, onChange: (e) => setAiPrompt(e.target.value), placeholder: baseAst ? 'Ask a follow-up question...' : 'Ask a question...' }), _jsx(ButtonComponent, { onClick: handleAsk, label: 'Ask AI' }), baseAst && (_jsx(SecondaryButtonComponent, { label: 'New report', onClick: clearAllState }))] })), baseAst && (_jsx(TableComponent, { isLoading: loading && errorMessage.length === 0, rows: applyFormatting({
2554
+ rows: pivotData?.rows || rows,
2555
+ fields: pivotData?.fields || fields,
2556
+ }, baseAst?.columns ?? []), columns: pivot
2557
+ ? pivotData?.columns || emptyPivotColumns()
2558
+ : enforceOrderOnColumns(Object.keys(rows[0] ?? {})).map((c) => {
2559
+ return { label: snakeCaseToTitleCase(c), field: c };
2560
+ }) })), _jsxs("div", { style: {
2436
2561
  display: 'flex',
2437
2562
  flexDirection: 'row',
2438
2563
  gap: '12px',
@@ -2441,7 +2566,7 @@ export default function ReportBuilder({ initialTableName = '', onAddToDashboardC
2441
2566
  fontSize: 14,
2442
2567
  padding: '12px',
2443
2568
  whiteSpace: 'nowrap',
2444
- }, children: errorMessage })), _jsx("div", { style: { width: '100%' } }), baseAst && (_jsxs(_Fragment, { children: [_jsx(SecondaryButton, { label: isCopying ? '✅ Copied' : 'Copy SQL', onClick: () => copyToClipboard(activeQuery) }), _jsx(Button, { onClick: () => {
2569
+ }, children: errorMessage })), _jsx("div", { style: { width: '100%' } }), baseAst && (_jsxs(_Fragment, { children: [_jsx(SecondaryButtonComponent, { label: isCopying ? '✅ Copied' : 'Copy SQL', onClick: () => copyToClipboard(activeQuery) }), _jsx(ButtonComponent, { onClick: () => {
2445
2570
  setIsChartBuilderOpen(true);
2446
- }, label: 'Add to dashboard' })] }))] })] }), _jsx("style", { children: `body{margin:0;}` }), _jsx(ChartBuilderWithModal, { rows: applyFormatting({ rows, fields }, baseAst?.columns ?? []), columns: processColumnsForChartBuilder(Object.keys(rows[0] ?? {})), fields: fields, pivot: pivot, query: activeQuery, showTableFormatOptions: admin ? true : false, showDateFieldOptions: admin ? true : false, showAccessControlOptions: admin ? true : false, title: "Add to dashboard", isEditMode: true, isOpen: isChartBuilderOpen, setIsOpen: setIsChartBuilderOpen, onAddToDashboardComplete: onAddToDashboardComplete, destinationDashboard: destinationDashboard, organizationName: organizationName, pivotData: pivotData })] }));
2571
+ }, label: 'Add to dashboard' })] }))] })] }), _jsx("style", { children: `body{margin:0;}` }), _jsx(ChartBuilderWithModal, { rows: rows, columns: processColumnsForChartBuilder(Object.keys(rows[0] ?? {})), fields: fields, pivot: pivot, query: activeQuery, showTableFormatOptions: isAdminEnabled, showDateFieldOptions: isAdminEnabled, showAccessControlOptions: isAdminEnabled, title: "Add to dashboard", isOpen: isChartBuilderOpen, setIsOpen: setIsChartBuilderOpen, onAddToDashboardComplete: onSubmitChartBuilder, destinationDashboard: destinationDashboard, organizationName: organizationName, pivotData: pivotData, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, HeaderComponent: HeaderComponent, LabelComponent: LabelComponent, TextComponent: TextComponent, ModalComponent: ModalComponent, PopoverComponent: PopoverComponent, DeleteButtonComponent: DeleteButtonComponent })] }));
2447
2572
  }