@odoo/o-spreadsheet 17.4.9 → 17.4.11

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.9
6
- * @date 2024-10-14T07:53:51.633Z
7
- * @hash b7015b7
5
+ * @version 17.4.11
6
+ * @date 2024-11-08T12:15:26.239Z
7
+ * @hash 2eb3f1c
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';
@@ -7625,7 +7625,10 @@ function parseOperand(tokens) {
7625
7625
  case "STRING":
7626
7626
  return { type: "STRING", value: removeStringQuotes(current.value) };
7627
7627
  case "INVALID_REFERENCE":
7628
- throw new InvalidReferenceError();
7628
+ return {
7629
+ type: "REFERENCE",
7630
+ value: CellErrorType.InvalidReference,
7631
+ };
7629
7632
  case "REFERENCE":
7630
7633
  if (tokens[0]?.value === ":" && tokens[1]?.type === "REFERENCE") {
7631
7634
  tokens.shift();
@@ -8429,6 +8432,7 @@ const ChartTerms = {
8429
8432
  StackedBarChart: _t("Stacked bar chart"),
8430
8433
  StackedLineChart: _t("Stacked line chart"),
8431
8434
  StackedAreaChart: _t("Stacked area chart"),
8435
+ StackedColumnChart: _t("Stacked column chart"),
8432
8436
  CumulativeData: _t("Cumulative data"),
8433
8437
  TreatLabelsAsText: _t("Treat labels as text"),
8434
8438
  AggregatedChart: _t("Aggregate"),
@@ -10623,67 +10627,112 @@ const chartShowValuesPlugin = {
10623
10627
  ctx.save();
10624
10628
  ctx.textAlign = "center";
10625
10629
  ctx.textBaseline = "middle";
10626
- ctx.fillStyle = chartFontColor(options.background);
10627
- ctx.strokeStyle = chartFontColor(ctx.fillStyle);
10628
- chart._metasets.forEach(function (dataset) {
10629
- switch (dataset.type) {
10630
- case "doughnut":
10631
- case "pie": {
10632
- for (let i = 0; i < dataset._parsed.length; i++) {
10633
- const bar = dataset.data[i];
10634
- const { startAngle, endAngle, innerRadius, outerRadius } = bar;
10635
- const midAngle = (startAngle + endAngle) / 2;
10636
- const midRadius = (innerRadius + outerRadius) / 2;
10637
- const x = bar.x + midRadius * Math.cos(midAngle);
10638
- const y = bar.y + midRadius * Math.sin(midAngle) + 7;
10639
- ctx.fillStyle = chartFontColor(bar.options.backgroundColor);
10640
- ctx.strokeStyle = chartFontColor(ctx.fillStyle);
10641
- const value = options.callback(dataset._parsed[i]);
10642
- ctx.strokeText(value, x, y);
10643
- ctx.fillText(value, x, y);
10644
- }
10645
- break;
10646
- }
10647
- case "bar":
10648
- case "line": {
10649
- const yOffset = dataset.type === "bar" && !options.horizontal ? 0 : 3;
10650
- for (let i = 0; i < dataset._parsed.length; i++) {
10651
- const point = dataset.data[i];
10652
- const value = options.horizontal ? dataset._parsed[i].x : dataset._parsed[i].y;
10653
- const displayedValue = options.callback(value - 0);
10654
- let xPosition = 0, yPosition = 0;
10655
- if (options.horizontal) {
10656
- yPosition = point.y;
10657
- if (value < 0) {
10658
- ctx.textAlign = "right";
10659
- xPosition = point.x - yOffset;
10660
- }
10661
- else {
10662
- ctx.textAlign = "left";
10663
- xPosition = point.x + yOffset;
10664
- }
10665
- }
10666
- else {
10667
- xPosition = point.x;
10668
- if (value < 0) {
10669
- ctx.textBaseline = "top";
10670
- yPosition = point.y + yOffset;
10671
- }
10672
- else {
10673
- ctx.textBaseline = "bottom";
10674
- yPosition = point.y - yOffset;
10675
- }
10676
- }
10677
- ctx.strokeText(displayedValue, xPosition, yPosition);
10678
- ctx.fillText(displayedValue, xPosition, yPosition);
10679
- }
10680
- break;
10681
- }
10682
- }
10683
- });
10630
+ ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
10631
+ switch (chart.config.type) {
10632
+ case "pie":
10633
+ case "doughnut":
10634
+ drawPieChartValues(chart, options, ctx);
10635
+ break;
10636
+ case "bar":
10637
+ case "line":
10638
+ options.horizontal
10639
+ ? drawHorizontalBarChartValues(chart, options, ctx)
10640
+ : drawLineOrBarChartValues(chart, options, ctx);
10641
+ break;
10642
+ }
10684
10643
  ctx.restore();
10685
10644
  },
10686
10645
  };
10646
+ function drawTextWithBackground(text, x, y, ctx) {
10647
+ ctx.lineWidth = 3; // Stroke the text with a big lineWidth width to have some kind of background
10648
+ ctx.strokeText(text, x, y);
10649
+ ctx.lineWidth = 1;
10650
+ ctx.fillText(text, x, y);
10651
+ }
10652
+ function drawLineOrBarChartValues(chart, options, ctx) {
10653
+ const yMax = chart.chartArea.bottom;
10654
+ const yMin = chart.chartArea.top;
10655
+ const textsPositions = {};
10656
+ for (const dataset of chart._metasets) {
10657
+ for (let i = 0; i < dataset._parsed.length; i++) {
10658
+ const value = dataset._parsed[i].y;
10659
+ const point = dataset.data[i];
10660
+ const xPosition = point.x;
10661
+ let yPosition = 0;
10662
+ if (chart.config.type === "line") {
10663
+ yPosition = point.y - 10;
10664
+ }
10665
+ else {
10666
+ yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
10667
+ }
10668
+ yPosition = Math.min(yPosition, yMax);
10669
+ yPosition = Math.max(yPosition, yMin);
10670
+ // Avoid overlapping texts with same X
10671
+ if (!textsPositions[xPosition]) {
10672
+ textsPositions[xPosition] = [];
10673
+ }
10674
+ for (const otherPosition of textsPositions[xPosition] || []) {
10675
+ if (Math.abs(otherPosition - yPosition) < 13) {
10676
+ yPosition = otherPosition - 13;
10677
+ }
10678
+ }
10679
+ textsPositions[xPosition].push(yPosition);
10680
+ ctx.fillStyle = point.options.backgroundColor;
10681
+ ctx.strokeStyle = options.background || "#ffffff";
10682
+ drawTextWithBackground(options.callback(value - 0), xPosition, yPosition, ctx);
10683
+ }
10684
+ }
10685
+ }
10686
+ function drawHorizontalBarChartValues(chart, options, ctx) {
10687
+ const xMax = chart.chartArea.right;
10688
+ const xMin = chart.chartArea.left;
10689
+ const textsPositions = {};
10690
+ for (const dataset of chart._metasets) {
10691
+ for (let i = 0; i < dataset._parsed.length; i++) {
10692
+ const value = dataset._parsed[i].x;
10693
+ const displayValue = options.callback(value - 0);
10694
+ const point = dataset.data[i];
10695
+ const yPosition = point.y;
10696
+ let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
10697
+ xPosition = Math.min(xPosition, xMax);
10698
+ xPosition = Math.max(xPosition, xMin);
10699
+ // Avoid overlapping texts with same Y
10700
+ if (!textsPositions[yPosition]) {
10701
+ textsPositions[yPosition] = [];
10702
+ }
10703
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
10704
+ for (const otherPosition of textsPositions[yPosition]) {
10705
+ if (Math.abs(otherPosition - xPosition) < textWidth) {
10706
+ xPosition = otherPosition + textWidth + 3;
10707
+ }
10708
+ }
10709
+ textsPositions[yPosition].push(xPosition);
10710
+ ctx.fillStyle = point.options.backgroundColor;
10711
+ ctx.strokeStyle = options.background || "#ffffff";
10712
+ drawTextWithBackground(displayValue, xPosition, yPosition, ctx);
10713
+ }
10714
+ }
10715
+ }
10716
+ function drawPieChartValues(chart, options, ctx) {
10717
+ for (const dataset of chart._metasets) {
10718
+ for (let i = 0; i < dataset._parsed.length; i++) {
10719
+ const value = Number(dataset._parsed[i]);
10720
+ if (isNaN(value) || value === 0) {
10721
+ continue;
10722
+ }
10723
+ const bar = dataset.data[i];
10724
+ const { startAngle, endAngle, innerRadius, outerRadius } = bar;
10725
+ const midAngle = (startAngle + endAngle) / 2;
10726
+ const midRadius = (innerRadius + outerRadius) / 2;
10727
+ const x = bar.x + midRadius * Math.cos(midAngle);
10728
+ const y = bar.y + midRadius * Math.sin(midAngle) + 7;
10729
+ ctx.fillStyle = chartFontColor(options.background);
10730
+ ctx.strokeStyle = options.background || "#ffffff";
10731
+ const displayValue = options.callback(value);
10732
+ drawTextWithBackground(displayValue, x, y, ctx);
10733
+ }
10734
+ }
10735
+ }
10687
10736
 
10688
10737
  /** This is a chartJS plugin that will draw connector lines between the bars of a Waterfall chart */
10689
10738
  const waterfallLinesPlugin = {
@@ -23413,7 +23462,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
23413
23462
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
23414
23463
  // tooltipItem.parsed can be an object or a number for pie charts
23415
23464
  let yLabel = horizontalChart ? tooltipItem.parsed.x : tooltipItem.parsed.y;
23416
- if (!yLabel) {
23465
+ if (yLabel === undefined || yLabel === null) {
23417
23466
  yLabel = tooltipItem.parsed;
23418
23467
  }
23419
23468
  const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
@@ -31584,6 +31633,12 @@ class GenericChartConfigPanel extends Component {
31584
31633
 
31585
31634
  class BarConfigPanel extends GenericChartConfigPanel {
31586
31635
  static template = "o-spreadsheet-BarConfigPanel";
31636
+ get stackedLabel() {
31637
+ const definition = this.props.definition;
31638
+ return definition.horizontal
31639
+ ? this.chartTerms.StackedBarChart
31640
+ : this.chartTerms.StackedColumnChart;
31641
+ }
31587
31642
  onUpdateStacked(stacked) {
31588
31643
  this.props.updateChart(this.props.figureId, {
31589
31644
  stacked,
@@ -32752,7 +32807,9 @@ class LineConfigPanel extends GenericChartConfigPanel {
32752
32807
  }
32753
32808
  get stackedLabel() {
32754
32809
  const definition = this.props.definition;
32755
- return definition.fillArea ? this.chartTerms.StackedAreaChart : this.chartTerms.StackedBarChart;
32810
+ return definition.fillArea
32811
+ ? this.chartTerms.StackedAreaChart
32812
+ : this.chartTerms.StackedLineChart;
32756
32813
  }
32757
32814
  getLabelRangeOptions() {
32758
32815
  const options = super.getLabelRangeOptions();
@@ -46530,7 +46587,7 @@ function load(data, verboseImport) {
46530
46587
  if (!data) {
46531
46588
  return createEmptyWorkbookData();
46532
46589
  }
46533
- console.group("Loading data");
46590
+ console.debug("### Loading data ###");
46534
46591
  const start = performance.now();
46535
46592
  if (data["[Content_Types].xml"]) {
46536
46593
  const reader = new XlsxReader(data);
@@ -46544,13 +46601,13 @@ function load(data, verboseImport) {
46544
46601
  // apply migrations, if needed
46545
46602
  if ("version" in data) {
46546
46603
  if (data.version < CURRENT_VERSION) {
46547
- console.info("Migrating data from version", data.version);
46604
+ console.debug("Migrating data from version", data.version);
46548
46605
  data = migrate(data);
46549
46606
  }
46550
46607
  }
46551
46608
  data = repairData(data);
46552
- console.info("Data loaded in", performance.now() - start, "ms");
46553
- console.groupEnd();
46609
+ console.debug("Data loaded in", performance.now() - start, "ms");
46610
+ console.debug("###");
46554
46611
  return data;
46555
46612
  }
46556
46613
  function migrate(data) {
@@ -46559,7 +46616,7 @@ function migrate(data) {
46559
46616
  for (let i = index; i < MIGRATIONS.length; i++) {
46560
46617
  data = MIGRATIONS[i].applyMigration(data);
46561
46618
  }
46562
- console.info("Data migrated in", performance.now() - start, "ms");
46619
+ console.debug("Data migrated in", performance.now() - start, "ms");
46563
46620
  return data;
46564
46621
  }
46565
46622
  const MIGRATIONS = [
@@ -54119,7 +54176,7 @@ class Evaluator {
54119
54176
  cellsToCompute.addMany(arrayFormulasPositions);
54120
54177
  cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositions));
54121
54178
  this.evaluate(cellsToCompute);
54122
- console.info("evaluate Cells", performance.now() - start, "ms");
54179
+ console.debug("evaluate Cells", performance.now() - start, "ms");
54123
54180
  }
54124
54181
  getArrayFormulasImpactedByChangesOf(positions) {
54125
54182
  const impactedPositions = this.createEmptyPositionSet();
@@ -54158,7 +54215,7 @@ class Evaluator {
54158
54215
  const start = performance.now();
54159
54216
  this.evaluatedCells = new PositionMap();
54160
54217
  this.evaluate(this.getAllCells());
54161
- console.info("evaluate all cells", performance.now() - start, "ms");
54218
+ console.debug("evaluate all cells", performance.now() - start, "ms");
54162
54219
  }
54163
54220
  evaluateFormulaResult(sheetId, formulaString) {
54164
54221
  try {
@@ -55980,6 +56037,10 @@ class PivotUIPlugin extends UIPlugin {
55980
56037
  if (!pivot.isValid()) {
55981
56038
  return EMPTY_PIVOT_CELL;
55982
56039
  }
56040
+ if (functionName === "PIVOT" &&
56041
+ !cell.content.replaceAll(" ", "").toUpperCase().startsWith("=PIVOT")) {
56042
+ return EMPTY_PIVOT_CELL;
56043
+ }
55983
56044
  if (functionName === "PIVOT") {
55984
56045
  const includeTotal = args[2] === false ? false : undefined;
55985
56046
  const includeColumnHeaders = args[3] === false ? false : undefined;
@@ -57308,7 +57369,7 @@ class Session extends EventBus {
57308
57369
  this.onMessageReceived(message);
57309
57370
  }
57310
57371
  this.isReplayingInitialRevisions = false;
57311
- console.info("Replayed", numberOfCommands, "commands in", performance.now() - start, "ms");
57372
+ console.debug("Replayed", numberOfCommands, "commands in", performance.now() - start, "ms");
57312
57373
  }
57313
57374
  /**
57314
57375
  * Notify the server that the user client left the collaborative session
@@ -66571,7 +66632,8 @@ function addFormula(cell) {
66571
66632
  }
66572
66633
  const attrs = [["t", type]];
66573
66634
  const XlsxFormula = adaptFormulaToExcel(formula);
66574
- const node = escapeXml /*xml*/ `<f>${XlsxFormula}</f><v>${cell.value}</v>`;
66635
+ const exportedValue = adaptFormulaValueToExcel(cell.value);
66636
+ const node = escapeXml /*xml*/ `<f>${XlsxFormula}</f><v>${exportedValue}</v>`;
66575
66637
  return { attrs, node };
66576
66638
  }
66577
66639
  function addContent(content, sharedStrings, forceString = false) {
@@ -66606,8 +66668,14 @@ function adaptFormulaToExcel(formulaText) {
66606
66668
  ast = addMissingRequiredArgs(ast);
66607
66669
  return ast;
66608
66670
  });
66671
+ ast = convertAstNodes(ast, "REFERENCE", (ast) => {
66672
+ return ast.value === CellErrorType.InvalidReference ? { ...ast, value: "#REF!" } : ast;
66673
+ });
66609
66674
  return ast ? astToFormula(ast) : formulaText;
66610
66675
  }
66676
+ function adaptFormulaValueToExcel(formulaValue) {
66677
+ return formulaValue === CellErrorType.InvalidReference ? "#REF!" : formulaValue;
66678
+ }
66611
66679
  /**
66612
66680
  * Some Excel function need required args that might not be mandatory in o-spreadsheet.
66613
66681
  * This adds those missing args.
@@ -67918,7 +67986,7 @@ class Model extends EventBus {
67918
67986
  coreHandlers = [];
67919
67987
  constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
67920
67988
  const start = performance.now();
67921
- console.group("Model creation");
67989
+ console.debug("##### Model creation #####");
67922
67990
  super();
67923
67991
  setDefaultTranslationMethod();
67924
67992
  stateUpdateMessages = repairInitialMessages(data, stateUpdateMessages);
@@ -67990,16 +68058,16 @@ class Model extends EventBus {
67990
68058
  this.joinSession();
67991
68059
  if (config.snapshotRequested) {
67992
68060
  const startSnapshot = performance.now();
67993
- console.info("Snapshot requested");
68061
+ console.debug("Snapshot requested");
67994
68062
  this.session.snapshot(this.exportData());
67995
68063
  this.garbageCollectExternalResources();
67996
- console.info("Snapshot taken in", performance.now() - startSnapshot, "ms");
68064
+ console.debug("Snapshot taken in", performance.now() - startSnapshot, "ms");
67997
68065
  }
67998
68066
  // mark all models as "raw", so they will not be turned into reactive objects
67999
68067
  // by owl, since we do not rely on reactivity
68000
68068
  markRaw(this);
68001
- console.info("Model created in", performance.now() - start, "ms");
68002
- console.groupEnd();
68069
+ console.debug("Model created in", performance.now() - start, "ms");
68070
+ console.debug("######");
68003
68071
  }
68004
68072
  joinSession() {
68005
68073
  this.session.join(this.config.client);
@@ -68222,7 +68290,7 @@ class Model extends EventBus {
68222
68290
  this.finalize();
68223
68291
  const time = performance.now() - start;
68224
68292
  if (time > 5) {
68225
- console.info(type, time, "ms");
68293
+ console.debug(type, time, "ms");
68226
68294
  }
68227
68295
  });
68228
68296
  this.session.save(command, commands, changes);
@@ -68565,6 +68633,6 @@ const constants = {
68565
68633
  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 };
68566
68634
 
68567
68635
 
68568
- __info__.version = "17.4.9";
68569
- __info__.date = "2024-10-14T07:53:51.633Z";
68570
- __info__.hash = "b7015b7";
68636
+ __info__.version = "17.4.11";
68637
+ __info__.date = "2024-11-08T12:15:26.239Z";
68638
+ __info__.hash = "2eb3f1c";