@odoo/o-spreadsheet 17.4.11 → 17.4.13

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.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.4.11
6
- * @date 2024-11-08T12:15:26.239Z
7
- * @hash 2eb3f1c
5
+ * @version 17.4.13
6
+ * @date 2024-11-22T14:17:01.675Z
7
+ * @hash a5e4e16
8
8
  */
9
9
 
10
10
  'use strict';
@@ -3136,7 +3136,9 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
3136
3136
  return reverseSearch ? numberOfValues - i - 1 : i;
3137
3137
  }
3138
3138
  }
3139
- return reverseSearch ? numberOfValues - closestMatchIndex - 1 : closestMatchIndex;
3139
+ return reverseSearch && closestMatchIndex !== -1
3140
+ ? numberOfValues - closestMatchIndex - 1
3141
+ : closestMatchIndex;
3140
3142
  }
3141
3143
  /**
3142
3144
  * Normalize a value.
@@ -23489,11 +23491,14 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
23489
23491
  function getChartLabelFormat(getters, range) {
23490
23492
  if (!range)
23491
23493
  return undefined;
23492
- return getters.getEvaluatedCell({
23493
- sheetId: range.sheetId,
23494
- col: range.zone.left,
23495
- row: range.zone.top,
23496
- }).format;
23494
+ const { sheetId, zone: { left, top, bottom }, } = range;
23495
+ for (let row = top; row <= bottom; row++) {
23496
+ const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
23497
+ if (format) {
23498
+ return format;
23499
+ }
23500
+ }
23501
+ return undefined;
23497
23502
  }
23498
23503
  function getChartLabelValues(getters, dataSets, labelRange) {
23499
23504
  let labels = { values: [], formattedValues: [] };
@@ -24032,11 +24037,7 @@ function canBeDateChart(labelRange, getters) {
24032
24037
  if (!labelRange || !canBeLinearChart(labelRange, getters)) {
24033
24038
  return false;
24034
24039
  }
24035
- const labelFormat = getters.getEvaluatedCell({
24036
- sheetId: labelRange.sheetId,
24037
- col: labelRange.zone.left,
24038
- row: labelRange.zone.top,
24039
- }).format;
24040
+ const labelFormat = getChartLabelFormat(getters, labelRange);
24040
24041
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
24041
24042
  }
24042
24043
  function canBeLinearChart(labelRange, getters) {
@@ -32069,6 +32070,7 @@ class ColorPicker extends owl.Component {
32069
32070
  currentColor: { type: String, optional: true },
32070
32071
  maxHeight: { type: Number, optional: true },
32071
32072
  anchorRect: Object,
32073
+ disableNoColor: { type: Boolean, optional: true },
32072
32074
  };
32073
32075
  static defaultProps = { currentColor: "" };
32074
32076
  static components = { Popover };
@@ -32294,6 +32296,7 @@ class RoundColorPicker extends owl.Component {
32294
32296
  currentColor: { type: String, optional: true },
32295
32297
  title: { type: String, optional: true },
32296
32298
  onColorPicked: Function,
32299
+ disableNoColor: { type: Boolean, optional: true },
32297
32300
  };
32298
32301
  colorPickerButtonRef = owl.useRef("colorPickerButton");
32299
32302
  state;
@@ -34355,6 +34358,9 @@ class ConditionalFormattingEditor extends owl.Component {
34355
34358
  }
34356
34359
  }
34357
34360
  setColorScaleColor(target, color) {
34361
+ if (!isColorValid(color)) {
34362
+ return;
34363
+ }
34358
34364
  const point = this.state.rules.colorScale[target];
34359
34365
  if (point) {
34360
34366
  point.color = Number.parseInt(color.substr(1), 16);
@@ -54277,6 +54283,9 @@ class Evaluator {
54277
54283
  }
54278
54284
  for (let i = 0; i < positions.length; ++i) {
54279
54285
  const position = positions[i];
54286
+ if (this.nextPositionsToUpdate.has(position)) {
54287
+ continue;
54288
+ }
54280
54289
  const evaluatedCell = this.computeCell(position);
54281
54290
  if (evaluatedCell !== EMPTY_CELL) {
54282
54291
  this.evaluatedCells.set(position, evaluatedCell);
@@ -54284,6 +54293,9 @@ class Evaluator {
54284
54293
  }
54285
54294
  onIterationEndEvaluationRegistry.getAll().forEach((callback) => callback(this.getters));
54286
54295
  }
54296
+ if (currentIteration >= MAX_ITERATION) {
54297
+ console.warn("Maximum iteration reached while evaluating cells");
54298
+ }
54287
54299
  }
54288
54300
  computeCell(position) {
54289
54301
  const evaluation = this.evaluatedCells.get(position);
@@ -54318,7 +54330,6 @@ class Evaluator {
54318
54330
  }
54319
54331
  finally {
54320
54332
  this.cellsBeingComputed.delete(cellId);
54321
- this.nextPositionsToUpdate.delete(position);
54322
54333
  }
54323
54334
  }
54324
54335
  computeAndSave(position) {
@@ -54369,6 +54380,7 @@ class Evaluator {
54369
54380
  { sheetId, zone: rightPartZone },
54370
54381
  { sheetId, zone: leftColumnZone },
54371
54382
  ]);
54383
+ invalidatedPositions.delete(arrayFormulaPosition);
54372
54384
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
54373
54385
  }
54374
54386
  assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
@@ -55427,25 +55439,11 @@ class EvaluationDataValidationPlugin extends UIPlugin {
55427
55439
  }
55428
55440
  switch (cmd.type) {
55429
55441
  case "ADD_DATA_VALIDATION_RULE":
55430
- const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
55431
- if (cmd.rule.criterion.type === "isBoolean") {
55432
- this.setContentToBooleanCells({ ...cmd.rule, ranges });
55433
- }
55434
- delete this.validationResults[cmd.sheetId];
55435
- break;
55436
55442
  case "REMOVE_DATA_VALIDATION_RULE":
55437
55443
  delete this.validationResults[cmd.sheetId];
55438
55444
  break;
55439
55445
  }
55440
55446
  }
55441
- setContentToBooleanCells(rule) {
55442
- for (const position of getCellPositionsInRanges(rule.ranges)) {
55443
- const evaluatedCell = this.getters.getEvaluatedCell(position);
55444
- if (evaluatedCell.type !== CellValueType.boolean) {
55445
- this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
55446
- }
55447
- }
55448
- }
55449
55447
  isDataValidationInvalid(cellPosition) {
55450
55448
  return !this.getValidationResultForCell(cellPosition).isValid;
55451
55449
  }
@@ -57377,7 +57375,7 @@ class Session extends EventBus {
57377
57375
  * Notify the server that the user client left the collaborative session
57378
57376
  */
57379
57377
  async leave(data) {
57380
- if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
57378
+ if (data && Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
57381
57379
  await this.snapshot(data());
57382
57380
  }
57383
57381
  delete this.clients[this.clientId];
@@ -58848,6 +58846,42 @@ class CellComputedStylePlugin extends UIPlugin {
58848
58846
  }
58849
58847
  }
58850
58848
 
58849
+ class DataValidationInsertionPlugin extends UIPlugin {
58850
+ handle(cmd) {
58851
+ switch (cmd.type) {
58852
+ case "ADD_DATA_VALIDATION_RULE":
58853
+ if (cmd.rule.criterion.type === "isBoolean") {
58854
+ const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
58855
+ for (const position of getCellPositionsInRanges(ranges)) {
58856
+ const cell = this.getters.getCell(position);
58857
+ const evaluatedCell = this.getters.getEvaluatedCell(position);
58858
+ if (!cell?.content) {
58859
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
58860
+ // In this case, a cell has been updated in the core plugin but
58861
+ // not yet evaluated. This can occur after a paste operation.
58862
+ }
58863
+ else if (cell?.content && evaluatedCell.type === CellValueType.empty) {
58864
+ let value;
58865
+ if (cell.content.startsWith("=")) {
58866
+ const result = this.getters.evaluateFormula(position.sheetId, cell.content);
58867
+ value = (isMatrix(result) ? result[0][0] : result)?.toString();
58868
+ }
58869
+ else {
58870
+ value = cell.content;
58871
+ }
58872
+ if (!value || !isBoolean(value)) {
58873
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
58874
+ }
58875
+ }
58876
+ else if (evaluatedCell.type !== CellValueType.boolean) {
58877
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
58878
+ }
58879
+ }
58880
+ }
58881
+ }
58882
+ }
58883
+ }
58884
+
58851
58885
  const genericRepeatsTransforms = [
58852
58886
  repeatSheetDependantCommand,
58853
58887
  repeatTargetDependantCommand,
@@ -61913,7 +61947,8 @@ const featurePluginRegistry = new Registry()
61913
61947
  .add("history", HistoryPlugin)
61914
61948
  .add("data_cleanup", DataCleanupPlugin)
61915
61949
  .add("table_autofill", TableAutofillPlugin)
61916
- .add("table_ui_resize", TableResizeUI);
61950
+ .add("table_ui_resize", TableResizeUI)
61951
+ .add("datavalidation_insert", DataValidationInsertionPlugin);
61917
61952
  // Plugins which have a state, but which should not be shared in collaborative
61918
61953
  const statefulUIPluginRegistry = new Registry()
61919
61954
  .add("selection", GridSelectionPlugin)
@@ -68075,7 +68110,8 @@ class Model extends EventBus {
68075
68110
  this.session.join(this.config.client);
68076
68111
  }
68077
68112
  async leaveSession() {
68078
- await this.session.leave(lazy(() => this.exportData()));
68113
+ const snapshot = this.getters.isReadonly() ? undefined : lazy(() => this.exportData());
68114
+ await this.session.leave(snapshot);
68079
68115
  }
68080
68116
  setupUiPlugin(Plugin) {
68081
68117
  const plugin = new Plugin(this.uiPluginConfig);
@@ -68678,6 +68714,6 @@ exports.tokenColors = tokenColors;
68678
68714
  exports.tokenize = tokenize;
68679
68715
 
68680
68716
 
68681
- __info__.version = "17.4.11";
68682
- __info__.date = "2024-11-08T12:15:26.239Z";
68683
- __info__.hash = "2eb3f1c";
68717
+ __info__.version = "17.4.13";
68718
+ __info__.date = "2024-11-22T14:17:01.675Z";
68719
+ __info__.hash = "a5e4e16";
@@ -3868,7 +3868,7 @@ declare class Session extends EventBus<CollaborativeEvent> {
3868
3868
  /**
3869
3869
  * Notify the server that the user client left the collaborative session
3870
3870
  */
3871
- leave(data: Lazy<WorkbookData>): Promise<void>;
3871
+ leave(data?: Lazy<WorkbookData>): Promise<void>;
3872
3872
  /**
3873
3873
  * Send a snapshot of the spreadsheet to the collaboration server
3874
3874
  */
@@ -4128,7 +4128,6 @@ declare class EvaluationDataValidationPlugin extends UIPlugin {
4128
4128
  static getters: readonly ["getDataValidationInvalidCriterionValueMessage", "getInvalidDataValidationMessage", "getValidationResultForCellValue", "isCellValidCheckbox", "isDataValidationInvalid"];
4129
4129
  validationResults: Record<UID, SheetValidationResult>;
4130
4130
  handle(cmd: CoreViewCommand): void;
4131
- private setContentToBooleanCells;
4132
4131
  isDataValidationInvalid(cellPosition: CellPosition): boolean;
4133
4132
  getInvalidDataValidationMessage(cellPosition: CellPosition): string | undefined;
4134
4133
  /**
@@ -6887,6 +6886,7 @@ interface ColorPickerProps {
6887
6886
  maxHeight?: Pixel;
6888
6887
  onColorPicked: (color: Color) => void;
6889
6888
  currentColor: Color;
6889
+ disableNoColor?: boolean;
6890
6890
  }
6891
6891
  declare class ColorPicker extends Component<ColorPickerProps, SpreadsheetChildEnv> {
6892
6892
  static template: string;
@@ -6901,6 +6901,10 @@ declare class ColorPicker extends Component<ColorPickerProps, SpreadsheetChildEn
6901
6901
  optional: boolean;
6902
6902
  };
6903
6903
  anchorRect: ObjectConstructor;
6904
+ disableNoColor: {
6905
+ type: BooleanConstructor;
6906
+ optional: boolean;
6907
+ };
6904
6908
  };
6905
6909
  static defaultProps: {
6906
6910
  currentColor: string;
@@ -6984,6 +6988,7 @@ interface Props$U {
6984
6988
  currentColor?: string;
6985
6989
  onColorPicked: (color: string) => void;
6986
6990
  title?: string;
6991
+ disableNoColor?: boolean;
6987
6992
  }
6988
6993
  declare class RoundColorPicker extends Component<Props$U, SpreadsheetChildEnv> {
6989
6994
  static template: string;
@@ -7002,6 +7007,10 @@ declare class RoundColorPicker extends Component<Props$U, SpreadsheetChildEnv> {
7002
7007
  optional: boolean;
7003
7008
  };
7004
7009
  onColorPicked: FunctionConstructor;
7010
+ disableNoColor: {
7011
+ type: BooleanConstructor;
7012
+ optional: boolean;
7013
+ };
7005
7014
  };
7006
7015
  colorPickerButtonRef: {
7007
7016
  el: HTMLElement | null;
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.4.11
6
- * @date 2024-11-08T12:15:26.239Z
7
- * @hash 2eb3f1c
5
+ * @version 17.4.13
6
+ * @date 2024-11-22T14:17:01.675Z
7
+ * @hash a5e4e16
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -3134,7 +3134,9 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
3134
3134
  return reverseSearch ? numberOfValues - i - 1 : i;
3135
3135
  }
3136
3136
  }
3137
- return reverseSearch ? numberOfValues - closestMatchIndex - 1 : closestMatchIndex;
3137
+ return reverseSearch && closestMatchIndex !== -1
3138
+ ? numberOfValues - closestMatchIndex - 1
3139
+ : closestMatchIndex;
3138
3140
  }
3139
3141
  /**
3140
3142
  * Normalize a value.
@@ -23487,11 +23489,14 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
23487
23489
  function getChartLabelFormat(getters, range) {
23488
23490
  if (!range)
23489
23491
  return undefined;
23490
- return getters.getEvaluatedCell({
23491
- sheetId: range.sheetId,
23492
- col: range.zone.left,
23493
- row: range.zone.top,
23494
- }).format;
23492
+ const { sheetId, zone: { left, top, bottom }, } = range;
23493
+ for (let row = top; row <= bottom; row++) {
23494
+ const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
23495
+ if (format) {
23496
+ return format;
23497
+ }
23498
+ }
23499
+ return undefined;
23495
23500
  }
23496
23501
  function getChartLabelValues(getters, dataSets, labelRange) {
23497
23502
  let labels = { values: [], formattedValues: [] };
@@ -24030,11 +24035,7 @@ function canBeDateChart(labelRange, getters) {
24030
24035
  if (!labelRange || !canBeLinearChart(labelRange, getters)) {
24031
24036
  return false;
24032
24037
  }
24033
- const labelFormat = getters.getEvaluatedCell({
24034
- sheetId: labelRange.sheetId,
24035
- col: labelRange.zone.left,
24036
- row: labelRange.zone.top,
24037
- }).format;
24038
+ const labelFormat = getChartLabelFormat(getters, labelRange);
24038
24039
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
24039
24040
  }
24040
24041
  function canBeLinearChart(labelRange, getters) {
@@ -32067,6 +32068,7 @@ class ColorPicker extends Component {
32067
32068
  currentColor: { type: String, optional: true },
32068
32069
  maxHeight: { type: Number, optional: true },
32069
32070
  anchorRect: Object,
32071
+ disableNoColor: { type: Boolean, optional: true },
32070
32072
  };
32071
32073
  static defaultProps = { currentColor: "" };
32072
32074
  static components = { Popover };
@@ -32292,6 +32294,7 @@ class RoundColorPicker extends Component {
32292
32294
  currentColor: { type: String, optional: true },
32293
32295
  title: { type: String, optional: true },
32294
32296
  onColorPicked: Function,
32297
+ disableNoColor: { type: Boolean, optional: true },
32295
32298
  };
32296
32299
  colorPickerButtonRef = useRef("colorPickerButton");
32297
32300
  state;
@@ -34353,6 +34356,9 @@ class ConditionalFormattingEditor extends Component {
34353
34356
  }
34354
34357
  }
34355
34358
  setColorScaleColor(target, color) {
34359
+ if (!isColorValid(color)) {
34360
+ return;
34361
+ }
34356
34362
  const point = this.state.rules.colorScale[target];
34357
34363
  if (point) {
34358
34364
  point.color = Number.parseInt(color.substr(1), 16);
@@ -54275,6 +54281,9 @@ class Evaluator {
54275
54281
  }
54276
54282
  for (let i = 0; i < positions.length; ++i) {
54277
54283
  const position = positions[i];
54284
+ if (this.nextPositionsToUpdate.has(position)) {
54285
+ continue;
54286
+ }
54278
54287
  const evaluatedCell = this.computeCell(position);
54279
54288
  if (evaluatedCell !== EMPTY_CELL) {
54280
54289
  this.evaluatedCells.set(position, evaluatedCell);
@@ -54282,6 +54291,9 @@ class Evaluator {
54282
54291
  }
54283
54292
  onIterationEndEvaluationRegistry.getAll().forEach((callback) => callback(this.getters));
54284
54293
  }
54294
+ if (currentIteration >= MAX_ITERATION) {
54295
+ console.warn("Maximum iteration reached while evaluating cells");
54296
+ }
54285
54297
  }
54286
54298
  computeCell(position) {
54287
54299
  const evaluation = this.evaluatedCells.get(position);
@@ -54316,7 +54328,6 @@ class Evaluator {
54316
54328
  }
54317
54329
  finally {
54318
54330
  this.cellsBeingComputed.delete(cellId);
54319
- this.nextPositionsToUpdate.delete(position);
54320
54331
  }
54321
54332
  }
54322
54333
  computeAndSave(position) {
@@ -54367,6 +54378,7 @@ class Evaluator {
54367
54378
  { sheetId, zone: rightPartZone },
54368
54379
  { sheetId, zone: leftColumnZone },
54369
54380
  ]);
54381
+ invalidatedPositions.delete(arrayFormulaPosition);
54370
54382
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
54371
54383
  }
54372
54384
  assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
@@ -55425,25 +55437,11 @@ class EvaluationDataValidationPlugin extends UIPlugin {
55425
55437
  }
55426
55438
  switch (cmd.type) {
55427
55439
  case "ADD_DATA_VALIDATION_RULE":
55428
- const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
55429
- if (cmd.rule.criterion.type === "isBoolean") {
55430
- this.setContentToBooleanCells({ ...cmd.rule, ranges });
55431
- }
55432
- delete this.validationResults[cmd.sheetId];
55433
- break;
55434
55440
  case "REMOVE_DATA_VALIDATION_RULE":
55435
55441
  delete this.validationResults[cmd.sheetId];
55436
55442
  break;
55437
55443
  }
55438
55444
  }
55439
- setContentToBooleanCells(rule) {
55440
- for (const position of getCellPositionsInRanges(rule.ranges)) {
55441
- const evaluatedCell = this.getters.getEvaluatedCell(position);
55442
- if (evaluatedCell.type !== CellValueType.boolean) {
55443
- this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
55444
- }
55445
- }
55446
- }
55447
55445
  isDataValidationInvalid(cellPosition) {
55448
55446
  return !this.getValidationResultForCell(cellPosition).isValid;
55449
55447
  }
@@ -57375,7 +57373,7 @@ class Session extends EventBus {
57375
57373
  * Notify the server that the user client left the collaborative session
57376
57374
  */
57377
57375
  async leave(data) {
57378
- if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
57376
+ if (data && Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
57379
57377
  await this.snapshot(data());
57380
57378
  }
57381
57379
  delete this.clients[this.clientId];
@@ -58846,6 +58844,42 @@ class CellComputedStylePlugin extends UIPlugin {
58846
58844
  }
58847
58845
  }
58848
58846
 
58847
+ class DataValidationInsertionPlugin extends UIPlugin {
58848
+ handle(cmd) {
58849
+ switch (cmd.type) {
58850
+ case "ADD_DATA_VALIDATION_RULE":
58851
+ if (cmd.rule.criterion.type === "isBoolean") {
58852
+ const ranges = cmd.ranges.map((range) => this.getters.getRangeFromRangeData(range));
58853
+ for (const position of getCellPositionsInRanges(ranges)) {
58854
+ const cell = this.getters.getCell(position);
58855
+ const evaluatedCell = this.getters.getEvaluatedCell(position);
58856
+ if (!cell?.content) {
58857
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
58858
+ // In this case, a cell has been updated in the core plugin but
58859
+ // not yet evaluated. This can occur after a paste operation.
58860
+ }
58861
+ else if (cell?.content && evaluatedCell.type === CellValueType.empty) {
58862
+ let value;
58863
+ if (cell.content.startsWith("=")) {
58864
+ const result = this.getters.evaluateFormula(position.sheetId, cell.content);
58865
+ value = (isMatrix(result) ? result[0][0] : result)?.toString();
58866
+ }
58867
+ else {
58868
+ value = cell.content;
58869
+ }
58870
+ if (!value || !isBoolean(value)) {
58871
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
58872
+ }
58873
+ }
58874
+ else if (evaluatedCell.type !== CellValueType.boolean) {
58875
+ this.dispatch("UPDATE_CELL", { ...position, content: "FALSE" });
58876
+ }
58877
+ }
58878
+ }
58879
+ }
58880
+ }
58881
+ }
58882
+
58849
58883
  const genericRepeatsTransforms = [
58850
58884
  repeatSheetDependantCommand,
58851
58885
  repeatTargetDependantCommand,
@@ -61911,7 +61945,8 @@ const featurePluginRegistry = new Registry()
61911
61945
  .add("history", HistoryPlugin)
61912
61946
  .add("data_cleanup", DataCleanupPlugin)
61913
61947
  .add("table_autofill", TableAutofillPlugin)
61914
- .add("table_ui_resize", TableResizeUI);
61948
+ .add("table_ui_resize", TableResizeUI)
61949
+ .add("datavalidation_insert", DataValidationInsertionPlugin);
61915
61950
  // Plugins which have a state, but which should not be shared in collaborative
61916
61951
  const statefulUIPluginRegistry = new Registry()
61917
61952
  .add("selection", GridSelectionPlugin)
@@ -68073,7 +68108,8 @@ class Model extends EventBus {
68073
68108
  this.session.join(this.config.client);
68074
68109
  }
68075
68110
  async leaveSession() {
68076
- await this.session.leave(lazy(() => this.exportData()));
68111
+ const snapshot = this.getters.isReadonly() ? undefined : lazy(() => this.exportData());
68112
+ await this.session.leave(snapshot);
68077
68113
  }
68078
68114
  setupUiPlugin(Plugin) {
68079
68115
  const plugin = new Plugin(this.uiPluginConfig);
@@ -68633,6 +68669,6 @@ const constants = {
68633
68669
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, 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 };
68634
68670
 
68635
68671
 
68636
- __info__.version = "17.4.11";
68637
- __info__.date = "2024-11-08T12:15:26.239Z";
68638
- __info__.hash = "2eb3f1c";
68672
+ __info__.version = "17.4.13";
68673
+ __info__.date = "2024-11-22T14:17:01.675Z";
68674
+ __info__.hash = "a5e4e16";