@adaptabletools/adaptable-cjs 22.0.0 → 22.0.1-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/package.json +1 -1
  2. package/src/AdaptableInterfaces/IAdaptable.d.ts +1 -0
  3. package/src/AdaptableOptions/AdaptablePlugin.d.ts +4 -0
  4. package/src/AdaptableOptions/AdaptablePlugin.js +1 -0
  5. package/src/Api/EventApi.d.ts +14 -2
  6. package/src/Api/Events/BeforeAdaptableStateChange.d.ts +20 -0
  7. package/src/Api/Events/BeforeAdaptableStateChange.js +2 -0
  8. package/src/Api/GridApi.d.ts +4 -0
  9. package/src/Api/Implementation/GridApiImpl.d.ts +1 -0
  10. package/src/Api/Implementation/GridApiImpl.js +3 -0
  11. package/src/Api/Implementation/RowFormApiImpl.d.ts +1 -0
  12. package/src/Api/Implementation/RowFormApiImpl.js +13 -0
  13. package/src/Api/Internal/ActionColumnInternalApi.js +2 -19
  14. package/src/Api/Internal/EventInternalApi.d.ts +1 -0
  15. package/src/Api/Internal/EventInternalApi.js +9 -0
  16. package/src/Api/Internal/ExportInternalApi.js +1 -1
  17. package/src/Api/RowFormApi.d.ts +5 -0
  18. package/src/Redux/Store/AdaptableStore.d.ts +2 -0
  19. package/src/Redux/Store/AdaptableStore.js +15 -0
  20. package/src/Redux/Store/Interface/IAdaptableStore.d.ts +1 -0
  21. package/src/Strategy/CellSummaryModule.d.ts +1 -0
  22. package/src/Strategy/CellSummaryModule.js +3 -0
  23. package/src/Strategy/LayoutModule.js +22 -18
  24. package/src/Strategy/PlusMinusModule.d.ts +1 -0
  25. package/src/Strategy/PlusMinusModule.js +8 -2
  26. package/src/Utilities/only.d.ts +6 -3
  27. package/src/Utilities/only.js +20 -34
  28. package/src/Utilities/weightedAverage.d.ts +11 -0
  29. package/src/Utilities/weightedAverage.js +59 -45
  30. package/src/agGrid/AdaptableAgGrid.d.ts +1 -0
  31. package/src/agGrid/AdaptableAgGrid.js +11 -1
  32. package/src/env.js +2 -2
  33. package/src/types.d.ts +1 -0
  34. package/tsconfig.cjs.tsbuildinfo +1 -1
@@ -11,56 +11,70 @@ const getNumericValue = (input) => {
11
11
  return isNaN(numericValue) ? null : numericValue;
12
12
  };
13
13
  exports.getNumericValue = getNumericValue;
14
- function getWeightedAverageLeafNodes(gridApi, groupRowNode, filteredOnly) {
15
- const nodeList = (filteredOnly ? groupRowNode.childrenAfterFilter : groupRowNode.childrenAfterGroup) ?? [];
16
- let leafNodes = [];
17
- nodeList.forEach((rowNode) => {
18
- if (rowNode.group === true) {
19
- // Recursively extract leaf nodes from group
20
- leafNodes = leafNodes.concat(getWeightedAverageLeafNodes(gridApi, rowNode, filteredOnly));
21
- }
22
- else {
23
- leafNodes.push(rowNode);
24
- }
25
- });
26
- return leafNodes;
27
- }
14
+ /**
15
+ * Computes a weighted average aggregation: Σ(value × weight) / Σ(weight)
16
+ *
17
+ * AG Grid calls agg functions bottom-up through the group hierarchy. For each group:
18
+ * - Leaf children contribute their raw value × weight
19
+ * - Sub-group children already have partial sums from a previous pass,
20
+ * so we combine those directly instead of re-traversing to leaves
21
+ *
22
+ * The returned object stores partial sums ([columnId] and [weightColumnId])
23
+ * so parent groups can combine sub-group results correctly.
24
+ */
28
25
  const weightedAverage = (params, columnId, weightColumnId) => {
29
- const { api: gridApi, rowNode: groupRowNode } = params;
30
- let weightedColumnValueSum = 0;
31
- let columnValueSum = 0;
32
- const filteredOnly = !gridApi.getGridOption('suppressAggFilteredOnly');
33
- const leafNodes = getWeightedAverageLeafNodes(gridApi, groupRowNode, filteredOnly);
34
- leafNodes.forEach((rowNode) => {
35
- // when editing values might be converted to strings
36
- const rawColumnValue = gridApi.getCellValue({ colKey: columnId, rowNode });
37
- const columnValue = (0, exports.getNumericValue)(rawColumnValue);
38
- const rawWeightedColumnValue = gridApi.getCellValue({ colKey: weightColumnId, rowNode });
39
- const weightedColumnValue = (0, exports.getNumericValue)(rawWeightedColumnValue);
40
- if (weightedColumnValue !== null) {
41
- weightedColumnValueSum += weightedColumnValue;
26
+ const { api: gridApi, rowNode: groupRowNode, values } = params;
27
+ // numerator: Σ(value × weight)
28
+ let weightedValueSum = 0;
29
+ // denominator: Σ(weight)
30
+ let totalWeight = 0;
31
+ // params.values already respects suppressAggFilteredOnly.
32
+ // We need the matching child nodes only for leaf rows (to look up weight column values).
33
+ const childNodes = getMatchingChildNodes(groupRowNode, values.length);
34
+ for (let i = 0; i < values.length; i++) {
35
+ const value = values[i];
36
+ if (value != null && typeof value === 'object') {
37
+ // sub-group: partial sums already computed by a previous aggregation pass
38
+ weightedValueSum += value[columnId] ?? 0;
39
+ totalWeight += value[weightColumnId] ?? 0;
42
40
  }
43
- if (columnValue !== null) {
44
- columnValueSum += columnValue * weightedColumnValue;
41
+ else {
42
+ // leaf row: compute value × weight from cell data
43
+ const childNode = childNodes[i];
44
+ if (!childNode) {
45
+ continue;
46
+ }
47
+ // values might be strings during editing
48
+ const columnValue = (0, exports.getNumericValue)(value);
49
+ const weightValue = (0, exports.getNumericValue)(gridApi.getCellValue({ colKey: weightColumnId, rowNode: childNode }));
50
+ if (weightValue !== null) {
51
+ totalWeight += weightValue;
52
+ }
53
+ if (columnValue !== null && weightValue !== null) {
54
+ weightedValueSum += columnValue * weightValue;
55
+ }
45
56
  }
46
- });
47
- let result = columnValueSum / weightedColumnValueSum;
48
- // 0 / 0 = NaN
49
- if (isNaN(result)) {
50
- result = 0;
51
57
  }
58
+ const result = totalWeight !== 0 ? weightedValueSum / totalWeight : 0;
52
59
  return {
53
- // the grid by default uses toString to render values for an object, so this
54
- // is a trick to get the default cellRenderer to display the avg value
55
- toString: () => {
56
- return String(result);
57
- },
58
- // used for sorting
59
- toNumber: function () {
60
- return result;
61
- },
62
- [columnId]: columnValueSum,
63
- [weightColumnId]: weightedColumnValueSum,
60
+ // toString/toNumber let AG Grid's default cell renderer display and sort the value
61
+ toString: () => String(result),
62
+ toNumber: () => result,
63
+ // partial sums stored so parent groups can combine sub-group results
64
+ [columnId]: weightedValueSum,
65
+ [weightColumnId]: totalWeight,
64
66
  };
65
67
  };
66
68
  exports.weightedAverage = weightedAverage;
69
+ /**
70
+ * Returns the child node list that corresponds to params.values.
71
+ * When suppressAggFilteredOnly is false, params.values comes from childrenAfterFilter.
72
+ * When true, it comes from childrenAfterGroup (all children).
73
+ * We match by length to pick the right list without checking the grid option directly.
74
+ */
75
+ function getMatchingChildNodes(groupRowNode, valueCount) {
76
+ if (groupRowNode.childrenAfterFilter?.length === valueCount) {
77
+ return groupRowNode.childrenAfterFilter;
78
+ }
79
+ return groupRowNode.childrenAfterGroup ?? [];
80
+ }
@@ -223,6 +223,7 @@ export declare class AdaptableAgGrid implements IAdaptable {
223
223
  redrawBody(): void;
224
224
  refreshHeader(): void;
225
225
  redrawRows(rowNodes?: IRowNode[]): void;
226
+ refreshGridHeader(): void;
226
227
  redrawRow(rowNode: IRowNode): void;
227
228
  refreshCell(rowNode: IRowNode, column: string | any, forceUpdate: boolean, suppressFlash?: boolean): void;
228
229
  refreshCells(rowNode: IRowNode, columns: (string | Column)[], forceUpdate: boolean, suppressFlash?: boolean): void;
@@ -961,6 +961,7 @@ class AdaptableAgGrid {
961
961
  if (rowGroupDisplayType === 'single') {
962
962
  return true;
963
963
  }
964
+ // this is required because of AG Grid bug, see https://github.com/AdaptableTools/adaptable/issues/3212
964
965
  if (rowGroupDisplayType === 'multi') {
965
966
  const groupedColumnFilterConfig = this.api.layoutApi.internalApi.areAllGroupedColumnsFilterable();
966
967
  if (groupedColumnFilterConfig.floatingFilter) {
@@ -1086,7 +1087,7 @@ class AdaptableAgGrid {
1086
1087
  this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'aggFuncs', (original_aggFuncs) => {
1087
1088
  const aggregationFunctions = original_aggFuncs || {};
1088
1089
  aggregationFunctions[AggregationColumns_1.ONLY_AGG_FN_NAME] = (params) => {
1089
- return (0, only_1.only)(params, params.column.getColId());
1090
+ return (0, only_1.only)(params);
1090
1091
  };
1091
1092
  aggregationFunctions[AggregationColumns_1.WEIGHTED_AVERAGE_AGG_FN_NAME] = (params) => {
1092
1093
  const columnId = params.column.getColId();
@@ -1616,6 +1617,12 @@ class AdaptableAgGrid {
1616
1617
  const perfNewAdaptableStore = this.logger.beginPerf(`initAdaptableStore()`);
1617
1618
  const initAdaptableStoreMarker = (0, devTools_1.getMarker)(this.adaptableOptions.adaptableId).track.Init.label.InitStore.start();
1618
1619
  const adaptableStore = new AdaptableStore_1.AdaptableStore(this);
1620
+ adaptableStore.onBeforeAny((eventName, data) => {
1621
+ if (this.isReady) {
1622
+ this.api.eventApi.internalApi.fireBeforeAdaptableStateChangeEvent(data.action, data.state);
1623
+ }
1624
+ this.forPlugins((plugin) => plugin.onBeforeStoreEvent?.(eventName, data, this.adaptableStore));
1625
+ });
1619
1626
  adaptableStore.onAny((eventName, data) => {
1620
1627
  if (this.isReady) {
1621
1628
  this.api.eventApi.internalApi.fireAdaptableStateChangedEvent(data.action, data.state, data.newState);
@@ -2264,6 +2271,9 @@ class AdaptableAgGrid {
2264
2271
  this.logger.consoleError('AG Grid redrawRows failed to locate some row nodes.', rowNodes, ex);
2265
2272
  }
2266
2273
  }
2274
+ refreshGridHeader() {
2275
+ this.agGridAdapter.getAgGridApi().refreshHeader();
2276
+ }
2267
2277
  redrawRow(rowNode) {
2268
2278
  this.redrawRows([rowNode]);
2269
2279
  }
package/src/env.js CHANGED
@@ -2,6 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = {
4
4
  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" || '',
5
- PUBLISH_TIMESTAMP: 1771927501120 || Date.now(),
6
- VERSION: "22.0.0" || '--current-version--',
5
+ PUBLISH_TIMESTAMP: 1772179397651 || Date.now(),
6
+ VERSION: "22.0.1-canary.1" || '--current-version--',
7
7
  };
package/src/types.d.ts CHANGED
@@ -139,6 +139,7 @@ export type { ThemeChangedInfo } from './Api/Events/ThemeChanged';
139
139
  export type { DashboardChangedInfo } from './Api/Events/DashboardChanged';
140
140
  export type { ScheduleTriggeredInfo } from './Api/Events/ScheduleTriggered';
141
141
  export type { AdaptableStateChangedInfo } from './Api/Events/AdaptableStateChanged';
142
+ export type { BeforeAdaptableStateChangeInfo } from './Api/Events/BeforeAdaptableStateChange';
142
143
  export type { CommentChangedInfo } from './Api/Events/CommentChanged';
143
144
  export type { Fdc3MessageInfo, Fdc3MessageSentInfo, Fdc3MessageReceivedInfo, } from './Api/Events/Fdc3MessageInfo';
144
145
  export type { AdaptableState, AdaptablePersistentState, AdaptableTransientState, } from './AdaptableState/AdaptableState';