@odoo/o-spreadsheet 17.2.0 → 17.2.2

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.0
7
- * @date 2024-03-20T08:12:44.398Z
8
- * @hash 1869c24
6
+ * @version 17.2.2
7
+ * @date 2024-04-05T14:01:19.824Z
8
+ * @hash c15836d
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';
@@ -29,7 +29,6 @@ const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
29
29
  const LINK_COLOR = "#017E84";
30
30
  const FILTERS_COLOR = "#188038";
31
31
  const BACKGROUND_HEADER_FILTER_COLOR = "#E6F4EA";
32
- const BACKGROUND_HEADER_SELECTED_FILTER_COLOR = "#CEEAD6";
33
32
  const SEPARATOR_COLOR = "#E0E2E4";
34
33
  const ICONS_COLOR = "#4A4F59";
35
34
  const HEADER_GROUPING_BACKGROUND_COLOR = "#F5F5F5";
@@ -465,7 +464,7 @@ function getItemId(item, itemsDic) {
465
464
  }
466
465
  // Generate new Id if the item didn't exist in the dictionary
467
466
  const ids = Object.keys(itemsDic);
468
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
467
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
469
468
  itemsDic[maxId + 1] = item;
470
469
  return maxId + 1;
471
470
  }
@@ -685,6 +684,34 @@ function getSearchRegex(searchStr, searchOptions) {
685
684
  }
686
685
  return RegExp(searchValue, flags);
687
686
  }
687
+ /**
688
+ * Alternative to Math.max that works with large arrays.
689
+ * Typically useful for arrays bigger than 100k elements.
690
+ */
691
+ function largeMax(array) {
692
+ let len = array.length;
693
+ if (len < 100000)
694
+ return Math.max(...array);
695
+ let max = -Infinity;
696
+ while (len--) {
697
+ max = array[len] > max ? array[len] : max;
698
+ }
699
+ return max;
700
+ }
701
+ /**
702
+ * Alternative to Math.min that works with large arrays.
703
+ * Typically useful for arrays bigger than 100k elements.
704
+ */
705
+ function largeMin(array) {
706
+ let len = array.length;
707
+ if (len < 100000)
708
+ return Math.min(...array);
709
+ let min = +Infinity;
710
+ while (len--) {
711
+ min = array[len] < min ? array[len] : min;
712
+ }
713
+ return min;
714
+ }
688
715
 
689
716
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
690
717
  const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
@@ -4544,8 +4571,9 @@ function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
4544
4571
  * Get the default height of the cell given its style.
4545
4572
  */
4546
4573
  function getDefaultCellHeight(ctx, cell, colSize) {
4547
- if (!cell || !cell.content)
4574
+ if (!cell || (!cell.isFormula && !cell.content)) {
4548
4575
  return DEFAULT_CELL_HEIGHT;
4576
+ }
4549
4577
  const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4550
4578
  const numberOfLines = cell.isFormula
4551
4579
  ? 1
@@ -8003,6 +8031,9 @@ class DependencyContainer {
8003
8031
  instantiate(Store, ...args) {
8004
8032
  return this.factory.build(Store, ...args);
8005
8033
  }
8034
+ resetStores() {
8035
+ this.dependencies.clear();
8036
+ }
8006
8037
  }
8007
8038
  class StoreFactory {
8008
8039
  get;
@@ -9936,11 +9967,11 @@ autoCompleteProviders.add("dataValidation", {
9936
9967
  }
9937
9968
  else {
9938
9969
  const range = this.getters.getRangeFromSheetXC(position.sheetId, rule.criterion.values[0]);
9939
- values = this.getters
9970
+ values = Array.from(new Set(this.getters
9940
9971
  .getRangeValues(range)
9941
9972
  .filter(isNotNull)
9942
9973
  .map((value) => value.toString())
9943
- .filter((val) => val !== "");
9974
+ .filter((val) => val !== "")));
9944
9975
  }
9945
9976
  return values.map((value) => ({ text: value }));
9946
9977
  },
@@ -19387,10 +19418,10 @@ function aggregateDataForLabels(labels, datasets) {
19387
19418
  }
19388
19419
  }
19389
19420
  return {
19390
- labels: Object.keys(labelMap),
19421
+ labels: Array.from(labelSet),
19391
19422
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
19392
19423
  ...dataset,
19393
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
19424
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
19394
19425
  })),
19395
19426
  };
19396
19427
  }
@@ -20122,7 +20153,7 @@ function getBestTimeUnitForScale(labels, format, locale) {
20122
20153
  return undefined;
20123
20154
  }
20124
20155
  const labelsTimestamps = labelDates.map((date) => date.getTime());
20125
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
20156
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
20126
20157
  const minUnit = getFormatMinDisplayUnit(format);
20127
20158
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
20128
20159
  return "second";
@@ -20610,7 +20641,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
20610
20641
  }
20611
20642
  function getPieColors(colors, dataSetsValues) {
20612
20643
  const pieColors = [];
20613
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
20644
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
20614
20645
  for (let i = 0; i <= maxLength; i++) {
20615
20646
  pieColors.push(colors.next());
20616
20647
  }
@@ -23415,8 +23446,8 @@ const DELETE_CONTENT_ROWS_NAME = (env) => {
23415
23446
  let last;
23416
23447
  const activesRows = env.model.getters.getActiveRows();
23417
23448
  if (activesRows.size !== 0) {
23418
- first = Math.min(...activesRows);
23419
- last = Math.max(...activesRows);
23449
+ first = largeMin([...activesRows]);
23450
+ last = largeMax([...activesRows]);
23420
23451
  }
23421
23452
  else {
23422
23453
  const zone = env.model.getters.getSelectedZones()[0];
@@ -23444,8 +23475,8 @@ const DELETE_CONTENT_COLUMNS_NAME = (env) => {
23444
23475
  let last;
23445
23476
  const activeCols = env.model.getters.getActiveCols();
23446
23477
  if (activeCols.size !== 0) {
23447
- first = Math.min(...activeCols);
23448
- last = Math.max(...activeCols);
23478
+ first = largeMin([...activeCols]);
23479
+ last = largeMax([...activeCols]);
23449
23480
  }
23450
23481
  else {
23451
23482
  const zone = env.model.getters.getSelectedZones()[0];
@@ -23473,8 +23504,8 @@ const REMOVE_ROWS_NAME = (env) => {
23473
23504
  let last;
23474
23505
  const activesRows = env.model.getters.getActiveRows();
23475
23506
  if (activesRows.size !== 0) {
23476
- first = Math.min(...activesRows);
23477
- last = Math.max(...activesRows);
23507
+ first = largeMin([...activesRows]);
23508
+ last = largeMax([...activesRows]);
23478
23509
  }
23479
23510
  else {
23480
23511
  const zone = env.model.getters.getSelectedZones()[0];
@@ -23515,8 +23546,8 @@ const REMOVE_COLUMNS_NAME = (env) => {
23515
23546
  let last;
23516
23547
  const activeCols = env.model.getters.getActiveCols();
23517
23548
  if (activeCols.size !== 0) {
23518
- first = Math.min(...activeCols);
23519
- last = Math.max(...activeCols);
23549
+ first = largeMin([...activeCols]);
23550
+ last = largeMax([...activeCols]);
23520
23551
  }
23521
23552
  else {
23522
23553
  const zone = env.model.getters.getSelectedZones()[0];
@@ -23557,7 +23588,7 @@ const INSERT_ROWS_BEFORE_ACTION = (env) => {
23557
23588
  let row;
23558
23589
  let quantity;
23559
23590
  if (activeRows.size) {
23560
- row = Math.min(...activeRows);
23591
+ row = largeMin([...activeRows]);
23561
23592
  quantity = activeRows.size;
23562
23593
  }
23563
23594
  else {
@@ -23578,7 +23609,7 @@ const INSERT_ROWS_AFTER_ACTION = (env) => {
23578
23609
  let row;
23579
23610
  let quantity;
23580
23611
  if (activeRows.size) {
23581
- row = Math.max(...activeRows);
23612
+ row = largeMax([...activeRows]);
23582
23613
  quantity = activeRows.size;
23583
23614
  }
23584
23615
  else {
@@ -23599,7 +23630,7 @@ const INSERT_COLUMNS_BEFORE_ACTION = (env) => {
23599
23630
  let column;
23600
23631
  let quantity;
23601
23632
  if (activeCols.size) {
23602
- column = Math.min(...activeCols);
23633
+ column = largeMin([...activeCols]);
23603
23634
  quantity = activeCols.size;
23604
23635
  }
23605
23636
  else {
@@ -23620,7 +23651,7 @@ const INSERT_COLUMNS_AFTER_ACTION = (env) => {
23620
23651
  let column;
23621
23652
  let quantity;
23622
23653
  if (activeCols.size) {
23623
- column = Math.max(...activeCols);
23654
+ column = largeMax([...activeCols]);
23624
23655
  quantity = activeCols.size;
23625
23656
  }
23626
23657
  else {
@@ -24213,14 +24244,19 @@ const categorieFunctionAll = {
24213
24244
  children: [allFunctionListMenuBuilder],
24214
24245
  };
24215
24246
  function allFunctionListMenuBuilder() {
24216
- const fnNames = functionRegistry.getKeys();
24247
+ const fnNames = functionRegistry.getKeys().filter((key) => !functionRegistry.get(key).hidden);
24217
24248
  return createFormulaFunctions(fnNames);
24218
24249
  }
24219
24250
  const categoriesFunctionListMenuBuilder = () => {
24220
24251
  const functions = functionRegistry.content;
24221
- const categories = [...new Set(functionRegistry.getAll().map((fn) => fn.category))].filter(isDefined$1);
24252
+ const categories = [
24253
+ ...new Set(functionRegistry
24254
+ .getAll()
24255
+ .filter((fn) => !fn.hidden)
24256
+ .map((fn) => fn.category)),
24257
+ ].filter(isDefined$1);
24222
24258
  return categories.sort().map((category, i) => {
24223
- const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category);
24259
+ const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category && !functions[key].hidden);
24224
24260
  return {
24225
24261
  name: category,
24226
24262
  children: createFormulaFunctions(functionsInCategory),
@@ -28378,11 +28414,9 @@ css /* scss */ `
28378
28414
  }
28379
28415
  .o-cell-is-operator {
28380
28416
  margin-bottom: 5px;
28381
- width: 96%;
28382
28417
  }
28383
28418
  .o-cell-is-value {
28384
28419
  margin-bottom: 5px;
28385
- width: 96%;
28386
28420
  }
28387
28421
  .o-color-picker-widget .o-color-picker-button {
28388
28422
  pointer-events: all;
@@ -30216,7 +30250,11 @@ class SplitIntoColumnsPanel extends Component {
30216
30250
  const composerStore = useStore(ComposerStore);
30217
30251
  // The feature makes no sense if we are editing a cell, because then the selection isn't active
30218
30252
  // Stop the edition when the panel is mounted, and close the panel if the user start editing a cell
30219
- useEffect(this.props.onCloseSidePanel, () => [composerStore.editionMode]);
30253
+ useEffect((editionMode) => {
30254
+ if (editionMode !== "inactive") {
30255
+ this.props.onCloseSidePanel();
30256
+ }
30257
+ }, () => [composerStore.editionMode]);
30220
30258
  onMounted(() => {
30221
30259
  composerStore.stopEdition();
30222
30260
  });
@@ -31084,6 +31122,9 @@ class FigureComponent extends Component {
31084
31122
  el?.focus({ preventScroll: true });
31085
31123
  }
31086
31124
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
31125
+ onWillUnmount(() => {
31126
+ this.props.onFigureDeleted();
31127
+ });
31087
31128
  }
31088
31129
  clickAnchor(dirX, dirY, ev) {
31089
31130
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -31102,6 +31143,7 @@ class FigureComponent extends Component {
31102
31143
  this.props.onFigureDeleted();
31103
31144
  ev.stopPropagation();
31104
31145
  ev.preventDefault();
31146
+ ev.stopPropagation();
31105
31147
  break;
31106
31148
  case "ArrowDown":
31107
31149
  case "ArrowLeft":
@@ -31122,6 +31164,7 @@ class FigureComponent extends Component {
31122
31164
  });
31123
31165
  ev.stopPropagation();
31124
31166
  ev.preventDefault();
31167
+ ev.stopPropagation();
31125
31168
  break;
31126
31169
  }
31127
31170
  }
@@ -31789,6 +31832,7 @@ function compareContentToSpanElement(content, node) {
31789
31832
  // -----------------------------------------------------------------------------
31790
31833
  css /* scss */ `
31791
31834
  .o-formula-assistant {
31835
+ background: #ffffff;
31792
31836
  .o-formula-assistant-head {
31793
31837
  background-color: #f2f2f2;
31794
31838
  padding: 10px;
@@ -31844,6 +31888,9 @@ class FunctionDescriptionProvider extends Component {
31844
31888
  this.assistantState.allowCellSelectionBehind = false;
31845
31889
  }, 2000);
31846
31890
  }
31891
+ get formulaArgSeparator() {
31892
+ return this.env.model.getters.getLocale().formulaArgSeparator + " ";
31893
+ }
31847
31894
  }
31848
31895
 
31849
31896
  const functions$2 = functionRegistry.content;
@@ -32003,6 +32050,12 @@ class Composer extends Component {
32003
32050
  useEffect(() => {
32004
32051
  this.processContent();
32005
32052
  });
32053
+ onPatched(() => {
32054
+ // Required because typing '=SUM' and double-clicking another cell leaves ShowProvider/ShowDescription true
32055
+ if (this.composerStore.editionMode === "inactive") {
32056
+ this.processTokenAtCursor();
32057
+ }
32058
+ });
32006
32059
  }
32007
32060
  // ---------------------------------------------------------------------------
32008
32061
  // Handlers
@@ -33983,11 +34036,6 @@ css /* scss */ `
33983
34036
  height: 10000px;
33984
34037
  background-color: ${SELECTION_BORDER_COLOR};
33985
34038
  }
33986
- .o-unhide-buttons {
33987
- width: fit-content;
33988
- gap: 5px;
33989
- transform: translate(-50%, 0);
33990
- }
33991
34039
  .o-unhide:hover {
33992
34040
  z-index: ${ComponentsImportance.Grid + 1};
33993
34041
  background-color: lightgrey;
@@ -34149,10 +34197,6 @@ css /* scss */ `
34149
34197
  height: 1px;
34150
34198
  background-color: ${SELECTION_BORDER_COLOR};
34151
34199
  }
34152
- .o-unhide-buttons {
34153
- height: fit-content;
34154
- transform: translate(0, -50%);
34155
- }
34156
34200
  .o-unhide:hover {
34157
34201
  z-index: ${ComponentsImportance.Grid + 1};
34158
34202
  background-color: lightgrey;
@@ -34613,19 +34657,16 @@ class GridRenderer {
34613
34657
  for (let col = left; col <= right; col++) {
34614
34658
  const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
34615
34659
  const { x, width } = this.getters.getVisibleRect(colZone);
34616
- const colHasFilter = this.getters.doesZonesContainFilter(sheetId, [colZone]);
34617
34660
  const isColActive = activeCols.has(col);
34618
34661
  const isColSelected = selectedCols.has(col);
34619
34662
  if (isColActive) {
34620
- ctx.fillStyle = colHasFilter ? FILTERS_COLOR : BACKGROUND_HEADER_ACTIVE_COLOR;
34663
+ ctx.fillStyle = BACKGROUND_HEADER_ACTIVE_COLOR;
34621
34664
  }
34622
34665
  else if (isColSelected) {
34623
- ctx.fillStyle = colHasFilter
34624
- ? BACKGROUND_HEADER_SELECTED_FILTER_COLOR
34625
- : BACKGROUND_HEADER_SELECTED_COLOR;
34666
+ ctx.fillStyle = BACKGROUND_HEADER_SELECTED_COLOR;
34626
34667
  }
34627
34668
  else {
34628
- ctx.fillStyle = colHasFilter ? BACKGROUND_HEADER_FILTER_COLOR : BACKGROUND_HEADER_COLOR;
34669
+ ctx.fillStyle = BACKGROUND_HEADER_COLOR;
34629
34670
  }
34630
34671
  ctx.fillRect(x, 0, width, HEADER_HEIGHT);
34631
34672
  }
@@ -34633,19 +34674,16 @@ class GridRenderer {
34633
34674
  for (let row = top; row <= bottom; row++) {
34634
34675
  const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
34635
34676
  const { y, height } = this.getters.getVisibleRect(rowZone);
34636
- const rowHasFilter = this.getters.doesZonesContainFilter(sheetId, [rowZone]);
34637
34677
  const isRowActive = activeRows.has(row);
34638
34678
  const isRowSelected = selectedRows.has(row);
34639
34679
  if (isRowActive) {
34640
- ctx.fillStyle = rowHasFilter ? FILTERS_COLOR : BACKGROUND_HEADER_ACTIVE_COLOR;
34680
+ ctx.fillStyle = BACKGROUND_HEADER_ACTIVE_COLOR;
34641
34681
  }
34642
34682
  else if (isRowSelected) {
34643
- ctx.fillStyle = rowHasFilter
34644
- ? BACKGROUND_HEADER_SELECTED_FILTER_COLOR
34645
- : BACKGROUND_HEADER_SELECTED_COLOR;
34683
+ ctx.fillStyle = BACKGROUND_HEADER_SELECTED_COLOR;
34646
34684
  }
34647
34685
  else {
34648
- ctx.fillStyle = rowHasFilter ? BACKGROUND_HEADER_FILTER_COLOR : BACKGROUND_HEADER_COLOR;
34686
+ ctx.fillStyle = BACKGROUND_HEADER_COLOR;
34649
34687
  }
34650
34688
  ctx.fillRect(0, y, HEADER_WIDTH, height);
34651
34689
  }
@@ -37852,7 +37890,7 @@ function convertHyperlink(link, cellValue, warningManager) {
37852
37890
  function getSheetDims(sheet) {
37853
37891
  const dims = [0, 0];
37854
37892
  for (let row of sheet.rows) {
37855
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
37893
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
37856
37894
  dims[1] = Math.max(dims[1], row.index);
37857
37895
  }
37858
37896
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -42359,6 +42397,9 @@ class DataValidationPlugin extends CorePlugin {
42359
42397
  if (newRule.criterion.type === "isBoolean") {
42360
42398
  this.setCenterStyleToBooleanCells(newRule);
42361
42399
  }
42400
+ else if (newRule.criterion.type === "isValueInList") {
42401
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
42402
+ }
42362
42403
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
42363
42404
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
42364
42405
  if (ruleIndex !== -1) {
@@ -42755,7 +42796,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
42755
42796
  if (hiddenElements.size >= elements) {
42756
42797
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
42757
42798
  }
42758
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
42799
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
42759
42800
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
42760
42801
  }
42761
42802
  else {
@@ -43573,8 +43614,8 @@ class RangeAdapter {
43573
43614
  let newRange = range;
43574
43615
  let changeType = "NONE";
43575
43616
  for (let group of groups) {
43576
- const min = Math.min(...group);
43577
- const max = Math.max(...group);
43617
+ const min = largeMin(group);
43618
+ const max = largeMax(group);
43578
43619
  if (range.zone[start] <= min && min <= range.zone[end]) {
43579
43620
  const toRemove = Math.min(range.zone[end], max) - min + 1;
43580
43621
  changeType = "RESIZE";
@@ -44023,8 +44064,8 @@ class SheetPlugin extends CorePlugin {
44023
44064
  }
44024
44065
  return "Success" /* CommandResult.Success */;
44025
44066
  case "REMOVE_COLUMNS_ROWS": {
44026
- const min = Math.min(...cmd.elements);
44027
- const max = Math.max(...cmd.elements);
44067
+ const min = largeMin(cmd.elements);
44068
+ const max = largeMax(cmd.elements);
44028
44069
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
44029
44070
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
44030
44071
  }
@@ -44818,7 +44859,6 @@ class SheetPlugin extends CorePlugin {
44818
44859
 
44819
44860
  class TablePlugin extends CorePlugin {
44820
44861
  static getters = [
44821
- "doesZonesContainFilter",
44822
44862
  "getFilter",
44823
44863
  "getFilters",
44824
44864
  "getTable",
@@ -44975,10 +45015,6 @@ class TablePlugin extends CorePlugin {
44975
45015
  getTablesOverlappingZones(sheetId, zones) {
44976
45016
  return this.getTables(sheetId).filter((table) => zones.some((zone) => overlap(table.range.zone, zone)));
44977
45017
  }
44978
- doesZonesContainFilter(sheetId, zones) {
44979
- return (this.getTablesOverlappingZones(sheetId, zones).filter((table) => table.config.hasFilters)
44980
- .length > 0);
44981
- }
44982
45018
  getFilterHeaders(sheetId) {
44983
45019
  const headers = [];
44984
45020
  for (const table of this.getTables(sheetId)) {
@@ -47493,7 +47529,7 @@ class EvaluationPlugin extends UIPlugin {
47493
47529
  ? getItemId(newFormat, data.formats)
47494
47530
  : exportedCellData.format;
47495
47531
  let content;
47496
- if (formulaCell instanceof FormulaCellWithDependencies) {
47532
+ if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
47497
47533
  content = formulaCell.contentWithFixedReferences;
47498
47534
  }
47499
47535
  else {
@@ -47942,13 +47978,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
47942
47978
  .map((cell) => cell.value);
47943
47979
  switch (threshold.type) {
47944
47980
  case "value":
47945
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
47981
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
47946
47982
  return result;
47947
47983
  case "number":
47948
47984
  return Number(threshold.value);
47949
47985
  case "percentage":
47950
- const min = Math.min(...rangeValues);
47951
- const max = Math.max(...rangeValues);
47986
+ const min = largeMin(rangeValues);
47987
+ const max = largeMax(rangeValues);
47952
47988
  const delta = max - min;
47953
47989
  return min + (delta * Number(threshold.value)) / 100;
47954
47990
  case "percentile":
@@ -49021,13 +49057,13 @@ class AutomaticSumPlugin extends UIPlugin {
49021
49057
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
49022
49058
  const cellPositions = range(end, -1, -1);
49023
49059
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
49024
- const maxValidPosition = Math.max(...invalidCells);
49060
+ const maxValidPosition = largeMax(invalidCells);
49025
49061
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
49026
49062
  const firstSequence = numberSequences[0] || [];
49027
- if (Math.max(...firstSequence) < maxValidPosition) {
49063
+ if (largeMax(firstSequence) < maxValidPosition) {
49028
49064
  return Infinity;
49029
49065
  }
49030
- return Math.min(...firstSequence);
49066
+ return largeMin(firstSequence);
49031
49067
  }
49032
49068
  shouldFindData(sheetId, zone) {
49033
49069
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -50768,7 +50804,7 @@ class SheetUIPlugin extends UIPlugin {
50768
50804
  getColMaxWidth(sheetId, index) {
50769
50805
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
50770
50806
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
50771
- return Math.max(0, ...sizes);
50807
+ return Math.max(0, largeMax(sizes));
50772
50808
  }
50773
50809
  /**
50774
50810
  * Check that any "sheetId" in the command matches an existing
@@ -52473,6 +52509,7 @@ class GridSelectionPlugin extends UIPlugin {
52473
52509
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
52474
52510
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
52475
52511
  this.setSelectionMixin(this.gridSelection.anchor, this.gridSelection.zones);
52512
+ this.selectedFigureId = null;
52476
52513
  break;
52477
52514
  }
52478
52515
  /** Any change to the selection has to be reflected in the selection processor. */
@@ -53663,7 +53700,7 @@ class SheetViewPlugin extends UIPlugin {
53663
53700
  * column of the current viewport
53664
53701
  */
53665
53702
  getColDimensionsInViewport(sheetId, col) {
53666
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
53703
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
53667
53704
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
53668
53705
  const size = this.getters.getColSize(sheetId, col);
53669
53706
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -53678,7 +53715,7 @@ class SheetViewPlugin extends UIPlugin {
53678
53715
  * of the current viewport
53679
53716
  */
53680
53717
  getRowDimensionsInViewport(sheetId, row) {
53681
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
53718
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
53682
53719
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
53683
53720
  const size = this.getters.getRowSize(sheetId, row);
53684
53721
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -54391,12 +54428,14 @@ class BottomBarSheet extends Component {
54391
54428
  this.editionState = "initializing";
54392
54429
  }
54393
54430
  stopEdition() {
54394
- if (!this.state.isEditing)
54431
+ const input = this.sheetNameRef.el;
54432
+ if (!this.state.isEditing || !input)
54395
54433
  return;
54396
54434
  this.state.isEditing = false;
54397
54435
  this.editionState = "initializing";
54398
- this.sheetNameRef.el?.blur();
54436
+ input.blur();
54399
54437
  const inputValue = this.getInputContent() || "";
54438
+ input.innerText = inputValue;
54400
54439
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
54401
54440
  }
54402
54441
  cancelEdition() {
@@ -54687,7 +54726,7 @@ class BottomBar extends Component {
54687
54726
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
54688
54727
  }
54689
54728
  onSheetMouseDown(sheetId, event) {
54690
- if (event.button !== 0)
54729
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
54691
54730
  return;
54692
54731
  this.closeMenu();
54693
54732
  const visibleSheets = this.getVisibleSheets();
@@ -56091,9 +56130,6 @@ css /* scss */ `
56091
56130
  .text-muted {
56092
56131
  color: grey !important;
56093
56132
  }
56094
- button {
56095
- color: #333;
56096
- }
56097
56133
  .o-disabled {
56098
56134
  opacity: 0.4;
56099
56135
  pointer: default;
@@ -56214,17 +56250,17 @@ css /* scss */ `
56214
56250
  }
56215
56251
 
56216
56252
  .o-button {
56217
- border: 1px solid lightgrey;
56253
+ border: 1px solid;
56218
56254
  padding: 0px 20px 0px 20px;
56219
56255
  border-radius: 4px;
56220
56256
  font-weight: 500;
56221
56257
  font-size: 14px;
56222
56258
  height: 30px;
56223
56259
  line-height: 16px;
56224
- background: white;
56225
56260
  margin-right: 8px;
56226
- &:hover:enabled {
56227
- background-color: rgba(0, 0, 0, 0.08);
56261
+
56262
+ &:not(:hover) {
56263
+ background-color: transparent;
56228
56264
  }
56229
56265
 
56230
56266
  &:enabled {
@@ -56238,6 +56274,15 @@ css /* scss */ `
56238
56274
  &:last-child {
56239
56275
  margin-right: 0px;
56240
56276
  }
56277
+
56278
+ &.o-button-grey {
56279
+ border-color: lightgrey;
56280
+ background: #ffffff;
56281
+ color: #333;
56282
+ &:hover:enabled {
56283
+ background-color: rgba(0, 0, 0, 0.08);
56284
+ }
56285
+ }
56241
56286
  }
56242
56287
 
56243
56288
  .o-input {
@@ -58135,7 +58180,7 @@ function addLineChart(chart) {
58135
58180
  }
58136
58181
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
58137
58182
  const colors = new ChartColors();
58138
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
58183
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
58139
58184
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
58140
58185
  const dataSetsNodes = [];
58141
58186
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -60124,6 +60169,6 @@ const constants = {
60124
60169
  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 };
60125
60170
 
60126
60171
 
60127
- __info__.version = "17.2.0";
60128
- __info__.date = "2024-03-20T08:12:44.398Z";
60129
- __info__.hash = "1869c24";
60172
+ __info__.version = "17.2.2";
60173
+ __info__.date = "2024-04-05T14:01:19.824Z";
60174
+ __info__.hash = "c15836d";