@odoo/o-spreadsheet 17.3.1 → 17.3.3

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.3.1
7
- * @date 2024-06-03T15:28:03.284Z
8
- * @hash 605d098
6
+ * @version 17.3.3
7
+ * @date 2024-06-14T10:02:58.082Z
8
+ * @hash c690e9f
9
9
  */
10
10
 
11
11
  (function (exports, owl) {
@@ -310,7 +310,10 @@
310
310
  * Check if the object is a plain old javascript object.
311
311
  */
312
312
  function isPlainObject(obj) {
313
- return typeof obj === "object" && obj?.constructor === Object;
313
+ return (typeof obj === "object" &&
314
+ obj !== null &&
315
+ // obj.constructor can be undefined when there's no prototype (`Object.create(null, {})`)
316
+ (obj?.constructor === Object || obj?.constructor === undefined));
314
317
  }
315
318
  /**
316
319
  * Sanitize the name of a sheet, by eventually removing quotes
@@ -2777,7 +2780,7 @@
2777
2780
  return false;
2778
2781
  }
2779
2782
  if (typeof operand === "number" && operator === "=") {
2780
- return toString(value) === toString(operand);
2783
+ return value.toString() === operand.toString();
2781
2784
  }
2782
2785
  if (operator === "<>" || operator === "=") {
2783
2786
  let result;
@@ -2837,14 +2840,13 @@
2837
2840
  if (countArg % 2 === 1) {
2838
2841
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range and criterion to be in pairs."));
2839
2842
  }
2840
- const dimRow = args[0].length;
2841
- const dimCol = args[0][0].length;
2843
+ const firstArg = toMatrix(args[0]);
2844
+ const dimRow = firstArg.length;
2845
+ const dimCol = firstArg[0].length;
2842
2846
  let predicates = [];
2843
2847
  for (let i = 0; i < countArg - 1; i += 2) {
2844
- const criteriaRange = args[i];
2845
- if (!isMatrix(criteriaRange) ||
2846
- criteriaRange.length !== dimRow ||
2847
- criteriaRange[0].length !== dimCol) {
2848
+ const criteriaRange = toMatrix(args[i]);
2849
+ if (criteriaRange.length !== dimRow || criteriaRange[0].length !== dimCol) {
2848
2850
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range to have the same dimension"));
2849
2851
  }
2850
2852
  const description = toString(args[i + 1]);
@@ -2858,7 +2860,7 @@
2858
2860
  for (let j = 0; j < dimCol; j++) {
2859
2861
  let validatedPredicates = true;
2860
2862
  for (let k = 0; k < countArg - 1; k += 2) {
2861
- const criteriaValue = args[k][i][j].value;
2863
+ const criteriaValue = toMatrix(args[k])[i][j].value;
2862
2864
  const criterion = predicates[k / 2];
2863
2865
  validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
2864
2866
  if (!validatedPredicates) {
@@ -10986,6 +10988,9 @@ stores.inject(MyMetaStore, storeInstance);
10986
10988
  if (types.some((t) => t.startsWith("RANGE"))) {
10987
10989
  result.acceptMatrix = true;
10988
10990
  }
10991
+ if (types.every((t) => t.startsWith("RANGE"))) {
10992
+ result.acceptMatrixOnly = true;
10993
+ }
10989
10994
  return result;
10990
10995
  }
10991
10996
  /**
@@ -11267,11 +11272,16 @@ stores.inject(MyMetaStore, storeInstance);
11267
11272
  compute: function (array, ...columns) {
11268
11273
  const _array = toMatrix(array);
11269
11274
  const _columns = flattenRowFirst(columns, (item) => toInteger(item?.value, this.locale));
11270
- assert(() => _columns.every((col) => col > 0 && col <= _array.length), _t("The columns arguments must be between 1 and %s (got %s).", _array.length.toString(), (_columns.find((col) => col <= 0 || col > _array.length) || 0).toString()));
11275
+ const argOutOfRange = _columns.filter((col) => col === 0 || _array.length < Math.abs(col));
11276
+ assert(() => argOutOfRange.length === 0, _t("The columns arguments must be between -%s and %s (got %s), excluding 0.", _array.length.toString(), _array.length.toString(), argOutOfRange.join(",")));
11271
11277
  const result = Array(_columns.length);
11272
11278
  for (let col = 0; col < _columns.length; col++) {
11273
- const colIndex = _columns[col] - 1; // -1 because columns arguments are 1-indexed
11274
- result[col] = _array[colIndex];
11279
+ if (_columns[col] > 0) {
11280
+ result[col] = _array[_columns[col] - 1]; // -1 because columns arguments are 1-indexed
11281
+ }
11282
+ else {
11283
+ result[col] = _array[_array.length + _columns[col]];
11284
+ }
11275
11285
  }
11276
11286
  return result;
11277
11287
  },
@@ -11292,8 +11302,14 @@ stores.inject(MyMetaStore, storeInstance);
11292
11302
  const _array = toMatrix(array);
11293
11303
  const _rows = flattenRowFirst(rows, (item) => toInteger(item?.value, this.locale));
11294
11304
  const _nbColumns = _array.length;
11295
- assert(() => _rows.every((row) => row > 0 && row <= _array[0].length), _t("The rows arguments must be between 1 and %s (got %s).", _array[0].length.toString(), (_rows.find((row) => row <= 0 || row > _array[0].length) || 0).toString()));
11296
- return generateMatrix(_nbColumns, _rows.length, (col, row) => _array[col][_rows[row] - 1]); // -1 because rows arguments are 1-indexed
11305
+ const argOutOfRange = _rows.filter((row) => row === 0 || _array[0].length < Math.abs(row));
11306
+ assert(() => argOutOfRange.length === 0, _t("The rows arguments must be between -%s and %s (got %s), excluding 0.", _array[0].length.toString(), _array[0].length.toString(), argOutOfRange.join(",")));
11307
+ return generateMatrix(_nbColumns, _rows.length, (col, row) => {
11308
+ if (_rows[row] > 0) {
11309
+ return _array[col][_rows[row] - 1]; // -1 because columns arguments are 1-indexed
11310
+ }
11311
+ return _array[col][_array[col].length + _rows[row]];
11312
+ });
11297
11313
  },
11298
11314
  isExported: true,
11299
11315
  };
@@ -19760,6 +19776,9 @@ stores.inject(MyMetaStore, storeInstance);
19760
19776
  }
19761
19777
  args[i] = arg[0][0];
19762
19778
  }
19779
+ if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
19780
+ throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
19781
+ }
19763
19782
  }
19764
19783
  return descr.compute.apply(this, args);
19765
19784
  }
@@ -20901,8 +20920,15 @@ stores.inject(MyMetaStore, storeInstance);
20901
20920
  }
20902
20921
  onPaste(ev) {
20903
20922
  if (this.composerStore.editionMode !== "inactive") {
20923
+ // let the browser clipboard work
20904
20924
  ev.stopPropagation();
20905
20925
  }
20926
+ else {
20927
+ // the user meant to paste in the sheet, not open the composer with the pasted content
20928
+ // While we're not editing, we still have the focus and should therefore prevent
20929
+ // the native "paste" to occur.
20930
+ ev.preventDefault();
20931
+ }
20906
20932
  }
20907
20933
  /*
20908
20934
  * Triggered automatically by the content-editable between the keydown and key up
@@ -20911,9 +20937,6 @@ stores.inject(MyMetaStore, storeInstance);
20911
20937
  if (!this.shouldProcessInputEvents) {
20912
20938
  return;
20913
20939
  }
20914
- if (ev.inputType === "insertFromPaste" && this.composerStore.editionMode === "inactive") {
20915
- return;
20916
- }
20917
20940
  ev.stopPropagation();
20918
20941
  let content;
20919
20942
  if (this.composerStore.editionMode === "inactive") {
@@ -21350,12 +21373,6 @@ stores.inject(MyMetaStore, storeInstance);
21350
21373
  // detect when an argument need to be evaluated as a meta argument
21351
21374
  const isMeta = argTypes.includes("META");
21352
21375
  const hasRange = argTypes.some((t) => isRangeType(t));
21353
- const isRangeOnly = argTypes.every((t) => isRangeType(t));
21354
- if (isRangeOnly) {
21355
- if (!isRangeInput(currentArg)) {
21356
- throw new BadExpressionError(_t("Function %(function_name)s expects the parameter %(arg_index)s to be a reference to a cell or a range.", { function_name: functionName, arg_index: i + 1 }));
21357
- }
21358
- }
21359
21376
  compiledArgs.push(compileAST(currentArg, isMeta, hasRange));
21360
21377
  }
21361
21378
  return compiledArgs;
@@ -21520,16 +21537,6 @@ stores.inject(MyMetaStore, storeInstance);
21520
21537
  function isRangeType(type) {
21521
21538
  return type.startsWith("RANGE");
21522
21539
  }
21523
- function isRangeInput(arg) {
21524
- if (arg.type === "REFERENCE") {
21525
- return true;
21526
- }
21527
- if (arg.type === "FUNCALL") {
21528
- const fnDef = functions$1[arg.value.toUpperCase()];
21529
- return fnDef && isRangeType(fnDef.returns[0]);
21530
- }
21531
- return false;
21532
- }
21533
21540
 
21534
21541
  const functions = functionRegistry.content;
21535
21542
  function isExportableToExcel(tokens) {
@@ -21958,7 +21965,9 @@ stores.inject(MyMetaStore, storeInstance);
21958
21965
  if (!groupByField) {
21959
21966
  return;
21960
21967
  }
21961
- return dataSource.getPossibleFieldValues(groupByField.split(":")[0]).map(({ value, label }) => {
21968
+ return dataSource
21969
+ .getPossibleFieldValues(groupByField.toString().split(":")[0])
21970
+ .map(({ value, label }) => {
21962
21971
  const isString = typeof value === "string";
21963
21972
  const text = isString ? `"${value}"` : value.toString();
21964
21973
  const color = isString ? tokenColors.STRING : tokenColors.NUMBER;
@@ -25322,8 +25331,7 @@ stores.inject(MyMetaStore, storeInstance);
25322
25331
  */
25323
25332
  function useSpreadsheetRect() {
25324
25333
  const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
25325
- let spreadsheetElement = document.querySelector(".o-spreadsheet");
25326
- updatePosition();
25334
+ let spreadsheetElement = null;
25327
25335
  function updatePosition() {
25328
25336
  if (!spreadsheetElement) {
25329
25337
  spreadsheetElement = document.querySelector(".o-spreadsheet");
@@ -25445,7 +25453,7 @@ stores.inject(MyMetaStore, storeInstance);
25445
25453
  if (!anchor)
25446
25454
  return;
25447
25455
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
25448
- const elDims = {
25456
+ let elDims = {
25449
25457
  width: el.getBoundingClientRect().width,
25450
25458
  height: el.getBoundingClientRect().height,
25451
25459
  };
@@ -25453,7 +25461,14 @@ stores.inject(MyMetaStore, storeInstance);
25453
25461
  const popoverPositionHelper = this.props.positioning === "BottomLeft"
25454
25462
  ? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
25455
25463
  : new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
25456
- const style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
25464
+ el.style["max-height"] = popoverPositionHelper.getMaxHeight(elDims.height) + "px";
25465
+ el.style["max-width"] = popoverPositionHelper.getMaxWidth(elDims.width) + "px";
25466
+ // Re-compute the dimensions after setting the max-width and max-height
25467
+ elDims = {
25468
+ width: el.getBoundingClientRect().width,
25469
+ height: el.getBoundingClientRect().height,
25470
+ };
25471
+ let style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
25457
25472
  for (const property of Object.keys(style)) {
25458
25473
  el.style[property] = style[property];
25459
25474
  }
@@ -25516,8 +25531,6 @@ stores.inject(MyMetaStore, storeInstance);
25516
25531
  const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
25517
25532
  verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
25518
25533
  const cssProperties = {
25519
- "max-height": maxHeight + "px",
25520
- "max-width": maxWidth + "px",
25521
25534
  top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
25522
25535
  this.spreadsheetOffset.y -
25523
25536
  verticalOffset +
@@ -31331,10 +31344,8 @@ stores.inject(MyMetaStore, storeInstance);
31331
31344
 
31332
31345
  class AxisDesignEditor extends owl.Component {
31333
31346
  static template = "o-spreadsheet-AxisDesignEditor";
31334
- static components = {
31335
- Section,
31336
- ChartTitle,
31337
- };
31347
+ static components = { Section, ChartTitle };
31348
+ static props = { figureId: String, definition: Object, updateChart: Function, axesList: Array };
31338
31349
  state = owl.useState({ currentAxis: "x" });
31339
31350
  get axisTitleStyle() {
31340
31351
  const axisDesign = this.props.definition.axesDesign?.[this.state.currentAxis] ?? {};
@@ -31485,6 +31496,12 @@ stores.inject(MyMetaStore, storeInstance);
31485
31496
  AxisDesignEditor,
31486
31497
  RoundColorPicker,
31487
31498
  };
31499
+ static props = {
31500
+ figureId: String,
31501
+ definition: Object,
31502
+ canUpdateChart: Function,
31503
+ updateChart: Function,
31504
+ };
31488
31505
  state = owl.useState({ index: 0 });
31489
31506
  get axesList() {
31490
31507
  const { useLeftAxis, useRightAxis } = getDefinedAxis(this.props.definition);
@@ -31666,14 +31683,6 @@ stores.inject(MyMetaStore, storeInstance);
31666
31683
  const cancelledReasons = [...(this.state.sectionRuleDispatchResult?.reasons || [])];
31667
31684
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
31668
31685
  }
31669
- updateBackgroundColor(color) {
31670
- this.props.updateChart(this.props.figureId, {
31671
- background: color,
31672
- });
31673
- }
31674
- updateTitle(content) {
31675
- this.props.updateChart(this.props.figureId, { title: { text: content } });
31676
- }
31677
31686
  isRangeMinInvalid() {
31678
31687
  return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause("EmptyGaugeRangeMin" /* CommandResult.EmptyGaugeRangeMin */) ||
31679
31688
  this.state.sectionRuleDispatchResult?.isCancelledBecause("GaugeRangeMinNaN" /* CommandResult.GaugeRangeMinNaN */) ||
@@ -31713,9 +31722,6 @@ stores.inject(MyMetaStore, storeInstance);
31713
31722
  sectionRule,
31714
31723
  });
31715
31724
  }
31716
- get backgroundColorTitle() {
31717
- return ChartTerms.BackgroundColor;
31718
- }
31719
31725
  }
31720
31726
 
31721
31727
  class LineConfigPanel extends GenericChartConfigPanel {
@@ -31898,9 +31904,6 @@ stores.inject(MyMetaStore, storeInstance);
31898
31904
  get humanizeNumbersLabel() {
31899
31905
  return _t("Humanize numbers");
31900
31906
  }
31901
- updateTitle(content) {
31902
- this.props.updateChart(this.props.figureId, { title: { text: content } });
31903
- }
31904
31907
  updateHumanizeNumbers(humanize) {
31905
31908
  this.props.updateChart(this.props.figureId, { humanize });
31906
31909
  }
@@ -31923,9 +31926,6 @@ stores.inject(MyMetaStore, storeInstance);
31923
31926
  break;
31924
31927
  }
31925
31928
  }
31926
- get backgroundColorTitle() {
31927
- return ChartTerms.BackgroundColor;
31928
- }
31929
31929
  }
31930
31930
 
31931
31931
  class WaterfallChartDesignPanel extends owl.Component {
@@ -33426,13 +33426,17 @@ stores.inject(MyMetaStore, storeInstance);
33426
33426
  class: { type: String, optional: true },
33427
33427
  };
33428
33428
  static components = { Menu };
33429
+ menuId = new UuidGenerator().uuidv4();
33429
33430
  selectRef = owl.useRef("select");
33430
33431
  selectRect = useAbsoluteBoundingRect(this.selectRef);
33431
33432
  state = owl.useState({
33432
33433
  isMenuOpen: false,
33433
33434
  });
33434
- onClick() {
33435
- this.state.isMenuOpen = true;
33435
+ onClick(ev) {
33436
+ if (ev.closedMenuId === this.menuId) {
33437
+ return;
33438
+ }
33439
+ this.state.isMenuOpen = !this.state.isMenuOpen;
33436
33440
  }
33437
33441
  onMenuClosed() {
33438
33442
  this.state.isMenuOpen = false;
@@ -33440,7 +33444,7 @@ stores.inject(MyMetaStore, storeInstance);
33440
33444
  get menuPosition() {
33441
33445
  return {
33442
33446
  x: this.selectRect.x,
33443
- y: this.selectRect.y,
33447
+ y: this.selectRect.y + this.selectRect.height,
33444
33448
  };
33445
33449
  }
33446
33450
  }
@@ -34380,9 +34384,9 @@ stores.inject(MyMetaStore, storeInstance);
34380
34384
  static props = {
34381
34385
  onCloseSidePanel: Function,
34382
34386
  };
34383
- dataRange = "";
34384
34387
  searchInput = owl.useRef("searchInput");
34385
34388
  store;
34389
+ state;
34386
34390
  get hasSearchResult() {
34387
34391
  return this.store.selectedMatchIndex !== null;
34388
34392
  }
@@ -34412,6 +34416,7 @@ stores.inject(MyMetaStore, storeInstance);
34412
34416
  }
34413
34417
  setup() {
34414
34418
  this.store = useLocalStore(FindAndReplaceStore);
34419
+ this.state = owl.useState({ dataRange: "" });
34415
34420
  owl.onMounted(() => this.searchInput.el?.focus());
34416
34421
  }
34417
34422
  onFocusSearch() {
@@ -34448,13 +34453,13 @@ stores.inject(MyMetaStore, storeInstance);
34448
34453
  this.store.updateSearchOptions({ searchScope });
34449
34454
  }
34450
34455
  onSearchRangeChanged(ranges) {
34451
- this.dataRange = ranges[0];
34456
+ this.state.dataRange = ranges[0];
34452
34457
  }
34453
34458
  updateDataRange() {
34454
- if (!this.dataRange || this.searchOptions.searchScope !== "specificRange") {
34459
+ if (!this.state.dataRange || this.searchOptions.searchScope !== "specificRange") {
34455
34460
  return;
34456
34461
  }
34457
- const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.dataRange);
34462
+ const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
34458
34463
  this.store.updateSearchOptions({ specificRange });
34459
34464
  }
34460
34465
  }
@@ -36125,6 +36130,7 @@ stores.inject(MyMetaStore, storeInstance);
36125
36130
  class RemoveDuplicatesPanel extends owl.Component {
36126
36131
  static template = "o-spreadsheet-RemoveDuplicatesPanel";
36127
36132
  static components = { ValidationMessages, Section, Checkbox };
36133
+ static props = { onCloseSidePanel: Function };
36128
36134
  state = owl.useState({
36129
36135
  hasHeader: false,
36130
36136
  columns: {},
@@ -37917,10 +37923,7 @@ stores.inject(MyMetaStore, storeInstance);
37917
37923
  }
37918
37924
  get containerStyle() {
37919
37925
  if (this.composerStore.editionMode === "inactive") {
37920
- return `
37921
- position: absolute;
37922
- z-index: -1000;
37923
- `;
37926
+ return `z-index: -1000;`;
37924
37927
  }
37925
37928
  const isFormula = this.composerStore.currentContent.startsWith("=");
37926
37929
  const cell = this.env.model.getters.getActiveCell();
@@ -38552,7 +38555,7 @@ stores.inject(MyMetaStore, storeInstance);
38552
38555
  });
38553
38556
  }
38554
38557
  getContainerRect(container) {
38555
- const { width: viewWidth, height: viewHeight } = this.env.model.getters.getMainViewportRect();
38558
+ const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
38556
38559
  const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
38557
38560
  const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
38558
38561
  const width = viewWidth - x;
@@ -51157,22 +51160,6 @@ stores.inject(MyMetaStore, storeInstance);
51157
51160
  this.addPivotFormula(cellPosition, formulaId, pivotCell);
51158
51161
  }
51159
51162
  }
51160
- const pivotZone = {
51161
- top: position.row,
51162
- bottom: position.row + pivotCells[0].length - 1,
51163
- left: position.col,
51164
- right: position.col + pivotCells.length - 1,
51165
- };
51166
- const numberOfHeaders = table.columns.length - 1;
51167
- const cmdContent = {
51168
- sheetId: position.sheetId,
51169
- ranges: [this.getters.getRangeDataFromZone(position.sheetId, pivotZone)],
51170
- config: { ...PIVOT_TABLE_CONFIG, numberOfHeaders },
51171
- tableType: "static",
51172
- };
51173
- if (this.canDispatch("CREATE_TABLE", cmdContent).isSuccessful) {
51174
- this.dispatch("CREATE_TABLE", cmdContent);
51175
- }
51176
51163
  }
51177
51164
  resizeSheet(sheetId, { col, row }, table) {
51178
51165
  const colLimit = table.getNumberOfDataColumns() + 1; // +1 for the Top-Left
@@ -54567,17 +54554,18 @@ stores.inject(MyMetaStore, storeInstance);
54567
54554
  const pivotCol = position.col - mainPosition.col;
54568
54555
  const pivotRow = position.row - mainPosition.row;
54569
54556
  const pivotCell = pivotCells[pivotCol][pivotRow];
54570
- const domain = pivotCell.domain;
54557
+ let domain = pivotCell.domain;
54571
54558
  if (domain?.at(-2) === "measure") {
54572
- return domain.slice(0, -2);
54559
+ domain = domain.slice(0, -2);
54573
54560
  }
54574
- return domain;
54561
+ return { domainArgs: domain, isHeader: pivotCell.isHeader };
54575
54562
  }
54576
- const domain = args.slice(functionName === "PIVOT.VALUE" ? 2 : 1);
54563
+ let domain = args.slice(functionName === "PIVOT.VALUE" ? 2 : 1);
54577
54564
  if (domain.at(-2) === "measure") {
54578
- return domain.slice(0, -2);
54565
+ domain = domain.slice(0, -2);
54579
54566
  }
54580
- return domain;
54567
+ const isHeader = functionName === "PIVOT.HEADER";
54568
+ return { domainArgs: domain, isHeader };
54581
54569
  }
54582
54570
  getPivot(pivotId) {
54583
54571
  return this.pivots[pivotId];
@@ -55897,7 +55885,10 @@ stores.inject(MyMetaStore, storeInstance);
55897
55885
  /**
55898
55886
  * Notify the server that the user client left the collaborative session
55899
55887
  */
55900
- leave() {
55888
+ leave(data) {
55889
+ if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
55890
+ this.snapshot(data);
55891
+ }
55901
55892
  delete this.clients[this.clientId];
55902
55893
  this.transportService.leave(this.clientId);
55903
55894
  this.transportService.sendMessage({
@@ -55910,6 +55901,9 @@ stores.inject(MyMetaStore, storeInstance);
55910
55901
  * Send a snapshot of the spreadsheet to the collaboration server
55911
55902
  */
55912
55903
  snapshot(data) {
55904
+ if (this.pendingMessages.length !== 0) {
55905
+ return;
55906
+ }
55913
55907
  const snapshotId = this.uuidGenerator.uuidv4();
55914
55908
  this.transportService.sendMessage({
55915
55909
  type: "SNAPSHOT",
@@ -66397,7 +66391,7 @@ stores.inject(MyMetaStore, storeInstance);
66397
66391
  this.session.join(this.config.client);
66398
66392
  }
66399
66393
  leaveSession() {
66400
- this.session.leave();
66394
+ this.session.leave(this.exportData());
66401
66395
  }
66402
66396
  setupUiPlugin(Plugin) {
66403
66397
  const plugin = new Plugin(this.uiPluginConfig);
@@ -66988,9 +66982,9 @@ stores.inject(MyMetaStore, storeInstance);
66988
66982
  exports.tokenize = tokenize;
66989
66983
 
66990
66984
 
66991
- __info__.version = "17.3.1";
66992
- __info__.date = "2024-06-03T15:28:03.284Z";
66993
- __info__.hash = "605d098";
66985
+ __info__.version = "17.3.3";
66986
+ __info__.date = "2024-06-14T10:02:58.082Z";
66987
+ __info__.hash = "c690e9f";
66994
66988
 
66995
66989
 
66996
66990
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);