@odoo/o-spreadsheet 18.4.1 → 18.4.2

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.4.1
6
- * @date 2025-06-27T09:13:01.303Z
7
- * @hash 5cecc0e
5
+ * @version 18.4.2
6
+ * @date 2025-07-11T11:11:12.642Z
7
+ * @hash 29b6458
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -853,6 +853,7 @@
853
853
  ];
854
854
  const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
855
855
  const newLineRegexp = /(\r\n|\r)/g;
856
+ const whiteSpaceCharacters = specialWhiteSpaceSpecialCharacters.concat([" "]);
856
857
  /**
857
858
  * Replace all different newlines characters by \n
858
859
  */
@@ -1989,8 +1990,9 @@
1989
1990
  const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
1990
1991
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
1991
1992
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
1992
- const dateSeparatorsRegex = /\/|-|\s/;
1993
- const dateRegexp = /^(\d{1,4})[\/-\s](\d{1,4})([\/-\s](\d{1,4}))?$/;
1993
+ const whiteSpaceChars = whiteSpaceCharacters.join("");
1994
+ const dateSeparatorsRegex = new RegExp(`\/|-|${whiteSpaceCharacters.join("|")}`);
1995
+ const dateRegexp = new RegExp(`^(\\d{1,4})[\/${whiteSpaceChars}\-](\\d{1,4})([\/${whiteSpaceChars}\-](\\d{1,4}))?$`);
1994
1996
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
1995
1997
  /** Convert a value number representing a date, or return undefined if it isn't possible */
1996
1998
  function valueToDateNumber(value, locale) {
@@ -6925,6 +6927,8 @@
6925
6927
  function splitTextToWidth(ctx, text, style, width) {
6926
6928
  if (!style)
6927
6929
  style = {};
6930
+ if (isMarkdownLink(text))
6931
+ text = parseMarkdownLink(text).label;
6928
6932
  const brokenText = [];
6929
6933
  // Checking if text contains NEWLINE before split makes it very slightly slower if text contains it,
6930
6934
  // but 5-10x faster if it doesn't
@@ -8765,6 +8769,10 @@
8765
8769
  if (groupValue === null || groupValue === "null") {
8766
8770
  return null;
8767
8771
  }
8772
+ const extractedGroupValue = typeof groupValue === "object" ? groupValue.value : groupValue;
8773
+ if (isEvaluationError(extractedGroupValue)) {
8774
+ return extractedGroupValue;
8775
+ }
8768
8776
  const groupValueString = typeof groupValue === "boolean"
8769
8777
  ? toString(groupValue).toLocaleLowerCase()
8770
8778
  : toString(groupValue);
@@ -27447,7 +27455,9 @@ stores.inject(MyMetaStore, storeInstance);
27447
27455
  }
27448
27456
  function getFormulaNumberValue(sheetId, formula, getters) {
27449
27457
  const value = getters.evaluateFormula(sheetId, formula);
27450
- return isMatrix(value) ? undefined : tryToNumber(value, getters.getLocale());
27458
+ return isMultipleElementMatrix(value)
27459
+ ? undefined
27460
+ : tryToNumber(toScalar(value), getters.getLocale());
27451
27461
  }
27452
27462
  function getInvalidGaugeRuntime(chart, getters) {
27453
27463
  return {
@@ -31072,6 +31082,9 @@ stores.inject(MyMetaStore, storeInstance);
31072
31082
  return undefined;
31073
31083
  }
31074
31084
  get errorOriginPositionString() {
31085
+ if (this.env.model.getters.isDashboard()) {
31086
+ return "";
31087
+ }
31075
31088
  const evaluationError = this.evaluationError;
31076
31089
  const position = evaluationError?.errorOriginPosition;
31077
31090
  if (!position || deepEquals(position, this.props.cellPosition)) {
@@ -39220,40 +39233,112 @@ stores.inject(MyMetaStore, storeInstance);
39220
39233
  * In all the sheets, replace the table-only references in the formula cells with standard references.
39221
39234
  */
39222
39235
  function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
39236
+ let deconstructedSheets = null;
39223
39237
  for (const tableSheet of convertedSheets) {
39224
39238
  const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
39239
+ if (!tables || tables.length === 0) {
39240
+ continue;
39241
+ }
39242
+ // Only deconstruct sheets if we are sure there are tables to process
39243
+ if (!deconstructedSheets) {
39244
+ deconstructedSheets = deconstructSheets(convertedSheets);
39245
+ }
39225
39246
  for (const table of tables) {
39226
- const tabRef = table.name + "[";
39227
- for (const sheet of convertedSheets) {
39228
- for (const xc in sheet.cells) {
39229
- const cell = sheet.cells[xc];
39230
- let cellContent = sheet.cells[xc];
39231
- if (cell && cellContent && cellContent.startsWith("=")) {
39232
- let refIndex;
39233
- while ((refIndex = cellContent.indexOf(tabRef)) !== -1) {
39234
- let endIndex = refIndex + tabRef.length;
39235
- let openBrackets = 1;
39236
- while (openBrackets > 0 && endIndex < cellContent.length) {
39237
- if (cellContent[endIndex] === "[") {
39238
- openBrackets++;
39239
- }
39240
- else if (cellContent[endIndex] === "]") {
39241
- openBrackets--;
39242
- }
39243
- endIndex++;
39244
- }
39245
- const reference = cellContent.slice(refIndex + tabRef.length, endIndex - 1);
39246
- const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
39247
- const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
39248
- cellContent =
39249
- cellContent.slice(0, refIndex) + convertedRef + cellContent.slice(endIndex);
39247
+ for (const sheetId in deconstructedSheets) {
39248
+ const sheet = convertedSheets.find((s) => s.id === sheetId);
39249
+ for (const xc in deconstructedSheets[sheetId]) {
39250
+ const deconstructedCell = deconstructedSheets[sheetId][xc];
39251
+ for (let i = deconstructedCell.length - 3; i >= 0; i -= 2) {
39252
+ const possibleTable = deconstructedSheets[sheetId][xc][i];
39253
+ if (!possibleTable.endsWith(table.name)) {
39254
+ continue;
39250
39255
  }
39256
+ const possibleRef = deconstructedSheets[sheetId][xc][i + 1];
39257
+ const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
39258
+ const convertedRef = convertTableReference(sheetPrefix, possibleRef, table, xc);
39259
+ deconstructedSheets[sheetId][xc][i + 2] =
39260
+ possibleTable.slice(0, possibleTable.indexOf(table.name)) +
39261
+ convertedRef +
39262
+ deconstructedSheets[sheetId][xc][i + 2];
39263
+ deconstructedSheets[sheetId][xc].splice(i, 2);
39264
+ }
39265
+ // sheet.cells[xc] = cellContent;
39266
+ }
39267
+ }
39268
+ }
39269
+ }
39270
+ if (!deconstructedSheets) {
39271
+ return;
39272
+ }
39273
+ for (const sheetId in deconstructedSheets) {
39274
+ const sheet = convertedSheets.find((s) => s.id === sheetId);
39275
+ for (const xc in deconstructedSheets[sheetId]) {
39276
+ const deconstructedCell = deconstructedSheets[sheetId][xc];
39277
+ if (deconstructedCell.length === 1) {
39278
+ sheet.cells[xc] = deconstructedCell[0];
39279
+ continue;
39280
+ }
39281
+ let newContent = "";
39282
+ for (let i = 0; i < deconstructedCell.length; i += 2) {
39283
+ newContent += deconstructedCell[i] + "[" + deconstructedCell[i + 1] + "]";
39284
+ }
39285
+ newContent += deconstructedCell[deconstructedCell.length - 1];
39286
+ sheet.cells[xc] = newContent;
39287
+ }
39288
+ }
39289
+ }
39290
+ /**
39291
+ * Deconstruct the content of the cells in the sheets to extract possible table references.
39292
+ * Example from "=AVERAGE(Table1[colName1])-AVERAGE(Table2[colName2])":
39293
+ * return --> ["=AVERAGE(Table1", "colName1", ")-AVERAGE(Table2", "colName2", ")"]
39294
+ */
39295
+ function deconstructSheets(convertedSheets) {
39296
+ const deconstructedSheets = {};
39297
+ for (const sheet of convertedSheets) {
39298
+ for (const xc in sheet.cells) {
39299
+ const cellContent = sheet.cells[xc];
39300
+ if (!cellContent || !cellContent.startsWith("=")) {
39301
+ continue;
39302
+ }
39303
+ const startIndex = cellContent.indexOf("[");
39304
+ if (startIndex === -1) {
39305
+ continue;
39306
+ }
39307
+ const deconstructedCell = [];
39308
+ let possibleTable = cellContent.slice(0, startIndex);
39309
+ let possibleRef = "";
39310
+ let openBrackets = 1;
39311
+ let mainPossibleTableIndex = 0;
39312
+ let mainOpenBracketIndex = startIndex;
39313
+ for (let index = startIndex + 1; index < cellContent.length; index++) {
39314
+ if (cellContent[index] === "[") {
39315
+ if (openBrackets === 0) {
39316
+ possibleTable = cellContent.slice(mainPossibleTableIndex, index);
39317
+ mainOpenBracketIndex = index;
39318
+ }
39319
+ openBrackets++;
39320
+ continue;
39321
+ }
39322
+ if (cellContent[index] === "]") {
39323
+ openBrackets--;
39324
+ if (openBrackets === 0) {
39325
+ possibleRef = cellContent.slice(mainOpenBracketIndex + 1, index);
39326
+ deconstructedCell.push(possibleTable);
39327
+ deconstructedCell.push(possibleRef);
39328
+ mainPossibleTableIndex = index + 1;
39251
39329
  }
39252
- sheet.cells[xc] = cellContent;
39253
39330
  }
39254
39331
  }
39332
+ if (deconstructedCell.length) {
39333
+ if (!deconstructedSheets[sheet.id]) {
39334
+ deconstructedSheets[sheet.id] = {};
39335
+ }
39336
+ deconstructedCell.push(cellContent.slice(mainPossibleTableIndex));
39337
+ deconstructedSheets[sheet.id][xc] = [...deconstructedCell];
39338
+ }
39255
39339
  }
39256
39340
  }
39341
+ return deconstructedSheets;
39257
39342
  }
39258
39343
  /**
39259
39344
  * Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
@@ -45565,10 +45650,10 @@ stores.inject(MyMetaStore, storeInstance);
45565
45650
  const cellValue = isFormula(content)
45566
45651
  ? this.getters.evaluateFormula(this.sheetId, content)
45567
45652
  : parseLiteral(content, this.getters.getLocale());
45568
- if (isMatrix(cellValue)) {
45653
+ if (isMultipleElementMatrix(cellValue)) {
45569
45654
  return true;
45570
45655
  }
45571
- const validationResult = this.getters.getValidationResultForCellValue(cellValue, cellPosition);
45656
+ const validationResult = this.getters.getValidationResultForCellValue(toScalar(cellValue), cellPosition);
45572
45657
  if (!validationResult.isValid && validationResult.rule.isBlocking) {
45573
45658
  return false;
45574
45659
  }
@@ -50680,10 +50765,10 @@ stores.inject(MyMetaStore, storeInstance);
50680
50765
  return tryToNumber(value, locale) !== undefined;
50681
50766
  }
50682
50767
  const evaluatedValue = this.env.model.getters.evaluateFormula(this.sheetId, value);
50683
- if (isMatrix(evaluatedValue)) {
50768
+ if (isMultipleElementMatrix(evaluatedValue)) {
50684
50769
  return false;
50685
50770
  }
50686
- return tryToNumber(evaluatedValue, locale) !== undefined;
50771
+ return tryToNumber(toScalar(evaluatedValue), locale) !== undefined;
50687
50772
  }
50688
50773
  get sheetId() {
50689
50774
  const chart = this.env.model.getters.getChart(this.props.figureId);
@@ -55494,10 +55579,7 @@ stores.inject(MyMetaStore, storeInstance);
55494
55579
  if (finalCell.value === null) {
55495
55580
  return { value: _t("(Undefined)") };
55496
55581
  }
55497
- return {
55498
- value: finalCell.value,
55499
- format: finalCell.format,
55500
- };
55582
+ return finalCell;
55501
55583
  }
55502
55584
  getPivotCellValueAndFormat(measureId, domain) {
55503
55585
  const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
@@ -55735,7 +55817,6 @@ stores.inject(MyMetaStore, storeInstance);
55735
55817
  ui: SpreadsheetPivot,
55736
55818
  definition: SpreadsheetPivotRuntimeDefinition,
55737
55819
  externalData: false,
55738
- onIterationEndEvaluation: (pivot) => pivot.markAsDirtyForEvaluation(),
55739
55820
  dateGranularities: [...dateGranularities],
55740
55821
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
55741
55822
  isMeasureCandidate: (field) => field.type !== "boolean",
@@ -64386,7 +64467,7 @@ stores.inject(MyMetaStore, storeInstance);
64386
64467
  onIterationEndEvaluationRegistry.add("pivots", (getters) => {
64387
64468
  for (const pivotId of getters.getPivotIds()) {
64388
64469
  const pivot = getters.getPivot(pivotId);
64389
- pivotRegistry.get(pivot.type).onIterationEndEvaluation(pivot);
64470
+ pivot.markAsDirtyForEvaluation?.();
64390
64471
  }
64391
64472
  });
64392
64473
 
@@ -66850,12 +66931,12 @@ stores.inject(MyMetaStore, storeInstance);
66850
66931
  }
66851
66932
  return this.getters.evaluateFormula(sheetId, value) ?? "";
66852
66933
  });
66853
- if (evaluatedCriterionValues.some(isMatrix)) {
66934
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
66854
66935
  return false;
66855
66936
  }
66856
66937
  const evaluatedCriterion = {
66857
66938
  type: rule.operator,
66858
- values: evaluatedCriterionValues,
66939
+ values: evaluatedCriterionValues.map(toScalar),
66859
66940
  };
66860
66941
  return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion, this.getters, sheetId);
66861
66942
  }
@@ -67015,10 +67096,10 @@ stores.inject(MyMetaStore, storeInstance);
67015
67096
  const evaluator = criterionEvaluatorRegistry.get(criterion.type);
67016
67097
  const offset = this.getCellOffsetInRule(cellPosition, rule);
67017
67098
  const evaluatedCriterionValues = this.getEvaluatedCriterionValues(sheetId, offset, criterion);
67018
- if (evaluatedCriterionValues.some(isMatrix)) {
67099
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
67019
67100
  return undefined;
67020
67101
  }
67021
- const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues };
67102
+ const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues.map(toScalar) };
67022
67103
  if (evaluator.isValueValid(cellValue, evaluatedCriterion, this.getters, sheetId)) {
67023
67104
  return undefined;
67024
67105
  }
@@ -67661,13 +67742,13 @@ stores.inject(MyMetaStore, storeInstance);
67661
67742
  super(custom, params);
67662
67743
  this.getters = params.getters;
67663
67744
  }
67664
- init(params) {
67745
+ markAsDirtyForEvaluation() {
67665
67746
  this.cache = {};
67666
67747
  this.rankAsc = {};
67667
67748
  this.rankDesc = {};
67668
67749
  this.runningTotal = {};
67669
67750
  this.runningTotalInPercent = {};
67670
- super.init(params);
67751
+ super.markAsDirtyForEvaluation?.();
67671
67752
  }
67672
67753
  getPivotCellValueAndFormat(measureName, domain) {
67673
67754
  return this.getMeasureDisplayValue(measureName, domain);
@@ -67792,7 +67873,7 @@ stores.inject(MyMetaStore, storeInstance);
67792
67873
  return this.getSubTreeMatchingDomain(node.children, domain, domainLevel + 1);
67793
67874
  }
67794
67875
  }
67795
- return tree;
67876
+ return [];
67796
67877
  }
67797
67878
  treeToLeafDomains(tree, parentDomain = []) {
67798
67879
  const domains = [];
@@ -73524,12 +73605,12 @@ stores.inject(MyMetaStore, storeInstance);
73524
73605
  }
73525
73606
  return this.getters.evaluateFormula(sheetId, value) ?? "";
73526
73607
  });
73527
- if (evaluatedCriterionValues.some(isMatrix)) {
73608
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
73528
73609
  continue;
73529
73610
  }
73530
73611
  const evaluatedCriterion = {
73531
73612
  type: filterValue.type,
73532
- values: evaluatedCriterionValues,
73613
+ values: evaluatedCriterionValues.map(toScalar),
73533
73614
  dateValue: filterValue.dateValue,
73534
73615
  };
73535
73616
  for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
@@ -84457,6 +84538,7 @@ stores.inject(MyMetaStore, storeInstance);
84457
84538
  PivotSidePanelStore,
84458
84539
  PivotMeasureDisplayPanelStore,
84459
84540
  ClientFocusStore,
84541
+ GridRenderer,
84460
84542
  };
84461
84543
  function addFunction(functionName, functionDescription) {
84462
84544
  functionRegistry.add(functionName, functionDescription);
@@ -84523,9 +84605,9 @@ stores.inject(MyMetaStore, storeInstance);
84523
84605
  exports.tokenize = tokenize;
84524
84606
 
84525
84607
 
84526
- __info__.version = "18.4.1";
84527
- __info__.date = "2025-06-27T09:13:01.303Z";
84528
- __info__.hash = "5cecc0e";
84608
+ __info__.version = "18.4.2";
84609
+ __info__.date = "2025-07-11T11:11:12.642Z";
84610
+ __info__.hash = "29b6458";
84529
84611
 
84530
84612
 
84531
84613
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);