@adaptabletools/adaptable 20.1.4 → 20.1.6
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 +1 -0
- package/base.css.map +1 -1
- package/index.css +1 -0
- package/index.css.map +1 -1
- package/package.json +1 -1
- package/src/AdaptableInterfaces/IAdaptable.d.ts +3 -1
- package/src/AdaptableState/Common/AdaptableFilterState.d.ts +1 -1
- package/src/AdaptableState/Common/AdaptableSortState.d.ts +8 -3
- package/src/Api/CustomSortApi.d.ts +19 -9
- package/src/Api/GridApi.d.ts +3 -3
- package/src/Api/Implementation/CustomSortApiImpl.d.ts +3 -0
- package/src/Api/Implementation/CustomSortApiImpl.js +36 -0
- package/src/Api/Implementation/LayoutApiImpl.js +1 -1
- package/src/Api/Implementation/LayoutHelpers.d.ts +3 -3
- package/src/Api/Implementation/LayoutHelpers.js +126 -79
- package/src/Api/Implementation/StateApiImpl.d.ts +1 -2
- package/src/Api/Implementation/StateApiImpl.js +2 -4
- package/src/Api/Internal/EventInternalApi.d.ts +1 -1
- package/src/Api/Internal/EventInternalApi.js +11 -9
- package/src/Redux/ActionsReducers/LayoutRedux.js +24 -1
- package/src/Redux/Store/AdaptableStore.js +7 -4
- package/src/View/Components/FilterForm/ListBoxFilterForm.js +1 -1
- package/src/agGrid/AdaptableAgGrid.d.ts +7 -10
- package/src/agGrid/AdaptableAgGrid.js +80 -108
- package/src/components/ExpressionEditor/BaseEditorInput.js +2 -0
- package/src/components/Select/Select.d.ts +1 -0
- package/src/components/Select/Select.js +43 -17
- package/src/env.js +2 -2
- package/src/layout-manager/src/LayoutManagerModel.d.ts +29 -2
- package/src/layout-manager/src/index.d.ts +3 -0
- package/src/layout-manager/src/index.js +101 -30
- package/src/layout-manager/src/isLayoutEqual.js +11 -2
- package/src/layout-manager/src/normalizeLayoutModel.js +6 -0
- package/src/layout-manager/src/simplifyLayoutModel.js +3 -3
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -143,7 +143,6 @@ const adaptableInstances = {};
|
|
|
143
143
|
const publishTimestamp = Number(ADAPTABLE_PUBLISH_TIMESTAMP);
|
|
144
144
|
export class AdaptableAgGrid {
|
|
145
145
|
constructor(config) {
|
|
146
|
-
this.filteredOutPrimaryKeys = new Set();
|
|
147
146
|
this.columnMinMaxValuesCache = {};
|
|
148
147
|
this.renderReactRoot = (node, container) => defaultRenderReactRoot(node, container);
|
|
149
148
|
/**
|
|
@@ -380,9 +379,7 @@ export class AdaptableAgGrid {
|
|
|
380
379
|
gridApi: agGridApi,
|
|
381
380
|
debugId: this.adaptableOptions.adaptableId,
|
|
382
381
|
});
|
|
383
|
-
this.
|
|
384
|
-
normalize: true,
|
|
385
|
-
});
|
|
382
|
+
this.silentUpdateCurrentLayoutModel(layoutModel);
|
|
386
383
|
// this shouldn't be needed
|
|
387
384
|
// but AG Grid has a bug, and in pivot layout,
|
|
388
385
|
// even if we provide an initial AG Grid state with
|
|
@@ -395,8 +392,7 @@ export class AdaptableAgGrid {
|
|
|
395
392
|
});
|
|
396
393
|
}
|
|
397
394
|
this.layoutManager.onChange((layoutModel) => {
|
|
398
|
-
const
|
|
399
|
-
const newLayoutObject = layoutModelToLayoutState(layoutModel, currentLayout);
|
|
395
|
+
const newLayoutObject = layoutModelToLayoutState(layoutModel);
|
|
400
396
|
this.onLayoutChange(newLayoutObject);
|
|
401
397
|
});
|
|
402
398
|
this.layoutManager.onColumnDefsChanged(() => {
|
|
@@ -405,7 +401,7 @@ export class AdaptableAgGrid {
|
|
|
405
401
|
this.logger.info(`Hide Loading Screen`);
|
|
406
402
|
this.unmountLoadingScreen?.();
|
|
407
403
|
perfInitAgGrid.end();
|
|
408
|
-
// we need to intercept several AG Grid Api methods and trigger
|
|
404
|
+
// we need to intercept several AG Grid Api methods and trigger Adaptable state changes
|
|
409
405
|
this.agGridAdapter.setAgGridApi(agGridApi);
|
|
410
406
|
this.agGridAdapter.monkeyPatchingGridOptionsUpdates(agGridApi);
|
|
411
407
|
this.lifecycleState = 'agGridReady';
|
|
@@ -428,7 +424,6 @@ export class AdaptableAgGrid {
|
|
|
428
424
|
this.refreshHeader();
|
|
429
425
|
const currentLayout = this.api.layoutApi.getCurrentLayout();
|
|
430
426
|
checkForDuplicateColumns(currentLayout);
|
|
431
|
-
this.layoutManager.silentSetCurrentLayout(layoutStateToLayoutModel(currentLayout));
|
|
432
427
|
if (isPivotLayout(currentLayout)) {
|
|
433
428
|
// this is very very strange!
|
|
434
429
|
// for some projects, if the initial layout is pivot, the columnDefs of the pivot resutl columns are NOT derived correctly from the main colDefs
|
|
@@ -548,6 +543,21 @@ You need to define at least one Layout!`);
|
|
|
548
543
|
state.ToolPanel = toolPanelState;
|
|
549
544
|
return state;
|
|
550
545
|
}
|
|
546
|
+
getCurrentLayoutModel() {
|
|
547
|
+
const currentLayout = this.api.layoutApi.getCurrentLayout();
|
|
548
|
+
if (!currentLayout) {
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
return layoutStateToLayoutModel(currentLayout);
|
|
552
|
+
}
|
|
553
|
+
silentUpdateCurrentLayoutModel(layoutModel = this.getCurrentLayoutModel()) {
|
|
554
|
+
if (!layoutModel) {
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
this.layoutManager.silentSetCurrentLayout(layoutModel, {
|
|
558
|
+
normalize: true,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
551
561
|
applyFiltering() {
|
|
552
562
|
const agGridApi = this.agGridAdapter.getAgGridApi();
|
|
553
563
|
this._emit('AdapTableFiltersApplied');
|
|
@@ -763,12 +773,7 @@ You need to define at least one Layout!`);
|
|
|
763
773
|
* `doesExternalFilterPass`
|
|
764
774
|
*/
|
|
765
775
|
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'doesExternalFilterPass', (original_doesExternalFilterPass) => {
|
|
766
|
-
const { filteredOutPrimaryKeys } = this;
|
|
767
|
-
filteredOutPrimaryKeys.clear();
|
|
768
776
|
return (node) => {
|
|
769
|
-
if (node.rowIndex === 0) {
|
|
770
|
-
filteredOutPrimaryKeys.clear();
|
|
771
|
-
}
|
|
772
777
|
if (!this.isAvailable) {
|
|
773
778
|
return true;
|
|
774
779
|
}
|
|
@@ -800,14 +805,12 @@ You need to define at least one Layout!`);
|
|
|
800
805
|
// Not sure about this - what should we do with an invalid Grid Filter?
|
|
801
806
|
// Here we essentially clear the Grid for invalid Grid Filter by returning false for each row
|
|
802
807
|
if (!isCurrentGridFilterValid) {
|
|
803
|
-
filteredOutPrimaryKeys.add(primaryKey);
|
|
804
808
|
return false;
|
|
805
809
|
}
|
|
806
810
|
const gridFilterEvaluationResult = this.api.internalApi
|
|
807
811
|
.getQueryLanguageService()
|
|
808
812
|
.evaluateBooleanExpression(currentGridFilterExpression, GridFilterModuleId, node);
|
|
809
813
|
if (!gridFilterEvaluationResult) {
|
|
810
|
-
filteredOutPrimaryKeys.add(primaryKey);
|
|
811
814
|
return false;
|
|
812
815
|
}
|
|
813
816
|
}
|
|
@@ -821,7 +824,6 @@ You need to define at least one Layout!`);
|
|
|
821
824
|
if (evaluateColumnFilterOnClient) {
|
|
822
825
|
const columnFilterEvaluationResult = this.api.filterApi.columnFilterApi.internalApi.evaluateColumnFilter(columnFilter, node);
|
|
823
826
|
if (!columnFilterEvaluationResult) {
|
|
824
|
-
filteredOutPrimaryKeys.add(primaryKey);
|
|
825
827
|
return false;
|
|
826
828
|
}
|
|
827
829
|
}
|
|
@@ -830,15 +832,11 @@ You need to define at least one Layout!`);
|
|
|
830
832
|
}
|
|
831
833
|
catch (ex) {
|
|
832
834
|
this.logger.error(ex);
|
|
833
|
-
filteredOutPrimaryKeys.add(primaryKey);
|
|
834
835
|
return false;
|
|
835
836
|
}
|
|
836
837
|
const result = original_doesExternalFilterPass
|
|
837
838
|
? original_doesExternalFilterPass(node)
|
|
838
839
|
: true;
|
|
839
|
-
if (!result) {
|
|
840
|
-
filteredOutPrimaryKeys.add(primaryKey);
|
|
841
|
-
}
|
|
842
840
|
return result;
|
|
843
841
|
};
|
|
844
842
|
});
|
|
@@ -1353,8 +1351,8 @@ You need to define at least one Layout!`);
|
|
|
1353
1351
|
* Action2: Set Selected Cells (on a debounce)
|
|
1354
1352
|
*/
|
|
1355
1353
|
this.agGridAdapter.getAgGridApi().addEventListener('sortChanged', (this.listenerSortChanged = () => {
|
|
1356
|
-
this.api.eventApi.internalApi.fireGridSortedEvent();
|
|
1357
1354
|
this.debouncedSetSelectedCells();
|
|
1355
|
+
this.api.eventApi.internalApi.fireGridSortedEvent();
|
|
1358
1356
|
}));
|
|
1359
1357
|
/**
|
|
1360
1358
|
* Use Case: Charts have been created or destroyed, Chart ranges selected or Chart options changed
|
|
@@ -1617,6 +1615,17 @@ You need to define at least one Layout!`);
|
|
|
1617
1615
|
}
|
|
1618
1616
|
return this.createGridCell(rowNode, columnId);
|
|
1619
1617
|
}
|
|
1618
|
+
isRowNodeAvailableAfterFiltering(rowNode) {
|
|
1619
|
+
if (rowNode.displayed) {
|
|
1620
|
+
return true;
|
|
1621
|
+
}
|
|
1622
|
+
const parentRowNode = rowNode.parent;
|
|
1623
|
+
if (parentRowNode == null || parentRowNode.id == 'ROOT_NODE_ID') {
|
|
1624
|
+
return false;
|
|
1625
|
+
}
|
|
1626
|
+
const foundNode = parentRowNode.childrenAfterFilter?.find((c) => c.id == rowNode.id);
|
|
1627
|
+
return foundNode != null;
|
|
1628
|
+
}
|
|
1620
1629
|
/**
|
|
1621
1630
|
* Use (lazy evaluated) getters to avoid unnecessary calculations and memoization to avoid recalculating the same values
|
|
1622
1631
|
*/
|
|
@@ -1647,7 +1656,7 @@ You need to define at least one Layout!`);
|
|
|
1647
1656
|
return getRawValue();
|
|
1648
1657
|
},
|
|
1649
1658
|
get visible() {
|
|
1650
|
-
return self.
|
|
1659
|
+
return self.isRowNodeAvailableAfterFiltering(rowNode);
|
|
1651
1660
|
},
|
|
1652
1661
|
get displayValue() {
|
|
1653
1662
|
if (_displayValue === undefined) {
|
|
@@ -2289,9 +2298,6 @@ You need to define at least one Layout!`);
|
|
|
2289
2298
|
return gridCells;
|
|
2290
2299
|
}
|
|
2291
2300
|
}
|
|
2292
|
-
isPrimaryKeyVisible(primaryKey) {
|
|
2293
|
-
return !this.filteredOutPrimaryKeys.has(primaryKey);
|
|
2294
|
-
}
|
|
2295
2301
|
addDistinctColumnValue(rowNode, columnId) {
|
|
2296
2302
|
// we do not return the values of the aggregates when in grouping mode
|
|
2297
2303
|
// otherwise they would appear in the filter dropdown etc....
|
|
@@ -2318,29 +2324,39 @@ You need to define at least one Layout!`);
|
|
|
2318
2324
|
}
|
|
2319
2325
|
return value;
|
|
2320
2326
|
};
|
|
2327
|
+
const self = this;
|
|
2328
|
+
// those are grid cells unique per primary key - so cells corresponding to this column
|
|
2329
|
+
// by for every row in the grid
|
|
2330
|
+
// but here we want to collapse them down to values/cells unique by the
|
|
2331
|
+
// value of this column: eg - if this is country column and we have multiple rownodes
|
|
2332
|
+
// in the grid with country: UK, and multiple with country: France, then the end result
|
|
2333
|
+
// of the current function should be 2 cells: one for UK and one for France
|
|
2321
2334
|
gridCells.forEach((dataItem) => {
|
|
2322
2335
|
const value = getter(dataItem);
|
|
2323
|
-
const primaryKey = dataItem.primaryKeyValue;
|
|
2324
2336
|
if (!cache.has(value)) {
|
|
2325
2337
|
cache.set(value, {
|
|
2326
2338
|
count: 1,
|
|
2327
2339
|
cell: dataItem,
|
|
2328
|
-
|
|
2340
|
+
rowNodesWithSameCellValue: [dataItem.rowNode],
|
|
2329
2341
|
});
|
|
2330
2342
|
}
|
|
2331
2343
|
else {
|
|
2332
2344
|
const data = cache.get(value);
|
|
2333
2345
|
data.count++;
|
|
2334
|
-
data.
|
|
2346
|
+
data.rowNodesWithSameCellValue.push(dataItem.rowNode);
|
|
2335
2347
|
}
|
|
2336
2348
|
});
|
|
2337
2349
|
const result = [];
|
|
2338
|
-
cache.forEach(({ count, cell,
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2350
|
+
cache.forEach(({ count, cell, rowNodesWithSameCellValue }) => {
|
|
2351
|
+
const cellWithCount = cell;
|
|
2352
|
+
cellWithCount.count = count;
|
|
2353
|
+
// the visibility of this cell is true if any of the row nodes with this value is visible
|
|
2354
|
+
Object.defineProperty(cellWithCount, 'visible', {
|
|
2355
|
+
get: () => {
|
|
2356
|
+
return (rowNodesWithSameCellValue.findIndex((pk) => self.isRowNodeAvailableAfterFiltering(pk) === true) !== -1);
|
|
2357
|
+
},
|
|
2343
2358
|
});
|
|
2359
|
+
result.push(cellWithCount);
|
|
2344
2360
|
});
|
|
2345
2361
|
return result;
|
|
2346
2362
|
}
|
|
@@ -2814,57 +2830,23 @@ You need to define at least one Layout!`);
|
|
|
2814
2830
|
config.destroyAgGrid = true;
|
|
2815
2831
|
}
|
|
2816
2832
|
}
|
|
2817
|
-
this.
|
|
2833
|
+
this.__prevLayoutForRefresh = undefined;
|
|
2818
2834
|
this.layoutManager?.destroy();
|
|
2819
2835
|
this.layoutManager = null;
|
|
2820
|
-
this.
|
|
2821
|
-
if (
|
|
2822
|
-
this.
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
this.
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
this.agGridAdapter
|
|
2829
|
-
.getAgGridApi()
|
|
2830
|
-
.removeEventListener('cellEditingStarted', this.listenerCellEditingStarted);
|
|
2831
|
-
this.agGridAdapter
|
|
2832
|
-
.getAgGridApi()
|
|
2833
|
-
.removeEventListener('columnRowGroupChanged', this.listenerColumnRowGroupChanged);
|
|
2834
|
-
this.agGridAdapter
|
|
2835
|
-
.getAgGridApi()
|
|
2836
|
-
.removeEventListener('cellSelectionChanged', this.listenerCellSelectionChanged);
|
|
2837
|
-
this.agGridAdapter
|
|
2838
|
-
.getAgGridApi()
|
|
2839
|
-
.removeEventListener('columnResized', this.listenerColumnResized);
|
|
2840
|
-
this.agGridAdapter
|
|
2841
|
-
.getAgGridApi()
|
|
2842
|
-
.removeEventListener('sortChanged', this.listenerSortChanged);
|
|
2843
|
-
this.agGridAdapter
|
|
2844
|
-
.getAgGridApi()
|
|
2845
|
-
.removeEventListener('modelUpdated', this.listenerModelUpdated);
|
|
2846
|
-
this.agGridAdapter.getAgGridApi().removeGlobalListener(this.listenerGlobalSetRowSelection);
|
|
2847
|
-
this.agGridAdapter
|
|
2848
|
-
.getAgGridApi()
|
|
2849
|
-
.removeGlobalListener(this.listenerGlobalColumnEventsThatTriggerStateChange);
|
|
2850
|
-
this.agGridAdapter
|
|
2851
|
-
.getAgGridApi()
|
|
2852
|
-
.removeGlobalListener(this.listenerGlobalColumnEventsThatTriggerAutoLayoutSave);
|
|
2853
|
-
this.agGridAdapter
|
|
2854
|
-
.getAgGridApi()
|
|
2855
|
-
.removeGlobalListener(this.listenerGlobalRowGroupEventsThatTriggerAutoLayoutSave);
|
|
2836
|
+
const agGridApi = this.agGridAdapter?.getAgGridApi();
|
|
2837
|
+
if (agGridApi && !agGridApi.isDestroyed()) {
|
|
2838
|
+
agGridApi.removeEventListener('firstDataRendered', this.listenerFirstDataRendered);
|
|
2839
|
+
agGridApi.removeEventListener('columnPivotChanged', this.listenerPivotChanged);
|
|
2840
|
+
agGridApi.removeEventListener('cellEditingStarted', this.listenerCellEditingStarted);
|
|
2841
|
+
agGridApi.removeEventListener('cellSelectionChanged', this.listenerCellSelectionChanged);
|
|
2842
|
+
agGridApi.removeEventListener('sortChanged', this.listenerSortChanged);
|
|
2843
|
+
agGridApi.removeGlobalListener(this.listenerGlobalSetRowSelection);
|
|
2856
2844
|
this.listenerFirstDataRendered = null;
|
|
2857
2845
|
this.listenerPivotChanged = null;
|
|
2858
2846
|
this.listenerCellEditingStarted = null;
|
|
2859
|
-
this.listenerColumnRowGroupChanged = null;
|
|
2860
2847
|
this.listenerCellSelectionChanged = null;
|
|
2861
|
-
this.listenerColumnResized = null;
|
|
2862
2848
|
this.listenerGlobalSetRowSelection = null;
|
|
2863
2849
|
this.listenerSortChanged = null;
|
|
2864
|
-
this.listenerModelUpdated = null;
|
|
2865
|
-
this.listenerGlobalColumnEventsThatTriggerStateChange = null;
|
|
2866
|
-
this.listenerGlobalColumnEventsThatTriggerAutoLayoutSave = null;
|
|
2867
|
-
this.listenerGlobalRowGroupEventsThatTriggerAutoLayoutSave = null;
|
|
2868
2850
|
this.throttleFilterOnDataChange = null;
|
|
2869
2851
|
const liveGridOptions = this.agGridAdapter.DANGER_getLiveGridOptions();
|
|
2870
2852
|
if (liveGridOptions) {
|
|
@@ -3007,10 +2989,7 @@ You need to define at least one Layout!`);
|
|
|
3007
2989
|
getChartRef(chartId) {
|
|
3008
2990
|
return this.agGridAdapter.getAgGridApi().getChartRef(chartId);
|
|
3009
2991
|
}
|
|
3010
|
-
|
|
3011
|
-
if (!layout) {
|
|
3012
|
-
layout = this.api.layoutApi.getCurrentLayout();
|
|
3013
|
-
}
|
|
2992
|
+
updateLayoutInManagerAfterStoreHasChanged(layout = this.api.layoutApi.getCurrentLayout()) {
|
|
3014
2993
|
checkForDuplicateColumns(layout);
|
|
3015
2994
|
const isLayoutSwitch = this._prevLayout && layout.Name != this._prevLayout.Name;
|
|
3016
2995
|
let shouldUpdateExpandState = isLayoutSwitch;
|
|
@@ -3045,9 +3024,11 @@ You need to define at least one Layout!`);
|
|
|
3045
3024
|
// and is specific to Adaptable, therefore we need to refresh it manually
|
|
3046
3025
|
this.refreshHeader();
|
|
3047
3026
|
const layoutModel = layoutStateToLayoutModel(layout);
|
|
3048
|
-
|
|
3027
|
+
this.layoutManager?.setLayout(layoutModel, {
|
|
3049
3028
|
skipApplyRowGroupsExpandedState: !shouldUpdateExpandState,
|
|
3029
|
+
skipTriggerChange: true,
|
|
3050
3030
|
});
|
|
3031
|
+
this.refreshAdaptableAfterLayoutChange(layout);
|
|
3051
3032
|
if (layout.AutoSizeColumns) {
|
|
3052
3033
|
if (isPivot) {
|
|
3053
3034
|
requestAnimationFrame(() => {
|
|
@@ -3068,15 +3049,6 @@ You need to define at least one Layout!`);
|
|
|
3068
3049
|
plugin.afterSetLayout(this, layout);
|
|
3069
3050
|
}
|
|
3070
3051
|
});
|
|
3071
|
-
if (!layoutChanged) {
|
|
3072
|
-
// we won't get an onLayoutChange event
|
|
3073
|
-
// most likely only filters have changed (column or grid filters)
|
|
3074
|
-
// and because filters are not part of the layout manager
|
|
3075
|
-
// there will be no change to the layout
|
|
3076
|
-
// so we need to manually trigger the onLayoutChange event
|
|
3077
|
-
// for other layout-related updates
|
|
3078
|
-
this.onLayoutChange(layout, { skipRefresh: true });
|
|
3079
|
-
}
|
|
3080
3052
|
perfSetLayout.end();
|
|
3081
3053
|
}
|
|
3082
3054
|
getActiveAdaptableAggFuncForCol(columnId) {
|
|
@@ -3355,7 +3327,7 @@ You need to define at least one Layout!`);
|
|
|
3355
3327
|
this.agGridAdapter.setGridOption('columnDefs', columnDefs);
|
|
3356
3328
|
// this is needed here for when we call setAdaptableStateKey
|
|
3357
3329
|
// and pass a new config
|
|
3358
|
-
this.
|
|
3330
|
+
this.updateLayoutInManagerAfterStoreHasChanged();
|
|
3359
3331
|
this.applyFiltering();
|
|
3360
3332
|
}
|
|
3361
3333
|
isRowGroupDifferentInLayout(one, other) {
|
|
@@ -3385,25 +3357,25 @@ You need to define at least one Layout!`);
|
|
|
3385
3357
|
};
|
|
3386
3358
|
return hasPivotTotals(one) || hasPivotTotals(other);
|
|
3387
3359
|
}
|
|
3388
|
-
onLayoutChange(layout
|
|
3389
|
-
this.
|
|
3390
|
-
const skipRefresh = options?.skipRefresh;
|
|
3391
|
-
if (!skipRefresh) {
|
|
3392
|
-
const prevOnChangeLayout = this.__prevLayoutForOnChange || this.api.layoutApi.getCurrentLayout();
|
|
3393
|
-
// see #on-regroup-expect-group-column-to-be-recomputed-and-setup-properly
|
|
3394
|
-
const rowGroupsChanged = this.isRowGroupDifferentInLayout(prevOnChangeLayout, layout);
|
|
3395
|
-
const hasPivotTotalsInLayout = this.hasPivotTotalsInLayout(prevOnChangeLayout, layout);
|
|
3396
|
-
const pivotColsChanged = JSON.stringify(layout.PivotColumns) !== JSON.stringify(prevOnChangeLayout.PivotColumns);
|
|
3397
|
-
if (rowGroupsChanged || pivotColsChanged || hasPivotTotalsInLayout) {
|
|
3398
|
-
this.updateColumnModelAndRefreshGrid();
|
|
3399
|
-
}
|
|
3400
|
-
else {
|
|
3401
|
-
this.deriveAdaptableColumnStateFromAgGrid();
|
|
3402
|
-
}
|
|
3403
|
-
}
|
|
3404
|
-
this.__prevLayoutForOnChange = layout;
|
|
3360
|
+
onLayoutChange(layout) {
|
|
3361
|
+
this.refreshAdaptableAfterLayoutChange(layout);
|
|
3405
3362
|
this.api.layoutApi.createOrUpdateLayout(layout);
|
|
3406
3363
|
}
|
|
3364
|
+
refreshAdaptableAfterLayoutChange(layout) {
|
|
3365
|
+
this.logger.info('refreshAdaptableAfterLayoutChange()');
|
|
3366
|
+
const prevLayoutForRefresh = this.__prevLayoutForRefresh || this.api.layoutApi.getCurrentLayout();
|
|
3367
|
+
// see #on-regroup-expect-group-column-to-be-recomputed-and-setup-properly
|
|
3368
|
+
const rowGroupsChanged = this.isRowGroupDifferentInLayout(prevLayoutForRefresh, layout);
|
|
3369
|
+
const hasPivotTotalsInLayout = this.hasPivotTotalsInLayout(prevLayoutForRefresh, layout);
|
|
3370
|
+
const pivotColsChanged = JSON.stringify(layout.PivotColumns) !== JSON.stringify(prevLayoutForRefresh.PivotColumns);
|
|
3371
|
+
if (rowGroupsChanged || pivotColsChanged || hasPivotTotalsInLayout) {
|
|
3372
|
+
this.updateColumnModelAndRefreshGrid();
|
|
3373
|
+
}
|
|
3374
|
+
else {
|
|
3375
|
+
this.deriveAdaptableColumnStateFromAgGrid();
|
|
3376
|
+
}
|
|
3377
|
+
this.__prevLayoutForRefresh = layout;
|
|
3378
|
+
}
|
|
3407
3379
|
validateColumnDefTypes(columnDefs) {
|
|
3408
3380
|
// in Adaptable version 20 we switched from colDef.type to colDef.cellDataType
|
|
3409
3381
|
// although we documented this change and try to infer the correct cellDataTypes, it's best to also check if the client dev forgot to adjust his colDefs
|
|
@@ -24,6 +24,7 @@ const filterableCategories = [
|
|
|
24
24
|
'logical',
|
|
25
25
|
'maths',
|
|
26
26
|
'strings',
|
|
27
|
+
'changes',
|
|
27
28
|
'comparison',
|
|
28
29
|
'observable',
|
|
29
30
|
'aggregation',
|
|
@@ -38,6 +39,7 @@ const getCategoryOrder = (category) => {
|
|
|
38
39
|
strings: 5,
|
|
39
40
|
maths: 6,
|
|
40
41
|
dates: 7,
|
|
42
|
+
changes: 8,
|
|
41
43
|
};
|
|
42
44
|
return predefinedOrder[category] || 0;
|
|
43
45
|
};
|
|
@@ -14,6 +14,7 @@ export type SelectProps<SelectValue extends unknown, IsMulti extends boolean = f
|
|
|
14
14
|
menuStyle?: React.CSSProperties;
|
|
15
15
|
menuMinWidth?: string | number;
|
|
16
16
|
searchable?: boolean;
|
|
17
|
+
resizable?: boolean;
|
|
17
18
|
isClearable?: boolean;
|
|
18
19
|
closeMenuOnSelect?: boolean;
|
|
19
20
|
hideSelectedOptions?: boolean;
|
|
@@ -4,9 +4,18 @@ import ReactSelect, { components, } from 'react-select';
|
|
|
4
4
|
import CreatableSelect from 'react-select/creatable';
|
|
5
5
|
import { Icon } from '../icons';
|
|
6
6
|
import { Box } from 'rebass';
|
|
7
|
-
import { DataSource, InfiniteTable, } from '@infinite-table/infinite-react';
|
|
8
|
-
import { useMemo } from 'react';
|
|
7
|
+
import { DataSource, InfiniteTable, components as InfiniteTableComponents, } from '@infinite-table/infinite-react';
|
|
8
|
+
import { useCallback, useMemo } from 'react';
|
|
9
9
|
import join from '../utils/join';
|
|
10
|
+
import { Resizable } from 're-resizable';
|
|
11
|
+
const resizableDirections = {
|
|
12
|
+
right: true,
|
|
13
|
+
bottom: true,
|
|
14
|
+
bottomRight: true,
|
|
15
|
+
};
|
|
16
|
+
const defaultResizableSize = {
|
|
17
|
+
width: '100%',
|
|
18
|
+
};
|
|
10
19
|
const checkboxStyle = {
|
|
11
20
|
position: 'relative',
|
|
12
21
|
top: 1,
|
|
@@ -15,7 +24,7 @@ const INFINITE_DOM_PROPS = {
|
|
|
15
24
|
style: {
|
|
16
25
|
height: '100%',
|
|
17
26
|
minHeight: `var(--ab-cmp-select-menu__min-height, 25rem)`,
|
|
18
|
-
maxHeight: '50vh',
|
|
27
|
+
// maxHeight: '50vh',
|
|
19
28
|
width: '100%',
|
|
20
29
|
},
|
|
21
30
|
};
|
|
@@ -28,7 +37,12 @@ const INFINITE_COLUMNS_WITH_CHECKBOX = {
|
|
|
28
37
|
},
|
|
29
38
|
resizable: false,
|
|
30
39
|
defaultSortable: false,
|
|
31
|
-
renderSelectionCheckBox:
|
|
40
|
+
renderSelectionCheckBox: (params) => {
|
|
41
|
+
// disable reacting to onChange
|
|
42
|
+
// as we handle selection change in the onCellClick
|
|
43
|
+
return React.createElement(InfiniteTableComponents.CheckBox, { checked: params.rowInfo?.rowSelected ?? false });
|
|
44
|
+
},
|
|
45
|
+
renderHeaderSelectionCheckBox: true,
|
|
32
46
|
className: 'ab-Select-CheckboxColumn',
|
|
33
47
|
renderValue: ({ renderBag }) => {
|
|
34
48
|
return React.createElement("div", { className: "InfiniteCell_content_value" }, renderBag.value);
|
|
@@ -148,6 +162,7 @@ export const Select = function (props) {
|
|
|
148
162
|
} }));
|
|
149
163
|
};
|
|
150
164
|
}, []);
|
|
165
|
+
const resizable = props.resizable ?? false;
|
|
151
166
|
const ValueContainer = React.useMemo(() => {
|
|
152
167
|
return (props) => {
|
|
153
168
|
let { children, ...inputProps } = props;
|
|
@@ -176,24 +191,33 @@ export const Select = function (props) {
|
|
|
176
191
|
} }, children));
|
|
177
192
|
};
|
|
178
193
|
}, [renderMultipleValues, props.placeholder]);
|
|
194
|
+
const sizeRef = React.useRef({ ...defaultResizableSize });
|
|
179
195
|
const MenuComponent = React.useMemo(() => {
|
|
180
196
|
return (inputProps) => {
|
|
181
197
|
const { isLoading } = inputProps;
|
|
198
|
+
const theChildren = (React.createElement(React.Fragment, null,
|
|
199
|
+
inputProps.children,
|
|
200
|
+
React.createElement("div", { style: {
|
|
201
|
+
display: isLoading ? 'block' : 'none',
|
|
202
|
+
position: 'absolute',
|
|
203
|
+
inset: 0,
|
|
204
|
+
background: `var(--ab-cmp-select-loading__background)`,
|
|
205
|
+
zIndex: 1,
|
|
206
|
+
} })));
|
|
207
|
+
const onResizeStop = useCallback((_e, _direction, ref) => {
|
|
208
|
+
const newSize = {
|
|
209
|
+
width: ref.style.width,
|
|
210
|
+
height: ref.style.height,
|
|
211
|
+
};
|
|
212
|
+
sizeRef.current = newSize;
|
|
213
|
+
}, []);
|
|
182
214
|
return (React.createElement(React.Fragment, null,
|
|
183
215
|
React.createElement(components.Menu, { ...inputProps, innerProps: {
|
|
184
216
|
'data-name': 'menu-container',
|
|
185
217
|
...inputProps.innerProps,
|
|
186
|
-
} },
|
|
187
|
-
inputProps.children,
|
|
188
|
-
React.createElement("div", { style: {
|
|
189
|
-
display: isLoading ? 'block' : 'none',
|
|
190
|
-
position: 'absolute',
|
|
191
|
-
inset: 0,
|
|
192
|
-
background: `var(--ab-cmp-select-loading__background)`,
|
|
193
|
-
zIndex: 1,
|
|
194
|
-
} }))));
|
|
218
|
+
} }, resizable ? (React.createElement(Resizable, { enable: resizableDirections, minWidth: '100%', maxHeight: '60vh', maxWidth: '60vw', defaultSize: sizeRef.current, onResizeStop: onResizeStop }, theChildren)) : (theChildren))));
|
|
195
219
|
};
|
|
196
|
-
}, []);
|
|
220
|
+
}, [resizable]);
|
|
197
221
|
const SelectComponent = props.isCreatable ? CreatableSelect : ReactSelect;
|
|
198
222
|
const ClearIndicator = React.useMemo(() => {
|
|
199
223
|
return (clearIndicatorProps) => {
|
|
@@ -324,8 +348,10 @@ export const Select = function (props) {
|
|
|
324
348
|
setValue({ value }, 'select-option');
|
|
325
349
|
}, [setValue]);
|
|
326
350
|
const onCellClick = React.useCallback(({ rowIndex, api, dataSourceApi }) => {
|
|
327
|
-
|
|
328
|
-
|
|
351
|
+
if (isMulti) {
|
|
352
|
+
const pk = dataSourceApi.getPrimaryKeyByIndex(rowIndex);
|
|
353
|
+
api.rowSelectionApi.toggleRowSelection(pk);
|
|
354
|
+
}
|
|
329
355
|
// see #ensure-select-closes-after-clicking-outside
|
|
330
356
|
requestAnimationFrame(() => {
|
|
331
357
|
ref.current?.focus();
|
|
@@ -425,7 +451,7 @@ export const Select = function (props) {
|
|
|
425
451
|
zIndex: 999999,
|
|
426
452
|
boxShadow: 'var(--ab-cmp-select-menu__box-shadow)',
|
|
427
453
|
minWidth: `var(--ab-cmp-select-menu__min-width)`,
|
|
428
|
-
width: `${Math.max(maxLabelLength, 10)}ch`,
|
|
454
|
+
width: resizable ? '100%' : `${Math.max(maxLabelLength, 10)}ch`,
|
|
429
455
|
'--ab-cmp-select-menu__min-height': `min(${(props.options || []).length + (showHeaderSelectionCheckbox ? 1 : 0)} * var(--ab-grid-row-height), 20rem)`,
|
|
430
456
|
maxHeight: 'var(--ab-cmp-select-menu__max-height)',
|
|
431
457
|
maxWidth: 'var(--ab-cmp-select-menu__max-width)',
|
package/src/env.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
NEXT_PUBLIC_INFINITE_TABLE_LICENSE_KEY: "StartDate=2021-06-29|EndDate=2030-01-01|Owner=Adaptable|Type=distribution|TS=1624971462479|C=137829811,1004007071,2756196225,1839832928,3994409405,636616862" || '',
|
|
3
|
-
PUBLISH_TIMESTAMP:
|
|
4
|
-
VERSION: "20.1.
|
|
3
|
+
PUBLISH_TIMESTAMP: 1748524771920 || Date.now(),
|
|
4
|
+
VERSION: "20.1.6" || '--current-version--',
|
|
5
5
|
};
|
|
@@ -18,11 +18,38 @@ export interface BaseLayoutModel {
|
|
|
18
18
|
* fully specified back to Adaptable, with this prop
|
|
19
19
|
* set as it was when we received it from Adaptable
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
Ignore_ColumnFilters?: any[];
|
|
22
22
|
/**
|
|
23
23
|
* Same as ColumnFilters, but for Grid Filter
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
Ignore_GridFilter?: any;
|
|
26
|
+
/**
|
|
27
|
+
* Same as AutoSizeColumns, but for Pivot Layout
|
|
28
|
+
*/
|
|
29
|
+
Ignore_AutoSizeColumns?: any;
|
|
30
|
+
/**
|
|
31
|
+
* Same as above, but for IsReadOnly
|
|
32
|
+
*/
|
|
33
|
+
Ignore_IsReadOnly?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Same as above, but for Tags
|
|
36
|
+
*/
|
|
37
|
+
Ignore_Tags?: any[];
|
|
38
|
+
/**
|
|
39
|
+
* Same as RowSummaries, but for Pivot Layout
|
|
40
|
+
*/
|
|
41
|
+
Ignore_RowSummaries?: any;
|
|
42
|
+
/**
|
|
43
|
+
* Same as above, but
|
|
44
|
+
*/
|
|
45
|
+
Ignore_Name?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Same as above, but for Column Headers
|
|
48
|
+
*/
|
|
49
|
+
Ignore_ColumnHeaders?: any;
|
|
50
|
+
Ignore_Source?: string;
|
|
51
|
+
Ignore_AdaptableVersion?: string;
|
|
52
|
+
Ignore_Uuid?: string;
|
|
26
53
|
ColumnVisibility?: {
|
|
27
54
|
[columnId: string]: false;
|
|
28
55
|
};
|
|
@@ -54,8 +54,11 @@ export declare class LayoutManager<DATA_TYPE = any> extends LMEmitter {
|
|
|
54
54
|
}): void;
|
|
55
55
|
setLayout(layout: TableLayoutModel | PivotLayoutModel, options?: ApplyLayoutOptions & {
|
|
56
56
|
force?: boolean;
|
|
57
|
+
skipTriggerChange?: boolean;
|
|
57
58
|
}): boolean;
|
|
58
59
|
isCurrentLayoutPivot(): boolean;
|
|
60
|
+
private suspendAgGridListener;
|
|
61
|
+
private resumeAgGridListener;
|
|
59
62
|
private applyLayout;
|
|
60
63
|
private applyTableLayout;
|
|
61
64
|
private getRowGroupNodePathsAs;
|