@visactor/vtable-plugins 1.22.6-alpha.2 → 1.22.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/cjs/auto-fill/__tests__/formula-integration.test.d.ts +23 -0
  2. package/cjs/auto-fill/__tests__/formula-integration.test.js +61 -0
  3. package/cjs/auto-fill/__tests__/formula-integration.test.js.map +1 -0
  4. package/cjs/auto-fill/auto-fill-manager.d.ts +1 -0
  5. package/cjs/auto-fill/auto-fill-manager.js +27 -10
  6. package/cjs/auto-fill/auto-fill-manager.js.map +1 -1
  7. package/cjs/auto-fill/auto-fill-services.js +1 -1
  8. package/cjs/auto-fill/auto-fill-services.js.map +1 -1
  9. package/cjs/auto-fill/formula-integration.d.ts +40 -0
  10. package/cjs/auto-fill/formula-integration.js +77 -0
  11. package/cjs/auto-fill/formula-integration.js.map +1 -0
  12. package/cjs/auto-fill/index.d.ts +6 -0
  13. package/cjs/auto-fill/index.js +19 -1
  14. package/cjs/auto-fill/index.js.map +1 -1
  15. package/cjs/auto-fill/rules.d.ts +1 -0
  16. package/cjs/auto-fill/rules.js +128 -3
  17. package/cjs/auto-fill/rules.js.map +1 -1
  18. package/cjs/contextmenu/index.js +1 -2
  19. package/cjs/contextmenu/menu-manager.js +2 -1
  20. package/cjs/excel-edit-cell-keyboard.d.ts +1 -0
  21. package/cjs/excel-edit-cell-keyboard.js +5 -4
  22. package/cjs/excel-edit-cell-keyboard.js.map +1 -1
  23. package/cjs/filter/filter-state-manager.js +1 -1
  24. package/cjs/filter/filter-state-manager.js.map +1 -1
  25. package/cjs/filter/filter-toolbar.d.ts +1 -0
  26. package/cjs/filter/filter-toolbar.js +10 -2
  27. package/cjs/filter/filter-toolbar.js.map +1 -1
  28. package/cjs/filter/filter.js +2 -1
  29. package/cjs/filter/filter.js.map +1 -1
  30. package/cjs/filter/types.d.ts +1 -1
  31. package/cjs/filter/types.js.map +1 -1
  32. package/cjs/filter/value-filter.d.ts +14 -9
  33. package/cjs/filter/value-filter.js +102 -182
  34. package/cjs/filter/value-filter.js.map +1 -1
  35. package/cjs/master-detail-plugin/config.js +1 -2
  36. package/cjs/master-detail-plugin/core.js +2 -1
  37. package/cjs/table-export/index.js +1 -1
  38. package/dist/vtable-plugins.js +698 -403
  39. package/dist/vtable-plugins.min.js +3 -3
  40. package/es/auto-fill/__tests__/formula-integration.test.d.ts +23 -0
  41. package/es/auto-fill/__tests__/formula-integration.test.js +54 -0
  42. package/es/auto-fill/__tests__/formula-integration.test.js.map +1 -0
  43. package/es/auto-fill/auto-fill-manager.d.ts +1 -0
  44. package/es/auto-fill/auto-fill-manager.js +34 -15
  45. package/es/auto-fill/auto-fill-manager.js.map +1 -1
  46. package/es/auto-fill/auto-fill-services.js +2 -2
  47. package/es/auto-fill/auto-fill-services.js.map +1 -1
  48. package/es/auto-fill/formula-integration.d.ts +40 -0
  49. package/es/auto-fill/formula-integration.js +67 -0
  50. package/es/auto-fill/formula-integration.js.map +1 -0
  51. package/es/auto-fill/index.d.ts +6 -0
  52. package/es/auto-fill/index.js +7 -1
  53. package/es/auto-fill/index.js.map +1 -1
  54. package/es/auto-fill/rules.d.ts +1 -0
  55. package/es/auto-fill/rules.js +127 -0
  56. package/es/auto-fill/rules.js.map +1 -1
  57. package/es/contextmenu/index.js +1 -2
  58. package/es/contextmenu/menu-manager.js +2 -1
  59. package/es/excel-edit-cell-keyboard.d.ts +1 -0
  60. package/es/excel-edit-cell-keyboard.js +5 -4
  61. package/es/excel-edit-cell-keyboard.js.map +1 -1
  62. package/es/filter/filter-state-manager.js +1 -1
  63. package/es/filter/filter-state-manager.js.map +1 -1
  64. package/es/filter/filter-toolbar.d.ts +1 -0
  65. package/es/filter/filter-toolbar.js +10 -2
  66. package/es/filter/filter-toolbar.js.map +1 -1
  67. package/es/filter/filter.js +2 -1
  68. package/es/filter/filter.js.map +1 -1
  69. package/es/filter/types.d.ts +1 -1
  70. package/es/filter/types.js.map +1 -1
  71. package/es/filter/value-filter.d.ts +14 -9
  72. package/es/filter/value-filter.js +101 -182
  73. package/es/filter/value-filter.js.map +1 -1
  74. package/es/master-detail-plugin/config.js +1 -2
  75. package/es/master-detail-plugin/core.js +2 -1
  76. package/es/table-export/index.js +1 -1
  77. package/package.json +8 -8
@@ -1125,7 +1125,7 @@
1125
1125
  document.addEventListener('keydown', this.handleKeyDown.bind(this), true);
1126
1126
  }
1127
1127
  handleKeyDown(event) {
1128
- if (this.table.editorManager && this.isExcelShortcutKey(event)) {
1128
+ if (this.table?.editorManager && this.isExcelShortcutKey(event)) {
1129
1129
  const eventKey = event.key.toLowerCase();
1130
1130
  if (this.table.editorManager.editingEditor && this.table.editorManager.beginTriggerEditCellMode === 'keydown') {
1131
1131
  const { col, row } = this.table.editorManager.editCell;
@@ -1173,7 +1173,7 @@
1173
1173
  (eventKey === exports.ExcelEditCellKeyboardResponse.DELETE || eventKey === exports.ExcelEditCellKeyboardResponse.BACKSPACE)) {
1174
1174
  const selectCells = this.table.getSelectedCellInfos();
1175
1175
  if (selectCells?.length > 0 && document.activeElement === this.table.getElement()) {
1176
- deleteSelectRange(selectCells, this.table);
1176
+ deleteSelectRange(selectCells, this.table, this.pluginOptions?.deleteWorkOnEditableCell ?? true);
1177
1177
  event.stopPropagation();
1178
1178
  event.preventDefault();
1179
1179
  }
@@ -1197,10 +1197,10 @@
1197
1197
  document.removeEventListener('keydown', this.handleKeyDown, true);
1198
1198
  }
1199
1199
  }
1200
- function deleteSelectRange(selectCells, tableInstance) {
1200
+ function deleteSelectRange(selectCells, tableInstance, workOnEditableCell = false) {
1201
1201
  for (let i = 0; i < selectCells.length; i++) {
1202
1202
  for (let j = 0; j < selectCells[i].length; j++) {
1203
- tableInstance.changeCellValue(selectCells[i][j].col, selectCells[i][j].row, '');
1203
+ tableInstance.changeCellValue(selectCells[i][j].col, selectCells[i][j].row, '', workOnEditableCell);
1204
1204
  }
1205
1205
  }
1206
1206
  }
@@ -10144,7 +10144,7 @@ ${recordsStr}
10144
10144
  exports.FilterActionType.CLEAR_ALL_FILTERS,
10145
10145
  exports.FilterActionType.APPLY_FILTERS
10146
10146
  ];
10147
- return shouldApplyActions.includes(action.type) || action.payload.enable;
10147
+ return shouldApplyActions.includes(action.type);
10148
10148
  }
10149
10149
  }
10150
10150
 
@@ -10296,289 +10296,171 @@ ${recordsStr}
10296
10296
  class ValueFilter {
10297
10297
  table;
10298
10298
  filterStateManager;
10299
- uniqueKeys = new Map();
10300
- displayToRawValueMap = new Map();
10301
10299
  selectedField;
10300
+ selectedKeys = new Map();
10301
+ candidateKeys = new Map();
10302
+ formatFnCache = new Map();
10303
+ toUnformattedCache = new Map();
10302
10304
  valueFilterOptionList = new Map();
10303
10305
  filterByValuePanel;
10304
10306
  filterByValueSearchInput;
10305
10307
  selectAllCheckbox;
10308
+ totalCountSpan;
10306
10309
  filterItemsContainer;
10310
+ _onInputKeyUpHandler;
10311
+ _onCheckboxChangeHandler;
10307
10312
  constructor(table, filterStateManager) {
10308
10313
  this.table = table;
10309
10314
  this.filterStateManager = filterStateManager;
10310
- this.filterStateManager.subscribe((state) => {
10311
- const filterState = state.filters.get(this.selectedField);
10312
- if (filterState && filterState.type === 'byValue') {
10313
- this.updateUI(filterState);
10314
- }
10315
- });
10316
- }
10317
- updateUI(filterState) {
10318
- this.syncCheckboxesWithFilterState(filterState);
10319
- this.syncSelectAllWithFilterState(filterState);
10320
10315
  }
10321
10316
  setSelectedField(fieldId) {
10322
10317
  this.selectedField = fieldId;
10323
- this.collectUniqueColumnValues(fieldId);
10324
- }
10325
- collectUniqueColumnValues(fieldId) {
10326
- const isEnable = this.filterStateManager.getFilterState(fieldId)?.enable;
10327
- const displayValueMap = new Map();
10328
- const rawToDisplayMap = new Map();
10329
- const displayToRawMap = new Map();
10330
- let targetCol = -1;
10331
- for (let col = 0; col < this.table.colCount; col++) {
10332
- for (let row = this.table.columnHeaderLevelCount; row < this.table.rowCount; row++) {
10333
- if (!this.table.internalProps.layoutMap.isHeader(col, row)) {
10334
- const bodyInfo = this.table.internalProps.layoutMap.getBody(col, row);
10335
- if (bodyInfo && bodyInfo.field === fieldId) {
10336
- targetCol = col;
10337
- break;
10338
- }
10339
- }
10340
- }
10341
- if (targetCol !== -1) {
10342
- break;
10343
- }
10318
+ }
10319
+ getFormatFnCache(fieldId) {
10320
+ let formatFn = this.formatFnCache.get(fieldId);
10321
+ if (formatFn !== null && formatFn !== undefined) {
10322
+ return formatFn;
10344
10323
  }
10345
- if (isEnable) {
10346
- const records = this.table.internalProps.records;
10347
- const recordsLength = records.length;
10348
- for (let i = 0; i < recordsLength; i++) {
10349
- let rawValue;
10350
- let displayValue;
10351
- if (targetCol !== -1) {
10352
- const row = this.table.columnHeaderLevelCount + i;
10353
- const currentRecord = records[i];
10354
- rawValue = currentRecord[fieldId];
10355
- const bodyInfo = this.table.internalProps.layoutMap.getBody(targetCol, row);
10356
- if (bodyInfo &&
10357
- 'fieldFormat' in bodyInfo &&
10358
- bodyInfo.fieldFormat &&
10359
- typeof bodyInfo.fieldFormat === 'function') {
10360
- displayValue = bodyInfo.fieldFormat({ [fieldId]: rawValue });
10361
- }
10362
- else {
10363
- displayValue = rawValue;
10364
- }
10365
- }
10366
- if (rawValue !== undefined && rawValue !== null) {
10367
- displayValueMap.set(displayValue, (displayValueMap.get(displayValue) || 0) + 1);
10368
- rawToDisplayMap.set(rawValue, displayValue);
10369
- displayToRawMap.set(displayValue, rawValue);
10370
- }
10371
- }
10324
+ const headerAddress = this.table.internalProps.layoutMap.getHeaderCellAddressByField(String(fieldId));
10325
+ const bodyInfo = this.table.internalProps.layoutMap.getBody(headerAddress?.col, headerAddress?.row);
10326
+ if (bodyInfo && 'fieldFormat' in bodyInfo && typeof bodyInfo.fieldFormat === 'function') {
10327
+ formatFn = bodyInfo.fieldFormat;
10328
+ }
10329
+ else if (bodyInfo && 'format' in bodyInfo && typeof bodyInfo.format === 'function') {
10330
+ formatFn = bodyInfo.format;
10372
10331
  }
10373
10332
  else {
10374
- const dataSource = this.table.internalProps.dataSource;
10375
- const currentLength = dataSource.length;
10376
- for (let i = 0; i < currentLength; i++) {
10377
- let rawValue;
10378
- let displayValue;
10379
- if (targetCol !== -1) {
10380
- const row = this.table.columnHeaderLevelCount + i;
10381
- if (row < this.table.rowCount) {
10382
- rawValue = this.table.getCellOriginValue(targetCol, row);
10383
- displayValue = this.table.getCellValue(targetCol, row);
10384
- }
10333
+ formatFn = (record) => record[fieldId];
10334
+ }
10335
+ this.formatFnCache.set(fieldId, formatFn);
10336
+ return formatFn;
10337
+ }
10338
+ collectCandidateKeysForUnfilteredColumn(fieldId) {
10339
+ const countMap = new Map();
10340
+ const records = this.table.internalProps.dataSource.records;
10341
+ const formatFn = this.getFormatFnCache(fieldId);
10342
+ const toUnformatted = new Map();
10343
+ records.forEach(record => {
10344
+ const originalValue = record[fieldId];
10345
+ const formattedValue = formatFn(record);
10346
+ if (formattedValue !== undefined && formattedValue !== null) {
10347
+ countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1);
10348
+ const unformattedSet = toUnformatted.get(formattedValue);
10349
+ if (unformattedSet !== undefined && unformattedSet !== null) {
10350
+ unformattedSet.add(originalValue);
10385
10351
  }
10386
10352
  else {
10387
- rawValue = this.table.getFieldData(String(fieldId), targetCol !== -1 ? targetCol : 0, this.table.columnHeaderLevelCount + i);
10388
- displayValue = rawValue;
10389
- }
10390
- if (rawValue !== undefined && rawValue !== null) {
10391
- displayValueMap.set(displayValue, (displayValueMap.get(displayValue) || 0) + 1);
10392
- rawToDisplayMap.set(rawValue, displayValue);
10393
- displayToRawMap.set(displayValue, rawValue);
10353
+ toUnformatted.set(formattedValue, new Set([originalValue]));
10394
10354
  }
10395
10355
  }
10396
- }
10397
- this.displayToRawValueMap.set(fieldId, displayToRawMap);
10398
- const uniqueValues = Array.from(displayValueMap.entries()).map(([displayValue, count]) => ({
10399
- value: displayValue,
10400
- count,
10401
- rawValue: displayToRawMap.get(displayValue)
10356
+ });
10357
+ this.candidateKeys.set(fieldId, countMap);
10358
+ this.toUnformattedCache.set(fieldId, toUnformatted);
10359
+ }
10360
+ collectCandidateKeysForFilteredColumn(candidateField) {
10361
+ const filteredFields = this.filterStateManager.getActiveFilterFields().filter(field => field !== candidateField);
10362
+ const toUnformatted = new Map();
10363
+ const formatFn = this.getFormatFnCache(candidateField);
10364
+ const countMap = new Map();
10365
+ const recordsList = this.table.internalProps.records;
10366
+ const records = recordsList.filter(record => filteredFields.every(field => {
10367
+ const set = this.selectedKeys.get(field);
10368
+ return set.has(record[field]);
10402
10369
  }));
10403
- this.uniqueKeys.set(fieldId, uniqueValues);
10404
- }
10405
- onValueSelect(fieldId, displayValue, selected) {
10406
- const displayToRawMap = this.displayToRawValueMap.get(fieldId);
10407
- const rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue;
10408
- const filter = this.filterStateManager.getFilterState(fieldId);
10409
- if (!filter) {
10410
- this.filterStateManager.dispatch({
10411
- type: exports.FilterActionType.ADD_FILTER,
10412
- payload: {
10413
- field: fieldId,
10414
- type: 'byValue',
10415
- values: [rawValue]
10370
+ records.forEach(record => {
10371
+ const originalValue = record[candidateField];
10372
+ const formattedValue = formatFn(record);
10373
+ countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1);
10374
+ if (formattedValue !== undefined && formattedValue !== null) {
10375
+ const unformattedSet = toUnformatted.get(formattedValue);
10376
+ if (unformattedSet !== undefined && unformattedSet !== null) {
10377
+ unformattedSet.add(originalValue);
10416
10378
  }
10417
- });
10418
- }
10419
- else {
10420
- const updatedValues = selected
10421
- ? [...(filter.values || []), rawValue]
10422
- : (filter.values || []).filter(v => v !== rawValue);
10423
- this.filterStateManager.dispatch({
10424
- type: exports.FilterActionType.UPDATE_FILTER,
10425
- payload: {
10426
- field: fieldId,
10427
- values: updatedValues
10379
+ else {
10380
+ toUnformatted.set(formattedValue, new Set([originalValue]));
10428
10381
  }
10429
- });
10430
- }
10382
+ }
10383
+ });
10384
+ this.candidateKeys.set(candidateField, countMap);
10385
+ this.toUnformattedCache.set(candidateField, toUnformatted);
10431
10386
  }
10432
10387
  toggleSelectAll(fieldId, selected) {
10433
- const filter = this.filterStateManager.getFilterState(fieldId);
10434
- const rawValuesToUpdate = selected ? this.uniqueKeys.get(fieldId)?.map(item => item.rawValue) || [] : [];
10435
- if (!filter) {
10436
- this.filterStateManager.dispatch({
10437
- type: exports.FilterActionType.ADD_FILTER,
10438
- payload: {
10439
- field: fieldId,
10440
- type: 'byValue',
10441
- values: rawValuesToUpdate,
10442
- enable: true
10443
- }
10444
- });
10445
- }
10446
- else {
10447
- const updatedValues = selected ? rawValuesToUpdate : [];
10448
- this.filterStateManager.dispatch({
10449
- type: exports.FilterActionType.UPDATE_FILTER,
10450
- payload: {
10451
- field: fieldId,
10452
- values: updatedValues
10453
- }
10454
- });
10455
- }
10388
+ const options = this.valueFilterOptionList.get(fieldId);
10389
+ options.forEach(option => {
10390
+ option.checkbox.checked = selected;
10391
+ });
10392
+ }
10393
+ syncSelectAllCheckbox(fieldId) {
10394
+ const options = this.valueFilterOptionList.get(fieldId) || [];
10395
+ const allChecked = options.every(o => o.checkbox.checked);
10396
+ const noneChecked = options.every(o => !o.checkbox.checked);
10397
+ this.selectAllCheckbox.checked = allChecked;
10398
+ this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked;
10456
10399
  }
10457
10400
  onSearch(fieldId, value) {
10401
+ const items = this.valueFilterOptionList.get(fieldId);
10458
10402
  const filterKeywords = value
10459
10403
  .toUpperCase()
10460
10404
  .split(' ')
10461
10405
  .filter(s => s);
10462
- const items = this.valueFilterOptionList.get(fieldId);
10463
10406
  for (const item of items) {
10464
10407
  const txtValue = item.id.toUpperCase() || '';
10465
10408
  const match = filterKeywords.some(keyword => txtValue.includes(keyword));
10466
- item.itemContainer.style.display = filterKeywords.length === 0 || match ? 'flex' : 'none';
10409
+ const isVisible = filterKeywords.length === 0 || match;
10410
+ item.itemContainer.style.display = isVisible ? 'flex' : 'none';
10467
10411
  }
10468
10412
  }
10469
10413
  initFilterStateFromTableData(fieldId) {
10470
- const filter = this.filterStateManager.getFilterState(fieldId);
10471
- const selectedRawValues = new Set();
10472
- const displayToRawMap = this.displayToRawValueMap.get(fieldId);
10473
- let targetCol = -1;
10474
- for (let col = 0; col < this.table.colCount; col++) {
10475
- for (let row = this.table.columnHeaderLevelCount; row < this.table.rowCount; row++) {
10476
- if (!this.table.internalProps.layoutMap.isHeader(col, row)) {
10477
- const bodyInfo = this.table.internalProps.layoutMap.getBody(col, row);
10478
- if (bodyInfo && bodyInfo.field === fieldId) {
10479
- targetCol = col;
10480
- break;
10481
- }
10482
- }
10483
- }
10484
- if (targetCol !== -1) {
10485
- break;
10486
- }
10487
- }
10488
- const dataSource = this.table.internalProps.dataSource;
10489
- const currentLength = dataSource.length;
10490
- for (let i = 0; i < currentLength; i++) {
10491
- let displayValue;
10492
- let rawValue;
10493
- if (targetCol !== -1) {
10494
- const row = this.table.columnHeaderLevelCount + i;
10495
- if (row < this.table.rowCount) {
10496
- displayValue = this.table.getCellValue(targetCol, row);
10497
- rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue;
10498
- }
10499
- }
10500
- else {
10501
- displayValue = this.table.getFieldData(String(fieldId), targetCol !== -1 ? targetCol : 0, this.table.columnHeaderLevelCount + i);
10502
- rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue;
10503
- }
10504
- if (rawValue !== undefined && rawValue !== null) {
10505
- selectedRawValues.add(rawValue);
10506
- }
10507
- }
10508
- const hasChanged = !filter || !arrayEqual(filter.values, Array.from(selectedRawValues));
10509
- if (!hasChanged) {
10414
+ const isHasFilteredState = this.filterStateManager.getActiveFilterFields();
10415
+ if (isHasFilteredState) {
10510
10416
  return;
10511
10417
  }
10512
- if (filter) {
10513
- this.filterStateManager.dispatch({
10514
- type: exports.FilterActionType.UPDATE_FILTER,
10515
- payload: {
10516
- field: fieldId,
10517
- type: 'byValue',
10518
- values: Array.from(selectedRawValues)
10519
- }
10520
- });
10521
- }
10522
- else {
10418
+ const selectedValues = new Set();
10419
+ const originalValues = new Set();
10420
+ const currentRecords = this.table.internalProps.dataSource.records;
10421
+ currentRecords.forEach(record => {
10422
+ selectedValues.add(record[fieldId]);
10423
+ });
10424
+ const originalRecords = this.table.internalProps.records;
10425
+ originalRecords.forEach(record => {
10426
+ originalValues.add(record[fieldId]);
10427
+ });
10428
+ const hasFiltered = !arrayEqual(Array.from(originalValues), Array.from(selectedValues));
10429
+ if (hasFiltered) {
10430
+ this.selectedKeys.set(fieldId, selectedValues);
10523
10431
  this.filterStateManager.dispatch({
10524
10432
  type: exports.FilterActionType.ADD_FILTER,
10525
10433
  payload: {
10526
10434
  field: fieldId,
10527
10435
  type: 'byValue',
10528
- values: Array.from(selectedRawValues)
10436
+ values: Array.from(selectedValues),
10437
+ enable: true
10529
10438
  }
10530
10439
  });
10531
10440
  }
10532
10441
  }
10533
- syncCheckboxesWithFilterState(filter) {
10534
- if (!filter) {
10535
- return;
10536
- }
10537
- const selectedRawValues = filter.values || [];
10538
- const displayToRawMap = this.displayToRawValueMap.get(filter.field);
10539
- const optionDomList = this.valueFilterOptionList.get(filter.field);
10540
- optionDomList?.forEach(optionDom => {
10541
- const displayValue = optionDom.originalValue;
10542
- const rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue;
10543
- optionDom.checkbox.checked = selectedRawValues.some(v => v === rawValue);
10544
- const count = this.uniqueKeys.get(filter.field)?.find(key => String(key.value) === optionDom.id)?.count || 0;
10545
- optionDom.countSpan.textContent = String(count);
10546
- optionDom.itemContainer.style.display = count === 0 ? 'none' : 'flex';
10547
- });
10548
- }
10549
- syncSelectAllWithFilterState(filter) {
10550
- if (!filter || !filter.values) {
10551
- this.selectAllCheckbox.checked = false;
10552
- this.selectAllCheckbox.indeterminate = false;
10442
+ applyFilter(fieldId = this.selectedField) {
10443
+ const options = this.valueFilterOptionList.get(fieldId);
10444
+ if (!options || options.length === 0) {
10553
10445
  return;
10554
10446
  }
10555
- const uniqueValuesCount = this.uniqueKeys.get(filter.field)?.length || 0;
10556
- if (uniqueValuesCount === 0) {
10557
- this.selectAllCheckbox.checked = false;
10558
- this.selectAllCheckbox.indeterminate = false;
10559
- }
10560
- else if (filter.values.length === 0) {
10561
- this.selectAllCheckbox.checked = false;
10562
- this.selectAllCheckbox.indeterminate = false;
10563
- }
10564
- else if (filter.values.length === uniqueValuesCount) {
10565
- this.selectAllCheckbox.checked = true;
10566
- this.selectAllCheckbox.indeterminate = false;
10567
- }
10568
- else {
10569
- this.selectAllCheckbox.checked = false;
10570
- this.selectAllCheckbox.indeterminate = true;
10571
- }
10572
- }
10573
- applyFilter(fieldId = this.selectedField) {
10574
- const selectedKeys = this.filterStateManager.getFilterState(fieldId)?.values || [];
10575
- if (selectedKeys.length > 0 && selectedKeys.length < this.uniqueKeys.get(fieldId)?.length) {
10447
+ const selections = options
10448
+ .map(option => {
10449
+ if (option.checkbox.checked) {
10450
+ return option.originalValue;
10451
+ }
10452
+ return null;
10453
+ })
10454
+ .filter(key => key !== null)
10455
+ .flat();
10456
+ this.selectedKeys.set(fieldId, new Set(selections));
10457
+ if (selections.length > 0 && selections.length < this.valueFilterOptionList.get(fieldId).length) {
10576
10458
  this.filterStateManager.dispatch({
10577
10459
  type: exports.FilterActionType.APPLY_FILTERS,
10578
10460
  payload: {
10579
10461
  field: fieldId,
10580
10462
  type: 'byValue',
10581
- values: selectedKeys,
10463
+ values: selections,
10582
10464
  enable: true
10583
10465
  }
10584
10466
  });
@@ -10621,8 +10503,11 @@ ${recordsStr}
10621
10503
  this.selectAllCheckbox.type = 'checkbox';
10622
10504
  this.selectAllCheckbox.checked = true;
10623
10505
  applyStyles(this.selectAllCheckbox, filterStyles.checkbox);
10506
+ this.totalCountSpan = document.createElement('span');
10507
+ this.totalCountSpan.textContent = '';
10508
+ applyStyles(this.totalCountSpan, filterStyles.countSpan);
10624
10509
  selectAllLabel.append(this.selectAllCheckbox, ' 全选');
10625
- selectAllItemDiv.appendChild(selectAllLabel);
10510
+ selectAllItemDiv.append(selectAllLabel, this.totalCountSpan);
10626
10511
  this.filterItemsContainer = document.createElement('div');
10627
10512
  optionsContainer.append(selectAllItemDiv, this.filterItemsContainer);
10628
10513
  this.filterByValuePanel.append(searchContainer, optionsContainer);
@@ -10633,28 +10518,49 @@ ${recordsStr}
10633
10518
  this.filterItemsContainer.innerHTML = '';
10634
10519
  this.valueFilterOptionList.delete(field);
10635
10520
  this.valueFilterOptionList.set(field, []);
10636
- const selectedRawValues = this.filterStateManager.getFilterState(field)?.values || [];
10637
- const selectedRawValueSet = new Set(selectedRawValues);
10521
+ let totalCount = 0;
10522
+ let allChecked = true;
10523
+ let noneChecked = true;
10524
+ const selectedKeysSet = this.selectedKeys.get(field);
10638
10525
  const itemDomList = [];
10639
- this.uniqueKeys.get(field)?.forEach(({ value, count, rawValue }) => {
10526
+ const isFiltered = this.filterStateManager.getFilterState(field)?.enable;
10527
+ const toUnformatted = this.toUnformattedCache.get(field);
10528
+ const candidates = this.candidateKeys.get(field);
10529
+ if (!candidates || candidates.size === 0) {
10530
+ return;
10531
+ }
10532
+ const candidatesArr = [...candidates.entries()];
10533
+ const sortedCandidatesArr = typeof candidatesArr[0][0] === 'number'
10534
+ ? [...candidatesArr]?.sort(([a], [b]) => Number(a) - Number(b))
10535
+ : [...candidatesArr]?.sort(([a], [b]) => String(a).localeCompare(String(b)));
10536
+ sortedCandidatesArr?.forEach(([val, count]) => {
10537
+ totalCount += count;
10538
+ const unformattedArr = Array.from(toUnformatted.get(val) || new Set());
10640
10539
  const itemDiv = document.createElement('div');
10641
10540
  applyStyles(itemDiv, filterStyles.optionItem);
10541
+ itemDiv.style.display = 'flex';
10642
10542
  const label = document.createElement('label');
10643
10543
  applyStyles(label, filterStyles.optionLabel);
10644
10544
  const checkbox = document.createElement('input');
10645
10545
  checkbox.type = 'checkbox';
10646
- checkbox.value = String(value);
10647
- checkbox.checked = selectedRawValueSet.has(rawValue);
10546
+ checkbox.value = String(val);
10547
+ checkbox.checked = isFiltered ? unformattedArr.some(v => selectedKeysSet?.has(v)) : true;
10648
10548
  applyStyles(checkbox, filterStyles.checkbox);
10549
+ if (checkbox.checked) {
10550
+ noneChecked = false;
10551
+ }
10552
+ else {
10553
+ allChecked = false;
10554
+ }
10649
10555
  const countSpan = document.createElement('span');
10650
10556
  countSpan.textContent = String(count);
10651
10557
  applyStyles(countSpan, filterStyles.countSpan);
10652
- label.append(checkbox, ` ${value}`);
10558
+ label.append(checkbox, ` ${val}`);
10653
10559
  itemDiv.append(label, countSpan);
10654
10560
  this.filterItemsContainer.appendChild(itemDiv);
10655
10561
  const itemDom = {
10656
- id: String(value),
10657
- originalValue: value,
10562
+ id: String(val),
10563
+ originalValue: unformattedArr,
10658
10564
  itemContainer: itemDiv,
10659
10565
  checkbox: checkbox,
10660
10566
  countSpan: countSpan
@@ -10662,34 +10568,44 @@ ${recordsStr}
10662
10568
  itemDomList.push(itemDom);
10663
10569
  });
10664
10570
  this.valueFilterOptionList.set(field, itemDomList);
10571
+ this.selectAllCheckbox.checked = allChecked;
10572
+ this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked;
10573
+ this.totalCountSpan.textContent = String(totalCount);
10665
10574
  }
10666
10575
  bindEventForFilterByValue() {
10667
- this.filterByValuePanel.addEventListener('keyup', (event) => {
10576
+ this._onInputKeyUpHandler = (event) => {
10668
10577
  const target = event.target;
10669
10578
  if (target instanceof HTMLInputElement && target.type === 'text') {
10670
10579
  const value = target.value;
10671
10580
  this.onSearch(this.selectedField, value);
10672
10581
  }
10673
- });
10674
- this.filterByValuePanel.addEventListener('change', (event) => {
10582
+ };
10583
+ this._onCheckboxChangeHandler = (event) => {
10675
10584
  const target = event.target;
10676
10585
  if (target instanceof HTMLInputElement && target.type === 'checkbox') {
10677
10586
  if (target === this.selectAllCheckbox) {
10678
10587
  this.toggleSelectAll(this.selectedField, this.selectAllCheckbox.checked);
10679
10588
  }
10680
10589
  else {
10681
- const checkbox = target;
10682
- const checked = checkbox.checked;
10683
- const value = this.valueFilterOptionList
10684
- .get(this.selectedField)
10685
- ?.find(item => item.id === checkbox.value)?.originalValue;
10686
- this.onValueSelect(this.selectedField, value, checked);
10590
+ this.syncSelectAllCheckbox(this.selectedField);
10687
10591
  }
10688
10592
  }
10689
- });
10593
+ };
10594
+ this.filterByValuePanel.addEventListener('keyup', this._onInputKeyUpHandler);
10595
+ this.filterByValuePanel.addEventListener('change', this._onCheckboxChangeHandler);
10690
10596
  }
10691
10597
  show() {
10598
+ const isFiltered = this.filterStateManager.getFilterState(this.selectedField)?.enable;
10599
+ if (!isFiltered) {
10600
+ this.collectCandidateKeysForUnfilteredColumn(this.selectedField);
10601
+ }
10602
+ else {
10603
+ this.collectCandidateKeysForFilteredColumn(this.selectedField);
10604
+ }
10692
10605
  this.initFilterStateFromTableData(this.selectedField);
10606
+ if (this.filterByValueSearchInput) {
10607
+ this.filterByValueSearchInput.value = '';
10608
+ }
10693
10609
  this.renderFilterOptions(this.selectedField);
10694
10610
  this.filterByValuePanel.style.display = 'block';
10695
10611
  }
@@ -10699,6 +10615,43 @@ ${recordsStr}
10699
10615
  clearSearchInputValue() {
10700
10616
  this.filterByValueSearchInput.value = '';
10701
10617
  }
10618
+ destroy() {
10619
+ if (this.filterByValuePanel) {
10620
+ if (this._onInputKeyUpHandler) {
10621
+ this.filterByValuePanel.removeEventListener('keyup', this._onInputKeyUpHandler);
10622
+ }
10623
+ if (this._onCheckboxChangeHandler) {
10624
+ this.filterByValuePanel.removeEventListener('change', this._onCheckboxChangeHandler);
10625
+ }
10626
+ }
10627
+ this._onInputKeyUpHandler = undefined;
10628
+ this._onCheckboxChangeHandler = undefined;
10629
+ if (this.filterByValuePanel) {
10630
+ const parent = this.filterByValuePanel.parentElement;
10631
+ if (parent) {
10632
+ parent.removeChild(this.filterByValuePanel);
10633
+ }
10634
+ else {
10635
+ this.filterByValuePanel.remove();
10636
+ }
10637
+ }
10638
+ if (this.filterItemsContainer) {
10639
+ this.filterItemsContainer.innerHTML = '';
10640
+ }
10641
+ if (this.filterByValueSearchInput) {
10642
+ this.filterByValueSearchInput.value = '';
10643
+ }
10644
+ this.selectedKeys && this.selectedKeys.clear();
10645
+ this.candidateKeys && this.candidateKeys.clear();
10646
+ this.formatFnCache && this.formatFnCache.clear();
10647
+ this.toUnformattedCache && this.toUnformattedCache.clear();
10648
+ this.valueFilterOptionList && this.valueFilterOptionList.clear();
10649
+ this.filterByValuePanel = undefined;
10650
+ this.filterByValueSearchInput = undefined;
10651
+ this.selectAllCheckbox = undefined;
10652
+ this.totalCountSpan = undefined;
10653
+ this.filterItemsContainer = undefined;
10654
+ }
10702
10655
  }
10703
10656
 
10704
10657
  class ConditionFilter {
@@ -11032,6 +10985,11 @@ ${recordsStr}
11032
10985
  this.valueFilter = new ValueFilter(this.table, this.filterStateManager);
11033
10986
  this.conditionFilter = new ConditionFilter(this.table, this.filterStateManager);
11034
10987
  this.filterMenuWidth = 300;
10988
+ this.filterStateManager.subscribe(state => {
10989
+ if (this.isVisible && this.selectedField !== null) {
10990
+ this.updateClearFilterButtonState(this.selectedField);
10991
+ }
10992
+ });
11035
10993
  }
11036
10994
  onTabSwitch(tab) {
11037
10995
  this.activeTab = tab;
@@ -11074,6 +11032,14 @@ ${recordsStr}
11074
11032
  }
11075
11033
  this.hide();
11076
11034
  }
11035
+ updateClearFilterButtonState(field) {
11036
+ const currentFilter = this.filterStateManager.getFilterState(field);
11037
+ const hasActiveFilter = currentFilter && currentFilter.enable;
11038
+ this.clearFilterOptionLink.style.display = 'inline';
11039
+ this.clearFilterOptionLink.style.opacity = hasActiveFilter ? '1' : '0.5';
11040
+ this.clearFilterOptionLink.style.pointerEvents = hasActiveFilter ? 'auto' : 'none';
11041
+ this.clearFilterOptionLink.style.cursor = hasActiveFilter ? 'pointer' : 'not-allowed';
11042
+ }
11077
11043
  render(container) {
11078
11044
  this.filterMenu = document.createElement('div');
11079
11045
  applyStyles(this.filterMenu, filterStyles.filterMenu);
@@ -11185,6 +11151,7 @@ ${recordsStr}
11185
11151
  else {
11186
11152
  this.onTabSwitch('byValue');
11187
11153
  }
11154
+ this.updateClearFilterButtonState(field);
11188
11155
  setTimeout(() => {
11189
11156
  this.isVisible = true;
11190
11157
  }, 0);
@@ -11414,6 +11381,7 @@ ${recordsStr}
11414
11381
  this.table = null;
11415
11382
  this.filterEngine = null;
11416
11383
  this.filterStateManager = null;
11384
+ this.filterToolbar.valueFilter.destroy();
11417
11385
  this.filterToolbar = null;
11418
11386
  }
11419
11387
  }
@@ -12295,26 +12263,26 @@ ${recordsStr}
12295
12263
  }
12296
12264
  }
12297
12265
 
12298
- var Direction;
12266
+ exports.Direction = void 0;
12299
12267
  (function (Direction) {
12300
12268
  Direction["UP"] = "top";
12301
12269
  Direction["RIGHT"] = "right";
12302
12270
  Direction["DOWN"] = "bottom";
12303
12271
  Direction["LEFT"] = "left";
12304
- })(Direction || (Direction = {}));
12305
- var APPLY_TYPE;
12272
+ })(exports.Direction || (exports.Direction = {}));
12273
+ exports.APPLY_TYPE = void 0;
12306
12274
  (function (APPLY_TYPE) {
12307
12275
  APPLY_TYPE["COPY"] = "copy";
12308
12276
  APPLY_TYPE["SERIES"] = "series";
12309
- })(APPLY_TYPE || (APPLY_TYPE = {}));
12310
- var CellValueType;
12277
+ })(exports.APPLY_TYPE || (exports.APPLY_TYPE = {}));
12278
+ exports.CellValueType = void 0;
12311
12279
  (function (CellValueType) {
12312
12280
  CellValueType[CellValueType["STRING"] = 1] = "STRING";
12313
12281
  CellValueType[CellValueType["NUMBER"] = 2] = "NUMBER";
12314
12282
  CellValueType[CellValueType["BOOLEAN"] = 3] = "BOOLEAN";
12315
12283
  CellValueType[CellValueType["FORCE_STRING"] = 4] = "FORCE_STRING";
12316
- })(CellValueType || (CellValueType = {}));
12317
- var DATA_TYPE;
12284
+ })(exports.CellValueType || (exports.CellValueType = {}));
12285
+ exports.DATA_TYPE = void 0;
12318
12286
  (function (DATA_TYPE) {
12319
12287
  DATA_TYPE["NUMBER"] = "number";
12320
12288
  DATA_TYPE["DATE"] = "date";
@@ -12325,7 +12293,188 @@ ${recordsStr}
12325
12293
  DATA_TYPE["LOOP_SERIES"] = "loopSeries";
12326
12294
  DATA_TYPE["FORMULA"] = "formula";
12327
12295
  DATA_TYPE["OTHER"] = "other";
12328
- })(DATA_TYPE || (DATA_TYPE = {}));
12296
+ })(exports.DATA_TYPE || (exports.DATA_TYPE = {}));
12297
+
12298
+ function getSelectedRangeArray(selectedRange) {
12299
+ const minCol = Math.min(selectedRange.start.col, selectedRange.end.col);
12300
+ const minRow = Math.min(selectedRange.start.row, selectedRange.end.row);
12301
+ const maxCol = Math.max(selectedRange.start.col, selectedRange.end.col);
12302
+ const maxRow = Math.max(selectedRange.start.row, selectedRange.end.row);
12303
+ const cols = [];
12304
+ const rows = [];
12305
+ for (let i = minCol; i <= maxCol; i++) {
12306
+ cols.push(i);
12307
+ }
12308
+ for (let i = minRow; i <= maxRow; i++) {
12309
+ rows.push(i);
12310
+ }
12311
+ return { cols, rows };
12312
+ }
12313
+ function getTargetRange(direction, sourceRange, selectedRange) {
12314
+ if (direction === exports.Direction.DOWN || direction === exports.Direction.UP) {
12315
+ return {
12316
+ cols: selectedRange.cols,
12317
+ rows: selectedRange.rows.filter(row => !sourceRange.rows.includes(row))
12318
+ };
12319
+ }
12320
+ else {
12321
+ return {
12322
+ cols: selectedRange.cols.filter(col => !sourceRange.cols.includes(col)),
12323
+ rows: selectedRange.rows
12324
+ };
12325
+ }
12326
+ }
12327
+ function openAutoFillMenu(tableInstance, endCol, endRow) {
12328
+ const rect = tableInstance.scenegraph.highPerformanceGetCell(endCol, endRow).globalAABBBounds;
12329
+ tableInstance.showDropDownMenu(endCol, endRow, {
12330
+ content: [
12331
+ {
12332
+ type: 'item',
12333
+ text: '复制填充',
12334
+ icon: {
12335
+ width: 16,
12336
+ height: 16,
12337
+ svg: '<svg t="1756136702877" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1474" width="200" height="200"><path d="M853.333333 981.333333h-384c-72.533333 0-128-55.466667-128-128v-384c0-72.533333 55.466667-128 128-128h384c72.533333 0 128 55.466667 128 128v384c0 72.533333-55.466667 128-128 128z m-384-554.666666c-25.6 0-42.666667 17.066667-42.666666 42.666666v384c0 25.6 17.066667 42.666667 42.666666 42.666667h384c25.6 0 42.666667-17.066667 42.666667-42.666667v-384c0-25.6-17.066667-42.666667-42.666667-42.666666h-384z" p-id="1475"></path><path d="M213.333333 682.666667H170.666667c-72.533333 0-128-55.466667-128-128V170.666667c0-72.533333 55.466667-128 128-128h384c72.533333 0 128 55.466667 128 128v42.666666c0 25.6-17.066667 42.666667-42.666667 42.666667s-42.666667-17.066667-42.666667-42.666667V170.666667c0-25.6-17.066667-42.666667-42.666666-42.666667H170.666667c-25.6 0-42.666667 17.066667-42.666667 42.666667v384c0 25.6 17.066667 42.666667 42.666667 42.666666h42.666666c25.6 0 42.666667 17.066667 42.666667 42.666667s-17.066667 42.666667-42.666667 42.666667z" p-id="1476"></path></svg>'
12338
+ }
12339
+ },
12340
+ {
12341
+ type: 'item',
12342
+ text: '序列填充',
12343
+ icon: {
12344
+ width: 16,
12345
+ height: 16,
12346
+ svg: '<svg t="1756136788547" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2463" width="200" height="200"><path d="M312.832482 65.167035H959.204489c35.706211 0 64.64232 29.473622 64.64232 65.832527 0 36.346107-28.936109 65.832527-64.629522 65.832527H312.819684c-35.693413 0-64.629522-29.473622-64.629522-65.832527 0-36.346107 28.936109-65.832527 64.629522-65.832527z m0 394.982363H959.204489c35.706211 0 64.64232 29.460824 64.64232 65.819729 0 36.358905-28.936109 65.832527-64.629522 65.832527H312.819684c-35.693413 0-64.629522-29.473622-64.629522-65.832527 0-36.346107 28.936109-65.819729 64.629522-65.819729z m0 394.969566H959.204489c35.706211 0 64.64232 29.473622 64.64232 65.819729 0 36.358905-28.936109 65.832527-64.629522 65.832527H312.819684c-35.693413 0-64.629522-29.473622-64.629522-65.832527 0-36.346107 28.936109-65.819729 64.629522-65.819729zM12.286008 69.108796V38.176211c9.892796 0.767876 19.836784 0.767876 29.72958 0A41.823619 41.823619 0 0 0 63.989626 25.672638c4.261709-4.671243 7.358807-10.315128 9.048133-16.458132 0.37114-3.058704 0.37114-6.143004 0-9.214506H114.413451v229.748352H65.93491V69.108796H12.286008z m0 510.176487a130.730805 130.730805 0 0 1 45.240665-49.374395 334.537763 334.537763 0 0 0 40.070304-32.250771 48.47854 48.47854 0 0 0 14.218495-33.581756 37.31875 37.31875 0 0 0-7.755543-24.354451 28.193829 28.193829 0 0 0-23.266628-9.879998 27.643518 27.643518 0 0 0-31.02217 15.139945 78.27211 78.27211 0 0 0-5.170362 28.30901H2.585181a114.311067 114.311067 0 0 1 10.340723-48.056208c12.388392-24.124089 38.086625-37.984242 64.629522-34.887144a79.897447 79.897447 0 0 1 57.539472 20.41269 71.783562 71.783562 0 0 1 21.321343 53.981648 74.637499 74.637499 0 0 1-14.858391 46.072531 152.16733 152.16733 0 0 1-32.967455 29.627197L90.481331 553.625443l-23.266628 17.763521c-4.082538 3.583419-7.563574 7.806734-10.353522 12.51637h99.542262v40.147092H0a110.945213 110.945213 0 0 1 10.340724-45.419837l1.945284 0.665492zM44.600769 948.582211a53.495327 53.495327 0 0 0 4.517668 23.036265 30.279891 30.279891 0 0 0 29.742378 17.110826c7.422797 0.255959 14.717614-2.073264 20.681447-6.578133 6.7829-6.962071 10.315128-16.547717 9.688029-26.325332a30.356678 30.356678 0 0 0-18.096266-30.945383 91.735527 91.735527 0 0 0-32.314761-8.561812V883.440772a83.903197 83.903197 0 0 0 30.382274-4.607253 27.106005 27.106005 0 0 0 14.858391-28.30901 30.612637 30.612637 0 0 0-7.755542-21.730877 27.528337 27.528337 0 0 0-21.321344-8.549014 26.939632 26.939632 0 0 0-23.279425 10.532692 44.063256 44.063256 0 0 0-7.102849 27.643519H2.585181a117.101015 117.101015 0 0 1 5.823056-32.916264 74.381541 74.381541 0 0 1 17.443572-25.019944 60.534186 60.534186 0 0 1 20.681447-12.503572 89.55988 89.55988 0 0 1 29.742378-3.289067A78.540867 78.540867 0 0 1 129.259044 801.79001a57.744238 57.744238 0 0 1 20.041551 46.085328 51.921182 51.921182 0 0 1-12.286008 34.887144c-4.159326 5.170362-9.470465 9.227304-15.511086 11.850879 6.7829 1.510155 12.900309 5.208756 17.45637 10.532692a57.821026 57.821026 0 0 1 17.443572 44.10165 75.136618 75.136618 0 0 1-20.028753 52.010768 76.122059 76.122059 0 0 1-59.471958 22.383571 71.962733 71.962733 0 0 1-64.629522-32.250771A97.52019 97.52019 0 0 1 1.279793 946.611331l43.308178 1.97088z" fill="#515151" p-id="2464"></path></svg>'
12347
+ }
12348
+ }
12349
+ ],
12350
+ referencePosition: {
12351
+ rect: {
12352
+ right: rect.x2 + 110,
12353
+ bottom: rect.y2
12354
+ }
12355
+ }
12356
+ });
12357
+ }
12358
+ function getCellMatrix(table) {
12359
+ return {
12360
+ getValue: (row, col) => {
12361
+ const value = table.getCellValue(col, row);
12362
+ if (typeof value === 'number' || !isNaN(Number(value))) {
12363
+ return {
12364
+ v: value,
12365
+ t: exports.CellValueType.NUMBER
12366
+ };
12367
+ }
12368
+ return {
12369
+ v: value || '',
12370
+ t: exports.CellValueType.STRING
12371
+ };
12372
+ },
12373
+ getMaxRows: () => {
12374
+ return table.records.length;
12375
+ },
12376
+ getMaxColumns: () => {
12377
+ return table.columns.length;
12378
+ }
12379
+ };
12380
+ }
12381
+ function isMergeCell(table, col, row) {
12382
+ const cellRange = table.getCellRange(col, row);
12383
+ if (cellRange.start.col !== cellRange.end.col || cellRange.start.row !== cellRange.end.row) {
12384
+ return cellRange;
12385
+ }
12386
+ return null;
12387
+ }
12388
+
12389
+ class DefaultFormulaAdapter {
12390
+ table;
12391
+ constructor(table) {
12392
+ this.table = table;
12393
+ }
12394
+ isFormulaCell(col, row) {
12395
+ const cellValue = this.table.getCellValue(col, row);
12396
+ return typeof cellValue === 'string' && cellValue.startsWith('=');
12397
+ }
12398
+ getCellFormula(col, row) {
12399
+ const cellValue = this.table.getCellValue(col, row);
12400
+ if (typeof cellValue === 'string' && cellValue.startsWith('=')) {
12401
+ return cellValue;
12402
+ }
12403
+ return undefined;
12404
+ }
12405
+ setCellFormula(col, row, formula) {
12406
+ this.table.changeCellValue(col, row, formula);
12407
+ }
12408
+ getCalculatedValue(col, row) {
12409
+ return this.table.getCellValue(col, row);
12410
+ }
12411
+ refreshFormulas() {
12412
+ }
12413
+ hasFormulaEngine() {
12414
+ return false;
12415
+ }
12416
+ }
12417
+ function createFormulaAdapter(table, customIsFormulaCell, customGetCellFormula, customSetCellFormula) {
12418
+ if (customIsFormulaCell || customGetCellFormula || customSetCellFormula) {
12419
+ return new CustomFormulaAdapter(table, customIsFormulaCell, customGetCellFormula, customSetCellFormula);
12420
+ }
12421
+ return new DefaultFormulaAdapter(table);
12422
+ }
12423
+ class CustomFormulaAdapter {
12424
+ table;
12425
+ isFormulaCellFn;
12426
+ getCellFormulaFn;
12427
+ setCellFormulaFn;
12428
+ constructor(table, isFormulaCellFn, getCellFormulaFn, setCellFormulaFn) {
12429
+ this.table = table;
12430
+ this.isFormulaCellFn = isFormulaCellFn;
12431
+ this.getCellFormulaFn = getCellFormulaFn;
12432
+ this.setCellFormulaFn = setCellFormulaFn;
12433
+ }
12434
+ isFormulaCell(col, row) {
12435
+ if (this.isFormulaCellFn) {
12436
+ const cellData = this.table.getCellValue(col, row);
12437
+ return this.isFormulaCellFn(col, row, cellData, this.table);
12438
+ }
12439
+ const cellValue = this.table.getCellValue(col, row);
12440
+ return typeof cellValue === 'string' && cellValue.startsWith('=');
12441
+ }
12442
+ getCellFormula(col, row) {
12443
+ if (this.getCellFormulaFn) {
12444
+ const cellData = this.table.getCellValue(col, row);
12445
+ return this.getCellFormulaFn(col, row, cellData, this.table);
12446
+ }
12447
+ const cellValue = this.table.getCellValue(col, row);
12448
+ if (typeof cellValue === 'string' && cellValue.startsWith('=')) {
12449
+ return cellValue;
12450
+ }
12451
+ return undefined;
12452
+ }
12453
+ setCellFormula(col, row, formula) {
12454
+ if (this.setCellFormulaFn) {
12455
+ this.setCellFormulaFn(col, row, formula, this.table);
12456
+ return;
12457
+ }
12458
+ this.table.changeCellValue(col, row, formula);
12459
+ }
12460
+ getCalculatedValue(col, row) {
12461
+ return this.table.getCellValue(col, row);
12462
+ }
12463
+ refreshFormulas() {
12464
+ }
12465
+ hasFormulaEngine() {
12466
+ return false;
12467
+ }
12468
+ }
12469
+ function enhanceCellDataWithFormula(cellData, col, row, formulaAdapter) {
12470
+ const enhanced = { ...cellData };
12471
+ if (formulaAdapter.isFormulaCell(col, row)) {
12472
+ enhanced.isFormula = true;
12473
+ enhanced.formula = formulaAdapter.getCellFormula(col, row);
12474
+ enhanced.calculatedValue = formulaAdapter.getCalculatedValue(col, row);
12475
+ }
12476
+ return enhanced;
12477
+ }
12329
12478
 
12330
12479
  /**
12331
12480
  * A specialized version of `_.forEach` for arrays without support for
@@ -13508,7 +13657,7 @@ ${recordsStr}
13508
13657
  const index = (i - 1) % data.length;
13509
13658
  const d = deepClone(data[index]);
13510
13659
  removeCellCustom(d);
13511
- const forward = direction === Direction.DOWN || direction === Direction.RIGHT;
13660
+ const forward = direction === exports.Direction.DOWN || direction === exports.Direction.RIGHT;
13512
13661
  const y = forecast(data.length + i, dataNumArr, xArr, forward);
13513
13662
  if (d) {
13514
13663
  d.v = converter ? converter.fromNumber(y, d.f) : y;
@@ -13858,22 +14007,22 @@ ${recordsStr}
13858
14007
  converterManager.register(new DateConverter());
13859
14008
 
13860
14009
  const dateRule = {
13861
- type: DATA_TYPE.DATE,
14010
+ type: exports.DATA_TYPE.DATE,
13862
14011
  priority: 1100,
13863
14012
  match: (cellData, accessor) => {
13864
14013
  return typeof cellData?.v === 'string' && converterManager.getConverter(cellData.v) instanceof DateConverter;
13865
14014
  },
13866
14015
  isContinue: (prev, cur) => {
13867
- if (prev.type === DATA_TYPE.DATE) {
14016
+ if (prev.type === exports.DATA_TYPE.DATE) {
13868
14017
  return true;
13869
14018
  }
13870
14019
  return false;
13871
14020
  },
13872
14021
  applyFunctions: {
13873
- [APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14022
+ [exports.APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
13874
14023
  const { data } = dataWithIndex;
13875
14024
  const converter = converterManager.getConverter(data[0]?.v);
13876
- if (direction === Direction.LEFT || direction === Direction.UP) {
14025
+ if (direction === exports.Direction.LEFT || direction === exports.Direction.UP) {
13877
14026
  data.reverse();
13878
14027
  return fillSeries(data, len, direction, converter).reverse();
13879
14028
  }
@@ -13882,19 +14031,19 @@ ${recordsStr}
13882
14031
  }
13883
14032
  };
13884
14033
  const numberRule = {
13885
- type: DATA_TYPE.NUMBER,
14034
+ type: exports.DATA_TYPE.NUMBER,
13886
14035
  priority: 1000,
13887
- match: (cellData) => typeof cellData?.v === 'number' || cellData?.t === CellValueType.NUMBER,
14036
+ match: (cellData) => typeof cellData?.v === 'number' || cellData?.t === exports.CellValueType.NUMBER,
13888
14037
  isContinue: (prev, cur) => {
13889
- if (prev.type === DATA_TYPE.NUMBER) {
14038
+ if (prev.type === exports.DATA_TYPE.NUMBER) {
13890
14039
  return true;
13891
14040
  }
13892
14041
  return false;
13893
14042
  },
13894
14043
  applyFunctions: {
13895
- [APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14044
+ [exports.APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
13896
14045
  const { data } = dataWithIndex;
13897
- if (direction === Direction.LEFT || direction === Direction.UP) {
14046
+ if (direction === exports.Direction.LEFT || direction === exports.Direction.UP) {
13898
14047
  data.reverse();
13899
14048
  return fillSeries(data, len, direction).reverse();
13900
14049
  }
@@ -13903,22 +14052,22 @@ ${recordsStr}
13903
14052
  }
13904
14053
  };
13905
14054
  const otherRule = {
13906
- type: DATA_TYPE.OTHER,
14055
+ type: exports.DATA_TYPE.OTHER,
13907
14056
  priority: 0,
13908
14057
  match: () => true,
13909
14058
  isContinue: (prev, cur) => {
13910
- if (prev.type === DATA_TYPE.OTHER) {
14059
+ if (prev.type === exports.DATA_TYPE.OTHER) {
13911
14060
  return true;
13912
14061
  }
13913
14062
  return false;
13914
14063
  }
13915
14064
  };
13916
14065
  const extendNumberRule = {
13917
- type: DATA_TYPE.EXTEND_NUMBER,
14066
+ type: exports.DATA_TYPE.EXTEND_NUMBER,
13918
14067
  priority: 900,
13919
14068
  match: cellData => matchExtendNumber(`${cellData?.v ?? ''}` || '').isExtendNumber,
13920
14069
  isContinue: (prev, cur) => {
13921
- if (prev.type === DATA_TYPE.EXTEND_NUMBER) {
14070
+ if (prev.type === exports.DATA_TYPE.EXTEND_NUMBER) {
13922
14071
  const { beforeTxt, afterTxt } = matchExtendNumber(`${prev.cellData?.v ?? ''}` || '');
13923
14072
  const { beforeTxt: curBeforeTxt, afterTxt: curAfterTxt } = matchExtendNumber(`${cur?.v ?? ''}` || '');
13924
14073
  if (beforeTxt === curBeforeTxt && afterTxt === curAfterTxt) {
@@ -13928,9 +14077,9 @@ ${recordsStr}
13928
14077
  return false;
13929
14078
  },
13930
14079
  applyFunctions: {
13931
- [APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14080
+ [exports.APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
13932
14081
  const { data } = dataWithIndex;
13933
- const isReverse = direction === Direction.UP || direction === Direction.LEFT;
14082
+ const isReverse = direction === exports.Direction.UP || direction === exports.Direction.LEFT;
13934
14083
  let step;
13935
14084
  if (data.length === 1) {
13936
14085
  step = isReverse ? -1 : 1;
@@ -13954,7 +14103,7 @@ ${recordsStr}
13954
14103
  }
13955
14104
  };
13956
14105
  const chnNumberRule = {
13957
- type: DATA_TYPE.CHN_NUMBER,
14106
+ type: exports.DATA_TYPE.CHN_NUMBER,
13958
14107
  priority: 830,
13959
14108
  match: cellData => {
13960
14109
  if (isChnNumber(`${cellData?.v ?? ''}` || '')) {
@@ -13963,15 +14112,15 @@ ${recordsStr}
13963
14112
  return false;
13964
14113
  },
13965
14114
  isContinue: (prev, cur) => {
13966
- if (prev.type === DATA_TYPE.CHN_NUMBER) {
14115
+ if (prev.type === exports.DATA_TYPE.CHN_NUMBER) {
13967
14116
  return true;
13968
14117
  }
13969
14118
  return false;
13970
14119
  },
13971
14120
  applyFunctions: {
13972
- [APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14121
+ [exports.APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
13973
14122
  const { data } = dataWithIndex;
13974
- const isReverse = direction === Direction.LEFT || direction === Direction.UP;
14123
+ const isReverse = direction === exports.Direction.LEFT || direction === exports.Direction.UP;
13975
14124
  if (data.length === 1) {
13976
14125
  let step;
13977
14126
  if (!isReverse) {
@@ -14023,7 +14172,7 @@ ${recordsStr}
14023
14172
  }
14024
14173
  };
14025
14174
  const chnWeek2Rule = {
14026
- type: DATA_TYPE.CHN_WEEK2,
14175
+ type: exports.DATA_TYPE.CHN_WEEK2,
14027
14176
  priority: 820,
14028
14177
  match: cellData => {
14029
14178
  if (isChnWeek2(`${cellData?.v ?? ''}` || '')) {
@@ -14031,11 +14180,11 @@ ${recordsStr}
14031
14180
  }
14032
14181
  return false;
14033
14182
  },
14034
- isContinue: (prev, cur) => prev.type === DATA_TYPE.CHN_WEEK2,
14183
+ isContinue: (prev, cur) => prev.type === exports.DATA_TYPE.CHN_WEEK2,
14035
14184
  applyFunctions: {
14036
- [APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14185
+ [exports.APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14037
14186
  const { data } = dataWithIndex;
14038
- const isReverse = direction === Direction.LEFT || direction === Direction.UP;
14187
+ const isReverse = direction === exports.Direction.LEFT || direction === exports.Direction.UP;
14039
14188
  if (data.length === 1) {
14040
14189
  let step;
14041
14190
  if (!isReverse) {
@@ -14077,14 +14226,14 @@ ${recordsStr}
14077
14226
  }
14078
14227
  };
14079
14228
  const chnWeek3Rule = {
14080
- type: DATA_TYPE.CHN_WEEK3,
14229
+ type: exports.DATA_TYPE.CHN_WEEK3,
14081
14230
  priority: 810,
14082
14231
  match: cellData => isChnWeek3(`${cellData?.v ?? ''}` || ''),
14083
- isContinue: (prev, cur) => prev.type === DATA_TYPE.CHN_WEEK3,
14232
+ isContinue: (prev, cur) => prev.type === exports.DATA_TYPE.CHN_WEEK3,
14084
14233
  applyFunctions: {
14085
- [APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14234
+ [exports.APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14086
14235
  const { data } = dataWithIndex;
14087
- const isReverse = direction === Direction.LEFT || direction === Direction.UP;
14236
+ const isReverse = direction === exports.Direction.LEFT || direction === exports.Direction.UP;
14088
14237
  if (data.length === 1) {
14089
14238
  let step;
14090
14239
  if (!isReverse) {
@@ -14128,20 +14277,20 @@ ${recordsStr}
14128
14277
  }
14129
14278
  };
14130
14279
  const loopSeriesRule = {
14131
- type: DATA_TYPE.LOOP_SERIES,
14280
+ type: exports.DATA_TYPE.LOOP_SERIES,
14132
14281
  priority: 800,
14133
14282
  match: cellData => isLoopSeries(`${cellData?.v ?? ''}` || ''),
14134
14283
  isContinue: (prev, cur) => {
14135
- if (prev.type === DATA_TYPE.LOOP_SERIES) {
14284
+ if (prev.type === exports.DATA_TYPE.LOOP_SERIES) {
14136
14285
  return (getLoopSeriesInfo(`${prev.cellData?.v ?? ''}` || '').name ===
14137
14286
  getLoopSeriesInfo(`${cur?.v ?? ''}` || '').name);
14138
14287
  }
14139
14288
  return false;
14140
14289
  },
14141
14290
  applyFunctions: {
14142
- [APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14291
+ [exports.APPLY_TYPE.SERIES]: (dataWithIndex, len, direction) => {
14143
14292
  const { data } = dataWithIndex;
14144
- const isReverse = direction === Direction.LEFT || direction === Direction.UP;
14293
+ const isReverse = direction === exports.Direction.LEFT || direction === exports.Direction.UP;
14145
14294
  const { series } = getLoopSeriesInfo(`${data[0]?.v}` || '');
14146
14295
  if (data.length === 1) {
14147
14296
  let step;
@@ -14187,6 +14336,192 @@ ${recordsStr}
14187
14336
  function reverseIfNeed(data, reverse) {
14188
14337
  return reverse ? data.reverse() : data;
14189
14338
  }
14339
+ const formulaRule = {
14340
+ type: exports.DATA_TYPE.FORMULA,
14341
+ priority: 1200,
14342
+ match: (cellData, accessor) => {
14343
+ return typeof cellData?.v === 'string' && cellData.v.startsWith('=');
14344
+ },
14345
+ isContinue: (prev, cur) => {
14346
+ if (prev.type === exports.DATA_TYPE.FORMULA && cur?.v?.startsWith('=')) {
14347
+ return true;
14348
+ }
14349
+ return false;
14350
+ },
14351
+ applyFunctions: {
14352
+ [exports.APPLY_TYPE.COPY]: (dataWithIndex, len, direction, copyDataPiece, location) => {
14353
+ const { data } = dataWithIndex;
14354
+ return fillCopy(data, len);
14355
+ },
14356
+ [exports.APPLY_TYPE.SERIES]: (dataWithIndex, len, direction, copyDataPiece, location) => {
14357
+ const { data } = dataWithIndex;
14358
+ if (data.length === 1) {
14359
+ return adjustFormulaReferences(data, len, direction);
14360
+ }
14361
+ const adjustedFormulas = adjustFormulaReferencesInSeries(data, len);
14362
+ if (adjustedFormulas) {
14363
+ return adjustedFormulas;
14364
+ }
14365
+ return fillCopy(data, len);
14366
+ }
14367
+ }
14368
+ };
14369
+ function adjustFormulaReferences(formulas, len, direction, location) {
14370
+ const result = [];
14371
+ const baseFormula = formulas[0]?.v || '';
14372
+ for (let i = 0; i < len; i++) {
14373
+ let newFormula = baseFormula;
14374
+ let rowOffset = 0;
14375
+ let colOffset = 0;
14376
+ switch (direction) {
14377
+ case exports.Direction.DOWN:
14378
+ rowOffset = i + 1;
14379
+ break;
14380
+ case exports.Direction.UP:
14381
+ rowOffset = -(i + 1);
14382
+ break;
14383
+ case exports.Direction.RIGHT:
14384
+ colOffset = i + 1;
14385
+ break;
14386
+ case exports.Direction.LEFT:
14387
+ colOffset = -(i + 1);
14388
+ break;
14389
+ }
14390
+ newFormula = adjustCellReferencesInFormula(baseFormula, rowOffset, colOffset);
14391
+ result.push({
14392
+ v: newFormula,
14393
+ t: formulas[0]?.t
14394
+ });
14395
+ }
14396
+ return result;
14397
+ }
14398
+ function adjustFormulaReferencesInSeries(formulas, len, direction, location) {
14399
+ if (formulas.length < 2) {
14400
+ return null;
14401
+ }
14402
+ const baseFormula1 = formulas[0]?.v || '';
14403
+ const baseFormula2 = formulas[1]?.v || '';
14404
+ const pattern = detectFormulaPattern(baseFormula1, baseFormula2);
14405
+ if (!pattern) {
14406
+ return null;
14407
+ }
14408
+ const result = [];
14409
+ for (let i = 0; i < len; i++) {
14410
+ let newFormula = baseFormula1;
14411
+ const multiplier = i + 1;
14412
+ newFormula = applyFormulaPattern(newFormula, pattern, multiplier);
14413
+ result.push({
14414
+ v: newFormula,
14415
+ t: formulas[0]?.t
14416
+ });
14417
+ }
14418
+ return result;
14419
+ }
14420
+ function detectFormulaPattern(formula1, formula2) {
14421
+ const cellRefRegex = /\$?([A-Z]+)\$?(\d+)/g;
14422
+ const matches1 = [...formula1.matchAll(cellRefRegex)];
14423
+ const matches2 = [...formula2.matchAll(cellRefRegex)];
14424
+ if (matches1.length !== matches2.length || matches1.length === 0) {
14425
+ return null;
14426
+ }
14427
+ let totalRowOffset = 0;
14428
+ let totalColOffset = 0;
14429
+ let validMatches = 0;
14430
+ for (let i = 0; i < matches1.length; i++) {
14431
+ const col1 = matches1[i][1];
14432
+ const row1 = parseInt(matches1[i][2], 10);
14433
+ const col2 = matches2[i][1];
14434
+ const row2 = parseInt(matches2[i][2], 10);
14435
+ const colOffset = columnToNumber(col2) - columnToNumber(col1);
14436
+ const rowOffset = row2 - row1;
14437
+ if (Math.abs(colOffset) < 100 && Math.abs(rowOffset) < 10000) {
14438
+ totalColOffset += colOffset;
14439
+ totalRowOffset += rowOffset;
14440
+ validMatches++;
14441
+ }
14442
+ }
14443
+ if (validMatches === 0) {
14444
+ return null;
14445
+ }
14446
+ return {
14447
+ rowOffset: totalRowOffset / validMatches,
14448
+ colOffset: totalColOffset / validMatches
14449
+ };
14450
+ }
14451
+ function applyFormulaPattern(formula, pattern, multiplier, direction) {
14452
+ const cellRefRegex = /\$?([A-Z]+)\$?(\d+)/g;
14453
+ return formula.replace(cellRefRegex, (match, colStr, rowStr) => {
14454
+ const isColAbsolute = match.startsWith('$') && match.indexOf(colStr) > 0;
14455
+ const isRowAbsolute = match.includes('$' + rowStr);
14456
+ let newCol = colStr;
14457
+ let newRow = rowStr;
14458
+ if (!isColAbsolute && pattern.colOffset !== 0) {
14459
+ const colNum = columnToNumber(colStr);
14460
+ const newColNum = colNum + pattern.colOffset * multiplier;
14461
+ newCol = numberToColumn(newColNum);
14462
+ }
14463
+ if (!isRowAbsolute && pattern.rowOffset !== 0) {
14464
+ const rowNum = parseInt(rowStr, 10);
14465
+ const newRowNum = rowNum + pattern.rowOffset * multiplier;
14466
+ newRow = newRowNum.toString();
14467
+ }
14468
+ let result = '';
14469
+ if (isColAbsolute) {
14470
+ result += '$';
14471
+ }
14472
+ result += newCol;
14473
+ if (isRowAbsolute) {
14474
+ result += '$';
14475
+ }
14476
+ result += newRow;
14477
+ return result;
14478
+ });
14479
+ }
14480
+ function adjustCellReferencesInFormula(formula, rowOffset, colOffset) {
14481
+ const cellRefRegex = /\$?([A-Z]+)\$?(\d+)/g;
14482
+ return formula.replace(cellRefRegex, (match, colStr, rowStr) => {
14483
+ const isColAbsolute = match.startsWith('$') && match.indexOf(colStr) > 0;
14484
+ const isRowAbsolute = match.includes('$' + rowStr);
14485
+ let newCol = colStr;
14486
+ let newRow = rowStr;
14487
+ if (!isColAbsolute && colOffset !== 0) {
14488
+ const colNum = columnToNumber(colStr);
14489
+ const newColNum = colNum + colOffset;
14490
+ newCol = numberToColumn(newColNum);
14491
+ }
14492
+ if (!isRowAbsolute && rowOffset !== 0) {
14493
+ const rowNum = parseInt(rowStr, 10);
14494
+ const newRowNum = rowNum + rowOffset;
14495
+ newRow = newRowNum.toString();
14496
+ }
14497
+ let result = '';
14498
+ if (isColAbsolute) {
14499
+ result += '$';
14500
+ }
14501
+ result += newCol;
14502
+ if (isRowAbsolute) {
14503
+ result += '$';
14504
+ }
14505
+ result += newRow;
14506
+ return result;
14507
+ });
14508
+ }
14509
+ function columnToNumber(col) {
14510
+ let result = 0;
14511
+ for (let i = 0; i < col.length; i++) {
14512
+ result = result * 26 + (col.charCodeAt(i) - 'A'.charCodeAt(0) + 1);
14513
+ }
14514
+ return result;
14515
+ }
14516
+ function numberToColumn(num) {
14517
+ let result = '';
14518
+ while (num > 0) {
14519
+ num--;
14520
+ result = String.fromCharCode('A'.charCodeAt(0) + (num % 26)) + result;
14521
+ num = Math.floor(num / 26);
14522
+ }
14523
+ return result;
14524
+ }
14190
14525
 
14191
14526
  class AutoFillService {
14192
14527
  _rules = [];
@@ -14195,6 +14530,7 @@ ${recordsStr}
14195
14530
  }
14196
14531
  _init() {
14197
14532
  this._rules = [
14533
+ formulaRule,
14198
14534
  dateRule,
14199
14535
  numberRule,
14200
14536
  extendNumberRule,
@@ -14217,97 +14553,6 @@ ${recordsStr}
14217
14553
  }
14218
14554
  }
14219
14555
 
14220
- function getSelectedRangeArray(selectedRange) {
14221
- const minCol = Math.min(selectedRange.start.col, selectedRange.end.col);
14222
- const minRow = Math.min(selectedRange.start.row, selectedRange.end.row);
14223
- const maxCol = Math.max(selectedRange.start.col, selectedRange.end.col);
14224
- const maxRow = Math.max(selectedRange.start.row, selectedRange.end.row);
14225
- const cols = [];
14226
- const rows = [];
14227
- for (let i = minCol; i <= maxCol; i++) {
14228
- cols.push(i);
14229
- }
14230
- for (let i = minRow; i <= maxRow; i++) {
14231
- rows.push(i);
14232
- }
14233
- return { cols, rows };
14234
- }
14235
- function getTargetRange(direction, sourceRange, selectedRange) {
14236
- if (direction === Direction.DOWN || direction === Direction.UP) {
14237
- return {
14238
- cols: selectedRange.cols,
14239
- rows: selectedRange.rows.filter(row => !sourceRange.rows.includes(row))
14240
- };
14241
- }
14242
- else {
14243
- return {
14244
- cols: selectedRange.cols.filter(col => !sourceRange.cols.includes(col)),
14245
- rows: selectedRange.rows
14246
- };
14247
- }
14248
- }
14249
- function openAutoFillMenu(tableInstance, endCol, endRow) {
14250
- const rect = tableInstance.scenegraph.highPerformanceGetCell(endCol, endRow).globalAABBBounds;
14251
- tableInstance.showDropDownMenu(endCol, endRow, {
14252
- content: [
14253
- {
14254
- type: 'item',
14255
- text: '复制填充',
14256
- icon: {
14257
- width: 16,
14258
- height: 16,
14259
- svg: '<svg t="1756136702877" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1474" width="200" height="200"><path d="M853.333333 981.333333h-384c-72.533333 0-128-55.466667-128-128v-384c0-72.533333 55.466667-128 128-128h384c72.533333 0 128 55.466667 128 128v384c0 72.533333-55.466667 128-128 128z m-384-554.666666c-25.6 0-42.666667 17.066667-42.666666 42.666666v384c0 25.6 17.066667 42.666667 42.666666 42.666667h384c25.6 0 42.666667-17.066667 42.666667-42.666667v-384c0-25.6-17.066667-42.666667-42.666667-42.666666h-384z" p-id="1475"></path><path d="M213.333333 682.666667H170.666667c-72.533333 0-128-55.466667-128-128V170.666667c0-72.533333 55.466667-128 128-128h384c72.533333 0 128 55.466667 128 128v42.666666c0 25.6-17.066667 42.666667-42.666667 42.666667s-42.666667-17.066667-42.666667-42.666667V170.666667c0-25.6-17.066667-42.666667-42.666666-42.666667H170.666667c-25.6 0-42.666667 17.066667-42.666667 42.666667v384c0 25.6 17.066667 42.666667 42.666667 42.666666h42.666666c25.6 0 42.666667 17.066667 42.666667 42.666667s-17.066667 42.666667-42.666667 42.666667z" p-id="1476"></path></svg>'
14260
- }
14261
- },
14262
- {
14263
- type: 'item',
14264
- text: '序列填充',
14265
- icon: {
14266
- width: 16,
14267
- height: 16,
14268
- svg: '<svg t="1756136788547" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2463" width="200" height="200"><path d="M312.832482 65.167035H959.204489c35.706211 0 64.64232 29.473622 64.64232 65.832527 0 36.346107-28.936109 65.832527-64.629522 65.832527H312.819684c-35.693413 0-64.629522-29.473622-64.629522-65.832527 0-36.346107 28.936109-65.832527 64.629522-65.832527z m0 394.982363H959.204489c35.706211 0 64.64232 29.460824 64.64232 65.819729 0 36.358905-28.936109 65.832527-64.629522 65.832527H312.819684c-35.693413 0-64.629522-29.473622-64.629522-65.832527 0-36.346107 28.936109-65.819729 64.629522-65.819729z m0 394.969566H959.204489c35.706211 0 64.64232 29.473622 64.64232 65.819729 0 36.358905-28.936109 65.832527-64.629522 65.832527H312.819684c-35.693413 0-64.629522-29.473622-64.629522-65.832527 0-36.346107 28.936109-65.819729 64.629522-65.819729zM12.286008 69.108796V38.176211c9.892796 0.767876 19.836784 0.767876 29.72958 0A41.823619 41.823619 0 0 0 63.989626 25.672638c4.261709-4.671243 7.358807-10.315128 9.048133-16.458132 0.37114-3.058704 0.37114-6.143004 0-9.214506H114.413451v229.748352H65.93491V69.108796H12.286008z m0 510.176487a130.730805 130.730805 0 0 1 45.240665-49.374395 334.537763 334.537763 0 0 0 40.070304-32.250771 48.47854 48.47854 0 0 0 14.218495-33.581756 37.31875 37.31875 0 0 0-7.755543-24.354451 28.193829 28.193829 0 0 0-23.266628-9.879998 27.643518 27.643518 0 0 0-31.02217 15.139945 78.27211 78.27211 0 0 0-5.170362 28.30901H2.585181a114.311067 114.311067 0 0 1 10.340723-48.056208c12.388392-24.124089 38.086625-37.984242 64.629522-34.887144a79.897447 79.897447 0 0 1 57.539472 20.41269 71.783562 71.783562 0 0 1 21.321343 53.981648 74.637499 74.637499 0 0 1-14.858391 46.072531 152.16733 152.16733 0 0 1-32.967455 29.627197L90.481331 553.625443l-23.266628 17.763521c-4.082538 3.583419-7.563574 7.806734-10.353522 12.51637h99.542262v40.147092H0a110.945213 110.945213 0 0 1 10.340724-45.419837l1.945284 0.665492zM44.600769 948.582211a53.495327 53.495327 0 0 0 4.517668 23.036265 30.279891 30.279891 0 0 0 29.742378 17.110826c7.422797 0.255959 14.717614-2.073264 20.681447-6.578133 6.7829-6.962071 10.315128-16.547717 9.688029-26.325332a30.356678 30.356678 0 0 0-18.096266-30.945383 91.735527 91.735527 0 0 0-32.314761-8.561812V883.440772a83.903197 83.903197 0 0 0 30.382274-4.607253 27.106005 27.106005 0 0 0 14.858391-28.30901 30.612637 30.612637 0 0 0-7.755542-21.730877 27.528337 27.528337 0 0 0-21.321344-8.549014 26.939632 26.939632 0 0 0-23.279425 10.532692 44.063256 44.063256 0 0 0-7.102849 27.643519H2.585181a117.101015 117.101015 0 0 1 5.823056-32.916264 74.381541 74.381541 0 0 1 17.443572-25.019944 60.534186 60.534186 0 0 1 20.681447-12.503572 89.55988 89.55988 0 0 1 29.742378-3.289067A78.540867 78.540867 0 0 1 129.259044 801.79001a57.744238 57.744238 0 0 1 20.041551 46.085328 51.921182 51.921182 0 0 1-12.286008 34.887144c-4.159326 5.170362-9.470465 9.227304-15.511086 11.850879 6.7829 1.510155 12.900309 5.208756 17.45637 10.532692a57.821026 57.821026 0 0 1 17.443572 44.10165 75.136618 75.136618 0 0 1-20.028753 52.010768 76.122059 76.122059 0 0 1-59.471958 22.383571 71.962733 71.962733 0 0 1-64.629522-32.250771A97.52019 97.52019 0 0 1 1.279793 946.611331l43.308178 1.97088z" fill="#515151" p-id="2464"></path></svg>'
14269
- }
14270
- }
14271
- ],
14272
- referencePosition: {
14273
- rect: {
14274
- right: rect.x2 + 110,
14275
- bottom: rect.y2
14276
- }
14277
- }
14278
- });
14279
- }
14280
- function getCellMatrix(table) {
14281
- return {
14282
- getValue: (row, col) => {
14283
- const value = table.getCellValue(col, row);
14284
- if (typeof value === 'number' || !isNaN(Number(value))) {
14285
- return {
14286
- v: value,
14287
- t: CellValueType.NUMBER
14288
- };
14289
- }
14290
- return {
14291
- v: value || '',
14292
- t: CellValueType.STRING
14293
- };
14294
- },
14295
- getMaxRows: () => {
14296
- return table.records.length;
14297
- },
14298
- getMaxColumns: () => {
14299
- return table.columns.length;
14300
- }
14301
- };
14302
- }
14303
- function isMergeCell(table, col, row) {
14304
- const cellRange = table.getCellRange(col, row);
14305
- if (cellRange.start.col !== cellRange.end.col || cellRange.start.row !== cellRange.end.row) {
14306
- return cellRange;
14307
- }
14308
- return null;
14309
- }
14310
-
14311
14556
  class AutoFillManager {
14312
14557
  sourceData = [];
14313
14558
  autoFillService;
@@ -14317,9 +14562,11 @@ ${recordsStr}
14317
14562
  direction;
14318
14563
  headers;
14319
14564
  options;
14565
+ formulaAdapter;
14320
14566
  constructor(options) {
14321
14567
  this.options = options;
14322
14568
  this.autoFillService = new AutoFillService();
14569
+ this.formulaAdapter = new DefaultFormulaAdapter({});
14323
14570
  }
14324
14571
  setTable(table) {
14325
14572
  this.headers = {
@@ -14327,12 +14574,13 @@ ${recordsStr}
14327
14574
  col: new Set()
14328
14575
  };
14329
14576
  this.tableInstance = table;
14577
+ this.formulaAdapter = createFormulaAdapter(table, this.options?.isFormulaCell, this.options?.getCellFormula, this.options?.setCellFormula);
14330
14578
  table.on(VTable.TABLE_EVENT_TYPE.DROPDOWN_MENU_CLICK, (args) => {
14331
14579
  if (args.text === '复制填充') {
14332
- this.fillData(APPLY_TYPE.COPY);
14580
+ this.fillData(exports.APPLY_TYPE.COPY);
14333
14581
  }
14334
14582
  else if (args.text === '序列填充') {
14335
- this.fillData(APPLY_TYPE.SERIES);
14583
+ this.fillData(exports.APPLY_TYPE.SERIES);
14336
14584
  }
14337
14585
  });
14338
14586
  const rowHeaderCells = this.tableInstance.getAllRowHeaderCells()[0];
@@ -14370,7 +14618,7 @@ ${recordsStr}
14370
14618
  if (!this.sourceRange) {
14371
14619
  return;
14372
14620
  }
14373
- this.direction = Direction.DOWN;
14621
+ this.direction = exports.Direction.DOWN;
14374
14622
  const detectFillRange = getSelectedRangeArray(this._detectFillRange());
14375
14623
  this.targetRange = getTargetRange(this.direction, this.sourceRange, detectFillRange);
14376
14624
  this.targetRange.cols = this.targetRange.cols.filter(col => !this.headers.col.has(col));
@@ -14406,7 +14654,7 @@ ${recordsStr}
14406
14654
  getSourceData(source, direction) {
14407
14655
  const rules = this.autoFillService.getRules();
14408
14656
  const sourceData = [];
14409
- const isVertical = direction === Direction.DOWN || direction === Direction.UP;
14657
+ const isVertical = direction === exports.Direction.DOWN || direction === exports.Direction.UP;
14410
14658
  let aArray;
14411
14659
  let bArray;
14412
14660
  if (isVertical) {
@@ -14426,13 +14674,25 @@ ${recordsStr}
14426
14674
  };
14427
14675
  bArray.forEach(b => {
14428
14676
  let data;
14677
+ const col = isVertical ? a : b;
14678
+ const row = isVertical ? b : a;
14429
14679
  if (isVertical) {
14430
14680
  data = matrix.getValue(b, a);
14431
14681
  }
14432
14682
  else {
14433
14683
  data = matrix.getValue(a, b);
14434
14684
  }
14435
- const { type, isContinue } = rules.find(r => r.match(data, null)) || otherRule;
14685
+ if (data && this.formulaAdapter.isFormulaCell(col, row)) {
14686
+ const formula = this.formulaAdapter.getCellFormula(col, row);
14687
+ if (formula) {
14688
+ data = {
14689
+ ...data,
14690
+ v: formula
14691
+ };
14692
+ }
14693
+ }
14694
+ const ruleMatch = rules.find((r) => r.match(data, null)) || otherRule;
14695
+ const { type, isContinue } = ruleMatch;
14436
14696
  if (isContinue(prevData, data)) {
14437
14697
  const typeInfo = sourceDataPiece[type];
14438
14698
  const last = typeInfo[typeInfo.length - 1];
@@ -14513,14 +14773,14 @@ ${recordsStr}
14513
14773
  const { cols: sourceCols, rows: sourceRows } = source;
14514
14774
  const sourceData = this.sourceData;
14515
14775
  let csLen;
14516
- if (direction === Direction.DOWN || direction === Direction.UP) {
14776
+ if (direction === exports.Direction.DOWN || direction === exports.Direction.UP) {
14517
14777
  csLen = sourceRows.length;
14518
14778
  }
14519
14779
  else {
14520
14780
  csLen = sourceCols.length;
14521
14781
  }
14522
14782
  const applyDatas = [];
14523
- if (direction === Direction.DOWN || direction === Direction.UP) {
14783
+ if (direction === exports.Direction.DOWN || direction === exports.Direction.UP) {
14524
14784
  const asLen = targetRows.length;
14525
14785
  const untransformedApplyDatas = [];
14526
14786
  targetCols.forEach((_, i) => {
@@ -14549,6 +14809,7 @@ ${recordsStr}
14549
14809
  });
14550
14810
  }
14551
14811
  const values = [];
14812
+ const formulaUpdates = [];
14552
14813
  targetRows.forEach((row, rowIndex) => {
14553
14814
  const rowValues = [];
14554
14815
  targetCols.forEach((col, colIndex) => {
@@ -14557,7 +14818,19 @@ ${recordsStr}
14557
14818
  this.tableInstance.unmergeCells(range.start.col, range.start.row, range.end.col, range.end.row);
14558
14819
  }
14559
14820
  if (applyDatas[rowIndex][colIndex]) {
14560
- rowValues.push(applyDatas[rowIndex][colIndex]?.v + '');
14821
+ const cellData = applyDatas[rowIndex][colIndex];
14822
+ const cellValue = cellData?.v + '';
14823
+ if (cellData && typeof cellData.v === 'string' && cellData.v.startsWith('=')) {
14824
+ formulaUpdates.push({
14825
+ col,
14826
+ row,
14827
+ formula: cellData.v
14828
+ });
14829
+ rowValues.push(cellValue);
14830
+ }
14831
+ else {
14832
+ rowValues.push(cellValue);
14833
+ }
14561
14834
  }
14562
14835
  });
14563
14836
  values.push(rowValues);
@@ -14565,6 +14838,14 @@ ${recordsStr}
14565
14838
  const minRow = Math.min(...targetRows);
14566
14839
  const minCol = Math.min(...targetCols);
14567
14840
  this.tableInstance.changeCellValues(minCol, minRow, values);
14841
+ if (formulaUpdates.length > 0) {
14842
+ formulaUpdates.forEach(({ col, row, formula }) => {
14843
+ this.formulaAdapter.setCellFormula(col, row, formula);
14844
+ });
14845
+ if (this.formulaAdapter.hasFormulaEngine()) {
14846
+ this.formulaAdapter.refreshFormulas();
14847
+ }
14848
+ }
14568
14849
  }
14569
14850
  getApplyData(sourceDataPiece, csLen, asLen, direction, applyType, location) {
14570
14851
  const applyData = [];
@@ -14572,10 +14853,10 @@ ${recordsStr}
14572
14853
  const rsd = asLen % csLen;
14573
14854
  const rules = this.autoFillService.getRules();
14574
14855
  const applyDataInTypes = {};
14575
- rules.forEach(r => {
14856
+ rules.forEach((r) => {
14576
14857
  applyDataInTypes[r.type] = [];
14577
14858
  });
14578
- rules.forEach(r => {
14859
+ rules.forEach((r) => {
14579
14860
  const { type, applyFunctions: customApplyFunctions = {} } = r;
14580
14861
  const copyDataInType = sourceDataPiece[type];
14581
14862
  if (!copyDataInType) {
@@ -14590,7 +14871,7 @@ ${recordsStr}
14590
14871
  });
14591
14872
  });
14592
14873
  for (let x = 0; x < asLen; x++) {
14593
- rules.forEach(r => {
14874
+ rules.forEach((r) => {
14594
14875
  const { type } = r;
14595
14876
  const applyDataInType = applyDataInTypes[type];
14596
14877
  for (let y = 0; y < applyDataInType.length; y++) {
@@ -14604,23 +14885,23 @@ ${recordsStr}
14604
14885
  }
14605
14886
  applyFunctions(copySquad, len, direction, applyType, customApplyFunctions, sourceDataPiece, location) {
14606
14887
  const { data } = copySquad;
14607
- const isReverse = direction === Direction.UP || direction === Direction.LEFT;
14608
- if (applyType === APPLY_TYPE.COPY) {
14609
- const custom = customApplyFunctions?.[APPLY_TYPE.COPY];
14888
+ const isReverse = direction === exports.Direction.UP || direction === exports.Direction.LEFT;
14889
+ if (applyType === exports.APPLY_TYPE.COPY) {
14890
+ const custom = customApplyFunctions?.[exports.APPLY_TYPE.COPY];
14610
14891
  if (custom) {
14611
14892
  return custom(copySquad, len, direction, sourceDataPiece, location);
14612
14893
  }
14613
14894
  isReverse && data.reverse();
14614
14895
  return fillCopy(data, len);
14615
14896
  }
14616
- if (applyType === APPLY_TYPE.SERIES) {
14617
- const custom = customApplyFunctions?.[APPLY_TYPE.SERIES];
14897
+ if (applyType === exports.APPLY_TYPE.SERIES) {
14898
+ const custom = customApplyFunctions?.[exports.APPLY_TYPE.SERIES];
14618
14899
  if (custom) {
14619
14900
  return custom(copySquad, len, direction, sourceDataPiece);
14620
14901
  }
14621
14902
  isReverse && data.reverse();
14622
- if (customApplyFunctions?.[APPLY_TYPE.COPY]) {
14623
- return customApplyFunctions[APPLY_TYPE.COPY](copySquad, len, direction, sourceDataPiece, location);
14903
+ if (customApplyFunctions?.[exports.APPLY_TYPE.COPY]) {
14904
+ return customApplyFunctions[exports.APPLY_TYPE.COPY](copySquad, len, direction, sourceDataPiece, location);
14624
14905
  }
14625
14906
  return fillCopy(data, len);
14626
14907
  }
@@ -14643,7 +14924,7 @@ ${recordsStr}
14643
14924
  }
14644
14925
  run(...args) {
14645
14926
  if (args[1] === VTable.TABLE_EVENT_TYPE.MOUSEDOWN_FILL_HANDLE) {
14646
- const [_, __, table] = args;
14927
+ const [, , table] = args;
14647
14928
  this.table = table;
14648
14929
  this.autoFillManager.setTable(this.table);
14649
14930
  this.autoFillManager.handleStartDrag(this.table?.getSelectedCellRanges()[0]);
@@ -14664,11 +14945,13 @@ ${recordsStr}
14664
14945
  exports.ColumnSeriesPlugin = ColumnSeriesPlugin;
14665
14946
  exports.ConditionFilter = ConditionFilter;
14666
14947
  exports.ContextMenuPlugin = ContextMenuPlugin;
14948
+ exports.CustomFormulaAdapter = CustomFormulaAdapter;
14667
14949
  exports.DEFAULT_BODY_MENU_ITEMS = DEFAULT_BODY_MENU_ITEMS;
14668
14950
  exports.DEFAULT_COLUMN_SERIES_MENU_ITEMS = DEFAULT_COLUMN_SERIES_MENU_ITEMS;
14669
14951
  exports.DEFAULT_CORNER_SERIES_MENU_ITEMS = DEFAULT_CORNER_SERIES_MENU_ITEMS;
14670
14952
  exports.DEFAULT_HEADER_MENU_ITEMS = DEFAULT_HEADER_MENU_ITEMS;
14671
14953
  exports.DEFAULT_ROW_SERIES_MENU_ITEMS = DEFAULT_ROW_SERIES_MENU_ITEMS;
14954
+ exports.DefaultFormulaAdapter = DefaultFormulaAdapter;
14672
14955
  exports.ExcelEditCellKeyboardPlugin = ExcelEditCellKeyboardPlugin;
14673
14956
  exports.ExcelImportPlugin = ExcelImportPlugin;
14674
14957
  exports.ExportGanttPlugin = ExportGanttPlugin;
@@ -14698,9 +14981,21 @@ ${recordsStr}
14698
14981
  exports.WpsFillHandlePlugin = WpsFillHandlePlugin;
14699
14982
  exports.applyStyles = applyStyles$1;
14700
14983
  exports.cancelTransform = cancelTransform;
14984
+ exports.chnNumberRule = chnNumberRule;
14985
+ exports.chnWeek2Rule = chnWeek2Rule;
14986
+ exports.chnWeek3Rule = chnWeek3Rule;
14701
14987
  exports.createElement = createElement$1;
14988
+ exports.createFormulaAdapter = createFormulaAdapter;
14702
14989
  exports.createIcon = createIcon;
14703
14990
  exports.createNumberInputItem = createNumberInputItem;
14991
+ exports.dateRule = dateRule;
14992
+ exports.enhanceCellDataWithFormula = enhanceCellDataWithFormula;
14993
+ exports.extendNumberRule = extendNumberRule;
14994
+ exports.formulaRule = formulaRule;
14995
+ exports.loopSeriesRule = loopSeriesRule;
14996
+ exports.numberRule = numberRule;
14997
+ exports.otherRule = otherRule;
14998
+ exports.reverseIfNeed = reverseIfNeed;
14704
14999
  exports.rotate90WithTransform = rotate90WithTransform;
14705
15000
 
14706
15001
  }));