@odoo/o-spreadsheet 17.2.26 → 17.2.28

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.
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * This file is generated by o-spreadsheet build tools. Do not edit it.
5
5
  * @see https://github.com/odoo/o-spreadsheet
6
- * @version 17.2.26
7
- * @date 2024-11-13T15:04:03.710Z
8
- * @hash 19b7478
6
+ * @version 17.2.28
7
+ * @date 2024-11-28T09:04:19.153Z
8
+ * @hash fb1cbd8
9
9
  */
10
10
 
11
11
  'use strict';
@@ -2933,7 +2933,9 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
2933
2933
  return reverseSearch ? numberOfValues - i - 1 : i;
2934
2934
  }
2935
2935
  }
2936
- return reverseSearch ? numberOfValues - closestMatchIndex - 1 : closestMatchIndex;
2936
+ return reverseSearch && closestMatchIndex !== -1
2937
+ ? numberOfValues - closestMatchIndex - 1
2938
+ : closestMatchIndex;
2937
2939
  }
2938
2940
  /**
2939
2941
  * Normalize a value.
@@ -47831,12 +47833,18 @@ class Evaluator {
47831
47833
  }
47832
47834
  for (let i = 0; i < positions.length; ++i) {
47833
47835
  const position = positions[i];
47836
+ if (this.nextPositionsToUpdate.has(position)) {
47837
+ continue;
47838
+ }
47834
47839
  const evaluatedCell = this.computeCell(position);
47835
47840
  if (evaluatedCell !== EMPTY_CELL) {
47836
47841
  this.evaluatedCells.set(position, evaluatedCell);
47837
47842
  }
47838
47843
  }
47839
47844
  }
47845
+ if (currentIteration >= MAX_ITERATION) {
47846
+ console.warn("Maximum iteration reached while evaluating cells");
47847
+ }
47840
47848
  }
47841
47849
  computeCell(position) {
47842
47850
  const evaluation = this.evaluatedCells.get(position);
@@ -47868,7 +47876,6 @@ class Evaluator {
47868
47876
  }
47869
47877
  finally {
47870
47878
  this.cellsBeingComputed.delete(cellId);
47871
- this.nextPositionsToUpdate.delete(position);
47872
47879
  }
47873
47880
  }
47874
47881
  computeAndSave(position) {
@@ -47918,6 +47925,7 @@ class Evaluator {
47918
47925
  { sheetId, zone: rightPartZone },
47919
47926
  { sheetId, zone: leftColumnZone },
47920
47927
  ]);
47928
+ invalidatedPositions.delete(arrayFormulaPosition);
47921
47929
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
47922
47930
  }
47923
47931
  assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
@@ -47981,6 +47989,7 @@ class Evaluator {
47981
47989
  }
47982
47990
  this.nextPositionsToUpdate.addMany(this.getCellsDependingOn(invalidated));
47983
47991
  this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedBy(invalidated));
47992
+ [...invalidated].forEach((inv) => this.spreadingRelations.removeNode(inv));
47984
47993
  this.spreadingRelations.removeNode(position);
47985
47994
  }
47986
47995
  // ----------------------------------------------------------
@@ -48962,25 +48971,11 @@ class EvaluationDataValidationPlugin extends UIPlugin {
48962
48971
  }
48963
48972
  switch (cmd.type) {
48964
48973
  case "ADD_DATA_VALIDATION_RULE":
48965
- const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
48966
- if (cmd.rule.criterion.type === "isBoolean") {
48967
- this.setContentToBooleanCells({ ...cmd.rule, ranges });
48968
- }
48969
- delete this.validationResults[cmd.sheetId];
48970
- break;
48971
48974
  case "REMOVE_DATA_VALIDATION_RULE":
48972
48975
  delete this.validationResults[cmd.sheetId];
48973
48976
  break;
48974
48977
  }
48975
48978
  }
48976
- setContentToBooleanCells(rule) {
48977
- for (const position of getCellPositionsInRanges(rule.ranges)) {
48978
- const evaluatedCell = this.getters.getEvaluatedCell(position);
48979
- if (evaluatedCell.type !== CellValueType.boolean) {
48980
- this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
48981
- }
48982
- }
48983
- }
48984
48979
  isDataValidationInvalid(cellPosition) {
48985
48980
  return !this.getValidationResultForCell(cellPosition).isValid;
48986
48981
  }
@@ -50452,7 +50447,7 @@ class Session extends EventBus {
50452
50447
  * Notify the server that the user client left the collaborative session
50453
50448
  */
50454
50449
  async leave(data) {
50455
- if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
50450
+ if (data && Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
50456
50451
  await this.snapshot(data());
50457
50452
  }
50458
50453
  delete this.clients[this.clientId];
@@ -51558,6 +51553,42 @@ class SheetUIPlugin extends UIPlugin {
51558
51553
  }
51559
51554
  }
51560
51555
 
51556
+ class DataValidationInsertionPlugin extends UIPlugin {
51557
+ handle(cmd) {
51558
+ switch (cmd.type) {
51559
+ case "ADD_DATA_VALIDATION_RULE":
51560
+ if (cmd.rule.criterion.type === "isBoolean") {
51561
+ const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
51562
+ for (const position of getCellPositionsInRanges(ranges)) {
51563
+ const cell = this.getters.getCell(position);
51564
+ const evaluatedCell = this.getters.getEvaluatedCell(position);
51565
+ if (!cell?.content) {
51566
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51567
+ // In this case, a cell has been updated in the core plugin but
51568
+ // not yet evaluated. This can occur after a paste operation.
51569
+ }
51570
+ else if (cell?.content && evaluatedCell.type === CellValueType.empty) {
51571
+ let value;
51572
+ if (cell.content.startsWith("=")) {
51573
+ const result = this.getters.evaluateFormula(position.sheetId, cell.content);
51574
+ value = (isMatrix(result) ? result[0][0] : result)?.toString();
51575
+ }
51576
+ else {
51577
+ value = cell.content;
51578
+ }
51579
+ if (!value || !isBoolean(value)) {
51580
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51581
+ }
51582
+ }
51583
+ else if (evaluatedCell.type !== CellValueType.boolean) {
51584
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51585
+ }
51586
+ }
51587
+ }
51588
+ }
51589
+ }
51590
+ }
51591
+
51561
51592
  const genericRepeatsTransforms = [
51562
51593
  repeatSheetDependantCommand,
51563
51594
  repeatTargetDependantCommand,
@@ -54791,7 +54822,8 @@ const featurePluginRegistry = new Registry()
54791
54822
  .add("collaborative", CollaborativePlugin)
54792
54823
  .add("history", HistoryPlugin)
54793
54824
  .add("data_cleanup", DataCleanupPlugin)
54794
- .add("table_autofill", TableAutofillPlugin);
54825
+ .add("table_autofill", TableAutofillPlugin)
54826
+ .add("datavalidation_insert", DataValidationInsertionPlugin);
54795
54827
  // Plugins which have a state, but which should not be shared in collaborative
54796
54828
  const statefulUIPluginRegistry = new Registry()
54797
54829
  .add("selection", GridSelectionPlugin)
@@ -60419,7 +60451,8 @@ class Model extends EventBus {
60419
60451
  this.session.join(this.config.client);
60420
60452
  }
60421
60453
  async leaveSession() {
60422
- await this.session.leave(lazy(() => this.exportData()));
60454
+ const snapshot = this.getters.isReadonly() ? undefined : lazy(() => this.exportData());
60455
+ await this.session.leave(snapshot);
60423
60456
  }
60424
60457
  setupUiPlugin(Plugin) {
60425
60458
  const plugin = new Plugin(this.uiPluginConfig);
@@ -60973,6 +61006,6 @@ exports.tokenColors = tokenColors;
60973
61006
  exports.tokenize = tokenize;
60974
61007
 
60975
61008
 
60976
- __info__.version = "17.2.26";
60977
- __info__.date = "2024-11-13T15:04:03.710Z";
60978
- __info__.hash = "19b7478";
61009
+ __info__.version = "17.2.28";
61010
+ __info__.date = "2024-11-28T09:04:19.153Z";
61011
+ __info__.hash = "fb1cbd8";
@@ -3451,7 +3451,7 @@ declare class Session extends EventBus<CollaborativeEvent> {
3451
3451
  /**
3452
3452
  * Notify the server that the user client left the collaborative session
3453
3453
  */
3454
- leave(data: Lazy<WorkbookData>): Promise<void>;
3454
+ leave(data?: Lazy<WorkbookData>): Promise<void>;
3455
3455
  /**
3456
3456
  * Send a snapshot of the spreadsheet to the collaboration server
3457
3457
  */
@@ -3703,7 +3703,6 @@ declare class EvaluationDataValidationPlugin extends UIPlugin {
3703
3703
  static getters: readonly ["getDataValidationInvalidCriterionValueMessage", "getInvalidDataValidationMessage", "getValidationResultForCellValue", "isCellValidCheckbox", "isDataValidationInvalid"];
3704
3704
  validationResults: Record<UID, SheetValidationResult>;
3705
3705
  handle(cmd: CoreViewCommand): void;
3706
- private setContentToBooleanCells;
3707
3706
  isDataValidationInvalid(cellPosition: CellPosition): boolean;
3708
3707
  getInvalidDataValidationMessage(cellPosition: CellPosition): string | undefined;
3709
3708
  /**
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * This file is generated by o-spreadsheet build tools. Do not edit it.
5
5
  * @see https://github.com/odoo/o-spreadsheet
6
- * @version 17.2.26
7
- * @date 2024-11-13T15:04:03.710Z
8
- * @hash 19b7478
6
+ * @version 17.2.28
7
+ * @date 2024-11-28T09:04:19.153Z
8
+ * @hash fb1cbd8
9
9
  */
10
10
 
11
11
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw } from '@odoo/owl';
@@ -2931,7 +2931,9 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
2931
2931
  return reverseSearch ? numberOfValues - i - 1 : i;
2932
2932
  }
2933
2933
  }
2934
- return reverseSearch ? numberOfValues - closestMatchIndex - 1 : closestMatchIndex;
2934
+ return reverseSearch && closestMatchIndex !== -1
2935
+ ? numberOfValues - closestMatchIndex - 1
2936
+ : closestMatchIndex;
2935
2937
  }
2936
2938
  /**
2937
2939
  * Normalize a value.
@@ -47829,12 +47831,18 @@ class Evaluator {
47829
47831
  }
47830
47832
  for (let i = 0; i < positions.length; ++i) {
47831
47833
  const position = positions[i];
47834
+ if (this.nextPositionsToUpdate.has(position)) {
47835
+ continue;
47836
+ }
47832
47837
  const evaluatedCell = this.computeCell(position);
47833
47838
  if (evaluatedCell !== EMPTY_CELL) {
47834
47839
  this.evaluatedCells.set(position, evaluatedCell);
47835
47840
  }
47836
47841
  }
47837
47842
  }
47843
+ if (currentIteration >= MAX_ITERATION) {
47844
+ console.warn("Maximum iteration reached while evaluating cells");
47845
+ }
47838
47846
  }
47839
47847
  computeCell(position) {
47840
47848
  const evaluation = this.evaluatedCells.get(position);
@@ -47866,7 +47874,6 @@ class Evaluator {
47866
47874
  }
47867
47875
  finally {
47868
47876
  this.cellsBeingComputed.delete(cellId);
47869
- this.nextPositionsToUpdate.delete(position);
47870
47877
  }
47871
47878
  }
47872
47879
  computeAndSave(position) {
@@ -47916,6 +47923,7 @@ class Evaluator {
47916
47923
  { sheetId, zone: rightPartZone },
47917
47924
  { sheetId, zone: leftColumnZone },
47918
47925
  ]);
47926
+ invalidatedPositions.delete(arrayFormulaPosition);
47919
47927
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
47920
47928
  }
47921
47929
  assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
@@ -47979,6 +47987,7 @@ class Evaluator {
47979
47987
  }
47980
47988
  this.nextPositionsToUpdate.addMany(this.getCellsDependingOn(invalidated));
47981
47989
  this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedBy(invalidated));
47990
+ [...invalidated].forEach((inv) => this.spreadingRelations.removeNode(inv));
47982
47991
  this.spreadingRelations.removeNode(position);
47983
47992
  }
47984
47993
  // ----------------------------------------------------------
@@ -48960,25 +48969,11 @@ class EvaluationDataValidationPlugin extends UIPlugin {
48960
48969
  }
48961
48970
  switch (cmd.type) {
48962
48971
  case "ADD_DATA_VALIDATION_RULE":
48963
- const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
48964
- if (cmd.rule.criterion.type === "isBoolean") {
48965
- this.setContentToBooleanCells({ ...cmd.rule, ranges });
48966
- }
48967
- delete this.validationResults[cmd.sheetId];
48968
- break;
48969
48972
  case "REMOVE_DATA_VALIDATION_RULE":
48970
48973
  delete this.validationResults[cmd.sheetId];
48971
48974
  break;
48972
48975
  }
48973
48976
  }
48974
- setContentToBooleanCells(rule) {
48975
- for (const position of getCellPositionsInRanges(rule.ranges)) {
48976
- const evaluatedCell = this.getters.getEvaluatedCell(position);
48977
- if (evaluatedCell.type !== CellValueType.boolean) {
48978
- this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
48979
- }
48980
- }
48981
- }
48982
48977
  isDataValidationInvalid(cellPosition) {
48983
48978
  return !this.getValidationResultForCell(cellPosition).isValid;
48984
48979
  }
@@ -50450,7 +50445,7 @@ class Session extends EventBus {
50450
50445
  * Notify the server that the user client left the collaborative session
50451
50446
  */
50452
50447
  async leave(data) {
50453
- if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
50448
+ if (data && Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
50454
50449
  await this.snapshot(data());
50455
50450
  }
50456
50451
  delete this.clients[this.clientId];
@@ -51556,6 +51551,42 @@ class SheetUIPlugin extends UIPlugin {
51556
51551
  }
51557
51552
  }
51558
51553
 
51554
+ class DataValidationInsertionPlugin extends UIPlugin {
51555
+ handle(cmd) {
51556
+ switch (cmd.type) {
51557
+ case "ADD_DATA_VALIDATION_RULE":
51558
+ if (cmd.rule.criterion.type === "isBoolean") {
51559
+ const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
51560
+ for (const position of getCellPositionsInRanges(ranges)) {
51561
+ const cell = this.getters.getCell(position);
51562
+ const evaluatedCell = this.getters.getEvaluatedCell(position);
51563
+ if (!cell?.content) {
51564
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51565
+ // In this case, a cell has been updated in the core plugin but
51566
+ // not yet evaluated. This can occur after a paste operation.
51567
+ }
51568
+ else if (cell?.content && evaluatedCell.type === CellValueType.empty) {
51569
+ let value;
51570
+ if (cell.content.startsWith("=")) {
51571
+ const result = this.getters.evaluateFormula(position.sheetId, cell.content);
51572
+ value = (isMatrix(result) ? result[0][0] : result)?.toString();
51573
+ }
51574
+ else {
51575
+ value = cell.content;
51576
+ }
51577
+ if (!value || !isBoolean(value)) {
51578
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51579
+ }
51580
+ }
51581
+ else if (evaluatedCell.type !== CellValueType.boolean) {
51582
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51583
+ }
51584
+ }
51585
+ }
51586
+ }
51587
+ }
51588
+ }
51589
+
51559
51590
  const genericRepeatsTransforms = [
51560
51591
  repeatSheetDependantCommand,
51561
51592
  repeatTargetDependantCommand,
@@ -54789,7 +54820,8 @@ const featurePluginRegistry = new Registry()
54789
54820
  .add("collaborative", CollaborativePlugin)
54790
54821
  .add("history", HistoryPlugin)
54791
54822
  .add("data_cleanup", DataCleanupPlugin)
54792
- .add("table_autofill", TableAutofillPlugin);
54823
+ .add("table_autofill", TableAutofillPlugin)
54824
+ .add("datavalidation_insert", DataValidationInsertionPlugin);
54793
54825
  // Plugins which have a state, but which should not be shared in collaborative
54794
54826
  const statefulUIPluginRegistry = new Registry()
54795
54827
  .add("selection", GridSelectionPlugin)
@@ -60417,7 +60449,8 @@ class Model extends EventBus {
60417
60449
  this.session.join(this.config.client);
60418
60450
  }
60419
60451
  async leaveSession() {
60420
- await this.session.leave(lazy(() => this.exportData()));
60452
+ const snapshot = this.getters.isReadonly() ? undefined : lazy(() => this.exportData());
60453
+ await this.session.leave(snapshot);
60421
60454
  }
60422
60455
  setupUiPlugin(Plugin) {
60423
60456
  const plugin = new Plugin(this.uiPluginConfig);
@@ -60930,6 +60963,6 @@ const constants = {
60930
60963
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
60931
60964
 
60932
60965
 
60933
- __info__.version = "17.2.26";
60934
- __info__.date = "2024-11-13T15:04:03.710Z";
60935
- __info__.hash = "19b7478";
60966
+ __info__.version = "17.2.28";
60967
+ __info__.date = "2024-11-28T09:04:19.153Z";
60968
+ __info__.hash = "fb1cbd8";
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * This file is generated by o-spreadsheet build tools. Do not edit it.
5
5
  * @see https://github.com/odoo/o-spreadsheet
6
- * @version 17.2.26
7
- * @date 2024-11-13T15:04:03.710Z
8
- * @hash 19b7478
6
+ * @version 17.2.28
7
+ * @date 2024-11-28T09:04:19.153Z
8
+ * @hash fb1cbd8
9
9
  */
10
10
 
11
11
  (function (exports, owl) {
@@ -2932,7 +2932,9 @@
2932
2932
  return reverseSearch ? numberOfValues - i - 1 : i;
2933
2933
  }
2934
2934
  }
2935
- return reverseSearch ? numberOfValues - closestMatchIndex - 1 : closestMatchIndex;
2935
+ return reverseSearch && closestMatchIndex !== -1
2936
+ ? numberOfValues - closestMatchIndex - 1
2937
+ : closestMatchIndex;
2936
2938
  }
2937
2939
  /**
2938
2940
  * Normalize a value.
@@ -47830,12 +47832,18 @@ stores.inject(MyMetaStore, storeInstance);
47830
47832
  }
47831
47833
  for (let i = 0; i < positions.length; ++i) {
47832
47834
  const position = positions[i];
47835
+ if (this.nextPositionsToUpdate.has(position)) {
47836
+ continue;
47837
+ }
47833
47838
  const evaluatedCell = this.computeCell(position);
47834
47839
  if (evaluatedCell !== EMPTY_CELL) {
47835
47840
  this.evaluatedCells.set(position, evaluatedCell);
47836
47841
  }
47837
47842
  }
47838
47843
  }
47844
+ if (currentIteration >= MAX_ITERATION) {
47845
+ console.warn("Maximum iteration reached while evaluating cells");
47846
+ }
47839
47847
  }
47840
47848
  computeCell(position) {
47841
47849
  const evaluation = this.evaluatedCells.get(position);
@@ -47867,7 +47875,6 @@ stores.inject(MyMetaStore, storeInstance);
47867
47875
  }
47868
47876
  finally {
47869
47877
  this.cellsBeingComputed.delete(cellId);
47870
- this.nextPositionsToUpdate.delete(position);
47871
47878
  }
47872
47879
  }
47873
47880
  computeAndSave(position) {
@@ -47917,6 +47924,7 @@ stores.inject(MyMetaStore, storeInstance);
47917
47924
  { sheetId, zone: rightPartZone },
47918
47925
  { sheetId, zone: leftColumnZone },
47919
47926
  ]);
47927
+ invalidatedPositions.delete(arrayFormulaPosition);
47920
47928
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
47921
47929
  }
47922
47930
  assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
@@ -47980,6 +47988,7 @@ stores.inject(MyMetaStore, storeInstance);
47980
47988
  }
47981
47989
  this.nextPositionsToUpdate.addMany(this.getCellsDependingOn(invalidated));
47982
47990
  this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedBy(invalidated));
47991
+ [...invalidated].forEach((inv) => this.spreadingRelations.removeNode(inv));
47983
47992
  this.spreadingRelations.removeNode(position);
47984
47993
  }
47985
47994
  // ----------------------------------------------------------
@@ -48961,25 +48970,11 @@ stores.inject(MyMetaStore, storeInstance);
48961
48970
  }
48962
48971
  switch (cmd.type) {
48963
48972
  case "ADD_DATA_VALIDATION_RULE":
48964
- const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
48965
- if (cmd.rule.criterion.type === "isBoolean") {
48966
- this.setContentToBooleanCells({ ...cmd.rule, ranges });
48967
- }
48968
- delete this.validationResults[cmd.sheetId];
48969
- break;
48970
48973
  case "REMOVE_DATA_VALIDATION_RULE":
48971
48974
  delete this.validationResults[cmd.sheetId];
48972
48975
  break;
48973
48976
  }
48974
48977
  }
48975
- setContentToBooleanCells(rule) {
48976
- for (const position of getCellPositionsInRanges(rule.ranges)) {
48977
- const evaluatedCell = this.getters.getEvaluatedCell(position);
48978
- if (evaluatedCell.type !== CellValueType.boolean) {
48979
- this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
48980
- }
48981
- }
48982
- }
48983
48978
  isDataValidationInvalid(cellPosition) {
48984
48979
  return !this.getValidationResultForCell(cellPosition).isValid;
48985
48980
  }
@@ -50451,7 +50446,7 @@ stores.inject(MyMetaStore, storeInstance);
50451
50446
  * Notify the server that the user client left the collaborative session
50452
50447
  */
50453
50448
  async leave(data) {
50454
- if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
50449
+ if (data && Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
50455
50450
  await this.snapshot(data());
50456
50451
  }
50457
50452
  delete this.clients[this.clientId];
@@ -51557,6 +51552,42 @@ stores.inject(MyMetaStore, storeInstance);
51557
51552
  }
51558
51553
  }
51559
51554
 
51555
+ class DataValidationInsertionPlugin extends UIPlugin {
51556
+ handle(cmd) {
51557
+ switch (cmd.type) {
51558
+ case "ADD_DATA_VALIDATION_RULE":
51559
+ if (cmd.rule.criterion.type === "isBoolean") {
51560
+ const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
51561
+ for (const position of getCellPositionsInRanges(ranges)) {
51562
+ const cell = this.getters.getCell(position);
51563
+ const evaluatedCell = this.getters.getEvaluatedCell(position);
51564
+ if (!cell?.content) {
51565
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51566
+ // In this case, a cell has been updated in the core plugin but
51567
+ // not yet evaluated. This can occur after a paste operation.
51568
+ }
51569
+ else if (cell?.content && evaluatedCell.type === CellValueType.empty) {
51570
+ let value;
51571
+ if (cell.content.startsWith("=")) {
51572
+ const result = this.getters.evaluateFormula(position.sheetId, cell.content);
51573
+ value = (isMatrix(result) ? result[0][0] : result)?.toString();
51574
+ }
51575
+ else {
51576
+ value = cell.content;
51577
+ }
51578
+ if (!value || !isBoolean(value)) {
51579
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51580
+ }
51581
+ }
51582
+ else if (evaluatedCell.type !== CellValueType.boolean) {
51583
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
51584
+ }
51585
+ }
51586
+ }
51587
+ }
51588
+ }
51589
+ }
51590
+
51560
51591
  const genericRepeatsTransforms = [
51561
51592
  repeatSheetDependantCommand,
51562
51593
  repeatTargetDependantCommand,
@@ -54790,7 +54821,8 @@ stores.inject(MyMetaStore, storeInstance);
54790
54821
  .add("collaborative", CollaborativePlugin)
54791
54822
  .add("history", HistoryPlugin)
54792
54823
  .add("data_cleanup", DataCleanupPlugin)
54793
- .add("table_autofill", TableAutofillPlugin);
54824
+ .add("table_autofill", TableAutofillPlugin)
54825
+ .add("datavalidation_insert", DataValidationInsertionPlugin);
54794
54826
  // Plugins which have a state, but which should not be shared in collaborative
54795
54827
  const statefulUIPluginRegistry = new Registry()
54796
54828
  .add("selection", GridSelectionPlugin)
@@ -60418,7 +60450,8 @@ stores.inject(MyMetaStore, storeInstance);
60418
60450
  this.session.join(this.config.client);
60419
60451
  }
60420
60452
  async leaveSession() {
60421
- await this.session.leave(lazy(() => this.exportData()));
60453
+ const snapshot = this.getters.isReadonly() ? undefined : lazy(() => this.exportData());
60454
+ await this.session.leave(snapshot);
60422
60455
  }
60423
60456
  setupUiPlugin(Plugin) {
60424
60457
  const plugin = new Plugin(this.uiPluginConfig);
@@ -60972,9 +61005,9 @@ stores.inject(MyMetaStore, storeInstance);
60972
61005
  exports.tokenize = tokenize;
60973
61006
 
60974
61007
 
60975
- __info__.version = "17.2.26";
60976
- __info__.date = "2024-11-13T15:04:03.710Z";
60977
- __info__.hash = "19b7478";
61008
+ __info__.version = "17.2.28";
61009
+ __info__.date = "2024-11-28T09:04:19.153Z";
61010
+ __info__.hash = "fb1cbd8";
60978
61011
 
60979
61012
 
60980
61013
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);