@odoo/o-spreadsheet 17.4.3 → 17.4.5

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.3
6
- * @date 2024-08-02T08:23:56.573Z
7
- * @hash 40ecd1e
5
+ * @version 17.4.5
6
+ * @date 2024-08-19T08:12:00.492Z
7
+ * @hash 28579ad
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -2009,6 +2009,7 @@
2009
2009
  "UPDATE_CELL",
2010
2010
  "UPDATE_CELL_POSITION",
2011
2011
  "CLEAR_CELL",
2012
+ "CLEAR_CELLS",
2012
2013
  "DELETE_CONTENT",
2013
2014
  /** GRID SHAPE */
2014
2015
  "ADD_COLUMNS_ROWS",
@@ -6744,13 +6745,10 @@
6744
6745
  * Clear the clipped zones: remove the cells and clear the formatting
6745
6746
  */
6746
6747
  clearClippedZones(content) {
6747
- for (const row of content.cells) {
6748
- for (const cell of row) {
6749
- if (cell.cell) {
6750
- this.dispatch("CLEAR_CELL", cell.position);
6751
- }
6752
- }
6753
- }
6748
+ this.dispatch("CLEAR_CELLS", {
6749
+ sheetId: content.sheetId,
6750
+ target: content.zones,
6751
+ });
6754
6752
  this.dispatch("CLEAR_FORMATTING", {
6755
6753
  sheetId: content.sheetId,
6756
6754
  target: content.zones,
@@ -7718,7 +7716,7 @@
7718
7716
  }
7719
7717
  function parseTokens(tokens) {
7720
7718
  tokens = tokens.filter((x) => x.type !== "SPACE");
7721
- if (tokens[0].value === "=") {
7719
+ if (tokens[0]?.value === "=") {
7722
7720
  tokens.splice(0, 1);
7723
7721
  }
7724
7722
  const result = parseExpression(tokens);
@@ -9952,7 +9950,7 @@ stores.inject(MyMetaStore, storeInstance);
9952
9950
  if (pivotId && pivotCell.type !== "EMPTY" && !cell?.isFormula) {
9953
9951
  const formulaPivotId = this.getters.getPivotFormulaId(pivotId);
9954
9952
  const formula = createPivotFormula(formulaPivotId, pivotCell);
9955
- return formula.slice(1); // strip leading =
9953
+ return localizeFormula(formula, this.getters.getLocale()).slice(1); // strip leading =
9956
9954
  }
9957
9955
  }
9958
9956
  const range = this.getters.getRangeFromZone(sheetId, zone);
@@ -10577,6 +10575,18 @@ stores.inject(MyMetaStore, storeInstance);
10577
10575
  useLeftAxis ||= !useRightAxis;
10578
10576
  return { useLeftAxis, useRightAxis };
10579
10577
  }
10578
+ function formatTickValue(localeFormat) {
10579
+ return (value) => {
10580
+ value = Number(value);
10581
+ if (isNaN(value))
10582
+ return value;
10583
+ const { locale, format } = localeFormat;
10584
+ return formatValue(value, {
10585
+ locale,
10586
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
10587
+ });
10588
+ };
10589
+ }
10580
10590
 
10581
10591
  /** This is a chartJS plugin that will draw the values of each data next to the point/bar/pie slice */
10582
10592
  const chartShowValuesPlugin = {
@@ -19125,6 +19135,7 @@ stores.inject(MyMetaStore, storeInstance);
19125
19135
  const pivot = this.getters.getPivot(pivotId);
19126
19136
  const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
19127
19137
  addPivotDependencies(this, coreDefinition);
19138
+ pivot.init({ reload: pivot.needsReevaluation });
19128
19139
  const error = pivot.assertIsValid({ throwOnError: false });
19129
19140
  if (error) {
19130
19141
  return error;
@@ -19153,6 +19164,7 @@ stores.inject(MyMetaStore, storeInstance);
19153
19164
  const pivot = this.getters.getPivot(_pivotId);
19154
19165
  const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
19155
19166
  addPivotDependencies(this, coreDefinition);
19167
+ pivot.init({ reload: pivot.needsReevaluation });
19156
19168
  const error = pivot.assertIsValid({ throwOnError: false });
19157
19169
  if (error) {
19158
19170
  return error;
@@ -20370,14 +20382,6 @@ stores.inject(MyMetaStore, storeInstance);
20370
20382
  }
20371
20383
  const notAvailableError = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
20372
20384
  function createComputeFunction(descr, functionName) {
20373
- function runtimeCompute(...args) {
20374
- try {
20375
- return vectorizedCompute.apply(this, args);
20376
- }
20377
- catch (e) {
20378
- return handleError(e, functionName);
20379
- }
20380
- }
20381
20385
  function vectorizedCompute(...args) {
20382
20386
  let countVectorizableCol = 1;
20383
20387
  let countVectorizableRow = 1;
@@ -20418,13 +20422,13 @@ stores.inject(MyMetaStore, storeInstance);
20418
20422
  }
20419
20423
  }
20420
20424
  if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
20421
- throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
20425
+ throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
20422
20426
  }
20423
20427
  }
20424
20428
  //#endregion
20425
20429
  if (countVectorizableCol === 1 && countVectorizableRow === 1) {
20426
20430
  // either this function is not vectorized or it ends up with a 1x1 dimension
20427
- return computeFunctionToObject.apply(this, args);
20431
+ return errorHandlingCompute.apply(this, args);
20428
20432
  }
20429
20433
  const getArgOffset = (i, j) => args.map((arg, index) => {
20430
20434
  switch (vectorArgsType?.[index]) {
@@ -20442,7 +20446,7 @@ stores.inject(MyMetaStore, storeInstance);
20442
20446
  if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
20443
20447
  return notAvailableError;
20444
20448
  }
20445
- const singleCellComputeResult = computeFunctionToObject.apply(this, getArgOffset(col, row));
20449
+ const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
20446
20450
  // In the case where the user tries to vectorize arguments of an array formula, we will get an
20447
20451
  // array for every combination of the vectorized arguments, which will lead to a 3D matrix and
20448
20452
  // we won't be able to return the values.
@@ -20457,6 +20461,14 @@ stores.inject(MyMetaStore, storeInstance);
20457
20461
  : singleCellComputeResult;
20458
20462
  });
20459
20463
  }
20464
+ function errorHandlingCompute(...args) {
20465
+ try {
20466
+ return computeFunctionToObject.apply(this, args);
20467
+ }
20468
+ catch (e) {
20469
+ return handleError(e, functionName);
20470
+ }
20471
+ }
20460
20472
  function computeFunctionToObject(...args) {
20461
20473
  const result = descr.compute.apply(this, args);
20462
20474
  if (!isMatrix(result)) {
@@ -20472,7 +20484,7 @@ stores.inject(MyMetaStore, storeInstance);
20472
20484
  }
20473
20485
  return matrixMap(result, (row) => ({ value: row }));
20474
20486
  }
20475
- return runtimeCompute;
20487
+ return vectorizedCompute;
20476
20488
  }
20477
20489
  function handleError(e, functionName) {
20478
20490
  // the error could be an user error (instance of EvaluationError)
@@ -23693,23 +23705,13 @@ stores.inject(MyMetaStore, storeInstance);
23693
23705
  padding: { left: 20, right: 20, top: chart.title ? 10 : 25, bottom: 10 },
23694
23706
  };
23695
23707
  config.options.indexAxis = chart.horizontal ? "y" : "x";
23696
- const formatCallback = (value) => {
23697
- value = Number(value);
23698
- if (isNaN(value))
23699
- return value;
23700
- const { locale, format } = localeFormat;
23701
- return formatValue(value, {
23702
- locale,
23703
- format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
23704
- });
23705
- };
23706
23708
  config.options.scales = {};
23707
23709
  const labelsAxis = { ticks: { padding: 5, color: fontColor } };
23708
23710
  const valuesAxis = {
23709
23711
  beginAtZero: true, // the origin of the y axis is always zero
23710
23712
  ticks: {
23711
23713
  color: fontColor,
23712
- callback: formatCallback,
23714
+ callback: formatTickValue(localeFormat),
23713
23715
  },
23714
23716
  };
23715
23717
  const xAxis = chart.horizontal ? valuesAxis : labelsAxis;
@@ -23746,7 +23748,7 @@ stores.inject(MyMetaStore, storeInstance);
23746
23748
  showValues: chart.showValues,
23747
23749
  background: chart.background,
23748
23750
  horizontal: chart.horizontal,
23749
- callback: formatCallback,
23751
+ callback: formatTickValue(localeFormat),
23750
23752
  };
23751
23753
  return config;
23752
23754
  }
@@ -24025,21 +24027,11 @@ stores.inject(MyMetaStore, storeInstance);
24025
24027
  title: getChartAxisTitleRuntime(chart.axesDesign?.x),
24026
24028
  },
24027
24029
  };
24028
- const formatCallback = (value) => {
24029
- value = Number(value);
24030
- if (isNaN(value))
24031
- return value;
24032
- const { locale, format } = options;
24033
- return formatValue(value, {
24034
- locale,
24035
- format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
24036
- });
24037
- };
24038
24030
  const yAxis = {
24039
24031
  beginAtZero: true, // the origin of the y axis is always zero
24040
24032
  ticks: {
24041
24033
  color: fontColor,
24042
- callback: formatCallback,
24034
+ callback: formatTickValue(options),
24043
24035
  },
24044
24036
  };
24045
24037
  const { useLeftAxis, useRightAxis } = getDefinedAxis(chart.getDefinition());
@@ -24070,7 +24062,7 @@ stores.inject(MyMetaStore, storeInstance);
24070
24062
  config.options.plugins.chartShowValuesPlugin = {
24071
24063
  showValues: chart.showValues,
24072
24064
  background: chart.background,
24073
- callback: formatCallback,
24065
+ callback: formatTickValue(options),
24074
24066
  };
24075
24067
  return config;
24076
24068
  }
@@ -24345,30 +24337,18 @@ stores.inject(MyMetaStore, storeInstance);
24345
24337
  title: getChartAxisTitleRuntime(chart.axesDesign?.x),
24346
24338
  },
24347
24339
  };
24348
- const formatCallback = (format) => {
24349
- return (value) => {
24350
- value = Number(value);
24351
- if (isNaN(value))
24352
- return value;
24353
- const { locale } = localeFormat;
24354
- return formatValue(value, {
24355
- locale,
24356
- format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
24357
- });
24358
- };
24359
- };
24360
24340
  const leftVerticalAxis = {
24361
24341
  beginAtZero: true, // the origin of the y axis is always zero
24362
24342
  ticks: {
24363
24343
  color: fontColor,
24364
- callback: formatCallback(mainDataSetFormat),
24344
+ callback: formatTickValue({ format: mainDataSetFormat, locale }),
24365
24345
  },
24366
24346
  };
24367
24347
  const rightVerticalAxis = {
24368
24348
  beginAtZero: true, // the origin of the y axis is always zero
24369
24349
  ticks: {
24370
24350
  color: fontColor,
24371
- callback: formatCallback(lineDataSetsFormat),
24351
+ callback: formatTickValue({ format: lineDataSetsFormat, locale }),
24372
24352
  },
24373
24353
  };
24374
24354
  const definition = chart.getDefinition();
@@ -24393,7 +24373,7 @@ stores.inject(MyMetaStore, storeInstance);
24393
24373
  config.options.plugins.chartShowValuesPlugin = {
24394
24374
  showValues: chart.showValues,
24395
24375
  background: chart.background,
24396
- callback: formatCallback(mainDataSetFormat),
24376
+ callback: formatTickValue({ format: mainDataSetFormat, locale }),
24397
24377
  };
24398
24378
  const colors = new ColorGenerator();
24399
24379
  for (let [index, { label, data }] of dataSetsValues.entries()) {
@@ -24925,7 +24905,10 @@ stores.inject(MyMetaStore, storeInstance);
24925
24905
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
24926
24906
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
24927
24907
  };
24928
- config.options.plugins.chartShowValuesPlugin = { showValues: chart.showValues };
24908
+ config.options.plugins.chartShowValuesPlugin = {
24909
+ showValues: chart.showValues,
24910
+ callback: formatTickValue(localeFormat),
24911
+ };
24929
24912
  return config;
24930
24913
  }
24931
24914
  function getPieColors(colors, dataSetsValues) {
@@ -25509,6 +25492,7 @@ stores.inject(MyMetaStore, storeInstance);
25509
25492
  config.options.plugins.chartShowValuesPlugin = {
25510
25493
  showValues: chart.showValues,
25511
25494
  background: chart.background,
25495
+ callback: formatTickValue(localeFormat),
25512
25496
  };
25513
25497
  return config;
25514
25498
  }
@@ -44369,6 +44353,7 @@ stores.inject(MyMetaStore, storeInstance);
44369
44353
  return {
44370
44354
  dataRange: convertExcelRangeToSheetXC(data.range, dataSetsHaveTitle),
44371
44355
  label,
44356
+ backgroundColor: data.backgroundColor,
44372
44357
  };
44373
44358
  });
44374
44359
  // For doughnut charts, in chartJS first dataset = outer dataset, in excel first dataset = inner dataset
@@ -45562,11 +45547,13 @@ stores.inject(MyMetaStore, storeInstance);
45562
45547
  label = { text };
45563
45548
  }
45564
45549
  }
45550
+ const color = this.extractChildAttr(chartDataElement, "c:spPr a:solidFill a:srgbClr", "val");
45565
45551
  return {
45566
45552
  label,
45567
45553
  range: this.extractChildTextContent(chartDataElement, "c:val c:f", {
45568
45554
  required: true,
45569
45555
  }),
45556
+ backgroundColor: color ? `${toHex(color.asString())}` : undefined,
45570
45557
  };
45571
45558
  });
45572
45559
  })
@@ -47772,6 +47759,9 @@ stores.inject(MyMetaStore, storeInstance);
47772
47759
  format: "",
47773
47760
  });
47774
47761
  break;
47762
+ case "CLEAR_CELLS":
47763
+ this.clearCells(cmd.sheetId, cmd.target);
47764
+ break;
47775
47765
  case "DELETE_CONTENT":
47776
47766
  this.clearZones(cmd.sheetId, cmd.target);
47777
47767
  break;
@@ -47830,6 +47820,25 @@ stores.inject(MyMetaStore, storeInstance);
47830
47820
  }
47831
47821
  }
47832
47822
  }
47823
+ /**
47824
+ * Clear the styles, the format and the content of zones
47825
+ */
47826
+ clearCells(sheetId, zones) {
47827
+ for (const zone of zones) {
47828
+ for (let col = zone.left; col <= zone.right; col++) {
47829
+ for (let row = zone.top; row <= zone.bottom; row++) {
47830
+ this.dispatch("UPDATE_CELL", {
47831
+ sheetId: sheetId,
47832
+ col,
47833
+ row,
47834
+ content: "",
47835
+ style: null,
47836
+ format: "",
47837
+ });
47838
+ }
47839
+ }
47840
+ }
47841
+ }
47833
47842
  /**
47834
47843
  * Copy the style of the reference column/row to the new columns/rows.
47835
47844
  */
@@ -50413,7 +50422,7 @@ stores.inject(MyMetaStore, storeInstance);
50413
50422
  * @param sheetXC the string description of a range, in the form SheetName!XC:XC
50414
50423
  */
50415
50424
  getRangeFromSheetXC(defaultSheetId, sheetXC) {
50416
- if (!rangeReference.test(sheetXC)) {
50425
+ if (!rangeReference.test(sheetXC) || !this.getters.tryGetSheet(defaultSheetId)) {
50417
50426
  return new RangeImpl({
50418
50427
  sheetId: "",
50419
50428
  zone: { left: -1, top: -1, right: -1, bottom: -1 },
@@ -51290,19 +51299,23 @@ stores.inject(MyMetaStore, storeInstance);
51290
51299
  }
51291
51300
  }
51292
51301
  moveCellOnColumnsDeletion(sheet, deletedColumn) {
51302
+ this.dispatch("CLEAR_CELLS", {
51303
+ sheetId: sheet.id,
51304
+ target: [
51305
+ {
51306
+ left: deletedColumn,
51307
+ top: 0,
51308
+ right: deletedColumn,
51309
+ bottom: sheet.rows.length - 1,
51310
+ },
51311
+ ],
51312
+ });
51293
51313
  for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
51294
51314
  const row = sheet.rows[rowIndex];
51295
51315
  for (let i in row.cells) {
51296
51316
  const colIndex = Number(i);
51297
51317
  const cellId = row.cells[i];
51298
51318
  if (cellId) {
51299
- if (colIndex === deletedColumn) {
51300
- this.dispatch("CLEAR_CELL", {
51301
- sheetId: sheet.id,
51302
- col: colIndex,
51303
- row: rowIndex,
51304
- });
51305
- }
51306
51319
  if (colIndex > deletedColumn) {
51307
51320
  this.setNewPosition(cellId, sheet.id, colIndex - 1, rowIndex);
51308
51321
  }
@@ -51348,22 +51361,20 @@ stores.inject(MyMetaStore, storeInstance);
51348
51361
  *
51349
51362
  */
51350
51363
  moveCellOnRowsDeletion(sheet, deleteFromRow, deleteToRow) {
51364
+ this.dispatch("CLEAR_CELLS", {
51365
+ sheetId: sheet.id,
51366
+ target: [
51367
+ {
51368
+ left: 0,
51369
+ top: deleteFromRow,
51370
+ right: this.getters.getNumberCols(sheet.id),
51371
+ bottom: deleteToRow,
51372
+ },
51373
+ ],
51374
+ });
51351
51375
  const numberRows = deleteToRow - deleteFromRow + 1;
51352
51376
  for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
51353
51377
  const row = sheet.rows[rowIndex];
51354
- if (rowIndex >= deleteFromRow && rowIndex <= deleteToRow) {
51355
- for (let i in row.cells) {
51356
- const colIndex = Number(i);
51357
- const cellId = row.cells[i];
51358
- if (cellId) {
51359
- this.dispatch("CLEAR_CELL", {
51360
- sheetId: sheet.id,
51361
- col: colIndex,
51362
- row: rowIndex,
51363
- });
51364
- }
51365
- }
51366
- }
51367
51378
  if (rowIndex > deleteToRow) {
51368
51379
  for (let i in row.cells) {
51369
51380
  const colIndex = Number(i);
@@ -54066,18 +54077,23 @@ stores.inject(MyMetaStore, storeInstance);
54066
54077
  this.evaluate(this.getAllCells());
54067
54078
  console.info("evaluate all cells", performance.now() - start, "ms");
54068
54079
  }
54069
- evaluateFormula(sheetId, formulaString) {
54070
- const compiledFormula = compile(formulaString);
54071
- const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
54072
- this.updateCompilationParameters();
54073
- const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
54074
- if (isMatrix(result)) {
54075
- return matrixMap(result, (cell) => cell.value);
54080
+ evaluateFormulaResult(sheetId, formulaString) {
54081
+ try {
54082
+ const compiledFormula = compile(formulaString);
54083
+ const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
54084
+ this.updateCompilationParameters();
54085
+ const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
54086
+ if (isMatrix(result)) {
54087
+ return result;
54088
+ }
54089
+ if (result.value === null) {
54090
+ return { value: 0, format: result.format };
54091
+ }
54092
+ return result;
54076
54093
  }
54077
- if (result.value === null) {
54078
- return 0;
54094
+ catch (error) {
54095
+ return handleError(error, "");
54079
54096
  }
54080
- return result.value;
54081
54097
  }
54082
54098
  getAllCells() {
54083
54099
  const positions = this.createEmptyPositionSet();
@@ -54440,6 +54456,7 @@ stores.inject(MyMetaStore, storeInstance);
54440
54456
  class EvaluationPlugin extends UIPlugin {
54441
54457
  static getters = [
54442
54458
  "evaluateFormula",
54459
+ "evaluateFormulaResult",
54443
54460
  "getCorrespondingFormulaCell",
54444
54461
  "getRangeFormattedValues",
54445
54462
  "getRangeValues",
@@ -54499,12 +54516,14 @@ stores.inject(MyMetaStore, storeInstance);
54499
54516
  // Getters
54500
54517
  // ---------------------------------------------------------------------------
54501
54518
  evaluateFormula(sheetId, formulaString) {
54502
- try {
54503
- return this.evaluator.evaluateFormula(sheetId, formulaString);
54504
- }
54505
- catch (error) {
54506
- return error.value || CellErrorType.GenericError;
54519
+ const result = this.evaluateFormulaResult(sheetId, formulaString);
54520
+ if (isMatrix(result)) {
54521
+ return matrixMap(result, (cell) => cell.value);
54507
54522
  }
54523
+ return result.value;
54524
+ }
54525
+ evaluateFormulaResult(sheetId, formulaString) {
54526
+ return this.evaluator.evaluateFormulaResult(sheetId, formulaString);
54508
54527
  }
54509
54528
  /**
54510
54529
  * Return the value of each cell in the range as they are displayed in the grid.
@@ -55775,6 +55794,10 @@ stores.inject(MyMetaStore, storeInstance);
55775
55794
  this.setupPivot(cmd.pivotId, { recreate: true });
55776
55795
  break;
55777
55796
  }
55797
+ case "REMOVE_PIVOT": {
55798
+ delete this.pivots[cmd.pivotId];
55799
+ break;
55800
+ }
55778
55801
  case "DELETE_SHEET":
55779
55802
  case "UPDATE_CELL": {
55780
55803
  this.unusedPivots = undefined;
@@ -55887,28 +55910,33 @@ stores.inject(MyMetaStore, storeInstance);
55887
55910
  const pivotRow = position.row - mainPosition.row;
55888
55911
  return pivotCells[pivotCol][pivotRow];
55889
55912
  }
55890
- if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
55891
- const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
55913
+ try {
55914
+ if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
55915
+ const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
55916
+ return {
55917
+ type: "MEASURE_HEADER",
55918
+ domain,
55919
+ measure: args.at(-1)?.toString() || "",
55920
+ };
55921
+ }
55922
+ else if (functionName === "PIVOT.HEADER") {
55923
+ const domain = pivot.parseArgsToPivotDomain(args.slice(1).map((value) => ({ value })));
55924
+ return {
55925
+ type: "HEADER",
55926
+ domain,
55927
+ };
55928
+ }
55929
+ const [measure, ...domainArgs] = args.slice(1);
55930
+ const domain = pivot.parseArgsToPivotDomain(domainArgs.map((value) => ({ value })));
55892
55931
  return {
55893
- type: "MEASURE_HEADER",
55932
+ type: "VALUE",
55894
55933
  domain,
55895
- measure: args.at(-1)?.toString() || "",
55934
+ measure: measure?.toString() || "",
55896
55935
  };
55897
55936
  }
55898
- else if (functionName === "PIVOT.HEADER") {
55899
- const domain = pivot.parseArgsToPivotDomain(args.slice(1).map((value) => ({ value })));
55900
- return {
55901
- type: "HEADER",
55902
- domain,
55903
- };
55937
+ catch (_) {
55938
+ return EMPTY_PIVOT_CELL;
55904
55939
  }
55905
- const [measure, ...domainArgs] = args.slice(1);
55906
- const domain = pivot.parseArgsToPivotDomain(domainArgs.map((value) => ({ value })));
55907
- return {
55908
- type: "VALUE",
55909
- domain,
55910
- measure: measure?.toString() || "",
55911
- };
55912
55940
  }
55913
55941
  getPivot(pivotId) {
55914
55942
  return this.pivots[pivotId];
@@ -57204,7 +57232,7 @@ stores.inject(MyMetaStore, storeInstance);
57204
57232
  */
57205
57233
  leave(data) {
57206
57234
  if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
57207
- this.snapshot(data);
57235
+ this.snapshot(data());
57208
57236
  }
57209
57237
  delete this.clients[this.clientId];
57210
57238
  this.transportService.leave(this.clientId);
@@ -57626,9 +57654,7 @@ stores.inject(MyMetaStore, storeInstance);
57626
57654
  if (!data) {
57627
57655
  return;
57628
57656
  }
57629
- for (const { col, row } of positions(zone)) {
57630
- this.dispatch("CLEAR_CELL", { col, row, sheetId });
57631
- }
57657
+ this.dispatch("CLEAR_CELLS", { target: [zone], sheetId });
57632
57658
  const zonePasted = {
57633
57659
  left: zone.left,
57634
57660
  top: zone.top,
@@ -57776,6 +57802,7 @@ stores.inject(MyMetaStore, storeInstance);
57776
57802
  * evaluated and updated with the number type.
57777
57803
  */
57778
57804
  setDecimal(sheetId, zones, step) {
57805
+ const positionsByFormat = {};
57779
57806
  // Find the each cell with a number value and get the format
57780
57807
  for (const zone of recomputeZones(zones)) {
57781
57808
  for (const position of positions(zone)) {
@@ -57785,15 +57812,20 @@ stores.inject(MyMetaStore, storeInstance);
57785
57812
  // of the format
57786
57813
  this.getters.getLocale();
57787
57814
  const newFormat = changeDecimalPlaces(numberFormat, step);
57788
- // Apply the new format on the whole zone
57789
- this.dispatch("SET_FORMATTING", {
57790
- sheetId,
57791
- target: [positionToZone(position)],
57792
- format: newFormat,
57793
- });
57815
+ positionsByFormat[newFormat] = positionsByFormat[newFormat] || [];
57816
+ positionsByFormat[newFormat].push(position);
57794
57817
  }
57795
57818
  }
57796
57819
  }
57820
+ // consolidate all positions with the same format in bigger zones
57821
+ for (const newFormat in positionsByFormat) {
57822
+ const zones = recomputeZones(positionsByFormat[newFormat].map((position) => positionToZone(position)));
57823
+ this.dispatch("SET_FORMATTING", {
57824
+ sheetId,
57825
+ format: newFormat,
57826
+ target: zones,
57827
+ });
57828
+ }
57797
57829
  }
57798
57830
  /**
57799
57831
  * Take a range of cells and return the format of the first cell containing a
@@ -58295,6 +58327,9 @@ stores.inject(MyMetaStore, storeInstance);
58295
58327
  if (showFormula && cell?.isFormula) {
58296
58328
  return localizeFormula(cell.content, this.getters.getLocale());
58297
58329
  }
58330
+ else if (showFormula && !cell?.content) {
58331
+ return "";
58332
+ }
58298
58333
  else {
58299
58334
  return this.getters.getEvaluatedCell(position).formattedValue;
58300
58335
  }
@@ -58793,6 +58828,7 @@ stores.inject(MyMetaStore, storeInstance);
58793
58828
  const repeatCommandTransformRegistry = new Registry();
58794
58829
  repeatCommandTransformRegistry.add("UPDATE_CELL", genericRepeat);
58795
58830
  repeatCommandTransformRegistry.add("CLEAR_CELL", genericRepeat);
58831
+ repeatCommandTransformRegistry.add("CLEAR_CELLS", genericRepeat);
58796
58832
  repeatCommandTransformRegistry.add("DELETE_CONTENT", genericRepeat);
58797
58833
  repeatCommandTransformRegistry.add("ADD_MERGE", genericRepeat);
58798
58834
  repeatCommandTransformRegistry.add("REMOVE_MERGE", genericRepeat);
@@ -59417,9 +59453,10 @@ stores.inject(MyMetaStore, storeInstance);
59417
59453
  case "DELETE_CELL": {
59418
59454
  const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
59419
59455
  if (!isZoneValid(cut[0])) {
59420
- for (const { col, row } of positions(cmd.zone)) {
59421
- this.dispatch("CLEAR_CELL", { col, row, sheetId: this.getters.getActiveSheetId() });
59422
- }
59456
+ this.dispatch("CLEAR_CELLS", {
59457
+ target: [cmd.zone],
59458
+ sheetId: this.getters.getActiveSheetId(),
59459
+ });
59423
59460
  break;
59424
59461
  }
59425
59462
  const copiedData = this.copy(cut);
@@ -67821,7 +67858,7 @@ stores.inject(MyMetaStore, storeInstance);
67821
67858
  this.session.join(this.config.client);
67822
67859
  }
67823
67860
  leaveSession() {
67824
- this.session.leave(this.exportData());
67861
+ this.session.leave(lazy(() => this.exportData()));
67825
67862
  }
67826
67863
  setupUiPlugin(Plugin) {
67827
67864
  const plugin = new Plugin(this.uiPluginConfig);
@@ -68423,9 +68460,9 @@ stores.inject(MyMetaStore, storeInstance);
68423
68460
  exports.tokenize = tokenize;
68424
68461
 
68425
68462
 
68426
- __info__.version = "17.4.3";
68427
- __info__.date = "2024-08-02T08:23:56.573Z";
68428
- __info__.hash = "40ecd1e";
68463
+ __info__.version = "17.4.5";
68464
+ __info__.date = "2024-08-19T08:12:00.492Z";
68465
+ __info__.hash = "28579ad";
68429
68466
 
68430
68467
 
68431
68468
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);