@odoo/o-spreadsheet 18.0.16 → 18.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 18.0.16
6
- * @date 2025-02-14T08:44:19.475Z
7
- * @hash 39979ab
5
+ * @version 18.0.17
6
+ * @date 2025-02-25T05:58:39.632Z
7
+ * @hash 2ee4347
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -2064,17 +2064,7 @@ function toZoneWithoutBoundaryChanges(xc) {
2064
2064
  */
2065
2065
  function toUnboundedZone(xc) {
2066
2066
  const zone = toZoneWithoutBoundaryChanges(xc);
2067
- if (zone.right !== undefined && zone.right < zone.left) {
2068
- const tmp = zone.left;
2069
- zone.left = zone.right;
2070
- zone.right = tmp;
2071
- }
2072
- if (zone.bottom !== undefined && zone.bottom < zone.top) {
2073
- const tmp = zone.top;
2074
- zone.top = zone.bottom;
2075
- zone.bottom = tmp;
2076
- }
2077
- return zone;
2067
+ return reorderZone(zone);
2078
2068
  }
2079
2069
  /**
2080
2070
  * Convert from a cartesian reference to a Zone.
@@ -2348,11 +2338,11 @@ function positions(zone) {
2348
2338
  return positions;
2349
2339
  }
2350
2340
  function reorderZone(zone) {
2351
- if (zone.left > zone.right) {
2352
- zone = { left: zone.right, right: zone.left, top: zone.top, bottom: zone.bottom };
2341
+ if (zone.right !== undefined && zone.left > zone.right) {
2342
+ zone = { ...zone, left: zone.right, right: zone.left };
2353
2343
  }
2354
- if (zone.top > zone.bottom) {
2355
- zone = { left: zone.left, right: zone.right, top: zone.bottom, bottom: zone.top };
2344
+ if (zone.bottom !== undefined && zone.top > zone.bottom) {
2345
+ zone = { ...zone, top: zone.bottom, bottom: zone.top };
2356
2346
  }
2357
2347
  return zone;
2358
2348
  }
@@ -3246,12 +3236,12 @@ function isTargetDependent(cmd) {
3246
3236
  function isRangeDependant(cmd) {
3247
3237
  return "ranges" in cmd;
3248
3238
  }
3249
- function isZoneDependent(cmd) {
3250
- return "zone" in cmd;
3251
- }
3252
3239
  function isPositionDependent(cmd) {
3253
3240
  return "col" in cmd && "row" in cmd && "sheetId" in cmd;
3254
3241
  }
3242
+ function isZoneDependent(cmd) {
3243
+ return "sheetId" in cmd && "zone" in cmd;
3244
+ }
3255
3245
  const invalidateEvaluationCommands = new Set([
3256
3246
  "RENAME_SHEET",
3257
3247
  "DELETE_SHEET",
@@ -3263,6 +3253,7 @@ const invalidateEvaluationCommands = new Set([
3263
3253
  "REDO",
3264
3254
  "ADD_MERGE",
3265
3255
  "REMOVE_MERGE",
3256
+ "DUPLICATE_SHEET",
3266
3257
  "UPDATE_LOCALE",
3267
3258
  "ADD_PIVOT",
3268
3259
  "UPDATE_PIVOT",
@@ -3291,7 +3282,6 @@ const invalidateChartEvaluationCommands = new Set([
3291
3282
  ]);
3292
3283
  const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
3293
3284
  const invalidateCFEvaluationCommands = new Set([
3294
- "DUPLICATE_SHEET",
3295
3285
  "EVALUATE_CELLS",
3296
3286
  "ADD_CONDITIONAL_FORMAT",
3297
3287
  "REMOVE_CONDITIONAL_FORMAT",
@@ -3460,6 +3450,7 @@ var CommandResult;
3460
3450
  CommandResult["InvalidRange"] = "InvalidRange";
3461
3451
  CommandResult["InvalidZones"] = "InvalidZones";
3462
3452
  CommandResult["InvalidSheetId"] = "InvalidSheetId";
3453
+ CommandResult["InvalidCellId"] = "InvalidCellId";
3463
3454
  CommandResult["InvalidFigureId"] = "InvalidFigureId";
3464
3455
  CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
3465
3456
  CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
@@ -6358,11 +6349,12 @@ class UuidGenerator {
6358
6349
  if (this.isFastIdStrategy) {
6359
6350
  this.fastIdStart++;
6360
6351
  return String(this.fastIdStart);
6361
- //@ts-ignore
6362
6352
  }
6363
- else if (window.crypto && window.crypto.getRandomValues) {
6364
- //@ts-ignore
6365
- return ([1e7] + -1e3).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
6353
+ else if (window.crypto) {
6354
+ return "10000000-1000".replace(/[01]/g, (c) => {
6355
+ const n = Number(c);
6356
+ return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
6357
+ });
6366
6358
  }
6367
6359
  else {
6368
6360
  // mainly for jest and other browsers that do not have the crypto functionality
@@ -6380,11 +6372,12 @@ class UuidGenerator {
6380
6372
  if (this.isFastIdStrategy) {
6381
6373
  this.fastIdStart++;
6382
6374
  return String(this.fastIdStart);
6383
- //@ts-ignore
6384
6375
  }
6385
- else if (window.crypto && window.crypto.getRandomValues) {
6386
- //@ts-ignore
6387
- return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
6376
+ else if (window.crypto) {
6377
+ return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
6378
+ const n = Number(c);
6379
+ return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
6380
+ });
6388
6381
  }
6389
6382
  else {
6390
6383
  // mainly for jest and other browsers that do not have the crypto functionality
@@ -9668,6 +9661,9 @@ function getTrendDatasetForBarChart(config, dataset) {
9668
9661
  const filteredValues = [];
9669
9662
  const filteredLabels = [];
9670
9663
  const labels = [];
9664
+ if (dataset.hidden) {
9665
+ return;
9666
+ }
9671
9667
  for (let i = 0; i < dataset.data.length; i++) {
9672
9668
  if (typeof dataset.data[i] === "number") {
9673
9669
  filteredValues.push(dataset.data[i]);
@@ -12003,6 +11999,25 @@ const LN = {
12003
11999
  isExported: true,
12004
12000
  };
12005
12001
  // -----------------------------------------------------------------------------
12002
+ // LOG
12003
+ // -----------------------------------------------------------------------------
12004
+ const LOG = {
12005
+ description: _t("The logarithm of a number, for a given base."),
12006
+ args: [
12007
+ arg("value (number)", _t("The value for which to calculate the logarithm.")),
12008
+ arg("base (number, default=10)", _t("The base of the logarithm.")),
12009
+ ],
12010
+ compute: function (value, base = { value: 10 }) {
12011
+ const _value = toNumber(value, this.locale);
12012
+ const _base = toNumber(base, this.locale);
12013
+ assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
12014
+ assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
12015
+ assert(() => _base !== 1, _t("The base must be different from 1."));
12016
+ return Math.log10(_value) / Math.log10(_base);
12017
+ },
12018
+ isExported: true,
12019
+ };
12020
+ // -----------------------------------------------------------------------------
12006
12021
  // MOD
12007
12022
  // -----------------------------------------------------------------------------
12008
12023
  function mod(dividend, divisor) {
@@ -12542,6 +12557,7 @@ var math = /*#__PURE__*/Object.freeze({
12542
12557
  ISODD: ISODD,
12543
12558
  ISO_CEILING: ISO_CEILING,
12544
12559
  LN: LN,
12560
+ LOG: LOG,
12545
12561
  MOD: MOD,
12546
12562
  MUNIT: MUNIT,
12547
12563
  ODD: ODD,
@@ -28608,10 +28624,8 @@ function getChartDatasetFormat(getters, dataSets) {
28608
28624
  function getChartDatasetValues(getters, dataSets) {
28609
28625
  const datasetValues = [];
28610
28626
  for (const [dsIndex, ds] of Object.entries(dataSets)) {
28611
- if (getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left)) {
28612
- continue;
28613
- }
28614
28627
  let label;
28628
+ let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
28615
28629
  if (ds.labelCell) {
28616
28630
  const labelRange = ds.labelCell;
28617
28631
  const cell = labelRange
@@ -28638,9 +28652,9 @@ function getChartDatasetValues(getters, dataSets) {
28638
28652
  data.fill(1);
28639
28653
  }
28640
28654
  else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
28641
- continue;
28655
+ hidden = true;
28642
28656
  }
28643
- datasetValues.push({ data, label });
28657
+ datasetValues.push({ data, label, hidden });
28644
28658
  }
28645
28659
  return datasetValues;
28646
28660
  }
@@ -28707,6 +28721,20 @@ const backgroundColorChartJSPlugin = {
28707
28721
  ctx.restore();
28708
28722
  },
28709
28723
  };
28724
+ function getChartJsLegend(fontColor, legend = {}) {
28725
+ return {
28726
+ ...legend,
28727
+ labels: {
28728
+ color: fontColor,
28729
+ filter: (legendItem, data) => {
28730
+ return "datasetIndex" in legendItem
28731
+ ? !data.datasets[legendItem.datasetIndex].hidden
28732
+ : true;
28733
+ },
28734
+ ...legend.labels,
28735
+ },
28736
+ };
28737
+ }
28710
28738
 
28711
28739
  class BarChart extends AbstractChart {
28712
28740
  dataSets;
@@ -28856,9 +28884,7 @@ function createBarChartRuntime(chart, getters) {
28856
28884
  ...localeFormat,
28857
28885
  horizontalChart: chart.horizontal,
28858
28886
  });
28859
- const legend = {
28860
- labels: { color: fontColor },
28861
- };
28887
+ const legend = getChartJsLegend(fontColor);
28862
28888
  if (chart.legendPosition === "none") {
28863
28889
  legend.display = false;
28864
28890
  }
@@ -28922,11 +28948,12 @@ function createBarChartRuntime(chart, getters) {
28922
28948
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
28923
28949
  const trendDatasets = [];
28924
28950
  for (const index in dataSetsValues) {
28925
- const { label, data } = dataSetsValues[index];
28951
+ const { label, data, hidden } = dataSetsValues[index];
28926
28952
  const color = colors.next();
28927
28953
  const dataset = {
28928
28954
  label,
28929
28955
  data,
28956
+ hidden,
28930
28957
  borderColor: definition.background || BACKGROUND_CHART_COLOR,
28931
28958
  borderWidth: definition.stacked ? 1 : 0,
28932
28959
  backgroundColor: color,
@@ -29170,6 +29197,9 @@ function getTrendDatasetForLineChart(config, dataset, axisType, locale) {
29170
29197
  const filteredLabels = [];
29171
29198
  const labels = [];
29172
29199
  const datasetLength = dataset.data.length;
29200
+ if (dataset.hidden) {
29201
+ return;
29202
+ }
29173
29203
  if (datasetLength < 2) {
29174
29204
  return;
29175
29205
  }
@@ -29243,9 +29273,8 @@ function createLineOrScatterChartRuntime(chart, getters) {
29243
29273
  const options = { format: dataSetFormat, locale, truncateLabels };
29244
29274
  const fontColor = chartFontColor(chart.background);
29245
29275
  const config = getDefaultChartJsRuntime(chart, labels, fontColor, options);
29246
- const legend = {
29276
+ const legend = getChartJsLegend(fontColor, {
29247
29277
  labels: {
29248
- color: fontColor,
29249
29278
  generateLabels(chart) {
29250
29279
  // color the legend labels with the dataset color, without any transparency
29251
29280
  const { data } = chart;
@@ -29256,7 +29285,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
29256
29285
  return labels;
29257
29286
  },
29258
29287
  },
29259
- };
29288
+ });
29260
29289
  if (chart.legendPosition === "none") {
29261
29290
  legend.display = false;
29262
29291
  }
@@ -29356,7 +29385,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
29356
29385
  const cumulative = "cumulative" in chart ? chart.cumulative : false;
29357
29386
  const definition = chart.getDefinition();
29358
29387
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
29359
- for (let [index, { label, data }] of dataSetsValues.entries()) {
29388
+ for (let [index, { label, data, hidden }] of dataSetsValues.entries()) {
29360
29389
  const color = colors.next();
29361
29390
  let backgroundRGBA = colorToRGBA(color);
29362
29391
  if (areaChart) {
@@ -29380,6 +29409,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
29380
29409
  const dataset = {
29381
29410
  label,
29382
29411
  data,
29412
+ hidden,
29383
29413
  tension: 0, // 0 -> render straight lines, which is much faster
29384
29414
  borderColor: color,
29385
29415
  backgroundColor,
@@ -29585,9 +29615,7 @@ function createComboChartRuntime(chart, getters) {
29585
29615
  const localeFormat = { format: mainDataSetFormat, locale };
29586
29616
  const fontColor = chartFontColor(chart.background);
29587
29617
  const config = getDefaultChartJsRuntime(chart, labels, fontColor, localeFormat);
29588
- const legend = {
29589
- labels: { color: fontColor },
29590
- };
29618
+ const legend = getChartJsLegend(fontColor);
29591
29619
  if (chart.legendPosition === "none") {
29592
29620
  legend.display = false;
29593
29621
  }
@@ -29651,13 +29679,14 @@ function createComboChartRuntime(chart, getters) {
29651
29679
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
29652
29680
  let maxLength = 0;
29653
29681
  const trendDatasets = [];
29654
- for (let [index, { label, data }] of dataSetsValues.entries()) {
29682
+ for (let [index, { label, data, hidden }] of dataSetsValues.entries()) {
29655
29683
  const design = definition.dataSets[index];
29656
29684
  const color = colors.next();
29657
29685
  const type = design?.type ?? "line";
29658
29686
  const dataset = {
29659
29687
  label: design?.label ?? label,
29660
29688
  data,
29689
+ hidden,
29661
29690
  borderColor: color,
29662
29691
  backgroundColor: color,
29663
29692
  yAxisID: design?.yAxisId ?? "y",
@@ -30265,7 +30294,7 @@ function filterNegativeValues(labels, datasets) {
30265
30294
  function createPieChartRuntime(chart, getters) {
30266
30295
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
30267
30296
  let labels = labelValues.formattedValues;
30268
- let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
30297
+ let dataSetsValues = getChartDatasetValues(getters, chart.dataSets).filter((dataSet) => !dataSet.hidden);
30269
30298
  if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
30270
30299
  labels.shift();
30271
30300
  }
@@ -30283,7 +30312,7 @@ function createPieChartRuntime(chart, getters) {
30283
30312
  const dataset = {
30284
30313
  label,
30285
30314
  data,
30286
- borderColor: BACKGROUND_CHART_COLOR,
30315
+ borderColor: chart.background || "#FFFFFF",
30287
30316
  backgroundColor,
30288
30317
  hoverOffset: 30,
30289
30318
  };
@@ -30412,8 +30441,9 @@ function createPyramidChartRuntime(chart, getters) {
30412
30441
  const barDef = { ...chart.getDefinition(), type: "bar" };
30413
30442
  const barChart = new BarChart(barDef, chart.sheetId, getters);
30414
30443
  const barRuntime = createBarChartRuntime(barChart, getters);
30444
+ // align design with filtered datasets
30415
30445
  const config = barRuntime.chartJsConfig;
30416
- let datasets = config.data?.datasets;
30446
+ let datasets = config.data?.datasets.filter((dataSet) => !dataSet.hidden);
30417
30447
  if (datasets && datasets[0]) {
30418
30448
  datasets[0].data = datasets[0].data.map((value) => (value > 0 ? value : 0));
30419
30449
  }
@@ -30810,7 +30840,7 @@ function getWaterfallConfiguration(chart, labels, dataSeriesLabels, localeFormat
30810
30840
  function createWaterfallChartRuntime(chart, getters) {
30811
30841
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
30812
30842
  let labels = labelValues.formattedValues;
30813
- let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
30843
+ let dataSetsValues = getChartDatasetValues(getters, chart.dataSets).filter((ds) => !ds.hidden);
30814
30844
  if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
30815
30845
  labels.shift();
30816
30846
  }
@@ -51166,6 +51196,10 @@ class CellPlugin extends CorePlugin {
51166
51196
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
51167
51197
  case "CLEAR_CELL":
51168
51198
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
51199
+ case "UPDATE_CELL_POSITION":
51200
+ return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
51201
+ ? "Success" /* CommandResult.Success */
51202
+ : "InvalidCellId" /* CommandResult.InvalidCellId */;
51169
51203
  default:
51170
51204
  return "Success" /* CommandResult.Success */;
51171
51205
  }
@@ -51210,6 +51244,9 @@ class CellPlugin extends CorePlugin {
51210
51244
  case "DELETE_CONTENT":
51211
51245
  this.clearZones(cmd.sheetId, cmd.target);
51212
51246
  break;
51247
+ case "DELETE_SHEET": {
51248
+ this.history.update("cells", cmd.sheetId, undefined);
51249
+ }
51213
51250
  }
51214
51251
  }
51215
51252
  clearZones(sheetId, zones) {
@@ -52431,8 +52468,14 @@ class DataValidationPlugin extends CorePlugin {
52431
52468
  allowDispatch(cmd) {
52432
52469
  switch (cmd.type) {
52433
52470
  case "ADD_DATA_VALIDATION_RULE":
52471
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
52472
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
52473
+ }
52434
52474
  return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
52435
52475
  case "REMOVE_DATA_VALIDATION_RULE":
52476
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
52477
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
52478
+ }
52436
52479
  if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
52437
52480
  return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
52438
52481
  }
@@ -52652,6 +52695,7 @@ class DataValidationPlugin extends CorePlugin {
52652
52695
  class FigurePlugin extends CorePlugin {
52653
52696
  static getters = ["getFigures", "getFigure", "getFigureSheetId"];
52654
52697
  figures = {};
52698
+ insertionOrders = []; // TODO use a list in master
52655
52699
  // ---------------------------------------------------------------------------
52656
52700
  // Command Handling
52657
52701
  // ---------------------------------------------------------------------------
@@ -52754,11 +52798,14 @@ class FigurePlugin extends CorePlugin {
52754
52798
  }
52755
52799
  addFigure(figure, sheetId) {
52756
52800
  this.history.update("figures", sheetId, figure.id, figure);
52801
+ this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
52757
52802
  }
52758
52803
  deleteSheet(sheetId) {
52804
+ this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
52759
52805
  this.history.update("figures", sheetId, undefined);
52760
52806
  }
52761
52807
  removeFigure(id, sheetId) {
52808
+ this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
52762
52809
  this.history.update("figures", sheetId, id, undefined);
52763
52810
  }
52764
52811
  checkFigureExists(sheetId, figureId) {
@@ -52777,7 +52824,14 @@ class FigurePlugin extends CorePlugin {
52777
52824
  // Getters
52778
52825
  // ---------------------------------------------------------------------------
52779
52826
  getFigures(sheetId) {
52780
- return Object.values(this.figures[sheetId] || {}).filter(isDefined);
52827
+ const figures = [];
52828
+ for (const figureId of this.insertionOrders) {
52829
+ const figure = this.figures[sheetId]?.[figureId];
52830
+ if (figure) {
52831
+ figures.push(figure);
52832
+ }
52833
+ }
52834
+ return figures;
52781
52835
  }
52782
52836
  getFigure(sheetId, figureId) {
52783
52837
  return this.figures[sheetId]?.[figureId];
@@ -52790,11 +52844,9 @@ class FigurePlugin extends CorePlugin {
52790
52844
  // ---------------------------------------------------------------------------
52791
52845
  import(data) {
52792
52846
  for (let sheet of data.sheets) {
52793
- const figures = {};
52794
- sheet.figures.forEach((figure) => {
52795
- figures[figure.id] = figure;
52796
- });
52797
- this.figures[sheet.id] = figures;
52847
+ for (const figure of sheet.figures) {
52848
+ this.addFigure(figure, sheet.id);
52849
+ }
52798
52850
  }
52799
52851
  }
52800
52852
  export(data) {
@@ -54220,6 +54272,9 @@ class SheetPlugin extends CorePlugin {
54220
54272
  case "CREATE_SHEET": {
54221
54273
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
54222
54274
  }
54275
+ case "DUPLICATE_SHEET": {
54276
+ return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
54277
+ }
54223
54278
  case "MOVE_SHEET":
54224
54279
  try {
54225
54280
  const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
@@ -55031,6 +55086,10 @@ class SheetPlugin extends CorePlugin {
55031
55086
  checkZonesAreInSheet(cmd) {
55032
55087
  if (!("sheetId" in cmd))
55033
55088
  return "Success" /* CommandResult.Success */;
55089
+ if ("ranges" in cmd &&
55090
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
55091
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55092
+ }
55034
55093
  return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
55035
55094
  }
55036
55095
  }
@@ -55038,6 +55097,7 @@ class SheetPlugin extends CorePlugin {
55038
55097
  class TablePlugin extends CorePlugin {
55039
55098
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
55040
55099
  tables = {};
55100
+ insertionOrders = {};
55041
55101
  adaptRanges(applyChange, sheetId) {
55042
55102
  const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
55043
55103
  for (const sheetId of sheetIds) {
@@ -55049,6 +55109,9 @@ class TablePlugin extends CorePlugin {
55049
55109
  allowDispatch(cmd) {
55050
55110
  switch (cmd.type) {
55051
55111
  case "CREATE_TABLE":
55112
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
55113
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55114
+ }
55052
55115
  const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
55053
55116
  if (!areZonesContinuous(zones)) {
55054
55117
  return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
@@ -55079,11 +55142,13 @@ class TablePlugin extends CorePlugin {
55079
55142
  switch (cmd.type) {
55080
55143
  case "CREATE_SHEET":
55081
55144
  this.history.update("tables", cmd.sheetId, {});
55145
+ this.history.update("insertionOrders", cmd.sheetId, []);
55082
55146
  break;
55083
55147
  case "DELETE_SHEET": {
55084
55148
  const tables = { ...this.tables };
55085
55149
  delete tables[cmd.sheetId];
55086
55150
  this.history.update("tables", tables);
55151
+ this.history.update("insertionOrders", cmd.sheetId, undefined);
55087
55152
  break;
55088
55153
  }
55089
55154
  case "DUPLICATE_SHEET": {
@@ -55095,6 +55160,9 @@ class TablePlugin extends CorePlugin {
55095
55160
  : this.copyStaticTableForSheet(cmd.sheetIdTo, table);
55096
55161
  }
55097
55162
  this.history.update("tables", cmd.sheetIdTo, newTables);
55163
+ this.history.update("insertionOrders", cmd.sheetIdTo, [
55164
+ ...(this.insertionOrders[cmd.sheetId] ?? []),
55165
+ ]);
55098
55166
  break;
55099
55167
  }
55100
55168
  case "CREATE_TABLE": {
@@ -55108,6 +55176,10 @@ class TablePlugin extends CorePlugin {
55108
55176
  ? this.createDynamicTable(id, union, config)
55109
55177
  : this.createStaticTable(id, cmd.tableType, union, config);
55110
55178
  this.history.update("tables", cmd.sheetId, newTable.id, newTable);
55179
+ this.history.update("insertionOrders", cmd.sheetId, [
55180
+ ...(this.insertionOrders[cmd.sheetId] ?? []),
55181
+ newTable.id,
55182
+ ]);
55111
55183
  break;
55112
55184
  }
55113
55185
  case "REMOVE_TABLE": {
@@ -55118,6 +55190,7 @@ class TablePlugin extends CorePlugin {
55118
55190
  }
55119
55191
  }
55120
55192
  this.history.update("tables", cmd.sheetId, tables);
55193
+ this.history.update("insertionOrders", cmd.sheetId, this.insertionOrders[cmd.sheetId]?.filter((id) => id in tables));
55121
55194
  break;
55122
55195
  }
55123
55196
  case "UPDATE_TABLE": {
@@ -55153,7 +55226,14 @@ class TablePlugin extends CorePlugin {
55153
55226
  }
55154
55227
  }
55155
55228
  getCoreTables(sheetId) {
55156
- return this.tables[sheetId] ? Object.values(this.tables[sheetId]).filter(isDefined) : [];
55229
+ const tables = [];
55230
+ for (const tableId of this.insertionOrders[sheetId] || []) {
55231
+ const table = this.tables[sheetId][tableId];
55232
+ if (table) {
55233
+ tables.push(table);
55234
+ }
55235
+ }
55236
+ return tables;
55157
55237
  }
55158
55238
  getCoreTable({ sheetId, col, row }) {
55159
55239
  return this.getCoreTables(sheetId).find((table) => isInside(col, row, table.range.zone));
@@ -55436,6 +55516,7 @@ class TablePlugin extends CorePlugin {
55436
55516
  // ---------------------------------------------------------------------------
55437
55517
  import(data) {
55438
55518
  for (const sheet of data.sheets) {
55519
+ const tableIds = [];
55439
55520
  for (const tableData of sheet.tables || []) {
55440
55521
  const uuid = this.uuidGenerator.uuidv4();
55441
55522
  const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
@@ -55445,7 +55526,9 @@ class TablePlugin extends CorePlugin {
55445
55526
  ? this.createDynamicTable(uuid, range, tableConfig)
55446
55527
  : this.createStaticTable(uuid, tableType, range, tableConfig);
55447
55528
  this.history.update("tables", sheet.id, table.id, table);
55529
+ tableIds.push(table.id);
55448
55530
  }
55531
+ this.history.update("insertionOrders", sheet.id, tableIds);
55449
55532
  }
55450
55533
  }
55451
55534
  export(data) {
@@ -55485,7 +55568,10 @@ class HeaderGroupingPlugin extends CorePlugin {
55485
55568
  allowDispatch(cmd) {
55486
55569
  switch (cmd.type) {
55487
55570
  case "GROUP_HEADERS": {
55488
- const { start, end } = cmd;
55571
+ const { start, end, sheetId } = cmd;
55572
+ if (!this.getters.tryGetSheet(sheetId)) {
55573
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55574
+ }
55489
55575
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
55490
55576
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
55491
55577
  }
@@ -55498,7 +55584,10 @@ class HeaderGroupingPlugin extends CorePlugin {
55498
55584
  break;
55499
55585
  }
55500
55586
  case "UNGROUP_HEADERS": {
55501
- const { start, end } = cmd;
55587
+ const { start, end, sheetId } = cmd;
55588
+ if (!this.getters.tryGetSheet(sheetId)) {
55589
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55590
+ }
55502
55591
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
55503
55592
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
55504
55593
  }
@@ -55509,6 +55598,9 @@ class HeaderGroupingPlugin extends CorePlugin {
55509
55598
  }
55510
55599
  case "UNFOLD_HEADER_GROUP":
55511
55600
  case "FOLD_HEADER_GROUP":
55601
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
55602
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55603
+ }
55512
55604
  const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
55513
55605
  if (!group) {
55514
55606
  return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
@@ -55909,6 +56001,9 @@ class PivotCorePlugin extends CorePlugin {
55909
56001
  return this.checkDuplicatedMeasureIds(cmd.pivot);
55910
56002
  }
55911
56003
  case "UPDATE_PIVOT": {
56004
+ if (!(cmd.pivotId in this.pivots)) {
56005
+ return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
56006
+ }
55912
56007
  if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
55913
56008
  return "NoChanges" /* CommandResult.NoChanges */;
55914
56009
  }
@@ -55925,6 +56020,8 @@ class PivotCorePlugin extends CorePlugin {
55925
56020
  return "EmptyName" /* CommandResult.EmptyName */;
55926
56021
  }
55927
56022
  break;
56023
+ case "REMOVE_PIVOT":
56024
+ case "DUPLICATE_PIVOT":
55928
56025
  case "INSERT_PIVOT": {
55929
56026
  if (!(cmd.pivotId in this.pivots)) {
55930
56027
  return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
@@ -55974,7 +56071,7 @@ class PivotCorePlugin extends CorePlugin {
55974
56071
  break;
55975
56072
  }
55976
56073
  case "UPDATE_PIVOT": {
55977
- this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
56074
+ this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
55978
56075
  this.compileCalculatedMeasures(cmd.pivot.measures);
55979
56076
  break;
55980
56077
  }
@@ -56045,7 +56142,7 @@ class PivotCorePlugin extends CorePlugin {
56045
56142
  // Private
56046
56143
  // -------------------------------------------------------------------------
56047
56144
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
56048
- this.history.update("pivots", pivotId, { definition: pivot, formulaId });
56145
+ this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
56049
56146
  this.compileCalculatedMeasures(pivot.measures);
56050
56147
  this.history.update("formulaIds", formulaId, pivotId);
56051
56148
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
@@ -60977,6 +61074,9 @@ function updateChartRangesTransformation(toTransform, executed) {
60977
61074
  };
60978
61075
  }
60979
61076
  function createSheetTransformation(toTransform, executed) {
61077
+ if (toTransform.sheetId === executed.sheetId) {
61078
+ toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
61079
+ }
60980
61080
  if (toTransform.name === executed.name) {
60981
61081
  return {
60982
61082
  ...toTransform,
@@ -61621,15 +61721,6 @@ class Session extends EventBus {
61621
61721
  this.waitingAck = true;
61622
61722
  this.sendPendingMessage();
61623
61723
  }
61624
- dropPendingRevision(revisionId) {
61625
- this.revisions.drop(revisionId);
61626
- const revisionIds = this.pendingMessages
61627
- .filter((message) => message.type === "REMOTE_REVISION")
61628
- .map((message) => message.nextRevisionId);
61629
- this.trigger("pending-revisions-dropped", { revisionIds });
61630
- this.waitingAck = false;
61631
- this.waitingUndoRedoAck = false;
61632
- }
61633
61724
  /**
61634
61725
  * Send the next pending message
61635
61726
  */
@@ -61638,15 +61729,14 @@ class Session extends EventBus {
61638
61729
  if (!message)
61639
61730
  return;
61640
61731
  if (message.type === "REMOTE_REVISION") {
61641
- const revision = this.revisions.get(message.nextRevisionId);
61732
+ let revision = this.revisions.get(message.nextRevisionId);
61642
61733
  if (revision.commands.length === 0) {
61643
61734
  /**
61644
- * The command is empty, we have to drop all the next local revisions
61735
+ * The command is empty, we have to rebase all the next local revisions
61645
61736
  * to avoid issues with undo/redo
61646
61737
  */
61647
- this.dropPendingRevision(revision.id);
61648
- this.pendingMessages = [];
61649
- return;
61738
+ this.revisions.rebase(revision.id);
61739
+ revision = this.revisions.get(message.nextRevisionId);
61650
61740
  }
61651
61741
  message = {
61652
61742
  ...message,
@@ -61681,18 +61771,16 @@ class Session extends EventBus {
61681
61771
  case "REVISION_UNDONE": {
61682
61772
  this.waitingAck = false;
61683
61773
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
61684
- const pendingRemoteRevisions = this.pendingMessages.filter((message) => message.type === "REMOTE_REVISION");
61685
- const firstTransformedRevisionIndex = pendingRemoteRevisions.findIndex((message) => !deepEquals(message.commands, this.revisions.get(message.nextRevisionId).commands));
61686
- if (firstTransformedRevisionIndex !== -1) {
61774
+ const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
61775
+ if (firstPendingRevisionId !== -1) {
61687
61776
  /**
61688
61777
  * Some revisions undergo transformations that may cause issues with
61689
61778
  * undo/redo if the transformation is destructive (we don't get back
61690
61779
  * the original command by transforming it with the inverse).
61691
- * To prevent these problems, we must discard all subsequent local
61780
+ * To prevent these problems, we must rebase all subsequent local
61692
61781
  * revisions.
61693
61782
  */
61694
- this.dropPendingRevision(this.pendingMessages[firstTransformedRevisionIndex].nextRevisionId);
61695
- this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
61783
+ this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
61696
61784
  }
61697
61785
  this.serverRevisionId = message.nextRevisionId;
61698
61786
  this.processedRevisions.add(message.nextRevisionId);
@@ -62781,6 +62869,10 @@ class SheetUIPlugin extends UIPlugin {
62781
62869
  */
62782
62870
  checkZonesAreInSheet(cmd) {
62783
62871
  const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
62872
+ if ("ranges" in cmd &&
62873
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
62874
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
62875
+ }
62784
62876
  const zones = this.getters.getCommandZones(cmd);
62785
62877
  if (!sheetId && zones.length > 0) {
62786
62878
  return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
@@ -63335,7 +63427,6 @@ class HistoryPlugin extends UIPlugin {
63335
63427
  super(config);
63336
63428
  this.session = config.session;
63337
63429
  this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
63338
- this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
63339
63430
  this.session.on("snapshot", this, () => {
63340
63431
  this.undoStack = [];
63341
63432
  this.redoStack = [];
@@ -63405,10 +63496,6 @@ class HistoryPlugin extends UIPlugin {
63405
63496
  const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
63406
63497
  return canRepeatRevision(lastNonRedoRevision);
63407
63498
  }
63408
- drop(revisionIds) {
63409
- this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
63410
- this.redoStack = [];
63411
- }
63412
63499
  onNewLocalStateUpdate({ id }) {
63413
63500
  this.undoStack.push(id);
63414
63501
  this.redoStack = [];
@@ -66108,7 +66195,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
66108
66195
  case "UNGROUP_HEADERS":
66109
66196
  case "GROUP_HEADERS":
66110
66197
  case "CREATE_SHEET":
66111
- this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
66198
+ if (this.getters.tryGetSheet(cmd.sheetId)) {
66199
+ this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
66200
+ }
66112
66201
  break;
66113
66202
  case "DUPLICATE_SHEET":
66114
66203
  this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
@@ -66116,12 +66205,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
66116
66205
  }
66117
66206
  }
66118
66207
  finalize() {
66119
- if (this.isDirty) {
66120
- for (const sheetId of this.getters.getSheetIds()) {
66208
+ for (const sheetId of this.getters.getSheetIds()) {
66209
+ // sheets can be created without this plugin being aware of it
66210
+ // in concurrent situations.
66211
+ if (this.isDirty || !this.headerPositions[sheetId]) {
66121
66212
  this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
66122
66213
  }
66123
- this.isDirty = false;
66124
66214
  }
66215
+ this.isDirty = false;
66125
66216
  }
66126
66217
  /**
66127
66218
  * Returns the size, start and end coordinates of a column on an unfolded sheet
@@ -69624,9 +69715,16 @@ class SelectiveHistory {
69624
69715
  this.fastForward();
69625
69716
  this.insert(redoId, this.buildEmpty(redoId), insertAfter);
69626
69717
  }
69627
- drop(operationId) {
69718
+ rebase(operationId) {
69719
+ const operation = this.get(operationId);
69720
+ const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
69628
69721
  this.revertBefore(operationId);
69722
+ const baseId = this.HEAD_OPERATION.id;
69629
69723
  this.tree.drop(operationId);
69724
+ this.insert(operationId, operation, baseId);
69725
+ for (const { operation } of execution) {
69726
+ this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
69727
+ }
69630
69728
  }
69631
69729
  /**
69632
69730
  * Revert the state as it was *before* the given operation was executed.
@@ -72668,6 +72766,11 @@ class Model extends EventBus {
72668
72766
  dispatch: (command) => {
72669
72767
  const result = this.checkDispatchAllowed(command);
72670
72768
  if (!result.isSuccessful) {
72769
+ // core views plugins need to be invalidated
72770
+ this.dispatchToHandlers(this.coreHandlers, {
72771
+ type: "UNDO",
72772
+ commands: [command],
72773
+ });
72671
72774
  return;
72672
72775
  }
72673
72776
  this.isReplayingCommand = true;
@@ -73183,6 +73286,6 @@ const constants = {
73183
73286
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
73184
73287
 
73185
73288
 
73186
- __info__.version = "18.0.16";
73187
- __info__.date = "2025-02-14T08:44:19.475Z";
73188
- __info__.hash = "39979ab";
73289
+ __info__.version = "18.0.17";
73290
+ __info__.date = "2025-02-25T05:58:39.632Z";
73291
+ __info__.hash = "2ee4347";