@odoo/o-spreadsheet 18.3.19 → 18.3.21

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.19
6
- * @date 2025-09-05T07:38:30.661Z
7
- * @hash 77fd307
5
+ * @version 18.3.21
6
+ * @date 2025-09-19T07:25:12.089Z
7
+ * @hash b64ee85
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -863,8 +863,19 @@
863
863
  },
864
864
  }[funcName];
865
865
  }
866
+ /**
867
+ * Removes the specified indexes from the array.
868
+ * Sparse (empty) elements are transformed to undefined (unless their index is explicitly removed).
869
+ */
866
870
  function removeIndexesFromArray(array, indexes) {
867
- return array.filter((_, index) => !indexes.includes(index));
871
+ const toRemove = new Set(indexes);
872
+ const newArray = [];
873
+ for (let i = 0; i < array.length; i++) {
874
+ if (!toRemove.has(i)) {
875
+ newArray.push(array[i]);
876
+ }
877
+ }
878
+ return newArray;
868
879
  }
869
880
  function insertItemsAtIndex(array, items, index) {
870
881
  const newArray = [...array];
@@ -7208,7 +7219,7 @@
7208
7219
  this.getters = getters;
7209
7220
  this.dispatch = dispatch;
7210
7221
  }
7211
- copy(data, isCutOperation) {
7222
+ copy(data, isCutOperation, mode = "copyPaste") {
7212
7223
  return;
7213
7224
  }
7214
7225
  paste(target, clippedContent, options) { }
@@ -7227,7 +7238,7 @@
7227
7238
  }
7228
7239
 
7229
7240
  class AbstractCellClipboardHandler extends ClipboardHandler {
7230
- copy(data) {
7241
+ copy(data, isCutOperation, mode = "copyPaste") {
7231
7242
  return;
7232
7243
  }
7233
7244
  pasteFromCopy(sheetId, target, content, options) {
@@ -8950,7 +8961,7 @@
8950
8961
  }
8951
8962
  return "Success" /* CommandResult.Success */;
8952
8963
  }
8953
- copy(data) {
8964
+ copy(data, isCutOperation, mode = "copyPaste") {
8954
8965
  const sheetId = data.sheetId;
8955
8966
  const { clippedZones, rowsIndexes, columnsIndexes } = data;
8956
8967
  const clippedCells = [];
@@ -8963,7 +8974,7 @@
8963
8974
  const evaluatedCell = this.getters.getEvaluatedCell(position);
8964
8975
  const pivotId = this.getters.getPivotIdFromPosition(position);
8965
8976
  const spreader = this.getters.getArrayFormulaSpreadingOn(position);
8966
- if (pivotId && spreader) {
8977
+ if (mode !== "shiftCells" && pivotId && spreader) {
8967
8978
  const pivotZone = this.getters.getSpreadZone(spreader);
8968
8979
  if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
8969
8980
  pivotZone &&
@@ -8981,7 +8992,7 @@
8981
8992
  };
8982
8993
  }
8983
8994
  }
8984
- else {
8995
+ else if (mode !== "shiftCells") {
8985
8996
  if (spreader && !deepEquals(spreader, position)) {
8986
8997
  const isSpreaderCopied = rowsIndexes.includes(spreader.row) && columnsIndexes.includes(spreader.col);
8987
8998
  const content = isSpreaderCopied
@@ -9681,7 +9692,7 @@
9681
9692
  }
9682
9693
 
9683
9694
  class TableClipboardHandler extends AbstractCellClipboardHandler {
9684
- copy(data, isCutOperation) {
9695
+ copy(data, isCutOperation, mode = "copyPaste") {
9685
9696
  const sheetId = data.sheetId;
9686
9697
  const { rowsIndexes, columnsIndexes, zones } = data;
9687
9698
  const copiedTablesIds = new Set();
@@ -9719,11 +9730,13 @@
9719
9730
  type: coreTable.type,
9720
9731
  };
9721
9732
  }
9722
- tableCellsInRow.push({
9723
- table: copiedTable,
9724
- style: this.getTableStyleToCopy(position),
9725
- isWholeTableCopied: copiedTablesIds.has(table.id),
9726
- });
9733
+ if (mode !== "shiftCells") {
9734
+ tableCellsInRow.push({
9735
+ table: copiedTable,
9736
+ style: this.getTableStyleToCopy(position),
9737
+ isWholeTableCopied: copiedTablesIds.has(table.id),
9738
+ });
9739
+ }
9727
9740
  }
9728
9741
  }
9729
9742
  return {
@@ -14807,8 +14820,9 @@ stores.inject(MyMetaStore, storeInstance);
14807
14820
  }
14808
14821
 
14809
14822
  function sortMatrix(matrix, locale, ...criteria) {
14810
- for (const [i, value] of criteria.entries()) {
14811
- assert(() => value !== undefined, _t("Value for parameter %d is missing, while the function [[FUNCTION_NAME]] expect a number or a range.", i + 1));
14823
+ for (let i = 0; i < criteria.length; i++) {
14824
+ const param = i % 2 === 0 ? "sort_column" : "is_ascending";
14825
+ assert(() => criteria[i] !== undefined, _t("Value for parameter %s is missing in [[FUNCTION_NAME]].", param));
14812
14826
  }
14813
14827
  const sortingOrders = [];
14814
14828
  const sortColumns = [];
@@ -30885,7 +30899,7 @@ stores.inject(MyMetaStore, storeInstance);
30885
30899
  ];
30886
30900
  const SUPPORTED_VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
30887
30901
  const SUPPORTED_FONTS = ["Arial"];
30888
- const SUPPORTED_FILL_PATTERNS = ["solid"];
30902
+ const SUPPORTED_FILL_PATTERNS = ["solid", "none"];
30889
30903
  const SUPPORTED_CF_TYPES = [
30890
30904
  "expression",
30891
30905
  "cellIs",
@@ -31070,7 +31084,7 @@ stores.inject(MyMetaStore, storeInstance);
31070
31084
  };
31071
31085
  /** Mapping between Excel format indexes (see XLSX_FORMAT_MAP) and some supported formats */
31072
31086
  const XLSX_FORMATS_CONVERSION_MAP = {
31073
- 0: "",
31087
+ 0: "General",
31074
31088
  1: "0",
31075
31089
  2: "0.00",
31076
31090
  3: "#,#00",
@@ -31396,11 +31410,11 @@ stores.inject(MyMetaStore, storeInstance);
31396
31410
  * Excel format are defined in openXML §18.8.31
31397
31411
  */
31398
31412
  function convertXlsxFormat(numFmtId, formats, warningManager) {
31399
- if (numFmtId === 0) {
31400
- return undefined;
31401
- }
31402
31413
  // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
31403
31414
  let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format;
31415
+ if (format === "General") {
31416
+ return undefined;
31417
+ }
31404
31418
  if (format) {
31405
31419
  try {
31406
31420
  let convertedFormat = format.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
@@ -34245,10 +34259,11 @@ stores.inject(MyMetaStore, storeInstance);
34245
34259
  });
34246
34260
  }
34247
34261
  extractRows(worksheet) {
34262
+ const spilledCells = new Set();
34248
34263
  return this.mapOnElements({ parent: worksheet, query: "sheetData row" }, (rowElement) => {
34249
34264
  return {
34250
34265
  index: this.extractAttr(rowElement, "r", { required: true })?.asNum(),
34251
- cells: this.extractCells(rowElement),
34266
+ cells: this.extractCells(rowElement, spilledCells),
34252
34267
  height: this.extractAttr(rowElement, "ht")?.asNum(),
34253
34268
  customHeight: this.extractAttr(rowElement, "customHeight")?.asBool(),
34254
34269
  hidden: this.extractAttr(rowElement, "hidden")?.asBool(),
@@ -34258,14 +34273,26 @@ stores.inject(MyMetaStore, storeInstance);
34258
34273
  };
34259
34274
  });
34260
34275
  }
34261
- extractCells(row) {
34276
+ extractCells(row, spilledCells) {
34262
34277
  return this.mapOnElements({ parent: row, query: "c" }, (cellElement) => {
34278
+ const xc = this.extractAttr(cellElement, "r", { required: true })?.asString();
34279
+ const formula = this.extractCellFormula(cellElement);
34280
+ if (formula?.ref && formula.sharedIndex === undefined) {
34281
+ const zone = toZone(formula.ref);
34282
+ for (const { col, row } of positions(zone)) {
34283
+ const followerXc = toXC(col, row);
34284
+ if (followerXc !== xc) {
34285
+ spilledCells.add(followerXc);
34286
+ }
34287
+ }
34288
+ }
34289
+ const isSpilled = spilledCells.has(xc);
34263
34290
  return {
34264
- xc: this.extractAttr(cellElement, "r", { required: true })?.asString(),
34291
+ xc,
34265
34292
  styleIndex: this.extractAttr(cellElement, "s")?.asNum(),
34266
34293
  type: CELL_TYPE_CONVERSION_MAP[this.extractAttr(cellElement, "t", { default: "n" })?.asString()],
34267
- value: this.extractChildTextContent(cellElement, "v"),
34268
- formula: this.extractCellFormula(cellElement),
34294
+ value: isSpilled ? undefined : this.extractChildTextContent(cellElement, "v") ?? undefined,
34295
+ formula: isSpilled ? undefined : formula,
34269
34296
  };
34270
34297
  });
34271
34298
  }
@@ -34273,11 +34300,14 @@ stores.inject(MyMetaStore, storeInstance);
34273
34300
  const formulaElement = this.querySelector(cellElement, "f");
34274
34301
  if (!formulaElement)
34275
34302
  return undefined;
34276
- return {
34277
- content: this.extractTextContent(formulaElement),
34278
- sharedIndex: this.extractAttr(formulaElement, "si")?.asNum(),
34279
- ref: this.extractAttr(formulaElement, "ref")?.asString(),
34280
- };
34303
+ const content = this.extractTextContent(formulaElement);
34304
+ const sharedIndex = this.extractAttr(formulaElement, "si")?.asNum();
34305
+ const ref = this.extractAttr(formulaElement, "ref")?.asString();
34306
+ // This is the case of spilled cells of array formulas where <f> is empty
34307
+ if ((content === undefined || content.trim() === "") && sharedIndex === undefined) {
34308
+ return undefined;
34309
+ }
34310
+ return { content, sharedIndex, ref };
34281
34311
  }
34282
34312
  extractHyperLinks(worksheet) {
34283
34313
  return this.mapOnElements({ parent: worksheet, query: "hyperlink" }, (linkElement) => {
@@ -48860,12 +48890,13 @@ stores.inject(MyMetaStore, storeInstance);
48860
48890
  addCalculatedMeasure() {
48861
48891
  const { measures } = this.props.definition;
48862
48892
  const measureName = this.env.model.getters.generateNewCalculatedMeasureName(measures);
48893
+ const aggregator = "sum";
48863
48894
  this.props.onDimensionsUpdated({
48864
48895
  measures: measures.concat([
48865
48896
  {
48866
- id: this.getMeasureId(measureName),
48897
+ id: this.getMeasureId(measureName, aggregator),
48867
48898
  fieldName: measureName,
48868
- aggregator: "sum",
48899
+ aggregator,
48869
48900
  computedBy: {
48870
48901
  sheetId: this.env.model.getters.getActiveSheetId(),
48871
48902
  formula: "=0",
@@ -66216,7 +66247,7 @@ stores.inject(MyMetaStore, storeInstance);
66216
66247
  return { value: 0 };
66217
66248
  }
66218
66249
  const { columns, rows } = super.definition;
66219
- if (columns.length + rows.length !== domain.length) {
66250
+ if (measure.aggregator && columns.length + rows.length !== domain.length) {
66220
66251
  const values = this.getValuesToAggregate(measure, domain);
66221
66252
  const aggregator = AGGREGATORS_FN[measure.aggregator];
66222
66253
  if (!aggregator) {
@@ -66235,11 +66266,17 @@ stores.inject(MyMetaStore, storeInstance);
66235
66266
  if (columns.find((col) => col.nameWithGranularity === symbolName)) {
66236
66267
  const { colDomain } = domainToColRowDomain(this, domain);
66237
66268
  const symbolIndex = colDomain.findIndex((node) => node.field === symbolName);
66269
+ if (symbolIndex === -1) {
66270
+ return new NotAvailableError();
66271
+ }
66238
66272
  return this.getPivotHeaderValueAndFormat(colDomain.slice(0, symbolIndex + 1));
66239
66273
  }
66240
66274
  if (rows.find((row) => row.nameWithGranularity === symbolName)) {
66241
66275
  const { rowDomain } = domainToColRowDomain(this, domain);
66242
66276
  const symbolIndex = rowDomain.findIndex((row) => row.field === symbolName);
66277
+ if (symbolIndex === -1) {
66278
+ return new NotAvailableError();
66279
+ }
66243
66280
  return this.getPivotHeaderValueAndFormat(rowDomain.slice(0, symbolIndex + 1));
66244
66281
  }
66245
66282
  return this.getPivotCellValueAndFormat(symbolName, domain);
@@ -68830,7 +68867,7 @@ stores.inject(MyMetaStore, storeInstance);
68830
68867
  bottom: rowIndex,
68831
68868
  }));
68832
68869
  const handler = new CellClipboardHandler(this.getters, this.dispatch);
68833
- const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep));
68870
+ const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep), false);
68834
68871
  if (!data) {
68835
68872
  return;
68836
68873
  }
@@ -70870,12 +70907,12 @@ stores.inject(MyMetaStore, storeInstance);
70870
70907
  }
70871
70908
  case "INSERT_CELL": {
70872
70909
  const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
70873
- const copiedData = this.copy(cut);
70910
+ const copiedData = this.copy(cut, "shiftCells");
70874
70911
  return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
70875
70912
  }
70876
70913
  case "DELETE_CELL": {
70877
70914
  const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
70878
- const copiedData = this.copy(cut);
70915
+ const copiedData = this.copy(cut, "shiftCells");
70879
70916
  return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
70880
70917
  }
70881
70918
  }
@@ -70986,13 +71023,13 @@ stores.inject(MyMetaStore, storeInstance);
70986
71023
  });
70987
71024
  break;
70988
71025
  }
70989
- const copiedData = this.copy(cut);
71026
+ const copiedData = this.copy(cut, "shiftCells");
70990
71027
  this.paste(paste, copiedData, { isCutOperation: true });
70991
71028
  break;
70992
71029
  }
70993
71030
  case "INSERT_CELL": {
70994
71031
  const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
70995
- const copiedData = this.copy(cut);
71032
+ const copiedData = this.copy(cut, "shiftCells");
70996
71033
  this.paste(paste, copiedData, { isCutOperation: true });
70997
71034
  break;
70998
71035
  }
@@ -71107,11 +71144,11 @@ stores.inject(MyMetaStore, storeInstance);
71107
71144
  }
71108
71145
  return false;
71109
71146
  }
71110
- copy(zones) {
71147
+ copy(zones, mode = "copyPaste") {
71111
71148
  let copiedData = {};
71112
71149
  const clipboardData = this.getClipboardData(zones);
71113
71150
  for (const { handlerName, handler } of this.selectClipboardHandlers(clipboardData)) {
71114
- const data = handler.copy(clipboardData, this._isCutOperation);
71151
+ const data = handler.copy(clipboardData, this._isCutOperation, mode);
71115
71152
  copiedData[handlerName] = data;
71116
71153
  const minimalKeys = ["sheetId", "cells", "zones", "figureId"];
71117
71154
  for (const key of minimalKeys) {
@@ -72035,13 +72072,10 @@ stores.inject(MyMetaStore, storeInstance);
72035
72072
  const deltaCol = isBasedBefore && isCol ? thickness : 0;
72036
72073
  const deltaRow = isBasedBefore && !isCol ? thickness : 0;
72037
72074
  const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
72038
- const originalSize = Object.fromEntries(toRemove.map((element) => {
72039
- const size = isCol
72040
- ? this.getters.getColSize(cmd.sheetId, element)
72041
- : this.getters.getUserRowSize(cmd.sheetId, element);
72042
- const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
72043
- return [element, isDefaultCol ? undefined : size];
72044
- }));
72075
+ const originalSize = {};
72076
+ for (const element of toRemove) {
72077
+ originalSize[element] = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
72078
+ }
72045
72079
  const target = [
72046
72080
  {
72047
72081
  left: isCol ? start + deltaCol : 0,
@@ -72062,7 +72096,7 @@ stores.inject(MyMetaStore, storeInstance);
72062
72096
  ];
72063
72097
  for (const Handler of clipboardHandlersRegistries.cellHandlers.getAll()) {
72064
72098
  const handler = new Handler(this.getters, this.dispatch);
72065
- const data = handler.copy(getClipboardDataPositions(sheetId, target));
72099
+ const data = handler.copy(getClipboardDataPositions(sheetId, target), false, "shiftCells");
72066
72100
  if (!data) {
72067
72101
  continue;
72068
72102
  }
@@ -72077,11 +72111,11 @@ stores.inject(MyMetaStore, storeInstance);
72077
72111
  for (const element of toRemove) {
72078
72112
  const size = originalSize[element];
72079
72113
  const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
72080
- if (size && size != currentSize) {
72114
+ if (size != currentSize) {
72081
72115
  resizingGroups[size] ??= [];
72082
72116
  resizingGroups[size].push(currentIndex);
72083
- currentIndex += 1;
72084
72117
  }
72118
+ currentIndex += 1;
72085
72119
  }
72086
72120
  for (const size in resizingGroups) {
72087
72121
  this.dispatch("RESIZE_COLUMNS_ROWS", {
@@ -80253,7 +80287,7 @@ stores.inject(MyMetaStore, storeInstance);
80253
80287
  handlers = [];
80254
80288
  uiHandlers = [];
80255
80289
  coreHandlers = [];
80256
- constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
80290
+ constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = false) {
80257
80291
  const start = performance.now();
80258
80292
  console.debug("##### Model creation #####");
80259
80293
  super();
@@ -80996,9 +81030,9 @@ stores.inject(MyMetaStore, storeInstance);
80996
81030
  exports.tokenize = tokenize;
80997
81031
 
80998
81032
 
80999
- __info__.version = "18.3.19";
81000
- __info__.date = "2025-09-05T07:38:30.661Z";
81001
- __info__.hash = "77fd307";
81033
+ __info__.version = "18.3.21";
81034
+ __info__.date = "2025-09-19T07:25:12.089Z";
81035
+ __info__.hash = "b64ee85";
81002
81036
 
81003
81037
 
81004
81038
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);