handsontable 0.0.0-next-9891faa-20240822 → 0.0.0-next-eaf150e-20240823

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of handsontable might be problematic. Click here for more details.

package/helpers/mixed.js CHANGED
@@ -134,7 +134,7 @@ const domMessages = {
134
134
  function _injectProductInfo(key, element) {
135
135
  const hasValidType = !isEmpty(key);
136
136
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
137
- const hotVersion = "0.0.0-next-9891faa-20240822";
137
+ const hotVersion = "0.0.0-next-eaf150e-20240823";
138
138
  let keyValidityDate;
139
139
  let consoleMessageState = 'invalid';
140
140
  let domMessageState = 'invalid';
package/helpers/mixed.mjs CHANGED
@@ -124,7 +124,7 @@ const domMessages = {
124
124
  export function _injectProductInfo(key, element) {
125
125
  const hasValidType = !isEmpty(key);
126
126
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
127
- const hotVersion = "0.0.0-next-9891faa-20240822";
127
+ const hotVersion = "0.0.0-next-eaf150e-20240823";
128
128
  let keyValidityDate;
129
129
  let consoleMessageState = 'invalid';
130
130
  let domMessageState = 'invalid';
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/handsontable/handsontable/issues"
11
11
  },
12
12
  "author": "Handsoncode <hello@handsontable.com>",
13
- "version": "0.0.0-next-9891faa-20240822",
13
+ "version": "0.0.0-next-eaf150e-20240823",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
package/pluginHooks.d.ts CHANGED
@@ -180,7 +180,7 @@ export interface Events {
180
180
  beforeDrawBorders?: (corners: number[], borderClassName: 'current' | 'area' | 'highlight' | undefined) => void;
181
181
  beforeDropdownMenuSetItems?: (menuItems: ContextMenuMenuItemConfig[]) => void;
182
182
  beforeDropdownMenuShow?: (instance: DropdownMenu) => void;
183
- beforeFilter?: (conditionsStack: FiltersColumnConditions[]) => void | boolean;
183
+ beforeFilter?: (conditionsStack: FiltersColumnConditions[], previousConditionsStack: FiltersColumnConditions[]) => void | boolean;
184
184
  beforeGetCellMeta?: (row: number, column: number, cellProperties: CellProperties) => void;
185
185
  beforeHideColumns?: (currentHideConfig: number[], destinationHideConfig: number[], actionPossible: boolean) => void | boolean;
186
186
  beforeHideRows?: (currentHideConfig: number[], destinationHideConfig: number[], actionPossible: boolean) => void | boolean;
package/pluginHooks.js CHANGED
@@ -2004,6 +2004,7 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
2004
2004
  *
2005
2005
  * @event Hooks#beforeFilter
2006
2006
  * @param {object[]} conditionsStack An array of objects with your [column filters](@/api/filters.md#addcondition).
2007
+ * @param {object[]|null} previousConditionsStack An array of objects with your previous [column filters](@/api/filters.md#addcondition). It can also be `null` if there was no previous filters applied or the conditions did not change between performing the `filter` action.
2007
2008
  * @returns {boolean} To perform server-side filtering (i.e., to not apply filtering to Handsontable's UI), return `false`.
2008
2009
  */
2009
2010
  'beforeFilter',
package/pluginHooks.mjs CHANGED
@@ -2000,6 +2000,7 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
2000
2000
  *
2001
2001
  * @event Hooks#beforeFilter
2002
2002
  * @param {object[]} conditionsStack An array of objects with your [column filters](@/api/filters.md#addcondition).
2003
+ * @param {object[]|null} previousConditionsStack An array of objects with your previous [column filters](@/api/filters.md#addcondition). It can also be `null` if there was no previous filters applied or the conditions did not change between performing the `filter` action.
2003
2004
  * @returns {boolean} To perform server-side filtering (i.e., to not apply filtering to Handsontable's UI), return `false`.
2004
2005
  */
2005
2006
  'beforeFilter',
@@ -45,6 +45,13 @@ class ConditionCollection {
45
45
  * @type {LinkedPhysicalIndexToValueMap}
46
46
  */
47
47
  _defineProperty(this, "filteringStates", new _translations.LinkedPhysicalIndexToValueMap());
48
+ /**
49
+ * Stores the previous state of the condition stack before the latest filter operation.
50
+ * This is used in the `beforeFilter` plugin to allow performing the undo operation.
51
+ *
52
+ * @type {null|Array}
53
+ */
54
+ _defineProperty(this, "previousConditionStack", null);
48
55
  this.hot = hot;
49
56
  this.isMapRegistrable = isMapRegistrable;
50
57
  if (this.isMapRegistrable === true) {
@@ -113,6 +120,13 @@ class ConditionCollection {
113
120
  const localeForColumn = this.hot.getCellMeta(0, column).locale;
114
121
  const args = (0, _array.arrayMap)(conditionDefinition.args, v => typeof v === 'string' ? v.toLocaleLowerCase(localeForColumn) : v);
115
122
  const name = conditionDefinition.name || conditionDefinition.command.key;
123
+
124
+ // If there's no previous condition stack defined (which means the condition stack was not cleared after the
125
+ // previous filter operation or that there was no filter operation performed yet), store the current conditions as
126
+ // the previous condition stack.
127
+ if (this.previousConditionStack === null) {
128
+ this.setPreviousConditionStack(this.exportAllConditions());
129
+ }
116
130
  this.runLocalHooks('beforeAdd', column);
117
131
  const columnType = this.getOperation(column);
118
132
  if (columnType) {
@@ -241,6 +255,8 @@ class ConditionCollection {
241
255
  * @fires ConditionCollection#afterRemove
242
256
  */
243
257
  removeConditions(column) {
258
+ // Store the current conditions as the previous condition stack before it's cleared.
259
+ this.setPreviousConditionStack(this.exportAllConditions());
244
260
  this.runLocalHooks('beforeRemove', column);
245
261
  this.filteringStates.clearValue(column);
246
262
  this.runLocalHooks('afterRemove', column);
@@ -274,6 +290,16 @@ class ConditionCollection {
274
290
  return conditions.length > 0;
275
291
  }
276
292
 
293
+ /**
294
+ * Updates the `previousConditionStack` property with the provided stack.
295
+ * It is used to store the current conditions before they are modified, allowing for undo operations.
296
+ *
297
+ * @param {Array|null} previousConditionStack The stack of previous conditions.
298
+ */
299
+ setPreviousConditionStack(previousConditionStack) {
300
+ this.previousConditionStack = previousConditionStack;
301
+ }
302
+
277
303
  /**
278
304
  * Destroy object.
279
305
  */
@@ -41,6 +41,13 @@ class ConditionCollection {
41
41
  * @type {LinkedPhysicalIndexToValueMap}
42
42
  */
43
43
  _defineProperty(this, "filteringStates", new IndexToValueMap());
44
+ /**
45
+ * Stores the previous state of the condition stack before the latest filter operation.
46
+ * This is used in the `beforeFilter` plugin to allow performing the undo operation.
47
+ *
48
+ * @type {null|Array}
49
+ */
50
+ _defineProperty(this, "previousConditionStack", null);
44
51
  this.hot = hot;
45
52
  this.isMapRegistrable = isMapRegistrable;
46
53
  if (this.isMapRegistrable === true) {
@@ -109,6 +116,13 @@ class ConditionCollection {
109
116
  const localeForColumn = this.hot.getCellMeta(0, column).locale;
110
117
  const args = arrayMap(conditionDefinition.args, v => typeof v === 'string' ? v.toLocaleLowerCase(localeForColumn) : v);
111
118
  const name = conditionDefinition.name || conditionDefinition.command.key;
119
+
120
+ // If there's no previous condition stack defined (which means the condition stack was not cleared after the
121
+ // previous filter operation or that there was no filter operation performed yet), store the current conditions as
122
+ // the previous condition stack.
123
+ if (this.previousConditionStack === null) {
124
+ this.setPreviousConditionStack(this.exportAllConditions());
125
+ }
112
126
  this.runLocalHooks('beforeAdd', column);
113
127
  const columnType = this.getOperation(column);
114
128
  if (columnType) {
@@ -237,6 +251,8 @@ class ConditionCollection {
237
251
  * @fires ConditionCollection#afterRemove
238
252
  */
239
253
  removeConditions(column) {
254
+ // Store the current conditions as the previous condition stack before it's cleared.
255
+ this.setPreviousConditionStack(this.exportAllConditions());
240
256
  this.runLocalHooks('beforeRemove', column);
241
257
  this.filteringStates.clearValue(column);
242
258
  this.runLocalHooks('afterRemove', column);
@@ -270,6 +286,16 @@ class ConditionCollection {
270
286
  return conditions.length > 0;
271
287
  }
272
288
 
289
+ /**
290
+ * Updates the `previousConditionStack` property with the provided stack.
291
+ * It is used to store the current conditions before they are modified, allowing for undo operations.
292
+ *
293
+ * @param {Array|null} previousConditionStack The stack of previous conditions.
294
+ */
295
+ setPreviousConditionStack(previousConditionStack) {
296
+ this.previousConditionStack = previousConditionStack;
297
+ }
298
+
273
299
  /**
274
300
  * Destroy object.
275
301
  */
@@ -483,7 +483,7 @@ class Filters extends _base.BasePlugin {
483
483
  const needToFilter = !this.conditionCollection.isEmpty();
484
484
  let visibleVisualRows = [];
485
485
  const conditions = this.conditionCollection.exportAllConditions();
486
- const allowFiltering = this.hot.runHooks('beforeFilter', conditions);
486
+ const allowFiltering = this.hot.runHooks('beforeFilter', conditions, this.conditionCollection.previousConditionStack);
487
487
  if (allowFiltering !== false) {
488
488
  if (needToFilter) {
489
489
  const trimmedRows = [];
@@ -508,6 +508,7 @@ class Filters extends _base.BasePlugin {
508
508
  }
509
509
  }
510
510
  this.hot.runHooks('afterFilter', conditions);
511
+ this.conditionCollection.setPreviousConditionStack(null);
511
512
  this.hot.view.adjustElementsSize();
512
513
  this.hot.render();
513
514
  if (this.hot.selection.isSelected()) {
@@ -477,7 +477,7 @@ export class Filters extends BasePlugin {
477
477
  const needToFilter = !this.conditionCollection.isEmpty();
478
478
  let visibleVisualRows = [];
479
479
  const conditions = this.conditionCollection.exportAllConditions();
480
- const allowFiltering = this.hot.runHooks('beforeFilter', conditions);
480
+ const allowFiltering = this.hot.runHooks('beforeFilter', conditions, this.conditionCollection.previousConditionStack);
481
481
  if (allowFiltering !== false) {
482
482
  if (needToFilter) {
483
483
  const trimmedRows = [];
@@ -502,6 +502,7 @@ export class Filters extends BasePlugin {
502
502
  }
503
503
  }
504
504
  this.hot.runHooks('afterFilter', conditions);
505
+ this.conditionCollection.setPreviousConditionStack(null);
505
506
  this.hot.view.adjustElementsSize();
506
507
  this.hot.render();
507
508
  if (this.hot.selection.isSelected()) {
@@ -124,8 +124,8 @@ function UndoRedo(instance) {
124
124
  instance.addHook('beforeCellAlignment', (stateBefore, range, type, alignment) => {
125
125
  plugin.done(() => new UndoRedo.CellAlignmentAction(stateBefore, range, type, alignment));
126
126
  });
127
- instance.addHook('beforeFilter', conditionsStack => {
128
- plugin.done(() => new UndoRedo.FiltersAction(conditionsStack));
127
+ instance.addHook('beforeFilter', (conditionsStack, previousConditionsStack) => {
128
+ plugin.done(() => new UndoRedo.FiltersAction(conditionsStack, previousConditionsStack));
129
129
  });
130
130
  instance.addHook('beforeRowMove', (rows, finalIndex) => {
131
131
  if (rows === false) {
@@ -645,9 +645,11 @@ UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback
645
645
  * Filters action.
646
646
  *
647
647
  * @private
648
- * @param {Array} conditionsStack An array of the filter condition.
648
+ * @param {Array} conditionsStack An array of the filter conditions.
649
+ * @param {Array} previousConditionsStack An array of the previous filter conditions.
649
650
  */
650
- UndoRedo.FiltersAction = function (conditionsStack) {
651
+ UndoRedo.FiltersAction = function (conditionsStack, previousConditionsStack) {
652
+ this.previousConditionsStack = previousConditionsStack;
651
653
  this.conditionsStack = conditionsStack;
652
654
  this.actionType = 'filter';
653
655
  };
@@ -655,7 +657,9 @@ UndoRedo.FiltersAction = function (conditionsStack) {
655
657
  UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) {
656
658
  const filters = instance.getPlugin('filters');
657
659
  instance.addHookOnce('afterViewRender', undoneCallback);
658
- filters.conditionCollection.importAllConditions(this.conditionsStack.slice(0, this.conditionsStack.length - 1));
660
+ if (this.previousConditionsStack) {
661
+ filters.conditionCollection.importAllConditions(this.previousConditionsStack);
662
+ }
659
663
  filters.filter();
660
664
  };
661
665
  UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) {
@@ -120,8 +120,8 @@ function UndoRedo(instance) {
120
120
  instance.addHook('beforeCellAlignment', (stateBefore, range, type, alignment) => {
121
121
  plugin.done(() => new UndoRedo.CellAlignmentAction(stateBefore, range, type, alignment));
122
122
  });
123
- instance.addHook('beforeFilter', conditionsStack => {
124
- plugin.done(() => new UndoRedo.FiltersAction(conditionsStack));
123
+ instance.addHook('beforeFilter', (conditionsStack, previousConditionsStack) => {
124
+ plugin.done(() => new UndoRedo.FiltersAction(conditionsStack, previousConditionsStack));
125
125
  });
126
126
  instance.addHook('beforeRowMove', (rows, finalIndex) => {
127
127
  if (rows === false) {
@@ -641,9 +641,11 @@ UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback
641
641
  * Filters action.
642
642
  *
643
643
  * @private
644
- * @param {Array} conditionsStack An array of the filter condition.
644
+ * @param {Array} conditionsStack An array of the filter conditions.
645
+ * @param {Array} previousConditionsStack An array of the previous filter conditions.
645
646
  */
646
- UndoRedo.FiltersAction = function (conditionsStack) {
647
+ UndoRedo.FiltersAction = function (conditionsStack, previousConditionsStack) {
648
+ this.previousConditionsStack = previousConditionsStack;
647
649
  this.conditionsStack = conditionsStack;
648
650
  this.actionType = 'filter';
649
651
  };
@@ -651,7 +653,9 @@ inherit(UndoRedo.FiltersAction, UndoRedo.Action);
651
653
  UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) {
652
654
  const filters = instance.getPlugin('filters');
653
655
  instance.addHookOnce('afterViewRender', undoneCallback);
654
- filters.conditionCollection.importAllConditions(this.conditionsStack.slice(0, this.conditionsStack.length - 1));
656
+ if (this.previousConditionsStack) {
657
+ filters.conditionCollection.importAllConditions(this.previousConditionsStack);
658
+ }
655
659
  filters.filter();
656
660
  };
657
661
  UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) {