@visactor/vtable-plugins 1.23.3-alpha.0 → 1.24.0-alpha.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 (143) hide show
  1. package/cjs/auto-fill/index.d.ts +3 -2
  2. package/cjs/auto-fill/index.js.map +1 -1
  3. package/cjs/auto-fill/series-converters.d.ts +3 -3
  4. package/cjs/auto-fill/series-converters.js.map +1 -1
  5. package/cjs/contextmenu/handle-menu-helper.js +1 -2
  6. package/cjs/contextmenu/index.js +2 -1
  7. package/cjs/excel-edit-cell-keyboard.d.ts +4 -2
  8. package/cjs/excel-edit-cell-keyboard.js.map +1 -1
  9. package/cjs/filter/filter-engine.js +5 -1
  10. package/cjs/filter/filter-engine.js.map +1 -1
  11. package/cjs/filter/filter-state-manager.d.ts +6 -1
  12. package/cjs/filter/filter-state-manager.js +81 -0
  13. package/cjs/filter/filter-state-manager.js.map +1 -1
  14. package/cjs/filter/filter-toolbar.d.ts +2 -0
  15. package/cjs/filter/filter-toolbar.js +23 -3
  16. package/cjs/filter/filter-toolbar.js.map +1 -1
  17. package/cjs/filter/filter.d.ts +4 -2
  18. package/cjs/filter/filter.js +32 -10
  19. package/cjs/filter/filter.js.map +1 -1
  20. package/cjs/filter/index.js +2 -1
  21. package/cjs/filter/types.d.ts +3 -0
  22. package/cjs/filter/types.js.map +1 -1
  23. package/cjs/filter/value-filter.js +11 -41
  24. package/cjs/filter/value-filter.js.map +1 -1
  25. package/cjs/filter/value-filter.syncSingleStateFromTableData.backup.d.ts +46 -0
  26. package/cjs/filter/value-filter.syncSingleStateFromTableData.backup.js +247 -0
  27. package/cjs/filter/value-filter.syncSingleStateFromTableData.backup.js.map +1 -0
  28. package/cjs/history/formula.d.ts +40 -0
  29. package/cjs/history/formula.js +112 -0
  30. package/cjs/history/formula.js.map +1 -0
  31. package/cjs/history/history-plugin.d.ts +88 -0
  32. package/cjs/history/history-plugin.js +699 -0
  33. package/cjs/history/history-plugin.js.map +1 -0
  34. package/cjs/history/index.d.ts +3 -0
  35. package/cjs/history/index.js +24 -0
  36. package/cjs/history/index.js.map +1 -0
  37. package/cjs/history/replay.d.ts +9 -0
  38. package/cjs/history/replay.js +268 -0
  39. package/cjs/history/replay.js.map +1 -0
  40. package/cjs/history/sheet-key.d.ts +9 -0
  41. package/cjs/history/sheet-key.js +44 -0
  42. package/cjs/history/sheet-key.js.map +1 -0
  43. package/cjs/history/snapshot.d.ts +15 -0
  44. package/cjs/history/snapshot.js +78 -0
  45. package/cjs/history/snapshot.js.map +1 -0
  46. package/cjs/history/types.d.ts +105 -0
  47. package/cjs/history/types.js +6 -0
  48. package/cjs/history/types.js.map +1 -0
  49. package/cjs/history-plugin.d.ts +1 -0
  50. package/cjs/history-plugin.js +21 -0
  51. package/cjs/history-plugin.js.map +1 -0
  52. package/cjs/index.d.ts +1 -0
  53. package/cjs/index.js +2 -1
  54. package/cjs/index.js.map +1 -1
  55. package/cjs/master-detail-plugin/checkbox.js +1 -1
  56. package/cjs/master-detail-plugin/config.js +1 -1
  57. package/cjs/master-detail-plugin/core.js +1 -1
  58. package/cjs/master-detail-plugin/events.js +1 -1
  59. package/cjs/master-detail-plugin/types.d.ts +1 -1
  60. package/cjs/master-detail-plugin/types.js.map +1 -1
  61. package/cjs/rotate-table.d.ts +7 -6
  62. package/cjs/rotate-table.js +12 -13
  63. package/cjs/rotate-table.js.map +1 -1
  64. package/cjs/row-series.js +2 -1
  65. package/cjs/table-export/util/pagination.js.map +1 -1
  66. package/cjs/wps-fill-handle.d.ts +4 -2
  67. package/cjs/wps-fill-handle.js.map +1 -1
  68. package/dist/vtable-plugins.js +1903 -81
  69. package/dist/vtable-plugins.min.js +3 -3
  70. package/es/auto-fill/index.d.ts +3 -2
  71. package/es/auto-fill/index.js.map +1 -1
  72. package/es/auto-fill/series-converters.d.ts +3 -3
  73. package/es/auto-fill/series-converters.js.map +1 -1
  74. package/es/contextmenu/handle-menu-helper.js +1 -2
  75. package/es/contextmenu/index.js +2 -1
  76. package/es/excel-edit-cell-keyboard.d.ts +4 -2
  77. package/es/excel-edit-cell-keyboard.js.map +1 -1
  78. package/es/filter/filter-engine.js +5 -1
  79. package/es/filter/filter-engine.js.map +1 -1
  80. package/es/filter/filter-state-manager.d.ts +6 -1
  81. package/es/filter/filter-state-manager.js +81 -0
  82. package/es/filter/filter-state-manager.js.map +1 -1
  83. package/es/filter/filter-toolbar.d.ts +2 -0
  84. package/es/filter/filter-toolbar.js +23 -3
  85. package/es/filter/filter-toolbar.js.map +1 -1
  86. package/es/filter/filter.d.ts +4 -2
  87. package/es/filter/filter.js +32 -10
  88. package/es/filter/filter.js.map +1 -1
  89. package/es/filter/index.js +2 -1
  90. package/es/filter/types.d.ts +3 -0
  91. package/es/filter/types.js.map +1 -1
  92. package/es/filter/value-filter.js +12 -41
  93. package/es/filter/value-filter.js.map +1 -1
  94. package/es/filter/value-filter.syncSingleStateFromTableData.backup.d.ts +46 -0
  95. package/es/filter/value-filter.syncSingleStateFromTableData.backup.js +242 -0
  96. package/es/filter/value-filter.syncSingleStateFromTableData.backup.js.map +1 -0
  97. package/es/history/formula.d.ts +40 -0
  98. package/es/history/formula.js +103 -0
  99. package/es/history/formula.js.map +1 -0
  100. package/es/history/history-plugin.d.ts +88 -0
  101. package/es/history/history-plugin.js +698 -0
  102. package/es/history/history-plugin.js.map +1 -0
  103. package/es/history/index.d.ts +3 -0
  104. package/es/history/index.js +4 -0
  105. package/es/history/index.js.map +1 -0
  106. package/es/history/replay.d.ts +9 -0
  107. package/es/history/replay.js +260 -0
  108. package/es/history/replay.js.map +1 -0
  109. package/es/history/sheet-key.d.ts +9 -0
  110. package/es/history/sheet-key.js +38 -0
  111. package/es/history/sheet-key.js.map +1 -0
  112. package/es/history/snapshot.d.ts +15 -0
  113. package/es/history/snapshot.js +71 -0
  114. package/es/history/snapshot.js.map +1 -0
  115. package/es/history/types.d.ts +105 -0
  116. package/es/history/types.js +2 -0
  117. package/es/history/types.js.map +1 -0
  118. package/es/history-plugin.d.ts +1 -0
  119. package/es/history-plugin.js +2 -0
  120. package/es/history-plugin.js.map +1 -0
  121. package/es/index.d.ts +1 -0
  122. package/es/index.js +2 -0
  123. package/es/index.js.map +1 -1
  124. package/es/master-detail-plugin/checkbox.js +1 -1
  125. package/es/master-detail-plugin/config.js +1 -1
  126. package/es/master-detail-plugin/core.js +1 -1
  127. package/es/master-detail-plugin/events.js +1 -1
  128. package/es/master-detail-plugin/types.d.ts +1 -1
  129. package/es/master-detail-plugin/types.js.map +1 -1
  130. package/es/rotate-table.d.ts +7 -6
  131. package/es/rotate-table.js +2 -3
  132. package/es/rotate-table.js.map +1 -1
  133. package/es/row-series.js +2 -1
  134. package/es/table-export/util/pagination.js.map +1 -1
  135. package/es/wps-fill-handle.d.ts +4 -2
  136. package/es/wps-fill-handle.js.map +1 -1
  137. package/package.json +10 -8
  138. package/cjs/auto-fill/__tests__/formula-integration.test.d.ts +0 -23
  139. package/cjs/auto-fill/__tests__/formula-integration.test.js +0 -61
  140. package/cjs/auto-fill/__tests__/formula-integration.test.js.map +0 -1
  141. package/es/auto-fill/__tests__/formula-integration.test.d.ts +0 -23
  142. package/es/auto-fill/__tests__/formula-integration.test.js +0 -54
  143. package/es/auto-fill/__tests__/formula-integration.test.js.map +0 -1
@@ -200,7 +200,7 @@
200
200
  };
201
201
  var isNumber$3 = isNumber$2;
202
202
 
203
- function cloneDeep$1(value, ignoreWhen, excludeKeys) {
203
+ function cloneDeep$2(value, ignoreWhen, excludeKeys) {
204
204
  let result;
205
205
  if (!isValid$2(value) || "object" != typeof value || ignoreWhen && ignoreWhen(value)) return value;
206
206
  const isArr = isArray$6(value),
@@ -211,18 +211,11 @@
211
211
  if (result) for (; ++index < (props || value).length;) {
212
212
  const key = props ? props[index] : index,
213
213
  subValue = value[key];
214
- excludeKeys && excludeKeys.includes(key.toString()) ? result[key] = subValue : result[key] = cloneDeep$1(subValue, ignoreWhen, excludeKeys);
214
+ excludeKeys && excludeKeys.includes(key.toString()) ? result[key] = subValue : result[key] = cloneDeep$2(subValue, ignoreWhen, excludeKeys);
215
215
  }
216
216
  return result;
217
217
  }
218
218
 
219
- function arrayEqual(a, b) {
220
- if (!isArray$6(a) || !isArray$6(b)) return !1;
221
- if (a.length !== b.length) return !1;
222
- for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return !1;
223
- return !0;
224
- }
225
-
226
219
  var InteractionState;
227
220
  !function (InteractionState) {
228
221
  InteractionState.default = "default", InteractionState.grabing = "grabing", InteractionState.scrolling = "scrolling";
@@ -2096,7 +2089,7 @@
2096
2089
  const domRect = this.getElement().getBoundingClientRect();
2097
2090
  const x1 = domRect.top;
2098
2091
  const y1 = viewPortWidth - domRect.right;
2099
- const matrix = vrender.matrixAllocate.allocate(1, 0, 0, 1, 0, 0);
2092
+ const matrix = VTable.matrixAllocate.allocate(1, 0, 0, 1, 0, 0);
2100
2093
  matrix.translate(x1, y1);
2101
2094
  const centerX = rotateCenter - x1;
2102
2095
  const centerY = rotateCenter - y1;
@@ -2109,13 +2102,13 @@
2109
2102
  }
2110
2103
  return matrix;
2111
2104
  };
2112
- vrender.registerGlobalEventTransformer(vrender.vglobal, this.getElement(), getMatrix, getRect, vrender.transformPointForCanvas);
2113
- vrender.registerWindowEventTransformer(this.scenegraph.stage.window, this.getElement(), getMatrix, getRect, vrender.transformPointForCanvas);
2105
+ VTable.registerGlobalEventTransformer(VTable.vglobal, this.getElement(), getMatrix, getRect, VTable.transformPointForCanvas);
2106
+ VTable.registerWindowEventTransformer(this.scenegraph.stage.window, this.getElement(), getMatrix, getRect, VTable.transformPointForCanvas);
2114
2107
  const rotateRablePlugin = this.pluginManager.getPluginByName('Rotate Table');
2115
2108
  if (rotateRablePlugin) {
2116
- rotateRablePlugin.vglobal_mapToCanvasPoint = vrender.vglobal.mapToCanvasPoint;
2109
+ rotateRablePlugin.vglobal_mapToCanvasPoint = VTable.vglobal.mapToCanvasPoint;
2117
2110
  }
2118
- vrender.vglobal.mapToCanvasPoint = vrender.mapToCanvasPointForCanvas;
2111
+ VTable.vglobal.mapToCanvasPoint = VTable.mapToCanvasPointForCanvas;
2119
2112
  }
2120
2113
  function cancelTransform(rotateDom) {
2121
2114
  this.rotateDegree = 0;
@@ -2135,15 +2128,15 @@
2135
2128
  };
2136
2129
  };
2137
2130
  const getMatrix = () => {
2138
- const matrix = vrender.matrixAllocate.allocate(1, 0, 0, 1, 0, 0);
2131
+ const matrix = VTable.matrixAllocate.allocate(1, 0, 0, 1, 0, 0);
2139
2132
  matrix.translate(x1, y1);
2140
2133
  return matrix;
2141
2134
  };
2142
- vrender.registerGlobalEventTransformer(vrender.vglobal, this.getElement(), getMatrix, getRect, vrender.transformPointForCanvas);
2143
- vrender.registerWindowEventTransformer(this.scenegraph.stage.window, this.getElement(), getMatrix, getRect, vrender.transformPointForCanvas);
2135
+ VTable.registerGlobalEventTransformer(VTable.vglobal, this.getElement(), getMatrix, getRect, VTable.transformPointForCanvas);
2136
+ VTable.registerWindowEventTransformer(this.scenegraph.stage.window, this.getElement(), getMatrix, getRect, VTable.transformPointForCanvas);
2144
2137
  const rotateRablePlugin = this.pluginManager.getPluginByName('Rotate Table');
2145
2138
  if (rotateRablePlugin) {
2146
- vrender.vglobal.mapToCanvasPoint = rotateRablePlugin.vglobal_mapToCanvasPoint;
2139
+ VTable.vglobal.mapToCanvasPoint = rotateRablePlugin.vglobal_mapToCanvasPoint;
2147
2140
  }
2148
2141
  }
2149
2142
 
@@ -10451,6 +10444,11 @@ ${recordsStr}
10451
10444
  table.updateFilterRules([...this.filterFuncRule, ...this.filterValueRule], {
10452
10445
  clearRowHeightCache: false,
10453
10446
  onFilterRecordsEnd: this.pluginOptions?.onFilterRecordsEnd
10447
+ ? (records) => {
10448
+ this.pluginOptions.onFilterRecordsEnd?.(records);
10449
+ return records;
10450
+ }
10451
+ : undefined
10454
10452
  });
10455
10453
  }
10456
10454
  createFilterFunction(filter) {
@@ -10580,6 +10578,119 @@ ${recordsStr}
10580
10578
  getAllFilterStates() {
10581
10579
  return this.state;
10582
10580
  }
10581
+ getSnapshot() {
10582
+ const filters = [];
10583
+ this.state.filters.forEach(v => {
10584
+ const next = { ...v };
10585
+ if (next && next.type === 'byValue' && Array.isArray(next.values)) {
10586
+ next.values = next.values.slice().sort((a, b) => String(a).localeCompare(String(b)));
10587
+ }
10588
+ if (next && Array.isArray(next.condition) && next.condition.length > 2) {
10589
+ next.condition = next.condition.slice();
10590
+ }
10591
+ filters.push(next);
10592
+ });
10593
+ filters.sort((a, b) => String(a.field).localeCompare(String(b.field)));
10594
+ return { filters };
10595
+ }
10596
+ applySnapshot(snapshot, actionType = exports.FilterActionType.APPLY_FILTERS) {
10597
+ const next = new Map();
10598
+ (snapshot?.filters ?? []).forEach(cfg => {
10599
+ if (!cfg) {
10600
+ return;
10601
+ }
10602
+ const cloned = { ...cfg };
10603
+ if (cloned && cloned.type === 'byValue' && Array.isArray(cloned.values)) {
10604
+ cloned.values = cloned.values.slice();
10605
+ }
10606
+ if (cloned && Array.isArray(cloned.condition)) {
10607
+ cloned.condition = cloned.condition.slice();
10608
+ }
10609
+ next.set(cloned.field, cloned);
10610
+ });
10611
+ this.state = { ...this.state, filters: next };
10612
+ this.applyFilters();
10613
+ this.notifyListeners({ type: actionType, payload: { fromSnapshot: true } });
10614
+ }
10615
+ shiftFieldsOnAddColumns(columnIndex, columnCount) {
10616
+ if (!Number.isFinite(columnIndex) || !Number.isFinite(columnCount) || columnCount <= 0) {
10617
+ return;
10618
+ }
10619
+ const next = new Map();
10620
+ this.state.filters.forEach((cfg, key) => {
10621
+ let newKey = key;
10622
+ const cloned = { ...cfg };
10623
+ if (typeof newKey === 'number' && newKey >= columnIndex) {
10624
+ newKey = newKey + columnCount;
10625
+ }
10626
+ if (typeof cloned.field === 'number' && cloned.field >= columnIndex) {
10627
+ cloned.field = cloned.field + columnCount;
10628
+ }
10629
+ if (cloned && cloned.type === 'byValue' && Array.isArray(cloned.values)) {
10630
+ cloned.values = cloned.values.slice();
10631
+ }
10632
+ if (cloned && Array.isArray(cloned.condition)) {
10633
+ cloned.condition = cloned.condition.slice();
10634
+ }
10635
+ next.set(newKey, cloned);
10636
+ });
10637
+ this.state = { ...this.state, filters: next };
10638
+ }
10639
+ shiftFieldsOnDeleteColumns(deleteColIndexs) {
10640
+ if (!Array.isArray(deleteColIndexs) || deleteColIndexs.length === 0) {
10641
+ return;
10642
+ }
10643
+ const sorted = deleteColIndexs
10644
+ .slice()
10645
+ .filter(n => Number.isFinite(n))
10646
+ .sort((a, b) => a - b);
10647
+ const deleteIndexNums = sorted.map((idx, i) => idx - i);
10648
+ const next = new Map();
10649
+ this.state.filters.forEach((cfg, key) => {
10650
+ let newKey = key;
10651
+ const cloned = { ...cfg };
10652
+ let removed = false;
10653
+ if (typeof newKey === 'number') {
10654
+ let k = newKey;
10655
+ for (let i = 0; i < deleteIndexNums.length; i++) {
10656
+ const d = deleteIndexNums[i];
10657
+ if (k === d) {
10658
+ removed = true;
10659
+ break;
10660
+ }
10661
+ if (k > d) {
10662
+ k -= 1;
10663
+ }
10664
+ }
10665
+ newKey = k;
10666
+ }
10667
+ if (typeof cloned.field === 'number') {
10668
+ let f = cloned.field;
10669
+ for (let i = 0; i < deleteIndexNums.length; i++) {
10670
+ const d = deleteIndexNums[i];
10671
+ if (f === d) {
10672
+ removed = true;
10673
+ break;
10674
+ }
10675
+ if (f > d) {
10676
+ f -= 1;
10677
+ }
10678
+ }
10679
+ cloned.field = f;
10680
+ }
10681
+ if (removed) {
10682
+ return;
10683
+ }
10684
+ if (cloned && cloned.type === 'byValue' && Array.isArray(cloned.values)) {
10685
+ cloned.values = cloned.values.slice();
10686
+ }
10687
+ if (cloned && Array.isArray(cloned.condition)) {
10688
+ cloned.condition = cloned.condition.slice();
10689
+ }
10690
+ next.set(newKey, cloned);
10691
+ });
10692
+ this.state = { ...this.state, filters: next };
10693
+ }
10583
10694
  reapplyCurrentFilters() {
10584
10695
  const activeFields = this.getActiveFilterFields();
10585
10696
  if (activeFields.length > 0) {
@@ -10947,7 +11058,7 @@ ${recordsStr}
10947
11058
  this.toUnformattedCache.set(candidateField, toUnformatted);
10948
11059
  }
10949
11060
  toggleSelectAll(fieldId, selected) {
10950
- const options = this.valueFilterOptionList.get(fieldId);
11061
+ const options = this.valueFilterOptionList.get(fieldId) || [];
10951
11062
  options.forEach(option => {
10952
11063
  if (option.itemContainer.style.display !== 'none') {
10953
11064
  option.checkbox.checked = selected;
@@ -10962,7 +11073,7 @@ ${recordsStr}
10962
11073
  this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked;
10963
11074
  }
10964
11075
  onSearch(fieldId, value) {
10965
- const items = this.valueFilterOptionList.get(fieldId);
11076
+ const items = this.valueFilterOptionList.get(fieldId) || [];
10966
11077
  const filterKeywords = value
10967
11078
  .toUpperCase()
10968
11079
  .split(' ')
@@ -10975,7 +11086,6 @@ ${recordsStr}
10975
11086
  }
10976
11087
  }
10977
11088
  syncSingleStateFromTableData(fieldId) {
10978
- const selectedValues = new Set();
10979
11089
  const originalValues = new Set();
10980
11090
  const originalRecords = this.table.internalProps.records;
10981
11091
  originalRecords.forEach(record => {
@@ -10983,56 +11093,23 @@ ${recordsStr}
10983
11093
  originalValues.add(record[fieldId]);
10984
11094
  }
10985
11095
  });
10986
- const syncFilterItemsState = this.pluginOptions?.syncFilterItemsState ?? true;
10987
- const hasFiltered = !arrayEqual(Array.from(originalValues), Array.from(selectedValues));
10988
- if (syncFilterItemsState) {
10989
- if (hasFiltered) {
10990
- this.selectedKeys.set(fieldId, selectedValues);
10991
- this.filterStateManager.dispatch({
10992
- type: exports.FilterActionType.UPDATE_FILTER,
10993
- payload: {
10994
- field: fieldId,
10995
- values: Array.from(selectedValues),
10996
- enable: true
10997
- }
10998
- });
10999
- const hasFiltered = !arrayEqual(Array.from(originalValues), Array.from(selectedValues));
11000
- if (hasFiltered) {
11001
- this.selectedKeys.set(fieldId, selectedValues);
11002
- this.filterStateManager.dispatch({
11003
- type: exports.FilterActionType.ADD_FILTER,
11004
- payload: {
11005
- field: fieldId,
11006
- type: 'byValue',
11007
- values: Array.from(selectedValues),
11008
- enable: true
11009
- }
11010
- });
11011
- }
11012
- }
11096
+ const current = this.filterStateManager.getFilterState(fieldId);
11097
+ if (current?.type === 'byValue' && Array.isArray(current.values)) {
11098
+ this.selectedKeys.set(fieldId, new Set(current.values));
11099
+ return;
11013
11100
  }
11014
- else {
11015
- const selectedRules = this.filterStateManager.getFilterState(fieldId)?.values;
11016
- if (selectedRules) {
11017
- const hasFiltered = !arrayEqual(Array.from(originalValues), selectedRules);
11018
- if (hasFiltered) {
11019
- this.selectedKeys.set(fieldId, new Set(selectedRules));
11020
- this.filterStateManager.dispatch({
11021
- type: exports.FilterActionType.ADD_FILTER,
11022
- payload: {
11023
- field: fieldId,
11024
- type: 'byValue',
11025
- values: selectedRules,
11026
- enable: true,
11027
- shouldKeepUnrelatedState: true
11028
- }
11029
- });
11101
+ if (current?.type === 'byCondition' && current.enable) {
11102
+ const visibleValues = new Set();
11103
+ const visibleRecords = this.getRecords(this.table, false);
11104
+ visibleRecords.forEach(record => {
11105
+ if (isValid$2(record)) {
11106
+ visibleValues.add(record[fieldId]);
11030
11107
  }
11031
- }
11032
- else {
11033
- this.selectedKeys.set(fieldId, originalValues);
11034
- }
11108
+ });
11109
+ this.selectedKeys.set(fieldId, visibleValues);
11110
+ return;
11035
11111
  }
11112
+ this.selectedKeys.set(fieldId, originalValues);
11036
11113
  }
11037
11114
  applyFilter(fieldId = this.selectedField) {
11038
11115
  const options = this.valueFilterOptionList.get(fieldId);
@@ -11633,12 +11710,14 @@ ${recordsStr}
11633
11710
  clearFilterOptionLink;
11634
11711
  cancelFilterButton;
11635
11712
  applyFilterButton;
11713
+ pluginId;
11636
11714
  constructor(table, filterStateManager, pluginOptions) {
11637
11715
  this.table = table;
11638
11716
  this.filterStateManager = filterStateManager;
11639
11717
  this.valueFilter = new ValueFilter(this.table, this.filterStateManager, pluginOptions);
11640
11718
  this.conditionFilter = new ConditionFilter(this.table, this.filterStateManager, pluginOptions, this.hide);
11641
11719
  this.pluginOptions = pluginOptions;
11720
+ this.pluginId = pluginOptions?.id ?? 'filter';
11642
11721
  this.filterMenuWidth = 300;
11643
11722
  this.filterStateManager.subscribe(state => {
11644
11723
  if (this.isVisible && this.selectedField !== null) {
@@ -11687,6 +11766,24 @@ ${recordsStr}
11687
11766
  }
11688
11767
  this.hide();
11689
11768
  }
11769
+ recordHistory(before, after) {
11770
+ const beforeKey = JSON.stringify(before);
11771
+ const afterKey = JSON.stringify(after);
11772
+ if (beforeKey === afterKey) {
11773
+ return;
11774
+ }
11775
+ const pm = this.table.pluginManager;
11776
+ const history = pm?.getPlugin?.('history-plugin') ??
11777
+ pm?.getPluginByName?.('History') ??
11778
+ pm?.getPlugin?.('history') ??
11779
+ pm?.getPluginByName?.('history');
11780
+ history?.recordExternalCommand?.({
11781
+ type: 'filter',
11782
+ pluginId: this.pluginId,
11783
+ oldSnapshot: before,
11784
+ newSnapshot: after
11785
+ });
11786
+ }
11690
11787
  updateClearFilterButtonState(field) {
11691
11788
  const currentFilter = this.filterStateManager.getFilterState(field);
11692
11789
  const hasActiveFilter = currentFilter && currentFilter.enable;
@@ -11761,10 +11858,16 @@ ${recordsStr}
11761
11858
  this.cancelFilterButton.addEventListener('click', () => this.hide());
11762
11859
  this.clearFilterOptionLink.addEventListener('click', e => {
11763
11860
  e.preventDefault();
11861
+ const before = this.filterStateManager.getSnapshot();
11764
11862
  this.clearFilter(this.selectedField);
11863
+ const after = this.filterStateManager.getSnapshot();
11864
+ this.recordHistory(before, after);
11765
11865
  });
11766
11866
  this.applyFilterButton.addEventListener('click', () => {
11867
+ const before = this.filterStateManager.getSnapshot();
11767
11868
  this.applyFilter(this.selectedField);
11869
+ const after = this.filterStateManager.getSnapshot();
11870
+ this.recordHistory(before, after);
11768
11871
  });
11769
11872
  document.addEventListener('click', () => {
11770
11873
  if (this.isVisible) {
@@ -11828,7 +11931,7 @@ ${recordsStr}
11828
11931
  if (currentFilter && currentFilter.type === 'byCondition') {
11829
11932
  this.onTabSwitch('byCondition');
11830
11933
  }
11831
- else {
11934
+ else if (this.filterModes.includes('byValue')) {
11832
11935
  this.onTabSwitch('byValue');
11833
11936
  }
11834
11937
  this.updateClearFilterButtonState(field);
@@ -21331,7 +21434,9 @@ ${recordsStr}
21331
21434
  VTable.TABLE_EVENT_TYPE.CHANGE_CELL_VALUE,
21332
21435
  VTable.TABLE_EVENT_TYPE.UPDATE_RECORD,
21333
21436
  VTable.TABLE_EVENT_TYPE.ADD_RECORD,
21334
- VTable.TABLE_EVENT_TYPE.DELETE_RECORD
21437
+ VTable.TABLE_EVENT_TYPE.DELETE_RECORD,
21438
+ VTable.TABLE_EVENT_TYPE.ADD_COLUMN,
21439
+ VTable.TABLE_EVENT_TYPE.DELETE_COLUMN
21335
21440
  ];
21336
21441
  pluginOptions;
21337
21442
  table;
@@ -21415,10 +21520,6 @@ ${recordsStr}
21415
21520
  }
21416
21521
  else {
21417
21522
  this.filterToolbar.show(col, row, this.pluginOptions.filterModes);
21418
- this.table.fireListeners(VTable.TABLE_EVENT_TYPE.FILTER_MENU_SHOW, {
21419
- col: eventArgs.col,
21420
- row: eventArgs.row
21421
- });
21422
21523
  }
21423
21524
  }
21424
21525
  else if (runtime === VTable.TABLE_EVENT_TYPE.SCROLL) {
@@ -21434,11 +21535,31 @@ ${recordsStr}
21434
21535
  this.syncFilterWithTableData();
21435
21536
  }
21436
21537
  else if (runtime === VTable.TABLE_EVENT_TYPE.ADD_RECORD) {
21538
+ const hasActiveFilter = this.filterStateManager?.getActiveFilterFields?.().length > 0;
21539
+ if (hasActiveFilter && Array.isArray(eventArgs?.records)) {
21540
+ const ds = this.table.dataSource;
21541
+ eventArgs.records.forEach((r) => ds?.markForceVisibleRecord?.(r));
21542
+ }
21437
21543
  this.syncFilterWithTableData();
21438
21544
  }
21439
21545
  else if (runtime === VTable.TABLE_EVENT_TYPE.DELETE_RECORD) {
21440
21546
  this.syncFilterWithTableData();
21441
21547
  }
21548
+ else if (runtime === VTable.TABLE_EVENT_TYPE.ADD_COLUMN) {
21549
+ const columnIndex = eventArgs?.columnIndex;
21550
+ const columnCount = eventArgs?.columnCount;
21551
+ if (typeof columnIndex === 'number' && typeof columnCount === 'number' && columnCount > 0) {
21552
+ this.filterStateManager?.shiftFieldsOnAddColumns?.(columnIndex, columnCount);
21553
+ }
21554
+ this.reapplyActiveFilters();
21555
+ }
21556
+ else if (runtime === VTable.TABLE_EVENT_TYPE.DELETE_COLUMN) {
21557
+ const deleteColIndexs = eventArgs?.deleteColIndexs;
21558
+ if (Array.isArray(deleteColIndexs) && deleteColIndexs.length > 0) {
21559
+ this.filterStateManager?.shiftFieldsOnDeleteColumns?.(deleteColIndexs);
21560
+ }
21561
+ this.reapplyActiveFilters();
21562
+ }
21442
21563
  }
21443
21564
  updatePluginOptions(pluginOptions) {
21444
21565
  this.pluginOptions = lodashExports.merge(this.pluginOptions, pluginOptions);
@@ -21447,6 +21568,12 @@ ${recordsStr}
21447
21568
  clearRowHeightCache: false
21448
21569
  });
21449
21570
  }
21571
+ getFilterSnapshot() {
21572
+ return this.filterStateManager?.getSnapshot?.() ?? { filters: [] };
21573
+ }
21574
+ applyFilterSnapshot(snapshot) {
21575
+ this.filterStateManager?.applySnapshot?.(snapshot, exports.FilterActionType.APPLY_FILTERS);
21576
+ }
21450
21577
  update() {
21451
21578
  if (this.filterStateManager) {
21452
21579
  this.reapplyActiveFilters();
@@ -21964,7 +22091,7 @@ ${recordsStr}
21964
22091
  }
21965
22092
 
21966
22093
  function handlePaginationExport(table, exportAllData) {
21967
- const pagination = cloneDeep$1(table.pagination);
22094
+ const pagination = cloneDeep$2(table.pagination);
21968
22095
  const isPivot = table.isPivotTable();
21969
22096
  const layoutMap = table.internalProps.layoutMap;
21970
22097
  let maxRow = table.rowCount - 1;
@@ -23602,10 +23729,10 @@ ${recordsStr}
23602
23729
  * console.log(deep[0] === objects[0]);
23603
23730
  * // => false
23604
23731
  */
23605
- function cloneDeep(value) {
23732
+ function cloneDeep$1(value) {
23606
23733
  return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
23607
23734
  }
23608
- var cloneDeep_1 = cloneDeep;
23735
+ var cloneDeep_1 = cloneDeep$1;
23609
23736
  var deepClone = /*@__PURE__*/getDefaultExportFromCjs(cloneDeep_1);
23610
23737
 
23611
23738
  const chnNumChar = { 零: 0, 一: 1, 二: 2, 三: 3, 四: 4, 五: 5, 六: 6, 七: 7, 八: 8, 九: 9 };
@@ -24199,8 +24326,9 @@ ${recordsStr}
24199
24326
  format: 'yyyy年M月d日',
24200
24327
  parser: (value) => {
24201
24328
  const match = value.match(/(\d{4})年(\d{1,2})月(\d{1,2})/);
24202
- if (!match)
24329
+ if (!match) {
24203
24330
  throw new Error('无效的中文日期格式');
24331
+ }
24204
24332
  return new Date(+match[1], +match[2] - 1, +match[3]);
24205
24333
  }
24206
24334
  }
@@ -24229,19 +24357,22 @@ ${recordsStr}
24229
24357
  let date;
24230
24358
  let formatMeta;
24231
24359
  if (value instanceof Date) {
24232
- if (!isValid(value))
24360
+ if (!isValid(value)) {
24233
24361
  throw new Error('无效的日期对象');
24362
+ }
24234
24363
  date = value;
24235
24364
  formatMeta = 'yyyy-MM-dd';
24236
24365
  }
24237
24366
  else {
24238
24367
  const str = value.trim();
24239
24368
  const matchedFormat = this.dateFormats.find(rule => rule.pattern.test(str));
24240
- if (!matchedFormat)
24369
+ if (!matchedFormat) {
24241
24370
  throw new Error(`不支持的日期格式: ${str}`);
24371
+ }
24242
24372
  date = matchedFormat.parser ? matchedFormat.parser(str) : parse(str, matchedFormat.format, new Date());
24243
- if (!isValid(date))
24373
+ if (!isValid(date)) {
24244
24374
  throw new Error(`无效的日期值: ${str}`);
24375
+ }
24245
24376
  formatMeta = matchedFormat.format;
24246
24377
  }
24247
24378
  return {
@@ -25203,6 +25334,1695 @@ ${recordsStr}
25203
25334
  }
25204
25335
  }
25205
25336
 
25337
+ function makeCellKey(sheetKey, row, col) {
25338
+ return `${sheetKey}:${row}:${col}`;
25339
+ }
25340
+ function parseA1Notation(a1) {
25341
+ const match = a1.match(/^([A-Z]+)([0-9]+)$/i);
25342
+ if (!match) {
25343
+ return null;
25344
+ }
25345
+ const letters = match[1].toUpperCase();
25346
+ const rowNumber = parseInt(match[2], 10);
25347
+ if (!rowNumber || rowNumber < 1) {
25348
+ return null;
25349
+ }
25350
+ let col = 0;
25351
+ for (let i = 0; i < letters.length; i++) {
25352
+ col = col * 26 + (letters.charCodeAt(i) - 64);
25353
+ }
25354
+ return { row: rowNumber - 1, col: col - 1 };
25355
+ }
25356
+ function captureCellPreChangeContent(args) {
25357
+ const { sheetKey, row, col, currentValue, formulaManager, store } = args;
25358
+ if (!sheetKey) {
25359
+ return;
25360
+ }
25361
+ const cellKey = makeCellKey(sheetKey, row, col);
25362
+ if (formulaManager?.getCellFormula) {
25363
+ try {
25364
+ const oldFormula = formulaManager.getCellFormula({ sheet: sheetKey, row, col });
25365
+ if (oldFormula) {
25366
+ const normalized = typeof oldFormula === 'string' && !oldFormula.startsWith('=') ? `=${oldFormula}` : oldFormula;
25367
+ store.set(cellKey, normalized);
25368
+ return;
25369
+ }
25370
+ }
25371
+ catch {
25372
+ }
25373
+ }
25374
+ store.set(cellKey, currentValue == null ? '' : currentValue);
25375
+ }
25376
+ function popCellPreChangeContent(args) {
25377
+ const { sheetKey, row, col, fallbackOldContent, store } = args;
25378
+ if (!sheetKey) {
25379
+ return fallbackOldContent;
25380
+ }
25381
+ const cellKey = makeCellKey(sheetKey, row, col);
25382
+ const oldContent = store.get(cellKey);
25383
+ store.delete(cellKey);
25384
+ return typeof oldContent !== 'undefined' ? oldContent : fallbackOldContent;
25385
+ }
25386
+ function applyCellContent(args) {
25387
+ const { table, sheetKey, row, col, content, formulaManager } = args;
25388
+ if (sheetKey && formulaManager?.setCellContent && formulaManager?.getCellValue) {
25389
+ try {
25390
+ formulaManager.setCellContent({ sheet: sheetKey, row, col }, content);
25391
+ }
25392
+ catch {
25393
+ table.changeCellValue(col, row, content, false, false, true);
25394
+ return;
25395
+ }
25396
+ const isFormula = typeof content === 'string' && content.startsWith('=');
25397
+ if (isFormula) {
25398
+ const result = formulaManager.getCellValue({ sheet: sheetKey, row, col });
25399
+ const display = result?.error ? '#ERROR!' : result?.value;
25400
+ table.changeCellValue(col, row, display, false, false, true);
25401
+ refreshDependentDisplays({ table, sheetKey, startCell: { sheet: sheetKey, row, col }, formulaManager });
25402
+ return;
25403
+ }
25404
+ table.changeCellValue(col, row, content, false, false, true);
25405
+ refreshDependentDisplays({ table, sheetKey, startCell: { sheet: sheetKey, row, col }, formulaManager });
25406
+ return;
25407
+ }
25408
+ table.changeCellValue(col, row, content, false, false, true);
25409
+ }
25410
+ function refreshDependentDisplays(args) {
25411
+ const { table, sheetKey, startCell, formulaManager } = args;
25412
+ const maxCells = args.maxCells ?? 5000;
25413
+ if (!formulaManager?.getCellDependents || !formulaManager?.getCellValue) {
25414
+ return;
25415
+ }
25416
+ const visited = new Set();
25417
+ const queue = [...(formulaManager.getCellDependents(startCell) || [])];
25418
+ let processed = 0;
25419
+ while (queue.length) {
25420
+ const cell = queue.shift();
25421
+ if (!cell || cell.sheet !== sheetKey) {
25422
+ continue;
25423
+ }
25424
+ const key = makeCellKey(cell.sheet, cell.row, cell.col);
25425
+ if (visited.has(key)) {
25426
+ continue;
25427
+ }
25428
+ visited.add(key);
25429
+ processed++;
25430
+ if (processed > maxCells) {
25431
+ break;
25432
+ }
25433
+ const result = formulaManager.getCellValue(cell);
25434
+ const display = result?.error ? '#ERROR!' : result?.value;
25435
+ table.changeCellValue(cell.col, cell.row, display, false, false, true);
25436
+ const deps = formulaManager.getCellDependents(cell) || [];
25437
+ deps.forEach((d) => queue.push(d));
25438
+ }
25439
+ }
25440
+
25441
+ function cloneMergeConfig(input) {
25442
+ if (Array.isArray(input)) {
25443
+ return input.map(i => ({
25444
+ ...i,
25445
+ range: i?.range
25446
+ ? {
25447
+ start: { ...i.range.start },
25448
+ end: { ...i.range.end }
25449
+ }
25450
+ : i?.range
25451
+ }));
25452
+ }
25453
+ return input;
25454
+ }
25455
+ function getCustomMergeCellFunc(customMergeCell) {
25456
+ if (typeof customMergeCell === 'function') {
25457
+ return customMergeCell;
25458
+ }
25459
+ if (Array.isArray(customMergeCell)) {
25460
+ return (col, row) => {
25461
+ return customMergeCell.find(item => {
25462
+ return (item.range.start.col <= col &&
25463
+ item.range.end.col >= col &&
25464
+ item.range.start.row <= row &&
25465
+ item.range.end.row >= row);
25466
+ });
25467
+ };
25468
+ }
25469
+ return undefined;
25470
+ }
25471
+ function applyMergeConfig(table, customMergeCell) {
25472
+ if (!table?.options || !table?.internalProps) {
25473
+ return;
25474
+ }
25475
+ table.options.customMergeCell = cloneMergeConfig(customMergeCell);
25476
+ table.internalProps.customMergeCell = getCustomMergeCellFunc(table.options.customMergeCell);
25477
+ }
25478
+ function cloneSortState(input) {
25479
+ if (!input) {
25480
+ return null;
25481
+ }
25482
+ if (Array.isArray(input)) {
25483
+ return input.filter(Boolean).map((s) => ({
25484
+ field: s.field,
25485
+ order: s.order
25486
+ }));
25487
+ }
25488
+ return {
25489
+ field: input.field,
25490
+ order: input.order
25491
+ };
25492
+ }
25493
+ function replayCommand(args) {
25494
+ const { table, vtableSheet, cmd, direction, deleteRecordsByReference } = args;
25495
+ switch (cmd.type) {
25496
+ case 'cell':
25497
+ case 'cells': {
25498
+ const sheetKey = cmd.sheetKey;
25499
+ const cells = cmd.cells;
25500
+ cells.forEach(c => {
25501
+ const content = direction === 'undo' ? c.oldContent : c.newContent;
25502
+ applyCellContent({
25503
+ table,
25504
+ sheetKey,
25505
+ row: c.row,
25506
+ col: c.col,
25507
+ content,
25508
+ formulaManager: vtableSheet?.formulaManager
25509
+ });
25510
+ });
25511
+ break;
25512
+ }
25513
+ case 'merge_cells': {
25514
+ const c = cmd;
25515
+ const next = direction === 'undo' ? c.oldCustomMergeCell : c.newCustomMergeCell;
25516
+ applyMergeConfig(table, next);
25517
+ const sg = table.scenegraph;
25518
+ if (sg?.updateCellContent) {
25519
+ for (let i = c.startCol; i <= c.endCol; i++) {
25520
+ for (let j = c.startRow; j <= c.endRow; j++) {
25521
+ sg.updateCellContent(i, j);
25522
+ }
25523
+ }
25524
+ sg.updateNextFrame?.();
25525
+ }
25526
+ else if (typeof table.renderWithRecreateCells === 'function') {
25527
+ table.renderWithRecreateCells();
25528
+ }
25529
+ break;
25530
+ }
25531
+ case 'filter': {
25532
+ const c = cmd;
25533
+ const pluginId = c.pluginId;
25534
+ const snapshot = direction === 'undo' ? c.oldSnapshot : c.newSnapshot;
25535
+ const pm = table.pluginManager;
25536
+ const filterPlugin = pm?.getPlugin?.(pluginId) ??
25537
+ pm?.getPluginByName?.('Filter') ??
25538
+ pm?.getPlugin?.('filter') ??
25539
+ pm?.getPluginByName?.('filter');
25540
+ if (filterPlugin?.applyFilterSnapshot) {
25541
+ filterPlugin.applyFilterSnapshot(snapshot);
25542
+ }
25543
+ break;
25544
+ }
25545
+ case 'sort': {
25546
+ const c = cmd;
25547
+ const next = direction === 'undo' ? c.oldSortState : c.newSortState;
25548
+ table.updateSortState?.(cloneSortState(next) ?? null, true);
25549
+ break;
25550
+ }
25551
+ case 'add_record': {
25552
+ const c = cmd;
25553
+ if (direction === 'undo') {
25554
+ const ds = table?.internalProps?.dataSource;
25555
+ const rawRecords = ds?.dataSourceObj?.records;
25556
+ let deletedByRaw = false;
25557
+ if (Array.isArray(rawRecords) && typeof c.rawInsertIndex === 'number' && c.recordCount > 0) {
25558
+ const idx = c.rawInsertIndex;
25559
+ if (idx >= 0 && idx < rawRecords.length) {
25560
+ rawRecords.splice(idx, c.recordCount);
25561
+ deletedByRaw = true;
25562
+ }
25563
+ }
25564
+ if (Array.isArray(rawRecords) && Array.isArray(c.records) && c.records.length) {
25565
+ for (let i = 0; i < c.records.length; i++) {
25566
+ const rawIndex = rawRecords.indexOf(c.records[i]);
25567
+ if (rawIndex >= 0) {
25568
+ rawRecords.splice(rawIndex, 1);
25569
+ deletedByRaw = true;
25570
+ }
25571
+ }
25572
+ }
25573
+ if (!deletedByRaw && Array.isArray(rawRecords) && typeof c.recordCount === 'number' && c.recordCount > 0) {
25574
+ const before = c.anchorBefore;
25575
+ const after = c.anchorAfter;
25576
+ const beforeIndex = before ? rawRecords.indexOf(before) : -1;
25577
+ const afterIndex = after ? rawRecords.indexOf(after) : -1;
25578
+ if (beforeIndex >= 0) {
25579
+ rawRecords.splice(beforeIndex + 1, c.recordCount);
25580
+ deletedByRaw = true;
25581
+ }
25582
+ else if (afterIndex >= 0) {
25583
+ rawRecords.splice(Math.max(0, afterIndex - c.recordCount), c.recordCount);
25584
+ deletedByRaw = true;
25585
+ }
25586
+ }
25587
+ if (deletedByRaw) {
25588
+ ds?.beforeChangedRecordsMap?.clear?.();
25589
+ ds?.sortedIndexMap?.clear?.();
25590
+ if (typeof table.updateFilterRules === 'function') {
25591
+ table.updateFilterRules(ds?.dataConfig?.filterRules, {
25592
+ clearRowHeightCache: false
25593
+ });
25594
+ }
25595
+ else {
25596
+ ds?.updateFilterRules?.(ds?.dataConfig?.filterRules);
25597
+ }
25598
+ }
25599
+ if (!deletedByRaw) {
25600
+ if (typeof c.recordIndex === 'number' && c.recordCount > 0) {
25601
+ const indexs = [];
25602
+ for (let i = 0; i < c.recordCount; i++) {
25603
+ indexs.push(c.recordIndex + i);
25604
+ }
25605
+ table.deleteRecords?.(indexs);
25606
+ }
25607
+ else {
25608
+ deleteRecordsByReference(c.records);
25609
+ }
25610
+ }
25611
+ }
25612
+ else {
25613
+ if (c.records.length) {
25614
+ table.addRecords?.(c.records, c.recordIndex);
25615
+ }
25616
+ }
25617
+ break;
25618
+ }
25619
+ case 'delete_record': {
25620
+ const c = cmd;
25621
+ if (direction === 'undo') {
25622
+ if (table.addRecord && Array.isArray(c.records) && Array.isArray(c.recordIndexs)) {
25623
+ const pairs = [];
25624
+ for (let i = 0; i < c.recordIndexs.length; i++) {
25625
+ const idx = c.recordIndexs[i];
25626
+ if (typeof idx === 'number') {
25627
+ pairs.push({ idx, record: c.records[i] });
25628
+ }
25629
+ }
25630
+ pairs.sort((a, b) => a.idx - b.idx);
25631
+ for (const p of pairs) {
25632
+ table.addRecord(p.record, p.idx);
25633
+ }
25634
+ }
25635
+ if (c.deletedRowHeights && typeof table.setRowHeight === 'function') {
25636
+ const headerCount = table.transpose
25637
+ ? table.rowHeaderLevelCount
25638
+ : table.columnHeaderLevelCount;
25639
+ Object.keys(c.deletedRowHeights).forEach(k => {
25640
+ const idx = Number(k);
25641
+ const height = c.deletedRowHeights[k];
25642
+ if (!Number.isFinite(idx) || typeof height !== 'number') {
25643
+ return;
25644
+ }
25645
+ table.setRowHeight(idx + (headerCount ?? 0), height);
25646
+ });
25647
+ }
25648
+ }
25649
+ else {
25650
+ if (table.deleteRecords) {
25651
+ table.deleteRecords(c.recordIndexs);
25652
+ }
25653
+ }
25654
+ const hasMergeSnapshot = 'oldCustomMergeCell' in c || 'newCustomMergeCell' in c;
25655
+ if (hasMergeSnapshot) {
25656
+ const target = direction === 'undo' ? c.oldCustomMergeCell : c.newCustomMergeCell;
25657
+ applyMergeConfig(table, target);
25658
+ const sg = table.scenegraph;
25659
+ if (sg?.updateCellContent) {
25660
+ const prevRanges = Array.isArray(c.oldCustomMergeCell)
25661
+ ? c.oldCustomMergeCell.map(i => i?.range).filter(Boolean)
25662
+ : [];
25663
+ const nextRanges = Array.isArray(c.newCustomMergeCell)
25664
+ ? c.newCustomMergeCell.map(i => i?.range).filter(Boolean)
25665
+ : [];
25666
+ const refreshRanges = [...prevRanges, ...nextRanges];
25667
+ refreshRanges.forEach(r => {
25668
+ if (!r?.start) {
25669
+ return;
25670
+ }
25671
+ for (let col = r.start.col; col <= r.end.col; col++) {
25672
+ for (let row = r.start.row; row <= r.end.row; row++) {
25673
+ sg.updateCellContent(col, row);
25674
+ }
25675
+ }
25676
+ });
25677
+ sg.updateNextFrame?.();
25678
+ }
25679
+ else if (typeof table.renderWithRecreateCells === 'function') {
25680
+ table.renderWithRecreateCells();
25681
+ }
25682
+ }
25683
+ break;
25684
+ }
25685
+ case 'update_record': {
25686
+ const c = cmd;
25687
+ if (table.updateRecords) {
25688
+ if (direction === 'undo') {
25689
+ table.updateRecords(c.oldRecords, c.recordIndexs);
25690
+ }
25691
+ else {
25692
+ table.updateRecords(c.newRecords, c.recordIndexs);
25693
+ }
25694
+ }
25695
+ break;
25696
+ }
25697
+ case 'add_column': {
25698
+ const c = cmd;
25699
+ if (direction === 'undo') {
25700
+ const deleteIndexs = [];
25701
+ for (let i = 0; i < c.columnCount; i++) {
25702
+ deleteIndexs.push(c.columnIndex + i);
25703
+ }
25704
+ table.deleteColumns?.(deleteIndexs, true);
25705
+ }
25706
+ else {
25707
+ table.addColumns?.(c.columns, c.columnIndex, true);
25708
+ }
25709
+ break;
25710
+ }
25711
+ case 'delete_column': {
25712
+ const c = cmd;
25713
+ if (direction === 'undo') {
25714
+ const items = c.deleteColIndexs.map((idx, i) => ({ idx, column: c.columns[i] })).sort((a, b) => a.idx - b.idx);
25715
+ items.forEach(item => {
25716
+ table.addColumns?.([item.column], item.idx, true);
25717
+ });
25718
+ if (c.deletedColWidths && typeof table.setColWidth === 'function') {
25719
+ Object.entries(c.deletedColWidths).forEach(([k, width]) => {
25720
+ const idx = Number(k);
25721
+ if (!Number.isFinite(idx) || typeof width !== 'number') {
25722
+ return;
25723
+ }
25724
+ table.setColWidth(idx, width);
25725
+ });
25726
+ }
25727
+ if (Array.isArray(c.deletedRecordValues) && c.deletedRecordValues.length) {
25728
+ const records = table.records;
25729
+ if (Array.isArray(records) && records.length) {
25730
+ const recordIndexs = [];
25731
+ const newRecords = [];
25732
+ for (let i = 0; i < records.length; i++) {
25733
+ const rec = records[i];
25734
+ const rowValues = c.deletedRecordValues[i];
25735
+ if (!Array.isArray(rec) || !Array.isArray(rowValues) || rowValues.length !== c.deleteColIndexs.length) {
25736
+ continue;
25737
+ }
25738
+ const next = rec.slice();
25739
+ for (let k = 0; k < c.deleteColIndexs.length; k++) {
25740
+ next[c.deleteColIndexs[k]] = rowValues[k];
25741
+ }
25742
+ recordIndexs.push(i);
25743
+ newRecords.push(next);
25744
+ }
25745
+ if (recordIndexs.length) {
25746
+ table.updateRecords?.(newRecords, recordIndexs, false);
25747
+ }
25748
+ }
25749
+ }
25750
+ if (c.sheetKey) {
25751
+ const fm = vtableSheet?.formulaManager;
25752
+ const engine = fm?.formulaEngine;
25753
+ if (fm?.normalizeSheetData && engine?.updateSheetData) {
25754
+ try {
25755
+ const normalized = fm.normalizeSheetData(table.records || [], table);
25756
+ engine.updateSheetData(c.sheetKey, normalized);
25757
+ }
25758
+ catch {
25759
+ }
25760
+ }
25761
+ }
25762
+ if (c.sheetKey && c.deletedFormulas) {
25763
+ const entries = Object.entries(c.deletedFormulas);
25764
+ entries.forEach(([cellRef, formula]) => {
25765
+ const parsed = parseA1Notation(cellRef);
25766
+ if (!parsed) {
25767
+ return;
25768
+ }
25769
+ applyCellContent({
25770
+ table,
25771
+ sheetKey: c.sheetKey,
25772
+ row: parsed.row,
25773
+ col: parsed.col,
25774
+ content: formula,
25775
+ formulaManager: vtableSheet?.formulaManager
25776
+ });
25777
+ });
25778
+ }
25779
+ }
25780
+ else {
25781
+ table.deleteColumns?.(c.deleteColIndexs, true);
25782
+ }
25783
+ break;
25784
+ }
25785
+ case 'change_header_position': {
25786
+ const c = cmd;
25787
+ const moving = c.moving;
25788
+ const from = direction === 'undo' ? c.targetIndex : c.sourceIndex;
25789
+ const to = direction === 'undo' ? c.sourceIndex : c.targetIndex;
25790
+ if (moving === 'column') {
25791
+ table.changeHeaderPosition?.({
25792
+ source: { col: from, row: 0 },
25793
+ target: { col: to, row: 0 },
25794
+ movingColumnOrRow: 'column'
25795
+ });
25796
+ }
25797
+ else {
25798
+ table.changeHeaderPosition?.({
25799
+ source: { col: 0, row: from },
25800
+ target: { col: 0, row: to },
25801
+ movingColumnOrRow: 'row'
25802
+ });
25803
+ }
25804
+ break;
25805
+ }
25806
+ case 'resize_row': {
25807
+ const c = cmd;
25808
+ const height = direction === 'undo' ? c.oldHeight : c.newHeight;
25809
+ table.setRowHeight?.(c.row, height);
25810
+ break;
25811
+ }
25812
+ case 'resize_column': {
25813
+ const c = cmd;
25814
+ const width = direction === 'undo' ? c.oldWidth : c.newWidth;
25815
+ table.setColWidth?.(c.col, width);
25816
+ break;
25817
+ }
25818
+ }
25819
+ }
25820
+
25821
+ function cloneDeep(input, cache = new WeakMap()) {
25822
+ if (input === null || input === undefined) {
25823
+ return input;
25824
+ }
25825
+ const t = typeof input;
25826
+ if (t === 'function' || t !== 'object') {
25827
+ return input;
25828
+ }
25829
+ const obj = input;
25830
+ if (obj instanceof Date) {
25831
+ return new Date(obj.getTime());
25832
+ }
25833
+ if (obj instanceof RegExp) {
25834
+ return new RegExp(obj);
25835
+ }
25836
+ if (cache.has(obj)) {
25837
+ return cache.get(obj);
25838
+ }
25839
+ if (Array.isArray(obj)) {
25840
+ const arr = [];
25841
+ cache.set(obj, arr);
25842
+ for (let i = 0; i < obj.length; i++) {
25843
+ arr[i] = cloneDeep(obj[i], cache);
25844
+ }
25845
+ return arr;
25846
+ }
25847
+ const out = {};
25848
+ cache.set(obj, out);
25849
+ Object.keys(obj).forEach(key => {
25850
+ out[key] = cloneDeep(obj[key], cache);
25851
+ });
25852
+ return out;
25853
+ }
25854
+ function captureSnapshot(table, state, options) {
25855
+ const tableOptions = table.options || {};
25856
+ const columns = tableOptions.columns;
25857
+ if (Array.isArray(columns)) {
25858
+ state.prevColumnsSnapshot = columns.map(c => cloneDeep(c));
25859
+ }
25860
+ else {
25861
+ state.prevColumnsSnapshot = null;
25862
+ }
25863
+ const merge = tableOptions.customMergeCell;
25864
+ if (Array.isArray(merge)) {
25865
+ state.prevMergeSnapshot = merge.map(m => ({
25866
+ ...m,
25867
+ range: {
25868
+ start: { ...m.range.start },
25869
+ end: { ...m.range.end }
25870
+ }
25871
+ }));
25872
+ }
25873
+ else {
25874
+ state.prevMergeSnapshot = merge;
25875
+ }
25876
+ const records = (table.records || []);
25877
+ if (Array.isArray(records)) {
25878
+ state.prevRecordsSnapshot = records.map(r => cloneRecord(r));
25879
+ }
25880
+ else {
25881
+ state.prevRecordsSnapshot = null;
25882
+ }
25883
+ try {
25884
+ const resizedRowIndexs = Array.from(table.internalProps?._heightResizedRowMap?.keys?.() ?? []);
25885
+ if (resizedRowIndexs.length && typeof table.getRowHeight === 'function') {
25886
+ const map = {};
25887
+ resizedRowIndexs.forEach((rowIndex) => {
25888
+ if (typeof rowIndex !== 'number') {
25889
+ return;
25890
+ }
25891
+ const h = table.getRowHeight(rowIndex);
25892
+ if (typeof h === 'number') {
25893
+ map[rowIndex] = h;
25894
+ }
25895
+ });
25896
+ state.prevResizedRowHeightsSnapshot = map;
25897
+ }
25898
+ else {
25899
+ state.prevResizedRowHeightsSnapshot = null;
25900
+ }
25901
+ }
25902
+ catch {
25903
+ state.prevResizedRowHeightsSnapshot = null;
25904
+ }
25905
+ try {
25906
+ const resizedColIndexs = Array.from(table.internalProps?._widthResizedColMap?.keys?.() ?? []);
25907
+ if (resizedColIndexs.length && typeof table.getColWidth === 'function') {
25908
+ const map = {};
25909
+ resizedColIndexs.forEach((colIndex) => {
25910
+ if (typeof colIndex !== 'number') {
25911
+ return;
25912
+ }
25913
+ const w = table.getColWidth(colIndex);
25914
+ if (typeof w === 'number') {
25915
+ map[colIndex] = w;
25916
+ }
25917
+ });
25918
+ state.prevResizedColWidthsSnapshot = map;
25919
+ }
25920
+ else {
25921
+ state.prevResizedColWidthsSnapshot = null;
25922
+ }
25923
+ }
25924
+ catch {
25925
+ state.prevResizedColWidthsSnapshot = null;
25926
+ }
25927
+ if (options?.formulaManager?.exportFormulas && options.sheetKey) {
25928
+ try {
25929
+ const formulas = options.formulaManager.exportFormulas(options.sheetKey);
25930
+ state.prevFormulasSnapshot = formulas ? { ...formulas } : null;
25931
+ }
25932
+ catch {
25933
+ state.prevFormulasSnapshot = null;
25934
+ }
25935
+ }
25936
+ else {
25937
+ state.prevFormulasSnapshot = null;
25938
+ }
25939
+ }
25940
+ function cloneRecord(record) {
25941
+ if (Array.isArray(record)) {
25942
+ return record.slice();
25943
+ }
25944
+ if (record && typeof record === 'object') {
25945
+ return { ...record };
25946
+ }
25947
+ return record;
25948
+ }
25949
+
25950
+ function resolveSheetKey(args) {
25951
+ const { vtableSheet, table, cached } = args;
25952
+ if (!vtableSheet) {
25953
+ return { sheetKey: undefined, cached: undefined };
25954
+ }
25955
+ if (cached) {
25956
+ return { sheetKey: cached, cached };
25957
+ }
25958
+ try {
25959
+ const workSheetInstances = vtableSheet.workSheetInstances;
25960
+ if (workSheetInstances && table) {
25961
+ for (const [sheetKey, worksheet] of workSheetInstances.entries()) {
25962
+ if (worksheet?.tableInstance === table) {
25963
+ return { sheetKey, cached: sheetKey };
25964
+ }
25965
+ }
25966
+ }
25967
+ const active = vtableSheet.getActiveSheet?.();
25968
+ if (active?.getKey) {
25969
+ const key = active.getKey();
25970
+ return { sheetKey: key, cached: key };
25971
+ }
25972
+ const activeDefine = vtableSheet.sheetManager?.getActiveSheet?.();
25973
+ const key = activeDefine?.sheetKey;
25974
+ return { sheetKey: key, cached: key };
25975
+ }
25976
+ catch {
25977
+ return { sheetKey: undefined, cached: undefined };
25978
+ }
25979
+ }
25980
+
25981
+ class HistoryPlugin {
25982
+ id = 'history-plugin';
25983
+ name = 'History';
25984
+ runTime = [
25985
+ VTable.TABLE_EVENT_TYPE.BEFORE_INIT,
25986
+ VTable.TABLE_EVENT_TYPE.INITIALIZED,
25987
+ VTable.TABLE_EVENT_TYPE.BEFORE_KEYDOWN,
25988
+ VTable.TABLE_EVENT_TYPE.CHANGE_CELL_VALUE,
25989
+ VTable.TABLE_EVENT_TYPE.CHANGE_CELL_VALUES,
25990
+ VTable.TABLE_EVENT_TYPE.PASTED_DATA,
25991
+ VTable.TABLE_EVENT_TYPE.MERGE_CELLS,
25992
+ VTable.TABLE_EVENT_TYPE.UNMERGE_CELLS,
25993
+ VTable.TABLE_EVENT_TYPE.ADD_RECORD,
25994
+ VTable.TABLE_EVENT_TYPE.DELETE_RECORD,
25995
+ VTable.TABLE_EVENT_TYPE.UPDATE_RECORD,
25996
+ VTable.TABLE_EVENT_TYPE.ADD_COLUMN,
25997
+ VTable.TABLE_EVENT_TYPE.DELETE_COLUMN,
25998
+ VTable.TABLE_EVENT_TYPE.CHANGE_HEADER_POSITION,
25999
+ VTable.TABLE_EVENT_TYPE.SORT_CLICK,
26000
+ VTable.TABLE_EVENT_TYPE.RESIZE_ROW,
26001
+ VTable.TABLE_EVENT_TYPE.RESIZE_ROW_END,
26002
+ VTable.TABLE_EVENT_TYPE.RESIZE_COLUMN,
26003
+ VTable.TABLE_EVENT_TYPE.RESIZE_COLUMN_END
26004
+ ];
26005
+ table = null;
26006
+ vtableSheet;
26007
+ resolvedSheetKey;
26008
+ undoStack = [];
26009
+ redoStack = [];
26010
+ currentTransaction = null;
26011
+ isReplaying = false;
26012
+ maxHistory;
26013
+ enableCompression;
26014
+ onTransactionPushed;
26015
+ prevColumnsSnapshot = null;
26016
+ prevMergeSnapshot;
26017
+ prevRecordsSnapshot = null;
26018
+ prevFormulasSnapshot = null;
26019
+ prevResizedRowHeightsSnapshot = null;
26020
+ prevResizedColWidthsSnapshot = null;
26021
+ lastKnownSortState = null;
26022
+ sortStartSnapshot = null;
26023
+ sortPending = false;
26024
+ sortEventBound = false;
26025
+ sortChangeOrderListenerId;
26026
+ cellPreChangeContent = new Map();
26027
+ formulaCache = new Map();
26028
+ formulaEventBound = false;
26029
+ formulaEventManager;
26030
+ onFormulaAddedHandler;
26031
+ resizeRowStartHeight = new Map();
26032
+ resizeColStartWidth = new Map();
26033
+ filterEventBound = false;
26034
+ filterUnsubscribe = null;
26035
+ filterSnapshotCache;
26036
+ filterPluginId;
26037
+ filterPluginRef;
26038
+ filterApplySnapshotOriginal;
26039
+ filterApplyingSnapshot = false;
26040
+ constructor(options) {
26041
+ this.id = options?.id ?? this.id;
26042
+ this.maxHistory = options?.maxHistory ?? 100;
26043
+ this.enableCompression = options?.enableCompression ?? false;
26044
+ this.onTransactionPushed = options?.onTransactionPushed;
26045
+ }
26046
+ run(...args) {
26047
+ const eventArgs = args[0];
26048
+ const runtime = args[1];
26049
+ const table = args[2];
26050
+ if (!table) {
26051
+ return;
26052
+ }
26053
+ if (!this.table) {
26054
+ this.table = table;
26055
+ this.vtableSheet = table.__vtableSheet;
26056
+ if (runtime !== VTable.TABLE_EVENT_TYPE.BEFORE_INIT && table.internalProps?.dataSource) {
26057
+ const state = this.getSnapshotState();
26058
+ const sheetKey = this.getSheetKey();
26059
+ captureSnapshot(table, state, {
26060
+ formulaManager: this.vtableSheet?.formulaManager,
26061
+ sheetKey
26062
+ });
26063
+ this.setSnapshotState(state);
26064
+ this.lastKnownSortState = this.normalizeSortState(table.internalProps?.sortState);
26065
+ }
26066
+ }
26067
+ else if (!this.vtableSheet) {
26068
+ this.vtableSheet = table.__vtableSheet;
26069
+ }
26070
+ this.ensureFilterEventBindings();
26071
+ if (runtime === VTable.TABLE_EVENT_TYPE.BEFORE_INIT) {
26072
+ return;
26073
+ }
26074
+ this.ensureFormulaEventBindings();
26075
+ this.ensureSortEventBindings();
26076
+ const workbookReplaying = this.table?.__vtableSheet?.__workbookHistoryReplaying;
26077
+ if (this.isReplaying || workbookReplaying) {
26078
+ return;
26079
+ }
26080
+ switch (runtime) {
26081
+ case VTable.TABLE_EVENT_TYPE.INITIALIZED:
26082
+ break;
26083
+ case VTable.TABLE_EVENT_TYPE.BEFORE_KEYDOWN:
26084
+ this.handleBeforeKeydown(eventArgs);
26085
+ break;
26086
+ case VTable.TABLE_EVENT_TYPE.CHANGE_CELL_VALUE:
26087
+ this.handleChangeCellValue(eventArgs);
26088
+ break;
26089
+ case VTable.TABLE_EVENT_TYPE.CHANGE_CELL_VALUES:
26090
+ this.handleChangeCellValues(eventArgs);
26091
+ break;
26092
+ case VTable.TABLE_EVENT_TYPE.PASTED_DATA:
26093
+ break;
26094
+ case VTable.TABLE_EVENT_TYPE.MERGE_CELLS:
26095
+ this.handleMergeCells(eventArgs);
26096
+ break;
26097
+ case VTable.TABLE_EVENT_TYPE.UNMERGE_CELLS:
26098
+ this.handleUnmergeCells(eventArgs);
26099
+ break;
26100
+ case VTable.TABLE_EVENT_TYPE.ADD_RECORD:
26101
+ this.handleAddRecord(eventArgs);
26102
+ break;
26103
+ case VTable.TABLE_EVENT_TYPE.DELETE_RECORD:
26104
+ this.handleDeleteRecord(eventArgs);
26105
+ break;
26106
+ case VTable.TABLE_EVENT_TYPE.UPDATE_RECORD:
26107
+ this.handleUpdateRecord(eventArgs);
26108
+ break;
26109
+ case VTable.TABLE_EVENT_TYPE.ADD_COLUMN:
26110
+ this.handleAddColumn(eventArgs);
26111
+ break;
26112
+ case VTable.TABLE_EVENT_TYPE.DELETE_COLUMN:
26113
+ this.handleDeleteColumn(eventArgs);
26114
+ break;
26115
+ case VTable.TABLE_EVENT_TYPE.CHANGE_HEADER_POSITION:
26116
+ this.handleChangeHeaderPosition(eventArgs);
26117
+ break;
26118
+ case VTable.TABLE_EVENT_TYPE.SORT_CLICK:
26119
+ this.handleSortClick(eventArgs);
26120
+ break;
26121
+ case VTable.TABLE_EVENT_TYPE.RESIZE_ROW:
26122
+ this.handleResizeRow(eventArgs);
26123
+ break;
26124
+ case VTable.TABLE_EVENT_TYPE.RESIZE_ROW_END:
26125
+ this.handleResizeRowEnd(eventArgs);
26126
+ break;
26127
+ case VTable.TABLE_EVENT_TYPE.RESIZE_COLUMN:
26128
+ this.handleResizeColumn(eventArgs);
26129
+ break;
26130
+ case VTable.TABLE_EVENT_TYPE.RESIZE_COLUMN_END:
26131
+ this.handleResizeColumnEnd(eventArgs);
26132
+ break;
26133
+ }
26134
+ if (this.table) {
26135
+ const state = this.getSnapshotState();
26136
+ const sheetKey = this.getSheetKey();
26137
+ captureSnapshot(this.table, state, {
26138
+ formulaManager: this.vtableSheet?.formulaManager,
26139
+ sheetKey
26140
+ });
26141
+ this.setSnapshotState(state);
26142
+ }
26143
+ }
26144
+ startTransaction() {
26145
+ if (this.currentTransaction) {
26146
+ return;
26147
+ }
26148
+ this.currentTransaction = { commands: [] };
26149
+ }
26150
+ endTransaction() {
26151
+ if (!this.currentTransaction || this.currentTransaction.commands.length === 0) {
26152
+ this.currentTransaction = null;
26153
+ return;
26154
+ }
26155
+ this.pushTransaction(this.currentTransaction);
26156
+ this.currentTransaction = null;
26157
+ }
26158
+ undo() {
26159
+ if (!this.table || this.undoStack.length === 0) {
26160
+ return;
26161
+ }
26162
+ const transaction = this.undoStack.pop();
26163
+ this.isReplaying = true;
26164
+ try {
26165
+ for (let i = transaction.commands.length - 1; i >= 0; i--) {
26166
+ this.applyCommand(transaction.commands[i], 'undo');
26167
+ }
26168
+ }
26169
+ finally {
26170
+ this.isReplaying = false;
26171
+ }
26172
+ this.redoStack.push(transaction);
26173
+ if (this.table) {
26174
+ const state = this.getSnapshotState();
26175
+ const sheetKey = this.getSheetKey();
26176
+ captureSnapshot(this.table, state, {
26177
+ formulaManager: this.vtableSheet?.formulaManager,
26178
+ sheetKey
26179
+ });
26180
+ this.setSnapshotState(state);
26181
+ }
26182
+ }
26183
+ redo() {
26184
+ if (!this.table || this.redoStack.length === 0) {
26185
+ return;
26186
+ }
26187
+ const transaction = this.redoStack.pop();
26188
+ this.isReplaying = true;
26189
+ try {
26190
+ for (const cmd of transaction.commands) {
26191
+ this.applyCommand(cmd, 'redo');
26192
+ }
26193
+ }
26194
+ finally {
26195
+ this.isReplaying = false;
26196
+ }
26197
+ this.undoStack.push(transaction);
26198
+ if (this.table) {
26199
+ const state = this.getSnapshotState();
26200
+ const sheetKey = this.getSheetKey();
26201
+ captureSnapshot(this.table, state, {
26202
+ formulaManager: this.vtableSheet?.formulaManager,
26203
+ sheetKey
26204
+ });
26205
+ this.setSnapshotState(state);
26206
+ }
26207
+ }
26208
+ clear() {
26209
+ this.undoStack = [];
26210
+ this.redoStack = [];
26211
+ this.currentTransaction = null;
26212
+ }
26213
+ updateOptions(options) {
26214
+ if (options.maxHistory != null) {
26215
+ this.maxHistory = options.maxHistory;
26216
+ this.trimHistory();
26217
+ }
26218
+ if (options.enableCompression != null) {
26219
+ this.enableCompression = options.enableCompression;
26220
+ }
26221
+ if (options.onTransactionPushed) {
26222
+ this.onTransactionPushed = options.onTransactionPushed;
26223
+ }
26224
+ }
26225
+ release() {
26226
+ this.clear();
26227
+ this.unbindFormulaEvents();
26228
+ this.unbindSortEvents();
26229
+ this.unbindFilterEvents();
26230
+ this.table = null;
26231
+ this.vtableSheet = null;
26232
+ this.resolvedSheetKey = undefined;
26233
+ this.prevColumnsSnapshot = null;
26234
+ this.prevMergeSnapshot = undefined;
26235
+ this.prevRecordsSnapshot = null;
26236
+ this.prevFormulasSnapshot = null;
26237
+ this.prevResizedRowHeightsSnapshot = null;
26238
+ this.prevResizedColWidthsSnapshot = null;
26239
+ this.lastKnownSortState = null;
26240
+ this.sortStartSnapshot = null;
26241
+ this.sortPending = false;
26242
+ this.sortEventBound = false;
26243
+ this.sortChangeOrderListenerId = undefined;
26244
+ this.cellPreChangeContent.clear();
26245
+ this.formulaCache.clear();
26246
+ this.resizeRowStartHeight.clear();
26247
+ this.resizeColStartWidth.clear();
26248
+ this.filterEventBound = false;
26249
+ this.filterUnsubscribe = null;
26250
+ this.filterSnapshotCache = undefined;
26251
+ this.filterPluginId = undefined;
26252
+ }
26253
+ ensureFilterEventBindings() {
26254
+ if (!this.table) {
26255
+ return;
26256
+ }
26257
+ const pm = this.table.pluginManager;
26258
+ const filterPlugin = pm?.getPlugin?.('filter') ??
26259
+ pm?.getPluginByName?.('Filter') ??
26260
+ pm?.getPlugin?.('filter-plugin') ??
26261
+ pm?.getPluginByName?.('filter-plugin');
26262
+ if (!filterPlugin?.getFilterSnapshot || !filterPlugin?.applyFilterSnapshot) {
26263
+ return;
26264
+ }
26265
+ if (!this.filterEventBound) {
26266
+ this.filterEventBound = true;
26267
+ this.filterPluginRef = filterPlugin;
26268
+ this.filterPluginId = filterPlugin.id ?? 'filter';
26269
+ this.filterSnapshotCache = cloneDeep(filterPlugin.getFilterSnapshot());
26270
+ }
26271
+ if (!this.filterApplySnapshotOriginal) {
26272
+ this.filterApplySnapshotOriginal = filterPlugin.applyFilterSnapshot?.bind(filterPlugin);
26273
+ if (this.filterApplySnapshotOriginal) {
26274
+ filterPlugin.applyFilterSnapshot = (snapshot) => {
26275
+ if (this.isReplaying) {
26276
+ return this.filterApplySnapshotOriginal(snapshot);
26277
+ }
26278
+ const oldSnapshot = this.filterSnapshotCache ?? filterPlugin.getFilterSnapshot();
26279
+ this.filterApplyingSnapshot = true;
26280
+ try {
26281
+ return this.filterApplySnapshotOriginal(snapshot);
26282
+ }
26283
+ finally {
26284
+ this.filterApplyingSnapshot = false;
26285
+ const newSnapshot = filterPlugin.getFilterSnapshot();
26286
+ if (JSON.stringify(oldSnapshot) !== JSON.stringify(newSnapshot)) {
26287
+ const cmd = {
26288
+ type: 'filter',
26289
+ sheetKey: this.getSheetKey(),
26290
+ pluginId: this.filterPluginId ?? 'filter',
26291
+ oldSnapshot,
26292
+ newSnapshot
26293
+ };
26294
+ this.pushCommand(cmd);
26295
+ this.filterSnapshotCache = cloneDeep(newSnapshot);
26296
+ }
26297
+ else {
26298
+ this.filterSnapshotCache = cloneDeep(newSnapshot);
26299
+ }
26300
+ }
26301
+ };
26302
+ }
26303
+ }
26304
+ const stateManager = filterPlugin?.filterStateManager;
26305
+ if (!this.filterUnsubscribe && stateManager?.subscribe) {
26306
+ this.filterUnsubscribe = stateManager.subscribe((_state, action) => {
26307
+ if (this.isReplaying) {
26308
+ return;
26309
+ }
26310
+ if (this.filterApplyingSnapshot) {
26311
+ this.filterSnapshotCache = cloneDeep(filterPlugin.getFilterSnapshot());
26312
+ return;
26313
+ }
26314
+ const t = action?.type;
26315
+ if (t !== exports.FilterActionType.APPLY_FILTERS &&
26316
+ t !== exports.FilterActionType.CLEAR_ALL_FILTERS &&
26317
+ t !== exports.FilterActionType.REMOVE_FILTER &&
26318
+ t !== exports.FilterActionType.DISABLE_FILTER) {
26319
+ return;
26320
+ }
26321
+ const oldSnapshot = this.filterSnapshotCache ?? filterPlugin.getFilterSnapshot();
26322
+ const newSnapshot = filterPlugin.getFilterSnapshot();
26323
+ if (JSON.stringify(oldSnapshot) === JSON.stringify(newSnapshot)) {
26324
+ return;
26325
+ }
26326
+ const cmd = {
26327
+ type: 'filter',
26328
+ sheetKey: this.getSheetKey(),
26329
+ pluginId: this.filterPluginId ?? 'filter',
26330
+ oldSnapshot,
26331
+ newSnapshot
26332
+ };
26333
+ this.pushCommand(cmd);
26334
+ this.filterSnapshotCache = cloneDeep(newSnapshot);
26335
+ });
26336
+ }
26337
+ }
26338
+ unbindFilterEvents() {
26339
+ this.filterUnsubscribe?.();
26340
+ this.filterUnsubscribe = null;
26341
+ this.filterEventBound = false;
26342
+ if (this.filterPluginRef && this.filterApplySnapshotOriginal) {
26343
+ this.filterPluginRef.applyFilterSnapshot = this.filterApplySnapshotOriginal;
26344
+ }
26345
+ this.filterPluginRef = null;
26346
+ this.filterApplySnapshotOriginal = null;
26347
+ this.filterApplyingSnapshot = false;
26348
+ }
26349
+ getSheetKey() {
26350
+ const resolved = resolveSheetKey({
26351
+ vtableSheet: this.vtableSheet,
26352
+ table: this.table,
26353
+ cached: this.resolvedSheetKey
26354
+ });
26355
+ this.resolvedSheetKey = resolved.cached;
26356
+ return resolved.sheetKey;
26357
+ }
26358
+ getSnapshotState() {
26359
+ return {
26360
+ prevColumnsSnapshot: this.prevColumnsSnapshot,
26361
+ prevMergeSnapshot: this.prevMergeSnapshot,
26362
+ prevRecordsSnapshot: this.prevRecordsSnapshot,
26363
+ prevFormulasSnapshot: this.prevFormulasSnapshot,
26364
+ prevResizedRowHeightsSnapshot: this.prevResizedRowHeightsSnapshot,
26365
+ prevResizedColWidthsSnapshot: this.prevResizedColWidthsSnapshot
26366
+ };
26367
+ }
26368
+ setSnapshotState(next) {
26369
+ this.prevColumnsSnapshot = next.prevColumnsSnapshot;
26370
+ this.prevMergeSnapshot = next.prevMergeSnapshot;
26371
+ this.prevRecordsSnapshot = next.prevRecordsSnapshot;
26372
+ this.prevFormulasSnapshot = next.prevFormulasSnapshot ?? null;
26373
+ this.prevResizedRowHeightsSnapshot = next.prevResizedRowHeightsSnapshot ?? null;
26374
+ this.prevResizedColWidthsSnapshot = next.prevResizedColWidthsSnapshot ?? null;
26375
+ }
26376
+ pushTransaction(tx) {
26377
+ if (tx.commands.length === 0) {
26378
+ return;
26379
+ }
26380
+ this.undoStack.push(tx);
26381
+ this.redoStack = [];
26382
+ this.trimHistory();
26383
+ if (this.onTransactionPushed && !this.isReplaying) {
26384
+ const workbookReplaying = this.table?.__vtableSheet?.__workbookHistoryReplaying;
26385
+ if (!workbookReplaying) {
26386
+ this.onTransactionPushed({ tx, sheetKey: this.getSheetKey(), table: this.table ?? undefined });
26387
+ }
26388
+ }
26389
+ }
26390
+ trimHistory() {
26391
+ if (this.undoStack.length > this.maxHistory) {
26392
+ this.undoStack.splice(0, this.undoStack.length - this.maxHistory);
26393
+ }
26394
+ }
26395
+ pushCommand(cmd) {
26396
+ if (this.currentTransaction) {
26397
+ this.currentTransaction.commands.push(cmd);
26398
+ return;
26399
+ }
26400
+ this.pushTransaction({ commands: [cmd] });
26401
+ }
26402
+ recordExternalCommand(cmd) {
26403
+ if (this.isReplaying) {
26404
+ return;
26405
+ }
26406
+ this.pushCommand(cmd);
26407
+ }
26408
+ tryCompressCellChange(change, sheetKey) {
26409
+ if (!this.enableCompression) {
26410
+ return false;
26411
+ }
26412
+ const targetTx = this.currentTransaction || this.undoStack[this.undoStack.length - 1];
26413
+ if (!targetTx || targetTx.commands.length === 0) {
26414
+ return false;
26415
+ }
26416
+ const last = targetTx.commands[targetTx.commands.length - 1];
26417
+ if ((last.type === 'cell' || last.type === 'cells') && last.sheetKey === sheetKey) {
26418
+ const cells = last.cells;
26419
+ if (cells.length === 1 && cells[0].row === change.row && cells[0].col === change.col) {
26420
+ cells[0].newContent = change.newContent;
26421
+ return true;
26422
+ }
26423
+ }
26424
+ return false;
26425
+ }
26426
+ handleBeforeKeydown(eventArgs) {
26427
+ const e = eventArgs.event;
26428
+ if (!e || !this.table) {
26429
+ return;
26430
+ }
26431
+ const isCtrlOrMeta = e.ctrlKey || e.metaKey;
26432
+ if (!isCtrlOrMeta) {
26433
+ return;
26434
+ }
26435
+ const formulaManager = this.vtableSheet?.formulaManager;
26436
+ if (formulaManager?.formulaWorkingOnCell) {
26437
+ return;
26438
+ }
26439
+ if (this.table.editorManager?.editingEditor) {
26440
+ return;
26441
+ }
26442
+ const key = e.key.toLowerCase();
26443
+ if (key === 'z') {
26444
+ const workbookHistory = this.vtableSheet?.getWorkbookHistoryManager?.();
26445
+ if (e.shiftKey) {
26446
+ workbookHistory ? workbookHistory.redo() : this.redo();
26447
+ }
26448
+ else {
26449
+ workbookHistory ? workbookHistory.undo() : this.undo();
26450
+ }
26451
+ e.preventDefault();
26452
+ e.stopPropagation();
26453
+ }
26454
+ else if (key === 'y') {
26455
+ const workbookHistory = this.vtableSheet?.getWorkbookHistoryManager?.();
26456
+ workbookHistory ? workbookHistory.redo() : this.redo();
26457
+ e.preventDefault();
26458
+ e.stopPropagation();
26459
+ }
26460
+ }
26461
+ handleChangeCellValue(eventArgs) {
26462
+ captureCellPreChangeContent({
26463
+ sheetKey: this.getSheetKey(),
26464
+ row: eventArgs.row,
26465
+ col: eventArgs.col,
26466
+ currentValue: eventArgs.currentValue,
26467
+ formulaManager: this.vtableSheet?.formulaManager,
26468
+ store: this.cellPreChangeContent
26469
+ });
26470
+ }
26471
+ handleChangeCellValues(eventArgs) {
26472
+ if (!this.table) {
26473
+ return;
26474
+ }
26475
+ const sheetKey = this.getSheetKey();
26476
+ const formulaManager = this.vtableSheet?.formulaManager;
26477
+ const cells = eventArgs.values
26478
+ .map(v => {
26479
+ const oldContent = popCellPreChangeContent({
26480
+ sheetKey,
26481
+ row: v.row,
26482
+ col: v.col,
26483
+ fallbackOldContent: v.currentValue,
26484
+ store: this.cellPreChangeContent
26485
+ });
26486
+ const normalizedOld = oldContent == null ? '' : oldContent;
26487
+ const normalizedNew = v.changedValue == null ? '' : v.changedValue;
26488
+ return { row: v.row, col: v.col, oldContent: normalizedOld, newContent: normalizedNew };
26489
+ })
26490
+ .filter(c => {
26491
+ if (c.oldContent === c.newContent) {
26492
+ return false;
26493
+ }
26494
+ if (!sheetKey || !formulaManager?.getCellFormula || !formulaManager?.getCellValue) {
26495
+ return true;
26496
+ }
26497
+ if (typeof c.newContent === 'string' && c.newContent.startsWith('=')) {
26498
+ return false;
26499
+ }
26500
+ const formula = formulaManager.getCellFormula({ sheet: sheetKey, row: c.row, col: c.col });
26501
+ if (!formula) {
26502
+ return true;
26503
+ }
26504
+ const result = formulaManager.getCellValue({ sheet: sheetKey, row: c.row, col: c.col });
26505
+ const display = result?.error ? '#ERROR!' : result?.value;
26506
+ if (display === c.newContent) {
26507
+ return false;
26508
+ }
26509
+ if (display != null && c.newContent != null && String(display) === String(c.newContent)) {
26510
+ return false;
26511
+ }
26512
+ return true;
26513
+ });
26514
+ if (!cells.length) {
26515
+ return;
26516
+ }
26517
+ if (sheetKey && cells.length === 1 && this.tryCompressCellChange(cells[0], sheetKey)) {
26518
+ return;
26519
+ }
26520
+ const cmd = { type: 'cells', sheetKey, cells };
26521
+ this.pushCommand(cmd);
26522
+ }
26523
+ ensureFormulaEventBindings() {
26524
+ if (!this.table || !this.vtableSheet || this.formulaEventBound) {
26525
+ return;
26526
+ }
26527
+ const sheetKey = this.getSheetKey();
26528
+ if (!sheetKey) {
26529
+ return;
26530
+ }
26531
+ const worksheet = this.vtableSheet.getWorkSheetByKey?.(sheetKey) ?? this.vtableSheet.workSheetInstances?.get?.(sheetKey);
26532
+ const eventManager = worksheet?.eventManager;
26533
+ if (!eventManager?.on || !eventManager?.off) {
26534
+ return;
26535
+ }
26536
+ this.formulaEventBound = true;
26537
+ this.formulaEventManager = eventManager;
26538
+ this.onFormulaAddedHandler = (event) => {
26539
+ if (this.isReplaying) {
26540
+ return;
26541
+ }
26542
+ const cell = event?.cell;
26543
+ const formula = event?.formula;
26544
+ if (!cell || typeof cell.row !== 'number' || typeof cell.col !== 'number') {
26545
+ return;
26546
+ }
26547
+ if (typeof formula !== 'string' || !formula.length) {
26548
+ return;
26549
+ }
26550
+ const normalized = formula.startsWith('=') ? formula : `=${formula}`;
26551
+ const key = `${sheetKey}:${cell.row}:${cell.col}`;
26552
+ const prev = this.formulaCache.get(key);
26553
+ const oldContent = popCellPreChangeContent({
26554
+ sheetKey,
26555
+ row: cell.row,
26556
+ col: cell.col,
26557
+ fallbackOldContent: typeof prev !== 'undefined' ? prev : '',
26558
+ store: this.cellPreChangeContent
26559
+ });
26560
+ if (oldContent === normalized) {
26561
+ this.formulaCache.set(key, normalized);
26562
+ return;
26563
+ }
26564
+ const cmd = {
26565
+ type: 'cells',
26566
+ sheetKey,
26567
+ cells: [{ row: cell.row, col: cell.col, oldContent, newContent: normalized }]
26568
+ };
26569
+ this.pushCommand(cmd);
26570
+ this.formulaCache.set(key, normalized);
26571
+ };
26572
+ eventManager.on('formula_added', this.onFormulaAddedHandler);
26573
+ }
26574
+ ensureSortEventBindings() {
26575
+ if (!this.table || this.sortEventBound) {
26576
+ return;
26577
+ }
26578
+ const ds = this.table.internalProps?.dataSource;
26579
+ if (!ds?.on || !ds?.off) {
26580
+ return;
26581
+ }
26582
+ this.sortEventBound = true;
26583
+ this.sortChangeOrderListenerId = ds.on('change_order', () => {
26584
+ if (this.isReplaying || !this.table || !this.sortPending) {
26585
+ return;
26586
+ }
26587
+ const sheetKey = this.getSheetKey();
26588
+ const oldSortState = this.sortStartSnapshot;
26589
+ this.sortStartSnapshot = null;
26590
+ this.sortPending = false;
26591
+ const newSortState = this.normalizeSortState(this.table.internalProps?.sortState);
26592
+ if (JSON.stringify(oldSortState) === JSON.stringify(newSortState)) {
26593
+ this.lastKnownSortState = newSortState;
26594
+ return;
26595
+ }
26596
+ const cmd = {
26597
+ type: 'sort',
26598
+ sheetKey,
26599
+ oldSortState: oldSortState,
26600
+ newSortState: newSortState
26601
+ };
26602
+ this.pushCommand(cmd);
26603
+ this.lastKnownSortState = newSortState;
26604
+ });
26605
+ }
26606
+ unbindSortEvents() {
26607
+ if (!this.sortEventBound) {
26608
+ return;
26609
+ }
26610
+ const ds = this.table?.internalProps?.dataSource;
26611
+ try {
26612
+ if (ds?.off && this.sortChangeOrderListenerId) {
26613
+ ds.off(this.sortChangeOrderListenerId);
26614
+ }
26615
+ }
26616
+ catch {
26617
+ }
26618
+ finally {
26619
+ this.sortEventBound = false;
26620
+ this.sortChangeOrderListenerId = undefined;
26621
+ this.sortPending = false;
26622
+ this.sortStartSnapshot = null;
26623
+ }
26624
+ }
26625
+ unbindFormulaEvents() {
26626
+ if (!this.formulaEventBound || !this.formulaEventManager) {
26627
+ return;
26628
+ }
26629
+ try {
26630
+ if (this.onFormulaAddedHandler) {
26631
+ this.formulaEventManager.off('formula_added', this.onFormulaAddedHandler);
26632
+ }
26633
+ }
26634
+ catch {
26635
+ }
26636
+ finally {
26637
+ this.formulaEventBound = false;
26638
+ this.formulaEventManager = undefined;
26639
+ this.onFormulaAddedHandler = undefined;
26640
+ }
26641
+ }
26642
+ cloneMergeConfig(input) {
26643
+ if (Array.isArray(input)) {
26644
+ return input.map(i => cloneDeep(i));
26645
+ }
26646
+ return input;
26647
+ }
26648
+ isSameMergeConfig(a, b) {
26649
+ const normalize = (v) => {
26650
+ if (v == null) {
26651
+ return [];
26652
+ }
26653
+ if (Array.isArray(v)) {
26654
+ return v;
26655
+ }
26656
+ return v;
26657
+ };
26658
+ const aa = normalize(a);
26659
+ const bb = normalize(b);
26660
+ if (aa === bb) {
26661
+ return true;
26662
+ }
26663
+ if (Array.isArray(aa) && Array.isArray(bb)) {
26664
+ if (aa.length !== bb.length) {
26665
+ return false;
26666
+ }
26667
+ for (let i = 0; i < aa.length; i++) {
26668
+ const ra = aa[i]?.range;
26669
+ const rb = bb[i]?.range;
26670
+ if (!ra ||
26671
+ !rb ||
26672
+ ra.start?.col !== rb.start?.col ||
26673
+ ra.start?.row !== rb.start?.row ||
26674
+ ra.end?.col !== rb.end?.col ||
26675
+ ra.end?.row !== rb.end?.row ||
26676
+ aa[i]?.text !== bb[i]?.text) {
26677
+ return false;
26678
+ }
26679
+ }
26680
+ return true;
26681
+ }
26682
+ return false;
26683
+ }
26684
+ handleMergeCells(eventArgs) {
26685
+ this.handleMergeConfigChanged(eventArgs);
26686
+ }
26687
+ handleUnmergeCells(eventArgs) {
26688
+ this.handleMergeConfigChanged(eventArgs);
26689
+ }
26690
+ handleMergeConfigChanged(eventArgs) {
26691
+ if (!this.table) {
26692
+ return;
26693
+ }
26694
+ const { startCol, startRow, endCol, endRow } = eventArgs;
26695
+ const before = this.cloneMergeConfig(this.prevMergeSnapshot);
26696
+ const after = this.cloneMergeConfig(this.table.options?.customMergeCell);
26697
+ if (this.isSameMergeConfig(before, after)) {
26698
+ return;
26699
+ }
26700
+ const cmd = {
26701
+ type: 'merge_cells',
26702
+ sheetKey: this.getSheetKey(),
26703
+ startCol,
26704
+ startRow,
26705
+ endCol,
26706
+ endRow,
26707
+ oldCustomMergeCell: before,
26708
+ newCustomMergeCell: after
26709
+ };
26710
+ this.pushCommand(cmd);
26711
+ }
26712
+ handleAddRecord(eventArgs) {
26713
+ const sheetKey = this.getSheetKey();
26714
+ const cmd = {
26715
+ type: 'add_record',
26716
+ sheetKey,
26717
+ records: Array.isArray(eventArgs.records) ? eventArgs.records.slice() : [],
26718
+ recordIndex: eventArgs.recordIndex,
26719
+ recordCount: eventArgs.recordCount ?? (Array.isArray(eventArgs.records) ? eventArgs.records.length : 0)
26720
+ };
26721
+ if (this.table && typeof eventArgs.recordIndex === 'number') {
26722
+ const start = eventArgs.recordIndex;
26723
+ const count = cmd.recordCount;
26724
+ const ds = this.table?.internalProps?.dataSource;
26725
+ const rawRecords = ds?.dataSourceObj?.records;
26726
+ const viewRecords = this.table.records;
26727
+ if (Array.isArray(viewRecords) && viewRecords.length) {
26728
+ cmd.anchorBefore = start > 0 ? viewRecords[start - 1] : undefined;
26729
+ cmd.anchorAfter = viewRecords[start + count];
26730
+ }
26731
+ if (Array.isArray(rawRecords) && Array.isArray(viewRecords)) {
26732
+ let rawInsertIndex = rawRecords.length;
26733
+ if (viewRecords.length === 0) {
26734
+ rawInsertIndex = rawRecords.length;
26735
+ }
26736
+ else if (start <= 0) {
26737
+ const first = viewRecords[0];
26738
+ const idx = rawRecords.indexOf(first);
26739
+ rawInsertIndex = idx >= 0 ? idx : 0;
26740
+ }
26741
+ else if (start >= viewRecords.length) {
26742
+ const last = viewRecords[viewRecords.length - 1];
26743
+ const idx = rawRecords.indexOf(last);
26744
+ rawInsertIndex = idx >= 0 ? idx + 1 : rawRecords.length;
26745
+ }
26746
+ else {
26747
+ const prev = viewRecords[start - 1];
26748
+ const idx = rawRecords.indexOf(prev);
26749
+ rawInsertIndex = idx >= 0 ? idx + 1 : rawRecords.length;
26750
+ }
26751
+ cmd.rawInsertIndex = rawInsertIndex;
26752
+ }
26753
+ }
26754
+ this.pushCommand(cmd);
26755
+ }
26756
+ handleDeleteRecord(eventArgs) {
26757
+ const sheetKey = this.getSheetKey();
26758
+ const recordIndexs = Array.isArray(eventArgs.recordIndexs)
26759
+ ? eventArgs.recordIndexs.slice()
26760
+ : [eventArgs.recordIndexs];
26761
+ let deletedRowHeights;
26762
+ if (this.table && this.prevResizedRowHeightsSnapshot) {
26763
+ const headerCount = this.table.transpose
26764
+ ? this.table.rowHeaderLevelCount
26765
+ : this.table.columnHeaderLevelCount;
26766
+ recordIndexs.forEach(idx => {
26767
+ if (typeof idx !== 'number') {
26768
+ return;
26769
+ }
26770
+ const rowIndex = idx + (headerCount ?? 0);
26771
+ const height = this.prevResizedRowHeightsSnapshot?.[rowIndex];
26772
+ if (typeof height === 'number') {
26773
+ if (!deletedRowHeights) {
26774
+ deletedRowHeights = {};
26775
+ }
26776
+ deletedRowHeights[idx] = height;
26777
+ }
26778
+ });
26779
+ }
26780
+ const oldCustomMergeCell = this.cloneMergeConfig(this.prevMergeSnapshot);
26781
+ const newCustomMergeCell = this.cloneMergeConfig(this.table?.options?.customMergeCell);
26782
+ const cmd = {
26783
+ type: 'delete_record',
26784
+ sheetKey,
26785
+ records: Array.isArray(eventArgs.records) ? eventArgs.records.slice() : [],
26786
+ recordIndexs,
26787
+ deletedRowHeights,
26788
+ oldCustomMergeCell,
26789
+ newCustomMergeCell
26790
+ };
26791
+ this.pushCommand(cmd);
26792
+ }
26793
+ handleUpdateRecord(eventArgs) {
26794
+ if (!this.table) {
26795
+ return;
26796
+ }
26797
+ const sheetKey = this.getSheetKey();
26798
+ const recordIndexs = (eventArgs.recordIndexs || []);
26799
+ const newRecords = Array.isArray(eventArgs.records) ? eventArgs.records.slice() : [];
26800
+ if (!this.prevRecordsSnapshot || !Array.isArray(this.prevRecordsSnapshot) || !recordIndexs.length) {
26801
+ return;
26802
+ }
26803
+ const oldRecords = [];
26804
+ recordIndexs.forEach(idx => {
26805
+ if (typeof idx === 'number') {
26806
+ const rec = this.prevRecordsSnapshot[idx];
26807
+ oldRecords.push(rec !== undefined ? cloneRecord(rec) : undefined);
26808
+ }
26809
+ else {
26810
+ oldRecords.push(undefined);
26811
+ }
26812
+ });
26813
+ const cmd = { type: 'update_record', sheetKey, oldRecords, newRecords, recordIndexs };
26814
+ this.pushCommand(cmd);
26815
+ }
26816
+ handleAddColumn(eventArgs) {
26817
+ if (!this.table) {
26818
+ return;
26819
+ }
26820
+ const sheetKey = this.getSheetKey();
26821
+ const { columnIndex, columnCount, columns } = eventArgs;
26822
+ const addedColumns = columns
26823
+ .slice(columnIndex, columnIndex + columnCount)
26824
+ .map(c => cloneDeep(c));
26825
+ const cmd = { type: 'add_column', sheetKey, columnIndex, columnCount, columns: addedColumns };
26826
+ this.pushCommand(cmd);
26827
+ }
26828
+ handleDeleteColumn(eventArgs) {
26829
+ if (!this.table) {
26830
+ return;
26831
+ }
26832
+ const sheetKey = this.getSheetKey();
26833
+ const deleteColIndexs = (eventArgs.deleteColIndexs || []).slice();
26834
+ const deletedColumnsFromEvent = eventArgs.deletedColumns;
26835
+ const prevColumns = this.prevColumnsSnapshot || [];
26836
+ const deletedColumns = Array.isArray(deletedColumnsFromEvent)
26837
+ ? deletedColumnsFromEvent.map(c => cloneDeep(c))
26838
+ : [];
26839
+ if (!deletedColumns.length) {
26840
+ deleteColIndexs.forEach(idx => {
26841
+ if (idx >= 0 && idx < prevColumns.length) {
26842
+ deletedColumns.push(cloneDeep(prevColumns[idx]));
26843
+ }
26844
+ });
26845
+ }
26846
+ let deletedRecordValues = eventArgs.deletedRecordValues;
26847
+ if (!Array.isArray(deletedRecordValues) || !deletedRecordValues.length) {
26848
+ deletedRecordValues = undefined;
26849
+ if (Array.isArray(this.prevRecordsSnapshot) && this.prevRecordsSnapshot.length) {
26850
+ deletedRecordValues = this.prevRecordsSnapshot.map(rec => {
26851
+ if (Array.isArray(rec)) {
26852
+ return deleteColIndexs.map(idx => rec[idx]);
26853
+ }
26854
+ return [];
26855
+ });
26856
+ if (deletedRecordValues.every(v => v.length === 0)) {
26857
+ deletedRecordValues = undefined;
26858
+ }
26859
+ }
26860
+ }
26861
+ let deletedFormulas;
26862
+ if (this.prevFormulasSnapshot && deleteColIndexs.length) {
26863
+ const entries = Object.entries(this.prevFormulasSnapshot);
26864
+ entries.forEach(([cellRef, formula]) => {
26865
+ const parsed = parseA1Notation(cellRef);
26866
+ if (parsed && deleteColIndexs.includes(parsed.col)) {
26867
+ if (!deletedFormulas) {
26868
+ deletedFormulas = {};
26869
+ }
26870
+ deletedFormulas[cellRef] = formula;
26871
+ }
26872
+ });
26873
+ }
26874
+ let deletedColWidths;
26875
+ if (this.prevResizedColWidthsSnapshot && deleteColIndexs.length) {
26876
+ deleteColIndexs.forEach(idx => {
26877
+ const w = this.prevResizedColWidthsSnapshot?.[idx];
26878
+ if (typeof w === 'number') {
26879
+ if (!deletedColWidths) {
26880
+ deletedColWidths = {};
26881
+ }
26882
+ deletedColWidths[idx] = w;
26883
+ }
26884
+ });
26885
+ }
26886
+ const cmd = {
26887
+ type: 'delete_column',
26888
+ sheetKey,
26889
+ deleteColIndexs,
26890
+ columns: deletedColumns,
26891
+ deletedRecordValues,
26892
+ deletedFormulas,
26893
+ deletedColWidths
26894
+ };
26895
+ this.pushCommand(cmd);
26896
+ }
26897
+ handleChangeHeaderPosition(eventArgs) {
26898
+ const sheetKey = this.getSheetKey();
26899
+ const moving = eventArgs.movingColumnOrRow ?? 'column';
26900
+ const sourceIndex = moving === 'column' ? eventArgs.source.col : eventArgs.source.row;
26901
+ const targetIndex = moving === 'column' ? eventArgs.target.col : eventArgs.target.row;
26902
+ const cmd = {
26903
+ type: 'change_header_position',
26904
+ sheetKey,
26905
+ moving,
26906
+ sourceIndex,
26907
+ targetIndex
26908
+ };
26909
+ this.pushCommand(cmd);
26910
+ }
26911
+ normalizeSortState(input) {
26912
+ if (!input) {
26913
+ return null;
26914
+ }
26915
+ if (Array.isArray(input)) {
26916
+ const list = input
26917
+ .filter(Boolean)
26918
+ .map((s) => ({ field: s.field, order: s.order }))
26919
+ .filter((s) => typeof s.field !== 'undefined' && s.order && s.order !== 'normal');
26920
+ return list.length ? list : null;
26921
+ }
26922
+ const s = input;
26923
+ if (typeof s.field === 'undefined' || !s.order || s.order === 'normal') {
26924
+ return null;
26925
+ }
26926
+ return { field: s.field, order: s.order };
26927
+ }
26928
+ handleSortClick(_eventArgs) {
26929
+ if (!this.table) {
26930
+ return;
26931
+ }
26932
+ this.sortStartSnapshot = this.lastKnownSortState;
26933
+ this.sortPending = true;
26934
+ setTimeout(() => {
26935
+ if (this.sortPending) {
26936
+ this.sortPending = false;
26937
+ this.sortStartSnapshot = null;
26938
+ }
26939
+ }, 0);
26940
+ }
26941
+ handleResizeRow(eventArgs) {
26942
+ if (!this.table) {
26943
+ return;
26944
+ }
26945
+ const row = eventArgs.row;
26946
+ if (!this.resizeRowStartHeight.has(row)) {
26947
+ const oldHeight = this.table.getRowHeight?.(row);
26948
+ if (typeof oldHeight === 'number') {
26949
+ this.resizeRowStartHeight.set(row, oldHeight);
26950
+ }
26951
+ }
26952
+ }
26953
+ handleResizeRowEnd(eventArgs) {
26954
+ if (!this.table) {
26955
+ return;
26956
+ }
26957
+ const sheetKey = this.getSheetKey();
26958
+ const row = eventArgs.row;
26959
+ const newHeight = eventArgs.rowHeight;
26960
+ const oldHeight = this.resizeRowStartHeight.get(row) ?? newHeight;
26961
+ this.resizeRowStartHeight.delete(row);
26962
+ if (typeof oldHeight === 'number' && typeof newHeight === 'number' && oldHeight === newHeight) {
26963
+ return;
26964
+ }
26965
+ const cmd = { type: 'resize_row', sheetKey, row, oldHeight, newHeight };
26966
+ this.pushCommand(cmd);
26967
+ }
26968
+ handleResizeColumn(eventArgs) {
26969
+ if (!this.table) {
26970
+ return;
26971
+ }
26972
+ const col = eventArgs.col;
26973
+ if (!this.resizeColStartWidth.has(col)) {
26974
+ const oldWidth = this.table.getColWidth?.(col);
26975
+ if (typeof oldWidth === 'number') {
26976
+ this.resizeColStartWidth.set(col, oldWidth);
26977
+ }
26978
+ }
26979
+ }
26980
+ handleResizeColumnEnd(eventArgs) {
26981
+ if (!this.table) {
26982
+ return;
26983
+ }
26984
+ const sheetKey = this.getSheetKey();
26985
+ const col = eventArgs.col;
26986
+ const colWidths = eventArgs.colWidths || [];
26987
+ const newWidth = colWidths[col] ?? this.table.getColWidth?.(col);
26988
+ const oldWidth = this.resizeColStartWidth.get(col) ?? newWidth;
26989
+ this.resizeColStartWidth.delete(col);
26990
+ if (typeof oldWidth === 'number' && typeof newWidth === 'number' && oldWidth === newWidth) {
26991
+ return;
26992
+ }
26993
+ const cmd = { type: 'resize_column', sheetKey, col, oldWidth, newWidth };
26994
+ this.pushCommand(cmd);
26995
+ }
26996
+ applyCommand(cmd, direction) {
26997
+ if (!this.table) {
26998
+ return;
26999
+ }
27000
+ replayCommand({
27001
+ table: this.table,
27002
+ vtableSheet: this.vtableSheet,
27003
+ cmd,
27004
+ direction,
27005
+ deleteRecordsByReference: (records) => this.deleteRecordsByReference(records)
27006
+ });
27007
+ }
27008
+ deleteRecordsByReference(records) {
27009
+ if (!this.table || !records?.length) {
27010
+ return;
27011
+ }
27012
+ const tableRecords = (this.table.records || []);
27013
+ const indexs = [];
27014
+ records.forEach(rec => {
27015
+ const idx = tableRecords.indexOf(rec);
27016
+ if (idx >= 0) {
27017
+ indexs.push(idx);
27018
+ }
27019
+ });
27020
+ if (indexs.length && this.table.deleteRecords) {
27021
+ this.table.deleteRecords(indexs);
27022
+ }
27023
+ }
27024
+ }
27025
+
25206
27026
  exports.AddRowColumnPlugin = AddRowColumnPlugin;
25207
27027
  exports.AutoFillPlugin = AutoFillPlugin;
25208
27028
  exports.CarouselAnimationPlugin = CarouselAnimationPlugin;
@@ -25226,6 +27046,7 @@ ${recordsStr}
25226
27046
  exports.FocusHighlightPlugin = FocusHighlightPlugin;
25227
27047
  exports.HeaderHighlightPlugin = HeaderHighlightPlugin;
25228
27048
  exports.HighlightHeaderWhenSelectCellPlugin = HighlightHeaderWhenSelectCellPlugin;
27049
+ exports.HistoryPlugin = HistoryPlugin;
25229
27050
  exports.InvertHighlightPlugin = InvertHighlightPlugin;
25230
27051
  exports.MENU_CONTAINER_CLASS = MENU_CONTAINER_CLASS;
25231
27052
  exports.MENU_ITEM_CLASS = MENU_ITEM_CLASS;
@@ -25259,6 +27080,7 @@ ${recordsStr}
25259
27080
  exports.loopSeriesRule = loopSeriesRule;
25260
27081
  exports.numberRule = numberRule;
25261
27082
  exports.otherRule = otherRule;
27083
+ exports.replayCommand = replayCommand;
25262
27084
  exports.reverseIfNeed = reverseIfNeed;
25263
27085
  exports.rotate90WithTransform = rotate90WithTransform;
25264
27086