@finos/legend-data-cube 0.0.24 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/column-configuration.display-value-as-link.md +6 -0
- package/docs/column-configuration.kind.md +14 -0
- package/docs/column-configuration.missing-value-format.md +5 -0
- package/docs/column-configuration.unit.md +5 -0
- package/docs/extended-column.level.md +14 -0
- package/docs/grid-configuration.row-limit.md +5 -0
- package/lib/__lib__/DataCubeDocumentation.d.ts +5 -3
- package/lib/__lib__/DataCubeDocumentation.d.ts.map +1 -1
- package/lib/__lib__/DataCubeDocumentation.js +5 -3
- package/lib/__lib__/DataCubeDocumentation.js.map +1 -1
- package/lib/components/core/DataCubeFormUtils.d.ts +1 -0
- package/lib/components/core/DataCubeFormUtils.d.ts.map +1 -1
- package/lib/components/core/DataCubeFormUtils.js +4 -3
- package/lib/components/core/DataCubeFormUtils.js.map +1 -1
- package/lib/components/view/editor/DataCubeEditorColumnPropertiesPanel.d.ts.map +1 -1
- package/lib/components/view/editor/DataCubeEditorColumnPropertiesPanel.js +12 -9
- package/lib/components/view/editor/DataCubeEditorColumnPropertiesPanel.js.map +1 -1
- package/lib/components/view/editor/DataCubeEditorColumnSelector.js +2 -2
- package/lib/components/view/editor/DataCubeEditorGeneralPropertiesPanel.d.ts.map +1 -1
- package/lib/components/view/editor/DataCubeEditorGeneralPropertiesPanel.js +8 -7
- package/lib/components/view/editor/DataCubeEditorGeneralPropertiesPanel.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/core/DataCubeQueryBuilder.d.ts +3 -0
- package/lib/stores/core/DataCubeQueryBuilder.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilder.js +8 -1
- package/lib/stores/core/DataCubeQueryBuilder.js.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts +1 -0
- package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilderUtils.js +14 -7
- package/lib/stores/core/DataCubeQueryBuilderUtils.js.map +1 -1
- package/lib/stores/core/DataCubeQueryEngine.d.ts +6 -0
- package/lib/stores/core/DataCubeQueryEngine.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQueryEngine.js +7 -0
- package/lib/stores/core/DataCubeQueryEngine.js.map +1 -1
- package/lib/stores/core/models/DataCubeConfiguration.d.ts +1 -0
- package/lib/stores/core/models/DataCubeConfiguration.d.ts.map +1 -1
- package/lib/stores/core/models/DataCubeConfiguration.js +2 -0
- package/lib/stores/core/models/DataCubeConfiguration.js.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorGeneralPropertiesPanelState.d.ts +2 -2
- package/lib/stores/view/editor/DataCubeEditorGeneralPropertiesPanelState.d.ts.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorGeneralPropertiesPanelState.js +4 -3
- package/lib/stores/view/editor/DataCubeEditorGeneralPropertiesPanelState.js.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.d.ts +1 -0
- package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.d.ts.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.js +5 -0
- package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts +14 -2
- package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridClientEngine.js +42 -42
- package/lib/stores/view/grid/DataCubeGridClientEngine.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts +20 -3
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js +81 -35
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridMenuBuilder.js +1 -1
- package/lib/stores/view/grid/DataCubeGridMenuBuilder.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts +3 -3
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.js +39 -8
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridQuerySnapshotBuilder.d.ts +2 -2
- package/lib/stores/view/grid/DataCubeGridQuerySnapshotBuilder.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridQuerySnapshotBuilder.js +30 -14
- package/lib/stores/view/grid/DataCubeGridQuerySnapshotBuilder.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridState.d.ts +2 -0
- package/lib/stores/view/grid/DataCubeGridState.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridState.js +5 -1
- package/lib/stores/view/grid/DataCubeGridState.js.map +1 -1
- package/package.json +4 -4
- package/src/__lib__/DataCubeDocumentation.ts +5 -3
- package/src/components/core/DataCubeFormUtils.tsx +5 -1
- package/src/components/view/editor/DataCubeEditorColumnPropertiesPanel.tsx +40 -14
- package/src/components/view/editor/DataCubeEditorColumnSelector.tsx +2 -2
- package/src/components/view/editor/DataCubeEditorGeneralPropertiesPanel.tsx +41 -30
- package/src/stores/core/DataCubeQueryBuilder.ts +13 -0
- package/src/stores/core/DataCubeQueryBuilderUtils.ts +32 -6
- package/src/stores/core/DataCubeQueryEngine.ts +8 -0
- package/src/stores/core/models/DataCubeConfiguration.ts +2 -0
- package/src/stores/view/editor/DataCubeEditorGeneralPropertiesPanelState.ts +5 -4
- package/src/stores/view/editor/DataCubeEditorMutableConfiguration.ts +7 -0
- package/src/stores/view/grid/DataCubeGridClientEngine.ts +56 -51
- package/src/stores/view/grid/DataCubeGridConfigurationBuilder.tsx +90 -37
- package/src/stores/view/grid/DataCubeGridMenuBuilder.tsx +1 -1
- package/src/stores/view/grid/DataCubeGridQueryBuilder.ts +70 -14
- package/src/stores/view/grid/DataCubeGridQuerySnapshotBuilder.ts +40 -20
- package/src/stores/view/grid/DataCubeGridState.ts +12 -1
|
@@ -33,7 +33,7 @@ import type {
|
|
|
33
33
|
ICellRendererParams,
|
|
34
34
|
} from '@ag-grid-community/core';
|
|
35
35
|
import {
|
|
36
|
-
|
|
36
|
+
DataCubeGridClientSortDirection,
|
|
37
37
|
INTERNAL__GRID_CLIENT_COLUMN_MIN_WIDTH,
|
|
38
38
|
INTERNAL__GridClientUtilityCssClassName,
|
|
39
39
|
generateFontFamilyUtilityClassName,
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
generateTextColorUtilityClassName,
|
|
44
44
|
generateBackgroundColorUtilityClassName,
|
|
45
45
|
generateFontCaseUtilityClassName,
|
|
46
|
-
|
|
46
|
+
DataCubeGridClientPinnedAlignement,
|
|
47
47
|
INTERNAL__GRID_CLIENT_ROW_HEIGHT,
|
|
48
48
|
INTERNAL__GRID_CLIENT_AUTO_RESIZE_PADDING,
|
|
49
49
|
INTERNAL__GRID_CLIENT_HEADER_HEIGHT,
|
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
INTERNAL__GRID_CLIENT_DATA_FETCH_MANUAL_TRIGGER_COLUMN_ID,
|
|
55
55
|
INTERNAL__GRID_CLIENT_PIVOT_COLUMN_GROUP_COLOR_ROTATION_SIZE,
|
|
56
56
|
INTERNAL__GRID_CLIENT_TREE_COLUMN_ID,
|
|
57
|
+
INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
57
58
|
} from './DataCubeGridClientEngine.js';
|
|
58
59
|
import {
|
|
59
60
|
getNonNullableEntry,
|
|
@@ -82,6 +83,7 @@ import {
|
|
|
82
83
|
PIVOT_COLUMN_NAME_VALUE_SEPARATOR,
|
|
83
84
|
isPivotResultColumnName,
|
|
84
85
|
TREE_COLUMN_VALUE_SEPARATOR,
|
|
86
|
+
DEFAULT_ROOT_AGGREGATION_COLUMN_VALUE,
|
|
85
87
|
} from '../../core/DataCubeQueryEngine.js';
|
|
86
88
|
import type { CustomLoadingCellRendererProps } from '@ag-grid-community/react';
|
|
87
89
|
import { DataCubeIcon } from '@finos/legend-art';
|
|
@@ -226,8 +228,8 @@ function _displaySpec(columnData: ColumnData) {
|
|
|
226
228
|
pinned:
|
|
227
229
|
column.pinned !== undefined
|
|
228
230
|
? column.pinned === DataCubeColumnPinPlacement.RIGHT
|
|
229
|
-
?
|
|
230
|
-
:
|
|
231
|
+
? DataCubeGridClientPinnedAlignement.RIGHT
|
|
232
|
+
: DataCubeGridClientPinnedAlignement.LEFT
|
|
231
233
|
: null,
|
|
232
234
|
headerClass: isPivotResultColumnName(name)
|
|
233
235
|
? 'pl-1 border border-neutral-300'
|
|
@@ -313,13 +315,18 @@ function _displaySpec(columnData: ColumnData) {
|
|
|
313
315
|
}
|
|
314
316
|
: {}),
|
|
315
317
|
});
|
|
316
|
-
// 3. add the parentheses
|
|
317
|
-
|
|
318
|
+
// 3. add the parentheses, scale unit, unit, etc.
|
|
319
|
+
let displayValue =
|
|
318
320
|
(showNegativeNumberInParens
|
|
319
321
|
? `(${formattedValue})`
|
|
320
322
|
: formattedValue) +
|
|
321
|
-
(scaledNumber.unit ? ` ${scaledNumber.unit}` : '')
|
|
322
|
-
)
|
|
323
|
+
(scaledNumber.unit ? ` ${scaledNumber.unit}` : '');
|
|
324
|
+
if (column.unit) {
|
|
325
|
+
displayValue = !column.unit.startsWith('_')
|
|
326
|
+
? `${displayValue}${column.unit}`
|
|
327
|
+
: `${column.unit.substring(1)}${displayValue}`;
|
|
328
|
+
}
|
|
329
|
+
return displayValue;
|
|
323
330
|
}
|
|
324
331
|
: (params) =>
|
|
325
332
|
params.value === INTERNAL__GRID_CLIENT_MISSING_VALUE
|
|
@@ -357,7 +364,7 @@ function _groupDisplaySpec(
|
|
|
357
364
|
hide: !snapshot.data.groupBy,
|
|
358
365
|
lockPosition: true,
|
|
359
366
|
lockPinned: true,
|
|
360
|
-
pinned:
|
|
367
|
+
pinned: DataCubeGridClientPinnedAlignement.LEFT,
|
|
361
368
|
cellClassRules: {
|
|
362
369
|
[generateFontFamilyUtilityClassName(fontFamily)]: () => true,
|
|
363
370
|
[generateFontSizeUtilityClassName(fontSize)]: () => true,
|
|
@@ -413,11 +420,6 @@ function _sizeSpec(columnData: ColumnData) {
|
|
|
413
420
|
INTERNAL__GRID_CLIENT_COLUMN_MIN_WIDTH,
|
|
414
421
|
),
|
|
415
422
|
maxWidth: column.maxWidth,
|
|
416
|
-
// Make sure the column spans the width if possible so when total width
|
|
417
|
-
// is less than grid width, removing/adding one column will cause the other
|
|
418
|
-
// columns to take/give up space
|
|
419
|
-
flex:
|
|
420
|
-
column.fixedWidth === undefined ? 1 : (undefined as unknown as number),
|
|
421
423
|
} as ColDef;
|
|
422
424
|
}
|
|
423
425
|
|
|
@@ -429,28 +431,34 @@ function _sortSpec(columnData: ColumnData) {
|
|
|
429
431
|
sortable: true, // if this is pivot column, no sorting is supported yet
|
|
430
432
|
sort: sortCol
|
|
431
433
|
? sortCol.direction === DataCubeQuerySortDirection.ASCENDING
|
|
432
|
-
?
|
|
433
|
-
:
|
|
434
|
+
? DataCubeGridClientSortDirection.ASCENDING
|
|
435
|
+
: DataCubeGridClientSortDirection.DESCENDING
|
|
434
436
|
: null,
|
|
435
437
|
sortIndex: sortCol ? sortColumns.indexOf(sortCol) : null,
|
|
436
438
|
} satisfies ColDef;
|
|
437
439
|
}
|
|
438
440
|
|
|
439
441
|
function _aggregationSpec(columnData: ColumnData) {
|
|
440
|
-
const { name, snapshot, column } = columnData;
|
|
442
|
+
const { name, snapshot, column, configuration } = columnData;
|
|
441
443
|
const data = snapshot.data;
|
|
442
444
|
const pivotCol = _findCol(data.pivot?.columns, name);
|
|
443
445
|
const groupByCol = _findCol(data.groupBy?.columns, name);
|
|
444
446
|
const isGroupExtendedColumn = Boolean(
|
|
445
447
|
_findCol(data.groupExtendedColumns, name),
|
|
446
448
|
);
|
|
449
|
+
const rowGroupIndex =
|
|
450
|
+
!isGroupExtendedColumn && groupByCol
|
|
451
|
+
? (data.groupBy?.columns.indexOf(groupByCol) ?? null)
|
|
452
|
+
: null;
|
|
447
453
|
return {
|
|
448
454
|
enableRowGroup:
|
|
449
455
|
!isGroupExtendedColumn && column.kind === DataCubeColumnKind.DIMENSION,
|
|
450
456
|
rowGroup: !isGroupExtendedColumn && Boolean(groupByCol),
|
|
451
457
|
rowGroupIndex:
|
|
452
|
-
|
|
453
|
-
?
|
|
458
|
+
rowGroupIndex !== null
|
|
459
|
+
? configuration.showRootAggregation
|
|
460
|
+
? rowGroupIndex + 1
|
|
461
|
+
: rowGroupIndex
|
|
454
462
|
: null,
|
|
455
463
|
enablePivot:
|
|
456
464
|
!isGroupExtendedColumn && column.kind === DataCubeColumnKind.DIMENSION,
|
|
@@ -546,8 +554,6 @@ export function generateBaseGridOptions(view: DataCubeViewState): GridOptions {
|
|
|
546
554
|
event.api.hidePopupMenu(); // hide context-menu while scrolling
|
|
547
555
|
},
|
|
548
556
|
onBodyScrollEnd: () => grid.setScrollHintText(undefined),
|
|
549
|
-
scrollbarWidth: 10,
|
|
550
|
-
alwaysShowVerticalScroll: true, // this is needed to ensure column resize calculation is accurate
|
|
551
557
|
// -------------------------------------- CONTEXT MENU --------------------------------------
|
|
552
558
|
preventDefaultOnContextMenu: true, // prevent showing the browser's context menu
|
|
553
559
|
columnMenu: 'new', // ensure context menu works on header
|
|
@@ -572,16 +578,8 @@ export function generateBaseGridOptions(view: DataCubeViewState): GridOptions {
|
|
|
572
578
|
},
|
|
573
579
|
// -------------------------------------- COLUMN SIZING --------------------------------------
|
|
574
580
|
autoSizePadding: INTERNAL__GRID_CLIENT_AUTO_RESIZE_PADDING,
|
|
575
|
-
// ensure columns are resized to fit the grid width initially and on window resize
|
|
576
|
-
// NOTE: this has to be used with `alwaysShowVerticalScroll` to ensure accurate sizing
|
|
577
|
-
// otherwise on initial load, the computation will be done when no data is rendered,
|
|
578
|
-
// so when data is rendered and the vertical scrollbar shows up, it will block a part of
|
|
579
|
-
// the last column.
|
|
580
581
|
autoSizeStrategy: {
|
|
581
|
-
type: '
|
|
582
|
-
},
|
|
583
|
-
onGridSizeChanged: (event) => {
|
|
584
|
-
event.api.sizeColumnsToFit();
|
|
582
|
+
type: 'fitCellContents',
|
|
585
583
|
},
|
|
586
584
|
// -------------------------------------- TOOLTIP --------------------------------------
|
|
587
585
|
tooltipShowDelay: INTERNAL__GRID_CLIENT_TOOLTIP_SHOW_DELAY,
|
|
@@ -594,6 +592,10 @@ export function generateBaseGridOptions(view: DataCubeViewState): GridOptions {
|
|
|
594
592
|
suppressScrollOnNewData: true,
|
|
595
593
|
// NOTE: use row loader instead of showing loader in each cell to improve performance
|
|
596
594
|
// otherwise, when we have many columns (i.e. when pivoting), the app could freeze.
|
|
595
|
+
//
|
|
596
|
+
// This would render the loading cell as the full-width row, which, in combination with
|
|
597
|
+
// fit cell content auto-sizing strategy creates an unwanted row flashing effect while loading.
|
|
598
|
+
// To compensate for that, we modify the styling to make sure the full-width row has a blank background
|
|
597
599
|
loadingCellRenderer: DataCubeGridLoadingCellRenderer,
|
|
598
600
|
// By default, when row-grouping is active, ag-grid's caching mechanism causes sort
|
|
599
601
|
// to not work properly for pivot result columns, so we must disable this mechanism.
|
|
@@ -819,6 +821,24 @@ export function generateColumnDefs(
|
|
|
819
821
|
filter: 'agTextColumnFilter',
|
|
820
822
|
suppressColumnsToolPanel: true,
|
|
821
823
|
},
|
|
824
|
+
...(configuration.showRootAggregation
|
|
825
|
+
? [
|
|
826
|
+
{
|
|
827
|
+
colId: INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
828
|
+
headerName: 'Root',
|
|
829
|
+
field: INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
830
|
+
hide: true,
|
|
831
|
+
enableValue: false, // disable GUI interactions to modify this column's aggregate function
|
|
832
|
+
allowedAggFuncs: [], // disable GUI for options of the agg functions
|
|
833
|
+
enablePivot: false,
|
|
834
|
+
enableRowGroup: false,
|
|
835
|
+
|
|
836
|
+
suppressColumnsToolPanel: true,
|
|
837
|
+
rowGroup: true,
|
|
838
|
+
rowGroupIndex: 0,
|
|
839
|
+
} satisfies ColDef,
|
|
840
|
+
]
|
|
841
|
+
: []),
|
|
822
842
|
...generateDefinitionForPivotResultColumns(
|
|
823
843
|
pivotResultColumns,
|
|
824
844
|
snapshot,
|
|
@@ -863,15 +883,36 @@ export function generateGridOptionsFromSnapshot(
|
|
|
863
883
|
if (
|
|
864
884
|
configuration.initialExpandLevel !== undefined &&
|
|
865
885
|
configuration.initialExpandLevel > 0 &&
|
|
866
|
-
params.rowNode.level <=
|
|
886
|
+
params.rowNode.level <=
|
|
887
|
+
// root aggregation (if enabled) should not be counted when applying initial expand level
|
|
888
|
+
(configuration.showRootAggregation
|
|
889
|
+
? configuration.initialExpandLevel + 1
|
|
890
|
+
: configuration.initialExpandLevel) -
|
|
891
|
+
1
|
|
867
892
|
) {
|
|
868
893
|
return true;
|
|
869
894
|
}
|
|
870
895
|
|
|
871
|
-
const routes = params.rowNode.getRoute();
|
|
872
|
-
if (!routes) {
|
|
896
|
+
const routes = params.rowNode.getRoute() ?? [];
|
|
897
|
+
if (!routes.length) {
|
|
873
898
|
return false;
|
|
874
899
|
}
|
|
900
|
+
|
|
901
|
+
// when root aggregation is enabled, the root node should be
|
|
902
|
+
// expanded automatically by default
|
|
903
|
+
if (
|
|
904
|
+
configuration.showRootAggregation &&
|
|
905
|
+
routes.length === 1 &&
|
|
906
|
+
routes[0] === DEFAULT_ROOT_AGGREGATION_COLUMN_VALUE
|
|
907
|
+
) {
|
|
908
|
+
return true;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// when root aggregation is enabled, the root node should not be removed
|
|
912
|
+
// from path when matching against all expanded paths
|
|
913
|
+
if (configuration.showRootAggregation) {
|
|
914
|
+
routes.shift();
|
|
915
|
+
}
|
|
875
916
|
const path = routes.join(TREE_COLUMN_VALUE_SEPARATOR);
|
|
876
917
|
if (configuration.pivotLayout.expandedPaths.includes(path)) {
|
|
877
918
|
return true;
|
|
@@ -909,7 +950,7 @@ export function generateGridOptionsFromSnapshot(
|
|
|
909
950
|
column.getColId(),
|
|
910
951
|
pinned === null
|
|
911
952
|
? undefined
|
|
912
|
-
: pinned ===
|
|
953
|
+
: pinned === DataCubeGridClientPinnedAlignement.LEFT
|
|
913
954
|
? DataCubeColumnPinPlacement.LEFT
|
|
914
955
|
: DataCubeColumnPinPlacement.RIGHT,
|
|
915
956
|
);
|
|
@@ -941,7 +982,13 @@ export function generateGridOptionsFromSnapshot(
|
|
|
941
982
|
// expanded-to-level is specified, causing the groups to be automatically drilled down, resultant
|
|
942
983
|
// expanded paths will not be kept for record.
|
|
943
984
|
if (event.event) {
|
|
944
|
-
const
|
|
985
|
+
const routes = event.node.getRoute() ?? [];
|
|
986
|
+
// when root aggregation is enabled, the root node should not be counted
|
|
987
|
+
// when formulating the expanded path
|
|
988
|
+
if (routes.length && configuration.showRootAggregation) {
|
|
989
|
+
routes.shift();
|
|
990
|
+
}
|
|
991
|
+
const path = routes.join(TREE_COLUMN_VALUE_SEPARATOR);
|
|
945
992
|
if (!path) {
|
|
946
993
|
return;
|
|
947
994
|
}
|
|
@@ -953,6 +1000,14 @@ export function generateGridOptionsFromSnapshot(
|
|
|
953
1000
|
}
|
|
954
1001
|
},
|
|
955
1002
|
|
|
1003
|
+
// Virtual columns when being rendered (as user scrolls horizontally) would get resized
|
|
1004
|
+
// to fit their content dynamically. This can potentially cause some performance issues,
|
|
1005
|
+
// so we debounce the resize operation.
|
|
1006
|
+
onVirtualColumnsChanged: () => {
|
|
1007
|
+
view.grid.debouncedAutoResizeColumns?.cancel();
|
|
1008
|
+
view.grid.debouncedAutoResizeColumns?.();
|
|
1009
|
+
},
|
|
1010
|
+
|
|
956
1011
|
// -------------------------------------- COLUMNS --------------------------------------
|
|
957
1012
|
|
|
958
1013
|
columnDefs: generateColumnDefs(snapshot, configuration, view),
|
|
@@ -971,8 +1026,6 @@ export function generateGridOptionsFromSnapshot(
|
|
|
971
1026
|
..._groupDisplaySpec(snapshot, configuration),
|
|
972
1027
|
|
|
973
1028
|
// size
|
|
974
|
-
suppressAutoSize: true,
|
|
975
|
-
suppressSizeToFit: true,
|
|
976
1029
|
minWidth: 200,
|
|
977
1030
|
|
|
978
1031
|
// sorting
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
|
|
17
17
|
import {
|
|
18
18
|
PRIMITIVE_TYPE,
|
|
19
|
-
V1_ClassInstance,
|
|
20
|
-
V1_ColSpecArray,
|
|
21
19
|
V1_GenericTypeInstance,
|
|
22
20
|
type V1_ColSpec,
|
|
23
21
|
type V1_AppliedFunction,
|
|
22
|
+
V1_GenericType,
|
|
23
|
+
V1_RelationType,
|
|
24
24
|
} from '@finos/legend-graph';
|
|
25
25
|
import { type DataCubeQuerySnapshot } from '../../core/DataCubeQuerySnapshot.js';
|
|
26
26
|
import {
|
|
@@ -53,12 +53,16 @@ import {
|
|
|
53
53
|
} from '../../core/DataCubeQueryBuilderUtils.js';
|
|
54
54
|
import {
|
|
55
55
|
INTERNAL__GRID_CLIENT_MISSING_VALUE,
|
|
56
|
+
INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
56
57
|
INTERNAL__GRID_CLIENT_ROW_GROUPING_COUNT_AGG_COLUMN_ID,
|
|
58
|
+
type DataCubeGridClientDataFetchRequest,
|
|
57
59
|
} from './DataCubeGridClientEngine.js';
|
|
58
|
-
import
|
|
60
|
+
import { DataCubeConfiguration } from '../../core/models/DataCubeConfiguration.js';
|
|
59
61
|
import type { DataCubeQueryFilterOperation } from '../../core/filter/DataCubeQueryFilterOperation.js';
|
|
60
62
|
import type { DataCubeQueryAggregateOperation } from '../../core/aggregation/DataCubeQueryAggregateOperation.js';
|
|
61
63
|
import { _colSpecArrayParam } from '../../core/DataCubeQuerySnapshotBuilderUtils.js';
|
|
64
|
+
import { buildExecutableQuery } from '../../core/DataCubeQueryBuilder.js';
|
|
65
|
+
import type { DataCubeSource } from '../../core/models/DataCubeSource.js';
|
|
62
66
|
|
|
63
67
|
/*****************************************************************************
|
|
64
68
|
* [GRID]
|
|
@@ -100,11 +104,13 @@ function _addCountAggColumnToPivot(
|
|
|
100
104
|
const castColumns = guaranteeType(
|
|
101
105
|
guaranteeType(
|
|
102
106
|
guaranteeType(funcMap.pivotCast.parameters[0], V1_GenericTypeInstance)
|
|
103
|
-
.typeArguments[0],
|
|
104
|
-
|
|
105
|
-
).
|
|
106
|
-
|
|
107
|
-
).
|
|
107
|
+
.genericType.typeArguments[0],
|
|
108
|
+
V1_GenericType,
|
|
109
|
+
).rawType,
|
|
110
|
+
V1_RelationType,
|
|
111
|
+
).columns.map((column) =>
|
|
112
|
+
_colSpec(column.name, undefined, undefined, column.type),
|
|
113
|
+
);
|
|
108
114
|
uniq(
|
|
109
115
|
castColumns
|
|
110
116
|
.filter((col) => isPivotResultColumnName(col.name))
|
|
@@ -131,8 +137,58 @@ function _addCountAggColumnToPivot(
|
|
|
131
137
|
|
|
132
138
|
// --------------------------------- MAIN ---------------------------------
|
|
133
139
|
|
|
134
|
-
export function
|
|
135
|
-
|
|
140
|
+
export function buildGridDataFetchExecutableQuery(
|
|
141
|
+
request: DataCubeGridClientDataFetchRequest,
|
|
142
|
+
snapshot: DataCubeQuerySnapshot,
|
|
143
|
+
source: DataCubeSource,
|
|
144
|
+
executionContextBuilder: (
|
|
145
|
+
source: DataCubeSource,
|
|
146
|
+
) => V1_AppliedFunction | undefined,
|
|
147
|
+
filterOperations: DataCubeQueryFilterOperation[],
|
|
148
|
+
aggregateOperations: DataCubeQueryAggregateOperation[],
|
|
149
|
+
enablePagination: boolean,
|
|
150
|
+
) {
|
|
151
|
+
const processedSnapshot = snapshot.clone();
|
|
152
|
+
const configuration = DataCubeConfiguration.serialization.fromJson(
|
|
153
|
+
processedSnapshot.data.configuration,
|
|
154
|
+
);
|
|
155
|
+
if (configuration.showRootAggregation) {
|
|
156
|
+
processedSnapshot.data.groupBy = {
|
|
157
|
+
columns: [
|
|
158
|
+
{
|
|
159
|
+
name: INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
160
|
+
type: PRIMITIVE_TYPE.STRING,
|
|
161
|
+
},
|
|
162
|
+
...(processedSnapshot.data.groupBy?.columns ?? []),
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return buildExecutableQuery(
|
|
167
|
+
processedSnapshot,
|
|
168
|
+
source,
|
|
169
|
+
executionContextBuilder,
|
|
170
|
+
filterOperations,
|
|
171
|
+
aggregateOperations,
|
|
172
|
+
{
|
|
173
|
+
postProcessor: generateGridDataFetchExecutableQueryPostProcessor(request),
|
|
174
|
+
rootAggregation: {
|
|
175
|
+
columnName: INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
176
|
+
},
|
|
177
|
+
pagination:
|
|
178
|
+
enablePagination &&
|
|
179
|
+
request.startRow !== undefined &&
|
|
180
|
+
request.endRow !== undefined
|
|
181
|
+
? {
|
|
182
|
+
start: request.startRow,
|
|
183
|
+
end: request.endRow,
|
|
184
|
+
}
|
|
185
|
+
: undefined,
|
|
186
|
+
},
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function generateGridDataFetchExecutableQueryPostProcessor(
|
|
191
|
+
request: DataCubeGridClientDataFetchRequest,
|
|
136
192
|
) {
|
|
137
193
|
return (
|
|
138
194
|
snapshot: DataCubeQuerySnapshot,
|
|
@@ -151,7 +207,7 @@ export function generateRowGroupingDrilldownExecutableQueryPostProcessor(
|
|
|
151
207
|
|
|
152
208
|
// if any level of drilldown has been done
|
|
153
209
|
// add a pre-filter to groupBy()
|
|
154
|
-
if (
|
|
210
|
+
if (request.groupKeys.length) {
|
|
155
211
|
sequence.splice(
|
|
156
212
|
sequence.indexOf(funcMap.groupBy),
|
|
157
213
|
0,
|
|
@@ -161,7 +217,7 @@ export function generateRowGroupingDrilldownExecutableQueryPostProcessor(
|
|
|
161
217
|
[
|
|
162
218
|
_filter(
|
|
163
219
|
{
|
|
164
|
-
conditions:
|
|
220
|
+
conditions: request.groupKeys.map((value, i) => {
|
|
165
221
|
const groupByColumn = guaranteeNonNullable(
|
|
166
222
|
groupBy.columns[i],
|
|
167
223
|
);
|
|
@@ -230,14 +286,14 @@ export function generateRowGroupingDrilldownExecutableQueryPostProcessor(
|
|
|
230
286
|
}
|
|
231
287
|
|
|
232
288
|
// modify groupBy() based off the current drilldown level
|
|
233
|
-
if (
|
|
289
|
+
if (request.groupKeys.length < groupBy.columns.length) {
|
|
234
290
|
const countAggColumns: V1_ColSpec[] = [];
|
|
235
291
|
_addCountAggColumnToPivot(funcMap, countAggColumns);
|
|
236
292
|
|
|
237
293
|
const groupByIdx = sequence.indexOf(funcMap.groupBy);
|
|
238
294
|
const groupByColumns = groupBy.columns.slice(
|
|
239
295
|
0,
|
|
240
|
-
|
|
296
|
+
request.groupKeys.length + 1,
|
|
241
297
|
);
|
|
242
298
|
const groupByFunc = _function(DataCubeFunction.GROUP_BY, [
|
|
243
299
|
_cols(groupByColumns.map((col) => _colSpec(col.name))),
|
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
* of the grid client, AG Grid.
|
|
22
22
|
***************************************************************************************/
|
|
23
23
|
|
|
24
|
-
import type { IServerSideGetRowsRequest } from '@ag-grid-community/core';
|
|
25
24
|
import { type DataCubeQuerySnapshot } from '../../core/DataCubeQuerySnapshot.js';
|
|
26
25
|
import { _toCol } from '../../core/models/DataCubeColumn.js';
|
|
27
26
|
import {
|
|
28
|
-
|
|
27
|
+
DataCubeGridClientSortDirection,
|
|
28
|
+
INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
29
29
|
INTERNAL__GRID_CLIENT_TREE_COLUMN_ID,
|
|
30
|
+
type DataCubeGridClientDataFetchRequest,
|
|
30
31
|
} from './DataCubeGridClientEngine.js';
|
|
31
32
|
import {
|
|
32
33
|
DataCubeQuerySortDirection,
|
|
@@ -50,24 +51,27 @@ export function getColumnConfiguration(
|
|
|
50
51
|
// --------------------------------- MAIN ---------------------------------
|
|
51
52
|
|
|
52
53
|
export function buildQuerySnapshot(
|
|
53
|
-
request:
|
|
54
|
+
request: DataCubeGridClientDataFetchRequest,
|
|
54
55
|
baseSnapshot: DataCubeQuerySnapshot,
|
|
55
56
|
) {
|
|
56
57
|
const snapshot = baseSnapshot.clone();
|
|
57
58
|
const configuration = DataCubeConfiguration.serialization.fromJson(
|
|
58
59
|
snapshot.data.configuration,
|
|
59
60
|
);
|
|
61
|
+
const rowGroupColumns = request.rowGroupColumns.filter(
|
|
62
|
+
(col) => col !== INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
63
|
+
);
|
|
60
64
|
|
|
61
65
|
// --------------------------------- SELECT ---------------------------------
|
|
62
66
|
|
|
63
67
|
snapshot.data.selectColumns = uniqBy(
|
|
64
68
|
[
|
|
65
69
|
...snapshot.data.selectColumns,
|
|
66
|
-
...request.
|
|
67
|
-
getColumnConfiguration(col
|
|
70
|
+
...request.pivotColumns.map((col) =>
|
|
71
|
+
getColumnConfiguration(col, configuration),
|
|
68
72
|
),
|
|
69
|
-
...
|
|
70
|
-
getColumnConfiguration(col
|
|
73
|
+
...rowGroupColumns.map((col) =>
|
|
74
|
+
getColumnConfiguration(col, configuration),
|
|
71
75
|
),
|
|
72
76
|
],
|
|
73
77
|
(col) => col.name,
|
|
@@ -75,10 +79,10 @@ export function buildQuerySnapshot(
|
|
|
75
79
|
|
|
76
80
|
// --------------------------------- PIVOT ---------------------------------
|
|
77
81
|
|
|
78
|
-
snapshot.data.pivot = request.
|
|
82
|
+
snapshot.data.pivot = request.pivotColumns.length
|
|
79
83
|
? {
|
|
80
|
-
columns: request.
|
|
81
|
-
_toCol(getColumnConfiguration(col
|
|
84
|
+
columns: request.pivotColumns.map((col) =>
|
|
85
|
+
_toCol(getColumnConfiguration(col, configuration)),
|
|
82
86
|
),
|
|
83
87
|
// NOTE: since we re-fetch the cast columns anyway in this flow, we just
|
|
84
88
|
// reuse the current cast columns
|
|
@@ -88,33 +92,39 @@ export function buildQuerySnapshot(
|
|
|
88
92
|
|
|
89
93
|
// --------------------------------- GROUP BY ---------------------------------
|
|
90
94
|
|
|
91
|
-
snapshot.data.groupBy =
|
|
95
|
+
snapshot.data.groupBy = rowGroupColumns.length
|
|
92
96
|
? {
|
|
93
|
-
columns:
|
|
94
|
-
_toCol(getColumnConfiguration(col
|
|
97
|
+
columns: rowGroupColumns.map((col) =>
|
|
98
|
+
_toCol(getColumnConfiguration(col, configuration)),
|
|
95
99
|
),
|
|
96
100
|
}
|
|
97
101
|
: undefined;
|
|
98
102
|
|
|
99
103
|
// --------------------------------- SORT ---------------------------------
|
|
100
104
|
|
|
101
|
-
snapshot.data.sortColumns = request.
|
|
105
|
+
snapshot.data.sortColumns = request.sortColumns
|
|
102
106
|
// Make sure the tree column is not being sorted since it's a synthetic column
|
|
103
107
|
// the sorting state of this special column is `synthesized` by ag-grid
|
|
104
108
|
// so when all group by columns are sorted in the same direction, the tree group
|
|
105
109
|
// column will be sorted in that direction, and vice versa, when user sorts
|
|
106
110
|
// the tree column, all groupBy columns will be sorted in that direction
|
|
107
|
-
.filter(
|
|
111
|
+
.filter(
|
|
112
|
+
(item) =>
|
|
113
|
+
![
|
|
114
|
+
INTERNAL__GRID_CLIENT_TREE_COLUMN_ID,
|
|
115
|
+
INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
116
|
+
].includes(item.name),
|
|
117
|
+
)
|
|
108
118
|
.map((item) => ({
|
|
109
|
-
name: item.
|
|
119
|
+
name: item.name,
|
|
110
120
|
type: getColumnConfiguration(
|
|
111
|
-
isPivotResultColumnName(item.
|
|
112
|
-
? getPivotResultColumnBaseColumnName(item.
|
|
113
|
-
: item.
|
|
121
|
+
isPivotResultColumnName(item.name)
|
|
122
|
+
? getPivotResultColumnBaseColumnName(item.name)
|
|
123
|
+
: item.name,
|
|
114
124
|
configuration,
|
|
115
125
|
).type,
|
|
116
126
|
direction:
|
|
117
|
-
item.
|
|
127
|
+
item.direction === DataCubeGridClientSortDirection.ASCENDING
|
|
118
128
|
? DataCubeQuerySortDirection.ASCENDING
|
|
119
129
|
: DataCubeQuerySortDirection.DESCENDING,
|
|
120
130
|
}));
|
|
@@ -126,6 +136,16 @@ export function buildQuerySnapshot(
|
|
|
126
136
|
snapshot.data.groupBy?.columns ?? [],
|
|
127
137
|
configuration.pivotLayout.expandedPaths,
|
|
128
138
|
);
|
|
139
|
+
// if root aggregation synthetic column has been removed
|
|
140
|
+
// pdate the configuration to disable root aggregation
|
|
141
|
+
if (
|
|
142
|
+
!request.rowGroupColumns.includes(
|
|
143
|
+
INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
144
|
+
) &&
|
|
145
|
+
configuration.showRootAggregation
|
|
146
|
+
) {
|
|
147
|
+
configuration.showRootAggregation = false;
|
|
148
|
+
}
|
|
129
149
|
snapshot.data.configuration = configuration.serialize();
|
|
130
150
|
|
|
131
151
|
// --------------------------------- FINALIZE ---------------------------------
|
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
debounce,
|
|
19
|
+
guaranteeNonNullable,
|
|
20
|
+
type DebouncedFunc,
|
|
21
|
+
} from '@finos/legend-shared';
|
|
18
22
|
import { action, makeObservable, observable } from 'mobx';
|
|
19
23
|
import type { GridApi } from '@ag-grid-community/core';
|
|
20
24
|
import type { DataCubeViewState } from '../DataCubeViewState.js';
|
|
@@ -59,6 +63,9 @@ export class DataCubeGridState extends DataCubeQuerySnapshotController {
|
|
|
59
63
|
rowLimit?: number | undefined;
|
|
60
64
|
isPaginationEnabled = INTERNAL__GRID_CLIENT_DEFAULT_ENABLE_PAGINATION;
|
|
61
65
|
scrollHintText?: string | undefined;
|
|
66
|
+
// As we resize columns dynamically to fit their content, virtual columns are being rendered
|
|
67
|
+
// and resized as user scrolls horizontally, this can cause performance issues, so we debounce.
|
|
68
|
+
debouncedAutoResizeColumns?: DebouncedFunc<() => void>;
|
|
62
69
|
|
|
63
70
|
constructor(view: DataCubeViewState) {
|
|
64
71
|
super(view);
|
|
@@ -112,6 +119,10 @@ export class DataCubeGridState extends DataCubeQuerySnapshotController {
|
|
|
112
119
|
|
|
113
120
|
configureClient(val: GridApi | undefined) {
|
|
114
121
|
this._client = val;
|
|
122
|
+
this.debouncedAutoResizeColumns = debounce(
|
|
123
|
+
() => val?.autoSizeAllColumns(),
|
|
124
|
+
100,
|
|
125
|
+
);
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
override getSnapshotSubscriberName() {
|