@adaptabletools/adaptable 20.0.5 → 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.
- package/base.css +20 -0
- package/base.css.map +1 -1
- package/index.css +16 -0
- package/index.css.map +1 -1
- package/package.json +1 -1
- package/src/AdaptableOptions/ColumnOptions.d.ts +173 -2
- package/src/AdaptableState/Common/AggregationColumns.d.ts +8 -1
- package/src/AdaptableState/LayoutState.d.ts +12 -0
- package/src/Api/Implementation/ColumnApiImpl.d.ts +1 -0
- package/src/Api/Implementation/ColumnApiImpl.js +11 -1
- package/src/Api/Implementation/LayoutHelpers.js +25 -2
- package/src/Api/Internal/ColumnInternalApi.d.ts +3 -1
- package/src/Api/Internal/ColumnInternalApi.js +201 -0
- package/src/Utilities/Constants/GeneralConstants.d.ts +1 -0
- package/src/Utilities/Constants/GeneralConstants.js +1 -0
- package/src/Utilities/Extensions/StringExtensions.js +11 -3
- package/src/Utilities/adaptableOverrideCheck.d.ts +2 -0
- package/src/Utilities/adaptableOverrideCheck.js +8 -0
- package/src/agGrid/AdaptableAgGrid.js +29 -0
- package/src/agGrid/AgGridAdapter.js +1 -0
- package/src/agGrid/AgGridColumnAdapter.d.ts +1 -1
- package/src/agGrid/AgGridColumnAdapter.js +7 -13
- package/src/components/Select/Select.js +3 -3
- package/src/env.js +2 -2
- package/src/layout-manager/src/LayoutManagerModel.d.ts +23 -20
- package/src/layout-manager/src/destructurePivotColumnId.d.ts +10 -0
- package/src/layout-manager/src/destructurePivotColumnId.js +80 -0
- package/src/layout-manager/src/index.d.ts +5 -0
- package/src/layout-manager/src/index.js +168 -2
- package/src/layout-manager/src/isPivotGroupTotalColumn.d.ts +2 -0
- package/src/layout-manager/src/isPivotGroupTotalColumn.js +5 -0
- package/src/layout-manager/src/isPivotTotalColumn.d.ts +2 -0
- package/src/layout-manager/src/isPivotTotalColumn.js +3 -0
- package/src/layout-manager/src/normalizeLayoutModel.js +3 -0
- package/src/metamodel/adaptable.metamodel.d.ts +12 -4
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -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
|
-
//
|
|
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
|
-
|
|
32
|
-
const
|
|
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(' ');
|
|
@@ -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
|
*/
|
|
@@ -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):
|
|
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
|
|
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
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
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', () => {
|
|
@@ -29,7 +29,7 @@ const INFINITE_COLUMNS_WITH_CHECKBOX = {
|
|
|
29
29
|
resizable: false,
|
|
30
30
|
defaultSortable: false,
|
|
31
31
|
renderSelectionCheckBox: ({ renderBag }) => {
|
|
32
|
-
return
|
|
32
|
+
return renderBag.selectionCheckBox;
|
|
33
33
|
},
|
|
34
34
|
renderHeader: (headerParams) => {
|
|
35
35
|
return (React.createElement(React.Fragment, null,
|
|
@@ -149,7 +149,7 @@ export const Select = function (props) {
|
|
|
149
149
|
placeholder: props.placeholder,
|
|
150
150
|
});
|
|
151
151
|
const title = typeof customRenderValue === 'string' ? customRenderValue : '';
|
|
152
|
-
children = customRenderValue ? (React.createElement(Box, { display: 'flex', flexDirection: 'row', flex: 1, flexWrap: 'nowrap', alignItems: 'center', overflow: 'hidden' },
|
|
152
|
+
children = customRenderValue ? (React.createElement(Box, { display: 'flex', flexDirection: 'row', flex: 1, flexWrap: 'nowrap', alignItems: 'center', overflow: 'hidden', height: '100%' },
|
|
153
153
|
React.createElement("span", { title: title, "data-name": "multi-value-text", style: {
|
|
154
154
|
flex: '0 1 auto',
|
|
155
155
|
appearance: 'none',
|
|
@@ -466,7 +466,7 @@ export const Select = function (props) {
|
|
|
466
466
|
return {
|
|
467
467
|
...baseStyle,
|
|
468
468
|
...commonStyles(state), // height: 30,
|
|
469
|
-
minHeight: props.size === 'small' ? 0 :
|
|
469
|
+
minHeight: props.size === 'small' ? 0 : '100%',
|
|
470
470
|
boxShadow: state.isFocused ? 'var(--ab-cmp-select-focused__box-shadow)' : 'none',
|
|
471
471
|
outline: state.isFocused ? 'var(--ab-cmp-select-focused__outline)' : 'none',
|
|
472
472
|
border: 'var(--ab-cmp-select__border)',
|
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:
|
|
4
|
-
VERSION: "20.0.
|
|
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
|
|
65
|
+
export type AggregationColumnsModelItem = {
|
|
66
66
|
ColumnId: string;
|
|
67
67
|
AggFunc: ColumnAggregationModel;
|
|
68
|
-
}
|
|
69
|
-
type
|
|
70
|
-
export
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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?:
|
|
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 {};
|