@odoo/o-spreadsheet 18.4.19 → 18.4.23

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.19
6
- * @date 2025-12-02T05:34:03.902Z
7
- * @hash 95b1252
5
+ * @version 18.4.23
6
+ * @date 2026-01-07T16:21:07.502Z
7
+ * @hash a0135e8
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -5214,17 +5214,41 @@
5214
5214
  const today = DateTime.now();
5215
5215
  switch (dateValue) {
5216
5216
  case "today":
5217
- return jsDateToNumber(today);
5218
- case "yesterday":
5219
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 1)));
5220
- case "tomorrow":
5221
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() + 1)));
5217
+ return Math.floor(jsDateToNumber(today));
5218
+ case "yesterday": {
5219
+ today.setDate(today.getDate() - 1);
5220
+ return Math.floor(jsDateToNumber(today));
5221
+ }
5222
+ case "tomorrow": {
5223
+ today.setDate(today.getDate() + 1);
5224
+ return Math.floor(jsDateToNumber(today));
5225
+ }
5222
5226
  case "lastWeek":
5223
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 7)));
5224
- case "lastMonth":
5225
- return jsDateToNumber(DateTime.fromTimestamp(today.setMonth(today.getMonth() - 1)));
5227
+ today.setDate(today.getDate() - 6);
5228
+ return Math.floor(jsDateToNumber(today));
5229
+ case "lastMonth": {
5230
+ const lastMonth = today.getMonth() === 0 ? 11 : today.getMonth() - 1;
5231
+ const dateInLastMonth = new DateTime(today.getFullYear(), lastMonth, 1);
5232
+ if (today.getDate() > getDaysInMonth(dateInLastMonth)) {
5233
+ today.setDate(1);
5234
+ }
5235
+ else {
5236
+ today.setDate(today.getDate() + 1);
5237
+ today.setMonth(today.getMonth() - 1);
5238
+ }
5239
+ return Math.floor(jsDateToNumber(today));
5240
+ }
5226
5241
  case "lastYear":
5227
- return jsDateToNumber(DateTime.fromTimestamp(today.setFullYear(today.getFullYear() - 1)));
5242
+ // Handle leap year case
5243
+ if (today.getMonth() === 1 && today.getDate() === 29) {
5244
+ today.setDate(28);
5245
+ today.setFullYear(today.getFullYear() - 1);
5246
+ }
5247
+ else {
5248
+ today.setDate(today.getDate() + 1);
5249
+ today.setFullYear(today.getFullYear() - 1);
5250
+ }
5251
+ return Math.floor(jsDateToNumber(today));
5228
5252
  }
5229
5253
  }
5230
5254
  /** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
@@ -29719,7 +29743,7 @@ stores.inject(MyMetaStore, storeInstance);
29719
29743
  return query.replaceAll(/([a-zA-Z0-9]+):([a-zA-Z0-9]+)/g, "NAMESPACE" + "$1" + "NAMESPACE" + "$2");
29720
29744
  }
29721
29745
 
29722
- function getChartMenuActions(figureId, onFigureDeleted, env) {
29746
+ function getChartMenuActions(figureId, env) {
29723
29747
  const menuItemSpecs = [
29724
29748
  {
29725
29749
  id: "edit",
@@ -29770,11 +29794,11 @@ stores.inject(MyMetaStore, storeInstance);
29770
29794
  },
29771
29795
  isReadonlyAllowed: true,
29772
29796
  },
29773
- getDeleteMenuItem(figureId, onFigureDeleted, env),
29797
+ getDeleteMenuItem(figureId, env),
29774
29798
  ];
29775
29799
  return createActions(menuItemSpecs).filter((action) => env.model.getters.isReadonly() ? action.isReadonlyAllowed : true);
29776
29800
  }
29777
- function getImageMenuActions(figureId, onFigureDeleted, env) {
29801
+ function getImageMenuActions(figureId, env) {
29778
29802
  const menuItemSpecs = [
29779
29803
  getCopyMenuItem(figureId, env, _t("Image copied to clipboard")),
29780
29804
  getCutMenuItem(figureId, env),
@@ -29819,7 +29843,7 @@ stores.inject(MyMetaStore, storeInstance);
29819
29843
  },
29820
29844
  icon: "o-spreadsheet-Icon.DOWNLOAD",
29821
29845
  },
29822
- getDeleteMenuItem(figureId, onFigureDeleted, env),
29846
+ getDeleteMenuItem(figureId, env),
29823
29847
  ];
29824
29848
  return createActions(menuItemSpecs);
29825
29849
  }
@@ -29855,7 +29879,7 @@ stores.inject(MyMetaStore, storeInstance);
29855
29879
  icon: "o-spreadsheet-Icon.CUT",
29856
29880
  };
29857
29881
  }
29858
- function getDeleteMenuItem(figureId, onFigureDeleted, env) {
29882
+ function getDeleteMenuItem(figureId, env) {
29859
29883
  return {
29860
29884
  id: "delete",
29861
29885
  name: _t("Delete"),
@@ -29865,7 +29889,6 @@ stores.inject(MyMetaStore, storeInstance);
29865
29889
  sheetId: env.model.getters.getActiveSheetId(),
29866
29890
  figureId,
29867
29891
  });
29868
- onFigureDeleted();
29869
29892
  },
29870
29893
  icon: "o-spreadsheet-Icon.TRASH",
29871
29894
  };
@@ -30710,7 +30733,7 @@ stores.inject(MyMetaStore, storeInstance);
30710
30733
  openContextMenu(ev) {
30711
30734
  this.menuState.isOpen = true;
30712
30735
  this.menuState.anchorRect = getBoundingRectAsPOJO(ev.currentTarget);
30713
- this.menuState.menuItems = getChartMenuActions(this.props.figureUI.id, () => { }, this.env);
30736
+ this.menuState.menuItems = getChartMenuActions(this.props.figureUI.id, this.env);
30714
30737
  }
30715
30738
  get fullScreenMenuItem() {
30716
30739
  const definition = this.env.model.getters.getChartDefinition(this.props.figureUI.id);
@@ -30752,7 +30775,6 @@ stores.inject(MyMetaStore, storeInstance);
30752
30775
  static template = "o-spreadsheet-ChartFigure";
30753
30776
  static props = {
30754
30777
  figureUI: Object,
30755
- onFigureDeleted: Function,
30756
30778
  };
30757
30779
  static components = { ChartDashboardMenu };
30758
30780
  onDoubleClick() {
@@ -30776,7 +30798,6 @@ stores.inject(MyMetaStore, storeInstance);
30776
30798
  static template = "o-spreadsheet-ImageFigure";
30777
30799
  static props = {
30778
30800
  figureUI: Object,
30779
- onFigureDeleted: Function,
30780
30801
  };
30781
30802
  static components = {};
30782
30803
  // ---------------------------------------------------------------------------
@@ -30887,13 +30908,11 @@ stores.inject(MyMetaStore, storeInstance);
30887
30908
  static props = {
30888
30909
  figureUI: Object,
30889
30910
  style: { type: String, optional: true },
30890
- onFigureDeleted: { type: Function, optional: true },
30891
30911
  onMouseDown: { type: Function, optional: true },
30892
30912
  onClickAnchor: { type: Function, optional: true },
30893
30913
  };
30894
30914
  static components = { MenuPopover };
30895
30915
  static defaultProps = {
30896
- onFigureDeleted: () => { },
30897
30916
  onMouseDown: () => { },
30898
30917
  onClickAnchor: () => { },
30899
30918
  };
@@ -30970,9 +30989,6 @@ stores.inject(MyMetaStore, storeInstance);
30970
30989
  this.props.figureUI.id,
30971
30990
  this.figureRef.el,
30972
30991
  ]);
30973
- owl.onWillUnmount(() => {
30974
- this.props.onFigureDeleted();
30975
- });
30976
30992
  }
30977
30993
  clickAnchor(dirX, dirY, ev) {
30978
30994
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -30996,7 +31012,6 @@ stores.inject(MyMetaStore, storeInstance);
30996
31012
  sheetId: this.env.model.getters.getActiveSheetId(),
30997
31013
  figureId: this.props.figureUI.id,
30998
31014
  });
30999
- this.props.onFigureDeleted();
31000
31015
  ev.preventDefault();
31001
31016
  ev.stopPropagation();
31002
31017
  break;
@@ -31089,7 +31104,7 @@ stores.inject(MyMetaStore, storeInstance);
31089
31104
  this.menuState.anchorRect = anchorRect;
31090
31105
  this.menuState.menuItems = figureRegistry
31091
31106
  .get(this.props.figureUI.tag)
31092
- .menuBuilder(this.props.figureUI.id, this.props.onFigureDeleted, this.env);
31107
+ .menuBuilder(this.props.figureUI.id, this.env);
31093
31108
  }
31094
31109
  }
31095
31110
 
@@ -31454,7 +31469,7 @@ stores.inject(MyMetaStore, storeInstance);
31454
31469
  return false;
31455
31470
  }
31456
31471
  if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
31457
- const today = jsDateToRoundNumber(DateTime.now());
31472
+ const today = Math.floor(jsDateToNumber(DateTime.now()));
31458
31473
  return isDateBetween(dateValue, today, criterionValue);
31459
31474
  }
31460
31475
  return areDatesSameDay(dateValue, criterionValue);
@@ -45256,7 +45271,6 @@ stores.inject(MyMetaStore, storeInstance);
45256
45271
  }
45257
45272
  get highlights() {
45258
45273
  const position = this.model.getters.getActivePosition();
45259
- const cell = this.getters.getEvaluatedCell(position);
45260
45274
  const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
45261
45275
  const zone = spreader
45262
45276
  ? this.model.getters.getSpreadZone(spreader, { ignoreSpillError: true })
@@ -45264,10 +45278,11 @@ stores.inject(MyMetaStore, storeInstance);
45264
45278
  if (!zone) {
45265
45279
  return [];
45266
45280
  }
45281
+ const isArrayFormulaBlocked = this.model.getters.isArrayFormulaSpillBlocked(spreader ?? position);
45267
45282
  return [
45268
45283
  {
45269
45284
  range: this.model.getters.getRangeFromZone(position.sheetId, zone),
45270
- dashed: cell.value === CellErrorType.SpilledBlocked,
45285
+ dashed: isArrayFormulaBlocked,
45271
45286
  color: "#17A2B8",
45272
45287
  noFill: true,
45273
45288
  thinLine: true,
@@ -46365,9 +46380,7 @@ stores.inject(MyMetaStore, storeInstance);
46365
46380
  */
46366
46381
  class FiguresContainer extends owl.Component {
46367
46382
  static template = "o-spreadsheet-FiguresContainer";
46368
- static props = {
46369
- onFigureDeleted: Function,
46370
- };
46383
+ static props = {};
46371
46384
  static components = { FigureComponent };
46372
46385
  dnd = owl.useState({
46373
46386
  draggedFigure: undefined,
@@ -46742,16 +46755,16 @@ stores.inject(MyMetaStore, storeInstance);
46742
46755
  `;
46743
46756
  class GridAddRowsFooter extends owl.Component {
46744
46757
  static template = "o-spreadsheet-GridAddRowsFooter";
46745
- static props = {
46746
- focusGrid: Function,
46747
- };
46758
+ static props = {};
46748
46759
  static components = { ValidationMessages };
46760
+ DOMFocusableElementStore;
46749
46761
  inputRef = owl.useRef("inputRef");
46750
46762
  state = owl.useState({
46751
46763
  inputValue: "100",
46752
46764
  errorFlag: false,
46753
46765
  });
46754
46766
  setup() {
46767
+ this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
46755
46768
  owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
46756
46769
  }
46757
46770
  get addRowsPosition() {
@@ -46769,7 +46782,7 @@ stores.inject(MyMetaStore, storeInstance);
46769
46782
  }
46770
46783
  onKeydown(ev) {
46771
46784
  if (ev.key.toUpperCase() === "ESCAPE") {
46772
- this.props.focusGrid();
46785
+ this.focusDefaultElement();
46773
46786
  }
46774
46787
  else if (ev.key.toUpperCase() === "ENTER") {
46775
46788
  this.onConfirm();
@@ -46796,7 +46809,7 @@ stores.inject(MyMetaStore, storeInstance);
46796
46809
  quantity,
46797
46810
  dimension: "ROW",
46798
46811
  });
46799
- this.props.focusGrid();
46812
+ this.focusDefaultElement();
46800
46813
  // After adding new rows, scroll down to the new last row
46801
46814
  const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
46802
46815
  const { end } = this.env.model.getters.getRowDimensions(activeSheetId, rowNumber + quantity - 1);
@@ -46809,7 +46822,12 @@ stores.inject(MyMetaStore, storeInstance);
46809
46822
  if (this.inputRef.el !== document.activeElement || ev.target === this.inputRef.el) {
46810
46823
  return;
46811
46824
  }
46812
- this.props.focusGrid();
46825
+ this.focusDefaultElement();
46826
+ }
46827
+ focusDefaultElement() {
46828
+ if (document.activeElement === this.inputRef.el) {
46829
+ this.DOMFocusableElementStore.focus();
46830
+ }
46813
46831
  }
46814
46832
  }
46815
46833
 
@@ -47084,11 +47102,9 @@ stores.inject(MyMetaStore, storeInstance);
47084
47102
  onCellClicked: { type: Function, optional: true },
47085
47103
  onCellRightClicked: { type: Function, optional: true },
47086
47104
  onGridResized: { type: Function, optional: true },
47087
- onFigureDeleted: { type: Function, optional: true },
47088
47105
  onGridMoved: Function,
47089
47106
  gridOverlayDimensions: String,
47090
47107
  slots: { type: Object, optional: true },
47091
- getGridSize: Function,
47092
47108
  };
47093
47109
  static components = {
47094
47110
  FiguresContainer,
@@ -47099,7 +47115,6 @@ stores.inject(MyMetaStore, storeInstance);
47099
47115
  onCellClicked: () => { },
47100
47116
  onCellRightClicked: () => { },
47101
47117
  onGridResized: () => { },
47102
- onFigureDeleted: () => { },
47103
47118
  };
47104
47119
  gridOverlay = owl.useRef("gridOverlay");
47105
47120
  cellPopovers;
@@ -47108,14 +47123,7 @@ stores.inject(MyMetaStore, storeInstance);
47108
47123
  setup() {
47109
47124
  useCellHovered(this.env, this.gridOverlay);
47110
47125
  const resizeObserver = new ResizeObserver(() => {
47111
- const boundingRect = this.gridOverlayEl.getBoundingClientRect();
47112
- const { width, height } = this.props.getGridSize();
47113
- this.props.onGridResized({
47114
- x: boundingRect.left,
47115
- y: boundingRect.top,
47116
- height: height,
47117
- width: width,
47118
- });
47126
+ this.props.onGridResized();
47119
47127
  });
47120
47128
  owl.onMounted(() => {
47121
47129
  resizeObserver.observe(this.gridOverlayEl);
@@ -51958,7 +51966,7 @@ stores.inject(MyMetaStore, storeInstance);
51958
51966
  }
51959
51967
 
51960
51968
  css /* scss */ `
51961
- .o-cf-preview {
51969
+ .o-spreadsheet .o-cf-preview {
51962
51970
  &.o-cf-cursor-ptr {
51963
51971
  cursor: pointer;
51964
51972
  }
@@ -51966,6 +51974,7 @@ stores.inject(MyMetaStore, storeInstance);
51966
51974
  border-bottom: 1px solid ${GRAY_300};
51967
51975
  height: 80px;
51968
51976
  padding: 10px;
51977
+ box-sizing: border-box;
51969
51978
  position: relative;
51970
51979
  cursor: pointer;
51971
51980
  &:hover,
@@ -51979,7 +51988,6 @@ stores.inject(MyMetaStore, storeInstance);
51979
51988
  .o-cf-preview-icon {
51980
51989
  border: 1px solid ${GRAY_300};
51981
51990
  background-color: #fff;
51982
- position: absolute;
51983
51991
  height: 50px;
51984
51992
  width: 50px;
51985
51993
  .o-icon {
@@ -51988,12 +51996,6 @@ stores.inject(MyMetaStore, storeInstance);
51988
51996
  }
51989
51997
  }
51990
51998
  .o-cf-preview-description {
51991
- left: 65px;
51992
- margin-bottom: auto;
51993
- margin-right: 8px;
51994
- margin-top: auto;
51995
- position: relative;
51996
- width: 142px;
51997
51999
  .o-cf-preview-description-rule {
51998
52000
  margin-bottom: 4px;
51999
52001
  max-height: 2.8em;
@@ -52003,16 +52005,11 @@ stores.inject(MyMetaStore, storeInstance);
52003
52005
  font-size: 12px;
52004
52006
  }
52005
52007
  }
52006
- .o-cf-delete {
52007
- left: 90%;
52008
- top: 39%;
52009
- position: absolute;
52010
- }
52011
52008
  &:not(:hover):not(.o-cf-dragging) .o-cf-drag-handle {
52012
52009
  display: none !important;
52013
52010
  }
52014
52011
  .o-cf-drag-handle {
52015
- left: -8px;
52012
+ left: 2px;
52016
52013
  cursor: move;
52017
52014
  .o-icon {
52018
52015
  width: 6px;
@@ -56061,7 +56058,37 @@ stores.inject(MyMetaStore, storeInstance);
56061
56058
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
56062
56059
  isMeasureCandidate: (field) => field.type !== "boolean",
56063
56060
  isGroupable: () => true,
56061
+ adaptRanges: (getters, definition, applyChange) => {
56062
+ if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
56063
+ return definition;
56064
+ }
56065
+ const { sheetId, zone } = definition.dataSet;
56066
+ const range = getters.getRangeFromZone(sheetId, zone);
56067
+ const adaptedRange = adaptPivotRange(range, applyChange);
56068
+ if (adaptedRange === range) {
56069
+ return definition;
56070
+ }
56071
+ const dataSet = adaptedRange && {
56072
+ sheetId: adaptedRange.sheetId,
56073
+ zone: adaptedRange.zone,
56074
+ };
56075
+ return { ...definition, dataSet };
56076
+ },
56064
56077
  });
56078
+ function adaptPivotRange(range, applyChange) {
56079
+ if (!range) {
56080
+ return undefined;
56081
+ }
56082
+ const change = applyChange(range);
56083
+ switch (change.changeType) {
56084
+ case "NONE":
56085
+ return range;
56086
+ case "REMOVE":
56087
+ return undefined;
56088
+ default:
56089
+ return change.range;
56090
+ }
56091
+ }
56065
56092
 
56066
56093
  class PivotSidePanelStore extends SpreadsheetStore {
56067
56094
  pivotId;
@@ -58032,7 +58059,8 @@ stores.inject(MyMetaStore, storeInstance);
58032
58059
  });
58033
58060
  return !(rect.width === 0 || rect.height === 0);
58034
58061
  }
58035
- onGridResized({ height, width }) {
58062
+ onGridResized() {
58063
+ const { height, width } = this.props.getGridSize();
58036
58064
  this.env.model.dispatch("RESIZE_SHEETVIEW", {
58037
58065
  width: width - HEADER_WIDTH,
58038
58066
  height: height - HEADER_HEIGHT,
@@ -62214,6 +62242,7 @@ stores.inject(MyMetaStore, storeInstance);
62214
62242
  class RangeAdapter {
62215
62243
  getters;
62216
62244
  providers = [];
62245
+ isAdaptingRanges = false;
62217
62246
  constructor(getters) {
62218
62247
  this.getters = getters;
62219
62248
  }
@@ -62245,6 +62274,9 @@ stores.inject(MyMetaStore, storeInstance);
62245
62274
  }
62246
62275
  beforeHandle(command) { }
62247
62276
  handle(cmd) {
62277
+ if (this.isAdaptingRanges) {
62278
+ throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
62279
+ }
62248
62280
  const rangeAdapter = getRangeAdapter(cmd);
62249
62281
  if (rangeAdapter?.applyChange) {
62250
62282
  this.executeOnAllRanges(rangeAdapter.applyChange, rangeAdapter.sheetId, rangeAdapter.sheetName);
@@ -62267,10 +62299,12 @@ stores.inject(MyMetaStore, storeInstance);
62267
62299
  };
62268
62300
  }
62269
62301
  executeOnAllRanges(adaptRange, sheetId, sheetName) {
62302
+ this.isAdaptingRanges = true;
62270
62303
  const func = this.verifyRangeRemoved(adaptRange);
62271
62304
  for (const provider of this.providers) {
62272
62305
  provider(func, sheetId, sheetName);
62273
62306
  }
62307
+ this.isAdaptingRanges = false;
62274
62308
  }
62275
62309
  /**
62276
62310
  * Stores the functions bound to each plugin to be able to iterate over all ranges of the application,
@@ -64306,6 +64340,18 @@ stores.inject(MyMetaStore, storeInstance);
64306
64340
  }
64307
64341
  }
64308
64342
  adaptRanges(applyChange) {
64343
+ for (const pivotId in this.pivots) {
64344
+ const definition = deepCopy(this.pivots[pivotId]?.definition);
64345
+ if (!definition) {
64346
+ continue;
64347
+ }
64348
+ const newDefinition = pivotRegistry
64349
+ .get(definition.type)
64350
+ ?.adaptRanges?.(this.getters, definition, applyChange);
64351
+ if (newDefinition && !deepEquals(definition, newDefinition)) {
64352
+ this.history.update("pivots", pivotId, "definition", newDefinition);
64353
+ }
64354
+ }
64309
64355
  for (const sheetId in this.compiledMeasureFormulas) {
64310
64356
  for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
64311
64357
  const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
@@ -64450,17 +64496,10 @@ stores.inject(MyMetaStore, storeInstance);
64450
64496
  if (!pivot) {
64451
64497
  continue;
64452
64498
  }
64453
- const def = deepCopy(pivot.definition);
64454
- for (const measure of def.measures) {
64499
+ for (const measure of pivot.definition.measures) {
64455
64500
  if (measure.computedBy?.formula === formulaString) {
64456
- const measureIndex = def.measures.indexOf(measure);
64457
- if (measureIndex !== -1) {
64458
- def.measures[measureIndex].computedBy = {
64459
- formula: newFormulaString,
64460
- sheetId,
64461
- };
64462
- }
64463
- this.dispatch("UPDATE_PIVOT", { pivotId, pivot: def });
64501
+ const measureIndex = pivot.definition.measures.indexOf(measure);
64502
+ this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
64464
64503
  }
64465
64504
  }
64466
64505
  }
@@ -64564,20 +64603,6 @@ stores.inject(MyMetaStore, storeInstance);
64564
64603
  }
64565
64604
  }
64566
64605
 
64567
- function adaptPivotRange(range, applyChange) {
64568
- if (!range) {
64569
- return undefined;
64570
- }
64571
- const change = applyChange(range);
64572
- switch (change.changeType) {
64573
- case "NONE":
64574
- return range;
64575
- case "REMOVE":
64576
- return undefined;
64577
- default:
64578
- return change.range;
64579
- }
64580
- }
64581
64606
  class SpreadsheetPivotCorePlugin extends CorePlugin {
64582
64607
  allowDispatch(cmd) {
64583
64608
  switch (cmd.type) {
@@ -64588,27 +64613,6 @@ stores.inject(MyMetaStore, storeInstance);
64588
64613
  }
64589
64614
  return "Success" /* CommandResult.Success */;
64590
64615
  }
64591
- adaptRanges(applyChange) {
64592
- for (const pivotId of this.getters.getPivotIds()) {
64593
- const definition = this.getters.getPivotCoreDefinition(pivotId);
64594
- if (definition.type !== "SPREADSHEET") {
64595
- continue;
64596
- }
64597
- if (definition.dataSet) {
64598
- const { sheetId, zone } = definition.dataSet;
64599
- const range = this.getters.getRangeFromZone(sheetId, zone);
64600
- const adaptedRange = adaptPivotRange(range, applyChange);
64601
- if (adaptedRange === range) {
64602
- return;
64603
- }
64604
- const dataSet = adaptedRange && {
64605
- sheetId: adaptedRange.sheetId,
64606
- zone: adaptedRange.zone,
64607
- };
64608
- this.dispatch("UPDATE_PIVOT", { pivotId, pivot: { ...definition, dataSet } });
64609
- }
64610
- }
64611
- }
64612
64616
  checkDataSetValidity(definition) {
64613
64617
  if (definition.type === "SPREADSHEET" && definition.dataSet) {
64614
64618
  const { zone, sheetId } = definition.dataSet;
@@ -65950,6 +65954,9 @@ stores.inject(MyMetaStore, storeInstance);
65950
65954
  const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
65951
65955
  return Array.from(arrayFormulas).find((position) => !this.blockedArrayFormulas.has(position));
65952
65956
  }
65957
+ isArrayFormulaSpillBlocked(position) {
65958
+ return this.blockedArrayFormulas.has(position);
65959
+ }
65953
65960
  updateDependencies(position) {
65954
65961
  // removing dependencies is slow because it requires
65955
65962
  // to traverse the entire r-tree.
@@ -65961,13 +65968,8 @@ stores.inject(MyMetaStore, storeInstance);
65961
65968
  addDependencies(position, dependencies) {
65962
65969
  this.formulaDependencies().addDependencies(position, dependencies);
65963
65970
  for (const range of dependencies) {
65964
- const sheetId = range.sheetId;
65965
- const { left, bottom, right, top } = range.zone;
65966
- for (let col = left; col <= right; col++) {
65967
- for (let row = top; row <= bottom; row++) {
65968
- this.computeAndSave({ sheetId, col, row });
65969
- }
65970
- }
65971
+ // ensure that all ranges are computed
65972
+ this.compilationParams.ensureRange(range);
65971
65973
  }
65972
65974
  }
65973
65975
  updateCompilationParameters() {
@@ -66170,6 +66172,10 @@ stores.inject(MyMetaStore, storeInstance);
66170
66172
  this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
66171
66173
  const nbColumns = formulaReturn.length;
66172
66174
  const nbRows = formulaReturn[0].length;
66175
+ if (nbRows === 0) {
66176
+ // empty matrix
66177
+ return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
66178
+ }
66173
66179
  const resultZone = {
66174
66180
  top: formulaPosition.row,
66175
66181
  bottom: formulaPosition.row + nbRows - 1,
@@ -66445,6 +66451,7 @@ stores.inject(MyMetaStore, storeInstance);
66445
66451
  "getEvaluatedCellsPositions",
66446
66452
  "getSpreadZone",
66447
66453
  "getArrayFormulaSpreadingOn",
66454
+ "isArrayFormulaSpillBlocked",
66448
66455
  "isEmpty",
66449
66456
  ];
66450
66457
  shouldRebuildDependenciesGraph = true;
@@ -66557,6 +66564,9 @@ stores.inject(MyMetaStore, storeInstance);
66557
66564
  getArrayFormulaSpreadingOn(position) {
66558
66565
  return this.evaluator.getArrayFormulaSpreadingOn(position);
66559
66566
  }
66567
+ isArrayFormulaSpillBlocked(position) {
66568
+ return this.evaluator.isArrayFormulaSpillBlocked(position);
66569
+ }
66560
66570
  /**
66561
66571
  * Check if a zone only contains empty cells
66562
66572
  */
@@ -78156,10 +78166,8 @@ stores.inject(MyMetaStore, storeInstance);
78156
78166
  });
78157
78167
  }
78158
78168
  get gridContainer() {
78159
- const sheetId = this.env.model.getters.getActiveSheetId();
78160
- const { right } = this.env.model.getters.getSheetZone(sheetId);
78161
- const { end } = this.env.model.getters.getColDimensions(sheetId, right);
78162
- return cssPropertiesToCss({ "max-width": `${end}px` });
78169
+ const maxWidth = this.getMaxSheetWidth();
78170
+ return cssPropertiesToCss({ "max-width": `${maxWidth}px` });
78163
78171
  }
78164
78172
  get gridOverlayDimensions() {
78165
78173
  return cssPropertiesToCss({
@@ -78191,10 +78199,12 @@ stores.inject(MyMetaStore, storeInstance);
78191
78199
  onClosePopover() {
78192
78200
  this.cellPopovers.close();
78193
78201
  }
78194
- onGridResized({ height, width }) {
78202
+ onGridResized() {
78203
+ const { height, width } = this.props.getGridSize();
78204
+ const maxWidth = this.getMaxSheetWidth();
78195
78205
  this.env.model.dispatch("RESIZE_SHEETVIEW", {
78196
- width: width,
78197
- height: height,
78206
+ width: Math.min(maxWidth, width),
78207
+ height,
78198
78208
  gridOffsetX: 0,
78199
78209
  gridOffsetY: 0,
78200
78210
  });
@@ -78212,6 +78222,11 @@ stores.inject(MyMetaStore, storeInstance);
78212
78222
  ...this.env.model.getters.getSheetViewDimensionWithHeaders(),
78213
78223
  };
78214
78224
  }
78225
+ getMaxSheetWidth() {
78226
+ const sheetId = this.env.model.getters.getActiveSheetId();
78227
+ const { right } = this.env.model.getters.getSheetZone(sheetId);
78228
+ return this.env.model.getters.getColDimensions(sheetId, right).end;
78229
+ }
78215
78230
  }
78216
78231
 
78217
78232
  css /* scss */ `
@@ -80359,7 +80374,7 @@ stores.inject(MyMetaStore, storeInstance);
80359
80374
  document.activeElement?.contains(this.spreadsheetRef.el)) {
80360
80375
  this.focusGrid();
80361
80376
  }
80362
- }, () => [this.env.model.getters.getActiveSheetId()]);
80377
+ });
80363
80378
  owl.useExternalListener(window, "resize", () => this.render(true));
80364
80379
  // For some reason, the wheel event is not properly registered inside templates
80365
80380
  // in Chromium-based browsers based on chromium 125
@@ -80452,22 +80467,20 @@ stores.inject(MyMetaStore, storeInstance);
80452
80467
  return this.env.model.getters.getVisibleGroupLayers(sheetId, "COL");
80453
80468
  }
80454
80469
  getGridSize() {
80455
- const topBarHeight = this.spreadsheetRef.el
80456
- ?.querySelector(".o-spreadsheet-topbar-wrapper")
80457
- ?.getBoundingClientRect().height || 0;
80458
- const bottomBarHeight = this.spreadsheetRef.el
80459
- ?.querySelector(".o-spreadsheet-bottombar-wrapper")
80460
- ?.getBoundingClientRect().height || 0;
80461
- const gridWidth = this.spreadsheetRef.el?.querySelector(".o-grid")?.getBoundingClientRect().width || 0;
80462
- const gridHeight = (this.spreadsheetRef.el?.getBoundingClientRect().height || 0) -
80463
- (this.spreadsheetRef.el?.querySelector(".o-column-groups")?.getBoundingClientRect().height ||
80464
- 0) -
80465
- topBarHeight -
80466
- bottomBarHeight;
80467
- return {
80468
- width: Math.max(gridWidth - SCROLLBAR_WIDTH, 0),
80469
- height: Math.max(gridHeight - SCROLLBAR_WIDTH, 0),
80470
- };
80470
+ const el = this.spreadsheetRef.el;
80471
+ if (!el) {
80472
+ return { width: 0, height: 0 };
80473
+ }
80474
+ const getHeight = (selector) => el.querySelector(selector)?.getBoundingClientRect().height || 0;
80475
+ const getWidth = (selector) => el.querySelector(selector)?.getBoundingClientRect().width || 0;
80476
+ const rect = el.getBoundingClientRect();
80477
+ const topBarHeight = getHeight(".o-spreadsheet-topbar-wrapper");
80478
+ const bottomBarHeight = getHeight(".o-spreadsheet-bottombar-wrapper");
80479
+ const colGroupHeight = getHeight(".o-column-groups");
80480
+ const gridWidth = getWidth(".o-grid");
80481
+ const width = Math.max(gridWidth - SCROLLBAR_WIDTH, 0);
80482
+ const height = Math.max(rect.height - topBarHeight - bottomBarHeight - colGroupHeight - SCROLLBAR_WIDTH, 0);
80483
+ return { width, height };
80471
80484
  }
80472
80485
  }
80473
80486
 
@@ -85000,9 +85013,9 @@ stores.inject(MyMetaStore, storeInstance);
85000
85013
  exports.tokenize = tokenize;
85001
85014
 
85002
85015
 
85003
- __info__.version = "18.4.19";
85004
- __info__.date = "2025-12-02T05:34:03.902Z";
85005
- __info__.hash = "95b1252";
85016
+ __info__.version = "18.4.23";
85017
+ __info__.date = "2026-01-07T16:21:07.502Z";
85018
+ __info__.hash = "a0135e8";
85006
85019
 
85007
85020
 
85008
85021
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);