ag-grid-community 35.0.0 → 35.0.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.
@@ -8618,12 +8618,12 @@ exports._defaultComparator = exports._jsonEquals = exports._toStringOrNull = exp
8618
8618
  * @param {T} value
8619
8619
  * @returns {T | null}
8620
8620
  */
8621
- function _makeNull(value) {
8621
+ const _makeNull = (value) => {
8622
8622
  if (value == null || value === '') {
8623
8623
  return null;
8624
8624
  }
8625
8625
  return value;
8626
- }
8626
+ };
8627
8627
  exports._makeNull = _makeNull;
8628
8628
  function _exists(value) {
8629
8629
  return value != null && value !== '';
@@ -8633,60 +8633,44 @@ function _missing(value) {
8633
8633
  return !_exists(value);
8634
8634
  }
8635
8635
  exports._missing = _missing;
8636
- function _toStringOrNull(value) {
8636
+ const _toStringOrNull = (value) => {
8637
8637
  return value != null && typeof value.toString === 'function' ? value.toString() : null;
8638
- }
8638
+ };
8639
8639
  exports._toStringOrNull = _toStringOrNull;
8640
- function _jsonEquals(val1, val2) {
8640
+ const _jsonEquals = (val1, val2) => {
8641
8641
  const val1Json = val1 ? JSON.stringify(val1) : null;
8642
8642
  const val2Json = val2 ? JSON.stringify(val2) : null;
8643
8643
  return val1Json === val2Json;
8644
- }
8644
+ };
8645
8645
  exports._jsonEquals = _jsonEquals;
8646
- function _defaultComparator(valueA, valueB, options = {}) {
8647
- if (options.transform) {
8648
- valueA = options.transform(valueA);
8649
- valueB = options.transform(valueB);
8646
+ const _defaultComparator = (valueA, valueB, accentedCompare = false) => {
8647
+ if (valueA == null) {
8648
+ return valueB == null ? 0 : -1;
8649
+ }
8650
+ if (valueB == null) {
8651
+ return 1;
8650
8652
  }
8651
- const valueAMissing = valueA == null;
8652
- const valueBMissing = valueB == null;
8653
8653
  // this is for aggregations sum and avg, where the result can be a number that is wrapped.
8654
8654
  // if we didn't do this, then the toString() value would be used, which would result in
8655
8655
  // the strings getting used instead of the numbers.
8656
- if (valueA?.toNumber) {
8656
+ if (typeof valueA === 'object' && valueA.toNumber) {
8657
8657
  valueA = valueA.toNumber();
8658
8658
  }
8659
- if (valueB?.toNumber) {
8659
+ if (typeof valueB === 'object' && valueB.toNumber) {
8660
8660
  valueB = valueB.toNumber();
8661
8661
  }
8662
- if (valueAMissing && valueBMissing) {
8662
+ if (!accentedCompare || typeof valueA !== 'string') {
8663
+ if (valueA > valueB) {
8664
+ return 1;
8665
+ }
8666
+ if (valueA < valueB) {
8667
+ return -1;
8668
+ }
8663
8669
  return 0;
8664
8670
  }
8665
- if (valueAMissing) {
8666
- return -1;
8667
- }
8668
- if (valueBMissing) {
8669
- return 1;
8670
- }
8671
- function doQuickCompare(a, b) {
8672
- return a > b ? 1 : a < b ? -1 : 0;
8673
- }
8674
- if (typeof valueA !== 'string') {
8675
- return doQuickCompare(valueA, valueB);
8676
- }
8677
- if (!options.accentedCompare) {
8678
- return doQuickCompare(valueA, valueB);
8679
- }
8680
- try {
8681
- // using local compare also allows chinese comparisons
8682
- return valueA.localeCompare(valueB);
8683
- }
8684
- catch (e) {
8685
- // if something wrong with localeCompare, eg not supported
8686
- // by browser, then just continue with the quick one
8687
- return doQuickCompare(valueA, valueB);
8688
- }
8689
- }
8671
+ // using locale compare also allows chinese comparisons
8672
+ return valueA.localeCompare(valueB);
8673
+ };
8690
8674
  exports._defaultComparator = _defaultComparator;
8691
8675
 
8692
8676
 
@@ -13444,6 +13428,159 @@ const _csrmReorderAllLeafs = (allLeafs, leafsToMove, target, above) => {
13444
13428
  exports._csrmReorderAllLeafs = _csrmReorderAllLeafs;
13445
13429
 
13446
13430
 
13431
+ /***/ }),
13432
+
13433
+ /***/ 55813:
13434
+ /***/ (function(__unused_webpack_module, exports) {
13435
+
13436
+
13437
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
13438
+ exports.doDeltaSort = void 0;
13439
+ /**
13440
+ * Minimum number of rows changed to enable delta sort.
13441
+ * Below this threshold, full sort is much faster due to lower overhead.
13442
+ */
13443
+ const MIN_DELTA_SORT_ROWS = 4;
13444
+ /**
13445
+ * Performs an incremental (delta) sort that avoids re-sorting unchanged rows.
13446
+ *
13447
+ * Algorithm outline:
13448
+ * 1. Handle edge cases: empty input or single element - return early
13449
+ * 2. Fall back to full sort if no previous sorted result or too few rows
13450
+ * 3. Classify rows as "touched" (updated, added, or in changed path) vs "untouched"
13451
+ * 4. If no rows are touched, return previous sorted array (filtering removed nodes if needed)
13452
+ * 5. Sort only the touched rows using a stable sort with original index as tie-breaker
13453
+ * 6. If all rows are touched, return the sorted touched rows directly
13454
+ * 7. Merge the sorted touched rows with untouched rows from previous sort order
13455
+ * using a two-pointer merge algorithm (similar to merge sort's merge step)
13456
+ *
13457
+ * Time complexity: O(t log t + n) where t = touched rows, n = total rows
13458
+ * This is faster than full sort O(n log n) when t << n
13459
+ */
13460
+ const doDeltaSort = (rowNodeSorter, rowNode, changedRowNodes, changedPath, sortOptions) => {
13461
+ const oldSortedRows = rowNode.childrenAfterSort;
13462
+ const unsortedRows = rowNode.childrenAfterAggFilter;
13463
+ if (!unsortedRows) {
13464
+ return oldSortedRows && oldSortedRows.length > 0 ? oldSortedRows : [];
13465
+ }
13466
+ const unsortedRowsLen = unsortedRows.length;
13467
+ if (unsortedRowsLen <= 1) {
13468
+ if (oldSortedRows?.length === unsortedRowsLen &&
13469
+ (unsortedRowsLen === 0 || oldSortedRows[0] === unsortedRows[0])) {
13470
+ return oldSortedRows; // Same content, reuse old array
13471
+ }
13472
+ return unsortedRows.slice(); // Different content, need new reference
13473
+ }
13474
+ if (!oldSortedRows || unsortedRowsLen <= MIN_DELTA_SORT_ROWS) {
13475
+ // No previous sort, or just too few elements, do full sort
13476
+ return rowNodeSorter.doFullSortInPlace(unsortedRows.slice(), sortOptions);
13477
+ }
13478
+ const indexByNode = new Map();
13479
+ // Classify rows as touched or untouched and build an index map.
13480
+ // Map stores current index with sign encoding: negative = touched, non-negative = untouched.
13481
+ const { updates, adds } = changedRowNodes;
13482
+ const touchedRows = [];
13483
+ for (let i = 0; i < unsortedRowsLen; ++i) {
13484
+ const node = unsortedRows[i];
13485
+ if (updates.has(node) || adds.has(node) || !changedPath.canSkip(node)) {
13486
+ indexByNode.set(node, ~i); // Bitwise NOT for touched (negative)
13487
+ touchedRows.push(node);
13488
+ }
13489
+ else {
13490
+ indexByNode.set(node, i); // Non-negative for untouched
13491
+ }
13492
+ }
13493
+ const touchedRowsLen = touchedRows.length;
13494
+ if (touchedRowsLen === 0) {
13495
+ // No touched rows: return oldSortedRows if nothing removed, otherwise filter out removed nodes
13496
+ return unsortedRowsLen === oldSortedRows.length
13497
+ ? oldSortedRows // Nothing removed
13498
+ : filterRemovedNodes(oldSortedRows, indexByNode, touchedRows);
13499
+ }
13500
+ // Sort touched rows with stable tie-breaker based on current index
13501
+ touchedRows.sort((a, b) => rowNodeSorter.compareRowNodes(sortOptions, a, b) || ~indexByNode.get(a) - ~indexByNode.get(b));
13502
+ if (touchedRowsLen === unsortedRowsLen) {
13503
+ return touchedRows; // All touched: no merge needed, return sorted touched rows directly.
13504
+ }
13505
+ return mergeDeltaSortedArrays(rowNodeSorter, sortOptions, touchedRows, oldSortedRows, indexByNode, unsortedRowsLen);
13506
+ };
13507
+ exports.doDeltaSort = doDeltaSort;
13508
+ /**
13509
+ * Merge touched rows with untouched rows from previous sorted order.
13510
+ * Optimized version: caches untouched index to avoid repeated map lookups in hot loop.
13511
+ * See https://en.wikipedia.org/wiki/Merge_algorithm
13512
+ */
13513
+ const mergeDeltaSortedArrays = (rowNodeSorter, sortOptions, touchedRows, oldSortedRows, indexByNode, resultSize) => {
13514
+ // Result array - size equals total number of rows to output
13515
+ const result = new Array(resultSize);
13516
+ let touchedIdx = 0;
13517
+ let touchedNode = touchedRows[touchedIdx];
13518
+ let untouchedNode;
13519
+ let untouchedIdx = -1;
13520
+ let oldIdx = 0;
13521
+ let resultIdx = 0;
13522
+ const touchedLength = touchedRows.length;
13523
+ const oldSortedLength = oldSortedRows.length;
13524
+ while (true) {
13525
+ // Advance to next valid untouched node if needed
13526
+ if (untouchedIdx < 0) {
13527
+ if (oldIdx >= oldSortedLength) {
13528
+ break; // No more untouched nodes
13529
+ }
13530
+ untouchedNode = oldSortedRows[oldIdx++];
13531
+ untouchedIdx = indexByNode.get(untouchedNode) ?? -1;
13532
+ if (untouchedIdx < 0) {
13533
+ continue; // Skip touched/removed nodes
13534
+ }
13535
+ }
13536
+ const orderDelta = rowNodeSorter.compareRowNodes(sortOptions, touchedNode, untouchedNode) ||
13537
+ ~indexByNode.get(touchedNode) - untouchedIdx;
13538
+ if (orderDelta < 0) {
13539
+ result[resultIdx++] = touchedNode; // Touched node comes next
13540
+ if (++touchedIdx >= touchedLength) {
13541
+ break; // No more touched nodes
13542
+ }
13543
+ touchedNode = touchedRows[touchedIdx];
13544
+ }
13545
+ else {
13546
+ result[resultIdx++] = untouchedNode; // Untouched node comes next
13547
+ untouchedIdx = -1; // Will be fetched on next iteration
13548
+ }
13549
+ }
13550
+ // Copy remaining touched nodes
13551
+ while (touchedIdx < touchedLength) {
13552
+ result[resultIdx++] = touchedRows[touchedIdx++];
13553
+ }
13554
+ // If no pending untouched node, we already searched through remaining nodes
13555
+ if (untouchedIdx < 0) {
13556
+ return result;
13557
+ }
13558
+ // Add pending untouched node
13559
+ result[resultIdx++] = untouchedNode;
13560
+ // Copy remaining untouched nodes
13561
+ while (oldIdx < oldSortedLength) {
13562
+ const node = oldSortedRows[oldIdx++];
13563
+ if (indexByNode.get(node) >= 0) {
13564
+ result[resultIdx++] = node;
13565
+ }
13566
+ }
13567
+ return result;
13568
+ };
13569
+ /** Filter out removed nodes from oldSortedRows using preallocated array for performance. */
13570
+ const filterRemovedNodes = (rows, map, result) => {
13571
+ let count = 0;
13572
+ result.length = map.size;
13573
+ for (let i = 0, len = rows.length; i < len; ++i) {
13574
+ const node = rows[i];
13575
+ if (map.has(node)) {
13576
+ result[count++] = node;
13577
+ }
13578
+ }
13579
+ result.length = count;
13580
+ return result;
13581
+ };
13582
+
13583
+
13447
13584
  /***/ }),
13448
13585
 
13449
13586
  /***/ 48287:
@@ -13565,6 +13702,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
13565
13702
  exports.SortStage = exports.updateRowNodeAfterSort = void 0;
13566
13703
  const beanStub_1 = __webpack_require__(68731);
13567
13704
  const gridOptionsUtils_1 = __webpack_require__(67274);
13705
+ const deltaSort_1 = __webpack_require__(55813);
13568
13706
  const updateRowNodeAfterSort = (rowNode) => {
13569
13707
  const childrenAfterSort = rowNode.childrenAfterSort;
13570
13708
  const sibling = rowNode.sibling;
@@ -13643,12 +13781,12 @@ class SortStage extends beanStub_1.BeanStub {
13643
13781
  // if there's no sort to make, skip this step
13644
13782
  }
13645
13783
  else if (useDeltaSort && changedRowNodes) {
13646
- newChildrenAfterSort = doDeltaSort(rowNodeSorter, rowNode, changedRowNodes, changedPath, sortOptions);
13784
+ newChildrenAfterSort = (0, deltaSort_1.doDeltaSort)(rowNodeSorter, rowNode, changedRowNodes, changedPath, sortOptions);
13647
13785
  }
13648
13786
  else {
13649
- newChildrenAfterSort = rowNodeSorter.doFullSort(rowNode.childrenAfterAggFilter, sortOptions);
13787
+ newChildrenAfterSort = rowNodeSorter.doFullSortInPlace(rowNode.childrenAfterAggFilter.slice(), sortOptions);
13650
13788
  }
13651
- newChildrenAfterSort || (newChildrenAfterSort = rowNode.childrenAfterAggFilter?.slice(0) ?? []);
13789
+ newChildrenAfterSort || (newChildrenAfterSort = rowNode.childrenAfterAggFilter?.slice() ?? []);
13652
13790
  hasAnyFirstChildChanged || (hasAnyFirstChildChanged = rowNode.childrenAfterSort?.[0] !== newChildrenAfterSort[0]);
13653
13791
  rowNode.childrenAfterSort = newChildrenAfterSort;
13654
13792
  (0, exports.updateRowNodeAfterSort)(rowNode);
@@ -13691,64 +13829,6 @@ class SortStage extends beanStub_1.BeanStub {
13691
13829
  }
13692
13830
  }
13693
13831
  exports.SortStage = SortStage;
13694
- const doDeltaSort = (rowNodeSorter, rowNode, changedRowNodes, changedPath, sortOptions) => {
13695
- const unsortedRows = rowNode.childrenAfterAggFilter;
13696
- const oldSortedRows = rowNode.childrenAfterSort;
13697
- if (!oldSortedRows) {
13698
- return rowNodeSorter.doFullSort(unsortedRows, sortOptions);
13699
- }
13700
- const untouchedRows = new Set();
13701
- const touchedRows = [];
13702
- const { updates, adds } = changedRowNodes;
13703
- for (let i = 0, len = unsortedRows.length; i < len; ++i) {
13704
- const row = unsortedRows[i];
13705
- if (updates.has(row) || adds.has(row) || (changedPath && !changedPath.canSkip(row))) {
13706
- touchedRows.push({
13707
- currentPos: touchedRows.length,
13708
- rowNode: row,
13709
- });
13710
- }
13711
- else {
13712
- untouchedRows.add(row);
13713
- }
13714
- }
13715
- const sortedUntouchedRows = oldSortedRows
13716
- .filter((child) => untouchedRows.has(child))
13717
- .map((rowNode, currentPos) => ({ currentPos, rowNode }));
13718
- touchedRows.sort((a, b) => rowNodeSorter.compareRowNodes(sortOptions, a, b));
13719
- return mergeSortedArrays(rowNodeSorter, sortOptions, touchedRows, sortedUntouchedRows);
13720
- };
13721
- // Merge two sorted arrays into each other
13722
- const mergeSortedArrays = (rowNodeSorter, sortOptions, arr1, arr2) => {
13723
- let i = 0;
13724
- let j = 0;
13725
- const arr1Length = arr1.length;
13726
- const arr2Length = arr2.length;
13727
- const res = new Array(arr1Length + arr2Length);
13728
- let k = 0;
13729
- // Traverse both arrays, adding them in order
13730
- while (i < arr1Length && j < arr2Length) {
13731
- const a = arr1[i];
13732
- const b = arr2[j];
13733
- if (rowNodeSorter.compareRowNodes(sortOptions, a, b) < 0) {
13734
- res[k++] = a.rowNode;
13735
- ++i;
13736
- }
13737
- else {
13738
- res[k++] = b.rowNode;
13739
- ++j;
13740
- }
13741
- }
13742
- // add remaining from arr1
13743
- while (i < arr1Length) {
13744
- res[k++] = arr1[i++].rowNode;
13745
- }
13746
- // add remaining from arr2
13747
- while (j < arr2Length) {
13748
- res[k++] = arr2[j++].rowNode;
13749
- }
13750
- return res;
13751
- };
13752
13832
  /**
13753
13833
  * O(n) merge preserving previous visual order and appending new items in current order.
13754
13834
  */
@@ -26701,9 +26781,26 @@ class FullRowEditStrategy extends baseEditStrategy_1.BaseEditStrategy {
26701
26781
  super.cleanupEditors(position, includeEditing);
26702
26782
  for (const rowNode of this.startedRows) {
26703
26783
  this.dispatchRowEvent({ rowNode }, 'rowEditingStopped');
26784
+ this.destroyEditorsForRow(rowNode);
26704
26785
  }
26705
26786
  this.startedRows.length = 0;
26706
26787
  }
26788
+ /**
26789
+ * Destroys all editors for a row that started full row editing, including editors
26790
+ * that are not represented in the edit model (e.g. empty/unedited editors).
26791
+ */
26792
+ destroyEditorsForRow(rowNode) {
26793
+ const rowCtrl = (0, controllers_1._getRowCtrl)(this.beans, { rowNode });
26794
+ if (!rowCtrl) {
26795
+ return; // Row not rendered, no editors to destroy.
26796
+ }
26797
+ // Destroy every editor created for this row, including those without edit model entries.
26798
+ for (const cellCtrl of rowCtrl.getAllCellCtrls()) {
26799
+ if (cellCtrl.comp?.getCellEditor()) {
26800
+ (0, editors_1._destroyEditor)(this.beans, cellCtrl, undefined, cellCtrl);
26801
+ }
26802
+ }
26803
+ }
26707
26804
  // returns null if no navigation should be performed
26708
26805
  moveToNextEditingCell(prevCell, backwards, event, source = 'ui', preventNavigation = false) {
26709
26806
  const prevPos = prevCell.cellPosition;
@@ -27629,10 +27726,9 @@ function _destroyEditors(beans, edits, params) {
27629
27726
  }
27630
27727
  }
27631
27728
  exports._destroyEditors = _destroyEditors;
27632
- function _destroyEditor(beans, position, params) {
27729
+ function _destroyEditor(beans, position, params, cellCtrl = (0, controllers_1._getCellCtrl)(beans, position)) {
27633
27730
  const enableGroupEditing = beans.gos.get('enableGroupEdit');
27634
- const { editModelSvc } = beans;
27635
- const cellCtrl = (0, controllers_1._getCellCtrl)(beans, position);
27731
+ const editModelSvc = beans.editModelSvc;
27636
27732
  const edit = editModelSvc?.getEdit(position, true);
27637
27733
  if (!cellCtrl) {
27638
27734
  if (edit) {
@@ -27640,9 +27736,10 @@ function _destroyEditor(beans, position, params) {
27640
27736
  }
27641
27737
  return;
27642
27738
  }
27643
- const { comp } = cellCtrl;
27739
+ const comp = cellCtrl.comp;
27740
+ const cellEditor = comp?.getCellEditor();
27644
27741
  // editor already cleaned up, refresh cell (React usually)
27645
- if (comp && !comp.getCellEditor()) {
27742
+ if (comp && !cellEditor) {
27646
27743
  cellCtrl?.refreshCell();
27647
27744
  if (edit) {
27648
27745
  editModelSvc?.setEdit(position, { state: 'changed' });
@@ -27658,7 +27755,7 @@ function _destroyEditor(beans, position, params) {
27658
27755
  return;
27659
27756
  }
27660
27757
  if (_hasValidationRules(beans)) {
27661
- const errorMessages = comp?.getCellEditor()?.getValidationErrors?.();
27758
+ const errorMessages = edit && cellEditor?.getValidationErrors?.();
27662
27759
  const cellValidationModel = editModelSvc?.getCellValidationModel();
27663
27760
  if (errorMessages?.length) {
27664
27761
  cellValidationModel?.setCellValidation(position, { errorMessages });
@@ -27667,7 +27764,9 @@ function _destroyEditor(beans, position, params) {
27667
27764
  cellValidationModel?.clearCellValidation(position);
27668
27765
  }
27669
27766
  }
27670
- editModelSvc?.setEdit(position, { state: 'changed' });
27767
+ if (edit) {
27768
+ editModelSvc?.setEdit(position, { state: 'changed' });
27769
+ }
27671
27770
  comp?.setEditDetails(); // passing nothing stops editing
27672
27771
  comp?.refreshEditStyles(false, false);
27673
27772
  cellCtrl?.refreshCell({ force: true, suppressFlash: true });
@@ -30683,13 +30782,8 @@ class GridSerializer extends beanStub_1.BeanStub {
30683
30782
  // if the level is the same, compare these nodes, or their parents
30684
30783
  if (rowA.level === rowB.level) {
30685
30784
  if (rowA.parent?.id === rowB.parent?.id) {
30686
- return rowNodeSorter.compareRowNodes(sortOptions, {
30687
- rowNode: rowA,
30688
- currentPos: rowA.rowIndex ?? -1,
30689
- }, {
30690
- rowNode: rowB,
30691
- currentPos: rowB.rowIndex ?? -1,
30692
- });
30785
+ return (rowNodeSorter.compareRowNodes(sortOptions, rowA, rowB) ||
30786
+ (rowA.rowIndex ?? -1) - (rowB.rowIndex ?? -1));
30693
30787
  }
30694
30788
  // level is same, but parent isn't, compare parents
30695
30789
  return compareNodes(rowA.parent, rowB.parent);
@@ -52796,10 +52890,11 @@ class PinnedRows {
52796
52890
  const { sortSvc, rowNodeSorter, gos } = this.beans;
52797
52891
  const sortOptions = sortSvc?.getSortOptions() ?? [];
52798
52892
  // first remove the grand total row so it doesn't get sorted
52799
- const grandTotalNode = _removeGrandTotalRow(this.order);
52893
+ const order = this.order;
52894
+ const grandTotalNode = _removeGrandTotalRow(order);
52800
52895
  // pre-sort by existing row-index otherwise we'll fall back to order in which rows are pinned
52801
- this.order.sort((a, b) => (a.pinnedSibling?.rowIndex ?? 0) - (b.pinnedSibling?.rowIndex ?? 0));
52802
- this.order = rowNodeSorter?.doFullSort(this.order, sortOptions) ?? this.order;
52896
+ order.sort((a, b) => rowNodeSorter?.compareRowNodes(sortOptions, a, b) ||
52897
+ (a.pinnedSibling?.rowIndex ?? 0) - (b.pinnedSibling?.rowIndex ?? 0));
52803
52898
  // post-sort re-insert the grand total row in the correct place
52804
52899
  if (!grandTotalNode) {
52805
52900
  return;
@@ -63532,32 +63627,43 @@ class RowNodeSorter extends beanStub_1.BeanStub {
63532
63627
  constructor() {
63533
63628
  super(...arguments);
63534
63629
  this.beanName = 'rowNodeSorter';
63630
+ this.accentedSort = false;
63631
+ this.primaryColumnsSortGroups = false;
63632
+ this.pivotActive = false;
63535
63633
  }
63536
63634
  postConstruct() {
63537
- const { gos } = this;
63538
- this.isAccentedSort = gos.get('accentedSort');
63539
- this.primaryColumnsSortGroups = (0, gridOptionsUtils_1._isColumnsSortingCoupledToGroup)(gos);
63540
- this.firstLeaf = (0, gridOptionsUtils_1._isClientSideRowModel)(gos) ? clientSideRowModelUtils_1._csrmFirstLeaf : defaultGetLeaf;
63541
- this.addManagedPropertyListener('accentedSort', (propChange) => (this.isAccentedSort = propChange.currentValue));
63542
- this.addManagedPropertyListener('autoGroupColumnDef', () => (this.primaryColumnsSortGroups = (0, gridOptionsUtils_1._isColumnsSortingCoupledToGroup)(gos)));
63543
- }
63544
- doFullSort(rowNodes, sortOptions) {
63545
- const sortedRowNodes = rowNodes.map((rowNode, currentPos) => ({
63546
- currentPos,
63547
- rowNode,
63548
- }));
63549
- sortedRowNodes.sort(this.compareRowNodes.bind(this, sortOptions));
63550
- return sortedRowNodes.map((item) => item.rowNode);
63635
+ this.firstLeaf = (0, gridOptionsUtils_1._isClientSideRowModel)(this.gos) ? clientSideRowModelUtils_1._csrmFirstLeaf : defaultGetLeaf;
63636
+ this.addManagedPropertyListeners(['accentedSort', 'autoGroupColumnDef', 'treeData'], this.updateOptions.bind(this));
63637
+ const updatePivotModeState = this.updatePivotModeState.bind(this);
63638
+ this.addManagedEventListeners({
63639
+ columnPivotModeChanged: updatePivotModeState,
63640
+ columnPivotChanged: updatePivotModeState,
63641
+ });
63642
+ this.updateOptions();
63643
+ updatePivotModeState();
63644
+ }
63645
+ updateOptions() {
63646
+ this.accentedSort = !!this.gos.get('accentedSort');
63647
+ this.primaryColumnsSortGroups = (0, gridOptionsUtils_1._isColumnsSortingCoupledToGroup)(this.gos);
63551
63648
  }
63552
- compareRowNodes(sortOptions, sortedNodeA, sortedNodeB) {
63553
- const nodeA = sortedNodeA.rowNode;
63554
- const nodeB = sortedNodeB.rowNode;
63649
+ updatePivotModeState() {
63650
+ this.pivotActive = this.beans.colModel.isPivotActive();
63651
+ }
63652
+ doFullSortInPlace(rowNodes, sortOptions) {
63653
+ // This relies on stable sorting, present since ECMAScript 2019 - all browser within AG Grid's support matrix
63654
+ return rowNodes.sort((a, b) => this.compareRowNodes(sortOptions, a, b));
63655
+ }
63656
+ compareRowNodes(sortOptions, nodeA, nodeB) {
63657
+ if (nodeA === nodeB) {
63658
+ return 0;
63659
+ }
63660
+ const accentedCompare = this.accentedSort;
63555
63661
  // Iterate columns, return the first that doesn't match
63556
- for (let i = 0, len = sortOptions.length; i < len; i++) {
63662
+ for (let i = 0, len = sortOptions.length; i < len; ++i) {
63557
63663
  const sortOption = sortOptions[i];
63558
63664
  const isDescending = sortOption.sort === 'desc';
63559
- const valueA = this.getValue(nodeA, sortOption.column);
63560
- const valueB = this.getValue(nodeB, sortOption.column);
63665
+ let valueA = this.getValue(nodeA, sortOption.column);
63666
+ let valueB = this.getValue(nodeB, sortOption.column);
63561
63667
  let comparatorResult;
63562
63668
  const providedComparator = this.getComparator(sortOption, nodeA);
63563
63669
  if (providedComparator) {
@@ -63566,21 +63672,19 @@ class RowNodeSorter extends beanStub_1.BeanStub {
63566
63672
  }
63567
63673
  else {
63568
63674
  //otherwise do our own comparison
63569
- const opts = { accentedCompare: this.isAccentedSort };
63570
63675
  if (sortOption.type === 'absolute') {
63571
- opts.transform = _absoluteValueTransformer;
63676
+ valueA = absoluteValueTransformer(valueA);
63677
+ valueB = absoluteValueTransformer(valueB);
63572
63678
  }
63573
- comparatorResult = (0, generic_1._defaultComparator)(valueA, valueB, opts);
63679
+ comparatorResult = (0, generic_1._defaultComparator)(valueA, valueB, accentedCompare);
63574
63680
  }
63575
63681
  // user provided comparators can return 'NaN' if they don't correctly handle 'undefined' values, this
63576
63682
  // typically occurs when the comparator is used on a group row
63577
- const validResult = !isNaN(comparatorResult);
63578
- if (validResult && comparatorResult !== 0) {
63579
- return sortOption.sort === 'asc' ? comparatorResult : comparatorResult * -1;
63683
+ if (comparatorResult) {
63684
+ return sortOption.sort === 'asc' ? comparatorResult : -comparatorResult;
63580
63685
  }
63581
63686
  }
63582
- // All matched, we make is so that the original sort order is kept:
63583
- return sortedNodeA.currentPos - sortedNodeB.currentPos;
63687
+ return 0;
63584
63688
  }
63585
63689
  /**
63586
63690
  * if user defines a comparator as a function then use that.
@@ -63623,33 +63727,33 @@ class RowNodeSorter extends beanStub_1.BeanStub {
63623
63727
  return comparator;
63624
63728
  }
63625
63729
  getValue(node, column) {
63626
- if (this.primaryColumnsSortGroups && node.rowGroupColumn === column) {
63627
- return this.getGroupDataValue(node, column);
63628
- }
63629
- if (node.group && column.getColDef().showRowGroup) {
63630
- return undefined;
63730
+ const beans = this.beans;
63731
+ if (this.primaryColumnsSortGroups) {
63732
+ if (node.rowGroupColumn === column) {
63733
+ return this.getGroupDataValue(node, column);
63734
+ }
63735
+ if (node.group && column.getColDef().showRowGroup) {
63736
+ return undefined;
63737
+ }
63631
63738
  }
63632
- const { valueSvc, formula } = this.beans;
63633
- const value = valueSvc.getValue(column, node, false);
63634
- if (column.isAllowFormula() && formula?.isFormula(value)) {
63635
- return formula.resolveValue(column, node);
63739
+ const value = beans.valueSvc.getValue(column, node, false, 'api');
63740
+ if (column.isAllowFormula()) {
63741
+ const formula = beans.formula;
63742
+ if (formula?.isFormula(value)) {
63743
+ return formula.resolveValue(column, node);
63744
+ }
63636
63745
  }
63637
63746
  return value;
63638
63747
  }
63639
63748
  getGroupDataValue(node, column) {
63640
- const { gos, valueSvc, colModel, showRowGroupCols } = this.beans;
63641
- const isGroupRows = (0, gridOptionsUtils_1._isGroupUseEntireRow)(gos, colModel.isPivotActive());
63642
63749
  // because they're group rows, no display cols exist, so groupData never populated.
63643
63750
  // instead delegate to getting value from leaf child.
63644
- if (isGroupRows) {
63751
+ if ((0, gridOptionsUtils_1._isGroupUseEntireRow)(this.gos, this.pivotActive)) {
63645
63752
  const leafChild = this.firstLeaf(node);
63646
- return leafChild && valueSvc.getValue(column, leafChild, false);
63753
+ return leafChild && this.beans.valueSvc.getValue(column, leafChild, false, 'api');
63647
63754
  }
63648
- const displayCol = showRowGroupCols?.getShowRowGroupCol(column.getId());
63649
- if (!displayCol) {
63650
- return undefined;
63651
- }
63652
- return node.groupData?.[displayCol.getId()];
63755
+ const displayCol = this.beans.showRowGroupCols?.getShowRowGroupCol(column.getId());
63756
+ return displayCol ? node.groupData?.[displayCol.getId()] : undefined;
63653
63757
  }
63654
63758
  }
63655
63759
  exports.RowNodeSorter = RowNodeSorter;
@@ -63674,13 +63778,13 @@ const defaultGetLeaf = (row) => {
63674
63778
  childrenAfterGroup = node.childrenAfterGroup;
63675
63779
  }
63676
63780
  };
63677
- function _absoluteValueTransformer(value) {
63781
+ const absoluteValueTransformer = (value) => {
63678
63782
  if (!value) {
63679
63783
  return value;
63680
63784
  }
63681
63785
  const numberValue = Number(value);
63682
63786
  return isNaN(numberValue) ? value : Math.abs(numberValue);
63683
- }
63787
+ };
63684
63788
 
63685
63789
 
63686
63790
  /***/ }),
@@ -71463,7 +71567,7 @@ exports.VanillaFrameworkOverrides = VanillaFrameworkOverrides;
71463
71567
  Object.defineProperty(exports, "__esModule", ({ value: true }));
71464
71568
  exports.VERSION = void 0;
71465
71569
  // DO NOT UPDATE MANUALLY: Generated from script during build time
71466
- exports.VERSION = '35.0.0';
71570
+ exports.VERSION = '35.0.1';
71467
71571
 
71468
71572
 
71469
71573
  /***/ }),