@odoo/o-spreadsheet 17.0.16 → 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.16
6
- * @date 2024-03-25T09:42:01.717Z
7
- * @hash 9b128f8
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 {
@@ -31855,7 +31890,7 @@
31855
31890
  function getSheetDims(sheet) {
31856
31891
  const dims = [0, 0];
31857
31892
  for (let row of sheet.rows) {
31858
- 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)));
31859
31894
  dims[1] = Math.max(dims[1], row.index);
31860
31895
  }
31861
31896
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -36745,6 +36780,9 @@
36745
36780
  if (newRule.criterion.type === "isBoolean") {
36746
36781
  this.setCenterStyleToBooleanCells(newRule);
36747
36782
  }
36783
+ else if (newRule.criterion.type === "isValueInList") {
36784
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
36785
+ }
36748
36786
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
36749
36787
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
36750
36788
  if (ruleIndex !== -1) {
@@ -37471,7 +37509,7 @@
37471
37509
  if (hiddenElements.size >= elements) {
37472
37510
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
37473
37511
  }
37474
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
37512
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
37475
37513
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
37476
37514
  }
37477
37515
  else {
@@ -38286,8 +38324,8 @@
38286
38324
  let newRange = range;
38287
38325
  let changeType = "NONE";
38288
38326
  for (let group of groups) {
38289
- const min = Math.min(...group);
38290
- const max = Math.max(...group);
38327
+ const min = largeMin(group);
38328
+ const max = largeMax(group);
38291
38329
  if (range.zone[start] <= min && min <= range.zone[end]) {
38292
38330
  const toRemove = Math.min(range.zone[end], max) - min + 1;
38293
38331
  changeType = "RESIZE";
@@ -38710,8 +38748,8 @@
38710
38748
  }
38711
38749
  return "Success" /* CommandResult.Success */;
38712
38750
  case "REMOVE_COLUMNS_ROWS": {
38713
- const min = Math.min(...cmd.elements);
38714
- const max = Math.max(...cmd.elements);
38751
+ const min = largeMin(cmd.elements);
38752
+ const max = largeMax(cmd.elements);
38715
38753
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
38716
38754
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
38717
38755
  }
@@ -42043,13 +42081,13 @@
42043
42081
  .map((cell) => cell.value);
42044
42082
  switch (threshold.type) {
42045
42083
  case "value":
42046
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
42084
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
42047
42085
  return result;
42048
42086
  case "number":
42049
42087
  return Number(threshold.value);
42050
42088
  case "percentage":
42051
- const min = Math.min(...rangeValues);
42052
- const max = Math.max(...rangeValues);
42089
+ const min = largeMin(rangeValues);
42090
+ const max = largeMax(rangeValues);
42053
42091
  const delta = max - min;
42054
42092
  return min + (delta * Number(threshold.value)) / 100;
42055
42093
  case "percentile":
@@ -43101,13 +43139,13 @@
43101
43139
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
43102
43140
  const cellPositions = range(end, -1, -1);
43103
43141
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
43104
- const maxValidPosition = Math.max(...invalidCells);
43142
+ const maxValidPosition = largeMax(invalidCells);
43105
43143
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
43106
43144
  const firstSequence = numberSequences[0] || [];
43107
- if (Math.max(...firstSequence) < maxValidPosition) {
43145
+ if (largeMax(firstSequence) < maxValidPosition) {
43108
43146
  return Infinity;
43109
43147
  }
43110
- return Math.min(...firstSequence);
43148
+ return largeMin(firstSequence);
43111
43149
  }
43112
43150
  shouldFindData(sheetId, zone) {
43113
43151
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -45511,7 +45549,7 @@
45511
45549
  * column of the current viewport
45512
45550
  */
45513
45551
  getColDimensionsInViewport(sheetId, col) {
45514
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
45552
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
45515
45553
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
45516
45554
  const size = this.getters.getColSize(sheetId, col);
45517
45555
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -45526,7 +45564,7 @@
45526
45564
  * of the current viewport
45527
45565
  */
45528
45566
  getRowDimensionsInViewport(sheetId, row) {
45529
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
45567
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
45530
45568
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
45531
45569
  const size = this.getters.getRowSize(sheetId, row);
45532
45570
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -46990,7 +47028,7 @@
46990
47028
  getColMaxWidth(sheetId, index) {
46991
47029
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
46992
47030
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
46993
- return Math.max(0, ...sizes);
47031
+ return Math.max(0, largeMax(sizes));
46994
47032
  }
46995
47033
  /**
46996
47034
  * Check that any "sheetId" in the command matches an existing
@@ -47755,7 +47793,7 @@
47755
47793
  }
47756
47794
  getPasteZone(target) {
47757
47795
  const height = this.values.length;
47758
- const width = Math.max(...this.values.map((a) => a.length));
47796
+ const width = largeMax(this.values.map((a) => a.length));
47759
47797
  const { left: activeCol, top: activeRow } = target[0];
47760
47798
  return {
47761
47799
  top: activeRow,
@@ -48792,11 +48830,11 @@
48792
48830
  }
48793
48831
  else {
48794
48832
  const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
48795
- values = this.getters
48833
+ values = Array.from(new Set(this.getters
48796
48834
  .getRangeValues(range)
48797
48835
  .filter(isNotNull)
48798
48836
  .map((value) => value.toString())
48799
- .filter((val) => val !== "");
48837
+ .filter((val) => val !== "")));
48800
48838
  }
48801
48839
  const composerContent = this.getCurrentContent();
48802
48840
  if (composerContent && composerContent !== this.getInitialComposerContent()) {
@@ -51253,12 +51291,14 @@
51253
51291
  this.editionState = "initializing";
51254
51292
  }
51255
51293
  stopEdition() {
51256
- if (!this.state.isEditing)
51294
+ const input = this.sheetNameRef.el;
51295
+ if (!this.state.isEditing || !input)
51257
51296
  return;
51258
51297
  this.state.isEditing = false;
51259
51298
  this.editionState = "initializing";
51260
- this.sheetNameRef.el?.blur();
51299
+ input.blur();
51261
51300
  const inputValue = this.getInputContent() || "";
51301
+ input.innerText = inputValue;
51262
51302
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
51263
51303
  }
51264
51304
  cancelEdition() {
@@ -51552,7 +51592,7 @@
51552
51592
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
51553
51593
  }
51554
51594
  onSheetMouseDown(sheetId, event) {
51555
- if (event.button !== 0)
51595
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
51556
51596
  return;
51557
51597
  this.closeMenu();
51558
51598
  const visibleSheets = this.getVisibleSheets();
@@ -55057,7 +55097,7 @@
55057
55097
  }
55058
55098
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
55059
55099
  const colors = new ChartColors();
55060
- 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)));
55061
55101
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
55062
55102
  const dataSetsNodes = [];
55063
55103
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -57011,9 +57051,9 @@
57011
57051
  exports.tokenize = tokenize;
57012
57052
 
57013
57053
 
57014
- __info__.version = "17.0.16";
57015
- __info__.date = "2024-03-25T09:42:01.717Z";
57016
- __info__.hash = "9b128f8";
57054
+ __info__.version = "17.0.17";
57055
+ __info__.date = "2024-04-05T13:59:37.139Z";
57056
+ __info__.hash = "33f09d7";
57017
57057
 
57018
57058
 
57019
57059
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);