@odoo/o-spreadsheet 18.0.14 → 18.0.16

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.14
6
- * @date 2025-02-05T06:47:33.041Z
7
- * @hash 90f2af4
5
+ * @version 18.0.16
6
+ * @date 2025-02-14T08:44:19.475Z
7
+ * @hash 39979ab
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -766,9 +766,16 @@
766
766
  }
767
767
  return true;
768
768
  }
769
- /** Check if the given array contains all the values of the other array. */
769
+ /**
770
+ * Check if the given array contains all the values of the other array.
771
+ * It makes the assumption that both array do not contain duplicates.
772
+ */
770
773
  function includesAll(arr, values) {
771
- return values.every((value) => arr.includes(value));
774
+ if (arr.length < values.length) {
775
+ return false;
776
+ }
777
+ const set = new Set(arr);
778
+ return values.every((value) => set.has(value));
772
779
  }
773
780
  /**
774
781
  * Return an object with all the keys in the object that have a falsy value removed.
@@ -6339,6 +6346,37 @@
6339
6346
  setIsFastStrategy(isFast) {
6340
6347
  this.isFastIdStrategy = isFast;
6341
6348
  }
6349
+ /**
6350
+ * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
6351
+ * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
6352
+ * it also has a smaller size, which is preferable to alleviate the overall data size.
6353
+ *
6354
+ * This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
6355
+ * as they will appear several times in the revisions and local history.
6356
+ *
6357
+ */
6358
+ smallUuid() {
6359
+ if (this.isFastIdStrategy) {
6360
+ this.fastIdStart++;
6361
+ return String(this.fastIdStart);
6362
+ //@ts-ignore
6363
+ }
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));
6367
+ }
6368
+ else {
6369
+ // mainly for jest and other browsers that do not have the crypto functionality
6370
+ return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
6371
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
6372
+ return v.toString(16);
6373
+ });
6374
+ }
6375
+ }
6376
+ /**
6377
+ * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
6378
+ * This method should be used when you need to avoid collisions at all costs, like the id of a revision.
6379
+ */
6342
6380
  uuidv4() {
6343
6381
  if (this.isFastIdStrategy) {
6344
6382
  this.fastIdStart++;
@@ -6352,7 +6390,7 @@
6352
6390
  else {
6353
6391
  // mainly for jest and other browsers that do not have the crypto functionality
6354
6392
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
6355
- var r = (Math.random() * 16) | 0, v = c === "x" ? r : (r & 0x3) | 0x8;
6393
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
6356
6394
  return v.toString(16);
6357
6395
  });
6358
6396
  }
@@ -8331,7 +8369,7 @@
8331
8369
  };
8332
8370
  }
8333
8371
  getPasteTarget(sheetId, target, content, options) {
8334
- const newId = new UuidGenerator().uuidv4();
8372
+ const newId = new UuidGenerator().smallUuid();
8335
8373
  return { zones: [], figureId: newId, sheetId };
8336
8374
  }
8337
8375
  paste(target, clippedContent, options) {
@@ -8497,7 +8535,7 @@
8497
8535
  if (!targetCF && queuedCfs) {
8498
8536
  targetCF = queuedCfs.find((queued) => queued.cf.stopIfTrue === originCF.stopIfTrue && deepEquals(queued.cf.rule, originCF.rule))?.cf;
8499
8537
  }
8500
- return targetCF || { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
8538
+ return targetCF || { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
8501
8539
  }
8502
8540
  }
8503
8541
 
@@ -8590,7 +8628,7 @@
8590
8628
  }
8591
8629
  return (targetRule || {
8592
8630
  ...originRule,
8593
- id: newId ? this.uuidGenerator.uuidv4() : originRule.id,
8631
+ id: newId ? this.uuidGenerator.smallUuid() : originRule.id,
8594
8632
  ranges: [],
8595
8633
  });
8596
8634
  }
@@ -8652,7 +8690,7 @@
8652
8690
  };
8653
8691
  }
8654
8692
  getPasteTarget(sheetId, target, content, options) {
8655
- const newId = new UuidGenerator().uuidv4();
8693
+ const newId = new UuidGenerator().smallUuid();
8656
8694
  return { sheetId, zones: [], figureId: newId };
8657
8695
  }
8658
8696
  paste(target, clippedContent, options) {
@@ -15054,7 +15092,7 @@ stores.inject(MyMetaStore, storeInstance);
15054
15092
  }
15055
15093
  }
15056
15094
  },
15057
- isExported: true,
15095
+ isExported: false,
15058
15096
  };
15059
15097
  // -----------------------------------------------------------------------------
15060
15098
  // UNIQUE
@@ -28508,17 +28546,15 @@ stores.inject(MyMetaStore, storeInstance);
28508
28546
  plugins: [],
28509
28547
  };
28510
28548
  }
28511
- function getChartLabelFormat(getters, range) {
28549
+ function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
28512
28550
  if (!range)
28513
28551
  return undefined;
28514
- const { sheetId, zone: { left, top, bottom }, } = range;
28515
- for (let row = top; row <= bottom; row++) {
28516
- const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
28517
- if (format) {
28518
- return format;
28519
- }
28552
+ const { sheetId, zone } = range;
28553
+ const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
28554
+ if (shouldRemoveFirstLabel) {
28555
+ formats.shift();
28520
28556
  }
28521
- return undefined;
28557
+ return formats.find((format) => format !== undefined);
28522
28558
  }
28523
28559
  function getChartLabelValues(getters, dataSets, labelRange) {
28524
28560
  let labels = { values: [], formattedValues: [] };
@@ -28806,9 +28842,7 @@ stores.inject(MyMetaStore, storeInstance);
28806
28842
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
28807
28843
  let labels = labelValues.formattedValues;
28808
28844
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
28809
- if (chart.dataSetsHaveTitle &&
28810
- dataSetsValues[0] &&
28811
- labels.length > dataSetsValues[0].data.length) {
28845
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
28812
28846
  labels.shift();
28813
28847
  }
28814
28848
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -29077,8 +29111,8 @@ stores.inject(MyMetaStore, storeInstance);
29077
29111
  }
29078
29112
  return { labels: newLabels, dataSetsValues: newDatasets };
29079
29113
  }
29080
- function canChartParseLabels(labelRange, getters) {
29081
- return canBeDateChart(labelRange, getters) || canBeLinearChart(labelRange, getters);
29114
+ function canChartParseLabels(chart, getters) {
29115
+ return canBeDateChart(chart, getters) || canBeLinearChart(chart, getters);
29082
29116
  }
29083
29117
  function getChartAxisType(chart, getters) {
29084
29118
  if (isDateChart(chart, getters) && isLuxonTimeAdapterInstalled()) {
@@ -29090,23 +29124,26 @@ stores.inject(MyMetaStore, storeInstance);
29090
29124
  return "category";
29091
29125
  }
29092
29126
  function isDateChart(chart, getters) {
29093
- return !chart.labelsAsText && canBeDateChart(chart.labelRange, getters);
29127
+ return !chart.labelsAsText && canBeDateChart(chart, getters);
29094
29128
  }
29095
29129
  function isLinearChart(chart, getters) {
29096
- return !chart.labelsAsText && canBeLinearChart(chart.labelRange, getters);
29130
+ return !chart.labelsAsText && canBeLinearChart(chart, getters);
29097
29131
  }
29098
- function canBeDateChart(labelRange, getters) {
29099
- if (!labelRange || !canBeLinearChart(labelRange, getters)) {
29132
+ function canBeDateChart(chart, getters) {
29133
+ if (!chart.labelRange || !canBeLinearChart(chart, getters)) {
29100
29134
  return false;
29101
29135
  }
29102
- const labelFormat = getChartLabelFormat(getters, labelRange);
29136
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle));
29103
29137
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
29104
29138
  }
29105
- function canBeLinearChart(labelRange, getters) {
29106
- if (!labelRange) {
29139
+ function canBeLinearChart(chart, getters) {
29140
+ if (!chart.labelRange) {
29107
29141
  return false;
29108
29142
  }
29109
- const labels = getters.getRangeValues(labelRange);
29143
+ const labels = getters.getRangeValues(chart.labelRange);
29144
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
29145
+ labels.shift();
29146
+ }
29110
29147
  if (labels.some((label) => isNaN(Number(label)) && label)) {
29111
29148
  return false;
29112
29149
  }
@@ -29190,9 +29227,8 @@ stores.inject(MyMetaStore, storeInstance);
29190
29227
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
29191
29228
  let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
29192
29229
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
29193
- if (chart.dataSetsHaveTitle &&
29194
- dataSetsValues[0] &&
29195
- labels.length > dataSetsValues[0].data.length) {
29230
+ const removeFirstLabel = shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle);
29231
+ if (removeFirstLabel) {
29196
29232
  labels.shift();
29197
29233
  }
29198
29234
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -29282,12 +29318,7 @@ stores.inject(MyMetaStore, storeInstance);
29282
29318
  background: chart.background,
29283
29319
  callback: formatTickValue(options),
29284
29320
  };
29285
- if (chart.dataSetsHaveTitle &&
29286
- dataSetsValues[0] &&
29287
- labels.length > dataSetsValues[0].data.length) {
29288
- labels.shift();
29289
- }
29290
- const labelFormat = getChartLabelFormat(getters, chart.labelRange);
29321
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, removeFirstLabel);
29291
29322
  if (axisType === "time") {
29292
29323
  const axis = {
29293
29324
  type: "time",
@@ -29545,9 +29576,7 @@ stores.inject(MyMetaStore, storeInstance);
29545
29576
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
29546
29577
  let labels = labelValues.formattedValues;
29547
29578
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
29548
- if (chart.dataSetsHaveTitle &&
29549
- dataSetsValues[0] &&
29550
- labels.length > dataSetsValues[0].data.length) {
29579
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
29551
29580
  labels.shift();
29552
29581
  }
29553
29582
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -30238,9 +30267,7 @@ stores.inject(MyMetaStore, storeInstance);
30238
30267
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
30239
30268
  let labels = labelValues.formattedValues;
30240
30269
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
30241
- if (chart.dataSetsHaveTitle &&
30242
- dataSetsValues[0] &&
30243
- labels.length > dataSetsValues[0].data.length) {
30270
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
30244
30271
  labels.shift();
30245
30272
  }
30246
30273
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -30785,9 +30812,7 @@ stores.inject(MyMetaStore, storeInstance);
30785
30812
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
30786
30813
  let labels = labelValues.formattedValues;
30787
30814
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
30788
- if (chart.dataSetsHaveTitle &&
30789
- dataSetsValues[0] &&
30790
- labels.length > dataSetsValues[0].data.length) {
30815
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
30791
30816
  labels.shift();
30792
30817
  }
30793
30818
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -32283,7 +32308,7 @@ stores.inject(MyMetaStore, storeInstance);
32283
32308
  const deleteSheet = {
32284
32309
  name: _t("Delete"),
32285
32310
  isVisible: (env) => {
32286
- return env.model.getters.getSheetIds().length > 1;
32311
+ return env.model.getters.getVisibleSheetIds().length > 1;
32287
32312
  },
32288
32313
  execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
32289
32314
  env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
@@ -32294,7 +32319,7 @@ stores.inject(MyMetaStore, storeInstance);
32294
32319
  name: _t("Duplicate"),
32295
32320
  execute: (env) => {
32296
32321
  const sheetIdFrom = env.model.getters.getActiveSheetId();
32297
- const sheetIdTo = env.model.uuidGenerator.uuidv4();
32322
+ const sheetIdTo = env.model.uuidGenerator.smallUuid();
32298
32323
  env.model.dispatch("DUPLICATE_SHEET", {
32299
32324
  sheetId: sheetIdFrom,
32300
32325
  sheetIdTo,
@@ -32921,20 +32946,21 @@ stores.inject(MyMetaStore, storeInstance);
32921
32946
  }
32922
32947
  // Only display legend for several datasets.
32923
32948
  const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
32924
- const labelRange = labelRangeXc ? getters.getRangeFromSheetXC(sheetId, labelRangeXc) : undefined;
32925
- if (canChartParseLabels(labelRange, getters)) {
32926
- return {
32927
- title: {},
32928
- dataSets,
32929
- labelsAsText: false,
32930
- stacked: false,
32931
- aggregated: false,
32932
- cumulative: false,
32933
- labelRange: labelRangeXc,
32934
- type: "line",
32935
- dataSetsHaveTitle,
32936
- legendPosition: newLegendPos,
32937
- };
32949
+ const lineChartDefinition = {
32950
+ title: {},
32951
+ dataSets,
32952
+ labelsAsText: false,
32953
+ stacked: false,
32954
+ aggregated: false,
32955
+ cumulative: false,
32956
+ labelRange: labelRangeXc,
32957
+ type: "line",
32958
+ dataSetsHaveTitle,
32959
+ legendPosition: newLegendPos,
32960
+ };
32961
+ const chart = new LineChart(lineChartDefinition, sheetId, getters);
32962
+ if (canChartParseLabels(chart, getters)) {
32963
+ return lineChartDefinition;
32938
32964
  }
32939
32965
  const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
32940
32966
  if (singleColumn &&
@@ -33302,7 +33328,7 @@ stores.inject(MyMetaStore, storeInstance);
33302
33328
  //------------------------------------------------------------------------------
33303
33329
  const CREATE_CHART = (env) => {
33304
33330
  const getters = env.model.getters;
33305
- const id = env.model.uuidGenerator.uuidv4();
33331
+ const id = env.model.uuidGenerator.smallUuid();
33306
33332
  const sheetId = getters.getActiveSheetId();
33307
33333
  if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
33308
33334
  env.model.selection.selectTableAroundSelection();
@@ -33325,8 +33351,8 @@ stores.inject(MyMetaStore, storeInstance);
33325
33351
  // Pivots
33326
33352
  //------------------------------------------------------------------------------
33327
33353
  const CREATE_PIVOT = (env) => {
33328
- const pivotId = env.model.uuidGenerator.uuidv4();
33329
- const newSheetId = env.model.uuidGenerator.uuidv4();
33354
+ const pivotId = env.model.uuidGenerator.smallUuid();
33355
+ const newSheetId = env.model.uuidGenerator.smallUuid();
33330
33356
  const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
33331
33357
  if (result.isSuccessful) {
33332
33358
  env.openSidePanel("PivotSidePanel", { pivotId });
@@ -33385,7 +33411,7 @@ stores.inject(MyMetaStore, storeInstance);
33385
33411
  const CREATE_IMAGE = async (env) => {
33386
33412
  if (env.imageProvider) {
33387
33413
  const sheetId = env.model.getters.getActiveSheetId();
33388
- const figureId = env.model.uuidGenerator.uuidv4();
33414
+ const figureId = env.model.uuidGenerator.smallUuid();
33389
33415
  const image = await requestImage(env);
33390
33416
  if (!image) {
33391
33417
  throw new Error("No image provider was given to the environment");
@@ -33938,7 +33964,7 @@ stores.inject(MyMetaStore, storeInstance);
33938
33964
  ranges,
33939
33965
  sheetId,
33940
33966
  rule: {
33941
- id: env.model.uuidGenerator.uuidv4(),
33967
+ id: env.model.uuidGenerator.smallUuid(),
33942
33968
  criterion: {
33943
33969
  type: "isBoolean",
33944
33970
  values: [],
@@ -33954,7 +33980,7 @@ stores.inject(MyMetaStore, storeInstance);
33954
33980
  const zones = env.model.getters.getSelectedZones();
33955
33981
  const sheetId = env.model.getters.getActiveSheetId();
33956
33982
  const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
33957
- const ruleID = env.model.uuidGenerator.uuidv4();
33983
+ const ruleID = env.model.uuidGenerator.smallUuid();
33958
33984
  env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
33959
33985
  ranges,
33960
33986
  sheetId,
@@ -33985,7 +34011,7 @@ stores.inject(MyMetaStore, storeInstance);
33985
34011
  execute: (env) => {
33986
34012
  const activeSheetId = env.model.getters.getActiveSheetId();
33987
34013
  const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
33988
- const sheetId = env.model.uuidGenerator.uuidv4();
34014
+ const sheetId = env.model.uuidGenerator.smallUuid();
33989
34015
  env.model.dispatch("CREATE_SHEET", { sheetId, position });
33990
34016
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
33991
34017
  },
@@ -37980,7 +38006,7 @@ stores.inject(MyMetaStore, storeInstance);
37980
38006
  get canTreatLabelsAsText() {
37981
38007
  const chart = this.env.model.getters.getChart(this.props.figureId);
37982
38008
  if (chart && chart instanceof LineChart) {
37983
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
38009
+ return canChartParseLabels(chart, this.env.model.getters);
37984
38010
  }
37985
38011
  return false;
37986
38012
  }
@@ -38049,7 +38075,7 @@ stores.inject(MyMetaStore, storeInstance);
38049
38075
  get canTreatLabelsAsText() {
38050
38076
  const chart = this.env.model.getters.getChart(this.props.figureId);
38051
38077
  if (chart && chart instanceof ScatterChart) {
38052
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
38078
+ return canChartParseLabels(chart, this.env.model.getters);
38053
38079
  }
38054
38080
  return false;
38055
38081
  }
@@ -39256,8 +39282,8 @@ stores.inject(MyMetaStore, storeInstance);
39256
39282
  document.body.style.cursor = "move";
39257
39283
  state.draggedItemId = args.draggedItemId;
39258
39284
  const container = direction === "horizontal"
39259
- ? new HorizontalContainer(args.containerEl)
39260
- : new VerticalContainer(args.containerEl);
39285
+ ? new HorizontalContainer(args.scrollableContainerEl)
39286
+ : new VerticalContainer(args.scrollableContainerEl);
39261
39287
  dndHelper = new DOMDndHelper({
39262
39288
  ...args,
39263
39289
  container,
@@ -39268,8 +39294,8 @@ stores.inject(MyMetaStore, storeInstance);
39268
39294
  const stopListening = startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
39269
39295
  cleanupFns.push(stopListening);
39270
39296
  const onScroll = dndHelper.onScroll.bind(dndHelper);
39271
- args.containerEl.addEventListener("scroll", onScroll);
39272
- cleanupFns.push(() => args.containerEl.removeEventListener("scroll", onScroll));
39297
+ args.scrollableContainerEl.addEventListener("scroll", onScroll);
39298
+ cleanupFns.push(() => args.scrollableContainerEl.removeEventListener("scroll", onScroll));
39273
39299
  cleanupFns.push(dndHelper.destroy.bind(dndHelper));
39274
39300
  };
39275
39301
  owl.onWillUnmount(() => {
@@ -39733,7 +39759,7 @@ stores.inject(MyMetaStore, storeInstance);
39733
39759
  draggedItemId: cf.id,
39734
39760
  initialMousePosition: event.clientY,
39735
39761
  items: items,
39736
- containerEl: this.cfListRef.el,
39762
+ scrollableContainerEl: this.cfListRef.el,
39737
39763
  onDragEnd: (cfId, finalIndex) => this.onDragEnd(cfId, finalIndex),
39738
39764
  });
39739
39765
  }
@@ -39864,7 +39890,7 @@ stores.inject(MyMetaStore, storeInstance);
39864
39890
  state;
39865
39891
  setup() {
39866
39892
  const cf = this.props.editedCf || {
39867
- id: this.env.model.uuidGenerator.uuidv4(),
39893
+ id: this.env.model.uuidGenerator.smallUuid(),
39868
39894
  ranges: this.env.model.getters
39869
39895
  .getSelectedZones()
39870
39896
  .map((zone) => this.env.model.getters.zoneToXC(this.env.model.getters.getActiveSheetId(), zone)),
@@ -41460,7 +41486,7 @@ stores.inject(MyMetaStore, storeInstance);
41460
41486
  .getSelectedZones()
41461
41487
  .map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
41462
41488
  return {
41463
- id: this.env.model.uuidGenerator.uuidv4(),
41489
+ id: this.env.model.uuidGenerator.smallUuid(),
41464
41490
  criterion: { type: "textContains", values: [""] },
41465
41491
  ranges,
41466
41492
  };
@@ -42717,6 +42743,7 @@ stores.inject(MyMetaStore, storeInstance);
42717
42743
  unusedGranularities: Object,
42718
42744
  dateGranularities: Array,
42719
42745
  datetimeGranularities: Array,
42746
+ getScrollableContainerEl: { type: Function, optional: true },
42720
42747
  pivotId: String,
42721
42748
  };
42722
42749
  dimensionsRef = owl.useRef("pivot-dimensions");
@@ -42750,7 +42777,7 @@ stores.inject(MyMetaStore, storeInstance);
42750
42777
  draggedItemId: dimension.nameWithGranularity,
42751
42778
  initialMousePosition: event.clientY,
42752
42779
  items: draggableItems,
42753
- containerEl: this.dimensionsRef.el,
42780
+ scrollableContainerEl: this.props.getScrollableContainerEl?.() || this.dimensionsRef.el,
42754
42781
  onDragEnd: (dimensionName, finalIndex) => {
42755
42782
  const originalIndex = draggableIds.findIndex((id) => id === dimensionName);
42756
42783
  if (originalIndex === finalIndex) {
@@ -42799,7 +42826,7 @@ stores.inject(MyMetaStore, storeInstance);
42799
42826
  draggedItemId: measure.id,
42800
42827
  initialMousePosition: event.clientY,
42801
42828
  items: draggableItems,
42802
- containerEl: this.dimensionsRef.el,
42829
+ scrollableContainerEl: this.props.getScrollableContainerEl?.() || this.dimensionsRef.el,
42803
42830
  onDragEnd: (measureName, finalIndex) => {
42804
42831
  const originalIndex = draggableIds.findIndex((id) => id === measureName);
42805
42832
  if (originalIndex === finalIndex) {
@@ -42978,8 +43005,8 @@ stores.inject(MyMetaStore, storeInstance);
42978
43005
  return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
42979
43006
  }
42980
43007
  duplicatePivot() {
42981
- const newPivotId = this.env.model.uuidGenerator.uuidv4();
42982
- const newSheetId = this.env.model.uuidGenerator.uuidv4();
43008
+ const newPivotId = this.env.model.uuidGenerator.smallUuid();
43009
+ const newSheetId = this.env.model.uuidGenerator.smallUuid();
42983
43010
  const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
42984
43011
  pivotId: this.props.pivotId,
42985
43012
  newPivotId,
@@ -44427,6 +44454,7 @@ stores.inject(MyMetaStore, storeInstance);
44427
44454
  };
44428
44455
  store;
44429
44456
  state;
44457
+ pivotSidePanelRef = owl.useRef("pivotSidePanel");
44430
44458
  setup() {
44431
44459
  this.store = useLocalStore(PivotSidePanelStore, this.props.pivotId);
44432
44460
  this.state = owl.useState({
@@ -44455,6 +44483,9 @@ stores.inject(MyMetaStore, storeInstance);
44455
44483
  get definition() {
44456
44484
  return this.store.definition;
44457
44485
  }
44486
+ getScrollableContainerEl() {
44487
+ return this.pivotSidePanelRef.el;
44488
+ }
44458
44489
  onSelectionChanged(ranges) {
44459
44490
  this.state.rangeHasChanged = true;
44460
44491
  this.state.range = ranges[0];
@@ -45540,7 +45571,7 @@ stores.inject(MyMetaStore, storeInstance);
45540
45571
  this.state.selectedTemplateName = templateName;
45541
45572
  }
45542
45573
  onConfirm() {
45543
- const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.uuidv4();
45574
+ const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
45544
45575
  this.env.model.dispatch("CREATE_TABLE_STYLE", {
45545
45576
  tableStyleId,
45546
45577
  tableStyleName: this.state.styleName,
@@ -54206,7 +54237,7 @@ stores.inject(MyMetaStore, storeInstance);
54206
54237
  ? "Success" /* CommandResult.Success */
54207
54238
  : "InvalidColor" /* CommandResult.InvalidColor */;
54208
54239
  case "DELETE_SHEET":
54209
- return this.orderedSheetIds.length > 1
54240
+ return this.getVisibleSheetIds().length > 1
54210
54241
  ? "Success" /* CommandResult.Success */
54211
54242
  : "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
54212
54243
  case "ADD_COLUMNS_ROWS":
@@ -55072,7 +55103,7 @@ stores.inject(MyMetaStore, storeInstance);
55072
55103
  const union = this.getters.getRangesUnion(ranges);
55073
55104
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
55074
55105
  this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
55075
- const id = this.uuidGenerator.uuidv4();
55106
+ const id = this.uuidGenerator.smallUuid();
55076
55107
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
55077
55108
  const newTable = cmd.tableType === "dynamic"
55078
55109
  ? this.createDynamicTable(id, union, config)
@@ -55225,7 +55256,7 @@ stores.inject(MyMetaStore, storeInstance);
55225
55256
  filters = [];
55226
55257
  for (const i of range(zone.left, zone.right + 1)) {
55227
55258
  const filterZone = { ...zone, left: i, right: i };
55228
- const uid = this.uuidGenerator.uuidv4();
55259
+ const uid = this.uuidGenerator.smallUuid();
55229
55260
  filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
55230
55261
  }
55231
55262
  }
@@ -55290,7 +55321,7 @@ stores.inject(MyMetaStore, storeInstance);
55290
55321
  ? table.filters.find((f) => f.col === i)
55291
55322
  : undefined;
55292
55323
  const filterZone = { ...tableZone, left: i, right: i };
55293
- const filterId = oldFilter?.id || this.uuidGenerator.uuidv4();
55324
+ const filterId = oldFilter?.id || this.uuidGenerator.smallUuid();
55294
55325
  filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
55295
55326
  }
55296
55327
  }
@@ -55391,7 +55422,7 @@ stores.inject(MyMetaStore, storeInstance);
55391
55422
  if (filters.length < zoneToDimension(tableZone).numberOfCols) {
55392
55423
  for (let col = tableZone.left; col <= tableZone.right; col++) {
55393
55424
  if (!filters.find((filter) => filter.col === col)) {
55394
- const uid = this.uuidGenerator.uuidv4();
55425
+ const uid = this.uuidGenerator.smallUuid();
55395
55426
  const filterZone = { ...tableZone, left: col, right: col };
55396
55427
  filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
55397
55428
  }
@@ -61591,6 +61622,15 @@ stores.inject(MyMetaStore, storeInstance);
61591
61622
  this.waitingAck = true;
61592
61623
  this.sendPendingMessage();
61593
61624
  }
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
+ }
61594
61634
  /**
61595
61635
  * Send the next pending message
61596
61636
  */
@@ -61605,13 +61645,7 @@ stores.inject(MyMetaStore, storeInstance);
61605
61645
  * The command is empty, we have to drop all the next local revisions
61606
61646
  * to avoid issues with undo/redo
61607
61647
  */
61608
- this.revisions.drop(revision.id);
61609
- const revisionIds = this.pendingMessages
61610
- .filter((message) => message.type === "REMOTE_REVISION")
61611
- .map((message) => message.nextRevisionId);
61612
- this.trigger("pending-revisions-dropped", { revisionIds });
61613
- this.waitingAck = false;
61614
- this.waitingUndoRedoAck = false;
61648
+ this.dropPendingRevision(revision.id);
61615
61649
  this.pendingMessages = [];
61616
61650
  return;
61617
61651
  }
@@ -61637,7 +61671,6 @@ stores.inject(MyMetaStore, storeInstance);
61637
61671
  switch (message.type) {
61638
61672
  case "REMOTE_REVISION":
61639
61673
  case "REVISION_REDONE":
61640
- case "REVISION_UNDONE":
61641
61674
  case "SNAPSHOT_CREATED":
61642
61675
  this.waitingAck = false;
61643
61676
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
@@ -61646,6 +61679,27 @@ stores.inject(MyMetaStore, storeInstance);
61646
61679
  this.lastRevisionMessage = message;
61647
61680
  this.sendPendingMessage();
61648
61681
  break;
61682
+ case "REVISION_UNDONE": {
61683
+ this.waitingAck = false;
61684
+ 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) {
61688
+ /**
61689
+ * Some revisions undergo transformations that may cause issues with
61690
+ * undo/redo if the transformation is destructive (we don't get back
61691
+ * the original command by transforming it with the inverse).
61692
+ * To prevent these problems, we must discard all subsequent local
61693
+ * revisions.
61694
+ */
61695
+ this.dropPendingRevision(this.pendingMessages[firstTransformedRevisionIndex].nextRevisionId);
61696
+ this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
61697
+ }
61698
+ this.serverRevisionId = message.nextRevisionId;
61699
+ this.processedRevisions.add(message.nextRevisionId);
61700
+ this.sendPendingMessage();
61701
+ break;
61702
+ }
61649
61703
  }
61650
61704
  }
61651
61705
  isAlreadyProcessed(message) {
@@ -63077,23 +63131,23 @@ stores.inject(MyMetaStore, storeInstance);
63077
63131
  function repeatCreateChartCommand(getters, cmd) {
63078
63132
  return {
63079
63133
  ...repeatSheetDependantCommand(getters, cmd),
63080
- id: uuidGenerator.uuidv4(),
63134
+ id: uuidGenerator.smallUuid(),
63081
63135
  };
63082
63136
  }
63083
63137
  function repeatCreateImageCommand(getters, cmd) {
63084
63138
  return {
63085
63139
  ...repeatSheetDependantCommand(getters, cmd),
63086
- figureId: uuidGenerator.uuidv4(),
63140
+ figureId: uuidGenerator.smallUuid(),
63087
63141
  };
63088
63142
  }
63089
63143
  function repeatCreateFigureCommand(getters, cmd) {
63090
63144
  const newCmd = repeatSheetDependantCommand(getters, cmd);
63091
- newCmd.figure.id = uuidGenerator.uuidv4();
63145
+ newCmd.figure.id = uuidGenerator.smallUuid();
63092
63146
  return newCmd;
63093
63147
  }
63094
63148
  function repeatCreateSheetCommand(getters, cmd) {
63095
63149
  const newCmd = deepCopy(cmd);
63096
- newCmd.sheetId = uuidGenerator.uuidv4();
63150
+ newCmd.sheetId = uuidGenerator.smallUuid();
63097
63151
  const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
63098
63152
  // Extract the prefix of the sheet name (everything before the number at the end of the name)
63099
63153
  const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
@@ -64556,23 +64610,7 @@ stores.inject(MyMetaStore, storeInstance);
64556
64610
  gridSelection: deepCopy(gridSelection),
64557
64611
  };
64558
64612
  }
64559
- if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
64560
- const currentSheetIds = this.getters.getVisibleSheetIds();
64561
- this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
64562
- if (this.activeSheet.id in this.sheetsData) {
64563
- const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
64564
- this.selectCell(anchor.cell.col, anchor.cell.row);
64565
- }
64566
- else {
64567
- this.selectCell(0, 0);
64568
- }
64569
- const { col, row } = this.gridSelection.anchor.cell;
64570
- this.moveClient({
64571
- sheetId: this.getters.getActiveSheetId(),
64572
- col,
64573
- row,
64574
- });
64575
- }
64613
+ this.fallbackToVisibleSheet();
64576
64614
  const sheetId = this.getters.getActiveSheetId();
64577
64615
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
64578
64616
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
@@ -64582,6 +64620,7 @@ stores.inject(MyMetaStore, storeInstance);
64582
64620
  }
64583
64621
  }
64584
64622
  finalize() {
64623
+ this.fallbackToVisibleSheet();
64585
64624
  /** Any change to the selection has to be reflected in the selection processor. */
64586
64625
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
64587
64626
  }
@@ -64885,6 +64924,25 @@ stores.inject(MyMetaStore, storeInstance);
64885
64924
  }
64886
64925
  return "Success" /* CommandResult.Success */;
64887
64926
  }
64927
+ fallbackToVisibleSheet() {
64928
+ if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
64929
+ const currentSheetIds = this.getters.getVisibleSheetIds();
64930
+ this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
64931
+ if (this.activeSheet.id in this.sheetsData) {
64932
+ const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
64933
+ this.selectCell(anchor.cell.col, anchor.cell.row);
64934
+ }
64935
+ else {
64936
+ this.selectCell(0, 0);
64937
+ }
64938
+ const { col, row } = this.gridSelection.anchor.cell;
64939
+ this.moveClient({
64940
+ sheetId: this.getters.getActiveSheetId(),
64941
+ col,
64942
+ row,
64943
+ });
64944
+ }
64945
+ }
64888
64946
  //-------------------------------------------
64889
64947
  // Helpers for extensions
64890
64948
  // ------------------------------------------
@@ -66887,7 +66945,7 @@ stores.inject(MyMetaStore, storeInstance);
66887
66945
  clickAddSheet(ev) {
66888
66946
  const activeSheetId = this.env.model.getters.getActiveSheetId();
66889
66947
  const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
66890
- const sheetId = this.env.model.uuidGenerator.uuidv4();
66948
+ const sheetId = this.env.model.uuidGenerator.smallUuid();
66891
66949
  const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
66892
66950
  this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
66893
66951
  this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
@@ -67004,7 +67062,7 @@ stores.inject(MyMetaStore, storeInstance);
67004
67062
  draggedItemId: sheetId,
67005
67063
  initialMousePosition: event.clientX,
67006
67064
  items: sheets,
67007
- containerEl: this.sheetListRef.el,
67065
+ scrollableContainerEl: this.sheetListRef.el,
67008
67066
  onDragEnd: (sheetId, finalIndex) => this.onDragEnd(sheetId, finalIndex),
67009
67067
  });
67010
67068
  }
@@ -67975,7 +68033,7 @@ stores.inject(MyMetaStore, storeInstance);
67975
68033
  .o-font-size-editor {
67976
68034
  height: calc(100% - 4px);
67977
68035
  input.o-font-size {
67978
- outline-color: ${SELECTION_BORDER_COLOR};
68036
+ outline: none;
67979
68037
  height: 20px;
67980
68038
  width: 23px;
67981
68039
  }
@@ -69262,7 +69320,7 @@ stores.inject(MyMetaStore, storeInstance);
69262
69320
  }
69263
69321
  /**
69264
69322
  * Drop the operation and all following operations in every
69265
- * branch
69323
+ * branches
69266
69324
  */
69267
69325
  drop(operationId) {
69268
69326
  for (const branch of this.branches) {
@@ -72639,7 +72697,7 @@ stores.inject(MyMetaStore, storeInstance);
72639
72697
  }
72640
72698
  setupConfig(config) {
72641
72699
  const client = config.client || {
72642
- id: this.uuidGenerator.uuidv4(),
72700
+ id: this.uuidGenerator.smallUuid(),
72643
72701
  name: _t("Anonymous").toString(),
72644
72702
  };
72645
72703
  const transportService = config.transportService || new LocalTransportService();
@@ -73169,9 +73227,9 @@ stores.inject(MyMetaStore, storeInstance);
73169
73227
  exports.tokenize = tokenize;
73170
73228
 
73171
73229
 
73172
- __info__.version = "18.0.14";
73173
- __info__.date = "2025-02-05T06:47:33.041Z";
73174
- __info__.hash = "90f2af4";
73230
+ __info__.version = "18.0.16";
73231
+ __info__.date = "2025-02-14T08:44:19.475Z";
73232
+ __info__.hash = "39979ab";
73175
73233
 
73176
73234
 
73177
73235
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);