@adaptabletools/adaptable 23.0.21 → 23.1.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/package.json +3 -2
  2. package/src/AdaptableInterfaces/IAdaptable.d.ts +1 -0
  3. package/src/AdaptableOptions/ColumnMenuOptions.d.ts +1 -1
  4. package/src/AdaptableOptions/ContextMenuOptions.d.ts +1 -1
  5. package/src/AdaptableOptions/FilterOptions.d.ts +34 -0
  6. package/src/Api/GridApi.d.ts +5 -1
  7. package/src/Api/Implementation/GridApiImpl.d.ts +1 -0
  8. package/src/Api/Implementation/GridApiImpl.js +22 -1
  9. package/src/Redux/Store/AdaptableStore.js +6 -1
  10. package/src/Utilities/Helpers/DisplayFormatHelper.js +16 -4
  11. package/src/Utilities/Helpers/StyledColumns/SparklineStyleHelper.d.ts +2 -0
  12. package/src/Utilities/Helpers/StyledColumns/SparklineStyleHelper.js +13 -10
  13. package/src/Utilities/Hooks/useAdaptableOptions.d.ts +1 -1
  14. package/src/Utilities/Services/AnnotationsService.js +8 -8
  15. package/src/View/Components/ColumnFilter/components/FloatingFilterValues.d.ts +3 -0
  16. package/src/View/Components/ColumnFilter/components/FloatingFilterValues.js +16 -1
  17. package/src/View/Components/FilterForm/ListBoxFilterForm.js +1 -1
  18. package/src/View/Components/PredicateEditor/PredicateEditor.js +11 -1
  19. package/src/View/FormatColumn/Wizard/FormatColumnFormatWizardSection.js +6 -2
  20. package/src/View/StyledColumn/Wizard/StyledColumnSparklineSettingsSection.js +18 -8
  21. package/src/View/Wizard/OnePageAdaptableWizard.d.ts +2 -2
  22. package/src/View/Wizard/OnePageWizards.d.ts +1 -1
  23. package/src/agGrid/AdaptableAgGrid.d.ts +30 -6
  24. package/src/agGrid/AdaptableAgGrid.js +60 -78
  25. package/src/agGrid/AgGridAdapter.d.ts +32 -1
  26. package/src/agGrid/AgGridAdapter.js +88 -0
  27. package/src/agGrid/AgGridColumnAdapter.d.ts +44 -0
  28. package/src/agGrid/AgGridColumnAdapter.js +153 -37
  29. package/src/agGrid/AgGridMenuAdapter.d.ts +8 -2
  30. package/src/agGrid/AgGridMenuAdapter.js +17 -4
  31. package/src/agGrid/AgGridModulesAdapter.js +6 -1
  32. package/src/agGrid/AgGridThemeAdapter.d.ts +17 -0
  33. package/src/agGrid/AgGridThemeAdapter.js +37 -6
  34. package/src/components/Combobox/index.d.ts +11 -0
  35. package/src/components/Combobox/index.js +5 -3
  36. package/src/components/Radio/index.d.ts +2 -2
  37. package/src/components/Tree/TreeDropdown/index.d.ts +11 -0
  38. package/src/components/Tree/TreeDropdown/index.js +6 -3
  39. package/src/env.js +2 -2
  40. package/src/layout-manager/src/index.d.ts +9 -0
  41. package/src/layout-manager/src/index.js +38 -17
  42. package/src/types.d.ts +1 -1
  43. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -49,6 +49,22 @@ const stripCssKeys = (style, keys) => {
49
49
  };
50
50
  const stripFontCssKeys = (style) => stripCssKeys(style, FONT_CSS_KEYS);
51
51
  const stripCellBoxCssKeys = (style) => stripCssKeys(style, CELL_BOX_CSS_KEYS);
52
+ const STABLE_CALLBACK_COL_DEF_PROPERTIES = new Set([
53
+ 'cellStyle',
54
+ 'cellClass',
55
+ 'headerStyle',
56
+ 'headerClass',
57
+ 'valueGetter',
58
+ 'valueFormatter',
59
+ 'valueSetter',
60
+ 'editable',
61
+ 'comparator',
62
+ 'pivotComparator',
63
+ 'getFindText',
64
+ 'getQuickFilterText',
65
+ 'tooltipValueGetter',
66
+ 'cellEditorParams',
67
+ ]);
52
68
  export function getEditorForColumnDataType(columnDataType, variant) {
53
69
  if (columnDataType === 'number') {
54
70
  return variant === 'react' ? AdaptableReactNumberEditor : AdaptableNumberEditor;
@@ -60,9 +76,20 @@ export function getEditorForColumnDataType(columnDataType, variant) {
60
76
  export class AgGridColumnAdapter {
61
77
  adaptableInstance;
62
78
  colDefPropertyCache;
79
+ workingColDefs;
80
+ sortCacheInvalidationNeeded = false;
81
+ stableCallbacks;
82
+ stableCallbackImplementations;
83
+ stableCallbackOwners;
84
+ adaptableColumnFilterDef;
85
+ adaptableFloatingFilterComponent;
63
86
  constructor(adaptableInstance) {
64
87
  this.adaptableInstance = adaptableInstance;
65
88
  this.colDefPropertyCache = new Map();
89
+ this.workingColDefs = new Map();
90
+ this.stableCallbacks = new Map();
91
+ this.stableCallbackImplementations = new Map();
92
+ this.stableCallbackOwners = new WeakMap();
66
93
  }
67
94
  getVariant() {
68
95
  return this.adaptableInstance.variant;
@@ -71,6 +98,15 @@ export class AgGridColumnAdapter {
71
98
  this.adaptableInstance = null;
72
99
  this.colDefPropertyCache.clear();
73
100
  this.colDefPropertyCache = null;
101
+ this.workingColDefs.clear();
102
+ this.workingColDefs = null;
103
+ this.stableCallbacks.clear();
104
+ this.stableCallbacks = null;
105
+ this.stableCallbackImplementations.clear();
106
+ this.stableCallbackImplementations = null;
107
+ this.stableCallbackOwners = null;
108
+ this.adaptableColumnFilterDef = null;
109
+ this.adaptableFloatingFilterComponent = null;
74
110
  }
75
111
  get adaptableApi() {
76
112
  return this.adaptableInstance.api;
@@ -81,9 +117,55 @@ export class AgGridColumnAdapter {
81
117
  get agGridApi() {
82
118
  return this.adaptableApi.agGridApi;
83
119
  }
120
+ getColDefForSetup(col) {
121
+ return this.workingColDefs.get(col.getColId()) ?? col.getColDef();
122
+ }
123
+ beginColDefChanges(col) {
124
+ const workingColDef = { ...col.getColDef() };
125
+ this.workingColDefs.set(col.getColId(), workingColDef);
126
+ return workingColDef;
127
+ }
128
+ commitColDefChanges(col) {
129
+ const colId = col.getColId();
130
+ const workingColDef = this.workingColDefs.get(colId);
131
+ this.workingColDefs.delete(colId);
132
+ if (!workingColDef) {
133
+ return;
134
+ }
135
+ const agColumn = col;
136
+ if (typeof agColumn.setColDef !== 'function') {
137
+ errorOnce(`CRITICAL: AG Grid 'AgColumn.setColDef()' is not available, Adaptable cannot commit column definition changes! (see #col_def_commit)`);
138
+ Object.assign(col.getColDef(), workingColDef);
139
+ return;
140
+ }
141
+ agColumn.setColDef(workingColDef, col.getUserProvidedColDef(), 'api');
142
+ }
143
+ toStableCallback(colId, propertyName, implementation) {
144
+ const key = `${colId}.${propertyName}`;
145
+ this.stableCallbackImplementations.set(key, implementation);
146
+ let stableCallback = this.stableCallbacks.get(key);
147
+ if (!stableCallback) {
148
+ stableCallback = (...args) => {
149
+ return this.stableCallbackImplementations?.get(key)?.(...args);
150
+ };
151
+ this.stableCallbacks.set(key, stableCallback);
152
+ this.stableCallbackOwners.set(stableCallback, { colId, propertyName });
153
+ }
154
+ return stableCallback;
155
+ }
156
+ resolveUserProvidedValue(propertyName, value) {
157
+ if (typeof value !== 'function') {
158
+ return value;
159
+ }
160
+ const owner = this.stableCallbackOwners.get(value);
161
+ if (!owner) {
162
+ return value;
163
+ }
164
+ return this.colDefPropertyCache.get(`user.${owner.colId}.${propertyName}`);
165
+ }
84
166
  setColDefProperty(col, propertyName, propertyGetter) {
85
167
  const colId = col.getColId();
86
- const colDef = col.getColDef();
168
+ const colDef = this.getColDefForSetup(col);
87
169
  const colSetupInfo = {
88
170
  col,
89
171
  colDef,
@@ -94,10 +176,15 @@ export class AgGridColumnAdapter {
94
176
  const value = colDef[propertyName];
95
177
  const isUserDefined = value !== this.colDefPropertyCache.get(adaptableKey);
96
178
  if (isUserDefined) {
97
- this.colDefPropertyCache.set(userKey, value);
179
+ this.colDefPropertyCache.set(userKey, this.resolveUserProvidedValue(propertyName, value));
98
180
  }
99
181
  const userValue = this.colDefPropertyCache.get(userKey);
100
- const adaptableValue = propertyGetter(userValue);
182
+ let adaptableValue = propertyGetter(userValue);
183
+ if (typeof adaptableValue === 'function' &&
184
+ adaptableValue !== userValue &&
185
+ STABLE_CALLBACK_COL_DEF_PROPERTIES.has(propertyName)) {
186
+ adaptableValue = this.toStableCallback(colId, propertyName, adaptableValue);
187
+ }
101
188
  if (adaptableValue != null) {
102
189
  this.colDefPropertyCache.set(adaptableKey, adaptableValue);
103
190
  }
@@ -115,7 +202,12 @@ export class AgGridColumnAdapter {
115
202
  if (theValue === undefined && colDef[propertyName] === undefined) {
116
203
  return;
117
204
  }
205
+ const previousValue = colDef[propertyName];
118
206
  colDef[propertyName] = theValue;
207
+ if ((propertyName === 'comparator' || propertyName === 'pivotComparator') &&
208
+ previousValue !== theValue) {
209
+ this.sortCacheInvalidationNeeded = true;
210
+ }
119
211
  }
120
212
  getUserColDefProperty(columnId, propertyName) {
121
213
  const userKey = `user.${columnId}.${propertyName}`;
@@ -148,42 +240,54 @@ export class AgGridColumnAdapter {
148
240
  cols = cols.filter((col) => specificColumnIds.includes(col.getColId()));
149
241
  }
150
242
  cols.forEach((col) => {
151
- const colDef = col.getColDef();
152
243
  const colId = col.getColId();
153
244
  if (this.shouldSkipColumn(colId)) {
154
245
  return;
155
246
  }
156
- const abColumn = this.adaptableApi.columnApi.getColumnWithColumnId(colId);
157
- const colSetupInfo = {
158
- col,
159
- colDef,
160
- colId,
161
- abColumn,
162
- };
163
- const isAutoRowGroupColumn = this.adaptableApi.columnApi.isAutoRowGroupColumn(colId);
164
- this.setupColumnCellRenderer(colSetupInfo);
165
- this.setupColumnCellStyle(colSetupInfo);
166
- this.setupColumnCellClass(colSetupInfo);
167
- this.setupColumnHeaderStyle(colSetupInfo);
168
- this.setupColumnHeaderClass(colSetupInfo);
169
- this.setupColumnValueGetter(colSetupInfo);
170
- this.setupColumnTooltipValueGetter(colSetupInfo);
171
- if (!isAutoRowGroupColumn) {
172
- this.setupColumnFilter(colSetupInfo);
173
- this.setupColumnFloatingFilter(colSetupInfo);
247
+ const colDef = this.beginColDefChanges(col);
248
+ try {
249
+ this.setupColumn({ col, colDef, colId });
250
+ }
251
+ finally {
252
+ this.commitColDefChanges(col);
174
253
  }
175
- this.setupColumnValueFormatter(colSetupInfo);
176
- this.setupColumnEditable(colSetupInfo);
177
- this.setupColumnValueSetter(colSetupInfo);
178
- this.setupColumnComparator(colSetupInfo);
179
- this.setupColumnGetFindText(colSetupInfo);
180
- this.setupColumnCellEditor(colSetupInfo);
181
- this.setupColumnHeader(colSetupInfo);
182
- this.setupColumnQuickFilterText(colSetupInfo);
183
- this.setupColumnAllowedAggFuncs(colSetupInfo);
184
- this.setupColumnType(colSetupInfo);
185
- this.setupColumnCellDataType(colSetupInfo);
186
254
  });
255
+ if (this.sortCacheInvalidationNeeded) {
256
+ this.sortCacheInvalidationNeeded = false;
257
+ this.adaptableInstance.agGridAdapter?.DANGER_invalidateSortCache();
258
+ }
259
+ }
260
+ setupColumn({ col, colDef, colId }) {
261
+ const abColumn = this.adaptableApi.columnApi.getColumnWithColumnId(colId);
262
+ const colSetupInfo = {
263
+ col,
264
+ colDef,
265
+ colId,
266
+ abColumn,
267
+ };
268
+ const isAutoRowGroupColumn = this.adaptableApi.columnApi.isAutoRowGroupColumn(colId);
269
+ this.setupColumnCellRenderer(colSetupInfo);
270
+ this.setupColumnCellStyle(colSetupInfo);
271
+ this.setupColumnCellClass(colSetupInfo);
272
+ this.setupColumnHeaderStyle(colSetupInfo);
273
+ this.setupColumnHeaderClass(colSetupInfo);
274
+ this.setupColumnValueGetter(colSetupInfo);
275
+ this.setupColumnTooltipValueGetter(colSetupInfo);
276
+ if (!isAutoRowGroupColumn) {
277
+ this.setupColumnFilter(colSetupInfo);
278
+ this.setupColumnFloatingFilter(colSetupInfo);
279
+ }
280
+ this.setupColumnValueFormatter(colSetupInfo);
281
+ this.setupColumnEditable(colSetupInfo);
282
+ this.setupColumnValueSetter(colSetupInfo);
283
+ this.setupColumnComparator(colSetupInfo);
284
+ this.setupColumnGetFindText(colSetupInfo);
285
+ this.setupColumnCellEditor(colSetupInfo);
286
+ this.setupColumnHeader(colSetupInfo);
287
+ this.setupColumnQuickFilterText(colSetupInfo);
288
+ this.setupColumnAllowedAggFuncs(colSetupInfo);
289
+ this.setupColumnType(colSetupInfo);
290
+ this.setupColumnCellDataType(colSetupInfo);
187
291
  }
188
292
  setupColumnValueGetter({ col }) {
189
293
  this.setColDefProperty(col, 'valueGetter', (userValue) => {
@@ -744,11 +848,23 @@ export class AgGridColumnAdapter {
744
848
  this.adaptableApi.consoleError(`Column "${colId}" has a custom filter in colDef.filter, but Adaptable filtering only accepts boolean (true/false) values for this property.`);
745
849
  return false;
746
850
  }
747
- return {
851
+ return this.getAdaptableColumnFilterDef();
852
+ });
853
+ }
854
+ getAdaptableColumnFilterDef() {
855
+ if (!this.adaptableColumnFilterDef) {
856
+ this.adaptableColumnFilterDef = {
748
857
  component: AgGridFilterAdapterFactory(this.adaptableInstance),
749
858
  handler: () => new AdaptableFilterHandler(this.adaptableApi),
750
859
  };
751
- });
860
+ }
861
+ return this.adaptableColumnFilterDef;
862
+ }
863
+ getAdaptableFloatingFilterComponent() {
864
+ if (!this.adaptableFloatingFilterComponent) {
865
+ this.adaptableFloatingFilterComponent = AgGridFloatingFilterAdapterFactory(this.adaptableInstance);
866
+ }
867
+ return this.adaptableFloatingFilterComponent;
752
868
  }
753
869
  setupColumnFloatingFilter({ col, colDef }) {
754
870
  const userProvidedFilterProp = this.getUserColDefProperty(col.getColId(), 'filter');
@@ -775,13 +891,13 @@ export class AgGridColumnAdapter {
775
891
  if (isFloatingFilterDisabled) {
776
892
  return;
777
893
  }
778
- return AgGridFloatingFilterAdapterFactory(this.adaptableInstance);
894
+ return this.getAdaptableFloatingFilterComponent();
779
895
  });
780
896
  this.setColDefProperty(col, 'floatingFilter', () => {
781
897
  if (isFloatingFilterDisabled) {
782
898
  return;
783
899
  }
784
- return AgGridFloatingFilterAdapterFactory(this.adaptableInstance);
900
+ return this.getAdaptableFloatingFilterComponent();
785
901
  });
786
902
  this.setColDefProperty(col, 'suppressFloatingFilterButton', () => {
787
903
  return !isFloatingFilterDisabled;
@@ -1,5 +1,5 @@
1
1
  import { AdaptableAgGrid } from './AdaptableAgGrid';
2
- import { DefaultMenuItem, GetContextMenuItems, GetContextMenuItemsParams, GetMainMenuItems, GetMainMenuItemsParams, MenuItemDef } from 'ag-grid-enterprise';
2
+ import { DefaultMenuItem, GetContextMenuItems, GetContextMenuItemsParams, GetColumnMenuItemsParams, GetMainMenuItems, GetMainMenuItemsParams, MenuItemDef } from 'ag-grid-enterprise';
3
3
  import { AdaptableColumn } from '../AdaptableState/Common/AdaptableColumn';
4
4
  import { AdaptableMenuItem } from '../AdaptableState/Common/Menu';
5
5
  export declare class AgGridMenuAdapter {
@@ -8,8 +8,14 @@ export declare class AgGridMenuAdapter {
8
8
  private get adaptableOptions();
9
9
  private get adaptableApi();
10
10
  destroy(): void;
11
- buildColumnMenu(params: GetMainMenuItemsParams, originalGetMainMenuItems: GetMainMenuItems): (DefaultMenuItem | MenuItemDef)[];
11
+ buildColumnMenu(params: GetMainMenuItemsParams | GetColumnMenuItemsParams, _originalGetMainMenuItems?: GetMainMenuItems): (DefaultMenuItem | MenuItemDef)[];
12
+ /**
13
+ * Columns Tool Panel / Column Chooser (AG Grid 36.1 `getColumnMenuItems`).
14
+ * Phase 1 only strips dual-UI items; AdapTable items are added in Phase 2.
15
+ */
16
+ buildColumnsToolPanelMenu(params: GetColumnMenuItemsParams): (DefaultMenuItem | MenuItemDef)[];
12
17
  buildContextMenu(params: GetContextMenuItemsParams, originalGetContextMenuItems: GetContextMenuItems): (DefaultMenuItem | MenuItemDef)[];
18
+ private filterSuppressedAgGridDualUiMenuItems;
13
19
  private mapAgGridItemTypeToAgGridMenuItem;
14
20
  private removeConsecutiveSeparators;
15
21
  private createColumnMenuContextObject;
@@ -3,6 +3,13 @@ import { iconToString } from '../components/icons';
3
3
  import ArrayExtensions from '../Utilities/Extensions/ArrayExtensions';
4
4
  import { MENU_SEPARATOR } from '../Utilities/Constants/GeneralConstants';
5
5
  import { getAggFuncName, getDisplayAggFuncNames, isWeightedAverageAggregation, WEIGHTED_AVERAGE_AGG_FN_NAME, } from '../AdaptableState/Common/AggregationColumns';
6
+ const AG_GRID_DUAL_UI_MENU_ITEMS = new Set([
7
+ 'calculatedColumn',
8
+ 'editCalculatedColumn',
9
+ 'removeCalculatedColumn',
10
+ 'editColumnName',
11
+ 'showValuesAsSubMenu',
12
+ ]);
6
13
  function createAgGridIcon(name) {
7
14
  const element = document.createElement('span');
8
15
  element.className = `ag-icon ag-icon-${name}`;
@@ -114,8 +121,8 @@ export class AgGridMenuAdapter {
114
121
  destroy() {
115
122
  this._adaptableInstance = null;
116
123
  }
117
- buildColumnMenu(params, originalGetMainMenuItems) {
118
- const agGridMenuItems = (params.defaultItems ? [...params.defaultItems] : []);
124
+ buildColumnMenu(params, _originalGetMainMenuItems) {
125
+ const agGridMenuItems = this.filterSuppressedAgGridDualUiMenuItems(params.defaultItems ? [...params.defaultItems] : []);
119
126
  if (!params.column) {
120
127
  return agGridMenuItems;
121
128
  }
@@ -158,18 +165,21 @@ export class AgGridMenuAdapter {
158
165
  ];
159
166
  return this.removeConsecutiveSeparators(defaultContextMenu);
160
167
  }
168
+ buildColumnsToolPanelMenu(params) {
169
+ return this.removeConsecutiveSeparators(this.filterSuppressedAgGridDualUiMenuItems(params.defaultItems ? [...params.defaultItems] : []));
170
+ }
161
171
  buildContextMenu(params, originalGetContextMenuItems) {
162
172
  if (!params.column) {
163
173
  return [];
164
174
  }
165
175
  if (!this.adaptableApi.userInterfaceApi.isAdaptableUIVisible()) {
166
- return (params.defaultItems ? [...params.defaultItems] : []);
176
+ return this.filterSuppressedAgGridDualUiMenuItems(params.defaultItems ? [...params.defaultItems] : []);
167
177
  }
168
178
  this._adaptableInstance.refreshSelectedCellsState();
169
179
  const contextMenuOptions = this.adaptableOptions.contextMenuOptions;
170
180
  const adaptableColumn = this.adaptableApi.columnApi.getColumnWithColumnId(params.column?.getColId());
171
181
  const menuContext = this.createContextMenuContextObject(params, adaptableColumn);
172
- const agGridMenuItems = (params.defaultItems ? [...params.defaultItems] : []);
182
+ const agGridMenuItems = this.filterSuppressedAgGridDualUiMenuItems(params.defaultItems ? [...params.defaultItems] : []);
173
183
  const agGridCopyItems = agGridMenuItems.filter((item) => ['copy', 'copyWithHeaders', 'copyWithGroupHeaders', 'cut', 'paste'].includes(item));
174
184
  const otherAgGridItems = agGridMenuItems.filter((item) => !agGridCopyItems.includes(item) &&
175
185
  !['export', 'csvExport', 'excelExport'].includes(item));
@@ -213,6 +223,9 @@ export class AgGridMenuAdapter {
213
223
  ];
214
224
  return this.removeConsecutiveSeparators(defaultContextMenu);
215
225
  }
226
+ filterSuppressedAgGridDualUiMenuItems(items) {
227
+ return items.filter((item) => typeof item !== 'string' || !AG_GRID_DUAL_UI_MENU_ITEMS.has(item));
228
+ }
216
229
  mapAgGridItemTypeToAgGridMenuItem(itemName) {
217
230
  return {
218
231
  menuType: 'AgGrid',
@@ -17,6 +17,12 @@ export class AgGridModulesAdapter {
17
17
  return this.adaptableInstance.agGridAdapter.getAgGridApi();
18
18
  }
19
19
  isAgGridModuleRegistered(moduleName) {
20
+ if (moduleName === 'ClientSideRowModelModule') {
21
+ const rowModelType = this.agGridApi.getGridOption('rowModelType');
22
+ if (rowModelType == null || rowModelType === 'clientSide') {
23
+ return true;
24
+ }
25
+ }
20
26
  let isModuleRegistered = this.agGridApi.isModuleRegistered(moduleName);
21
27
  if (!isModuleRegistered) {
22
28
  const serverSideDependencies = [
@@ -61,7 +67,6 @@ export class AgGridModulesAdapter {
61
67
  mandatoryModules.push('ViewportRowModelModule');
62
68
  break;
63
69
  default:
64
- mandatoryModules.push('ClientSideRowModelModule');
65
70
  mandatoryModules.push('ClientSideRowModelApiModule');
66
71
  }
67
72
  mandatoryModules.push('CellApiModule', 'CellStyleModule', 'ColumnApiModule', 'ColumnMenuModule', 'ContextMenuModule', 'CustomFilterModule', 'EventApiModule', 'ExternalFilterModule', 'GridStateModule', 'GroupFilterModule', 'RenderApiModule', 'RowApiModule', 'RowGroupingModule', 'RowStyleModule', 'ScrollApiModule');
@@ -13,7 +13,24 @@ export declare class AgGridThemeAdapter {
13
13
  applyAgGridThemeOnAdaptableThemeChange(adaptableTheme: AdaptableTheme, variantTheme: string, agGridContainer: HTMLElement, themesToRemove: AdaptableTheme[]): void;
14
14
  private getAgGridContainerElement;
15
15
  private legacy_applyAgGridThemeOnAdaptableThemeChange;
16
+ /**
17
+ * Returns the space-separated `ag-theme-*` class names which have to be applied to elements rendered
18
+ * OUTSIDE the grid DOM (e.g. AdapTable popups/tooltips portaled to `document.body`) so that they
19
+ * pick up the AG Grid theme.
20
+ *
21
+ * - legacy theme mode: the `ag-theme-<name>` class of the grid container
22
+ * - Theming API: the `ag-theme-inherit-N` + `ag-theme-<part>-N ... ag-theme-params-N` classes
23
+ * AG Grid 36 applies on the grid-owned `.ag-styled-root` wrappers around the grid
24
+ */
16
25
  getAgGridCurrentThemeClassNames(): string;
26
+ /**
27
+ * AG Grid 36+ wraps the grid in three grid-owned `div.ag-styled-root` elements
28
+ * (outer: `ag-theme-inherit-N`, middle: `ag-theme-<part>-N ... ag-theme-params-N`, inner: `ag-ltr|ag-rtl`);
29
+ * `AgGridAdapter.getAgGridRootElement()` is the innermost one.
30
+ * Collects the `ag-theme-*` classes of these wrappers (direction classes are skipped).
31
+ */
32
+ private getThemeClassNamesFromStyledRoots;
33
+ private getThemeClassNamesFromThemeInternals;
17
34
  private getAgGridLightThemeName;
18
35
  private legacy_getAgGridCurrentThemeClassNames;
19
36
  }
@@ -74,15 +74,46 @@ export class AgGridThemeAdapter {
74
74
  }
75
75
  }
76
76
  getAgGridCurrentThemeClassNames() {
77
- if (this.agGridThemeMode === 'legacy') {
78
- this.legacy_getAgGridCurrentThemeClassNames();
79
- }
80
77
  const currentAgGridTheme = this._adaptableInstance.agGridAdapter.getGridOption('theme');
81
- if (currentAgGridTheme === 'legacy') {
78
+ if (this.agGridThemeMode === 'legacy' || currentAgGridTheme === 'legacy') {
82
79
  return this.legacy_getAgGridCurrentThemeClassNames();
83
80
  }
84
- const currentAgGridTheme__cssClassCache = currentAgGridTheme?._cssClassCache;
85
- return currentAgGridTheme__cssClassCache ?? '';
81
+ const classNamesFromDom = this.getThemeClassNamesFromStyledRoots();
82
+ if (classNamesFromDom) {
83
+ return classNamesFromDom;
84
+ }
85
+ return this.getThemeClassNamesFromThemeInternals(currentAgGridTheme);
86
+ }
87
+ getThemeClassNamesFromStyledRoots() {
88
+ const gridRoot = this._adaptableInstance.agGridAdapter.getAgGridRootElement();
89
+ const themeClassNames = [];
90
+ let element = gridRoot ?? null;
91
+ while (element && element.classList?.contains('ag-styled-root')) {
92
+ element.classList.forEach((cls) => {
93
+ if (cls.indexOf('ag-theme-') === 0) {
94
+ themeClassNames.push(cls);
95
+ }
96
+ });
97
+ element = element.parentElement;
98
+ }
99
+ return themeClassNames.join(' ');
100
+ }
101
+ getThemeClassNamesFromThemeInternals(theme) {
102
+ if (!theme || typeof theme === 'string') {
103
+ return '';
104
+ }
105
+ const themeInternals = theme;
106
+ let cssClasses;
107
+ try {
108
+ cssClasses = themeInternals._getCssClasses?.() ?? themeInternals._cssClassCache;
109
+ }
110
+ catch {
111
+ cssClasses = themeInternals._cssClassCache;
112
+ }
113
+ if (Array.isArray(cssClasses)) {
114
+ return cssClasses.filter(Boolean).join(' ');
115
+ }
116
+ return typeof cssClasses === 'string' ? cssClasses : '';
86
117
  }
87
118
  getAgGridLightThemeName() {
88
119
  const container = this.getAgGridContainerElement();
@@ -33,7 +33,18 @@ export type MultiComboboxProps<T extends ComboboxItemType> = Omit<AdaptableCombo
33
33
  } & ComboboxDataProps<T>;
34
34
  export declare const MultiCombobox: <T extends ComboboxItemType>(props: MultiComboboxProps<T>) => React.JSX.Element;
35
35
  export type GridFilterComboboxProps<T extends ComboboxItemType> = Omit<MultiComboboxProps<T>, 'showSelectAllCheckbox' | 'searchable' | 'renderInput' | 'renderInputValues'> & {
36
+ /**
37
+ * When true, prefix the selected values in the collapsed input with the
38
+ * selected count (e.g. `(3)`). Ignored when `renderInputValues` is provided.
39
+ */
36
40
  showSelectedCount?: boolean;
41
+ /**
42
+ * Custom content for the selected values in the collapsed input (rendered inside the
43
+ * standard wrapper). When provided, the built-in selected count is not rendered -
44
+ * include one in the returned content if needed.
45
+ * When omitted, selected labels are joined with a comma.
46
+ */
47
+ renderInputValues?: (items: T[]) => React.ReactNode;
37
48
  };
38
49
  export declare const GRID_FILTER_COMBBOX_ADJUSTMENTS_CLASSNAME: string;
39
50
  export declare const GridFilterCombobox: <T extends ComboboxItemType>(props: GridFilterComboboxProps<T>) => React.JSX.Element;
@@ -567,7 +567,7 @@ export const MultiCombobox = (props) => {
567
567
  };
568
568
  export const GRID_FILTER_COMBBOX_ADJUSTMENTS_CLASSNAME = cn('twa:[.ab-FloatingFilter_&]:border-none twa:[.ab-FloatingFilter_&]:inset-y-0.5 twa:[.ab-FloatingFilter_&]:inset-x-0 twa:[.ab-FloatingFilter_&]:absolute twa:[.ab-FloatingFilter_&]:shadow-none twa:[.ab-FloatingFilter_&]:min-h-auto!', 'twa:[.ab-FloatingFilter_&]:[line-height:1]', 'twa:[.ab-FloatingFilter_[data-slot=combobox-trigger]]:py-0', 'twa:[.ab-FloatingFilter_&]:[container-type:size]');
569
569
  export const GridFilterCombobox = (props) => {
570
- const { showSelectedCount = false, placeholder = 'Select...', ...comboboxProps } = props;
570
+ const { showSelectedCount = false, placeholder = 'Select...', renderInputValues: renderInputValuesProp, ...comboboxProps } = props;
571
571
  const sharedProps = {
572
572
  placeholder,
573
573
  showSelectAllCheckbox: true,
@@ -579,11 +579,13 @@ export const GridFilterCombobox = (props) => {
579
579
  showClear: false,
580
580
  showTrigger: false,
581
581
  renderInputValues: (items) => {
582
- let children = items.map((item) => getItemTextLabel(item)).join(', ');
582
+ let children = renderInputValuesProp
583
+ ? renderInputValuesProp(items)
584
+ : items.map((item) => getItemTextLabel(item)).join(', ');
583
585
  if (items.length === 0) {
584
586
  children = (_jsx("span", { "data-name": "placeholder", className: "twa:text-muted-foreground", children: placeholder }));
585
587
  }
586
- return (_jsx(_Fragment, { children: _jsxs("div", { className: "twa:text-ellipsis twa:overflow-hidden twa:whitespace-nowrap twa:flex-1000", "data-slot": "combobox-selected-values", children: [showSelectedCount && items.length > 0 && (_jsxs("span", { "data-name": "multiple-values-count", className: "twa:mr-0.5", children: ["(", items.length, ")"] })), children] }) }));
588
+ return (_jsx(_Fragment, { children: _jsxs("div", { className: "twa:text-ellipsis twa:overflow-hidden twa:whitespace-nowrap twa:flex-1000", "data-slot": "combobox-selected-values", children: [showSelectedCount && !renderInputValuesProp && items.length > 0 && (_jsxs(_Fragment, { children: [_jsxs("span", { "data-name": "multiple-values-count", children: ["(", items.length, ")"] }), ' '] })), children] }) }));
587
589
  },
588
590
  };
589
591
  const className = cn(GRID_FILTER_COMBBOX_ADJUSTMENTS_CLASSNAME, comboboxProps.className);
@@ -22,14 +22,14 @@ export interface RadioProps extends TypeProps, Omit<BoxProps, keyof TypeProps> {
22
22
  onClick?: React.MouseEventHandler<HTMLDivElement>;
23
23
  onFocus?: React.FocusEventHandler<HTMLDivElement>;
24
24
  }
25
- export declare const useRadioContext: <T extends unknown>() => {
25
+ export declare const useRadioContext: <T extends any>() => {
26
26
  value: T;
27
27
  onChange: (value: T) => void;
28
28
  name: string;
29
29
  variant: Variant;
30
30
  };
31
31
  declare const Radio: ({ children, checked, onChange, value, name, gapDistance, childrenPosition, as, id, tabIndex, disabled, ...props }: RadioProps) => React.JSX.Element;
32
- export declare const RadioGroup: <T extends unknown>(props: {
32
+ export declare const RadioGroup: <T extends any>(props: {
33
33
  orientation: "horizontal" | "vertical";
34
34
  value?: T;
35
35
  name?: string;
@@ -48,7 +48,18 @@ export type GridFilterTreeDropdownProps<T extends TreeListItem<any>> = Omit<NewT
48
48
  /**
49
49
  * When true, prefix the selected-values summary with `(N)` where N is the
50
50
  * number of selected leaves. Mirrors `GridFilterCombobox.showSelectedCount`.
51
+ * Ignored when `renderInputValues` is provided.
51
52
  */
52
53
  showSelectedCount?: boolean;
54
+ /**
55
+ * Custom content for the selected values in the collapsed input (rendered inside the
56
+ * standard wrapper). Mirrors `GridFilterCombobox.renderInputValues`: called with one
57
+ * item per selected leaf (`value` is the full leaf path, `label` its display label).
58
+ * When provided, the built-in selected count is not rendered.
59
+ */
60
+ renderInputValues?: (items: {
61
+ value: any;
62
+ label: string;
63
+ }[]) => React.ReactNode;
53
64
  };
54
65
  export declare function GridFilterTreeDropdown<T extends TreeListItem<any>>(props: GridFilterTreeDropdownProps<T>): React.JSX.Element;
@@ -399,17 +399,20 @@ export function TreeDropdown(props) {
399
399
  return (_jsx(MultiCombobox, { ...comboboxProps }));
400
400
  }
401
401
  export function GridFilterTreeDropdown(props) {
402
- const { showSelectedCount = false, placeholder = 'Select...', className, ...rest } = props;
402
+ const { showSelectedCount = false, placeholder = 'Select...', renderInputValues: renderInputValuesProp, className, ...rest } = props;
403
403
  const renderSelectedValues = useCallback(({ selectedLeafPaths, getLabelForPath }) => {
404
404
  let children;
405
405
  if (selectedLeafPaths.length === 0) {
406
406
  children = (_jsx("span", { "data-name": "placeholder", className: "twa:text-muted-foreground", children: placeholder }));
407
407
  }
408
+ else if (renderInputValuesProp) {
409
+ children = renderInputValuesProp(selectedLeafPaths.map((path) => ({ value: path, label: getLabelForPath(path) })));
410
+ }
408
411
  else {
409
412
  children = selectedLeafPaths.map((path) => getLabelForPath(path)).join(', ');
410
413
  }
411
- return (_jsxs("div", { className: "twa:text-ellipsis twa:overflow-hidden twa:whitespace-nowrap twa:flex-1000", "data-slot": "combobox-selected-values", children: [showSelectedCount && selectedLeafPaths.length > 0 && (_jsxs("span", { "data-name": "multiple-values-count", className: "twa:mr-0.5", children: ["(", selectedLeafPaths.length, ")"] })), children] }));
412
- }, [placeholder, showSelectedCount]);
414
+ return (_jsxs("div", { className: "twa:text-ellipsis twa:overflow-hidden twa:whitespace-nowrap twa:flex-1000", "data-slot": "combobox-selected-values", children: [showSelectedCount && !renderInputValuesProp && selectedLeafPaths.length > 0 && (_jsxs("span", { "data-name": "multiple-values-count", className: "twa:mr-0.5", children: ["(", selectedLeafPaths.length, ")"] })), children] }));
415
+ }, [placeholder, showSelectedCount, renderInputValuesProp]);
413
416
  const mergedClassName = cn(GRID_FILTER_COMBBOX_ADJUSTMENTS_CLASSNAME, className);
414
417
  return (_jsx(TreeDropdown, { ...rest, placeholder: placeholder, className: mergedClassName, showClear: rest.showClear ?? false, resizable: rest.resizable ?? true, renderSelectedValues: renderSelectedValues }));
415
418
  }
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: 1787139899825 || Date.now(),
4
- VERSION: "23.0.21" || '--current-version--',
3
+ PUBLISH_TIMESTAMP: 1789413930421 || Date.now(),
4
+ VERSION: "23.1.0-canary.0" || '--current-version--',
5
5
  };
@@ -104,6 +104,15 @@ export declare class LayoutManager<DATA_TYPE = any> extends LMEmitter {
104
104
  private computeColumnOrderAndVisibility;
105
105
  autoSizeColumns(columnIds?: string[]): false | string[];
106
106
  private applyPivotLayout;
107
+ /**
108
+ * Applies the layout state that targets pivot result columns (order, sorts, pinning).
109
+ *
110
+ * Must be called after the primary applyColumnState call(s) - i.e. after the pivot
111
+ * result columns have been (re)generated by AG Grid - because pivot result column
112
+ * state included in the same call that changes pivot/aggregation config is applied
113
+ * to the previous generation of pivot result columns (see AG Grid 36 notes in applyPivotLayout).
114
+ */
115
+ private applyPivotResultColumnsState;
107
116
  applyPivotTotals(layout: PivotLayoutModel): void;
108
117
  applyColumnGroupCollapseExpandState(layout: PivotLayoutModel | TableLayoutModel): void;
109
118
  private withSuppressColumnAnimation;