@sisense/sdk-pivot-query-client 2.17.0

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 (189) hide show
  1. package/LICENSE.md +35 -0
  2. package/README.md +2 -0
  3. package/dist/__test-helpers__/testUtils.d.ts +30 -0
  4. package/dist/__test-helpers__/testUtils.js +89 -0
  5. package/dist/builders/index.d.ts +2 -0
  6. package/dist/builders/index.js +2 -0
  7. package/dist/builders/pivot-data-builder.d.ts +34 -0
  8. package/dist/builders/pivot-data-builder.js +182 -0
  9. package/dist/builders/socket-builder.d.ts +18 -0
  10. package/dist/builders/socket-builder.js +72 -0
  11. package/dist/cjs/__test-helpers__/testUtils.d.ts +30 -0
  12. package/dist/cjs/__test-helpers__/testUtils.js +104 -0
  13. package/dist/cjs/builders/index.d.ts +2 -0
  14. package/dist/cjs/builders/index.js +7 -0
  15. package/dist/cjs/builders/pivot-data-builder.d.ts +34 -0
  16. package/dist/cjs/builders/pivot-data-builder.js +186 -0
  17. package/dist/cjs/builders/socket-builder.d.ts +18 -0
  18. package/dist/cjs/builders/socket-builder.js +79 -0
  19. package/dist/cjs/data-handling/DataService.d.ts +672 -0
  20. package/dist/cjs/data-handling/DataService.js +1364 -0
  21. package/dist/cjs/data-handling/DivergenceComparator.d.ts +7 -0
  22. package/dist/cjs/data-handling/DivergenceComparator.js +20 -0
  23. package/dist/cjs/data-handling/constants.d.ts +44 -0
  24. package/dist/cjs/data-handling/constants.js +43 -0
  25. package/dist/cjs/data-handling/index.d.ts +3 -0
  26. package/dist/cjs/data-handling/index.js +23 -0
  27. package/dist/cjs/data-handling/types.d.ts +104 -0
  28. package/dist/cjs/data-handling/types.js +2 -0
  29. package/dist/cjs/data-handling/utils/createPivotTreeNode.d.ts +13 -0
  30. package/dist/cjs/data-handling/utils/createPivotTreeNode.js +21 -0
  31. package/dist/cjs/data-handling/utils/index.d.ts +4 -0
  32. package/dist/cjs/data-handling/utils/index.js +14 -0
  33. package/dist/cjs/data-handling/utils/jaqlProcessor.d.ts +122 -0
  34. package/dist/cjs/data-handling/utils/jaqlProcessor.js +661 -0
  35. package/dist/cjs/data-handling/utils/pivotTransforms.d.ts +74 -0
  36. package/dist/cjs/data-handling/utils/pivotTransforms.js +373 -0
  37. package/dist/cjs/data-handling/utils/plugins/PluginService.d.ts +135 -0
  38. package/dist/cjs/data-handling/utils/plugins/PluginService.js +383 -0
  39. package/dist/cjs/data-handling/utils/plugins/getters.d.ts +23 -0
  40. package/dist/cjs/data-handling/utils/plugins/getters.js +70 -0
  41. package/dist/cjs/data-handling/utils/plugins/types.d.ts +75 -0
  42. package/dist/cjs/data-handling/utils/plugins/types.js +2 -0
  43. package/dist/cjs/data-handling/utils/plugins/validator.d.ts +13 -0
  44. package/dist/cjs/data-handling/utils/plugins/validator.js +169 -0
  45. package/dist/cjs/data-load/AbstractDataLoadService.d.ts +256 -0
  46. package/dist/cjs/data-load/AbstractDataLoadService.js +473 -0
  47. package/dist/cjs/data-load/DataLoadService.d.ts +63 -0
  48. package/dist/cjs/data-load/DataLoadService.js +152 -0
  49. package/dist/cjs/data-load/SisenseDataLoadService.d.ts +44 -0
  50. package/dist/cjs/data-load/SisenseDataLoadService.js +87 -0
  51. package/dist/cjs/data-load/TestDataLoadService.d.ts +27 -0
  52. package/dist/cjs/data-load/TestDataLoadService.js +76 -0
  53. package/dist/cjs/data-load/constants.d.ts +13 -0
  54. package/dist/cjs/data-load/constants.js +28 -0
  55. package/dist/cjs/data-load/index.d.ts +6 -0
  56. package/dist/cjs/data-load/index.js +14 -0
  57. package/dist/cjs/data-load/sockets/SisenseSocket.d.ts +81 -0
  58. package/dist/cjs/data-load/sockets/SisenseSocket.js +162 -0
  59. package/dist/cjs/data-load/sockets/TestSocket.d.ts +61 -0
  60. package/dist/cjs/data-load/sockets/TestSocket.js +90 -0
  61. package/dist/cjs/data-load/sockets/helpers.d.ts +4 -0
  62. package/dist/cjs/data-load/sockets/helpers.js +27 -0
  63. package/dist/cjs/data-load/sockets/index.d.ts +2 -0
  64. package/dist/cjs/data-load/sockets/index.js +8 -0
  65. package/dist/cjs/data-load/types.d.ts +90 -0
  66. package/dist/cjs/data-load/types.js +2 -0
  67. package/dist/cjs/errors/LoadingCanceledError.d.ts +7 -0
  68. package/dist/cjs/errors/LoadingCanceledError.js +24 -0
  69. package/dist/cjs/errors/index.d.ts +1 -0
  70. package/dist/cjs/errors/index.js +6 -0
  71. package/dist/cjs/index.d.ts +17 -0
  72. package/dist/cjs/index.js +32 -0
  73. package/dist/cjs/package.json +12 -0
  74. package/dist/cjs/pivot-query-client.d.ts +13 -0
  75. package/dist/cjs/pivot-query-client.js +26 -0
  76. package/dist/cjs/tree-structure/AbstractTreeService.d.ts +308 -0
  77. package/dist/cjs/tree-structure/AbstractTreeService.js +716 -0
  78. package/dist/cjs/tree-structure/HeaderTreeService.d.ts +180 -0
  79. package/dist/cjs/tree-structure/HeaderTreeService.js +280 -0
  80. package/dist/cjs/tree-structure/TreeCellMap.d.ts +104 -0
  81. package/dist/cjs/tree-structure/TreeCellMap.js +145 -0
  82. package/dist/cjs/tree-structure/TreeService.d.ts +8 -0
  83. package/dist/cjs/tree-structure/TreeService.js +12 -0
  84. package/dist/cjs/tree-structure/constants.d.ts +6 -0
  85. package/dist/cjs/tree-structure/constants.js +10 -0
  86. package/dist/cjs/tree-structure/index.d.ts +5 -0
  87. package/dist/cjs/tree-structure/index.js +10 -0
  88. package/dist/cjs/tree-structure/types.d.ts +93 -0
  89. package/dist/cjs/tree-structure/types.js +2 -0
  90. package/dist/cjs/tree-structure/utils/index.d.ts +1 -0
  91. package/dist/cjs/tree-structure/utils/index.js +9 -0
  92. package/dist/cjs/tree-structure/utils/treeNode.d.ts +147 -0
  93. package/dist/cjs/tree-structure/utils/treeNode.js +534 -0
  94. package/dist/cjs/utils/array.d.ts +13 -0
  95. package/dist/cjs/utils/array.js +25 -0
  96. package/dist/cjs/utils/cloneObject.d.ts +30 -0
  97. package/dist/cjs/utils/cloneObject.js +225 -0
  98. package/dist/cjs/utils/index.d.ts +3 -0
  99. package/dist/cjs/utils/index.js +9 -0
  100. package/dist/cjs/utils/throttle.d.ts +12 -0
  101. package/dist/cjs/utils/throttle.js +39 -0
  102. package/dist/cjs/utils/types.d.ts +12 -0
  103. package/dist/cjs/utils/types.js +2 -0
  104. package/dist/data-handling/DataService.d.ts +672 -0
  105. package/dist/data-handling/DataService.js +1357 -0
  106. package/dist/data-handling/DivergenceComparator.d.ts +7 -0
  107. package/dist/data-handling/DivergenceComparator.js +16 -0
  108. package/dist/data-handling/constants.d.ts +44 -0
  109. package/dist/data-handling/constants.js +40 -0
  110. package/dist/data-handling/index.d.ts +3 -0
  111. package/dist/data-handling/index.js +4 -0
  112. package/dist/data-handling/types.d.ts +104 -0
  113. package/dist/data-handling/types.js +1 -0
  114. package/dist/data-handling/utils/createPivotTreeNode.d.ts +13 -0
  115. package/dist/data-handling/utils/createPivotTreeNode.js +17 -0
  116. package/dist/data-handling/utils/index.d.ts +4 -0
  117. package/dist/data-handling/utils/index.js +4 -0
  118. package/dist/data-handling/utils/jaqlProcessor.d.ts +122 -0
  119. package/dist/data-handling/utils/jaqlProcessor.js +621 -0
  120. package/dist/data-handling/utils/pivotTransforms.d.ts +74 -0
  121. package/dist/data-handling/utils/pivotTransforms.js +335 -0
  122. package/dist/data-handling/utils/plugins/PluginService.d.ts +135 -0
  123. package/dist/data-handling/utils/plugins/PluginService.js +379 -0
  124. package/dist/data-handling/utils/plugins/getters.d.ts +23 -0
  125. package/dist/data-handling/utils/plugins/getters.js +65 -0
  126. package/dist/data-handling/utils/plugins/types.d.ts +75 -0
  127. package/dist/data-handling/utils/plugins/types.js +1 -0
  128. package/dist/data-handling/utils/plugins/validator.d.ts +13 -0
  129. package/dist/data-handling/utils/plugins/validator.js +165 -0
  130. package/dist/data-load/AbstractDataLoadService.d.ts +256 -0
  131. package/dist/data-load/AbstractDataLoadService.js +466 -0
  132. package/dist/data-load/DataLoadService.d.ts +63 -0
  133. package/dist/data-load/DataLoadService.js +148 -0
  134. package/dist/data-load/SisenseDataLoadService.d.ts +44 -0
  135. package/dist/data-load/SisenseDataLoadService.js +83 -0
  136. package/dist/data-load/TestDataLoadService.d.ts +27 -0
  137. package/dist/data-load/TestDataLoadService.js +69 -0
  138. package/dist/data-load/constants.d.ts +13 -0
  139. package/dist/data-load/constants.js +25 -0
  140. package/dist/data-load/index.d.ts +6 -0
  141. package/dist/data-load/index.js +6 -0
  142. package/dist/data-load/sockets/SisenseSocket.d.ts +81 -0
  143. package/dist/data-load/sockets/SisenseSocket.js +155 -0
  144. package/dist/data-load/sockets/TestSocket.d.ts +61 -0
  145. package/dist/data-load/sockets/TestSocket.js +83 -0
  146. package/dist/data-load/sockets/helpers.d.ts +4 -0
  147. package/dist/data-load/sockets/helpers.js +23 -0
  148. package/dist/data-load/sockets/index.d.ts +2 -0
  149. package/dist/data-load/sockets/index.js +3 -0
  150. package/dist/data-load/types.d.ts +90 -0
  151. package/dist/data-load/types.js +1 -0
  152. package/dist/errors/LoadingCanceledError.d.ts +7 -0
  153. package/dist/errors/LoadingCanceledError.js +20 -0
  154. package/dist/errors/index.d.ts +1 -0
  155. package/dist/errors/index.js +2 -0
  156. package/dist/index.d.ts +17 -0
  157. package/dist/index.js +9 -0
  158. package/dist/pivot-query-client.d.ts +13 -0
  159. package/dist/pivot-query-client.js +22 -0
  160. package/dist/tree-structure/AbstractTreeService.d.ts +308 -0
  161. package/dist/tree-structure/AbstractTreeService.js +712 -0
  162. package/dist/tree-structure/HeaderTreeService.d.ts +180 -0
  163. package/dist/tree-structure/HeaderTreeService.js +276 -0
  164. package/dist/tree-structure/TreeCellMap.d.ts +104 -0
  165. package/dist/tree-structure/TreeCellMap.js +141 -0
  166. package/dist/tree-structure/TreeService.d.ts +8 -0
  167. package/dist/tree-structure/TreeService.js +8 -0
  168. package/dist/tree-structure/constants.d.ts +6 -0
  169. package/dist/tree-structure/constants.js +7 -0
  170. package/dist/tree-structure/index.d.ts +5 -0
  171. package/dist/tree-structure/index.js +4 -0
  172. package/dist/tree-structure/types.d.ts +93 -0
  173. package/dist/tree-structure/types.js +1 -0
  174. package/dist/tree-structure/utils/index.d.ts +1 -0
  175. package/dist/tree-structure/utils/index.js +1 -0
  176. package/dist/tree-structure/utils/treeNode.d.ts +147 -0
  177. package/dist/tree-structure/utils/treeNode.js +515 -0
  178. package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
  179. package/dist/utils/array.d.ts +13 -0
  180. package/dist/utils/array.js +21 -0
  181. package/dist/utils/cloneObject.d.ts +30 -0
  182. package/dist/utils/cloneObject.js +221 -0
  183. package/dist/utils/index.d.ts +3 -0
  184. package/dist/utils/index.js +3 -0
  185. package/dist/utils/throttle.d.ts +12 -0
  186. package/dist/utils/throttle.js +35 -0
  187. package/dist/utils/types.d.ts +12 -0
  188. package/dist/utils/types.js +1 -0
  189. package/package.json +61 -0
@@ -0,0 +1,621 @@
1
+ import isEqual from 'lodash-es/isEqual.js';
2
+ import { treeNode } from '../../tree-structure/utils/index.js';
3
+ import { JaqlDataType, PanelType, SortingDirection, } from '../constants.js';
4
+ import createPivotTreeNode from './createPivotTreeNode.js';
5
+ import * as jaqlProcessor from './jaqlProcessor.js';
6
+ export function getDataTypes(panels = []) {
7
+ const dataTypes = {};
8
+ panels.forEach((panel) => {
9
+ const { index = Infinity } = panel.field || {};
10
+ const indexStr = `${index}`;
11
+ dataTypes[indexStr] = panel.jaql.datatype || JaqlDataType.TEXT;
12
+ });
13
+ return dataTypes;
14
+ }
15
+ function defaultFormatter(value, dataType) {
16
+ if (value && dataType === JaqlDataType.DATETIME) {
17
+ try {
18
+ return new Date(value).toISOString();
19
+ }
20
+ catch (e) {
21
+ return value;
22
+ }
23
+ }
24
+ return value;
25
+ }
26
+ function normalizeMeasurePath(path) {
27
+ if (path === null) {
28
+ return undefined;
29
+ }
30
+ if (isEqual(path, {})) {
31
+ return undefined;
32
+ }
33
+ return path;
34
+ }
35
+ // eslint-disable-next-line sonarjs/cognitive-complexity
36
+ export function isMeasurePathEqual(_measurePathA, _measurePathB, dataTypes = {}) {
37
+ const measurePathA = normalizeMeasurePath(_measurePathA);
38
+ const measurePathB = normalizeMeasurePath(_measurePathB);
39
+ let result = false;
40
+ if (typeof measurePathA === 'object' &&
41
+ measurePathA !== null &&
42
+ typeof measurePathB === 'object' &&
43
+ measurePathB !== null) {
44
+ result = true;
45
+ const measurePathAKeys = Object.keys(measurePathA);
46
+ const measurePathBKeys = Object.keys(measurePathB);
47
+ if (measurePathAKeys.length !== measurePathBKeys.length) {
48
+ result = false;
49
+ }
50
+ else {
51
+ measurePathAKeys.forEach((key) => {
52
+ const dataType = dataTypes[key] || '';
53
+ let valueA = (measurePathA || {})[key];
54
+ let valueB = (measurePathB || {})[key];
55
+ if (typeof valueA === 'undefined' || typeof valueB === 'undefined') {
56
+ result = false;
57
+ return;
58
+ }
59
+ if (dataType === JaqlDataType.DATETIME) {
60
+ valueA = defaultFormatter(valueA, dataType);
61
+ valueB = defaultFormatter(valueB, dataType);
62
+ }
63
+ if (valueA !== valueB) {
64
+ result = false;
65
+ }
66
+ });
67
+ }
68
+ }
69
+ else {
70
+ result = measurePathA === measurePathB;
71
+ }
72
+ return result;
73
+ }
74
+ function getCompatibleMeasurePath(measurePath, dataTypes, formatter = defaultFormatter) {
75
+ if (!measurePath || typeof measurePath !== 'object') {
76
+ return measurePath;
77
+ }
78
+ const result = {};
79
+ Object.keys(measurePath).forEach((key) => {
80
+ const dataType = dataTypes[key];
81
+ const value = (measurePath || {})[key];
82
+ const formattedValue = formatter(value, dataType);
83
+ result[key] = formattedValue;
84
+ });
85
+ return result;
86
+ }
87
+ /**
88
+ * Get appropriate metadata panels (rows/columns/measures) from JAQL request object
89
+ *
90
+ * @param {JaqlRequest} jaql - jaql with metadata
91
+ * @param {string} type - panels type to receive
92
+ * @returns {Array<JaqlPanel>} - list of panels
93
+ */
94
+ export const getMetadataPanels = (jaql, type) => {
95
+ let panels = (jaql && jaql.metadata) || [];
96
+ if (type) {
97
+ panels = panels.filter((item) => item.panel === type);
98
+ }
99
+ panels.sort((prev, next) => {
100
+ const defaultField = { index: Infinity };
101
+ const prevField = prev.field || defaultField;
102
+ const nextField = next.field || defaultField;
103
+ return prevField.index - nextField.index;
104
+ });
105
+ return panels;
106
+ };
107
+ /**
108
+ * Get appropriate metadata panel (rows/columns/measures) from JAQL request object by panel index
109
+ *
110
+ * @param {JaqlRequest} jaql - jaql with metadata
111
+ * @param {number} index - panel index
112
+ * @param {string} [type] - panels type to receive
113
+ * @returns {JaqlPanel} - jaql panels
114
+ */
115
+ export const getMetadataPanelByIndex = (jaql, index, type) => {
116
+ if (typeof index === 'undefined') {
117
+ return undefined;
118
+ }
119
+ const panels = getMetadataPanels(jaql, type);
120
+ const filteredPanels = panels.filter((panel) => {
121
+ const panelField = panel.field || { index: Infinity };
122
+ return panelField.index === index;
123
+ });
124
+ return filteredPanels[0];
125
+ };
126
+ /**
127
+ * sortingLastDimension jaql's sorting param processing method
128
+ *
129
+ * @param {JaqlPanel} processedPanel - panel to be identified
130
+ * @param {?JaqlRequest} jaql - jaql to be processed
131
+ * @returns {boolean} - sortingLastDimension initialization
132
+ */
133
+ const isPanelsLastDimension = (processedPanel, jaql) => {
134
+ const processedPanelField = processedPanel.field || { index: Infinity };
135
+ if (processedPanel.panel === PanelType.MEASURES) {
136
+ return true;
137
+ }
138
+ if (processedPanel.panel === PanelType.ROWS) {
139
+ const panels = getMetadataPanels(jaql, PanelType.ROWS);
140
+ const lastPanel = panels[panels.length - 1] || {};
141
+ const lastPanelField = lastPanel.field || { index: Infinity };
142
+ if (panels.length && lastPanelField.index === processedPanelField.index) {
143
+ return true;
144
+ }
145
+ if (!panels.length) {
146
+ // eslint-disable-next-line no-console
147
+ console.error('Missing rows panel in jaql!');
148
+ }
149
+ }
150
+ return false;
151
+ };
152
+ function checkRowSortedBySubtotal(sortDetails, jaqlIndex) {
153
+ if (!sortDetails) {
154
+ return false;
155
+ }
156
+ if (typeof sortDetails.field !== 'number') {
157
+ return false;
158
+ }
159
+ return sortDetails.field !== jaqlIndex;
160
+ }
161
+ /**
162
+ * Get appropriate metadata panels (rows/columns/measures) in TreeNode structure from
163
+ * JAQL request object
164
+ *
165
+ * @param {JaqlRequest} jaql - jaql with metadata
166
+ * @param {string} [type=PanelType.ROWS] - panels type to receive
167
+ * @returns {PivotTreeNode} - metadata panels tree
168
+ */
169
+ export const getMetadataTree = (jaql, type = PanelType.ROWS) => {
170
+ const panels = getMetadataPanels(jaql, type);
171
+ const nodes = panels.map((item, index) => {
172
+ const node = treeNode.create(item.jaql.title, undefined, undefined, index);
173
+ const pivotNode = createPivotTreeNode(node, type);
174
+ pivotNode.jaqlIndex = item.field ? item.field.index : undefined;
175
+ switch (type) {
176
+ case PanelType.ROWS: {
177
+ pivotNode.measurePath = undefined;
178
+ const isSortedBySubtotal = checkRowSortedBySubtotal(item.jaql.sortDetails, pivotNode.jaqlIndex);
179
+ if (item.jaql.sort && !isSortedBySubtotal) {
180
+ pivotNode.dir = item.jaql.sort;
181
+ }
182
+ else {
183
+ pivotNode.dir = null;
184
+ }
185
+ break;
186
+ }
187
+ case PanelType.MEASURES:
188
+ pivotNode.databars = item.format ? item.format.databars : false;
189
+ pivotNode.measureJaqlIndex = pivotNode.jaqlIndex;
190
+ if (!getMetadataPanels(jaql, PanelType.COLUMNS).length) {
191
+ pivotNode.measurePath = undefined;
192
+ if (item.jaql.sortDetails && item.jaql.sortDetails.measurePath === null) {
193
+ pivotNode.dir = item.jaql.sortDetails.dir;
194
+ }
195
+ else {
196
+ pivotNode.dir = null;
197
+ }
198
+ }
199
+ break;
200
+ default:
201
+ break;
202
+ }
203
+ return pivotNode;
204
+ });
205
+ return treeNode.wrapInRootNode(nodes);
206
+ };
207
+ /**
208
+ * method to clear sorting information in panels with
209
+ * sortingLastDimension === false
210
+ *
211
+ * @param {?JaqlRequest} jaql - jaql to clear
212
+ * @returns {void}
213
+ */
214
+ const clearLastDimesionSortDetails = (jaql) => {
215
+ const metadata = jaql && jaql.metadata ? jaql.metadata : [];
216
+ metadata.forEach((panel) => {
217
+ if (panel &&
218
+ panel.jaql &&
219
+ panel.jaql.sort &&
220
+ panel.jaql.sortDetails &&
221
+ panel.jaql.sortDetails.sortingLastDimension) {
222
+ panel.jaql.sort = null;
223
+ delete panel.jaql.sortDetails;
224
+ }
225
+ });
226
+ };
227
+ /**
228
+ * Clears panel sort details
229
+ *
230
+ * @param {JaqlPanel} panel - jaql panel
231
+ * @returns {void}
232
+ */
233
+ const clearPanelSortDetails = (panel) => {
234
+ if (panel && panel.jaql) {
235
+ panel.jaql.sort = null;
236
+ delete panel.jaql.sortDetails;
237
+ }
238
+ };
239
+ /**
240
+ * method to clear sorting all information in panels
241
+ *
242
+ * @param {?JaqlRequest} jaql - jaql to clear
243
+ * @returns {void}
244
+ */
245
+ const clearAllSortDetails = (jaql) => {
246
+ const metadata = jaql && jaql.metadata ? jaql.metadata : [];
247
+ metadata.forEach((panel) => clearPanelSortDetails(panel));
248
+ };
249
+ /**
250
+ * Getter for last sorted panel
251
+ *
252
+ * @param {JaqlRequest} jaql - jaql request
253
+ * @returns {JaqlPanel|undefined} - panel item
254
+ */
255
+ const getLastSortedPanel = (jaql) => (jaql.metadata || []).reverse().find((item) => !!item.jaql.sortDetails);
256
+ /**
257
+ * Getter for panel item on which sorting was last applied
258
+ *
259
+ * @param {JaqlRequest} jaql - jaql request
260
+ * @returns {JaqlPanel|undefined} - panel item
261
+ */
262
+ const getLastAppliedSortedPanel = (jaql) => (jaql.metadata || []).find((item) => !!(item.jaql.sortDetails && item.jaql.sortDetails.isLastApplied));
263
+ /**
264
+ * Removes redundant sort details for single branch tree
265
+ * (As such pivot can be sorted only by one panel)
266
+ *
267
+ * @param {JaqlRequest} jaql - jaql request
268
+ * @returns {void}
269
+ */
270
+ export const normalizeSingleBranchTreeSortDetails = (jaql) => {
271
+ const sortedPanel = getLastAppliedSortedPanel(jaql) || getLastSortedPanel(jaql);
272
+ if (!sortedPanel) {
273
+ return;
274
+ }
275
+ const sortedIndex = sortedPanel.field && sortedPanel.field.index;
276
+ (jaql.metadata || []).forEach((panel) => {
277
+ const currentIndex = panel.field && panel.field.index;
278
+ if (currentIndex !== sortedIndex) {
279
+ clearPanelSortDetails(panel);
280
+ }
281
+ });
282
+ };
283
+ /**
284
+ * Updates last applied flag on metadata item sort details
285
+ * (Required for proper apply single branch tree sorting)
286
+ *
287
+ * @param {JaqlRequest} jaql - jaql request
288
+ * @param {SortDetails} sortDetails - last updated sort details
289
+ * @returns {void}
290
+ */
291
+ export const updateLastAppliedSortingFlag = (jaql, sortDetails) => {
292
+ jaql.metadata.forEach((item) => {
293
+ const currentIndex = item.field && item.field.index;
294
+ if (sortDetails.field === currentIndex) {
295
+ item.jaql.sortDetails = item.jaql.sortDetails || sortDetails;
296
+ item.jaql.sortDetails.isLastApplied = true;
297
+ return;
298
+ }
299
+ if (item.jaql.sortDetails && item.jaql.sortDetails) {
300
+ delete item.jaql.sortDetails.isLastApplied;
301
+ }
302
+ });
303
+ };
304
+ /**
305
+ * method to handle new sorting metadata
306
+ *
307
+ * @param {SortDetails} sortDetails - node with sorting metadata
308
+ * @param {?JaqlRequest} jaql - jaql to process
309
+ * @param {object} [options] - additional options
310
+ * @param {Function} [options.formatter] - fields formatter for measurePath
311
+ * @param {boolean} [options.isSingleRowTree] - defines data structure
312
+ * @returns {JaqlRequest} - reload pivot after jaql formatting
313
+ */
314
+ export const updatePanelsSortingMetadata = (sortDetails, jaql, options) => {
315
+ const { isSingleRowTree = false, formatter } = options || {};
316
+ if (!jaql) {
317
+ // eslint-disable-next-line no-console
318
+ console.warn('jaql is undefined or null!');
319
+ return;
320
+ }
321
+ const panelToSortBy = getMetadataPanelByIndex(jaql, sortDetails.field);
322
+ if (panelToSortBy && panelToSortBy.panel === PanelType.COLUMNS) {
323
+ // eslint-disable-next-line no-console
324
+ console.warn('Should not be sorted by "COLUMN" type panels!');
325
+ return;
326
+ }
327
+ if (!panelToSortBy) {
328
+ return;
329
+ }
330
+ const sortingLastDimension = isPanelsLastDimension(panelToSortBy, jaql);
331
+ if (isSingleRowTree) {
332
+ clearAllSortDetails(jaql);
333
+ }
334
+ else if (sortingLastDimension) {
335
+ clearLastDimesionSortDetails(jaql);
336
+ }
337
+ switch (sortDetails.dir) {
338
+ case SortingDirection.DESC:
339
+ case null:
340
+ panelToSortBy.jaql.sort = SortingDirection.ASC;
341
+ break;
342
+ case SortingDirection.ASC:
343
+ panelToSortBy.jaql.sort = SortingDirection.DESC;
344
+ break;
345
+ default:
346
+ panelToSortBy.jaql.sort = undefined;
347
+ }
348
+ const panelToSortByField = panelToSortBy.field || { index: Infinity };
349
+ if (panelToSortBy.jaql.sort) {
350
+ let { measurePath } = sortDetails;
351
+ if (measurePath) {
352
+ const panels = getMetadataPanels(jaql);
353
+ const dataTypes = getDataTypes(panels);
354
+ measurePath = getCompatibleMeasurePath(measurePath, dataTypes, formatter);
355
+ }
356
+ panelToSortBy.jaql.sortDetails = {
357
+ field: panelToSortByField.index,
358
+ dir: panelToSortBy.jaql.sort,
359
+ sortingLastDimension,
360
+ measurePath,
361
+ initialized: true,
362
+ };
363
+ }
364
+ else {
365
+ panelToSortBy.jaql.sortDetails = undefined;
366
+ }
367
+ if (jaql && jaql.metadata && panelToSortByField.index !== undefined) {
368
+ jaql.metadata[panelToSortByField.index] = panelToSortBy;
369
+ }
370
+ updateLastAppliedSortingFlag(jaql, sortDetails);
371
+ };
372
+ /**
373
+ * Set width for jaql panel item
374
+ *
375
+ * @param {JaqlRequest} jaql - jaql request object
376
+ * @param {number} jaqlIndex - jaql panel item index
377
+ * @param {number} width - jaql panel item width
378
+ * @returns {void}
379
+ */
380
+ export const setResizeWidthToJaql = (jaql, jaqlIndex, width) => {
381
+ if (!jaql) {
382
+ return;
383
+ }
384
+ const jaqlPanel = getMetadataPanelByIndex(jaql, jaqlIndex);
385
+ if (!jaqlPanel) {
386
+ return;
387
+ }
388
+ jaqlPanel.format = jaqlPanel.format || {};
389
+ jaqlPanel.format.width = width;
390
+ };
391
+ /**
392
+ * Get pairs 'jaqlIndex: value' for jaql panel items
393
+ *
394
+ * @param {JaqlRequest} jaql - jaql request object
395
+ * @returns {object} - object, keys - jaqlIndex, value - width
396
+ * appropriate width
397
+ */
398
+ export const getResizeWidthFromJaql = (jaql) => {
399
+ const result = {};
400
+ if (!jaql) {
401
+ return result;
402
+ }
403
+ const panels = getMetadataPanels(jaql);
404
+ panels.forEach((panel) => {
405
+ const panelField = panel.field || { index: Infinity };
406
+ if (panel.format &&
407
+ typeof panel.format.width !== 'undefined' &&
408
+ typeof panelField.index !== 'undefined') {
409
+ result[panelField.index] = panel.format.width;
410
+ }
411
+ });
412
+ return result;
413
+ };
414
+ export const markSortedNode = (jaql, item) => {
415
+ if (typeof item.measureJaqlIndex !== 'undefined') {
416
+ const panels = getMetadataPanels(jaql);
417
+ const dataTypes = getDataTypes(panels);
418
+ const rowWhereSortPropIs = panels
419
+ .filter((p) => p.panel === PanelType.ROWS)
420
+ .find((rp) => {
421
+ const rowSortDetails = rp.jaql.sortDetails;
422
+ if (!rowSortDetails) {
423
+ return false;
424
+ }
425
+ const isIndexSame = rowSortDetails.field === item.measureJaqlIndex;
426
+ if (!isIndexSame) {
427
+ return false;
428
+ }
429
+ return Boolean(isMeasurePathEqual(item.measurePath, rowSortDetails.measurePath, dataTypes));
430
+ });
431
+ if (rowWhereSortPropIs) {
432
+ item.dir = rowWhereSortPropIs.jaql.sort ? rowWhereSortPropIs.jaql.sort : null;
433
+ return;
434
+ }
435
+ const panel = getMetadataPanelByIndex(jaql, item.measureJaqlIndex);
436
+ if (panel && panel.jaql.sortDetails) {
437
+ const panelMeasurePath = panel.jaql.sortDetails.measurePath;
438
+ const itemMeasurePath = item.measurePath;
439
+ if (isMeasurePathEqual(panelMeasurePath, itemMeasurePath, dataTypes)) {
440
+ item.dir = panel.jaql.sort || null;
441
+ return;
442
+ }
443
+ }
444
+ }
445
+ item.dir = null;
446
+ };
447
+ function handleComplexSortingSettingsUpdate(jaql, desiredSortingSettings, possibleSortDetailsOfCurrentMeasure, options) {
448
+ const { isSingleRowTree, formatter } = options;
449
+ if (isSingleRowTree) {
450
+ clearAllSortDetails(jaql);
451
+ }
452
+ jaql.metadata.forEach((item) => {
453
+ if (item.jaql.sortDetails) {
454
+ delete item.jaql.sortDetails.isLastApplied;
455
+ }
456
+ });
457
+ desiredSortingSettings.forEach((dss, index) => {
458
+ let indexOfPanelToSortBy;
459
+ if (index === desiredSortingSettings.length - 1) {
460
+ if (dss.selected) {
461
+ clearLastDimesionSortDetails(jaql);
462
+ }
463
+ indexOfPanelToSortBy = possibleSortDetailsOfCurrentMeasure.field;
464
+ }
465
+ else {
466
+ indexOfPanelToSortBy = dss.indexInJaql;
467
+ }
468
+ const panelToSortBy = getMetadataPanelByIndex(jaql, indexOfPanelToSortBy);
469
+ if (!panelToSortBy) {
470
+ // eslint-disable-next-line no-console
471
+ console.warn(new Error('Panel not found'));
472
+ return;
473
+ }
474
+ if (dss.selected && !dss.direction) {
475
+ // eslint-disable-next-line no-console
476
+ console.warn(new Error("Direction should be defined and equal to 'asc' or 'desc'"));
477
+ }
478
+ const panels = getMetadataPanels(jaql);
479
+ const dataTypes = getDataTypes(panels);
480
+ if (!dss.direction || !dss.selected) {
481
+ const { sortDetails } = panelToSortBy.jaql;
482
+ const shouldDeleteSorting = Boolean(sortDetails &&
483
+ possibleSortDetailsOfCurrentMeasure.field === sortDetails.field &&
484
+ isMeasurePathEqual(possibleSortDetailsOfCurrentMeasure.measurePath, sortDetails.measurePath, dataTypes));
485
+ if (shouldDeleteSorting) {
486
+ delete panelToSortBy.jaql.sort;
487
+ delete panelToSortBy.jaql.sortDetails;
488
+ }
489
+ }
490
+ if (dss.selected && dss.direction) {
491
+ panelToSortBy.jaql.sort = dss.direction;
492
+ let { measurePath } = possibleSortDetailsOfCurrentMeasure;
493
+ if (measurePath) {
494
+ measurePath = getCompatibleMeasurePath(measurePath, dataTypes, formatter);
495
+ }
496
+ if (possibleSortDetailsOfCurrentMeasure.measurePath === undefined &&
497
+ panelToSortBy.field && // for type checker
498
+ panelToSortBy.panel === 'rows' &&
499
+ possibleSortDetailsOfCurrentMeasure.field !== panelToSortBy.field.index) {
500
+ measurePath = {};
501
+ }
502
+ panelToSortBy.jaql.sortDetails = {
503
+ field: possibleSortDetailsOfCurrentMeasure.field,
504
+ dir: dss.direction,
505
+ sortingLastDimension: false,
506
+ measurePath,
507
+ isLastApplied: true,
508
+ initialized: true,
509
+ };
510
+ }
511
+ });
512
+ }
513
+ function checkLastRowSortedByMeasure(lastRow, // TODO: fix
514
+ possibleSortDetailsOfCurrentMeasure, currentSortDetailsOfCurrentMeasure, dataTypesOfPanels) {
515
+ if (lastRow.jaql.sortDetails) {
516
+ // case 1: last row sorted
517
+ // then `.dir` and `.sortDetails` will be on row `.jaql`
518
+ // `direction` should be `undefined`
519
+ // `selected` should be `false`
520
+ return false;
521
+ }
522
+ if (currentSortDetailsOfCurrentMeasure) {
523
+ // case 2: measure sorted
524
+ // then `.dir` and `.sortDetails` will be on measure `.jaql`
525
+ // `direction` should be `currentSortDetailsOfCurrentMeasure.dir`
526
+ // `selected` should be `true`
527
+ return jaqlProcessor.isMeasurePathEqual(possibleSortDetailsOfCurrentMeasure.measurePath, currentSortDetailsOfCurrentMeasure.measurePath, dataTypesOfPanels);
528
+ }
529
+ // case 3: nothing sorted
530
+ return false;
531
+ }
532
+ function pickDirectionProperty(sd) {
533
+ const dir = sd && sd.dir;
534
+ switch (dir) {
535
+ case 'asc':
536
+ case 'desc':
537
+ return dir;
538
+ default:
539
+ return null;
540
+ }
541
+ }
542
+ function mapWidgetJaqlToComplexSortingSettings(jaql, possibleSortDetailsOfCurrentMeasure) {
543
+ var _a, _b;
544
+ const listOfRows = jaql.metadata.filter((meta) => meta.panel === 'rows'); // TODO: fix `any`
545
+ const metadataPanelOfCurrentMeasure = jaqlProcessor.getMetadataPanelByIndex(jaql, possibleSortDetailsOfCurrentMeasure.field); // TODO: fix `as`
546
+ // TODO: fix `as` type assertion
547
+ const datatype = metadataPanelOfCurrentMeasure.jaql.datatype;
548
+ // currentSortDetailsOfCurrentMeasure is not possibleSortDetailsOfCurrentMeasure
549
+ // (measurePath can be different)
550
+ const currentSortDetailsOfCurrentMeasure = metadataPanelOfCurrentMeasure.jaql // TODO: name it better
551
+ .sortDetails; // TODO: fix `SortDetails`
552
+ const dataTypesOfPanels = jaqlProcessor.getDataTypes(jaqlProcessor.getMetadataPanels(jaql));
553
+ const listOfSettingsEntries = [];
554
+ for (let index = 0; index < listOfRows.length - 1; index += 1) {
555
+ const row = listOfRows[index];
556
+ const isRowSortedBySubtotals = Boolean(row.jaql.sortDetails &&
557
+ row.jaql.sortDetails.field === possibleSortDetailsOfCurrentMeasure.field &&
558
+ jaqlProcessor.isMeasurePathEqual(possibleSortDetailsOfCurrentMeasure.measurePath, row.jaql.sortDetails.measurePath, dataTypesOfPanels));
559
+ const direction = pickDirectionProperty(row.jaql.sortDetails);
560
+ listOfSettingsEntries.push({
561
+ title: row.jaql.title,
562
+ // `datatype` should correspond to datatype of value column on which
563
+ // sorting settings was called
564
+ datatype,
565
+ selected: isRowSortedBySubtotals,
566
+ direction,
567
+ indexInJaql: (_a = row.field) === null || _a === void 0 ? void 0 : _a.index,
568
+ });
569
+ }
570
+ const lastRow = listOfRows[listOfRows.length - 1];
571
+ const isLastRowSortedByMeasure = checkLastRowSortedByMeasure(lastRow, possibleSortDetailsOfCurrentMeasure, currentSortDetailsOfCurrentMeasure, dataTypesOfPanels);
572
+ const direction = pickDirectionProperty(currentSortDetailsOfCurrentMeasure);
573
+ const lastEntry = {
574
+ title: lastRow.jaql.title,
575
+ // `datatype` should correspond to datatype of value column on which
576
+ // sorting settings was called
577
+ datatype,
578
+ selected: isLastRowSortedByMeasure,
579
+ direction,
580
+ indexInJaql: (_b = metadataPanelOfCurrentMeasure.field) === null || _b === void 0 ? void 0 : _b.index,
581
+ };
582
+ listOfSettingsEntries.push(lastEntry);
583
+ return listOfSettingsEntries;
584
+ }
585
+ function mapWidgetJaqlToSimpleSortingSettings(metadataPanels, possibleSortDetailsOfCurrentMeasure, dataTypes) {
586
+ const result = metadataPanels
587
+ .filter((meta) => {
588
+ // eslint-disable-line arrow-body-style
589
+ return meta.field && possibleSortDetailsOfCurrentMeasure.field === meta.field.index;
590
+ })
591
+ .map((metadataPanel) => {
592
+ const { sortDetails } = metadataPanel.jaql;
593
+ const selected = Boolean(sortDetails &&
594
+ jaqlProcessor.isMeasurePathEqual(possibleSortDetailsOfCurrentMeasure.measurePath, sortDetails.measurePath, dataTypes));
595
+ const direction = selected ? pickDirectionProperty(sortDetails) : null;
596
+ return {
597
+ title: metadataPanel.jaql.title,
598
+ // TODO: remove `as` type assertion
599
+ datatype: metadataPanel.jaql.datatype,
600
+ selected,
601
+ direction,
602
+ };
603
+ });
604
+ return result[0];
605
+ }
606
+ export default {
607
+ isMeasurePathEqual,
608
+ getDataTypes,
609
+ updatePanelsSortingMetadata,
610
+ getMetadataTree,
611
+ getMetadataPanels,
612
+ getMetadataPanelByIndex,
613
+ setResizeWidthToJaql,
614
+ getResizeWidthFromJaql,
615
+ markSortedNode,
616
+ normalizeSingleBranchTreeSortDetails,
617
+ updateLastAppliedSortingFlag,
618
+ handleComplexSortingSettingsUpdate,
619
+ mapWidgetJaqlToSimpleSortingSettings,
620
+ mapWidgetJaqlToComplexSortingSettings,
621
+ };
@@ -0,0 +1,74 @@
1
+ import { JaqlPanel, JaqlRequest } from '../../data-load/types.js';
2
+ import { TreeNode } from '../../tree-structure/types.js';
3
+ import { PivotDataNode, PivotTreeNode } from '../types.js';
4
+ export declare const insertSubTotals: (items: PivotTreeNode[], originalData: TreeNode | undefined, type: string, jaql: JaqlRequest | undefined, subtotalsForSingleRow: boolean | undefined) => Array<PivotTreeNode>;
5
+ export declare const postProcessSubTotal: (item: PivotTreeNode, jaql?: JaqlRequest) => void;
6
+ export declare const insertGrandTotals: (items: PivotTreeNode[], originalData: TreeNode | undefined, type: string, jaql?: JaqlRequest) => Array<PivotTreeNode>;
7
+ export declare const postProcessGrandTotal: (item: PivotTreeNode, jaql?: JaqlRequest) => void;
8
+ export declare const insertMeasureNodes: (items: PivotTreeNode[], originalData: TreeNode | undefined, type: string, jaql?: JaqlRequest) => Array<PivotTreeNode>;
9
+ export declare const postProcessMeasureNode: (item: PivotTreeNode, jaql?: JaqlRequest) => void;
10
+ export declare const applyColorFormatting: (item: PivotDataNode, rowItem: PivotTreeNode, columnItem: PivotTreeNode, measurePanel?: JaqlPanel) => void;
11
+ /**
12
+ * Pre-process initial tree structure
13
+ *
14
+ * @param {Array<TreeNode>} items - items to normalize
15
+ * @param {string} type - items types to normalize
16
+ * @param {JaqlRequest} jaql - jaql request
17
+ * @param {object} options - additional options
18
+ * @param {number} [options.level=0] - tree level, for internal use only
19
+ * @param {object} [options.measurePath={}] - items types to normalize
20
+ * @returns {Array<PivotTreeNode>} - normalized list of items
21
+ */
22
+ export declare const preProcessTree: (items: TreeNode | Array<TreeNode>, type: string, jaql: JaqlRequest, options?: {
23
+ level?: number | undefined;
24
+ measurePath?: {
25
+ [key: string]: string;
26
+ } | undefined;
27
+ } | undefined) => Array<PivotTreeNode>;
28
+ /**
29
+ * Post-process final tree structure with formatting event
30
+ *
31
+ * @param {PivotTreeNode} items - list of PivotTreeNode items
32
+ * @param {JaqlRequest} jaql - jaql request
33
+ * @param {object} [options] - additional options
34
+ * @param {boolean} [options.skipFormatEvent] - process tree but skip format event trigger
35
+ * @param {boolean} [options.onlyFormatEvents] - process tree with format event trigger only
36
+ * @param {Function} [options.iterateFn] - iterate function to call for each tree node
37
+ * @param {Function} [options.emitFn] - transform event emit function to call for each tree node
38
+ * @returns {void}
39
+ */
40
+ export declare const postProcessTree: (items: Array<PivotTreeNode>, jaql: JaqlRequest, options?: {
41
+ skipFormatEvent?: boolean | undefined;
42
+ onlyFormatEvents?: boolean | undefined;
43
+ iterateFn?: Function | undefined;
44
+ emitFn?: ((item: PivotTreeNode, panel: JaqlPanel | undefined, jaql: JaqlRequest) => void) | undefined;
45
+ } | undefined) => void;
46
+ declare const _default: {
47
+ insertSubTotals: (items: PivotTreeNode<any>[], originalData: TreeNode | undefined, type: string, jaql: JaqlRequest | undefined, subtotalsForSingleRow: boolean | undefined) => PivotTreeNode<any>[];
48
+ postProcessSubTotal: (item: PivotTreeNode<any>, jaql?: JaqlRequest | undefined) => void;
49
+ insertGrandTotals: (items: PivotTreeNode<any>[], originalData: TreeNode | undefined, type: string, jaql?: JaqlRequest | undefined) => PivotTreeNode<any>[];
50
+ postProcessGrandTotal: (item: PivotTreeNode<any>, jaql?: JaqlRequest | undefined) => void;
51
+ insertMeasureNodes: (items: PivotTreeNode<any>[], originalData: TreeNode | undefined, type: string, jaql?: JaqlRequest | undefined) => PivotTreeNode<any>[];
52
+ postProcessMeasureNode: (item: PivotTreeNode<any>, jaql?: JaqlRequest | undefined) => void;
53
+ applyColorFormatting: (item: PivotDataNode<any, import("../../index.js").InputStyles<{
54
+ [x: string]: string | number | null | undefined;
55
+ }>>, rowItem: PivotTreeNode<any>, columnItem: PivotTreeNode<any>, measurePanel?: JaqlPanel | undefined) => void;
56
+ preProcessTree: (items: TreeNode | TreeNode[], type: string, jaql: JaqlRequest, options?: {
57
+ level?: number | undefined;
58
+ measurePath?: {
59
+ [key: string]: string;
60
+ } | undefined;
61
+ } | undefined) => PivotTreeNode<any>[];
62
+ modifyTree: (items: PivotTreeNode<any>[], type: string, jaql: JaqlRequest, options?: {
63
+ originalData?: TreeNode | undefined;
64
+ applyIndexDivergence?: ((items: PivotTreeNode<any>[]) => void) | undefined;
65
+ subtotalsForSingleRow?: boolean | undefined;
66
+ } | undefined) => PivotTreeNode<any>[];
67
+ postProcessTree: (items: PivotTreeNode<any>[], jaql: JaqlRequest, options?: {
68
+ skipFormatEvent?: boolean | undefined;
69
+ onlyFormatEvents?: boolean | undefined;
70
+ iterateFn?: Function | undefined;
71
+ emitFn?: ((item: PivotTreeNode<any>, panel: JaqlPanel | undefined, jaql: JaqlRequest) => void) | undefined;
72
+ } | undefined) => void;
73
+ };
74
+ export default _default;