@odoo/o-spreadsheet 18.4.1 → 18.4.3

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.3
6
+ * @date 2025-07-28T13:39:06.036Z
7
+ * @hash 4b596d7
8
8
  */
9
9
 
10
10
  'use strict';
@@ -854,6 +854,7 @@ const specialWhiteSpaceSpecialCharacters = [
854
854
  ];
855
855
  const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
856
856
  const newLineRegexp = /(\r\n|\r)/g;
857
+ const whiteSpaceCharacters = specialWhiteSpaceSpecialCharacters.concat([" "]);
857
858
  /**
858
859
  * Replace all different newlines characters by \n
859
860
  */
@@ -1990,8 +1991,9 @@ const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
1990
1991
  const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
1991
1992
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
1992
1993
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
1993
- const dateSeparatorsRegex = /\/|-|\s/;
1994
- const dateRegexp = /^(\d{1,4})[\/-\s](\d{1,4})([\/-\s](\d{1,4}))?$/;
1994
+ const whiteSpaceChars = whiteSpaceCharacters.join("");
1995
+ const dateSeparatorsRegex = new RegExp(`\/|-|${whiteSpaceCharacters.join("|")}`);
1996
+ const dateRegexp = new RegExp(`^(\\d{1,4})[\/${whiteSpaceChars}\-](\\d{1,4})([\/${whiteSpaceChars}\-](\\d{1,4}))?$`);
1995
1997
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
1996
1998
  /** Convert a value number representing a date, or return undefined if it isn't possible */
1997
1999
  function valueToDateNumber(value, locale) {
@@ -6926,6 +6928,8 @@ function splitWordToSpecificWidth(ctx, word, width, style) {
6926
6928
  function splitTextToWidth(ctx, text, style, width) {
6927
6929
  if (!style)
6928
6930
  style = {};
6931
+ if (isMarkdownLink(text))
6932
+ text = parseMarkdownLink(text).label;
6929
6933
  const brokenText = [];
6930
6934
  // Checking if text contains NEWLINE before split makes it very slightly slower if text contains it,
6931
6935
  // but 5-10x faster if it doesn't
@@ -8766,6 +8770,10 @@ function toNormalizedPivotValue(dimension, groupValue) {
8766
8770
  if (groupValue === null || groupValue === "null") {
8767
8771
  return null;
8768
8772
  }
8773
+ const extractedGroupValue = typeof groupValue === "object" ? groupValue.value : groupValue;
8774
+ if (isEvaluationError(extractedGroupValue)) {
8775
+ return extractedGroupValue;
8776
+ }
8769
8777
  const groupValueString = typeof groupValue === "boolean"
8770
8778
  ? toString(groupValue).toLocaleLowerCase()
8771
8779
  : toString(groupValue);
@@ -19027,13 +19035,19 @@ const COLUMN = {
19027
19035
  if (isEvaluationError(cellReference?.value)) {
19028
19036
  return cellReference;
19029
19037
  }
19030
- const column = cellReference === undefined
19031
- ? this.__originCellPosition?.col
19032
- : toZone(cellReference.value).left;
19033
- if (column === undefined) {
19034
- return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
19038
+ if (cellReference === undefined) {
19039
+ if (this.__originCellPosition?.col === undefined) {
19040
+ return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
19041
+ }
19042
+ return this.__originCellPosition.col + 1;
19043
+ }
19044
+ const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
19045
+ if (zone.left === zone.right) {
19046
+ return zone.left + 1;
19035
19047
  }
19036
- return column + 1;
19048
+ return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
19049
+ value: zone.left + col + 1,
19050
+ }));
19037
19051
  },
19038
19052
  isExported: true,
19039
19053
  };
@@ -19264,13 +19278,19 @@ const ROW = {
19264
19278
  if (isEvaluationError(cellReference?.value)) {
19265
19279
  return cellReference;
19266
19280
  }
19267
- const row = cellReference === undefined
19268
- ? this.__originCellPosition?.row
19269
- : toZone(cellReference.value).top;
19270
- if (row === undefined) {
19271
- return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
19281
+ if (cellReference === undefined) {
19282
+ if (this.__originCellPosition?.row === undefined) {
19283
+ return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
19284
+ }
19285
+ return this.__originCellPosition.row + 1;
19286
+ }
19287
+ const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
19288
+ if (zone.top === zone.bottom) {
19289
+ return zone.top + 1;
19272
19290
  }
19273
- return row + 1;
19291
+ return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
19292
+ value: zone.top + row + 1,
19293
+ }));
19274
19294
  },
19275
19295
  isExported: true,
19276
19296
  };
@@ -27448,7 +27468,9 @@ function getSectionThresholdValue(sheetId, threshold, minValue, maxValue, getter
27448
27468
  }
27449
27469
  function getFormulaNumberValue(sheetId, formula, getters) {
27450
27470
  const value = getters.evaluateFormula(sheetId, formula);
27451
- return isMatrix(value) ? undefined : tryToNumber(value, getters.getLocale());
27471
+ return isMultipleElementMatrix(value)
27472
+ ? undefined
27473
+ : tryToNumber(toScalar(value), getters.getLocale());
27452
27474
  }
27453
27475
  function getInvalidGaugeRuntime(chart, getters) {
27454
27476
  return {
@@ -31073,6 +31095,9 @@ class ErrorToolTip extends owl.Component {
31073
31095
  return undefined;
31074
31096
  }
31075
31097
  get errorOriginPositionString() {
31098
+ if (this.env.model.getters.isDashboard()) {
31099
+ return "";
31100
+ }
31076
31101
  const evaluationError = this.evaluationError;
31077
31102
  const position = evaluationError?.errorOriginPosition;
31078
31103
  if (!position || deepEquals(position, this.props.cellPosition)) {
@@ -32595,6 +32620,9 @@ class AbstractComposerStore extends SpreadsheetStore {
32595
32620
  get isAutoCompleteDisplayed() {
32596
32621
  return !!this.autoComplete.provider;
32597
32622
  }
32623
+ get canBeToggled() {
32624
+ return this.autoComplete.provider?.canBeToggled ?? true;
32625
+ }
32598
32626
  cycleReferences() {
32599
32627
  const locale = this.getters.getLocale();
32600
32628
  const updated = cycleFixedReference(this.composerSelection, this._currentContent, locale);
@@ -33124,6 +33152,7 @@ class AbstractComposerStore extends SpreadsheetStore {
33124
33152
  proposals,
33125
33153
  selectProposal: provider.selectProposal,
33126
33154
  autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
33155
+ canBeToggled: provider.canBeToggled,
33127
33156
  };
33128
33157
  }
33129
33158
  if (exactMatch && this._currentContent !== this.initialContent) {
@@ -33146,6 +33175,7 @@ class AbstractComposerStore extends SpreadsheetStore {
33146
33175
  proposals,
33147
33176
  selectProposal: provider.selectProposal,
33148
33177
  autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
33178
+ canBeToggled: provider.canBeToggled,
33149
33179
  };
33150
33180
  }
33151
33181
  }
@@ -33716,9 +33746,13 @@ class Composer extends owl.Component {
33716
33746
  }
33717
33747
  }
33718
33748
  closeAssistant() {
33749
+ if (!this.props.composerStore.canBeToggled)
33750
+ return;
33719
33751
  this.assistant.forcedClosed = true;
33720
33752
  }
33721
33753
  openAssistant() {
33754
+ if (!this.props.composerStore.canBeToggled)
33755
+ return;
33722
33756
  this.assistant.forcedClosed = false;
33723
33757
  }
33724
33758
  onWheel(event) {
@@ -33908,7 +33942,7 @@ class Composer extends owl.Component {
33908
33942
  return [...new Set(argsToFocus)];
33909
33943
  }
33910
33944
  autoComplete(value) {
33911
- if (!value || this.assistant.forcedClosed) {
33945
+ if (!value || (this.assistant.forcedClosed && this.props.composerStore.canBeToggled)) {
33912
33946
  return;
33913
33947
  }
33914
33948
  this.props.composerStore.insertAutoCompleteValue(value);
@@ -39221,40 +39255,112 @@ function convertPivotTableConfig(pivotTable) {
39221
39255
  * In all the sheets, replace the table-only references in the formula cells with standard references.
39222
39256
  */
39223
39257
  function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
39258
+ let deconstructedSheets = null;
39224
39259
  for (const tableSheet of convertedSheets) {
39225
39260
  const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
39261
+ if (!tables || tables.length === 0) {
39262
+ continue;
39263
+ }
39264
+ // Only deconstruct sheets if we are sure there are tables to process
39265
+ if (!deconstructedSheets) {
39266
+ deconstructedSheets = deconstructSheets(convertedSheets);
39267
+ }
39226
39268
  for (const table of tables) {
39227
- const tabRef = table.name + "[";
39228
- for (const sheet of convertedSheets) {
39229
- for (const xc in sheet.cells) {
39230
- const cell = sheet.cells[xc];
39231
- let cellContent = sheet.cells[xc];
39232
- if (cell && cellContent && cellContent.startsWith("=")) {
39233
- let refIndex;
39234
- while ((refIndex = cellContent.indexOf(tabRef)) !== -1) {
39235
- let endIndex = refIndex + tabRef.length;
39236
- let openBrackets = 1;
39237
- while (openBrackets > 0 && endIndex < cellContent.length) {
39238
- if (cellContent[endIndex] === "[") {
39239
- openBrackets++;
39240
- }
39241
- else if (cellContent[endIndex] === "]") {
39242
- openBrackets--;
39243
- }
39244
- endIndex++;
39245
- }
39246
- const reference = cellContent.slice(refIndex + tabRef.length, endIndex - 1);
39247
- const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
39248
- const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
39249
- cellContent =
39250
- cellContent.slice(0, refIndex) + convertedRef + cellContent.slice(endIndex);
39269
+ for (const sheetId in deconstructedSheets) {
39270
+ const sheet = convertedSheets.find((s) => s.id === sheetId);
39271
+ for (const xc in deconstructedSheets[sheetId]) {
39272
+ const deconstructedCell = deconstructedSheets[sheetId][xc];
39273
+ for (let i = deconstructedCell.length - 3; i >= 0; i -= 2) {
39274
+ const possibleTable = deconstructedSheets[sheetId][xc][i];
39275
+ if (!possibleTable.endsWith(table.name)) {
39276
+ continue;
39251
39277
  }
39278
+ const possibleRef = deconstructedSheets[sheetId][xc][i + 1];
39279
+ const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
39280
+ const convertedRef = convertTableReference(sheetPrefix, possibleRef, table, xc);
39281
+ deconstructedSheets[sheetId][xc][i + 2] =
39282
+ possibleTable.slice(0, possibleTable.indexOf(table.name)) +
39283
+ convertedRef +
39284
+ deconstructedSheets[sheetId][xc][i + 2];
39285
+ deconstructedSheets[sheetId][xc].splice(i, 2);
39252
39286
  }
39253
- sheet.cells[xc] = cellContent;
39287
+ // sheet.cells[xc] = cellContent;
39254
39288
  }
39255
39289
  }
39256
39290
  }
39257
39291
  }
39292
+ if (!deconstructedSheets) {
39293
+ return;
39294
+ }
39295
+ for (const sheetId in deconstructedSheets) {
39296
+ const sheet = convertedSheets.find((s) => s.id === sheetId);
39297
+ for (const xc in deconstructedSheets[sheetId]) {
39298
+ const deconstructedCell = deconstructedSheets[sheetId][xc];
39299
+ if (deconstructedCell.length === 1) {
39300
+ sheet.cells[xc] = deconstructedCell[0];
39301
+ continue;
39302
+ }
39303
+ let newContent = "";
39304
+ for (let i = 0; i < deconstructedCell.length; i += 2) {
39305
+ newContent += deconstructedCell[i] + "[" + deconstructedCell[i + 1] + "]";
39306
+ }
39307
+ newContent += deconstructedCell[deconstructedCell.length - 1];
39308
+ sheet.cells[xc] = newContent;
39309
+ }
39310
+ }
39311
+ }
39312
+ /**
39313
+ * Deconstruct the content of the cells in the sheets to extract possible table references.
39314
+ * Example from "=AVERAGE(Table1[colName1])-AVERAGE(Table2[colName2])":
39315
+ * return --> ["=AVERAGE(Table1", "colName1", ")-AVERAGE(Table2", "colName2", ")"]
39316
+ */
39317
+ function deconstructSheets(convertedSheets) {
39318
+ const deconstructedSheets = {};
39319
+ for (const sheet of convertedSheets) {
39320
+ for (const xc in sheet.cells) {
39321
+ const cellContent = sheet.cells[xc];
39322
+ if (!cellContent || !cellContent.startsWith("=")) {
39323
+ continue;
39324
+ }
39325
+ const startIndex = cellContent.indexOf("[");
39326
+ if (startIndex === -1) {
39327
+ continue;
39328
+ }
39329
+ const deconstructedCell = [];
39330
+ let possibleTable = cellContent.slice(0, startIndex);
39331
+ let possibleRef = "";
39332
+ let openBrackets = 1;
39333
+ let mainPossibleTableIndex = 0;
39334
+ let mainOpenBracketIndex = startIndex;
39335
+ for (let index = startIndex + 1; index < cellContent.length; index++) {
39336
+ if (cellContent[index] === "[") {
39337
+ if (openBrackets === 0) {
39338
+ possibleTable = cellContent.slice(mainPossibleTableIndex, index);
39339
+ mainOpenBracketIndex = index;
39340
+ }
39341
+ openBrackets++;
39342
+ continue;
39343
+ }
39344
+ if (cellContent[index] === "]") {
39345
+ openBrackets--;
39346
+ if (openBrackets === 0) {
39347
+ possibleRef = cellContent.slice(mainOpenBracketIndex + 1, index);
39348
+ deconstructedCell.push(possibleTable);
39349
+ deconstructedCell.push(possibleRef);
39350
+ mainPossibleTableIndex = index + 1;
39351
+ }
39352
+ }
39353
+ }
39354
+ if (deconstructedCell.length) {
39355
+ if (!deconstructedSheets[sheet.id]) {
39356
+ deconstructedSheets[sheet.id] = {};
39357
+ }
39358
+ deconstructedCell.push(cellContent.slice(mainPossibleTableIndex));
39359
+ deconstructedSheets[sheet.id][xc] = [...deconstructedCell];
39360
+ }
39361
+ }
39362
+ }
39363
+ return deconstructedSheets;
39258
39364
  }
39259
39365
  /**
39260
39366
  * Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
@@ -45566,10 +45672,10 @@ class CellComposerStore extends AbstractComposerStore {
45566
45672
  const cellValue = isFormula(content)
45567
45673
  ? this.getters.evaluateFormula(this.sheetId, content)
45568
45674
  : parseLiteral(content, this.getters.getLocale());
45569
- if (isMatrix(cellValue)) {
45675
+ if (isMultipleElementMatrix(cellValue)) {
45570
45676
  return true;
45571
45677
  }
45572
- const validationResult = this.getters.getValidationResultForCellValue(cellValue, cellPosition);
45678
+ const validationResult = this.getters.getValidationResultForCellValue(toScalar(cellValue), cellPosition);
45573
45679
  if (!validationResult.isValid && validationResult.rule.isBlocking) {
45574
45680
  return false;
45575
45681
  }
@@ -50681,10 +50787,10 @@ class GaugeChartDesignPanel extends owl.Component {
50681
50787
  return tryToNumber(value, locale) !== undefined;
50682
50788
  }
50683
50789
  const evaluatedValue = this.env.model.getters.evaluateFormula(this.sheetId, value);
50684
- if (isMatrix(evaluatedValue)) {
50790
+ if (isMultipleElementMatrix(evaluatedValue)) {
50685
50791
  return false;
50686
50792
  }
50687
- return tryToNumber(evaluatedValue, locale) !== undefined;
50793
+ return tryToNumber(toScalar(evaluatedValue), locale) !== undefined;
50688
50794
  }
50689
50795
  get sheetId() {
50690
50796
  const chart = this.env.model.getters.getChart(this.props.figureId);
@@ -55495,10 +55601,7 @@ class SpreadsheetPivot {
55495
55601
  if (finalCell.value === null) {
55496
55602
  return { value: _t("(Undefined)") };
55497
55603
  }
55498
- return {
55499
- value: finalCell.value,
55500
- format: finalCell.format,
55501
- };
55604
+ return finalCell;
55502
55605
  }
55503
55606
  getPivotCellValueAndFormat(measureId, domain) {
55504
55607
  const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
@@ -55600,9 +55703,15 @@ class SpreadsheetPivot {
55600
55703
  return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
55601
55704
  }
55602
55705
  filterDataEntriesFromDomainNode(dataEntries, domain) {
55603
- const { field, value } = domain;
55706
+ const { field, value, type } = domain;
55604
55707
  const { nameWithGranularity } = this.getDimension(field);
55605
- return dataEntries.filter((entry) => entry[nameWithGranularity]?.value === value);
55708
+ return dataEntries.filter((entry) => {
55709
+ const cellValue = entry[nameWithGranularity]?.value;
55710
+ if (type === "char") {
55711
+ return String(cellValue) === String(value);
55712
+ }
55713
+ return cellValue === value;
55714
+ });
55606
55715
  }
55607
55716
  getDimension(nameWithGranularity) {
55608
55717
  return this.definition.getDimension(nameWithGranularity);
@@ -55736,7 +55845,6 @@ pivotRegistry.add("SPREADSHEET", {
55736
55845
  ui: SpreadsheetPivot,
55737
55846
  definition: SpreadsheetPivotRuntimeDefinition,
55738
55847
  externalData: false,
55739
- onIterationEndEvaluation: (pivot) => pivot.markAsDirtyForEvaluation(),
55740
55848
  dateGranularities: [...dateGranularities],
55741
55849
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
55742
55850
  isMeasureCandidate: (field) => field.type !== "boolean",
@@ -64387,7 +64495,7 @@ const onIterationEndEvaluationRegistry = new Registry();
64387
64495
  onIterationEndEvaluationRegistry.add("pivots", (getters) => {
64388
64496
  for (const pivotId of getters.getPivotIds()) {
64389
64497
  const pivot = getters.getPivot(pivotId);
64390
- pivotRegistry.get(pivot.type).onIterationEndEvaluation(pivot);
64498
+ pivot.markAsDirtyForEvaluation?.();
64391
64499
  }
64392
64500
  });
64393
64501
 
@@ -66851,12 +66959,12 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
66851
66959
  }
66852
66960
  return this.getters.evaluateFormula(sheetId, value) ?? "";
66853
66961
  });
66854
- if (evaluatedCriterionValues.some(isMatrix)) {
66962
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
66855
66963
  return false;
66856
66964
  }
66857
66965
  const evaluatedCriterion = {
66858
66966
  type: rule.operator,
66859
- values: evaluatedCriterionValues,
66967
+ values: evaluatedCriterionValues.map(toScalar),
66860
66968
  };
66861
66969
  return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion, this.getters, sheetId);
66862
66970
  }
@@ -67016,10 +67124,10 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
67016
67124
  const evaluator = criterionEvaluatorRegistry.get(criterion.type);
67017
67125
  const offset = this.getCellOffsetInRule(cellPosition, rule);
67018
67126
  const evaluatedCriterionValues = this.getEvaluatedCriterionValues(sheetId, offset, criterion);
67019
- if (evaluatedCriterionValues.some(isMatrix)) {
67127
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
67020
67128
  return undefined;
67021
67129
  }
67022
- const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues };
67130
+ const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues.map(toScalar) };
67023
67131
  if (evaluator.isValueValid(cellValue, evaluatedCriterion, this.getters, sheetId)) {
67024
67132
  return undefined;
67025
67133
  }
@@ -67472,6 +67580,23 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
67472
67580
  static getters = ["getRowSize", "getHeaderSize", "getMaxAnchorOffset"];
67473
67581
  tallestCellInRow = {};
67474
67582
  ctx = document.createElement("canvas").getContext("2d");
67583
+ beforeHandle(cmd) {
67584
+ switch (cmd.type) {
67585
+ // Ensure rows are updated before "UPDATE_CELL" is dispatched from cell plugin.
67586
+ // "UPDATE_CELL" uses the Sheet core plugin to access row data.
67587
+ // If "ADD_COLUMNS_ROWS" has not been processed yet by header_sizes_ui,
67588
+ // size updates may apply to incorrect (pre-insert) rows.
67589
+ case "ADD_COLUMNS_ROWS":
67590
+ if (cmd.dimension === "COL") {
67591
+ return;
67592
+ }
67593
+ const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
67594
+ const newCells = Array(cmd.quantity).fill(undefined);
67595
+ const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
67596
+ this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
67597
+ break;
67598
+ }
67599
+ }
67475
67600
  handle(cmd) {
67476
67601
  switch (cmd.type) {
67477
67602
  case "START":
@@ -67501,16 +67626,6 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
67501
67626
  this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
67502
67627
  break;
67503
67628
  }
67504
- case "ADD_COLUMNS_ROWS": {
67505
- if (cmd.dimension === "COL") {
67506
- return;
67507
- }
67508
- const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
67509
- const newCells = Array(cmd.quantity).fill(undefined);
67510
- const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
67511
- this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
67512
- break;
67513
- }
67514
67629
  case "RESIZE_COLUMNS_ROWS":
67515
67630
  {
67516
67631
  const sheetId = cmd.sheetId;
@@ -67662,13 +67777,13 @@ function withPivotPresentationLayer (PivotClass) {
67662
67777
  super(custom, params);
67663
67778
  this.getters = params.getters;
67664
67779
  }
67665
- init(params) {
67780
+ markAsDirtyForEvaluation() {
67666
67781
  this.cache = {};
67667
67782
  this.rankAsc = {};
67668
67783
  this.rankDesc = {};
67669
67784
  this.runningTotal = {};
67670
67785
  this.runningTotalInPercent = {};
67671
- super.init(params);
67786
+ super.markAsDirtyForEvaluation?.();
67672
67787
  }
67673
67788
  getPivotCellValueAndFormat(measureName, domain) {
67674
67789
  return this.getMeasureDisplayValue(measureName, domain);
@@ -67793,7 +67908,7 @@ function withPivotPresentationLayer (PivotClass) {
67793
67908
  return this.getSubTreeMatchingDomain(node.children, domain, domainLevel + 1);
67794
67909
  }
67795
67910
  }
67796
- return tree;
67911
+ return [];
67797
67912
  }
67798
67913
  treeToLeafDomains(tree, parentDomain = []) {
67799
67914
  const domains = [];
@@ -73525,12 +73640,12 @@ class FilterEvaluationPlugin extends UIPlugin {
73525
73640
  }
73526
73641
  return this.getters.evaluateFormula(sheetId, value) ?? "";
73527
73642
  });
73528
- if (evaluatedCriterionValues.some(isMatrix)) {
73643
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
73529
73644
  continue;
73530
73645
  }
73531
73646
  const evaluatedCriterion = {
73532
73647
  type: filterValue.type,
73533
- values: evaluatedCriterionValues,
73648
+ values: evaluatedCriterionValues.map(toScalar),
73534
73649
  dateValue: filterValue.dateValue,
73535
73650
  };
73536
73651
  for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
@@ -74052,6 +74167,14 @@ class GridSelectionPlugin extends UIPlugin {
74052
74167
  const isBasedBefore = cmd.base < start;
74053
74168
  const deltaCol = isBasedBefore && isCol ? thickness : 0;
74054
74169
  const deltaRow = isBasedBefore && !isCol ? thickness : 0;
74170
+ const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
74171
+ const originalSize = Object.fromEntries(toRemove.map((element) => {
74172
+ const size = isCol
74173
+ ? this.getters.getColSize(cmd.sheetId, element)
74174
+ : this.getters.getUserRowSize(cmd.sheetId, element);
74175
+ const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
74176
+ return [element, isDefaultCol ? undefined : size];
74177
+ }));
74055
74178
  const target = [
74056
74179
  {
74057
74180
  left: isCol ? start + deltaCol : 0,
@@ -74082,13 +74205,12 @@ class GridSelectionPlugin extends UIPlugin {
74082
74205
  const col = selection.left;
74083
74206
  const row = selection.top;
74084
74207
  this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
74085
- const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
74086
74208
  let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
74087
74209
  const resizingGroups = {};
74088
74210
  for (const element of toRemove) {
74089
- const size = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
74211
+ const size = originalSize[element];
74090
74212
  const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
74091
- if (size !== currentSize) {
74213
+ if (size && size !== currentSize) {
74092
74214
  resizingGroups[size] ??= [];
74093
74215
  resizingGroups[size].push(currentIndex);
74094
74216
  currentIndex += 1;
@@ -75514,6 +75636,7 @@ const coreViewsPluginRegistry = new Registry()
75514
75636
 
75515
75637
  autoCompleteProviders.add("dataValidation", {
75516
75638
  displayAllOnInitialContent: true,
75639
+ canBeToggled: false,
75517
75640
  getProposals(tokenAtCursor, content) {
75518
75641
  if (isFormula(content)) {
75519
75642
  return [];
@@ -77079,14 +77202,12 @@ class BottomBarSheet extends owl.Component {
77079
77202
  this.editionState = "initializing";
77080
77203
  }
77081
77204
  stopEdition() {
77082
- const input = this.sheetNameRef.el;
77083
- if (!this.state.isEditing || !input)
77205
+ if (!this.state.isEditing || !this.sheetNameRef.el)
77084
77206
  return;
77085
77207
  this.state.isEditing = false;
77086
77208
  this.editionState = "initializing";
77087
- input.blur();
77209
+ this.sheetNameRef.el.blur();
77088
77210
  const inputValue = this.getInputContent() || "";
77089
- input.innerText = inputValue;
77090
77211
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
77091
77212
  }
77092
77213
  cancelEdition() {
@@ -84458,6 +84579,7 @@ const stores = {
84458
84579
  PivotSidePanelStore,
84459
84580
  PivotMeasureDisplayPanelStore,
84460
84581
  ClientFocusStore,
84582
+ GridRenderer,
84461
84583
  };
84462
84584
  function addFunction(functionName, functionDescription) {
84463
84585
  functionRegistry.add(functionName, functionDescription);
@@ -84524,6 +84646,6 @@ exports.tokenColors = tokenColors;
84524
84646
  exports.tokenize = tokenize;
84525
84647
 
84526
84648
 
84527
- __info__.version = "18.4.1";
84528
- __info__.date = "2025-06-27T09:13:01.303Z";
84529
- __info__.hash = "5cecc0e";
84649
+ __info__.version = "18.4.3";
84650
+ __info__.date = "2025-07-28T13:39:06.036Z";
84651
+ __info__.hash = "4b596d7";
@@ -5689,6 +5689,7 @@ declare class HeaderSizeUIPlugin extends CoreViewPlugin<HeaderSizeState> impleme
5689
5689
  static getters: readonly ["getRowSize", "getHeaderSize", "getMaxAnchorOffset"];
5690
5690
  readonly tallestCellInRow: Immutable<Record<UID, Array<CellWithSize | undefined>>>;
5691
5691
  private ctx;
5692
+ beforeHandle(cmd: Command): void;
5692
5693
  handle(cmd: Command): void;
5693
5694
  getRowSize(sheetId: UID, row: HeaderIndex): Pixel;
5694
5695
  getMaxAnchorOffset(sheetId: UID, height: Pixel, width: Pixel): AnchorOffset;
@@ -5835,6 +5836,7 @@ interface Pivot<T = PivotRuntimeDefinition> {
5835
5836
  label: string;
5836
5837
  }[];
5837
5838
  needsReevaluation: boolean;
5839
+ markAsDirtyForEvaluation?(): void;
5838
5840
  }
5839
5841
 
5840
5842
  declare class PivotUIPlugin extends CoreViewPlugin {
@@ -6750,7 +6752,6 @@ interface PivotRegistryItem {
6750
6752
  ui: PivotUIConstructor;
6751
6753
  definition: PivotDefinitionConstructor;
6752
6754
  externalData: boolean;
6753
- onIterationEndEvaluation: (pivot: Pivot) => void;
6754
6755
  dateGranularities: string[];
6755
6756
  datetimeGranularities: string[];
6756
6757
  isMeasureCandidate: (field: PivotField) => boolean;
@@ -8551,6 +8552,7 @@ declare abstract class AbstractComposerStore extends SpreadsheetStore {
8551
8552
  get autoCompleteProposals(): AutoCompleteProposal[];
8552
8553
  get autoCompleteSelectedIndex(): number | undefined;
8553
8554
  get isAutoCompleteDisplayed(): boolean;
8555
+ get canBeToggled(): boolean;
8554
8556
  cycleReferences(): void;
8555
8557
  toggleEditionMode(): void;
8556
8558
  hoverToken(tokenIndex: number | undefined): void;
@@ -8857,6 +8859,7 @@ interface AutoCompleteProvider {
8857
8859
  proposals: AutoCompleteProposal[];
8858
8860
  selectProposal(text: string): void;
8859
8861
  autoSelectFirstProposal: boolean;
8862
+ canBeToggled?: boolean;
8860
8863
  }
8861
8864
  interface ComposerStoreInterface {
8862
8865
  currentEditedCell?: CellPosition;
@@ -8876,6 +8879,7 @@ interface ComposerStoreInterface {
8876
8879
  interface AutoCompleteProviderDefinition {
8877
8880
  sequence?: number;
8878
8881
  autoSelectFirstProposal?: boolean;
8882
+ canBeToggled?: boolean;
8879
8883
  displayAllOnInitialContent?: boolean;
8880
8884
  maxDisplayedProposals?: number;
8881
8885
  getProposals(this: {
@@ -10855,7 +10859,7 @@ declare function createPivotFormula(formulaId: string, cell: PivotTableCell): st
10855
10859
  * e.g. given the following formula PIVOT.VALUE("1", "stage_id", "42", "status", "won"),
10856
10860
  * the two group values are "42" and "won".
10857
10861
  */
10858
- declare function toNormalizedPivotValue(dimension: Pick<PivotDimension$1, "type" | "displayName" | "granularity">, groupValue: any): CellValue;
10862
+ declare function toNormalizedPivotValue(dimension: Pick<PivotDimension$1, "type" | "displayName" | "granularity">, groupValue: Maybe<CellValue | FunctionResultObject>): CellValue;
10859
10863
  declare function toFunctionPivotValue(value: CellValue, dimension: Pick<PivotDimension$1, "type" | "granularity">): string;
10860
10864
 
10861
10865
  interface Props$k {
@@ -11668,6 +11672,39 @@ declare class ClientFocusStore extends SpreadsheetStore {
11668
11672
  unfocusClient(clientId: ClientId): void;
11669
11673
  }
11670
11674
 
11675
+ declare class GridRenderer extends SpreadsheetStore {
11676
+ private fingerprints;
11677
+ private hoveredTables;
11678
+ private hoveredIcon;
11679
+ private lastRenderBoxes;
11680
+ private preventNewAnimationsInNextFrame;
11681
+ private zonesWithPreventedAnimationsInNextFrame;
11682
+ private animations;
11683
+ constructor(get: Get);
11684
+ handle(cmd: Command): void;
11685
+ get renderingLayers(): readonly ["Background", "Headers"];
11686
+ drawLayer(renderingContext: GridRenderingContext, layer: LayerName, timeStamp: number | undefined): void;
11687
+ private drawGlobalBackground;
11688
+ private drawBackground;
11689
+ private drawCellBackground;
11690
+ private drawOverflowingCellBackground;
11691
+ private drawBorders;
11692
+ private drawTexts;
11693
+ private drawIcon;
11694
+ private drawHeaders;
11695
+ private drawFrozenPanesHeaders;
11696
+ private drawFrozenPanes;
11697
+ private findNextEmptyCol;
11698
+ private findPreviousEmptyCol;
11699
+ private computeCellAlignment;
11700
+ private createZoneBox;
11701
+ private getGridBoxes;
11702
+ private getBoxesWithAnimations;
11703
+ private updateBoxesWithAnimations;
11704
+ private updateAnimationsProgress;
11705
+ private addNewAnimations;
11706
+ }
11707
+
11671
11708
  declare class LocalTransportService implements TransportService<CollaborationMessage> {
11672
11709
  private listeners;
11673
11710
  sendMessage(message: CollaborationMessage): Promise<void>;
@@ -12585,6 +12622,7 @@ declare const stores: {
12585
12622
  PivotSidePanelStore: typeof PivotSidePanelStore;
12586
12623
  PivotMeasureDisplayPanelStore: typeof PivotMeasureDisplayPanelStore;
12587
12624
  ClientFocusStore: typeof ClientFocusStore;
12625
+ GridRenderer: typeof GridRenderer;
12588
12626
  };
12589
12627
 
12590
12628
  declare function addFunction(functionName: string, functionDescription: AddFunctionDescription): {