@odoo/o-spreadsheet 17.2.3 → 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.3
7
- * @date 2024-04-10T12:28:36.552Z
8
- * @hash ab5e22d
6
+ * @version 17.2.4
7
+ * @date 2024-04-18T16:41:38.407Z
8
+ * @hash 0c66038
9
9
  */
10
10
 
11
11
  'use strict';
@@ -2509,6 +2509,15 @@ function matrixMap(matrix, fn) {
2509
2509
  }
2510
2510
  return generateMatrix(matrix.length, matrix[0].length, (col, row) => fn(matrix[col][row]));
2511
2511
  }
2512
+ function matrixForEach(matrix, fn) {
2513
+ const numberOfCols = matrix.length;
2514
+ const numberOfRows = matrix[0]?.length ?? 0;
2515
+ for (let col = 0; col < numberOfCols; col++) {
2516
+ for (let row = 0; row < numberOfRows; row++) {
2517
+ fn(matrix[col][row]);
2518
+ }
2519
+ }
2520
+ }
2512
2521
  function transposeMatrix(matrix) {
2513
2522
  if (!matrix.length) {
2514
2523
  return [];
@@ -18636,7 +18645,7 @@ class FunctionRegistry extends Registry {
18636
18645
  }
18637
18646
  const descr = addMetaInfoFromArg(addDescr);
18638
18647
  validateArguments(descr.args);
18639
- this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr)), name);
18648
+ this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr), name), name);
18640
18649
  super.add(name, descr);
18641
18650
  return this;
18642
18651
  }
@@ -18675,9 +18684,7 @@ function handleError(e, functionName) {
18675
18684
  // so we fallback to a generic error
18676
18685
  if (hasStringValue(e) && isEvaluationError(e.value)) {
18677
18686
  if (hasStringMessage(e)) {
18678
- if (e.message?.includes("[[FUNCTION_NAME]]")) {
18679
- e.message = e.message.replace("[[FUNCTION_NAME]]", functionName);
18680
- }
18687
+ replaceFunctionNamePlaceholder(e, functionName);
18681
18688
  }
18682
18689
  return e;
18683
18690
  }
@@ -18692,21 +18699,29 @@ function hasStringMessage(obj) {
18692
18699
  return (obj?.message !== undefined &&
18693
18700
  typeof obj.message === "string");
18694
18701
  }
18695
- function addResultHandling(compute) {
18696
- return function (...args) {
18702
+ function addResultHandling(compute, functionName) {
18703
+ return function computeWithResultHandling(...args) {
18697
18704
  const result = compute.apply(this, args);
18698
18705
  if (!isMatrix(result)) {
18699
18706
  if (typeof result === "object" && result !== null && "value" in result) {
18707
+ replaceFunctionNamePlaceholder(result, functionName);
18700
18708
  return result;
18701
18709
  }
18702
18710
  return { value: result };
18703
18711
  }
18704
18712
  if (typeof result[0][0] === "object" && result[0][0] !== null && "value" in result[0][0]) {
18713
+ matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, functionName));
18705
18714
  return result;
18706
18715
  }
18707
18716
  return matrixMap(result, (row) => ({ value: row }));
18708
18717
  };
18709
18718
  }
18719
+ function replaceFunctionNamePlaceholder(fPayload, functionName) {
18720
+ // for performance reasons: change in place and only if needed
18721
+ if (fPayload.message?.includes("[[FUNCTION_NAME]]")) {
18722
+ fPayload.message = fPayload.message.replace("[[FUNCTION_NAME]]", functionName);
18723
+ }
18724
+ }
18710
18725
  const functionRegistry = new FunctionRegistry();
18711
18726
  for (let category of categories) {
18712
18727
  const fns = category.functions;
@@ -19474,7 +19489,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale })
19474
19489
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
19475
19490
  // tooltipItem.parsed.y can be an object or a number for pie charts
19476
19491
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
19477
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
19492
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
19478
19493
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
19479
19494
  return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
19480
19495
  },
@@ -19774,7 +19789,10 @@ function getBarConfiguration(chart, labels, localeFormat) {
19774
19789
  if (isNaN(value))
19775
19790
  return value;
19776
19791
  const { locale, format } = localeFormat;
19777
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
19792
+ return formatValue(value, {
19793
+ locale,
19794
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
19795
+ });
19778
19796
  },
19779
19797
  },
19780
19798
  },
@@ -20295,7 +20313,10 @@ function getLineOrScatterConfiguration(chart, labels, localeFormat) {
20295
20313
  if (isNaN(value))
20296
20314
  return value;
20297
20315
  const { locale, format } = localeFormat;
20298
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
20316
+ return formatValue(value, {
20317
+ locale,
20318
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
20319
+ });
20299
20320
  },
20300
20321
  },
20301
20322
  },
@@ -20635,7 +20656,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
20635
20656
  const percentage = calculatePercentage(data, dataIndex);
20636
20657
  const xLabel = tooltipItem.label || tooltipItem.dataset.label;
20637
20658
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
20638
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
20659
+ const toolTipFormat = !format && yLabel >= 1000 ? "#,##" : format;
20639
20660
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
20640
20661
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
20641
20662
  };
@@ -22887,6 +22908,7 @@ class LinkEditor extends owl.Component {
22887
22908
  this.save();
22888
22909
  }
22889
22910
  ev.stopPropagation();
22911
+ ev.preventDefault();
22890
22912
  break;
22891
22913
  case "Escape":
22892
22914
  this.cancel();
@@ -33163,6 +33185,10 @@ css /*SCSS*/ `
33163
33185
  height: 0px;
33164
33186
  }
33165
33187
  }
33188
+ .o-figure-container {
33189
+ -webkit-user-select: none; // safari
33190
+ user-select: none;
33191
+ }
33166
33192
  `;
33167
33193
  /**
33168
33194
  * Each figure ⭐ is positioned inside a container `div` placed and sized
@@ -52086,7 +52112,7 @@ class FilterEvaluationPlugin extends UIPlugin {
52086
52112
  "isFilterActive",
52087
52113
  ];
52088
52114
  filterValues = {};
52089
- hiddenRows = new Set();
52115
+ hiddenRows = {};
52090
52116
  isEvaluationDirty = false;
52091
52117
  allowDispatch(cmd) {
52092
52118
  switch (cmd.type) {
@@ -52130,11 +52156,11 @@ class FilterEvaluationPlugin extends UIPlugin {
52130
52156
  case "UNFOLD_HEADER_GROUP":
52131
52157
  case "FOLD_ALL_HEADER_GROUPS":
52132
52158
  case "UNFOLD_ALL_HEADER_GROUPS":
52133
- this.updateHiddenRows();
52159
+ this.updateHiddenRows(cmd.sheetId);
52134
52160
  break;
52135
52161
  case "UPDATE_FILTER":
52136
52162
  this.updateFilter(cmd);
52137
- this.updateHiddenRows();
52163
+ this.updateHiddenRows(cmd.sheetId);
52138
52164
  break;
52139
52165
  case "DUPLICATE_SHEET":
52140
52166
  const filterValues = {};
@@ -52154,15 +52180,14 @@ class FilterEvaluationPlugin extends UIPlugin {
52154
52180
  }
52155
52181
  finalize() {
52156
52182
  if (this.isEvaluationDirty) {
52157
- this.updateHiddenRows();
52183
+ for (const sheetId of this.getters.getSheetIds()) {
52184
+ this.updateHiddenRows(sheetId);
52185
+ }
52158
52186
  this.isEvaluationDirty = false;
52159
52187
  }
52160
52188
  }
52161
52189
  isRowFiltered(sheetId, row) {
52162
- if (sheetId !== this.getters.getActiveSheetId()) {
52163
- return false;
52164
- }
52165
- return this.hiddenRows.has(row);
52190
+ return !!this.hiddenRows[sheetId]?.has(row);
52166
52191
  }
52167
52192
  getFilterHiddenValues(position) {
52168
52193
  const id = this.getters.getFilterId(position);
@@ -52189,8 +52214,7 @@ class FilterEvaluationPlugin extends UIPlugin {
52189
52214
  this.filterValues[sheetId] = {};
52190
52215
  this.filterValues[sheetId][id] = hiddenValues;
52191
52216
  }
52192
- updateHiddenRows() {
52193
- const sheetId = this.getters.getActiveSheetId();
52217
+ updateHiddenRows(sheetId) {
52194
52218
  const filters = this.getters
52195
52219
  .getFilters(sheetId)
52196
52220
  .sort((filter1, filter2) => filter1.rangeWithHeaders.zone.top - filter2.rangeWithHeaders.zone.top);
@@ -52212,7 +52236,7 @@ class FilterEvaluationPlugin extends UIPlugin {
52212
52236
  }
52213
52237
  }
52214
52238
  }
52215
- this.hiddenRows = hiddenRows;
52239
+ this.hiddenRows[sheetId] = hiddenRows;
52216
52240
  }
52217
52241
  getCellValueAsString(sheetId, col, row) {
52218
52242
  const value = this.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue;
@@ -53331,13 +53355,14 @@ class SheetViewPlugin extends UIPlugin {
53331
53355
  }
53332
53356
  }
53333
53357
  handleEvent(event) {
53358
+ const sheetId = this.getters.getActiveSheetId();
53334
53359
  if (event.options.scrollIntoView) {
53335
53360
  let { col, row } = findCellInNewZone(event.previousAnchor.zone, event.anchor.zone);
53336
53361
  if (event.mode === "updateAnchor") {
53337
53362
  const oldZone = event.previousAnchor.zone;
53338
53363
  const newZone = event.anchor.zone;
53339
53364
  // altering a zone should not move the viewport in a dimension that wasn't changed
53340
- const { top, bottom, left, right } = this.getters.getActiveMainViewport();
53365
+ const { top, bottom, left, right } = this.getMainInternalViewport(sheetId);
53341
53366
  if (oldZone.left === newZone.left && oldZone.right === newZone.right) {
53342
53367
  col = left > col || col > right ? left : col;
53343
53368
  }
@@ -53345,7 +53370,6 @@ class SheetViewPlugin extends UIPlugin {
53345
53370
  row = top > row || row > bottom ? top : row;
53346
53371
  }
53347
53372
  }
53348
- const sheetId = this.getters.getActiveSheetId();
53349
53373
  col = Math.min(col, this.getters.getNumberCols(sheetId) - 1);
53350
53374
  row = Math.min(row, this.getters.getNumberRows(sheetId) - 1);
53351
53375
  if (!this.sheetsWithDirtyViewports.has(sheetId)) {
@@ -53382,16 +53406,16 @@ class SheetViewPlugin extends UIPlugin {
53382
53406
  this.setSheetViewOffset(cmd.offsetX, cmd.offsetY);
53383
53407
  break;
53384
53408
  case "SHIFT_VIEWPORT_DOWN":
53385
- const { top } = this.getActiveMainViewport();
53386
53409
  const sheetId = this.getters.getActiveSheetId();
53387
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).start + this.sheetViewHeight);
53388
- this.shiftVertically(shiftedOffsetY);
53410
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
53411
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
53412
+ this.shiftVertically(topRowDims.start + viewportHeight - offsetCorrectionY);
53389
53413
  break;
53390
53414
  case "SHIFT_VIEWPORT_UP": {
53391
- const { top } = this.getActiveMainViewport();
53392
53415
  const sheetId = this.getters.getActiveSheetId();
53393
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).end - this.sheetViewHeight);
53394
- this.shiftVertically(shiftedOffsetY);
53416
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
53417
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
53418
+ this.shiftVertically(topRowDims.end - offsetCorrectionY - viewportHeight);
53395
53419
  break;
53396
53420
  }
53397
53421
  case "REMOVE_TABLE":
@@ -53814,17 +53838,6 @@ class SheetViewPlugin extends UIPlugin {
53814
53838
  const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
53815
53839
  Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
53816
53840
  }
53817
- /**
53818
- * Clip the vertical offset within the allowed range.
53819
- * Not above the sheet, nor below the sheet.
53820
- */
53821
- clipOffsetY(offsetY) {
53822
- const { height } = this.getMainViewportRect();
53823
- const maxOffset = height - this.sheetViewHeight;
53824
- offsetY = Math.min(offsetY, maxOffset);
53825
- offsetY = Math.max(offsetY, 0);
53826
- return offsetY;
53827
- }
53828
53841
  getViewportOffset(sheetId) {
53829
53842
  return {
53830
53843
  x: this.viewports[sheetId]?.bottomRight.offsetScrollbarX || 0,
@@ -53880,12 +53893,15 @@ class SheetViewPlugin extends UIPlugin {
53880
53893
  * viewport top.
53881
53894
  */
53882
53895
  shiftVertically(offset) {
53883
- const { top } = this.getActiveMainViewport();
53896
+ const sheetId = this.getters.getActiveSheetId();
53897
+ const { top } = this.getMainInternalViewport(sheetId);
53884
53898
  const { scrollX } = this.getActiveSheetScrollInfo();
53885
53899
  this.setSheetViewOffset(scrollX, offset);
53886
53900
  const { anchor } = this.getters.getSelection();
53887
- const deltaRow = this.getActiveMainViewport().top - top;
53888
- this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
53901
+ if (anchor.cell.row >= this.getters.getPaneDivisions(sheetId).ySplit) {
53902
+ const deltaRow = this.getMainInternalViewport(sheetId).top - top;
53903
+ this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
53904
+ }
53889
53905
  }
53890
53906
  getVisibleFigures() {
53891
53907
  const sheetId = this.getters.getActiveSheetId();
@@ -54804,7 +54820,6 @@ css /* scss */ `
54804
54820
  cursor: pointer;
54805
54821
  }
54806
54822
  `;
54807
- let tKey = 1;
54808
54823
  class SpreadsheetDashboard extends owl.Component {
54809
54824
  static template = "o-spreadsheet-SpreadsheetDashboard";
54810
54825
  static props = {};
@@ -54883,13 +54898,9 @@ class SpreadsheetDashboard extends owl.Component {
54883
54898
  coordinates: rect,
54884
54899
  position: { col, row },
54885
54900
  action,
54886
- // we can't rely on position only because a row or a column could
54887
- // be inserted at any time.
54888
- tKey: `${tKey}-${col}-${row}`,
54889
54901
  });
54890
54902
  }
54891
54903
  }
54892
- tKey++;
54893
54904
  return cells;
54894
54905
  }
54895
54906
  getClickableAction(position) {
@@ -60229,6 +60240,6 @@ exports.tokenColors = tokenColors;
60229
60240
  exports.tokenize = tokenize;
60230
60241
 
60231
60242
 
60232
- __info__.version = "17.2.3";
60233
- __info__.date = "2024-04-10T12:28:36.552Z";
60234
- __info__.hash = "ab5e22d";
60243
+ __info__.version = "17.2.4";
60244
+ __info__.date = "2024-04-18T16:41:38.407Z";
60245
+ __info__.hash = "0c66038";
@@ -4151,7 +4151,7 @@ declare class ClipboardPlugin extends UIPlugin {
4151
4151
  declare class FilterEvaluationPlugin extends UIPlugin {
4152
4152
  static getters: readonly ["getFilterHiddenValues", "getFirstTableInSelection", "isRowFiltered", "isFilterActive"];
4153
4153
  private filterValues;
4154
- hiddenRows: Set<number>;
4154
+ hiddenRows: Record<UID, Set<number> | undefined>;
4155
4155
  isEvaluationDirty: boolean;
4156
4156
  allowDispatch(cmd: LocalCommand): CommandResult;
4157
4157
  handle(cmd: Command): void;
@@ -4288,8 +4288,8 @@ declare class InternalViewport {
4288
4288
  canScrollHorizontally: boolean;
4289
4289
  viewportWidth: Pixel;
4290
4290
  viewportHeight: Pixel;
4291
- private offsetCorrectionX;
4292
- private offsetCorrectionY;
4291
+ offsetCorrectionX: Pixel;
4292
+ offsetCorrectionY: Pixel;
4293
4293
  constructor(getters: Getters, sheetId: UID, boundaries: Zone, sizeInGrid: DOMDimension, options: {
4294
4294
  canScrollVertically: boolean;
4295
4295
  canScrollHorizontally: boolean;
@@ -4494,11 +4494,6 @@ declare class SheetViewPlugin extends UIPlugin {
4494
4494
  private resizeSheetView;
4495
4495
  private recomputeViewports;
4496
4496
  private setSheetViewOffset;
4497
- /**
4498
- * Clip the vertical offset within the allowed range.
4499
- * Not above the sheet, nor below the sheet.
4500
- */
4501
- private clipOffsetY;
4502
4497
  private getViewportOffset;
4503
4498
  private resetViewports;
4504
4499
  /**
@@ -8316,7 +8311,6 @@ interface ClickableCell {
8316
8311
  coordinates: Rect;
8317
8312
  position: Position$1;
8318
8313
  action: (position: CellPosition, env: SpreadsheetChildEnv) => void;
8319
- tKey: string;
8320
8314
  }
8321
8315
  declare class SpreadsheetDashboard extends Component<Props$8, SpreadsheetChildEnv> {
8322
8316
  static template: string;
@@ -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.3
7
- * @date 2024-04-10T12:28:36.552Z
8
- * @hash ab5e22d
6
+ * @version 17.2.4
7
+ * @date 2024-04-18T16:41:38.407Z
8
+ * @hash 0c66038
9
9
  */
10
10
 
11
11
  import { reactive, useEnv, useSubEnv, useState, onWillUnmount, markRaw, toRaw, Component, useRef, onMounted, useEffect, onPatched, useComponent, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv } from '@odoo/owl';
@@ -2507,6 +2507,15 @@ function matrixMap(matrix, fn) {
2507
2507
  }
2508
2508
  return generateMatrix(matrix.length, matrix[0].length, (col, row) => fn(matrix[col][row]));
2509
2509
  }
2510
+ function matrixForEach(matrix, fn) {
2511
+ const numberOfCols = matrix.length;
2512
+ const numberOfRows = matrix[0]?.length ?? 0;
2513
+ for (let col = 0; col < numberOfCols; col++) {
2514
+ for (let row = 0; row < numberOfRows; row++) {
2515
+ fn(matrix[col][row]);
2516
+ }
2517
+ }
2518
+ }
2510
2519
  function transposeMatrix(matrix) {
2511
2520
  if (!matrix.length) {
2512
2521
  return [];
@@ -18634,7 +18643,7 @@ class FunctionRegistry extends Registry {
18634
18643
  }
18635
18644
  const descr = addMetaInfoFromArg(addDescr);
18636
18645
  validateArguments(descr.args);
18637
- this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr)), name);
18646
+ this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr), name), name);
18638
18647
  super.add(name, descr);
18639
18648
  return this;
18640
18649
  }
@@ -18673,9 +18682,7 @@ function handleError(e, functionName) {
18673
18682
  // so we fallback to a generic error
18674
18683
  if (hasStringValue(e) && isEvaluationError(e.value)) {
18675
18684
  if (hasStringMessage(e)) {
18676
- if (e.message?.includes("[[FUNCTION_NAME]]")) {
18677
- e.message = e.message.replace("[[FUNCTION_NAME]]", functionName);
18678
- }
18685
+ replaceFunctionNamePlaceholder(e, functionName);
18679
18686
  }
18680
18687
  return e;
18681
18688
  }
@@ -18690,21 +18697,29 @@ function hasStringMessage(obj) {
18690
18697
  return (obj?.message !== undefined &&
18691
18698
  typeof obj.message === "string");
18692
18699
  }
18693
- function addResultHandling(compute) {
18694
- return function (...args) {
18700
+ function addResultHandling(compute, functionName) {
18701
+ return function computeWithResultHandling(...args) {
18695
18702
  const result = compute.apply(this, args);
18696
18703
  if (!isMatrix(result)) {
18697
18704
  if (typeof result === "object" && result !== null && "value" in result) {
18705
+ replaceFunctionNamePlaceholder(result, functionName);
18698
18706
  return result;
18699
18707
  }
18700
18708
  return { value: result };
18701
18709
  }
18702
18710
  if (typeof result[0][0] === "object" && result[0][0] !== null && "value" in result[0][0]) {
18711
+ matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, functionName));
18703
18712
  return result;
18704
18713
  }
18705
18714
  return matrixMap(result, (row) => ({ value: row }));
18706
18715
  };
18707
18716
  }
18717
+ function replaceFunctionNamePlaceholder(fPayload, functionName) {
18718
+ // for performance reasons: change in place and only if needed
18719
+ if (fPayload.message?.includes("[[FUNCTION_NAME]]")) {
18720
+ fPayload.message = fPayload.message.replace("[[FUNCTION_NAME]]", functionName);
18721
+ }
18722
+ }
18708
18723
  const functionRegistry = new FunctionRegistry();
18709
18724
  for (let category of categories) {
18710
18725
  const fns = category.functions;
@@ -19472,7 +19487,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale })
19472
19487
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
19473
19488
  // tooltipItem.parsed.y can be an object or a number for pie charts
19474
19489
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
19475
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
19490
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
19476
19491
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
19477
19492
  return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
19478
19493
  },
@@ -19772,7 +19787,10 @@ function getBarConfiguration(chart, labels, localeFormat) {
19772
19787
  if (isNaN(value))
19773
19788
  return value;
19774
19789
  const { locale, format } = localeFormat;
19775
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
19790
+ return formatValue(value, {
19791
+ locale,
19792
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
19793
+ });
19776
19794
  },
19777
19795
  },
19778
19796
  },
@@ -20293,7 +20311,10 @@ function getLineOrScatterConfiguration(chart, labels, localeFormat) {
20293
20311
  if (isNaN(value))
20294
20312
  return value;
20295
20313
  const { locale, format } = localeFormat;
20296
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
20314
+ return formatValue(value, {
20315
+ locale,
20316
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
20317
+ });
20297
20318
  },
20298
20319
  },
20299
20320
  },
@@ -20633,7 +20654,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
20633
20654
  const percentage = calculatePercentage(data, dataIndex);
20634
20655
  const xLabel = tooltipItem.label || tooltipItem.dataset.label;
20635
20656
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
20636
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
20657
+ const toolTipFormat = !format && yLabel >= 1000 ? "#,##" : format;
20637
20658
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
20638
20659
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
20639
20660
  };
@@ -22885,6 +22906,7 @@ class LinkEditor extends Component {
22885
22906
  this.save();
22886
22907
  }
22887
22908
  ev.stopPropagation();
22909
+ ev.preventDefault();
22888
22910
  break;
22889
22911
  case "Escape":
22890
22912
  this.cancel();
@@ -33161,6 +33183,10 @@ css /*SCSS*/ `
33161
33183
  height: 0px;
33162
33184
  }
33163
33185
  }
33186
+ .o-figure-container {
33187
+ -webkit-user-select: none; // safari
33188
+ user-select: none;
33189
+ }
33164
33190
  `;
33165
33191
  /**
33166
33192
  * Each figure ⭐ is positioned inside a container `div` placed and sized
@@ -52084,7 +52110,7 @@ class FilterEvaluationPlugin extends UIPlugin {
52084
52110
  "isFilterActive",
52085
52111
  ];
52086
52112
  filterValues = {};
52087
- hiddenRows = new Set();
52113
+ hiddenRows = {};
52088
52114
  isEvaluationDirty = false;
52089
52115
  allowDispatch(cmd) {
52090
52116
  switch (cmd.type) {
@@ -52128,11 +52154,11 @@ class FilterEvaluationPlugin extends UIPlugin {
52128
52154
  case "UNFOLD_HEADER_GROUP":
52129
52155
  case "FOLD_ALL_HEADER_GROUPS":
52130
52156
  case "UNFOLD_ALL_HEADER_GROUPS":
52131
- this.updateHiddenRows();
52157
+ this.updateHiddenRows(cmd.sheetId);
52132
52158
  break;
52133
52159
  case "UPDATE_FILTER":
52134
52160
  this.updateFilter(cmd);
52135
- this.updateHiddenRows();
52161
+ this.updateHiddenRows(cmd.sheetId);
52136
52162
  break;
52137
52163
  case "DUPLICATE_SHEET":
52138
52164
  const filterValues = {};
@@ -52152,15 +52178,14 @@ class FilterEvaluationPlugin extends UIPlugin {
52152
52178
  }
52153
52179
  finalize() {
52154
52180
  if (this.isEvaluationDirty) {
52155
- this.updateHiddenRows();
52181
+ for (const sheetId of this.getters.getSheetIds()) {
52182
+ this.updateHiddenRows(sheetId);
52183
+ }
52156
52184
  this.isEvaluationDirty = false;
52157
52185
  }
52158
52186
  }
52159
52187
  isRowFiltered(sheetId, row) {
52160
- if (sheetId !== this.getters.getActiveSheetId()) {
52161
- return false;
52162
- }
52163
- return this.hiddenRows.has(row);
52188
+ return !!this.hiddenRows[sheetId]?.has(row);
52164
52189
  }
52165
52190
  getFilterHiddenValues(position) {
52166
52191
  const id = this.getters.getFilterId(position);
@@ -52187,8 +52212,7 @@ class FilterEvaluationPlugin extends UIPlugin {
52187
52212
  this.filterValues[sheetId] = {};
52188
52213
  this.filterValues[sheetId][id] = hiddenValues;
52189
52214
  }
52190
- updateHiddenRows() {
52191
- const sheetId = this.getters.getActiveSheetId();
52215
+ updateHiddenRows(sheetId) {
52192
52216
  const filters = this.getters
52193
52217
  .getFilters(sheetId)
52194
52218
  .sort((filter1, filter2) => filter1.rangeWithHeaders.zone.top - filter2.rangeWithHeaders.zone.top);
@@ -52210,7 +52234,7 @@ class FilterEvaluationPlugin extends UIPlugin {
52210
52234
  }
52211
52235
  }
52212
52236
  }
52213
- this.hiddenRows = hiddenRows;
52237
+ this.hiddenRows[sheetId] = hiddenRows;
52214
52238
  }
52215
52239
  getCellValueAsString(sheetId, col, row) {
52216
52240
  const value = this.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue;
@@ -53329,13 +53353,14 @@ class SheetViewPlugin extends UIPlugin {
53329
53353
  }
53330
53354
  }
53331
53355
  handleEvent(event) {
53356
+ const sheetId = this.getters.getActiveSheetId();
53332
53357
  if (event.options.scrollIntoView) {
53333
53358
  let { col, row } = findCellInNewZone(event.previousAnchor.zone, event.anchor.zone);
53334
53359
  if (event.mode === "updateAnchor") {
53335
53360
  const oldZone = event.previousAnchor.zone;
53336
53361
  const newZone = event.anchor.zone;
53337
53362
  // altering a zone should not move the viewport in a dimension that wasn't changed
53338
- const { top, bottom, left, right } = this.getters.getActiveMainViewport();
53363
+ const { top, bottom, left, right } = this.getMainInternalViewport(sheetId);
53339
53364
  if (oldZone.left === newZone.left && oldZone.right === newZone.right) {
53340
53365
  col = left > col || col > right ? left : col;
53341
53366
  }
@@ -53343,7 +53368,6 @@ class SheetViewPlugin extends UIPlugin {
53343
53368
  row = top > row || row > bottom ? top : row;
53344
53369
  }
53345
53370
  }
53346
- const sheetId = this.getters.getActiveSheetId();
53347
53371
  col = Math.min(col, this.getters.getNumberCols(sheetId) - 1);
53348
53372
  row = Math.min(row, this.getters.getNumberRows(sheetId) - 1);
53349
53373
  if (!this.sheetsWithDirtyViewports.has(sheetId)) {
@@ -53380,16 +53404,16 @@ class SheetViewPlugin extends UIPlugin {
53380
53404
  this.setSheetViewOffset(cmd.offsetX, cmd.offsetY);
53381
53405
  break;
53382
53406
  case "SHIFT_VIEWPORT_DOWN":
53383
- const { top } = this.getActiveMainViewport();
53384
53407
  const sheetId = this.getters.getActiveSheetId();
53385
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).start + this.sheetViewHeight);
53386
- this.shiftVertically(shiftedOffsetY);
53408
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
53409
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
53410
+ this.shiftVertically(topRowDims.start + viewportHeight - offsetCorrectionY);
53387
53411
  break;
53388
53412
  case "SHIFT_VIEWPORT_UP": {
53389
- const { top } = this.getActiveMainViewport();
53390
53413
  const sheetId = this.getters.getActiveSheetId();
53391
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).end - this.sheetViewHeight);
53392
- this.shiftVertically(shiftedOffsetY);
53414
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
53415
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
53416
+ this.shiftVertically(topRowDims.end - offsetCorrectionY - viewportHeight);
53393
53417
  break;
53394
53418
  }
53395
53419
  case "REMOVE_TABLE":
@@ -53812,17 +53836,6 @@ class SheetViewPlugin extends UIPlugin {
53812
53836
  const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
53813
53837
  Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
53814
53838
  }
53815
- /**
53816
- * Clip the vertical offset within the allowed range.
53817
- * Not above the sheet, nor below the sheet.
53818
- */
53819
- clipOffsetY(offsetY) {
53820
- const { height } = this.getMainViewportRect();
53821
- const maxOffset = height - this.sheetViewHeight;
53822
- offsetY = Math.min(offsetY, maxOffset);
53823
- offsetY = Math.max(offsetY, 0);
53824
- return offsetY;
53825
- }
53826
53839
  getViewportOffset(sheetId) {
53827
53840
  return {
53828
53841
  x: this.viewports[sheetId]?.bottomRight.offsetScrollbarX || 0,
@@ -53878,12 +53891,15 @@ class SheetViewPlugin extends UIPlugin {
53878
53891
  * viewport top.
53879
53892
  */
53880
53893
  shiftVertically(offset) {
53881
- const { top } = this.getActiveMainViewport();
53894
+ const sheetId = this.getters.getActiveSheetId();
53895
+ const { top } = this.getMainInternalViewport(sheetId);
53882
53896
  const { scrollX } = this.getActiveSheetScrollInfo();
53883
53897
  this.setSheetViewOffset(scrollX, offset);
53884
53898
  const { anchor } = this.getters.getSelection();
53885
- const deltaRow = this.getActiveMainViewport().top - top;
53886
- this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
53899
+ if (anchor.cell.row >= this.getters.getPaneDivisions(sheetId).ySplit) {
53900
+ const deltaRow = this.getMainInternalViewport(sheetId).top - top;
53901
+ this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
53902
+ }
53887
53903
  }
53888
53904
  getVisibleFigures() {
53889
53905
  const sheetId = this.getters.getActiveSheetId();
@@ -54802,7 +54818,6 @@ css /* scss */ `
54802
54818
  cursor: pointer;
54803
54819
  }
54804
54820
  `;
54805
- let tKey = 1;
54806
54821
  class SpreadsheetDashboard extends Component {
54807
54822
  static template = "o-spreadsheet-SpreadsheetDashboard";
54808
54823
  static props = {};
@@ -54881,13 +54896,9 @@ class SpreadsheetDashboard extends Component {
54881
54896
  coordinates: rect,
54882
54897
  position: { col, row },
54883
54898
  action,
54884
- // we can't rely on position only because a row or a column could
54885
- // be inserted at any time.
54886
- tKey: `${tKey}-${col}-${row}`,
54887
54899
  });
54888
54900
  }
54889
54901
  }
54890
- tKey++;
54891
54902
  return cells;
54892
54903
  }
54893
54904
  getClickableAction(position) {
@@ -60186,6 +60197,6 @@ const constants = {
60186
60197
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, 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 };
60187
60198
 
60188
60199
 
60189
- __info__.version = "17.2.3";
60190
- __info__.date = "2024-04-10T12:28:36.552Z";
60191
- __info__.hash = "ab5e22d";
60200
+ __info__.version = "17.2.4";
60201
+ __info__.date = "2024-04-18T16:41:38.407Z";
60202
+ __info__.hash = "0c66038";