@odoo/o-spreadsheet 18.3.8 → 18.3.9

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 18.3.8
6
- * @date 2025-06-12T09:51:55.929Z
7
- * @hash 32dedd1
5
+ * @version 18.3.9
6
+ * @date 2025-06-19T18:24:02.754Z
7
+ * @hash a820230
8
8
  */
9
9
 
10
10
  'use strict';
@@ -20953,6 +20953,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20953
20953
  if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
20954
20954
  continue;
20955
20955
  }
20956
+ const yAxisScale = chart.scales[dataset.yAxisID];
20956
20957
  for (let i = 0; i < dataset._parsed.length; i++) {
20957
20958
  const parsedValue = dataset._parsed[i];
20958
20959
  const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
@@ -20963,10 +20964,18 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20963
20964
  const xPosition = point.x;
20964
20965
  let yPosition = 0;
20965
20966
  if (chart.config.type === "line" || chart.config.type === "radar") {
20966
- yPosition = point.y - 10;
20967
+ yPosition = value < 0 ? point.y + 10 : point.y - 10;
20967
20968
  }
20968
20969
  else {
20969
- yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
20970
+ const yZeroLine = yAxisScale.getPixelForValue(0);
20971
+ const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
20972
+ const textHeight = 12; // ChartJS default text height
20973
+ if (distanceFromAxisOrigin < textHeight) {
20974
+ yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
20975
+ }
20976
+ else {
20977
+ yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
20978
+ }
20970
20979
  }
20971
20980
  yPosition = Math.min(yPosition, yMax);
20972
20981
  yPosition = Math.max(yPosition, yMin);
@@ -20976,7 +20985,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20976
20985
  }
20977
20986
  for (const otherPosition of textsPositions[xPosition] || []) {
20978
20987
  if (Math.abs(otherPosition - yPosition) < 13) {
20979
- yPosition = otherPosition - 13;
20988
+ yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
20980
20989
  }
20981
20990
  }
20982
20991
  textsPositions[xPosition].push(yPosition);
@@ -20995,6 +21004,8 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
20995
21004
  if (isTrendLineAxis(dataset.xAxisID)) {
20996
21005
  return; // ignore trend lines
20997
21006
  }
21007
+ const xAxisScale = chart.scales[dataset.xAxisID];
21008
+ const xZeroLine = xAxisScale.getPixelForValue(0);
20998
21009
  for (let i = 0; i < dataset._parsed.length; i++) {
20999
21010
  const value = Number(dataset._parsed[i].x);
21000
21011
  if (isNaN(value)) {
@@ -21003,17 +21014,27 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
21003
21014
  const displayValue = options.callback(value, dataset, i);
21004
21015
  const point = dataset.data[i];
21005
21016
  const yPosition = point.y;
21006
- let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
21007
- xPosition = Math.min(xPosition, xMax);
21008
- xPosition = Math.max(xPosition, xMin);
21017
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
21018
+ const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
21019
+ const PADDING = 3;
21020
+ let xPosition;
21021
+ if (distanceFromAxisOrigin < textWidth) {
21022
+ xPosition =
21023
+ value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
21024
+ }
21025
+ else {
21026
+ xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
21027
+ xPosition = Math.min(xPosition, xMax);
21028
+ xPosition = Math.max(xPosition, xMin);
21029
+ }
21009
21030
  // Avoid overlapping texts with same Y
21010
21031
  if (!textsPositions[yPosition]) {
21011
21032
  textsPositions[yPosition] = [];
21012
21033
  }
21013
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
21014
21034
  for (const otherPosition of textsPositions[yPosition]) {
21015
21035
  if (Math.abs(otherPosition - xPosition) < textWidth) {
21016
- xPosition = otherPosition + textWidth + 3;
21036
+ xPosition =
21037
+ value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
21017
21038
  }
21018
21039
  }
21019
21040
  textsPositions[yPosition].push(xPosition);
@@ -26400,7 +26421,9 @@ function getPyramidChartShowValues(definition, args) {
26400
26421
  background: definition.background,
26401
26422
  callback: (value, dataset) => {
26402
26423
  value = Math.abs(Number(value));
26403
- return formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
26424
+ return value === 0
26425
+ ? ""
26426
+ : formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
26404
26427
  },
26405
26428
  };
26406
26429
  }
@@ -37133,6 +37156,10 @@ const REMOVE_ROWS_ACTION = (env) => {
37133
37156
  });
37134
37157
  };
37135
37158
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
37159
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
37160
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
37161
+ return false;
37162
+ }
37136
37163
  const sheetId = env.model.getters.getActiveSheetId();
37137
37164
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
37138
37165
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -40030,11 +40057,11 @@ class OTRegistry extends Registry {
40030
40057
  * transformation function given
40031
40058
  */
40032
40059
  addTransformation(executed, toTransforms, fn) {
40033
- for (let toTransform of toTransforms) {
40034
- if (!this.content[toTransform]) {
40035
- this.content[toTransform] = new Map();
40036
- }
40037
- this.content[toTransform].set(executed, fn);
40060
+ if (!this.content[executed]) {
40061
+ this.content[executed] = new Map();
40062
+ }
40063
+ for (const toTransform of toTransforms) {
40064
+ this.content[executed].set(toTransform, fn);
40038
40065
  }
40039
40066
  return this;
40040
40067
  }
@@ -40043,7 +40070,7 @@ class OTRegistry extends Registry {
40043
40070
  * that the executed command happened.
40044
40071
  */
40045
40072
  getTransformation(toTransform, executed) {
40046
- return this.content[toTransform] && this.content[toTransform].get(executed);
40073
+ return this.content[executed] && this.content[executed].get(toTransform);
40047
40074
  }
40048
40075
  }
40049
40076
  const otRegistry = new OTRegistry();
@@ -43333,6 +43360,12 @@ class Composer extends owl.Component {
43333
43360
  owl.useEffect(() => {
43334
43361
  this.processTokenAtCursor();
43335
43362
  }, () => [this.props.composerStore.editionMode !== "inactive"]);
43363
+ owl.useEffect(() => {
43364
+ this.contentHelper.scrollSelectionIntoView();
43365
+ }, () => [
43366
+ this.props.composerStore.composerSelection.start,
43367
+ this.props.composerStore.composerSelection.end,
43368
+ ]);
43336
43369
  }
43337
43370
  // ---------------------------------------------------------------------------
43338
43371
  // Handlers
@@ -43555,6 +43588,7 @@ class Composer extends owl.Component {
43555
43588
  // not main button, probably a context menu
43556
43589
  return;
43557
43590
  }
43591
+ this.debouncedHover.stopDebounce();
43558
43592
  this.contentHelper.removeSelection();
43559
43593
  }
43560
43594
  onMouseup() {
@@ -43633,7 +43667,6 @@ class Composer extends owl.Component {
43633
43667
  const { start, end } = this.props.composerStore.composerSelection;
43634
43668
  this.contentHelper.selectRange(start, end);
43635
43669
  }
43636
- this.contentHelper.scrollSelectionIntoView();
43637
43670
  }
43638
43671
  this.shouldProcessInputEvents = true;
43639
43672
  }
@@ -67778,10 +67811,20 @@ function adaptTransform(toTransform, executed) {
67778
67811
  */
67779
67812
  function transformAll(toTransform, executed) {
67780
67813
  let transformedCommands = [...toTransform];
67814
+ const possibleTransformations = new Set(otRegistry.getKeys());
67781
67815
  for (const executedCommand of executed) {
67782
- transformedCommands = transformedCommands
67783
- .map((cmd) => transform(cmd, executedCommand))
67784
- .filter(isDefined);
67816
+ // If the executed command is not in the registry, we skip it
67817
+ // because we know there won't be any transformation impacting the
67818
+ // commands to transform.
67819
+ if (possibleTransformations.has(executedCommand.type)) {
67820
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
67821
+ const transformed = transform(cmd, executedCommand);
67822
+ if (transformed) {
67823
+ acc.push(transformed);
67824
+ }
67825
+ return acc;
67826
+ }, []);
67827
+ }
67785
67828
  }
67786
67829
  return transformedCommands;
67787
67830
  }
@@ -69483,7 +69526,7 @@ class SheetUIPlugin extends UIPlugin {
69483
69526
  }
69484
69527
  const position = this.getters.getCellPosition(cell.id);
69485
69528
  const colSize = this.getters.getColSize(sheetId, position.col);
69486
- if (cell.isFormula) {
69529
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
69487
69530
  const content = this.getters.getEvaluatedCell(position).formattedValue;
69488
69531
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
69489
69532
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -80668,6 +80711,6 @@ exports.tokenColors = tokenColors;
80668
80711
  exports.tokenize = tokenize;
80669
80712
 
80670
80713
 
80671
- __info__.version = "18.3.8";
80672
- __info__.date = "2025-06-12T09:51:55.929Z";
80673
- __info__.hash = "32dedd1";
80714
+ __info__.version = "18.3.9";
80715
+ __info__.date = "2025-06-19T18:24:02.754Z";
80716
+ __info__.hash = "a820230";
@@ -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 18.3.8
6
- * @date 2025-06-12T09:51:55.929Z
7
- * @hash 32dedd1
5
+ * @version 18.3.9
6
+ * @date 2025-06-19T18:24:02.754Z
7
+ * @hash a820230
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -20951,6 +20951,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20951
20951
  if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
20952
20952
  continue;
20953
20953
  }
20954
+ const yAxisScale = chart.scales[dataset.yAxisID];
20954
20955
  for (let i = 0; i < dataset._parsed.length; i++) {
20955
20956
  const parsedValue = dataset._parsed[i];
20956
20957
  const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
@@ -20961,10 +20962,18 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20961
20962
  const xPosition = point.x;
20962
20963
  let yPosition = 0;
20963
20964
  if (chart.config.type === "line" || chart.config.type === "radar") {
20964
- yPosition = point.y - 10;
20965
+ yPosition = value < 0 ? point.y + 10 : point.y - 10;
20965
20966
  }
20966
20967
  else {
20967
- yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
20968
+ const yZeroLine = yAxisScale.getPixelForValue(0);
20969
+ const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
20970
+ const textHeight = 12; // ChartJS default text height
20971
+ if (distanceFromAxisOrigin < textHeight) {
20972
+ yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
20973
+ }
20974
+ else {
20975
+ yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
20976
+ }
20968
20977
  }
20969
20978
  yPosition = Math.min(yPosition, yMax);
20970
20979
  yPosition = Math.max(yPosition, yMin);
@@ -20974,7 +20983,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
20974
20983
  }
20975
20984
  for (const otherPosition of textsPositions[xPosition] || []) {
20976
20985
  if (Math.abs(otherPosition - yPosition) < 13) {
20977
- yPosition = otherPosition - 13;
20986
+ yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
20978
20987
  }
20979
20988
  }
20980
20989
  textsPositions[xPosition].push(yPosition);
@@ -20993,6 +21002,8 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
20993
21002
  if (isTrendLineAxis(dataset.xAxisID)) {
20994
21003
  return; // ignore trend lines
20995
21004
  }
21005
+ const xAxisScale = chart.scales[dataset.xAxisID];
21006
+ const xZeroLine = xAxisScale.getPixelForValue(0);
20996
21007
  for (let i = 0; i < dataset._parsed.length; i++) {
20997
21008
  const value = Number(dataset._parsed[i].x);
20998
21009
  if (isNaN(value)) {
@@ -21001,17 +21012,27 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
21001
21012
  const displayValue = options.callback(value, dataset, i);
21002
21013
  const point = dataset.data[i];
21003
21014
  const yPosition = point.y;
21004
- let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
21005
- xPosition = Math.min(xPosition, xMax);
21006
- xPosition = Math.max(xPosition, xMin);
21015
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
21016
+ const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
21017
+ const PADDING = 3;
21018
+ let xPosition;
21019
+ if (distanceFromAxisOrigin < textWidth) {
21020
+ xPosition =
21021
+ value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
21022
+ }
21023
+ else {
21024
+ xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
21025
+ xPosition = Math.min(xPosition, xMax);
21026
+ xPosition = Math.max(xPosition, xMin);
21027
+ }
21007
21028
  // Avoid overlapping texts with same Y
21008
21029
  if (!textsPositions[yPosition]) {
21009
21030
  textsPositions[yPosition] = [];
21010
21031
  }
21011
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
21012
21032
  for (const otherPosition of textsPositions[yPosition]) {
21013
21033
  if (Math.abs(otherPosition - xPosition) < textWidth) {
21014
- xPosition = otherPosition + textWidth + 3;
21034
+ xPosition =
21035
+ value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
21015
21036
  }
21016
21037
  }
21017
21038
  textsPositions[yPosition].push(xPosition);
@@ -26398,7 +26419,9 @@ function getPyramidChartShowValues(definition, args) {
26398
26419
  background: definition.background,
26399
26420
  callback: (value, dataset) => {
26400
26421
  value = Math.abs(Number(value));
26401
- return formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
26422
+ return value === 0
26423
+ ? ""
26424
+ : formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
26402
26425
  },
26403
26426
  };
26404
26427
  }
@@ -37131,6 +37154,10 @@ const REMOVE_ROWS_ACTION = (env) => {
37131
37154
  });
37132
37155
  };
37133
37156
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
37157
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
37158
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
37159
+ return false;
37160
+ }
37134
37161
  const sheetId = env.model.getters.getActiveSheetId();
37135
37162
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
37136
37163
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -40028,11 +40055,11 @@ class OTRegistry extends Registry {
40028
40055
  * transformation function given
40029
40056
  */
40030
40057
  addTransformation(executed, toTransforms, fn) {
40031
- for (let toTransform of toTransforms) {
40032
- if (!this.content[toTransform]) {
40033
- this.content[toTransform] = new Map();
40034
- }
40035
- this.content[toTransform].set(executed, fn);
40058
+ if (!this.content[executed]) {
40059
+ this.content[executed] = new Map();
40060
+ }
40061
+ for (const toTransform of toTransforms) {
40062
+ this.content[executed].set(toTransform, fn);
40036
40063
  }
40037
40064
  return this;
40038
40065
  }
@@ -40041,7 +40068,7 @@ class OTRegistry extends Registry {
40041
40068
  * that the executed command happened.
40042
40069
  */
40043
40070
  getTransformation(toTransform, executed) {
40044
- return this.content[toTransform] && this.content[toTransform].get(executed);
40071
+ return this.content[executed] && this.content[executed].get(toTransform);
40045
40072
  }
40046
40073
  }
40047
40074
  const otRegistry = new OTRegistry();
@@ -43331,6 +43358,12 @@ class Composer extends Component {
43331
43358
  useEffect(() => {
43332
43359
  this.processTokenAtCursor();
43333
43360
  }, () => [this.props.composerStore.editionMode !== "inactive"]);
43361
+ useEffect(() => {
43362
+ this.contentHelper.scrollSelectionIntoView();
43363
+ }, () => [
43364
+ this.props.composerStore.composerSelection.start,
43365
+ this.props.composerStore.composerSelection.end,
43366
+ ]);
43334
43367
  }
43335
43368
  // ---------------------------------------------------------------------------
43336
43369
  // Handlers
@@ -43553,6 +43586,7 @@ class Composer extends Component {
43553
43586
  // not main button, probably a context menu
43554
43587
  return;
43555
43588
  }
43589
+ this.debouncedHover.stopDebounce();
43556
43590
  this.contentHelper.removeSelection();
43557
43591
  }
43558
43592
  onMouseup() {
@@ -43631,7 +43665,6 @@ class Composer extends Component {
43631
43665
  const { start, end } = this.props.composerStore.composerSelection;
43632
43666
  this.contentHelper.selectRange(start, end);
43633
43667
  }
43634
- this.contentHelper.scrollSelectionIntoView();
43635
43668
  }
43636
43669
  this.shouldProcessInputEvents = true;
43637
43670
  }
@@ -67776,10 +67809,20 @@ function adaptTransform(toTransform, executed) {
67776
67809
  */
67777
67810
  function transformAll(toTransform, executed) {
67778
67811
  let transformedCommands = [...toTransform];
67812
+ const possibleTransformations = new Set(otRegistry.getKeys());
67779
67813
  for (const executedCommand of executed) {
67780
- transformedCommands = transformedCommands
67781
- .map((cmd) => transform(cmd, executedCommand))
67782
- .filter(isDefined);
67814
+ // If the executed command is not in the registry, we skip it
67815
+ // because we know there won't be any transformation impacting the
67816
+ // commands to transform.
67817
+ if (possibleTransformations.has(executedCommand.type)) {
67818
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
67819
+ const transformed = transform(cmd, executedCommand);
67820
+ if (transformed) {
67821
+ acc.push(transformed);
67822
+ }
67823
+ return acc;
67824
+ }, []);
67825
+ }
67783
67826
  }
67784
67827
  return transformedCommands;
67785
67828
  }
@@ -69481,7 +69524,7 @@ class SheetUIPlugin extends UIPlugin {
69481
69524
  }
69482
69525
  const position = this.getters.getCellPosition(cell.id);
69483
69526
  const colSize = this.getters.getColSize(sheetId, position.col);
69484
- if (cell.isFormula) {
69527
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
69485
69528
  const content = this.getters.getEvaluatedCell(position).formattedValue;
69486
69529
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
69487
69530
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -80620,6 +80663,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
80620
80663
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
80621
80664
 
80622
80665
 
80623
- __info__.version = "18.3.8";
80624
- __info__.date = "2025-06-12T09:51:55.929Z";
80625
- __info__.hash = "32dedd1";
80666
+ __info__.version = "18.3.9";
80667
+ __info__.date = "2025-06-19T18:24:02.754Z";
80668
+ __info__.hash = "a820230";
@@ -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 18.3.8
6
- * @date 2025-06-12T09:51:55.929Z
7
- * @hash 32dedd1
5
+ * @version 18.3.9
6
+ * @date 2025-06-19T18:24:02.754Z
7
+ * @hash a820230
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -20952,6 +20952,7 @@ stores.inject(MyMetaStore, storeInstance);
20952
20952
  if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
20953
20953
  continue;
20954
20954
  }
20955
+ const yAxisScale = chart.scales[dataset.yAxisID];
20955
20956
  for (let i = 0; i < dataset._parsed.length; i++) {
20956
20957
  const parsedValue = dataset._parsed[i];
20957
20958
  const value = Number(chart.config.type === "radar" ? parsedValue.r : parsedValue.y);
@@ -20962,10 +20963,18 @@ stores.inject(MyMetaStore, storeInstance);
20962
20963
  const xPosition = point.x;
20963
20964
  let yPosition = 0;
20964
20965
  if (chart.config.type === "line" || chart.config.type === "radar") {
20965
- yPosition = point.y - 10;
20966
+ yPosition = value < 0 ? point.y + 10 : point.y - 10;
20966
20967
  }
20967
20968
  else {
20968
- yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
20969
+ const yZeroLine = yAxisScale.getPixelForValue(0);
20970
+ const distanceFromAxisOrigin = Math.abs(yZeroLine - point.y);
20971
+ const textHeight = 12; // ChartJS default text height
20972
+ if (distanceFromAxisOrigin < textHeight) {
20973
+ yPosition = value < 0 ? yZeroLine + textHeight / 2 : yZeroLine - textHeight / 2;
20974
+ }
20975
+ else {
20976
+ yPosition = value < 0 ? point.y - point.height / 2 : point.y + point.height / 2;
20977
+ }
20969
20978
  }
20970
20979
  yPosition = Math.min(yPosition, yMax);
20971
20980
  yPosition = Math.max(yPosition, yMin);
@@ -20975,7 +20984,7 @@ stores.inject(MyMetaStore, storeInstance);
20975
20984
  }
20976
20985
  for (const otherPosition of textsPositions[xPosition] || []) {
20977
20986
  if (Math.abs(otherPosition - yPosition) < 13) {
20978
- yPosition = otherPosition - 13;
20987
+ yPosition = value < 0 ? otherPosition + 13 : otherPosition - 13;
20979
20988
  }
20980
20989
  }
20981
20990
  textsPositions[xPosition].push(yPosition);
@@ -20994,6 +21003,8 @@ stores.inject(MyMetaStore, storeInstance);
20994
21003
  if (isTrendLineAxis(dataset.xAxisID)) {
20995
21004
  return; // ignore trend lines
20996
21005
  }
21006
+ const xAxisScale = chart.scales[dataset.xAxisID];
21007
+ const xZeroLine = xAxisScale.getPixelForValue(0);
20997
21008
  for (let i = 0; i < dataset._parsed.length; i++) {
20998
21009
  const value = Number(dataset._parsed[i].x);
20999
21010
  if (isNaN(value)) {
@@ -21002,17 +21013,27 @@ stores.inject(MyMetaStore, storeInstance);
21002
21013
  const displayValue = options.callback(value, dataset, i);
21003
21014
  const point = dataset.data[i];
21004
21015
  const yPosition = point.y;
21005
- let xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
21006
- xPosition = Math.min(xPosition, xMax);
21007
- xPosition = Math.max(xPosition, xMin);
21016
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
21017
+ const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
21018
+ const PADDING = 3;
21019
+ let xPosition;
21020
+ if (distanceFromAxisOrigin < textWidth) {
21021
+ xPosition =
21022
+ value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
21023
+ }
21024
+ else {
21025
+ xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
21026
+ xPosition = Math.min(xPosition, xMax);
21027
+ xPosition = Math.max(xPosition, xMin);
21028
+ }
21008
21029
  // Avoid overlapping texts with same Y
21009
21030
  if (!textsPositions[yPosition]) {
21010
21031
  textsPositions[yPosition] = [];
21011
21032
  }
21012
- const textWidth = computeTextWidth(ctx, displayValue, { fontSize: 12 }, "px");
21013
21033
  for (const otherPosition of textsPositions[yPosition]) {
21014
21034
  if (Math.abs(otherPosition - xPosition) < textWidth) {
21015
- xPosition = otherPosition + textWidth + 3;
21035
+ xPosition =
21036
+ value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
21016
21037
  }
21017
21038
  }
21018
21039
  textsPositions[yPosition].push(xPosition);
@@ -26399,7 +26420,9 @@ stores.inject(MyMetaStore, storeInstance);
26399
26420
  background: definition.background,
26400
26421
  callback: (value, dataset) => {
26401
26422
  value = Math.abs(Number(value));
26402
- return formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
26423
+ return value === 0
26424
+ ? ""
26425
+ : formatChartDatasetValue(axisFormats, locale)(value, dataset.xAxisID || "x");
26403
26426
  },
26404
26427
  };
26405
26428
  }
@@ -37132,6 +37155,10 @@ stores.inject(MyMetaStore, storeInstance);
37132
37155
  });
37133
37156
  };
37134
37157
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
37158
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
37159
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
37160
+ return false;
37161
+ }
37135
37162
  const sheetId = env.model.getters.getActiveSheetId();
37136
37163
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
37137
37164
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -40029,11 +40056,11 @@ stores.inject(MyMetaStore, storeInstance);
40029
40056
  * transformation function given
40030
40057
  */
40031
40058
  addTransformation(executed, toTransforms, fn) {
40032
- for (let toTransform of toTransforms) {
40033
- if (!this.content[toTransform]) {
40034
- this.content[toTransform] = new Map();
40035
- }
40036
- this.content[toTransform].set(executed, fn);
40059
+ if (!this.content[executed]) {
40060
+ this.content[executed] = new Map();
40061
+ }
40062
+ for (const toTransform of toTransforms) {
40063
+ this.content[executed].set(toTransform, fn);
40037
40064
  }
40038
40065
  return this;
40039
40066
  }
@@ -40042,7 +40069,7 @@ stores.inject(MyMetaStore, storeInstance);
40042
40069
  * that the executed command happened.
40043
40070
  */
40044
40071
  getTransformation(toTransform, executed) {
40045
- return this.content[toTransform] && this.content[toTransform].get(executed);
40072
+ return this.content[executed] && this.content[executed].get(toTransform);
40046
40073
  }
40047
40074
  }
40048
40075
  const otRegistry = new OTRegistry();
@@ -43332,6 +43359,12 @@ stores.inject(MyMetaStore, storeInstance);
43332
43359
  owl.useEffect(() => {
43333
43360
  this.processTokenAtCursor();
43334
43361
  }, () => [this.props.composerStore.editionMode !== "inactive"]);
43362
+ owl.useEffect(() => {
43363
+ this.contentHelper.scrollSelectionIntoView();
43364
+ }, () => [
43365
+ this.props.composerStore.composerSelection.start,
43366
+ this.props.composerStore.composerSelection.end,
43367
+ ]);
43335
43368
  }
43336
43369
  // ---------------------------------------------------------------------------
43337
43370
  // Handlers
@@ -43554,6 +43587,7 @@ stores.inject(MyMetaStore, storeInstance);
43554
43587
  // not main button, probably a context menu
43555
43588
  return;
43556
43589
  }
43590
+ this.debouncedHover.stopDebounce();
43557
43591
  this.contentHelper.removeSelection();
43558
43592
  }
43559
43593
  onMouseup() {
@@ -43632,7 +43666,6 @@ stores.inject(MyMetaStore, storeInstance);
43632
43666
  const { start, end } = this.props.composerStore.composerSelection;
43633
43667
  this.contentHelper.selectRange(start, end);
43634
43668
  }
43635
- this.contentHelper.scrollSelectionIntoView();
43636
43669
  }
43637
43670
  this.shouldProcessInputEvents = true;
43638
43671
  }
@@ -67777,10 +67810,20 @@ stores.inject(MyMetaStore, storeInstance);
67777
67810
  */
67778
67811
  function transformAll(toTransform, executed) {
67779
67812
  let transformedCommands = [...toTransform];
67813
+ const possibleTransformations = new Set(otRegistry.getKeys());
67780
67814
  for (const executedCommand of executed) {
67781
- transformedCommands = transformedCommands
67782
- .map((cmd) => transform(cmd, executedCommand))
67783
- .filter(isDefined);
67815
+ // If the executed command is not in the registry, we skip it
67816
+ // because we know there won't be any transformation impacting the
67817
+ // commands to transform.
67818
+ if (possibleTransformations.has(executedCommand.type)) {
67819
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
67820
+ const transformed = transform(cmd, executedCommand);
67821
+ if (transformed) {
67822
+ acc.push(transformed);
67823
+ }
67824
+ return acc;
67825
+ }, []);
67826
+ }
67784
67827
  }
67785
67828
  return transformedCommands;
67786
67829
  }
@@ -69482,7 +69525,7 @@ stores.inject(MyMetaStore, storeInstance);
69482
69525
  }
69483
69526
  const position = this.getters.getCellPosition(cell.id);
69484
69527
  const colSize = this.getters.getColSize(sheetId, position.col);
69485
- if (cell.isFormula) {
69528
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
69486
69529
  const content = this.getters.getEvaluatedCell(position).formattedValue;
69487
69530
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
69488
69531
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -80667,9 +80710,9 @@ stores.inject(MyMetaStore, storeInstance);
80667
80710
  exports.tokenize = tokenize;
80668
80711
 
80669
80712
 
80670
- __info__.version = "18.3.8";
80671
- __info__.date = "2025-06-12T09:51:55.929Z";
80672
- __info__.hash = "32dedd1";
80713
+ __info__.version = "18.3.9";
80714
+ __info__.date = "2025-06-19T18:24:02.754Z";
80715
+ __info__.hash = "a820230";
80673
80716
 
80674
80717
 
80675
80718
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);