@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
  'use strict';
@@ -460,7 +460,7 @@ function getItemId(item, itemsDic) {
460
460
  }
461
461
  // Generate new Id if the item didn't exist in the dictionary
462
462
  const ids = Object.keys(itemsDic);
463
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
463
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
464
464
  itemsDic[maxId + 1] = item;
465
465
  return maxId + 1;
466
466
  }
@@ -677,6 +677,34 @@ function isNumberBetween(value, min, max) {
677
677
  }
678
678
  return value >= min && value <= max;
679
679
  }
680
+ /**
681
+ * Alternative to Math.max that works with large arrays.
682
+ * Typically useful for arrays bigger than 100k elements.
683
+ */
684
+ function largeMax(array) {
685
+ let len = array.length;
686
+ if (len < 100000)
687
+ return Math.max(...array);
688
+ let max = -Infinity;
689
+ while (len--) {
690
+ max = array[len] > max ? array[len] : max;
691
+ }
692
+ return max;
693
+ }
694
+ /**
695
+ * Alternative to Math.min that works with large arrays.
696
+ * Typically useful for arrays bigger than 100k elements.
697
+ */
698
+ function largeMin(array) {
699
+ let len = array.length;
700
+ if (len < 100000)
701
+ return Math.min(...array);
702
+ let min = +Infinity;
703
+ while (len--) {
704
+ min = array[len] < min ? array[len] : min;
705
+ }
706
+ return min;
707
+ }
680
708
 
681
709
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
682
710
  const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
@@ -4479,8 +4507,9 @@ function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
4479
4507
  * Get the default height of the cell given its style.
4480
4508
  */
4481
4509
  function getDefaultCellHeight(ctx, cell, colSize) {
4482
- if (!cell || !cell.content)
4510
+ if (!cell || (!cell.isFormula && !cell.content)) {
4483
4511
  return DEFAULT_CELL_HEIGHT;
4512
+ }
4484
4513
  const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4485
4514
  const numberOfLines = cell.isFormula
4486
4515
  ? 1
@@ -8382,10 +8411,10 @@ function aggregateDataForLabels(labels, datasets) {
8382
8411
  }
8383
8412
  }
8384
8413
  return {
8385
- labels: Object.keys(labelMap),
8414
+ labels: Array.from(labelSet),
8386
8415
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
8387
8416
  ...dataset,
8388
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
8417
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
8389
8418
  })),
8390
8419
  };
8391
8420
  }
@@ -9137,7 +9166,7 @@ function getBestTimeUnitForScale(labels, format, locale) {
9137
9166
  return undefined;
9138
9167
  }
9139
9168
  const labelsTimestamps = labelDates.map((date) => date.getTime());
9140
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
9169
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
9141
9170
  const minUnit = getFormatMinDisplayUnit(format);
9142
9171
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
9143
9172
  return "second";
@@ -9609,7 +9638,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
9609
9638
  }
9610
9639
  function getPieColors(colors, dataSetsValues) {
9611
9640
  const pieColors = [];
9612
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
9641
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
9613
9642
  for (let i = 0; i <= maxLength; i++) {
9614
9643
  pieColors.push(colors.next());
9615
9644
  }
@@ -10533,8 +10562,8 @@ const DELETE_CONTENT_ROWS_NAME = (env) => {
10533
10562
  let last;
10534
10563
  const activesRows = env.model.getters.getActiveRows();
10535
10564
  if (activesRows.size !== 0) {
10536
- first = Math.min(...activesRows);
10537
- last = Math.max(...activesRows);
10565
+ first = largeMin([...activesRows]);
10566
+ last = largeMax([...activesRows]);
10538
10567
  }
10539
10568
  else {
10540
10569
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10562,8 +10591,8 @@ const DELETE_CONTENT_COLUMNS_NAME = (env) => {
10562
10591
  let last;
10563
10592
  const activeCols = env.model.getters.getActiveCols();
10564
10593
  if (activeCols.size !== 0) {
10565
- first = Math.min(...activeCols);
10566
- last = Math.max(...activeCols);
10594
+ first = largeMin([...activeCols]);
10595
+ last = largeMax([...activeCols]);
10567
10596
  }
10568
10597
  else {
10569
10598
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10591,8 +10620,8 @@ const REMOVE_ROWS_NAME = (env) => {
10591
10620
  let last;
10592
10621
  const activesRows = env.model.getters.getActiveRows();
10593
10622
  if (activesRows.size !== 0) {
10594
- first = Math.min(...activesRows);
10595
- last = Math.max(...activesRows);
10623
+ first = largeMin([...activesRows]);
10624
+ last = largeMax([...activesRows]);
10596
10625
  }
10597
10626
  else {
10598
10627
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10633,8 +10662,8 @@ const REMOVE_COLUMNS_NAME = (env) => {
10633
10662
  let last;
10634
10663
  const activeCols = env.model.getters.getActiveCols();
10635
10664
  if (activeCols.size !== 0) {
10636
- first = Math.min(...activeCols);
10637
- last = Math.max(...activeCols);
10665
+ first = largeMin([...activeCols]);
10666
+ last = largeMax([...activeCols]);
10638
10667
  }
10639
10668
  else {
10640
10669
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10675,7 +10704,7 @@ const INSERT_ROWS_BEFORE_ACTION = (env) => {
10675
10704
  let row;
10676
10705
  let quantity;
10677
10706
  if (activeRows.size) {
10678
- row = Math.min(...activeRows);
10707
+ row = largeMin([...activeRows]);
10679
10708
  quantity = activeRows.size;
10680
10709
  }
10681
10710
  else {
@@ -10696,7 +10725,7 @@ const INSERT_ROWS_AFTER_ACTION = (env) => {
10696
10725
  let row;
10697
10726
  let quantity;
10698
10727
  if (activeRows.size) {
10699
- row = Math.max(...activeRows);
10728
+ row = largeMax([...activeRows]);
10700
10729
  quantity = activeRows.size;
10701
10730
  }
10702
10731
  else {
@@ -10717,7 +10746,7 @@ const INSERT_COLUMNS_BEFORE_ACTION = (env) => {
10717
10746
  let column;
10718
10747
  let quantity;
10719
10748
  if (activeCols.size) {
10720
- column = Math.min(...activeCols);
10749
+ column = largeMin([...activeCols]);
10721
10750
  quantity = activeCols.size;
10722
10751
  }
10723
10752
  else {
@@ -10738,7 +10767,7 @@ const INSERT_COLUMNS_AFTER_ACTION = (env) => {
10738
10767
  let column;
10739
10768
  let quantity;
10740
10769
  if (activeCols.size) {
10741
- column = Math.max(...activeCols);
10770
+ column = largeMax([...activeCols]);
10742
10771
  quantity = activeCols.size;
10743
10772
  }
10744
10773
  else {
@@ -11129,6 +11158,9 @@ function makeArg(str, description) {
11129
11158
  result.default = true;
11130
11159
  result.defaultValue = defaultValue;
11131
11160
  }
11161
+ if (types.some((t) => t.startsWith("RANGE"))) {
11162
+ result.acceptMatrix = true;
11163
+ }
11132
11164
  return result;
11133
11165
  }
11134
11166
  /**
@@ -19724,11 +19756,27 @@ class FunctionRegistry extends Registry {
19724
19756
  }
19725
19757
  const descr = addMetaInfoFromArg(addDescr);
19726
19758
  validateArguments(descr.args);
19727
- this.mapping[name] = addErrorHandling(addResultHandling(descr.compute), name);
19759
+ this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr)), name);
19728
19760
  super.add(name, descr);
19729
19761
  return this;
19730
19762
  }
19731
19763
  }
19764
+ function addInputHandling(descr) {
19765
+ function computeWithInputHandling(...args) {
19766
+ for (let i = 0; i < args.length; i++) {
19767
+ const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
19768
+ const arg = args[i];
19769
+ if (isMatrix(arg) && !argDefinition.acceptMatrix) {
19770
+ if (arg.length !== 1 || arg[0].length !== 1) {
19771
+ 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));
19772
+ }
19773
+ args[i] = arg[0][0];
19774
+ }
19775
+ }
19776
+ return descr.compute.apply(this, args);
19777
+ }
19778
+ return computeWithInputHandling;
19779
+ }
19732
19780
  function addErrorHandling(compute, functionName) {
19733
19781
  return function (...args) {
19734
19782
  try {
@@ -19979,14 +20027,19 @@ const categorieFunctionAll = {
19979
20027
  children: [allFunctionListMenuBuilder],
19980
20028
  };
19981
20029
  function allFunctionListMenuBuilder() {
19982
- const fnNames = functionRegistry.getKeys();
20030
+ const fnNames = functionRegistry.getKeys().filter((key) => !functionRegistry.get(key).hidden);
19983
20031
  return createFormulaFunctions(fnNames);
19984
20032
  }
19985
20033
  const categoriesFunctionListMenuBuilder = () => {
19986
20034
  const functions = functionRegistry.content;
19987
- const categories = [...new Set(functionRegistry.getAll().map((fn) => fn.category))].filter(isDefined$1);
20035
+ const categories = [
20036
+ ...new Set(functionRegistry
20037
+ .getAll()
20038
+ .filter((fn) => !fn.hidden)
20039
+ .map((fn) => fn.category)),
20040
+ ].filter(isDefined$1);
19988
20041
  return categories.sort().map((category, i) => {
19989
- const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category);
20042
+ const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category && !functions[key].hidden);
19990
20043
  return {
19991
20044
  name: category,
19992
20045
  children: createFormulaFunctions(functionsInCategory),
@@ -23775,11 +23828,9 @@ css /* scss */ `
23775
23828
  }
23776
23829
  .o-cell-is-operator {
23777
23830
  margin-bottom: 5px;
23778
- width: 96%;
23779
23831
  }
23780
23832
  .o-cell-is-value {
23781
23833
  margin-bottom: 5px;
23782
- width: 96%;
23783
23834
  }
23784
23835
  .o-color-picker-widget .o-color-picker-button {
23785
23836
  pointer-events: all;
@@ -26199,6 +26250,9 @@ class FigureComponent extends owl.Component {
26199
26250
  el?.focus({ preventScroll: true });
26200
26251
  }
26201
26252
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
26253
+ owl.onWillUnmount(() => {
26254
+ this.props.onFigureDeleted();
26255
+ });
26202
26256
  }
26203
26257
  clickAnchor(dirX, dirY, ev) {
26204
26258
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -26217,6 +26271,7 @@ class FigureComponent extends owl.Component {
26217
26271
  this.props.onFigureDeleted();
26218
26272
  ev.stopPropagation();
26219
26273
  ev.preventDefault();
26274
+ ev.stopPropagation();
26220
26275
  break;
26221
26276
  case "ArrowDown":
26222
26277
  case "ArrowLeft":
@@ -26237,6 +26292,7 @@ class FigureComponent extends owl.Component {
26237
26292
  });
26238
26293
  ev.stopPropagation();
26239
26294
  ev.preventDefault();
26295
+ ev.stopPropagation();
26240
26296
  break;
26241
26297
  }
26242
26298
  }
@@ -26911,6 +26967,7 @@ function compareContentToSpanElement(content, node) {
26911
26967
  // -----------------------------------------------------------------------------
26912
26968
  css /* scss */ `
26913
26969
  .o-formula-assistant {
26970
+ background: #ffffff;
26914
26971
  .o-formula-assistant-head {
26915
26972
  background-color: #f2f2f2;
26916
26973
  padding: 10px;
@@ -26966,6 +27023,9 @@ class FunctionDescriptionProvider extends owl.Component {
26966
27023
  this.assistantState.allowCellSelectionBehind = false;
26967
27024
  }, 2000);
26968
27025
  }
27026
+ get formulaArgSeparator() {
27027
+ return this.env.model.getters.getLocale().formulaArgSeparator + " ";
27028
+ }
26969
27029
  }
26970
27030
 
26971
27031
  const functions$2 = functionRegistry.content;
@@ -27123,6 +27183,12 @@ class Composer extends owl.Component {
27123
27183
  owl.useEffect(() => {
27124
27184
  this.processContent();
27125
27185
  });
27186
+ owl.onPatched(() => {
27187
+ // Required because typing '=SUM' and double-clicking another cell leaves ShowProvider/ShowDescription true
27188
+ if (this.env.model.getters.getEditionMode() === "inactive") {
27189
+ this.processTokenAtCursor();
27190
+ }
27191
+ });
27126
27192
  }
27127
27193
  // ---------------------------------------------------------------------------
27128
27194
  // Handlers
@@ -29182,11 +29248,6 @@ css /* scss */ `
29182
29248
  height: 10000px;
29183
29249
  background-color: ${SELECTION_BORDER_COLOR};
29184
29250
  }
29185
- .o-unhide-buttons {
29186
- width: fit-content;
29187
- gap: 5px;
29188
- transform: translate(-50%, 0);
29189
- }
29190
29251
  .o-unhide:hover {
29191
29252
  z-index: ${ComponentsImportance.Grid + 1};
29192
29253
  background-color: lightgrey;
@@ -29348,10 +29409,6 @@ css /* scss */ `
29348
29409
  height: 1px;
29349
29410
  background-color: ${SELECTION_BORDER_COLOR};
29350
29411
  }
29351
- .o-unhide-buttons {
29352
- height: fit-content;
29353
- transform: translate(0, -50%);
29354
- }
29355
29412
  .o-unhide:hover {
29356
29413
  z-index: ${ComponentsImportance.Grid + 1};
29357
29414
  background-color: lightgrey;
@@ -32292,7 +32349,7 @@ function convertHyperlink(link, cellValue, warningManager) {
32292
32349
  function getSheetDims(sheet) {
32293
32350
  const dims = [0, 0];
32294
32351
  for (let row of sheet.rows) {
32295
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
32352
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
32296
32353
  dims[1] = Math.max(dims[1], row.index);
32297
32354
  }
32298
32355
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -37192,6 +37249,9 @@ class DataValidationPlugin extends CorePlugin {
37192
37249
  if (newRule.criterion.type === "isBoolean") {
37193
37250
  this.setCenterStyleToBooleanCells(newRule);
37194
37251
  }
37252
+ else if (newRule.criterion.type === "isValueInList") {
37253
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
37254
+ }
37195
37255
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
37196
37256
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
37197
37257
  if (ruleIndex !== -1) {
@@ -37918,7 +37978,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
37918
37978
  if (hiddenElements.size >= elements) {
37919
37979
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
37920
37980
  }
37921
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
37981
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
37922
37982
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
37923
37983
  }
37924
37984
  else {
@@ -38733,8 +38793,8 @@ class RangeAdapter {
38733
38793
  let newRange = range;
38734
38794
  let changeType = "NONE";
38735
38795
  for (let group of groups) {
38736
- const min = Math.min(...group);
38737
- const max = Math.max(...group);
38796
+ const min = largeMin(group);
38797
+ const max = largeMax(group);
38738
38798
  if (range.zone[start] <= min && min <= range.zone[end]) {
38739
38799
  const toRemove = Math.min(range.zone[end], max) - min + 1;
38740
38800
  changeType = "RESIZE";
@@ -39157,8 +39217,8 @@ class SheetPlugin extends CorePlugin {
39157
39217
  }
39158
39218
  return "Success" /* CommandResult.Success */;
39159
39219
  case "REMOVE_COLUMNS_ROWS": {
39160
- const min = Math.min(...cmd.elements);
39161
- const max = Math.max(...cmd.elements);
39220
+ const min = largeMin(cmd.elements);
39221
+ const max = largeMax(cmd.elements);
39162
39222
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
39163
39223
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
39164
39224
  }
@@ -42066,7 +42126,7 @@ class EvaluationPlugin extends UIPlugin {
42066
42126
  ? getItemId(newFormat, data.formats)
42067
42127
  : exportedCellData.format;
42068
42128
  let content;
42069
- if (formulaCell instanceof FormulaCellWithDependencies) {
42129
+ if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42070
42130
  content = formulaCell.contentWithFixedReferences;
42071
42131
  }
42072
42132
  else {
@@ -42487,13 +42547,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
42487
42547
  .map((cell) => cell.value);
42488
42548
  switch (threshold.type) {
42489
42549
  case "value":
42490
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
42550
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
42491
42551
  return result;
42492
42552
  case "number":
42493
42553
  return Number(threshold.value);
42494
42554
  case "percentage":
42495
- const min = Math.min(...rangeValues);
42496
- const max = Math.max(...rangeValues);
42555
+ const min = largeMin(rangeValues);
42556
+ const max = largeMax(rangeValues);
42497
42557
  const delta = max - min;
42498
42558
  return min + (delta * Number(threshold.value)) / 100;
42499
42559
  case "percentile":
@@ -43535,13 +43595,13 @@ class AutomaticSumPlugin extends UIPlugin {
43535
43595
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
43536
43596
  const cellPositions = range(end, -1, -1);
43537
43597
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
43538
- const maxValidPosition = Math.max(...invalidCells);
43598
+ const maxValidPosition = largeMax(invalidCells);
43539
43599
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
43540
43600
  const firstSequence = numberSequences[0] || [];
43541
- if (Math.max(...firstSequence) < maxValidPosition) {
43601
+ if (largeMax(firstSequence) < maxValidPosition) {
43542
43602
  return Infinity;
43543
43603
  }
43544
- return Math.min(...firstSequence);
43604
+ return largeMin(firstSequence);
43545
43605
  }
43546
43606
  shouldFindData(sheetId, zone) {
43547
43607
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -46034,7 +46094,7 @@ class RendererPlugin extends UIPlugin {
46034
46094
  * column of the current viewport
46035
46095
  */
46036
46096
  getColDimensionsInViewport(sheetId, col) {
46037
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
46097
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
46038
46098
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
46039
46099
  const size = this.getters.getColSize(sheetId, col);
46040
46100
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -46049,7 +46109,7 @@ class RendererPlugin extends UIPlugin {
46049
46109
  * of the current viewport
46050
46110
  */
46051
46111
  getRowDimensionsInViewport(sheetId, row) {
46052
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
46112
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
46053
46113
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
46054
46114
  const size = this.getters.getRowSize(sheetId, row);
46055
46115
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -47432,7 +47492,7 @@ class SheetUIPlugin extends UIPlugin {
47432
47492
  getColMaxWidth(sheetId, index) {
47433
47493
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
47434
47494
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
47435
- return Math.max(0, ...sizes);
47495
+ return Math.max(0, largeMax(sizes));
47436
47496
  }
47437
47497
  /**
47438
47498
  * Check that any "sheetId" in the command matches an existing
@@ -48199,7 +48259,7 @@ class ClipboardOsState extends ClipboardCellsAbstractState {
48199
48259
  }
48200
48260
  getPasteZone(target) {
48201
48261
  const height = this.values.length;
48202
- const width = Math.max(...this.values.map((a) => a.length));
48262
+ const width = largeMax(this.values.map((a) => a.length));
48203
48263
  const { left: activeCol, top: activeRow } = target[0];
48204
48264
  return {
48205
48265
  top: activeRow,
@@ -49145,11 +49205,11 @@ class EditionPlugin extends UIPlugin {
49145
49205
  }
49146
49206
  else {
49147
49207
  const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
49148
- values = this.getters
49208
+ values = Array.from(new Set(this.getters
49149
49209
  .getRangeValues(range)
49150
49210
  .filter(isNotNull)
49151
49211
  .map((value) => value.toString())
49152
- .filter((val) => val !== "");
49212
+ .filter((val) => val !== "")));
49153
49213
  }
49154
49214
  const composerContent = this.getCurrentContent();
49155
49215
  if (composerContent && composerContent !== this.getInitialComposerContent()) {
@@ -49686,6 +49746,7 @@ class GridSelectionPlugin extends UIPlugin {
49686
49746
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
49687
49747
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
49688
49748
  this.setSelectionMixin(this.gridSelection.anchor, this.gridSelection.zones);
49749
+ this.selectedFigureId = null;
49689
49750
  break;
49690
49751
  }
49691
49752
  /** Any change to the selection has to be reflected in the selection processor. */
@@ -51580,12 +51641,14 @@ class BottomBarSheet extends owl.Component {
51580
51641
  this.editionState = "initializing";
51581
51642
  }
51582
51643
  stopEdition() {
51583
- if (!this.state.isEditing)
51644
+ const input = this.sheetNameRef.el;
51645
+ if (!this.state.isEditing || !input)
51584
51646
  return;
51585
51647
  this.state.isEditing = false;
51586
51648
  this.editionState = "initializing";
51587
- this.sheetNameRef.el?.blur();
51649
+ input.blur();
51588
51650
  const inputValue = this.getInputContent() || "";
51651
+ input.innerText = inputValue;
51589
51652
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
51590
51653
  }
51591
51654
  cancelEdition() {
@@ -51876,7 +51939,7 @@ class BottomBar extends owl.Component {
51876
51939
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
51877
51940
  }
51878
51941
  onSheetMouseDown(sheetId, event) {
51879
- if (event.button !== 0)
51942
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
51880
51943
  return;
51881
51944
  this.closeMenu();
51882
51945
  const visibleSheets = this.getVisibleSheets();
@@ -53226,9 +53289,6 @@ css /* scss */ `
53226
53289
  .text-muted {
53227
53290
  color: grey !important;
53228
53291
  }
53229
- button {
53230
- color: #333;
53231
- }
53232
53292
  .o-disabled {
53233
53293
  opacity: 0.4;
53234
53294
  pointer: default;
@@ -53349,17 +53409,17 @@ css /* scss */ `
53349
53409
  }
53350
53410
 
53351
53411
  .o-button {
53352
- border: 1px solid lightgrey;
53412
+ border: 1px solid;
53353
53413
  padding: 0px 20px 0px 20px;
53354
53414
  border-radius: 4px;
53355
53415
  font-weight: 500;
53356
53416
  font-size: 14px;
53357
53417
  height: 30px;
53358
53418
  line-height: 16px;
53359
- background: white;
53360
53419
  margin-right: 8px;
53361
- &:hover:enabled {
53362
- background-color: rgba(0, 0, 0, 0.08);
53420
+
53421
+ &:not(:hover) {
53422
+ background-color: transparent;
53363
53423
  }
53364
53424
 
53365
53425
  &:enabled {
@@ -53373,6 +53433,15 @@ css /* scss */ `
53373
53433
  &:last-child {
53374
53434
  margin-right: 0px;
53375
53435
  }
53436
+
53437
+ &.o-button-grey {
53438
+ border-color: lightgrey;
53439
+ background: #ffffff;
53440
+ color: #333;
53441
+ &:hover:enabled {
53442
+ background-color: rgba(0, 0, 0, 0.08);
53443
+ }
53444
+ }
53376
53445
  }
53377
53446
 
53378
53447
  .o-input {
@@ -55324,7 +55393,7 @@ function addLineChart(chart) {
55324
55393
  }
55325
55394
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
55326
55395
  const colors = new ChartColors();
55327
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55396
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55328
55397
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
55329
55398
  const dataSetsNodes = [];
55330
55399
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -57288,6 +57357,6 @@ exports.setTranslationMethod = setTranslationMethod;
57288
57357
  exports.tokenize = tokenize;
57289
57358
 
57290
57359
 
57291
- __info__.version = "17.1.8";
57292
- __info__.date = "2024-03-15T10:59:39.362Z";
57293
- __info__.hash = "bd0c9e0";
57360
+ __info__.version = "17.1.10";
57361
+ __info__.date = "2024-04-05T14:00:03.890Z";
57362
+ __info__.hash = "edc821c";
@@ -5204,6 +5204,7 @@ type Getters = {
5204
5204
 
5205
5205
  type ArgType = "ANY" | "BOOLEAN" | "NUMBER" | "STRING" | "DATE" | "RANGE" | "RANGE<BOOLEAN>" | "RANGE<NUMBER>" | "RANGE<DATE>" | "RANGE<STRING>" | "RANGE<ANY>" | "META";
5206
5206
  interface ArgDefinition {
5207
+ acceptMatrix?: boolean;
5207
5208
  repeating?: boolean;
5208
5209
  optional?: boolean;
5209
5210
  description: string;
@@ -7806,7 +7807,7 @@ interface Props$a {
7806
7807
  interface AssistantState {
7807
7808
  allowCellSelectionBehind: boolean;
7808
7809
  }
7809
- declare class FunctionDescriptionProvider extends Component<Props$a> {
7810
+ declare class FunctionDescriptionProvider extends Component<Props$a, SpreadsheetChildEnv> {
7810
7811
  static template: string;
7811
7812
  static props: {
7812
7813
  functionName: StringConstructor;
@@ -7818,6 +7819,7 @@ declare class FunctionDescriptionProvider extends Component<Props$a> {
7818
7819
  setup(): void;
7819
7820
  getContext(): Props$a;
7820
7821
  onMouseMove(): void;
7822
+ get formulaArgSeparator(): string;
7821
7823
  }
7822
7824
 
7823
7825
  type HtmlContent = {