@finos/legend-application-repl 0.0.56 → 0.0.58

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 (143) hide show
  1. package/lib/components/dataCube/editor/DataCubeEditor.d.ts.map +1 -1
  2. package/lib/components/dataCube/editor/DataCubeEditor.js +2 -4
  3. package/lib/components/dataCube/editor/DataCubeEditor.js.map +1 -1
  4. package/lib/components/dataCube/editor/DataCubeEditorColumnsPanel.js +1 -1
  5. package/lib/components/dataCube/editor/DataCubeEditorColumnsPanel.js.map +1 -1
  6. package/lib/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.d.ts.map +1 -1
  7. package/lib/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.js +5 -1
  8. package/lib/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.js.map +1 -1
  9. package/lib/components/dataCube/extend/DataCubeColumnEditor.d.ts.map +1 -1
  10. package/lib/components/dataCube/extend/DataCubeColumnEditor.js +2 -1
  11. package/lib/components/dataCube/extend/DataCubeColumnEditor.js.map +1 -1
  12. package/lib/components/dataCube/grid/DataCubeGrid.js +2 -2
  13. package/lib/components/dataCube/grid/DataCubeGrid.js.map +1 -1
  14. package/lib/components/repl/Form.js +1 -1
  15. package/lib/components/repl/Form.js.map +1 -1
  16. package/lib/index.css +2 -2
  17. package/lib/index.css.map +1 -1
  18. package/lib/package.json +18 -18
  19. package/lib/stores/dataCube/DataCubeEngine.d.ts +1 -1
  20. package/lib/stores/dataCube/DataCubeEngine.d.ts.map +1 -1
  21. package/lib/stores/dataCube/DataCubeEngine.js.map +1 -1
  22. package/lib/stores/dataCube/core/DataCubeConfiguration.d.ts +3 -4
  23. package/lib/stores/dataCube/core/DataCubeConfiguration.d.ts.map +1 -1
  24. package/lib/stores/dataCube/core/DataCubeConfiguration.js +6 -8
  25. package/lib/stores/dataCube/core/DataCubeConfiguration.js.map +1 -1
  26. package/lib/stores/dataCube/core/DataCubeQueryBuilder.d.ts.map +1 -1
  27. package/lib/stores/dataCube/core/DataCubeQueryBuilder.js +26 -13
  28. package/lib/stores/dataCube/core/DataCubeQueryBuilder.js.map +1 -1
  29. package/lib/stores/dataCube/core/DataCubeQueryBuilderUtils.d.ts +4 -2
  30. package/lib/stores/dataCube/core/DataCubeQueryBuilderUtils.d.ts.map +1 -1
  31. package/lib/stores/dataCube/core/DataCubeQueryBuilderUtils.js +83 -13
  32. package/lib/stores/dataCube/core/DataCubeQueryBuilderUtils.js.map +1 -1
  33. package/lib/stores/dataCube/core/DataCubeQueryEngine.d.ts +6 -7
  34. package/lib/stores/dataCube/core/DataCubeQueryEngine.d.ts.map +1 -1
  35. package/lib/stores/dataCube/core/DataCubeQueryEngine.js +4 -7
  36. package/lib/stores/dataCube/core/DataCubeQueryEngine.js.map +1 -1
  37. package/lib/stores/dataCube/core/DataCubeQuerySnapshot.d.ts +1 -10
  38. package/lib/stores/dataCube/core/DataCubeQuerySnapshot.d.ts.map +1 -1
  39. package/lib/stores/dataCube/core/DataCubeQuerySnapshot.js +23 -17
  40. package/lib/stores/dataCube/core/DataCubeQuerySnapshot.js.map +1 -1
  41. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.d.ts.map +1 -1
  42. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.js +67 -73
  43. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.js.map +1 -1
  44. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.d.ts +1 -0
  45. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.d.ts.map +1 -1
  46. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.js +21 -5
  47. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.js.map +1 -1
  48. package/lib/stores/dataCube/editor/DataCubeEditorColumnsPanelState.d.ts +9 -1
  49. package/lib/stores/dataCube/editor/DataCubeEditorColumnsPanelState.d.ts.map +1 -1
  50. package/lib/stores/dataCube/editor/DataCubeEditorColumnsPanelState.js +33 -10
  51. package/lib/stores/dataCube/editor/DataCubeEditorColumnsPanelState.js.map +1 -1
  52. package/lib/stores/dataCube/editor/DataCubeEditorHorizontalPivotsPanelState.d.ts +7 -1
  53. package/lib/stores/dataCube/editor/DataCubeEditorHorizontalPivotsPanelState.d.ts.map +1 -1
  54. package/lib/stores/dataCube/editor/DataCubeEditorHorizontalPivotsPanelState.js +41 -3
  55. package/lib/stores/dataCube/editor/DataCubeEditorHorizontalPivotsPanelState.js.map +1 -1
  56. package/lib/stores/dataCube/editor/DataCubeEditorMutableConfiguration.d.ts +1 -2
  57. package/lib/stores/dataCube/editor/DataCubeEditorMutableConfiguration.d.ts.map +1 -1
  58. package/lib/stores/dataCube/editor/DataCubeEditorMutableConfiguration.js +4 -9
  59. package/lib/stores/dataCube/editor/DataCubeEditorMutableConfiguration.js.map +1 -1
  60. package/lib/stores/dataCube/editor/DataCubeEditorSortsPanelState.d.ts +1 -0
  61. package/lib/stores/dataCube/editor/DataCubeEditorSortsPanelState.d.ts.map +1 -1
  62. package/lib/stores/dataCube/editor/DataCubeEditorSortsPanelState.js +7 -2
  63. package/lib/stores/dataCube/editor/DataCubeEditorSortsPanelState.js.map +1 -1
  64. package/lib/stores/dataCube/editor/DataCubeEditorState.d.ts +2 -5
  65. package/lib/stores/dataCube/editor/DataCubeEditorState.d.ts.map +1 -1
  66. package/lib/stores/dataCube/editor/DataCubeEditorState.js +39 -21
  67. package/lib/stores/dataCube/editor/DataCubeEditorState.js.map +1 -1
  68. package/lib/stores/dataCube/editor/DataCubeEditorVerticalPivotsPanelState.d.ts +1 -0
  69. package/lib/stores/dataCube/editor/DataCubeEditorVerticalPivotsPanelState.d.ts.map +1 -1
  70. package/lib/stores/dataCube/editor/DataCubeEditorVerticalPivotsPanelState.js +6 -1
  71. package/lib/stores/dataCube/editor/DataCubeEditorVerticalPivotsPanelState.js.map +1 -1
  72. package/lib/stores/dataCube/extend/DataCubeColumnEditorState.d.ts.map +1 -1
  73. package/lib/stores/dataCube/extend/DataCubeColumnEditorState.js +1 -1
  74. package/lib/stores/dataCube/extend/DataCubeColumnEditorState.js.map +1 -1
  75. package/lib/stores/dataCube/extend/DataCubeExtendManagerState.d.ts +1 -1
  76. package/lib/stores/dataCube/extend/DataCubeExtendManagerState.d.ts.map +1 -1
  77. package/lib/stores/dataCube/extend/DataCubeExtendManagerState.js +8 -2
  78. package/lib/stores/dataCube/extend/DataCubeExtendManagerState.js.map +1 -1
  79. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.d.ts +12 -3
  80. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  81. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.js +94 -9
  82. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.js.map +1 -1
  83. package/lib/stores/dataCube/grid/DataCubeGridConfigurationBuilder.d.ts +193 -1
  84. package/lib/stores/dataCube/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
  85. package/lib/stores/dataCube/grid/DataCubeGridConfigurationBuilder.js +176 -82
  86. package/lib/stores/dataCube/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
  87. package/lib/stores/dataCube/grid/DataCubeGridControllerState.d.ts +8 -0
  88. package/lib/stores/dataCube/grid/DataCubeGridControllerState.d.ts.map +1 -1
  89. package/lib/stores/dataCube/grid/DataCubeGridControllerState.js +69 -5
  90. package/lib/stores/dataCube/grid/DataCubeGridControllerState.js.map +1 -1
  91. package/lib/stores/dataCube/grid/DataCubeGridMenuBuilder.d.ts.map +1 -1
  92. package/lib/stores/dataCube/grid/DataCubeGridMenuBuilder.js +69 -20
  93. package/lib/stores/dataCube/grid/DataCubeGridMenuBuilder.js.map +1 -1
  94. package/lib/stores/dataCube/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
  95. package/lib/stores/dataCube/grid/DataCubeGridQueryBuilder.js +0 -2
  96. package/lib/stores/dataCube/grid/DataCubeGridQueryBuilder.js.map +1 -1
  97. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotBuilder.js +2 -2
  98. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotBuilder.js.map +1 -1
  99. package/lib/stores/dataCube/grid/DataCubeGridState.d.ts +2 -11
  100. package/lib/stores/dataCube/grid/DataCubeGridState.d.ts.map +1 -1
  101. package/lib/stores/dataCube/grid/DataCubeGridState.js +15 -36
  102. package/lib/stores/dataCube/grid/DataCubeGridState.js.map +1 -1
  103. package/package.json +24 -24
  104. package/src/components/dataCube/editor/DataCubeEditor.tsx +2 -7
  105. package/src/components/dataCube/editor/DataCubeEditorColumnsPanel.tsx +1 -1
  106. package/src/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.tsx +19 -1
  107. package/src/components/dataCube/extend/DataCubeColumnEditor.tsx +2 -1
  108. package/src/components/dataCube/grid/DataCubeGrid.tsx +2 -2
  109. package/src/components/repl/Form.tsx +1 -1
  110. package/src/stores/dataCube/DataCubeEngine.ts +1 -1
  111. package/src/stores/dataCube/core/DataCubeConfiguration.ts +7 -9
  112. package/src/stores/dataCube/core/DataCubeQueryBuilder.ts +52 -13
  113. package/src/stores/dataCube/core/DataCubeQueryBuilderUtils.ts +142 -18
  114. package/src/stores/dataCube/core/DataCubeQueryEngine.ts +9 -13
  115. package/src/stores/dataCube/core/DataCubeQuerySnapshot.ts +24 -21
  116. package/src/stores/dataCube/core/DataCubeQuerySnapshotBuilder.ts +122 -113
  117. package/src/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.ts +33 -12
  118. package/src/stores/dataCube/editor/DataCubeEditorColumnsPanelState.ts +34 -28
  119. package/src/stores/dataCube/editor/DataCubeEditorHorizontalPivotsPanelState.ts +64 -5
  120. package/src/stores/dataCube/editor/DataCubeEditorMutableConfiguration.ts +4 -11
  121. package/src/stores/dataCube/editor/DataCubeEditorSortsPanelState.ts +17 -5
  122. package/src/stores/dataCube/editor/DataCubeEditorState.tsx +45 -22
  123. package/src/stores/dataCube/editor/DataCubeEditorVerticalPivotsPanelState.ts +12 -0
  124. package/src/stores/dataCube/extend/DataCubeColumnEditorState.tsx +1 -0
  125. package/src/stores/dataCube/extend/DataCubeExtendManagerState.tsx +9 -1
  126. package/src/stores/dataCube/grid/DataCubeGridClientEngine.ts +150 -10
  127. package/src/stores/dataCube/grid/DataCubeGridConfigurationBuilder.tsx +217 -81
  128. package/src/stores/dataCube/grid/DataCubeGridControllerState.ts +97 -4
  129. package/src/stores/dataCube/grid/DataCubeGridMenuBuilder.tsx +91 -24
  130. package/src/stores/dataCube/grid/DataCubeGridQueryBuilder.ts +0 -3
  131. package/src/stores/dataCube/grid/DataCubeGridQuerySnapshotBuilder.ts +2 -2
  132. package/src/stores/dataCube/grid/DataCubeGridState.ts +23 -45
  133. package/tsconfig.json +0 -2
  134. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.d.ts +0 -22
  135. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.d.ts.map +0 -1
  136. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.js +0 -26
  137. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.js.map +0 -1
  138. package/lib/stores/dataCube/editor/DataCubeEditorCodePanelState.d.ts +0 -39
  139. package/lib/stores/dataCube/editor/DataCubeEditorCodePanelState.d.ts.map +0 -1
  140. package/lib/stores/dataCube/editor/DataCubeEditorCodePanelState.js +0 -89
  141. package/lib/stores/dataCube/editor/DataCubeEditorCodePanelState.js.map +0 -1
  142. package/src/components/dataCube/editor/DataCubeEditorCodePanel.tsx +0 -43
  143. package/src/stores/dataCube/editor/DataCubeEditorCodePanelState.ts +0 -167
@@ -17,7 +17,6 @@
17
17
  import { action, makeObservable, observable } from 'mobx';
18
18
  import type { DataCubeState } from '../DataCubeState.js';
19
19
  import { DataCubeEditorSortsPanelState } from './DataCubeEditorSortsPanelState.js';
20
- import { DataCubeEditorCodePanelState } from './DataCubeEditorCodePanelState.js';
21
20
  import { DataCubeQuerySnapshotController } from '../core/DataCubeQuerySnapshotManager.js';
22
21
  import { type DataCubeQuerySnapshot } from '../core/DataCubeQuerySnapshot.js';
23
22
  import {
@@ -43,7 +42,6 @@ export enum DataCubeEditorTab {
43
42
  VERTICAL_PIVOTS = 'Vertical Pivots',
44
43
  HORIZONTAL_PIVOTS = 'Horizontal Pivots',
45
44
  SORTS = 'Sorts',
46
- CODE = 'Code',
47
45
  }
48
46
 
49
47
  /**
@@ -59,14 +57,12 @@ export class DataCubeEditorState extends DataCubeQuerySnapshotController {
59
57
  readonly display: DisplayState;
60
58
  readonly finalizationState = ActionState.create();
61
59
 
62
- readonly code: DataCubeEditorCodePanelState;
63
-
64
60
  readonly generalProperties: DataCubeEditorGeneralPropertiesPanelState;
65
61
  readonly columnProperties: DataCubeEditorColumnPropertiesPanelState;
66
62
 
67
63
  readonly columns: DataCubeEditorColumnsPanelState;
68
- readonly verticalPivots: DataCubeEditorVerticalPivotsPanelState;
69
64
  readonly horizontalPivots: DataCubeEditorHorizontalPivotsPanelState;
65
+ readonly verticalPivots: DataCubeEditorVerticalPivotsPanelState;
70
66
  readonly sorts: DataCubeEditorSortsPanelState;
71
67
 
72
68
  currentTab = DataCubeEditorTab.GENERAL_PROPERTIES;
@@ -91,10 +87,9 @@ export class DataCubeEditorState extends DataCubeQuerySnapshotController {
91
87
  );
92
88
  this.columnProperties = new DataCubeEditorColumnPropertiesPanelState(this);
93
89
  this.columns = new DataCubeEditorColumnsPanelState(this);
94
- this.verticalPivots = new DataCubeEditorVerticalPivotsPanelState(this);
95
90
  this.horizontalPivots = new DataCubeEditorHorizontalPivotsPanelState(this);
91
+ this.verticalPivots = new DataCubeEditorVerticalPivotsPanelState(this);
96
92
  this.sorts = new DataCubeEditorSortsPanelState(this);
97
- this.code = new DataCubeEditorCodePanelState(this);
98
93
  }
99
94
 
100
95
  setCurrentTab(val: DataCubeEditorTab) {
@@ -105,32 +100,59 @@ export class DataCubeEditorState extends DataCubeQuerySnapshotController {
105
100
  this.finalizationState.inProgress();
106
101
 
107
102
  const baseSnapshot = guaranteeNonNullable(this.getLatestSnapshot());
108
- const snapshot = baseSnapshot.clone();
103
+ const newSnapshot = baseSnapshot.clone();
109
104
 
110
105
  // NOTE: column selection must be processed first so necessary
111
106
  // prunings can be done to make sure other panel stats are in sync
112
107
  // with the current column selection
113
- this.columns.buildSnapshot(snapshot, baseSnapshot);
114
- this.verticalPivots.buildSnapshot(snapshot, baseSnapshot);
115
- this.horizontalPivots.buildSnapshot(snapshot, baseSnapshot);
116
- this.sorts.buildSnapshot(snapshot, baseSnapshot);
108
+ this.columns.buildSnapshot(newSnapshot, baseSnapshot);
109
+ this.horizontalPivots.buildSnapshot(newSnapshot, baseSnapshot);
110
+ this.verticalPivots.buildSnapshot(newSnapshot, baseSnapshot);
111
+ this.sorts.buildSnapshot(newSnapshot, baseSnapshot);
117
112
 
118
113
  // grid configuration must be processed before processing columns' configuration
119
114
  // to properly generate the container configuration
120
- this.generalProperties.buildSnapshot(snapshot, baseSnapshot);
121
- this.columnProperties.buildSnapshot(snapshot, baseSnapshot);
115
+ this.generalProperties.buildSnapshot(newSnapshot, baseSnapshot);
116
+ this.columnProperties.buildSnapshot(newSnapshot, baseSnapshot);
117
+
118
+ newSnapshot.finalize();
119
+ if (newSnapshot.hashCode === baseSnapshot.hashCode) {
120
+ if (options?.closeAfterApply) {
121
+ this.display.close();
122
+ }
123
+ this.finalizationState.complete();
124
+ return;
125
+ }
122
126
 
123
- // compile the query to validate it
124
- // NOTE: This is a helpful check for a lot of different scenarios where the
125
- // consistency of the query might be thrown off by changes
127
+ // NOTE: Compile the query to validate. This is a helpful check for a lot of different scenarios
128
+ // where the consistency of the query might be thrown off by changes from various parts that the
129
+ // editor does not have full control over (i.e. extended columns, pivot cast columns, etc.)
126
130
  // e.g. when a column that group-level extended columns' expressions depend on has been unselected.
127
131
  try {
132
+ const tempSnapshot = newSnapshot.clone();
133
+ // NOTE: in order to obtain the actual pivot result columns information, we need to execute
134
+ // the query which is expensive in certain cases, so here, we just compute the "optimistic" set
135
+ // of pivot result columns for casting to guarantee validation is not thronn off.
136
+ if (tempSnapshot.data.pivot) {
137
+ tempSnapshot.data.pivot.castColumns =
138
+ this.sorts.selector.availableColumns
139
+ .filter(
140
+ (col) =>
141
+ !tempSnapshot.data.groupExtendedColumns.find(
142
+ (column) => column.name === col.name,
143
+ ),
144
+ )
145
+ .map((col) => ({
146
+ name: col.name,
147
+ type: col.type,
148
+ }));
149
+ }
128
150
  await this.dataCube.engine.getQueryRelationType(
129
151
  _lambda(
130
152
  [],
131
153
  [
132
154
  buildExecutableQuery(
133
- snapshot,
155
+ tempSnapshot,
134
156
  this.dataCube.engine.filterOperations,
135
157
  this.dataCube.engine.aggregateOperations,
136
158
  ),
@@ -147,9 +169,10 @@ export class DataCubeEditorState extends DataCubeQuerySnapshotController {
147
169
  this.finalizationState.complete();
148
170
  }
149
171
 
150
- snapshot.finalize();
151
- if (snapshot.hashCode !== baseSnapshot.hashCode) {
152
- this.publishSnapshot(snapshot);
172
+ // finalize
173
+ newSnapshot.finalize();
174
+ if (newSnapshot.hashCode !== baseSnapshot.hashCode) {
175
+ this.publishSnapshot(newSnapshot);
153
176
  }
154
177
 
155
178
  if (options?.closeAfterApply) {
@@ -166,8 +189,8 @@ export class DataCubeEditorState extends DataCubeQuerySnapshotController {
166
189
  );
167
190
 
168
191
  this.columns.applySnaphot(snapshot, configuration);
169
- this.verticalPivots.applySnaphot(snapshot, configuration);
170
192
  this.horizontalPivots.applySnaphot(snapshot, configuration);
193
+ this.verticalPivots.applySnaphot(snapshot, configuration);
171
194
  this.sorts.applySnaphot(snapshot, configuration);
172
195
 
173
196
  this.generalProperties.applySnaphot(snapshot, configuration);
@@ -44,6 +44,10 @@ export class DataCubeEditorVerticalPivotColumnsSelectorState extends DataCubeEdi
44
44
  // exclude group-level extended columns
45
45
  !this.editor.columns.groupExtendColumns.find(
46
46
  (col) => col.name === column.name,
47
+ ) &&
48
+ // prune available columns if h-pivot is present
49
+ !this.editor.horizontalPivots.columnsConsumedByPivot.find(
50
+ (col) => col.name === column.name,
47
51
  ),
48
52
  )
49
53
  .map(
@@ -66,6 +70,14 @@ export class DataCubeEditorVerticalPivotsPanelState
66
70
  this.selector = new DataCubeEditorVerticalPivotColumnsSelectorState(editor);
67
71
  }
68
72
 
73
+ adaptPropagatedChanges(): void {
74
+ this.selector.setSelectedColumns(
75
+ this.selector.selectedColumns.filter((column) =>
76
+ this.selector.availableColumns.find((col) => col.name === column.name),
77
+ ),
78
+ );
79
+ }
80
+
69
81
  applySnaphot(
70
82
  snapshot: DataCubeQuerySnapshot,
71
83
  configuration: DataCubeConfiguration,
@@ -350,6 +350,7 @@ export class DataCubeNewColumnState {
350
350
  },
351
351
  this.isGroupLevel,
352
352
  this.columnKind,
353
+ this,
353
354
  );
354
355
 
355
356
  this.close();
@@ -20,7 +20,7 @@ import type {
20
20
  DataCubeQuerySnapshotColumn,
21
21
  DataCubeQuerySnapshotExtendedColumn,
22
22
  } from '../core/DataCubeQuerySnapshot.js';
23
- import { guaranteeNonNullable } from '@finos/legend-shared';
23
+ import { deleteEntry, guaranteeNonNullable, noop } from '@finos/legend-shared';
24
24
  import type { DataCubeState } from '../DataCubeState.js';
25
25
  import { DataCubeQuerySnapshotController } from '../core/DataCubeQuerySnapshotManager.js';
26
26
  import {
@@ -98,6 +98,7 @@ export class DataCubeExtendManagerState extends DataCubeQuerySnapshotController
98
98
  column: T,
99
99
  isGroupLevel: boolean,
100
100
  columnKind: DataCubeColumnKind | undefined,
101
+ editor: DataCubeNewColumnState,
101
102
  ) {
102
103
  (isGroupLevel ? this.groupExtendedColumns : this.leafExtendedColumns).push(
103
104
  new DataCubeQueryExtendedColumnState(column),
@@ -111,6 +112,7 @@ export class DataCubeExtendManagerState extends DataCubeQuerySnapshotController
111
112
  }
112
113
 
113
114
  this.columnConfigurations.push(columnConfiguration);
115
+ deleteEntry(this.newColumnEditors, editor);
114
116
  this.applyChanges();
115
117
  }
116
118
 
@@ -129,6 +131,12 @@ export class DataCubeExtendManagerState extends DataCubeQuerySnapshotController
129
131
  this.groupExtendedColumns = snapshot.data.groupExtendedColumns.map(
130
132
  (col) => new DataCubeQueryExtendedColumnState(col),
131
133
  );
134
+
135
+ // trigger re-compile in each existing column editor as the base query has changed
136
+ this.newColumnEditors.forEach((editor) => {
137
+ editor.getReturnType().catch(noop());
138
+ });
139
+ // TODO: existingColumnEditors
132
140
  }
133
141
 
134
142
  applyChanges() {
@@ -22,21 +22,37 @@ import type {
22
22
  } from '@ag-grid-community/core';
23
23
  import type { DataCubeGridState } from './DataCubeGridState.js';
24
24
  import {
25
+ IllegalStateError,
25
26
  LogEvent,
26
27
  assertErrorThrown,
27
28
  guaranteeNonNullable,
29
+ hashObject,
28
30
  isBoolean,
29
31
  isNonNullable,
32
+ pruneObject,
30
33
  } from '@finos/legend-shared';
31
34
  import { buildExecutableQuery } from '../core/DataCubeQueryBuilder.js';
32
- import { type TabularDataSet, V1_Lambda } from '@finos/legend-graph';
35
+ import {
36
+ type TabularDataSet,
37
+ type V1_AppliedFunction,
38
+ V1_Lambda,
39
+ } from '@finos/legend-graph';
33
40
  import { APPLICATION_EVENT } from '@finos/legend-application';
34
41
  import { buildQuerySnapshot } from './DataCubeGridQuerySnapshotBuilder.js';
35
42
  import { generateRowGroupingDrilldownExecutableQueryPostProcessor } from './DataCubeGridQueryBuilder.js';
36
43
  import { makeObservable, observable, runInAction } from 'mobx';
37
- import type { DataCubeConfigurationColorKey } from '../core/DataCubeConfiguration.js';
44
+ import type {
45
+ DataCubeConfiguration,
46
+ DataCubeConfigurationColorKey,
47
+ } from '../core/DataCubeConfiguration.js';
38
48
  import { AlertType } from '../../../components/repl/Alert.js';
39
49
  import { DEFAULT_LARGE_ALERT_WINDOW_CONFIG } from '../../LayoutManagerState.js';
50
+ import type { DataCubeQuerySnapshot } from '../core/DataCubeQuerySnapshot.js';
51
+ import type { DataCubeEngine } from '../DataCubeEngine.js';
52
+ import { generateColumnDefs } from './DataCubeGridConfigurationBuilder.js';
53
+ import type { DataCubeQueryFunctionMap } from '../core/DataCubeQueryEngine.js';
54
+ import type { DataCubeQueryFilterOperation } from '../core/filter/DataCubeQueryFilterOperation.js';
55
+ import type { DataCubeQueryAggregateOperation } from '../core/aggregation/DataCubeQueryAggregateOperation.js';
40
56
 
41
57
  type GridClientCellValue = string | number | boolean | null | undefined;
42
58
  type GridClientRowData = {
@@ -69,6 +85,9 @@ export enum INTERNAL__GridClientUtilityCssClassName {
69
85
  TEXT_ALIGN_PREFIX = 'data-cube-grid__utility--text-align-',
70
86
  TEXT_COLOR_PREFIX = 'data-cube-grid__utility--text-color-',
71
87
  BACKGROUND_COLOR_PREFIX = 'data-cube-grid__utility--background-color-',
88
+
89
+ PIVOT_COLUMN_GROUP = 'data-cube-grid__utility--pivot-column-group',
90
+ PIVOT_COLUMN_GROUP_PREFIX = 'data-cube-grid__utility--pivot-column-group-',
72
91
  }
73
92
  export const generateFontFamilyUtilityClassName = (fontFamily: string) =>
74
93
  `${INTERNAL__GridClientUtilityCssClassName.FONT_FAMILY_PREFIX}${fontFamily.replaceAll(' ', '-')}`;
@@ -103,6 +122,7 @@ export const INTERNAL__GRID_CLIENT_DEFAULT_CACHE_BLOCK_SIZE = 100;
103
122
  // so the value set must be reasonable, or else it can crash the application!
104
123
  export const INTERNAL__GRID_CLIENT_MAX_CACHE_BLOCK_SIZE = 1e5;
105
124
 
125
+ export const INTERNAL__GRID_CLIENT_PIVOT_COLUMN_GROUP_COLOR_ROTATION_SIZE = 5;
106
126
  export const INTERNAL__GRID_CLIENT_SIDE_BAR_WIDTH = 200;
107
127
  export const INTERNAL__GRID_CLIENT_COLUMN_MIN_WIDTH = 50;
108
128
  export const INTERNAL__GRID_CLIENT_HEADER_HEIGHT = 24;
@@ -111,8 +131,8 @@ export const INTERNAL__GRID_CLIENT_TOOLTIP_SHOW_DELAY = 1000;
111
131
  export const INTERNAL__GRID_CLIENT_AUTO_RESIZE_PADDING = 10;
112
132
  export const INTERNAL__GRID_CLIENT_MISSING_VALUE = '__MISSING';
113
133
  export const INTERNAL__GRID_CLIENT_TREE_COLUMN_ID = 'INTERNAL__tree';
114
- export const INTERNAL__GRID_CLIENT_FILTER_TRIGGER_COLUMN_ID =
115
- 'INTERNAL__filterTrigger';
134
+ export const INTERNAL__GRID_CLIENT_DATA_FETCH_MANUAL_TRIGGER_COLUMN_ID =
135
+ 'INTERNAL__dataFetchManualTrigger';
116
136
  export const INTERNAL__GRID_CLIENT_ROW_GROUPING_COUNT_AGG_COLUMN_ID =
117
137
  'INTERNAL__count';
118
138
 
@@ -150,6 +170,36 @@ export function getDataForAllFilteredNodes<T>(client: GridApi<T>): T[] {
150
170
  return rows;
151
171
  }
152
172
 
173
+ /**
174
+ * This method computes the hash code for the parts of the snapshot that should trigger data fetching.
175
+ * This is used to manually trigger server-side row model data source getRows() method.
176
+ */
177
+ export function computeHashCodeForDataFetchManualTrigger(
178
+ snapshot: DataCubeQuerySnapshot,
179
+ configuration: DataCubeConfiguration,
180
+ ) {
181
+ return hashObject(
182
+ pruneObject({
183
+ ...snapshot.data,
184
+ configuration: {
185
+ initialExpandLevel: configuration.initialExpandLevel,
186
+ showRootAggregation: configuration.showRootAggregation,
187
+ showLeafCount: configuration.showLeafCount,
188
+ pivotTotalColumnPlacement: configuration.pivotTotalColumnPlacement,
189
+ treeGroupSortFunction: configuration.treeGroupSortFunction,
190
+ columns: configuration.columns.map((column) => ({
191
+ name: column.name,
192
+ type: column.type,
193
+ aggregateOperator: column.aggregateOperator,
194
+ aggregationParameters: column.aggregationParameters,
195
+ excludedFromHorizontalPivot: column.excludedFromHorizontalPivot,
196
+ horizontalPivotSortFunction: column.horizontalPivotSortFunction,
197
+ })),
198
+ },
199
+ }),
200
+ );
201
+ }
202
+
153
203
  function TDStoRowData(tds: TabularDataSet): GridClientRowData[] {
154
204
  return tds.rows.map((_row, rowIdx) => {
155
205
  const row: GridClientRowData = {};
@@ -167,6 +217,58 @@ function TDStoRowData(tds: TabularDataSet): GridClientRowData[] {
167
217
  });
168
218
  }
169
219
 
220
+ async function getCastColumns(
221
+ currentSnapshot: DataCubeQuerySnapshot,
222
+ engine: DataCubeEngine,
223
+ ) {
224
+ if (!currentSnapshot.data.pivot) {
225
+ throw new IllegalStateError(
226
+ `Can't build cast columns collector query when no pivot is specified`,
227
+ );
228
+ }
229
+ const snapshot = currentSnapshot.clone();
230
+ guaranteeNonNullable(snapshot.data.pivot).castColumns = [];
231
+ snapshot.data.groupBy = undefined;
232
+ snapshot.data.sortColumns = [];
233
+ snapshot.data.limit = 0;
234
+ const query = buildExecutableQuery(
235
+ snapshot,
236
+ engine.filterOperations,
237
+ engine.aggregateOperations,
238
+ {
239
+ postProcessor: (
240
+ _snapshot: DataCubeQuerySnapshot,
241
+ sequence: V1_AppliedFunction[],
242
+ funcMap: DataCubeQueryFunctionMap,
243
+ configuration: DataCubeConfiguration,
244
+ filterOperations: DataCubeQueryFilterOperation[],
245
+ aggregateOperations: DataCubeQueryAggregateOperation[],
246
+ ) => {
247
+ const _unprocess = (funcMapKey: keyof DataCubeQueryFunctionMap) => {
248
+ const func = funcMap[funcMapKey];
249
+ if (func) {
250
+ sequence.splice(sequence.indexOf(func), 1);
251
+ funcMap[funcMapKey] = undefined;
252
+ }
253
+ };
254
+
255
+ if (funcMap.groupExtend) {
256
+ _unprocess('groupExtend');
257
+ }
258
+ },
259
+ },
260
+ );
261
+
262
+ const lambda = new V1_Lambda();
263
+ lambda.body.push(query);
264
+ const result = await engine.executeQuery(lambda);
265
+
266
+ return result.result.builder.columns.map((column) => ({
267
+ name: column.name,
268
+ type: column.type as string,
269
+ }));
270
+ }
271
+
170
272
  export class DataCubeGridClientServerSideDataSource
171
273
  implements IServerSideDatasource
172
274
  {
@@ -205,18 +307,56 @@ export class DataCubeGridClientServerSideDataSource
205
307
  // ------------------------------ SNAPSHOT ------------------------------
206
308
 
207
309
  const currentSnapshot = guaranteeNonNullable(this.grid.getLatestSnapshot());
208
- // TODO: when we support pivoting, we should make a quick call to check for columns
209
- // created by pivots and specify them as cast columns when pivot is activated
210
- const syncedSnapshot = buildQuerySnapshot(params.request, currentSnapshot);
211
- if (syncedSnapshot.hashCode !== currentSnapshot.hashCode) {
212
- this.grid.publishSnapshot(syncedSnapshot);
310
+ const newSnapshot = buildQuerySnapshot(params.request, currentSnapshot);
311
+ // NOTE: if h-pivot is enabled
312
+ // if h-pivot is enabled, update the cast columns
313
+ // and panels which might be affected by this (e.g. sorts)
314
+ // TOOD?: this is an expensive operation in certain case, so we might want to
315
+ // optimize when this gets called
316
+ if (newSnapshot.data.pivot) {
317
+ try {
318
+ const castColumns = await getCastColumns(
319
+ newSnapshot,
320
+ this.grid.dataCube.engine,
321
+ );
322
+ newSnapshot.data.pivot.castColumns = castColumns;
323
+ newSnapshot.data.sortColumns = newSnapshot.data.sortColumns.filter(
324
+ (column) =>
325
+ [...castColumns, ...newSnapshot.data.groupExtendedColumns].find(
326
+ (col) => column.name === col.name,
327
+ ),
328
+ );
329
+ } catch (error) {
330
+ assertErrorThrown(error);
331
+ this.grid.dataCube.repl.alertError(error, {
332
+ message: `Query Validation Failure: Can't retrieve pivot results column metadata. ${error.message}`,
333
+ });
334
+ // fail early since we can't proceed without the cast columns validated
335
+ params.fail();
336
+ this.grid.dataCube.endTask(task);
337
+ return;
338
+ }
339
+ }
340
+
341
+ newSnapshot.finalize();
342
+ if (newSnapshot.hashCode !== currentSnapshot.hashCode) {
343
+ // update grid column definitions since new columns could have been added
344
+ // due to changes in pivot
345
+ this.grid.client.updateGridOptions({
346
+ columnDefs: generateColumnDefs(
347
+ newSnapshot,
348
+ this.grid.queryConfiguration,
349
+ this.grid.dataCube,
350
+ ),
351
+ });
352
+ this.grid.publishSnapshot(newSnapshot);
213
353
  }
214
354
 
215
355
  // ------------------------------ DATA ------------------------------
216
356
 
217
357
  try {
218
358
  const executableQuery = buildExecutableQuery(
219
- syncedSnapshot,
359
+ newSnapshot,
220
360
  this.grid.dataCube.engine.filterOperations,
221
361
  this.grid.dataCube.engine.aggregateOperations,
222
362
  {