@quillsql/react 2.11.12 → 2.11.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/cjs/ChartBuilder.d.ts.map +1 -1
  2. package/dist/cjs/ChartBuilder.js +1 -1
  3. package/dist/cjs/Dashboard.js +1 -1
  4. package/dist/cjs/ReportBuilder.d.ts.map +1 -1
  5. package/dist/cjs/ReportBuilder.js +354 -197
  6. package/dist/cjs/SQLEditor.d.ts.map +1 -1
  7. package/dist/cjs/SQLEditor.js +1 -0
  8. package/dist/cjs/components/Chart/ChartTooltipFrame.d.ts.map +1 -1
  9. package/dist/cjs/components/Chart/ChartTooltipFrame.js +1 -0
  10. package/dist/cjs/components/Chart/LineChart.d.ts.map +1 -1
  11. package/dist/cjs/components/Chart/LineChart.js +3 -0
  12. package/dist/cjs/components/Dashboard/MetricComponent.js +2 -2
  13. package/dist/cjs/components/QuillCard.d.ts.map +1 -1
  14. package/dist/cjs/components/QuillCard.js +2 -4
  15. package/dist/cjs/components/QuillSelect.d.ts.map +1 -1
  16. package/dist/cjs/components/QuillSelect.js +7 -1
  17. package/dist/cjs/components/QuillTable.d.ts.map +1 -1
  18. package/dist/cjs/components/QuillTable.js +2 -2
  19. package/dist/cjs/components/ReportBuilder/AddColumnPopover.js +3 -3
  20. package/dist/cjs/components/ReportBuilder/AddLimitPopover.d.ts +3 -0
  21. package/dist/cjs/components/ReportBuilder/AddLimitPopover.d.ts.map +1 -0
  22. package/dist/cjs/components/ReportBuilder/AddLimitPopover.js +43 -0
  23. package/dist/cjs/components/ReportBuilder/AddSortPopover.d.ts.map +1 -1
  24. package/dist/cjs/components/ReportBuilder/AddSortPopover.js +10 -4
  25. package/dist/cjs/components/ReportBuilder/bigDateMap.d.ts.map +1 -1
  26. package/dist/cjs/components/ReportBuilder/bigDateMap.js +2 -1
  27. package/dist/cjs/components/ReportBuilder/convert.d.ts.map +1 -1
  28. package/dist/cjs/components/ReportBuilder/convert.js +38 -12
  29. package/dist/cjs/components/ReportBuilder/ui.d.ts.map +1 -1
  30. package/dist/cjs/components/ReportBuilder/ui.js +4 -3
  31. package/dist/cjs/components/ReportBuilder/util.d.ts.map +1 -1
  32. package/dist/cjs/components/ReportBuilder/util.js +7 -5
  33. package/dist/cjs/components/UiComponents.js +2 -2
  34. package/dist/cjs/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  35. package/dist/cjs/internals/ReportBuilder/PivotList.js +28 -2
  36. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts +2 -1
  37. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  38. package/dist/cjs/internals/ReportBuilder/PivotModal.js +49 -32
  39. package/dist/cjs/utils/getDomain.d.ts.map +1 -1
  40. package/dist/cjs/utils/getDomain.js +3 -0
  41. package/dist/esm/ChartBuilder.d.ts.map +1 -1
  42. package/dist/esm/ChartBuilder.js +1 -1
  43. package/dist/esm/Dashboard.js +1 -1
  44. package/dist/esm/ReportBuilder.d.ts.map +1 -1
  45. package/dist/esm/ReportBuilder.js +354 -197
  46. package/dist/esm/SQLEditor.d.ts.map +1 -1
  47. package/dist/esm/SQLEditor.js +1 -0
  48. package/dist/esm/components/Chart/ChartTooltipFrame.d.ts.map +1 -1
  49. package/dist/esm/components/Chart/ChartTooltipFrame.js +1 -0
  50. package/dist/esm/components/Chart/LineChart.d.ts.map +1 -1
  51. package/dist/esm/components/Chart/LineChart.js +3 -0
  52. package/dist/esm/components/Dashboard/MetricComponent.js +2 -2
  53. package/dist/esm/components/QuillCard.d.ts.map +1 -1
  54. package/dist/esm/components/QuillCard.js +2 -4
  55. package/dist/esm/components/QuillSelect.d.ts.map +1 -1
  56. package/dist/esm/components/QuillSelect.js +7 -1
  57. package/dist/esm/components/QuillTable.d.ts.map +1 -1
  58. package/dist/esm/components/QuillTable.js +2 -2
  59. package/dist/esm/components/ReportBuilder/AddColumnPopover.js +3 -3
  60. package/dist/esm/components/ReportBuilder/AddLimitPopover.d.ts +3 -0
  61. package/dist/esm/components/ReportBuilder/AddLimitPopover.d.ts.map +1 -0
  62. package/dist/esm/components/ReportBuilder/AddLimitPopover.js +38 -0
  63. package/dist/esm/components/ReportBuilder/AddSortPopover.d.ts.map +1 -1
  64. package/dist/esm/components/ReportBuilder/AddSortPopover.js +10 -4
  65. package/dist/esm/components/ReportBuilder/bigDateMap.d.ts.map +1 -1
  66. package/dist/esm/components/ReportBuilder/bigDateMap.js +2 -1
  67. package/dist/esm/components/ReportBuilder/convert.d.ts.map +1 -1
  68. package/dist/esm/components/ReportBuilder/convert.js +38 -12
  69. package/dist/esm/components/ReportBuilder/ui.d.ts.map +1 -1
  70. package/dist/esm/components/ReportBuilder/ui.js +4 -3
  71. package/dist/esm/components/ReportBuilder/util.d.ts.map +1 -1
  72. package/dist/esm/components/ReportBuilder/util.js +7 -5
  73. package/dist/esm/components/UiComponents.js +2 -2
  74. package/dist/esm/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  75. package/dist/esm/internals/ReportBuilder/PivotList.js +28 -2
  76. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts +2 -1
  77. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  78. package/dist/esm/internals/ReportBuilder/PivotModal.js +49 -32
  79. package/dist/esm/utils/getDomain.d.ts.map +1 -1
  80. package/dist/esm/utils/getDomain.js +3 -0
  81. package/package.json +2 -2
@@ -26,6 +26,8 @@ const PivotModal_1 = require("./internals/ReportBuilder/PivotModal");
26
26
  const PivotList_1 = require("./internals/ReportBuilder/PivotList");
27
27
  const QuillTable_1 = __importDefault(require("./components/QuillTable"));
28
28
  const QuillSelect_1 = require("./components/QuillSelect");
29
+ const textProcessing_1 = require("./utils/textProcessing");
30
+ const AddLimitPopover_1 = require("./components/ReportBuilder/AddLimitPopover");
29
31
  /**
30
32
  * Quill Report Builder
31
33
  *
@@ -63,6 +65,8 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
63
65
  const [showPivotPopover, setShowPivotPopover] = (0, react_1.useState)(false);
64
66
  const [isEdittingPivot, setIsEdittingPivot] = (0, react_1.useState)(false);
65
67
  const [selectedPivotIndex, setSelectedPivotIndex] = (0, react_1.useState)(-1);
68
+ const [initialLoad, setInitialLoad] = (0, react_1.useState)(true);
69
+ const [currentTable, setCurrentTable] = (0, react_1.useState)(initialTableName || '');
66
70
  const parentRef = (0, react_1.useRef)(null);
67
71
  const [theme] = (0, react_1.useContext)(Context_1.ThemeContext);
68
72
  const [pivotRowField, setPivotRowField] = (0, react_1.useState)(undefined);
@@ -90,7 +94,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
90
94
  return columns.map((col) => ({
91
95
  label: col,
92
96
  name: col,
93
- displayName: col,
97
+ displayName: (0, textProcessing_1.snakeCaseToTitleCase)(col),
94
98
  field: col,
95
99
  format: (0, util_1.getPostgresBasicType)(fields.find((f) => f.name === col))?.replace('number', 'whole_number') || 'string',
96
100
  fieldType: schemaTables
@@ -122,6 +126,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
122
126
  // setUniqueValues({});
123
127
  setPivot(null);
124
128
  setPivotData(null);
129
+ setRecommendedPivots([]);
125
130
  }, 0);
126
131
  };
127
132
  (0, react_1.useEffect)(() => {
@@ -182,7 +187,9 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
182
187
  }
183
188
  setUniqueValues(newValues);
184
189
  };
185
- const fetchSqlQuery = async () => {
190
+ const fetchSqlQuery = async (ast, formData) => {
191
+ setLoading(true);
192
+ setErrorMessage('');
186
193
  try {
187
194
  const response = await fetch(`https://quill-344421.uc.r.appspot.com/sqlify`, {
188
195
  method: 'POST',
@@ -190,32 +197,19 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
190
197
  'Content-Type': 'application/json',
191
198
  },
192
199
  body: JSON.stringify({
193
- ast: { ...baseAst, where: formData },
200
+ ast: { ...ast, where: formData },
194
201
  publicKey: client.publicKey,
195
202
  }),
196
203
  });
197
204
  const data = await response.json();
198
205
  setActiveQuery(data.query);
199
- fetchUponChange();
206
+ fetchUponChange(ast, formData);
200
207
  }
201
208
  catch (error) {
209
+ setLoading(false);
202
210
  console.error(error);
203
211
  }
204
212
  };
205
- (0, react_1.useEffect)(() => {
206
- setErrorMessage('');
207
- if (baseAst || formData) {
208
- fetchSqlQuery();
209
- }
210
- }, [baseAst]);
211
- // Returns an array of all the column names in the pivot config
212
- // if there are any, otherwise returns [].
213
- const getColumnsInPivot = () => {
214
- if (!pivot)
215
- return [];
216
- const { valueField, rowField, columnField } = pivot;
217
- return [valueField, rowField, columnField].filter(Boolean);
218
- };
219
213
  // It's just like getColumnsInPivot but we expand the columnField
220
214
  // if there is one to include all the variants just like it would
221
215
  // show up in the table. (eg. category -> ...[Fuel, Food, Other])
@@ -234,81 +228,78 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
234
228
  result.push(valueField, rowField);
235
229
  return result.filter(Boolean);
236
230
  };
237
- (0, react_1.useEffect)(() => {
238
- if (errorMessage) {
239
- console.error(errorMessage);
231
+ const fetchDistinctHelper = async (column, table) => {
232
+ try {
233
+ const query = `SELECT DISTINCT ${column} FROM ${table};`;
234
+ const response = await fetch(`https://quill-344421.uc.r.appspot.com/dashquery`, {
235
+ method: 'POST',
236
+ headers: {
237
+ 'Content-Type': 'application/json',
238
+ },
239
+ body: JSON.stringify({
240
+ orgId: client.customerId,
241
+ publicKey: client.publicKey,
242
+ query: query,
243
+ }),
244
+ });
245
+ const data = await response.json();
246
+ if (data.errorMessage) {
247
+ // console.error(data.errorMessage);
248
+ return null;
249
+ }
250
+ const options = data.rows.map((r) => r[column]);
251
+ const newCheckboxValues = options.reduce((obj, col) => {
252
+ obj[col] = false;
253
+ return obj;
254
+ }, {});
255
+ return { table, column, values: newCheckboxValues };
256
+ }
257
+ catch (e) {
258
+ console.error(e);
259
+ return null;
240
260
  }
241
- }, [errorMessage]);
261
+ };
242
262
  (0, react_1.useEffect)(() => {
243
- const fetchDistinctHelper = async (column, table) => {
263
+ const fetchSchema = async () => {
244
264
  try {
245
- const query = `SELECT DISTINCT ${column} FROM ${table};`;
246
- const response = await fetch(`https://quill-344421.uc.r.appspot.com/dashquery`, {
265
+ const response = await fetch(`${client.queryEndpoint}`, {
247
266
  method: 'POST',
248
267
  headers: {
268
+ ...client.queryHeaders,
249
269
  'Content-Type': 'application/json',
250
270
  },
251
271
  body: JSON.stringify({
252
- orgId: client.customerId,
253
- publicKey: client.publicKey,
254
- query: query,
272
+ metadata: {
273
+ clientId: client.publicKey,
274
+ publicKey: client.publicKey,
275
+ task: 'schema',
276
+ removeCustomerField: true,
277
+ },
255
278
  }),
256
279
  });
257
- const data = await response.json();
258
- if (data.errorMessage) {
259
- // console.error(data.errorMessage);
260
- return null;
261
- }
262
- const options = data.rows.map((r) => r[column]);
263
- const newCheckboxValues = options.reduce((obj, col) => {
264
- obj[col] = false;
265
- return obj;
266
- }, {});
267
- return { table, column, values: newCheckboxValues };
268
- }
269
- catch (e) {
270
- console.error(e);
271
- return null;
272
- }
273
- };
274
- const fetchSchema = async () => {
275
- try {
276
- const response = await fetch(`https://quill-344421.uc.r.appspot.com/schema2/${client.publicKey}`).then((res) => res.json());
280
+ const results = await response.json();
277
281
  // Filter out hidden columns on tables back from schema2.
278
- const tables = response?.tables;
279
- for (const table of tables) {
280
- table.columns = table.columns.filter((column) =>
281
- // Quick and dirty fix for removing org ids from response.
282
- // TODO: Fix this on the backend or something.
283
- column.isVisible && column.displayName !== 'pm_company_id');
284
- }
282
+ const tables = results.data.tables || results.data.data.tables;
285
283
  setSchemaTables(tables ?? []);
286
- setOrderedColumnNames((tables ?? [])
287
- // .filter((t: any) => t.displayName === initialTableName)
288
- .flatMap((table) => table.columns.map((c) => `${table.displayName}.${c.displayName}`)));
289
- // Fetch all the unique values in parallel
290
- const pendingFetches = [];
291
- for (let table of tables ?? []) {
292
- for (let column of table.columns) {
293
- if (!(0, ast_1.isTextColumnType)(column.fieldType))
294
- continue;
295
- const fetchPromise = fetchDistinctHelper(column.name, table.displayName);
296
- pendingFetches.push(fetchPromise);
297
- }
298
- }
299
- const newUniqueValues = {};
300
- const resolvedPromises = await Promise.all(pendingFetches);
301
- for (const resolvedData of resolvedPromises) {
302
- if (resolvedData) {
303
- const { table, column, values } = resolvedData;
304
- if (!newUniqueValues[table]) {
305
- newUniqueValues[table] = {};
306
- }
307
- newUniqueValues[table][column] = values;
308
- }
309
- }
310
- if ((0, crypto_1.hashCode)(uniqueValues) !== (0, crypto_1.hashCode)(newUniqueValues)) {
311
- setUniqueValues(newUniqueValues);
284
+ setOrderedColumnNames((tables ?? []).flatMap((table) => table.columns
285
+ .map((c) => `${table.name}.${c.name}`)
286
+ .sort((a, b) => {
287
+ const aIsId = a.endsWith('.id') || a.endsWith('_id');
288
+ const bIsId = b.endsWith('.id') || b.endsWith('_id');
289
+ if (aIsId && !bIsId)
290
+ return 1;
291
+ if (bIsId && !aIsId)
292
+ return -1;
293
+ return 0;
294
+ })));
295
+ if (initialTableName && initialLoad) {
296
+ setInitialLoad(false);
297
+ setLoading(true);
298
+ await getDistinctValues(initialTableName, tables);
299
+ const columnsForTable = tables
300
+ .find((t) => t.name === initialTableName)
301
+ ?.columns.map((c) => c.name);
302
+ await handleAsk(`get ${columnsForTable} from ${initialTableName}`);
312
303
  }
313
304
  }
314
305
  catch (error) {
@@ -332,7 +323,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
332
323
  const paths = globalPath.split('.').filter((p) => p);
333
324
  if (paths.length === 0 && !isInsertion && !isReplaceSubtree) {
334
325
  setFormData(null);
335
- setBaseAst((0, util_1.deepCopy)({
326
+ const newAst = (0, util_1.deepCopy)({
336
327
  ...constants_1.defaultAST,
337
328
  ...baseAst,
338
329
  ...(!baseAst?.columns && {
@@ -346,12 +337,13 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
346
337
  from: [{ ...constants_1.defaultTable, table: initialTableName }],
347
338
  }),
348
339
  where: null,
349
- }));
340
+ });
341
+ setBaseAst(newAst);
342
+ fetchSqlQuery(newAst, null);
350
343
  return;
351
344
  }
352
345
  if (!formData && isInsertion) {
353
- setFormData(value);
354
- setBaseAst((0, util_1.deepCopy)({
346
+ const newAst = (0, util_1.deepCopy)({
355
347
  ...constants_1.defaultAST,
356
348
  ...baseAst,
357
349
  ...(!baseAst?.columns && {
@@ -365,7 +357,10 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
365
357
  from: [{ ...constants_1.defaultTable, table: initialTableName }],
366
358
  }),
367
359
  where: value,
368
- }));
360
+ });
361
+ setFormData(value);
362
+ setBaseAst(newAst);
363
+ fetchSqlQuery(newAst, value);
369
364
  return;
370
365
  }
371
366
  let newState = (0, util_1.deepCopy)(formData);
@@ -449,7 +444,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
449
444
  }
450
445
  }
451
446
  setFormData(newState);
452
- setBaseAst({
447
+ const newAst = {
453
448
  ...constants_1.defaultAST,
454
449
  ...baseAst,
455
450
  ...(!baseAst?.columns && {
@@ -463,7 +458,9 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
463
458
  from: [{ ...constants_1.defaultTable, table: initialTableName }],
464
459
  }),
465
460
  where: { ...newState },
466
- });
461
+ };
462
+ setBaseAst(newAst);
463
+ fetchSqlQuery(newAst, newState);
467
464
  });
468
465
  };
469
466
  // TODO: Merge this function with the updateFormData function
@@ -612,6 +609,9 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
612
609
  };
613
610
  // Function to handle operator changes
614
611
  const handleOperatorChange = (value, node, keyPrefix, column = null) => {
612
+ if (!keyPrefix) {
613
+ setTopLevelBinaryOperator(value);
614
+ }
615
615
  if (isPending) {
616
616
  updateActiveItem([{ path: keyPrefix + 'operator', value }], { column });
617
617
  }
@@ -680,6 +680,23 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
680
680
  .find((c) => c.name === columnName);
681
681
  return column?.fieldType;
682
682
  };
683
+ const emptyPivotColumns = () => {
684
+ if (pivot && pivot.rowField && pivot.columnField && pivot.valueField) {
685
+ return [
686
+ { label: (0, textProcessing_1.snakeCaseToTitleCase)(pivot.rowField) },
687
+ { label: (0, textProcessing_1.snakeCaseToTitleCase)(pivot.columnField) },
688
+ ];
689
+ }
690
+ else if (pivot && pivot.rowField && pivot.valueField) {
691
+ return [
692
+ { label: (0, textProcessing_1.snakeCaseToTitleCase)(pivot.rowField) },
693
+ { label: (0, textProcessing_1.snakeCaseToTitleCase)(pivot.valueField) },
694
+ ];
695
+ }
696
+ else {
697
+ return [{ label: (0, textProcessing_1.snakeCaseToTitleCase)(pivot.valueField) }];
698
+ }
699
+ };
683
700
  /**
684
701
  * Render form fields based on the type of the node
685
702
  * @param node the AST or subtree to render recursively
@@ -726,7 +743,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
726
743
  handleReplaceSubtree(keyPrefix, newSubtree);
727
744
  }
728
745
  }, options: getAllPossibleColumns().map((column) => ({
729
- label: column.displayName,
746
+ label: (0, textProcessing_1.snakeCaseToTitleCase)(column.displayName),
730
747
  value: column.name,
731
748
  })) }), (0, jsx_runtime_1.jsx)(Select, { theme: theme, value: dateFilterType, onChange: (value) => {
732
749
  if (value === dateFilterType)
@@ -820,7 +837,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
820
837
  else if ((0, util_1.isInTheLastInterval)(node, client.databaseType)) {
821
838
  const { dateColumn, dateFilterType, intervalCount, intervalType } = (0, util_1.getDateFilterInfo)(node);
822
839
  const options = getAllPossibleColumns().map((column) => ({
823
- label: column.displayName,
840
+ label: (0, textProcessing_1.snakeCaseToTitleCase)(column.displayName),
824
841
  value: column.name,
825
842
  }));
826
843
  const plural = node.right.args.value[1].expr.value > 1 ? 's' : '';
@@ -871,7 +888,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
871
888
  else if ((0, util_1.isTheCurrentInterval)(node, client.databaseType)) {
872
889
  const { dateFilterType } = (0, util_1.getDateFilterInfo)(node);
873
890
  const options = getAllPossibleColumns().map((column) => ({
874
- label: column.displayName,
891
+ label: (0, textProcessing_1.snakeCaseToTitleCase)(column.displayName),
875
892
  value: column.name,
876
893
  }));
877
894
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
@@ -916,7 +933,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
916
933
  }
917
934
  else if ((0, util_1.isThePreviousInterval)(node, client.databaseType)) {
918
935
  const options = getAllPossibleColumns().map((column) => ({
919
- label: column.displayName,
936
+ label: (0, textProcessing_1.snakeCaseToTitleCase)(column.displayName),
920
937
  value: column.name,
921
938
  }));
922
939
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
@@ -977,7 +994,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
977
994
  }
978
995
  else if ((0, util_1.isColumnComparison)(node)) {
979
996
  const options = getAllPossibleColumns().map((column) => ({
980
- label: column.displayName,
997
+ label: (0, textProcessing_1.snakeCaseToTitleCase)(column.displayName),
981
998
  value: column.name,
982
999
  }));
983
1000
  // grab the value of the left child of the column comparison
@@ -1031,6 +1048,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1031
1048
  gap: 12,
1032
1049
  flexDirection: 'column',
1033
1050
  width: '100%',
1051
+ padding: '6px 0px',
1034
1052
  }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
1035
1053
  display: 'flex',
1036
1054
  gap: 20,
@@ -1072,7 +1090,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1072
1090
  else {
1073
1091
  handleDeleteVariant(keyPrefix + 'right.' + 'value', key);
1074
1092
  }
1075
- } }), (0, jsx_runtime_1.jsx)("span", { children: key })] }, key))) }, keyPrefix + 'right.'))] }));
1093
+ } }), (0, jsx_runtime_1.jsx)("span", { style: { fontFamily: theme.fontFamily }, children: key })] }, key))) }, keyPrefix + 'right.'))] }));
1076
1094
  }
1077
1095
  else {
1078
1096
  const columnName = node.left.column;
@@ -1126,7 +1144,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1126
1144
  }
1127
1145
  case 'column_ref': {
1128
1146
  const options = getAllPossibleColumns().map((column) => ({
1129
- label: column.displayName,
1147
+ label: (0, textProcessing_1.snakeCaseToTitleCase)(column.displayName),
1130
1148
  value: column.name,
1131
1149
  }));
1132
1150
  return ((0, jsx_runtime_1.jsx)(Select, { theme: theme, style: { width: '120px' }, value: node.column ?? options[0]?.value, onChange: (value) => {
@@ -1253,10 +1271,10 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1253
1271
  isInTheCurrentIntervalSentence ??
1254
1272
  isInTheLastIntervalSentence ??
1255
1273
  isInThePreviousIntervalSentence ?? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [node.left &&
1256
- renderSentence(formData, node.left, keyPrefix + 'left.', false, false, isRow), isRow ? (' ' + OPS[node.operator] + ' ') : topLevelBinaryOperator === 'OR' ? ((0, jsx_runtime_1.jsx)(TopLevelBooleanSwitch, { node: node, keyPrefix: keyPrefix, handleOperatorChange: handleOperatorChange, Select: Select })) : null, node.right &&
1274
+ renderSentence(formData, node.left, keyPrefix + 'left.', false, false, isRow), isRow ? (' ' + OPS[node.operator] + ' ') : isTopLevel || topLevelBinaryOperator === 'OR' ? ((0, jsx_runtime_1.jsx)(TopLevelBooleanSwitch, { node: node, keyPrefix: keyPrefix, handleOperatorChange: handleOperatorChange, Select: Select })) : null, node.right &&
1257
1275
  renderSentence(formData, node.right, keyPrefix + 'right.', false, false, isRow)] })) }));
1258
1276
  case 'column_ref':
1259
- return node.column;
1277
+ return (0, textProcessing_1.snakeCaseToTitleCase)(node.column);
1260
1278
  case 'expr_list':
1261
1279
  if (node.value.length === 1) {
1262
1280
  const subQuery = renderSentence(formData, node.value[0]);
@@ -1288,10 +1306,10 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1288
1306
  if (node.args.value.length < 1)
1289
1307
  return null;
1290
1308
  if (node.args.value[0].value) {
1291
- return node.args.value[0].value.replaceAll('%', '');
1309
+ return (0, textProcessing_1.snakeCaseToTitleCase)(node.args.value[0].value.replaceAll('%', ''));
1292
1310
  }
1293
1311
  if (node.args.value[0].column)
1294
- return node.args.value[0].column.replaceAll('%', '');
1312
+ return (0, textProcessing_1.snakeCaseToTitleCase)(node.args.value[0].column.replaceAll('%', ''));
1295
1313
  return null;
1296
1314
  }
1297
1315
  if (node.name.toLowerCase() === 'current_date' ||
@@ -1328,37 +1346,22 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1328
1346
  const tableNamesInQuery = baseAst.from.map((tbl) => tbl.table);
1329
1347
  return schemaTables
1330
1348
  .filter((t) => tableNamesInQuery.includes(t.displayName))
1331
- .flatMap((table) => table.columns.map((c) => ({
1349
+ .flatMap((table) => table.columns
1350
+ .map((c) => ({
1332
1351
  ...c,
1333
1352
  table: table.displayName,
1334
- })));
1335
- };
1336
- const getDateColumns = () => {
1337
- const allColumns = getAllPossibleColumns();
1338
- return allColumns.filter((c) => (0, ast_1.isDateishColumnType)(c.fieldType));
1339
- };
1340
- const getNumericColumns = () => {
1341
- const allColumns = getAllPossibleColumns();
1342
- const selectedColumnNames = selectedColumns.map((col) => col.split('.')[1]);
1343
- return allColumns
1344
- .filter((column) => {
1345
- return selectedColumnNames.includes(column.name);
1346
- })
1347
- .filter((c) => (0, ast_1.isNumericColumnType)(c.fieldType));
1348
- };
1349
- const getNonNumericColumns = () => {
1350
- const allColumns = getAllPossibleColumns();
1351
- const selectedColumnNames = selectedColumns.map((col) => col.split('.')[1]);
1352
- return allColumns
1353
- .filter((column) => selectedColumnNames.includes(column.name))
1354
- .filter((c) => !(0, ast_1.isNumericColumnType)(c.fieldType));
1355
- };
1356
- const getStringColumns = () => {
1357
- const allColumns = getAllPossibleColumns();
1358
- const selectedColumnNames = selectedColumns.map((col) => col.split('.')[1]);
1359
- return allColumns
1360
- .filter((column) => selectedColumnNames.includes(column.name))
1361
- .filter((c) => (0, ast_1.isTextColumnType)(c.fieldType));
1353
+ }))
1354
+ .sort((a, b) => {
1355
+ const aIsId = a.name.toLowerCase() === 'id' ||
1356
+ a.name.toLowerCase().endsWith('_id');
1357
+ const bIsId = b.name.toLowerCase() === 'id' ||
1358
+ b.name.toLowerCase().endsWith('_id');
1359
+ if (aIsId && !bIsId)
1360
+ return 1;
1361
+ if (bIsId && !aIsId)
1362
+ return -1;
1363
+ return 0;
1364
+ }));
1362
1365
  };
1363
1366
  /**
1364
1367
  * Return whether all columns have been selected (used to hide select all
@@ -1382,26 +1385,6 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1382
1385
  },
1383
1386
  as: null,
1384
1387
  });
1385
- const SortableItem = ({ id, label, setSelectedColumns, selectedColumns, }) => {
1386
- const { attributes, listeners, setNodeRef, transform, transition } = (0, sortable_1.useSortable)({ id: id });
1387
- const style = {
1388
- transform: utilities_1.CSS.Transform.toString(transform),
1389
- transition,
1390
- };
1391
- const handleSelect = () => {
1392
- setSelectedColumns((selectedColumns) => {
1393
- if (selectedColumns.includes(id)) {
1394
- return selectedColumns.filter((column) => column !== id);
1395
- }
1396
- else {
1397
- return [...selectedColumns, id];
1398
- }
1399
- });
1400
- };
1401
- return ((0, jsx_runtime_1.jsx)("div", { style: { userSelect: 'none', ...style }, ref: setNodeRef, children: (0, jsx_runtime_1.jsx)(SelectColumn, { selected: selectedColumns?.includes(id), setSelected: handleSelect, label: label, children: (0, jsx_runtime_1.jsx)("div", { style: {
1402
- cursor: 'grab',
1403
- }, ...attributes, ...listeners, children: (0, jsx_runtime_1.jsx)(HandleButton, {}) }) }) }));
1404
- };
1405
1388
  const AddConditionPopover = ({ onSave }) => {
1406
1389
  return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [(0, jsx_runtime_1.jsx)("h1", { style: {
1407
1390
  fontWeight: '600',
@@ -1415,8 +1398,10 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1415
1398
  justifyContent: 'end',
1416
1399
  }, children: (0, jsx_runtime_1.jsx)(Button, { onClick: onSave, label: 'Add condition' }) })] }));
1417
1400
  };
1418
- const fetchUponChange = async () => {
1419
- if ((formData || baseAst) && !loading) {
1401
+ const fetchUponChange = async (baseAst, newFormData) => {
1402
+ // if newFormData is null still use it
1403
+ const curFormData = newFormData !== undefined ? newFormData : formData;
1404
+ if ((curFormData || baseAst) && !loading) {
1420
1405
  try {
1421
1406
  setLoading(true);
1422
1407
  const res2 = await fetch('https://quill-344421.uc.r.appspot.com/patterns', {
@@ -1425,7 +1410,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1425
1410
  'Content-Type': 'application/json',
1426
1411
  },
1427
1412
  body: JSON.stringify({
1428
- ast: { ...baseAst, where: formData },
1413
+ ast: { ...baseAst, where: curFormData },
1429
1414
  publicKey: client.publicKey,
1430
1415
  orgId: client.customerId,
1431
1416
  }),
@@ -1434,6 +1419,21 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1434
1419
  if (data2.rows && data2.rows.length) {
1435
1420
  const tables = (0, ast_1.getTableNames)(baseAst);
1436
1421
  const table = tables.length >= 1 ? tables[0] : initialTableName;
1422
+ if (table !== currentTable) {
1423
+ getDistinctValues(table);
1424
+ setCurrentTable(table);
1425
+ }
1426
+ const sortedFields = data2.fields.sort((a, b) => {
1427
+ const aIsId = a.name.toLowerCase() === 'id' ||
1428
+ a.name.toLowerCase().endsWith('_id');
1429
+ const bIsId = b.name.toLowerCase() === 'id' ||
1430
+ b.name.toLowerCase().endsWith('_id');
1431
+ if (aIsId && !bIsId)
1432
+ return 1;
1433
+ if (bIsId && !aIsId)
1434
+ return -1;
1435
+ return 0;
1436
+ });
1437
1437
  if (pivot) {
1438
1438
  // Do all of this to make sure we have the right unique columns when applying a pivot
1439
1439
  let uniqueFormatted = {};
@@ -1444,7 +1444,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1444
1444
  uniqueFormatted[pivot.columnField] = uniqueRecords;
1445
1445
  const pivotedData = (0, PivotModal_1.generatePivotTable)(pivot, data2.rows, [null, null, null], false);
1446
1446
  console.info(`%c[Pivot]: ${JSON.stringify(pivot)}`, 'color: dimgray');
1447
- setPivotData(pivotedData);
1447
+ setPivotData(pivotedData || []);
1448
1448
  setRows(data2.rows);
1449
1449
  setFields(data2.fields);
1450
1450
  }
@@ -1567,8 +1567,35 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1567
1567
  }
1568
1568
  return false;
1569
1569
  };
1570
- const handleAsk = async () => {
1571
- if (!aiPrompt) {
1570
+ const getDistinctValues = async (table, overrideSchema) => {
1571
+ const schemaInfo = overrideSchema || schemaTables;
1572
+ const tableInfo = schemaInfo.find((tableInfo) => tableInfo.name === table);
1573
+ if (tableInfo) {
1574
+ const pendingFetches = [];
1575
+ for (let column of tableInfo.columns) {
1576
+ if (!(0, ast_1.isTextColumnType)(column.fieldType))
1577
+ continue;
1578
+ const fetchPromise = fetchDistinctHelper(column.name, tableInfo.displayName);
1579
+ pendingFetches.push(fetchPromise);
1580
+ }
1581
+ const newUniqueValues = {};
1582
+ const resolvedPromises = await Promise.all(pendingFetches);
1583
+ for (const resolvedData of resolvedPromises) {
1584
+ if (resolvedData) {
1585
+ const { table, column, values } = resolvedData;
1586
+ if (!newUniqueValues[table]) {
1587
+ newUniqueValues[table] = {};
1588
+ }
1589
+ newUniqueValues[table][column] = values;
1590
+ }
1591
+ }
1592
+ if ((0, crypto_1.hashCode)(uniqueValues) !== (0, crypto_1.hashCode)(newUniqueValues)) {
1593
+ setUniqueValues(newUniqueValues);
1594
+ }
1595
+ }
1596
+ };
1597
+ const handleAsk = async (overridePrompt = '') => {
1598
+ if (!aiPrompt && !overridePrompt) {
1572
1599
  return;
1573
1600
  }
1574
1601
  try {
@@ -1587,7 +1614,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1587
1614
  method: 'POST',
1588
1615
  headers: { 'Content-Type': 'application/json' },
1589
1616
  body: JSON.stringify({
1590
- initialQuestion: aiPrompt,
1617
+ initialQuestion: aiPrompt || overridePrompt,
1591
1618
  publicKey: client.publicKey,
1592
1619
  }),
1593
1620
  });
@@ -1635,11 +1662,14 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1635
1662
  newAst = (0, util_1.removeNonSelectedTableReferences)(newAst, tableAlias ?? table);
1636
1663
  // newAst = convertDateComparison(newAst); // TODO
1637
1664
  ast = newAst; // so we fetch data for newAst later.
1665
+ if (table !== currentTable) {
1666
+ getDistinctValues(table);
1667
+ setCurrentTable(table);
1668
+ }
1638
1669
  setPivotRowField(groupByPivot?.rowField);
1639
1670
  setPivotColumnField(groupByPivot?.columnField);
1640
1671
  setPivotValueField(groupByPivot?.valueField);
1641
1672
  setPivotAggregation(groupByPivot?.aggregationType);
1642
- setPivot(groupByPivot);
1643
1673
  setSelectedColumns((0, util_1.deepCopy)(newAst).columns?.map((column) => {
1644
1674
  if (column.expr.type === 'column_ref') {
1645
1675
  return `${table}.${column.expr.column}`;
@@ -1650,7 +1680,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1650
1680
  return `${table}.${column.expr.value}`;
1651
1681
  }));
1652
1682
  if (groupByPivot) {
1653
- setBaseAst((0, util_1.deepCopy)({ ...newAst, orderby: null }));
1683
+ setBaseAst((0, util_1.deepCopy)({ ...newAst, orderby: null, limit: null }));
1654
1684
  }
1655
1685
  else {
1656
1686
  setBaseAst((0, util_1.deepCopy)({ ...newAst }));
@@ -1659,8 +1689,6 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1659
1689
  setTopLevelBinaryOperator(
1660
1690
  // @ts-ignore
1661
1691
  newAst?.where ? newAst?.where?.operator : 'AND');
1662
- if (groupByPivot)
1663
- return; // the useEffect will handle the rest
1664
1692
  }
1665
1693
  const res2 = await fetch('https://quill-344421.uc.r.appspot.com/patterns', {
1666
1694
  method: 'POST',
@@ -1676,11 +1704,13 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1676
1704
  const data2 = await res2.json();
1677
1705
  if (data2.rows && data2.rows.length) {
1678
1706
  const tables = (0, ast_1.getTableNames)(newAst);
1679
- const table = tables.length >= 1 ? tables[0] : initialTableName;
1680
1707
  if (groupByPivot) {
1681
- const pivotedData = (0, PivotModal_1.generatePivotTable)(pivot, data2.rows, [null, null, null], false);
1708
+ const pivotedData = (0, PivotModal_1.generatePivotTable)(
1709
+ // @ts-ignore
1710
+ groupByPivot, data2.rows, [null, null, null], false);
1682
1711
  console.info(`%c[Pivot]: ${JSON.stringify(groupByPivot)}`, 'color: dimgray');
1683
1712
  setPivotData(pivotedData);
1713
+ setPivot(groupByPivot);
1684
1714
  setRows(data2.rows);
1685
1715
  setFields(data2.fields);
1686
1716
  }
@@ -1690,6 +1720,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1690
1720
  }
1691
1721
  }
1692
1722
  else {
1723
+ setPivotData([]);
1693
1724
  setRows([]);
1694
1725
  setFields([]);
1695
1726
  }
@@ -1708,7 +1739,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1708
1739
  }
1709
1740
  catch (e) {
1710
1741
  console.error(e);
1711
- setErrorMessage(`${e.name}: ${e.message}`);
1742
+ setErrorMessage(`Error: Couldn't process your request, please re-word your prompt.`);
1712
1743
  }
1713
1744
  finally {
1714
1745
  setLoading(false);
@@ -1734,11 +1765,17 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1734
1765
  clearAllState();
1735
1766
  return;
1736
1767
  }
1737
- const newAst = { ...baseAst, columns };
1738
- setBaseAst((0, util_1.deepCopy)(newAst));
1768
+ const newAst = (0, util_1.deepCopy)({ ...baseAst, columns });
1769
+ setBaseAst(newAst);
1770
+ fetchSqlQuery(newAst);
1739
1771
  };
1740
1772
  function TopLevelBooleanSwitch({ node, keyPrefix, handleOperatorChange, }) {
1741
- return ((0, jsx_runtime_1.jsx)("div", { style: { width: 'fit-content' }, children: (0, jsx_runtime_1.jsx)(Tabs, { defaultValue: node.operator, options: ui_1.DEFAULT_TAB_OPTIONS, onValueChange: (value) => handleOperatorChange(value, node, keyPrefix) }) }));
1773
+ return ((0, jsx_runtime_1.jsx)("div", { style: { width: 'fit-content' }, children: (0, jsx_runtime_1.jsx)(Tabs, { defaultValue: node.operator, options: ui_1.DEFAULT_TAB_OPTIONS, onValueChange: (value) => {
1774
+ if (loading) {
1775
+ return;
1776
+ }
1777
+ handleOperatorChange(value, node, keyPrefix);
1778
+ } }) }));
1742
1779
  }
1743
1780
  const DraggableItem = ({ id, label, onDelete }) => {
1744
1781
  const { attributes, listeners, setNodeRef, transform, transition } = (0, sortable_1.useSortable)({ id: id });
@@ -1746,7 +1783,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1746
1783
  transform: utilities_1.CSS.Transform.toString(transform),
1747
1784
  transition,
1748
1785
  };
1749
- return ((0, jsx_runtime_1.jsx)("div", { style: { ...style }, ref: setNodeRef, children: (0, jsx_runtime_1.jsx)(DraggableColumn, { label: label, onDelete: onDelete, children: (0, jsx_runtime_1.jsx)("div", { style: {
1786
+ return ((0, jsx_runtime_1.jsx)("div", { style: { ...style }, ref: setNodeRef, children: (0, jsx_runtime_1.jsx)(DraggableColumn, { label: (0, textProcessing_1.snakeCaseToTitleCase)(label), onDelete: onDelete, children: (0, jsx_runtime_1.jsx)("div", { style: {
1750
1787
  cursor: 'grab',
1751
1788
  }, ...attributes, ...listeners, children: (0, jsx_runtime_1.jsx)(HandleButton, {}) }) }) }));
1752
1789
  };
@@ -1784,6 +1821,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1784
1821
  };
1785
1822
  const newAst = baseAst ? newBaseAst : fallbackAST;
1786
1823
  setBaseAst(newAst);
1824
+ fetchSqlQuery(newAst);
1787
1825
  }
1788
1826
  }
1789
1827
  const columnNamesInAst = baseAst?.columns.map((col) => {
@@ -1807,18 +1845,6 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1807
1845
  gap: 8,
1808
1846
  }, children: [columnNamesInAst.map((name) => ((0, jsx_runtime_1.jsx)(DraggableItem, { id: name, label: name, onDelete: () => handleDeleteColumn(name) }, name))), columnNamesInAst?.length > 0 && (0, jsx_runtime_1.jsx)("div", { style: { height: 6 } })] }) }) }));
1809
1847
  }
1810
- const allNumericColumns = getNumericColumns().map((column) => ({
1811
- label: column.displayName,
1812
- value: column.name,
1813
- }));
1814
- const allNonNumericColumns = getNonNumericColumns().map((column) => ({
1815
- label: column.displayName,
1816
- value: column.name,
1817
- }));
1818
- const allStringColumns = getStringColumns().map((column) => ({
1819
- label: column.displayName,
1820
- value: column.name,
1821
- }));
1822
1848
  if (loading) {
1823
1849
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
1824
1850
  display: 'flex',
@@ -1829,7 +1855,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1829
1855
  if (!openPopover) {
1830
1856
  setOpenPopover('AddColumnPopover');
1831
1857
  }
1832
- }, label: 'Select columns' }), title: "Select columns", onClose: () => {
1858
+ }, label: 'Select columns' }), label: "Select columns", onClose: () => {
1833
1859
  setIsPending(false);
1834
1860
  setActiveEditItem(null);
1835
1861
  setActivePath(null);
@@ -1838,7 +1864,10 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1838
1864
  setActiveEditItem(null);
1839
1865
  setActivePath(null);
1840
1866
  setOpenPopover(null);
1841
- }, orderedColumnNames: orderedColumnNames, setOrderedColumnNames: setOrderedColumnNames, selectedColumns: selectedColumns, setSelectedColumns: setSelectedColumns, isSelectedAllColumns: isSelectedAllColumns, clearAllState: clearAllState, nameToColumn: nameToColumn, baseAst: baseAst, setBaseAst: setBaseAst, pivot: pivot, initialTableName: initialTableName, defaultAST: constants_1.defaultAST, defaultTable: constants_1.defaultTable, setPivot: setPivot, TextInput: TextInput, SelectColumn: SelectColumn, SecondaryButton: SecondaryButton, Button: Button, HandleButton: HandleButton }) }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Filters" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), formData && ((0, jsx_runtime_1.jsx)("div", { style: {
1867
+ }, orderedColumnNames: orderedColumnNames, setOrderedColumnNames: setOrderedColumnNames, selectedColumns: selectedColumns, setSelectedColumns: setSelectedColumns, isSelectedAllColumns: isSelectedAllColumns, clearAllState: clearAllState, nameToColumn: nameToColumn, baseAst: baseAst, setBaseAst: (newAst) => {
1868
+ setBaseAst(newAst);
1869
+ fetchSqlQuery(newAst);
1870
+ }, pivot: pivot, initialTableName: initialTableName, defaultAST: constants_1.defaultAST, defaultTable: constants_1.defaultTable, setPivot: setPivot, TextInput: TextInput, SelectColumn: SelectColumn, SecondaryButton: SecondaryButton, Button: Button, HandleButton: HandleButton }) }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Filters" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), formData && ((0, jsx_runtime_1.jsx)("div", { style: {
1842
1871
  display: 'flex',
1843
1872
  flexDirection: 'column',
1844
1873
  gap: 8,
@@ -1849,6 +1878,9 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1849
1878
  gap: 2.5,
1850
1879
  alignItems: 'flex-start',
1851
1880
  }, children: [(0, jsx_runtime_1.jsx)(Popover, { isOpen: openPopover === 'AddFilterPopover', title: 'Add filter', trigger: (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => {
1881
+ if (!selectedColumns || selectedColumns.length === 0) {
1882
+ return;
1883
+ }
1852
1884
  if (!openPopover) {
1853
1885
  const value = orderedColumnNames[0];
1854
1886
  const [_table, column] = value.split('.');
@@ -1935,14 +1967,18 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1935
1967
  } }) }))] }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Pivot" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), (0, jsx_runtime_1.jsx)(PivotModal_1.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: () => {
1936
1968
  setPivot(null);
1937
1969
  setPivotData(null);
1938
- }, selectPivot: (pivot) => {
1970
+ },
1971
+ // TODOs
1972
+ selectPivot: (pivot) => {
1939
1973
  if (!pivot)
1940
1974
  return;
1941
1975
  const newAst = { ...baseAst };
1942
1976
  newAst.orderby = null;
1943
1977
  setBaseAst(newAst); // trigger refetch
1944
1978
  setPivot(pivot);
1945
- }, selectPivotOnEdit: true, showTrigger: !pivot || !pivotData, theme: theme, LabelComponent: Label, HeaderComponent: Header, dateRange: [null, null, null], recommendPivotCount: 3 }), pivot && pivotData && ((0, jsx_runtime_1.jsx)(PivotList_1.PivotCard, { pivotTable: {
1979
+ const pivotedData = (0, PivotModal_1.generatePivotTable)(pivot, rows, [null, null, null], false);
1980
+ setPivotData(pivotedData || []);
1981
+ }, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: Label, HeaderComponent: Header, dateRange: [null, null, null], recommendPivotCount: 3, SecondaryButtonComponent: SecondaryButton }), pivot && ((0, jsx_runtime_1.jsx)(PivotList_1.PivotCard, { pivotTable: {
1946
1982
  pivot: pivot,
1947
1983
  rows: pivotData?.rows || [],
1948
1984
  columns: pivotData?.columns || [],
@@ -1969,10 +2005,16 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1969
2005
  }, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setOpenPopover: setOpenPopover, SortPopover: SortPopover, EditPopover: AddSortPopover_1.AddSortPopover, handleDelete: () => {
1970
2006
  setPivot({ ...pivot, sort: false });
1971
2007
  setBaseAst((0, util_1.deepCopy)(baseAst));
2008
+ if (!pivot) {
2009
+ fetchSqlQuery(baseAst);
2010
+ }
1972
2011
  }, onSave: (column, direction) => {
1973
2012
  setPivot({ ...pivot, sort: true, sortDirection: direction });
1974
2013
  setOpenPopover(null);
1975
2014
  setBaseAst((0, util_1.deepCopy)(baseAst));
2015
+ if (!pivot) {
2016
+ fetchSqlQuery(baseAst);
2017
+ }
1976
2018
  } }, `sort-sentence-pivot`) })), baseAst && baseAst.orderby && ((0, jsx_runtime_1.jsx)("div", { style: {
1977
2019
  display: 'flex',
1978
2020
  flexDirection: 'column',
@@ -1997,11 +2039,17 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
1997
2039
  setActivePath(null);
1998
2040
  setOpenPopover(null);
1999
2041
  setBaseAst((0, util_1.deepCopy)(newAst));
2042
+ if (!pivot) {
2043
+ fetchSqlQuery(newAst);
2044
+ }
2000
2045
  }, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setOpenPopover: setOpenPopover, SortPopover: SortPopover, EditPopover: AddSortPopover_1.AddSortPopover, handleDelete: () => {
2001
2046
  const newAst = { ...baseAst };
2002
2047
  newAst.orderby.splice(id, 1);
2003
2048
  setBaseAst((0, util_1.deepCopy)(newAst));
2004
- } }, `sort-sentence-${id}`))) })), (0, jsx_runtime_1.jsx)(Popover, { isOpen: openPopover === 'AddSortPopover', trigger: (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => {
2049
+ if (!pivot) {
2050
+ fetchSqlQuery(newAst);
2051
+ }
2052
+ } }, `sort-sentence-${id}`))) })), (0, jsx_runtime_1.jsx)(Popover, { isOpen: openPopover === 'AddSortPopover', setIsOpen: () => { }, trigger: (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => {
2005
2053
  if (!openPopover) {
2006
2054
  setOpenPopover('AddSortPopover');
2007
2055
  }
@@ -2010,18 +2058,51 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2010
2058
  setActiveEditItem(null);
2011
2059
  setActivePath(null);
2012
2060
  setOpenPopover(null);
2013
- }, children: (0, jsx_runtime_1.jsx)(AddSortPopover_1.AddSortPopover, { columns: selectedColumns, Select: Select, Button: Button, onSave: () => { } }) })] }), (0, jsx_runtime_1.jsxs)(Container, { children: [!hideAi && ((0, jsx_runtime_1.jsxs)("form", { onSubmit: (event) => {
2061
+ }, children: (0, jsx_runtime_1.jsx)(AddSortPopover_1.AddSortPopover, { columns: selectedColumns, Select: Select, Button: Button, onSave: () => { } }) }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Limit" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), baseAst && baseAst.limit ? ((0, jsx_runtime_1.jsx)("div", { style: {
2062
+ display: 'flex',
2063
+ flexDirection: 'column',
2064
+ gap: 8,
2065
+ marginBottom: 12,
2066
+ }, children: (0, jsx_runtime_1.jsx)(AddLimitPopover_1.LimitSentence, { limit: baseAst.limit, setOpenPopover: setOpenPopover, LimitPopover: SortPopover, EditPopover: AddLimitPopover_1.AddLimitPopover, handleDelete: () => {
2067
+ const newAst = { ...baseAst };
2068
+ newAst.limit = null;
2069
+ setBaseAst((0, util_1.deepCopy)(newAst));
2070
+ fetchSqlQuery(newAst);
2071
+ }, onSave: (limit) => {
2072
+ const newAst = { ...baseAst };
2073
+ newAst.limit = {
2074
+ seperator: '',
2075
+ value: [
2076
+ {
2077
+ type: 'number',
2078
+ value: limit,
2079
+ },
2080
+ ],
2081
+ };
2082
+ setOpenPopover(null);
2083
+ setBaseAst((0, util_1.deepCopy)(newAst));
2084
+ fetchSqlQuery(newAst);
2085
+ } }) })) : ((0, jsx_runtime_1.jsx)(Popover, { isOpen: openPopover === 'AddLimitPopover', setIsOpen: () => { }, trigger: (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => {
2086
+ if (!openPopover) {
2087
+ setOpenPopover('AddLimitPopover');
2088
+ }
2089
+ }, label: 'Add limit' }), title: "Limit", onClose: () => {
2090
+ setIsPending(false);
2091
+ setActiveEditItem(null);
2092
+ setActivePath(null);
2093
+ setOpenPopover(null);
2094
+ }, children: (0, jsx_runtime_1.jsx)(TextInput, { value: 0, type: "number", style: { width: 120, minHeight: 32 }, onChange: (e) => { } }) }))] }), (0, jsx_runtime_1.jsxs)(Container, { children: [!hideAi && ((0, jsx_runtime_1.jsxs)("form", { onSubmit: (event) => {
2014
2095
  event.preventDefault();
2015
2096
  }, style: {
2016
2097
  display: 'flex',
2017
2098
  flexDirection: 'row',
2018
2099
  gap: 12,
2019
2100
  padding: 1,
2020
- }, children: [(0, jsx_runtime_1.jsx)(TextInput, { placeholder: "Ask a question...", type: "text", style: { width: '100%', fontSize: 14 }, value: aiPrompt }), (0, jsx_runtime_1.jsx)(Button, { onClick: () => { }, label: 'Ask AI' }), baseAst && ((0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: clearAllState, label: "New report" }))] })), baseAst && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TableLoadingState, {}), (0, jsx_runtime_1.jsxs)("div", { style: {
2101
+ }, children: [(0, jsx_runtime_1.jsx)(TextInput, { placeholder: baseAst ? 'Ask a follow-up question...' : 'Ask a question...', type: "text", style: { width: '100%', fontSize: 14 }, value: aiPrompt }), (0, jsx_runtime_1.jsx)(Button, { onClick: () => { }, label: 'Ask AI' }), baseAst && ((0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: clearAllState, label: "New report" }))] })), (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TableLoadingState, {}), (0, jsx_runtime_1.jsxs)("div", { style: {
2021
2102
  display: 'flex',
2022
2103
  flexDirection: 'row',
2023
2104
  gap: '12px',
2024
- }, children: [(0, jsx_runtime_1.jsx)("div", { style: { width: '100%' } }), (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => copyToClipboard(activeQuery), label: isCopying ? '✅ Copied' : 'Copy SQL' }), (0, jsx_runtime_1.jsx)(Button, { label: 'Add to dashboard', onClick: () => { } })] })] }))] }), (0, jsx_runtime_1.jsx)("style", { children: `body{margin:0;}` })] }));
2105
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: { width: '100%' } }), (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => copyToClipboard(activeQuery), label: isCopying ? '✅ Copied' : 'Copy SQL' }), (0, jsx_runtime_1.jsx)(Button, { label: 'Add to dashboard', onClick: () => { } })] })] })] }), (0, jsx_runtime_1.jsx)("style", { children: `body{margin:0;}` })] }));
2025
2106
  }
2026
2107
  return ((0, jsx_runtime_1.jsxs)("div", { ref: parentRef, style: {
2027
2108
  display: 'flex',
@@ -2046,7 +2127,10 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2046
2127
  setActiveEditItem(null);
2047
2128
  setActivePath(null);
2048
2129
  setOpenPopover(null);
2049
- }, orderedColumnNames: orderedColumnNames, setOrderedColumnNames: setOrderedColumnNames, selectedColumns: selectedColumns, setSelectedColumns: setSelectedColumns, isSelectedAllColumns: isSelectedAllColumns, clearAllState: clearAllState, nameToColumn: nameToColumn, baseAst: baseAst, setBaseAst: setBaseAst, pivot: pivot, initialTableName: initialTableName, defaultAST: constants_1.defaultAST, defaultTable: constants_1.defaultTable, setPivot: setPivot, TextInput: TextInput, SelectColumn: SelectColumn, SecondaryButton: SecondaryButton, Button: Button, HandleButton: HandleButton }) }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Filters" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), formData && ((0, jsx_runtime_1.jsx)("div", { style: {
2130
+ }, orderedColumnNames: orderedColumnNames, setOrderedColumnNames: setOrderedColumnNames, selectedColumns: selectedColumns, setSelectedColumns: setSelectedColumns, isSelectedAllColumns: isSelectedAllColumns, clearAllState: clearAllState, nameToColumn: nameToColumn, baseAst: baseAst, setBaseAst: (ast) => {
2131
+ setBaseAst(ast);
2132
+ fetchSqlQuery(ast);
2133
+ }, pivot: pivot, initialTableName: initialTableName, defaultAST: constants_1.defaultAST, defaultTable: constants_1.defaultTable, setPivot: setPivot, TextInput: TextInput, SelectColumn: SelectColumn, SecondaryButton: SecondaryButton, Button: Button, HandleButton: HandleButton }) }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Filters" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), formData && ((0, jsx_runtime_1.jsx)("div", { style: {
2050
2134
  display: 'flex',
2051
2135
  flexDirection: 'column',
2052
2136
  gap: 8,
@@ -2057,6 +2141,9 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2057
2141
  gap: 2.5,
2058
2142
  alignItems: 'flex-start',
2059
2143
  }, children: [(0, jsx_runtime_1.jsx)(Popover, { title: 'Add filter', isOpen: openPopover === 'AddFilterPopover', trigger: (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => {
2144
+ if (!selectedColumns || selectedColumns.length === 0) {
2145
+ return;
2146
+ }
2060
2147
  if (!openPopover) {
2061
2148
  const value = orderedColumnNames[0];
2062
2149
  const [_table, column] = value.split('.');
@@ -2142,7 +2229,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2142
2229
  setOpenPopover(null);
2143
2230
  clearCheckboxes();
2144
2231
  }
2145
- } }) }))] }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Pivot" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), (0, jsx_runtime_1.jsx)(PivotModal_1.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: () => {
2232
+ } }) }))] }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Pivot" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), (0, jsx_runtime_1.jsx)(PivotModal_1.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: () => {
2146
2233
  setPivot(null);
2147
2234
  setPivotData(null);
2148
2235
  }, selectPivot: (pivot) => {
@@ -2156,7 +2243,9 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2156
2243
  }
2157
2244
  setBaseAst(newAst); // trigger refetch
2158
2245
  setPivot(pivot);
2159
- }, selectPivotOnEdit: true, showTrigger: !pivot || !pivotData, theme: theme, LabelComponent: Label, HeaderComponent: Header, dateRange: [null, null, null], recommendPivotCount: 3 }), pivot && pivotData && ((0, jsx_runtime_1.jsx)(PivotList_1.PivotCard, { pivotTable: {
2246
+ const pivotedData = (0, PivotModal_1.generatePivotTable)(pivot, rows, [null, null, null], false);
2247
+ setPivotData(pivotedData || []);
2248
+ }, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: Label, HeaderComponent: Header, dateRange: [null, null, null], recommendPivotCount: 3 }), pivot && ((0, jsx_runtime_1.jsx)(PivotList_1.PivotCard, { pivotTable: {
2160
2249
  pivot: pivot,
2161
2250
  rows: pivotData?.rows || [],
2162
2251
  columns: pivotData?.columns || [],
@@ -2171,7 +2260,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2171
2260
  }, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: Button, HeaderComponent: Header, showEdit: false, onClose: () => {
2172
2261
  setPivot(null);
2173
2262
  setPivotData(null);
2174
- setBaseAst((0, util_1.deepCopy)(baseAst)); // trigger refetch
2263
+ setBaseAst((0, util_1.deepCopy)(baseAst));
2175
2264
  }, minHeight: 180, LabelComponent: Label, TextComponent: Text })), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Sort" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), pivot && pivot.sort && ((0, jsx_runtime_1.jsx)("div", { style: {
2176
2265
  display: 'flex',
2177
2266
  flexDirection: 'column',
@@ -2180,13 +2269,25 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2180
2269
  }, children: (0, jsx_runtime_1.jsx)(AddSortPopover_1.SortSentence, { sortData: {
2181
2270
  type: pivot.sortDirection,
2182
2271
  expr: { type: 'column_ref', column: pivot.rowField },
2183
- }, columns: selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setOpenPopover: setOpenPopover, SortPopover: SortPopover, EditPopover: AddSortPopover_1.AddSortPopover, handleDelete: () => {
2184
- setPivot({ ...pivot, sort: false });
2272
+ }, columns: pivot ? [`.${pivot.rowField}`] : selectedColumns, setIsPending: setIsPending, setEditPopoverKey: setEditPopoverKey, setActiveEditItem: setActiveEditItem, setOpenPopover: setOpenPopover, SortPopover: SortPopover, EditPopover: AddSortPopover_1.AddSortPopover, handleDelete: () => {
2273
+ if (pivot) {
2274
+ setPivot({ ...pivot, sort: false });
2275
+ const pivotedData = (0, PivotModal_1.generatePivotTable)({ ...pivot, sort: false }, rows, [null, null, null], false);
2276
+ setPivotData(pivotedData || []);
2277
+ return;
2278
+ }
2185
2279
  setBaseAst((0, util_1.deepCopy)(baseAst));
2280
+ fetchSqlQuery((0, util_1.deepCopy)(baseAst));
2186
2281
  }, onSave: (column, direction) => {
2187
- setPivot({ ...pivot, sort: true, sortDirection: direction });
2282
+ if (pivot) {
2283
+ setPivot({ ...pivot, sort: true, sortDirection: direction });
2284
+ const pivotedData = (0, PivotModal_1.generatePivotTable)({ ...pivot, sort: true, sortDirection: direction }, rows, [null, null, null], false);
2285
+ setPivotData(pivotedData || []);
2286
+ return;
2287
+ }
2188
2288
  setOpenPopover(null);
2189
2289
  setBaseAst((0, util_1.deepCopy)(baseAst));
2290
+ fetchSqlQuery((0, util_1.deepCopy)(baseAst));
2190
2291
  } }, `sort-sentence-pivot`) })), baseAst && baseAst.orderby && ((0, jsx_runtime_1.jsx)("div", { style: {
2191
2292
  display: 'flex',
2192
2293
  flexDirection: 'column',
@@ -2200,6 +2301,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2200
2301
  const newAst = { ...baseAst };
2201
2302
  newAst.orderby.splice(id, 1);
2202
2303
  setBaseAst((0, util_1.deepCopy)(newAst));
2304
+ fetchSqlQuery((0, util_1.deepCopy)(newAst));
2203
2305
  }, onSave: (column, direction) => {
2204
2306
  if (pivot) {
2205
2307
  setPivot({
@@ -2227,6 +2329,7 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2227
2329
  setActivePath(null);
2228
2330
  setOpenPopover(null);
2229
2331
  setBaseAst((0, util_1.deepCopy)(newAst));
2332
+ fetchSqlQuery((0, util_1.deepCopy)(newAst));
2230
2333
  } }, `sort-sentence-${id}`))) })), (0, jsx_runtime_1.jsx)(Popover, { isOpen: openPopover === 'AddSortPopover', trigger: (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => {
2231
2334
  if (!openPopover) {
2232
2335
  setOpenPopover('AddSortPopover');
@@ -2241,6 +2344,8 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2241
2344
  return;
2242
2345
  if (pivot) {
2243
2346
  setPivot({ ...pivot, sort: true, sortDirection: direction });
2347
+ const pivotedData = (0, PivotModal_1.generatePivotTable)({ ...pivot, sort: true, sortDirection: direction }, rows, [null, null, null], false);
2348
+ setPivotData(pivotedData || []);
2244
2349
  setActivePath(null);
2245
2350
  setOpenPopover(null);
2246
2351
  setBaseAst((0, util_1.deepCopy)(baseAst));
@@ -2257,7 +2362,58 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2257
2362
  setActivePath(null);
2258
2363
  setOpenPopover(null);
2259
2364
  setBaseAst((0, util_1.deepCopy)(newAst));
2260
- } }) })] }), (0, jsx_runtime_1.jsxs)(Container, { children: [!hideAi && ((0, jsx_runtime_1.jsxs)("form", { onSubmit: (event) => {
2365
+ fetchSqlQuery((0, util_1.deepCopy)(newAst));
2366
+ } }) }), (0, jsx_runtime_1.jsx)("div", { style: { height: 28, width: '100%' } }), (0, jsx_runtime_1.jsx)(SidebarHeading, { label: "Limit" }), (0, jsx_runtime_1.jsx)("div", { style: { height: 4, width: '100%' } }), baseAst && baseAst.limit ? ((0, jsx_runtime_1.jsx)("div", { style: {
2367
+ display: 'flex',
2368
+ flexDirection: 'column',
2369
+ gap: 8,
2370
+ marginBottom: 12,
2371
+ }, children: (0, jsx_runtime_1.jsx)(AddLimitPopover_1.LimitSentence, { limit: baseAst.limit, setOpenPopover: setOpenPopover, LimitPopover: SortPopover, EditPopover: AddLimitPopover_1.AddLimitPopover, handleDelete: () => {
2372
+ const newAst = { ...baseAst };
2373
+ newAst.limit = null;
2374
+ setBaseAst((0, util_1.deepCopy)(newAst));
2375
+ fetchSqlQuery((0, util_1.deepCopy)(newAst));
2376
+ }, onSave: (limit) => {
2377
+ const newAst = { ...baseAst };
2378
+ newAst.limit = {
2379
+ seperator: '',
2380
+ value: [
2381
+ {
2382
+ type: 'number',
2383
+ value: limit,
2384
+ },
2385
+ ],
2386
+ };
2387
+ setOpenPopover(null);
2388
+ setBaseAst((0, util_1.deepCopy)(newAst));
2389
+ fetchSqlQuery((0, util_1.deepCopy)(newAst));
2390
+ } }) })) : ((0, jsx_runtime_1.jsx)(Popover, { isOpen: openPopover === 'AddLimitPopover', setIsOpen: () => { }, trigger: (0, jsx_runtime_1.jsx)(SecondaryButton, { onClick: () => {
2391
+ if (!baseAst) {
2392
+ return;
2393
+ }
2394
+ if (!openPopover) {
2395
+ setOpenPopover('AddLimitPopover');
2396
+ }
2397
+ }, label: 'Add limit' }), title: "Limit", onClose: () => {
2398
+ setIsPending(false);
2399
+ setActiveEditItem(null);
2400
+ setActivePath(null);
2401
+ setOpenPopover(null);
2402
+ }, children: (0, jsx_runtime_1.jsx)(AddLimitPopover_1.AddLimitPopover, { TextInput: TextInput, onSave: (limit) => {
2403
+ const newAst = { ...baseAst };
2404
+ newAst.limit = {
2405
+ seperator: '',
2406
+ value: [
2407
+ {
2408
+ type: 'number',
2409
+ value: Number(limit),
2410
+ },
2411
+ ],
2412
+ };
2413
+ setOpenPopover(null);
2414
+ setBaseAst((0, util_1.deepCopy)(newAst));
2415
+ fetchSqlQuery((0, util_1.deepCopy)(newAst));
2416
+ } }) }))] }), (0, jsx_runtime_1.jsxs)(Container, { children: [!hideAi && ((0, jsx_runtime_1.jsxs)("form", { onSubmit: (event) => {
2261
2417
  event.preventDefault();
2262
2418
  handleAsk();
2263
2419
  }, style: {
@@ -2268,9 +2424,10 @@ function ReportBuilder({ initialTableName = '', onAddToDashboardComplete = () =>
2268
2424
  }, children: [(0, jsx_runtime_1.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...' }), (0, jsx_runtime_1.jsx)(Button, { onClick: handleAsk, label: 'Ask AI' }), baseAst && ((0, jsx_runtime_1.jsx)(SecondaryButton, { label: 'New report', onClick: clearAllState }))] })), baseAst && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: loading && errorMessage.length === 0 ? ((0, jsx_runtime_1.jsx)(TableLoadingState, {})) : ((0, jsx_runtime_1.jsx)(Table, { rows: applyFormatting({
2269
2425
  rows: pivotData?.rows || rows,
2270
2426
  fields: pivotData?.fields || fields,
2271
- }, baseAst?.columns ?? []), columns: pivotData?.columns ||
2272
- enforceOrderOnColumns(Object.keys(rows[0] ?? {})).map((c) => {
2273
- return { label: c, field: c };
2427
+ }, baseAst?.columns ?? []), columns: pivot
2428
+ ? pivotData?.columns || emptyPivotColumns()
2429
+ : enforceOrderOnColumns(Object.keys(rows[0] ?? {})).map((c) => {
2430
+ return { label: (0, textProcessing_1.snakeCaseToTitleCase)(c), field: c };
2274
2431
  }), error: errorMessage, rowsPerPage: 20 })) })), (0, jsx_runtime_1.jsxs)("div", { style: {
2275
2432
  display: 'flex',
2276
2433
  flexDirection: 'row',