@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptabletools/adaptable",
3
- "version": "20.0.6",
3
+ "version": "20.0.7-canary.0",
4
4
  "description": "Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements",
5
5
  "keywords": [
6
6
  "web-components",
@@ -1,5 +1,5 @@
1
1
  import { Column } from 'ag-grid-enterprise';
2
- import { AdaptableColumnGroup, BaseContext } from '../types';
2
+ import { AdaptableColumnGroup, BaseContext, Layout } from '../types';
3
3
  /**
4
4
  * Options related to managing Columns in Adaptable.
5
5
  */
@@ -9,6 +9,10 @@ export interface ColumnOptions {
9
9
  * @defaultValue undefined
10
10
  */
11
11
  columnFriendlyName?: (columnFriendlyNameContext: ColumnFriendlyNameContext) => string | undefined;
12
+ /**
13
+ * Provide a custom Header Name for a Table or Pivot Column
14
+ */
15
+ columnHeader?: (context: ColumnHeaderContext) => string;
12
16
  /**
13
17
  * Optional list of Column Types - used for Scope and creating Special Columns
14
18
  * @defaultValue Empty Array
@@ -31,10 +35,177 @@ export interface ColumnOptions {
31
35
  */
32
36
  addColumnGroupToColumnFriendlyName?: boolean;
33
37
  }
38
+ /**
39
+ * Common properties for Column Header Context
40
+ */
41
+ export type BaseColumnHeaderContext = {
42
+ /**
43
+ * The default header name for the column
44
+ */
45
+ defaultHeaderName: string;
46
+ /**
47
+ * The mame of the current Layout
48
+ */
49
+ currentLayoutName: string;
50
+ /**
51
+ * The type (table/pivot) of the current Layout
52
+ */
53
+ currentLayoutType: 'table' | 'pivot';
54
+ /**
55
+ * The current Layout
56
+ */
57
+ currentLayout: Layout;
58
+ } & BaseContext;
59
+ export type ColumnHeaderContext = BaseColumnHeaderContext & ({
60
+ /**
61
+ * Auto-generated Group Column when GroupDisplayType is `single` column
62
+ */
63
+ columnType: 'autoGroupColumn';
64
+ /**
65
+ * Technical ID of the Column
66
+ */
67
+ columnId: string;
68
+ /**
69
+ * IDs of the Columns that are grouped
70
+ */
71
+ groupedColumnIds: string[];
72
+ } | {
73
+ /**
74
+ * Group Columns - see `TableLayout.RowGroupedColumns` or `PivotLayout.PivotGroupedColumns`
75
+ */
76
+ columnType: 'groupColumn';
77
+ /**
78
+ * Technical ID of the Column
79
+ */
80
+ columnId: string;
81
+ /**
82
+ * ID of the grouped Column
83
+ */
84
+ groupColumnId: string;
85
+ } | {
86
+ /**
87
+ * Table Column - see `TableLayout.TableColumns`
88
+ */
89
+ columnType: 'tableColumn';
90
+ /**
91
+ * Technical ID of the Column
92
+ */
93
+ columnId: string;
94
+ /**
95
+ * Optional Aggregation function of the Column - see `TableLayout.TableAggregationColumns`
96
+ */
97
+ aggregation?: string;
98
+ } | {
99
+ /**
100
+ * Column Group - see https://www.ag-grid.com/javascript-data-grid/column-groups/
101
+ */
102
+ columnType: 'tableColumnGroup';
103
+ /**
104
+ * Technical ID of the Column Group - see `ColGroupDef.groupId`
105
+ */
106
+ groupId: string;
107
+ /**
108
+ * IDs of the Column Group children - see `ColGroupDef.children`
109
+ */
110
+ childrenColumnIds: string[];
111
+ /**
112
+ * State of the Column Group
113
+ */
114
+ state: 'expanded' | 'collapsed';
115
+ } | {
116
+ /**
117
+ * Pivot Column - see `PivotLayout.PivotColumns`
118
+ */
119
+ columnType: 'pivotColumnGroup';
120
+ /**
121
+ * Technical ID of the generated Column Group
122
+ */
123
+ groupId: string;
124
+ /**
125
+ * Pivot Keys for the current Column Group
126
+ */
127
+ pivotKeys: string[];
128
+ /**
129
+ * State of the Column Group
130
+ */
131
+ state: 'expanded' | 'collapsed';
132
+ } | {
133
+ /**
134
+ * Pivot Aggregation Column - see `PivotLayout.PivotAggregationColumns`
135
+ */
136
+ columnType: 'pivotAggregationColumn';
137
+ /**
138
+ * Technical ID of the generated Column
139
+ */
140
+ columnId: string;
141
+ /**
142
+ * Current Pivot Keys
143
+ */
144
+ pivotKeys: string[];
145
+ /**
146
+ * ID of the Aggregated Column - see `PivotLayout.PivotAggregationColumns`
147
+ */
148
+ aggregatedColumnId: string;
149
+ /**
150
+ * Aggregation function of the Column - see `PivotLayout.PivotAggregationColumns.AggregationColumnValue`
151
+ */
152
+ aggregation: string;
153
+ } | {
154
+ /**
155
+ * Grand Total Column - see `PivotLayout.GrandTotalColumn`
156
+ */
157
+ columnType: 'pivotGrandTotal';
158
+ /**
159
+ * ID of the Aggregated Column - see `PivotLayout.PivotAggregationColumns`
160
+ */
161
+ aggregatedColumnId: string;
162
+ /**
163
+ * Aggregation function of the Column - see `PivotLayout.PivotAggregationColumns.AggregationColumnValue`
164
+ */
165
+ aggregation: string;
166
+ } | {
167
+ /**
168
+ * Pivot Group Total Column - see `PivotLayout.PivotGroupTotalColumn`
169
+ */
170
+ columnType: 'pivotGroupTotal';
171
+ /**
172
+ * Current Pivot Keys
173
+ */
174
+ pivotKey: string;
175
+ /**
176
+ * ID of the Pivot Column - see `PivotLayout.PivotColumns`
177
+ */
178
+ pivotColumnId: string;
179
+ /**
180
+ * Aggregation function of the Column - see `PivotLayout.PivotAggregationColumns.AggregationColumnValue`
181
+ */
182
+ aggregation: string;
183
+ } | {
184
+ /**
185
+ * Pivot Aggregation Total Column - see `PivotLayout.PivotAggregationColumns.TotalColumn`
186
+ */
187
+ columnType: 'pivotAggregationTotal';
188
+ /**
189
+ * ID of the Aggregated Column - see `PivotLayout.PivotAggregationColumns`
190
+ */
191
+ aggregatedColumnId: string;
192
+ /**
193
+ * Aggregation function of the Column - see `PivotLayout.PivotAggregationColumns.AggregationColumnValue`
194
+ */
195
+ aggregation: string;
196
+ /**
197
+ * ID of the Pivot Column - see `PivotLayout.PivotColumns`
198
+ */
199
+ pivotColumnId: string;
200
+ /**
201
+ * Current Pivot Keys
202
+ */
203
+ pivotKey: string;
204
+ });
34
205
  /**
35
206
  * Context used when setting a Column Friendly Name
36
207
  */
37
- export interface ColumnFriendlyNameContext {
208
+ export interface ColumnFriendlyNameContext extends BaseContext {
38
209
  /**
39
210
  * Id of the Column
40
211
  */
@@ -12,7 +12,14 @@ export type TableAggregationColumns = {
12
12
  /**
13
13
  * Defines an Aggregated Column in a Pivot Layout
14
14
  */
15
- export type PivotAggregationColumns = TableAggregationColumns;
15
+ export type PivotAggregationColumns = {
16
+ ColumnId: string;
17
+ AggFunc: AggregationColumnValue;
18
+ TotalColumn?: boolean | 'before' | 'after' | {
19
+ PivotColumnId: string;
20
+ ShowTotal?: boolean | 'before' | 'after';
21
+ }[];
22
+ }[];
16
23
  export declare const WEIGHTED_AVERAGE_AGG_FN_NAME = "weightedAvg";
17
24
  /**
18
25
  * Defines a Weighted Average Agg
@@ -148,6 +148,18 @@ export interface PivotLayout extends LayoutBase {
148
148
  * Row Grouped Columns Columns - must NOT be provided
149
149
  */
150
150
  RowGroupedColumns?: never;
151
+ /**
152
+ * Display Grand Total Row at the top or bottom of the Pivot Table
153
+ */
154
+ GrandTotalRow?: 'top' | 'bottom' | boolean;
155
+ /**
156
+ * Display automatically calculated Totals of all Pivot Columns, in the position specified
157
+ */
158
+ GrandTotalColumn?: 'before' | 'after' | boolean;
159
+ /**
160
+ * Display automatically calculated Totals within EACH Pivot Column Group, in the position specified
161
+ */
162
+ PivotGroupTotalColumn?: 'before' | 'after' | boolean;
151
163
  }
152
164
  /**
153
165
  * Manages how (and which) Row Group values are stored
@@ -11,6 +11,7 @@ export declare function generateAutoTreeSingleColumn(): AdaptableColumn;
11
11
  export declare function generateAutoRowGroupColumnForColumn(column: AdaptableColumn): AdaptableColumn;
12
12
  export declare function getFriendlyNameForPivotResultColumn(columnId: string): string;
13
13
  export declare function isPivotResultColumn(columnId: string): boolean;
14
+ export declare function isPivotGrandTotalColumn(columnId: string): boolean;
14
15
  export declare class ColumnApiImpl extends ApiBase implements ColumnApi {
15
16
  internalApi: ColumnInternalApi;
16
17
  constructor(_adaptable: IAdaptable);
@@ -63,6 +63,13 @@ export function generateAutoRowGroupColumnForColumn(column) {
63
63
  };
64
64
  }
65
65
  export function getFriendlyNameForPivotResultColumn(columnId) {
66
+ if (isPivotGrandTotalColumn(columnId)) {
67
+ return `[Grand Total] ${columnId
68
+ .split('_')
69
+ .slice(2)
70
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
71
+ .join(' ')}`;
72
+ }
66
73
  return `[Pivot] ${columnId
67
74
  .split('_')
68
75
  .slice(1)
@@ -73,6 +80,9 @@ export function isPivotResultColumn(columnId) {
73
80
  // put this here as there might be other indicators we are not aware of?
74
81
  return columnId?.startsWith(GeneralConstants.AG_GRID_PIVOT_COLUMN);
75
82
  }
83
+ export function isPivotGrandTotalColumn(columnId) {
84
+ return columnId?.startsWith(GeneralConstants.AG_GRID_PIVOT_GRAND_TOTAL_COLUMN);
85
+ }
76
86
  export class ColumnApiImpl extends ApiBase {
77
87
  constructor(_adaptable) {
78
88
  super(_adaptable);
@@ -136,7 +146,7 @@ export class ColumnApiImpl extends ApiBase {
136
146
  return isAutoRowGroupColumn(columnId);
137
147
  }
138
148
  isPivotResultColumn(columnId) {
139
- return isPivotResultColumn(columnId);
149
+ return isPivotResultColumn(columnId) || isPivotGrandTotalColumn(columnId);
140
150
  }
141
151
  isAutoRowGroupColumnForSingle(columnId) {
142
152
  return columnId === GROUP_COLUMN_ID__SINGLE;
@@ -197,12 +197,16 @@ export const pivotLayoutToPivotLayoutModel = (pivotLayout) => {
197
197
  ColumnPinning: pivotLayout.ColumnPinning,
198
198
  PivotColumns: pivotLayout.PivotColumns,
199
199
  PivotExpandLevel: pivotLayout.PivotExpandLevel,
200
- PivotAggregationColumns: (pivotLayout.PivotAggregationColumns || []).map(({ ColumnId, AggFunc }) => {
200
+ PivotAggregationColumns: (pivotLayout.PivotAggregationColumns || []).map(({ ColumnId, AggFunc, TotalColumn }) => {
201
201
  return {
202
202
  ColumnId,
203
203
  AggFunc: toAggFunc(AggFunc),
204
+ TotalColumn,
204
205
  };
205
206
  }),
207
+ GrandTotalRow: pivotLayout.GrandTotalRow,
208
+ GrandTotalColumn: pivotLayout.GrandTotalColumn,
209
+ PivotGroupTotalColumn: pivotLayout.PivotGroupTotalColumn,
206
210
  RowGroupValues: pivotLayout.RowGroupValues
207
211
  ? pivotLayout.RowGroupValues.RowGroupDefaultBehavior === 'always-collapsed' ||
208
212
  pivotLayout.RowGroupValues.RowGroupDefaultBehavior === 'always-expanded'
@@ -326,10 +330,29 @@ export const pivotLayoutModelToPivotLayout = (layoutModel, defaults) => {
326
330
  else {
327
331
  delete pivotLayout.RowGroupValues;
328
332
  }
333
+ if (layoutModel.GrandTotalRow) {
334
+ pivotLayout.GrandTotalRow = layoutModel.GrandTotalRow;
335
+ }
336
+ else {
337
+ delete pivotLayout.GrandTotalRow;
338
+ }
339
+ if (layoutModel.GrandTotalColumn) {
340
+ pivotLayout.GrandTotalColumn = layoutModel.GrandTotalColumn;
341
+ }
342
+ else {
343
+ delete pivotLayout.GrandTotalColumn;
344
+ }
345
+ if (layoutModel.PivotGroupTotalColumn) {
346
+ pivotLayout.PivotGroupTotalColumn = layoutModel.PivotGroupTotalColumn;
347
+ }
348
+ else {
349
+ delete pivotLayout.PivotGroupTotalColumn;
350
+ }
329
351
  if (layoutModel.PivotAggregationColumns) {
330
- pivotLayout.PivotAggregationColumns = (layoutModel.PivotAggregationColumns || []).map(({ ColumnId, AggFunc }) => ({
352
+ pivotLayout.PivotAggregationColumns = (layoutModel.PivotAggregationColumns || []).map(({ ColumnId, AggFunc, TotalColumn }) => ({
331
353
  ColumnId,
332
354
  AggFunc: toAggregationColumnValue(AggFunc),
355
+ TotalColumn,
333
356
  }));
334
357
  }
335
358
  else {
@@ -1,5 +1,5 @@
1
1
  import { ApiBase } from '../Implementation/ApiBase';
2
- import { Column, IRowNode } from 'ag-grid-enterprise';
2
+ import { Column, HeaderValueGetterParams, IRowNode } from 'ag-grid-enterprise';
3
3
  import { CustomSort } from '../../AdaptableState/CustomSortState';
4
4
  import { ColumnValuesComparer } from '../../AdaptableOptions/CustomSortOptions';
5
5
  import { AdaptableColumn } from '../../types';
@@ -31,4 +31,6 @@ export declare class ColumnInternalApi extends ApiBase {
31
31
  getAgGridColumnForAdaptableColumn(columnId: string): Column;
32
32
  getActiveColumnComparator(columnId: string, customSort?: CustomSort, customSortComparer?: ColumnValuesComparer): (valueA: any, valueB: any, nodeA?: IRowNode, nodeB?: IRowNode, isInverted?: boolean) => number | undefined;
33
33
  isSpecialColumn(columnId: string, column?: AdaptableColumn): boolean;
34
+ getColumnHeaderName(params: HeaderValueGetterParams): string;
35
+ private buildColumnHeaderContext;
34
36
  }
@@ -2,6 +2,10 @@ import { ApiBase } from '../Implementation/ApiBase';
2
2
  import { AG_GRID_GROUPED_COLUMN } from '../../Utilities/Constants/GeneralConstants';
3
3
  import uniq from 'lodash/uniq';
4
4
  import StringExtensions from '../../Utilities/Extensions/StringExtensions';
5
+ import { isPivotGrandTotalColumn, isPivotResultColumn } from '../Implementation/ColumnApiImpl';
6
+ import { destructurePivotColumnId } from '../../layout-manager/src/destructurePivotColumnId';
7
+ import { isPivotGroupTotalColumn } from '../../layout-manager/src/isPivotGroupTotalColumn';
8
+ import { isPivotTotalColumn } from '../../layout-manager/src/isPivotTotalColumn';
5
9
  export function getAutoRowGroupColumnIdFor(columnId) {
6
10
  return `${AG_GRID_GROUPED_COLUMN}-${columnId}`;
7
11
  }
@@ -81,4 +85,201 @@ export class ColumnInternalApi extends ApiBase {
81
85
  this.getColumnApi().isActionColumn(columnId) ||
82
86
  this.getColumnApi().isFdc3Column(columnId));
83
87
  }
88
+ getColumnHeaderName(params) {
89
+ // this is the same object, but casting it makes it easier to work with
90
+ const isColumn = !params.columnGroup;
91
+ const columnParams = params;
92
+ const isColumnGroup = !!params.columnGroup;
93
+ const columnGroupParams = params;
94
+ const defaultHeaderName = params.colDef?.headerName ??
95
+ (isColumn ? StringExtensions.CamelCaseToHumanText(columnParams.colDef?.field) : '') ??
96
+ '';
97
+ // for now we override ONLY the header names
98
+ if (params.location !== 'header') {
99
+ return defaultHeaderName;
100
+ }
101
+ // 1. Layout specific header has the highest priority
102
+ const layoutSpecificCustomHeader = this.getLayoutApi().getCurrentLayout().ColumnHeaders?.[isColumn ? columnParams.column.getColId() : columnGroupParams.columnGroup.getGroupId()];
103
+ if (layoutSpecificCustomHeader) {
104
+ return layoutSpecificCustomHeader;
105
+ }
106
+ // 2. check for custom ColumnOptions.columnHeader
107
+ if (typeof this.getColumnOptions().columnHeader === 'function') {
108
+ const columnHeaderContext = this.buildColumnHeaderContext(params, defaultHeaderName);
109
+ if (columnHeaderContext === 'skip') {
110
+ return defaultHeaderName;
111
+ }
112
+ const customHeader = this.getColumnOptions().columnHeader(columnHeaderContext);
113
+ return customHeader;
114
+ }
115
+ // 3. fallback to default header name
116
+ return defaultHeaderName;
117
+ }
118
+ buildColumnHeaderContext(params, defaultHeaderName) {
119
+ const currentLayoutType = this.getLayoutApi().isCurrentLayoutPivot() ? 'pivot' : 'table';
120
+ const currentLayout = this.getLayoutApi().getCurrentLayout();
121
+ const baseContext = {
122
+ ...this.getAdaptableApi().internalApi.buildBaseContext(),
123
+ defaultHeaderName,
124
+ currentLayout,
125
+ currentLayoutName: currentLayout.Name,
126
+ currentLayoutType: currentLayoutType,
127
+ };
128
+ // makes it easier to work with
129
+ const currentTableLayout = currentLayout;
130
+ const currentPivotLayout = currentLayout;
131
+ if (params.column?.getColId() === AG_GRID_GROUPED_COLUMN) {
132
+ const columnType = 'autoGroupColumn';
133
+ return {
134
+ ...baseContext,
135
+ columnType,
136
+ columnId: params.column.getColId(),
137
+ groupedColumnIds: currentLayoutType === 'table'
138
+ ? currentTableLayout.RowGroupedColumns ?? []
139
+ : currentPivotLayout.PivotGroupedColumns ?? [],
140
+ };
141
+ }
142
+ if (params.column?.getColId().startsWith(`${AG_GRID_GROUPED_COLUMN}-`)) {
143
+ const columnType = 'groupColumn';
144
+ const columnId = params.column.getColId();
145
+ // remove `${AG_GRID_GROUPED_COLUMN}-` from beginning of columnId
146
+ const groupColumnId = columnId.substring(`${AG_GRID_GROUPED_COLUMN}-`.length);
147
+ return {
148
+ ...baseContext,
149
+ columnType,
150
+ columnId,
151
+ groupColumnId,
152
+ };
153
+ }
154
+ if (baseContext.currentLayoutType === 'table') {
155
+ if (params.columnGroup) {
156
+ const columnType = 'tableColumnGroup';
157
+ if (!params.colDef?.children) {
158
+ // AG Grid created virtual column groups for all columns
159
+ // we want to skip those
160
+ return 'skip';
161
+ }
162
+ return {
163
+ ...baseContext,
164
+ columnType,
165
+ groupId: params.columnGroup?.getGroupId(),
166
+ childrenColumnIds: params.columnGroup
167
+ ?.getChildren()
168
+ .map((col) => {
169
+ if (col.isColumn) {
170
+ return col.getColId();
171
+ }
172
+ })
173
+ .filter(Boolean),
174
+ state: params.columnGroup?.isExpandable() && !params.columnGroup?.isExpanded()
175
+ ? 'collapsed'
176
+ : 'expanded',
177
+ };
178
+ }
179
+ if (params.column) {
180
+ const columnType = 'tableColumn';
181
+ return {
182
+ ...baseContext,
183
+ columnType,
184
+ columnId: params.column?.getColId(),
185
+ aggregation: params.column.getAggFunc(),
186
+ };
187
+ }
188
+ }
189
+ if (baseContext.currentLayoutType === 'pivot') {
190
+ if (params.columnGroup) {
191
+ if (!params.colDef?.pivotKeys) {
192
+ // we might have user defined colGroups, but we are not interested in them in pivot mode
193
+ return 'skip';
194
+ }
195
+ const columnType = 'pivotColumnGroup';
196
+ return {
197
+ ...baseContext,
198
+ columnType,
199
+ groupId: params.columnGroup?.getGroupId(),
200
+ pivotKeys: params.colDef.pivotKeys,
201
+ state: params.columnGroup?.isExpandable() && !params.columnGroup?.isExpanded()
202
+ ? 'collapsed'
203
+ : 'expanded',
204
+ };
205
+ }
206
+ if (params.column) {
207
+ let columnId = params.column.getColId();
208
+ if (isPivotGrandTotalColumn(columnId)) {
209
+ const columnType = 'pivotGrandTotal';
210
+ const pivotValueCol = params.colDef.pivotValueColumn;
211
+ const aggregatedColumnId = pivotValueCol?.getColId();
212
+ const currentLayoutAggCols = currentPivotLayout.PivotAggregationColumns?.map((col) => col.ColumnId);
213
+ if (!currentLayoutAggCols?.includes(aggregatedColumnId)) {
214
+ // this column is not an aggregation column
215
+ return 'skip';
216
+ }
217
+ return {
218
+ ...baseContext,
219
+ columnType,
220
+ aggregatedColumnId,
221
+ aggregation: pivotValueCol.getAggFunc(),
222
+ };
223
+ }
224
+ if (isPivotGroupTotalColumn(params.colDef)) {
225
+ const columnType = 'pivotGroupTotal';
226
+ const pivotColInfo = destructurePivotColumnId(params.colDef, {
227
+ pivotColIds: currentPivotLayout.PivotColumns,
228
+ aggColIds: currentPivotLayout.PivotAggregationColumns.map((col) => col.ColumnId),
229
+ }, (message) => this.logWarn(message));
230
+ if (pivotColInfo === '!unknown!') {
231
+ return 'skip';
232
+ }
233
+ const pivotKey = pivotColInfo.pivotKeys[pivotColInfo.pivotKeys.length - 1];
234
+ return {
235
+ ...baseContext,
236
+ columnType,
237
+ pivotKey,
238
+ pivotColumnId: pivotColInfo.pivotColumnId,
239
+ aggregation: params.colDef?.pivotValueColumn?.getAggFunc(),
240
+ };
241
+ }
242
+ if (isPivotTotalColumn(params.colDef)) {
243
+ const columnType = 'pivotAggregationTotal';
244
+ const pivotValueCol = params.colDef.pivotValueColumn;
245
+ const pivotColInfo = destructurePivotColumnId(params.colDef, {
246
+ pivotColIds: currentPivotLayout.PivotColumns,
247
+ aggColIds: currentPivotLayout.PivotAggregationColumns.map((col) => col.ColumnId),
248
+ }, (message) => this.logWarn(message));
249
+ if (pivotColInfo === '!unknown!') {
250
+ return 'skip';
251
+ }
252
+ const pivotKey = pivotColInfo.pivotKeys[pivotColInfo.pivotKeys.length - 1];
253
+ return {
254
+ ...baseContext,
255
+ columnType,
256
+ aggregatedColumnId: pivotValueCol?.getColId(),
257
+ aggregation: pivotValueCol.getAggFunc(),
258
+ pivotColumnId: pivotColInfo.pivotColumnId,
259
+ pivotKey,
260
+ };
261
+ }
262
+ if (isPivotResultColumn(columnId)) {
263
+ const columnType = 'pivotAggregationColumn';
264
+ const pivotValueCol = params.colDef.pivotValueColumn;
265
+ const aggregatedColumnId = pivotValueCol?.getColId();
266
+ const currentLayoutAggCols = currentPivotLayout.PivotAggregationColumns?.map((col) => col.ColumnId);
267
+ if (!currentLayoutAggCols?.includes(aggregatedColumnId)) {
268
+ // this column is not an aggregation column
269
+ return 'skip';
270
+ }
271
+ return {
272
+ ...baseContext,
273
+ columnType,
274
+ columnId,
275
+ pivotKeys: params.colDef.pivotKeys,
276
+ aggregatedColumnId,
277
+ aggregation: pivotValueCol.getAggFunc(),
278
+ };
279
+ }
280
+ }
281
+ }
282
+ // if nothing matched, we skip this column[group]
283
+ return 'skip';
284
+ }
84
285
  }
@@ -24,6 +24,7 @@ export declare const GROUP_PATH_SEPARATOR: string;
24
24
  export declare const AG_GRID_GROUPED_COLUMN: string;
25
25
  export declare const AG_GRID_SELECTION_COLUMN: string;
26
26
  export declare const AG_GRID_PIVOT_COLUMN: string;
27
+ export declare const AG_GRID_PIVOT_GRAND_TOTAL_COLUMN: string;
27
28
  export declare const AG_GRID_CHART_WINDOW = "AG Grid Window";
28
29
  export declare const ADAPTABLE_FDC3_ACTION_COLUMN_FRIENDLY_NAME = "(FDC3ActionColumn)";
29
30
  export declare const DEFAULT_DATE_FORMAT_PATTERN = "dd-MM-yyyy";
@@ -23,6 +23,7 @@ export const GROUP_PATH_SEPARATOR = '/';
23
23
  export const AG_GRID_GROUPED_COLUMN = 'ag-Grid-AutoColumn';
24
24
  export const AG_GRID_SELECTION_COLUMN = 'ag-Grid-SelectionColumn';
25
25
  export const AG_GRID_PIVOT_COLUMN = 'pivot_';
26
+ export const AG_GRID_PIVOT_GRAND_TOTAL_COLUMN = 'PivotRowTotal_pivot_';
26
27
  export const AG_GRID_CHART_WINDOW = 'AG Grid Window';
27
28
  export const ADAPTABLE_FDC3_ACTION_COLUMN_FRIENDLY_NAME = '(FDC3ActionColumn)';
28
29
  // FIXME AFL - load this from DateInputOptions
@@ -23,13 +23,21 @@ export function IsNullOrEmptyOrWhiteSpace(stringToCheck) {
23
23
  export function IsNotNullOrEmptyOrWhiteSpace(stringToCheck) {
24
24
  return !IsNullOrEmptyOrWhiteSpace(stringToCheck);
25
25
  }
26
- // from https://stackoverflow.com/questions/15369566/putting-space-in-camel-case-string-using-regular-expression
26
+ // clone of A Grid's implementation
27
+ // https://github.com/ag-grid/ag-grid/blob/a5c3d9f56350271ab7e8d42d72aaf5314672719a/packages/ag-grid-community/src/columns/columnNameService.ts#L14
27
28
  export function CamelCaseToHumanText(camelCase) {
28
29
  if (!camelCase || camelCase == null) {
29
30
  return null;
30
31
  }
31
- const rex = /([A-Z])([A-Z])([a-z])|([a-z])([A-Z])/g;
32
- const words = camelCase.replace(rex, '$1$4 $2$3$5').replace('.', ' ').split(' ');
32
+ // either split on a lowercase followed by uppercase ie asHereTo -> as Here To
33
+ const rex = /([a-z])([A-Z])/g;
34
+ // or starts with uppercase and we take all expect the last which is assumed to be part of next word if followed by lowercase HEREToThere -> HERE To There
35
+ const rexCaps = /([A-Z]+)([A-Z])([a-z])/g;
36
+ const words = camelCase
37
+ .replace(rex, '$1 $2')
38
+ .replace(rexCaps, '$1 $2$3')
39
+ .replace(/\./g, ' ')
40
+ .split(' ');
33
41
  return words
34
42
  .map((word) => word.substring(0, 1).toUpperCase() + (word.length > 1 ? word.substring(1, word.length) : ''))
35
43
  .join(' ');
@@ -0,0 +1,2 @@
1
+ export declare function tagProvidedByAdaptable(fn: any): any;
2
+ export declare function isProvidedByAdaptable(fn: any): boolean;
@@ -0,0 +1,8 @@
1
+ const PROVIDED_BY_ADAPTABLE = Symbol('isProvidedByAdaptable');
2
+ export function tagProvidedByAdaptable(fn) {
3
+ fn[PROVIDED_BY_ADAPTABLE] = true;
4
+ return fn;
5
+ }
6
+ export function isProvidedByAdaptable(fn) {
7
+ return fn && !!fn[PROVIDED_BY_ADAPTABLE];
8
+ }
@@ -97,6 +97,7 @@ import { ACTION_COLUMN_TYPE, CALCULATED_COLUMN_TYPE, FDC3_COLUMN_TYPE, FREE_TEXT
97
97
  import { agGridDataTypeDefinitions } from './agGridDataTypeDefinitions';
98
98
  import { AgGridThemeAdapter } from './AgGridThemeAdapter';
99
99
  import { mapOldTypeToDataType } from '../migration/VersionUpgrade20';
100
+ import { tagProvidedByAdaptable } from '../Utilities/adaptableOverrideCheck';
100
101
  const LocalEventService_Prototype = LocalEventService.prototype;
101
102
  const LocalEventService_dispatchEvent = LocalEventService_Prototype.dispatchEvent;
102
103
  LocalEventService_Prototype.dispatchEvent = function (event) {
@@ -610,6 +611,34 @@ You need to define at least one Layout!`);
610
611
  this.agGridAdapter.setAgGridId(agGridId);
611
612
  return agGridId;
612
613
  });
614
+ /**
615
+ * `defaultColDef`
616
+ */
617
+ this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'defaultColDef', (original_defaultColDef) => {
618
+ if (original_defaultColDef?.headerValueGetter) {
619
+ this.logger.warn(`defaultColDef.headerValueGetter and overrides the Adaptable custom header mechanism! We recommend using a ColumnOptions.tableColumnHeader instead!`);
620
+ return original_defaultColDef;
621
+ }
622
+ const defaultColDef = original_defaultColDef ?? {};
623
+ defaultColDef.headerValueGetter = tagProvidedByAdaptable((params) => {
624
+ return this.api.columnApi.internalApi.getColumnHeaderName(params);
625
+ });
626
+ return defaultColDef;
627
+ });
628
+ /**
629
+ * `defaultColGroupDef`
630
+ */
631
+ this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'defaultColGroupDef', (original_defaultColGroupDef) => {
632
+ if (original_defaultColGroupDef?.headerValueGetter) {
633
+ this.logger.warn(`defaultColGroupDef.headerValueGetter and overrides the Adaptable custom header mechanism! We recommend using a ColumnOptions.tableColumnHeader instead!`);
634
+ return original_defaultColGroupDef;
635
+ }
636
+ const defaultColGroupDef = original_defaultColGroupDef ?? {};
637
+ defaultColGroupDef.headerValueGetter = tagProvidedByAdaptable((params) => {
638
+ return this.api.columnApi.internalApi.getColumnHeaderName(params);
639
+ });
640
+ return defaultColGroupDef;
641
+ });
613
642
  /**
614
643
  * `theme`
615
644
  */
@@ -374,6 +374,7 @@ export class AgGridAdapter {
374
374
  agColumn: agGridColumn,
375
375
  columnGroup: isRealColumnGroup ? ColumnGroup : undefined,
376
376
  displayName: displayName,
377
+ ...this.adaptableApi.internalApi.buildBaseContext(),
377
378
  })
378
379
  : null;
379
380
  friendlyName =