@odoo/o-spreadsheet 17.0.15 → 17.0.17

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.0.15
6
- * @date 2024-03-15T11:00:59.958Z
7
- * @hash e02add9
5
+ * @version 17.0.17
6
+ * @date 2024-04-05T13:59:37.139Z
7
+ * @hash 33f09d7
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -558,7 +558,7 @@
558
558
  }
559
559
  // Generate new Id if the item didn't exist in the dictionary
560
560
  const ids = Object.keys(itemsDic);
561
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
561
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
562
562
  itemsDic[maxId + 1] = item;
563
563
  return maxId + 1;
564
564
  }
@@ -775,6 +775,34 @@
775
775
  }
776
776
  return value >= min && value <= max;
777
777
  }
778
+ /**
779
+ * Alternative to Math.max that works with large arrays.
780
+ * Typically useful for arrays bigger than 100k elements.
781
+ */
782
+ function largeMax(array) {
783
+ let len = array.length;
784
+ if (len < 100000)
785
+ return Math.max(...array);
786
+ let max = -Infinity;
787
+ while (len--) {
788
+ max = array[len] > max ? array[len] : max;
789
+ }
790
+ return max;
791
+ }
792
+ /**
793
+ * Alternative to Math.min that works with large arrays.
794
+ * Typically useful for arrays bigger than 100k elements.
795
+ */
796
+ function largeMin(array) {
797
+ let len = array.length;
798
+ if (len < 100000)
799
+ return Math.min(...array);
800
+ let min = +Infinity;
801
+ while (len--) {
802
+ min = array[len] < min ? array[len] : min;
803
+ }
804
+ return min;
805
+ }
778
806
 
779
807
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
780
808
  const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
@@ -4421,8 +4449,9 @@
4421
4449
  * Get the default height of the cell given its style.
4422
4450
  */
4423
4451
  function getDefaultCellHeight(ctx, cell, colSize) {
4424
- if (!cell || !cell.content)
4452
+ if (!cell || (!cell.isFormula && !cell.content)) {
4425
4453
  return DEFAULT_CELL_HEIGHT;
4454
+ }
4426
4455
  const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4427
4456
  const numberOfLines = cell.isFormula
4428
4457
  ? 1
@@ -8325,10 +8354,10 @@
8325
8354
  }
8326
8355
  }
8327
8356
  return {
8328
- labels: Object.keys(labelMap),
8357
+ labels: Array.from(labelSet),
8329
8358
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
8330
8359
  ...dataset,
8331
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
8360
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
8332
8361
  })),
8333
8362
  };
8334
8363
  }
@@ -8379,7 +8408,7 @@
8379
8408
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
8380
8409
  // tooltipItem.parsed.y can be an object or a number for pie charts
8381
8410
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
8382
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
8411
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
8383
8412
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
8384
8413
  return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
8385
8414
  },
@@ -8665,7 +8694,10 @@
8665
8694
  if (isNaN(value))
8666
8695
  return value;
8667
8696
  const { locale, format } = localeFormat;
8668
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
8697
+ return formatValue(value, {
8698
+ locale,
8699
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
8700
+ });
8669
8701
  },
8670
8702
  },
8671
8703
  },
@@ -9079,7 +9111,7 @@
9079
9111
  return undefined;
9080
9112
  }
9081
9113
  const labelsTimestamps = labelDates.map((date) => date.getTime());
9082
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
9114
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
9083
9115
  const minUnit = getFormatMinDisplayUnit(format);
9084
9116
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
9085
9117
  return "second";
@@ -9316,7 +9348,10 @@
9316
9348
  if (isNaN(value))
9317
9349
  return value;
9318
9350
  const { locale, format } = localeFormat;
9319
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
9351
+ return formatValue(value, {
9352
+ locale,
9353
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
9354
+ });
9320
9355
  },
9321
9356
  },
9322
9357
  },
@@ -9543,7 +9578,7 @@
9543
9578
  const percentage = calculatePercentage(data, dataIndex);
9544
9579
  const xLabel = tooltipItem.label || tooltipItem.dataset.label;
9545
9580
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
9546
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
9581
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
9547
9582
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
9548
9583
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
9549
9584
  };
@@ -9551,7 +9586,7 @@
9551
9586
  }
9552
9587
  function getPieColors(colors, dataSetsValues) {
9553
9588
  const pieColors = [];
9554
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
9589
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
9555
9590
  for (let i = 0; i <= maxLength; i++) {
9556
9591
  pieColors.push(colors.next());
9557
9592
  }
@@ -10453,8 +10488,8 @@
10453
10488
  let last;
10454
10489
  const activesRows = env.model.getters.getActiveRows();
10455
10490
  if (activesRows.size !== 0) {
10456
- first = Math.min(...activesRows);
10457
- last = Math.max(...activesRows);
10491
+ first = largeMin([...activesRows]);
10492
+ last = largeMax([...activesRows]);
10458
10493
  }
10459
10494
  else {
10460
10495
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10482,8 +10517,8 @@
10482
10517
  let last;
10483
10518
  const activeCols = env.model.getters.getActiveCols();
10484
10519
  if (activeCols.size !== 0) {
10485
- first = Math.min(...activeCols);
10486
- last = Math.max(...activeCols);
10520
+ first = largeMin([...activeCols]);
10521
+ last = largeMax([...activeCols]);
10487
10522
  }
10488
10523
  else {
10489
10524
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10511,8 +10546,8 @@
10511
10546
  let last;
10512
10547
  const activesRows = env.model.getters.getActiveRows();
10513
10548
  if (activesRows.size !== 0) {
10514
- first = Math.min(...activesRows);
10515
- last = Math.max(...activesRows);
10549
+ first = largeMin([...activesRows]);
10550
+ last = largeMax([...activesRows]);
10516
10551
  }
10517
10552
  else {
10518
10553
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10553,8 +10588,8 @@
10553
10588
  let last;
10554
10589
  const activeCols = env.model.getters.getActiveCols();
10555
10590
  if (activeCols.size !== 0) {
10556
- first = Math.min(...activeCols);
10557
- last = Math.max(...activeCols);
10591
+ first = largeMin([...activeCols]);
10592
+ last = largeMax([...activeCols]);
10558
10593
  }
10559
10594
  else {
10560
10595
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10595,7 +10630,7 @@
10595
10630
  let row;
10596
10631
  let quantity;
10597
10632
  if (activeRows.size) {
10598
- row = Math.min(...activeRows);
10633
+ row = largeMin([...activeRows]);
10599
10634
  quantity = activeRows.size;
10600
10635
  }
10601
10636
  else {
@@ -10616,7 +10651,7 @@
10616
10651
  let row;
10617
10652
  let quantity;
10618
10653
  if (activeRows.size) {
10619
- row = Math.max(...activeRows);
10654
+ row = largeMax([...activeRows]);
10620
10655
  quantity = activeRows.size;
10621
10656
  }
10622
10657
  else {
@@ -10637,7 +10672,7 @@
10637
10672
  let column;
10638
10673
  let quantity;
10639
10674
  if (activeCols.size) {
10640
- column = Math.min(...activeCols);
10675
+ column = largeMin([...activeCols]);
10641
10676
  quantity = activeCols.size;
10642
10677
  }
10643
10678
  else {
@@ -10658,7 +10693,7 @@
10658
10693
  let column;
10659
10694
  let quantity;
10660
10695
  if (activeCols.size) {
10661
- column = Math.max(...activeCols);
10696
+ column = largeMax([...activeCols]);
10662
10697
  quantity = activeCols.size;
10663
10698
  }
10664
10699
  else {
@@ -11056,6 +11091,9 @@
11056
11091
  result.default = true;
11057
11092
  result.defaultValue = defaultValue;
11058
11093
  }
11094
+ if (types.some((t) => t.startsWith("RANGE"))) {
11095
+ result.acceptMatrix = true;
11096
+ }
11059
11097
  return result;
11060
11098
  }
11061
11099
  /**
@@ -19421,11 +19459,27 @@
19421
19459
  }
19422
19460
  const descr = addMetaInfoFromArg(addDescr);
19423
19461
  validateArguments(descr.args);
19424
- this.mapping[name] = createComputeFunctionFromDescription(descr);
19462
+ this.mapping[name] = addInputHandling(descr, createComputeFunctionFromDescription(descr));
19425
19463
  super.add(name, descr);
19426
19464
  return this;
19427
19465
  }
19428
19466
  }
19467
+ function addInputHandling(descr, computeFunction) {
19468
+ function computeWithInputHandling(...args) {
19469
+ for (let i = 0; i < args.length; i++) {
19470
+ const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
19471
+ const arg = args[i];
19472
+ if (isMatrix(arg) && !argDefinition.acceptMatrix) {
19473
+ if (arg.length !== 1 || arg[0].length !== 1) {
19474
+ throw new EvaluationError(CellErrorType.GenericError, _t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be a single value or a single cell reference, not a range.", argDefinition.name));
19475
+ }
19476
+ args[i] = arg[0][0];
19477
+ }
19478
+ }
19479
+ return computeFunction.apply(this, args);
19480
+ }
19481
+ return computeWithInputHandling;
19482
+ }
19429
19483
  function createComputeFunctionFromDescription(descr) {
19430
19484
  const computeValueAndFormat = "computeValueAndFormat" in descr;
19431
19485
  const computeValue = "compute" in descr;
@@ -19676,14 +19730,19 @@
19676
19730
  children: [allFunctionListMenuBuilder],
19677
19731
  };
19678
19732
  function allFunctionListMenuBuilder() {
19679
- const fnNames = functionRegistry.getKeys();
19733
+ const fnNames = functionRegistry.getKeys().filter((key) => !functionRegistry.get(key).hidden);
19680
19734
  return createFormulaFunctions(fnNames);
19681
19735
  }
19682
19736
  const categoriesFunctionListMenuBuilder = () => {
19683
19737
  const functions = functionRegistry.content;
19684
- const categories = [...new Set(functionRegistry.getAll().map((fn) => fn.category))].filter(isDefined$1);
19738
+ const categories = [
19739
+ ...new Set(functionRegistry
19740
+ .getAll()
19741
+ .filter((fn) => !fn.hidden)
19742
+ .map((fn) => fn.category)),
19743
+ ].filter(isDefined$1);
19685
19744
  return categories.sort().map((category, i) => {
19686
- const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category);
19745
+ const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category && !functions[key].hidden);
19687
19746
  return {
19688
19747
  name: category,
19689
19748
  children: createFormulaFunctions(functionsInCategory),
@@ -23336,11 +23395,9 @@
23336
23395
  }
23337
23396
  .o-cell-is-operator {
23338
23397
  margin-bottom: 5px;
23339
- width: 96%;
23340
23398
  }
23341
23399
  .o-cell-is-value {
23342
23400
  margin-bottom: 5px;
23343
- width: 96%;
23344
23401
  }
23345
23402
  .o-color-picker-widget .o-color-picker-button {
23346
23403
  pointer-events: all;
@@ -25706,6 +25763,9 @@
25706
25763
  el?.focus({ preventScroll: true });
25707
25764
  }
25708
25765
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
25766
+ owl.onWillUnmount(() => {
25767
+ this.props.onFigureDeleted();
25768
+ });
25709
25769
  }
25710
25770
  clickAnchor(dirX, dirY, ev) {
25711
25771
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -25724,6 +25784,7 @@
25724
25784
  this.props.onFigureDeleted();
25725
25785
  ev.stopPropagation();
25726
25786
  ev.preventDefault();
25787
+ ev.stopPropagation();
25727
25788
  break;
25728
25789
  case "ArrowDown":
25729
25790
  case "ArrowLeft":
@@ -25744,6 +25805,7 @@
25744
25805
  });
25745
25806
  ev.stopPropagation();
25746
25807
  ev.preventDefault();
25808
+ ev.stopPropagation();
25747
25809
  break;
25748
25810
  }
25749
25811
  }
@@ -26425,6 +26487,7 @@
26425
26487
  // -----------------------------------------------------------------------------
26426
26488
  css /* scss */ `
26427
26489
  .o-formula-assistant {
26490
+ background: #ffffff;
26428
26491
  .o-formula-assistant-head {
26429
26492
  background-color: #f2f2f2;
26430
26493
  padding: 10px;
@@ -26475,6 +26538,9 @@
26475
26538
  this.assistantState.allowCellSelectionBehind = false;
26476
26539
  }, 2000);
26477
26540
  }
26541
+ get formulaArgSeparator() {
26542
+ return this.env.model.getters.getLocale().formulaArgSeparator + " ";
26543
+ }
26478
26544
  }
26479
26545
  FunctionDescriptionProvider.props = {
26480
26546
  functionName: String,
@@ -26626,6 +26692,12 @@
26626
26692
  owl.useEffect(() => {
26627
26693
  this.processContent();
26628
26694
  });
26695
+ owl.onPatched(() => {
26696
+ // Required because typing '=SUM' and double-clicking another cell leaves ShowProvider/ShowDescription true
26697
+ if (this.env.model.getters.getEditionMode() === "inactive") {
26698
+ this.processTokenAtCursor();
26699
+ }
26700
+ });
26629
26701
  }
26630
26702
  // ---------------------------------------------------------------------------
26631
26703
  // Handlers
@@ -31818,7 +31890,7 @@
31818
31890
  function getSheetDims(sheet) {
31819
31891
  const dims = [0, 0];
31820
31892
  for (let row of sheet.rows) {
31821
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
31893
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
31822
31894
  dims[1] = Math.max(dims[1], row.index);
31823
31895
  }
31824
31896
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -36708,6 +36780,9 @@
36708
36780
  if (newRule.criterion.type === "isBoolean") {
36709
36781
  this.setCenterStyleToBooleanCells(newRule);
36710
36782
  }
36783
+ else if (newRule.criterion.type === "isValueInList") {
36784
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
36785
+ }
36711
36786
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
36712
36787
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
36713
36788
  if (ruleIndex !== -1) {
@@ -37434,7 +37509,7 @@
37434
37509
  if (hiddenElements.size >= elements) {
37435
37510
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
37436
37511
  }
37437
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
37512
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
37438
37513
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
37439
37514
  }
37440
37515
  else {
@@ -38249,8 +38324,8 @@
38249
38324
  let newRange = range;
38250
38325
  let changeType = "NONE";
38251
38326
  for (let group of groups) {
38252
- const min = Math.min(...group);
38253
- const max = Math.max(...group);
38327
+ const min = largeMin(group);
38328
+ const max = largeMax(group);
38254
38329
  if (range.zone[start] <= min && min <= range.zone[end]) {
38255
38330
  const toRemove = Math.min(range.zone[end], max) - min + 1;
38256
38331
  changeType = "RESIZE";
@@ -38673,8 +38748,8 @@
38673
38748
  }
38674
38749
  return "Success" /* CommandResult.Success */;
38675
38750
  case "REMOVE_COLUMNS_ROWS": {
38676
- const min = Math.min(...cmd.elements);
38677
- const max = Math.max(...cmd.elements);
38751
+ const min = largeMin(cmd.elements);
38752
+ const max = largeMax(cmd.elements);
38678
38753
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
38679
38754
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
38680
38755
  }
@@ -41586,7 +41661,7 @@
41586
41661
  ? getItemId(newFormat, data.formats)
41587
41662
  : exportedCellData.format;
41588
41663
  let content;
41589
- if (formulaCell instanceof FormulaCellWithDependencies) {
41664
+ if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
41590
41665
  content = this.getters.getFormulaCellContent(exportedSheetData.id, formulaCell.compiledFormula, formulaCell.compiledFormula.dependencies, true);
41591
41666
  }
41592
41667
  else {
@@ -42006,13 +42081,13 @@
42006
42081
  .map((cell) => cell.value);
42007
42082
  switch (threshold.type) {
42008
42083
  case "value":
42009
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
42084
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
42010
42085
  return result;
42011
42086
  case "number":
42012
42087
  return Number(threshold.value);
42013
42088
  case "percentage":
42014
- const min = Math.min(...rangeValues);
42015
- const max = Math.max(...rangeValues);
42089
+ const min = largeMin(rangeValues);
42090
+ const max = largeMax(rangeValues);
42016
42091
  const delta = max - min;
42017
42092
  return min + (delta * Number(threshold.value)) / 100;
42018
42093
  case "percentile":
@@ -43064,13 +43139,13 @@
43064
43139
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
43065
43140
  const cellPositions = range(end, -1, -1);
43066
43141
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
43067
- const maxValidPosition = Math.max(...invalidCells);
43142
+ const maxValidPosition = largeMax(invalidCells);
43068
43143
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
43069
43144
  const firstSequence = numberSequences[0] || [];
43070
- if (Math.max(...firstSequence) < maxValidPosition) {
43145
+ if (largeMax(firstSequence) < maxValidPosition) {
43071
43146
  return Infinity;
43072
43147
  }
43073
- return Math.min(...firstSequence);
43148
+ return largeMin(firstSequence);
43074
43149
  }
43075
43150
  shouldFindData(sheetId, zone) {
43076
43151
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -45474,7 +45549,7 @@
45474
45549
  * column of the current viewport
45475
45550
  */
45476
45551
  getColDimensionsInViewport(sheetId, col) {
45477
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
45552
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
45478
45553
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
45479
45554
  const size = this.getters.getColSize(sheetId, col);
45480
45555
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -45489,7 +45564,7 @@
45489
45564
  * of the current viewport
45490
45565
  */
45491
45566
  getRowDimensionsInViewport(sheetId, row) {
45492
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
45567
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
45493
45568
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
45494
45569
  const size = this.getters.getRowSize(sheetId, row);
45495
45570
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -46953,7 +47028,7 @@
46953
47028
  getColMaxWidth(sheetId, index) {
46954
47029
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
46955
47030
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
46956
- return Math.max(0, ...sizes);
47031
+ return Math.max(0, largeMax(sizes));
46957
47032
  }
46958
47033
  /**
46959
47034
  * Check that any "sheetId" in the command matches an existing
@@ -47718,7 +47793,7 @@
47718
47793
  }
47719
47794
  getPasteZone(target) {
47720
47795
  const height = this.values.length;
47721
- const width = Math.max(...this.values.map((a) => a.length));
47796
+ const width = largeMax(this.values.map((a) => a.length));
47722
47797
  const { left: activeCol, top: activeRow } = target[0];
47723
47798
  return {
47724
47799
  top: activeRow,
@@ -48755,11 +48830,11 @@
48755
48830
  }
48756
48831
  else {
48757
48832
  const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
48758
- values = this.getters
48833
+ values = Array.from(new Set(this.getters
48759
48834
  .getRangeValues(range)
48760
48835
  .filter(isNotNull)
48761
48836
  .map((value) => value.toString())
48762
- .filter((val) => val !== "");
48837
+ .filter((val) => val !== "")));
48763
48838
  }
48764
48839
  const composerContent = this.getCurrentContent();
48765
48840
  if (composerContent && composerContent !== this.getInitialComposerContent()) {
@@ -49296,6 +49371,7 @@
49296
49371
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
49297
49372
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
49298
49373
  this.setSelectionMixin(this.gridSelection.anchor, this.gridSelection.zones);
49374
+ this.selectedFigureId = null;
49299
49375
  break;
49300
49376
  }
49301
49377
  /** Any change to the selection has to be reflected in the selection processor. */
@@ -51215,12 +51291,14 @@
51215
51291
  this.editionState = "initializing";
51216
51292
  }
51217
51293
  stopEdition() {
51218
- if (!this.state.isEditing)
51294
+ const input = this.sheetNameRef.el;
51295
+ if (!this.state.isEditing || !input)
51219
51296
  return;
51220
51297
  this.state.isEditing = false;
51221
51298
  this.editionState = "initializing";
51222
- this.sheetNameRef.el?.blur();
51299
+ input.blur();
51223
51300
  const inputValue = this.getInputContent() || "";
51301
+ input.innerText = inputValue;
51224
51302
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
51225
51303
  }
51226
51304
  cancelEdition() {
@@ -51514,7 +51592,7 @@
51514
51592
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
51515
51593
  }
51516
51594
  onSheetMouseDown(sheetId, event) {
51517
- if (event.button !== 0)
51595
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
51518
51596
  return;
51519
51597
  this.closeMenu();
51520
51598
  const visibleSheets = this.getVisibleSheets();
@@ -52873,9 +52951,6 @@
52873
52951
  .text-muted {
52874
52952
  color: grey !important;
52875
52953
  }
52876
- button {
52877
- color: #333;
52878
- }
52879
52954
  .o-disabled {
52880
52955
  opacity: 0.4;
52881
52956
  pointer: default;
@@ -52996,17 +53071,17 @@
52996
53071
  }
52997
53072
 
52998
53073
  .o-button {
52999
- border: 1px solid lightgrey;
53074
+ border: 1px solid;
53000
53075
  padding: 0px 20px 0px 20px;
53001
53076
  border-radius: 4px;
53002
53077
  font-weight: 500;
53003
53078
  font-size: 14px;
53004
53079
  height: 30px;
53005
53080
  line-height: 16px;
53006
- background: white;
53007
53081
  margin-right: 8px;
53008
- &:hover:enabled {
53009
- background-color: rgba(0, 0, 0, 0.08);
53082
+
53083
+ &:not(:hover) {
53084
+ background-color: transparent;
53010
53085
  }
53011
53086
 
53012
53087
  &:enabled {
@@ -53020,6 +53095,15 @@
53020
53095
  &:last-child {
53021
53096
  margin-right: 0px;
53022
53097
  }
53098
+
53099
+ &.o-button-grey {
53100
+ border-color: lightgrey;
53101
+ background: #ffffff;
53102
+ color: #333;
53103
+ &:hover:enabled {
53104
+ background-color: rgba(0, 0, 0, 0.08);
53105
+ }
53106
+ }
53023
53107
  }
53024
53108
 
53025
53109
  .o-input {
@@ -55013,7 +55097,7 @@
55013
55097
  }
55014
55098
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
55015
55099
  const colors = new ChartColors();
55016
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55100
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55017
55101
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
55018
55102
  const dataSetsNodes = [];
55019
55103
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -56967,9 +57051,9 @@
56967
57051
  exports.tokenize = tokenize;
56968
57052
 
56969
57053
 
56970
- __info__.version = "17.0.15";
56971
- __info__.date = "2024-03-15T11:00:59.958Z";
56972
- __info__.hash = "e02add9";
57054
+ __info__.version = "17.0.17";
57055
+ __info__.date = "2024-04-05T13:59:37.139Z";
57056
+ __info__.hash = "33f09d7";
56973
57057
 
56974
57058
 
56975
57059
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);