@odoo/o-spreadsheet 17.4.3 → 17.4.4

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.4
6
+ * @date 2024-08-09T12:24:07.798Z
7
+ * @hash a43e855
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';
@@ -10576,6 +10576,18 @@ function getDefinedAxis(definition) {
10576
10576
  useLeftAxis ||= !useRightAxis;
10577
10577
  return { useLeftAxis, useRightAxis };
10578
10578
  }
10579
+ function formatTickValue(localeFormat) {
10580
+ return (value) => {
10581
+ value = Number(value);
10582
+ if (isNaN(value))
10583
+ return value;
10584
+ const { locale, format } = localeFormat;
10585
+ return formatValue(value, {
10586
+ locale,
10587
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
10588
+ });
10589
+ };
10590
+ }
10579
10591
 
10580
10592
  /** This is a chartJS plugin that will draw the values of each data next to the point/bar/pie slice */
10581
10593
  const chartShowValuesPlugin = {
@@ -19124,6 +19136,7 @@ const PIVOT_VALUE = {
19124
19136
  const pivot = this.getters.getPivot(pivotId);
19125
19137
  const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
19126
19138
  addPivotDependencies(this, coreDefinition);
19139
+ pivot.init({ reload: pivot.needsReevaluation });
19127
19140
  const error = pivot.assertIsValid({ throwOnError: false });
19128
19141
  if (error) {
19129
19142
  return error;
@@ -19152,6 +19165,7 @@ const PIVOT_HEADER = {
19152
19165
  const pivot = this.getters.getPivot(_pivotId);
19153
19166
  const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
19154
19167
  addPivotDependencies(this, coreDefinition);
19168
+ pivot.init({ reload: pivot.needsReevaluation });
19155
19169
  const error = pivot.assertIsValid({ throwOnError: false });
19156
19170
  if (error) {
19157
19171
  return error;
@@ -20369,14 +20383,6 @@ for (let category of categories) {
20369
20383
  }
20370
20384
  const notAvailableError = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
20371
20385
  function createComputeFunction(descr, functionName) {
20372
- function runtimeCompute(...args) {
20373
- try {
20374
- return vectorizedCompute.apply(this, args);
20375
- }
20376
- catch (e) {
20377
- return handleError(e, functionName);
20378
- }
20379
- }
20380
20386
  function vectorizedCompute(...args) {
20381
20387
  let countVectorizableCol = 1;
20382
20388
  let countVectorizableRow = 1;
@@ -20417,13 +20423,13 @@ function createComputeFunction(descr, functionName) {
20417
20423
  }
20418
20424
  }
20419
20425
  if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
20420
- throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
20426
+ throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
20421
20427
  }
20422
20428
  }
20423
20429
  //#endregion
20424
20430
  if (countVectorizableCol === 1 && countVectorizableRow === 1) {
20425
20431
  // either this function is not vectorized or it ends up with a 1x1 dimension
20426
- return computeFunctionToObject.apply(this, args);
20432
+ return errorHandlingCompute.apply(this, args);
20427
20433
  }
20428
20434
  const getArgOffset = (i, j) => args.map((arg, index) => {
20429
20435
  switch (vectorArgsType?.[index]) {
@@ -20441,7 +20447,7 @@ function createComputeFunction(descr, functionName) {
20441
20447
  if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
20442
20448
  return notAvailableError;
20443
20449
  }
20444
- const singleCellComputeResult = computeFunctionToObject.apply(this, getArgOffset(col, row));
20450
+ const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
20445
20451
  // In the case where the user tries to vectorize arguments of an array formula, we will get an
20446
20452
  // array for every combination of the vectorized arguments, which will lead to a 3D matrix and
20447
20453
  // we won't be able to return the values.
@@ -20456,6 +20462,14 @@ function createComputeFunction(descr, functionName) {
20456
20462
  : singleCellComputeResult;
20457
20463
  });
20458
20464
  }
20465
+ function errorHandlingCompute(...args) {
20466
+ try {
20467
+ return computeFunctionToObject.apply(this, args);
20468
+ }
20469
+ catch (e) {
20470
+ return handleError(e, functionName);
20471
+ }
20472
+ }
20459
20473
  function computeFunctionToObject(...args) {
20460
20474
  const result = descr.compute.apply(this, args);
20461
20475
  if (!isMatrix(result)) {
@@ -20471,7 +20485,7 @@ function createComputeFunction(descr, functionName) {
20471
20485
  }
20472
20486
  return matrixMap(result, (row) => ({ value: row }));
20473
20487
  }
20474
- return runtimeCompute;
20488
+ return vectorizedCompute;
20475
20489
  }
20476
20490
  function handleError(e, functionName) {
20477
20491
  // the error could be an user error (instance of EvaluationError)
@@ -23692,23 +23706,13 @@ function getBarConfiguration(chart, labels, localeFormat) {
23692
23706
  padding: { left: 20, right: 20, top: chart.title ? 10 : 25, bottom: 10 },
23693
23707
  };
23694
23708
  config.options.indexAxis = chart.horizontal ? "y" : "x";
23695
- const formatCallback = (value) => {
23696
- value = Number(value);
23697
- if (isNaN(value))
23698
- return value;
23699
- const { locale, format } = localeFormat;
23700
- return formatValue(value, {
23701
- locale,
23702
- format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
23703
- });
23704
- };
23705
23709
  config.options.scales = {};
23706
23710
  const labelsAxis = { ticks: { padding: 5, color: fontColor } };
23707
23711
  const valuesAxis = {
23708
23712
  beginAtZero: true, // the origin of the y axis is always zero
23709
23713
  ticks: {
23710
23714
  color: fontColor,
23711
- callback: formatCallback,
23715
+ callback: formatTickValue(localeFormat),
23712
23716
  },
23713
23717
  };
23714
23718
  const xAxis = chart.horizontal ? valuesAxis : labelsAxis;
@@ -23745,7 +23749,7 @@ function getBarConfiguration(chart, labels, localeFormat) {
23745
23749
  showValues: chart.showValues,
23746
23750
  background: chart.background,
23747
23751
  horizontal: chart.horizontal,
23748
- callback: formatCallback,
23752
+ callback: formatTickValue(localeFormat),
23749
23753
  };
23750
23754
  return config;
23751
23755
  }
@@ -24024,21 +24028,11 @@ function getLineOrScatterConfiguration(chart, labels, options) {
24024
24028
  title: getChartAxisTitleRuntime(chart.axesDesign?.x),
24025
24029
  },
24026
24030
  };
24027
- const formatCallback = (value) => {
24028
- value = Number(value);
24029
- if (isNaN(value))
24030
- return value;
24031
- const { locale, format } = options;
24032
- return formatValue(value, {
24033
- locale,
24034
- format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
24035
- });
24036
- };
24037
24031
  const yAxis = {
24038
24032
  beginAtZero: true, // the origin of the y axis is always zero
24039
24033
  ticks: {
24040
24034
  color: fontColor,
24041
- callback: formatCallback,
24035
+ callback: formatTickValue(options),
24042
24036
  },
24043
24037
  };
24044
24038
  const { useLeftAxis, useRightAxis } = getDefinedAxis(chart.getDefinition());
@@ -24069,7 +24063,7 @@ function getLineOrScatterConfiguration(chart, labels, options) {
24069
24063
  config.options.plugins.chartShowValuesPlugin = {
24070
24064
  showValues: chart.showValues,
24071
24065
  background: chart.background,
24072
- callback: formatCallback,
24066
+ callback: formatTickValue(options),
24073
24067
  };
24074
24068
  return config;
24075
24069
  }
@@ -24344,30 +24338,18 @@ function createComboChartRuntime(chart, getters) {
24344
24338
  title: getChartAxisTitleRuntime(chart.axesDesign?.x),
24345
24339
  },
24346
24340
  };
24347
- const formatCallback = (format) => {
24348
- return (value) => {
24349
- value = Number(value);
24350
- if (isNaN(value))
24351
- return value;
24352
- const { locale } = localeFormat;
24353
- return formatValue(value, {
24354
- locale,
24355
- format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
24356
- });
24357
- };
24358
- };
24359
24341
  const leftVerticalAxis = {
24360
24342
  beginAtZero: true, // the origin of the y axis is always zero
24361
24343
  ticks: {
24362
24344
  color: fontColor,
24363
- callback: formatCallback(mainDataSetFormat),
24345
+ callback: formatTickValue({ format: mainDataSetFormat, locale }),
24364
24346
  },
24365
24347
  };
24366
24348
  const rightVerticalAxis = {
24367
24349
  beginAtZero: true, // the origin of the y axis is always zero
24368
24350
  ticks: {
24369
24351
  color: fontColor,
24370
- callback: formatCallback(lineDataSetsFormat),
24352
+ callback: formatTickValue({ format: lineDataSetsFormat, locale }),
24371
24353
  },
24372
24354
  };
24373
24355
  const definition = chart.getDefinition();
@@ -24392,7 +24374,7 @@ function createComboChartRuntime(chart, getters) {
24392
24374
  config.options.plugins.chartShowValuesPlugin = {
24393
24375
  showValues: chart.showValues,
24394
24376
  background: chart.background,
24395
- callback: formatCallback(mainDataSetFormat),
24377
+ callback: formatTickValue({ format: mainDataSetFormat, locale }),
24396
24378
  };
24397
24379
  const colors = new ColorGenerator();
24398
24380
  for (let [index, { label, data }] of dataSetsValues.entries()) {
@@ -24924,7 +24906,10 @@ function getPieConfiguration(chart, labels, localeFormat) {
24924
24906
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
24925
24907
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
24926
24908
  };
24927
- config.options.plugins.chartShowValuesPlugin = { showValues: chart.showValues };
24909
+ config.options.plugins.chartShowValuesPlugin = {
24910
+ showValues: chart.showValues,
24911
+ callback: formatTickValue(localeFormat),
24912
+ };
24928
24913
  return config;
24929
24914
  }
24930
24915
  function getPieColors(colors, dataSetsValues) {
@@ -25508,6 +25493,7 @@ function getWaterfallConfiguration(chart, labels, dataSeriesLabels, localeFormat
25508
25493
  config.options.plugins.chartShowValuesPlugin = {
25509
25494
  showValues: chart.showValues,
25510
25495
  background: chart.background,
25496
+ callback: formatTickValue(localeFormat),
25511
25497
  };
25512
25498
  return config;
25513
25499
  }
@@ -50412,7 +50398,7 @@ class RangeAdapter {
50412
50398
  * @param sheetXC the string description of a range, in the form SheetName!XC:XC
50413
50399
  */
50414
50400
  getRangeFromSheetXC(defaultSheetId, sheetXC) {
50415
- if (!rangeReference.test(sheetXC)) {
50401
+ if (!rangeReference.test(sheetXC) || !this.getters.tryGetSheet(defaultSheetId)) {
50416
50402
  return new RangeImpl({
50417
50403
  sheetId: "",
50418
50404
  zone: { left: -1, top: -1, right: -1, bottom: -1 },
@@ -54065,18 +54051,23 @@ class Evaluator {
54065
54051
  this.evaluate(this.getAllCells());
54066
54052
  console.info("evaluate all cells", performance.now() - start, "ms");
54067
54053
  }
54068
- evaluateFormula(sheetId, formulaString) {
54069
- const compiledFormula = compile(formulaString);
54070
- const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
54071
- this.updateCompilationParameters();
54072
- const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
54073
- if (isMatrix(result)) {
54074
- return matrixMap(result, (cell) => cell.value);
54054
+ evaluateFormulaResult(sheetId, formulaString) {
54055
+ try {
54056
+ const compiledFormula = compile(formulaString);
54057
+ const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
54058
+ this.updateCompilationParameters();
54059
+ const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
54060
+ if (isMatrix(result)) {
54061
+ return result;
54062
+ }
54063
+ if (result.value === null) {
54064
+ return { value: 0, format: result.format };
54065
+ }
54066
+ return result;
54075
54067
  }
54076
- if (result.value === null) {
54077
- return 0;
54068
+ catch (error) {
54069
+ return handleError(error, "");
54078
54070
  }
54079
- return result.value;
54080
54071
  }
54081
54072
  getAllCells() {
54082
54073
  const positions = this.createEmptyPositionSet();
@@ -54439,6 +54430,7 @@ function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId
54439
54430
  class EvaluationPlugin extends UIPlugin {
54440
54431
  static getters = [
54441
54432
  "evaluateFormula",
54433
+ "evaluateFormulaResult",
54442
54434
  "getCorrespondingFormulaCell",
54443
54435
  "getRangeFormattedValues",
54444
54436
  "getRangeValues",
@@ -54498,12 +54490,14 @@ class EvaluationPlugin extends UIPlugin {
54498
54490
  // Getters
54499
54491
  // ---------------------------------------------------------------------------
54500
54492
  evaluateFormula(sheetId, formulaString) {
54501
- try {
54502
- return this.evaluator.evaluateFormula(sheetId, formulaString);
54503
- }
54504
- catch (error) {
54505
- return error.value || CellErrorType.GenericError;
54493
+ const result = this.evaluateFormulaResult(sheetId, formulaString);
54494
+ if (isMatrix(result)) {
54495
+ return matrixMap(result, (cell) => cell.value);
54506
54496
  }
54497
+ return result.value;
54498
+ }
54499
+ evaluateFormulaResult(sheetId, formulaString) {
54500
+ return this.evaluator.evaluateFormulaResult(sheetId, formulaString);
54507
54501
  }
54508
54502
  /**
54509
54503
  * Return the value of each cell in the range as they are displayed in the grid.
@@ -55886,28 +55880,33 @@ class PivotUIPlugin extends UIPlugin {
55886
55880
  const pivotRow = position.row - mainPosition.row;
55887
55881
  return pivotCells[pivotCol][pivotRow];
55888
55882
  }
55889
- if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
55890
- const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
55883
+ try {
55884
+ if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
55885
+ const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
55886
+ return {
55887
+ type: "MEASURE_HEADER",
55888
+ domain,
55889
+ measure: args.at(-1)?.toString() || "",
55890
+ };
55891
+ }
55892
+ else if (functionName === "PIVOT.HEADER") {
55893
+ const domain = pivot.parseArgsToPivotDomain(args.slice(1).map((value) => ({ value })));
55894
+ return {
55895
+ type: "HEADER",
55896
+ domain,
55897
+ };
55898
+ }
55899
+ const [measure, ...domainArgs] = args.slice(1);
55900
+ const domain = pivot.parseArgsToPivotDomain(domainArgs.map((value) => ({ value })));
55891
55901
  return {
55892
- type: "MEASURE_HEADER",
55902
+ type: "VALUE",
55893
55903
  domain,
55894
- measure: args.at(-1)?.toString() || "",
55904
+ measure: measure?.toString() || "",
55895
55905
  };
55896
55906
  }
55897
- else if (functionName === "PIVOT.HEADER") {
55898
- const domain = pivot.parseArgsToPivotDomain(args.slice(1).map((value) => ({ value })));
55899
- return {
55900
- type: "HEADER",
55901
- domain,
55902
- };
55907
+ catch (_) {
55908
+ return EMPTY_PIVOT_CELL;
55903
55909
  }
55904
- const [measure, ...domainArgs] = args.slice(1);
55905
- const domain = pivot.parseArgsToPivotDomain(domainArgs.map((value) => ({ value })));
55906
- return {
55907
- type: "VALUE",
55908
- domain,
55909
- measure: measure?.toString() || "",
55910
- };
55911
55910
  }
55912
55911
  getPivot(pivotId) {
55913
55912
  return this.pivots[pivotId];
@@ -57775,6 +57774,7 @@ class FormatPlugin extends UIPlugin {
57775
57774
  * evaluated and updated with the number type.
57776
57775
  */
57777
57776
  setDecimal(sheetId, zones, step) {
57777
+ const positionsByFormat = {};
57778
57778
  // Find the each cell with a number value and get the format
57779
57779
  for (const zone of recomputeZones(zones)) {
57780
57780
  for (const position of positions(zone)) {
@@ -57784,15 +57784,20 @@ class FormatPlugin extends UIPlugin {
57784
57784
  // of the format
57785
57785
  this.getters.getLocale();
57786
57786
  const newFormat = changeDecimalPlaces(numberFormat, step);
57787
- // Apply the new format on the whole zone
57788
- this.dispatch("SET_FORMATTING", {
57789
- sheetId,
57790
- target: [positionToZone(position)],
57791
- format: newFormat,
57792
- });
57787
+ positionsByFormat[newFormat] = positionsByFormat[newFormat] || [];
57788
+ positionsByFormat[newFormat].push(position);
57793
57789
  }
57794
57790
  }
57795
57791
  }
57792
+ // consolidate all positions with the same format in bigger zones
57793
+ for (const newFormat in positionsByFormat) {
57794
+ const zones = recomputeZones(positionsByFormat[newFormat].map((position) => positionToZone(position)));
57795
+ this.dispatch("SET_FORMATTING", {
57796
+ sheetId,
57797
+ format: newFormat,
57798
+ target: zones,
57799
+ });
57800
+ }
57796
57801
  }
57797
57802
  /**
57798
57803
  * Take a range of cells and return the format of the first cell containing a
@@ -68379,6 +68384,6 @@ const constants = {
68379
68384
  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 };
68380
68385
 
68381
68386
 
68382
- __info__.version = "17.4.3";
68383
- __info__.date = "2024-08-02T08:23:56.573Z";
68384
- __info__.hash = "40ecd1e";
68387
+ __info__.version = "17.4.4";
68388
+ __info__.date = "2024-08-09T12:24:07.798Z";
68389
+ __info__.hash = "a43e855";