@quillsql/react 2.11.23 → 2.11.25

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