@adaptabletools/adaptable 21.0.12 → 21.1.0-canary.1
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 +1811 -2336
- package/base.css.map +1 -1
- package/index.css +1768 -1413
- package/index.css.map +1 -1
- package/package.json +3 -3
- package/src/AdaptableInterfaces/IAdaptable.d.ts +2 -1
- package/src/AdaptableOptions/FilterOptions.d.ts +7 -0
- package/src/AdaptableOptions/PredicateOptions.d.ts +4 -3
- package/src/AdaptableState/Common/AdaptableColumn.d.ts +1 -1
- package/src/AdaptableState/Common/AdaptablePredicate.d.ts +12 -0
- package/src/AdaptableState/Common/AdaptablePredicate.js +132 -18
- package/src/AdaptableState/Selection/GridCell.d.ts +10 -0
- package/src/Api/Implementation/ExportApiImpl.js +2 -8
- package/src/Api/Implementation/PredicateApiImpl.d.ts +3 -1
- package/src/Api/Implementation/PredicateApiImpl.js +25 -2
- package/src/Api/Internal/AdaptableInternalApi.d.ts +2 -1
- package/src/Api/Internal/AdaptableInternalApi.js +6 -0
- package/src/Api/Internal/PredicateInternalApi.d.ts +3 -1
- package/src/Api/Internal/PredicateInternalApi.js +14 -0
- package/src/Api/PredicateApi.d.ts +1 -1
- package/src/Redux/Store/AdaptableStore.js +111 -3
- package/src/Utilities/Helpers/Helper.js +26 -2
- package/src/Utilities/Hooks/index.d.ts +4 -0
- package/src/Utilities/Hooks/index.js +4 -0
- package/src/Utilities/Hooks/useAdaptableColumn.d.ts +2 -0
- package/src/Utilities/Hooks/useAdaptableColumn.js +6 -0
- package/src/Utilities/Hooks/useAdaptableOptions.d.ts +2 -0
- package/src/Utilities/Hooks/useAdaptableOptions.js +5 -0
- package/src/Utilities/Hooks/useAdaptableState.d.ts +3 -0
- package/src/Utilities/Hooks/useAdaptableState.js +39 -0
- package/src/Utilities/Services/ModuleService.js +1 -1
- package/src/Utilities/adaptableQlUtils.js +3 -0
- package/src/View/AdaptableComputedCSSVarsContext.d.ts +12 -0
- package/src/View/AdaptableComputedCSSVarsContext.js +25 -0
- package/src/View/Components/AdaptableInput/AdaptableDateInlineInput.d.ts +1 -1
- package/src/View/Components/ColumnFilter/FloatingFilter.js +5 -1
- package/src/View/Components/ColumnFilter/components/FloatingFilterInputList.js +1 -1
- package/src/View/Components/ColumnFilter/components/FloatingFilterValues.js +34 -9
- package/src/View/Components/FilterForm/ListBoxFilterForm.d.ts +1 -0
- package/src/View/Components/FilterForm/ListBoxFilterForm.js +93 -16
- package/src/View/Layout/Wizard/sections/ColumnsSection.js +1 -1
- package/src/View/renderWithAdaptableContext.js +3 -1
- package/src/agGrid/AdaptableAgGrid.d.ts +3 -1
- package/src/agGrid/AdaptableAgGrid.js +361 -24
- package/src/agGrid/AdaptableFilterHandler.d.ts +3 -1
- package/src/agGrid/AdaptableFilterHandler.js +16 -12
- package/src/agGrid/AgGridAdapter.js +9 -5
- package/src/agGrid/AgGridColumnAdapter.js +14 -12
- package/src/components/OverlayTrigger/index.js +1 -1
- package/src/components/Select/Select.js +22 -22
- package/src/components/Tree/TreeDropdown/index.d.ts +27 -0
- package/src/components/Tree/TreeDropdown/index.js +250 -0
- package/src/components/Tree/TreeList/index.d.ts +25 -0
- package/src/components/Tree/TreeList/index.js +35 -0
- package/src/devTools/DevToolsTracks.d.ts +31 -0
- package/src/devTools/DevToolsTracks.js +31 -0
- package/src/devTools/PerfMarker.d.ts +12 -0
- package/src/devTools/PerfMarker.js +1 -0
- package/src/devTools/index.d.ts +102 -0
- package/src/devTools/index.js +159 -0
- package/src/env.js +2 -2
- package/src/layout-manager/src/index.d.ts +2 -0
- package/src/layout-manager/src/index.js +24 -0
- package/src/metamodel/adaptable.metamodel.d.ts +6 -0
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -8,7 +8,7 @@ import Emitter from '../Utilities/Emitter';
|
|
|
8
8
|
import { applyDefaultAdaptableOptions } from '../AdaptableOptions/DefaultAdaptableOptions';
|
|
9
9
|
import { AgGridAdapter } from './AgGridAdapter';
|
|
10
10
|
import * as GeneralConstants from '../Utilities/Constants/GeneralConstants';
|
|
11
|
-
import { AG_GRID_GRAND_TOTAL_ROW_ID, AUTOGENERATED_PK_COLUMN, ERROR_LAYOUT, GROUP_PATH_SEPARATOR, HALF_SECOND, QUARTER_SECOND, } from '../Utilities/Constants/GeneralConstants';
|
|
11
|
+
import { AG_GRID_GRAND_TOTAL_ROW_ID, AG_GRID_GROUPED_COLUMN, AUTOGENERATED_PK_COLUMN, ERROR_LAYOUT, GROUP_PATH_SEPARATOR, HALF_SECOND, QUARTER_SECOND, } from '../Utilities/Constants/GeneralConstants';
|
|
12
12
|
import { DataService } from '../Utilities/Services/DataService';
|
|
13
13
|
import { AdaptableStore } from '../Redux/Store/AdaptableStore';
|
|
14
14
|
import { AdaptableApiImpl } from '../Api/Implementation/AdaptableApiImpl';
|
|
@@ -99,6 +99,9 @@ import { AgGridThemeAdapter } from './AgGridThemeAdapter';
|
|
|
99
99
|
import { mapOldTypeToDataType } from '../migration/VersionUpgrade20';
|
|
100
100
|
import { tagProvidedByAdaptable } from '../Utilities/adaptableOverrideCheck';
|
|
101
101
|
import { AgGridModulesAdapter } from './AgGridModulesAdapter';
|
|
102
|
+
import { getMarker } from '../devTools';
|
|
103
|
+
import { DeepMap } from '@infinite-table/infinite-react';
|
|
104
|
+
import { DateFormatter } from '../Utilities/Helpers/FormatHelper';
|
|
102
105
|
const LocalEventService_Prototype = LocalEventService.prototype;
|
|
103
106
|
const LocalEventService_dispatchEvent = LocalEventService_Prototype.dispatchEvent;
|
|
104
107
|
LocalEventService_Prototype.dispatchEvent = function (event) {
|
|
@@ -277,6 +280,8 @@ export class AdaptableAgGrid {
|
|
|
277
280
|
this._rawAdaptableOptions.adaptableId = `adaptable_id_${Date.now()}`;
|
|
278
281
|
}
|
|
279
282
|
this.logger = this.logger ?? new AdaptableLogger(this._rawAdaptableOptions.adaptableId);
|
|
283
|
+
const adaptableId = this._rawAdaptableOptions.adaptableId;
|
|
284
|
+
const initMarker = getMarker(adaptableId).track.Init.label.Init.start();
|
|
280
285
|
const perfInitAdaptableAgGrid = this.logger.beginPerf(`Adaptable._initAdaptableAgGrid()`);
|
|
281
286
|
AdaptableAgGrid.collectInstance(this, this._rawAdaptableOptions.adaptableId);
|
|
282
287
|
this.variant = config.variant;
|
|
@@ -314,6 +319,7 @@ export class AdaptableAgGrid {
|
|
|
314
319
|
this.forPlugins((plugin) => plugin.afterInitServices(this));
|
|
315
320
|
this.adaptableModules = this.initModules();
|
|
316
321
|
this.forPlugins((plugin) => plugin.afterInitModules(this, this.adaptableModules));
|
|
322
|
+
const loadStoreMarker = getMarker(adaptableId).track.Init.label.LoadStore.start();
|
|
317
323
|
const perfLoadStore = this.logger.beginPerf(`loadStore()`);
|
|
318
324
|
this.adaptableStore = this.initAdaptableStore();
|
|
319
325
|
this.forPlugins((plugin) => plugin.afterInitStore(this));
|
|
@@ -340,6 +346,7 @@ export class AdaptableAgGrid {
|
|
|
340
346
|
},
|
|
341
347
|
});
|
|
342
348
|
perfLoadStore.end();
|
|
349
|
+
loadStoreMarker.end();
|
|
343
350
|
// just in case Adaptable was destroyed while loading the store (which is an async operation)
|
|
344
351
|
if (this.isDestroyed) {
|
|
345
352
|
this.midwayDestroy();
|
|
@@ -386,6 +393,7 @@ export class AdaptableAgGrid {
|
|
|
386
393
|
this.lifecycleState = 'initAgGrid';
|
|
387
394
|
this.agGridAdapter.initialGridOptions = gridOptions;
|
|
388
395
|
const perfInitAgGrid = this.logger.beginPerf(`initAgGrid()`);
|
|
396
|
+
const initAgGridMarker = getMarker(adaptableId).track.Init.label.InitAGGrid.start();
|
|
389
397
|
this.validateColumnDefTypes(gridOptions.columnDefs);
|
|
390
398
|
const agGridApi = await this.initializeAgGrid(gridOptions, config.modules, config.renderAgGridFrameworkComponent);
|
|
391
399
|
if (agGridApi === false) {
|
|
@@ -419,6 +427,7 @@ export class AdaptableAgGrid {
|
|
|
419
427
|
this.logger.info(`Hide Loading Screen`);
|
|
420
428
|
this.unmountLoadingScreen?.();
|
|
421
429
|
perfInitAgGrid.end();
|
|
430
|
+
initAgGridMarker.end();
|
|
422
431
|
// we need to intercept several AG Grid Api methods and trigger Adaptable state changes
|
|
423
432
|
this.agGridAdapter.setAgGridApi(agGridApi);
|
|
424
433
|
this.agGridAdapter.monkeyPatchingGridOptionsUpdates();
|
|
@@ -494,6 +503,7 @@ export class AdaptableAgGrid {
|
|
|
494
503
|
});
|
|
495
504
|
});
|
|
496
505
|
perfInitAdaptableAgGrid.end();
|
|
506
|
+
initMarker.end();
|
|
497
507
|
return Promise.resolve(this.api);
|
|
498
508
|
}
|
|
499
509
|
midwayDestroy() {
|
|
@@ -550,6 +560,36 @@ You need to define at least one Layout!`);
|
|
|
550
560
|
// eg: might not include the generated row group columns in the column order
|
|
551
561
|
// but the normalization does this for us
|
|
552
562
|
state.Layout.Layouts = state.Layout.Layouts.map((layout) => normalizeLayout(layout, normalizeOptions));
|
|
563
|
+
//now let's normalize the In/NotIn predicate for the group column
|
|
564
|
+
// the inputs in this predicate should be an array of arrays
|
|
565
|
+
// but for ease of use (and also for similarity with the In predicate for
|
|
566
|
+
// other columns) we allow the inputs to be an array of strings
|
|
567
|
+
// and change them to an array of arrays
|
|
568
|
+
state.Layout.Layouts = state.Layout.Layouts.map((layout) => {
|
|
569
|
+
if (Array.isArray(layout.ColumnFilters)) {
|
|
570
|
+
layout.ColumnFilters = layout.ColumnFilters.map((columnFilter) => {
|
|
571
|
+
if (columnFilter.ColumnId === AG_GRID_GROUPED_COLUMN) {
|
|
572
|
+
if (Array.isArray(columnFilter.Predicates)) {
|
|
573
|
+
columnFilter.Predicates = columnFilter.Predicates.map((predicate) => {
|
|
574
|
+
if (predicate.PredicateId === 'In' || predicate.PredicateId === 'NotIn') {
|
|
575
|
+
if (Array.isArray(predicate.Inputs)) {
|
|
576
|
+
predicate.Inputs = predicate.Inputs.map((input) => {
|
|
577
|
+
if (!Array.isArray(input)) {
|
|
578
|
+
return [input];
|
|
579
|
+
}
|
|
580
|
+
return input;
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
return predicate;
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return columnFilter;
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
return layout;
|
|
592
|
+
});
|
|
553
593
|
}
|
|
554
594
|
return state;
|
|
555
595
|
}
|
|
@@ -1288,6 +1328,7 @@ You need to define at least one Layout!`);
|
|
|
1288
1328
|
}
|
|
1289
1329
|
initAdaptableStore() {
|
|
1290
1330
|
const perfNewAdaptableStore = this.logger.beginPerf(`initAdaptableStore()`);
|
|
1331
|
+
const initAdaptableStoreMarker = getMarker(this.adaptableOptions.adaptableId).track.Init.label.InitStore.start();
|
|
1291
1332
|
const adaptableStore = new AdaptableStore(this);
|
|
1292
1333
|
adaptableStore.onAny((eventName, data) => {
|
|
1293
1334
|
if (this.isReady) {
|
|
@@ -1296,6 +1337,7 @@ You need to define at least one Layout!`);
|
|
|
1296
1337
|
this.forPlugins((plugin) => plugin.onStoreEvent(eventName, data, this.adaptableStore));
|
|
1297
1338
|
});
|
|
1298
1339
|
perfNewAdaptableStore.end();
|
|
1340
|
+
initAdaptableStoreMarker.end();
|
|
1299
1341
|
return adaptableStore;
|
|
1300
1342
|
}
|
|
1301
1343
|
mapAdaptableStateToAgGridState(adaptableState, agGridColDefs, options) {
|
|
@@ -1714,12 +1756,12 @@ You need to define at least one Layout!`);
|
|
|
1714
1756
|
/**
|
|
1715
1757
|
* Use (lazy evaluated) getters to avoid unnecessary calculations and memoization to avoid recalculating the same values
|
|
1716
1758
|
*/
|
|
1717
|
-
createGridCell(rowNode, columnId) {
|
|
1759
|
+
createGridCell(rowNode, columnId, defaults) {
|
|
1718
1760
|
let _column;
|
|
1719
1761
|
let _primaryKeyValue;
|
|
1720
|
-
let _rawValue;
|
|
1721
|
-
let _displayValue;
|
|
1722
|
-
let _normalisedValue;
|
|
1762
|
+
let _rawValue = defaults ? defaults.rawValue : undefined;
|
|
1763
|
+
let _displayValue = defaults ? defaults.displayValue : undefined;
|
|
1764
|
+
let _normalisedValue = defaults ? defaults.normalisedValue : undefined;
|
|
1723
1765
|
let _isRowGroupCell;
|
|
1724
1766
|
const _isPivotCell = this.api.columnApi.isPivotResultColumn(columnId);
|
|
1725
1767
|
const self = this;
|
|
@@ -2316,7 +2358,41 @@ You need to define at least one Layout!`);
|
|
|
2316
2358
|
if (currentGridCells) {
|
|
2317
2359
|
return currentGridCells;
|
|
2318
2360
|
}
|
|
2319
|
-
return (currentGridCells =
|
|
2361
|
+
return (currentGridCells =
|
|
2362
|
+
column.columnId === AG_GRID_GROUPED_COLUMN
|
|
2363
|
+
? this.getDistinctGridCellsForGroupedColumn()
|
|
2364
|
+
: column.dataType === 'date'
|
|
2365
|
+
? this.getDistinctGridCellsForDateColumn(column)
|
|
2366
|
+
: this.getDistinctGridCellsForColumn(column));
|
|
2367
|
+
};
|
|
2368
|
+
// No distinct values so lets return unique grid cells
|
|
2369
|
+
const mapFn = (gridCell, level) => {
|
|
2370
|
+
if (level || Array.isArray(gridCell.children)) {
|
|
2371
|
+
const cell = gridCell;
|
|
2372
|
+
const inFilterValue = {
|
|
2373
|
+
value: gridCell.rawValue,
|
|
2374
|
+
label: gridCell.displayValue,
|
|
2375
|
+
level: level ?? 0,
|
|
2376
|
+
tooltip: false,
|
|
2377
|
+
get visible() {
|
|
2378
|
+
return gridCell.visible;
|
|
2379
|
+
},
|
|
2380
|
+
count: gridCell.count ?? 0,
|
|
2381
|
+
leafChildrenCount: cell.leafChildrenCount ?? 0,
|
|
2382
|
+
get visibleCount() {
|
|
2383
|
+
return gridCell.visibleCount ?? 0;
|
|
2384
|
+
},
|
|
2385
|
+
isSelected: gridCell.rowNode.displayed,
|
|
2386
|
+
children: cell.children
|
|
2387
|
+
? cell.children.map((v) => mapFn(v, level ? level + 1 : 1))
|
|
2388
|
+
: undefined,
|
|
2389
|
+
};
|
|
2390
|
+
return inFilterValue;
|
|
2391
|
+
}
|
|
2392
|
+
return {
|
|
2393
|
+
value: gridCell.rawValue,
|
|
2394
|
+
label: gridCell.displayValue,
|
|
2395
|
+
};
|
|
2320
2396
|
};
|
|
2321
2397
|
// If there are custom distinct value, return them; otherwise return the Grids Cells just retrieved
|
|
2322
2398
|
const customInFilterValues = this.adaptableOptions.filterOptions.customInFilterValues;
|
|
@@ -2337,13 +2413,21 @@ You need to define at least one Layout!`);
|
|
|
2337
2413
|
label: gridCell.displayValue,
|
|
2338
2414
|
value: gridCell.rawValue,
|
|
2339
2415
|
isSelected: gridCell.rowNode.displayed,
|
|
2340
|
-
count: gridCell.count,
|
|
2416
|
+
count: gridCell.count ?? 0,
|
|
2341
2417
|
tooltip: false,
|
|
2418
|
+
level: 0,
|
|
2419
|
+
leafChildrenCount: gridCell.leafChildrenCount ?? 0,
|
|
2420
|
+
get children() {
|
|
2421
|
+
if (!gridCell.children) {
|
|
2422
|
+
return undefined;
|
|
2423
|
+
}
|
|
2424
|
+
return gridCell.children.map((gridCell) => mapFn(gridCell, 1));
|
|
2425
|
+
},
|
|
2342
2426
|
get visible() {
|
|
2343
2427
|
return gridCell.visible;
|
|
2344
2428
|
},
|
|
2345
2429
|
get visibleCount() {
|
|
2346
|
-
return gridCell.visibleCount;
|
|
2430
|
+
return gridCell.visibleCount ?? 0;
|
|
2347
2431
|
},
|
|
2348
2432
|
};
|
|
2349
2433
|
});
|
|
@@ -2355,13 +2439,21 @@ You need to define at least one Layout!`);
|
|
|
2355
2439
|
label: gridCell.displayValue,
|
|
2356
2440
|
value: gridCell.rawValue,
|
|
2357
2441
|
isSelected: gridCell.rowNode.displayed,
|
|
2358
|
-
count: gridCell.count,
|
|
2442
|
+
count: gridCell.count ?? 0,
|
|
2359
2443
|
tooltip: false,
|
|
2444
|
+
level: 0,
|
|
2445
|
+
leafChildrenCount: gridCell.leafChildrenCount ?? 0,
|
|
2446
|
+
get children() {
|
|
2447
|
+
if (!gridCell.children) {
|
|
2448
|
+
return undefined;
|
|
2449
|
+
}
|
|
2450
|
+
return gridCell.children.map((gridCell) => mapFn(gridCell, 1));
|
|
2451
|
+
},
|
|
2360
2452
|
get visible() {
|
|
2361
2453
|
return gridCell.visible;
|
|
2362
2454
|
},
|
|
2363
2455
|
get visibleCount() {
|
|
2364
|
-
return gridCell.visibleCount;
|
|
2456
|
+
return gridCell.visibleCount ?? 0;
|
|
2365
2457
|
},
|
|
2366
2458
|
};
|
|
2367
2459
|
});
|
|
@@ -2377,6 +2469,14 @@ You need to define at least one Layout!`);
|
|
|
2377
2469
|
isSelected: gridCell.rowNode.displayed,
|
|
2378
2470
|
count: gridCell.count,
|
|
2379
2471
|
tooltip: false,
|
|
2472
|
+
level: 0,
|
|
2473
|
+
get children() {
|
|
2474
|
+
if (!gridCell.children) {
|
|
2475
|
+
return undefined;
|
|
2476
|
+
}
|
|
2477
|
+
return gridCell.children.map((gridCell) => mapFn(gridCell, 1));
|
|
2478
|
+
},
|
|
2479
|
+
leafChildrenCount: gridCell.leafChildrenCount ?? 0,
|
|
2380
2480
|
get visible() {
|
|
2381
2481
|
return gridCell.visible;
|
|
2382
2482
|
},
|
|
@@ -2397,14 +2497,7 @@ You need to define at least one Layout!`);
|
|
|
2397
2497
|
}
|
|
2398
2498
|
return customInFilterValuesResult;
|
|
2399
2499
|
}
|
|
2400
|
-
|
|
2401
|
-
const values = getCurrentGridCells().map((gridCell) => {
|
|
2402
|
-
const inFilterValue = {
|
|
2403
|
-
value: gridCell.rawValue,
|
|
2404
|
-
label: gridCell.displayValue,
|
|
2405
|
-
};
|
|
2406
|
-
return inFilterValue;
|
|
2407
|
-
});
|
|
2500
|
+
const values = getCurrentGridCells().map((gridCell) => mapFn(gridCell));
|
|
2408
2501
|
return { values };
|
|
2409
2502
|
}
|
|
2410
2503
|
async getDistinctEditValuesForColumn(options) {
|
|
@@ -2454,6 +2547,218 @@ You need to define at least one Layout!`);
|
|
|
2454
2547
|
return result;
|
|
2455
2548
|
});
|
|
2456
2549
|
}
|
|
2550
|
+
getDistinctGridCellsForGroupedColumn(rowNodes) {
|
|
2551
|
+
const groupedColumns = this.api.columnApi.getRowGroupedColumns();
|
|
2552
|
+
const treeMode = this.api.gridApi.isTreeDataGrid();
|
|
2553
|
+
// if we're not in tree mode, return if there are no grouped columns
|
|
2554
|
+
// but in tree mode, we have to continue, even if there are no grouped columns
|
|
2555
|
+
if (!groupedColumns.length && !treeMode) {
|
|
2556
|
+
return [];
|
|
2557
|
+
}
|
|
2558
|
+
let prevLevel = -1;
|
|
2559
|
+
const currentGroupKey = [];
|
|
2560
|
+
const currentParentGridCells = [];
|
|
2561
|
+
const topLevelGridCells = [];
|
|
2562
|
+
const includeLeafNodes = treeMode || !!this.agGridAdapter.getAgGridApi().getColumnDef(AG_GRID_GROUPED_COLUMN)?.field;
|
|
2563
|
+
const rowNodeCallback = (rowNode) => {
|
|
2564
|
+
if (!rowNode.group && !includeLeafNodes) {
|
|
2565
|
+
return;
|
|
2566
|
+
}
|
|
2567
|
+
const level = rowNode.level;
|
|
2568
|
+
const key = rowNode.key;
|
|
2569
|
+
if (level <= prevLevel) {
|
|
2570
|
+
currentGroupKey.length = level;
|
|
2571
|
+
currentParentGridCells.length = level;
|
|
2572
|
+
}
|
|
2573
|
+
prevLevel = level;
|
|
2574
|
+
// for non-tree mode
|
|
2575
|
+
// or for tree mode, if the rowNode has data - so it's not a filler group
|
|
2576
|
+
if (!treeMode || (treeMode && rowNode.data)) {
|
|
2577
|
+
currentGroupKey.push(key);
|
|
2578
|
+
}
|
|
2579
|
+
const parentGridCell = currentParentGridCells[currentParentGridCells.length - 1];
|
|
2580
|
+
const gridCell = this.addDistinctColumnValue(rowNode, AG_GRID_GROUPED_COLUMN, false);
|
|
2581
|
+
// for tree-mode filler nodes, we might end up without a gridCell
|
|
2582
|
+
// so we need to make sure it's defined
|
|
2583
|
+
if (gridCell) {
|
|
2584
|
+
gridCell.leafChildrenCount = rowNode.allLeafChildren?.length ?? 0;
|
|
2585
|
+
currentParentGridCells.push(gridCell);
|
|
2586
|
+
if (parentGridCell) {
|
|
2587
|
+
parentGridCell.children = parentGridCell.children || [];
|
|
2588
|
+
parentGridCell.children.push(gridCell);
|
|
2589
|
+
}
|
|
2590
|
+
if (level === 0 && gridCell) {
|
|
2591
|
+
topLevelGridCells.push(gridCell);
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
};
|
|
2595
|
+
if (rowNodes) {
|
|
2596
|
+
rowNodes.forEach(rowNodeCallback);
|
|
2597
|
+
}
|
|
2598
|
+
else {
|
|
2599
|
+
this.agGridAdapter.getAgGridApi().forEachNode(rowNodeCallback);
|
|
2600
|
+
}
|
|
2601
|
+
const column = this.api.columnApi.getColumnWithColumnId(AG_GRID_GROUPED_COLUMN);
|
|
2602
|
+
return this.getUniqueGridCells(column, topLevelGridCells);
|
|
2603
|
+
}
|
|
2604
|
+
getDistinctGridCellsForDateColumn(column, rowNodes) {
|
|
2605
|
+
const topLevelGridCells = [];
|
|
2606
|
+
const treeDeepMap = new DeepMap();
|
|
2607
|
+
const isPivotResultColumn = column.isGeneratedPivotResultColumn;
|
|
2608
|
+
const includeTime = this.api.predicateApi.internalApi.shouldEvaluateInPredicateUsingTime(column.columnId);
|
|
2609
|
+
const colId = column.columnId;
|
|
2610
|
+
const rowNodeCallback = (rowNode) => {
|
|
2611
|
+
if (!rowNode) {
|
|
2612
|
+
return;
|
|
2613
|
+
}
|
|
2614
|
+
const initialCell = this.addDistinctColumnValue(rowNode, column.columnId, isPivotResultColumn);
|
|
2615
|
+
if (initialCell) {
|
|
2616
|
+
const value = initialCell.rawValue;
|
|
2617
|
+
// we want to filter out empty values
|
|
2618
|
+
if (value === '' || value === null || value === undefined) {
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
const dateInstance = parseDateValue(value);
|
|
2622
|
+
if (!(dateInstance instanceof Date)) {
|
|
2623
|
+
return;
|
|
2624
|
+
}
|
|
2625
|
+
const year = dateInstance.getFullYear();
|
|
2626
|
+
const month = dateInstance.getMonth() + 1;
|
|
2627
|
+
const day = dateInstance.getDate();
|
|
2628
|
+
const yearRawValue = `${year}`;
|
|
2629
|
+
const monthRawValue = `${year}-${`${month}`.padStart(2, '0')}`;
|
|
2630
|
+
const dayRawValue = `${monthRawValue}-${`${day}`.padStart(2, '0')}`;
|
|
2631
|
+
const yearCells = treeDeepMap.get([year]) || [];
|
|
2632
|
+
const yearCell = this.createGridCell(rowNode, colId, {
|
|
2633
|
+
rawValue: yearRawValue,
|
|
2634
|
+
displayValue: yearRawValue,
|
|
2635
|
+
normalisedValue: yearRawValue,
|
|
2636
|
+
});
|
|
2637
|
+
yearCells.push(yearCell);
|
|
2638
|
+
treeDeepMap.set([year], yearCells);
|
|
2639
|
+
const monthCells = treeDeepMap.get([year, month]) || [];
|
|
2640
|
+
const monthCell = this.createGridCell(rowNode, colId, {
|
|
2641
|
+
rawValue: monthRawValue,
|
|
2642
|
+
displayValue: DateFormatter(`${monthRawValue}-01`, { Pattern: 'LLLL' }),
|
|
2643
|
+
normalisedValue: monthRawValue,
|
|
2644
|
+
});
|
|
2645
|
+
monthCells.push(monthCell);
|
|
2646
|
+
treeDeepMap.set([year, month], monthCells);
|
|
2647
|
+
const dayCells = treeDeepMap.get([year, month, day]) || [];
|
|
2648
|
+
const dayCell = this.createGridCell(rowNode, colId, {
|
|
2649
|
+
rawValue: dayRawValue,
|
|
2650
|
+
displayValue: `${day}`.padStart(2, '0'),
|
|
2651
|
+
normalisedValue: dayRawValue,
|
|
2652
|
+
});
|
|
2653
|
+
dayCells.push(dayCell);
|
|
2654
|
+
treeDeepMap.set([year, month, day], dayCells);
|
|
2655
|
+
if (includeTime) {
|
|
2656
|
+
const timeCells = treeDeepMap.get([year, month, day, dateInstance.getTime()]) || [];
|
|
2657
|
+
// if the value is a string, let's use it as the final raw value
|
|
2658
|
+
const timeRawValue = typeof value === 'string' ? value : `${dateInstance.toISOString()}`;
|
|
2659
|
+
let timeDisplayValue = typeof value === 'string'
|
|
2660
|
+
? value
|
|
2661
|
+
: [dateInstance.getHours(), dateInstance.getMinutes(), dateInstance.getSeconds()]
|
|
2662
|
+
.map((v) => `${v}`.padStart(2, '0'))
|
|
2663
|
+
.join(':')
|
|
2664
|
+
.concat(dateInstance.getMilliseconds()
|
|
2665
|
+
? `.${dateInstance.getMilliseconds().toString().padStart(3, '0')}`
|
|
2666
|
+
: '');
|
|
2667
|
+
const timeCell = this.createGridCell(rowNode, colId, {
|
|
2668
|
+
rawValue: timeRawValue,
|
|
2669
|
+
displayValue: timeDisplayValue,
|
|
2670
|
+
normalisedValue: timeRawValue,
|
|
2671
|
+
});
|
|
2672
|
+
timeCells.push(timeCell);
|
|
2673
|
+
treeDeepMap.set([year, month, day, dateInstance.getTime()], timeCells);
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
};
|
|
2677
|
+
if (rowNodes) {
|
|
2678
|
+
rowNodes.forEach(rowNodeCallback);
|
|
2679
|
+
}
|
|
2680
|
+
else {
|
|
2681
|
+
this.agGridAdapter.getAgGridApi().forEachNode(rowNodeCallback);
|
|
2682
|
+
}
|
|
2683
|
+
const years = treeDeepMap.getKeysStartingWith([], {
|
|
2684
|
+
excludeSelf: true,
|
|
2685
|
+
depthLimit: 1,
|
|
2686
|
+
});
|
|
2687
|
+
for (const keys of years) {
|
|
2688
|
+
const [year] = keys;
|
|
2689
|
+
const yearCells = treeDeepMap.get([year]) || [];
|
|
2690
|
+
// should only be one item in the uniqueYearCells array
|
|
2691
|
+
const uniqueYearCell = this.getUniqueGridCells(column, yearCells)[0];
|
|
2692
|
+
if (!uniqueYearCell) {
|
|
2693
|
+
continue;
|
|
2694
|
+
}
|
|
2695
|
+
uniqueYearCell.children = [];
|
|
2696
|
+
topLevelGridCells.push(uniqueYearCell);
|
|
2697
|
+
const keysForYear = treeDeepMap.getKeysStartingWith([year], {
|
|
2698
|
+
depthLimit: 1,
|
|
2699
|
+
excludeSelf: true,
|
|
2700
|
+
});
|
|
2701
|
+
for (const keys of keysForYear) {
|
|
2702
|
+
const [_, month] = keys;
|
|
2703
|
+
const monthCells = treeDeepMap.get([year, month]) || [];
|
|
2704
|
+
const uniqueMonthCell = this.getUniqueGridCells(column, monthCells)[0];
|
|
2705
|
+
if (!uniqueMonthCell) {
|
|
2706
|
+
continue;
|
|
2707
|
+
}
|
|
2708
|
+
uniqueMonthCell.children = [];
|
|
2709
|
+
uniqueYearCell.children.push(uniqueMonthCell);
|
|
2710
|
+
// those are all the days for which there are values in this year/month
|
|
2711
|
+
const keysForMonth = treeDeepMap.getKeysStartingWith([year, month], {
|
|
2712
|
+
depthLimit: 1,
|
|
2713
|
+
excludeSelf: true,
|
|
2714
|
+
});
|
|
2715
|
+
for (const keys of keysForMonth) {
|
|
2716
|
+
const [_, __, day] = keys;
|
|
2717
|
+
const dayCells = treeDeepMap.get([year, month, day]) || [];
|
|
2718
|
+
const uniqueDayCell = this.getUniqueGridCells(column, dayCells)[0];
|
|
2719
|
+
if (!uniqueDayCell) {
|
|
2720
|
+
continue;
|
|
2721
|
+
}
|
|
2722
|
+
uniqueMonthCell.children.push(uniqueDayCell);
|
|
2723
|
+
if (includeTime) {
|
|
2724
|
+
uniqueDayCell.children = [];
|
|
2725
|
+
const keysForDay = treeDeepMap.getKeysStartingWith([year, month, day], {
|
|
2726
|
+
depthLimit: 1,
|
|
2727
|
+
excludeSelf: true,
|
|
2728
|
+
});
|
|
2729
|
+
for (const keys of keysForDay) {
|
|
2730
|
+
const [_, __, ___, time] = keys;
|
|
2731
|
+
const timeCells = treeDeepMap.get([year, month, day, time]) || [];
|
|
2732
|
+
const uniqueTimeCell = this.getUniqueGridCells(column, timeCells)[0];
|
|
2733
|
+
if (!uniqueTimeCell) {
|
|
2734
|
+
continue;
|
|
2735
|
+
}
|
|
2736
|
+
uniqueDayCell.children.push(uniqueTimeCell);
|
|
2737
|
+
}
|
|
2738
|
+
uniqueDayCell.leafChildrenCount =
|
|
2739
|
+
treeDeepMap.getKeysForLeafNodesStartingWith([year, month, day]).length;
|
|
2740
|
+
uniqueDayCell.children.sort((dayCell1, dayCell2) => {
|
|
2741
|
+
return dayCell1.rawValue.localeCompare(dayCell2.rawValue);
|
|
2742
|
+
});
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
uniqueMonthCell.leafChildrenCount =
|
|
2746
|
+
treeDeepMap.getKeysForLeafNodesStartingWith([year, month]).length;
|
|
2747
|
+
uniqueMonthCell.children.sort((monthCell1, monthCell2) => {
|
|
2748
|
+
return monthCell1.rawValue.localeCompare(monthCell2.rawValue);
|
|
2749
|
+
});
|
|
2750
|
+
}
|
|
2751
|
+
uniqueYearCell.leafChildrenCount =
|
|
2752
|
+
treeDeepMap.getKeysForLeafNodesStartingWith([year]).length;
|
|
2753
|
+
uniqueYearCell.children.sort((monthCell1, monthCell2) => {
|
|
2754
|
+
return monthCell1.rawValue.localeCompare(monthCell2.rawValue);
|
|
2755
|
+
});
|
|
2756
|
+
}
|
|
2757
|
+
topLevelGridCells.sort((yearCell1, yearCell2) => {
|
|
2758
|
+
return yearCell1.rawValue.localeCompare(yearCell2.rawValue);
|
|
2759
|
+
});
|
|
2760
|
+
return topLevelGridCells;
|
|
2761
|
+
}
|
|
2457
2762
|
getDistinctGridCellsForColumn(column, rowNodes) {
|
|
2458
2763
|
let gridCells = [];
|
|
2459
2764
|
const isPivotResultColumn = column.isGeneratedPivotResultColumn;
|
|
@@ -2490,10 +2795,17 @@ You need to define at least one Layout!`);
|
|
|
2490
2795
|
// see https://www.ag-grid.com/javascript-data-grid/tree-data-paths/#filler-groups
|
|
2491
2796
|
return;
|
|
2492
2797
|
}
|
|
2798
|
+
// if (columnId !== AG_GRID_GROUPED_COLUMN) {
|
|
2799
|
+
// return;
|
|
2800
|
+
// }
|
|
2801
|
+
return this.getGridCellFromRowNode(rowNode, columnId);
|
|
2493
2802
|
}
|
|
2494
2803
|
else {
|
|
2495
2804
|
// for normal Table Columns we do NOT return the values of the aggregates
|
|
2496
|
-
|
|
2805
|
+
if (columnId !== AG_GRID_GROUPED_COLUMN) {
|
|
2806
|
+
return;
|
|
2807
|
+
}
|
|
2808
|
+
return this.getGridCellFromRowNode(rowNode, columnId);
|
|
2497
2809
|
}
|
|
2498
2810
|
}
|
|
2499
2811
|
if (isPivotResultColumn) {
|
|
@@ -2507,14 +2819,12 @@ You need to define at least one Layout!`);
|
|
|
2507
2819
|
}
|
|
2508
2820
|
}
|
|
2509
2821
|
const returnValue = this.getGridCellFromRowNode(rowNode, columnId);
|
|
2510
|
-
|
|
2511
|
-
return returnValue;
|
|
2512
|
-
}
|
|
2822
|
+
return returnValue;
|
|
2513
2823
|
}
|
|
2514
2824
|
getUniqueGridCells(column, gridCells) {
|
|
2515
2825
|
let gridCellsToUse = gridCells;
|
|
2516
2826
|
const cache = new Map();
|
|
2517
|
-
const lowercase = this.api.predicateApi.useCaseSensitivity();
|
|
2827
|
+
const lowercase = this.api.predicateApi.useCaseSensitivity(column.columnId);
|
|
2518
2828
|
const getter = (dataItem) => {
|
|
2519
2829
|
let value = dataItem.rawValue;
|
|
2520
2830
|
if (value instanceof Date) {
|
|
@@ -3260,6 +3570,7 @@ You need to define at least one Layout!`);
|
|
|
3260
3570
|
const prevLayout = this._prevLayout;
|
|
3261
3571
|
this._prevLayout = layout;
|
|
3262
3572
|
const perfSetLayout = this.logger.beginPerf(`setLayout(${layout.Name})`);
|
|
3573
|
+
const setLayoutMarker = getMarker(this.adaptableOptions.adaptableId).track.Runtime.label.SetLayout.start();
|
|
3263
3574
|
const isPivot = isPivotLayout(layout);
|
|
3264
3575
|
// update the header name for all columns
|
|
3265
3576
|
this.agGridAdapter
|
|
@@ -3311,6 +3622,22 @@ You need to define at least one Layout!`);
|
|
|
3311
3622
|
}
|
|
3312
3623
|
});
|
|
3313
3624
|
perfSetLayout.end();
|
|
3625
|
+
setLayoutMarker.end({
|
|
3626
|
+
details: [
|
|
3627
|
+
{
|
|
3628
|
+
name: 'Layout name',
|
|
3629
|
+
value: layout.Name,
|
|
3630
|
+
},
|
|
3631
|
+
{
|
|
3632
|
+
name: 'Type',
|
|
3633
|
+
value: isPivot ? 'Pivot' : 'Table',
|
|
3634
|
+
},
|
|
3635
|
+
{
|
|
3636
|
+
name: isPivot ? 'Pivot Columns' : 'Table Columns',
|
|
3637
|
+
value: isPivot ? layout.PivotColumns.join(', ') : layout.TableColumns.join(', '),
|
|
3638
|
+
},
|
|
3639
|
+
],
|
|
3640
|
+
});
|
|
3314
3641
|
}
|
|
3315
3642
|
getActiveAdaptableAggFuncForCol(columnId) {
|
|
3316
3643
|
if (!columnId) {
|
|
@@ -3619,7 +3946,7 @@ You need to define at least one Layout!`);
|
|
|
3619
3946
|
return hasPivotTotals(one) || hasPivotTotals(other);
|
|
3620
3947
|
}
|
|
3621
3948
|
onLayoutChange(layout) {
|
|
3622
|
-
this.refreshAdaptableAfterLayoutChange(layout);
|
|
3949
|
+
layout = this.refreshAdaptableAfterLayoutChange(layout);
|
|
3623
3950
|
this.api.layoutApi.createOrUpdateLayout(layout);
|
|
3624
3951
|
}
|
|
3625
3952
|
refreshAdaptableAfterLayoutChange(layout) {
|
|
@@ -3627,6 +3954,15 @@ You need to define at least one Layout!`);
|
|
|
3627
3954
|
const prevLayoutForRefresh = this.__prevLayoutForRefresh || this.api.layoutApi.getCurrentLayout();
|
|
3628
3955
|
// see #on-regroup-expect-group-column-to-be-recomputed-and-setup-properly
|
|
3629
3956
|
const rowGroupsChanged = this.isRowGroupDifferentInLayout(prevLayoutForRefresh, layout);
|
|
3957
|
+
// when grouping changes, if we have a filter on the grouped column, we need to remove it
|
|
3958
|
+
// as it is no longer valid
|
|
3959
|
+
if (rowGroupsChanged && layout.ColumnFilters) {
|
|
3960
|
+
const newFilters = layout.ColumnFilters.filter((filter) => filter.ColumnId !== AG_GRID_GROUPED_COLUMN);
|
|
3961
|
+
if (newFilters.length != layout.ColumnFilters.length) {
|
|
3962
|
+
layout = { ...layout };
|
|
3963
|
+
layout.ColumnFilters = newFilters;
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3630
3966
|
const hasPivotTotalsInLayout = this.hasPivotTotalsInLayout(prevLayoutForRefresh, layout);
|
|
3631
3967
|
const pivotColsChanged = JSON.stringify(layout.PivotColumns) !== JSON.stringify(prevLayoutForRefresh.PivotColumns);
|
|
3632
3968
|
if (rowGroupsChanged || pivotColsChanged || hasPivotTotalsInLayout) {
|
|
@@ -3636,6 +3972,7 @@ You need to define at least one Layout!`);
|
|
|
3636
3972
|
this.deriveAdaptableColumnStateFromAgGrid();
|
|
3637
3973
|
}
|
|
3638
3974
|
this.__prevLayoutForRefresh = layout;
|
|
3975
|
+
return layout;
|
|
3639
3976
|
}
|
|
3640
3977
|
validateColumnDefTypes(columnDefs) {
|
|
3641
3978
|
// in Adaptable version 20 we switched from colDef.type to colDef.cellDataType
|
|
@@ -2,12 +2,14 @@ import { DoesFilterPassParams, FilterHandler, FilterHandlerParams } from 'ag-gri
|
|
|
2
2
|
import { AdaptableApi } from '../Api/AdaptableApi';
|
|
3
3
|
import { ColumnSetupInfo } from '../AdaptableState/Common/ColumnSetupInfo';
|
|
4
4
|
import { InFilterValueResult } from '../AdaptableOptions/FilterOptions';
|
|
5
|
+
import { ColumnFilter } from '../types';
|
|
5
6
|
export declare class AdaptableFilterHandler implements FilterHandler {
|
|
6
7
|
private adaptableApi;
|
|
7
8
|
readonly colId: string;
|
|
8
9
|
private filterDisplayValuesResult;
|
|
9
10
|
private previousFilterDisplayValuesResult;
|
|
10
11
|
constructor(adaptableApi: AdaptableApi, columnSetup: ColumnSetupInfo);
|
|
12
|
+
getCurrentColumnFilters(): ColumnFilter[];
|
|
11
13
|
doesFilterPass(params: DoesFilterPassParams): boolean;
|
|
12
14
|
getCachedFilterDisplayValues(): InFilterValueResult | undefined;
|
|
13
15
|
getLastCachedFilterDisplayValues(): InFilterValueResult | undefined;
|
|
@@ -21,6 +23,6 @@ export declare class AdaptableFilterHandler implements FilterHandler {
|
|
|
21
23
|
onAnyFilterChanged(): void;
|
|
22
24
|
resetFilterDisplayValues(): void;
|
|
23
25
|
refreshFilterDisplayValues(): Promise<InFilterValueResult>;
|
|
24
|
-
refresh(
|
|
26
|
+
refresh(_params: FilterHandlerParams<any, any, any, any>): void;
|
|
25
27
|
destroy(): void;
|
|
26
28
|
}
|
|
@@ -3,6 +3,17 @@ export class AdaptableFilterHandler {
|
|
|
3
3
|
this.adaptableApi = adaptableApi;
|
|
4
4
|
this.colId = columnSetup.colId;
|
|
5
5
|
}
|
|
6
|
+
getCurrentColumnFilters() {
|
|
7
|
+
const columnFilters = this.adaptableApi.filterApi.columnFilterApi
|
|
8
|
+
.getActiveColumnFilters()
|
|
9
|
+
.filter((columnFilter) => this.adaptableApi.filterApi.columnFilterApi.isColumnFilterActive(columnFilter))
|
|
10
|
+
.filter((columnFilter) => columnFilter.ColumnId === this.colId)
|
|
11
|
+
.filter((columnFilter) => {
|
|
12
|
+
const shouldEvaluateFilterOnClient = this.adaptableApi.expressionApi.internalApi.shouldEvaluatePredicatesInAdaptableQL('ColumnFilter', columnFilter, columnFilter.Predicates);
|
|
13
|
+
return shouldEvaluateFilterOnClient;
|
|
14
|
+
});
|
|
15
|
+
return columnFilters;
|
|
16
|
+
}
|
|
6
17
|
doesFilterPass(params) {
|
|
7
18
|
try {
|
|
8
19
|
const rowNode = params.node;
|
|
@@ -11,15 +22,11 @@ export class AdaptableFilterHandler {
|
|
|
11
22
|
if (!isRowFilterable) {
|
|
12
23
|
return true;
|
|
13
24
|
}
|
|
14
|
-
const columnFilters = this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
.filter((columnFilter) => {
|
|
19
|
-
const shouldEvaluateFilterOnClient = this.adaptableApi.expressionApi.internalApi.shouldEvaluatePredicatesInAdaptableQL('ColumnFilter', columnFilter, columnFilter.Predicates);
|
|
20
|
-
return shouldEvaluateFilterOnClient;
|
|
25
|
+
const columnFilters = this.getCurrentColumnFilters();
|
|
26
|
+
const anyFilterFailed = columnFilters.some((columnFilter) => {
|
|
27
|
+
const result = !this.adaptableApi.filterApi.columnFilterApi.internalApi.evaluateColumnFilter(columnFilter, rowNode);
|
|
28
|
+
return result;
|
|
21
29
|
});
|
|
22
|
-
const anyFilterFailed = columnFilters.some((columnFilter) => !this.adaptableApi.filterApi.columnFilterApi.internalApi.evaluateColumnFilter(columnFilter, rowNode));
|
|
23
30
|
return anyFilterFailed ? false : true;
|
|
24
31
|
}
|
|
25
32
|
catch (ex) {
|
|
@@ -77,10 +84,7 @@ export class AdaptableFilterHandler {
|
|
|
77
84
|
this.resetFilterDisplayValues();
|
|
78
85
|
return this.getFromCacheOrFetchFilterDisplayValues({ currentSearchValue: '' });
|
|
79
86
|
}
|
|
80
|
-
refresh(
|
|
81
|
-
// No specific refresh logic needed for this handler
|
|
82
|
-
// The filter display values will be reset on new rows loaded or any filter changed
|
|
83
|
-
}
|
|
87
|
+
refresh(_params) { }
|
|
84
88
|
destroy() {
|
|
85
89
|
this.filterDisplayValuesResult = undefined;
|
|
86
90
|
this.previousFilterDisplayValuesResult = undefined;
|