@odoo/o-spreadsheet 18.2.35 → 18.2.39

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.2.35
6
- * @date 2025-11-24T07:40:00.240Z
7
- * @hash 2e9a842
5
+ * @version 18.2.39
6
+ * @date 2025-12-26T10:18:44.735Z
7
+ * @hash 3de2479
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -3446,7 +3446,6 @@ const invalidateEvaluationCommands = new Set([
3446
3446
  "REDO",
3447
3447
  "ADD_MERGE",
3448
3448
  "REMOVE_MERGE",
3449
- "DUPLICATE_SHEET",
3450
3449
  "UPDATE_LOCALE",
3451
3450
  "ADD_PIVOT",
3452
3451
  "UPDATE_PIVOT",
@@ -6017,17 +6016,41 @@ function toCriterionDateNumber(dateValue) {
6017
6016
  const today = DateTime.now();
6018
6017
  switch (dateValue) {
6019
6018
  case "today":
6020
- return jsDateToNumber(today);
6021
- case "yesterday":
6022
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 1)));
6023
- case "tomorrow":
6024
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() + 1)));
6019
+ return Math.floor(jsDateToNumber(today));
6020
+ case "yesterday": {
6021
+ today.setDate(today.getDate() - 1);
6022
+ return Math.floor(jsDateToNumber(today));
6023
+ }
6024
+ case "tomorrow": {
6025
+ today.setDate(today.getDate() + 1);
6026
+ return Math.floor(jsDateToNumber(today));
6027
+ }
6025
6028
  case "lastWeek":
6026
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 7)));
6027
- case "lastMonth":
6028
- return jsDateToNumber(DateTime.fromTimestamp(today.setMonth(today.getMonth() - 1)));
6029
+ today.setDate(today.getDate() - 6);
6030
+ return Math.floor(jsDateToNumber(today));
6031
+ case "lastMonth": {
6032
+ const lastMonth = today.getMonth() === 0 ? 11 : today.getMonth() - 1;
6033
+ const dateInLastMonth = new DateTime(today.getFullYear(), lastMonth, 1);
6034
+ if (today.getDate() > getDaysInMonth(dateInLastMonth)) {
6035
+ today.setDate(1);
6036
+ }
6037
+ else {
6038
+ today.setDate(today.getDate() + 1);
6039
+ today.setMonth(today.getMonth() - 1);
6040
+ }
6041
+ return Math.floor(jsDateToNumber(today));
6042
+ }
6029
6043
  case "lastYear":
6030
- return jsDateToNumber(DateTime.fromTimestamp(today.setFullYear(today.getFullYear() - 1)));
6044
+ // Handle leap year case
6045
+ if (today.getMonth() === 1 && today.getDate() === 29) {
6046
+ today.setDate(28);
6047
+ today.setFullYear(today.getFullYear() - 1);
6048
+ }
6049
+ else {
6050
+ today.setDate(today.getDate() + 1);
6051
+ today.setFullYear(today.getFullYear() - 1);
6052
+ }
6053
+ return Math.floor(jsDateToNumber(today));
6031
6054
  }
6032
6055
  }
6033
6056
  /** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
@@ -21164,7 +21187,7 @@ class AbstractComposerStore extends SpreadsheetStore {
21164
21187
  }
21165
21188
  this.selectionStart = start;
21166
21189
  this.selectionEnd = end;
21167
- this.editionMode = "editing";
21190
+ this.stopComposerRangeSelection();
21168
21191
  this.computeFormulaCursorContext();
21169
21192
  this.computeParenthesisRelatedToCursor();
21170
21193
  }
@@ -23351,29 +23374,34 @@ function chartToImage(runtime, figure, type) {
23351
23374
  canvas.setAttribute("height", figure.height.toString());
23352
23375
  // we have to add the canvas to the DOM otherwise it won't be rendered
23353
23376
  document.body.append(div);
23377
+ let imgContent = undefined;
23354
23378
  if ("chartJsConfig" in runtime) {
23379
+ const extensionsLoaded = areChartJSExtensionsLoaded();
23380
+ if (!extensionsLoaded) {
23381
+ registerChartJSExtensions();
23382
+ }
23355
23383
  const config = deepCopy(runtime.chartJsConfig);
23356
23384
  config.plugins = [backgroundColorChartJSPlugin];
23357
23385
  const chart = new window.Chart(canvas, config);
23358
- const imgContent = chart.toBase64Image();
23386
+ imgContent = chart.toBase64Image();
23359
23387
  chart.destroy();
23360
23388
  div.remove();
23361
- return imgContent;
23389
+ if (!extensionsLoaded) {
23390
+ unregisterChartJsExtensions();
23391
+ }
23362
23392
  }
23363
23393
  else if (type === "scorecard") {
23364
23394
  const design = getScorecardConfiguration(figure, runtime);
23365
23395
  drawScoreChart(design, canvas);
23366
- const imgContent = canvas.toDataURL();
23396
+ imgContent = canvas.toDataURL();
23367
23397
  div.remove();
23368
- return imgContent;
23369
23398
  }
23370
23399
  else if (type === "gauge") {
23371
23400
  drawGaugeChart(canvas, runtime);
23372
- const imgContent = canvas.toDataURL();
23401
+ imgContent = canvas.toDataURL();
23373
23402
  div.remove();
23374
- return imgContent;
23375
23403
  }
23376
- return undefined;
23404
+ return imgContent;
23377
23405
  }
23378
23406
  /**
23379
23407
  * Custom chart.js plugin to set the background color of the canvas
@@ -32656,7 +32684,6 @@ class ChartFigure extends Component {
32656
32684
  static template = "o-spreadsheet-ChartFigure";
32657
32685
  static props = {
32658
32686
  figure: Object,
32659
- onFigureDeleted: Function,
32660
32687
  };
32661
32688
  static components = {};
32662
32689
  onDoubleClick() {
@@ -32680,7 +32707,6 @@ class ImageFigure extends Component {
32680
32707
  static template = "o-spreadsheet-ImageFigure";
32681
32708
  static props = {
32682
32709
  figure: Object,
32683
- onFigureDeleted: Function,
32684
32710
  };
32685
32711
  static components = {};
32686
32712
  // ---------------------------------------------------------------------------
@@ -32737,7 +32763,7 @@ figureRegistry.add("image", {
32737
32763
  borderWidth: 0,
32738
32764
  menuBuilder: getImageMenuRegistry,
32739
32765
  });
32740
- function getChartMenu(figureId, onFigureDeleted, env) {
32766
+ function getChartMenu(figureId, env) {
32741
32767
  const menuItemSpecs = [
32742
32768
  {
32743
32769
  id: "edit",
@@ -32751,11 +32777,11 @@ function getChartMenu(figureId, onFigureDeleted, env) {
32751
32777
  },
32752
32778
  getCopyMenuItem(figureId, env),
32753
32779
  getCutMenuItem(figureId, env),
32754
- getDeleteMenuItem(figureId, onFigureDeleted, env),
32780
+ getDeleteMenuItem(figureId, env),
32755
32781
  ];
32756
32782
  return createActions(menuItemSpecs);
32757
32783
  }
32758
- function getImageMenuRegistry(figureId, onFigureDeleted, env) {
32784
+ function getImageMenuRegistry(figureId, env) {
32759
32785
  const menuItemSpecs = [
32760
32786
  getCopyMenuItem(figureId, env),
32761
32787
  getCutMenuItem(figureId, env),
@@ -32781,7 +32807,7 @@ function getImageMenuRegistry(figureId, onFigureDeleted, env) {
32781
32807
  },
32782
32808
  icon: "o-spreadsheet-Icon.REFRESH",
32783
32809
  },
32784
- getDeleteMenuItem(figureId, onFigureDeleted, env),
32810
+ getDeleteMenuItem(figureId, env),
32785
32811
  ];
32786
32812
  return createActions(menuItemSpecs);
32787
32813
  }
@@ -32813,7 +32839,7 @@ function getCutMenuItem(figureId, env) {
32813
32839
  icon: "o-spreadsheet-Icon.CUT",
32814
32840
  };
32815
32841
  }
32816
- function getDeleteMenuItem(figureId, onFigureDeleted, env) {
32842
+ function getDeleteMenuItem(figureId, env) {
32817
32843
  return {
32818
32844
  id: "delete",
32819
32845
  name: _t("Delete"),
@@ -32823,7 +32849,6 @@ function getDeleteMenuItem(figureId, onFigureDeleted, env) {
32823
32849
  sheetId: env.model.getters.getActiveSheetId(),
32824
32850
  id: figureId,
32825
32851
  });
32826
- onFigureDeleted();
32827
32852
  },
32828
32853
  icon: "o-spreadsheet-Icon.TRASH",
32829
32854
  };
@@ -42617,7 +42642,7 @@ function useHighlights(highlightProvider) {
42617
42642
  }
42618
42643
 
42619
42644
  css /* scss */ `
42620
- .o-cf-preview {
42645
+ .o-spreadsheet .o-cf-preview {
42621
42646
  &.o-cf-cursor-ptr {
42622
42647
  cursor: pointer;
42623
42648
  }
@@ -42625,6 +42650,7 @@ css /* scss */ `
42625
42650
  border-bottom: 1px solid ${GRAY_300};
42626
42651
  height: 80px;
42627
42652
  padding: 10px;
42653
+ box-sizing: border-box;
42628
42654
  position: relative;
42629
42655
  cursor: pointer;
42630
42656
  &:hover,
@@ -42638,7 +42664,6 @@ css /* scss */ `
42638
42664
  .o-cf-preview-icon {
42639
42665
  border: 1px solid ${GRAY_300};
42640
42666
  background-color: #fff;
42641
- position: absolute;
42642
42667
  height: 50px;
42643
42668
  width: 50px;
42644
42669
  .o-icon {
@@ -42647,12 +42672,6 @@ css /* scss */ `
42647
42672
  }
42648
42673
  }
42649
42674
  .o-cf-preview-description {
42650
- left: 65px;
42651
- margin-bottom: auto;
42652
- margin-right: 8px;
42653
- margin-top: auto;
42654
- position: relative;
42655
- width: 142px;
42656
42675
  .o-cf-preview-description-rule {
42657
42676
  margin-bottom: 4px;
42658
42677
  max-height: 2.8em;
@@ -42662,16 +42681,11 @@ css /* scss */ `
42662
42681
  font-size: 12px;
42663
42682
  }
42664
42683
  }
42665
- .o-cf-delete {
42666
- left: 90%;
42667
- top: 39%;
42668
- position: absolute;
42669
- }
42670
42684
  &:not(:hover):not(.o-cf-dragging) .o-cf-drag-handle {
42671
42685
  display: none !important;
42672
42686
  }
42673
42687
  .o-cf-drag-handle {
42674
- left: -8px;
42688
+ left: 2px;
42675
42689
  cursor: move;
42676
42690
  .o-icon {
42677
42691
  width: 6px;
@@ -43660,7 +43674,7 @@ dataValidationEvaluatorRegistry.add("dateIs", {
43660
43674
  return false;
43661
43675
  }
43662
43676
  if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
43663
- const today = jsDateToRoundNumber(DateTime.now());
43677
+ const today = Math.floor(jsDateToNumber(DateTime.now()));
43664
43678
  return isDateBetween(dateValue, today, criterionValue);
43665
43679
  }
43666
43680
  return areDatesSameDay(dateValue, criterionValue);
@@ -47510,12 +47524,41 @@ const dateGranularities = [
47510
47524
  pivotRegistry.add("SPREADSHEET", {
47511
47525
  ui: SpreadsheetPivot,
47512
47526
  definition: SpreadsheetPivotRuntimeDefinition,
47513
- externalData: false,
47514
47527
  dateGranularities: [...dateGranularities],
47515
47528
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
47516
47529
  isMeasureCandidate: (field) => field.type !== "boolean",
47517
47530
  isGroupable: () => true,
47531
+ adaptRanges: (getters, definition, applyChange) => {
47532
+ if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
47533
+ return definition;
47534
+ }
47535
+ const { sheetId, zone } = definition.dataSet;
47536
+ const range = getters.getRangeFromZone(sheetId, zone);
47537
+ const adaptedRange = adaptPivotRange(range, applyChange);
47538
+ if (adaptedRange === range) {
47539
+ return definition;
47540
+ }
47541
+ const dataSet = adaptedRange && {
47542
+ sheetId: adaptedRange.sheetId,
47543
+ zone: adaptedRange.zone,
47544
+ };
47545
+ return { ...definition, dataSet };
47546
+ },
47518
47547
  });
47548
+ function adaptPivotRange(range, applyChange) {
47549
+ if (!range) {
47550
+ return undefined;
47551
+ }
47552
+ const change = applyChange(range);
47553
+ switch (change.changeType) {
47554
+ case "NONE":
47555
+ return range;
47556
+ case "REMOVE":
47557
+ return undefined;
47558
+ default:
47559
+ return change.range;
47560
+ }
47561
+ }
47519
47562
 
47520
47563
  class PivotSidePanelStore extends SpreadsheetStore {
47521
47564
  pivotId;
@@ -49156,13 +49199,11 @@ class FigureComponent extends Component {
49156
49199
  static props = {
49157
49200
  figure: Object,
49158
49201
  style: { type: String, optional: true },
49159
- onFigureDeleted: { type: Function, optional: true },
49160
49202
  onMouseDown: { type: Function, optional: true },
49161
49203
  onClickAnchor: { type: Function, optional: true },
49162
49204
  };
49163
49205
  static components = { Menu };
49164
49206
  static defaultProps = {
49165
- onFigureDeleted: () => { },
49166
49207
  onMouseDown: () => { },
49167
49208
  onClickAnchor: () => { },
49168
49209
  };
@@ -49236,9 +49277,6 @@ class FigureComponent extends Component {
49236
49277
  el?.focus({ preventScroll: true });
49237
49278
  }
49238
49279
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
49239
- onWillUnmount(() => {
49240
- this.props.onFigureDeleted();
49241
- });
49242
49280
  }
49243
49281
  clickAnchor(dirX, dirY, ev) {
49244
49282
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -49256,7 +49294,6 @@ class FigureComponent extends Component {
49256
49294
  sheetId: this.env.model.getters.getActiveSheetId(),
49257
49295
  id: figure.id,
49258
49296
  });
49259
- this.props.onFigureDeleted();
49260
49297
  ev.preventDefault();
49261
49298
  ev.stopPropagation();
49262
49299
  break;
@@ -49320,7 +49357,7 @@ class FigureComponent extends Component {
49320
49357
  this.menuState.position = position;
49321
49358
  this.menuState.menuItems = figureRegistry
49322
49359
  .get(this.props.figure.tag)
49323
- .menuBuilder(this.props.figure.id, this.props.onFigureDeleted, this.env);
49360
+ .menuBuilder(this.props.figure.id, this.env);
49324
49361
  }
49325
49362
  }
49326
49363
 
@@ -49433,21 +49470,20 @@ class ArrayFormulaHighlight extends SpreadsheetStore {
49433
49470
  this.highlightStore.register(this);
49434
49471
  }
49435
49472
  get highlights() {
49436
- let zone;
49437
49473
  const position = this.model.getters.getActivePosition();
49438
- const cell = this.getters.getEvaluatedCell(position);
49439
49474
  const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
49440
- zone = spreader
49475
+ const zone = spreader
49441
49476
  ? this.model.getters.getSpreadZone(spreader, { ignoreSpillError: true })
49442
49477
  : this.model.getters.getSpreadZone(position, { ignoreSpillError: true });
49443
49478
  if (!zone) {
49444
49479
  return [];
49445
49480
  }
49481
+ const isArrayFormulaBlocked = this.model.getters.isArrayFormulaSpillBlocked(spreader ?? position);
49446
49482
  return [
49447
49483
  {
49448
49484
  sheetId: position.sheetId,
49449
49485
  zone,
49450
- dashed: cell.value === CellErrorType.SpilledBlocked,
49486
+ dashed: isArrayFormulaBlocked,
49451
49487
  color: "#17A2B8",
49452
49488
  noFill: true,
49453
49489
  thinLine: true,
@@ -50515,9 +50551,7 @@ css /*SCSS*/ `
50515
50551
  */
50516
50552
  class FiguresContainer extends Component {
50517
50553
  static template = "o-spreadsheet-FiguresContainer";
50518
- static props = {
50519
- onFigureDeleted: Function,
50520
- };
50554
+ static props = {};
50521
50555
  static components = { FigureComponent };
50522
50556
  dnd = useState({
50523
50557
  draggedFigure: undefined,
@@ -50873,16 +50907,16 @@ css /* scss */ `
50873
50907
  `;
50874
50908
  class GridAddRowsFooter extends Component {
50875
50909
  static template = "o-spreadsheet-GridAddRowsFooter";
50876
- static props = {
50877
- focusGrid: Function,
50878
- };
50910
+ static props = {};
50879
50911
  static components = { ValidationMessages };
50912
+ DOMFocusableElementStore;
50880
50913
  inputRef = useRef("inputRef");
50881
50914
  state = useState({
50882
50915
  inputValue: "100",
50883
50916
  errorFlag: false,
50884
50917
  });
50885
50918
  setup() {
50919
+ this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
50886
50920
  useExternalListener(window, "click", this.onExternalClick, { capture: true });
50887
50921
  }
50888
50922
  get addRowsPosition() {
@@ -50900,7 +50934,7 @@ class GridAddRowsFooter extends Component {
50900
50934
  }
50901
50935
  onKeydown(ev) {
50902
50936
  if (ev.key.toUpperCase() === "ESCAPE") {
50903
- this.props.focusGrid();
50937
+ this.focusDefaultElement();
50904
50938
  }
50905
50939
  else if (ev.key.toUpperCase() === "ENTER") {
50906
50940
  this.onConfirm();
@@ -50926,7 +50960,7 @@ class GridAddRowsFooter extends Component {
50926
50960
  quantity,
50927
50961
  dimension: "ROW",
50928
50962
  });
50929
- this.props.focusGrid();
50963
+ this.focusDefaultElement();
50930
50964
  // After adding new rows, scroll down to the new last row
50931
50965
  const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
50932
50966
  const { end } = this.env.model.getters.getRowDimensions(activeSheetId, rowNumber + quantity - 1);
@@ -50939,7 +50973,12 @@ class GridAddRowsFooter extends Component {
50939
50973
  if (this.inputRef.el !== document.activeElement || ev.target === this.inputRef.el) {
50940
50974
  return;
50941
50975
  }
50942
- this.props.focusGrid();
50976
+ this.focusDefaultElement();
50977
+ }
50978
+ focusDefaultElement() {
50979
+ if (document.activeElement === this.inputRef.el) {
50980
+ this.DOMFocusableElementStore.focus();
50981
+ }
50943
50982
  }
50944
50983
  }
50945
50984
 
@@ -51128,7 +51167,6 @@ class GridOverlay extends Component {
51128
51167
  onCellClicked: { type: Function, optional: true },
51129
51168
  onCellRightClicked: { type: Function, optional: true },
51130
51169
  onGridResized: { type: Function, optional: true },
51131
- onFigureDeleted: { type: Function, optional: true },
51132
51170
  onGridMoved: Function,
51133
51171
  gridOverlayDimensions: String,
51134
51172
  };
@@ -51144,7 +51182,6 @@ class GridOverlay extends Component {
51144
51182
  onCellClicked: () => { },
51145
51183
  onCellRightClicked: () => { },
51146
51184
  onGridResized: () => { },
51147
- onFigureDeleted: () => { },
51148
51185
  };
51149
51186
  gridOverlay = useRef("gridOverlay");
51150
51187
  gridOverlayRect = useAbsoluteBoundingRect(this.gridOverlay);
@@ -57551,6 +57588,7 @@ function rangeToMerge(mergeId, range) {
57551
57588
  class RangeAdapter {
57552
57589
  getters;
57553
57590
  providers = [];
57591
+ isAdaptingRanges = false;
57554
57592
  constructor(getters) {
57555
57593
  this.getters = getters;
57556
57594
  }
@@ -57581,6 +57619,9 @@ class RangeAdapter {
57581
57619
  }
57582
57620
  beforeHandle(command) { }
57583
57621
  handle(cmd) {
57622
+ if (this.isAdaptingRanges) {
57623
+ throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
57624
+ }
57584
57625
  switch (cmd.type) {
57585
57626
  case "REMOVE_COLUMNS_ROWS": {
57586
57627
  let start = cmd.dimension === "COL" ? "left" : "top";
@@ -57736,10 +57777,12 @@ class RangeAdapter {
57736
57777
  return adaptedRange;
57737
57778
  }
57738
57779
  executeOnAllRanges(adaptRange, sheetId) {
57780
+ this.isAdaptingRanges = true;
57739
57781
  const func = this.verifyRangeRemoved(adaptRange);
57740
57782
  for (const provider of this.providers) {
57741
57783
  provider(func, sheetId);
57742
57784
  }
57785
+ this.isAdaptingRanges = false;
57743
57786
  }
57744
57787
  /**
57745
57788
  * Stores the functions bound to each plugin to be able to iterate over all ranges of the application,
@@ -59863,6 +59906,18 @@ class PivotCorePlugin extends CorePlugin {
59863
59906
  }
59864
59907
  }
59865
59908
  adaptRanges(applyChange) {
59909
+ for (const pivotId in this.pivots) {
59910
+ const definition = deepCopy(this.pivots[pivotId]?.definition);
59911
+ if (!definition) {
59912
+ continue;
59913
+ }
59914
+ const newDefinition = pivotRegistry
59915
+ .get(definition.type)
59916
+ ?.adaptRanges?.(this.getters, definition, applyChange);
59917
+ if (newDefinition && !deepEquals(definition, newDefinition)) {
59918
+ this.history.update("pivots", pivotId, "definition", newDefinition);
59919
+ }
59920
+ }
59866
59921
  for (const sheetId in this.compiledMeasureFormulas) {
59867
59922
  for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
59868
59923
  const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
@@ -60130,20 +60185,6 @@ class SettingsPlugin extends CorePlugin {
60130
60185
  }
60131
60186
  }
60132
60187
 
60133
- function adaptPivotRange(range, applyChange) {
60134
- if (!range) {
60135
- return undefined;
60136
- }
60137
- const change = applyChange(range);
60138
- switch (change.changeType) {
60139
- case "NONE":
60140
- return range;
60141
- case "REMOVE":
60142
- return undefined;
60143
- default:
60144
- return change.range;
60145
- }
60146
- }
60147
60188
  class SpreadsheetPivotCorePlugin extends CorePlugin {
60148
60189
  allowDispatch(cmd) {
60149
60190
  switch (cmd.type) {
@@ -60154,24 +60195,6 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
60154
60195
  }
60155
60196
  return "Success" /* CommandResult.Success */;
60156
60197
  }
60157
- adaptRanges(applyChange) {
60158
- for (const pivotId of this.getters.getPivotIds()) {
60159
- const definition = this.getters.getPivotCoreDefinition(pivotId);
60160
- if (definition.type !== "SPREADSHEET") {
60161
- continue;
60162
- }
60163
- if (definition.dataSet) {
60164
- const { sheetId, zone } = definition.dataSet;
60165
- const range = this.getters.getRangeFromZone(sheetId, zone);
60166
- const adaptedRange = adaptPivotRange(range, applyChange);
60167
- const dataSet = adaptedRange && {
60168
- sheetId: adaptedRange.sheetId,
60169
- zone: adaptedRange.zone,
60170
- };
60171
- this.dispatch("UPDATE_PIVOT", { pivotId, pivot: { ...definition, dataSet } });
60172
- }
60173
- }
60174
- }
60175
60198
  checkDataSetValidity(definition) {
60176
60199
  if (definition.type === "SPREADSHEET" && definition.dataSet) {
60177
60200
  const { zone, sheetId } = definition.dataSet;
@@ -61513,6 +61536,9 @@ class Evaluator {
61513
61536
  const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
61514
61537
  return Array.from(arrayFormulas).find((position) => !this.blockedArrayFormulas.has(position));
61515
61538
  }
61539
+ isArrayFormulaSpillBlocked(position) {
61540
+ return this.blockedArrayFormulas.has(position);
61541
+ }
61516
61542
  updateDependencies(position) {
61517
61543
  // removing dependencies is slow because it requires
61518
61544
  // to traverse the entire r-tree.
@@ -61524,13 +61550,8 @@ class Evaluator {
61524
61550
  addDependencies(position, dependencies) {
61525
61551
  this.formulaDependencies().addDependencies(position, dependencies);
61526
61552
  for (const range of dependencies) {
61527
- const sheetId = range.sheetId;
61528
- const { left, bottom, right, top } = range.zone;
61529
- for (let col = left; col <= right; col++) {
61530
- for (let row = top; row <= bottom; row++) {
61531
- this.computeAndSave({ sheetId, col, row });
61532
- }
61533
- }
61553
+ // ensure that all ranges are computed
61554
+ this.compilationParams.ensureRange(range);
61534
61555
  }
61535
61556
  }
61536
61557
  updateCompilationParameters() {
@@ -61733,6 +61754,10 @@ class Evaluator {
61733
61754
  this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
61734
61755
  const nbColumns = formulaReturn.length;
61735
61756
  const nbRows = formulaReturn[0].length;
61757
+ if (nbRows === 0) {
61758
+ // empty matrix
61759
+ return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
61760
+ }
61736
61761
  const resultZone = {
61737
61762
  top: formulaPosition.row,
61738
61763
  bottom: formulaPosition.row + nbRows - 1,
@@ -62008,6 +62033,7 @@ class EvaluationPlugin extends CoreViewPlugin {
62008
62033
  "getEvaluatedCellsPositions",
62009
62034
  "getSpreadZone",
62010
62035
  "getArrayFormulaSpreadingOn",
62036
+ "isArrayFormulaSpillBlocked",
62011
62037
  "isEmpty",
62012
62038
  ];
62013
62039
  shouldRebuildDependenciesGraph = true;
@@ -62120,6 +62146,9 @@ class EvaluationPlugin extends CoreViewPlugin {
62120
62146
  getArrayFormulaSpreadingOn(position) {
62121
62147
  return this.evaluator.getArrayFormulaSpreadingOn(position);
62122
62148
  }
62149
+ isArrayFormulaSpillBlocked(position) {
62150
+ return this.evaluator.isArrayFormulaSpillBlocked(position);
62151
+ }
62123
62152
  /**
62124
62153
  * Check if a zone only contains empty cells
62125
62154
  */
@@ -63886,9 +63915,7 @@ class PivotUIPlugin extends CoreViewPlugin {
63886
63915
  handle(cmd) {
63887
63916
  if (invalidateEvaluationCommands.has(cmd.type)) {
63888
63917
  for (const pivotId of this.getters.getPivotIds()) {
63889
- if (!pivotRegistry.get(this.getters.getPivotCoreDefinition(pivotId).type).externalData) {
63890
- this.setupPivot(pivotId, { recreate: true });
63891
- }
63918
+ this.setupPivot(pivotId, { recreate: true });
63892
63919
  }
63893
63920
  }
63894
63921
  switch (cmd.type) {
@@ -64089,7 +64116,7 @@ class PivotUIPlugin extends CoreViewPlugin {
64089
64116
  pivot.init({ reload: true });
64090
64117
  }
64091
64118
  setupPivot(pivotId, { recreate } = { recreate: false }) {
64092
- const definition = this.getters.getPivotCoreDefinition(pivotId);
64119
+ const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
64093
64120
  if (!(pivotId in this.pivots)) {
64094
64121
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
64095
64122
  this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
@@ -72827,7 +72854,7 @@ class Spreadsheet extends Component {
72827
72854
  document.activeElement?.contains(this.spreadsheetRef.el)) {
72828
72855
  this.focusGrid();
72829
72856
  }
72830
- }, () => [this.env.model.getters.getActiveSheetId()]);
72857
+ });
72831
72858
  useExternalListener(window, "resize", () => this.render(true));
72832
72859
  // For some reason, the wheel event is not properly registered inside templates
72833
72860
  // in Chromium-based browsers based on chromium 125
@@ -77347,6 +77374,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
77347
77374
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, 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, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
77348
77375
 
77349
77376
 
77350
- __info__.version = "18.2.35";
77351
- __info__.date = "2025-11-24T07:40:00.240Z";
77352
- __info__.hash = "2e9a842";
77377
+ __info__.version = "18.2.39";
77378
+ __info__.date = "2025-12-26T10:18:44.735Z";
77379
+ __info__.hash = "3de2479";