@quillsql/react 2.13.38 → 2.13.40

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 (91) hide show
  1. package/dist/cjs/Chart.d.ts.map +1 -1
  2. package/dist/cjs/Chart.js +0 -1
  3. package/dist/cjs/ChartBuilder.d.ts.map +1 -1
  4. package/dist/cjs/ChartBuilder.js +73 -66
  5. package/dist/cjs/ReportBuilder.d.ts.map +1 -1
  6. package/dist/cjs/ReportBuilder.js +69 -51
  7. package/dist/cjs/components/Chart/ChartTooltip.d.ts +1 -1
  8. package/dist/cjs/components/Chart/ChartTooltip.d.ts.map +1 -1
  9. package/dist/cjs/components/Chart/ChartTooltip.js +3 -3
  10. package/dist/cjs/components/Chart/LineChart.d.ts.map +1 -1
  11. package/dist/cjs/components/Chart/LineChart.js +4 -4
  12. package/dist/cjs/components/QuillMultiSelectSectionList.js +5 -5
  13. package/dist/cjs/components/ReportBuilder/convert.d.ts +1 -1
  14. package/dist/cjs/components/ReportBuilder/convert.d.ts.map +1 -1
  15. package/dist/cjs/components/ReportBuilder/convert.js +73 -21
  16. package/dist/cjs/components/UiComponents.d.ts +2 -1
  17. package/dist/cjs/components/UiComponents.d.ts.map +1 -1
  18. package/dist/cjs/components/UiComponents.js +11 -4
  19. package/dist/cjs/hooks/useExport.d.ts.map +1 -1
  20. package/dist/cjs/hooks/useExport.js +4 -5
  21. package/dist/cjs/internals/ReportBuilder/PivotForm.d.ts +19 -11
  22. package/dist/cjs/internals/ReportBuilder/PivotForm.d.ts.map +1 -1
  23. package/dist/cjs/internals/ReportBuilder/PivotForm.js +62 -48
  24. package/dist/cjs/internals/ReportBuilder/PivotList.js +5 -4
  25. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts +28 -31
  26. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  27. package/dist/cjs/internals/ReportBuilder/PivotModal.js +315 -633
  28. package/dist/cjs/models/Pivot.d.ts +27 -7
  29. package/dist/cjs/models/Pivot.d.ts.map +1 -1
  30. package/dist/cjs/utils/dashboard.d.ts.map +1 -1
  31. package/dist/cjs/utils/dashboard.js +36 -11
  32. package/dist/cjs/utils/merge.d.ts.map +1 -1
  33. package/dist/cjs/utils/merge.js +2 -1
  34. package/dist/cjs/utils/pivotConstructor.d.ts +1 -0
  35. package/dist/cjs/utils/pivotConstructor.d.ts.map +1 -1
  36. package/dist/cjs/utils/pivotConstructor.js +39 -8
  37. package/dist/cjs/utils/pivotProcessing.d.ts.map +1 -1
  38. package/dist/cjs/utils/pivotProcessing.js +10 -14
  39. package/dist/cjs/utils/queryConstructor.d.ts.map +1 -1
  40. package/dist/cjs/utils/queryConstructor.js +421 -134
  41. package/dist/cjs/utils/report.d.ts.map +1 -1
  42. package/dist/cjs/utils/report.js +2 -2
  43. package/dist/cjs/utils/textProcessing.d.ts +1 -1
  44. package/dist/cjs/utils/textProcessing.d.ts.map +1 -1
  45. package/dist/cjs/utils/textProcessing.js +3 -0
  46. package/dist/esm/Chart.d.ts.map +1 -1
  47. package/dist/esm/Chart.js +0 -1
  48. package/dist/esm/ChartBuilder.d.ts.map +1 -1
  49. package/dist/esm/ChartBuilder.js +73 -66
  50. package/dist/esm/ReportBuilder.d.ts.map +1 -1
  51. package/dist/esm/ReportBuilder.js +69 -51
  52. package/dist/esm/components/Chart/ChartTooltip.d.ts +1 -1
  53. package/dist/esm/components/Chart/ChartTooltip.d.ts.map +1 -1
  54. package/dist/esm/components/Chart/ChartTooltip.js +3 -3
  55. package/dist/esm/components/Chart/LineChart.d.ts.map +1 -1
  56. package/dist/esm/components/Chart/LineChart.js +4 -4
  57. package/dist/esm/components/QuillMultiSelectSectionList.js +5 -5
  58. package/dist/esm/components/ReportBuilder/convert.d.ts +1 -1
  59. package/dist/esm/components/ReportBuilder/convert.d.ts.map +1 -1
  60. package/dist/esm/components/ReportBuilder/convert.js +74 -22
  61. package/dist/esm/components/UiComponents.d.ts +2 -1
  62. package/dist/esm/components/UiComponents.d.ts.map +1 -1
  63. package/dist/esm/components/UiComponents.js +11 -4
  64. package/dist/esm/hooks/useExport.d.ts.map +1 -1
  65. package/dist/esm/hooks/useExport.js +4 -5
  66. package/dist/esm/internals/ReportBuilder/PivotForm.d.ts +19 -11
  67. package/dist/esm/internals/ReportBuilder/PivotForm.d.ts.map +1 -1
  68. package/dist/esm/internals/ReportBuilder/PivotForm.js +63 -49
  69. package/dist/esm/internals/ReportBuilder/PivotList.js +5 -4
  70. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts +28 -31
  71. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  72. package/dist/esm/internals/ReportBuilder/PivotModal.js +327 -635
  73. package/dist/esm/models/Pivot.d.ts +27 -7
  74. package/dist/esm/models/Pivot.d.ts.map +1 -1
  75. package/dist/esm/utils/dashboard.d.ts.map +1 -1
  76. package/dist/esm/utils/dashboard.js +36 -11
  77. package/dist/esm/utils/merge.d.ts.map +1 -1
  78. package/dist/esm/utils/merge.js +2 -1
  79. package/dist/esm/utils/pivotConstructor.d.ts +1 -0
  80. package/dist/esm/utils/pivotConstructor.d.ts.map +1 -1
  81. package/dist/esm/utils/pivotConstructor.js +39 -9
  82. package/dist/esm/utils/pivotProcessing.d.ts.map +1 -1
  83. package/dist/esm/utils/pivotProcessing.js +10 -14
  84. package/dist/esm/utils/queryConstructor.d.ts.map +1 -1
  85. package/dist/esm/utils/queryConstructor.js +421 -134
  86. package/dist/esm/utils/report.d.ts.map +1 -1
  87. package/dist/esm/utils/report.js +2 -2
  88. package/dist/esm/utils/textProcessing.d.ts +1 -1
  89. package/dist/esm/utils/textProcessing.d.ts.map +1 -1
  90. package/dist/esm/utils/textProcessing.js +3 -0
  91. package/package.json +1 -1
@@ -11,14 +11,12 @@ exports.getDateBuckets = getDateBuckets;
11
11
  exports.getDateString = getDateString;
12
12
  exports.isDateField = isDateField;
13
13
  exports.generatePivotTable = generatePivotTable;
14
- exports.generatePivotTableInMemory = generatePivotTableInMemory;
15
14
  const jsx_runtime_1 = require("react/jsx-runtime");
16
15
  const react_1 = require("react");
17
16
  const Context_1 = require("../../Context");
18
17
  const PivotList_1 = require("./PivotList");
19
18
  const date_fns_1 = require("date-fns");
20
19
  const valueFormatter_1 = require("../../utils/valueFormatter");
21
- const ChartBuilder_1 = require("../../ChartBuilder");
22
20
  const textProcessing_1 = require("../../utils/textProcessing");
23
21
  const UiComponents_1 = require("../../components/UiComponents");
24
22
  const QuillCard_1 = require("../../components/QuillCard");
@@ -27,14 +25,13 @@ const crypto_1 = require("../../utils/crypto");
27
25
  const tableProcessing_1 = require("../../utils/tableProcessing");
28
26
  const pivotConstructor_1 = require("../../utils/pivotConstructor");
29
27
  const dates_1 = require("../../utils/dates");
30
- // import Big from 'big.js';
31
28
  const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
32
- const filterProcessing_1 = require("../../utils/filterProcessing");
33
29
  const columnProcessing_1 = require("../../utils/columnProcessing");
34
30
  const dataFetcher_1 = require("../../utils/dataFetcher");
35
- const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivotColumnField, pivotValueField, setPivotValueField, pivotValueField2, setPivotValueField2, pivotAggregation, setPivotAggregation, popUpTitle, setPopUpTitle, selectedTable, SelectComponent, ButtonComponent, SecondaryButtonComponent, PopoverComponent, ErrorMessageComponent = UiComponents_1.QuillErrorMessageComponent, PivotRowContainer = UiComponents_1.QuillPivotRowContainer, PivotColumnContainer = UiComponents_1.QuillPivotColumnContainer, LoadingComponent = UiComponents_1.QuillLoadingComponent, CardComponent = QuillCard_1.QuillCard, HeaderComponent, LabelComponent, TextComponent, selectedPivotIndex, setSelectedPivotIndex, removePivot, selectPivot, showUpdatePivot, setShowUpdatePivot, data, columns, theme, isOpen, setIsOpen, dateRange, createdPivots, setCreatedPivots, recommendedPivots, setRecommendedPivots, triggerButtonText = 'Pivot', showPivotEditButton = false, showEditOnPivotClick = true, showTrigger = true, pivotCountRequest = 6, query, initialUniqueValues, uniqueValuesIsLoading, initialSelectedPivotTable, disabled = false, pivotRecommendationsEnabled = true, report, dashboardName, dateFilter, }) => {
31
+ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivotColumnField, pivotAggregations, setPivotAggregations, popUpTitle, setPopUpTitle, selectedTable, SelectComponent, ButtonComponent, SecondaryButtonComponent, PopoverComponent, ErrorMessageComponent = UiComponents_1.QuillErrorMessageComponent, PivotRowContainer = UiComponents_1.QuillPivotRowContainer, PivotColumnContainer = UiComponents_1.QuillPivotColumnContainer, LoadingComponent = UiComponents_1.QuillLoadingComponent, CardComponent = QuillCard_1.QuillCard, HeaderComponent, SubheaderComponent = UiComponents_1.MemoizedSubHeader, DeleteButtonComponent = UiComponents_1.MemoizedDeleteButton, LabelComponent, TextComponent, selectedPivotIndex, setSelectedPivotIndex, removePivot, selectPivot, showUpdatePivot, setShowUpdatePivot, data, columns, theme, isOpen, setIsOpen, dateRange, createdPivots, setCreatedPivots, recommendedPivots, setRecommendedPivots, triggerButtonText = 'Pivot', showPivotEditButton = false, showEditOnPivotClick = true, showTrigger = true, pivotCountRequest = 6, query, initialUniqueValues, uniqueValuesIsLoading, initialSelectedPivotTable, disabled = false, pivotRecommendationsEnabled = true, report, dashboardName, dateFilter, }) => {
36
32
  const [isLoading, setIsLoading] = (0, react_1.useState)(false);
37
33
  const [previewLoading, setPreviewLoading] = (0, react_1.useState)(false);
34
+ // const [showPercentageAggPopover, setShowPercentageAggPopover] = useState<number | undefined>(undefined);
38
35
  const [selectedPivotType, setSelectedPivotType] = (0, react_1.useState)('recommended');
39
36
  const [errors, setErrors] = (0, react_1.useState)([]);
40
37
  const [client] = (0, react_1.useContext)(Context_1.ClientContext);
@@ -52,6 +49,7 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
52
49
  const [allowedValueFields, setAllowedValueFields] = (0, react_1.useState)([]);
53
50
  const [uniqueValues, setUniqueValues] = (0, react_1.useState)(initialUniqueValues);
54
51
  const buttonRef = (0, react_1.useRef)(null);
52
+ // const percentageAggButtonRef = useRef<HTMLDivElement>(null);
55
53
  const [dateRanges, setDateRanges] = (0, react_1.useState)({});
56
54
  const [pivotError, setPivotError] = (0, react_1.useState)('');
57
55
  const getDistinctValues = async (fetchDistinct) => {
@@ -136,15 +134,25 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
136
134
  }, [showUpdatePivot, isOpen]);
137
135
  (0, react_1.useEffect)(() => {
138
136
  const fetchPivotData = async () => {
139
- if (pivotRowField && data && columns) {
137
+ if (pivotRowField && data && columns && pivotAggregations?.every((p) => p?.valueField && p?.aggregationType)) {
140
138
  const pivot = {
141
139
  rowField: pivotRowField || '',
142
- rowFieldType: columnsToShow[pivotRowField || ''],
140
+ rowFieldType: columnTypes[pivotRowField ?? ''],
143
141
  columnField: pivotColumnField,
144
- columnFieldType: columnsToShow[pivotColumnField || ''],
145
- valueField: pivotValueField || '',
146
- aggregationType: pivotAggregation || '',
147
- valueField2: pivotValueField2 || '',
142
+ columnFieldType: columnTypes[pivotColumnField ?? ''],
143
+ aggregations: pivotAggregations?.map((p) => ({
144
+ valueField: p.valueField,
145
+ valueFieldType: columnTypes[p.valueField ?? ''],
146
+ valueField2: p.valueField2,
147
+ valueField2Type: columnTypes[p.valueField2 ?? ''],
148
+ aggregationType: p.aggregationType,
149
+ })),
150
+ // For backwards compatibility
151
+ valueField: pivotAggregations?.[0]?.valueField,
152
+ valueFieldType: columnTypes[pivotAggregations?.[0]?.valueField ?? ''],
153
+ valueField2: pivotAggregations?.[0]?.valueField2,
154
+ valueField2Type: columnTypes[pivotAggregations?.[0]?.valueField2 ?? ''],
155
+ aggregationType: pivotAggregations?.[0]?.aggregationType,
148
156
  };
149
157
  try {
150
158
  const { rows, columns } = await generatePivotTable({
@@ -180,13 +188,23 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
180
188
  }
181
189
  if (pivotRowField && data && columns) {
182
190
  const pivot = {
183
- rowField: pivotRowField || '',
184
- rowFieldType: columnsToShow[pivotRowField || ''],
191
+ rowField: pivotRowField ?? '',
192
+ rowFieldType: columnTypes[pivotRowField ?? ''],
185
193
  columnField: pivotColumnField,
186
- columnFieldType: columnsToShow[pivotColumnField || ''],
187
- valueField: pivotValueField || '',
188
- aggregationType: pivotAggregation || '',
189
- valueField2: pivotValueField2 || '',
194
+ columnFieldType: columnTypes[pivotColumnField ?? ''],
195
+ aggregations: pivotAggregations?.map((p) => ({
196
+ valueField: p.valueField,
197
+ valueFieldType: columnTypes[p.valueField ?? ''],
198
+ valueField2: p.valueField2,
199
+ valueField2Type: columnTypes[p.valueField2 ?? ''],
200
+ aggregationType: p.aggregationType,
201
+ })),
202
+ // For backwards compatibility
203
+ valueField: pivotAggregations?.[0]?.valueField,
204
+ valueFieldType: columnTypes[pivotAggregations?.[0]?.valueField ?? ''],
205
+ valueField2: pivotAggregations?.[0]?.valueField2,
206
+ valueField2Type: columnTypes[pivotAggregations?.[0]?.valueField2 ?? ''],
207
+ aggregationType: pivotAggregations?.[0]?.aggregationType,
190
208
  };
191
209
  if (initialSelectedPivotTable) {
192
210
  setSamplePivotTable({
@@ -253,6 +271,12 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
253
271
  return map;
254
272
  }, {});
255
273
  }, [columns]);
274
+ const columnTypes = (0, react_1.useMemo)(() => {
275
+ return (columns || []).reduce((map, col) => {
276
+ map[col.field] = col.jsType;
277
+ return map;
278
+ }, {});
279
+ }, [columns]);
256
280
  const [selectedPivotTable, setSelectedPivotTable] = (0, react_1.useState)(null);
257
281
  (0, react_1.useEffect)(() => {
258
282
  const fetchPivotTables = async () => {
@@ -313,22 +337,78 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
313
337
  selectPivot(pivot);
314
338
  setSelectedPivotType('recommended');
315
339
  }
340
+ setPivotError('');
316
341
  setIsOpen(false);
317
342
  };
318
343
  const onSelectCreatedPivot = (pivot) => {
319
344
  selectPivot(pivot, pivot.columnField ? uniqueValues : undefined);
320
345
  setSelectedPivotType('created');
346
+ setPivotError('');
321
347
  setIsOpen(false);
322
348
  setPopUpTitle('Add pivot');
323
349
  };
350
+ const onCommitPivot = (0, react_1.useCallback)(() => {
351
+ const errors = [];
352
+ if ((pivotAggregations?.length ?? 0) === 0) {
353
+ errors.push('You must have at least one aggregation');
354
+ }
355
+ if (pivotAggregations.some((p) => !p.valueField && p.aggregationType !== 'count')) {
356
+ errors.push("Value field cannot be empty when aggregation is not 'count'");
357
+ }
358
+ if (pivotAggregations.some((p) => !p.aggregationType)) {
359
+ errors.push('Aggregation cannot be empty');
360
+ }
361
+ if (pivotRowField && !columnsToShow[pivotRowField]) {
362
+ errors.push('Error in row field: undefined type');
363
+ }
364
+ if (pivotColumnField &&
365
+ !columnsToShow[pivotColumnField]) {
366
+ errors.push('Error in column field: undefined type');
367
+ }
368
+ if (errors.length === 0 && pivotAggregations?.every((p) => p.valueField && p.aggregationType)) {
369
+ const pivot = {
370
+ rowField: pivotRowField,
371
+ rowFieldType: columnTypes[pivotRowField ?? ''],
372
+ columnField: pivotColumnField,
373
+ columnFieldType: columnsToShow[pivotColumnField ?? ''],
374
+ aggregations: pivotAggregations?.map((p) => ({
375
+ valueField: p.valueField,
376
+ valueFieldType: columnTypes[p.valueField ?? ''],
377
+ valueField2: p.valueField2,
378
+ valueField2Type: columnTypes[p.valueField2 ?? ''],
379
+ aggregationType: p.aggregationType,
380
+ })),
381
+ // For backwards compatibility
382
+ valueField: pivotAggregations?.[0]?.valueField,
383
+ valueFieldType: columnTypes[pivotAggregations?.[0]?.valueField ?? ''],
384
+ valueField2: pivotAggregations?.[0]?.valueField2,
385
+ valueField2Type: columnTypes[pivotAggregations?.[0]?.valueField2 ?? ''],
386
+ aggregationType: pivotAggregations?.[0]?.aggregationType,
387
+ };
388
+ if ((0, pivotProcessing_1.isValidPivot)(pivot).valid) {
389
+ pivot.title = generatePivotTitle(pivot);
390
+ setPivotError('');
391
+ setIsOpen(false);
392
+ setCreatedPivots([pivot]);
393
+ onSelectCreatedPivot(pivot);
394
+ setPopUpTitle('Add pivot');
395
+ }
396
+ else {
397
+ errors.push((0, pivotProcessing_1.isValidPivot)(pivot).reason);
398
+ }
399
+ }
400
+ setErrors(errors);
401
+ }, [
402
+ pivotRowField,
403
+ pivotColumnField,
404
+ pivotAggregations,
405
+ ]);
324
406
  const onEditPivot = async (pivot, index, pivotType) => {
325
407
  setIsLoading(false);
326
408
  setErrors([]);
327
409
  setPivotRowField(pivot.rowField);
328
410
  setPivotColumnField(pivot.columnField);
329
- setPivotValueField(pivot.valueField);
330
- setPivotValueField2(pivot.valueField2);
331
- setPivotAggregation(pivot.aggregationType);
411
+ setPivotAggregations(pivot.aggregations ?? []);
332
412
  setShowUpdatePivot(true);
333
413
  if (pivotType === 'recommended' &&
334
414
  index !== null &&
@@ -432,10 +512,8 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
432
512
  }
433
513
  return {
434
514
  ...pivot,
435
- rowFieldType: columnsToShow[pivot.rowField || ''],
436
- columnFieldType: pivot.columnField
437
- ? columnsToShow[pivot.columnField]
438
- : undefined,
515
+ rowFieldType: columnTypes[pivot.rowField ?? ''],
516
+ columnFieldType: columnTypes[pivot.columnField ?? ''],
439
517
  title: generatePivotTitle(pivot),
440
518
  };
441
519
  });
@@ -473,7 +551,17 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
473
551
  }
474
552
  }));
475
553
  const validPivotTables = pts.filter((pt) => pt !== undefined);
476
- setRecommendedPivotTables(validPivotTables);
554
+ setRecommendedPivotTables(validPivotTables.map((pt) => ({
555
+ ...pt,
556
+ pivot: {
557
+ ...pt.pivot,
558
+ aggregations: [{
559
+ valueField: pt.pivot.valueField,
560
+ aggregationType: pt.pivot.aggregationType,
561
+ valueField2: pt.pivot.valueField2,
562
+ }]
563
+ }
564
+ })));
477
565
  if (validPivotTables.length === 0) {
478
566
  sethasNoRecommendedPivots(true);
479
567
  }
@@ -498,29 +586,73 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
498
586
  columns,
499
587
  ]);
500
588
  const pivotFieldChange = async (field, value) => {
589
+ console.log();
590
+ if (typeof value !== 'string' && (!value?.length || !value?.every((p) => p?.aggregationType))) {
591
+ return;
592
+ }
593
+ if (typeof value !== 'string' && value.some((p) => !p?.valueField && (p?.aggregationType !== 'count' || !pivotRowField))) {
594
+ return;
595
+ }
501
596
  setErrors([]);
502
597
  const pivot = {
503
598
  rowField: pivotRowField,
504
- rowFieldType: columnsToShow[pivotRowField],
599
+ rowFieldType: columnTypes[pivotRowField ?? ''],
505
600
  columnField: pivotColumnField,
506
- valueField: pivotValueField,
507
- valueField2: pivotValueField2,
508
- aggregationType: pivotAggregation,
601
+ aggregations: pivotAggregations?.map((p) => {
602
+ return {
603
+ valueField: p.valueField,
604
+ valueFieldType: columnTypes[p.valueField ?? ''],
605
+ valueField2: p.valueField2,
606
+ valueField2Type: columnTypes[p.valueField2 ?? ''],
607
+ aggregationType: p.aggregationType
608
+ };
609
+ }),
610
+ // For backwards compatibility
611
+ valueField: pivotAggregations?.[0]?.valueField,
612
+ valueFieldType: columnTypes[pivotAggregations?.[0]?.valueField ?? ''],
613
+ valueField2: pivotAggregations?.[0]?.valueField2,
614
+ valueField2Type: columnTypes[pivotAggregations?.[0]?.valueField2 ?? ''],
615
+ aggregationType: pivotAggregations?.[0]?.aggregationType,
509
616
  };
510
- // @ts-ignore
511
- pivot[field] = value;
617
+ if (field === 'aggregations') {
618
+ pivot.aggregations = value.map((p) => ({
619
+ valueField: p.valueField,
620
+ valueFieldType: columnTypes[p.valueField ?? ''],
621
+ valueField2: p.valueField2,
622
+ valueField2Type: columnTypes[p.valueField2 ?? ''],
623
+ aggregationType: p.aggregationType
624
+ }));
625
+ }
626
+ else {
627
+ pivot[field] = value;
628
+ }
512
629
  pivot.title = generatePivotTitle(pivot);
513
630
  if (field === 'rowField') {
514
- pivot.rowFieldType = columnsToShow[value];
631
+ if (value === '') {
632
+ setPivotColumnField(undefined);
633
+ // Also clear any percent aggregations
634
+ setPivotAggregations(pivotAggregations.map((agg) => {
635
+ return {
636
+ ...agg,
637
+ aggregationType: agg.aggregationType === 'percentage' ? undefined : agg.aggregationType,
638
+ };
639
+ }));
640
+ }
641
+ pivot.rowFieldType = columnTypes[value];
515
642
  }
516
643
  else if (field === 'columnField') {
517
- pivot.columnFieldType = columnsToShow[value];
518
- if (!value && pivotValueField2 === pivotValueField) {
519
- // only allow same field percentage with columnField
520
- setPivotValueField2(undefined);
521
- pivot.valueField2 = undefined;
522
- }
644
+ pivot.columnFieldType = columnTypes[value];
523
645
  }
646
+ pivot.aggregations?.forEach((agg, index) => {
647
+ if (!value && agg.valueField === agg.valueField2) {
648
+ agg.valueField2 = undefined;
649
+ setPivotAggregations([
650
+ ...pivotAggregations.slice(0, index),
651
+ { ...pivotAggregations[index], valueField2: undefined },
652
+ ...pivotAggregations.slice(index + 1),
653
+ ]);
654
+ }
655
+ });
524
656
  if (!(0, pivotProcessing_1.isValidPivot)(pivot).valid) {
525
657
  setSamplePivotTable(null);
526
658
  return;
@@ -549,6 +681,7 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
549
681
  }
550
682
  catch (e) {
551
683
  if (e instanceof Error) {
684
+ console.log('error', e);
552
685
  setPivotError(e.message);
553
686
  setSamplePivotTable(null);
554
687
  return;
@@ -605,6 +738,7 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
605
738
  right: -2,
606
739
  } })) }), showTrigger && ((0, jsx_runtime_1.jsx)("div", { ref: buttonRef, children: (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { disabled: disabled, onClick: () => {
607
740
  if (columns.length === 0) {
741
+ setPivotError('');
608
742
  setIsOpen(false);
609
743
  }
610
744
  // table is not loaded yet, so pivot button is not clickable
@@ -643,135 +777,102 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
643
777
  width: pivotCardWidth,
644
778
  minHeight: 160,
645
779
  }, children: (0, jsx_runtime_1.jsx)(PivotList_1.PivotCard, { pivotTable: samplePivotTable, theme: theme, index: 0, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: ButtonComponent, showEdit: false, clickable: false, minHeight: 180, LabelComponent: LabelComponent, TextComponent: TextComponent, HeaderComponent: HeaderComponent, CardComponent: CardComponent, onSelectPivot: () => { }, onClose: () => {
646
- setPivotAggregation(null);
647
- setPivotRowField(null);
648
- setPivotValueField(null);
649
- setPivotValueField2(null);
650
- setPivotColumnField(null);
651
- setSamplePivotTable(null);
652
- } }) })), (0, jsx_runtime_1.jsxs)(PivotColumnContainer, { children: [(0, jsx_runtime_1.jsxs)(PivotRowContainer, { children: [(0, jsx_runtime_1.jsx)("div", { ref: rowFieldRef, children: (0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-row-field", label: "Row field", value: pivotRowField, onChange: (e) => {
653
- pivotFieldChange('rowField', e.target.value);
654
- setPivotRowField(e.target.value === ''
655
- ? undefined
656
- : e.target.value);
657
- }, options: allowedRowFields
658
- .filter((field) => field !== pivotColumnField)
659
- .map((field) => {
660
- return {
661
- label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(field),
662
- value: field,
663
- };
664
- }), isLoading: uniqueValuesIsLoading, width: 200 }) }), (0, jsx_runtime_1.jsx)("div", { ref: colFieldRef, children: (0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-row-field", label: "Column field", value: pivotColumnField, onChange: (e) => {
665
- pivotFieldChange('columnField', e.target.value);
666
- setPivotColumnField(e.target.value === ''
667
- ? undefined
668
- : e.target.value);
669
- }, options: allowedColumnFields
670
- .filter((field) => field !== pivotRowField)
671
- .map((field) => {
672
- return {
673
- label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(field),
674
- value: field,
675
- };
676
- }), isLoading: uniqueValuesIsLoading, width: 200 }) })] }), (0, jsx_runtime_1.jsxs)(PivotRowContainer, { children: [(0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-row-field", label: "Aggregation type", value: pivotAggregation, onChange: (e) => {
677
- if (e.target.value !== 'count' &&
678
- pivotValueField &&
679
- !ChartBuilder_1.numberFormatOptions.includes(columns.find((col) => col.field === pivotValueField).format)) {
680
- setPivotValueField(null);
681
- }
682
- pivotFieldChange('aggregationType', e.target.value);
683
- setPivotAggregation(e.target.value === ''
684
- ? undefined
685
- : e.target.value);
686
- }, options: [
687
- ...[
688
- 'sum',
689
- 'average',
690
- 'count',
691
- 'max',
692
- 'min',
693
- 'percentage',
694
- ].map((option) => {
695
- return { label: option, value: option };
696
- }),
697
- ], width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-row-field", label: "Value field", value: pivotValueField, onChange: (e) => {
698
- pivotFieldChange('valueField', e.target.value);
699
- setPivotValueField(e.target.value === ''
700
- ? undefined
701
- : e.target.value);
702
- }, options: allowedValueFields
703
- .map((field) => {
704
- return {
705
- label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(field),
706
- value: field,
707
- };
708
- })
709
- .filter((option) => {
710
- return (pivotAggregation !== 'percentage' ||
711
- pivotColumnField ||
712
- option.value !== pivotValueField2);
713
- }), isLoading: uniqueValuesIsLoading, width: 200 }), pivotAggregation === 'percentage' ? ((0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-row-field", label: "Total field", value: pivotValueField2, onChange: (e) => {
714
- pivotFieldChange('valueField2', e.target.value);
715
- setPivotValueField2(e.target.value === ''
716
- ? undefined
717
- : e.target.value);
718
- }, options: allowedValueFields
719
- .map((field) => {
720
- return {
721
- label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(field),
722
- value: field,
723
- };
724
- })
725
- .filter((option) => {
726
- return (pivotAggregation !== 'percentage' ||
727
- pivotColumnField ||
728
- option.value !== pivotValueField);
729
- }), isLoading: uniqueValuesIsLoading, width: 200 })) : null] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(ButtonComponent, { id: "custom-button", onClick: () => {
730
- const errors = [];
731
- if (!pivotValueField &&
732
- pivotAggregation !== 'count') {
733
- errors.push("Value field cannot be empty when aggregation is not 'count'");
734
- }
735
- if (!pivotAggregation) {
736
- errors.push('Aggregation cannot be empty');
737
- }
738
- if (pivotRowField && !columnsToShow[pivotRowField]) {
739
- errors.push('Error in row field: undefined type');
740
- }
741
- if (pivotColumnField &&
742
- !columnsToShow[pivotColumnField]) {
743
- errors.push('Error in column field: undefined type');
744
- }
745
- if (errors.length === 0) {
746
- const pivot = {
747
- rowField: pivotRowField || '',
748
- rowFieldType: columnsToShow[pivotRowField || ''],
749
- columnField: pivotColumnField,
750
- columnFieldType: columnsToShow[pivotColumnField || ''],
751
- valueField: pivotValueField || '',
752
- valueField2: pivotValueField2 || '',
753
- aggregationType: pivotAggregation || '',
754
- };
755
- if ((0, pivotProcessing_1.isValidPivot)(pivot).valid) {
756
- pivot.title = generatePivotTitle(pivot);
757
- setIsOpen(false);
758
- setCreatedPivots([pivot]);
759
- onSelectCreatedPivot(pivot);
760
- setPopUpTitle('Add pivot');
761
- }
762
- else {
763
- errors.push((0, pivotProcessing_1.isValidPivot)(pivot).reason);
764
- }
765
- }
766
- setErrors(errors);
767
- }, label: popUpTitle }), errors.length > 0 && ((0, jsx_runtime_1.jsx)("div", { style: {
768
- display: 'flex',
769
- flexDirection: 'column',
770
- gap: 8,
771
- paddingTop: 8,
772
- width: pivotCardWidth,
773
- maxWidth: pivotCardWidth,
774
- }, children: errors.map((error, index) => ((0, jsx_runtime_1.jsx)(ErrorMessageComponent, { errorMessage: error }, `error_message_${index}`))) }))] })] })) : ((0, jsx_runtime_1.jsx)("div", { style: {
780
+ setPivotAggregations([{ valueField: undefined, valueField2: undefined, aggregationType: undefined }]);
781
+ setPivotRowField(undefined);
782
+ setPivotColumnField(undefined);
783
+ setSamplePivotTable(undefined);
784
+ } }) })), (0, jsx_runtime_1.jsxs)(PivotColumnContainer, { children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children: [(0, jsx_runtime_1.jsx)(HeaderComponent, { label: "Groupings" }), (0, jsx_runtime_1.jsxs)(PivotRowContainer, { children: [(0, jsx_runtime_1.jsx)("div", { ref: rowFieldRef, children: (0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-row-field", label: "Group rows by", value: pivotRowField, onChange: (e) => {
785
+ pivotFieldChange('rowField', e.target.value);
786
+ setPivotRowField(e.target.value === ''
787
+ ? undefined
788
+ : e.target.value);
789
+ }, options: allowedRowFields
790
+ .filter((field) => field !== pivotColumnField)
791
+ .map((field) => {
792
+ return {
793
+ label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(field),
794
+ value: field,
795
+ };
796
+ }), isLoading: uniqueValuesIsLoading, width: 200 }) }), (0, jsx_runtime_1.jsx)("div", { ref: colFieldRef, children: (0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-column-field", label: "Group columns by", value: pivotColumnField, onChange: (e) => {
797
+ pivotFieldChange('columnField', e.target.value);
798
+ setPivotColumnField(e.target.value === ''
799
+ ? undefined
800
+ : e.target.value);
801
+ }, options: allowedColumnFields
802
+ .filter((field) => field !== pivotRowField)
803
+ .map((field) => {
804
+ return {
805
+ label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(field),
806
+ value: field,
807
+ };
808
+ }), isLoading: uniqueValuesIsLoading, width: 200, disabled: pivotRowField === undefined }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children: [(0, jsx_runtime_1.jsx)(HeaderComponent, { label: "Aggregations" }), (0, jsx_runtime_1.jsxs)(PivotRowContainer, { children: [(0, jsx_runtime_1.jsx)("div", { style: { width: 200 }, children: (0, jsx_runtime_1.jsx)(SubheaderComponent, { label: "Aggregation Type" }) }), (0, jsx_runtime_1.jsx)("div", { style: { width: 200 }, children: (0, jsx_runtime_1.jsx)(SubheaderComponent, { label: "Value Field" }) })] }), pivotAggregations?.map((agg, index) => (0, jsx_runtime_1.jsxs)(PivotRowContainer, { children: [(0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-aggregation-type", value: agg.aggregationType, onChange: (e) => {
809
+ // if (
810
+ // e.target.value !== 'count' &&
811
+ // agg.valueField &&
812
+ // !numberFormatOptions.includes(
813
+ // columns.find(
814
+ // (col: Column) =>
815
+ // col.field === agg.valueField,
816
+ // )!.format,
817
+ // )
818
+ // ) {
819
+ // setPivotValueField(undefined);
820
+ // }
821
+ const newAgg = [
822
+ ...pivotAggregations.slice(0, index),
823
+ { ...agg, aggregationType: e.target.value === '' ? undefined : e.target.value },
824
+ ...pivotAggregations.slice(index + 1),
825
+ ];
826
+ pivotFieldChange('aggregations', newAgg);
827
+ setPivotAggregations(newAgg);
828
+ }, options: [
829
+ ...[
830
+ 'sum',
831
+ 'average',
832
+ 'count',
833
+ 'max',
834
+ 'min',
835
+ ...(pivotRowField ? ['percentage'] : []),
836
+ ].map((option) => {
837
+ return { label: option, value: option };
838
+ }),
839
+ ], width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { id: "pivot-value-field", value: agg.valueField, onChange: (e) => {
840
+ const newAgg = [
841
+ ...pivotAggregations.slice(0, index),
842
+ { ...agg, valueField: e.target.value === '' ? undefined : e.target.value },
843
+ ...pivotAggregations.slice(index + 1),
844
+ ];
845
+ pivotFieldChange('aggregations', newAgg);
846
+ setPivotAggregations(newAgg);
847
+ }, options: allowedValueFields
848
+ .map((field) => {
849
+ return {
850
+ label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(field),
851
+ value: field,
852
+ };
853
+ }), isLoading: uniqueValuesIsLoading, width: 200 }), (0, jsx_runtime_1.jsx)("div", { style: { marginLeft: -16, marginRight: -16, visibility: index > 0 ? 'visible' : 'hidden' }, children: (0, jsx_runtime_1.jsx)(DeleteButtonComponent, { onClick: () => {
854
+ setPivotAggregations([
855
+ ...pivotAggregations.slice(0, index),
856
+ ...pivotAggregations.slice(index + 1),
857
+ ]);
858
+ } }) })] }, index))] })] }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'row', marginRight: 'auto' }, children: (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: 'Add Aggregation', onClick: () => {
859
+ setPivotAggregations([
860
+ ...pivotAggregations,
861
+ { aggregationType: undefined, valueField: undefined, valueField2: undefined },
862
+ ]);
863
+ } }) }), errors.length > 0 && ((0, jsx_runtime_1.jsx)("div", { style: {
864
+ display: 'flex',
865
+ flexDirection: 'column',
866
+ gap: 8,
867
+ paddingTop: 8,
868
+ width: pivotCardWidth,
869
+ maxWidth: pivotCardWidth,
870
+ }, children: errors.map((error, index) => ((0, jsx_runtime_1.jsx)(ErrorMessageComponent, { errorMessage: error }, `error_message_${index}`))) })), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'row', marginLeft: 'auto', gap: 8 }, children: [(0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { onClick: () => {
871
+ setPivotError('');
872
+ setIsOpen(false);
873
+ setPopUpTitle('Add pivot');
874
+ }, label: "Cancel" }), (0, jsx_runtime_1.jsx)(ButtonComponent, { id: "custom-button", onClick: onCommitPivot, label: 'Save', disabled: !(pivotAggregations?.length > 0) ||
875
+ pivotAggregations.some((agg) => !agg.aggregationType || !agg.valueField) })] })] })) : ((0, jsx_runtime_1.jsx)("div", { style: {
775
876
  display: 'flex',
776
877
  flexDirection: 'column',
777
878
  fontFamily: theme?.fontFamily,
@@ -792,7 +893,7 @@ const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivo
792
893
  display: 'flex',
793
894
  flexDirection: 'row',
794
895
  gap: 8,
795
- }, children: [(0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Regenerate", onClick: refreshPivots, icon: (0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", style: { width: 16, height: 16 }, children: (0, jsx_runtime_1.jsx)("path", { fillRule: "evenodd", d: "M9 4.5a.75.75 0 0 1 .721.544l.813 2.846a3.75 3.75 0 0 0 2.576 2.576l2.846.813a.75.75 0 0 1 0 1.442l-2.846.813a3.75 3.75 0 0 0-2.576 2.576l-.813 2.846a.75.75 0 0 1-1.442 0l-.813-2.846a3.75 3.75 0 0 0-2.576-2.576l-2.846-.813a.75.75 0 0 1 0-1.442l2.846-.813A3.75 3.75 0 0 0 7.466 7.89l.813-2.846A.75.75 0 0 1 9 4.5ZM18 1.5a.75.75 0 0 1 .728.568l.258 1.036c.236.94.97 1.674 1.91 1.91l1.036.258a.75.75 0 0 1 0 1.456l-1.036.258c-.94.236-1.674.97-1.91 1.91l-.258 1.036a.75.75 0 0 1-1.456 0l-.258-1.036a2.625 2.625 0 0 0-1.91-1.91l-1.036-.258a.75.75 0 0 1 0-1.456l1.036-.258a2.625 2.625 0 0 0 1.91-1.91l.258-1.036A.75.75 0 0 1 18 1.5ZM16.5 15a.75.75 0 0 1 .712.513l.394 1.183c.15.447.5.799.948.948l1.183.395a.75.75 0 0 1 0 1.422l-1.183.395c-.447.15-.799.5-.948.948l-.395 1.183a.75.75 0 0 1-1.422 0l-.395-1.183a1.5 1.5 0 0 0-.948-.948l-1.183-.395a.75.75 0 0 1 0-1.422l1.183-.395c.447-.15.799-.5.948-.948l.395-1.183A.75.75 0 0 1 16.5 15Z", clipRule: "evenodd" }) }) }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Create pivot +", onClick: () => onEditPivot({}, null) })] }), isLoading || uniqueValuesIsLoading ? ((0, jsx_runtime_1.jsx)(LoadingComponent, {})) : pivotError ? ((0, jsx_runtime_1.jsx)("div", { style: {
896
+ }, children: [(0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Regenerate", onClick: refreshPivots, icon: (0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", style: { width: 16, height: 16 }, children: (0, jsx_runtime_1.jsx)("path", { fillRule: "evenodd", d: "M9 4.5a.75.75 0 0 1 .721.544l.813 2.846a3.75 3.75 0 0 0 2.576 2.576l2.846.813a.75.75 0 0 1 0 1.442l-2.846.813a3.75 3.75 0 0 0-2.576 2.576l-.813 2.846a.75.75 0 0 1-1.442 0l-.813-2.846a3.75 3.75 0 0 0-2.576-2.576l-2.846-.813a.75.75 0 0 1 0-1.442l2.846-.813A3.75 3.75 0 0 0 7.466 7.89l.813-2.846A.75.75 0 0 1 9 4.5ZM18 1.5a.75.75 0 0 1 .728.568l.258 1.036c.236.94.97 1.674 1.91 1.91l1.036.258a.75.75 0 0 1 0 1.456l-1.036.258c-.94.236-1.674.97-1.91 1.91l-.258 1.036a.75.75 0 0 1-1.456 0l-.258-1.036a2.625 2.625 0 0 0-1.91-1.91l-1.036-.258a.75.75 0 0 1 0-1.456l1.036-.258a2.625 2.625 0 0 0 1.91-1.91l.258-1.036A.75.75 0 0 1 18 1.5ZM16.5 15a.75.75 0 0 1 .712.513l.394 1.183c.15.447.5.799.948.948l1.183.395a.75.75 0 0 1 0 1.422l-1.183.395c-.447.15-.799.5-.948.948l-.395 1.183a.75.75 0 0 1-1.422 0l-.395-1.183a1.5 1.5 0 0 0-.948-.948l-1.183-.395a.75.75 0 0 1 0-1.422l1.183-.395c.447-.15.799-.5.948-.948l.395-1.183A.75.75 0 0 1 16.5 15Z", clipRule: "evenodd" }) }) }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: "Create pivot +", onClick: () => onEditPivot({ aggregations: [{}] }, null) })] }), isLoading || uniqueValuesIsLoading ? ((0, jsx_runtime_1.jsx)(LoadingComponent, {})) : pivotError ? ((0, jsx_runtime_1.jsx)("div", { style: {
796
897
  width: '100%',
797
898
  height: '140px',
798
899
  display: 'flex',
@@ -820,7 +921,7 @@ function generatePivotTableYAxis(pivot, cols, yAxisField) {
820
921
  if (pivot?.aggregationType === 'count') {
821
922
  return [
822
923
  {
823
- field: pivot.valueField || 'count',
924
+ field: pivot.valueField ?? 'count',
824
925
  label: yAxisField.label,
825
926
  format: yAxisField.format,
826
927
  },
@@ -829,22 +930,22 @@ function generatePivotTableYAxis(pivot, cols, yAxisField) {
829
930
  // otherwise use the default (ie. the field label)
830
931
  return [
831
932
  {
832
- field: pivot.valueField,
933
+ field: pivot.valueField ?? 'count',
833
934
  label: yAxisField.label,
834
935
  format: yAxisField.format,
835
936
  },
836
937
  ];
837
938
  }
838
939
  function generatePivotTitle(pivot) {
839
- if (pivot.rowField && !pivot.valueField) {
840
- return (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(`${pivot.aggregationType} of ${pivot.rowField}
940
+ if (pivot.rowField && !pivot.valueField && pivot.aggregations?.[0]) {
941
+ return (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(`${pivot.aggregations[0].aggregationType} of ${pivot.rowField}
841
942
  `);
842
943
  }
843
- else if (pivot.valueField && !pivot.rowField) {
844
- return (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(`${pivot.aggregationType} of ${pivot.valueField}
944
+ else if (!pivot.rowField && pivot.aggregations?.[0]?.valueField) {
945
+ return (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(`${pivot.aggregations[0].aggregationType} of ${pivot.aggregations[0].valueField}
845
946
  `);
846
947
  }
847
- return (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(`${pivot.aggregationType} of ${pivot.valueField} by ${pivot.rowField}${pivot.columnField ? ` and ${pivot.columnField}` : ''}`);
948
+ return (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(`${pivot.aggregations?.[0]?.aggregationType ?? 'Aggregation'} of ${pivot.aggregations?.[0]?.valueField ?? 'value'} by ${pivot.rowField}${pivot.columnField ? ` and ${pivot.columnField}` : ''}`);
848
949
  }
849
950
  function castValueToDate(value) {
850
951
  if (!value) {
@@ -972,13 +1073,18 @@ function getDateBuckets(dateRange, column, data, dateBucket) {
972
1073
  const dayDifference = (0, date_fns_1.differenceInDays)(dateRange.end, dateRange.start);
973
1074
  return dayDifferenceToInterval(dayDifference, dateRange);
974
1075
  }
975
- function getCompDateBuckets(dateRange, compDateRange, column, data) {
976
- if (!dateRange) {
977
- return (0, date_fns_1.eachMonthOfInterval)(getDateRange(undefined, column, data));
978
- }
979
- const dayDifference = (0, date_fns_1.differenceInDays)(dateRange.end, dateRange.start);
980
- return dayDifferenceToInterval(dayDifference, compDateRange);
981
- }
1076
+ // function getCompDateBuckets(
1077
+ // dateRange: { start: Date; end: Date } | undefined,
1078
+ // compDateRange: any,
1079
+ // column: string,
1080
+ // data: any,
1081
+ // ) {
1082
+ // if (!dateRange) {
1083
+ // return eachMonthOfInterval(getDateRange(undefined, column, data));
1084
+ // }
1085
+ // const dayDifference = differenceInDays(dateRange.end, dateRange.start);
1086
+ // return dayDifferenceToInterval(dayDifference, compDateRange);
1087
+ // }
982
1088
  function dayDifferenceToInterval(dayDifference, dateRange) {
983
1089
  if (dayDifference < 14) {
984
1090
  return (0, date_fns_1.eachDayOfInterval)(dateRange);
@@ -1054,30 +1160,33 @@ function isDateField(fieldType) {
1054
1160
  fieldType === 'MMM_dd_hh:mm_ap_pm' ||
1055
1161
  fieldType === 'hh_ap_pm');
1056
1162
  }
1057
- const isNullUndefinedOrInvalidDate = (date) => date === null || date === undefined || isNaN(date.getTime());
1058
- // If the value is an object with key value (ie. a BigQuery date) we will
1059
- // return the inner value, otherwise return passed param as-is.
1060
- const handleBigQueryValue = (value) => {
1061
- if (Boolean(value) &&
1062
- typeof value === 'object' &&
1063
- Object.keys(value).length === 1 &&
1064
- value['value']) {
1065
- return value['value'];
1066
- }
1067
- return value;
1068
- };
1069
- // Process out all the BigQuery dates.
1070
- const fixBigQueryData = (data = []) => {
1071
- const newData = [];
1072
- for (const row of data) {
1073
- const newRow = {};
1074
- for (const key in row) {
1075
- newRow[key] = handleBigQueryValue(row[key]);
1076
- }
1077
- newData.push(newRow);
1078
- }
1079
- return newData;
1080
- };
1163
+ // const isNullUndefinedOrInvalidDate = (date: Date) =>
1164
+ // date === null || date === undefined || isNaN(date.getTime());
1165
+ // // If the value is an object with key value (ie. a BigQuery date) we will
1166
+ // // return the inner value, otherwise return passed param as-is.
1167
+ // const handleBigQueryValue = (value: any) => {
1168
+ // if (
1169
+ // Boolean(value) &&
1170
+ // typeof value === 'object' &&
1171
+ // Object.keys(value).length === 1 &&
1172
+ // value['value']
1173
+ // ) {
1174
+ // return value['value'];
1175
+ // }
1176
+ // return value;
1177
+ // };
1178
+ // // Process out all the BigQuery dates.
1179
+ // const fixBigQueryData = (data: any[] = []) => {
1180
+ // const newData = [];
1181
+ // for (const row of data) {
1182
+ // const newRow: any = {};
1183
+ // for (const key in row) {
1184
+ // newRow[key] = handleBigQueryValue(row[key]);
1185
+ // }
1186
+ // newData.push(newRow);
1187
+ // }
1188
+ // return newData;
1189
+ // };
1081
1190
  async function generatePivotTable({ pivot, dateBucket, dateFilter, report, client, uniqueValues, dashboardName, tenants, additionalProcessing, }) {
1082
1191
  try {
1083
1192
  if (report && client) {
@@ -1104,430 +1213,3 @@ async function generatePivotTable({ pivot, dateBucket, dateFilter, report, clien
1104
1213
  }
1105
1214
  throw Error('Failed to generate pivot table: invalid report');
1106
1215
  }
1107
- function generatePivotTableInMemory(pivot, data, dateRange, isComparison, rowLimit, compRange = undefined, dateBucket, uniqueValues) {
1108
- // If there is no rowField, aggregate on the valueField
1109
- if (!pivot.rowField) {
1110
- return valueFieldAggregation(data, pivot.valueField, pivot.aggregationType, isComparison);
1111
- }
1112
- // Handle edge-case for BigQuery objects.
1113
- data = fixBigQueryData(data);
1114
- if (!dateRange) {
1115
- if (isDateField(pivot.rowFieldType || '')) {
1116
- dateRange = getDateRange(dateRange, pivot.rowField, data);
1117
- }
1118
- }
1119
- if (!compRange ||
1120
- isNullUndefinedOrInvalidDate(compRange.start) ||
1121
- isNullUndefinedOrInvalidDate(compRange.end)) {
1122
- compRange = undefined;
1123
- }
1124
- const pivotRows = [];
1125
- const uniqueValuesMap = (0, filterProcessing_1.uniqueValuesToStringMap)(uniqueValues || {});
1126
- const uniqueRows = (isDateField(pivot.rowFieldType || '')
1127
- ? getDateBuckets(dateRange, pivot.rowField, data, dateBucket)
1128
- : uniqueValuesMap[pivot.rowField] &&
1129
- uniqueValuesMap[pivot.rowField]?.[0] !== 'EXCEEDS_LIMIT'
1130
- ? uniqueValuesMap[pivot.rowField]
1131
- : [...new Set(data.map((item) => item[pivot.rowField || '']))])
1132
- .filter((col) => col !== null && col !== '')
1133
- .map((col) => isDateField(pivot.rowFieldType || '') ? castValueToDate(col) : col);
1134
- const rowDateRange = getDateRange(dateRange, pivot.rowField, data);
1135
- const compRowDateRange = getDateRange(compRange ?? dateRange, pivot.rowField, data);
1136
- // If columnField is not provided, we will not be using uniqueColumns
1137
- // @ts-ignore
1138
- const uniqueColumns = (pivot.columnField
1139
- ? isDateField(pivot.columnFieldType || '')
1140
- ? getDateBuckets(dateRange, pivot.columnField, data, dateBucket)
1141
- : uniqueValues && pivot.columnField
1142
- ? uniqueValuesMap[pivot.columnField]
1143
- : [...new Set(data.map((item) => item[pivot.columnField || '']))]
1144
- : [pivot.valueField]).filter((col) => col !== null && col !== '' && col !== undefined);
1145
- // Map from new dates to their corresponding prior dates
1146
- const COL_DATE_MAP = {};
1147
- const ROW_DATE_MAP = {};
1148
- // add in the comparison columns for all columns in the pivot
1149
- let compUniqueRows = [];
1150
- if (isComparison) {
1151
- if (pivot.columnField) {
1152
- const col = pivot.columnField;
1153
- const row = pivot.rowField;
1154
- const isDateCol = isDateField(pivot.columnFieldType || '');
1155
- const isDateRow = isDateField(pivot.rowFieldType || '');
1156
- data.forEach((item) => {
1157
- if (isDateCol) {
1158
- const key = getDateString(item[col], dateRange);
1159
- const value = getDateString(item[`comparison_${col}`], dateRange, dateBucket);
1160
- COL_DATE_MAP[key] = value;
1161
- }
1162
- if (isDateRow) {
1163
- const key = getDateString(item[row], dateRange);
1164
- const value = getDateString(item[`comparison_${row}`], dateRange, dateBucket);
1165
- ROW_DATE_MAP[key] = value;
1166
- }
1167
- });
1168
- }
1169
- else {
1170
- const primaryColumns = [...uniqueColumns];
1171
- for (const primaryKey of primaryColumns) {
1172
- uniqueColumns.push(`comparison_${primaryKey}`);
1173
- }
1174
- }
1175
- compUniqueRows = (isDateField(pivot.rowFieldType || '')
1176
- ? getCompDateBuckets(dateRange, compRange ?? dateRange, pivot.rowField, data)
1177
- : (uniqueValuesMap[pivot.rowField] ?? [
1178
- ...new Set(data.map((item) => item[pivot.rowField || ''])),
1179
- ])).filter((col) => col !== null && col !== '');
1180
- }
1181
- // Special corner case for count with only rowField pivot
1182
- if (!pivot.valueField &&
1183
- !pivot.columnField &&
1184
- pivot.aggregationType === 'count') {
1185
- uniqueColumns.push('count');
1186
- if (isComparison) {
1187
- uniqueColumns.push('comparison_count');
1188
- }
1189
- }
1190
- const rowsToGenerate = rowLimit && rowLimit <= uniqueRows.length
1191
- ? uniqueRows.slice(0, rowLimit)
1192
- : uniqueRows;
1193
- rowsToGenerate.forEach((rowValue, rowIndex) => {
1194
- const row = {
1195
- [pivot.rowField || '']: isDateField(pivot.rowFieldType || '')
1196
- ? getDateString(rowValue, dateRange, dateBucket)
1197
- : rowValue === null
1198
- ? 'Null'
1199
- : rowValue === false
1200
- ? 'False'
1201
- : rowValue === true
1202
- ? 'True'
1203
- : rowValue,
1204
- };
1205
- uniqueColumns.forEach((colValue, colIndex) => {
1206
- let comparisonFilteredData = [];
1207
- let filteredData = [];
1208
- let comparisonValue;
1209
- let value;
1210
- const nextRowValue = isDateField(pivot.rowFieldType || '')
1211
- ? // @ts-ignore
1212
- (uniqueRows[rowIndex + 1] ?? (0, date_fns_1.endOfDay)(rowDateRange.end))
1213
- : null;
1214
- const compRowValue = compUniqueRows[rowIndex];
1215
- const compNextRowValue = isDateField(pivot.rowFieldType || '')
1216
- ? (compUniqueRows[rowIndex + 1] ?? (0, date_fns_1.endOfDay)(compRowDateRange.end))
1217
- : null;
1218
- if (pivot.columnField) {
1219
- const columnDateRange = getDateRange(dateRange, pivot.columnField, data);
1220
- const nextColumnValue = isDateField(pivot.columnFieldType || '')
1221
- ? uniqueColumns[colIndex + 1] || (0, date_fns_1.endOfDay)(columnDateRange.end)
1222
- : null;
1223
- // If columnField is provided, filter by both rowField and columnField
1224
- if (isDateField(pivot.columnFieldType || '') &&
1225
- isDateField(pivot.rowFieldType || '')) {
1226
- filteredData = data.filter((item) => {
1227
- return ((0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.rowField || '']) ?? 0, {
1228
- start: rowValue,
1229
- end: (0, date_fns_1.subMilliseconds)(nextRowValue, 1),
1230
- }) &&
1231
- (0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.columnField || '']) ?? 0, {
1232
- start: colValue,
1233
- end: (0, date_fns_1.subMilliseconds)(nextColumnValue, 1),
1234
- }));
1235
- });
1236
- if (isComparison) {
1237
- comparisonFilteredData = data.filter((item) => {
1238
- return ((0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.rowField || '']) ?? 0, {
1239
- start: rowValue,
1240
- end: (0, date_fns_1.subMilliseconds)(nextRowValue, 1),
1241
- }) &&
1242
- (0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.columnField || '']) ?? 0, {
1243
- start: colValue,
1244
- end: (0, date_fns_1.subMilliseconds)(nextColumnValue, 1),
1245
- }));
1246
- });
1247
- }
1248
- }
1249
- else if (isDateField(pivot.columnFieldType || '') &&
1250
- !isDateField(pivot.rowFieldType || '')) {
1251
- filteredData = data.filter((item) => {
1252
- return (item[pivot.rowField || ''] === rowValue &&
1253
- (0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.columnField || '']) ?? 0, {
1254
- start: colValue,
1255
- end: (0, date_fns_1.subMilliseconds)(nextColumnValue, 1),
1256
- }));
1257
- });
1258
- if (isComparison) {
1259
- comparisonFilteredData = data.filter((item) => {
1260
- return (item[`comparison_${pivot.rowField}`] === rowValue &&
1261
- (0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.columnField || '']) ?? 0, {
1262
- start: colValue,
1263
- end: (0, date_fns_1.subMilliseconds)(nextColumnValue, 1),
1264
- }));
1265
- });
1266
- }
1267
- }
1268
- else if (!isDateField(pivot.columnFieldType || '') &&
1269
- isDateField(pivot.rowFieldType || '')) {
1270
- filteredData = data.filter((item) => {
1271
- return ((0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.rowField || '']) ?? 0, {
1272
- start: rowValue,
1273
- end: (0, date_fns_1.subMilliseconds)(nextRowValue, 1),
1274
- }) && item[pivot.columnField || ''] === colValue);
1275
- });
1276
- if (isComparison) {
1277
- comparisonFilteredData = data.filter((item) => {
1278
- return ((0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.rowField || '']) ?? 0, {
1279
- start: rowValue,
1280
- end: (0, date_fns_1.subMilliseconds)(nextRowValue, 1),
1281
- }) &&
1282
- item[`comparison_${pivot.columnField}` || ''] === colValue);
1283
- });
1284
- }
1285
- }
1286
- else {
1287
- filteredData = data.filter((item) => {
1288
- return (item[pivot.rowField || ''] === rowValue &&
1289
- item[pivot.columnField || ''] === colValue);
1290
- });
1291
- if (isComparison) {
1292
- comparisonFilteredData = data.filter((item) => {
1293
- return (item[`comparison_${pivot.rowField}`] === rowValue &&
1294
- item[`comparison_${pivot.columnField}`] === colValue);
1295
- });
1296
- }
1297
- }
1298
- }
1299
- else {
1300
- // NOTE: For 1D columns, the comparisons are handled inside the colvalue
1301
- // so there is no need to filter for comparisonFilteredData here.
1302
- // If columnField is not provided, filter by rowField only
1303
- if (colValue.startsWith('comparison_')) {
1304
- filteredData = isDateField(pivot.rowFieldType || '')
1305
- ? data.filter((item) => {
1306
- return (compRowValue &&
1307
- (0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[`comparison_${pivot.rowField}`]) ?? 0, {
1308
- start: compRowValue,
1309
- end: (0, date_fns_1.subMilliseconds)(compNextRowValue, 1),
1310
- }));
1311
- })
1312
- : data.filter((item) => item[`comparison_${pivot.rowField}`] === compRowValue);
1313
- }
1314
- else {
1315
- filteredData = isDateField(pivot.rowFieldType || '')
1316
- ? data.filter((item) => {
1317
- return (0, date_fns_1.isWithinInterval)((0, valueFormatter_1.getValidDate)(item[pivot.rowField || '']) ?? 0, {
1318
- start: rowValue,
1319
- end: (0, date_fns_1.subMilliseconds)(nextRowValue, 1),
1320
- });
1321
- })
1322
- : data.filter((item) => item[pivot.rowField || ''] === rowValue);
1323
- }
1324
- }
1325
- // Aggregation logic remains the same
1326
- const key = pivot.columnField && pivot.columnField.trim()
1327
- ? pivot.valueField
1328
- : colValue;
1329
- switch (pivot.aggregationType) {
1330
- case 'sum':
1331
- value = filteredData.reduce((sum, item) => sum + parseFloat(item[key] ?? 0), 0);
1332
- if (isComparison) {
1333
- comparisonValue = comparisonFilteredData.reduce((sum, item) => sum + parseFloat(item[key] ?? 0), 0);
1334
- }
1335
- break;
1336
- case 'count':
1337
- value = filteredData.length;
1338
- if (isComparison) {
1339
- comparisonValue = comparisonFilteredData.length;
1340
- }
1341
- break;
1342
- case 'average':
1343
- case 'avg':
1344
- value = filteredData.length
1345
- ? filteredData.reduce((sum, item) => sum + parseFloat(item[key] ?? 0), 0) / filteredData.length
1346
- : 0;
1347
- if (isComparison) {
1348
- comparisonValue = comparisonFilteredData.length
1349
- ? comparisonFilteredData.reduce((sum, item) => sum + parseFloat(item[key] ?? 0), 0) / comparisonFilteredData.length
1350
- : 0;
1351
- }
1352
- break;
1353
- case 'max':
1354
- value = filteredData.reduce((max, item) => Math.max(max, parseFloat(item[key] ?? -Infinity)), -Infinity);
1355
- if (isComparison) {
1356
- comparisonValue = comparisonFilteredData.reduce((max, item) => Math.max(max, parseFloat(item[key] ?? -Infinity)), -Infinity);
1357
- }
1358
- break;
1359
- case 'min':
1360
- value = filteredData.reduce((min, item) => Math.min(min, parseFloat(item[key] ?? Infinity)), Infinity);
1361
- if (isComparison) {
1362
- comparisonValue = comparisonFilteredData.reduce((min, item) => Math.min(min, parseFloat(item[key] ?? Infinity)), Infinity);
1363
- }
1364
- break;
1365
- // Implement other aggregation types as needed
1366
- default:
1367
- throw new Error('Unsupported aggregation type');
1368
- }
1369
- // Set the value on the row
1370
- // If columnField is not provided, colValue will be valueField
1371
- row[isDateField(pivot.columnFieldType || '')
1372
- ? getDateString(colValue, dateRange)
1373
- : colValue] =
1374
- pivot.aggregationType === 'count' ? value.toFixed(0) : value.toFixed(2);
1375
- if (isComparison && pivot.columnField) {
1376
- if (isDateField(pivot.columnFieldType || '')) {
1377
- row[`comparison_${getDateString(colValue, dateRange)}`] =
1378
- pivot.aggregationType === 'count'
1379
- ? comparisonValue?.toFixed(0)
1380
- : comparisonValue?.toFixed(2);
1381
- }
1382
- else {
1383
- row[`comparison_${colValue}`] =
1384
- pivot.aggregationType === 'count'
1385
- ? comparisonValue?.toFixed(0)
1386
- : comparisonValue?.toFixed(2);
1387
- }
1388
- }
1389
- });
1390
- if (pivot.aggregationType === 'max' || pivot.aggregationType === 'min') {
1391
- for (const [key, value] of Object.entries(row)) {
1392
- if (value === '-Infinity' || value === 'Infinity') {
1393
- row[key] = null;
1394
- }
1395
- }
1396
- }
1397
- pivotRows.push(row);
1398
- });
1399
- const columns = [
1400
- {
1401
- label: pivot.rowField === null
1402
- ? 'Null'
1403
- : (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(pivot.rowField),
1404
- field: pivot.rowField,
1405
- },
1406
- ...uniqueColumns.map((column) => {
1407
- const columnName = isDateField(pivot.columnFieldType || '')
1408
- ? getDateString(column, dateRange, dateBucket)
1409
- : column;
1410
- return {
1411
- label: column === null
1412
- ? 'Null'
1413
- : column === false
1414
- ? 'False'
1415
- : (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(columnName).replace('Comparison', 'comparison'),
1416
- field: columnName,
1417
- };
1418
- }),
1419
- ...(isComparison && pivot.columnField
1420
- ? uniqueColumns.map((column, index) => {
1421
- const columnName = isDateField(pivot.columnFieldType || '')
1422
- ? getDateString(column, dateRange, dateBucket)
1423
- : column;
1424
- return {
1425
- label: column === null
1426
- ? 'Null'
1427
- : column === false
1428
- ? 'False'
1429
- : pivot.aggregationType === 'count' &&
1430
- !pivot.columnField &&
1431
- index === 1
1432
- ? `comparison Count`
1433
- : isDateField(pivot.columnFieldType || '')
1434
- ? (COL_DATE_MAP[getDateString(column, dateRange, dateBucket)] ?? 'comparison')
1435
- : `comparison ${(0, textProcessing_1.snakeAndCamelCaseToTitleCase)(columnName)}`,
1436
- field: `comparison_${columnName}`,
1437
- };
1438
- })
1439
- : []),
1440
- ];
1441
- if (pivot.sort) {
1442
- pivotRows.sort((a, b) => {
1443
- if (pivot.sortField) {
1444
- const result = (0, valueFormatter_1.compareValues)(a, b, pivot.sortField);
1445
- return pivot.sortDirection === 'ASC' ? result : -result;
1446
- }
1447
- else {
1448
- return b[pivot.sortField].localeCompare(a[pivot.sortField]);
1449
- }
1450
- });
1451
- }
1452
- return { rows: pivotRows, columns };
1453
- }
1454
- function valueFieldAggregation(data, valueField, aggregationType, isComparison) {
1455
- if (!data || data.length === 0) {
1456
- return {
1457
- rows: [],
1458
- columns: [
1459
- { label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(valueField), field: valueField },
1460
- ],
1461
- };
1462
- }
1463
- let value = 0;
1464
- let comparisonValue = 0;
1465
- let count = 0;
1466
- switch (aggregationType) {
1467
- case 'sum':
1468
- value = data.reduce((sum, item) =>
1469
- // Big(sum)
1470
- // .add(Big(parseFloat(item[valueField] ?? '0')))
1471
- // .toNumber(),
1472
- sum + parseFloat(item[valueField] ?? '0'), 0);
1473
- if (isComparison) {
1474
- comparisonValue = data.reduce((sum, item) =>
1475
- // Big(sum)
1476
- // .add(Big(parseFloat(item[`comparison_${valueField}`] ?? '0')))
1477
- // .toNumber(),
1478
- sum + parseFloat(item[`comparison_${valueField}`] ?? '0'), 0);
1479
- }
1480
- break;
1481
- case 'count':
1482
- value = data.reduce((count, item) => count + (item[valueField] ? 1 : 0), 0);
1483
- if (isComparison) {
1484
- comparisonValue = data.reduce((count, item) => count + (item[`comparison_${valueField}`] ? 1 : 0), 0);
1485
- }
1486
- break;
1487
- case 'avg':
1488
- case 'average':
1489
- count = data.reduce((count, item) => count + (item[valueField] ? 1 : 0), 0);
1490
- value =
1491
- data.reduce((sum, item) =>
1492
- // Big(sum)
1493
- // .add(Big(parseFloat(item[valueField] ?? '0')))
1494
- // .toNumber(),
1495
- sum + parseFloat(item[valueField] ?? '0'), 0) / (count === 0 ? 1 : count);
1496
- if (isComparison) {
1497
- const comparisonCount = data.reduce((count, item) => count + (item[`comparison_${valueField}`] ? 1 : 0), 0);
1498
- comparisonValue =
1499
- data.reduce((sum, item) =>
1500
- // Big(sum)
1501
- // .add(Big(parseFloat(item[`comparison_${valueField}`] ?? '0')))
1502
- // .toNumber(),
1503
- sum + parseFloat(item[`comparison_${valueField}`] ?? '0'), 0) / (comparisonCount === 0 ? 1 : comparisonCount);
1504
- }
1505
- break;
1506
- case 'max':
1507
- value = data.reduce((max, item) => Math.max(max, parseFloat(item[valueField] ?? -Infinity)), -Infinity);
1508
- if (isComparison) {
1509
- comparisonValue = data.reduce((max, item) => Math.max(max, parseFloat(item[`comparison_${valueField}`] ?? -Infinity)), -Infinity);
1510
- }
1511
- break;
1512
- case 'min':
1513
- value = data.reduce((min, item) => Math.min(min, parseFloat(item[valueField] ?? Infinity)), Infinity);
1514
- if (isComparison) {
1515
- comparisonValue = data.reduce((min, item) => Math.min(min, parseFloat(item[`comparison_${valueField}`] ?? Infinity)), Infinity);
1516
- }
1517
- break;
1518
- // Implement other aggregation types as needed
1519
- default:
1520
- throw new Error('Unsupported aggregation type');
1521
- }
1522
- const row = {};
1523
- row[valueField] = value;
1524
- if (isComparison) {
1525
- row[`comparison_${valueField}`] = comparisonValue;
1526
- }
1527
- return {
1528
- rows: [row],
1529
- columns: [
1530
- { label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(valueField), field: valueField },
1531
- ],
1532
- };
1533
- }