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