@odoo/o-spreadsheet 17.1.8 → 17.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.1.8
6
- * @date 2024-03-15T10:59:39.362Z
7
- * @hash bd0c9e0
5
+ * @version 17.1.10
6
+ * @date 2024-04-05T14:00:03.890Z
7
+ * @hash edc821c
8
8
  */
9
9
 
10
10
  import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
@@ -458,7 +458,7 @@ function getItemId(item, itemsDic) {
458
458
  }
459
459
  // Generate new Id if the item didn't exist in the dictionary
460
460
  const ids = Object.keys(itemsDic);
461
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
461
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
462
462
  itemsDic[maxId + 1] = item;
463
463
  return maxId + 1;
464
464
  }
@@ -675,6 +675,34 @@ function isNumberBetween(value, min, max) {
675
675
  }
676
676
  return value >= min && value <= max;
677
677
  }
678
+ /**
679
+ * Alternative to Math.max that works with large arrays.
680
+ * Typically useful for arrays bigger than 100k elements.
681
+ */
682
+ function largeMax(array) {
683
+ let len = array.length;
684
+ if (len < 100000)
685
+ return Math.max(...array);
686
+ let max = -Infinity;
687
+ while (len--) {
688
+ max = array[len] > max ? array[len] : max;
689
+ }
690
+ return max;
691
+ }
692
+ /**
693
+ * Alternative to Math.min that works with large arrays.
694
+ * Typically useful for arrays bigger than 100k elements.
695
+ */
696
+ function largeMin(array) {
697
+ let len = array.length;
698
+ if (len < 100000)
699
+ return Math.min(...array);
700
+ let min = +Infinity;
701
+ while (len--) {
702
+ min = array[len] < min ? array[len] : min;
703
+ }
704
+ return min;
705
+ }
678
706
 
679
707
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
680
708
  const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
@@ -4477,8 +4505,9 @@ function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
4477
4505
  * Get the default height of the cell given its style.
4478
4506
  */
4479
4507
  function getDefaultCellHeight(ctx, cell, colSize) {
4480
- if (!cell || !cell.content)
4508
+ if (!cell || (!cell.isFormula && !cell.content)) {
4481
4509
  return DEFAULT_CELL_HEIGHT;
4510
+ }
4482
4511
  const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4483
4512
  const numberOfLines = cell.isFormula
4484
4513
  ? 1
@@ -8380,10 +8409,10 @@ function aggregateDataForLabels(labels, datasets) {
8380
8409
  }
8381
8410
  }
8382
8411
  return {
8383
- labels: Object.keys(labelMap),
8412
+ labels: Array.from(labelSet),
8384
8413
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
8385
8414
  ...dataset,
8386
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
8415
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
8387
8416
  })),
8388
8417
  };
8389
8418
  }
@@ -9135,7 +9164,7 @@ function getBestTimeUnitForScale(labels, format, locale) {
9135
9164
  return undefined;
9136
9165
  }
9137
9166
  const labelsTimestamps = labelDates.map((date) => date.getTime());
9138
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
9167
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
9139
9168
  const minUnit = getFormatMinDisplayUnit(format);
9140
9169
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
9141
9170
  return "second";
@@ -9607,7 +9636,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
9607
9636
  }
9608
9637
  function getPieColors(colors, dataSetsValues) {
9609
9638
  const pieColors = [];
9610
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
9639
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
9611
9640
  for (let i = 0; i <= maxLength; i++) {
9612
9641
  pieColors.push(colors.next());
9613
9642
  }
@@ -10531,8 +10560,8 @@ const DELETE_CONTENT_ROWS_NAME = (env) => {
10531
10560
  let last;
10532
10561
  const activesRows = env.model.getters.getActiveRows();
10533
10562
  if (activesRows.size !== 0) {
10534
- first = Math.min(...activesRows);
10535
- last = Math.max(...activesRows);
10563
+ first = largeMin([...activesRows]);
10564
+ last = largeMax([...activesRows]);
10536
10565
  }
10537
10566
  else {
10538
10567
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10560,8 +10589,8 @@ const DELETE_CONTENT_COLUMNS_NAME = (env) => {
10560
10589
  let last;
10561
10590
  const activeCols = env.model.getters.getActiveCols();
10562
10591
  if (activeCols.size !== 0) {
10563
- first = Math.min(...activeCols);
10564
- last = Math.max(...activeCols);
10592
+ first = largeMin([...activeCols]);
10593
+ last = largeMax([...activeCols]);
10565
10594
  }
10566
10595
  else {
10567
10596
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10589,8 +10618,8 @@ const REMOVE_ROWS_NAME = (env) => {
10589
10618
  let last;
10590
10619
  const activesRows = env.model.getters.getActiveRows();
10591
10620
  if (activesRows.size !== 0) {
10592
- first = Math.min(...activesRows);
10593
- last = Math.max(...activesRows);
10621
+ first = largeMin([...activesRows]);
10622
+ last = largeMax([...activesRows]);
10594
10623
  }
10595
10624
  else {
10596
10625
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10631,8 +10660,8 @@ const REMOVE_COLUMNS_NAME = (env) => {
10631
10660
  let last;
10632
10661
  const activeCols = env.model.getters.getActiveCols();
10633
10662
  if (activeCols.size !== 0) {
10634
- first = Math.min(...activeCols);
10635
- last = Math.max(...activeCols);
10663
+ first = largeMin([...activeCols]);
10664
+ last = largeMax([...activeCols]);
10636
10665
  }
10637
10666
  else {
10638
10667
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10673,7 +10702,7 @@ const INSERT_ROWS_BEFORE_ACTION = (env) => {
10673
10702
  let row;
10674
10703
  let quantity;
10675
10704
  if (activeRows.size) {
10676
- row = Math.min(...activeRows);
10705
+ row = largeMin([...activeRows]);
10677
10706
  quantity = activeRows.size;
10678
10707
  }
10679
10708
  else {
@@ -10694,7 +10723,7 @@ const INSERT_ROWS_AFTER_ACTION = (env) => {
10694
10723
  let row;
10695
10724
  let quantity;
10696
10725
  if (activeRows.size) {
10697
- row = Math.max(...activeRows);
10726
+ row = largeMax([...activeRows]);
10698
10727
  quantity = activeRows.size;
10699
10728
  }
10700
10729
  else {
@@ -10715,7 +10744,7 @@ const INSERT_COLUMNS_BEFORE_ACTION = (env) => {
10715
10744
  let column;
10716
10745
  let quantity;
10717
10746
  if (activeCols.size) {
10718
- column = Math.min(...activeCols);
10747
+ column = largeMin([...activeCols]);
10719
10748
  quantity = activeCols.size;
10720
10749
  }
10721
10750
  else {
@@ -10736,7 +10765,7 @@ const INSERT_COLUMNS_AFTER_ACTION = (env) => {
10736
10765
  let column;
10737
10766
  let quantity;
10738
10767
  if (activeCols.size) {
10739
- column = Math.max(...activeCols);
10768
+ column = largeMax([...activeCols]);
10740
10769
  quantity = activeCols.size;
10741
10770
  }
10742
10771
  else {
@@ -11127,6 +11156,9 @@ function makeArg(str, description) {
11127
11156
  result.default = true;
11128
11157
  result.defaultValue = defaultValue;
11129
11158
  }
11159
+ if (types.some((t) => t.startsWith("RANGE"))) {
11160
+ result.acceptMatrix = true;
11161
+ }
11130
11162
  return result;
11131
11163
  }
11132
11164
  /**
@@ -19722,11 +19754,27 @@ class FunctionRegistry extends Registry {
19722
19754
  }
19723
19755
  const descr = addMetaInfoFromArg(addDescr);
19724
19756
  validateArguments(descr.args);
19725
- this.mapping[name] = addErrorHandling(addResultHandling(descr.compute), name);
19757
+ this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr)), name);
19726
19758
  super.add(name, descr);
19727
19759
  return this;
19728
19760
  }
19729
19761
  }
19762
+ function addInputHandling(descr) {
19763
+ function computeWithInputHandling(...args) {
19764
+ for (let i = 0; i < args.length; i++) {
19765
+ const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
19766
+ const arg = args[i];
19767
+ if (isMatrix(arg) && !argDefinition.acceptMatrix) {
19768
+ if (arg.length !== 1 || arg[0].length !== 1) {
19769
+ throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be a single value or a single cell reference, not a range.", argDefinition.name));
19770
+ }
19771
+ args[i] = arg[0][0];
19772
+ }
19773
+ }
19774
+ return descr.compute.apply(this, args);
19775
+ }
19776
+ return computeWithInputHandling;
19777
+ }
19730
19778
  function addErrorHandling(compute, functionName) {
19731
19779
  return function (...args) {
19732
19780
  try {
@@ -19977,14 +20025,19 @@ const categorieFunctionAll = {
19977
20025
  children: [allFunctionListMenuBuilder],
19978
20026
  };
19979
20027
  function allFunctionListMenuBuilder() {
19980
- const fnNames = functionRegistry.getKeys();
20028
+ const fnNames = functionRegistry.getKeys().filter((key) => !functionRegistry.get(key).hidden);
19981
20029
  return createFormulaFunctions(fnNames);
19982
20030
  }
19983
20031
  const categoriesFunctionListMenuBuilder = () => {
19984
20032
  const functions = functionRegistry.content;
19985
- const categories = [...new Set(functionRegistry.getAll().map((fn) => fn.category))].filter(isDefined$1);
20033
+ const categories = [
20034
+ ...new Set(functionRegistry
20035
+ .getAll()
20036
+ .filter((fn) => !fn.hidden)
20037
+ .map((fn) => fn.category)),
20038
+ ].filter(isDefined$1);
19986
20039
  return categories.sort().map((category, i) => {
19987
- const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category);
20040
+ const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category && !functions[key].hidden);
19988
20041
  return {
19989
20042
  name: category,
19990
20043
  children: createFormulaFunctions(functionsInCategory),
@@ -23773,11 +23826,9 @@ css /* scss */ `
23773
23826
  }
23774
23827
  .o-cell-is-operator {
23775
23828
  margin-bottom: 5px;
23776
- width: 96%;
23777
23829
  }
23778
23830
  .o-cell-is-value {
23779
23831
  margin-bottom: 5px;
23780
- width: 96%;
23781
23832
  }
23782
23833
  .o-color-picker-widget .o-color-picker-button {
23783
23834
  pointer-events: all;
@@ -26197,6 +26248,9 @@ class FigureComponent extends Component {
26197
26248
  el?.focus({ preventScroll: true });
26198
26249
  }
26199
26250
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
26251
+ onWillUnmount(() => {
26252
+ this.props.onFigureDeleted();
26253
+ });
26200
26254
  }
26201
26255
  clickAnchor(dirX, dirY, ev) {
26202
26256
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -26215,6 +26269,7 @@ class FigureComponent extends Component {
26215
26269
  this.props.onFigureDeleted();
26216
26270
  ev.stopPropagation();
26217
26271
  ev.preventDefault();
26272
+ ev.stopPropagation();
26218
26273
  break;
26219
26274
  case "ArrowDown":
26220
26275
  case "ArrowLeft":
@@ -26235,6 +26290,7 @@ class FigureComponent extends Component {
26235
26290
  });
26236
26291
  ev.stopPropagation();
26237
26292
  ev.preventDefault();
26293
+ ev.stopPropagation();
26238
26294
  break;
26239
26295
  }
26240
26296
  }
@@ -26909,6 +26965,7 @@ function compareContentToSpanElement(content, node) {
26909
26965
  // -----------------------------------------------------------------------------
26910
26966
  css /* scss */ `
26911
26967
  .o-formula-assistant {
26968
+ background: #ffffff;
26912
26969
  .o-formula-assistant-head {
26913
26970
  background-color: #f2f2f2;
26914
26971
  padding: 10px;
@@ -26964,6 +27021,9 @@ class FunctionDescriptionProvider extends Component {
26964
27021
  this.assistantState.allowCellSelectionBehind = false;
26965
27022
  }, 2000);
26966
27023
  }
27024
+ get formulaArgSeparator() {
27025
+ return this.env.model.getters.getLocale().formulaArgSeparator + " ";
27026
+ }
26967
27027
  }
26968
27028
 
26969
27029
  const functions$2 = functionRegistry.content;
@@ -27121,6 +27181,12 @@ class Composer extends Component {
27121
27181
  useEffect(() => {
27122
27182
  this.processContent();
27123
27183
  });
27184
+ onPatched(() => {
27185
+ // Required because typing '=SUM' and double-clicking another cell leaves ShowProvider/ShowDescription true
27186
+ if (this.env.model.getters.getEditionMode() === "inactive") {
27187
+ this.processTokenAtCursor();
27188
+ }
27189
+ });
27124
27190
  }
27125
27191
  // ---------------------------------------------------------------------------
27126
27192
  // Handlers
@@ -29180,11 +29246,6 @@ css /* scss */ `
29180
29246
  height: 10000px;
29181
29247
  background-color: ${SELECTION_BORDER_COLOR};
29182
29248
  }
29183
- .o-unhide-buttons {
29184
- width: fit-content;
29185
- gap: 5px;
29186
- transform: translate(-50%, 0);
29187
- }
29188
29249
  .o-unhide:hover {
29189
29250
  z-index: ${ComponentsImportance.Grid + 1};
29190
29251
  background-color: lightgrey;
@@ -29346,10 +29407,6 @@ css /* scss */ `
29346
29407
  height: 1px;
29347
29408
  background-color: ${SELECTION_BORDER_COLOR};
29348
29409
  }
29349
- .o-unhide-buttons {
29350
- height: fit-content;
29351
- transform: translate(0, -50%);
29352
- }
29353
29410
  .o-unhide:hover {
29354
29411
  z-index: ${ComponentsImportance.Grid + 1};
29355
29412
  background-color: lightgrey;
@@ -32290,7 +32347,7 @@ function convertHyperlink(link, cellValue, warningManager) {
32290
32347
  function getSheetDims(sheet) {
32291
32348
  const dims = [0, 0];
32292
32349
  for (let row of sheet.rows) {
32293
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
32350
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
32294
32351
  dims[1] = Math.max(dims[1], row.index);
32295
32352
  }
32296
32353
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -37190,6 +37247,9 @@ class DataValidationPlugin extends CorePlugin {
37190
37247
  if (newRule.criterion.type === "isBoolean") {
37191
37248
  this.setCenterStyleToBooleanCells(newRule);
37192
37249
  }
37250
+ else if (newRule.criterion.type === "isValueInList") {
37251
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
37252
+ }
37193
37253
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
37194
37254
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
37195
37255
  if (ruleIndex !== -1) {
@@ -37916,7 +37976,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
37916
37976
  if (hiddenElements.size >= elements) {
37917
37977
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
37918
37978
  }
37919
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
37979
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
37920
37980
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
37921
37981
  }
37922
37982
  else {
@@ -38731,8 +38791,8 @@ class RangeAdapter {
38731
38791
  let newRange = range;
38732
38792
  let changeType = "NONE";
38733
38793
  for (let group of groups) {
38734
- const min = Math.min(...group);
38735
- const max = Math.max(...group);
38794
+ const min = largeMin(group);
38795
+ const max = largeMax(group);
38736
38796
  if (range.zone[start] <= min && min <= range.zone[end]) {
38737
38797
  const toRemove = Math.min(range.zone[end], max) - min + 1;
38738
38798
  changeType = "RESIZE";
@@ -39155,8 +39215,8 @@ class SheetPlugin extends CorePlugin {
39155
39215
  }
39156
39216
  return "Success" /* CommandResult.Success */;
39157
39217
  case "REMOVE_COLUMNS_ROWS": {
39158
- const min = Math.min(...cmd.elements);
39159
- const max = Math.max(...cmd.elements);
39218
+ const min = largeMin(cmd.elements);
39219
+ const max = largeMax(cmd.elements);
39160
39220
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
39161
39221
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
39162
39222
  }
@@ -42064,7 +42124,7 @@ class EvaluationPlugin extends UIPlugin {
42064
42124
  ? getItemId(newFormat, data.formats)
42065
42125
  : exportedCellData.format;
42066
42126
  let content;
42067
- if (formulaCell instanceof FormulaCellWithDependencies) {
42127
+ if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42068
42128
  content = formulaCell.contentWithFixedReferences;
42069
42129
  }
42070
42130
  else {
@@ -42485,13 +42545,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
42485
42545
  .map((cell) => cell.value);
42486
42546
  switch (threshold.type) {
42487
42547
  case "value":
42488
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
42548
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
42489
42549
  return result;
42490
42550
  case "number":
42491
42551
  return Number(threshold.value);
42492
42552
  case "percentage":
42493
- const min = Math.min(...rangeValues);
42494
- const max = Math.max(...rangeValues);
42553
+ const min = largeMin(rangeValues);
42554
+ const max = largeMax(rangeValues);
42495
42555
  const delta = max - min;
42496
42556
  return min + (delta * Number(threshold.value)) / 100;
42497
42557
  case "percentile":
@@ -43533,13 +43593,13 @@ class AutomaticSumPlugin extends UIPlugin {
43533
43593
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
43534
43594
  const cellPositions = range(end, -1, -1);
43535
43595
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
43536
- const maxValidPosition = Math.max(...invalidCells);
43596
+ const maxValidPosition = largeMax(invalidCells);
43537
43597
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
43538
43598
  const firstSequence = numberSequences[0] || [];
43539
- if (Math.max(...firstSequence) < maxValidPosition) {
43599
+ if (largeMax(firstSequence) < maxValidPosition) {
43540
43600
  return Infinity;
43541
43601
  }
43542
- return Math.min(...firstSequence);
43602
+ return largeMin(firstSequence);
43543
43603
  }
43544
43604
  shouldFindData(sheetId, zone) {
43545
43605
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -46032,7 +46092,7 @@ class RendererPlugin extends UIPlugin {
46032
46092
  * column of the current viewport
46033
46093
  */
46034
46094
  getColDimensionsInViewport(sheetId, col) {
46035
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
46095
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
46036
46096
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
46037
46097
  const size = this.getters.getColSize(sheetId, col);
46038
46098
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -46047,7 +46107,7 @@ class RendererPlugin extends UIPlugin {
46047
46107
  * of the current viewport
46048
46108
  */
46049
46109
  getRowDimensionsInViewport(sheetId, row) {
46050
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
46110
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
46051
46111
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
46052
46112
  const size = this.getters.getRowSize(sheetId, row);
46053
46113
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -47430,7 +47490,7 @@ class SheetUIPlugin extends UIPlugin {
47430
47490
  getColMaxWidth(sheetId, index) {
47431
47491
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
47432
47492
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
47433
- return Math.max(0, ...sizes);
47493
+ return Math.max(0, largeMax(sizes));
47434
47494
  }
47435
47495
  /**
47436
47496
  * Check that any "sheetId" in the command matches an existing
@@ -48197,7 +48257,7 @@ class ClipboardOsState extends ClipboardCellsAbstractState {
48197
48257
  }
48198
48258
  getPasteZone(target) {
48199
48259
  const height = this.values.length;
48200
- const width = Math.max(...this.values.map((a) => a.length));
48260
+ const width = largeMax(this.values.map((a) => a.length));
48201
48261
  const { left: activeCol, top: activeRow } = target[0];
48202
48262
  return {
48203
48263
  top: activeRow,
@@ -49143,11 +49203,11 @@ class EditionPlugin extends UIPlugin {
49143
49203
  }
49144
49204
  else {
49145
49205
  const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
49146
- values = this.getters
49206
+ values = Array.from(new Set(this.getters
49147
49207
  .getRangeValues(range)
49148
49208
  .filter(isNotNull)
49149
49209
  .map((value) => value.toString())
49150
- .filter((val) => val !== "");
49210
+ .filter((val) => val !== "")));
49151
49211
  }
49152
49212
  const composerContent = this.getCurrentContent();
49153
49213
  if (composerContent && composerContent !== this.getInitialComposerContent()) {
@@ -49684,6 +49744,7 @@ class GridSelectionPlugin extends UIPlugin {
49684
49744
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
49685
49745
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
49686
49746
  this.setSelectionMixin(this.gridSelection.anchor, this.gridSelection.zones);
49747
+ this.selectedFigureId = null;
49687
49748
  break;
49688
49749
  }
49689
49750
  /** Any change to the selection has to be reflected in the selection processor. */
@@ -51578,12 +51639,14 @@ class BottomBarSheet extends Component {
51578
51639
  this.editionState = "initializing";
51579
51640
  }
51580
51641
  stopEdition() {
51581
- if (!this.state.isEditing)
51642
+ const input = this.sheetNameRef.el;
51643
+ if (!this.state.isEditing || !input)
51582
51644
  return;
51583
51645
  this.state.isEditing = false;
51584
51646
  this.editionState = "initializing";
51585
- this.sheetNameRef.el?.blur();
51647
+ input.blur();
51586
51648
  const inputValue = this.getInputContent() || "";
51649
+ input.innerText = inputValue;
51587
51650
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
51588
51651
  }
51589
51652
  cancelEdition() {
@@ -51874,7 +51937,7 @@ class BottomBar extends Component {
51874
51937
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
51875
51938
  }
51876
51939
  onSheetMouseDown(sheetId, event) {
51877
- if (event.button !== 0)
51940
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
51878
51941
  return;
51879
51942
  this.closeMenu();
51880
51943
  const visibleSheets = this.getVisibleSheets();
@@ -53224,9 +53287,6 @@ css /* scss */ `
53224
53287
  .text-muted {
53225
53288
  color: grey !important;
53226
53289
  }
53227
- button {
53228
- color: #333;
53229
- }
53230
53290
  .o-disabled {
53231
53291
  opacity: 0.4;
53232
53292
  pointer: default;
@@ -53347,17 +53407,17 @@ css /* scss */ `
53347
53407
  }
53348
53408
 
53349
53409
  .o-button {
53350
- border: 1px solid lightgrey;
53410
+ border: 1px solid;
53351
53411
  padding: 0px 20px 0px 20px;
53352
53412
  border-radius: 4px;
53353
53413
  font-weight: 500;
53354
53414
  font-size: 14px;
53355
53415
  height: 30px;
53356
53416
  line-height: 16px;
53357
- background: white;
53358
53417
  margin-right: 8px;
53359
- &:hover:enabled {
53360
- background-color: rgba(0, 0, 0, 0.08);
53418
+
53419
+ &:not(:hover) {
53420
+ background-color: transparent;
53361
53421
  }
53362
53422
 
53363
53423
  &:enabled {
@@ -53371,6 +53431,15 @@ css /* scss */ `
53371
53431
  &:last-child {
53372
53432
  margin-right: 0px;
53373
53433
  }
53434
+
53435
+ &.o-button-grey {
53436
+ border-color: lightgrey;
53437
+ background: #ffffff;
53438
+ color: #333;
53439
+ &:hover:enabled {
53440
+ background-color: rgba(0, 0, 0, 0.08);
53441
+ }
53442
+ }
53374
53443
  }
53375
53444
 
53376
53445
  .o-input {
@@ -55322,7 +55391,7 @@ function addLineChart(chart) {
55322
55391
  }
55323
55392
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
55324
55393
  const colors = new ChartColors();
55325
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55394
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55326
55395
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
55327
55396
  const dataSetsNodes = [];
55328
55397
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -57250,6 +57319,6 @@ const constants = {
57250
57319
  export { AbstractChart, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
57251
57320
 
57252
57321
 
57253
- __info__.version = "17.1.8";
57254
- __info__.date = "2024-03-15T10:59:39.362Z";
57255
- __info__.hash = "bd0c9e0";
57322
+ __info__.version = "17.1.10";
57323
+ __info__.date = "2024-04-05T14:00:03.890Z";
57324
+ __info__.hash = "edc821c";