@quillsql/react 2.11.23 → 2.11.24

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 (201) hide show
  1. package/dist/cjs/Chart.d.ts.map +1 -1
  2. package/dist/cjs/Chart.js +32 -16
  3. package/dist/cjs/ChartBuilder.d.ts +55 -2
  4. package/dist/cjs/ChartBuilder.d.ts.map +1 -1
  5. package/dist/cjs/ChartBuilder.js +223 -206
  6. package/dist/cjs/ChartEditor.d.ts +49 -2
  7. package/dist/cjs/ChartEditor.d.ts.map +1 -1
  8. package/dist/cjs/ChartEditor.js +3 -3
  9. package/dist/cjs/Dashboard.d.ts +5 -1
  10. package/dist/cjs/Dashboard.d.ts.map +1 -1
  11. package/dist/cjs/Dashboard.js +42 -18
  12. package/dist/cjs/DateRangePicker/QuillDateRangePicker.d.ts +2 -1
  13. package/dist/cjs/DateRangePicker/QuillDateRangePicker.d.ts.map +1 -1
  14. package/dist/cjs/DateRangePicker/QuillDateRangePicker.js +4 -3
  15. package/dist/cjs/ReportBuilder.d.ts +57 -2
  16. package/dist/cjs/ReportBuilder.d.ts.map +1 -1
  17. package/dist/cjs/ReportBuilder.js +969 -684
  18. package/dist/cjs/SQLEditor.d.ts +83 -2
  19. package/dist/cjs/SQLEditor.d.ts.map +1 -1
  20. package/dist/cjs/SQLEditor.js +10 -2
  21. package/dist/cjs/components/Chart/BarChart.d.ts.map +1 -1
  22. package/dist/cjs/components/Chart/BarChart.js +8 -6
  23. package/dist/cjs/components/Chart/BarList.d.ts.map +1 -1
  24. package/dist/cjs/components/Chart/BarList.js +0 -153
  25. package/dist/cjs/components/Chart/ChartError.d.ts +1 -1
  26. package/dist/cjs/components/Chart/ChartError.d.ts.map +1 -1
  27. package/dist/cjs/components/Chart/ChartError.js +13 -7
  28. package/dist/cjs/components/Chart/ChartTooltip.d.ts +1 -0
  29. package/dist/cjs/components/Chart/ChartTooltip.d.ts.map +1 -1
  30. package/dist/cjs/components/Chart/ChartTooltip.js +6 -7
  31. package/dist/cjs/components/Chart/LineChart.d.ts +1 -1
  32. package/dist/cjs/components/Chart/LineChart.d.ts.map +1 -1
  33. package/dist/cjs/components/Chart/LineChart.js +32 -31
  34. package/dist/cjs/components/Dashboard/DashboardFilter.d.ts +1 -1
  35. package/dist/cjs/components/Dashboard/DashboardFilter.d.ts.map +1 -1
  36. package/dist/cjs/components/Dashboard/DashboardFilter.js +21 -21
  37. package/dist/cjs/components/Dashboard/DataLoader.d.ts +24 -0
  38. package/dist/cjs/components/Dashboard/DataLoader.d.ts.map +1 -1
  39. package/dist/cjs/components/Dashboard/DataLoader.js +84 -0
  40. package/dist/cjs/components/Dashboard/MetricComponent.d.ts.map +1 -1
  41. package/dist/cjs/components/Dashboard/MetricComponent.js +4 -1
  42. package/dist/cjs/components/QuillSelect.js +1 -1
  43. package/dist/cjs/components/QuillTable.d.ts.map +1 -1
  44. package/dist/cjs/components/QuillTable.js +11 -12
  45. package/dist/cjs/components/ReportBuilder/{AddColumnPopover.d.ts → AddColumnModal.d.ts} +3 -2
  46. package/dist/cjs/components/ReportBuilder/AddColumnModal.d.ts.map +1 -0
  47. package/dist/cjs/components/ReportBuilder/{AddColumnPopover.js → AddColumnModal.js} +12 -8
  48. package/dist/cjs/components/ReportBuilder/AddLimitPopover.d.ts.map +1 -1
  49. package/dist/cjs/components/ReportBuilder/AddLimitPopover.js +1 -1
  50. package/dist/cjs/components/ReportBuilder/AddSortPopover.d.ts +1 -1
  51. package/dist/cjs/components/ReportBuilder/AddSortPopover.d.ts.map +1 -1
  52. package/dist/cjs/components/ReportBuilder/AddSortPopover.js +5 -5
  53. package/dist/cjs/components/ReportBuilder/ast.d.ts +6 -0
  54. package/dist/cjs/components/ReportBuilder/ast.d.ts.map +1 -1
  55. package/dist/cjs/components/ReportBuilder/ast.js +13 -2
  56. package/dist/cjs/components/ReportBuilder/constants.d.ts +13 -0
  57. package/dist/cjs/components/ReportBuilder/constants.d.ts.map +1 -1
  58. package/dist/cjs/components/ReportBuilder/constants.js +14 -1
  59. package/dist/cjs/components/ReportBuilder/convert.d.ts +18 -1
  60. package/dist/cjs/components/ReportBuilder/convert.d.ts.map +1 -1
  61. package/dist/cjs/components/ReportBuilder/convert.js +14 -3
  62. package/dist/cjs/components/ReportBuilder/operators.d.ts +15 -23
  63. package/dist/cjs/components/ReportBuilder/operators.d.ts.map +1 -1
  64. package/dist/cjs/components/ReportBuilder/operators.js +19 -27
  65. package/dist/cjs/components/ReportBuilder/pivot.d.ts +2 -0
  66. package/dist/cjs/components/ReportBuilder/pivot.d.ts.map +1 -1
  67. package/dist/cjs/components/ReportBuilder/ui.d.ts +3 -2
  68. package/dist/cjs/components/ReportBuilder/ui.d.ts.map +1 -1
  69. package/dist/cjs/components/ReportBuilder/ui.js +54 -28
  70. package/dist/cjs/components/ReportBuilder/util.d.ts +1 -1
  71. package/dist/cjs/components/ReportBuilder/util.d.ts.map +1 -1
  72. package/dist/cjs/components/ReportBuilder/util.js +3 -0
  73. package/dist/cjs/components/UiComponents.d.ts +34 -4
  74. package/dist/cjs/components/UiComponents.d.ts.map +1 -1
  75. package/dist/cjs/components/UiComponents.js +165 -68
  76. package/dist/cjs/hooks/useQuill.d.ts +1 -0
  77. package/dist/cjs/hooks/useQuill.d.ts.map +1 -1
  78. package/dist/cjs/internals/ReportBuilder/PivotList.d.ts +1 -2
  79. package/dist/cjs/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  80. package/dist/cjs/internals/ReportBuilder/PivotList.js +5 -7
  81. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts +31 -5
  82. package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  83. package/dist/cjs/internals/ReportBuilder/PivotModal.js +437 -282
  84. package/dist/cjs/utils/axisFormatter.js +3 -3
  85. package/dist/cjs/utils/getDomain.d.ts.map +1 -1
  86. package/dist/cjs/utils/getDomain.js +3 -0
  87. package/dist/cjs/utils/merge.d.ts.map +1 -1
  88. package/dist/cjs/utils/merge.js +2 -0
  89. package/dist/cjs/utils/pivotProcessing.d.ts +20 -0
  90. package/dist/cjs/utils/pivotProcessing.d.ts.map +1 -0
  91. package/dist/cjs/utils/pivotProcessing.js +177 -0
  92. package/dist/cjs/utils/queryConstructor.d.ts +2 -0
  93. package/dist/cjs/utils/queryConstructor.d.ts.map +1 -0
  94. package/dist/cjs/utils/queryConstructor.js +11 -0
  95. package/dist/cjs/utils/tableProcessing.d.ts +7 -0
  96. package/dist/cjs/utils/tableProcessing.d.ts.map +1 -0
  97. package/dist/cjs/utils/tableProcessing.js +84 -0
  98. package/dist/cjs/utils/valueFormatter.d.ts.map +1 -1
  99. package/dist/cjs/utils/valueFormatter.js +40 -8
  100. package/dist/esm/Chart.d.ts.map +1 -1
  101. package/dist/esm/Chart.js +33 -17
  102. package/dist/esm/ChartBuilder.d.ts +55 -2
  103. package/dist/esm/ChartBuilder.d.ts.map +1 -1
  104. package/dist/esm/ChartBuilder.js +225 -208
  105. package/dist/esm/ChartEditor.d.ts +49 -2
  106. package/dist/esm/ChartEditor.d.ts.map +1 -1
  107. package/dist/esm/ChartEditor.js +4 -4
  108. package/dist/esm/Dashboard.d.ts +5 -1
  109. package/dist/esm/Dashboard.d.ts.map +1 -1
  110. package/dist/esm/Dashboard.js +21 -20
  111. package/dist/esm/DateRangePicker/QuillDateRangePicker.d.ts +2 -1
  112. package/dist/esm/DateRangePicker/QuillDateRangePicker.d.ts.map +1 -1
  113. package/dist/esm/DateRangePicker/QuillDateRangePicker.js +4 -3
  114. package/dist/esm/ReportBuilder.d.ts +57 -2
  115. package/dist/esm/ReportBuilder.d.ts.map +1 -1
  116. package/dist/esm/ReportBuilder.js +971 -687
  117. package/dist/esm/SQLEditor.d.ts +83 -2
  118. package/dist/esm/SQLEditor.d.ts.map +1 -1
  119. package/dist/esm/SQLEditor.js +11 -3
  120. package/dist/esm/components/Chart/BarChart.d.ts.map +1 -1
  121. package/dist/esm/components/Chart/BarChart.js +8 -6
  122. package/dist/esm/components/Chart/BarList.d.ts.map +1 -1
  123. package/dist/esm/components/Chart/BarList.js +0 -153
  124. package/dist/esm/components/Chart/ChartError.d.ts +1 -1
  125. package/dist/esm/components/Chart/ChartError.d.ts.map +1 -1
  126. package/dist/esm/components/Chart/ChartError.js +13 -7
  127. package/dist/esm/components/Chart/ChartTooltip.d.ts +1 -0
  128. package/dist/esm/components/Chart/ChartTooltip.d.ts.map +1 -1
  129. package/dist/esm/components/Chart/ChartTooltip.js +6 -7
  130. package/dist/esm/components/Chart/LineChart.d.ts +1 -1
  131. package/dist/esm/components/Chart/LineChart.d.ts.map +1 -1
  132. package/dist/esm/components/Chart/LineChart.js +32 -31
  133. package/dist/esm/components/Dashboard/DashboardFilter.d.ts +1 -1
  134. package/dist/esm/components/Dashboard/DashboardFilter.d.ts.map +1 -1
  135. package/dist/esm/components/Dashboard/DashboardFilter.js +21 -21
  136. package/dist/esm/components/Dashboard/DataLoader.d.ts +24 -0
  137. package/dist/esm/components/Dashboard/DataLoader.d.ts.map +1 -1
  138. package/dist/esm/components/Dashboard/DataLoader.js +82 -0
  139. package/dist/esm/components/Dashboard/MetricComponent.d.ts.map +1 -1
  140. package/dist/esm/components/Dashboard/MetricComponent.js +4 -1
  141. package/dist/esm/components/QuillSelect.js +1 -1
  142. package/dist/esm/components/QuillTable.d.ts.map +1 -1
  143. package/dist/esm/components/QuillTable.js +11 -12
  144. package/dist/esm/components/ReportBuilder/{AddColumnPopover.d.ts → AddColumnModal.d.ts} +3 -2
  145. package/dist/esm/components/ReportBuilder/AddColumnModal.d.ts.map +1 -0
  146. package/dist/esm/components/ReportBuilder/{AddColumnPopover.js → AddColumnModal.js} +11 -7
  147. package/dist/esm/components/ReportBuilder/AddLimitPopover.d.ts.map +1 -1
  148. package/dist/esm/components/ReportBuilder/AddLimitPopover.js +1 -1
  149. package/dist/esm/components/ReportBuilder/AddSortPopover.d.ts +1 -1
  150. package/dist/esm/components/ReportBuilder/AddSortPopover.d.ts.map +1 -1
  151. package/dist/esm/components/ReportBuilder/AddSortPopover.js +5 -5
  152. package/dist/esm/components/ReportBuilder/ast.d.ts +6 -0
  153. package/dist/esm/components/ReportBuilder/ast.d.ts.map +1 -1
  154. package/dist/esm/components/ReportBuilder/ast.js +11 -1
  155. package/dist/esm/components/ReportBuilder/constants.d.ts +13 -0
  156. package/dist/esm/components/ReportBuilder/constants.d.ts.map +1 -1
  157. package/dist/esm/components/ReportBuilder/constants.js +13 -0
  158. package/dist/esm/components/ReportBuilder/convert.d.ts +18 -1
  159. package/dist/esm/components/ReportBuilder/convert.d.ts.map +1 -1
  160. package/dist/esm/components/ReportBuilder/convert.js +14 -3
  161. package/dist/esm/components/ReportBuilder/operators.d.ts +15 -23
  162. package/dist/esm/components/ReportBuilder/operators.d.ts.map +1 -1
  163. package/dist/esm/components/ReportBuilder/operators.js +19 -27
  164. package/dist/esm/components/ReportBuilder/pivot.d.ts +2 -0
  165. package/dist/esm/components/ReportBuilder/pivot.d.ts.map +1 -1
  166. package/dist/esm/components/ReportBuilder/ui.d.ts +3 -2
  167. package/dist/esm/components/ReportBuilder/ui.d.ts.map +1 -1
  168. package/dist/esm/components/ReportBuilder/ui.js +55 -29
  169. package/dist/esm/components/ReportBuilder/util.d.ts +1 -1
  170. package/dist/esm/components/ReportBuilder/util.d.ts.map +1 -1
  171. package/dist/esm/components/ReportBuilder/util.js +3 -0
  172. package/dist/esm/components/UiComponents.d.ts +34 -4
  173. package/dist/esm/components/UiComponents.d.ts.map +1 -1
  174. package/dist/esm/components/UiComponents.js +155 -66
  175. package/dist/esm/hooks/useQuill.d.ts +1 -0
  176. package/dist/esm/hooks/useQuill.d.ts.map +1 -1
  177. package/dist/esm/internals/ReportBuilder/PivotList.d.ts +1 -2
  178. package/dist/esm/internals/ReportBuilder/PivotList.d.ts.map +1 -1
  179. package/dist/esm/internals/ReportBuilder/PivotList.js +5 -7
  180. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts +31 -5
  181. package/dist/esm/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
  182. package/dist/esm/internals/ReportBuilder/PivotModal.js +438 -284
  183. package/dist/esm/utils/axisFormatter.js +3 -3
  184. package/dist/esm/utils/getDomain.d.ts.map +1 -1
  185. package/dist/esm/utils/getDomain.js +3 -0
  186. package/dist/esm/utils/merge.d.ts.map +1 -1
  187. package/dist/esm/utils/merge.js +2 -0
  188. package/dist/esm/utils/pivotProcessing.d.ts +20 -0
  189. package/dist/esm/utils/pivotProcessing.d.ts.map +1 -0
  190. package/dist/esm/utils/pivotProcessing.js +170 -0
  191. package/dist/esm/utils/queryConstructor.d.ts +2 -0
  192. package/dist/esm/utils/queryConstructor.d.ts.map +1 -0
  193. package/dist/esm/utils/queryConstructor.js +7 -0
  194. package/dist/esm/utils/tableProcessing.d.ts +7 -0
  195. package/dist/esm/utils/tableProcessing.d.ts.map +1 -0
  196. package/dist/esm/utils/tableProcessing.js +80 -0
  197. package/dist/esm/utils/valueFormatter.d.ts.map +1 -1
  198. package/dist/esm/utils/valueFormatter.js +41 -9
  199. package/package.json +1 -1
  200. package/dist/cjs/components/ReportBuilder/AddColumnPopover.d.ts.map +0 -1
  201. package/dist/esm/components/ReportBuilder/AddColumnPopover.d.ts.map +0 -1
@@ -1,16 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // @ts-nocheck
3
2
  import { useCallback, useContext, useMemo, useState, useEffect, useRef, } from 'react';
4
3
  import { ClientContext } from '../../Context';
5
4
  import { getDataFromCloud } from '../../utils/dataFetcher';
6
5
  import { PivotList, PivotCard } from './PivotList';
7
- import { differenceInDays, eachDayOfInterval, eachMonthOfInterval, eachWeekOfInterval, eachYearOfInterval, endOfDay, isWithinInterval, subMilliseconds, min, max, add, } from 'date-fns';
6
+ import { differenceInDays, eachDayOfInterval, eachMonthOfInterval, eachWeekOfInterval, eachYearOfInterval, endOfDay, isWithinInterval, subMilliseconds, add, } from 'date-fns';
8
7
  import { valueFormatter } from '../../utils/valueFormatter';
9
8
  import { numberFormatOptions, dateFormatOptions } from '../../ChartBuilder';
10
9
  import { snakeCaseToTitleCase } from '../../utils/textProcessing';
11
- import { isIdColumn } from '../../components/ReportBuilder/util';
12
- import { isNumericColumnType } from '../../components/ReportBuilder/ast';
10
+ import { QuillErrorMessageComponent, QuillPivotColumnContainer, QuillPivotRowContainer, } from '../../components/UiComponents';
11
+ import { isNumericColumnType, isTextColumnType, } from '../../components/ReportBuilder/ast';
13
12
  import { QuillCard } from '../../components/QuillCard';
13
+ import { cleanPivot, getPossiblePivotFieldOptions, isValidPivot, } from '../../utils/pivotProcessing';
14
+ import { hashCode } from '../../utils/crypto';
15
+ import { getUniqueValuesByColumns } from '../../utils/tableProcessing';
14
16
  const QuillHover = () => {
15
17
  return (_jsx("style", { children: `
16
18
  .quill-hover {
@@ -24,57 +26,153 @@ const QuillHover = () => {
24
26
  }
25
27
  ` }));
26
28
  };
27
- export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivotColumnField, pivotValueField, setPivotValueField, pivotAggregation, setPivotAggregation, popUpTitle, setPopUpTitle, selectedTable, SelectComponent, ButtonComponent, SecondaryButtonComponent, PopoverComponent, CardComponent = 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, selectPivotOnEdit = false, showTrigger = true, rightAlign = false, parentRef, recommendPivotCount = 6, }) => {
29
+ export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField, setPivotColumnField, pivotValueField, setPivotValueField, pivotAggregation, setPivotAggregation, popUpTitle, setPopUpTitle, selectedTable, SelectComponent, ButtonComponent, SecondaryButtonComponent, PopoverComponent, ErrorMessageComponent = QuillErrorMessageComponent, PivotRowContainer = QuillPivotRowContainer, PivotColumnContainer = QuillPivotColumnContainer, CardComponent = 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, selectPivotOnEdit = false, showTrigger = true, rightAlign = false, parentRef, pivotCountRequest = 6, query, initialUniqueValues, initialSelectedPivotTable, disabled = false, pivotRecommendationsEnabled = true, }) => {
28
30
  const [isLoading, setIsLoading] = useState(false);
29
- const [pivotUpdateIndex, setPivotUpdateIndex] = useState(null);
30
31
  const [selectedPivotType, setSelectedPivotType] = useState('recommended');
31
32
  const [errors, setErrors] = useState([]);
32
33
  const [client] = useContext(ClientContext);
34
+ const rowFieldRef = useRef(null);
35
+ const colFieldRef = useRef(null);
36
+ const [pivotCardWidth, setPivotCardWidth] = useState(420);
33
37
  const [divWidth, setDivWidth] = useState(0);
34
- const editModalRef = useRef();
35
- const calculateWidth = () => {
36
- return editModalRef.current.offsetWidth;
38
+ const [samplePivotTable, setSamplePivotTable] = useState(null);
39
+ const [allowedColumnFields, setAllowedColumnFields] = useState([]);
40
+ const [allowedRowFields, setAllowedRowFields] = useState([]);
41
+ const [allowedValueFields, setAllowedValueFields] = useState([]);
42
+ const [uniqueValues, setUniqueValues] = useState(initialUniqueValues);
43
+ const getDistinctValues = async () => {
44
+ if (columns) {
45
+ const stringColumns = columns.filter((column) => {
46
+ return isTextColumnType(column.fieldType || column.format);
47
+ });
48
+ if (stringColumns.length === 0) {
49
+ const possibleColumns = getPossiblePivotFieldOptions(columns, {});
50
+ setAllowedRowFields(possibleColumns.rowFields);
51
+ setAllowedColumnFields(possibleColumns.columnFields);
52
+ setAllowedValueFields(possibleColumns.valueFields);
53
+ return possibleColumns;
54
+ }
55
+ const newUniqueValues = await getUniqueValuesByColumns(stringColumns, query || '', data.rows || [], client);
56
+ if (!uniqueValues ||
57
+ hashCode(uniqueValues) !== hashCode(newUniqueValues)) {
58
+ const possibleColumns = getPossiblePivotFieldOptions(columns, newUniqueValues || {});
59
+ setAllowedRowFields(possibleColumns.rowFields);
60
+ setAllowedColumnFields(possibleColumns.columnFields);
61
+ setAllowedValueFields(possibleColumns.valueFields);
62
+ setUniqueValues(newUniqueValues);
63
+ return possibleColumns;
64
+ }
65
+ }
66
+ return { rowFields: [], columnFields: [], valueFields: [] };
37
67
  };
38
68
  useEffect(() => {
39
- // Measure the width of the div and update state
40
- if (editModalRef.current) {
41
- setDivWidth(calculateWidth());
42
- }
43
- // Optional: Handle window resize
44
- const handleResize = () => {
45
- if (editModalRef.current) {
46
- setDivWidth(calculateWidth());
69
+ const calculatePivotCardSize = () => {
70
+ // The pivot card should be the same width as the row of inputs
71
+ // below it (two selects, plus the gap between them).
72
+ if (rowFieldRef.current && colFieldRef.current) {
73
+ const rowFieldSize = rowFieldRef.current?.getBoundingClientRect();
74
+ const colFieldSize = colFieldRef.current?.getBoundingClientRect();
75
+ const selectWidth = rowFieldSize.width;
76
+ const gap = colFieldSize.left - rowFieldSize.right;
77
+ const width = 2 * selectWidth + gap;
78
+ setPivotCardWidth(width);
47
79
  }
48
80
  };
49
- window.addEventListener('resize', handleResize);
50
- // Cleanup listener
51
- return () => {
52
- window.removeEventListener('resize', handleResize);
53
- };
81
+ setTimeout(() => {
82
+ calculatePivotCardSize();
83
+ }, 300);
84
+ }, [showUpdatePivot, isOpen]);
85
+ useEffect(() => {
86
+ if (pivotRowField && data && columns) {
87
+ const pivot = {
88
+ rowField: pivotRowField || '',
89
+ rowFieldType: columnsToShow[pivotRowField || ''],
90
+ columnField: pivotColumnField,
91
+ columnFieldType: columnsToShow[pivotColumnField || ''],
92
+ valueField: pivotValueField || '',
93
+ aggregationType: pivotAggregation || '',
94
+ };
95
+ const { rows, columns } = generatePivotTable(pivot, data, dateRange, false);
96
+ setSamplePivotTable({ pivot: pivot, rows, columns });
97
+ }
98
+ if ((pivotRowField && data && columns) || initialSelectedPivotTable) {
99
+ getDistinctValues();
100
+ }
101
+ if (initialUniqueValues) {
102
+ const possibleColumns = getPossiblePivotFieldOptions(columns, initialUniqueValues);
103
+ setAllowedRowFields(possibleColumns.rowFields);
104
+ setAllowedColumnFields(possibleColumns.columnFields);
105
+ setAllowedValueFields(possibleColumns.valueFields);
106
+ setUniqueValues(initialUniqueValues);
107
+ }
108
+ if (pivotRowField && data && columns) {
109
+ const pivot = {
110
+ rowField: pivotRowField || '',
111
+ rowFieldType: columnsToShow[pivotRowField || ''],
112
+ columnField: pivotColumnField,
113
+ columnFieldType: columnsToShow[pivotColumnField || ''],
114
+ valueField: pivotValueField || '',
115
+ aggregationType: pivotAggregation || '',
116
+ };
117
+ if (initialSelectedPivotTable) {
118
+ setSamplePivotTable({
119
+ pivot: pivot,
120
+ rows: initialSelectedPivotTable.rows,
121
+ columns: initialSelectedPivotTable.columns,
122
+ });
123
+ }
124
+ else {
125
+ const { rows, columns } = generatePivotTable(pivot, data, dateRange, false);
126
+ setSamplePivotTable({ pivot: pivot, rows, columns });
127
+ }
128
+ }
54
129
  }, []);
55
130
  useEffect(() => {
56
- // Measure the width of the div and update state
57
- if (editModalRef.current) {
58
- setDivWidth(calculateWidth());
131
+ const pivot = {
132
+ rowField: pivotRowField || '',
133
+ rowFieldType: columnsToShow[pivotRowField || ''],
134
+ columnField: pivotColumnField,
135
+ columnFieldType: columnsToShow[pivotColumnField || ''],
136
+ valueField: pivotValueField || '',
137
+ aggregationType: pivotAggregation || '',
138
+ };
139
+ if (isValidPivot(pivot) && data && columns) {
140
+ const { rows, columns } = generatePivotTable(pivot, data, dateRange, false);
141
+ setSamplePivotTable({ pivot: pivot, rows, columns });
59
142
  }
60
- }, [editModalRef.current, showUpdatePivot]);
143
+ }, [
144
+ data,
145
+ columns,
146
+ pivotRowField,
147
+ pivotColumnField,
148
+ pivotValueField,
149
+ pivotAggregation,
150
+ ]);
61
151
  useEffect(() => {
62
152
  setSelectedPivotIndex(-1);
63
- setPivotUpdateIndex(null);
64
- setSelectedPivotType(undefined);
153
+ setSelectedPivotType('');
65
154
  setPivotRowField(undefined);
66
155
  setPivotColumnField(undefined);
67
156
  setPivotValueField(undefined);
68
157
  setPivotAggregation(undefined);
69
- setIsOpen(false);
70
158
  setErrors([]);
71
159
  }, [selectedTable]);
160
+ useEffect(() => {
161
+ if (!initialUniqueValues) {
162
+ return;
163
+ }
164
+ const possibleColumns = getPossiblePivotFieldOptions(columns, initialUniqueValues);
165
+ setAllowedRowFields(possibleColumns.rowFields);
166
+ setAllowedColumnFields(possibleColumns.columnFields);
167
+ setAllowedValueFields(possibleColumns.valueFields);
168
+ setUniqueValues(initialUniqueValues);
169
+ }, [initialUniqueValues, columns]);
72
170
  const columnsToShow = useMemo(() => {
73
171
  return (columns || []).reduce((map, col) => {
74
172
  // only use columns shown in the report builder's table
75
173
  // also filter out id
76
174
  if (col.field !== 'id') {
77
- map[col.field] = col.fieldType || col.format;
175
+ map[col.field] = col.format;
78
176
  }
79
177
  return map;
80
178
  }, {});
@@ -84,20 +182,13 @@ export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField,
84
182
  return null;
85
183
  }
86
184
  const pivot = createdPivots[selectedPivotIndex];
87
- const { rows, columns } = generatePivotTable(pivot, data, dateRange);
185
+ const { rows, columns } = generatePivotTable(pivot, data, dateRange, false);
88
186
  return {
89
187
  pivot: pivot,
90
188
  rows: rows,
91
189
  columns: columns,
92
190
  };
93
191
  }, [selectedPivotIndex, data, dateRange, createdPivots]);
94
- const columnSelectOptions = useMemo(() => {
95
- return [
96
- ...Object.keys(columnsToShow).map((key) => {
97
- return { label: snakeCaseToTitleCase(key), value: key };
98
- }),
99
- ];
100
- }, [columnsToShow]);
101
192
  const onSelectRecommendedPivot = (pivot, index) => {
102
193
  if (showEditOnPivotClick) {
103
194
  onEditPivot(pivot, index);
@@ -116,28 +207,47 @@ export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField,
116
207
  selectPivot(pivot);
117
208
  setSelectedPivotType('created');
118
209
  setIsOpen(false);
119
- setPopUpTitle('Add Pivot');
210
+ setPopUpTitle('Add pivot');
120
211
  };
121
212
  const onEditPivot = (pivot, index) => {
122
213
  setPivotRowField(pivot.rowField);
123
214
  setPivotColumnField(pivot.columnField);
124
215
  setPivotValueField(pivot.valueField);
125
216
  setPivotAggregation(pivot.aggregationType);
126
- setPivotUpdateIndex(index);
127
217
  setShowUpdatePivot(true);
218
+ if (isValidPivot(pivot)) {
219
+ const { rows, columns } = generatePivotTable(pivot, data, dateRange, false);
220
+ setSamplePivotTable({ pivot, rows, columns });
221
+ return;
222
+ }
223
+ setSamplePivotTable(null);
128
224
  };
129
225
  const onEditRecommendedPivot = (pivot, index) => {
130
226
  onEditPivot(pivot, null);
131
227
  };
132
228
  const refreshPivots = useCallback(async () => {
133
- if (!showTrigger) {
134
- return;
135
- }
136
- if (isLoading || Object.keys(columnsToShow).length === 0) {
229
+ if (isLoading ||
230
+ Object.keys(columnsToShow).length === 0 ||
231
+ !pivotRecommendationsEnabled) {
137
232
  return;
138
233
  }
139
234
  setIsLoading(true);
235
+ let possibleColumns = {
236
+ rowFields: allowedRowFields,
237
+ columnFields: allowedColumnFields,
238
+ valueFields: allowedValueFields,
239
+ };
240
+ if ((allowedRowFields.length === 0 &&
241
+ allowedColumnFields.length === 0 &&
242
+ allowedValueFields.length === 0) ||
243
+ !uniqueValues) {
244
+ possibleColumns = await getDistinctValues();
245
+ }
140
246
  const cloudBody = {
247
+ pivotCountRequest,
248
+ allowedRowFields: possibleColumns?.rowFields || [],
249
+ allowedColumnFields: possibleColumns?.columnFields || [],
250
+ allowedValueFields: possibleColumns?.valueFields || [],
141
251
  tableSchema: Object.keys(columnsToShow).reduce(function (map, col) {
142
252
  // stop ai from seeing date fields. this is meant to stop the ai
143
253
  // pivot tables from extracting month and year from the date
@@ -150,11 +260,10 @@ export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField,
150
260
  };
151
261
  try {
152
262
  const resp = await getDataFromCloud(client, 'pivotai', cloudBody);
153
- const recommendedPivots = resp?.data?.pivotTables.slice(0, recommendPivotCount) || [];
154
- setRecommendedPivots(recommendedPivots
155
- .filter((pivot) => pivot.rowField != '')
156
- .map((pivot) => {
157
- if (columnsToShow[pivot.columnField] === 'date') {
263
+ const recommendedPivots = resp?.data?.pivotTables.map((pivot) => cleanPivot(pivot, possibleColumns)) || [];
264
+ setRecommendedPivots(recommendedPivots.map((pivot) => {
265
+ if (pivot.columnField &&
266
+ columnsToShow[pivot.columnField] === 'date') {
158
267
  const columnField = pivot.columnField;
159
268
  pivot.columnField = pivot.rowField;
160
269
  pivot.rowField = columnField;
@@ -162,57 +271,71 @@ export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField,
162
271
  return {
163
272
  ...pivot,
164
273
  rowFieldType: columnsToShow[pivot.rowField],
165
- columnFieldType: columnsToShow[pivot.columnField],
274
+ columnFieldType: pivot.columnField
275
+ ? columnsToShow[pivot.columnField]
276
+ : undefined,
277
+ title: generatePivotTitle(pivot),
166
278
  };
167
279
  }));
168
- // refreshing means the currently selected pivot doesn't exist in the options anymore
169
280
  setSelectedPivotIndex(-1);
170
281
  }
171
282
  catch (e) {
172
283
  console.error('Failed parsing pivotai response', e);
173
284
  }
174
285
  setIsLoading(false);
175
- }, [selectedTable, data, columnsToShow, isLoading, showTrigger]);
176
- useEffect(() => {
177
- if (recommendedPivots.length === 0) {
178
- refreshPivots();
286
+ }, [
287
+ selectedTable,
288
+ data,
289
+ columnsToShow,
290
+ isLoading,
291
+ showTrigger,
292
+ allowedColumnFields,
293
+ allowedRowFields,
294
+ allowedValueFields,
295
+ ]);
296
+ const pivotFieldChange = async (field, value) => {
297
+ setIsLoading(true);
298
+ const pivot = {
299
+ rowField: pivotRowField,
300
+ rowFieldType: columnsToShow[pivotRowField],
301
+ columnField: pivotColumnField,
302
+ valueField: pivotValueField,
303
+ aggregationType: pivotAggregation,
304
+ };
305
+ // @ts-ignore
306
+ pivot[field] = value;
307
+ pivot.title = generatePivotTitle(pivot);
308
+ if (field === 'rowField') {
309
+ pivot.rowFieldType = columnsToShow[value];
179
310
  }
180
- }, []);
311
+ else if (field === 'columnField') {
312
+ pivot.columnFieldType = columnsToShow[value];
313
+ }
314
+ if (!isValidPivot(pivot)) {
315
+ setIsLoading(false);
316
+ setSamplePivotTable(null);
317
+ return;
318
+ }
319
+ setTimeout(() => {
320
+ const { rows, columns } = generatePivotTable(pivot, data, dateRange, false);
321
+ setSamplePivotTable({ pivot, rows, columns });
322
+ setIsLoading(false);
323
+ }, 500);
324
+ };
181
325
  const recommendedPivotTables = useMemo(() => {
182
326
  const pts = recommendedPivots.map((p) => {
183
- const { rows, columns } = generatePivotTable(p, data, dateRange, 6);
327
+ const { rows, columns } = generatePivotTable(p, data, dateRange, false, 6);
184
328
  return { pivot: p, rows, columns };
185
329
  });
186
330
  return pts;
187
331
  }, [recommendedPivots, data]);
188
332
  const createdPivotTables = useMemo(() => {
189
333
  const pts = createdPivots.map((p) => {
190
- const { rows, columns } = generatePivotTable(p, data, dateRange, 6);
334
+ const { rows, columns } = generatePivotTable(p, data, dateRange, false, 6);
191
335
  return { pivot: p, rows, columns };
192
336
  });
193
337
  return pts;
194
338
  }, [createdPivots, data]);
195
- const samplePivotTable = useMemo(() => {
196
- if (!pivotAggregation) {
197
- return null;
198
- }
199
- const pivot = {
200
- rowField: pivotRowField || '',
201
- rowFieldType: columnsToShow[pivotRowField || ''],
202
- columnField: pivotColumnField,
203
- columnFieldType: columnsToShow[pivotColumnField || ''],
204
- valueField: pivotValueField || '',
205
- aggregationType: pivotAggregation || '',
206
- };
207
- const { rows, columns } = generatePivotTable(pivot, data, dateRange);
208
- return { pivot: pivot, rows, columns };
209
- }, [
210
- pivotAggregation,
211
- pivotValueField,
212
- pivotRowField,
213
- pivotColumnField,
214
- columnsToShow,
215
- ]);
216
339
  return (_jsx("div", { style: { display: 'flex', flexDirection: 'column' }, children: _jsxs("div", { style: {
217
340
  position: 'relative',
218
341
  display: 'inline-block',
@@ -229,7 +352,7 @@ export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField,
229
352
  position: 'absolute',
230
353
  top: -2,
231
354
  right: -2,
232
- } })) }), showTrigger && (_jsx(SecondaryButtonComponent, { onClick: () => {
355
+ } })) }), showTrigger && (_jsx(SecondaryButtonComponent, { disabled: disabled, onClick: () => {
233
356
  if (columns.length === 0) {
234
357
  setIsOpen(false);
235
358
  }
@@ -242,149 +365,26 @@ export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField,
242
365
  }
243
366
  setIsOpen(!isOpen);
244
367
  setShowUpdatePivot(false);
245
- }, label: triggerButtonText })), _jsx(PopoverComponent, { isOpen: isOpen, setIsOpen: (isOpen) => {
246
- if (!isOpen) {
247
- setShowUpdatePivot(false);
248
- setPopUpTitle('Add Pivot');
249
- }
250
- setIsOpen(isOpen);
251
- }, popoverTitle: showUpdatePivot ? popUpTitle : 'Recommended pivots', popoverChildren: _jsx("div", { style: {
252
- paddingTop: showUpdatePivot ? 0 : 20,
253
- position: 'relative',
254
- }, children: showUpdatePivot ? (_jsxs("div", { className: "ref-in-use", ref: editModalRef, style: {
255
- backgroundColor: 'rgb(255, 255, 255)',
256
- display: 'flex',
257
- flexDirection: 'column',
258
- }, children: [_jsx("div", { style: { height: 12 } }), _jsx("div", { style: { width: divWidth }, children: samplePivotTable && (_jsx("div", { style: {
259
- marginBottom: 20,
260
- minHeight: 160,
261
- }, children: _jsx(PivotCard, { pivotTable: samplePivotTable, theme: theme, index: 0, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: ButtonComponent, showEdit: false, clickable: false, minHeight: 140, LabelComponent: LabelComponent, TextComponent: TextComponent, HeaderComponent: HeaderComponent, CardComponent: CardComponent }) })) }), _jsxs("div", { style: {
262
- display: 'flex',
263
- flexDirection: 'column',
264
- gap: 10,
265
- alignItems: 'center',
266
- justifyContent: 'space-between',
267
- }, children: [_jsxs("div", { style: {
268
- display: 'flex',
269
- flexDirection: 'row',
270
- gap: 20,
271
- marginBottom: 5,
272
- }, children: [_jsxs("div", { children: [_jsx(LabelComponent, { label: "Row Field" }), _jsx(SelectComponent, { id: "pivot-row-field", value: pivotRowField, onChange: (e) => {
273
- setPivotRowField(e.target.value === ''
274
- ? undefined
275
- : e.target.value);
276
- }, options: [
277
- ...columnSelectOptions.filter((option) => {
278
- const format = columns.find((col) => col.field === option.value)?.format;
279
- return (format === 'string' ||
280
- dateFormatOptions.includes(format) ||
281
- isIdColumn(option.value));
282
- }),
283
- ], width: 200 })] }), _jsxs("div", { children: [_jsx(LabelComponent, { label: "Column Field" }), _jsx(SelectComponent, { id: "pivot-row-field", value: pivotColumnField, onChange: (e) => {
284
- setPivotColumnField(e.target.value === ''
285
- ? undefined
286
- : e.target.value);
287
- }, options: [
288
- ...columnSelectOptions.filter((option) => {
289
- return (columns.find((col) => col.field === option.value)?.format === 'string');
290
- }),
291
- ], width: 200 })] })] }), _jsxs("div", { style: {
292
- display: 'flex',
293
- flexDirection: 'row',
294
- gap: 20,
295
- marginBottom: 20,
296
- }, children: [_jsxs("div", { children: [_jsx(LabelComponent, { label: "Value Field" }), _jsx(SelectComponent, { id: "pivot-row-field", value: pivotValueField, onChange: (e) => {
297
- setPivotValueField(e.target.value === ''
298
- ? undefined
299
- : e.target.value);
300
- }, options: [
301
- ...columnSelectOptions.filter((option) => {
302
- return ((option.value === '' ||
303
- numberFormatOptions.includes(columns.find((col) => col.field === option.value)?.format)) &&
304
- !isIdColumn(option.value));
305
- }),
306
- ], width: 200 })] }), _jsxs("div", { children: [_jsx(LabelComponent, { label: "Aggregation Type" }), _jsx(SelectComponent, { id: "pivot-row-field", value: pivotAggregation, onChange: (e) => {
307
- if (e.target.value !== 'count' &&
308
- pivotValueField &&
309
- !numberFormatOptions.includes(columns.find((col) => col.field === pivotValueField)?.format)) {
310
- setPivotValueField(null);
311
- }
312
- setPivotAggregation(e.target.value === ''
313
- ? undefined
314
- : e.target.value);
315
- }, options: [
316
- ...['sum', 'average', 'count', 'max', 'min'].map((option) => {
317
- return { label: option, value: option };
318
- }),
319
- ], width: 200 })] })] })] }), _jsx("div", { children: _jsx(ButtonComponent, { id: "custom-button", onClick: () => {
320
- const errors = [];
321
- if (!pivotValueField && pivotAggregation !== 'count') {
322
- errors.push("Value field cannot be empty when aggregation is not 'count'");
323
- }
324
- if (!pivotAggregation) {
325
- errors.push('Aggregation cannot be empty');
326
- }
327
- if (errors.length === 0) {
328
- const pivot = {
329
- rowField: pivotRowField || '',
330
- rowFieldType: columnsToShow[pivotRowField || ''],
331
- columnField: pivotColumnField,
332
- columnFieldType: columnsToShow[pivotColumnField || ''],
333
- valueField: pivotValueField || '',
334
- aggregationType: pivotAggregation || '',
335
- };
336
- pivot.title = generatePivotTitle(pivot);
337
- setIsOpen(false);
338
- setCreatedPivots([pivot]);
339
- onSelectCreatedPivot(pivot, 0);
340
- setPopUpTitle('Add Pivot');
341
- }
342
- setErrors(errors);
343
- }, label: popUpTitle }) }), _jsx("div", { children: errors.length > 0 && (_jsxs("div", { children: [_jsx("div", { style: {
344
- paddingTop: '8px',
345
- } }), errors.map((error, index) => (_jsx("div", { style: {
346
- borderRadius: 8,
347
- backgroundColor: '#FF9494',
348
- paddingLeft: '12px',
349
- paddingRight: '8px',
350
- height: 30,
351
- display: 'flex',
352
- alignItems: 'center',
353
- fontSize: 13,
354
- fontWeight: 'bold',
355
- fontFamily: theme?.fontFamily,
356
- color: 'white',
357
- marginBottom: 5,
358
- }, children: error }, index)))] })) })] })) : (_jsx("div", { style: {
359
- display: 'flex',
360
- flexDirection: 'column',
361
- fontFamily: theme?.fontFamily,
362
- color: theme?.primaryTextColor,
363
- width: selectedPivotTable ? 500 : 600,
364
- maxHeight: 600,
365
- overflowY: 'scroll',
366
- }, children: selectedPivotIndex >= 0 ? (_jsx("div", { children: _jsx("div", { onClick: () => {
367
- setPopUpTitle('Edit Pivot');
368
- onEditPivot(createdPivots[0], 0);
369
- }, children: _jsx(PivotCard, { pivotTable: {
370
- pivot: selectedPivotTable?.pivot,
371
- rows: selectedPivotTable?.rows,
372
- columns: selectedPivotTable?.columns,
373
- }, theme: theme, index: 0, onSelectPivot: () => { }, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: ButtonComponent, showEdit: false, onClose: () => {
374
- removePivot();
375
- }, clickable: true, minHeight: 180, CardComponent: CardComponent, LabelComponent: LabelComponent, TextComponent: TextComponent, HeaderComponent: HeaderComponent }) }) })) : (_jsxs("div", { style: { display: 'flex', flexDirection: 'column' }, children: [_jsx("div", { style: {
376
- // position button inline with the popover title
377
- position: 'absolute',
378
- top: -36,
379
- right: 0,
380
- }, children: _jsx(SecondaryButtonComponent, { onClick: refreshPivots, label: _jsxs("div", { style: {
381
- display: 'flex',
382
- flexDirection: 'row',
383
- whiteSpace: 'nowrap',
384
- alignItems: 'center',
385
- gap: 6,
386
- fontSize: 14,
387
- }, children: [_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", style: { width: 16, height: 16 }, children: _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" }) }), "Regenerate"] }) }) }), isLoading ? (_jsxs("div", { style: {
368
+ }, label: triggerButtonText })), _jsx("div", { style: {
369
+ position: 'relative',
370
+ ...(isOpen && showTrigger && { top: 12 }),
371
+ }, children: _jsx(PopoverComponent, { isOpen: isOpen, setIsOpen: (isOpen) => {
372
+ if (!isOpen) {
373
+ setShowUpdatePivot(false);
374
+ setPopUpTitle('Add pivot');
375
+ }
376
+ setIsOpen(isOpen);
377
+ }, popoverTitle: showUpdatePivot || !pivotRecommendationsEnabled
378
+ ? popUpTitle
379
+ : 'Recommended pivots', popoverChildren: _jsx("div", { style: {
380
+ paddingTop: showUpdatePivot || !pivotRecommendationsEnabled ? 0 : 20,
381
+ position: 'relative',
382
+ }, children: showUpdatePivot || !pivotRecommendationsEnabled ? (_jsxs("div", { style: {
383
+ backgroundColor: 'rgb(255, 255, 255)',
384
+ display: 'flex',
385
+ flexDirection: 'column',
386
+ gap: 20,
387
+ }, children: [isLoading && (_jsxs("div", { style: {
388
388
  background: theme.backgroundColor,
389
389
  width: 250,
390
390
  minWidth: 250,
@@ -395,7 +395,128 @@ export const PivotModal = ({ pivotRowField, setPivotRowField, pivotColumnField,
395
395
  display: 'flex',
396
396
  margin: '0px auto',
397
397
  justifyContent: 'center',
398
- }, children: [_jsx("div", { style: { height: 100 } }), _jsxs("svg", { width: "24", height: "24", children: [_jsx("circle", { cx: "12", cy: "12", r: "9.375", strokeWidth: "3.75", strokeDasharray: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 2 / 3)", strokeDashoffset: "calc(2 * 3.14 * 9.375 / 6)", stroke: theme?.primaryTextColor || '#364153', fill: "none", transform: "rotate(-90 12 12)", children: _jsx("animateTransform", { attributeName: "transform", attributeType: "XML", type: "rotate", from: "-180 12 12", to: "180 12 12", dur: "0.8s", repeatCount: "indefinite" }) }), _jsx("circle", { cx: "12", cy: "12", r: "9.375", strokeWidth: "3.75", strokeDasharray: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 1 / 3)", strokeDashoffset: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 2 / 3)", stroke: '#ADB1B9', fill: "none", transform: "rotate(90 12 12)", children: _jsx("animateTransform", { attributeName: "transform", attributeType: "XML", type: "rotate", from: "0 12 12", to: "360 12 12", dur: "0.8s", repeatCount: "indefinite" }) })] })] })) : (_jsx("div", { children: _jsx(PivotList, { recommendedPivotTables: recommendedPivotTables, createdPivotTables: createdPivotTables, theme: theme, onSelectRecommendedPivot: onSelectRecommendedPivot, onSelectCreatedPivot: onSelectCreatedPivot, selectedPivotIndex: selectedPivotIndex, selectedPivotType: selectedPivotType, ButtonComponent: ButtonComponent, HeaderComponent: HeaderComponent, onEditRecommendedPivot: onEditRecommendedPivot, onEditCreatedPivot: onEditPivot, showCreatePivot: true, showPivotEditButton: showPivotEditButton, LabelComponent: LabelComponent, TextComponent: TextComponent, CardComponent: CardComponent }) }))] })) })) }) })] }) }));
398
+ }, children: [_jsx("div", { style: { height: 100 } }), _jsxs("svg", { width: "24", height: "24", children: [_jsx("circle", { cx: "12", cy: "12", r: "9.375", strokeWidth: "3.75", strokeDasharray: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 2 / 3)", strokeDashoffset: "calc(2 * 3.14 * 9.375 / 6)", stroke: theme?.primaryTextColor || '#364153', fill: "none", transform: "rotate(-90 12 12)", children: _jsx("animateTransform", { attributeName: "transform", attributeType: "XML", type: "rotate", from: "-180 12 12", to: "180 12 12", dur: "0.8s", repeatCount: "indefinite" }) }), _jsx("circle", { cx: "12", cy: "12", r: "9.375", strokeWidth: "3.75", strokeDasharray: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 1 / 3)", strokeDashoffset: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 2 / 3)", stroke: '#ADB1B9', fill: "none", transform: "rotate(90 12 12)", children: _jsx("animateTransform", { attributeName: "transform", attributeType: "XML", type: "rotate", from: "0 12 12", to: "360 12 12", dur: "0.8s", repeatCount: "indefinite" }) })] })] })), samplePivotTable && !isLoading && (_jsx("div", { style: {
399
+ width: pivotCardWidth,
400
+ minHeight: 160,
401
+ }, children: _jsx(PivotCard, { pivotTable: samplePivotTable, theme: theme, index: 0, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: ButtonComponent, showEdit: false, clickable: false, minHeight: 140, LabelComponent: LabelComponent, TextComponent: TextComponent, HeaderComponent: HeaderComponent, CardComponent: CardComponent, onSelectPivot: () => { }, onClose: () => {
402
+ setPivotAggregation(null);
403
+ setPivotRowField(null);
404
+ setPivotValueField(null);
405
+ setPivotColumnField(null);
406
+ setSamplePivotTable(null);
407
+ } }) })), _jsxs(PivotColumnContainer, { children: [_jsxs(PivotRowContainer, { children: [_jsx("div", { ref: rowFieldRef, children: _jsx(SelectComponent, { id: "pivot-row-field", label: "Row field", value: pivotRowField, onChange: (e) => {
408
+ pivotFieldChange('rowField', e.target.value);
409
+ setPivotRowField(e.target.value === ''
410
+ ? undefined
411
+ : e.target.value);
412
+ }, options: allowedRowFields.map((field) => {
413
+ return {
414
+ label: snakeCaseToTitleCase(field),
415
+ value: field,
416
+ };
417
+ }), width: 200 }) }), _jsx("div", { ref: colFieldRef, children: _jsx(SelectComponent, { id: "pivot-row-field", label: "Column field", value: pivotColumnField, onChange: (e) => {
418
+ pivotFieldChange('columnField', e.target.value);
419
+ setPivotColumnField(e.target.value === ''
420
+ ? undefined
421
+ : e.target.value);
422
+ }, options: allowedColumnFields.map((field) => {
423
+ return {
424
+ label: snakeCaseToTitleCase(field),
425
+ value: field,
426
+ };
427
+ }), width: 200 }) })] }), _jsxs(PivotRowContainer, { children: [_jsx(SelectComponent, { id: "pivot-row-field", label: "Value field", value: pivotValueField, onChange: (e) => {
428
+ pivotFieldChange('valueField', e.target.value);
429
+ setPivotValueField(e.target.value === ''
430
+ ? undefined
431
+ : e.target.value);
432
+ }, options: allowedValueFields.map((field) => {
433
+ return {
434
+ label: snakeCaseToTitleCase(field),
435
+ value: field,
436
+ };
437
+ }), width: 200 }), _jsx(SelectComponent, { id: "pivot-row-field", label: "Aggregation type", value: pivotAggregation, onChange: (e) => {
438
+ if (e.target.value !== 'count' &&
439
+ pivotValueField &&
440
+ !numberFormatOptions.includes(columns.find((col) => col.field === pivotValueField)?.format)) {
441
+ setPivotValueField(null);
442
+ }
443
+ pivotFieldChange('aggregationType', e.target.value);
444
+ setPivotAggregation(e.target.value === ''
445
+ ? undefined
446
+ : e.target.value);
447
+ }, options: [
448
+ ...['sum', 'average', 'count', 'max', 'min'].map((option) => {
449
+ return { label: option, value: option };
450
+ }),
451
+ ], width: 200 })] })] }), _jsxs("div", { children: [_jsx(ButtonComponent, { id: "custom-button", onClick: () => {
452
+ const errors = [];
453
+ if (!pivotValueField &&
454
+ pivotAggregation !== 'count') {
455
+ errors.push("Value field cannot be empty when aggregation is not 'count'");
456
+ }
457
+ if (!pivotAggregation) {
458
+ errors.push('Aggregation cannot be empty');
459
+ }
460
+ if (errors.length === 0) {
461
+ const pivot = {
462
+ rowField: pivotRowField || '',
463
+ rowFieldType: columnsToShow[pivotRowField || ''],
464
+ columnField: pivotColumnField,
465
+ columnFieldType: columnsToShow[pivotColumnField || ''],
466
+ valueField: pivotValueField || '',
467
+ aggregationType: pivotAggregation || '',
468
+ };
469
+ pivot.title = generatePivotTitle(pivot);
470
+ setIsOpen(false);
471
+ setCreatedPivots([pivot]);
472
+ onSelectCreatedPivot(pivot, 0);
473
+ setPopUpTitle('Add pivot');
474
+ }
475
+ setErrors(errors);
476
+ }, label: popUpTitle }), errors.length > 0 && (_jsx("div", { style: {
477
+ display: 'flex',
478
+ flexDirection: 'column',
479
+ gap: 8,
480
+ paddingTop: 8,
481
+ width: pivotCardWidth,
482
+ maxWidth: pivotCardWidth,
483
+ }, children: errors.map((error, index) => (_jsx(ErrorMessageComponent, { errorMessage: error }, `error_message_${index}`))) }))] })] })) : (_jsx("div", { style: {
484
+ display: 'flex',
485
+ flexDirection: 'column',
486
+ fontFamily: theme?.fontFamily,
487
+ color: theme?.primaryTextColor,
488
+ width: selectedPivotTable ? 500 : 600,
489
+ maxHeight: 600,
490
+ overflowY: 'scroll',
491
+ }, children: selectedPivotIndex >= 0 ? (_jsx("div", { children: _jsx("div", { onClick: () => {
492
+ setPopUpTitle('Edit pivot');
493
+ onEditPivot(createdPivots[0], 0);
494
+ }, children: _jsx(PivotCard, { pivotTable: {
495
+ pivot: selectedPivotTable?.pivot,
496
+ rows: selectedPivotTable?.rows,
497
+ columns: selectedPivotTable?.columns,
498
+ }, theme: theme, index: 0, onSelectPivot: () => { }, selectedPivotIndex: -1, onEditPivot: () => { }, ButtonComponent: ButtonComponent, showEdit: false, onClose: () => {
499
+ removePivot();
500
+ }, clickable: true, minHeight: 180, CardComponent: CardComponent, LabelComponent: LabelComponent, TextComponent: TextComponent, HeaderComponent: HeaderComponent }) }) })) : (_jsxs("div", { style: { display: 'flex', flexDirection: 'column' }, children: [_jsxs("div", { style: {
501
+ // position button inline with the popover title
502
+ position: 'absolute',
503
+ top: -36,
504
+ right: 0,
505
+ display: 'flex',
506
+ flexDirection: 'row',
507
+ gap: 8,
508
+ }, children: [_jsx(SecondaryButtonComponent, { label: "Regenerate", onClick: refreshPivots, icon: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", style: { width: 16, height: 16 }, children: _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" }) }) }), _jsx(SecondaryButtonComponent, { label: "Create pivot +", onClick: () => onEditPivot({}, null) })] }), isLoading ? (_jsxs("div", { style: {
509
+ background: theme.backgroundColor,
510
+ width: 250,
511
+ minWidth: 250,
512
+ height: '100%',
513
+ paddingLeft: 20,
514
+ paddingRight: 30,
515
+ paddingTop: 40,
516
+ display: 'flex',
517
+ margin: '0px auto',
518
+ justifyContent: 'center',
519
+ }, children: [_jsx("div", { style: { height: 100 } }), _jsxs("svg", { width: "24", height: "24", children: [_jsx("circle", { cx: "12", cy: "12", r: "9.375", strokeWidth: "3.75", strokeDasharray: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 2 / 3)", strokeDashoffset: "calc(2 * 3.14 * 9.375 / 6)", stroke: theme?.primaryTextColor || '#364153', fill: "none", transform: "rotate(-90 12 12)", children: _jsx("animateTransform", { attributeName: "transform", attributeType: "XML", type: "rotate", from: "-180 12 12", to: "180 12 12", dur: "0.8s", repeatCount: "indefinite" }) }), _jsx("circle", { cx: "12", cy: "12", r: "9.375", strokeWidth: "3.75", strokeDasharray: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 1 / 3)", strokeDashoffset: "calc(2 * 3.14 * 9.375 / 3) calc(2 * 3.14 * 9.375 * 2 / 3)", stroke: '#ADB1B9', fill: "none", transform: "rotate(90 12 12)", children: _jsx("animateTransform", { attributeName: "transform", attributeType: "XML", type: "rotate", from: "0 12 12", to: "360 12 12", dur: "0.8s", repeatCount: "indefinite" }) })] })] })) : (_jsx("div", { children: _jsx(PivotList, { recommendedPivotTables: recommendedPivotTables, createdPivotTables: createdPivotTables, theme: theme, onSelectRecommendedPivot: onSelectRecommendedPivot, onSelectCreatedPivot: onSelectCreatedPivot, selectedPivotIndex: selectedPivotIndex, selectedPivotType: selectedPivotType, ButtonComponent: ButtonComponent, HeaderComponent: HeaderComponent, onEditRecommendedPivot: onEditRecommendedPivot, onEditCreatedPivot: onEditPivot, showPivotEditButton: showPivotEditButton, LabelComponent: LabelComponent, TextComponent: TextComponent, CardComponent: CardComponent }) }))] })) })) }) }) })] }) }));
399
520
  };
400
521
  export function generatePivotTableYAxis(pivot, cols, format) {
401
522
  // Use the column field for the field and label if there is one
@@ -404,12 +525,9 @@ export function generatePivotTableYAxis(pivot, cols, format) {
404
525
  }
405
526
  // For count aggregations, use 'count' for the label
406
527
  if (pivot?.aggregationType === 'count') {
407
- return [{ field: pivot.valueField, label: 'count', format: format }];
408
- }
409
- // For average aggregations, use 'average <label>' for the label
410
- if (pivot?.aggregationType === 'average') {
411
- const label = `average ${pivot.valueField}`;
412
- return [{ field: pivot.valueField, label, format: format }];
528
+ return [
529
+ { field: pivot.valueField || 'count', label: 'count', format: format },
530
+ ];
413
531
  }
414
532
  // otherwise use the default (ie. the field label)
415
533
  return [
@@ -420,7 +538,15 @@ export function generatePivotTableYAxis(pivot, cols, format) {
420
538
  },
421
539
  ];
422
540
  }
423
- function generatePivotTitle(pivot) {
541
+ export function generatePivotTitle(pivot) {
542
+ if (pivot.rowField && !pivot.valueField) {
543
+ return snakeCaseToTitleCase(`${pivot.aggregationType} of ${pivot.rowField}
544
+ `);
545
+ }
546
+ else if (pivot.valueField && !pivot.rowField) {
547
+ return snakeCaseToTitleCase(`${pivot.aggregationType} of ${pivot.valueField}
548
+ `);
549
+ }
424
550
  return snakeCaseToTitleCase(`${pivot.aggregationType} of ${pivot.valueField} by ${pivot.rowField}${pivot.columnField ? ` and ${pivot.columnField}` : ''}`);
425
551
  }
426
552
  function castValueToDate(value) {
@@ -432,7 +558,17 @@ function castValueToDate(value) {
432
558
  }
433
559
  return new Date(value);
434
560
  }
561
+ function getRecentDate(a, b) {
562
+ return a > b ? a : b;
563
+ }
564
+ function getEarliestDate(a, b) {
565
+ return a < b ? a : b;
566
+ }
435
567
  function getDateRange(dateRange, column, data) {
568
+ const currentTime = new Date().getTime();
569
+ const ONE_CENTURY_IN_MILLISECONDS = 100 * 365 * 24 * 60 * 60 * 1000;
570
+ const maxDate = new Date(currentTime + ONE_CENTURY_IN_MILLISECONDS);
571
+ const minDate = new Date(0);
436
572
  if (!dateRange || !dateRange[0]) {
437
573
  if (data.length == 0 || !data[0][column]) {
438
574
  return { start: new Date(), end: new Date() };
@@ -449,12 +585,28 @@ function getDateRange(dateRange, column, data) {
449
585
  for (let i = 0; i < data.length; i++) {
450
586
  if (data[i][column]) {
451
587
  const value = castValueToDate(data[i][column]);
452
- lastestDate = lastestDate === null ? value : max([lastestDate, value]);
453
- earliestDate =
454
- earliestDate === null ? value : min([earliestDate, value]);
588
+ if (lastestDate && lastestDate > minDate) {
589
+ lastestDate = value;
590
+ }
591
+ if (value && value < maxDate) {
592
+ lastestDate =
593
+ lastestDate === null ? value : getRecentDate(lastestDate, value);
594
+ }
595
+ if (value && value > minDate) {
596
+ if (earliestDate && earliestDate < minDate) {
597
+ earliestDate = value;
598
+ }
599
+ earliestDate =
600
+ earliestDate === null
601
+ ? value
602
+ : getEarliestDate(earliestDate, value);
603
+ }
455
604
  }
456
605
  }
457
- return { start: earliestDate, end: lastestDate };
606
+ return {
607
+ start: earliestDate,
608
+ end: lastestDate,
609
+ };
458
610
  }
459
611
  else {
460
612
  return { start: dateRange[0], end: dateRange[1] };
@@ -511,6 +663,7 @@ function getDateString(value, dateRange) {
511
663
  return valueFormatter({
512
664
  value,
513
665
  field: 'date',
666
+ // @ts-ignore
514
667
  fields: [{ field: 'date', format }],
515
668
  });
516
669
  }
@@ -571,15 +724,12 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
571
724
  const uniqueRows = (isDateField(pivot.rowFieldType)
572
725
  ? getDateBuckets(dateRange, pivot.rowField, data)
573
726
  : [...new Set(data.map((item) => item[pivot.rowField]))]).filter((row) => Boolean(row));
574
- const rowDateRange = pivot.rowField
575
- ? getDateRange(dateRange, pivot.rowField, data)
576
- : null;
577
- const columnDateRange = pivot.columnField
578
- ? getDateRange(dateRange, pivot.columnField, data)
579
- : null;
727
+ const rowDateRange = getDateRange(dateRange, pivot.rowField, data);
728
+ const compRowDateRange = getDateRange(compRange ?? dateRange, pivot.rowField, data);
580
729
  // If columnField is not provided, we will not be using uniqueColumns
581
- const uniqueColumns = (pivot.columnField && pivot.columnField.trim()
582
- ? isDateField(pivot.columnFieldType)
730
+ // @ts-ignore
731
+ const uniqueColumns = (pivot.columnField
732
+ ? isDateField(pivot.columnFieldType || '')
583
733
  ? getDateBuckets(dateRange, pivot.columnField, data)
584
734
  : [...new Set(data.map((item) => item[pivot.columnField || '']))]
585
735
  : [pivot.valueField]).filter((col) => Boolean(col));
@@ -588,12 +738,11 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
588
738
  const ROW_DATE_MAP = {};
589
739
  // add in the comparison columns for all columns in the pivot
590
740
  let compUniqueRows = [];
591
- let compRowDateRange = [];
592
741
  if (isComparison) {
593
742
  if (pivot.columnField) {
594
743
  const col = pivot.columnField;
595
744
  const row = pivot.rowField;
596
- const isDateCol = isDateField(pivot.columnFieldType);
745
+ const isDateCol = isDateField(pivot.columnFieldType || '');
597
746
  const isDateRow = isDateField(pivot.rowFieldType);
598
747
  data.forEach((item) => {
599
748
  if (isDateCol) {
@@ -617,9 +766,15 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
617
766
  compUniqueRows = (isDateField(pivot.rowFieldType)
618
767
  ? getCompDateBuckets(dateRange, compRange ?? dateRange, pivot.rowField, data)
619
768
  : [...new Set(data.map((item) => item[pivot.rowField]))]).filter((row) => Boolean(row));
620
- compRowDateRange = pivot.rowField
621
- ? getDateRange(compRange ?? dateRange, pivot.rowField, data)
622
- : null;
769
+ }
770
+ // Special corner case for count with only rowField pivot
771
+ if (!pivot.valueField &&
772
+ !pivot.columnField &&
773
+ pivot.aggregationType === 'count') {
774
+ uniqueColumns.push('count');
775
+ if (isComparison) {
776
+ uniqueColumns.push('comparison_count');
777
+ }
623
778
  }
624
779
  const rowsToGenerate = rowLimit !== -1 && rowLimit <= uniqueRows.length
625
780
  ? uniqueRows.slice(0, rowLimit + 1)
@@ -642,18 +797,20 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
642
797
  let comparisonValue;
643
798
  let value;
644
799
  const nextRowValue = isDateField(pivot.rowFieldType)
645
- ? uniqueRows[rowIndex + 1] ?? endOfDay(rowDateRange.end)
800
+ ? // @ts-ignore
801
+ uniqueRows[rowIndex + 1] ?? endOfDay(rowDateRange.end)
646
802
  : null;
647
803
  const compRowValue = compUniqueRows[rowIndex];
648
804
  const compNextRowValue = isDateField(pivot.rowFieldType)
649
805
  ? compUniqueRows[rowIndex + 1] ?? endOfDay(compRowDateRange.end)
650
806
  : null;
651
807
  if (pivot.columnField) {
652
- const nextColumnValue = isDateField(pivot.columnFieldType)
808
+ const columnDateRange = getDateRange(dateRange, pivot.columnField, data);
809
+ const nextColumnValue = isDateField(pivot.columnFieldType || '')
653
810
  ? uniqueColumns[colIndex + 1] || endOfDay(columnDateRange.end)
654
811
  : null;
655
812
  // If columnField is provided, filter by both rowField and columnField
656
- if (isDateField(pivot.columnFieldType) &&
813
+ if (isDateField(pivot.columnFieldType || '') &&
657
814
  isDateField(pivot.rowFieldType)) {
658
815
  filteredData = data.filter((item) => {
659
816
  return (isWithinInterval(new Date(item[pivot.rowField]), {
@@ -678,7 +835,7 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
678
835
  });
679
836
  }
680
837
  }
681
- else if (isDateField(pivot.columnFieldType) &&
838
+ else if (isDateField(pivot.columnFieldType || '') &&
682
839
  !isDateField(pivot.rowFieldType)) {
683
840
  filteredData = data.filter((item) => {
684
841
  return (item[pivot.rowField] === rowValue &&
@@ -697,7 +854,7 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
697
854
  });
698
855
  }
699
856
  }
700
- else if (!isDateField(pivot.columnFieldType) &&
857
+ else if (!isDateField(pivot.columnFieldType || '') &&
701
858
  isDateField(pivot.rowFieldType)) {
702
859
  filteredData = data.filter((item) => {
703
860
  return (isWithinInterval(new Date(item[pivot.rowField]), {
@@ -783,15 +940,15 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
783
940
  }
784
941
  break;
785
942
  case 'max':
786
- value = filteredData.reduce((max, item) => Math.max(max, parseFloat(item[key] ?? 0)), -Infinity);
943
+ value = filteredData.reduce((max, item) => Math.max(max, parseFloat(item[key] ?? -Infinity)), -Infinity);
787
944
  if (isComparison) {
788
- comparisonValue = comparisonFilteredData.reduce((max, item) => Math.max(max, parseFloat(item[key] ?? 0)), -Infinity);
945
+ comparisonValue = comparisonFilteredData.reduce((max, item) => Math.max(max, parseFloat(item[key] ?? -Infinity)), -Infinity);
789
946
  }
790
947
  break;
791
948
  case 'min':
792
- value = filteredData.reduce((min, item) => Math.min(min, parseFloat(item[key] ?? 0)), Infinity);
949
+ value = filteredData.reduce((min, item) => Math.min(min, parseFloat(item[key] ?? Infinity)), Infinity);
793
950
  if (isComparison) {
794
- comparisonValue = comparisonFilteredData.reduce((min, item) => Math.min(min, parseFloat(item[key] ?? 0)), Infinity);
951
+ comparisonValue = comparisonFilteredData.reduce((min, item) => Math.min(min, parseFloat(item[key] ?? Infinity)), Infinity);
795
952
  }
796
953
  break;
797
954
  // Implement other aggregation types as needed
@@ -800,11 +957,11 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
800
957
  }
801
958
  // Set the value on the row
802
959
  // If columnField is not provided, colValue will be valueField
803
- row[isDateField(pivot.columnFieldType)
960
+ row[isDateField(pivot.columnFieldType || '')
804
961
  ? getDateString(colValue, dateRange)
805
962
  : colValue] = pivot.aggregationType === 'count' ? value : value.toFixed(2);
806
963
  if (isComparison && pivot.columnField) {
807
- if (isDateField(pivot.columnFieldType)) {
964
+ if (isDateField(pivot.columnFieldType || '')) {
808
965
  row[`comparison_${getDateString(colValue, dateRange)}`] =
809
966
  pivot.aggregationType === 'count'
810
967
  ? comparisonValue
@@ -822,15 +979,11 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
822
979
  });
823
980
  const columns = [
824
981
  {
825
- label: pivot.rowField === null
826
- ? 'Null'
827
- : pivot.rowField === false
828
- ? 'False'
829
- : snakeCaseToTitleCase(pivot.rowField),
982
+ label: pivot.rowField === null ? 'Null' : snakeCaseToTitleCase(pivot.rowField),
830
983
  field: pivot.rowField,
831
984
  },
832
985
  ...uniqueColumns.map((column, index) => {
833
- const columnName = isDateField(pivot.columnFieldType)
986
+ const columnName = isDateField(pivot.columnFieldType || '')
834
987
  ? getDateString(column, dateRange)
835
988
  : column;
836
989
  return {
@@ -848,7 +1001,7 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
848
1001
  }),
849
1002
  ...(isComparison && pivot.columnField
850
1003
  ? uniqueColumns.map((column, index) => {
851
- const columnName = isDateField(pivot.columnFieldType)
1004
+ const columnName = isDateField(pivot.columnFieldType || '')
852
1005
  ? getDateString(column, dateRange)
853
1006
  : column;
854
1007
  return {
@@ -860,10 +1013,10 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
860
1013
  !pivot.columnField &&
861
1014
  index === 1
862
1015
  ? 'Comparison Count'
863
- : isDateField(pivot.columnFieldType)
1016
+ : isDateField(pivot.columnFieldType || '')
864
1017
  ? COL_DATE_MAP[getDateString(column, dateRange)] ??
865
1018
  'Comparison'
866
- : `Comparison ${snakeCaseToTitleCase(columnName)}`,
1019
+ : `comparison ${snakeCaseToTitleCase(columnName)}`,
867
1020
  field: `comparison_${columnName}`,
868
1021
  };
869
1022
  })
@@ -872,22 +1025,24 @@ export function generatePivotTable(pivot, data, dateRange, isComparison, rowLimi
872
1025
  if (pivot.sort) {
873
1026
  pivotRows.sort((a, b) => {
874
1027
  if (pivot.sortDirection === 'ASC') {
875
- if (pivot.rowFieldType === 'date') {
876
- return new Date(a[pivot.rowField]) - new Date(b[pivot.rowField]);
1028
+ if (dateFormatOptions.includes(pivot.sortFieldType ?? '')) {
1029
+ // @ts-ignore
1030
+ return new Date(a[pivot.sortField]) - new Date(b[pivot.sortField]);
877
1031
  }
878
- else if (isNumericColumnType(pivot.rowFieldType)) {
879
- return a[pivot.rowField] - b[pivot.rowField];
1032
+ else if (isNumericColumnType(pivot.sortFieldType)) {
1033
+ return a[pivot.sortField] - b[pivot.sortField];
880
1034
  }
881
- return a[pivot.rowField].localeCompare(b[pivot.rowField]);
1035
+ return a[pivot.sortField].localeCompare(b[pivot.sortField]);
882
1036
  }
883
1037
  else {
884
- if (pivot.rowFieldType === 'date') {
885
- return new Date(b[pivot.rowField]) - new Date(a[pivot.rowField]);
1038
+ if (dateFormatOptions.includes(pivot.sortFieldType ?? '')) {
1039
+ // @ts-ignore
1040
+ return new Date(b[pivot.sortField]) - new Date(a[pivot.sortField]);
886
1041
  }
887
- else if (isNumericColumnType(pivot.rowFieldType)) {
888
- return a[pivot.rowField] - b[pivot.rowField];
1042
+ else if (isNumericColumnType(pivot.sortFieldType)) {
1043
+ return b[pivot.sortField] - a[pivot.sortField];
889
1044
  }
890
- return b[pivot.rowField].localeCompare(a[pivot.rowField]);
1045
+ return b[pivot.sortField].localeCompare(a[pivot.sortField]);
891
1046
  }
892
1047
  });
893
1048
  }
@@ -913,8 +1068,7 @@ function valueFieldAggregation(data, valueField, aggregationType, isComparison)
913
1068
  case 'average':
914
1069
  const count = data.reduce((count, item) => count + (item[valueField] ? 1 : 0), 0);
915
1070
  value =
916
- data.reduce((sum, item) => sum + parseFloat(item[valueField] ?? 0), 0) /
917
- (count === 0 ? 1 : count);
1071
+ data.reduce((sum, item) => sum + parseFloat(item[valueField] ?? 0), 0) / (count === 0 ? 1 : count);
918
1072
  if (isComparison) {
919
1073
  const comparisonCount = data.reduce((count, item) => count + (item[`comparison_${valueField}`] ? 1 : 0), 0);
920
1074
  comparisonValue =
@@ -922,15 +1076,15 @@ function valueFieldAggregation(data, valueField, aggregationType, isComparison)
922
1076
  }
923
1077
  break;
924
1078
  case 'max':
925
- value = data.reduce((max, item) => Math.max(max, parseFloat(item[valueField] ?? 0)), -Infinity);
1079
+ value = data.reduce((max, item) => Math.max(max, parseFloat(item[valueField] ?? -Infinity)), -Infinity);
926
1080
  if (isComparison) {
927
- comparisonValue = data.reduce((max, item) => Math.max(max, parseFloat(item[`comparison_${valueField}`] ?? 0)), -Infinity);
1081
+ comparisonValue = data.reduce((max, item) => Math.max(max, parseFloat(item[`comparison_${valueField}`] ?? -Infinity)), -Infinity);
928
1082
  }
929
1083
  break;
930
1084
  case 'min':
931
- value = data.reduce((min, item) => Math.min(min, parseFloat(item[valueField] ?? 0)), Infinity);
1085
+ value = data.reduce((min, item) => Math.min(min, parseFloat(item[valueField] ?? Infinity)), Infinity);
932
1086
  if (isComparison) {
933
- comparisonValue = data.reduce((min, item) => Math.min(min, parseFloat(item[`comparison_${valueField}`] ?? 0)), Infinity);
1087
+ comparisonValue = data.reduce((min, item) => Math.min(min, parseFloat(item[`comparison_${valueField}`] ?? Infinity)), Infinity);
934
1088
  }
935
1089
  break;
936
1090
  // Implement other aggregation types as needed