@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.
@@ -526,7 +526,7 @@ function getItemId(item, itemsDic) {
526
526
  }
527
527
  // Generate new Id if the item didn't exist in the dictionary
528
528
  const ids = Object.keys(itemsDic);
529
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
529
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
530
530
  itemsDic[maxId + 1] = item;
531
531
  return maxId + 1;
532
532
  }
@@ -742,6 +742,34 @@ function insertItemsAtIndex(array, items, index) {
742
742
  const newArray = [...array];
743
743
  newArray.splice(index, 0, ...items);
744
744
  return newArray;
745
+ }
746
+ /**
747
+ * Alternative to Math.max that works with large arrays.
748
+ * Typically useful for arrays bigger than 100k elements.
749
+ */
750
+ function largeMax(array) {
751
+ let len = array.length;
752
+ if (len < 100000)
753
+ return Math.max(...array);
754
+ let max = -Infinity;
755
+ while (len--) {
756
+ max = array[len] > max ? array[len] : max;
757
+ }
758
+ return max;
759
+ }
760
+ /**
761
+ * Alternative to Math.min that works with large arrays.
762
+ * Typically useful for arrays bigger than 100k elements.
763
+ */
764
+ function largeMin(array) {
765
+ let len = array.length;
766
+ if (len < 100000)
767
+ return Math.min(...array);
768
+ let min = +Infinity;
769
+ while (len--) {
770
+ min = array[len] < min ? array[len] : min;
771
+ }
772
+ return min;
745
773
  }
746
774
 
747
775
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
@@ -16338,10 +16366,10 @@ function aggregateDataForLabels(labels, datasets) {
16338
16366
  }
16339
16367
  }
16340
16368
  return {
16341
- labels: Object.keys(labelMap),
16369
+ labels: Array.from(labelSet),
16342
16370
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
16343
16371
  ...dataset,
16344
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
16372
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
16345
16373
  })),
16346
16374
  };
16347
16375
  }
@@ -17062,7 +17090,7 @@ function getBestTimeUnitForScale(labels, format, locale) {
17062
17090
  return undefined;
17063
17091
  }
17064
17092
  const labelsTimestamps = labelDates.map((date) => date.getTime());
17065
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
17093
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
17066
17094
  const minUnit = getFormatMinDisplayUnit(format);
17067
17095
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
17068
17096
  return "second";
@@ -17504,7 +17532,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
17504
17532
  }
17505
17533
  function getPieColors(colors, dataSetsValues) {
17506
17534
  const pieColors = [];
17507
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
17535
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
17508
17536
  for (let i = 0; i <= maxLength; i++) {
17509
17537
  pieColors.push(colors.next());
17510
17538
  }
@@ -18321,8 +18349,8 @@ const DELETE_CONTENT_ROWS_NAME = (env) => {
18321
18349
  let last;
18322
18350
  const activesRows = env.model.getters.getActiveRows();
18323
18351
  if (activesRows.size !== 0) {
18324
- first = Math.min(...activesRows);
18325
- last = Math.max(...activesRows);
18352
+ first = largeMin([...activesRows]);
18353
+ last = largeMax([...activesRows]);
18326
18354
  }
18327
18355
  else {
18328
18356
  const zone = env.model.getters.getSelectedZones()[0];
@@ -18350,8 +18378,8 @@ const DELETE_CONTENT_COLUMNS_NAME = (env) => {
18350
18378
  let last;
18351
18379
  const activeCols = env.model.getters.getActiveCols();
18352
18380
  if (activeCols.size !== 0) {
18353
- first = Math.min(...activeCols);
18354
- last = Math.max(...activeCols);
18381
+ first = largeMin([...activeCols]);
18382
+ last = largeMax([...activeCols]);
18355
18383
  }
18356
18384
  else {
18357
18385
  const zone = env.model.getters.getSelectedZones()[0];
@@ -18379,8 +18407,8 @@ const REMOVE_ROWS_NAME = (env) => {
18379
18407
  let last;
18380
18408
  const activesRows = env.model.getters.getActiveRows();
18381
18409
  if (activesRows.size !== 0) {
18382
- first = Math.min(...activesRows);
18383
- last = Math.max(...activesRows);
18410
+ first = largeMin([...activesRows]);
18411
+ last = largeMax([...activesRows]);
18384
18412
  }
18385
18413
  else {
18386
18414
  const zone = env.model.getters.getSelectedZones()[0];
@@ -18421,8 +18449,8 @@ const REMOVE_COLUMNS_NAME = (env) => {
18421
18449
  let last;
18422
18450
  const activeCols = env.model.getters.getActiveCols();
18423
18451
  if (activeCols.size !== 0) {
18424
- first = Math.min(...activeCols);
18425
- last = Math.max(...activeCols);
18452
+ first = largeMin([...activeCols]);
18453
+ last = largeMax([...activeCols]);
18426
18454
  }
18427
18455
  else {
18428
18456
  const zone = env.model.getters.getSelectedZones()[0];
@@ -18463,7 +18491,7 @@ const INSERT_ROWS_BEFORE_ACTION = (env) => {
18463
18491
  let row;
18464
18492
  let quantity;
18465
18493
  if (activeRows.size) {
18466
- row = Math.min(...activeRows);
18494
+ row = largeMin([...activeRows]);
18467
18495
  quantity = activeRows.size;
18468
18496
  }
18469
18497
  else {
@@ -18484,7 +18512,7 @@ const INSERT_ROWS_AFTER_ACTION = (env) => {
18484
18512
  let row;
18485
18513
  let quantity;
18486
18514
  if (activeRows.size) {
18487
- row = Math.max(...activeRows);
18515
+ row = largeMax([...activeRows]);
18488
18516
  quantity = activeRows.size;
18489
18517
  }
18490
18518
  else {
@@ -18505,7 +18533,7 @@ const INSERT_COLUMNS_BEFORE_ACTION = (env) => {
18505
18533
  let column;
18506
18534
  let quantity;
18507
18535
  if (activeCols.size) {
18508
- column = Math.min(...activeCols);
18536
+ column = largeMin([...activeCols]);
18509
18537
  quantity = activeCols.size;
18510
18538
  }
18511
18539
  else {
@@ -18526,7 +18554,7 @@ const INSERT_COLUMNS_AFTER_ACTION = (env) => {
18526
18554
  let column;
18527
18555
  let quantity;
18528
18556
  if (activeCols.size) {
18529
- column = Math.max(...activeCols);
18557
+ column = largeMax([...activeCols]);
18530
18558
  quantity = activeCols.size;
18531
18559
  }
18532
18560
  else {
@@ -19042,14 +19070,19 @@ const categorieFunctionAll = {
19042
19070
  children: [allFunctionListMenuBuilder],
19043
19071
  };
19044
19072
  function allFunctionListMenuBuilder() {
19045
- const fnNames = functionRegistry.getKeys();
19073
+ const fnNames = functionRegistry.getKeys().filter((key) => !functionRegistry.get(key).hidden);
19046
19074
  return createFormulaFunctions(fnNames);
19047
19075
  }
19048
19076
  const categoriesFunctionListMenuBuilder = () => {
19049
19077
  const functions = functionRegistry.content;
19050
- const categories = [...new Set(functionRegistry.getAll().map((fn) => fn.category))].filter(isDefined$1);
19078
+ const categories = [
19079
+ ...new Set(functionRegistry
19080
+ .getAll()
19081
+ .filter((fn) => !fn.hidden)
19082
+ .map((fn) => fn.category)),
19083
+ ].filter(isDefined$1);
19051
19084
  return categories.sort().map((category, i) => {
19052
- const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category);
19085
+ const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category && !functions[key].hidden);
19053
19086
  return {
19054
19087
  name: category,
19055
19088
  children: createFormulaFunctions(functionsInCategory),
@@ -23390,6 +23423,9 @@ class FigureComponent extends owl.Component {
23390
23423
  el?.focus({ preventScroll: true });
23391
23424
  }
23392
23425
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
23426
+ owl.onWillUnmount(() => {
23427
+ this.props.onFigureDeleted();
23428
+ });
23393
23429
  }
23394
23430
  clickAnchor(dirX, dirY, ev) {
23395
23431
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -23408,6 +23444,7 @@ class FigureComponent extends owl.Component {
23408
23444
  this.props.onFigureDeleted();
23409
23445
  ev.stopPropagation();
23410
23446
  ev.preventDefault();
23447
+ ev.stopPropagation();
23411
23448
  break;
23412
23449
  case "ArrowDown":
23413
23450
  case "ArrowLeft":
@@ -23428,6 +23465,7 @@ class FigureComponent extends owl.Component {
23428
23465
  });
23429
23466
  ev.stopPropagation();
23430
23467
  ev.preventDefault();
23468
+ ev.stopPropagation();
23431
23469
  break;
23432
23470
  }
23433
23471
  }
@@ -24030,6 +24068,9 @@ class FunctionDescriptionProvider extends owl.Component {
24030
24068
  this.assistantState.allowCellSelectionBehind = false;
24031
24069
  }, 2000);
24032
24070
  }
24071
+ get formulaArgSeparator() {
24072
+ return this.env.model.getters.getLocale().formulaArgSeparator + " ";
24073
+ }
24033
24074
  }
24034
24075
  FunctionDescriptionProvider.props = {
24035
24076
  functionName: String,
@@ -24164,6 +24205,12 @@ class Composer extends owl.Component {
24164
24205
  owl.useEffect(() => {
24165
24206
  this.processContent();
24166
24207
  });
24208
+ owl.onPatched(() => {
24209
+ // Required because typing '=SUM' and double-clicking another cell leaves ShowProvider/ShowDescription true
24210
+ if (this.env.model.getters.getEditionMode() === "inactive") {
24211
+ this.processTokenAtCursor();
24212
+ }
24213
+ });
24167
24214
  }
24168
24215
  // ---------------------------------------------------------------------------
24169
24216
  // Handlers
@@ -29021,7 +29068,7 @@ function convertHyperlink(link, cellValue, warningManager) {
29021
29068
  function getSheetDims(sheet) {
29022
29069
  const dims = [0, 0];
29023
29070
  for (let row of sheet.rows) {
29024
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
29071
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
29025
29072
  dims[1] = Math.max(dims[1], row.index);
29026
29073
  }
29027
29074
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -33518,7 +33565,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
33518
33565
  if (hiddenElements.size >= elements) {
33519
33566
  return 69 /* CommandResult.TooManyHiddenElements */;
33520
33567
  }
33521
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
33568
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
33522
33569
  return 89 /* CommandResult.InvalidHeaderIndex */;
33523
33570
  }
33524
33571
  else {
@@ -34312,8 +34359,8 @@ class RangeAdapter {
34312
34359
  let newRange = range;
34313
34360
  let changeType = "NONE";
34314
34361
  for (let group of groups) {
34315
- const min = Math.min(...group);
34316
- const max = Math.max(...group);
34362
+ const min = largeMin(group);
34363
+ const max = largeMax(group);
34317
34364
  if (range.zone[start] <= min && min <= range.zone[end]) {
34318
34365
  const toRemove = Math.min(range.zone[end], max) - min + 1;
34319
34366
  changeType = "RESIZE";
@@ -34740,7 +34787,7 @@ class SheetPlugin extends CorePlugin {
34740
34787
  const elements = cmd.dimension === "COL"
34741
34788
  ? this.getNumberCols(cmd.sheetId)
34742
34789
  : this.getNumberRows(cmd.sheetId);
34743
- if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
34790
+ if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
34744
34791
  return 89 /* CommandResult.InvalidHeaderIndex */;
34745
34792
  }
34746
34793
  else if (this.checkElementsIncludeAllNonFrozenHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
@@ -37616,13 +37663,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
37616
37663
  .map((cell) => cell.value);
37617
37664
  switch (threshold.type) {
37618
37665
  case "value":
37619
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
37666
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
37620
37667
  return result;
37621
37668
  case "number":
37622
37669
  return Number(threshold.value);
37623
37670
  case "percentage":
37624
- const min = Math.min(...rangeValues);
37625
- const max = Math.max(...rangeValues);
37671
+ const min = largeMin(rangeValues);
37672
+ const max = largeMax(rangeValues);
37626
37673
  const delta = max - min;
37627
37674
  return min + (delta * Number(threshold.value)) / 100;
37628
37675
  case "percentile":
@@ -38505,13 +38552,13 @@ class AutomaticSumPlugin extends UIPlugin {
38505
38552
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
38506
38553
  const cellPositions = range(end, -1, -1);
38507
38554
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
38508
- const maxValidPosition = Math.max(...invalidCells);
38555
+ const maxValidPosition = largeMax(invalidCells);
38509
38556
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
38510
38557
  const firstSequence = numberSequences[0] || [];
38511
- if (Math.max(...firstSequence) < maxValidPosition) {
38558
+ if (largeMax(firstSequence) < maxValidPosition) {
38512
38559
  return Infinity;
38513
38560
  }
38514
- return Math.min(...firstSequence);
38561
+ return largeMin(firstSequence);
38515
38562
  }
38516
38563
  shouldFindData(sheetId, zone) {
38517
38564
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -40100,7 +40147,7 @@ class RendererPlugin extends UIPlugin {
40100
40147
  * column of the current viewport
40101
40148
  */
40102
40149
  getColDimensionsInViewport(sheetId, col) {
40103
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
40150
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
40104
40151
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
40105
40152
  const size = this.getters.getColSize(sheetId, col);
40106
40153
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -40115,7 +40162,7 @@ class RendererPlugin extends UIPlugin {
40115
40162
  * of the current viewport
40116
40163
  */
40117
40164
  getRowDimensionsInViewport(sheetId, row) {
40118
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
40165
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
40119
40166
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
40120
40167
  const size = this.getters.getRowSize(sheetId, row);
40121
40168
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -41612,7 +41659,7 @@ class SheetUIPlugin extends UIPlugin {
41612
41659
  getColMaxWidth(sheetId, index) {
41613
41660
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
41614
41661
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
41615
- return Math.max(0, ...sizes);
41662
+ return Math.max(0, largeMax(sizes));
41616
41663
  }
41617
41664
  /**
41618
41665
  * Check that any "sheetId" in the command matches an existing
@@ -42914,7 +42961,7 @@ class ClipboardOsState extends ClipboardCellsAbstractState {
42914
42961
  }
42915
42962
  getPasteZone(target) {
42916
42963
  const height = this.values.length;
42917
- const width = Math.max(...this.values.map((a) => a.length));
42964
+ const width = largeMax(this.values.map((a) => a.length));
42918
42965
  const { left: activeCol, top: activeRow } = target[0];
42919
42966
  return {
42920
42967
  top: activeRow,
@@ -44400,6 +44447,7 @@ class GridSelectionPlugin extends UIPlugin {
44400
44447
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
44401
44448
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
44402
44449
  this.setSelectionMixin(this.gridSelection.anchor, this.gridSelection.zones);
44450
+ this.selectedFigureId = null;
44403
44451
  break;
44404
44452
  }
44405
44453
  /** Any change to the selection has to be reflected in the selection processor. */
@@ -46134,12 +46182,14 @@ class BottomBarSheet extends owl.Component {
46134
46182
  this.editionState = "initializing";
46135
46183
  }
46136
46184
  stopEdition() {
46137
- if (!this.state.isEditing)
46185
+ const input = this.sheetNameRef.el;
46186
+ if (!this.state.isEditing || !input)
46138
46187
  return;
46139
46188
  this.state.isEditing = false;
46140
46189
  this.editionState = "initializing";
46141
- this.sheetNameRef.el?.blur();
46190
+ input.blur();
46142
46191
  const inputValue = this.getInputContent() || "";
46192
+ input.innerText = inputValue;
46143
46193
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
46144
46194
  }
46145
46195
  cancelEdition() {
@@ -46601,7 +46651,7 @@ class BottomBar extends owl.Component {
46601
46651
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
46602
46652
  }
46603
46653
  onSheetMouseDown(sheetId, event) {
46604
- if (event.button !== 0)
46654
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
46605
46655
  return;
46606
46656
  this.closeMenu();
46607
46657
  const mouseX = event.clientX;
@@ -49805,7 +49855,7 @@ function addLineChart(chart) {
49805
49855
  }
49806
49856
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
49807
49857
  const colors = new ChartColors();
49808
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
49858
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
49809
49859
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
49810
49860
  const dataSetsNodes = [];
49811
49861
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -51734,6 +51784,6 @@ exports.setTranslationMethod = setTranslationMethod;
51734
51784
  exports.tokenize = tokenize;
51735
51785
 
51736
51786
 
51737
- __info__.version = '16.4.26';
51738
- __info__.date = '2024-03-15T10:58:33.088Z';
51739
- __info__.hash = 'b8caa0f';
51787
+ __info__.version = '16.4.28';
51788
+ __info__.date = '2024-04-05T13:59:39.997Z';
51789
+ __info__.hash = '7127826';
@@ -6663,13 +6663,14 @@ interface Props$a {
6663
6663
  interface AssistantState {
6664
6664
  allowCellSelectionBehind: boolean;
6665
6665
  }
6666
- declare class FunctionDescriptionProvider extends Component<Props$a> {
6666
+ declare class FunctionDescriptionProvider extends Component<Props$a, SpreadsheetChildEnv> {
6667
6667
  static template: string;
6668
6668
  assistantState: AssistantState;
6669
6669
  private timeOutId;
6670
6670
  setup(): void;
6671
6671
  getContext(): Props$a;
6672
6672
  onMouseMove(): void;
6673
+ get formulaArgSeparator(): string;
6673
6674
  }
6674
6675
 
6675
6676
  type HtmlContent = {