@finos/legend-data-cube 0.0.24 → 0.0.26
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 +3 -3
- 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 +48 -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 +89 -40
- 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 +13 -4
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.js +40 -9
- 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 +8 -8
- 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 +67 -52
- package/src/stores/view/grid/DataCubeGridConfigurationBuilder.tsx +99 -42
- package/src/stores/view/grid/DataCubeGridMenuBuilder.tsx +1 -1
- package/src/stores/view/grid/DataCubeGridQueryBuilder.ts +71 -15
- package/src/stores/view/grid/DataCubeGridQuerySnapshotBuilder.ts +40 -20
- package/src/stores/view/grid/DataCubeGridState.ts +12 -1
- package/tsconfig.json +2 -0
|
@@ -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';
|
|
@@ -213,21 +215,23 @@ function _displaySpec(columnData: ColumnData) {
|
|
|
213
215
|
hide:
|
|
214
216
|
column.hideFromView ||
|
|
215
217
|
!column.isSelected ||
|
|
216
|
-
Boolean(
|
|
218
|
+
(Boolean(
|
|
217
219
|
snapshot.data.pivot &&
|
|
218
220
|
!snapshot.data.pivot.castColumns.find((col) => col.name === name),
|
|
219
|
-
)
|
|
221
|
+
) &&
|
|
222
|
+
!snapshot.data.groupExtendedColumns.find((col) => col.name === name)),
|
|
220
223
|
lockVisible:
|
|
221
224
|
!column.isSelected ||
|
|
222
|
-
Boolean(
|
|
225
|
+
(Boolean(
|
|
223
226
|
snapshot.data.pivot &&
|
|
224
227
|
!snapshot.data.pivot.castColumns.find((col) => col.name === name),
|
|
225
|
-
)
|
|
228
|
+
) &&
|
|
229
|
+
!snapshot.data.groupExtendedColumns.find((col) => col.name === name)),
|
|
226
230
|
pinned:
|
|
227
231
|
column.pinned !== undefined
|
|
228
232
|
? column.pinned === DataCubeColumnPinPlacement.RIGHT
|
|
229
|
-
?
|
|
230
|
-
:
|
|
233
|
+
? DataCubeGridClientPinnedAlignement.RIGHT
|
|
234
|
+
: DataCubeGridClientPinnedAlignement.LEFT
|
|
231
235
|
: null,
|
|
232
236
|
headerClass: isPivotResultColumnName(name)
|
|
233
237
|
? 'pl-1 border border-neutral-300'
|
|
@@ -313,13 +317,18 @@ function _displaySpec(columnData: ColumnData) {
|
|
|
313
317
|
}
|
|
314
318
|
: {}),
|
|
315
319
|
});
|
|
316
|
-
// 3. add the parentheses
|
|
317
|
-
|
|
320
|
+
// 3. add the parentheses, scale unit, unit, etc.
|
|
321
|
+
let displayValue =
|
|
318
322
|
(showNegativeNumberInParens
|
|
319
323
|
? `(${formattedValue})`
|
|
320
324
|
: formattedValue) +
|
|
321
|
-
(scaledNumber.unit ? ` ${scaledNumber.unit}` : '')
|
|
322
|
-
)
|
|
325
|
+
(scaledNumber.unit ? ` ${scaledNumber.unit}` : '');
|
|
326
|
+
if (column.unit) {
|
|
327
|
+
displayValue = !column.unit.startsWith('_')
|
|
328
|
+
? `${displayValue}${column.unit}`
|
|
329
|
+
: `${column.unit.substring(1)}${displayValue}`;
|
|
330
|
+
}
|
|
331
|
+
return displayValue;
|
|
323
332
|
}
|
|
324
333
|
: (params) =>
|
|
325
334
|
params.value === INTERNAL__GRID_CLIENT_MISSING_VALUE
|
|
@@ -357,7 +366,7 @@ function _groupDisplaySpec(
|
|
|
357
366
|
hide: !snapshot.data.groupBy,
|
|
358
367
|
lockPosition: true,
|
|
359
368
|
lockPinned: true,
|
|
360
|
-
pinned:
|
|
369
|
+
pinned: DataCubeGridClientPinnedAlignement.LEFT,
|
|
361
370
|
cellClassRules: {
|
|
362
371
|
[generateFontFamilyUtilityClassName(fontFamily)]: () => true,
|
|
363
372
|
[generateFontSizeUtilityClassName(fontSize)]: () => true,
|
|
@@ -413,11 +422,6 @@ function _sizeSpec(columnData: ColumnData) {
|
|
|
413
422
|
INTERNAL__GRID_CLIENT_COLUMN_MIN_WIDTH,
|
|
414
423
|
),
|
|
415
424
|
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
425
|
} as ColDef;
|
|
422
426
|
}
|
|
423
427
|
|
|
@@ -429,28 +433,34 @@ function _sortSpec(columnData: ColumnData) {
|
|
|
429
433
|
sortable: true, // if this is pivot column, no sorting is supported yet
|
|
430
434
|
sort: sortCol
|
|
431
435
|
? sortCol.direction === DataCubeQuerySortDirection.ASCENDING
|
|
432
|
-
?
|
|
433
|
-
:
|
|
436
|
+
? DataCubeGridClientSortDirection.ASCENDING
|
|
437
|
+
: DataCubeGridClientSortDirection.DESCENDING
|
|
434
438
|
: null,
|
|
435
439
|
sortIndex: sortCol ? sortColumns.indexOf(sortCol) : null,
|
|
436
440
|
} satisfies ColDef;
|
|
437
441
|
}
|
|
438
442
|
|
|
439
443
|
function _aggregationSpec(columnData: ColumnData) {
|
|
440
|
-
const { name, snapshot, column } = columnData;
|
|
444
|
+
const { name, snapshot, column, configuration } = columnData;
|
|
441
445
|
const data = snapshot.data;
|
|
442
446
|
const pivotCol = _findCol(data.pivot?.columns, name);
|
|
443
447
|
const groupByCol = _findCol(data.groupBy?.columns, name);
|
|
444
448
|
const isGroupExtendedColumn = Boolean(
|
|
445
449
|
_findCol(data.groupExtendedColumns, name),
|
|
446
450
|
);
|
|
451
|
+
const rowGroupIndex =
|
|
452
|
+
!isGroupExtendedColumn && groupByCol
|
|
453
|
+
? (data.groupBy?.columns.indexOf(groupByCol) ?? null)
|
|
454
|
+
: null;
|
|
447
455
|
return {
|
|
448
456
|
enableRowGroup:
|
|
449
457
|
!isGroupExtendedColumn && column.kind === DataCubeColumnKind.DIMENSION,
|
|
450
458
|
rowGroup: !isGroupExtendedColumn && Boolean(groupByCol),
|
|
451
459
|
rowGroupIndex:
|
|
452
|
-
|
|
453
|
-
?
|
|
460
|
+
rowGroupIndex !== null
|
|
461
|
+
? configuration.showRootAggregation
|
|
462
|
+
? rowGroupIndex + 1
|
|
463
|
+
: rowGroupIndex
|
|
454
464
|
: null,
|
|
455
465
|
enablePivot:
|
|
456
466
|
!isGroupExtendedColumn && column.kind === DataCubeColumnKind.DIMENSION,
|
|
@@ -546,8 +556,6 @@ export function generateBaseGridOptions(view: DataCubeViewState): GridOptions {
|
|
|
546
556
|
event.api.hidePopupMenu(); // hide context-menu while scrolling
|
|
547
557
|
},
|
|
548
558
|
onBodyScrollEnd: () => grid.setScrollHintText(undefined),
|
|
549
|
-
scrollbarWidth: 10,
|
|
550
|
-
alwaysShowVerticalScroll: true, // this is needed to ensure column resize calculation is accurate
|
|
551
559
|
// -------------------------------------- CONTEXT MENU --------------------------------------
|
|
552
560
|
preventDefaultOnContextMenu: true, // prevent showing the browser's context menu
|
|
553
561
|
columnMenu: 'new', // ensure context menu works on header
|
|
@@ -572,16 +580,8 @@ export function generateBaseGridOptions(view: DataCubeViewState): GridOptions {
|
|
|
572
580
|
},
|
|
573
581
|
// -------------------------------------- COLUMN SIZING --------------------------------------
|
|
574
582
|
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
583
|
autoSizeStrategy: {
|
|
581
|
-
type: '
|
|
582
|
-
},
|
|
583
|
-
onGridSizeChanged: (event) => {
|
|
584
|
-
event.api.sizeColumnsToFit();
|
|
584
|
+
type: 'fitCellContents',
|
|
585
585
|
},
|
|
586
586
|
// -------------------------------------- TOOLTIP --------------------------------------
|
|
587
587
|
tooltipShowDelay: INTERNAL__GRID_CLIENT_TOOLTIP_SHOW_DELAY,
|
|
@@ -594,6 +594,10 @@ export function generateBaseGridOptions(view: DataCubeViewState): GridOptions {
|
|
|
594
594
|
suppressScrollOnNewData: true,
|
|
595
595
|
// NOTE: use row loader instead of showing loader in each cell to improve performance
|
|
596
596
|
// otherwise, when we have many columns (i.e. when pivoting), the app could freeze.
|
|
597
|
+
//
|
|
598
|
+
// This would render the loading cell as the full-width row, which, in combination with
|
|
599
|
+
// fit cell content auto-sizing strategy creates an unwanted row flashing effect while loading.
|
|
600
|
+
// To compensate for that, we modify the styling to make sure the full-width row has a blank background
|
|
597
601
|
loadingCellRenderer: DataCubeGridLoadingCellRenderer,
|
|
598
602
|
// By default, when row-grouping is active, ag-grid's caching mechanism causes sort
|
|
599
603
|
// to not work properly for pivot result columns, so we must disable this mechanism.
|
|
@@ -807,7 +811,7 @@ export function generateColumnDefs(
|
|
|
807
811
|
);
|
|
808
812
|
}
|
|
809
813
|
|
|
810
|
-
|
|
814
|
+
const columnDefs = [
|
|
811
815
|
// NOTE: Internal column used for programatically trigger data fetch when filter is modified
|
|
812
816
|
{
|
|
813
817
|
colId: INTERNAL__GRID_CLIENT_DATA_FETCH_MANUAL_TRIGGER_COLUMN_ID,
|
|
@@ -819,6 +823,24 @@ export function generateColumnDefs(
|
|
|
819
823
|
filter: 'agTextColumnFilter',
|
|
820
824
|
suppressColumnsToolPanel: true,
|
|
821
825
|
},
|
|
826
|
+
...(configuration.showRootAggregation
|
|
827
|
+
? [
|
|
828
|
+
{
|
|
829
|
+
colId: INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
830
|
+
headerName: 'Root',
|
|
831
|
+
field: INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
|
|
832
|
+
hide: true,
|
|
833
|
+
enableValue: false, // disable GUI interactions to modify this column's aggregate function
|
|
834
|
+
allowedAggFuncs: [], // disable GUI for options of the agg functions
|
|
835
|
+
enablePivot: false,
|
|
836
|
+
enableRowGroup: false,
|
|
837
|
+
|
|
838
|
+
suppressColumnsToolPanel: true,
|
|
839
|
+
rowGroup: true,
|
|
840
|
+
rowGroupIndex: 0,
|
|
841
|
+
} satisfies ColDef,
|
|
842
|
+
]
|
|
843
|
+
: []),
|
|
822
844
|
...generateDefinitionForPivotResultColumns(
|
|
823
845
|
pivotResultColumns,
|
|
824
846
|
snapshot,
|
|
@@ -851,6 +873,8 @@ export function generateColumnDefs(
|
|
|
851
873
|
} satisfies ColDef;
|
|
852
874
|
}),
|
|
853
875
|
] satisfies (ColDef | ColGroupDef)[];
|
|
876
|
+
|
|
877
|
+
return columnDefs;
|
|
854
878
|
}
|
|
855
879
|
|
|
856
880
|
export function generateGridOptionsFromSnapshot(
|
|
@@ -863,15 +887,36 @@ export function generateGridOptionsFromSnapshot(
|
|
|
863
887
|
if (
|
|
864
888
|
configuration.initialExpandLevel !== undefined &&
|
|
865
889
|
configuration.initialExpandLevel > 0 &&
|
|
866
|
-
params.rowNode.level <=
|
|
890
|
+
params.rowNode.level <=
|
|
891
|
+
// root aggregation (if enabled) should not be counted when applying initial expand level
|
|
892
|
+
(configuration.showRootAggregation
|
|
893
|
+
? configuration.initialExpandLevel + 1
|
|
894
|
+
: configuration.initialExpandLevel) -
|
|
895
|
+
1
|
|
867
896
|
) {
|
|
868
897
|
return true;
|
|
869
898
|
}
|
|
870
899
|
|
|
871
|
-
const routes = params.rowNode.getRoute();
|
|
872
|
-
if (!routes) {
|
|
900
|
+
const routes = params.rowNode.getRoute() ?? [];
|
|
901
|
+
if (!routes.length) {
|
|
873
902
|
return false;
|
|
874
903
|
}
|
|
904
|
+
|
|
905
|
+
// when root aggregation is enabled, the root node should be
|
|
906
|
+
// expanded automatically by default
|
|
907
|
+
if (
|
|
908
|
+
configuration.showRootAggregation &&
|
|
909
|
+
routes.length === 1 &&
|
|
910
|
+
routes[0] === DEFAULT_ROOT_AGGREGATION_COLUMN_VALUE
|
|
911
|
+
) {
|
|
912
|
+
return true;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// when root aggregation is enabled, the root node should not be removed
|
|
916
|
+
// from path when matching against all expanded paths
|
|
917
|
+
if (configuration.showRootAggregation) {
|
|
918
|
+
routes.shift();
|
|
919
|
+
}
|
|
875
920
|
const path = routes.join(TREE_COLUMN_VALUE_SEPARATOR);
|
|
876
921
|
if (configuration.pivotLayout.expandedPaths.includes(path)) {
|
|
877
922
|
return true;
|
|
@@ -909,7 +954,7 @@ export function generateGridOptionsFromSnapshot(
|
|
|
909
954
|
column.getColId(),
|
|
910
955
|
pinned === null
|
|
911
956
|
? undefined
|
|
912
|
-
: pinned ===
|
|
957
|
+
: pinned === DataCubeGridClientPinnedAlignement.LEFT
|
|
913
958
|
? DataCubeColumnPinPlacement.LEFT
|
|
914
959
|
: DataCubeColumnPinPlacement.RIGHT,
|
|
915
960
|
);
|
|
@@ -941,7 +986,13 @@ export function generateGridOptionsFromSnapshot(
|
|
|
941
986
|
// expanded-to-level is specified, causing the groups to be automatically drilled down, resultant
|
|
942
987
|
// expanded paths will not be kept for record.
|
|
943
988
|
if (event.event) {
|
|
944
|
-
const
|
|
989
|
+
const routes = event.node.getRoute() ?? [];
|
|
990
|
+
// when root aggregation is enabled, the root node should not be counted
|
|
991
|
+
// when formulating the expanded path
|
|
992
|
+
if (routes.length && configuration.showRootAggregation) {
|
|
993
|
+
routes.shift();
|
|
994
|
+
}
|
|
995
|
+
const path = routes.join(TREE_COLUMN_VALUE_SEPARATOR);
|
|
945
996
|
if (!path) {
|
|
946
997
|
return;
|
|
947
998
|
}
|
|
@@ -953,6 +1004,14 @@ export function generateGridOptionsFromSnapshot(
|
|
|
953
1004
|
}
|
|
954
1005
|
},
|
|
955
1006
|
|
|
1007
|
+
// Virtual columns when being rendered (as user scrolls horizontally) would get resized
|
|
1008
|
+
// to fit their content dynamically. This can potentially cause some performance issues,
|
|
1009
|
+
// so we debounce the resize operation.
|
|
1010
|
+
onVirtualColumnsChanged: () => {
|
|
1011
|
+
view.grid.debouncedAutoResizeColumns?.cancel();
|
|
1012
|
+
view.grid.debouncedAutoResizeColumns?.();
|
|
1013
|
+
},
|
|
1014
|
+
|
|
956
1015
|
// -------------------------------------- COLUMNS --------------------------------------
|
|
957
1016
|
|
|
958
1017
|
columnDefs: generateColumnDefs(snapshot, configuration, view),
|
|
@@ -971,8 +1030,6 @@ export function generateGridOptionsFromSnapshot(
|
|
|
971
1030
|
..._groupDisplaySpec(snapshot, configuration),
|
|
972
1031
|
|
|
973
1032
|
// size
|
|
974
|
-
suppressAutoSize: true,
|
|
975
|
-
suppressSizeToFit: true,
|
|
976
1033
|
minWidth: 200,
|
|
977
1034
|
|
|
978
1035
|
// 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]
|
|
@@ -71,7 +75,7 @@ import { _colSpecArrayParam } from '../../core/DataCubeQuerySnapshotBuilderUtils
|
|
|
71
75
|
|
|
72
76
|
// --------------------------------- BUILDING BLOCKS ---------------------------------
|
|
73
77
|
|
|
74
|
-
function _aggCountCol() {
|
|
78
|
+
export function _aggCountCol() {
|
|
75
79
|
const variable = _var();
|
|
76
80
|
return _colSpec(
|
|
77
81
|
INTERNAL__GRID_CLIENT_ROW_GROUPING_COUNT_AGG_COLUMN_ID,
|
|
@@ -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() {
|
package/tsconfig.json
CHANGED
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
"isolatedModules": true,
|
|
31
31
|
"esModuleInterop": true,
|
|
32
32
|
"allowSyntheticDefaultImports": true,
|
|
33
|
+
"resolvePackageJsonExports": true,
|
|
34
|
+
"resolvePackageJsonImports": true,
|
|
33
35
|
"preserveConstEnums": true,
|
|
34
36
|
"incremental": true,
|
|
35
37
|
"useDefineForClassFields": true,
|