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