@odoo/o-spreadsheet 16.4.26 → 16.4.28

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.
@@ -522,7 +522,7 @@ function getItemId(item, itemsDic) {
522
522
  }
523
523
  // Generate new Id if the item didn't exist in the dictionary
524
524
  const ids = Object.keys(itemsDic);
525
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
525
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
526
526
  itemsDic[maxId + 1] = item;
527
527
  return maxId + 1;
528
528
  }
@@ -738,6 +738,34 @@ function insertItemsAtIndex(array, items, index) {
738
738
  const newArray = [...array];
739
739
  newArray.splice(index, 0, ...items);
740
740
  return newArray;
741
+ }
742
+ /**
743
+ * Alternative to Math.max that works with large arrays.
744
+ * Typically useful for arrays bigger than 100k elements.
745
+ */
746
+ function largeMax(array) {
747
+ let len = array.length;
748
+ if (len < 100000)
749
+ return Math.max(...array);
750
+ let max = -Infinity;
751
+ while (len--) {
752
+ max = array[len] > max ? array[len] : max;
753
+ }
754
+ return max;
755
+ }
756
+ /**
757
+ * Alternative to Math.min that works with large arrays.
758
+ * Typically useful for arrays bigger than 100k elements.
759
+ */
760
+ function largeMin(array) {
761
+ let len = array.length;
762
+ if (len < 100000)
763
+ return Math.min(...array);
764
+ let min = +Infinity;
765
+ while (len--) {
766
+ min = array[len] < min ? array[len] : min;
767
+ }
768
+ return min;
741
769
  }
742
770
 
743
771
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
@@ -16334,10 +16362,10 @@ function aggregateDataForLabels(labels, datasets) {
16334
16362
  }
16335
16363
  }
16336
16364
  return {
16337
- labels: Object.keys(labelMap),
16365
+ labels: Array.from(labelSet),
16338
16366
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
16339
16367
  ...dataset,
16340
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
16368
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
16341
16369
  })),
16342
16370
  };
16343
16371
  }
@@ -17058,7 +17086,7 @@ function getBestTimeUnitForScale(labels, format, locale) {
17058
17086
  return undefined;
17059
17087
  }
17060
17088
  const labelsTimestamps = labelDates.map((date) => date.getTime());
17061
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
17089
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
17062
17090
  const minUnit = getFormatMinDisplayUnit(format);
17063
17091
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
17064
17092
  return "second";
@@ -17500,7 +17528,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
17500
17528
  }
17501
17529
  function getPieColors(colors, dataSetsValues) {
17502
17530
  const pieColors = [];
17503
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
17531
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
17504
17532
  for (let i = 0; i <= maxLength; i++) {
17505
17533
  pieColors.push(colors.next());
17506
17534
  }
@@ -18317,8 +18345,8 @@ const DELETE_CONTENT_ROWS_NAME = (env) => {
18317
18345
  let last;
18318
18346
  const activesRows = env.model.getters.getActiveRows();
18319
18347
  if (activesRows.size !== 0) {
18320
- first = Math.min(...activesRows);
18321
- last = Math.max(...activesRows);
18348
+ first = largeMin([...activesRows]);
18349
+ last = largeMax([...activesRows]);
18322
18350
  }
18323
18351
  else {
18324
18352
  const zone = env.model.getters.getSelectedZones()[0];
@@ -18346,8 +18374,8 @@ const DELETE_CONTENT_COLUMNS_NAME = (env) => {
18346
18374
  let last;
18347
18375
  const activeCols = env.model.getters.getActiveCols();
18348
18376
  if (activeCols.size !== 0) {
18349
- first = Math.min(...activeCols);
18350
- last = Math.max(...activeCols);
18377
+ first = largeMin([...activeCols]);
18378
+ last = largeMax([...activeCols]);
18351
18379
  }
18352
18380
  else {
18353
18381
  const zone = env.model.getters.getSelectedZones()[0];
@@ -18375,8 +18403,8 @@ const REMOVE_ROWS_NAME = (env) => {
18375
18403
  let last;
18376
18404
  const activesRows = env.model.getters.getActiveRows();
18377
18405
  if (activesRows.size !== 0) {
18378
- first = Math.min(...activesRows);
18379
- last = Math.max(...activesRows);
18406
+ first = largeMin([...activesRows]);
18407
+ last = largeMax([...activesRows]);
18380
18408
  }
18381
18409
  else {
18382
18410
  const zone = env.model.getters.getSelectedZones()[0];
@@ -18417,8 +18445,8 @@ const REMOVE_COLUMNS_NAME = (env) => {
18417
18445
  let last;
18418
18446
  const activeCols = env.model.getters.getActiveCols();
18419
18447
  if (activeCols.size !== 0) {
18420
- first = Math.min(...activeCols);
18421
- last = Math.max(...activeCols);
18448
+ first = largeMin([...activeCols]);
18449
+ last = largeMax([...activeCols]);
18422
18450
  }
18423
18451
  else {
18424
18452
  const zone = env.model.getters.getSelectedZones()[0];
@@ -18459,7 +18487,7 @@ const INSERT_ROWS_BEFORE_ACTION = (env) => {
18459
18487
  let row;
18460
18488
  let quantity;
18461
18489
  if (activeRows.size) {
18462
- row = Math.min(...activeRows);
18490
+ row = largeMin([...activeRows]);
18463
18491
  quantity = activeRows.size;
18464
18492
  }
18465
18493
  else {
@@ -18480,7 +18508,7 @@ const INSERT_ROWS_AFTER_ACTION = (env) => {
18480
18508
  let row;
18481
18509
  let quantity;
18482
18510
  if (activeRows.size) {
18483
- row = Math.max(...activeRows);
18511
+ row = largeMax([...activeRows]);
18484
18512
  quantity = activeRows.size;
18485
18513
  }
18486
18514
  else {
@@ -18501,7 +18529,7 @@ const INSERT_COLUMNS_BEFORE_ACTION = (env) => {
18501
18529
  let column;
18502
18530
  let quantity;
18503
18531
  if (activeCols.size) {
18504
- column = Math.min(...activeCols);
18532
+ column = largeMin([...activeCols]);
18505
18533
  quantity = activeCols.size;
18506
18534
  }
18507
18535
  else {
@@ -18522,7 +18550,7 @@ const INSERT_COLUMNS_AFTER_ACTION = (env) => {
18522
18550
  let column;
18523
18551
  let quantity;
18524
18552
  if (activeCols.size) {
18525
- column = Math.max(...activeCols);
18553
+ column = largeMax([...activeCols]);
18526
18554
  quantity = activeCols.size;
18527
18555
  }
18528
18556
  else {
@@ -19038,14 +19066,19 @@ const categorieFunctionAll = {
19038
19066
  children: [allFunctionListMenuBuilder],
19039
19067
  };
19040
19068
  function allFunctionListMenuBuilder() {
19041
- const fnNames = functionRegistry.getKeys();
19069
+ const fnNames = functionRegistry.getKeys().filter((key) => !functionRegistry.get(key).hidden);
19042
19070
  return createFormulaFunctions(fnNames);
19043
19071
  }
19044
19072
  const categoriesFunctionListMenuBuilder = () => {
19045
19073
  const functions = functionRegistry.content;
19046
- const categories = [...new Set(functionRegistry.getAll().map((fn) => fn.category))].filter(isDefined$1);
19074
+ const categories = [
19075
+ ...new Set(functionRegistry
19076
+ .getAll()
19077
+ .filter((fn) => !fn.hidden)
19078
+ .map((fn) => fn.category)),
19079
+ ].filter(isDefined$1);
19047
19080
  return categories.sort().map((category, i) => {
19048
- const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category);
19081
+ const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category && !functions[key].hidden);
19049
19082
  return {
19050
19083
  name: category,
19051
19084
  children: createFormulaFunctions(functionsInCategory),
@@ -23386,6 +23419,9 @@ class FigureComponent extends Component {
23386
23419
  el?.focus({ preventScroll: true });
23387
23420
  }
23388
23421
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
23422
+ onWillUnmount(() => {
23423
+ this.props.onFigureDeleted();
23424
+ });
23389
23425
  }
23390
23426
  clickAnchor(dirX, dirY, ev) {
23391
23427
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -23404,6 +23440,7 @@ class FigureComponent extends Component {
23404
23440
  this.props.onFigureDeleted();
23405
23441
  ev.stopPropagation();
23406
23442
  ev.preventDefault();
23443
+ ev.stopPropagation();
23407
23444
  break;
23408
23445
  case "ArrowDown":
23409
23446
  case "ArrowLeft":
@@ -23424,6 +23461,7 @@ class FigureComponent extends Component {
23424
23461
  });
23425
23462
  ev.stopPropagation();
23426
23463
  ev.preventDefault();
23464
+ ev.stopPropagation();
23427
23465
  break;
23428
23466
  }
23429
23467
  }
@@ -24026,6 +24064,9 @@ class FunctionDescriptionProvider extends Component {
24026
24064
  this.assistantState.allowCellSelectionBehind = false;
24027
24065
  }, 2000);
24028
24066
  }
24067
+ get formulaArgSeparator() {
24068
+ return this.env.model.getters.getLocale().formulaArgSeparator + " ";
24069
+ }
24029
24070
  }
24030
24071
  FunctionDescriptionProvider.props = {
24031
24072
  functionName: String,
@@ -24160,6 +24201,12 @@ class Composer extends Component {
24160
24201
  useEffect(() => {
24161
24202
  this.processContent();
24162
24203
  });
24204
+ onPatched(() => {
24205
+ // Required because typing '=SUM' and double-clicking another cell leaves ShowProvider/ShowDescription true
24206
+ if (this.env.model.getters.getEditionMode() === "inactive") {
24207
+ this.processTokenAtCursor();
24208
+ }
24209
+ });
24163
24210
  }
24164
24211
  // ---------------------------------------------------------------------------
24165
24212
  // Handlers
@@ -29017,7 +29064,7 @@ function convertHyperlink(link, cellValue, warningManager) {
29017
29064
  function getSheetDims(sheet) {
29018
29065
  const dims = [0, 0];
29019
29066
  for (let row of sheet.rows) {
29020
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
29067
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
29021
29068
  dims[1] = Math.max(dims[1], row.index);
29022
29069
  }
29023
29070
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -33514,7 +33561,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
33514
33561
  if (hiddenElements.size >= elements) {
33515
33562
  return 69 /* CommandResult.TooManyHiddenElements */;
33516
33563
  }
33517
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
33564
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
33518
33565
  return 89 /* CommandResult.InvalidHeaderIndex */;
33519
33566
  }
33520
33567
  else {
@@ -34308,8 +34355,8 @@ class RangeAdapter {
34308
34355
  let newRange = range;
34309
34356
  let changeType = "NONE";
34310
34357
  for (let group of groups) {
34311
- const min = Math.min(...group);
34312
- const max = Math.max(...group);
34358
+ const min = largeMin(group);
34359
+ const max = largeMax(group);
34313
34360
  if (range.zone[start] <= min && min <= range.zone[end]) {
34314
34361
  const toRemove = Math.min(range.zone[end], max) - min + 1;
34315
34362
  changeType = "RESIZE";
@@ -34736,7 +34783,7 @@ class SheetPlugin extends CorePlugin {
34736
34783
  const elements = cmd.dimension === "COL"
34737
34784
  ? this.getNumberCols(cmd.sheetId)
34738
34785
  : this.getNumberRows(cmd.sheetId);
34739
- if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
34786
+ if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
34740
34787
  return 89 /* CommandResult.InvalidHeaderIndex */;
34741
34788
  }
34742
34789
  else if (this.checkElementsIncludeAllNonFrozenHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
@@ -37612,13 +37659,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
37612
37659
  .map((cell) => cell.value);
37613
37660
  switch (threshold.type) {
37614
37661
  case "value":
37615
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
37662
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
37616
37663
  return result;
37617
37664
  case "number":
37618
37665
  return Number(threshold.value);
37619
37666
  case "percentage":
37620
- const min = Math.min(...rangeValues);
37621
- const max = Math.max(...rangeValues);
37667
+ const min = largeMin(rangeValues);
37668
+ const max = largeMax(rangeValues);
37622
37669
  const delta = max - min;
37623
37670
  return min + (delta * Number(threshold.value)) / 100;
37624
37671
  case "percentile":
@@ -38501,13 +38548,13 @@ class AutomaticSumPlugin extends UIPlugin {
38501
38548
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
38502
38549
  const cellPositions = range(end, -1, -1);
38503
38550
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
38504
- const maxValidPosition = Math.max(...invalidCells);
38551
+ const maxValidPosition = largeMax(invalidCells);
38505
38552
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
38506
38553
  const firstSequence = numberSequences[0] || [];
38507
- if (Math.max(...firstSequence) < maxValidPosition) {
38554
+ if (largeMax(firstSequence) < maxValidPosition) {
38508
38555
  return Infinity;
38509
38556
  }
38510
- return Math.min(...firstSequence);
38557
+ return largeMin(firstSequence);
38511
38558
  }
38512
38559
  shouldFindData(sheetId, zone) {
38513
38560
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -40096,7 +40143,7 @@ class RendererPlugin extends UIPlugin {
40096
40143
  * column of the current viewport
40097
40144
  */
40098
40145
  getColDimensionsInViewport(sheetId, col) {
40099
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
40146
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
40100
40147
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
40101
40148
  const size = this.getters.getColSize(sheetId, col);
40102
40149
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -40111,7 +40158,7 @@ class RendererPlugin extends UIPlugin {
40111
40158
  * of the current viewport
40112
40159
  */
40113
40160
  getRowDimensionsInViewport(sheetId, row) {
40114
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
40161
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
40115
40162
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
40116
40163
  const size = this.getters.getRowSize(sheetId, row);
40117
40164
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -41608,7 +41655,7 @@ class SheetUIPlugin extends UIPlugin {
41608
41655
  getColMaxWidth(sheetId, index) {
41609
41656
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
41610
41657
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
41611
- return Math.max(0, ...sizes);
41658
+ return Math.max(0, largeMax(sizes));
41612
41659
  }
41613
41660
  /**
41614
41661
  * Check that any "sheetId" in the command matches an existing
@@ -42910,7 +42957,7 @@ class ClipboardOsState extends ClipboardCellsAbstractState {
42910
42957
  }
42911
42958
  getPasteZone(target) {
42912
42959
  const height = this.values.length;
42913
- const width = Math.max(...this.values.map((a) => a.length));
42960
+ const width = largeMax(this.values.map((a) => a.length));
42914
42961
  const { left: activeCol, top: activeRow } = target[0];
42915
42962
  return {
42916
42963
  top: activeRow,
@@ -44396,6 +44443,7 @@ class GridSelectionPlugin extends UIPlugin {
44396
44443
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
44397
44444
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
44398
44445
  this.setSelectionMixin(this.gridSelection.anchor, this.gridSelection.zones);
44446
+ this.selectedFigureId = null;
44399
44447
  break;
44400
44448
  }
44401
44449
  /** Any change to the selection has to be reflected in the selection processor. */
@@ -46130,12 +46178,14 @@ class BottomBarSheet extends Component {
46130
46178
  this.editionState = "initializing";
46131
46179
  }
46132
46180
  stopEdition() {
46133
- if (!this.state.isEditing)
46181
+ const input = this.sheetNameRef.el;
46182
+ if (!this.state.isEditing || !input)
46134
46183
  return;
46135
46184
  this.state.isEditing = false;
46136
46185
  this.editionState = "initializing";
46137
- this.sheetNameRef.el?.blur();
46186
+ input.blur();
46138
46187
  const inputValue = this.getInputContent() || "";
46188
+ input.innerText = inputValue;
46139
46189
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
46140
46190
  }
46141
46191
  cancelEdition() {
@@ -46597,7 +46647,7 @@ class BottomBar extends Component {
46597
46647
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
46598
46648
  }
46599
46649
  onSheetMouseDown(sheetId, event) {
46600
- if (event.button !== 0)
46650
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
46601
46651
  return;
46602
46652
  this.closeMenu();
46603
46653
  const mouseX = event.clientX;
@@ -49801,7 +49851,7 @@ function addLineChart(chart) {
49801
49851
  }
49802
49852
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
49803
49853
  const colors = new ChartColors();
49804
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
49854
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
49805
49855
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
49806
49856
  const dataSetsNodes = [];
49807
49857
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -51698,6 +51748,6 @@ const constants = {
51698
51748
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
51699
51749
 
51700
51750
 
51701
- __info__.version = '16.4.26';
51702
- __info__.date = '2024-03-15T10:58:33.088Z';
51703
- __info__.hash = 'b8caa0f';
51751
+ __info__.version = '16.4.28';
51752
+ __info__.date = '2024-04-05T13:59:39.997Z';
51753
+ __info__.hash = '7127826';