@odoo/o-spreadsheet 17.1.5 → 17.1.7

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 17.1.5
6
- * @date 2024-02-16T14:23:54.651Z
7
- * @hash 29d8ad6
5
+ * @version 17.1.7
6
+ * @date 2024-03-12T07:56:10.783Z
7
+ * @hash 3a9f334
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -6099,8 +6099,10 @@
6099
6099
  if (x === cell) {
6100
6100
  found = true;
6101
6101
  }
6102
- const cellValue = evaluateLiteral(x?.content, { locale: DEFAULT_LOCALE });
6103
- if (filter(cellValue)) {
6102
+ const cellValue = x?.isFormula
6103
+ ? undefined
6104
+ : evaluateLiteral(x?.content, { locale: DEFAULT_LOCALE });
6105
+ if (cellValue && filter(cellValue)) {
6104
6106
  group.push(cellValue);
6105
6107
  }
6106
6108
  else {
@@ -6324,11 +6326,14 @@
6324
6326
  * Transform CSS properties into a CSS string.
6325
6327
  */
6326
6328
  function cssPropertiesToCss(attributes) {
6327
- const str = Object.entries(attributes)
6328
- .filter(([attName, attValue]) => attValue !== undefined)
6329
- .map(([attName, attValue]) => `${attName}:${attValue};`)
6330
- .join(" ");
6331
- return str;
6329
+ let styleStr = "";
6330
+ for (const attName in attributes) {
6331
+ if (!attributes[attName]) {
6332
+ continue;
6333
+ }
6334
+ styleStr += `${attName}:${attributes[attName]}; `;
6335
+ }
6336
+ return styleStr;
6332
6337
  }
6333
6338
  function getElementMargins(el) {
6334
6339
  const style = window.getComputedStyle(el);
@@ -13052,6 +13057,18 @@
13052
13057
  },
13053
13058
  isExported: true,
13054
13059
  };
13060
+ // -----------------------------------------------------------------------------
13061
+ // INT
13062
+ // -----------------------------------------------------------------------------
13063
+ const INT = {
13064
+ description: _t("Rounds a number down to the nearest integer that is less than or equal to it."),
13065
+ args: [arg("value (number)", _t("The number to round down to the nearest integer."))],
13066
+ returns: ["NUMBER"],
13067
+ compute: function (value) {
13068
+ return Math.floor(toNumber(value, this.locale));
13069
+ },
13070
+ isExported: true,
13071
+ };
13055
13072
 
13056
13073
  var math = /*#__PURE__*/Object.freeze({
13057
13074
  __proto__: null,
@@ -13085,6 +13102,7 @@
13085
13102
  FLOOR: FLOOR,
13086
13103
  FLOOR_MATH: FLOOR_MATH,
13087
13104
  FLOOR_PRECISE: FLOOR_PRECISE,
13105
+ INT: INT,
13088
13106
  ISEVEN: ISEVEN,
13089
13107
  ISODD: ISODD,
13090
13108
  ISO_CEILING: ISO_CEILING,
@@ -18611,10 +18629,11 @@
18611
18629
  const DEFAULT_MATCH_MODE = 0;
18612
18630
  const DEFAULT_SEARCH_MODE = 1;
18613
18631
  const DEFAULT_ABSOLUTE_RELATIVE_MODE = 1;
18614
- function assertAvailable(variable, searchKey) {
18615
- if (variable === undefined) {
18616
- throw new NotAvailableError(_t("Did not find value '%s' in [[FUNCTION_NAME]] evaluation.", toString(searchKey)));
18617
- }
18632
+ function valueNotAvailable(searchKey) {
18633
+ return {
18634
+ value: CellErrorType.NotAvailable,
18635
+ message: _t("Did not find value '%s' in [[FUNCTION_NAME]] evaluation.", toString(searchKey)),
18636
+ };
18618
18637
  }
18619
18638
  // -----------------------------------------------------------------------------
18620
18639
  // ADDRESS
@@ -18711,7 +18730,9 @@
18711
18730
  ? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range.length, getValueFromRange)
18712
18731
  : linearSearch(range, searchKey, "strict", range.length, getValueFromRange);
18713
18732
  const col = range[colIndex];
18714
- assertAvailable(col, searchKey?.value);
18733
+ if (col === undefined) {
18734
+ return valueNotAvailable(searchKey);
18735
+ }
18715
18736
  return col[_index - 1];
18716
18737
  },
18717
18738
  isExported: true,
@@ -18768,11 +18789,11 @@
18768
18789
  : (range, index) => range[index][0].value;
18769
18790
  const rangeLength = verticalSearch ? nbRow : nbCol;
18770
18791
  const index = dichotomicSearch(searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
18771
- if (index === -1)
18772
- assertAvailable(undefined, searchKey?.value);
18773
- verticalSearch
18774
- ? assertAvailable(searchArray[0][index], searchKey?.value)
18775
- : assertAvailable(searchArray[index][nbRow - 1], searchKey?.value);
18792
+ if (index === -1 ||
18793
+ (verticalSearch && searchArray[0][index] === undefined) ||
18794
+ (!verticalSearch && searchArray[index][nbRow - 1] === undefined)) {
18795
+ return valueNotAvailable(searchKey);
18796
+ }
18776
18797
  if (resultRange === undefined) {
18777
18798
  return verticalSearch ? searchArray[nbCol - 1][index] : searchArray[index][nbRow - 1];
18778
18799
  }
@@ -18822,7 +18843,10 @@
18822
18843
  index = dichotomicSearch(range, searchKey, "nextGreater", "desc", rangeLen, getElement);
18823
18844
  break;
18824
18845
  }
18825
- assertAvailable(nbCol === 1 ? range[0][index] : range[index], searchKey);
18846
+ if ((nbCol === 1 && range[0][index] === undefined) ||
18847
+ (nbCol !== 1 && range[index] === undefined)) {
18848
+ return valueNotAvailable(searchKey);
18849
+ }
18826
18850
  return index + 1;
18827
18851
  },
18828
18852
  isExported: true,
@@ -18881,7 +18905,9 @@
18881
18905
  ? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range[0].length, getValueFromRange)
18882
18906
  : linearSearch(range, searchKey, "strict", range[0].length, getValueFromRange);
18883
18907
  const value = range[_index - 1][rowIndex];
18884
- assertAvailable(value, searchKey);
18908
+ if (value === undefined) {
18909
+ return valueNotAvailable(searchKey);
18910
+ }
18885
18911
  return value;
18886
18912
  },
18887
18913
  isExported: true,
@@ -18931,7 +18957,9 @@
18931
18957
  ? returnRange.map((col) => [col[index]])
18932
18958
  : [returnRange[index]];
18933
18959
  }
18934
- assertAvailable(defaultValue, searchKey);
18960
+ if (defaultValue === undefined) {
18961
+ return valueNotAvailable(searchKey);
18962
+ }
18935
18963
  return [[defaultValue]];
18936
18964
  },
18937
18965
  isExported: true,
@@ -19703,8 +19731,7 @@
19703
19731
  function addErrorHandling(compute, functionName) {
19704
19732
  return function (...args) {
19705
19733
  try {
19706
- const computeFormula = compute.bind(this);
19707
- return computeFormula(...args);
19734
+ return compute.apply(this, args);
19708
19735
  }
19709
19736
  catch (e) {
19710
19737
  return handleError(e, functionName);
@@ -19738,8 +19765,7 @@
19738
19765
  }
19739
19766
  function addResultHandling(compute) {
19740
19767
  return function (...args) {
19741
- const computeResult = compute.bind(this);
19742
- const result = computeResult(...args);
19768
+ const result = compute.apply(this, args);
19743
19769
  if (!isMatrix(result)) {
19744
19770
  if (typeof result === "object" && result !== null && "value" in result) {
19745
19771
  return result;
@@ -21706,7 +21732,7 @@
21706
21732
  ? existingSelectionRanges
21707
21733
  : this.props.ranges().map((xc, id) => ({
21708
21734
  xc,
21709
- id,
21735
+ id: id + 1,
21710
21736
  isFocused: false,
21711
21737
  }));
21712
21738
  return ranges.map((range) => ({
@@ -27746,7 +27772,11 @@
27746
27772
  }
27747
27773
  }
27748
27774
  updateCellReferenceVisibility() {
27749
- if (this.isCellReferenceVisible || this.env.model.getters.getEditionMode() === "inactive") {
27775
+ if (this.env.model.getters.getEditionMode() === "inactive") {
27776
+ this.isCellReferenceVisible = false;
27777
+ return;
27778
+ }
27779
+ if (this.isCellReferenceVisible) {
27750
27780
  return;
27751
27781
  }
27752
27782
  const sheetId = this.env.model.getters.getActiveSheetId();
@@ -27775,19 +27805,21 @@
27775
27805
  slots: Object,
27776
27806
  };
27777
27807
  get iconStyle() {
27778
- const x = this.getIconHorizontalPosition();
27779
- const y = this.getIconVerticalPosition();
27808
+ const cellPosition = this.props.cellPosition;
27809
+ const merge = this.env.model.getters.getMerge(cellPosition);
27810
+ const zone = merge || positionToZone(cellPosition);
27811
+ const rect = this.env.model.getters.getVisibleRectWithoutHeaders(zone);
27812
+ const x = this.getIconHorizontalPosition(rect, cellPosition);
27813
+ const y = this.getIconVerticalPosition(rect, cellPosition);
27780
27814
  return cssPropertiesToCss({
27781
27815
  top: `${y + (this.props.offset?.y || 0)}px`,
27782
27816
  left: `${x + (this.props.offset?.x || 0)}px`,
27783
27817
  });
27784
27818
  }
27785
- getIconVerticalPosition() {
27786
- const { sheetId, row } = this.props.cellPosition;
27787
- const merge = this.env.model.getters.getMerge(this.props.cellPosition);
27788
- const start = this.env.model.getters.getRowDimensionsInViewport(sheetId, row).start;
27789
- const end = this.env.model.getters.getRowDimensionsInViewport(sheetId, merge ? merge.bottom : row).end;
27790
- const cell = this.env.model.getters.getCell(this.props.cellPosition);
27819
+ getIconVerticalPosition(rect, cellPosition) {
27820
+ const start = rect.y;
27821
+ const end = rect.y + rect.height;
27822
+ const cell = this.env.model.getters.getCell(cellPosition);
27791
27823
  const align = this.props.verticalAlign || cell?.style?.verticalAlign || DEFAULT_VERTICAL_ALIGN;
27792
27824
  switch (align) {
27793
27825
  case "bottom":
@@ -27799,13 +27831,11 @@
27799
27831
  return end - GRID_ICON_EDGE_LENGTH - centeringOffset;
27800
27832
  }
27801
27833
  }
27802
- getIconHorizontalPosition() {
27803
- const { sheetId, col } = this.props.cellPosition;
27804
- const merge = this.env.model.getters.getMerge(this.props.cellPosition);
27805
- const start = this.env.model.getters.getColDimensionsInViewport(sheetId, col).start;
27806
- const end = this.env.model.getters.getColDimensionsInViewport(sheetId, merge ? merge.right : col).end;
27807
- const cell = this.env.model.getters.getCell(this.props.cellPosition);
27808
- const evaluatedCell = this.env.model.getters.getEvaluatedCell(this.props.cellPosition);
27834
+ getIconHorizontalPosition(rect, cellPosition) {
27835
+ const start = rect.x;
27836
+ const end = rect.x + rect.width;
27837
+ const cell = this.env.model.getters.getCell(cellPosition);
27838
+ const evaluatedCell = this.env.model.getters.getEvaluatedCell(cellPosition);
27809
27839
  const align = this.props.horizontalAlign || cell?.style?.align || evaluatedCell.defaultAlign;
27810
27840
  switch (align) {
27811
27841
  case "right":
@@ -27889,6 +27919,8 @@
27889
27919
  height: ${CHECKBOX_WIDTH}px;
27890
27920
  accent-color: #808080;
27891
27921
  margin: ${MARGIN}px;
27922
+ /** required to prevent the checkbox position to be sensible to the font-size (affects Firefox) */
27923
+ position: absolute;
27892
27924
  }
27893
27925
  `;
27894
27926
  class DataValidationCheckbox extends owl.Component {
@@ -27907,7 +27939,7 @@
27907
27939
  }
27908
27940
  get isDisabled() {
27909
27941
  const cell = this.env.model.getters.getCell(this.props.cellPosition);
27910
- return !!cell?.isFormula;
27942
+ return this.env.model.getters.isReadonly() || !!cell?.isFormula;
27911
27943
  }
27912
27944
  }
27913
27945
 
@@ -27947,12 +27979,17 @@
27947
27979
  static props = {};
27948
27980
  static components = { GridCellIcon, DataValidationCheckbox, DataValidationListIcon };
27949
27981
  get checkBoxCellPositions() {
27950
- return this.env.model.getters.getDataValidationCheckBoxCellPositions();
27982
+ return this.env.model.getters
27983
+ .getVisibleCellPositions()
27984
+ .filter(this.env.model.getters.isCellValidCheckbox);
27951
27985
  }
27952
27986
  get listIconsCellPositions() {
27953
- return this.env.model.getters.isReadonly()
27954
- ? []
27955
- : this.env.model.getters.getDataValidationListCellsPositions();
27987
+ if (this.env.model.getters.isReadonly()) {
27988
+ return [];
27989
+ }
27990
+ return this.env.model.getters
27991
+ .getVisibleCellPositions()
27992
+ .filter(this.env.model.getters.cellHasListDataValidationIcon);
27956
27993
  }
27957
27994
  }
27958
27995
 
@@ -34314,29 +34351,12 @@
34314
34351
  from: 12,
34315
34352
  to: 12.5,
34316
34353
  applyMigration(data) {
34317
- for (let sheet of data.sheets || []) {
34318
- let knownDataFilterZones = [];
34319
- for (let filterTable of sheet.filterTables || []) {
34320
- const zone = toZone(filterTable.range);
34321
- // See commit message for the details
34322
- const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
34323
- if (intersectZoneIndex !== -1) {
34324
- knownDataFilterZones[intersectZoneIndex] = zone;
34325
- }
34326
- else {
34327
- knownDataFilterZones.push(zone);
34328
- }
34329
- }
34330
- sheet.filterTables = knownDataFilterZones.map((zone) => ({
34331
- range: zoneToXc(zone),
34332
- }));
34333
- }
34334
- return data;
34354
+ return fixOverlappingFilters(data);
34335
34355
  },
34336
34356
  },
34337
34357
  {
34338
34358
  description: "Change Border description structure",
34339
- from: 12,
34359
+ from: 12.5,
34340
34360
  to: 13,
34341
34361
  applyMigration(data) {
34342
34362
  for (const borderId in data.borders) {
@@ -34367,6 +34387,14 @@
34367
34387
  return data;
34368
34388
  },
34369
34389
  },
34390
+ {
34391
+ description: "Fix datafilter duplication (post saas-16.4)",
34392
+ from: 14,
34393
+ to: 14.5,
34394
+ applyMigration(data) {
34395
+ return fixOverlappingFilters(data);
34396
+ },
34397
+ },
34370
34398
  ];
34371
34399
  /**
34372
34400
  * This function is used to repair faulty data independently of the migration.
@@ -34524,6 +34552,26 @@
34524
34552
  }
34525
34553
  return messages;
34526
34554
  }
34555
+ function fixOverlappingFilters(data) {
34556
+ for (let sheet of data.sheets || []) {
34557
+ let knownDataFilterZones = [];
34558
+ for (let filterTable of sheet.filterTables || []) {
34559
+ const zone = toZone(filterTable.range);
34560
+ // See commit message of https://github.com/odoo/o-spreadsheet/pull/3632 of more details
34561
+ const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
34562
+ if (intersectZoneIndex !== -1) {
34563
+ knownDataFilterZones[intersectZoneIndex] = zone;
34564
+ }
34565
+ else {
34566
+ knownDataFilterZones.push(zone);
34567
+ }
34568
+ }
34569
+ sheet.filterTables = knownDataFilterZones.map((zone) => ({
34570
+ range: zoneToXc(zone),
34571
+ }));
34572
+ }
34573
+ return data;
34574
+ }
34527
34575
  // -----------------------------------------------------------------------------
34528
34576
  // Helpers
34529
34577
  // -----------------------------------------------------------------------------
@@ -39045,7 +39093,6 @@
39045
39093
  "getNumberHeaders",
39046
39094
  "getGridLinesVisibility",
39047
39095
  "getNextSheetName",
39048
- "isEmpty",
39049
39096
  "getSheetSize",
39050
39097
  "getSheetZone",
39051
39098
  "getPaneDivisions",
@@ -39420,14 +39467,6 @@
39420
39467
  // ---------------------------------------------------------------------------
39421
39468
  // Row/Col manipulation
39422
39469
  // ---------------------------------------------------------------------------
39423
- /**
39424
- * Check if a zone only contains empty cells
39425
- */
39426
- isEmpty(sheetId, zone) {
39427
- return positions(zone)
39428
- .map(({ col, row }) => this.getCell({ sheetId, col, row }))
39429
- .every((cell) => !cell || cell.content === "");
39430
- }
39431
39470
  getCommandZones(cmd) {
39432
39471
  const zones = [];
39433
39472
  if ("zone" in cmd) {
@@ -41542,7 +41581,7 @@
41542
41581
  : evaluateLiteral(cell.content, localeFormat);
41543
41582
  }
41544
41583
  catch (e) {
41545
- return createEvaluatedCell(e.value, localeFormat, e.message);
41584
+ return createEvaluatedCell(e?.value || CellErrorType.GenericError, localeFormat, e?.message || implementationErrorMessage);
41546
41585
  }
41547
41586
  finally {
41548
41587
  this.cellsBeingComputed.delete(cellId);
@@ -41876,6 +41915,7 @@
41876
41915
  "getEvaluatedCellsInZone",
41877
41916
  "getSpreadPositionsOf",
41878
41917
  "getArrayFormulaSpreadingOn",
41918
+ "isEmpty",
41879
41919
  ];
41880
41920
  shouldRebuildDependenciesGraph = true;
41881
41921
  evaluator;
@@ -41981,6 +42021,14 @@
41981
42021
  getArrayFormulaSpreadingOn(position) {
41982
42022
  return this.evaluator.getArrayFormulaSpreadingOn(position);
41983
42023
  }
42024
+ /**
42025
+ * Check if a zone only contains empty cells
42026
+ */
42027
+ isEmpty(sheetId, zone) {
42028
+ return positions(zone)
42029
+ .map(({ col, row }) => this.getEvaluatedCell({ sheetId, col, row }))
42030
+ .every((cell) => cell.type === CellValueType.empty);
42031
+ }
41984
42032
  // ---------------------------------------------------------------------------
41985
42033
  // Export
41986
42034
  // ---------------------------------------------------------------------------
@@ -42628,8 +42676,6 @@
42628
42676
  class EvaluationDataValidationPlugin extends UIPlugin {
42629
42677
  static getters = [
42630
42678
  "getDataValidationInvalidCriterionValueMessage",
42631
- "getDataValidationCheckBoxCellPositions",
42632
- "getDataValidationListCellsPositions",
42633
42679
  "getInvalidDataValidationMessage",
42634
42680
  "getValidationResultForCellValue",
42635
42681
  "isCellValidCheckbox",
@@ -42693,19 +42739,6 @@
42693
42739
  const error = this.getRuleErrorForCellValue(cellValue, cellPosition, rule);
42694
42740
  return error ? { error, rule, isValid: false } : VALID_RESULT;
42695
42741
  }
42696
- getDataValidationCheckBoxCellPositions() {
42697
- const rules = this.getters
42698
- .getDataValidationRules(this.getters.getActiveSheetId())
42699
- .filter((rule) => rule.criterion.type === "isBoolean");
42700
- return getCellPositionsInRanges(rules.map((rule) => rule.ranges).flat()).filter((position) => this.isCellValidCheckbox(position));
42701
- }
42702
- getDataValidationListCellsPositions() {
42703
- const rules = this.getters
42704
- .getDataValidationRules(this.getters.getActiveSheetId())
42705
- .filter((rule) => (rule.criterion.type === "isValueInList" || rule.criterion.type === "isValueInRange") &&
42706
- rule.criterion.displayStyle === "arrow");
42707
- return getCellPositionsInRanges(rules.map((rule) => rule.ranges).flat());
42708
- }
42709
42742
  getValidationResultForCell(cellPosition) {
42710
42743
  const { col, row, sheetId } = cellPosition;
42711
42744
  if (!this.validationResults[sheetId]) {
@@ -45674,6 +45707,8 @@
45674
45707
  sheetIdFrom: this.getters.getActiveSheetId(),
45675
45708
  sheetIdTo: selectedMatch.sheetId,
45676
45709
  });
45710
+ // We do not want to reset the selection at finalize in this case
45711
+ this.isSearchDirty = false;
45677
45712
  }
45678
45713
  // we want grid selection to capture the selection stream
45679
45714
  this.selection.getBackToDefault();
@@ -46975,19 +47010,17 @@
46975
47010
  break;
46976
47011
  case "FOCUS_RANGE":
46977
47012
  case "CHANGE_RANGE":
46978
- if (cmd.id !== this.focusedInputId) {
46979
- const input = this.inputs[cmd.id];
46980
- const range = input.ranges.find((range) => range.id === cmd.rangeId);
46981
- if (this.isRangeValid(range?.xc || "A1")) {
46982
- const sheetId = this.getters.getActiveSheetId();
46983
- const zone = this.getters.getRangeFromSheetXC(sheetId, range?.xc || "A1").zone;
46984
- this.selection.capture(input, { cell: { col: zone.left, row: zone.top }, zone }, {
46985
- handleEvent: input.handleEvent.bind(input),
46986
- release: () => (this.focusedInputId = null),
46987
- });
46988
- }
46989
- this.focusedInputId = cmd.id;
47013
+ const input = this.inputs[cmd.id];
47014
+ const range = input.ranges.find((range) => range.id === cmd.rangeId);
47015
+ if (range) {
47016
+ const sheetId = this.getters.getActiveSheetId();
47017
+ const zone = this.getters.getRangeFromSheetXC(sheetId, range?.xc || "A1").zone;
47018
+ this.selection.capture(input, { cell: { col: zone.left, row: zone.top }, zone }, {
47019
+ handleEvent: input.handleEvent.bind(input),
47020
+ release: () => (this.focusedInputId = null),
47021
+ });
46990
47022
  }
47023
+ this.focusedInputId = cmd.id;
46991
47024
  break;
46992
47025
  }
46993
47026
  this.currentInput?.handle(cmd);
@@ -50406,6 +50439,8 @@
50406
50439
  "getEdgeScrollRow",
50407
50440
  "getVisibleFigures",
50408
50441
  "getVisibleRect",
50442
+ "getVisibleRectWithoutHeaders",
50443
+ "getVisibleCellPositions",
50409
50444
  "getColRowOffsetInViewport",
50410
50445
  "getMainViewportCoordinates",
50411
50446
  "getActiveSheetScrollInfo",
@@ -50649,6 +50684,26 @@
50649
50684
  const viewports = this.getSubViewports(sheetId);
50650
50685
  return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
50651
50686
  }
50687
+ /**
50688
+ * Get the positions of all the cells that are visible in the viewport, taking merges into account.
50689
+ */
50690
+ getVisibleCellPositions() {
50691
+ const visibleCols = this.getSheetViewVisibleCols();
50692
+ const visibleRows = this.getSheetViewVisibleRows();
50693
+ const sheetId = this.getters.getActiveSheetId();
50694
+ const positions = [];
50695
+ for (const col of visibleCols) {
50696
+ for (const row of visibleRows) {
50697
+ const position = { sheetId, col, row };
50698
+ const mainPosition = this.getters.getMainCellPosition(position);
50699
+ if (mainPosition.row !== row || mainPosition.col !== col) {
50700
+ continue;
50701
+ }
50702
+ positions.push(position);
50703
+ }
50704
+ }
50705
+ return positions;
50706
+ }
50652
50707
  /**
50653
50708
  * Return the main viewport maximum size relative to the client size.
50654
50709
  */
@@ -50768,6 +50823,13 @@
50768
50823
  * Computes the coordinates and size to draw the zone on the canvas
50769
50824
  */
50770
50825
  getVisibleRect(zone) {
50826
+ const rect = this.getVisibleRectWithoutHeaders(zone);
50827
+ return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
50828
+ }
50829
+ /**
50830
+ * Computes the coordinates and size to draw the zone without taking the grid offset into account
50831
+ */
50832
+ getVisibleRectWithoutHeaders(zone) {
50771
50833
  const sheetId = this.getters.getActiveSheetId();
50772
50834
  const viewportRects = this.getSubViewports(sheetId)
50773
50835
  .map((viewport) => viewport.getRect(zone))
@@ -50779,12 +50841,7 @@
50779
50841
  const y = Math.min(...viewportRects.map((rect) => rect.y));
50780
50842
  const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
50781
50843
  const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
50782
- return {
50783
- x: x + this.gridOffsetX,
50784
- y: y + this.gridOffsetY,
50785
- width,
50786
- height,
50787
- };
50844
+ return { x, y, width, height };
50788
50845
  }
50789
50846
  /**
50790
50847
  * Returns the position of the MainViewport relatively to the start of the grid (without headers)
@@ -51008,13 +51065,8 @@
51008
51065
  }
51009
51066
  break;
51010
51067
  case "UPDATE_CELL":
51011
- if ("content" in cmd || "format" in cmd) {
51012
- this.headerPositions = {};
51013
- this.isDirty = true;
51014
- }
51015
- else {
51016
- this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
51017
- }
51068
+ this.headerPositions = {};
51069
+ this.isDirty = true;
51018
51070
  break;
51019
51071
  case "UPDATE_FILTER":
51020
51072
  case "REMOVE_FILTER_TABLE":
@@ -57223,9 +57275,9 @@
57223
57275
  exports.tokenize = tokenize;
57224
57276
 
57225
57277
 
57226
- __info__.version = "17.1.5";
57227
- __info__.date = "2024-02-16T14:23:54.651Z";
57228
- __info__.hash = "29d8ad6";
57278
+ __info__.version = "17.1.7";
57279
+ __info__.date = "2024-03-12T07:56:10.783Z";
57280
+ __info__.hash = "3a9f334";
57229
57281
 
57230
57282
 
57231
57283
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);