@odoo/o-spreadsheet 18.5.0-alpha.1 → 18.5.0-alpha.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.5.0-alpha.1
6
- * @date 2025-06-27T09:12:49.245Z
7
- * @hash 756e75b
5
+ * @version 18.5.0-alpha.2
6
+ * @date 2025-07-11T11:13:53.317Z
7
+ * @hash 6d42178
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -852,6 +852,7 @@ const specialWhiteSpaceSpecialCharacters = [
852
852
  ];
853
853
  const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
854
854
  const newLineRegexp = /(\r\n|\r)/g;
855
+ const whiteSpaceCharacters = specialWhiteSpaceSpecialCharacters.concat([" "]);
855
856
  /**
856
857
  * Replace all different newlines characters by \n
857
858
  */
@@ -1988,8 +1989,9 @@ const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
1988
1989
  const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
1989
1990
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
1990
1991
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
1991
- const dateSeparatorsRegex = /\/|-|\s/;
1992
- const dateRegexp = /^(\d{1,4})[\/-\s](\d{1,4})([\/-\s](\d{1,4}))?$/;
1992
+ const whiteSpaceChars = whiteSpaceCharacters.join("");
1993
+ const dateSeparatorsRegex = new RegExp(`\/|-|${whiteSpaceCharacters.join("|")}`);
1994
+ const dateRegexp = new RegExp(`^(\\d{1,4})[\/${whiteSpaceChars}\-](\\d{1,4})([\/${whiteSpaceChars}\-](\\d{1,4}))?$`);
1993
1995
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
1994
1996
  /** Convert a value number representing a date, or return undefined if it isn't possible */
1995
1997
  function valueToDateNumber(value, locale) {
@@ -6924,6 +6926,8 @@ function splitWordToSpecificWidth(ctx, word, width, style) {
6924
6926
  function splitTextToWidth(ctx, text, style, width) {
6925
6927
  if (!style)
6926
6928
  style = {};
6929
+ if (isMarkdownLink(text))
6930
+ text = parseMarkdownLink(text).label;
6927
6931
  const brokenText = [];
6928
6932
  // Checking if text contains NEWLINE before split makes it very slightly slower if text contains it,
6929
6933
  // but 5-10x faster if it doesn't
@@ -8764,6 +8768,10 @@ function toNormalizedPivotValue(dimension, groupValue) {
8764
8768
  if (groupValue === null || groupValue === "null") {
8765
8769
  return null;
8766
8770
  }
8771
+ const extractedGroupValue = typeof groupValue === "object" ? groupValue.value : groupValue;
8772
+ if (isEvaluationError(extractedGroupValue)) {
8773
+ return extractedGroupValue;
8774
+ }
8767
8775
  const groupValueString = typeof groupValue === "boolean"
8768
8776
  ? toString(groupValue).toLocaleLowerCase()
8769
8777
  : toString(groupValue);
@@ -27446,7 +27454,9 @@ function getSectionThresholdValue(sheetId, threshold, minValue, maxValue, getter
27446
27454
  }
27447
27455
  function getFormulaNumberValue(sheetId, formula, getters) {
27448
27456
  const value = getters.evaluateFormula(sheetId, formula);
27449
- return isMatrix(value) ? undefined : tryToNumber(value, getters.getLocale());
27457
+ return isMultipleElementMatrix(value)
27458
+ ? undefined
27459
+ : tryToNumber(toScalar(value), getters.getLocale());
27450
27460
  }
27451
27461
  function getInvalidGaugeRuntime(chart, getters) {
27452
27462
  return {
@@ -31071,6 +31081,9 @@ class ErrorToolTip extends Component {
31071
31081
  return undefined;
31072
31082
  }
31073
31083
  get errorOriginPositionString() {
31084
+ if (this.env.model.getters.isDashboard()) {
31085
+ return "";
31086
+ }
31074
31087
  const evaluationError = this.evaluationError;
31075
31088
  const position = evaluationError?.errorOriginPosition;
31076
31089
  if (!position || deepEquals(position, this.props.cellPosition)) {
@@ -39219,40 +39232,112 @@ function convertPivotTableConfig(pivotTable) {
39219
39232
  * In all the sheets, replace the table-only references in the formula cells with standard references.
39220
39233
  */
39221
39234
  function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
39235
+ let deconstructedSheets = null;
39222
39236
  for (const tableSheet of convertedSheets) {
39223
39237
  const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
39238
+ if (!tables || tables.length === 0) {
39239
+ continue;
39240
+ }
39241
+ // Only deconstruct sheets if we are sure there are tables to process
39242
+ if (!deconstructedSheets) {
39243
+ deconstructedSheets = deconstructSheets(convertedSheets);
39244
+ }
39224
39245
  for (const table of tables) {
39225
- const tabRef = table.name + "[";
39226
- for (const sheet of convertedSheets) {
39227
- for (const xc in sheet.cells) {
39228
- const cell = sheet.cells[xc];
39229
- let cellContent = sheet.cells[xc];
39230
- if (cell && cellContent && cellContent.startsWith("=")) {
39231
- let refIndex;
39232
- while ((refIndex = cellContent.indexOf(tabRef)) !== -1) {
39233
- let endIndex = refIndex + tabRef.length;
39234
- let openBrackets = 1;
39235
- while (openBrackets > 0 && endIndex < cellContent.length) {
39236
- if (cellContent[endIndex] === "[") {
39237
- openBrackets++;
39238
- }
39239
- else if (cellContent[endIndex] === "]") {
39240
- openBrackets--;
39241
- }
39242
- endIndex++;
39243
- }
39244
- const reference = cellContent.slice(refIndex + tabRef.length, endIndex - 1);
39245
- const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
39246
- const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
39247
- cellContent =
39248
- cellContent.slice(0, refIndex) + convertedRef + cellContent.slice(endIndex);
39246
+ for (const sheetId in deconstructedSheets) {
39247
+ const sheet = convertedSheets.find((s) => s.id === sheetId);
39248
+ for (const xc in deconstructedSheets[sheetId]) {
39249
+ const deconstructedCell = deconstructedSheets[sheetId][xc];
39250
+ for (let i = deconstructedCell.length - 3; i >= 0; i -= 2) {
39251
+ const possibleTable = deconstructedSheets[sheetId][xc][i];
39252
+ if (!possibleTable.endsWith(table.name)) {
39253
+ continue;
39249
39254
  }
39255
+ const possibleRef = deconstructedSheets[sheetId][xc][i + 1];
39256
+ const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
39257
+ const convertedRef = convertTableReference(sheetPrefix, possibleRef, table, xc);
39258
+ deconstructedSheets[sheetId][xc][i + 2] =
39259
+ possibleTable.slice(0, possibleTable.indexOf(table.name)) +
39260
+ convertedRef +
39261
+ deconstructedSheets[sheetId][xc][i + 2];
39262
+ deconstructedSheets[sheetId][xc].splice(i, 2);
39250
39263
  }
39251
- sheet.cells[xc] = cellContent;
39264
+ // sheet.cells[xc] = cellContent;
39252
39265
  }
39253
39266
  }
39254
39267
  }
39255
39268
  }
39269
+ if (!deconstructedSheets) {
39270
+ return;
39271
+ }
39272
+ for (const sheetId in deconstructedSheets) {
39273
+ const sheet = convertedSheets.find((s) => s.id === sheetId);
39274
+ for (const xc in deconstructedSheets[sheetId]) {
39275
+ const deconstructedCell = deconstructedSheets[sheetId][xc];
39276
+ if (deconstructedCell.length === 1) {
39277
+ sheet.cells[xc] = deconstructedCell[0];
39278
+ continue;
39279
+ }
39280
+ let newContent = "";
39281
+ for (let i = 0; i < deconstructedCell.length; i += 2) {
39282
+ newContent += deconstructedCell[i] + "[" + deconstructedCell[i + 1] + "]";
39283
+ }
39284
+ newContent += deconstructedCell[deconstructedCell.length - 1];
39285
+ sheet.cells[xc] = newContent;
39286
+ }
39287
+ }
39288
+ }
39289
+ /**
39290
+ * Deconstruct the content of the cells in the sheets to extract possible table references.
39291
+ * Example from "=AVERAGE(Table1[colName1])-AVERAGE(Table2[colName2])":
39292
+ * return --> ["=AVERAGE(Table1", "colName1", ")-AVERAGE(Table2", "colName2", ")"]
39293
+ */
39294
+ function deconstructSheets(convertedSheets) {
39295
+ const deconstructedSheets = {};
39296
+ for (const sheet of convertedSheets) {
39297
+ for (const xc in sheet.cells) {
39298
+ const cellContent = sheet.cells[xc];
39299
+ if (!cellContent || !cellContent.startsWith("=")) {
39300
+ continue;
39301
+ }
39302
+ const startIndex = cellContent.indexOf("[");
39303
+ if (startIndex === -1) {
39304
+ continue;
39305
+ }
39306
+ const deconstructedCell = [];
39307
+ let possibleTable = cellContent.slice(0, startIndex);
39308
+ let possibleRef = "";
39309
+ let openBrackets = 1;
39310
+ let mainPossibleTableIndex = 0;
39311
+ let mainOpenBracketIndex = startIndex;
39312
+ for (let index = startIndex + 1; index < cellContent.length; index++) {
39313
+ if (cellContent[index] === "[") {
39314
+ if (openBrackets === 0) {
39315
+ possibleTable = cellContent.slice(mainPossibleTableIndex, index);
39316
+ mainOpenBracketIndex = index;
39317
+ }
39318
+ openBrackets++;
39319
+ continue;
39320
+ }
39321
+ if (cellContent[index] === "]") {
39322
+ openBrackets--;
39323
+ if (openBrackets === 0) {
39324
+ possibleRef = cellContent.slice(mainOpenBracketIndex + 1, index);
39325
+ deconstructedCell.push(possibleTable);
39326
+ deconstructedCell.push(possibleRef);
39327
+ mainPossibleTableIndex = index + 1;
39328
+ }
39329
+ }
39330
+ }
39331
+ if (deconstructedCell.length) {
39332
+ if (!deconstructedSheets[sheet.id]) {
39333
+ deconstructedSheets[sheet.id] = {};
39334
+ }
39335
+ deconstructedCell.push(cellContent.slice(mainPossibleTableIndex));
39336
+ deconstructedSheets[sheet.id][xc] = [...deconstructedCell];
39337
+ }
39338
+ }
39339
+ }
39340
+ return deconstructedSheets;
39256
39341
  }
39257
39342
  /**
39258
39343
  * Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
@@ -45564,10 +45649,10 @@ class CellComposerStore extends AbstractComposerStore {
45564
45649
  const cellValue = isFormula(content)
45565
45650
  ? this.getters.evaluateFormula(this.sheetId, content)
45566
45651
  : parseLiteral(content, this.getters.getLocale());
45567
- if (isMatrix(cellValue)) {
45652
+ if (isMultipleElementMatrix(cellValue)) {
45568
45653
  return true;
45569
45654
  }
45570
- const validationResult = this.getters.getValidationResultForCellValue(cellValue, cellPosition);
45655
+ const validationResult = this.getters.getValidationResultForCellValue(toScalar(cellValue), cellPosition);
45571
45656
  if (!validationResult.isValid && validationResult.rule.isBlocking) {
45572
45657
  return false;
45573
45658
  }
@@ -50679,10 +50764,10 @@ class GaugeChartDesignPanel extends Component {
50679
50764
  return tryToNumber(value, locale) !== undefined;
50680
50765
  }
50681
50766
  const evaluatedValue = this.env.model.getters.evaluateFormula(this.sheetId, value);
50682
- if (isMatrix(evaluatedValue)) {
50767
+ if (isMultipleElementMatrix(evaluatedValue)) {
50683
50768
  return false;
50684
50769
  }
50685
- return tryToNumber(evaluatedValue, locale) !== undefined;
50770
+ return tryToNumber(toScalar(evaluatedValue), locale) !== undefined;
50686
50771
  }
50687
50772
  get sheetId() {
50688
50773
  const chart = this.env.model.getters.getChart(this.props.figureId);
@@ -51536,12 +51621,32 @@ class ChartPanel extends Component {
51536
51621
  static template = "o-spreadsheet-ChartPanel";
51537
51622
  static components = { Section, ChartTypePicker };
51538
51623
  static props = { onCloseSidePanel: Function, figureId: String };
51624
+ panelContentRef;
51625
+ scrollPositions = {
51626
+ configuration: 0,
51627
+ design: 0,
51628
+ };
51539
51629
  store;
51540
51630
  get figureId() {
51541
51631
  return this.props.figureId;
51542
51632
  }
51543
51633
  setup() {
51544
51634
  this.store = useLocalStore(MainChartPanelStore);
51635
+ this.panelContentRef = useRef("panelContent");
51636
+ useEffect(() => {
51637
+ const el = this.panelContentRef.el;
51638
+ const activePanel = this.store.panel;
51639
+ if (el) {
51640
+ el.scrollTop = this.scrollPositions[activePanel];
51641
+ }
51642
+ }, () => [this.store.panel]);
51643
+ }
51644
+ switchPanel(panel) {
51645
+ const el = this.panelContentRef.el;
51646
+ if (el) {
51647
+ this.scrollPositions[this.store.panel] = el.scrollTop;
51648
+ }
51649
+ this.store.activatePanel(panel);
51545
51650
  }
51546
51651
  updateChart(figureId, updateDefinition) {
51547
51652
  if (figureId !== this.figureId) {
@@ -55493,10 +55598,7 @@ class SpreadsheetPivot {
55493
55598
  if (finalCell.value === null) {
55494
55599
  return { value: _t("(Undefined)") };
55495
55600
  }
55496
- return {
55497
- value: finalCell.value,
55498
- format: finalCell.format,
55499
- };
55601
+ return finalCell;
55500
55602
  }
55501
55603
  getPivotCellValueAndFormat(measureId, domain) {
55502
55604
  const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
@@ -55734,7 +55836,6 @@ pivotRegistry.add("SPREADSHEET", {
55734
55836
  ui: SpreadsheetPivot,
55735
55837
  definition: SpreadsheetPivotRuntimeDefinition,
55736
55838
  externalData: false,
55737
- onIterationEndEvaluation: (pivot) => pivot.markAsDirtyForEvaluation(),
55738
55839
  dateGranularities: [...dateGranularities],
55739
55840
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
55740
55841
  isMeasureCandidate: (field) => field.type !== "boolean",
@@ -64385,7 +64486,7 @@ const onIterationEndEvaluationRegistry = new Registry();
64385
64486
  onIterationEndEvaluationRegistry.add("pivots", (getters) => {
64386
64487
  for (const pivotId of getters.getPivotIds()) {
64387
64488
  const pivot = getters.getPivot(pivotId);
64388
- pivotRegistry.get(pivot.type).onIterationEndEvaluation(pivot);
64489
+ pivot.markAsDirtyForEvaluation?.();
64389
64490
  }
64390
64491
  });
64391
64492
 
@@ -66849,12 +66950,12 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
66849
66950
  }
66850
66951
  return this.getters.evaluateFormula(sheetId, value) ?? "";
66851
66952
  });
66852
- if (evaluatedCriterionValues.some(isMatrix)) {
66953
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
66853
66954
  return false;
66854
66955
  }
66855
66956
  const evaluatedCriterion = {
66856
66957
  type: rule.operator,
66857
- values: evaluatedCriterionValues,
66958
+ values: evaluatedCriterionValues.map(toScalar),
66858
66959
  };
66859
66960
  return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion, this.getters, sheetId);
66860
66961
  }
@@ -67014,10 +67115,10 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
67014
67115
  const evaluator = criterionEvaluatorRegistry.get(criterion.type);
67015
67116
  const offset = this.getCellOffsetInRule(cellPosition, rule);
67016
67117
  const evaluatedCriterionValues = this.getEvaluatedCriterionValues(sheetId, offset, criterion);
67017
- if (evaluatedCriterionValues.some(isMatrix)) {
67118
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
67018
67119
  return undefined;
67019
67120
  }
67020
- const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues };
67121
+ const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues.map(toScalar) };
67021
67122
  if (evaluator.isValueValid(cellValue, evaluatedCriterion, this.getters, sheetId)) {
67022
67123
  return undefined;
67023
67124
  }
@@ -67660,13 +67761,13 @@ function withPivotPresentationLayer (PivotClass) {
67660
67761
  super(custom, params);
67661
67762
  this.getters = params.getters;
67662
67763
  }
67663
- init(params) {
67764
+ markAsDirtyForEvaluation() {
67664
67765
  this.cache = {};
67665
67766
  this.rankAsc = {};
67666
67767
  this.rankDesc = {};
67667
67768
  this.runningTotal = {};
67668
67769
  this.runningTotalInPercent = {};
67669
- super.init(params);
67770
+ super.markAsDirtyForEvaluation?.();
67670
67771
  }
67671
67772
  getPivotCellValueAndFormat(measureName, domain) {
67672
67773
  return this.getMeasureDisplayValue(measureName, domain);
@@ -67791,7 +67892,7 @@ function withPivotPresentationLayer (PivotClass) {
67791
67892
  return this.getSubTreeMatchingDomain(node.children, domain, domainLevel + 1);
67792
67893
  }
67793
67894
  }
67794
- return tree;
67895
+ return [];
67795
67896
  }
67796
67897
  treeToLeafDomains(tree, parentDomain = []) {
67797
67898
  const domains = [];
@@ -73530,12 +73631,12 @@ class FilterEvaluationPlugin extends UIPlugin {
73530
73631
  }
73531
73632
  return this.getters.evaluateFormula(sheetId, value) ?? "";
73532
73633
  });
73533
- if (evaluatedCriterionValues.some(isMatrix)) {
73634
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
73534
73635
  continue;
73535
73636
  }
73536
73637
  const evaluatedCriterion = {
73537
73638
  type: filterValue.type,
73538
- values: evaluatedCriterionValues,
73639
+ values: evaluatedCriterionValues.map(toScalar),
73539
73640
  dateValue: filterValue.dateValue,
73540
73641
  };
73541
73642
  for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
@@ -84463,6 +84564,7 @@ const stores = {
84463
84564
  PivotSidePanelStore,
84464
84565
  PivotMeasureDisplayPanelStore,
84465
84566
  ClientFocusStore,
84567
+ GridRenderer,
84466
84568
  };
84467
84569
  function addFunction(functionName, functionDescription) {
84468
84570
  functionRegistry.add(functionName, functionDescription);
@@ -84481,6 +84583,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
84481
84583
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, 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 };
84482
84584
 
84483
84585
 
84484
- __info__.version = "18.5.0-alpha.1";
84485
- __info__.date = "2025-06-27T09:12:49.245Z";
84486
- __info__.hash = "756e75b";
84586
+ __info__.version = "18.5.0-alpha.2";
84587
+ __info__.date = "2025-07-11T11:13:53.317Z";
84588
+ __info__.hash = "6d42178";