@adaptabletools/adaptable 20.0.6 → 20.0.7-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/package.json +1 -1
  2. package/src/AdaptableOptions/ColumnOptions.d.ts +173 -2
  3. package/src/AdaptableState/Common/AggregationColumns.d.ts +8 -1
  4. package/src/AdaptableState/LayoutState.d.ts +12 -0
  5. package/src/Api/Implementation/ColumnApiImpl.d.ts +1 -0
  6. package/src/Api/Implementation/ColumnApiImpl.js +11 -1
  7. package/src/Api/Implementation/LayoutHelpers.js +25 -2
  8. package/src/Api/Internal/ColumnInternalApi.d.ts +3 -1
  9. package/src/Api/Internal/ColumnInternalApi.js +201 -0
  10. package/src/Utilities/Constants/GeneralConstants.d.ts +1 -0
  11. package/src/Utilities/Constants/GeneralConstants.js +1 -0
  12. package/src/Utilities/Extensions/StringExtensions.js +11 -3
  13. package/src/Utilities/adaptableOverrideCheck.d.ts +2 -0
  14. package/src/Utilities/adaptableOverrideCheck.js +8 -0
  15. package/src/agGrid/AdaptableAgGrid.js +29 -0
  16. package/src/agGrid/AgGridAdapter.js +1 -0
  17. package/src/agGrid/AgGridColumnAdapter.d.ts +1 -1
  18. package/src/agGrid/AgGridColumnAdapter.js +7 -13
  19. package/src/env.js +2 -2
  20. package/src/layout-manager/src/LayoutManagerModel.d.ts +23 -20
  21. package/src/layout-manager/src/destructurePivotColumnId.d.ts +10 -0
  22. package/src/layout-manager/src/destructurePivotColumnId.js +80 -0
  23. package/src/layout-manager/src/index.d.ts +5 -0
  24. package/src/layout-manager/src/index.js +168 -2
  25. package/src/layout-manager/src/isPivotGroupTotalColumn.d.ts +2 -0
  26. package/src/layout-manager/src/isPivotGroupTotalColumn.js +5 -0
  27. package/src/layout-manager/src/isPivotTotalColumn.d.ts +2 -0
  28. package/src/layout-manager/src/isPivotTotalColumn.js +3 -0
  29. package/src/layout-manager/src/normalizeLayoutModel.js +3 -0
  30. package/src/metamodel/adaptable.metamodel.d.ts +12 -4
  31. package/src/metamodel/adaptable.metamodel.js +1 -1
  32. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -27,7 +27,7 @@ export declare class AgGridColumnAdapter {
27
27
  private setupColumnAllowedAggFuncs;
28
28
  private setupColumnType;
29
29
  private setupColumnCellDataType;
30
- setupColumnHeader({ col, abColumn }: ColumnSetupInfo): boolean;
30
+ setupColumnHeader({ col, abColumn }: ColumnSetupInfo): void;
31
31
  private setupColumnFilter;
32
32
  setupColumnFloatingFilterTemporarily(initialGridOptions: GridOptions): void;
33
33
  private setupColumnFloatingFilter;
@@ -12,7 +12,8 @@ import Helper from '../Utilities/Helpers/Helper';
12
12
  import { AdaptableNumberEditor, AdaptableReactNumberEditor } from './editors/AdaptableNumberEditor';
13
13
  import { AdaptableDateEditor, AdaptableReactDateEditor } from './editors/AdaptableDateEditor';
14
14
  import { AgGridExportAdapter } from './AgGridExportAdapter';
15
- import { AdaptableHelper, } from '../Utilities/Helpers/AdaptableHelper';
15
+ import { AdaptableHelper } from '../Utilities/Helpers/AdaptableHelper';
16
+ import { isProvidedByAdaptable } from '../Utilities/adaptableOverrideCheck';
16
17
  export function getEditorForColumnDataType(columnDataType, variant) {
17
18
  if (columnDataType === 'number') {
18
19
  return variant === 'react' ? AdaptableReactNumberEditor : AdaptableNumberEditor;
@@ -371,19 +372,12 @@ export class AgGridColumnAdapter {
371
372
  });
372
373
  }
373
374
  setupColumnHeader({ col, abColumn }) {
374
- const previousColumnHeader = col?.getColDef()?.headerName;
375
- this.setColDefProperty(col, 'headerName', (userHeaderName) => {
376
- // set the default to the AG Grid provided values
377
- // from https://github.com/ag-grid/ag-grid/blob/v26.1.0/community-modules/core/src/ts/columns/columnModel.ts#L2515
378
- let resultHeaderName = userHeaderName ?? StringExtensions.CamelCaseToHumanText(col.getColDef().field);
379
- const layoutCustomHeader = this.adaptableApi.layoutApi.getCurrentLayout().ColumnHeaders?.[col.getColId()];
380
- if (layoutCustomHeader) {
381
- resultHeaderName = layoutCustomHeader;
382
- }
383
- return resultHeaderName;
375
+ this.setColDefProperty(col, 'headerValueGetter', (original_headerValueGetter) => {
376
+ if (!isProvidedByAdaptable(original_headerValueGetter)) {
377
+ this.adaptableApi.logWarn(`colDef.headerValueGetter is defined for column '${col.getColId()}', and overrides the Adaptable custom header mechanism! We recommend using a ColumnOptions.tableColumnHeader instead!`);
378
+ }
379
+ return original_headerValueGetter;
384
380
  });
385
- const newColumnHeader = col?.getColDef()?.headerName;
386
- return previousColumnHeader !== newColumnHeader;
387
381
  }
388
382
  setupColumnFilter({ col, colDef }) {
389
383
  this.setColDefProperty(col, 'filter', () => {
package/src/env.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export default {
2
2
  NEXT_PUBLIC_INFINITE_TABLE_LICENSE_KEY: "StartDate=2021-06-29|EndDate=2030-01-01|Owner=Adaptable|Type=distribution|TS=1624971462479|C=137829811,1004007071,2756196225,1839832928,3994409405,636616862" || '',
3
- PUBLISH_TIMESTAMP: 1744973609759 || Date.now(),
4
- VERSION: "20.0.6" || '--current-version--',
3
+ PUBLISH_TIMESTAMP: 1745347655771 || Date.now(),
4
+ VERSION: "20.0.7-canary.0" || '--current-version--',
5
5
  };
@@ -62,26 +62,17 @@ export type ColumnAggregationModel = {
62
62
  aggFunc: string | true;
63
63
  weightedColumnId?: string;
64
64
  };
65
- export type AggregationColumnsModel = {
65
+ export type AggregationColumnsModelItem = {
66
66
  ColumnId: string;
67
67
  AggFunc: ColumnAggregationModel;
68
- }[];
69
- type RowSummaryPosition = 'Top' | 'Bottom';
70
- export interface RowSummaryModel {
71
- /**
72
- * Where Row Summary appears - 'Top' or 'Bottom'
73
- */
74
- Position?: RowSummaryPosition;
75
- /**
76
- * Map of Columns with Summary Expressions
77
- */
78
- ColumnsMap: Record<string, string>;
79
- /**
80
- * Evaluates only currently filtered rows in the summary
81
- * @defaultValue true
82
- */
83
- IncludeOnlyFilteredRows?: boolean;
84
- }
68
+ };
69
+ export type AggregationColumnsModel = AggregationColumnsModelItem[];
70
+ export type PivotAggregationColumnsModel = (AggregationColumnsModelItem & {
71
+ TotalColumn?: boolean | 'before' | 'after' | {
72
+ PivotColumnId: string;
73
+ ShowTotal?: boolean | 'before' | 'after';
74
+ }[];
75
+ })[];
85
76
  export interface TableLayoutModel extends BaseLayoutModel {
86
77
  TableColumns: string[];
87
78
  /**
@@ -96,6 +87,7 @@ export interface TableLayoutModel extends BaseLayoutModel {
96
87
  * @defaultValue 'single'
97
88
  */
98
89
  RowGroupDisplayType?: 'single' | 'multi';
90
+ PivotAggregationColumns?: never;
99
91
  PivotColumns?: never;
100
92
  PivotGroupedColumns?: never;
101
93
  PivotExpandLevel?: never;
@@ -110,13 +102,24 @@ export interface PivotLayoutModel extends BaseLayoutModel {
110
102
  /**
111
103
  * Columns showing aggregated values in Group Rows; 1st value in record is Column name, 2nd is either aggfunc (e.g. sum, avg etc.) or 'true' (to use default aggfunc)
112
104
  */
113
- PivotAggregationColumns?: AggregationColumnsModel;
105
+ PivotAggregationColumns?: PivotAggregationColumnsModel;
114
106
  TableAggregationColumns?: never;
115
107
  /**
116
108
  * Columns which are row-grouped when the Layout is applied
117
109
  */
118
110
  PivotGroupedColumns?: string[];
119
111
  RowGroupedColumns?: never;
112
+ /**
113
+ * Display Grand Total Row at the top or bottom of the Pivot Table
114
+ */
115
+ GrandTotalRow?: 'top' | 'bottom' | boolean;
116
+ /**
117
+ * Display Total of all Pivot Columns before or after the Pivot Columns
118
+ */
119
+ GrandTotalColumn?: 'before' | 'after' | boolean;
120
+ /**
121
+ * Display automatically calculated Totals within EACH Pivot Column Group, in the position specified
122
+ */
123
+ PivotGroupTotalColumn?: 'before' | 'after' | boolean;
120
124
  }
121
125
  export type LayoutModel = TableLayoutModel | PivotLayoutModel;
122
- export {};
@@ -0,0 +1,10 @@
1
+ import { ColDef } from 'ag-grid-enterprise';
2
+ export declare function destructurePivotColumnId(colDef: ColDef, currentModel: {
3
+ pivotColIds: string[];
4
+ aggColIds: string[];
5
+ }, logWarning: (message: string) => void): '!unknown!' | {
6
+ pivotColumnIds: string[];
7
+ pivotKeys: string[];
8
+ pivotColumnId: string;
9
+ aggregationColumnId?: string;
10
+ };
@@ -0,0 +1,80 @@
1
+ // supports only pivotTotalColumns (aggregation total) and pivotGroupTotal
2
+ // AG Grid builds the ID as: `pivot_${pivotCols.join('-')}_${pivotKeys.join('-')}_${measureColumnId}`
3
+ // see https://github.com/ag-grid/ag-grid/blob/e0cfe533b55b75cdc148cdfb1a4e977731dc0712/packages/ag-grid-enterprise/src/pivot/pivotColDefService.ts#L454C16-L454C88
4
+ export function destructurePivotColumnId(colDef, currentModel, logWarning) {
5
+ const { colId } = colDef;
6
+ // Basic validation
7
+ if (!colId?.startsWith('pivot_')) {
8
+ logWarning(`Column id must start with 'pivot_': ${colId}`);
9
+ return '!unknown!';
10
+ }
11
+ const hasSpecialChars = (arr) => arr.some((str) => str.includes('-') || str.includes('_'));
12
+ // AG Grid uses _ and - as delimiters
13
+ // if we have these special characters in the column IDs, we need to parse them differently
14
+ const colIdsOrKeysContainSpecialChars = hasSpecialChars(currentModel.pivotColIds) ||
15
+ hasSpecialChars(currentModel.aggColIds) ||
16
+ hasSpecialChars(colDef.pivotKeys || []);
17
+ // Fast path - no special characters
18
+ if (!colIdsOrKeysContainSpecialChars) {
19
+ // Split by underscore to get 4 parts
20
+ const parts = colId.split('_');
21
+ if (parts.length !== 4) {
22
+ logWarning(`Unsupported format of pivot total column id: ${colId}`);
23
+ return '!unknown!';
24
+ }
25
+ const [_pivotPrefix, pivotColsTxt, pivotKeysTxt, aggregationColumnId] = parts;
26
+ const pivotColumnIds = pivotColsTxt.split('-');
27
+ const pivotKeys = pivotKeysTxt.split('-');
28
+ const pivotColumnId = pivotColumnIds[pivotKeys.length - 1];
29
+ return {
30
+ pivotColumnIds,
31
+ pivotKeys,
32
+ pivotColumnId,
33
+ aggregationColumnId: aggregationColumnId !== '' ? aggregationColumnId : undefined,
34
+ };
35
+ }
36
+ // the complex path, where we have to handle the special characters
37
+ // Remove 'pivot_' prefix
38
+ const withoutPrefix = colId.slice(6);
39
+ // Check if it's a pivot group total
40
+ const isPivotGroupTotal = withoutPrefix.endsWith('_');
41
+ // Get pivot keys from colDef (more reliable than string parsing)
42
+ const pivotKeys = colDef.pivotKeys || [];
43
+ if (isPivotGroupTotal) {
44
+ // Remove trailing underscore for pivot group totals
45
+ const content = withoutPrefix.slice(0, -1);
46
+ // The remaining content should be the pivot columns
47
+ const pivotColumnIds = currentModel.pivotColIds.filter((id) => content.includes(id));
48
+ if (!pivotColumnIds.length) {
49
+ logWarning(`Could not identify pivot columns in: ${content}`);
50
+ return '!unknown!';
51
+ }
52
+ return {
53
+ pivotColumnIds,
54
+ pivotKeys,
55
+ pivotColumnId: pivotColumnIds[pivotKeys.length],
56
+ };
57
+ }
58
+ // For regular pivot columns, work backwards to find aggregation column
59
+ const parts = withoutPrefix.split('_');
60
+ const lastPart = parts[parts.length - 1];
61
+ // Find the longest matching aggregation column id from the end
62
+ const aggregationColumnId = currentModel.aggColIds.find((aggId) => lastPart.endsWith(aggId));
63
+ if (!aggregationColumnId) {
64
+ logWarning(`Could not identify aggregation column in: ${lastPart}`);
65
+ return '!unknown!';
66
+ }
67
+ // Remove aggregation part and get pivot columns
68
+ const withoutAgg = withoutPrefix.slice(0, -(aggregationColumnId.length + 1));
69
+ const pivotColumnIds = currentModel.pivotColIds.filter((id) => withoutAgg.includes(id));
70
+ if (!pivotColumnIds.length) {
71
+ logWarning(`Could not identify pivot columns in: ${withoutAgg}`);
72
+ return '!unknown!';
73
+ }
74
+ return {
75
+ pivotColumnIds,
76
+ pivotKeys,
77
+ pivotColumnId: pivotColumnIds[pivotKeys.length - 1],
78
+ aggregationColumnId,
79
+ };
80
+ }
@@ -69,7 +69,12 @@ export declare class LayoutManager<DATA_TYPE = any> extends LMEmitter {
69
69
  private computeColumnOrderAndVisibility;
70
70
  autoSizeColumns(columnIds?: string[]): false | string[];
71
71
  private applyPivotLayout;
72
+ applyPivotTotals(layout: PivotLayoutModel): void;
72
73
  applyPivotExpandLevel(layout: PivotLayoutModel): void;
73
74
  private withSuppressColumnAnimation;
75
+ private setupPivotTotals;
76
+ private isPivotRowTotalColDef;
77
+ private patchPivotTotalColumn;
78
+ private getPivotTotalColumnConfig;
74
79
  }
75
80
  export {};
@@ -3,8 +3,10 @@ import { isPivotLayoutModel } from './isPivotLayoutModel';
3
3
  import { LMEmitter } from './LMEmitter';
4
4
  import { GROUP_COLUMN_ID__MULTI_PREFIX, GROUP_COLUMN_ID__SINGLE, normalizeLayoutModel, normalizePivotLayoutModel, normalizeTableLayoutModel, } from './normalizeLayoutModel';
5
5
  import { isLayoutEqual } from './isLayoutEqual';
6
- import { simplifyTableLayoutModel, simplifyPivotLayoutModel, simplifyLayoutModel, } from './simplifyLayoutModel';
6
+ import { simplifyLayoutModel, simplifyPivotLayoutModel, simplifyTableLayoutModel, } from './simplifyLayoutModel';
7
7
  import { sortColumnIdsByOrder } from './sortColumnIdsByOrder';
8
+ import { destructurePivotColumnId } from './destructurePivotColumnId';
9
+ import { isPivotTotalColumn } from './isPivotTotalColumn';
8
10
  function flattenColDefs(colDefs) {
9
11
  const res = [];
10
12
  const iteration = (c) => {
@@ -117,8 +119,12 @@ export class LayoutManager extends LMEmitter {
117
119
  }).bind(this);
118
120
  }
119
121
  this.setOptions(options);
122
+ // this ensures the grand total columns are positioned correctly (before/after) even when changed at runtime
123
+ // see https://www.ag-grid.com/react-data-grid/pivoting-column-groups/#changing-data-filters-and-configurations
124
+ this.gridApi.setGridOption('enableStrictPivotColumnOrder', true);
120
125
  this.setupEvents();
121
126
  this.indexColumns();
127
+ this.setupPivotTotals();
122
128
  globalThis.layoutManager = this;
123
129
  }
124
130
  destroy() {
@@ -252,6 +258,18 @@ export class LayoutManager extends LMEmitter {
252
258
  PivotAggregationColumns: layout.TableAggregationColumns,
253
259
  PivotExpandLevel: prevLayout?.PivotExpandLevel ?? -1,
254
260
  };
261
+ const grandTotalRow = this.gridApi.getGridOption('grandTotalRow');
262
+ if (grandTotalRow) {
263
+ pivotLayout.GrandTotalRow = grandTotalRow;
264
+ }
265
+ const grandTotalColumn = this.gridApi.getGridOption('pivotRowTotals');
266
+ if (grandTotalColumn) {
267
+ pivotLayout.GrandTotalColumn = grandTotalColumn;
268
+ }
269
+ const pivotGroupTotalColumn = this.gridApi.getGridOption('pivotColumnGroupTotals');
270
+ if (pivotGroupTotalColumn) {
271
+ pivotLayout.PivotGroupTotalColumn = pivotGroupTotalColumn;
272
+ }
255
273
  return simplifyPivotLayoutModel(pivotLayout);
256
274
  }
257
275
  getTableLayoutModelFromGrid() {
@@ -272,7 +290,7 @@ export class LayoutManager extends LMEmitter {
272
290
  let ColumnPinning = {};
273
291
  const gridState = this.gridApi.getState();
274
292
  const prevLayout = this.currentLayout;
275
- const prevAggColumns = prevLayout?.TableAggregationColumns;
293
+ const prevAggColumns = prevLayout?.TableAggregationColumns ?? prevLayout?.PivotAggregationColumns;
276
294
  const prevAggColumnsMap = prevAggColumns?.reduce((acc, agg) => {
277
295
  acc[agg.ColumnId] = agg;
278
296
  return acc;
@@ -983,6 +1001,7 @@ export class LayoutManager extends LMEmitter {
983
1001
  return columnIds;
984
1002
  }
985
1003
  applyPivotLayout(layout, options) {
1004
+ this.applyPivotTotals(layout);
986
1005
  const columnState = this.computeColumnStateForPivotLayout(layout);
987
1006
  // by simply calling this.gridApi.applyColumnState(columnState)
988
1007
  // the order of aggregations is not preserved/guaranteed by ag-grid
@@ -1010,6 +1029,50 @@ export class LayoutManager extends LMEmitter {
1010
1029
  this.applyRowGroupValues(layout.RowGroupValues);
1011
1030
  }
1012
1031
  }
1032
+ applyPivotTotals(layout) {
1033
+ /**
1034
+ * GrandTotalRow
1035
+ */
1036
+ if (layout.GrandTotalRow) {
1037
+ const grandTotalRow = layout.GrandTotalRow === true || layout.GrandTotalRow === 'top'
1038
+ ? 'top'
1039
+ : layout.GrandTotalRow === 'bottom'
1040
+ ? 'bottom'
1041
+ : null;
1042
+ this.gridApi.setGridOption('grandTotalRow', grandTotalRow);
1043
+ }
1044
+ else {
1045
+ this.gridApi.setGridOption('grandTotalRow', null);
1046
+ }
1047
+ /**
1048
+ * GrandTotalColumn
1049
+ */
1050
+ if (layout.GrandTotalColumn) {
1051
+ const grandTotalColumn = layout.GrandTotalColumn === true || layout.GrandTotalColumn === 'before'
1052
+ ? 'before'
1053
+ : layout.GrandTotalColumn === 'after'
1054
+ ? 'after'
1055
+ : null;
1056
+ this.gridApi.setGridOption('pivotRowTotals', grandTotalColumn);
1057
+ }
1058
+ else {
1059
+ this.gridApi.setGridOption('pivotRowTotals', null);
1060
+ }
1061
+ /**
1062
+ * PivotGroupTotalColumn
1063
+ */
1064
+ if (layout.PivotGroupTotalColumn) {
1065
+ const pivotGroupTotalColumn = layout.PivotGroupTotalColumn === true || layout.PivotGroupTotalColumn === 'before'
1066
+ ? 'before'
1067
+ : layout.PivotGroupTotalColumn === 'after'
1068
+ ? 'after'
1069
+ : null;
1070
+ this.gridApi.setGridOption('pivotColumnGroupTotals', pivotGroupTotalColumn);
1071
+ }
1072
+ else {
1073
+ this.gridApi.setGridOption('pivotColumnGroupTotals', null);
1074
+ }
1075
+ }
1013
1076
  applyPivotExpandLevel(layout) {
1014
1077
  const PivotExpandLevel = layout.PivotExpandLevel ?? -1;
1015
1078
  const allDisplayedColumnGroups = this.gridApi.getAllDisplayedColumnGroups();
@@ -1045,4 +1108,107 @@ export class LayoutManager extends LMEmitter {
1045
1108
  }
1046
1109
  return res;
1047
1110
  }
1111
+ setupPivotTotals() {
1112
+ const _original_processPivotResultColDef = this.gridApi.getGridOption('processPivotResultColDef');
1113
+ const _original_processPivotResultColGroupDef = this.gridApi.getGridOption('processPivotResultColGroupDef');
1114
+ this.gridApi.setGridOption('processPivotResultColGroupDef', (colGroupDef) => {
1115
+ _original_processPivotResultColGroupDef?.(colGroupDef);
1116
+ if (!isPivotLayoutModel(this.currentLayout)) {
1117
+ return;
1118
+ }
1119
+ this.patchPivotTotalColumn(colGroupDef);
1120
+ });
1121
+ }
1122
+ isPivotRowTotalColDef(colDef) {
1123
+ return colDef.colId?.startsWith('PivotRowTotal_');
1124
+ }
1125
+ patchPivotTotalColumn(colGroupDef) {
1126
+ const hasPivotTotalCols = (pivotLayout) => {
1127
+ return pivotLayout.PivotAggregationColumns?.some((aggCol) => !!aggCol.TotalColumn);
1128
+ };
1129
+ if (!isPivotLayoutModel(this.currentLayout) || !hasPivotTotalCols(this.currentLayout)) {
1130
+ return;
1131
+ }
1132
+ const pivotRowTotalColDefsBefore = [];
1133
+ const pivotRowTotalColDefsAfter = [];
1134
+ const pivotTotalColDefsBefore = [];
1135
+ const pivotTotalColDefsAfter = [];
1136
+ const normalColDefs = [];
1137
+ colGroupDef.children.forEach((colDef) => {
1138
+ if (this.isPivotRowTotalColDef(colDef)) {
1139
+ if (this.gridApi.getGridOption('pivotRowTotals') === 'after') {
1140
+ pivotRowTotalColDefsAfter.push(colDef);
1141
+ }
1142
+ else {
1143
+ pivotRowTotalColDefsBefore.push(colDef);
1144
+ }
1145
+ return;
1146
+ }
1147
+ if (isPivotTotalColumn(colDef)) {
1148
+ if (!colDef.colId.startsWith('pivot_')) {
1149
+ this.warn(`Pivot total column ${colDef.colId} is not prefixed with 'pivot_', skipping...`);
1150
+ return;
1151
+ }
1152
+ // we do this for all total cols, but we will hide the ones that are not visible
1153
+ colDef.columnGroupShow = undefined;
1154
+ const totalColConfig = this.getPivotTotalColumnConfig(colDef, this.currentLayout);
1155
+ if (!totalColConfig.visible) {
1156
+ colDef.hide = true;
1157
+ }
1158
+ else {
1159
+ if (totalColConfig.position === 'after') {
1160
+ pivotTotalColDefsAfter.push(colDef);
1161
+ }
1162
+ else {
1163
+ pivotTotalColDefsBefore.push(colDef);
1164
+ }
1165
+ }
1166
+ }
1167
+ else {
1168
+ normalColDefs.push(colDef);
1169
+ }
1170
+ });
1171
+ colGroupDef.children = [
1172
+ ...pivotRowTotalColDefsBefore,
1173
+ ...pivotTotalColDefsBefore,
1174
+ ...normalColDefs,
1175
+ ...pivotTotalColDefsAfter,
1176
+ ...pivotRowTotalColDefsAfter,
1177
+ ];
1178
+ }
1179
+ getPivotTotalColumnConfig(colDef, currentPivotLayout) {
1180
+ const defaultHiddenConfig = {
1181
+ visible: false,
1182
+ };
1183
+ const colIdInfo = destructurePivotColumnId(colDef, {
1184
+ pivotColIds: this.currentLayout.PivotColumns,
1185
+ aggColIds: this.currentLayout.PivotAggregationColumns.map((col) => col.ColumnId),
1186
+ }, (message) => this.warn(message));
1187
+ if (colIdInfo === '!unknown!') {
1188
+ return defaultHiddenConfig;
1189
+ }
1190
+ const { pivotColumnId, aggregationColumnId } = colIdInfo;
1191
+ const layoutAggCol = currentPivotLayout.PivotAggregationColumns?.find((col) => col.ColumnId === aggregationColumnId);
1192
+ if (!layoutAggCol) {
1193
+ this.warn(`Pivot Totals: could NOT find aggregation(value) column with id ${aggregationColumnId}`);
1194
+ return defaultHiddenConfig;
1195
+ }
1196
+ const layoutPivotTotalColumn = layoutAggCol.TotalColumn;
1197
+ if (!layoutPivotTotalColumn) {
1198
+ return defaultHiddenConfig;
1199
+ }
1200
+ if (Array.isArray(layoutPivotTotalColumn)) {
1201
+ const pivotSpecificConfig = layoutPivotTotalColumn.find((config) => config.PivotColumnId === pivotColumnId);
1202
+ return {
1203
+ visible: pivotSpecificConfig && pivotSpecificConfig.ShowTotal !== false,
1204
+ position: pivotSpecificConfig?.ShowTotal === 'after' ? 'after' : 'before',
1205
+ };
1206
+ }
1207
+ else {
1208
+ return {
1209
+ visible: !!layoutPivotTotalColumn,
1210
+ position: layoutPivotTotalColumn === 'after' ? 'after' : 'before',
1211
+ };
1212
+ }
1213
+ }
1048
1214
  }
@@ -0,0 +1,2 @@
1
+ import { ColDef } from 'ag-grid-enterprise';
2
+ export declare function isPivotGroupTotalColumn(colDef: ColDef): boolean;
@@ -0,0 +1,5 @@
1
+ export function isPivotGroupTotalColumn(colDef) {
2
+ // pivot group total are spanning cross all aggregations
3
+ // therefore the last part of the colId is empty (hence the "dangling" underscore)
4
+ return colDef.colId?.startsWith('pivot_') && colDef.colId?.endsWith('_');
5
+ }
@@ -0,0 +1,2 @@
1
+ import { ColDef } from 'ag-grid-enterprise';
2
+ export declare function isPivotTotalColumn(colDef: ColDef): colDef is ColDef;
@@ -0,0 +1,3 @@
1
+ export function isPivotTotalColumn(colDef) {
2
+ return !!colDef.pivotTotalColumnIds?.length;
3
+ }
@@ -139,6 +139,9 @@ export function normalizePivotLayoutModel(layout) {
139
139
  // make it an own property
140
140
  layout.SuppressAggFuncInHeader = undefined;
141
141
  }
142
+ if (!layout.GrandTotalRow) {
143
+ layout.GrandTotalRow = false;
144
+ }
142
145
  return layout;
143
146
  }
144
147
  export function normalizeLayoutModel(layout, options) {
@@ -2011,6 +2011,14 @@ export declare const ADAPTABLE_METAMODEL: {
2011
2011
  defVal: string;
2012
2012
  gridInfo?: undefined;
2013
2013
  noCode?: undefined;
2014
+ } | {
2015
+ name: string;
2016
+ kind: string;
2017
+ desc: string;
2018
+ isOpt: boolean;
2019
+ gridInfo?: undefined;
2020
+ noCode?: undefined;
2021
+ defVal?: undefined;
2014
2022
  })[];
2015
2023
  };
2016
2024
  ColumnScope: {
@@ -4368,18 +4376,18 @@ export declare const ADAPTABLE_METAMODEL: {
4368
4376
  kind: string;
4369
4377
  desc: string;
4370
4378
  isOpt: boolean;
4371
- ref: string;
4379
+ ref?: undefined;
4372
4380
  } | {
4373
4381
  name: string;
4374
4382
  kind: string;
4375
4383
  desc: string;
4376
- isOpt?: undefined;
4377
- ref?: undefined;
4384
+ isOpt: boolean;
4385
+ ref: string;
4378
4386
  } | {
4379
4387
  name: string;
4380
4388
  kind: string;
4381
4389
  desc: string;
4382
- isOpt: boolean;
4390
+ isOpt?: undefined;
4383
4391
  ref?: undefined;
4384
4392
  })[];
4385
4393
  };