@odoo/o-spreadsheet 17.1.9 → 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.9
6
- * @date 2024-03-25T09:43:27.017Z
7
- * @hash 5fb076e
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 {
@@ -29217,11 +29246,6 @@ css /* scss */ `
29217
29246
  height: 10000px;
29218
29247
  background-color: ${SELECTION_BORDER_COLOR};
29219
29248
  }
29220
- .o-unhide-buttons {
29221
- width: fit-content;
29222
- gap: 5px;
29223
- transform: translate(-50%, 0);
29224
- }
29225
29249
  .o-unhide:hover {
29226
29250
  z-index: ${ComponentsImportance.Grid + 1};
29227
29251
  background-color: lightgrey;
@@ -29383,10 +29407,6 @@ css /* scss */ `
29383
29407
  height: 1px;
29384
29408
  background-color: ${SELECTION_BORDER_COLOR};
29385
29409
  }
29386
- .o-unhide-buttons {
29387
- height: fit-content;
29388
- transform: translate(0, -50%);
29389
- }
29390
29410
  .o-unhide:hover {
29391
29411
  z-index: ${ComponentsImportance.Grid + 1};
29392
29412
  background-color: lightgrey;
@@ -32327,7 +32347,7 @@ function convertHyperlink(link, cellValue, warningManager) {
32327
32347
  function getSheetDims(sheet) {
32328
32348
  const dims = [0, 0];
32329
32349
  for (let row of sheet.rows) {
32330
- 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)));
32331
32351
  dims[1] = Math.max(dims[1], row.index);
32332
32352
  }
32333
32353
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -37227,6 +37247,9 @@ class DataValidationPlugin extends CorePlugin {
37227
37247
  if (newRule.criterion.type === "isBoolean") {
37228
37248
  this.setCenterStyleToBooleanCells(newRule);
37229
37249
  }
37250
+ else if (newRule.criterion.type === "isValueInList") {
37251
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
37252
+ }
37230
37253
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
37231
37254
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
37232
37255
  if (ruleIndex !== -1) {
@@ -37953,7 +37976,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
37953
37976
  if (hiddenElements.size >= elements) {
37954
37977
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
37955
37978
  }
37956
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
37979
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
37957
37980
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
37958
37981
  }
37959
37982
  else {
@@ -38768,8 +38791,8 @@ class RangeAdapter {
38768
38791
  let newRange = range;
38769
38792
  let changeType = "NONE";
38770
38793
  for (let group of groups) {
38771
- const min = Math.min(...group);
38772
- const max = Math.max(...group);
38794
+ const min = largeMin(group);
38795
+ const max = largeMax(group);
38773
38796
  if (range.zone[start] <= min && min <= range.zone[end]) {
38774
38797
  const toRemove = Math.min(range.zone[end], max) - min + 1;
38775
38798
  changeType = "RESIZE";
@@ -39192,8 +39215,8 @@ class SheetPlugin extends CorePlugin {
39192
39215
  }
39193
39216
  return "Success" /* CommandResult.Success */;
39194
39217
  case "REMOVE_COLUMNS_ROWS": {
39195
- const min = Math.min(...cmd.elements);
39196
- const max = Math.max(...cmd.elements);
39218
+ const min = largeMin(cmd.elements);
39219
+ const max = largeMax(cmd.elements);
39197
39220
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
39198
39221
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
39199
39222
  }
@@ -42101,7 +42124,7 @@ class EvaluationPlugin extends UIPlugin {
42101
42124
  ? getItemId(newFormat, data.formats)
42102
42125
  : exportedCellData.format;
42103
42126
  let content;
42104
- if (formulaCell instanceof FormulaCellWithDependencies) {
42127
+ if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42105
42128
  content = formulaCell.contentWithFixedReferences;
42106
42129
  }
42107
42130
  else {
@@ -42522,13 +42545,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
42522
42545
  .map((cell) => cell.value);
42523
42546
  switch (threshold.type) {
42524
42547
  case "value":
42525
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
42548
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
42526
42549
  return result;
42527
42550
  case "number":
42528
42551
  return Number(threshold.value);
42529
42552
  case "percentage":
42530
- const min = Math.min(...rangeValues);
42531
- const max = Math.max(...rangeValues);
42553
+ const min = largeMin(rangeValues);
42554
+ const max = largeMax(rangeValues);
42532
42555
  const delta = max - min;
42533
42556
  return min + (delta * Number(threshold.value)) / 100;
42534
42557
  case "percentile":
@@ -43570,13 +43593,13 @@ class AutomaticSumPlugin extends UIPlugin {
43570
43593
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
43571
43594
  const cellPositions = range(end, -1, -1);
43572
43595
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
43573
- const maxValidPosition = Math.max(...invalidCells);
43596
+ const maxValidPosition = largeMax(invalidCells);
43574
43597
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
43575
43598
  const firstSequence = numberSequences[0] || [];
43576
- if (Math.max(...firstSequence) < maxValidPosition) {
43599
+ if (largeMax(firstSequence) < maxValidPosition) {
43577
43600
  return Infinity;
43578
43601
  }
43579
- return Math.min(...firstSequence);
43602
+ return largeMin(firstSequence);
43580
43603
  }
43581
43604
  shouldFindData(sheetId, zone) {
43582
43605
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -46069,7 +46092,7 @@ class RendererPlugin extends UIPlugin {
46069
46092
  * column of the current viewport
46070
46093
  */
46071
46094
  getColDimensionsInViewport(sheetId, col) {
46072
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
46095
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
46073
46096
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
46074
46097
  const size = this.getters.getColSize(sheetId, col);
46075
46098
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -46084,7 +46107,7 @@ class RendererPlugin extends UIPlugin {
46084
46107
  * of the current viewport
46085
46108
  */
46086
46109
  getRowDimensionsInViewport(sheetId, row) {
46087
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
46110
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
46088
46111
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
46089
46112
  const size = this.getters.getRowSize(sheetId, row);
46090
46113
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -47467,7 +47490,7 @@ class SheetUIPlugin extends UIPlugin {
47467
47490
  getColMaxWidth(sheetId, index) {
47468
47491
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
47469
47492
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
47470
- return Math.max(0, ...sizes);
47493
+ return Math.max(0, largeMax(sizes));
47471
47494
  }
47472
47495
  /**
47473
47496
  * Check that any "sheetId" in the command matches an existing
@@ -48234,7 +48257,7 @@ class ClipboardOsState extends ClipboardCellsAbstractState {
48234
48257
  }
48235
48258
  getPasteZone(target) {
48236
48259
  const height = this.values.length;
48237
- const width = Math.max(...this.values.map((a) => a.length));
48260
+ const width = largeMax(this.values.map((a) => a.length));
48238
48261
  const { left: activeCol, top: activeRow } = target[0];
48239
48262
  return {
48240
48263
  top: activeRow,
@@ -49180,11 +49203,11 @@ class EditionPlugin extends UIPlugin {
49180
49203
  }
49181
49204
  else {
49182
49205
  const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
49183
- values = this.getters
49206
+ values = Array.from(new Set(this.getters
49184
49207
  .getRangeValues(range)
49185
49208
  .filter(isNotNull)
49186
49209
  .map((value) => value.toString())
49187
- .filter((val) => val !== "");
49210
+ .filter((val) => val !== "")));
49188
49211
  }
49189
49212
  const composerContent = this.getCurrentContent();
49190
49213
  if (composerContent && composerContent !== this.getInitialComposerContent()) {
@@ -51616,12 +51639,14 @@ class BottomBarSheet extends Component {
51616
51639
  this.editionState = "initializing";
51617
51640
  }
51618
51641
  stopEdition() {
51619
- if (!this.state.isEditing)
51642
+ const input = this.sheetNameRef.el;
51643
+ if (!this.state.isEditing || !input)
51620
51644
  return;
51621
51645
  this.state.isEditing = false;
51622
51646
  this.editionState = "initializing";
51623
- this.sheetNameRef.el?.blur();
51647
+ input.blur();
51624
51648
  const inputValue = this.getInputContent() || "";
51649
+ input.innerText = inputValue;
51625
51650
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
51626
51651
  }
51627
51652
  cancelEdition() {
@@ -51912,7 +51937,7 @@ class BottomBar extends Component {
51912
51937
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
51913
51938
  }
51914
51939
  onSheetMouseDown(sheetId, event) {
51915
- if (event.button !== 0)
51940
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
51916
51941
  return;
51917
51942
  this.closeMenu();
51918
51943
  const visibleSheets = this.getVisibleSheets();
@@ -55366,7 +55391,7 @@ function addLineChart(chart) {
55366
55391
  }
55367
55392
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
55368
55393
  const colors = new ChartColors();
55369
- 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)));
55370
55395
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
55371
55396
  const dataSetsNodes = [];
55372
55397
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -57294,6 +57319,6 @@ const constants = {
57294
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 };
57295
57320
 
57296
57321
 
57297
- __info__.version = "17.1.9";
57298
- __info__.date = "2024-03-25T09:43:27.017Z";
57299
- __info__.hash = "5fb076e";
57322
+ __info__.version = "17.1.10";
57323
+ __info__.date = "2024-04-05T14:00:03.890Z";
57324
+ __info__.hash = "edc821c";