@adaptabletools/adaptable 20.0.5-canary.0 → 20.0.5
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/package.json +1 -1
- package/src/AdaptableState/Common/AggregationColumns.d.ts +1 -8
- package/src/AdaptableState/LayoutState.d.ts +0 -12
- package/src/Api/Implementation/ColumnApiImpl.d.ts +0 -1
- package/src/Api/Implementation/ColumnApiImpl.js +1 -11
- package/src/Api/Implementation/LayoutHelpers.js +2 -25
- package/src/Utilities/Constants/GeneralConstants.d.ts +0 -1
- package/src/Utilities/Constants/GeneralConstants.js +0 -1
- package/src/View/Components/ColumnFilter/components/ColumnFilterInput.js +29 -1
- package/src/agGrid/FilterWrapper.js +6 -4
- package/src/env.js +2 -2
- package/src/layout-manager/src/LayoutManagerModel.d.ts +20 -23
- package/src/layout-manager/src/index.d.ts +1 -18
- package/src/layout-manager/src/index.js +2 -288
- package/src/layout-manager/src/normalizeLayoutModel.js +0 -3
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -3,7 +3,7 @@ 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 {
|
|
6
|
+
import { simplifyTableLayoutModel, simplifyPivotLayoutModel, simplifyLayoutModel, } from './simplifyLayoutModel';
|
|
7
7
|
import { sortColumnIdsByOrder } from './sortColumnIdsByOrder';
|
|
8
8
|
function flattenColDefs(colDefs) {
|
|
9
9
|
const res = [];
|
|
@@ -117,12 +117,8 @@ export class LayoutManager extends LMEmitter {
|
|
|
117
117
|
}).bind(this);
|
|
118
118
|
}
|
|
119
119
|
this.setOptions(options);
|
|
120
|
-
// this ensures the grand total columns are positioned correctly (before/after) even when changed at runtime
|
|
121
|
-
// see https://www.ag-grid.com/react-data-grid/pivoting-column-groups/#changing-data-filters-and-configurations
|
|
122
|
-
this.gridApi.setGridOption('enableStrictPivotColumnOrder', true);
|
|
123
120
|
this.setupEvents();
|
|
124
121
|
this.indexColumns();
|
|
125
|
-
this.setupPivotTotals();
|
|
126
122
|
globalThis.layoutManager = this;
|
|
127
123
|
}
|
|
128
124
|
destroy() {
|
|
@@ -256,18 +252,6 @@ export class LayoutManager extends LMEmitter {
|
|
|
256
252
|
PivotAggregationColumns: layout.TableAggregationColumns,
|
|
257
253
|
PivotExpandLevel: prevLayout?.PivotExpandLevel ?? -1,
|
|
258
254
|
};
|
|
259
|
-
const grandTotalRow = this.gridApi.getGridOption('grandTotalRow');
|
|
260
|
-
if (grandTotalRow) {
|
|
261
|
-
pivotLayout.GrandTotalRow = grandTotalRow;
|
|
262
|
-
}
|
|
263
|
-
const grandTotalColumn = this.gridApi.getGridOption('pivotRowTotals');
|
|
264
|
-
if (grandTotalColumn) {
|
|
265
|
-
pivotLayout.GrandTotalColumn = grandTotalColumn;
|
|
266
|
-
}
|
|
267
|
-
const pivotGroupTotalColumn = this.gridApi.getGridOption('pivotColumnGroupTotals');
|
|
268
|
-
if (pivotGroupTotalColumn) {
|
|
269
|
-
pivotLayout.PivotGroupTotalColumn = pivotGroupTotalColumn;
|
|
270
|
-
}
|
|
271
255
|
return simplifyPivotLayoutModel(pivotLayout);
|
|
272
256
|
}
|
|
273
257
|
getTableLayoutModelFromGrid() {
|
|
@@ -288,7 +272,7 @@ export class LayoutManager extends LMEmitter {
|
|
|
288
272
|
let ColumnPinning = {};
|
|
289
273
|
const gridState = this.gridApi.getState();
|
|
290
274
|
const prevLayout = this.currentLayout;
|
|
291
|
-
const prevAggColumns = prevLayout?.TableAggregationColumns
|
|
275
|
+
const prevAggColumns = prevLayout?.TableAggregationColumns;
|
|
292
276
|
const prevAggColumnsMap = prevAggColumns?.reduce((acc, agg) => {
|
|
293
277
|
acc[agg.ColumnId] = agg;
|
|
294
278
|
return acc;
|
|
@@ -999,7 +983,6 @@ export class LayoutManager extends LMEmitter {
|
|
|
999
983
|
return columnIds;
|
|
1000
984
|
}
|
|
1001
985
|
applyPivotLayout(layout, options) {
|
|
1002
|
-
this.applyPivotTotals(layout);
|
|
1003
986
|
const columnState = this.computeColumnStateForPivotLayout(layout);
|
|
1004
987
|
// by simply calling this.gridApi.applyColumnState(columnState)
|
|
1005
988
|
// the order of aggregations is not preserved/guaranteed by ag-grid
|
|
@@ -1027,50 +1010,6 @@ export class LayoutManager extends LMEmitter {
|
|
|
1027
1010
|
this.applyRowGroupValues(layout.RowGroupValues);
|
|
1028
1011
|
}
|
|
1029
1012
|
}
|
|
1030
|
-
applyPivotTotals(layout) {
|
|
1031
|
-
/**
|
|
1032
|
-
* GrandTotalRow
|
|
1033
|
-
*/
|
|
1034
|
-
if (layout.GrandTotalRow) {
|
|
1035
|
-
const grandTotalRow = layout.GrandTotalRow === true || layout.GrandTotalRow === 'top'
|
|
1036
|
-
? 'top'
|
|
1037
|
-
: layout.GrandTotalRow === 'bottom'
|
|
1038
|
-
? 'bottom'
|
|
1039
|
-
: null;
|
|
1040
|
-
this.gridApi.setGridOption('grandTotalRow', grandTotalRow);
|
|
1041
|
-
}
|
|
1042
|
-
else {
|
|
1043
|
-
this.gridApi.setGridOption('grandTotalRow', null);
|
|
1044
|
-
}
|
|
1045
|
-
/**
|
|
1046
|
-
* GrandTotalColumn
|
|
1047
|
-
*/
|
|
1048
|
-
if (layout.GrandTotalColumn) {
|
|
1049
|
-
const grandTotalColumn = layout.GrandTotalColumn === true || layout.GrandTotalColumn === 'before'
|
|
1050
|
-
? 'before'
|
|
1051
|
-
: layout.GrandTotalColumn === 'after'
|
|
1052
|
-
? 'after'
|
|
1053
|
-
: null;
|
|
1054
|
-
this.gridApi.setGridOption('pivotRowTotals', grandTotalColumn);
|
|
1055
|
-
}
|
|
1056
|
-
else {
|
|
1057
|
-
this.gridApi.setGridOption('pivotRowTotals', null);
|
|
1058
|
-
}
|
|
1059
|
-
/**
|
|
1060
|
-
* PivotGroupTotalColumn
|
|
1061
|
-
*/
|
|
1062
|
-
if (layout.PivotGroupTotalColumn) {
|
|
1063
|
-
const pivotGroupTotalColumn = layout.PivotGroupTotalColumn === true || layout.PivotGroupTotalColumn === 'before'
|
|
1064
|
-
? 'before'
|
|
1065
|
-
: layout.PivotGroupTotalColumn === 'after'
|
|
1066
|
-
? 'after'
|
|
1067
|
-
: null;
|
|
1068
|
-
this.gridApi.setGridOption('pivotColumnGroupTotals', pivotGroupTotalColumn);
|
|
1069
|
-
}
|
|
1070
|
-
else {
|
|
1071
|
-
this.gridApi.setGridOption('pivotColumnGroupTotals', null);
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
1013
|
applyPivotExpandLevel(layout) {
|
|
1075
1014
|
const PivotExpandLevel = layout.PivotExpandLevel ?? -1;
|
|
1076
1015
|
const allDisplayedColumnGroups = this.gridApi.getAllDisplayedColumnGroups();
|
|
@@ -1106,229 +1045,4 @@ export class LayoutManager extends LMEmitter {
|
|
|
1106
1045
|
}
|
|
1107
1046
|
return res;
|
|
1108
1047
|
}
|
|
1109
|
-
setupPivotTotals() {
|
|
1110
|
-
const _original_processPivotResultColDef = this.gridApi.getGridOption('processPivotResultColDef');
|
|
1111
|
-
this.gridApi.setGridOption('processPivotResultColDef', (resulColDef) => {
|
|
1112
|
-
_original_processPivotResultColDef?.(resulColDef);
|
|
1113
|
-
if (!isPivotLayoutModel(this.currentLayout)) {
|
|
1114
|
-
return;
|
|
1115
|
-
}
|
|
1116
|
-
// column that contain the aggregated total for each value column per row
|
|
1117
|
-
this.patchGrandTotalColumn(resulColDef);
|
|
1118
|
-
this.patchPivotGroupTotalColumn(resulColDef);
|
|
1119
|
-
});
|
|
1120
|
-
const _original_processPivotResultColGroupDef = this.gridApi.getGridOption('processPivotResultColGroupDef');
|
|
1121
|
-
this.gridApi.setGridOption('processPivotResultColGroupDef', (colGroupDef) => {
|
|
1122
|
-
_original_processPivotResultColGroupDef?.(colGroupDef);
|
|
1123
|
-
if (!isPivotLayoutModel(this.currentLayout)) {
|
|
1124
|
-
return;
|
|
1125
|
-
}
|
|
1126
|
-
this.patchPivotTotalColumn(colGroupDef);
|
|
1127
|
-
});
|
|
1128
|
-
}
|
|
1129
|
-
isPivotRowTotalColDef(colDef) {
|
|
1130
|
-
return colDef.colId?.startsWith('PivotRowTotal_');
|
|
1131
|
-
}
|
|
1132
|
-
patchGrandTotalColumn(resultColDef) {
|
|
1133
|
-
if (!isPivotLayoutModel(this.currentLayout) || !this.currentLayout.GrandTotalColumn) {
|
|
1134
|
-
return;
|
|
1135
|
-
}
|
|
1136
|
-
if (this.isPivotRowTotalColDef(resultColDef)) {
|
|
1137
|
-
resultColDef.headerName = `Grand Total ${resultColDef.headerName}`;
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
isPivotGroupTotalColumn(colDef) {
|
|
1141
|
-
// pivot group total are spanning cross all aggregations
|
|
1142
|
-
// therefore the last part of the colId is empty (hence the "dangling" underscore)
|
|
1143
|
-
return colDef.colId?.startsWith('pivot_') && colDef.colId?.endsWith('_');
|
|
1144
|
-
}
|
|
1145
|
-
patchPivotGroupTotalColumn(resultColDef) {
|
|
1146
|
-
if (!isPivotLayoutModel(this.currentLayout) || !this.currentLayout.PivotGroupTotalColumn) {
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
if (this.isPivotGroupTotalColumn(resultColDef)) {
|
|
1150
|
-
// resultColDef
|
|
1151
|
-
const colInfo = this.destructurePivotColumnId(resultColDef, {
|
|
1152
|
-
pivotColIds: this.currentLayout.PivotColumns,
|
|
1153
|
-
aggColIds: this.currentLayout.PivotAggregationColumns.map((col) => col.ColumnId),
|
|
1154
|
-
});
|
|
1155
|
-
if (colInfo !== '!unknown!') {
|
|
1156
|
-
const currentPivotKey = colInfo.pivotKeys[colInfo.pivotKeys.length - 1];
|
|
1157
|
-
resultColDef.headerName = `${currentPivotKey} Total`;
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
patchPivotTotalColumn(colGroupDef) {
|
|
1162
|
-
const hasPivotTotalCols = (pivotLayout) => {
|
|
1163
|
-
return pivotLayout.PivotAggregationColumns?.some((aggCol) => !!aggCol.TotalColumn);
|
|
1164
|
-
};
|
|
1165
|
-
const isPivotTotalColDef = (colDef) => {
|
|
1166
|
-
return !!colDef.pivotTotalColumnIds?.length;
|
|
1167
|
-
};
|
|
1168
|
-
if (!isPivotLayoutModel(this.currentLayout) || !hasPivotTotalCols(this.currentLayout)) {
|
|
1169
|
-
return;
|
|
1170
|
-
}
|
|
1171
|
-
const pivotRowTotalColDefsBefore = [];
|
|
1172
|
-
const pivotRowTotalColDefsAfter = [];
|
|
1173
|
-
const pivotTotalColDefsBefore = [];
|
|
1174
|
-
const pivotTotalColDefsAfter = [];
|
|
1175
|
-
const normalColDefs = [];
|
|
1176
|
-
colGroupDef.children.forEach((colDef) => {
|
|
1177
|
-
if (this.isPivotRowTotalColDef(colDef)) {
|
|
1178
|
-
if (this.gridApi.getGridOption('pivotRowTotals') === 'after') {
|
|
1179
|
-
pivotRowTotalColDefsAfter.push(colDef);
|
|
1180
|
-
}
|
|
1181
|
-
else {
|
|
1182
|
-
pivotRowTotalColDefsBefore.push(colDef);
|
|
1183
|
-
}
|
|
1184
|
-
return;
|
|
1185
|
-
}
|
|
1186
|
-
if (isPivotTotalColDef(colDef)) {
|
|
1187
|
-
if (!colDef.colId.startsWith('pivot_')) {
|
|
1188
|
-
this.warn(`Pivot total column ${colDef.colId} is not prefixed with 'pivot_', skipping...`);
|
|
1189
|
-
return;
|
|
1190
|
-
}
|
|
1191
|
-
// we do this for all total cols, but we will hide the ones that are not visible
|
|
1192
|
-
colDef.columnGroupShow = undefined;
|
|
1193
|
-
colDef.headerName = `Total ${colDef.headerName}`;
|
|
1194
|
-
const totalColConfig = this.getPivotTotalColumnConfig(colDef, this.currentLayout);
|
|
1195
|
-
if (!totalColConfig.visible) {
|
|
1196
|
-
colDef.hide = true;
|
|
1197
|
-
}
|
|
1198
|
-
else {
|
|
1199
|
-
if (totalColConfig.position === 'after') {
|
|
1200
|
-
pivotTotalColDefsAfter.push(colDef);
|
|
1201
|
-
}
|
|
1202
|
-
else {
|
|
1203
|
-
pivotTotalColDefsBefore.push(colDef);
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
else {
|
|
1208
|
-
normalColDefs.push(colDef);
|
|
1209
|
-
}
|
|
1210
|
-
});
|
|
1211
|
-
colGroupDef.children = [
|
|
1212
|
-
...pivotRowTotalColDefsBefore,
|
|
1213
|
-
...pivotTotalColDefsBefore,
|
|
1214
|
-
...normalColDefs,
|
|
1215
|
-
...pivotTotalColDefsAfter,
|
|
1216
|
-
...pivotRowTotalColDefsAfter,
|
|
1217
|
-
];
|
|
1218
|
-
}
|
|
1219
|
-
// supports only pivotTotalColumns (aggregation total) and pivotGroupTotal
|
|
1220
|
-
// AG Grid builds the ID as: `pivot_${pivotCols.join('-')}_${pivotKeys.join('-')}_${measureColumnId}`
|
|
1221
|
-
// see https://github.com/ag-grid/ag-grid/blob/e0cfe533b55b75cdc148cdfb1a4e977731dc0712/packages/ag-grid-enterprise/src/pivot/pivotColDefService.ts#L454C16-L454C88
|
|
1222
|
-
destructurePivotColumnId(colDef, currentModel) {
|
|
1223
|
-
const { colId } = colDef;
|
|
1224
|
-
// Basic validation
|
|
1225
|
-
if (!colId?.startsWith('pivot_')) {
|
|
1226
|
-
this.warn(`Column id must start with 'pivot_': ${colId}`);
|
|
1227
|
-
return '!unknown!';
|
|
1228
|
-
}
|
|
1229
|
-
const hasSpecialChars = (arr) => arr.some((str) => str.includes('-') || str.includes('_'));
|
|
1230
|
-
// AG Grid uses _ and - as delimiters
|
|
1231
|
-
// if we have these special characters in the column IDs, we need to parse them differently
|
|
1232
|
-
const colIdsOrKeysContainSpecialChars = hasSpecialChars(currentModel.pivotColIds) ||
|
|
1233
|
-
hasSpecialChars(currentModel.aggColIds) ||
|
|
1234
|
-
hasSpecialChars(colDef.pivotKeys || []);
|
|
1235
|
-
// Fast path - no special characters
|
|
1236
|
-
if (!colIdsOrKeysContainSpecialChars) {
|
|
1237
|
-
// Split by underscore to get 4 parts
|
|
1238
|
-
const parts = colId.split('_');
|
|
1239
|
-
if (parts.length !== 4) {
|
|
1240
|
-
this.warn(`Unsupported format of pivot total column id: ${colId}`);
|
|
1241
|
-
return '!unknown!';
|
|
1242
|
-
}
|
|
1243
|
-
const [_pivotPrefix, pivotColsTxt, pivotKeysTxt, aggregationColumnId] = parts;
|
|
1244
|
-
const pivotColumnIds = pivotColsTxt.split('-');
|
|
1245
|
-
const pivotKeys = pivotKeysTxt.split('-');
|
|
1246
|
-
const pivotColumnId = pivotColumnIds[pivotKeys.length - 1];
|
|
1247
|
-
return {
|
|
1248
|
-
pivotColumnIds,
|
|
1249
|
-
pivotKeys,
|
|
1250
|
-
pivotColumnId,
|
|
1251
|
-
aggregationColumnId: aggregationColumnId !== '' ? aggregationColumnId : undefined,
|
|
1252
|
-
};
|
|
1253
|
-
}
|
|
1254
|
-
// the complex path, where we have to handle the special characters
|
|
1255
|
-
// Remove 'pivot_' prefix
|
|
1256
|
-
const withoutPrefix = colId.slice(6);
|
|
1257
|
-
// Check if it's a pivot group total
|
|
1258
|
-
const isPivotGroupTotal = withoutPrefix.endsWith('_');
|
|
1259
|
-
// Get pivot keys from colDef (more reliable than string parsing)
|
|
1260
|
-
const pivotKeys = colDef.pivotKeys || [];
|
|
1261
|
-
if (isPivotGroupTotal) {
|
|
1262
|
-
// Remove trailing underscore for pivot group totals
|
|
1263
|
-
const content = withoutPrefix.slice(0, -1);
|
|
1264
|
-
// The remaining content should be the pivot columns
|
|
1265
|
-
const pivotColumnIds = currentModel.pivotColIds.filter((id) => content.includes(id));
|
|
1266
|
-
if (!pivotColumnIds.length) {
|
|
1267
|
-
this.warn(`Could not identify pivot columns in: ${content}`);
|
|
1268
|
-
return '!unknown!';
|
|
1269
|
-
}
|
|
1270
|
-
return {
|
|
1271
|
-
pivotColumnIds,
|
|
1272
|
-
pivotKeys,
|
|
1273
|
-
pivotColumnId: pivotColumnIds[pivotKeys.length],
|
|
1274
|
-
};
|
|
1275
|
-
}
|
|
1276
|
-
// For regular pivot columns, work backwards to find aggregation column
|
|
1277
|
-
const parts = withoutPrefix.split('_');
|
|
1278
|
-
const lastPart = parts[parts.length - 1];
|
|
1279
|
-
// Find the longest matching aggregation column id from the end
|
|
1280
|
-
const aggregationColumnId = currentModel.aggColIds.find((aggId) => lastPart.endsWith(aggId));
|
|
1281
|
-
if (!aggregationColumnId) {
|
|
1282
|
-
this.warn(`Could not identify aggregation column in: ${lastPart}`);
|
|
1283
|
-
return '!unknown!';
|
|
1284
|
-
}
|
|
1285
|
-
// Remove aggregation part and get pivot columns
|
|
1286
|
-
const withoutAgg = withoutPrefix.slice(0, -(aggregationColumnId.length + 1));
|
|
1287
|
-
const pivotColumnIds = currentModel.pivotColIds.filter((id) => withoutAgg.includes(id));
|
|
1288
|
-
if (!pivotColumnIds.length) {
|
|
1289
|
-
this.warn(`Could not identify pivot columns in: ${withoutAgg}`);
|
|
1290
|
-
return '!unknown!';
|
|
1291
|
-
}
|
|
1292
|
-
return {
|
|
1293
|
-
pivotColumnIds,
|
|
1294
|
-
pivotKeys,
|
|
1295
|
-
pivotColumnId: pivotColumnIds[pivotKeys.length - 1],
|
|
1296
|
-
aggregationColumnId,
|
|
1297
|
-
};
|
|
1298
|
-
}
|
|
1299
|
-
getPivotTotalColumnConfig(colDef, currentPivotLayout) {
|
|
1300
|
-
const defaultHiddenConfig = {
|
|
1301
|
-
visible: false,
|
|
1302
|
-
};
|
|
1303
|
-
const colIdInfo = this.destructurePivotColumnId(colDef, {
|
|
1304
|
-
pivotColIds: this.currentLayout.PivotColumns,
|
|
1305
|
-
aggColIds: this.currentLayout.PivotAggregationColumns.map((col) => col.ColumnId),
|
|
1306
|
-
});
|
|
1307
|
-
if (colIdInfo === '!unknown!') {
|
|
1308
|
-
return defaultHiddenConfig;
|
|
1309
|
-
}
|
|
1310
|
-
const { pivotColumnId, aggregationColumnId } = colIdInfo;
|
|
1311
|
-
const layoutAggCol = currentPivotLayout.PivotAggregationColumns?.find((col) => col.ColumnId === aggregationColumnId);
|
|
1312
|
-
if (!layoutAggCol) {
|
|
1313
|
-
this.warn(`Pivot Totals: could NOT find aggregation(value) column with id ${aggregationColumnId}`);
|
|
1314
|
-
return defaultHiddenConfig;
|
|
1315
|
-
}
|
|
1316
|
-
const layoutPivotTotalColumn = layoutAggCol.TotalColumn;
|
|
1317
|
-
if (!layoutPivotTotalColumn) {
|
|
1318
|
-
return defaultHiddenConfig;
|
|
1319
|
-
}
|
|
1320
|
-
if (Array.isArray(layoutPivotTotalColumn)) {
|
|
1321
|
-
const pivotSpecificConfig = layoutPivotTotalColumn.find((config) => config.PivotColumnId === pivotColumnId);
|
|
1322
|
-
return {
|
|
1323
|
-
visible: pivotSpecificConfig && pivotSpecificConfig.ShowTotal !== false,
|
|
1324
|
-
position: pivotSpecificConfig?.ShowTotal === 'after' ? 'after' : 'before',
|
|
1325
|
-
};
|
|
1326
|
-
}
|
|
1327
|
-
else {
|
|
1328
|
-
return {
|
|
1329
|
-
visible: !!layoutPivotTotalColumn,
|
|
1330
|
-
position: layoutPivotTotalColumn === 'after' ? 'after' : 'before',
|
|
1331
|
-
};
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1334
1048
|
}
|
|
@@ -139,9 +139,6 @@ 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
|
-
}
|
|
145
142
|
return layout;
|
|
146
143
|
}
|
|
147
144
|
export function normalizeLayoutModel(layout, options) {
|