@odoo/o-spreadsheet 17.2.2 → 17.2.4

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.
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * This file is generated by o-spreadsheet build tools. Do not edit it.
5
5
  * @see https://github.com/odoo/o-spreadsheet
6
- * @version 17.2.2
7
- * @date 2024-04-05T14:01:19.824Z
8
- * @hash c15836d
6
+ * @version 17.2.4
7
+ * @date 2024-04-18T16:41:38.407Z
8
+ * @hash 0c66038
9
9
  */
10
10
 
11
11
  (function (exports, owl) {
@@ -561,7 +561,7 @@
561
561
  if (typeof o1 !== typeof o2)
562
562
  return false;
563
563
  if (typeof o1 !== "object")
564
- return o1 === o2;
564
+ return false;
565
565
  // Objects can have different keys if the values are undefined
566
566
  for (const key in o2) {
567
567
  if (!(key in o1) && o2[key] !== undefined) {
@@ -2508,6 +2508,15 @@
2508
2508
  }
2509
2509
  return generateMatrix(matrix.length, matrix[0].length, (col, row) => fn(matrix[col][row]));
2510
2510
  }
2511
+ function matrixForEach(matrix, fn) {
2512
+ const numberOfCols = matrix.length;
2513
+ const numberOfRows = matrix[0]?.length ?? 0;
2514
+ for (let col = 0; col < numberOfCols; col++) {
2515
+ for (let row = 0; row < numberOfRows; row++) {
2516
+ fn(matrix[col][row]);
2517
+ }
2518
+ }
2519
+ }
2511
2520
  function transposeMatrix(matrix) {
2512
2521
  if (!matrix.length) {
2513
2522
  return [];
@@ -18635,7 +18644,7 @@ stores.inject(MyMetaStore, storeInstance);
18635
18644
  }
18636
18645
  const descr = addMetaInfoFromArg(addDescr);
18637
18646
  validateArguments(descr.args);
18638
- this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr)), name);
18647
+ this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr), name), name);
18639
18648
  super.add(name, descr);
18640
18649
  return this;
18641
18650
  }
@@ -18674,9 +18683,7 @@ stores.inject(MyMetaStore, storeInstance);
18674
18683
  // so we fallback to a generic error
18675
18684
  if (hasStringValue(e) && isEvaluationError(e.value)) {
18676
18685
  if (hasStringMessage(e)) {
18677
- if (e.message?.includes("[[FUNCTION_NAME]]")) {
18678
- e.message = e.message.replace("[[FUNCTION_NAME]]", functionName);
18679
- }
18686
+ replaceFunctionNamePlaceholder(e, functionName);
18680
18687
  }
18681
18688
  return e;
18682
18689
  }
@@ -18691,21 +18698,29 @@ stores.inject(MyMetaStore, storeInstance);
18691
18698
  return (obj?.message !== undefined &&
18692
18699
  typeof obj.message === "string");
18693
18700
  }
18694
- function addResultHandling(compute) {
18695
- return function (...args) {
18701
+ function addResultHandling(compute, functionName) {
18702
+ return function computeWithResultHandling(...args) {
18696
18703
  const result = compute.apply(this, args);
18697
18704
  if (!isMatrix(result)) {
18698
18705
  if (typeof result === "object" && result !== null && "value" in result) {
18706
+ replaceFunctionNamePlaceholder(result, functionName);
18699
18707
  return result;
18700
18708
  }
18701
18709
  return { value: result };
18702
18710
  }
18703
18711
  if (typeof result[0][0] === "object" && result[0][0] !== null && "value" in result[0][0]) {
18712
+ matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, functionName));
18704
18713
  return result;
18705
18714
  }
18706
18715
  return matrixMap(result, (row) => ({ value: row }));
18707
18716
  };
18708
18717
  }
18718
+ function replaceFunctionNamePlaceholder(fPayload, functionName) {
18719
+ // for performance reasons: change in place and only if needed
18720
+ if (fPayload.message?.includes("[[FUNCTION_NAME]]")) {
18721
+ fPayload.message = fPayload.message.replace("[[FUNCTION_NAME]]", functionName);
18722
+ }
18723
+ }
18709
18724
  const functionRegistry = new FunctionRegistry();
18710
18725
  for (let category of categories) {
18711
18726
  const fns = category.functions;
@@ -19473,7 +19488,7 @@ stores.inject(MyMetaStore, storeInstance);
19473
19488
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
19474
19489
  // tooltipItem.parsed.y can be an object or a number for pie charts
19475
19490
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
19476
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
19491
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
19477
19492
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
19478
19493
  return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
19479
19494
  },
@@ -19773,7 +19788,10 @@ stores.inject(MyMetaStore, storeInstance);
19773
19788
  if (isNaN(value))
19774
19789
  return value;
19775
19790
  const { locale, format } = localeFormat;
19776
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
19791
+ return formatValue(value, {
19792
+ locale,
19793
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
19794
+ });
19777
19795
  },
19778
19796
  },
19779
19797
  },
@@ -20294,7 +20312,10 @@ stores.inject(MyMetaStore, storeInstance);
20294
20312
  if (isNaN(value))
20295
20313
  return value;
20296
20314
  const { locale, format } = localeFormat;
20297
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
20315
+ return formatValue(value, {
20316
+ locale,
20317
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
20318
+ });
20298
20319
  },
20299
20320
  },
20300
20321
  },
@@ -20634,7 +20655,7 @@ stores.inject(MyMetaStore, storeInstance);
20634
20655
  const percentage = calculatePercentage(data, dataIndex);
20635
20656
  const xLabel = tooltipItem.label || tooltipItem.dataset.label;
20636
20657
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
20637
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
20658
+ const toolTipFormat = !format && yLabel >= 1000 ? "#,##" : format;
20638
20659
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
20639
20660
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
20640
20661
  };
@@ -22886,6 +22907,7 @@ stores.inject(MyMetaStore, storeInstance);
22886
22907
  this.save();
22887
22908
  }
22888
22909
  ev.stopPropagation();
22910
+ ev.preventDefault();
22889
22911
  break;
22890
22912
  case "Escape":
22891
22913
  this.cancel();
@@ -31968,6 +31990,7 @@ stores.inject(MyMetaStore, storeInstance);
31968
31990
  onComposerCellFocused: { type: Function, optional: true },
31969
31991
  onComposerContentFocused: Function,
31970
31992
  isDefaultFocus: { type: Boolean, optional: true },
31993
+ onInputContextMenu: { type: Function, optional: true },
31971
31994
  };
31972
31995
  static components = { TextValueProvider, FunctionDescriptionProvider };
31973
31996
  static defaultProps = {
@@ -32018,6 +32041,9 @@ stores.inject(MyMetaStore, storeInstance);
32018
32041
  assistantStyle.right = `0px`;
32019
32042
  }
32020
32043
  }
32044
+ else if (this.props.delimitation) {
32045
+ assistantStyle["max-height"] = `${this.props.delimitation.height}px`;
32046
+ }
32021
32047
  return cssPropertiesToCss(assistantStyle);
32022
32048
  }
32023
32049
  // we can't allow input events to be triggered while we remove and add back the content of the composer in processContent
@@ -32304,6 +32330,11 @@ stores.inject(MyMetaStore, storeInstance);
32304
32330
  }
32305
32331
  }
32306
32332
  }
32333
+ onContextMenu(ev) {
32334
+ if (this.composerStore.editionMode === "inactive") {
32335
+ this.props.onInputContextMenu?.(ev);
32336
+ }
32337
+ }
32307
32338
  // ---------------------------------------------------------------------------
32308
32339
  // Private
32309
32340
  // ---------------------------------------------------------------------------
@@ -32525,6 +32556,7 @@ stores.inject(MyMetaStore, storeInstance);
32525
32556
  static template = "o-spreadsheet-GridComposer";
32526
32557
  static props = {
32527
32558
  gridDims: Object,
32559
+ onInputContextMenu: Function,
32528
32560
  };
32529
32561
  static components = { Composer };
32530
32562
  rect = this.defaultRect;
@@ -32572,6 +32604,7 @@ stores.inject(MyMetaStore, storeInstance);
32572
32604
  isDefaultFocus: true,
32573
32605
  onComposerContentFocused: () => this.composerFocusStore.focusGridComposerContent(),
32574
32606
  onComposerCellFocused: (content) => this.composerFocusStore.focusGridComposerCell(content),
32607
+ onInputContextMenu: this.props.onInputContextMenu,
32575
32608
  };
32576
32609
  }
32577
32610
  get containerStyle() {
@@ -33151,6 +33184,10 @@ stores.inject(MyMetaStore, storeInstance);
33151
33184
  height: 0px;
33152
33185
  }
33153
33186
  }
33187
+ .o-figure-container {
33188
+ -webkit-user-select: none; // safari
33189
+ user-select: none;
33190
+ }
33154
33191
  `;
33155
33192
  /**
33156
33193
  * Each figure ⭐ is positioned inside a container `div` placed and sized
@@ -37294,29 +37331,12 @@ stores.inject(MyMetaStore, storeInstance);
37294
37331
  return width;
37295
37332
  return Math.round((width / WIDTH_FACTOR) * 100) / 100;
37296
37333
  }
37297
- function convertBorderDescr(descr) {
37298
- if (!descr) {
37299
- return undefined;
37300
- }
37301
- return {
37302
- style: descr.style,
37303
- color: { rgb: descr.color },
37304
- };
37305
- }
37306
37334
  function extractStyle(cell, data) {
37307
37335
  let style = {};
37308
37336
  if (cell.style) {
37309
37337
  style = data.styles[cell.style];
37310
37338
  }
37311
37339
  const format = extractFormat(cell, data);
37312
- const exportedBorder = {};
37313
- if (cell.border) {
37314
- const border = data.borders[cell.border];
37315
- exportedBorder.left = convertBorderDescr(border.left);
37316
- exportedBorder.right = convertBorderDescr(border.right);
37317
- exportedBorder.bottom = convertBorderDescr(border.bottom);
37318
- exportedBorder.top = convertBorderDescr(border.top);
37319
- }
37320
37340
  const styles = {
37321
37341
  font: {
37322
37342
  size: style?.fontSize || DEFAULT_FONT_SIZE,
@@ -37330,7 +37350,7 @@ stores.inject(MyMetaStore, storeInstance);
37330
37350
  }
37331
37351
  : { reservedAttribute: "none" },
37332
37352
  numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
37333
- border: exportedBorder || {},
37353
+ border: cell.border || 0,
37334
37354
  alignment: {
37335
37355
  horizontal: style.align,
37336
37356
  vertical: style.verticalAlign
@@ -37352,15 +37372,12 @@ stores.inject(MyMetaStore, storeInstance);
37352
37372
  return undefined;
37353
37373
  }
37354
37374
  function normalizeStyle(construct, styles) {
37355
- const { id: fontId } = pushElement(styles["font"], construct.fonts);
37356
- const { id: fillId } = pushElement(styles["fill"], construct.fills);
37357
- const { id: borderId } = pushElement(styles["border"], construct.borders);
37358
37375
  // Normalize this
37359
37376
  const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
37360
37377
  const style = {
37361
- fontId,
37362
- fillId,
37363
- borderId,
37378
+ fontId: pushElement(styles.font, construct.fonts),
37379
+ fillId: pushElement(styles.fill, construct.fills),
37380
+ borderId: styles.border,
37364
37381
  numFmtId,
37365
37382
  alignment: {
37366
37383
  vertical: styles.alignment.vertical,
@@ -37368,8 +37385,7 @@ stores.inject(MyMetaStore, storeInstance);
37368
37385
  wrapText: styles.alignment.wrapText,
37369
37386
  },
37370
37387
  };
37371
- const { id } = pushElement(style, construct.styles);
37372
- return id;
37388
+ return pushElement(style, construct.styles);
37373
37389
  }
37374
37390
  function convertFormat(format, numFmtStructure) {
37375
37391
  if (!format) {
@@ -37377,8 +37393,7 @@ stores.inject(MyMetaStore, storeInstance);
37377
37393
  }
37378
37394
  let formatId = XLSX_FORMAT_MAP[format.format];
37379
37395
  if (!formatId) {
37380
- const { id } = pushElement(format, numFmtStructure);
37381
- formatId = id + FIRST_NUMFMT_ID;
37396
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
37382
37397
  }
37383
37398
  return formatId;
37384
37399
  }
@@ -37403,20 +37418,15 @@ stores.inject(MyMetaStore, storeInstance);
37403
37418
  return id;
37404
37419
  }
37405
37420
  function pushElement(property, propertyList) {
37406
- for (let [key, value] of Object.entries(propertyList)) {
37407
- if (JSON.stringify(value) === JSON.stringify(property)) {
37408
- return { id: parseInt(key, 10), list: propertyList };
37421
+ let len = propertyList.length;
37422
+ const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
37423
+ for (let i = 0; i < len; i++) {
37424
+ if (operator(property, propertyList[i])) {
37425
+ return i;
37409
37426
  }
37410
37427
  }
37411
- let elemId = propertyList.findIndex((elem) => JSON.stringify(elem) === JSON.stringify(property));
37412
- if (elemId === -1) {
37413
- propertyList.push(property);
37414
- elemId = propertyList.length - 1;
37415
- }
37416
- return {
37417
- id: elemId,
37418
- list: propertyList,
37419
- };
37428
+ propertyList[propertyList.length] = property;
37429
+ return propertyList.length - 1;
37420
37430
  }
37421
37431
  const chartIds = [];
37422
37432
  /**
@@ -38211,7 +38221,25 @@ stores.inject(MyMetaStore, storeInstance);
38211
38221
  }
38212
38222
  return document;
38213
38223
  }
38214
- function getDefaultXLSXStructure() {
38224
+ function convertBorderDescr(descr) {
38225
+ if (!descr) {
38226
+ return undefined;
38227
+ }
38228
+ return {
38229
+ style: descr.style,
38230
+ color: { rgb: descr.color },
38231
+ };
38232
+ }
38233
+ function getDefaultXLSXStructure(data) {
38234
+ const xlsxBorders = Object.values(data.borders).map((border) => {
38235
+ return {
38236
+ left: convertBorderDescr(border.left),
38237
+ right: convertBorderDescr(border.right),
38238
+ bottom: convertBorderDescr(border.bottom),
38239
+ top: convertBorderDescr(border.top),
38240
+ };
38241
+ });
38242
+ const borders = [{}, ...xlsxBorders];
38215
38243
  return {
38216
38244
  relsFiles: [],
38217
38245
  sharedStrings: [],
@@ -38234,7 +38262,7 @@ stores.inject(MyMetaStore, storeInstance);
38234
38262
  },
38235
38263
  ],
38236
38264
  fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
38237
- borders: [{}],
38265
+ borders,
38238
38266
  numFmts: [],
38239
38267
  dxfs: [],
38240
38268
  };
@@ -45271,7 +45299,15 @@ stores.inject(MyMetaStore, storeInstance);
45271
45299
  }
45272
45300
  }
45273
45301
  exportForExcel(data) {
45274
- this.export(data);
45302
+ for (const sheet of data.sheets) {
45303
+ for (const table of this.getTables(sheet.id)) {
45304
+ if (zoneToDimension(table.range.zone).numberOfRows === 1) {
45305
+ continue;
45306
+ }
45307
+ const tableData = { range: zoneToXc(table.range.zone), filters: [] };
45308
+ sheet.tables.push(tableData);
45309
+ }
45310
+ }
45275
45311
  }
45276
45312
  }
45277
45313
 
@@ -47043,7 +47079,9 @@ stores.inject(MyMetaStore, storeInstance);
47043
47079
  this.blockedArrayFormulas = this.createEmptyPositionSet();
47044
47080
  this.spreadingRelations = new SpreadingRelation(this.createEmptyPositionSet.bind(this));
47045
47081
  this.formulaDependencies = lazy(() => {
47046
- const dependencies = [...this.getAllCells()].flatMap((position) => this.getDirectDependencies(position).map((range) => ({
47082
+ const dependencies = [...this.getAllCells()].flatMap((position) => this.getDirectDependencies(position)
47083
+ .filter((range) => !range.invalidSheetName && !range.invalidXc)
47084
+ .map((range) => ({
47047
47085
  data: position,
47048
47086
  boundingBox: {
47049
47087
  zone: range.zone,
@@ -52073,7 +52111,7 @@ stores.inject(MyMetaStore, storeInstance);
52073
52111
  "isFilterActive",
52074
52112
  ];
52075
52113
  filterValues = {};
52076
- hiddenRows = new Set();
52114
+ hiddenRows = {};
52077
52115
  isEvaluationDirty = false;
52078
52116
  allowDispatch(cmd) {
52079
52117
  switch (cmd.type) {
@@ -52117,11 +52155,11 @@ stores.inject(MyMetaStore, storeInstance);
52117
52155
  case "UNFOLD_HEADER_GROUP":
52118
52156
  case "FOLD_ALL_HEADER_GROUPS":
52119
52157
  case "UNFOLD_ALL_HEADER_GROUPS":
52120
- this.updateHiddenRows();
52158
+ this.updateHiddenRows(cmd.sheetId);
52121
52159
  break;
52122
52160
  case "UPDATE_FILTER":
52123
52161
  this.updateFilter(cmd);
52124
- this.updateHiddenRows();
52162
+ this.updateHiddenRows(cmd.sheetId);
52125
52163
  break;
52126
52164
  case "DUPLICATE_SHEET":
52127
52165
  const filterValues = {};
@@ -52141,15 +52179,14 @@ stores.inject(MyMetaStore, storeInstance);
52141
52179
  }
52142
52180
  finalize() {
52143
52181
  if (this.isEvaluationDirty) {
52144
- this.updateHiddenRows();
52182
+ for (const sheetId of this.getters.getSheetIds()) {
52183
+ this.updateHiddenRows(sheetId);
52184
+ }
52145
52185
  this.isEvaluationDirty = false;
52146
52186
  }
52147
52187
  }
52148
52188
  isRowFiltered(sheetId, row) {
52149
- if (sheetId !== this.getters.getActiveSheetId()) {
52150
- return false;
52151
- }
52152
- return this.hiddenRows.has(row);
52189
+ return !!this.hiddenRows[sheetId]?.has(row);
52153
52190
  }
52154
52191
  getFilterHiddenValues(position) {
52155
52192
  const id = this.getters.getFilterId(position);
@@ -52176,8 +52213,7 @@ stores.inject(MyMetaStore, storeInstance);
52176
52213
  this.filterValues[sheetId] = {};
52177
52214
  this.filterValues[sheetId][id] = hiddenValues;
52178
52215
  }
52179
- updateHiddenRows() {
52180
- const sheetId = this.getters.getActiveSheetId();
52216
+ updateHiddenRows(sheetId) {
52181
52217
  const filters = this.getters
52182
52218
  .getFilters(sheetId)
52183
52219
  .sort((filter1, filter2) => filter1.rangeWithHeaders.zone.top - filter2.rangeWithHeaders.zone.top);
@@ -52199,7 +52235,7 @@ stores.inject(MyMetaStore, storeInstance);
52199
52235
  }
52200
52236
  }
52201
52237
  }
52202
- this.hiddenRows = hiddenRows;
52238
+ this.hiddenRows[sheetId] = hiddenRows;
52203
52239
  }
52204
52240
  getCellValueAsString(sheetId, col, row) {
52205
52241
  const value = this.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue;
@@ -53318,13 +53354,14 @@ stores.inject(MyMetaStore, storeInstance);
53318
53354
  }
53319
53355
  }
53320
53356
  handleEvent(event) {
53357
+ const sheetId = this.getters.getActiveSheetId();
53321
53358
  if (event.options.scrollIntoView) {
53322
53359
  let { col, row } = findCellInNewZone(event.previousAnchor.zone, event.anchor.zone);
53323
53360
  if (event.mode === "updateAnchor") {
53324
53361
  const oldZone = event.previousAnchor.zone;
53325
53362
  const newZone = event.anchor.zone;
53326
53363
  // altering a zone should not move the viewport in a dimension that wasn't changed
53327
- const { top, bottom, left, right } = this.getters.getActiveMainViewport();
53364
+ const { top, bottom, left, right } = this.getMainInternalViewport(sheetId);
53328
53365
  if (oldZone.left === newZone.left && oldZone.right === newZone.right) {
53329
53366
  col = left > col || col > right ? left : col;
53330
53367
  }
@@ -53332,7 +53369,6 @@ stores.inject(MyMetaStore, storeInstance);
53332
53369
  row = top > row || row > bottom ? top : row;
53333
53370
  }
53334
53371
  }
53335
- const sheetId = this.getters.getActiveSheetId();
53336
53372
  col = Math.min(col, this.getters.getNumberCols(sheetId) - 1);
53337
53373
  row = Math.min(row, this.getters.getNumberRows(sheetId) - 1);
53338
53374
  if (!this.sheetsWithDirtyViewports.has(sheetId)) {
@@ -53369,16 +53405,16 @@ stores.inject(MyMetaStore, storeInstance);
53369
53405
  this.setSheetViewOffset(cmd.offsetX, cmd.offsetY);
53370
53406
  break;
53371
53407
  case "SHIFT_VIEWPORT_DOWN":
53372
- const { top } = this.getActiveMainViewport();
53373
53408
  const sheetId = this.getters.getActiveSheetId();
53374
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).start + this.sheetViewHeight);
53375
- this.shiftVertically(shiftedOffsetY);
53409
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
53410
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
53411
+ this.shiftVertically(topRowDims.start + viewportHeight - offsetCorrectionY);
53376
53412
  break;
53377
53413
  case "SHIFT_VIEWPORT_UP": {
53378
- const { top } = this.getActiveMainViewport();
53379
53414
  const sheetId = this.getters.getActiveSheetId();
53380
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).end - this.sheetViewHeight);
53381
- this.shiftVertically(shiftedOffsetY);
53415
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
53416
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
53417
+ this.shiftVertically(topRowDims.end - offsetCorrectionY - viewportHeight);
53382
53418
  break;
53383
53419
  }
53384
53420
  case "REMOVE_TABLE":
@@ -53801,17 +53837,6 @@ stores.inject(MyMetaStore, storeInstance);
53801
53837
  const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
53802
53838
  Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
53803
53839
  }
53804
- /**
53805
- * Clip the vertical offset within the allowed range.
53806
- * Not above the sheet, nor below the sheet.
53807
- */
53808
- clipOffsetY(offsetY) {
53809
- const { height } = this.getMainViewportRect();
53810
- const maxOffset = height - this.sheetViewHeight;
53811
- offsetY = Math.min(offsetY, maxOffset);
53812
- offsetY = Math.max(offsetY, 0);
53813
- return offsetY;
53814
- }
53815
53840
  getViewportOffset(sheetId) {
53816
53841
  return {
53817
53842
  x: this.viewports[sheetId]?.bottomRight.offsetScrollbarX || 0,
@@ -53867,12 +53892,15 @@ stores.inject(MyMetaStore, storeInstance);
53867
53892
  * viewport top.
53868
53893
  */
53869
53894
  shiftVertically(offset) {
53870
- const { top } = this.getActiveMainViewport();
53895
+ const sheetId = this.getters.getActiveSheetId();
53896
+ const { top } = this.getMainInternalViewport(sheetId);
53871
53897
  const { scrollX } = this.getActiveSheetScrollInfo();
53872
53898
  this.setSheetViewOffset(scrollX, offset);
53873
53899
  const { anchor } = this.getters.getSelection();
53874
- const deltaRow = this.getActiveMainViewport().top - top;
53875
- this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
53900
+ if (anchor.cell.row >= this.getters.getPaneDivisions(sheetId).ySplit) {
53901
+ const deltaRow = this.getMainInternalViewport(sheetId).top - top;
53902
+ this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
53903
+ }
53876
53904
  }
53877
53905
  getVisibleFigures() {
53878
53906
  const sheetId = this.getters.getActiveSheetId();
@@ -54791,7 +54819,6 @@ stores.inject(MyMetaStore, storeInstance);
54791
54819
  cursor: pointer;
54792
54820
  }
54793
54821
  `;
54794
- let tKey = 1;
54795
54822
  class SpreadsheetDashboard extends owl.Component {
54796
54823
  static template = "o-spreadsheet-SpreadsheetDashboard";
54797
54824
  static props = {};
@@ -54870,13 +54897,9 @@ stores.inject(MyMetaStore, storeInstance);
54870
54897
  coordinates: rect,
54871
54898
  position: { col, row },
54872
54899
  action,
54873
- // we can't rely on position only because a row or a column could
54874
- // be inserted at any time.
54875
- tKey: `${tKey}-${col}-${row}`,
54876
54900
  });
54877
54901
  }
54878
54902
  }
54879
- tKey++;
54880
54903
  return cells;
54881
54904
  }
54882
54905
  getClickableAction(position) {
@@ -55688,6 +55711,13 @@ stores.inject(MyMetaStore, storeInstance);
55688
55711
  "border-color": SELECTION_BORDER_COLOR,
55689
55712
  });
55690
55713
  }
55714
+ get delimitation() {
55715
+ const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
55716
+ return {
55717
+ width,
55718
+ height,
55719
+ };
55720
+ }
55691
55721
  onFocus(selection) {
55692
55722
  this.composerFocusStore.focusTopBarComposer(selection);
55693
55723
  }
@@ -58319,8 +58349,7 @@ stores.inject(MyMetaStore, storeInstance);
58319
58349
  attrs.push(["t", "b"]);
58320
58350
  }
58321
58351
  else if (forceString || !isNumber(value, DEFAULT_LOCALE)) {
58322
- const { id } = pushElement(content, sharedStrings);
58323
- value = id.toString();
58352
+ value = pushElement(content, sharedStrings);
58324
58353
  attrs.push(["t", "s"]);
58325
58354
  }
58326
58355
  return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
@@ -58445,8 +58474,7 @@ stores.inject(MyMetaStore, storeInstance);
58445
58474
  if (rule.style.fillColor) {
58446
58475
  dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
58447
58476
  }
58448
- const { id } = pushElement(dxf, dxfs);
58449
- ruleAttributes.push(["dxfId", id]);
58477
+ ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
58450
58478
  return escapeXml /*xml*/ `
58451
58479
  <conditionalFormatting sqref="${cf.ranges.join(" ")}">
58452
58480
  <cfRule ${formatAttributes(ruleAttributes)}>
@@ -59276,7 +59304,7 @@ stores.inject(MyMetaStore, storeInstance);
59276
59304
  */
59277
59305
  function getXLSX(data) {
59278
59306
  const files = [];
59279
- const construct = getDefaultXLSXStructure();
59307
+ const construct = getDefaultXLSXStructure(data);
59280
59308
  files.push(createWorkbook(data, construct));
59281
59309
  files.push(...createWorksheets(data, construct));
59282
59310
  files.push(createStylesSheet(construct));
@@ -60211,9 +60239,9 @@ stores.inject(MyMetaStore, storeInstance);
60211
60239
  exports.tokenize = tokenize;
60212
60240
 
60213
60241
 
60214
- __info__.version = "17.2.2";
60215
- __info__.date = "2024-04-05T14:01:19.824Z";
60216
- __info__.hash = "c15836d";
60242
+ __info__.version = "17.2.4";
60243
+ __info__.date = "2024-04-18T16:41:38.407Z";
60244
+ __info__.hash = "0c66038";
60217
60245
 
60218
60246
 
60219
60247
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);