@adaptabletools/adaptable 23.1.0-canary.0 → 23.1.0-canary.2
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 +3 -3
- package/src/AdaptableInterfaces/IAdaptable.d.ts +36 -1
- package/src/Api/Internal/FormatColumnInternalApi.d.ts +12 -2
- package/src/Api/Internal/FormatColumnInternalApi.js +4 -0
- package/src/Api/Internal/GridInternalApi.js +3 -1
- package/src/Redux/Store/AdaptableStore.js +15 -6
- package/src/Strategy/LayoutModule.js +4 -1
- package/src/agGrid/AdaptableAgGrid.d.ts +41 -4
- package/src/agGrid/AdaptableAgGrid.js +66 -12
- package/src/agGrid/AgGridAdapter.d.ts +1 -0
- package/src/agGrid/AgGridAdapter.js +3 -42
- package/src/agGrid/AgGridColumnAdapter.d.ts +24 -1
- package/src/agGrid/AgGridColumnAdapter.js +38 -36
- package/src/agGrid/gridRefreshScope.d.ts +20 -0
- package/src/agGrid/gridRefreshScope.js +39 -0
- package/src/devTools/DevToolsTracks.d.ts +6 -0
- package/src/devTools/DevToolsTracks.js +6 -0
- package/src/devTools/index.d.ts +25 -1
- package/src/env.js +2 -2
- package/src/parser/src/types.d.ts +3 -1
- package/tsconfig.esm.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptabletools/adaptable",
|
|
3
|
-
"version": "23.1.0-canary.
|
|
3
|
+
"version": "23.1.0-canary.2",
|
|
4
4
|
"description": "Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web-components",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"uuid": "9.0.1"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"ag-grid-enterprise": ">=36.
|
|
72
|
-
"ag-stack": ">=36.
|
|
71
|
+
"ag-grid-enterprise": ">=36.2.0",
|
|
72
|
+
"ag-stack": ">=36.2.0"
|
|
73
73
|
},
|
|
74
74
|
"publishTimestamp": 0,
|
|
75
75
|
"type": "module",
|
|
@@ -48,6 +48,36 @@ export interface AgGridConfig {
|
|
|
48
48
|
modules: Module[];
|
|
49
49
|
}
|
|
50
50
|
export type AdaptableVariant = 'vanilla' | 'react' | 'angular' | 'vue';
|
|
51
|
+
/**
|
|
52
|
+
* #narrow_column_model_refresh
|
|
53
|
+
*
|
|
54
|
+
* What has to be refreshed in AG Grid after a column-model pass (`updateColumnModelAndRefreshGrid()`),
|
|
55
|
+
* ie. after `setupColumns()` re-installed the Adaptable colDef callbacks.
|
|
56
|
+
*
|
|
57
|
+
* Whatever changed in a colDef VALUE (eg. a new `cellRenderer`, `comparator` or `valueFormatter`) is
|
|
58
|
+
* already taken care of by AG Grid: `AgColumn.setColDef()` (see #col_def_commit) force-refreshes the
|
|
59
|
+
* rendered cells and header of the changed column. The scope only has to cover state read by the
|
|
60
|
+
* #stable_col_def_callbacks at render time, which AG Grid cannot know about.
|
|
61
|
+
*/
|
|
62
|
+
export interface GridRefreshScope {
|
|
63
|
+
/**
|
|
64
|
+
* Destroy & recreate the rendered rows (`redrawRows()`).
|
|
65
|
+
* Only needed when a ROW-level definition may have changed: `getRowStyle` / `getRowClass` (Alert row
|
|
66
|
+
* highlights), row height, full-width rows. Cancels cell editing; implies `cells`.
|
|
67
|
+
*/
|
|
68
|
+
rows?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Re-run the cell-level callbacks (`cellStyle`, `cellClass`, `valueFormatter`, `cellRenderer` params)
|
|
71
|
+
* on the rendered cells (`refreshCells({ force: true })`). Keeps focus, selection and in-progress edits.
|
|
72
|
+
*/
|
|
73
|
+
cells?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Recreate the header cells (`refreshHeader()`).
|
|
76
|
+
* Only needed when a header-level callback (`headerStyle` / `headerClass` / `headerValueGetter`) reads
|
|
77
|
+
* state that changed, ie. Format Columns targeting the column header.
|
|
78
|
+
*/
|
|
79
|
+
header?: boolean;
|
|
80
|
+
}
|
|
51
81
|
/**
|
|
52
82
|
* The only interface for Adaptable
|
|
53
83
|
*
|
|
@@ -280,7 +310,12 @@ export interface IAdaptable {
|
|
|
280
310
|
expandRowGroupsForValues(columnValues: any[]): void;
|
|
281
311
|
getAdaptableContainerElement(): HTMLElement | null;
|
|
282
312
|
getAgGridContainerElement(): HTMLElement | null;
|
|
283
|
-
|
|
313
|
+
/**
|
|
314
|
+
* Re-derives the Adaptable column state, sets up all columns again and refreshes AG Grid.
|
|
315
|
+
* @param refreshScope what to refresh after the columns were set up (see #narrow_column_model_refresh);
|
|
316
|
+
* defaults to a full refresh (rows + header)
|
|
317
|
+
*/
|
|
318
|
+
updateColumnModelAndRefreshGrid(refreshScope?: GridRefreshScope): void;
|
|
284
319
|
refreshSortIfColumnsSorted(): void;
|
|
285
320
|
getAgGridColumnForColumnId(columnId: string): Column;
|
|
286
321
|
getMinMaxCachedValueForColumn(column: AdaptableColumn, aggregation: 'min' | 'max' | 'avg' | 'median'): number | undefined;
|
|
@@ -7,6 +7,13 @@ export declare class FormatColumnInternalApi extends ApiBase {
|
|
|
7
7
|
* Column-model update alone can leave visible cells stale until scroll.
|
|
8
8
|
*/
|
|
9
9
|
refreshFormatColumnPresentation(formatColumns: FormatColumn | FormatColumn[] | undefined): void;
|
|
10
|
+
/**
|
|
11
|
+
* see #narrow_column_model_refresh
|
|
12
|
+
* Whether ANY Format Column in state (suspended or not, in any layout) targets the column header -
|
|
13
|
+
* ie. whether the `headerStyle` / `headerClass` / header name callbacks read Format Column state at all.
|
|
14
|
+
* When none does, a Format Column change cannot alter the rendered header, so it does not have to be refreshed.
|
|
15
|
+
*/
|
|
16
|
+
hasFormatColumnsTargetingHeader(): boolean;
|
|
10
17
|
/**
|
|
11
18
|
* Retrieves all Format Columns in Adaptable State with the `Style` property set
|
|
12
19
|
* @returns format columns
|
|
@@ -83,8 +90,11 @@ export declare class FormatColumnInternalApi extends ApiBase {
|
|
|
83
90
|
* Checks if format column is relevant for a given cell (intersection of given AdaptableColumn and RowNode)
|
|
84
91
|
*
|
|
85
92
|
* @param formatColumn
|
|
86
|
-
* @param column
|
|
87
|
-
* @param
|
|
93
|
+
* @param column - the column the Format Column is scoped to
|
|
94
|
+
* @param rowNode
|
|
95
|
+
* @param cellValue
|
|
96
|
+
* @param pivotResultColumn - set when the cell belongs to a pivot result column, so that a Rule Expression
|
|
97
|
+
* written against the base column reads the pivot result cell value (see #derived_pivot_cell_style)
|
|
88
98
|
*/
|
|
89
99
|
formatColumnShouldRenderInCell(formatColumn: FormatColumn, column: AdaptableColumn, rowNode: IRowNode, cellValue: any, pivotResultColumn?: Column): boolean;
|
|
90
100
|
/**
|
|
@@ -49,6 +49,10 @@ export class FormatColumnInternalApi extends ApiBase {
|
|
|
49
49
|
this.getGridApi().refreshColumns([...columnIds]);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
hasFormatColumnsTargetingHeader() {
|
|
53
|
+
const headerTarget = 'columnHeader';
|
|
54
|
+
return (this.getFormatColumnApi().getFormatColumnState()?.FormatColumns ?? []).some((formatColumn) => formatColumn?.Target === headerTarget);
|
|
55
|
+
}
|
|
52
56
|
getAllFormatColumnWithStyle(config) {
|
|
53
57
|
return this.getFormatColumnApi()
|
|
54
58
|
.getFormatColumns(config)
|
|
@@ -205,7 +205,9 @@ export class GridInternalApi extends ApiBase {
|
|
|
205
205
|
Aggregatable: defaultColumnDefinition.enableValue,
|
|
206
206
|
SuppressMenu: defaultColumnDefinition.suppressHeaderMenuButton,
|
|
207
207
|
SuppressMovable: defaultColumnDefinition.suppressMovable,
|
|
208
|
-
HeaderToolTip: defaultColumnDefinition.headerTooltip
|
|
208
|
+
HeaderToolTip: typeof defaultColumnDefinition.headerTooltip === 'string'
|
|
209
|
+
? defaultColumnDefinition.headerTooltip
|
|
210
|
+
: undefined,
|
|
209
211
|
Width: defaultColumnDefinition.width,
|
|
210
212
|
};
|
|
211
213
|
}
|
|
@@ -464,7 +464,7 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
464
464
|
}
|
|
465
465
|
});
|
|
466
466
|
}
|
|
467
|
-
adaptable.updateColumnModelAndRefreshGrid();
|
|
467
|
+
adaptable.updateColumnModelAndRefreshGrid({ rows: true });
|
|
468
468
|
let module = (adaptable.adaptableModules.get(ModuleConstants.AlertModuleId));
|
|
469
469
|
if (module) {
|
|
470
470
|
module.checkListenToCellDataChanged();
|
|
@@ -480,7 +480,7 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
480
480
|
case FlashingCellRedux.FLASHING_CELL_DEFINITION_UNSUSPEND_ALL:
|
|
481
481
|
case FlashingCellRedux.FLASHING_CELL_DEFINITION_SUSPEND_ALL: {
|
|
482
482
|
const returnAction = next(action);
|
|
483
|
-
adaptable.updateColumnModelAndRefreshGrid();
|
|
483
|
+
adaptable.updateColumnModelAndRefreshGrid({ cells: true });
|
|
484
484
|
let module = (adaptable.adaptableModules.get(ModuleConstants.FlashingCellModuleId));
|
|
485
485
|
if (module) {
|
|
486
486
|
module.checkListenToCellDataChanged();
|
|
@@ -542,7 +542,7 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
542
542
|
if (StringExtensions.IsNotNullOrEmpty(adaptable.api.quickSearchApi.getQuickSearchValue())) {
|
|
543
543
|
adaptable.refreshAgGridFind();
|
|
544
544
|
}
|
|
545
|
-
adaptable.updateColumnModelAndRefreshGrid();
|
|
545
|
+
adaptable.updateColumnModelAndRefreshGrid({ cells: true });
|
|
546
546
|
return returnAction;
|
|
547
547
|
}
|
|
548
548
|
case FormatColumnRedux.FORMAT_COLUMN_ADD_BATCH:
|
|
@@ -555,7 +555,16 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
555
555
|
case FormatColumnRedux.FORMAT_COLUMN_SUSPEND:
|
|
556
556
|
case FormatColumnRedux.FORMAT_COLUMN_UNSUSPEND:
|
|
557
557
|
case FormatColumnRedux.FORMAT_COLUMN_SUSPEND_ALL:
|
|
558
|
-
case FormatColumnRedux.FORMAT_COLUMN_UNSUSPEND_ALL:
|
|
558
|
+
case FormatColumnRedux.FORMAT_COLUMN_UNSUSPEND_ALL: {
|
|
559
|
+
const hadHeaderFormatColumns = adaptable.api.formatColumnApi.internalApi.hasFormatColumnsTargetingHeader();
|
|
560
|
+
const returnAction = next(action);
|
|
561
|
+
const hasHeaderFormatColumns = adaptable.api.formatColumnApi.internalApi.hasFormatColumnsTargetingHeader();
|
|
562
|
+
adaptable.updateColumnModelAndRefreshGrid({
|
|
563
|
+
cells: true,
|
|
564
|
+
header: hadHeaderFormatColumns || hasHeaderFormatColumns,
|
|
565
|
+
});
|
|
566
|
+
return returnAction;
|
|
567
|
+
}
|
|
559
568
|
case StyledColumnRedux.STYLED_COLUMN_ADD:
|
|
560
569
|
case StyledColumnRedux.STYLED_COLUMN_EDIT:
|
|
561
570
|
case StyledColumnRedux.STYLED_COLUMN_DELETE:
|
|
@@ -564,7 +573,7 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
564
573
|
case StyledColumnRedux.STYLED_COLUMN_SUSPEND_ALL:
|
|
565
574
|
case StyledColumnRedux.STYLED_COLUMN_UNSUSPEND_ALL: {
|
|
566
575
|
const returnAction = next(action);
|
|
567
|
-
adaptable.updateColumnModelAndRefreshGrid();
|
|
576
|
+
adaptable.updateColumnModelAndRefreshGrid({ cells: true });
|
|
568
577
|
return returnAction;
|
|
569
578
|
}
|
|
570
579
|
case CustomSortRedux.CUSTOM_SORT_ADD:
|
|
@@ -575,7 +584,7 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
575
584
|
case CustomSortRedux.CUSTOM_SORT_SUSPEND_ALL:
|
|
576
585
|
case CustomSortRedux.CUSTOM_SORT_UNSUSPEND_ALL: {
|
|
577
586
|
const returnAction = next(action);
|
|
578
|
-
adaptable.updateColumnModelAndRefreshGrid();
|
|
587
|
+
adaptable.updateColumnModelAndRefreshGrid({});
|
|
579
588
|
adaptable.refreshSortIfColumnsSorted();
|
|
580
589
|
return returnAction;
|
|
581
590
|
}
|
|
@@ -361,7 +361,10 @@ export class LayoutModule extends AdaptableModuleBase {
|
|
|
361
361
|
.getModuleService()
|
|
362
362
|
.getModuleById('Shortcut')
|
|
363
363
|
.checkListenToKeyDown();
|
|
364
|
-
this.api.internalApi.getAdaptableInstance().updateColumnModelAndRefreshGrid(
|
|
364
|
+
this.api.internalApi.getAdaptableInstance().updateColumnModelAndRefreshGrid({
|
|
365
|
+
cells: true,
|
|
366
|
+
header: this.api.formatColumnApi.internalApi.hasFormatColumnsTargetingHeader(),
|
|
367
|
+
});
|
|
365
368
|
}
|
|
366
369
|
getReferencedNamedQueryNames(layout) {
|
|
367
370
|
if (!layout.GridFilter?.Expression) {
|
|
@@ -2,7 +2,7 @@ import { AdaptableOptions } from '../AdaptableOptions/AdaptableOptions';
|
|
|
2
2
|
import { ChartRef, Column, GridApi, GridOptions, IRowNode, Module, RowModelType, StatusPanelDef } from 'ag-grid-enterprise';
|
|
3
3
|
import { AdaptableLogger } from './AdaptableLogger';
|
|
4
4
|
import { AdaptableApi, DestroyConfig } from '../Api/AdaptableApi';
|
|
5
|
-
import { AdaptableVariant, IAdaptable, NormalizeAdaptableStateOptions } from '../AdaptableInterfaces/IAdaptable';
|
|
5
|
+
import { AdaptableVariant, GridRefreshScope, IAdaptable, NormalizeAdaptableStateOptions } from '../AdaptableInterfaces/IAdaptable';
|
|
6
6
|
import { EmitterCallback } from '../Utilities/Emitter';
|
|
7
7
|
import { AdaptablePlugin } from '../AdaptableOptions/AdaptablePlugin';
|
|
8
8
|
import { AgGridAdapter, RowNodeEvent } from './AgGridAdapter';
|
|
@@ -247,10 +247,47 @@ export declare class AdaptableAgGrid implements IAdaptable {
|
|
|
247
247
|
getDisplayValueFromRawValue(rowNode: IRowNode, columnId: string, rawValue: any): string | undefined;
|
|
248
248
|
private getCleanValue;
|
|
249
249
|
getNormalisedValueFromRawValue(rawValue: any, column: AdaptableColumn): string | number | boolean | Date | unknown;
|
|
250
|
-
|
|
250
|
+
/**
|
|
251
|
+
* The refresh scope already applied by a column-model pass in the current microtask window
|
|
252
|
+
* (`null` when no pass ran yet), see `updateColumnModelAndRefreshGrid`.
|
|
253
|
+
*/
|
|
254
|
+
private __columnModelRefreshDoneInThisTick;
|
|
251
255
|
private __forceUpdateColumnModel;
|
|
252
|
-
|
|
253
|
-
|
|
256
|
+
/**
|
|
257
|
+
* #narrow_column_model_refresh
|
|
258
|
+
*
|
|
259
|
+
* Runs the column-model pass at most once per microtask window: the first call runs it synchronously
|
|
260
|
+
* with the requested refresh scope; a later call in the same window does NOT set up the columns again
|
|
261
|
+
* (the #stable_col_def_callbacks read live state anyway) but still gets any refresh it asks for that
|
|
262
|
+
* the first call did not perform - eg a cells-only pass followed by a request for a row redraw.
|
|
263
|
+
*/
|
|
264
|
+
updateColumnModelAndRefreshGrid(refreshScope?: GridRefreshScope): void;
|
|
265
|
+
/**
|
|
266
|
+
* #column_model_refresh_perf
|
|
267
|
+
*
|
|
268
|
+
* The whole pass and each of its phases are published as DevTools performance tracks
|
|
269
|
+
* (`Runtime` track, see `DevToolsTracks`) when profiling is enabled (`localStorage.adaptableProfileTracks = 'true'`).
|
|
270
|
+
* The `Update column model & refresh grid` entry carries the number of columns set up, the number of
|
|
271
|
+
* colDefs AG Grid actually saw as changed (see `AgGridAdapter.DANGER_getColDefsVersion`) and the refresh
|
|
272
|
+
* scope applied, so a `performance.getEntriesByName()` consumer (eg the `perf/column-model-refresh`
|
|
273
|
+
* Playwright spec) can tell a callback-only pass from one that committed real colDef changes.
|
|
274
|
+
*
|
|
275
|
+
* @param refreshScope see #narrow_column_model_refresh; defaults to a full refresh (rows + header)
|
|
276
|
+
*/
|
|
277
|
+
_updateColumnModelAndRefreshGridNow(refreshScope?: GridRefreshScope): void;
|
|
278
|
+
/**
|
|
279
|
+
* see #narrow_column_model_refresh
|
|
280
|
+
* Applies the given refresh scope; each operation is a DevTools `Runtime` track entry (see #column_model_refresh_perf).
|
|
281
|
+
*/
|
|
282
|
+
private refreshGridAfterColumnModelUpdate;
|
|
283
|
+
/**
|
|
284
|
+
* see #narrow_column_model_refresh
|
|
285
|
+
* The cell-level counterpart of `redrawBody()`: re-runs the colDef callbacks on every rendered cell
|
|
286
|
+
* without destroying the rows, so cell focus, selection and an in-progress edit survive.
|
|
287
|
+
* `cellStyle` results are normalised (see `normalizeStyleForAgGrid`), so a style that no longer applies
|
|
288
|
+
* is cleared even though AG Grid only ever ADDS inline styles on refresh.
|
|
289
|
+
*/
|
|
290
|
+
refreshRenderedCells(): void;
|
|
254
291
|
/**
|
|
255
292
|
* Re-applies the current sort, eg. after a Custom Sort was added/edited/removed at runtime.
|
|
256
293
|
* The column comparators are already up to date (see #stable_col_def_callbacks), AG Grid just has to sort again.
|
|
@@ -2,6 +2,7 @@ import { debounce } from '../Utilities/Helpers/TimingHelper';
|
|
|
2
2
|
import { createGrid, } from 'ag-grid-enterprise';
|
|
3
3
|
import { AdaptableLogger } from './AdaptableLogger';
|
|
4
4
|
import { PrimaryKeyDocsLink } from '../Utilities/Constants/DocumentationLinkConstants';
|
|
5
|
+
import { describeGridRefreshScope, FULL_GRID_REFRESH_SCOPE, getMissingGridRefreshScope, mergeGridRefreshScopes, } from './gridRefreshScope';
|
|
5
6
|
import StringExtensions from '../Utilities/Extensions/StringExtensions';
|
|
6
7
|
import { applyQuickSearchFindCssVars } from '../Utilities/Helpers/QuickSearchHelper';
|
|
7
8
|
import Emitter from '../Utilities/Emitter';
|
|
@@ -617,7 +618,6 @@ export class AdaptableAgGrid {
|
|
|
617
618
|
agGridApi.onFilterChanged();
|
|
618
619
|
filteringApplied = true;
|
|
619
620
|
}
|
|
620
|
-
agGridApi.refreshCells();
|
|
621
621
|
this._emit('AdapTableFiltersApplied');
|
|
622
622
|
return filteringApplied;
|
|
623
623
|
}
|
|
@@ -1429,7 +1429,10 @@ export class AdaptableAgGrid {
|
|
|
1429
1429
|
if (this.api.formatColumnApi.getActiveFormatColumns().some((fc) => {
|
|
1430
1430
|
return fc.ColumnGroupScope != null;
|
|
1431
1431
|
})) {
|
|
1432
|
-
this.updateColumnModelAndRefreshGrid(
|
|
1432
|
+
this.updateColumnModelAndRefreshGrid({
|
|
1433
|
+
cells: true,
|
|
1434
|
+
header: this.api.formatColumnApi.internalApi.hasFormatColumnsTargetingHeader(),
|
|
1435
|
+
});
|
|
1433
1436
|
}
|
|
1434
1437
|
}));
|
|
1435
1438
|
this.agGridAdapter.getAgGridApi().addEventListener('columnPivotChanged', (this.listenerPivotChanged = (params) => {
|
|
@@ -1883,30 +1886,81 @@ export class AdaptableAgGrid {
|
|
|
1883
1886
|
}
|
|
1884
1887
|
return rawValue;
|
|
1885
1888
|
}
|
|
1886
|
-
|
|
1889
|
+
__columnModelRefreshDoneInThisTick = null;
|
|
1887
1890
|
__forceUpdateColumnModel = false;
|
|
1888
|
-
updateColumnModelAndRefreshGrid() {
|
|
1889
|
-
|
|
1891
|
+
updateColumnModelAndRefreshGrid(refreshScope = FULL_GRID_REFRESH_SCOPE) {
|
|
1892
|
+
const alreadyDone = this.__columnModelRefreshDoneInThisTick;
|
|
1893
|
+
if (alreadyDone && !this.__forceUpdateColumnModel) {
|
|
1894
|
+
const missingScope = getMissingGridRefreshScope(alreadyDone, refreshScope);
|
|
1895
|
+
if (missingScope) {
|
|
1896
|
+
this.refreshGridAfterColumnModelUpdate(missingScope);
|
|
1897
|
+
this.__columnModelRefreshDoneInThisTick = mergeGridRefreshScopes(alreadyDone, missingScope);
|
|
1898
|
+
}
|
|
1890
1899
|
return;
|
|
1891
1900
|
}
|
|
1892
1901
|
this.__forceUpdateColumnModel = false;
|
|
1893
1902
|
try {
|
|
1894
|
-
this._updateColumnModelAndRefreshGridNow();
|
|
1895
|
-
this.
|
|
1903
|
+
this._updateColumnModelAndRefreshGridNow(refreshScope);
|
|
1904
|
+
this.__columnModelRefreshDoneInThisTick = alreadyDone
|
|
1905
|
+
? mergeGridRefreshScopes(alreadyDone, refreshScope)
|
|
1906
|
+
: { ...refreshScope };
|
|
1896
1907
|
}
|
|
1897
1908
|
finally {
|
|
1898
1909
|
queueMicrotask(() => {
|
|
1899
|
-
this.
|
|
1910
|
+
this.__columnModelRefreshDoneInThisTick = null;
|
|
1900
1911
|
});
|
|
1901
1912
|
}
|
|
1902
1913
|
}
|
|
1903
|
-
_updateColumnModelAndRefreshGridNow() {
|
|
1914
|
+
_updateColumnModelAndRefreshGridNow(refreshScope = FULL_GRID_REFRESH_SCOPE) {
|
|
1904
1915
|
const startTime = performance.now();
|
|
1916
|
+
const adaptableId = this.adaptableOptions.adaptableId;
|
|
1917
|
+
const runtimeTrack = () => getMarker(adaptableId).track.Runtime.label;
|
|
1918
|
+
const colDefsVersionBefore = this.agGridAdapter.DANGER_getColDefsVersion();
|
|
1919
|
+
const passMarker = runtimeTrack().UpdateColumnModel.start();
|
|
1920
|
+
const deriveMarker = runtimeTrack().DeriveColumnState.start();
|
|
1905
1921
|
this.deriveAdaptableColumnStateFromAgGrid();
|
|
1922
|
+
deriveMarker.end();
|
|
1923
|
+
const setupColumnsMarker = runtimeTrack().SetupColumns.start();
|
|
1906
1924
|
this.agGridColumnAdapter.setupColumns();
|
|
1907
|
-
|
|
1908
|
-
this.
|
|
1909
|
-
|
|
1925
|
+
setupColumnsMarker.end();
|
|
1926
|
+
this.refreshGridAfterColumnModelUpdate(refreshScope);
|
|
1927
|
+
const colDefsVersionAfter = this.agGridAdapter.DANGER_getColDefsVersion();
|
|
1928
|
+
const colDefsChanged = colDefsVersionBefore != null && colDefsVersionAfter != null
|
|
1929
|
+
? colDefsVersionAfter - colDefsVersionBefore
|
|
1930
|
+
: -1;
|
|
1931
|
+
const columnCount = this.api.columnApi.getColumns().length;
|
|
1932
|
+
const refreshScopeLabel = describeGridRefreshScope(refreshScope);
|
|
1933
|
+
passMarker.end({
|
|
1934
|
+
details: [
|
|
1935
|
+
{ name: 'columns', value: columnCount },
|
|
1936
|
+
{ name: 'colDefsChanged', value: colDefsChanged },
|
|
1937
|
+
{ name: 'refresh', value: refreshScopeLabel },
|
|
1938
|
+
],
|
|
1939
|
+
});
|
|
1940
|
+
this.logger.info(`Updated column model and refreshed grid in ${Math.round(performance.now() - startTime)}ms (${columnCount} columns, ${colDefsChanged} colDefs changed, refresh: ${refreshScopeLabel}).`);
|
|
1941
|
+
}
|
|
1942
|
+
refreshGridAfterColumnModelUpdate(refreshScope) {
|
|
1943
|
+
const runtimeTrack = getMarker(this.adaptableOptions.adaptableId).track.Runtime.label;
|
|
1944
|
+
if (refreshScope.rows) {
|
|
1945
|
+
const redrawBodyMarker = runtimeTrack.RedrawBody.start();
|
|
1946
|
+
this.redrawBody();
|
|
1947
|
+
redrawBodyMarker.end();
|
|
1948
|
+
}
|
|
1949
|
+
else if (refreshScope.cells) {
|
|
1950
|
+
const refreshCellsMarker = runtimeTrack.RefreshCells.start();
|
|
1951
|
+
this.refreshRenderedCells();
|
|
1952
|
+
refreshCellsMarker.end();
|
|
1953
|
+
}
|
|
1954
|
+
if (refreshScope.header) {
|
|
1955
|
+
const refreshHeaderMarker = runtimeTrack.RefreshHeader.start();
|
|
1956
|
+
this.refreshHeader();
|
|
1957
|
+
refreshHeaderMarker.end();
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
refreshRenderedCells() {
|
|
1961
|
+
this.agGridAdapter.getAgGridApi().refreshCells({ force: true, suppressFlash: true });
|
|
1962
|
+
this.refreshAgGridFindIfNeeded();
|
|
1963
|
+
this._emit('GridRefreshed');
|
|
1910
1964
|
}
|
|
1911
1965
|
refreshSortIfColumnsSorted() {
|
|
1912
1966
|
const columnSorts = this.api.layoutApi.getCurrentLayout()?.ColumnSorts;
|
|
@@ -64,6 +64,7 @@ export declare class AgGridAdapter {
|
|
|
64
64
|
private DANGER_getPrivateAgGridBeans;
|
|
65
65
|
DANGER_getCreateSparkline(): ((options: AgSparklineOptions) => AgChartInstance<AgSparklineOptions>) | undefined;
|
|
66
66
|
DANGER_getLiveGridOptions(): GridOptions<any>;
|
|
67
|
+
DANGER_getColDefsVersion(): number | undefined;
|
|
67
68
|
DANGER_invalidateSortCache(): void;
|
|
68
69
|
getAgGridRootElement(): HTMLElement;
|
|
69
70
|
/**
|
|
@@ -48,47 +48,6 @@ const patchLocalEventServiceDispatchEvent = (beans) => {
|
|
|
48
48
|
DANGER_AG_GRID_ADAPTERS_MAP[gridId]?.handleRowNodeEvent(rowNodeEvent);
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
|
-
const patchVisibleColsPartition = (beans) => {
|
|
52
|
-
const visibleCols = beans?.visibleCols;
|
|
53
|
-
if (!visibleCols || typeof visibleCols.partitionVisibleCols !== 'function') {
|
|
54
|
-
console.error(`CRITICAL: could not get hold of AG Grid VisibleColsService.partitionVisibleCols, the selection column may NOT be displayed when it is the last column!`);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const original_partitionVisibleCols = visibleCols.partitionVisibleCols;
|
|
58
|
-
visibleCols.partitionVisibleCols = function () {
|
|
59
|
-
const result = original_partitionVisibleCols.apply(this, arguments);
|
|
60
|
-
const leftCols = result?.leftCols ?? [];
|
|
61
|
-
const rightCols = result?.rightCols ?? [];
|
|
62
|
-
const centerCols = result?.centerCols ?? [];
|
|
63
|
-
if (leftCols.length + rightCols.length + centerCols.length === 0) {
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
const colModel = beans.colModel;
|
|
67
|
-
const selectionCol = colModel?.colsList?.find((col) => col?.colKind === 'selection');
|
|
68
|
-
if (!selectionCol || !selectionCol.visible) {
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
if (leftCols.includes(selectionCol) ||
|
|
72
|
-
rightCols.includes(selectionCol) ||
|
|
73
|
-
centerCols.includes(selectionCol)) {
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
const showAutoGroupAndValuesOnly = colModel.pivotMode && !colModel.showingPivotResult;
|
|
77
|
-
if (showAutoGroupAndValuesOnly && !(beans.selectionColSvc?.isEnabled?.() ?? false)) {
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
if (selectionCol.pinned === 'right') {
|
|
81
|
-
rightCols.push(selectionCol);
|
|
82
|
-
}
|
|
83
|
-
else if (selectionCol.pinned) {
|
|
84
|
-
leftCols.push(selectionCol);
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
centerCols.push(selectionCol);
|
|
88
|
-
}
|
|
89
|
-
return result;
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
51
|
export class AgGridAdapter {
|
|
93
52
|
_adaptableInstance;
|
|
94
53
|
DANGER_USE_GETTER_gridApi;
|
|
@@ -117,7 +76,6 @@ export class AgGridAdapter {
|
|
|
117
76
|
}
|
|
118
77
|
DANGER_AG_GRID_BEANS_MAP[gridId] = beans;
|
|
119
78
|
patchLocalEventServiceDispatchEvent(beans);
|
|
120
|
-
patchVisibleColsPartition(beans);
|
|
121
79
|
};
|
|
122
80
|
}
|
|
123
81
|
}
|
|
@@ -308,6 +266,9 @@ export class AgGridAdapter {
|
|
|
308
266
|
DANGER_getLiveGridOptions() {
|
|
309
267
|
return this.DANGER_getPrivateAgGridBeans()?.gridOptions;
|
|
310
268
|
}
|
|
269
|
+
DANGER_getColDefsVersion() {
|
|
270
|
+
return this.DANGER_getPrivateAgGridBeans()?.colModel?.colDefsVersion;
|
|
271
|
+
}
|
|
311
272
|
DANGER_invalidateSortCache() {
|
|
312
273
|
this.DANGER_getPrivateAgGridBeans()?.sortSvc?.invalidate();
|
|
313
274
|
}
|
|
@@ -116,6 +116,22 @@ export declare class AgGridColumnAdapter {
|
|
|
116
116
|
* The combination of styled column and format cells
|
|
117
117
|
* This function decides when the two can be merged.
|
|
118
118
|
*/
|
|
119
|
+
/**
|
|
120
|
+
* #derived_pivot_cell_style
|
|
121
|
+
*
|
|
122
|
+
* A pivot result column is generated by AG Grid for a value (base) column, so the cells of
|
|
123
|
+
* `pivot_make_Ford_rating` show (aggregated) `rating` values. Adaptable objects are defined
|
|
124
|
+
* against the base column, and its pivot result cells inherit them:
|
|
125
|
+
* - Format Columns whose Scope contains the base column style the pivot result cells, and their
|
|
126
|
+
* Rule is evaluated against the pivot result cell: in a Rule Expression `[rating]` / `$SCOPE()`
|
|
127
|
+
* resolve to the pivot result cell value (`COL` / `$SCOPE` in `scalarExpressionFunctions.ts`
|
|
128
|
+
* read `pivotResultColumn` from the evaluation context), a Rule Predicate gets it as `value`;
|
|
129
|
+
* - the Styled Column of the base column contributes its cell style (e.g. Gradient background).
|
|
130
|
+
*
|
|
131
|
+
* Returns the context when `params` describe a pivot result cell, `undefined` otherwise.
|
|
132
|
+
* This is the single place deriving it; everything below `setupColumnCellStyle` receives it explicitly.
|
|
133
|
+
*/
|
|
134
|
+
private getPivotResultCellContext;
|
|
119
135
|
private getFormatColumnAndStyledColumnCellStyle;
|
|
120
136
|
/**
|
|
121
137
|
* Returns true when the active Styled Column declares a `Font` slot
|
|
@@ -136,7 +152,14 @@ export declare class AgGridColumnAdapter {
|
|
|
136
152
|
private styledColumnClaimsCellBoxStyle;
|
|
137
153
|
private getFormatColumnHeaderStyle;
|
|
138
154
|
private getStyledColumnStyle;
|
|
139
|
-
|
|
155
|
+
/**
|
|
156
|
+
* The given (in scope) Format Columns whose Rule matches the cell.
|
|
157
|
+
*
|
|
158
|
+
* @param abColumn - the column the Format Columns are scoped to: the cell's column, or its base column
|
|
159
|
+
* for a pivot result cell inheriting base column Format Columns (see #derived_pivot_cell_style)
|
|
160
|
+
* @param pivotResultColumn - set when the cell is a pivot result cell, see #derived_pivot_cell_style
|
|
161
|
+
*/
|
|
162
|
+
private getRelevantFormatColumnsForCell;
|
|
140
163
|
private getFormatColumnAdaptableStyle;
|
|
141
164
|
private getAlertCellStyle;
|
|
142
165
|
private getFlashingCellStyle;
|
|
@@ -462,31 +462,14 @@ export class AgGridColumnAdapter {
|
|
|
462
462
|
const textStyleToApply = isCurrentMatch
|
|
463
463
|
? { ...textMatchStyle, ...currentTextMatchStyle }
|
|
464
464
|
: textMatchStyle;
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const baseColumn = params.column.getColDef()?.pivotValueColumn;
|
|
468
|
-
if (baseColumn) {
|
|
469
|
-
const baseColDefCellStyle = baseColumn?.getColDef()?.cellStyle;
|
|
470
|
-
const baseColParams = {
|
|
471
|
-
...params,
|
|
472
|
-
column: baseColumn,
|
|
473
|
-
__pivotResultColumn: params.column,
|
|
474
|
-
};
|
|
475
|
-
baseStyles =
|
|
476
|
-
typeof baseColDefCellStyle === 'function'
|
|
477
|
-
? baseColDefCellStyle(baseColParams)
|
|
478
|
-
: baseColDefCellStyle;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
else {
|
|
482
|
-
baseStyles = typeof userCellStyle === 'function' ? userCellStyle(params) : userCellStyle;
|
|
483
|
-
}
|
|
465
|
+
const baseStyles = typeof userCellStyle === 'function' ? userCellStyle(params) : userCellStyle;
|
|
466
|
+
const pivotResultCell = this.getPivotResultCellContext(params);
|
|
484
467
|
const result = {
|
|
485
468
|
...baseStyles,
|
|
486
469
|
...this.getReadOnlyCellStyle(gridCell, params),
|
|
487
470
|
...this.getEditableCellStyle(gridCell, params),
|
|
488
471
|
...this.getEditedCellStyle(gridCell, params),
|
|
489
|
-
...this.getFormatColumnAndStyledColumnCellStyle(gridCell.column, params),
|
|
472
|
+
...this.getFormatColumnAndStyledColumnCellStyle(gridCell.column, params, pivotResultCell),
|
|
490
473
|
...(isQuickSearchActive ? quickSearchStyle : {}),
|
|
491
474
|
...(isQuickSearchActive && textStyleToApply ? textStyleToApply : {}),
|
|
492
475
|
...this.getAlertCellStyle(gridCell, params),
|
|
@@ -1317,21 +1300,44 @@ export class AgGridColumnAdapter {
|
|
|
1317
1300
|
}
|
|
1318
1301
|
return undefined;
|
|
1319
1302
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1303
|
+
getPivotResultCellContext(params) {
|
|
1304
|
+
if (!this.adaptableApi.columnApi.isPivotResultColumn(params.column.getColId())) {
|
|
1305
|
+
return undefined;
|
|
1306
|
+
}
|
|
1307
|
+
const baseAgColumn = params.column.getColDef()?.pivotValueColumn;
|
|
1308
|
+
const baseColumn = baseAgColumn
|
|
1309
|
+
? this.adaptableApi.columnApi.getColumnWithColumnId(baseAgColumn.getColId())
|
|
1310
|
+
: undefined;
|
|
1311
|
+
if (!baseColumn) {
|
|
1312
|
+
return undefined;
|
|
1313
|
+
}
|
|
1314
|
+
return { pivotResultColumn: params.column, baseColumn };
|
|
1315
|
+
}
|
|
1316
|
+
getFormatColumnAndStyledColumnCellStyle(column, params, pivotResultCell) {
|
|
1317
|
+
let styledColumn = this.adaptableApi.styledColumnApi.getStyledColumnForColumnId(column.columnId);
|
|
1318
|
+
let styledColumnColumn = column;
|
|
1319
|
+
if (!styledColumn && pivotResultCell) {
|
|
1320
|
+
styledColumn = this.adaptableApi.styledColumnApi.getStyledColumnForColumnId(pivotResultCell.baseColumn.columnId);
|
|
1321
|
+
styledColumnColumn = pivotResultCell.baseColumn;
|
|
1322
|
+
}
|
|
1322
1323
|
const styledColumnIsActive = !!styledColumn && !styledColumn?.IsSuspended;
|
|
1323
1324
|
const styledColumnStyle = styledColumnIsActive
|
|
1324
|
-
? this.getStyledColumnStyle(styledColumn,
|
|
1325
|
+
? this.getStyledColumnStyle(styledColumn, styledColumnColumn, params)
|
|
1325
1326
|
: {};
|
|
1326
|
-
const
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1327
|
+
const formatColumnInternalApi = this.adaptableApi.formatColumnApi.internalApi;
|
|
1328
|
+
const relevantFormatColumnsWithStyle = this.getRelevantFormatColumnsForCell(column, formatColumnInternalApi.getFormatColumnsWithStyleForColumn(column, { target: 'cell' }), params, pivotResultCell?.pivotResultColumn);
|
|
1329
|
+
if (pivotResultCell) {
|
|
1330
|
+
const baseFormatColumnsWithStyle = formatColumnInternalApi
|
|
1331
|
+
.getFormatColumnsWithStyleForColumn(pivotResultCell.baseColumn, { target: 'cell' })
|
|
1332
|
+
.filter((formatColumn) => !relevantFormatColumnsWithStyle.includes(formatColumn));
|
|
1333
|
+
relevantFormatColumnsWithStyle.push(...this.getRelevantFormatColumnsForCell(pivotResultCell.baseColumn, baseFormatColumnsWithStyle, params, pivotResultCell.pivotResultColumn));
|
|
1334
|
+
}
|
|
1335
|
+
let formatColumnStyle = this.getFormatColumnAdaptableStyle(relevantFormatColumnsWithStyle);
|
|
1330
1336
|
if (styledColumnIsActive) {
|
|
1331
|
-
if (this.styledColumnClaimsFontStyle(styledColumn,
|
|
1337
|
+
if (this.styledColumnClaimsFontStyle(styledColumn, styledColumnColumn)) {
|
|
1332
1338
|
formatColumnStyle = stripFontCssKeys(formatColumnStyle);
|
|
1333
1339
|
}
|
|
1334
|
-
if (this.styledColumnClaimsCellBoxStyle(styledColumn,
|
|
1340
|
+
if (this.styledColumnClaimsCellBoxStyle(styledColumn, styledColumnColumn)) {
|
|
1335
1341
|
formatColumnStyle = stripCellBoxCssKeys(formatColumnStyle);
|
|
1336
1342
|
}
|
|
1337
1343
|
}
|
|
@@ -1444,14 +1450,10 @@ export class AgGridColumnAdapter {
|
|
|
1444
1450
|
}
|
|
1445
1451
|
return style;
|
|
1446
1452
|
}
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
return
|
|
1450
|
-
}
|
|
1451
|
-
const relevantFormatColumnsWithStyle = activeFormatColumnsWithStyle.filter((formatColumn) => {
|
|
1452
|
-
return this.adaptableApi.formatColumnApi.internalApi.formatColumnShouldRenderInCell(formatColumn, abColumn, params.node, params.value, params.__pivotResultColumn);
|
|
1453
|
+
getRelevantFormatColumnsForCell(abColumn, activeFormatColumnsWithStyle, params, pivotResultColumn) {
|
|
1454
|
+
return activeFormatColumnsWithStyle.filter((formatColumn) => {
|
|
1455
|
+
return this.adaptableApi.formatColumnApi.internalApi.formatColumnShouldRenderInCell(formatColumn, abColumn, params.node, params.value, pivotResultColumn);
|
|
1453
1456
|
});
|
|
1454
|
-
return this.getFormatColumnAdaptableStyle(relevantFormatColumnsWithStyle);
|
|
1455
1457
|
}
|
|
1456
1458
|
getFormatColumnAdaptableStyle(formatColumns) {
|
|
1457
1459
|
return formatColumns.reduceRight((style, formatColumn) => {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { GridRefreshScope } from '../AdaptableInterfaces/IAdaptable';
|
|
2
|
+
/**
|
|
3
|
+
* see #narrow_column_model_refresh
|
|
4
|
+
*
|
|
5
|
+
* Helpers for the refresh scope of a column-model pass (`AdaptableAgGrid.updateColumnModelAndRefreshGrid`).
|
|
6
|
+
*/
|
|
7
|
+
/** The legacy behaviour: destroy & recreate every rendered row and every header cell. */
|
|
8
|
+
export declare const FULL_GRID_REFRESH_SCOPE: Readonly<GridRefreshScope>;
|
|
9
|
+
/** Re-run the cell-level callbacks on the rendered cells; rows and header are kept. */
|
|
10
|
+
export declare const CELLS_GRID_REFRESH_SCOPE: Readonly<GridRefreshScope>;
|
|
11
|
+
/** Only set up the columns; whatever colDef value changed is refreshed by AG Grid itself (see #col_def_commit). */
|
|
12
|
+
export declare const NO_GRID_REFRESH_SCOPE: Readonly<GridRefreshScope>;
|
|
13
|
+
export declare const mergeGridRefreshScopes: (a: GridRefreshScope, b: GridRefreshScope) => GridRefreshScope;
|
|
14
|
+
/**
|
|
15
|
+
* The part of `requested` that `done` did not cover, or `null` when `done` already covers everything.
|
|
16
|
+
* A row redraw covers a cell refresh (the cells are recreated with the rows).
|
|
17
|
+
*/
|
|
18
|
+
export declare const getMissingGridRefreshScope: (done: GridRefreshScope, requested: GridRefreshScope) => GridRefreshScope | null;
|
|
19
|
+
/** eg `rows+header`, `cells`, `none` - used in the perf track details and the log line */
|
|
20
|
+
export declare const describeGridRefreshScope: (scope: GridRefreshScope) => string;
|