@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
  'use strict';
@@ -311,7 +311,10 @@ function deepCopy(obj) {
311
311
  * Check if the object is a plain old javascript object.
312
312
  */
313
313
  function isPlainObject(obj) {
314
- return typeof obj === "object" && obj?.constructor === Object;
314
+ return (typeof obj === "object" &&
315
+ obj !== null &&
316
+ // obj.constructor can be undefined when there's no prototype (`Object.create(null, {})`)
317
+ (obj?.constructor === Object || obj?.constructor === undefined));
315
318
  }
316
319
  /**
317
320
  * Sanitize the name of a sheet, by eventually removing quotes
@@ -2778,7 +2781,7 @@ function evaluatePredicate(value, criterion) {
2778
2781
  return false;
2779
2782
  }
2780
2783
  if (typeof operand === "number" && operator === "=") {
2781
- return toString(value) === toString(operand);
2784
+ return value.toString() === operand.toString();
2782
2785
  }
2783
2786
  if (operator === "<>" || operator === "=") {
2784
2787
  let result;
@@ -2838,14 +2841,13 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
2838
2841
  if (countArg % 2 === 1) {
2839
2842
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range and criterion to be in pairs."));
2840
2843
  }
2841
- const dimRow = args[0].length;
2842
- const dimCol = args[0][0].length;
2844
+ const firstArg = toMatrix(args[0]);
2845
+ const dimRow = firstArg.length;
2846
+ const dimCol = firstArg[0].length;
2843
2847
  let predicates = [];
2844
2848
  for (let i = 0; i < countArg - 1; i += 2) {
2845
- const criteriaRange = args[i];
2846
- if (!isMatrix(criteriaRange) ||
2847
- criteriaRange.length !== dimRow ||
2848
- criteriaRange[0].length !== dimCol) {
2849
+ const criteriaRange = toMatrix(args[i]);
2850
+ if (criteriaRange.length !== dimRow || criteriaRange[0].length !== dimCol) {
2849
2851
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range to have the same dimension"));
2850
2852
  }
2851
2853
  const description = toString(args[i + 1]);
@@ -2859,7 +2861,7 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
2859
2861
  for (let j = 0; j < dimCol; j++) {
2860
2862
  let validatedPredicates = true;
2861
2863
  for (let k = 0; k < countArg - 1; k += 2) {
2862
- const criteriaValue = args[k][i][j].value;
2864
+ const criteriaValue = toMatrix(args[k])[i][j].value;
2863
2865
  const criterion = predicates[k / 2];
2864
2866
  validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
2865
2867
  if (!validatedPredicates) {
@@ -10987,6 +10989,9 @@ function makeArg(str, description) {
10987
10989
  if (types.some((t) => t.startsWith("RANGE"))) {
10988
10990
  result.acceptMatrix = true;
10989
10991
  }
10992
+ if (types.every((t) => t.startsWith("RANGE"))) {
10993
+ result.acceptMatrixOnly = true;
10994
+ }
10990
10995
  return result;
10991
10996
  }
10992
10997
  /**
@@ -11268,11 +11273,16 @@ const CHOOSECOLS = {
11268
11273
  compute: function (array, ...columns) {
11269
11274
  const _array = toMatrix(array);
11270
11275
  const _columns = flattenRowFirst(columns, (item) => toInteger(item?.value, this.locale));
11271
- 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()));
11276
+ const argOutOfRange = _columns.filter((col) => col === 0 || _array.length < Math.abs(col));
11277
+ 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(",")));
11272
11278
  const result = Array(_columns.length);
11273
11279
  for (let col = 0; col < _columns.length; col++) {
11274
- const colIndex = _columns[col] - 1; // -1 because columns arguments are 1-indexed
11275
- result[col] = _array[colIndex];
11280
+ if (_columns[col] > 0) {
11281
+ result[col] = _array[_columns[col] - 1]; // -1 because columns arguments are 1-indexed
11282
+ }
11283
+ else {
11284
+ result[col] = _array[_array.length + _columns[col]];
11285
+ }
11276
11286
  }
11277
11287
  return result;
11278
11288
  },
@@ -11293,8 +11303,14 @@ const CHOOSEROWS = {
11293
11303
  const _array = toMatrix(array);
11294
11304
  const _rows = flattenRowFirst(rows, (item) => toInteger(item?.value, this.locale));
11295
11305
  const _nbColumns = _array.length;
11296
- 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()));
11297
- return generateMatrix(_nbColumns, _rows.length, (col, row) => _array[col][_rows[row] - 1]); // -1 because rows arguments are 1-indexed
11306
+ const argOutOfRange = _rows.filter((row) => row === 0 || _array[0].length < Math.abs(row));
11307
+ 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(",")));
11308
+ return generateMatrix(_nbColumns, _rows.length, (col, row) => {
11309
+ if (_rows[row] > 0) {
11310
+ return _array[col][_rows[row] - 1]; // -1 because columns arguments are 1-indexed
11311
+ }
11312
+ return _array[col][_array[col].length + _rows[row]];
11313
+ });
11298
11314
  },
11299
11315
  isExported: true,
11300
11316
  };
@@ -19761,6 +19777,9 @@ function addInputHandling(descr) {
19761
19777
  }
19762
19778
  args[i] = arg[0][0];
19763
19779
  }
19780
+ if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
19781
+ throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
19782
+ }
19764
19783
  }
19765
19784
  return descr.compute.apply(this, args);
19766
19785
  }
@@ -20902,8 +20921,15 @@ class Composer extends owl.Component {
20902
20921
  }
20903
20922
  onPaste(ev) {
20904
20923
  if (this.composerStore.editionMode !== "inactive") {
20924
+ // let the browser clipboard work
20905
20925
  ev.stopPropagation();
20906
20926
  }
20927
+ else {
20928
+ // the user meant to paste in the sheet, not open the composer with the pasted content
20929
+ // While we're not editing, we still have the focus and should therefore prevent
20930
+ // the native "paste" to occur.
20931
+ ev.preventDefault();
20932
+ }
20907
20933
  }
20908
20934
  /*
20909
20935
  * Triggered automatically by the content-editable between the keydown and key up
@@ -20912,9 +20938,6 @@ class Composer extends owl.Component {
20912
20938
  if (!this.shouldProcessInputEvents) {
20913
20939
  return;
20914
20940
  }
20915
- if (ev.inputType === "insertFromPaste" && this.composerStore.editionMode === "inactive") {
20916
- return;
20917
- }
20918
20941
  ev.stopPropagation();
20919
20942
  let content;
20920
20943
  if (this.composerStore.editionMode === "inactive") {
@@ -21351,12 +21374,6 @@ function compileTokens(tokens) {
21351
21374
  // detect when an argument need to be evaluated as a meta argument
21352
21375
  const isMeta = argTypes.includes("META");
21353
21376
  const hasRange = argTypes.some((t) => isRangeType(t));
21354
- const isRangeOnly = argTypes.every((t) => isRangeType(t));
21355
- if (isRangeOnly) {
21356
- if (!isRangeInput(currentArg)) {
21357
- 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 }));
21358
- }
21359
- }
21360
21377
  compiledArgs.push(compileAST(currentArg, isMeta, hasRange));
21361
21378
  }
21362
21379
  return compiledArgs;
@@ -21521,16 +21538,6 @@ function assertEnoughArgs(ast) {
21521
21538
  function isRangeType(type) {
21522
21539
  return type.startsWith("RANGE");
21523
21540
  }
21524
- function isRangeInput(arg) {
21525
- if (arg.type === "REFERENCE") {
21526
- return true;
21527
- }
21528
- if (arg.type === "FUNCALL") {
21529
- const fnDef = functions$1[arg.value.toUpperCase()];
21530
- return fnDef && isRangeType(fnDef.returns[0]);
21531
- }
21532
- return false;
21533
- }
21534
21541
 
21535
21542
  const functions = functionRegistry.content;
21536
21543
  function isExportableToExcel(tokens) {
@@ -21959,7 +21966,9 @@ autoCompleteProviders.add("pivot_group_values", {
21959
21966
  if (!groupByField) {
21960
21967
  return;
21961
21968
  }
21962
- return dataSource.getPossibleFieldValues(groupByField.split(":")[0]).map(({ value, label }) => {
21969
+ return dataSource
21970
+ .getPossibleFieldValues(groupByField.toString().split(":")[0])
21971
+ .map(({ value, label }) => {
21963
21972
  const isString = typeof value === "string";
21964
21973
  const text = isString ? `"${value}"` : value.toString();
21965
21974
  const color = isString ? tokenColors.STRING : tokenColors.NUMBER;
@@ -25323,8 +25332,7 @@ function zoneToRect(zone) {
25323
25332
  */
25324
25333
  function useSpreadsheetRect() {
25325
25334
  const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
25326
- let spreadsheetElement = document.querySelector(".o-spreadsheet");
25327
- updatePosition();
25335
+ let spreadsheetElement = null;
25328
25336
  function updatePosition() {
25329
25337
  if (!spreadsheetElement) {
25330
25338
  spreadsheetElement = document.querySelector(".o-spreadsheet");
@@ -25446,7 +25454,7 @@ class Popover extends owl.Component {
25446
25454
  if (!anchor)
25447
25455
  return;
25448
25456
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
25449
- const elDims = {
25457
+ let elDims = {
25450
25458
  width: el.getBoundingClientRect().width,
25451
25459
  height: el.getBoundingClientRect().height,
25452
25460
  };
@@ -25454,7 +25462,14 @@ class Popover extends owl.Component {
25454
25462
  const popoverPositionHelper = this.props.positioning === "BottomLeft"
25455
25463
  ? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
25456
25464
  : new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
25457
- const style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
25465
+ el.style["max-height"] = popoverPositionHelper.getMaxHeight(elDims.height) + "px";
25466
+ el.style["max-width"] = popoverPositionHelper.getMaxWidth(elDims.width) + "px";
25467
+ // Re-compute the dimensions after setting the max-width and max-height
25468
+ elDims = {
25469
+ width: el.getBoundingClientRect().width,
25470
+ height: el.getBoundingClientRect().height,
25471
+ };
25472
+ let style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
25458
25473
  for (const property of Object.keys(style)) {
25459
25474
  el.style[property] = style[property];
25460
25475
  }
@@ -25517,8 +25532,6 @@ class PopoverPositionContext {
25517
25532
  const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
25518
25533
  verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
25519
25534
  const cssProperties = {
25520
- "max-height": maxHeight + "px",
25521
- "max-width": maxWidth + "px",
25522
25535
  top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
25523
25536
  this.spreadsheetOffset.y -
25524
25537
  verticalOffset +
@@ -31332,10 +31345,8 @@ class ChartTitle extends owl.Component {
31332
31345
 
31333
31346
  class AxisDesignEditor extends owl.Component {
31334
31347
  static template = "o-spreadsheet-AxisDesignEditor";
31335
- static components = {
31336
- Section,
31337
- ChartTitle,
31338
- };
31348
+ static components = { Section, ChartTitle };
31349
+ static props = { figureId: String, definition: Object, updateChart: Function, axesList: Array };
31339
31350
  state = owl.useState({ currentAxis: "x" });
31340
31351
  get axisTitleStyle() {
31341
31352
  const axisDesign = this.props.definition.axesDesign?.[this.state.currentAxis] ?? {};
@@ -31486,6 +31497,12 @@ class ChartWithAxisDesignPanel extends owl.Component {
31486
31497
  AxisDesignEditor,
31487
31498
  RoundColorPicker,
31488
31499
  };
31500
+ static props = {
31501
+ figureId: String,
31502
+ definition: Object,
31503
+ canUpdateChart: Function,
31504
+ updateChart: Function,
31505
+ };
31489
31506
  state = owl.useState({ index: 0 });
31490
31507
  get axesList() {
31491
31508
  const { useLeftAxis, useRightAxis } = getDefinedAxis(this.props.definition);
@@ -31667,14 +31684,6 @@ class GaugeChartDesignPanel extends owl.Component {
31667
31684
  const cancelledReasons = [...(this.state.sectionRuleDispatchResult?.reasons || [])];
31668
31685
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
31669
31686
  }
31670
- updateBackgroundColor(color) {
31671
- this.props.updateChart(this.props.figureId, {
31672
- background: color,
31673
- });
31674
- }
31675
- updateTitle(content) {
31676
- this.props.updateChart(this.props.figureId, { title: { text: content } });
31677
- }
31678
31687
  isRangeMinInvalid() {
31679
31688
  return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause("EmptyGaugeRangeMin" /* CommandResult.EmptyGaugeRangeMin */) ||
31680
31689
  this.state.sectionRuleDispatchResult?.isCancelledBecause("GaugeRangeMinNaN" /* CommandResult.GaugeRangeMinNaN */) ||
@@ -31714,9 +31723,6 @@ class GaugeChartDesignPanel extends owl.Component {
31714
31723
  sectionRule,
31715
31724
  });
31716
31725
  }
31717
- get backgroundColorTitle() {
31718
- return ChartTerms.BackgroundColor;
31719
- }
31720
31726
  }
31721
31727
 
31722
31728
  class LineConfigPanel extends GenericChartConfigPanel {
@@ -31899,9 +31905,6 @@ class ScorecardChartDesignPanel extends owl.Component {
31899
31905
  get humanizeNumbersLabel() {
31900
31906
  return _t("Humanize numbers");
31901
31907
  }
31902
- updateTitle(content) {
31903
- this.props.updateChart(this.props.figureId, { title: { text: content } });
31904
- }
31905
31908
  updateHumanizeNumbers(humanize) {
31906
31909
  this.props.updateChart(this.props.figureId, { humanize });
31907
31910
  }
@@ -31924,9 +31927,6 @@ class ScorecardChartDesignPanel extends owl.Component {
31924
31927
  break;
31925
31928
  }
31926
31929
  }
31927
- get backgroundColorTitle() {
31928
- return ChartTerms.BackgroundColor;
31929
- }
31930
31930
  }
31931
31931
 
31932
31932
  class WaterfallChartDesignPanel extends owl.Component {
@@ -33427,13 +33427,17 @@ class SelectMenu extends owl.Component {
33427
33427
  class: { type: String, optional: true },
33428
33428
  };
33429
33429
  static components = { Menu };
33430
+ menuId = new UuidGenerator().uuidv4();
33430
33431
  selectRef = owl.useRef("select");
33431
33432
  selectRect = useAbsoluteBoundingRect(this.selectRef);
33432
33433
  state = owl.useState({
33433
33434
  isMenuOpen: false,
33434
33435
  });
33435
- onClick() {
33436
- this.state.isMenuOpen = true;
33436
+ onClick(ev) {
33437
+ if (ev.closedMenuId === this.menuId) {
33438
+ return;
33439
+ }
33440
+ this.state.isMenuOpen = !this.state.isMenuOpen;
33437
33441
  }
33438
33442
  onMenuClosed() {
33439
33443
  this.state.isMenuOpen = false;
@@ -33441,7 +33445,7 @@ class SelectMenu extends owl.Component {
33441
33445
  get menuPosition() {
33442
33446
  return {
33443
33447
  x: this.selectRect.x,
33444
- y: this.selectRect.y,
33448
+ y: this.selectRect.y + this.selectRect.height,
33445
33449
  };
33446
33450
  }
33447
33451
  }
@@ -34381,9 +34385,9 @@ class FindAndReplacePanel extends owl.Component {
34381
34385
  static props = {
34382
34386
  onCloseSidePanel: Function,
34383
34387
  };
34384
- dataRange = "";
34385
34388
  searchInput = owl.useRef("searchInput");
34386
34389
  store;
34390
+ state;
34387
34391
  get hasSearchResult() {
34388
34392
  return this.store.selectedMatchIndex !== null;
34389
34393
  }
@@ -34413,6 +34417,7 @@ class FindAndReplacePanel extends owl.Component {
34413
34417
  }
34414
34418
  setup() {
34415
34419
  this.store = useLocalStore(FindAndReplaceStore);
34420
+ this.state = owl.useState({ dataRange: "" });
34416
34421
  owl.onMounted(() => this.searchInput.el?.focus());
34417
34422
  }
34418
34423
  onFocusSearch() {
@@ -34449,13 +34454,13 @@ class FindAndReplacePanel extends owl.Component {
34449
34454
  this.store.updateSearchOptions({ searchScope });
34450
34455
  }
34451
34456
  onSearchRangeChanged(ranges) {
34452
- this.dataRange = ranges[0];
34457
+ this.state.dataRange = ranges[0];
34453
34458
  }
34454
34459
  updateDataRange() {
34455
- if (!this.dataRange || this.searchOptions.searchScope !== "specificRange") {
34460
+ if (!this.state.dataRange || this.searchOptions.searchScope !== "specificRange") {
34456
34461
  return;
34457
34462
  }
34458
- const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.dataRange);
34463
+ const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
34459
34464
  this.store.updateSearchOptions({ specificRange });
34460
34465
  }
34461
34466
  }
@@ -36126,6 +36131,7 @@ css /* scss */ `
36126
36131
  class RemoveDuplicatesPanel extends owl.Component {
36127
36132
  static template = "o-spreadsheet-RemoveDuplicatesPanel";
36128
36133
  static components = { ValidationMessages, Section, Checkbox };
36134
+ static props = { onCloseSidePanel: Function };
36129
36135
  state = owl.useState({
36130
36136
  hasHeader: false,
36131
36137
  columns: {},
@@ -37918,10 +37924,7 @@ class GridComposer extends owl.Component {
37918
37924
  }
37919
37925
  get containerStyle() {
37920
37926
  if (this.composerStore.editionMode === "inactive") {
37921
- return `
37922
- position: absolute;
37923
- z-index: -1000;
37924
- `;
37927
+ return `z-index: -1000;`;
37925
37928
  }
37926
37929
  const isFormula = this.composerStore.currentContent.startsWith("=");
37927
37930
  const cell = this.env.model.getters.getActiveCell();
@@ -38553,7 +38556,7 @@ class FiguresContainer extends owl.Component {
38553
38556
  });
38554
38557
  }
38555
38558
  getContainerRect(container) {
38556
- const { width: viewWidth, height: viewHeight } = this.env.model.getters.getMainViewportRect();
38559
+ const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
38557
38560
  const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
38558
38561
  const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
38559
38562
  const width = viewWidth - x;
@@ -51158,22 +51161,6 @@ class PivotCorePlugin extends CorePlugin {
51158
51161
  this.addPivotFormula(cellPosition, formulaId, pivotCell);
51159
51162
  }
51160
51163
  }
51161
- const pivotZone = {
51162
- top: position.row,
51163
- bottom: position.row + pivotCells[0].length - 1,
51164
- left: position.col,
51165
- right: position.col + pivotCells.length - 1,
51166
- };
51167
- const numberOfHeaders = table.columns.length - 1;
51168
- const cmdContent = {
51169
- sheetId: position.sheetId,
51170
- ranges: [this.getters.getRangeDataFromZone(position.sheetId, pivotZone)],
51171
- config: { ...PIVOT_TABLE_CONFIG, numberOfHeaders },
51172
- tableType: "static",
51173
- };
51174
- if (this.canDispatch("CREATE_TABLE", cmdContent).isSuccessful) {
51175
- this.dispatch("CREATE_TABLE", cmdContent);
51176
- }
51177
51164
  }
51178
51165
  resizeSheet(sheetId, { col, row }, table) {
51179
51166
  const colLimit = table.getNumberOfDataColumns() + 1; // +1 for the Top-Left
@@ -54568,17 +54555,18 @@ class PivotUIPlugin extends UIPlugin {
54568
54555
  const pivotCol = position.col - mainPosition.col;
54569
54556
  const pivotRow = position.row - mainPosition.row;
54570
54557
  const pivotCell = pivotCells[pivotCol][pivotRow];
54571
- const domain = pivotCell.domain;
54558
+ let domain = pivotCell.domain;
54572
54559
  if (domain?.at(-2) === "measure") {
54573
- return domain.slice(0, -2);
54560
+ domain = domain.slice(0, -2);
54574
54561
  }
54575
- return domain;
54562
+ return { domainArgs: domain, isHeader: pivotCell.isHeader };
54576
54563
  }
54577
- const domain = args.slice(functionName === "PIVOT.VALUE" ? 2 : 1);
54564
+ let domain = args.slice(functionName === "PIVOT.VALUE" ? 2 : 1);
54578
54565
  if (domain.at(-2) === "measure") {
54579
- return domain.slice(0, -2);
54566
+ domain = domain.slice(0, -2);
54580
54567
  }
54581
- return domain;
54568
+ const isHeader = functionName === "PIVOT.HEADER";
54569
+ return { domainArgs: domain, isHeader };
54582
54570
  }
54583
54571
  getPivot(pivotId) {
54584
54572
  return this.pivots[pivotId];
@@ -55898,7 +55886,10 @@ class Session extends EventBus {
55898
55886
  /**
55899
55887
  * Notify the server that the user client left the collaborative session
55900
55888
  */
55901
- leave() {
55889
+ leave(data) {
55890
+ if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
55891
+ this.snapshot(data);
55892
+ }
55902
55893
  delete this.clients[this.clientId];
55903
55894
  this.transportService.leave(this.clientId);
55904
55895
  this.transportService.sendMessage({
@@ -55911,6 +55902,9 @@ class Session extends EventBus {
55911
55902
  * Send a snapshot of the spreadsheet to the collaboration server
55912
55903
  */
55913
55904
  snapshot(data) {
55905
+ if (this.pendingMessages.length !== 0) {
55906
+ return;
55907
+ }
55914
55908
  const snapshotId = this.uuidGenerator.uuidv4();
55915
55909
  this.transportService.sendMessage({
55916
55910
  type: "SNAPSHOT",
@@ -66398,7 +66392,7 @@ class Model extends EventBus {
66398
66392
  this.session.join(this.config.client);
66399
66393
  }
66400
66394
  leaveSession() {
66401
- this.session.leave();
66395
+ this.session.leave(this.exportData());
66402
66396
  }
66403
66397
  setupUiPlugin(Plugin) {
66404
66398
  const plugin = new Plugin(this.uiPluginConfig);
@@ -66989,6 +66983,6 @@ exports.tokenColors = tokenColors;
66989
66983
  exports.tokenize = tokenize;
66990
66984
 
66991
66985
 
66992
- __info__.version = "17.3.1";
66993
- __info__.date = "2024-06-03T15:28:03.284Z";
66994
- __info__.hash = "605d098";
66986
+ __info__.version = "17.3.3";
66987
+ __info__.date = "2024-06-14T10:02:58.082Z";
66988
+ __info__.hash = "c690e9f";
@@ -3800,7 +3800,7 @@ declare class Session extends EventBus<CollaborativeEvent> {
3800
3800
  /**
3801
3801
  * Notify the server that the user client left the collaborative session
3802
3802
  */
3803
- leave(): void;
3803
+ leave(data: WorkbookData): void;
3804
3804
  /**
3805
3805
  * Send a snapshot of the spreadsheet to the collaboration server
3806
3806
  */
@@ -4272,7 +4272,13 @@ declare class PivotUIPlugin extends UIPlugin {
4272
4272
  * If the cell is the result of PIVOT, the result is the domain of the cell
4273
4273
  * as if it was the individual pivot formula
4274
4274
  */
4275
- getPivotDomainArgsFromPosition(position: CellPosition): (CellValue | Matrix<CellValue> | undefined)[] | undefined;
4275
+ getPivotDomainArgsFromPosition(position: CellPosition): {
4276
+ domainArgs: string[] | undefined;
4277
+ isHeader: boolean;
4278
+ } | {
4279
+ domainArgs: (CellValue | Matrix<CellValue> | undefined)[];
4280
+ isHeader: boolean;
4281
+ } | undefined;
4276
4282
  getPivot(pivotId: UID): Pivot<PivotRuntimeDefinition>;
4277
4283
  isPivotUnused(pivotId: UID): boolean;
4278
4284
  /**
@@ -5138,6 +5144,7 @@ type Getters = {
5138
5144
  type ArgType = "ANY" | "BOOLEAN" | "NUMBER" | "STRING" | "DATE" | "RANGE" | "RANGE<BOOLEAN>" | "RANGE<NUMBER>" | "RANGE<DATE>" | "RANGE<STRING>" | "RANGE<ANY>" | "META";
5139
5145
  interface ArgDefinition {
5140
5146
  acceptMatrix?: boolean;
5147
+ acceptMatrixOnly?: boolean;
5141
5148
  repeating?: boolean;
5142
5149
  optional?: boolean;
5143
5150
  description: string;
@@ -6980,6 +6987,12 @@ declare class AxisDesignEditor extends Component<Props$O, SpreadsheetChildEnv> {
6980
6987
  Section: typeof Section;
6981
6988
  ChartTitle: typeof ChartTitle;
6982
6989
  };
6990
+ static props: {
6991
+ figureId: StringConstructor;
6992
+ definition: ObjectConstructor;
6993
+ updateChart: FunctionConstructor;
6994
+ axesList: ArrayConstructor;
6995
+ };
6983
6996
  state: {
6984
6997
  currentAxis: string;
6985
6998
  };
@@ -7043,6 +7056,12 @@ declare class ChartWithAxisDesignPanel extends Component<Props$M, SpreadsheetChi
7043
7056
  AxisDesignEditor: typeof AxisDesignEditor;
7044
7057
  RoundColorPicker: typeof RoundColorPicker;
7045
7058
  };
7059
+ static props: {
7060
+ figureId: StringConstructor;
7061
+ definition: ObjectConstructor;
7062
+ canUpdateChart: FunctionConstructor;
7063
+ updateChart: FunctionConstructor;
7064
+ };
7046
7065
  private state;
7047
7066
  get axesList(): AxisDefinition[];
7048
7067
  updateLegendPosition(ev: any): void;
@@ -7114,8 +7133,6 @@ declare class GaugeChartDesignPanel extends Component<Props$K, SpreadsheetChildE
7114
7133
  protected state: PanelState;
7115
7134
  setup(): void;
7116
7135
  get designErrorMessages(): string[];
7117
- updateBackgroundColor(color: Color): void;
7118
- updateTitle(content: string): void;
7119
7136
  isRangeMinInvalid(): boolean;
7120
7137
  isRangeMaxInvalid(): boolean;
7121
7138
  get isLowerInflectionPointInvalid(): boolean;
@@ -7123,7 +7140,6 @@ declare class GaugeChartDesignPanel extends Component<Props$K, SpreadsheetChildE
7123
7140
  updateSectionColor(target: string, color: Color): void;
7124
7141
  updateSectionRule(sectionRule: SectionRule): void;
7125
7142
  canUpdateSectionRule(sectionRule: SectionRule): void;
7126
- get backgroundColorTitle(): string;
7127
7143
  }
7128
7144
 
7129
7145
  declare class LineConfigPanel extends GenericChartConfigPanel {
@@ -7204,12 +7220,10 @@ declare class ScorecardChartDesignPanel extends Component<Props$I, SpreadsheetCh
7204
7220
  };
7205
7221
  get colorsSectionTitle(): string;
7206
7222
  get humanizeNumbersLabel(): string;
7207
- updateTitle(content: string): void;
7208
7223
  updateHumanizeNumbers(humanize: boolean): void;
7209
7224
  translate(term: any): string;
7210
7225
  updateBaselineDescr(ev: any): void;
7211
7226
  setColor(color: Color, colorPickerId: ColorPickerId): void;
7212
- get backgroundColorTitle(): string;
7213
7227
  }
7214
7228
 
7215
7229
  interface ChartSidePanel {