@finos/legend-data-cube 0.0.3 → 0.0.5

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 (108) hide show
  1. package/lib/components/editor/DataCubeEditorColumnPropertiesPanel.d.ts.map +1 -1
  2. package/lib/components/editor/DataCubeEditorColumnPropertiesPanel.js +7 -4
  3. package/lib/components/editor/DataCubeEditorColumnPropertiesPanel.js.map +1 -1
  4. package/lib/components/editor/DataCubeEditorGeneralPropertiesPanel.d.ts.map +1 -1
  5. package/lib/components/editor/DataCubeEditorGeneralPropertiesPanel.js +10 -15
  6. package/lib/components/editor/DataCubeEditorGeneralPropertiesPanel.js.map +1 -1
  7. package/lib/components/editor/DataCubeEditorSortsPanel.d.ts.map +1 -1
  8. package/lib/components/editor/DataCubeEditorSortsPanel.js +9 -9
  9. package/lib/components/editor/DataCubeEditorSortsPanel.js.map +1 -1
  10. package/lib/index.css +1 -1
  11. package/lib/package.json +1 -1
  12. package/lib/stores/core/DataCubeConfiguration.d.ts +13 -7
  13. package/lib/stores/core/DataCubeConfiguration.d.ts.map +1 -1
  14. package/lib/stores/core/DataCubeConfiguration.js +25 -15
  15. package/lib/stores/core/DataCubeConfiguration.js.map +1 -1
  16. package/lib/stores/core/DataCubeConfigurationBuilder.d.ts.map +1 -1
  17. package/lib/stores/core/DataCubeConfigurationBuilder.js +3 -2
  18. package/lib/stores/core/DataCubeConfigurationBuilder.js.map +1 -1
  19. package/lib/stores/core/DataCubeQueryBuilder.d.ts.map +1 -1
  20. package/lib/stores/core/DataCubeQueryBuilder.js +23 -17
  21. package/lib/stores/core/DataCubeQueryBuilder.js.map +1 -1
  22. package/lib/stores/core/DataCubeQueryBuilderUtils.js +2 -2
  23. package/lib/stores/core/DataCubeQueryBuilderUtils.js.map +1 -1
  24. package/lib/stores/core/DataCubeQueryEngine.d.ts +19 -11
  25. package/lib/stores/core/DataCubeQueryEngine.d.ts.map +1 -1
  26. package/lib/stores/core/DataCubeQueryEngine.js +21 -14
  27. package/lib/stores/core/DataCubeQueryEngine.js.map +1 -1
  28. package/lib/stores/core/DataCubeQuerySnapshot.d.ts +1 -1
  29. package/lib/stores/core/DataCubeQuerySnapshotBuilder.d.ts.map +1 -1
  30. package/lib/stores/core/DataCubeQuerySnapshotBuilder.js +131 -80
  31. package/lib/stores/core/DataCubeQuerySnapshotBuilder.js.map +1 -1
  32. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.d.ts +6 -7
  33. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.d.ts.map +1 -1
  34. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js +27 -91
  35. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js.map +1 -1
  36. package/lib/stores/core/DataCubeQuerySnapshotManager.js +1 -1
  37. package/lib/stores/core/DataCubeQuerySnapshotManager.js.map +1 -1
  38. package/lib/stores/editor/DataCubeEditorGeneralPropertiesPanelState.d.ts +1 -2
  39. package/lib/stores/editor/DataCubeEditorGeneralPropertiesPanelState.d.ts.map +1 -1
  40. package/lib/stores/editor/DataCubeEditorGeneralPropertiesPanelState.js +4 -6
  41. package/lib/stores/editor/DataCubeEditorGeneralPropertiesPanelState.js.map +1 -1
  42. package/lib/stores/editor/DataCubeEditorMutableConfiguration.d.ts +15 -8
  43. package/lib/stores/editor/DataCubeEditorMutableConfiguration.d.ts.map +1 -1
  44. package/lib/stores/editor/DataCubeEditorMutableConfiguration.js +50 -26
  45. package/lib/stores/editor/DataCubeEditorMutableConfiguration.js.map +1 -1
  46. package/lib/stores/editor/DataCubeEditorPivotLayoutPanelState.d.ts +30 -0
  47. package/lib/stores/editor/DataCubeEditorPivotLayoutPanelState.d.ts.map +1 -0
  48. package/lib/stores/editor/DataCubeEditorPivotLayoutPanelState.js +43 -0
  49. package/lib/stores/editor/DataCubeEditorPivotLayoutPanelState.js.map +1 -0
  50. package/lib/stores/editor/DataCubeEditorSortsPanelState.d.ts +3 -3
  51. package/lib/stores/editor/DataCubeEditorSortsPanelState.d.ts.map +1 -1
  52. package/lib/stores/editor/DataCubeEditorSortsPanelState.js +11 -11
  53. package/lib/stores/editor/DataCubeEditorSortsPanelState.js.map +1 -1
  54. package/lib/stores/editor/DataCubeEditorState.d.ts +2 -0
  55. package/lib/stores/editor/DataCubeEditorState.d.ts.map +1 -1
  56. package/lib/stores/editor/DataCubeEditorState.js +5 -0
  57. package/lib/stores/editor/DataCubeEditorState.js.map +1 -1
  58. package/lib/stores/extend/DataCubeExtendManagerState.js +1 -1
  59. package/lib/stores/extend/DataCubeExtendManagerState.js.map +1 -1
  60. package/lib/stores/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  61. package/lib/stores/grid/DataCubeGridClientEngine.js +41 -36
  62. package/lib/stores/grid/DataCubeGridClientEngine.js.map +1 -1
  63. package/lib/stores/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
  64. package/lib/stores/grid/DataCubeGridConfigurationBuilder.js +39 -3
  65. package/lib/stores/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
  66. package/lib/stores/grid/DataCubeGridControllerState.d.ts +6 -3
  67. package/lib/stores/grid/DataCubeGridControllerState.d.ts.map +1 -1
  68. package/lib/stores/grid/DataCubeGridControllerState.js +35 -17
  69. package/lib/stores/grid/DataCubeGridControllerState.js.map +1 -1
  70. package/lib/stores/grid/DataCubeGridMenuBuilder.d.ts.map +1 -1
  71. package/lib/stores/grid/DataCubeGridMenuBuilder.js +52 -31
  72. package/lib/stores/grid/DataCubeGridMenuBuilder.js.map +1 -1
  73. package/lib/stores/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
  74. package/lib/stores/grid/DataCubeGridQueryBuilder.js +3 -3
  75. package/lib/stores/grid/DataCubeGridQueryBuilder.js.map +1 -1
  76. package/lib/stores/grid/DataCubeGridQuerySnapshotBuilder.d.ts.map +1 -1
  77. package/lib/stores/grid/DataCubeGridQuerySnapshotBuilder.js +14 -7
  78. package/lib/stores/grid/DataCubeGridQuerySnapshotBuilder.js.map +1 -1
  79. package/lib/stores/grid/DataCubeGridState.d.ts.map +1 -1
  80. package/lib/stores/grid/DataCubeGridState.js +9 -5
  81. package/lib/stores/grid/DataCubeGridState.js.map +1 -1
  82. package/package.json +3 -3
  83. package/src/components/editor/DataCubeEditorColumnPropertiesPanel.tsx +11 -5
  84. package/src/components/editor/DataCubeEditorGeneralPropertiesPanel.tsx +94 -101
  85. package/src/components/editor/DataCubeEditorSortsPanel.tsx +12 -10
  86. package/src/stores/core/DataCubeConfiguration.ts +33 -15
  87. package/src/stores/core/DataCubeConfigurationBuilder.ts +3 -2
  88. package/src/stores/core/DataCubeQueryBuilder.ts +33 -20
  89. package/src/stores/core/DataCubeQueryBuilderUtils.ts +2 -2
  90. package/src/stores/core/DataCubeQueryEngine.ts +22 -12
  91. package/src/stores/core/DataCubeQuerySnapshot.ts +1 -1
  92. package/src/stores/core/DataCubeQuerySnapshotBuilder.ts +135 -120
  93. package/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts +33 -107
  94. package/src/stores/core/DataCubeQuerySnapshotManager.ts +1 -1
  95. package/src/stores/editor/DataCubeEditorGeneralPropertiesPanelState.ts +6 -9
  96. package/src/stores/editor/DataCubeEditorMutableConfiguration.ts +68 -28
  97. package/src/stores/editor/DataCubeEditorPivotLayoutPanelState.ts +71 -0
  98. package/src/stores/editor/DataCubeEditorSortsPanelState.ts +11 -11
  99. package/src/stores/editor/DataCubeEditorState.tsx +5 -0
  100. package/src/stores/extend/DataCubeExtendManagerState.tsx +1 -1
  101. package/src/stores/grid/DataCubeGridClientEngine.ts +52 -48
  102. package/src/stores/grid/DataCubeGridConfigurationBuilder.tsx +45 -4
  103. package/src/stores/grid/DataCubeGridControllerState.ts +44 -20
  104. package/src/stores/grid/DataCubeGridMenuBuilder.tsx +81 -52
  105. package/src/stores/grid/DataCubeGridQueryBuilder.ts +3 -7
  106. package/src/stores/grid/DataCubeGridQuerySnapshotBuilder.ts +20 -7
  107. package/src/stores/grid/DataCubeGridState.ts +9 -5
  108. package/tsconfig.json +1 -0
@@ -21,7 +21,7 @@ import {
21
21
  DataCubeFontCase,
22
22
  DataCubeFontFormatUnderlineVariant,
23
23
  DataCubeFontTextAlignment,
24
- DataCubeSelectionStat,
24
+ DataCubeQuerySortDirection,
25
25
  DEFAULT_BACKGROUND_COLOR,
26
26
  DEFAULT_ERROR_FOREGROUND_COLOR,
27
27
  DEFAULT_FOREGROUND_COLOR,
@@ -48,20 +48,18 @@ export const DataCubeEditorGeneralPropertiesPanel = observer(
48
48
  const { view } = props;
49
49
  const panel = view.editor.generalProperties;
50
50
  const configuration = panel.configuration;
51
+ const [
52
+ openTreeColumnSortDirectionDropdown,
53
+ closeTreeColumnSortDirectionDropdown,
54
+ treeColumnSortDirectionDropdownProps,
55
+ treeColumnSortDirectionDropdownPropsOpen,
56
+ ] = useDropdownMenu();
51
57
  const [
52
58
  openInitialExpandLevelDropdown,
53
59
  closeInitialExpandLevelDropdown,
54
60
  initialExpandLevelDropdownProps,
55
61
  initialExpandLevelDropdownPropsOpen,
56
62
  ] = useDropdownMenu();
57
- // TODO: selection stats should be shown as a list of checkboxes
58
- // rather than a dropdown!
59
- const [
60
- openSelectionStatDropdown,
61
- closeSelectionStatDropdown,
62
- selectionStatDropdownProps,
63
- selectionStatDropdownPropsOpen,
64
- ] = useDropdownMenu();
65
63
  const [
66
64
  openFontFamilyDropdown,
67
65
  closeFontFamilyDropdown,
@@ -109,12 +107,69 @@ export const DataCubeEditorGeneralPropertiesPanel = observer(
109
107
 
110
108
  <div className="mt-2 flex h-5 w-full items-center">
111
109
  <div className="flex h-full w-32 flex-shrink-0 items-center text-sm">
112
- Initially Expand to Level:
110
+ Tree Column:
111
+ </div>
112
+ <FormCheckbox
113
+ label="Show root aggregation"
114
+ checked={configuration.showRootAggregation}
115
+ onChange={() =>
116
+ configuration.setShowRootAggregation(
117
+ !configuration.showRootAggregation,
118
+ )
119
+ }
120
+ disabled={true}
121
+ />
122
+ <FormBadge_WIP />
123
+ <FormCheckbox
124
+ className="ml-3"
125
+ label="Show leaf count"
126
+ checked={configuration.showLeafCount}
127
+ onChange={() =>
128
+ configuration.setShowLeafCount(!configuration.showLeafCount)
129
+ }
130
+ />
131
+ <div className="ml-3 mr-1.5 flex h-full flex-shrink-0 items-center text-sm">
132
+ Sort:
133
+ </div>
134
+ <FormDropdownMenuTrigger
135
+ className="w-20"
136
+ onClick={openTreeColumnSortDirectionDropdown}
137
+ open={treeColumnSortDirectionDropdownPropsOpen}
138
+ >
139
+ {configuration.treeColumnSortDirection}
140
+ </FormDropdownMenuTrigger>
141
+ <FormDropdownMenu
142
+ className="w-20"
143
+ {...treeColumnSortDirectionDropdownProps}
144
+ >
145
+ {[
146
+ DataCubeQuerySortDirection.ASCENDING,
147
+ DataCubeQuerySortDirection.DESCENDING,
148
+ ].map((direction) => (
149
+ <FormDropdownMenuItem
150
+ key={direction}
151
+ onClick={() => {
152
+ configuration.setTreeColumnSortDirection(direction);
153
+ closeTreeColumnSortDirectionDropdown();
154
+ }}
155
+ autoFocus={
156
+ direction === configuration.treeColumnSortDirection
157
+ }
158
+ >
159
+ {direction}
160
+ </FormDropdownMenuItem>
161
+ ))}
162
+ </FormDropdownMenu>
163
+ </div>
164
+
165
+ <div className="mt-2 flex h-5 w-full items-center">
166
+ <div className="flex h-full w-32 flex-shrink-0 items-center text-sm" />
167
+ <div className="mr-1.5 flex h-full flex-shrink-0 items-center text-sm">
168
+ Initially expand to level:
113
169
  </div>
114
170
  <FormDropdownMenuTrigger
115
171
  className="w-16"
116
172
  onClick={openInitialExpandLevelDropdown}
117
- disabled={true}
118
173
  open={initialExpandLevelDropdownPropsOpen}
119
174
  >
120
175
  {configuration.initialExpandLevel ?? '(None)'}
@@ -136,33 +191,50 @@ export const DataCubeEditorGeneralPropertiesPanel = observer(
136
191
  </FormDropdownMenuItem>
137
192
  ))}
138
193
  </FormDropdownMenu>
139
- <FormBadge_WIP />
140
194
  </div>
141
195
 
142
196
  <div className="mt-2 flex h-5 w-full items-center">
143
197
  <div className="flex h-full w-32 flex-shrink-0 items-center text-sm">
144
- Show Root Aggregation?
198
+ Row Limit:
199
+ </div>
200
+ <FormNumberInput
201
+ className="w-16 text-sm"
202
+ value={panel.limit}
203
+ min={-1}
204
+ step={1}
205
+ defaultValue={-1}
206
+ isValid={(value) => value !== undefined && value >= -1}
207
+ setValue={(value) => panel.setLimit(value ?? -1)}
208
+ />
209
+ <div className="flex-shrink-0 pl-1 text-sm italic text-neutral-500">
210
+ Truncate result to this many rows at every level. Use -1 for
211
+ unlimited.
145
212
  </div>
213
+ </div>
214
+
215
+ <div className="mt-2 flex h-5 w-full items-center">
216
+ <div className="flex h-full w-32 flex-shrink-0 items-center text-sm" />
146
217
  <FormCheckbox
147
- checked={configuration.showRootAggregation}
218
+ label="Display warning when truncated"
219
+ checked={configuration.showWarningForTruncatedResult}
148
220
  onChange={() =>
149
- configuration.setShowRootAggregation(
150
- !configuration.showRootAggregation,
221
+ configuration.setShowWarningForTruncatedResult(
222
+ !configuration.showWarningForTruncatedResult,
151
223
  )
152
224
  }
153
- disabled={true}
154
225
  />
155
- <FormBadge_WIP />
156
226
  </div>
157
227
 
158
228
  <div className="mt-2 flex h-5 w-full items-center">
159
229
  <div className="flex h-full w-32 flex-shrink-0 items-center text-sm">
160
- Show Leaf Count?
230
+ Show Selection Stats?
161
231
  </div>
162
232
  <FormCheckbox
163
- checked={configuration.showLeafCount}
233
+ checked={configuration.showSelectionStats}
164
234
  onChange={() =>
165
- configuration.setShowLeafCount(!configuration.showLeafCount)
235
+ configuration.setShowSelectionStats(
236
+ !configuration.showSelectionStats,
237
+ )
166
238
  }
167
239
  disabled={true}
168
240
  />
@@ -174,16 +246,6 @@ export const DataCubeEditorGeneralPropertiesPanel = observer(
174
246
  Show Lines?
175
247
  </div>
176
248
  <FormCheckbox
177
- label="Tree"
178
- checked={configuration.showTreeLines}
179
- onChange={() =>
180
- configuration.setShowTreeLines(!configuration.showTreeLines)
181
- }
182
- disabled={true}
183
- />
184
- <FormBadge_WIP />
185
- <FormCheckbox
186
- className="ml-2"
187
249
  label="Horizontal"
188
250
  checked={configuration.showHorizontalGridLines}
189
251
  onChange={() =>
@@ -193,7 +255,7 @@ export const DataCubeEditorGeneralPropertiesPanel = observer(
193
255
  }
194
256
  />
195
257
  <FormCheckbox
196
- className="ml-2"
258
+ className="ml-3"
197
259
  label="Vertical"
198
260
  checked={configuration.showVerticalGridLines}
199
261
  onChange={() =>
@@ -211,75 +273,6 @@ export const DataCubeEditorGeneralPropertiesPanel = observer(
211
273
  />
212
274
  </div>
213
275
 
214
- <div className="mt-2 flex h-5 w-full items-center">
215
- <div className="flex h-full w-32 flex-shrink-0 items-center text-sm">
216
- Show Selection Stats:
217
- </div>
218
- <FormDropdownMenuTrigger
219
- className="w-16"
220
- onClick={openSelectionStatDropdown}
221
- disabled={true}
222
- open={selectionStatDropdownPropsOpen}
223
- >
224
- {'(None)'}
225
- </FormDropdownMenuTrigger>
226
- <FormDropdownMenu
227
- className="w-16"
228
- {...selectionStatDropdownProps}
229
- >
230
- {[
231
- DataCubeSelectionStat.SUM,
232
- DataCubeSelectionStat.AVERAGE,
233
- DataCubeSelectionStat.COUNT,
234
- DataCubeSelectionStat.MIN,
235
- DataCubeSelectionStat.MAX,
236
- ].map((operation) => (
237
- <FormDropdownMenuItem
238
- key={operation}
239
- onClick={() => {
240
- // TODO
241
- closeSelectionStatDropdown();
242
- }}
243
- >
244
- {operation}
245
- </FormDropdownMenuItem>
246
- ))}
247
- </FormDropdownMenu>
248
- <FormBadge_WIP />
249
- </div>
250
-
251
- <div className="mt-2 flex h-5 w-full items-center">
252
- <div className="flex h-full w-32 flex-shrink-0 items-center text-sm">
253
- Row Limit:
254
- </div>
255
- <FormNumberInput
256
- className="w-16 text-sm"
257
- value={panel.limit}
258
- min={-1}
259
- step={1}
260
- defaultValue={-1}
261
- isValid={(value) => value !== undefined && value >= -1}
262
- setValue={(value) => panel.setLimit(value ?? -1)}
263
- />
264
- <div className="flex-shrink-0 pl-1 text-sm italic text-neutral-500">
265
- Truncate result to this many rows at every level. Use -1 for
266
- unlimited.
267
- </div>
268
- </div>
269
-
270
- <div className="mt-2 flex h-5 w-full items-center">
271
- <div className="flex h-full w-32 flex-shrink-0 items-center text-sm" />
272
- <FormCheckbox
273
- label="Display warning when truncated"
274
- checked={configuration.showWarningForTruncatedResult}
275
- onChange={() =>
276
- configuration.setShowWarningForTruncatedResult(
277
- !configuration.showWarningForTruncatedResult,
278
- )
279
- }
280
- />
281
- </div>
282
-
283
276
  <div className="mt-2 flex h-5 w-full items-center">
284
277
  <div className="flex h-full w-32 flex-shrink-0 items-center text-sm">
285
278
  Hightlight Rows:
@@ -20,7 +20,7 @@ import { DataCubeEditorColumnsSelector } from './DataCubeEditorColumnsSelector.j
20
20
  import type { DataCubeEditorColumnsSelectorState } from '../../stores/editor/DataCubeEditorColumnsSelectorState.js';
21
21
  import type { DataCubeEditorSortColumnState } from '../../stores/editor/DataCubeEditorSortsPanelState.js';
22
22
  import {
23
- DataCubeQuerySortOperator,
23
+ DataCubeQuerySortDirection,
24
24
  PIVOT_COLUMN_NAME_VALUE_SEPARATOR,
25
25
  } from '../../stores/core/DataCubeQueryEngine.js';
26
26
  import { IllegalStateError } from '@finos/legend-shared';
@@ -33,9 +33,9 @@ import type { DataCubeViewState } from '../../stores/DataCubeViewState.js';
33
33
 
34
34
  function getSortDirectionLabel(operation: string) {
35
35
  switch (operation) {
36
- case DataCubeQuerySortOperator.ASCENDING:
36
+ case DataCubeQuerySortDirection.ASCENDING:
37
37
  return 'Ascending';
38
- case DataCubeQuerySortOperator.DESCENDING:
38
+ case DataCubeQuerySortDirection.DESCENDING:
39
39
  return 'Descending';
40
40
  default:
41
41
  throw new IllegalStateError(`Unsupported sort operation '${operation}'`);
@@ -59,12 +59,12 @@ const SortDirectionDropdown = observer(
59
59
  <div className="group relative flex h-full items-center">
60
60
  {!operationsDropdownPropsOpen && (
61
61
  <div className="flex h-[18px] w-32 items-center border border-transparent px-2 text-sm text-neutral-400 group-hover:invisible">
62
- {getSortDirectionLabel(column.operation)}
62
+ {getSortDirectionLabel(column.direction)}
63
63
  </div>
64
64
  )}
65
65
  {operationsDropdownPropsOpen && (
66
66
  <div className="flex h-[18px] w-32 items-center justify-between border border-sky-600 bg-sky-50 pl-2 pr-0.5 text-sm">
67
- <div>{getSortDirectionLabel(column.operation)}</div>
67
+ <div>{getSortDirectionLabel(column.direction)}</div>
68
68
  <div>
69
69
  <DataCubeIcon.CaretDown />
70
70
  </div>
@@ -83,7 +83,7 @@ const SortDirectionDropdown = observer(
83
83
  }}
84
84
  onClick={(event) => event.stopPropagation()}
85
85
  >
86
- <div>{getSortDirectionLabel(column.operation)}</div>
86
+ <div>{getSortDirectionLabel(column.direction)}</div>
87
87
  <div>
88
88
  <DataCubeIcon.CaretDown />
89
89
  </div>
@@ -91,10 +91,12 @@ const SortDirectionDropdown = observer(
91
91
  <FormDropdownMenu className="w-32" {...operationsDropdownProps}>
92
92
  <FormDropdownMenuItem
93
93
  onClick={() => {
94
- column.setOperation(DataCubeQuerySortOperator.ASCENDING);
94
+ column.setDirection(DataCubeQuerySortDirection.ASCENDING);
95
95
  closeOperationsDropdown();
96
96
  }}
97
- autoFocus={column.operation === DataCubeQuerySortOperator.ASCENDING}
97
+ autoFocus={
98
+ column.direction === DataCubeQuerySortDirection.ASCENDING
99
+ }
98
100
  >
99
101
  Ascending
100
102
  </FormDropdownMenuItem>
@@ -104,11 +106,11 @@ const SortDirectionDropdown = observer(
104
106
  </FormDropdownMenuItem>
105
107
  <FormDropdownMenuItem
106
108
  onClick={() => {
107
- column.setOperation(DataCubeQuerySortOperator.DESCENDING);
109
+ column.setDirection(DataCubeQuerySortDirection.DESCENDING);
108
110
  closeOperationsDropdown();
109
111
  }}
110
112
  autoFocus={
111
- column.operation === DataCubeQuerySortOperator.DESCENDING
113
+ column.direction === DataCubeQuerySortDirection.DESCENDING
112
114
  }
113
115
  >
114
116
  Descending
@@ -35,10 +35,11 @@ import {
35
35
  type DataCubeFontTextAlignment,
36
36
  type DataCubeFontFormatUnderlineVariant,
37
37
  type DataCubeNumberScale,
38
- type DataCubeSelectionStat,
39
38
  type DataCubeColumnPinPlacement,
40
39
  type DataCubeFontCase,
41
40
  type DataCubeOperationValue,
41
+ DEFAULT_PIVOT_STATISTIC_COLUMN_NAME,
42
+ DEFAULT_TREE_COLUMN_SORT_DIRECTION,
42
43
  } from './DataCubeQueryEngine.js';
43
44
  import { SerializationFactory, usingModelSchema } from '@finos/legend-shared';
44
45
  import { createModelSchema, list, optional, primitive, raw } from 'serializr';
@@ -104,8 +105,9 @@ export class DataCubeColumnConfiguration {
104
105
  // NOTE: these configurations, when changed, would potentially trigger data-fetching
105
106
  aggregateOperator!: string;
106
107
  aggregationParameters: DataCubeOperationValue[] = [];
107
- excludedFromHorizontalPivot = true; // this agrees with default column kind set as Dimension
108
- horizontalPivotSortFunction?: string | undefined;
108
+ excludedFromPivot = true; // this agrees with default column kind set as Dimension
109
+ pivotSortDirection?: string | undefined;
110
+ pivotStatisticColumnFunction?: string | undefined;
109
111
 
110
112
  constructor(name: string, type: string) {
111
113
  this.name = name;
@@ -123,7 +125,7 @@ export class DataCubeColumnConfiguration {
123
125
  displayName: optional(primitive()),
124
126
  errorBackgroundColor: optional(primitive()),
125
127
  errorForegroundColor: optional(primitive()),
126
- excludedFromHorizontalPivot: primitive(),
128
+ excludedFromPivot: primitive(),
127
129
  fixedWidth: optional(primitive()),
128
130
  fontBold: optional(primitive()),
129
131
  fontCase: optional(primitive()),
@@ -133,7 +135,6 @@ export class DataCubeColumnConfiguration {
133
135
  fontStrikethrough: optional(primitive()),
134
136
  fontUnderline: optional(primitive()),
135
137
  hideFromView: primitive(),
136
- horizontalPivotSortFunction: optional(primitive()),
137
138
  isSelected: primitive(),
138
139
  kind: primitive(),
139
140
  linkLabelParameter: optional(primitive()),
@@ -148,6 +149,8 @@ export class DataCubeColumnConfiguration {
148
149
  negativeNumberInParens: primitive(),
149
150
  numberScale: optional(primitive()),
150
151
  pinned: optional(primitive()),
152
+ pivotSortDirection: optional(primitive()),
153
+ pivotStatisticColumnFunction: optional(primitive()),
151
154
  textAlign: optional(primitive()),
152
155
  type: primitive(),
153
156
  zeroBackgroundColor: optional(primitive()),
@@ -156,11 +159,20 @@ export class DataCubeColumnConfiguration {
156
159
  );
157
160
  }
158
161
 
162
+ export class DataCubePivotLayoutConfiguration {
163
+ expandedPaths: string[] = [];
164
+
165
+ static readonly serialization = new SerializationFactory(
166
+ createModelSchema(DataCubePivotLayoutConfiguration, {
167
+ expandedPaths: list(primitive()),
168
+ }),
169
+ );
170
+ }
171
+
159
172
  export class DataCubeConfiguration {
160
173
  description?: string | undefined;
161
174
  columns: DataCubeColumnConfiguration[] = [];
162
175
 
163
- showTreeLines = false;
164
176
  showHorizontalGridLines = false;
165
177
  showVerticalGridLines = true;
166
178
  gridLineColor = DEFAULT_GRID_LINE_COLOR;
@@ -188,15 +200,18 @@ export class DataCubeConfiguration {
188
200
  alternateRowsColor = DEFAULT_ROW_HIGHLIGHT_BACKGROUND_COLOR;
189
201
  alternateRowsCount = 1;
190
202
 
191
- selectionStats: DataCubeSelectionStat[] = [];
203
+ showSelectionStats = false;
192
204
  showWarningForTruncatedResult = true;
193
205
 
194
- // NOTE: these configurations, when changed, would potentially trigger data-fetching
206
+ // these configurations, when changed, would potentially trigger data-fetching
195
207
  initialExpandLevel?: number | undefined;
196
208
  showRootAggregation = false;
197
- showLeafCount = false;
198
- pivotTotalColumnPlacement?: DataCubeColumnPinPlacement | undefined;
199
- treeGroupSortFunction?: string | undefined;
209
+ showLeafCount = true;
210
+ treeColumnSortDirection = DEFAULT_TREE_COLUMN_SORT_DIRECTION;
211
+ pivotStatisticColumnName = DEFAULT_PIVOT_STATISTIC_COLUMN_NAME;
212
+ pivotStatisticColumnPlacement?: DataCubeColumnPinPlacement | undefined; // unspecified -> hide the column
213
+
214
+ pivotLayout = new DataCubePivotLayoutConfiguration();
200
215
 
201
216
  static readonly serialization = new SerializationFactory(
202
217
  createModelSchema(DataCubeConfiguration, {
@@ -223,16 +238,19 @@ export class DataCubeConfiguration {
223
238
  negativeForegroundColor: primitive(),
224
239
  normalBackgroundColor: primitive(),
225
240
  normalForegroundColor: primitive(),
226
- pivotTotalColumnPlacement: optional(primitive()),
227
- selectionStats: list(primitive()),
241
+ pivotStatisticColumnName: primitive(),
242
+ pivotStatisticColumnPlacement: optional(primitive()),
243
+ pivotLayout: usingModelSchema(
244
+ DataCubePivotLayoutConfiguration.serialization.schema,
245
+ ),
228
246
  showHorizontalGridLines: primitive(),
229
247
  showLeafCount: primitive(),
248
+ showSelectionStats: primitive(),
230
249
  showRootAggregation: primitive(),
231
- showTreeLines: primitive(),
232
250
  showVerticalGridLines: primitive(),
233
251
  showWarningForTruncatedResult: primitive(),
234
252
  textAlign: primitive(),
235
- treeGroupSortFunction: optional(primitive()),
253
+ treeColumnSortDirection: primitive(),
236
254
  zeroBackgroundColor: primitive(),
237
255
  zeroForegroundColor: primitive(),
238
256
  }),
@@ -41,13 +41,14 @@ export function buildDefaultColumnConfiguration(column: {
41
41
  config.displayCommas = true;
42
42
  config.negativeNumberInParens = true;
43
43
  config.textAlign = DataCubeFontTextAlignment.RIGHT; // always align number to the right
44
- config.excludedFromHorizontalPivot = false;
44
+ config.excludedFromPivot = false;
45
45
  config.aggregateOperator = DataCubeAggregateOperator.SUM;
46
+ config.pivotStatisticColumnFunction = DataCubeAggregateOperator.SUM;
46
47
  break;
47
48
  }
48
49
  default: {
49
50
  config.kind = DataCubeColumnKind.DIMENSION;
50
- config.excludedFromHorizontalPivot = true;
51
+ config.excludedFromPivot = true;
51
52
  config.aggregateOperator = DataCubeAggregateOperator.UNIQUE;
52
53
  break;
53
54
  }
@@ -25,7 +25,6 @@ import {
25
25
  PRIMITIVE_TYPE,
26
26
  type V1_AppliedFunction,
27
27
  V1_deserializeValueSpecification,
28
- extractElementNameFromPath as _name,
29
28
  } from '@finos/legend-graph';
30
29
  import {
31
30
  type DataCubeQuerySnapshot,
@@ -39,7 +38,7 @@ import {
39
38
  import {
40
39
  DataCubeExtendedColumnType,
41
40
  DataCubeFunction,
42
- DataCubeQuerySortOperator,
41
+ DataCubeQuerySortDirection,
43
42
  type DataCubeQueryFunctionMap,
44
43
  } from './DataCubeQueryEngine.js';
45
44
  import { DataCubeConfiguration } from './DataCubeConfiguration.js';
@@ -98,7 +97,7 @@ export function buildExecutableQuery(
98
97
  if (data.leafExtendedColumns.length) {
99
98
  _process(
100
99
  'leafExtend',
101
- _function(_name(DataCubeFunction.EXTEND), [
100
+ _function(DataCubeFunction.EXTEND, [
102
101
  _cols(
103
102
  data.leafExtendedColumns.map((col) => {
104
103
  if (col._type === DataCubeExtendedColumnType.SIMPLE) {
@@ -119,7 +118,7 @@ export function buildExecutableQuery(
119
118
  if (data.filter) {
120
119
  _process(
121
120
  'filter',
122
- _function(_name(DataCubeFunction.FILTER), [
121
+ _function(DataCubeFunction.FILTER, [
123
122
  _lambda([_var()], [_filter(data.filter, filterOperations)]),
124
123
  ]),
125
124
  );
@@ -130,7 +129,7 @@ export function buildExecutableQuery(
130
129
  if (data.selectColumns.length) {
131
130
  _process(
132
131
  'select',
133
- _function(_name(DataCubeFunction.SELECT), [
132
+ _function(DataCubeFunction.SELECT, [
134
133
  _cols(data.selectColumns.map((col) => _colSpec(col.name))),
135
134
  ]),
136
135
  );
@@ -144,10 +143,10 @@ export function buildExecutableQuery(
144
143
  // pre-sort to maintain stable order for pivot result columns
145
144
  _process(
146
145
  'sort',
147
- _function(_name(DataCubeFunction.SORT), [
146
+ _function(DataCubeFunction.SORT, [
148
147
  _collection(
149
148
  data.pivot.columns.map((col) =>
150
- _function(_name(DataCubeFunction.ASC), [_col(col.name)]),
149
+ _function(DataCubeFunction.ASC, [_col(col.name)]),
151
150
  ),
152
151
  ),
153
152
  ]),
@@ -155,7 +154,7 @@ export function buildExecutableQuery(
155
154
 
156
155
  _process(
157
156
  'pivot',
158
- _function(_name(DataCubeFunction.PIVOT), [
157
+ _function(DataCubeFunction.PIVOT, [
159
158
  _cols(pivot.columns.map((col) => _colSpec(col.name))),
160
159
  _cols(
161
160
  _pivotAggCols(
@@ -171,7 +170,7 @@ export function buildExecutableQuery(
171
170
  if (pivot.castColumns.length) {
172
171
  _process(
173
172
  'pivotCast',
174
- _function(_name(DataCubeFunction.CAST), [_castCols(pivot.castColumns)]),
173
+ _function(DataCubeFunction.CAST, [_castCols(pivot.castColumns)]),
175
174
  );
176
175
  }
177
176
  }
@@ -182,7 +181,7 @@ export function buildExecutableQuery(
182
181
  const groupBy = data.groupBy;
183
182
  _process(
184
183
  'groupBy',
185
- _function(_name(DataCubeFunction.GROUP_BY), [
184
+ _function(DataCubeFunction.GROUP_BY, [
186
185
  _cols(groupBy.columns.map((col) => _colSpec(col.name))),
187
186
  _cols(
188
187
  _groupByAggCols(
@@ -194,6 +193,22 @@ export function buildExecutableQuery(
194
193
  ),
195
194
  ]),
196
195
  );
196
+ _process(
197
+ 'groupBySort',
198
+ _function(DataCubeFunction.SORT, [
199
+ _collection(
200
+ groupBy.columns.map((col) =>
201
+ _function(
202
+ configuration.treeColumnSortDirection ===
203
+ DataCubeQuerySortDirection.ASCENDING
204
+ ? DataCubeFunction.ASC
205
+ : DataCubeFunction.DESC,
206
+ [_col(col.name)],
207
+ ),
208
+ ),
209
+ ),
210
+ ]),
211
+ );
197
212
  }
198
213
 
199
214
  // --------------------------------- GROUP-LEVEL EXTEND ---------------------------------
@@ -201,7 +216,7 @@ export function buildExecutableQuery(
201
216
  if (data.groupExtendedColumns.length) {
202
217
  _process(
203
218
  'groupExtend',
204
- _function(_name(DataCubeFunction.EXTEND), [
219
+ _function(DataCubeFunction.EXTEND, [
205
220
  _cols(
206
221
  data.groupExtendedColumns.map((col) => {
207
222
  if (col._type === DataCubeExtendedColumnType.SIMPLE) {
@@ -222,15 +237,13 @@ export function buildExecutableQuery(
222
237
  if (data.sortColumns.length) {
223
238
  _process(
224
239
  'sort',
225
- _function(_name(DataCubeFunction.SORT), [
240
+ _function(DataCubeFunction.SORT, [
226
241
  _collection(
227
242
  data.sortColumns.map((col) =>
228
243
  _function(
229
- _name(
230
- col.operation === DataCubeQuerySortOperator.ASCENDING
231
- ? DataCubeFunction.ASC
232
- : DataCubeFunction.DESC,
233
- ),
244
+ col.direction === DataCubeQuerySortDirection.ASCENDING
245
+ ? DataCubeFunction.ASC
246
+ : DataCubeFunction.DESC,
234
247
  [_col(col.name)],
235
248
  ),
236
249
  ),
@@ -244,7 +257,7 @@ export function buildExecutableQuery(
244
257
  if (data.limit !== undefined) {
245
258
  _process(
246
259
  'limit',
247
- _function(_name(DataCubeFunction.LIMIT), [
260
+ _function(DataCubeFunction.LIMIT, [
248
261
  _primitiveValue(PRIMITIVE_TYPE.INTEGER, data.limit),
249
262
  ]),
250
263
  );
@@ -254,7 +267,7 @@ export function buildExecutableQuery(
254
267
 
255
268
  if (options?.pagination) {
256
269
  sequence.push(
257
- _function(_name(DataCubeFunction.SLICE), [
270
+ _function(DataCubeFunction.SLICE, [
258
271
  _primitiveValue(PRIMITIVE_TYPE.INTEGER, options.pagination.start),
259
272
  _primitiveValue(PRIMITIVE_TYPE.INTEGER, options.pagination.end),
260
273
  ]),
@@ -265,7 +278,7 @@ export function buildExecutableQuery(
265
278
 
266
279
  sequence.push(
267
280
  _function(
268
- _name(DataCubeFunction.FROM),
281
+ DataCubeFunction.FROM,
269
282
  [
270
283
  data.mapping ? _elementPtr(data.mapping) : undefined,
271
284
  _elementPtr(data.runtime),
@@ -352,7 +352,7 @@ export function _pivotAggCols(
352
352
  // are not helpful and therefore excluded
353
353
  column.kind === DataCubeColumnKind.MEASURE &&
354
354
  !pivotColumns.find((col) => col.name === column.name) &&
355
- !column.excludedFromHorizontalPivot &&
355
+ !column.excludedFromPivot &&
356
356
  !snapshot.data.groupExtendedColumns.find(
357
357
  (col) => col.name === column.name,
358
358
  ),
@@ -453,7 +453,7 @@ export function _groupByAggCols(
453
453
  }
454
454
  return aggCol;
455
455
  }),
456
- // these are the columns which are available for group-by but not selected for group-by
456
+ // these are the columns which are available for groupBy but not selected for groupBy
457
457
  // operation, they would be aggregated as well
458
458
  ...pivotGroupByColumns
459
459
  .filter(