@odoo/o-spreadsheet 18.5.0-alpha.0 → 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.0
6
- * @date 2025-06-24T12:26:38.163Z
7
- * @hash ed0f325
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);
@@ -26508,6 +26516,51 @@ cellAnimationRegistry.add("textFadeOut", {
26508
26516
  Object.assign(animatedBox.style, style);
26509
26517
  },
26510
26518
  });
26519
+ cellAnimationRegistry.add("iconFadeIn", {
26520
+ id: "iconFadeIn",
26521
+ easingFn: "easeInCubic",
26522
+ hasAnimation: (oldBox, newBox) => {
26523
+ return Boolean((!oldBox?.icons?.left && newBox?.icons?.left) ||
26524
+ (!oldBox?.icons?.right && newBox?.icons?.right) ||
26525
+ (!oldBox?.icons?.center && newBox?.icons?.center));
26526
+ },
26527
+ updateAnimation: function (progress, animatedBox, oldBox, newBox) {
26528
+ const iconOpacity = EASING_FN[this.easingFn](progress);
26529
+ if (animatedBox.icons.left && newBox.icons.left && !oldBox.icons.left) {
26530
+ animatedBox.icons.left.opacity = iconOpacity;
26531
+ }
26532
+ if (animatedBox.icons.right && newBox.icons.right && !oldBox.icons.right) {
26533
+ animatedBox.icons.right.opacity = iconOpacity;
26534
+ }
26535
+ if (animatedBox.icons.center && newBox.icons.center && !oldBox.icons.center) {
26536
+ animatedBox.icons.center.opacity = iconOpacity;
26537
+ }
26538
+ },
26539
+ });
26540
+ cellAnimationRegistry.add("iconFadeOut", {
26541
+ id: "iconFadeOut",
26542
+ easingFn: "easeOutCubic",
26543
+ hasAnimation: (oldBox, newBox) => {
26544
+ return Boolean((oldBox?.icons?.left && !newBox?.icons?.left) ||
26545
+ (oldBox?.icons?.right && !newBox?.icons?.right) ||
26546
+ (oldBox?.icons?.center && !newBox?.icons?.center));
26547
+ },
26548
+ updateAnimation: function (progress, animatedBox, oldBox, newBox) {
26549
+ const iconOpacity = 1 - EASING_FN[this.easingFn](progress);
26550
+ if (!animatedBox.icons) {
26551
+ animatedBox.icons = {};
26552
+ }
26553
+ if (oldBox.icons.left && !newBox.icons.left) {
26554
+ animatedBox.icons.left = { ...oldBox.icons.left, opacity: iconOpacity };
26555
+ }
26556
+ if (oldBox.icons.right && !newBox.icons.right) {
26557
+ animatedBox.icons.right = { ...oldBox.icons.right, opacity: iconOpacity };
26558
+ }
26559
+ if (oldBox.icons.center && !newBox.icons.center) {
26560
+ animatedBox.icons.center = { ...oldBox.icons.center, opacity: iconOpacity };
26561
+ }
26562
+ },
26563
+ });
26511
26564
  cellAnimationRegistry.add("textChange", {
26512
26565
  id: "textChange",
26513
26566
  easingFn: "easeOutCubic",
@@ -26516,7 +26569,7 @@ cellAnimationRegistry.add("textChange", {
26516
26569
  const newText = newBox?.content?.textLines?.join("\n");
26517
26570
  // Note: here, we also animate changes to icons layout (margins/size change, or icon appearing/disappearing)
26518
26571
  // because a change to the icon layout will impact where the text is positioned.
26519
- return (Boolean(oldText && newText && oldText !== newText) || hasIconLayoutChange(newBox, oldBox));
26572
+ return Boolean(oldText && newText && (oldText !== newText || hasIconLayoutChange(newBox, oldBox)));
26520
26573
  },
26521
26574
  updateAnimation: function (progress, animatedBox, oldBox, newBox) {
26522
26575
  const value = EASING_FN[this.easingFn](progress);
@@ -26531,7 +26584,7 @@ cellAnimationRegistry.add("textChange", {
26531
26584
  height: newBox.height,
26532
26585
  style: { ...newBox.style },
26533
26586
  skipCellGridLines: true,
26534
- content: newBox.content,
26587
+ content: newBox.content ? { ...newBox.content } : undefined,
26535
26588
  clipRect: newBox.clipRect || {
26536
26589
  ...newBox,
26537
26590
  // large width to avoid clipping the text it it didn't have a clipRect before,
@@ -26551,7 +26604,7 @@ cellAnimationRegistry.add("textChange", {
26551
26604
  height: newBox.height,
26552
26605
  style: { ...oldBox.style },
26553
26606
  skipCellGridLines: true,
26554
- content: oldBox.content,
26607
+ content: oldBox.content ? { ...oldBox.content } : undefined,
26555
26608
  clipRect: oldBox.clipRect || {
26556
26609
  ...newBox,
26557
26610
  x: Math.max(0, newBox.x - (oldBox.content?.width || 0)),
@@ -27401,7 +27454,9 @@ function getSectionThresholdValue(sheetId, threshold, minValue, maxValue, getter
27401
27454
  }
27402
27455
  function getFormulaNumberValue(sheetId, formula, getters) {
27403
27456
  const value = getters.evaluateFormula(sheetId, formula);
27404
- return isMatrix(value) ? undefined : tryToNumber(value, getters.getLocale());
27457
+ return isMultipleElementMatrix(value)
27458
+ ? undefined
27459
+ : tryToNumber(toScalar(value), getters.getLocale());
27405
27460
  }
27406
27461
  function getInvalidGaugeRuntime(chart, getters) {
27407
27462
  return {
@@ -31026,6 +31081,9 @@ class ErrorToolTip extends Component {
31026
31081
  return undefined;
31027
31082
  }
31028
31083
  get errorOriginPositionString() {
31084
+ if (this.env.model.getters.isDashboard()) {
31085
+ return "";
31086
+ }
31029
31087
  const evaluationError = this.evaluationError;
31030
31088
  const position = evaluationError?.errorOriginPosition;
31031
31089
  if (!position || deepEquals(position, this.props.cellPosition)) {
@@ -32663,7 +32721,7 @@ class AbstractComposerStore extends SpreadsheetStore {
32663
32721
  }
32664
32722
  captureSelection(zone, col, row) {
32665
32723
  this.model.selection.capture(this, {
32666
- cell: { col: col || zone.left, row: row || zone.right },
32724
+ cell: { col: col ?? zone.left, row: row ?? zone.right },
32667
32725
  zone,
32668
32726
  }, {
32669
32727
  handleEvent: this.handleEvent.bind(this),
@@ -39174,40 +39232,112 @@ function convertPivotTableConfig(pivotTable) {
39174
39232
  * In all the sheets, replace the table-only references in the formula cells with standard references.
39175
39233
  */
39176
39234
  function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
39235
+ let deconstructedSheets = null;
39177
39236
  for (const tableSheet of convertedSheets) {
39178
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
+ }
39179
39245
  for (const table of tables) {
39180
- const tabRef = table.name + "[";
39181
- for (const sheet of convertedSheets) {
39182
- for (const xc in sheet.cells) {
39183
- const cell = sheet.cells[xc];
39184
- let cellContent = sheet.cells[xc];
39185
- if (cell && cellContent && cellContent.startsWith("=")) {
39186
- let refIndex;
39187
- while ((refIndex = cellContent.indexOf(tabRef)) !== -1) {
39188
- let endIndex = refIndex + tabRef.length;
39189
- let openBrackets = 1;
39190
- while (openBrackets > 0 && endIndex < cellContent.length) {
39191
- if (cellContent[endIndex] === "[") {
39192
- openBrackets++;
39193
- }
39194
- else if (cellContent[endIndex] === "]") {
39195
- openBrackets--;
39196
- }
39197
- endIndex++;
39198
- }
39199
- const reference = cellContent.slice(refIndex + tabRef.length, endIndex - 1);
39200
- const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
39201
- const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
39202
- cellContent =
39203
- 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;
39204
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);
39205
39263
  }
39206
- sheet.cells[xc] = cellContent;
39264
+ // sheet.cells[xc] = cellContent;
39207
39265
  }
39208
39266
  }
39209
39267
  }
39210
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;
39211
39341
  }
39212
39342
  /**
39213
39343
  * Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
@@ -45519,10 +45649,10 @@ class CellComposerStore extends AbstractComposerStore {
45519
45649
  const cellValue = isFormula(content)
45520
45650
  ? this.getters.evaluateFormula(this.sheetId, content)
45521
45651
  : parseLiteral(content, this.getters.getLocale());
45522
- if (isMatrix(cellValue)) {
45652
+ if (isMultipleElementMatrix(cellValue)) {
45523
45653
  return true;
45524
45654
  }
45525
- const validationResult = this.getters.getValidationResultForCellValue(cellValue, cellPosition);
45655
+ const validationResult = this.getters.getValidationResultForCellValue(toScalar(cellValue), cellPosition);
45526
45656
  if (!validationResult.isValid && validationResult.rule.isBlocking) {
45527
45657
  return false;
45528
45658
  }
@@ -47943,6 +48073,7 @@ class GridRenderer extends SpreadsheetStore {
47943
48073
  continue;
47944
48074
  }
47945
48075
  ctx.save();
48076
+ ctx.globalAlpha = icon.opacity ?? 1;
47946
48077
  ctx.beginPath();
47947
48078
  const clipRect = icon.clipRect || box;
47948
48079
  ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
@@ -50633,10 +50764,10 @@ class GaugeChartDesignPanel extends Component {
50633
50764
  return tryToNumber(value, locale) !== undefined;
50634
50765
  }
50635
50766
  const evaluatedValue = this.env.model.getters.evaluateFormula(this.sheetId, value);
50636
- if (isMatrix(evaluatedValue)) {
50767
+ if (isMultipleElementMatrix(evaluatedValue)) {
50637
50768
  return false;
50638
50769
  }
50639
- return tryToNumber(evaluatedValue, locale) !== undefined;
50770
+ return tryToNumber(toScalar(evaluatedValue), locale) !== undefined;
50640
50771
  }
50641
50772
  get sheetId() {
50642
50773
  const chart = this.env.model.getters.getChart(this.props.figureId);
@@ -51490,12 +51621,32 @@ class ChartPanel extends Component {
51490
51621
  static template = "o-spreadsheet-ChartPanel";
51491
51622
  static components = { Section, ChartTypePicker };
51492
51623
  static props = { onCloseSidePanel: Function, figureId: String };
51624
+ panelContentRef;
51625
+ scrollPositions = {
51626
+ configuration: 0,
51627
+ design: 0,
51628
+ };
51493
51629
  store;
51494
51630
  get figureId() {
51495
51631
  return this.props.figureId;
51496
51632
  }
51497
51633
  setup() {
51498
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);
51499
51650
  }
51500
51651
  updateChart(figureId, updateDefinition) {
51501
51652
  if (figureId !== this.figureId) {
@@ -52331,6 +52482,9 @@ class ConditionalFormattingPanel extends Component {
52331
52482
  this.switchToList();
52332
52483
  }
52333
52484
  }
52485
+ else if (!this.editedCF) {
52486
+ this.switchToList();
52487
+ }
52334
52488
  });
52335
52489
  }
52336
52490
  get conditionalFormats() {
@@ -55444,10 +55598,7 @@ class SpreadsheetPivot {
55444
55598
  if (finalCell.value === null) {
55445
55599
  return { value: _t("(Undefined)") };
55446
55600
  }
55447
- return {
55448
- value: finalCell.value,
55449
- format: finalCell.format,
55450
- };
55601
+ return finalCell;
55451
55602
  }
55452
55603
  getPivotCellValueAndFormat(measureId, domain) {
55453
55604
  const dataEntries = this.filterDataEntriesFromDomain(this.dataEntries, domain);
@@ -55685,7 +55836,6 @@ pivotRegistry.add("SPREADSHEET", {
55685
55836
  ui: SpreadsheetPivot,
55686
55837
  definition: SpreadsheetPivotRuntimeDefinition,
55687
55838
  externalData: false,
55688
- onIterationEndEvaluation: (pivot) => pivot.markAsDirtyForEvaluation(),
55689
55839
  dateGranularities: [...dateGranularities],
55690
55840
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
55691
55841
  isMeasureCandidate: (field) => field.type !== "boolean",
@@ -64336,7 +64486,7 @@ const onIterationEndEvaluationRegistry = new Registry();
64336
64486
  onIterationEndEvaluationRegistry.add("pivots", (getters) => {
64337
64487
  for (const pivotId of getters.getPivotIds()) {
64338
64488
  const pivot = getters.getPivot(pivotId);
64339
- pivotRegistry.get(pivot.type).onIterationEndEvaluation(pivot);
64489
+ pivot.markAsDirtyForEvaluation?.();
64340
64490
  }
64341
64491
  });
64342
64492
 
@@ -66800,12 +66950,12 @@ class EvaluationConditionalFormatPlugin extends CoreViewPlugin {
66800
66950
  }
66801
66951
  return this.getters.evaluateFormula(sheetId, value) ?? "";
66802
66952
  });
66803
- if (evaluatedCriterionValues.some(isMatrix)) {
66953
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
66804
66954
  return false;
66805
66955
  }
66806
66956
  const evaluatedCriterion = {
66807
66957
  type: rule.operator,
66808
- values: evaluatedCriterionValues,
66958
+ values: evaluatedCriterionValues.map(toScalar),
66809
66959
  };
66810
66960
  return evaluator.isValueValid(cell.value ?? "", evaluatedCriterion, this.getters, sheetId);
66811
66961
  }
@@ -66965,10 +67115,10 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
66965
67115
  const evaluator = criterionEvaluatorRegistry.get(criterion.type);
66966
67116
  const offset = this.getCellOffsetInRule(cellPosition, rule);
66967
67117
  const evaluatedCriterionValues = this.getEvaluatedCriterionValues(sheetId, offset, criterion);
66968
- if (evaluatedCriterionValues.some(isMatrix)) {
67118
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
66969
67119
  return undefined;
66970
67120
  }
66971
- const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues };
67121
+ const evaluatedCriterion = { ...criterion, values: evaluatedCriterionValues.map(toScalar) };
66972
67122
  if (evaluator.isValueValid(cellValue, evaluatedCriterion, this.getters, sheetId)) {
66973
67123
  return undefined;
66974
67124
  }
@@ -67611,13 +67761,13 @@ function withPivotPresentationLayer (PivotClass) {
67611
67761
  super(custom, params);
67612
67762
  this.getters = params.getters;
67613
67763
  }
67614
- init(params) {
67764
+ markAsDirtyForEvaluation() {
67615
67765
  this.cache = {};
67616
67766
  this.rankAsc = {};
67617
67767
  this.rankDesc = {};
67618
67768
  this.runningTotal = {};
67619
67769
  this.runningTotalInPercent = {};
67620
- super.init(params);
67770
+ super.markAsDirtyForEvaluation?.();
67621
67771
  }
67622
67772
  getPivotCellValueAndFormat(measureName, domain) {
67623
67773
  return this.getMeasureDisplayValue(measureName, domain);
@@ -67742,7 +67892,7 @@ function withPivotPresentationLayer (PivotClass) {
67742
67892
  return this.getSubTreeMatchingDomain(node.children, domain, domainLevel + 1);
67743
67893
  }
67744
67894
  }
67745
- return tree;
67895
+ return [];
67746
67896
  }
67747
67897
  treeToLeafDomains(tree, parentDomain = []) {
67748
67898
  const domains = [];
@@ -68430,9 +68580,9 @@ autofillModifiersRegistry
68430
68580
  .add("ALPHANUMERIC_INCREMENT_MODIFIER", {
68431
68581
  apply: (rule, data) => {
68432
68582
  rule.current += rule.increment;
68433
- const content = `${rule.prefix}${rule.current
68434
- .toString()
68435
- .padStart(rule.numberPostfixLength || 0, "0")}`;
68583
+ let value = Math.abs(rule.current).toString();
68584
+ value = "0".repeat(Math.max(rule.numberPostfixLength - value.length, 0)) + value;
68585
+ const content = `${rule.prefix}${value}`;
68436
68586
  return {
68437
68587
  cellData: {
68438
68588
  border: data.border,
@@ -68550,6 +68700,7 @@ const autofillRulesRegistry = new Registry();
68550
68700
  const numberPostfixRegExp = /(\d+)$/;
68551
68701
  const stringPrefixRegExp = /^(.*\D+)/;
68552
68702
  const alphaNumericValueRegExp = /^(.*\D+)(\d+)$/;
68703
+ const leadingZerosRegex = /^0*/;
68553
68704
  /**
68554
68705
  * Get the consecutive evaluated cells that can pass the filter function (e.g. certain type filter).
68555
68706
  * Return the one which contains the given cell
@@ -68681,12 +68832,18 @@ autofillRulesRegistry
68681
68832
  generateRule: (cell, cells, direction) => {
68682
68833
  const numberPostfix = parseInt(cell.content.match(numberPostfixRegExp)[0]);
68683
68834
  const prefix = cell.content.match(stringPrefixRegExp)[0];
68684
- const numberPostfixLength = cell.content.length - prefix.length;
68685
68835
  const group = getGroup(cell, cells, (evaluatedCell) => evaluatedCell.type === CellValueType.text &&
68686
- alphaNumericValueRegExp.test(evaluatedCell.value)) // get consecutive alphanumeric cells, no matter what the prefix is
68836
+ alphaNumericValueRegExp.test(evaluatedCell.value))
68837
+ // get consecutive alphanumeric cells, no matter what the prefix is
68687
68838
  .filter((cell) => prefix === (cell.value ?? "").toString().match(stringPrefixRegExp)[0])
68688
- .map((cell) => parseInt((cell.value ?? "").toString().match(numberPostfixRegExp)[0]));
68689
- let increment = calculateIncrementBasedOnGroup(group);
68839
+ .map((cell) => (cell.value ?? "").toString().match(numberPostfixRegExp)[0]);
68840
+ // find the length of number with the most leading zeros
68841
+ const mostLeadingZeros = group.reduce((candidate, current) => {
68842
+ const currentLength = current.match(leadingZerosRegex)[0].length;
68843
+ return currentLength > candidate[1] ? [current, currentLength] : candidate;
68844
+ }, [group[0], 0]);
68845
+ const numberPostfixLength = mostLeadingZeros[1] ? mostLeadingZeros[0].length : 0;
68846
+ let increment = calculateIncrementBasedOnGroup(group.map((x) => parseInt(x)));
68690
68847
  if (["up", "left"].includes(direction) && group.length === 1) {
68691
68848
  increment = -increment;
68692
68849
  }
@@ -73474,12 +73631,12 @@ class FilterEvaluationPlugin extends UIPlugin {
73474
73631
  }
73475
73632
  return this.getters.evaluateFormula(sheetId, value) ?? "";
73476
73633
  });
73477
- if (evaluatedCriterionValues.some(isMatrix)) {
73634
+ if (evaluatedCriterionValues.some(isMultipleElementMatrix)) {
73478
73635
  continue;
73479
73636
  }
73480
73637
  const evaluatedCriterion = {
73481
73638
  type: filterValue.type,
73482
- values: evaluatedCriterionValues,
73639
+ values: evaluatedCriterionValues.map(toScalar),
73483
73640
  dateValue: filterValue.dateValue,
73484
73641
  };
73485
73642
  for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
@@ -80981,26 +81138,28 @@ class SelectionStreamProcessorImpl {
80981
81138
  bottom: Math.min(this.getters.getNumberRows(sheetId) - 1, bottom),
80982
81139
  };
80983
81140
  };
80984
- const { col: refCol, row: refRow } = this.getReferencePosition();
81141
+ const { cell: refCell, zone: refZone } = this.getReferenceAnchor();
81142
+ const { col: refCol, row: refRow } = refCell;
80985
81143
  // check if we can shrink selection
80986
81144
  let n = 0;
80987
81145
  while (result !== null) {
80988
81146
  n++;
80989
81147
  if (deltaCol < 0) {
80990
81148
  const newRight = this.getNextAvailableCol(deltaCol, right - (n - 1), refRow);
80991
- result = refCol <= right - n ? expand({ top, left, bottom, right: newRight }) : null;
81149
+ result = refZone.right <= right - n ? expand({ top, left, bottom, right: newRight }) : null;
80992
81150
  }
80993
81151
  if (deltaCol > 0) {
80994
81152
  const newLeft = this.getNextAvailableCol(deltaCol, left + (n - 1), refRow);
80995
- result = left + n <= refCol ? expand({ top, left: newLeft, bottom, right }) : null;
81153
+ result = left + n <= refZone.left ? expand({ top, left: newLeft, bottom, right }) : null;
80996
81154
  }
80997
81155
  if (deltaRow < 0) {
80998
81156
  const newBottom = this.getNextAvailableRow(deltaRow, refCol, bottom - (n - 1));
80999
- result = refRow <= bottom - n ? expand({ top, left, bottom: newBottom, right }) : null;
81157
+ result =
81158
+ refZone.bottom <= bottom - n ? expand({ top, left, bottom: newBottom, right }) : null;
81000
81159
  }
81001
81160
  if (deltaRow > 0) {
81002
81161
  const newTop = this.getNextAvailableRow(deltaRow, refCol, top + (n - 1));
81003
- result = top + n <= refRow ? expand({ top: newTop, left, bottom, right }) : null;
81162
+ result = top + n <= refZone.top ? expand({ top: newTop, left, bottom, right }) : null;
81004
81163
  }
81005
81164
  result = result ? reorderZone(result) : result;
81006
81165
  if (result && !isEqual(result, anchor.zone)) {
@@ -81230,18 +81389,26 @@ class SelectionStreamProcessorImpl {
81230
81389
  * If the anchor is hidden, browses from left to right and top to bottom to
81231
81390
  * find a visible cell.
81232
81391
  */
81233
- getReferencePosition() {
81392
+ getReferenceAnchor() {
81234
81393
  const sheetId = this.getters.getActiveSheetId();
81235
81394
  const anchor = this.anchor;
81236
81395
  const { left, right, top, bottom } = anchor.zone;
81237
81396
  const { col: anchorCol, row: anchorRow } = anchor.cell;
81397
+ const col = this.getters.isColHidden(sheetId, anchorCol)
81398
+ ? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
81399
+ : anchorCol;
81400
+ const row = this.getters.isRowHidden(sheetId, anchorRow)
81401
+ ? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
81402
+ : anchorRow;
81403
+ const zone = this.getters.expandZone(sheetId, {
81404
+ left: col,
81405
+ right: col,
81406
+ top: row,
81407
+ bottom: row,
81408
+ });
81238
81409
  return {
81239
- col: this.getters.isColHidden(sheetId, anchorCol)
81240
- ? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
81241
- : anchorCol,
81242
- row: this.getters.isRowHidden(sheetId, anchorRow)
81243
- ? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
81244
- : anchorRow,
81410
+ cell: { col, row },
81411
+ zone,
81245
81412
  };
81246
81413
  }
81247
81414
  deltaToTarget(position, direction, step) {
@@ -84397,6 +84564,7 @@ const stores = {
84397
84564
  PivotSidePanelStore,
84398
84565
  PivotMeasureDisplayPanelStore,
84399
84566
  ClientFocusStore,
84567
+ GridRenderer,
84400
84568
  };
84401
84569
  function addFunction(functionName, functionDescription) {
84402
84570
  functionRegistry.add(functionName, functionDescription);
@@ -84415,6 +84583,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
84415
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 };
84416
84584
 
84417
84585
 
84418
- __info__.version = "18.5.0-alpha.0";
84419
- __info__.date = "2025-06-24T12:26:38.163Z";
84420
- __info__.hash = "ed0f325";
84586
+ __info__.version = "18.5.0-alpha.2";
84587
+ __info__.date = "2025-07-11T11:13:53.317Z";
84588
+ __info__.hash = "6d42178";