@odoo/o-spreadsheet 18.2.8 → 18.2.10

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.2.8
6
- * @date 2025-04-18T16:26:20.673Z
7
- * @hash 5da9ddc
5
+ * @version 18.2.10
6
+ * @date 2025-05-02T12:34:39.632Z
7
+ * @hash e8ff3fc
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';
@@ -3769,6 +3769,7 @@ var CommandResult;
3769
3769
  CommandResult["ValueCellIsInvalidFormula"] = "ValueCellIsInvalidFormula";
3770
3770
  CommandResult["InvalidDefinition"] = "InvalidDefinition";
3771
3771
  CommandResult["InvalidColor"] = "InvalidColor";
3772
+ CommandResult["InvalidPivotDataSet"] = "InvalidPivotDataSet";
3772
3773
  })(CommandResult || (CommandResult = {}));
3773
3774
 
3774
3775
  const DEFAULT_LOCALES = [
@@ -3841,11 +3842,13 @@ const CellErrorType = {
3841
3842
  NullError: "#NULL!",
3842
3843
  };
3843
3844
  const errorTypes = new Set(Object.values(CellErrorType));
3844
- class EvaluationError extends Error {
3845
+ class EvaluationError {
3846
+ message;
3845
3847
  value;
3846
3848
  constructor(message = _t("Error"), value = CellErrorType.GenericError) {
3847
- super(message);
3849
+ this.message = message;
3848
3850
  this.value = value;
3851
+ this.message = message.toString();
3849
3852
  }
3850
3853
  }
3851
3854
  class BadExpressionError extends EvaluationError {
@@ -10169,7 +10172,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
10169
10172
  const yMin = chart.chartArea.top;
10170
10173
  const textsPositions = {};
10171
10174
  for (const dataset of chart._metasets) {
10172
- if (isTrendLineAxis(dataset.axisID) || dataset.hidden) {
10175
+ if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
10173
10176
  continue;
10174
10177
  }
10175
10178
  for (let i = 0; i < dataset._parsed.length; i++) {
@@ -10212,7 +10215,7 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
10212
10215
  const xMin = chart.chartArea.left;
10213
10216
  const textsPositions = {};
10214
10217
  for (const dataset of chart._metasets) {
10215
- if (isTrendLineAxis(dataset.axisID)) {
10218
+ if (isTrendLineAxis(dataset.xAxisID)) {
10216
10219
  return; // ignore trend lines
10217
10220
  }
10218
10221
  for (let i = 0; i < dataset._parsed.length; i++) {
@@ -10337,6 +10340,7 @@ class ChartJsComponent extends Component {
10337
10340
  canvas = useRef("graphContainer");
10338
10341
  chart;
10339
10342
  currentRuntime;
10343
+ currentDevicePixelRatio = window.devicePixelRatio;
10340
10344
  get background() {
10341
10345
  return this.chartRuntime.background;
10342
10346
  }
@@ -10370,6 +10374,10 @@ class ChartJsComponent extends Component {
10370
10374
  }
10371
10375
  this.currentRuntime = runtime;
10372
10376
  }
10377
+ else if (this.currentDevicePixelRatio !== window.devicePixelRatio) {
10378
+ this.currentDevicePixelRatio = window.devicePixelRatio;
10379
+ this.updateChartJs(deepCopy(this.currentRuntime.chartJsConfig));
10380
+ }
10373
10381
  });
10374
10382
  }
10375
10383
  createChart(chartData) {
@@ -10625,9 +10633,11 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
10625
10633
  };
10626
10634
  function drawScoreChart(structure, canvas) {
10627
10635
  const ctx = canvas.getContext("2d");
10628
- canvas.width = structure.canvas.width;
10629
- const availableWidth = canvas.width - CHART_PADDING$1 * 2;
10630
- canvas.height = structure.canvas.height;
10636
+ const dpr = window.devicePixelRatio || 1;
10637
+ canvas.width = dpr * structure.canvas.width;
10638
+ canvas.height = dpr * structure.canvas.height;
10639
+ ctx.scale(dpr, dpr);
10640
+ const availableWidth = structure.canvas.width - CHART_PADDING$1 * 2;
10631
10641
  ctx.fillStyle = structure.canvas.backgroundColor;
10632
10642
  ctx.fillRect(0, 0, structure.canvas.width, structure.canvas.height);
10633
10643
  if (structure.title) {
@@ -10990,7 +11000,7 @@ class ScorecardChart extends Component {
10990
11000
  useEffect(this.createChart.bind(this), () => {
10991
11001
  const canvas = this.canvas.el;
10992
11002
  const rect = canvas.getBoundingClientRect();
10993
- return [rect.width, rect.height, this.runtime, this.canvas.el];
11003
+ return [rect.width, rect.height, this.runtime, this.canvas.el, window.devicePixelRatio];
10994
11004
  });
10995
11005
  }
10996
11006
  createChart() {
@@ -13750,7 +13760,7 @@ const RANK = {
13750
13760
  }
13751
13761
  }
13752
13762
  if (!found) {
13753
- throw new NotAvailableError(_t("Value not found in the given data."));
13763
+ return new NotAvailableError(_t("Value not found in the given data."));
13754
13764
  }
13755
13765
  return rank;
13756
13766
  },
@@ -15490,7 +15500,7 @@ const UNIQUE = {
15490
15500
  result.push(row.data);
15491
15501
  }
15492
15502
  if (!result.length)
15493
- throw new EvaluationError(_t("No unique values found"));
15503
+ return new EvaluationError(_t("No unique values found"));
15494
15504
  return _byColumn ? result : transposeMatrix(result);
15495
15505
  },
15496
15506
  isExported: true,
@@ -19269,7 +19279,7 @@ const OFFSET = {
19269
19279
  }
19270
19280
  const _cellReference = cellReference?.value;
19271
19281
  if (!_cellReference) {
19272
- throw new Error("In this context, the function OFFSET needs to have a cell or range in parameter.");
19282
+ return new EvaluationError("In this context, the function OFFSET needs to have a cell or range in parameter.");
19273
19283
  }
19274
19284
  const zone = toZone(_cellReference);
19275
19285
  let offsetHeight = zone.bottom - zone.top + 1;
@@ -22579,9 +22589,11 @@ const GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN = 6;
22579
22589
  const GAUGE_TITLE_SECTION_HEIGHT = 25;
22580
22590
  function drawGaugeChart(canvas, runtime) {
22581
22591
  const canvasBoundingRect = canvas.getBoundingClientRect();
22582
- canvas.width = canvasBoundingRect.width;
22583
- canvas.height = canvasBoundingRect.height;
22592
+ const dpr = window.devicePixelRatio || 1;
22593
+ canvas.width = dpr * canvasBoundingRect.width;
22594
+ canvas.height = dpr * canvasBoundingRect.height;
22584
22595
  const ctx = canvas.getContext("2d");
22596
+ ctx.scale(dpr, dpr);
22585
22597
  const config = getGaugeRenderingConfig(canvasBoundingRect, runtime, ctx);
22586
22598
  drawBackground(ctx, config);
22587
22599
  drawGauge(ctx, config);
@@ -22916,7 +22928,7 @@ class GaugeChartComponent extends Component {
22916
22928
  useEffect(() => drawGaugeChart(this.canvas.el, this.runtime), () => {
22917
22929
  const canvas = this.canvas.el;
22918
22930
  const rect = canvas.getBoundingClientRect();
22919
- return [rect.width, rect.height, this.runtime, this.canvas.el];
22931
+ return [rect.width, rect.height, this.runtime, this.canvas.el, window.devicePixelRatio];
22920
22932
  });
22921
22933
  }
22922
22934
  }
@@ -29579,7 +29591,7 @@ function getBarChartScales(definition, args) {
29579
29591
  };
29580
29592
  scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID] = {
29581
29593
  ...scales.x,
29582
- offset: false,
29594
+ offset: true,
29583
29595
  display: false,
29584
29596
  };
29585
29597
  }
@@ -30299,9 +30311,6 @@ class BarChart extends AbstractChart {
30299
30311
  };
30300
30312
  }
30301
30313
  getDefinitionForExcel() {
30302
- // Excel does not support aggregating labels
30303
- if (this.aggregated)
30304
- return undefined;
30305
30314
  const dataSets = this.dataSets
30306
30315
  .map((ds) => toExcelDataset(this.getters, ds))
30307
30316
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -31016,9 +31025,6 @@ class LineChart extends AbstractChart {
31016
31025
  return new LineChart(definition, this.sheetId, this.getters);
31017
31026
  }
31018
31027
  getDefinitionForExcel() {
31019
- // Excel does not support aggregating labels
31020
- if (this.aggregated)
31021
- return undefined;
31022
31028
  const dataSets = this.dataSets
31023
31029
  .map((ds) => toExcelDataset(this.getters, ds))
31024
31030
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -31155,9 +31161,6 @@ class PieChart extends AbstractChart {
31155
31161
  return new PieChart(definition, sheetId, this.getters);
31156
31162
  }
31157
31163
  getDefinitionForExcel() {
31158
- // Excel does not support aggregating labels
31159
- if (this.aggregated)
31160
- return undefined;
31161
31164
  const dataSets = this.dataSets
31162
31165
  .map((ds) => toExcelDataset(this.getters, ds))
31163
31166
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -33656,18 +33659,28 @@ function isBrowserFirefox() {
33656
33659
  function useInterval(callback, delay) {
33657
33660
  let intervalId;
33658
33661
  const { setInterval, clearInterval } = window;
33662
+ const pause = () => {
33663
+ clearInterval(intervalId);
33664
+ intervalId = undefined;
33665
+ };
33666
+ const safeCallback = () => {
33667
+ try {
33668
+ callback();
33669
+ }
33670
+ catch (e) {
33671
+ pause();
33672
+ throw e;
33673
+ }
33674
+ };
33659
33675
  useEffect(() => {
33660
- intervalId = setInterval(callback, delay);
33676
+ intervalId = setInterval(safeCallback, delay);
33661
33677
  return () => clearInterval(intervalId);
33662
33678
  }, () => [delay]);
33663
33679
  return {
33664
- pause: () => {
33665
- clearInterval(intervalId);
33666
- intervalId = undefined;
33667
- },
33680
+ pause,
33668
33681
  resume: () => {
33669
33682
  if (intervalId === undefined) {
33670
- intervalId = setInterval(callback, delay);
33683
+ intervalId = setInterval(safeCallback, delay);
33671
33684
  }
33672
33685
  },
33673
33686
  };
@@ -38448,8 +38461,11 @@ class SelectionInput extends Component {
38448
38461
  }
38449
38462
  removeInput(rangeId) {
38450
38463
  const index = this.store.selectionInputs.findIndex((range) => range.id === rangeId);
38451
- this.props.onSelectionRemoved?.(index);
38452
- this.props.onSelectionConfirmed?.();
38464
+ if (this.ranges.find((range) => range.id === rangeId)?.xc) {
38465
+ this.props.onSelectionRemoved?.(index);
38466
+ this.props.onSelectionConfirmed?.();
38467
+ }
38468
+ this.store.removeRange(rangeId);
38453
38469
  }
38454
38470
  onInputChanged(rangeId, ev) {
38455
38471
  const target = ev.target;
@@ -39115,7 +39131,7 @@ class ColorPicker extends Component {
39115
39131
  }
39116
39132
  setHexColor(ev) {
39117
39133
  // only support HEX code input
39118
- const val = ev.target.value.slice(0, 7);
39134
+ const val = ev.target.value.replace("##", "#").slice(0, 7);
39119
39135
  this.state.customHexColor = val;
39120
39136
  if (!isColorValid(val)) ;
39121
39137
  else {
@@ -50849,7 +50865,7 @@ css /* scss */ `
50849
50865
  position: absolute;
50850
50866
  top: 0;
50851
50867
  left: ${HEADER_WIDTH}px;
50852
- right: 0;
50868
+ right: ${SCROLLBAR_WIDTH}px;
50853
50869
  height: ${HEADER_HEIGHT}px;
50854
50870
  width: calc(100% - ${HEADER_WIDTH + SCROLLBAR_WIDTH}px);
50855
50871
  &.o-dragging {
@@ -51042,9 +51058,8 @@ css /* scss */ `
51042
51058
  position: absolute;
51043
51059
  top: ${HEADER_HEIGHT}px;
51044
51060
  left: 0;
51045
- right: 0;
51061
+ bottom: ${SCROLLBAR_WIDTH}px;
51046
51062
  width: ${HEADER_WIDTH}px;
51047
- height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
51048
51063
  &.o-dragging {
51049
51064
  cursor: grabbing;
51050
51065
  }
@@ -59092,6 +59107,15 @@ function adaptPivotRange(range, applyChange) {
59092
59107
  }
59093
59108
  }
59094
59109
  class SpreadsheetPivotCorePlugin extends CorePlugin {
59110
+ allowDispatch(cmd) {
59111
+ switch (cmd.type) {
59112
+ case "ADD_PIVOT":
59113
+ case "UPDATE_PIVOT":
59114
+ const definition = cmd.pivot;
59115
+ return this.checkDataSetValidity(definition);
59116
+ }
59117
+ return "Success" /* CommandResult.Success */;
59118
+ }
59095
59119
  adaptRanges(applyChange) {
59096
59120
  for (const pivotId of this.getters.getPivotIds()) {
59097
59121
  const definition = this.getters.getPivotCoreDefinition(pivotId);
@@ -59110,6 +59134,16 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
59110
59134
  }
59111
59135
  }
59112
59136
  }
59137
+ checkDataSetValidity(definition) {
59138
+ if (definition.type === "SPREADSHEET" && definition.dataSet) {
59139
+ const { zone, sheetId } = definition.dataSet;
59140
+ if (!sheetId || !this.getters.tryGetSheet(sheetId) || !zone || !isZoneValid(zone)) {
59141
+ return "InvalidDataSet" /* CommandResult.InvalidDataSet */;
59142
+ }
59143
+ return this.getters.checkZonesExistInSheet(sheetId, [zone]);
59144
+ }
59145
+ return "Success" /* CommandResult.Success */;
59146
+ }
59113
59147
  }
59114
59148
 
59115
59149
  class TableStylePlugin extends CorePlugin {
@@ -61900,7 +61934,7 @@ class DynamicTablesPlugin extends CoreViewPlugin {
61900
61934
  tables = {};
61901
61935
  handle(cmd) {
61902
61936
  if (invalidateEvaluationCommands.has(cmd.type) ||
61903
- (cmd.type === "UPDATE_CELL" && "content" in cmd) ||
61937
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd)) ||
61904
61938
  cmd.type === "EVALUATE_CELLS") {
61905
61939
  this.tables = {};
61906
61940
  return;
@@ -62333,6 +62367,16 @@ function withPivotPresentationLayer (PivotClass) {
62333
62367
  }
62334
62368
  return values;
62335
62369
  }
62370
+ else if (rowDomain.length === this.definition.rows.length &&
62371
+ colDomain.length &&
62372
+ colDomain.length < this.definition.columns.length) {
62373
+ const colSubTree = this.getSubTreeMatchingDomain(table.getColTree(), colDomain);
62374
+ const domains = this.treeToLeafDomains(colSubTree, colDomain);
62375
+ for (const domain of domains) {
62376
+ values.push(this._getPivotCellValueAndFormat(measure.id, rowDomain.concat(domain)));
62377
+ }
62378
+ return values;
62379
+ }
62336
62380
  else {
62337
62381
  const tree = table.getRowTree();
62338
62382
  const subTree = this.getSubTreeMatchingDomain(tree, rowDomain);
@@ -65762,7 +65806,7 @@ class TableComputedStylePlugin extends UIPlugin {
65762
65806
  tableStyles = {};
65763
65807
  handle(cmd) {
65764
65808
  if (invalidateEvaluationCommands.has(cmd.type) ||
65765
- (cmd.type === "UPDATE_CELL" && "content" in cmd) ||
65809
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd)) ||
65766
65810
  cmd.type === "EVALUATE_CELLS") {
65767
65811
  this.tableStyles = {};
65768
65812
  return;
@@ -67723,6 +67767,8 @@ class GridSelectionPlugin extends UIPlugin {
67723
67767
  });
67724
67768
  this.selectCell(col, row);
67725
67769
  }
67770
+ const { col, row } = this.gridSelection.anchor.cell;
67771
+ this.moveClient({ sheetId: this.activeSheet.id, col, row });
67726
67772
  }
67727
67773
  /**
67728
67774
  * Ensure selections are not outside sheet boundaries.
@@ -68438,8 +68484,11 @@ class SheetViewPlugin extends UIPlugin {
68438
68484
  case "REMOVE_TABLE":
68439
68485
  case "UPDATE_TABLE":
68440
68486
  case "UPDATE_FILTER":
68441
- this.sheetsWithDirtyViewports.add(cmd.sheetId);
68442
- break;
68487
+ case "UNFREEZE_ROWS":
68488
+ case "UNFREEZE_COLUMNS":
68489
+ case "FREEZE_COLUMNS":
68490
+ case "FREEZE_ROWS":
68491
+ case "UNFREEZE_COLUMNS_ROWS":
68443
68492
  case "REMOVE_COLUMNS_ROWS":
68444
68493
  case "RESIZE_COLUMNS_ROWS":
68445
68494
  case "HIDE_COLUMNS_ROWS":
@@ -68452,11 +68501,9 @@ class SheetViewPlugin extends UIPlugin {
68452
68501
  case "FOLD_HEADER_GROUPS_IN_ZONE":
68453
68502
  case "UNFOLD_HEADER_GROUPS_IN_ZONE":
68454
68503
  case "UNFOLD_ALL_HEADER_GROUPS":
68455
- case "FOLD_ALL_HEADER_GROUPS": {
68456
- const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.getActiveSheetId();
68457
- this.sheetsWithDirtyViewports.add(sheetId);
68504
+ case "FOLD_ALL_HEADER_GROUPS":
68505
+ this.sheetsWithDirtyViewports.add(cmd.sheetId);
68458
68506
  break;
68459
- }
68460
68507
  case "UPDATE_CELL":
68461
68508
  // update cell content or format can change hidden rows because of data filters
68462
68509
  if ("content" in cmd || "format" in cmd || cmd.style?.fontSize !== undefined) {
@@ -68472,13 +68519,6 @@ class SheetViewPlugin extends UIPlugin {
68472
68519
  case "ACTIVATE_SHEET":
68473
68520
  this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
68474
68521
  break;
68475
- case "UNFREEZE_ROWS":
68476
- case "UNFREEZE_COLUMNS":
68477
- case "FREEZE_COLUMNS":
68478
- case "FREEZE_ROWS":
68479
- case "UNFREEZE_COLUMNS_ROWS":
68480
- this.resetViewports(this.getters.getActiveSheetId());
68481
- break;
68482
68522
  case "SCROLL_TO_CELL":
68483
68523
  this.refreshViewport(this.getters.getActiveSheetId(), { col: cmd.col, row: cmd.row });
68484
68524
  break;
@@ -69646,7 +69686,7 @@ class AggregateStatisticsStore extends SpreadsheetStore {
69646
69686
  }
69647
69687
  handle(cmd) {
69648
69688
  if (invalidateEvaluationCommands.has(cmd.type) ||
69649
- (cmd.type === "UPDATE_CELL" && "content" in cmd)) {
69689
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
69650
69690
  this.isDirty = true;
69651
69691
  }
69652
69692
  switch (cmd.type) {
@@ -76183,6 +76223,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
76183
76223
  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, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
76184
76224
 
76185
76225
 
76186
- __info__.version = "18.2.8";
76187
- __info__.date = "2025-04-18T16:26:20.673Z";
76188
- __info__.hash = "5da9ddc";
76226
+ __info__.version = "18.2.10";
76227
+ __info__.date = "2025-05-02T12:34:39.632Z";
76228
+ __info__.hash = "e8ff3fc";