@odoo/o-spreadsheet 18.0.15 → 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.15
6
- * @date 2025-02-10T08:59:22.993Z
7
- * @hash 5b19f88
5
+ * @version 18.0.16
6
+ * @date 2025-02-14T08:44:19.475Z
7
+ * @hash 39979ab
8
8
  */
9
9
 
10
10
  'use strict';
@@ -6347,6 +6347,37 @@ class UuidGenerator {
6347
6347
  setIsFastStrategy(isFast) {
6348
6348
  this.isFastIdStrategy = isFast;
6349
6349
  }
6350
+ /**
6351
+ * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
6352
+ * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
6353
+ * it also has a smaller size, which is preferable to alleviate the overall data size.
6354
+ *
6355
+ * This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
6356
+ * as they will appear several times in the revisions and local history.
6357
+ *
6358
+ */
6359
+ smallUuid() {
6360
+ if (this.isFastIdStrategy) {
6361
+ this.fastIdStart++;
6362
+ return String(this.fastIdStart);
6363
+ //@ts-ignore
6364
+ }
6365
+ else if (window.crypto && window.crypto.getRandomValues) {
6366
+ //@ts-ignore
6367
+ return ([1e7] + -1e3).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
6368
+ }
6369
+ else {
6370
+ // mainly for jest and other browsers that do not have the crypto functionality
6371
+ return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
6372
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
6373
+ return v.toString(16);
6374
+ });
6375
+ }
6376
+ }
6377
+ /**
6378
+ * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
6379
+ * This method should be used when you need to avoid collisions at all costs, like the id of a revision.
6380
+ */
6350
6381
  uuidv4() {
6351
6382
  if (this.isFastIdStrategy) {
6352
6383
  this.fastIdStart++;
@@ -6360,7 +6391,7 @@ class UuidGenerator {
6360
6391
  else {
6361
6392
  // mainly for jest and other browsers that do not have the crypto functionality
6362
6393
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
6363
- var r = (Math.random() * 16) | 0, v = c === "x" ? r : (r & 0x3) | 0x8;
6394
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
6364
6395
  return v.toString(16);
6365
6396
  });
6366
6397
  }
@@ -8339,7 +8370,7 @@ class ChartClipboardHandler extends AbstractFigureClipboardHandler {
8339
8370
  };
8340
8371
  }
8341
8372
  getPasteTarget(sheetId, target, content, options) {
8342
- const newId = new UuidGenerator().uuidv4();
8373
+ const newId = new UuidGenerator().smallUuid();
8343
8374
  return { zones: [], figureId: newId, sheetId };
8344
8375
  }
8345
8376
  paste(target, clippedContent, options) {
@@ -8505,7 +8536,7 @@ class ConditionalFormatClipboardHandler extends AbstractCellClipboardHandler {
8505
8536
  if (!targetCF && queuedCfs) {
8506
8537
  targetCF = queuedCfs.find((queued) => queued.cf.stopIfTrue === originCF.stopIfTrue && deepEquals(queued.cf.rule, originCF.rule))?.cf;
8507
8538
  }
8508
- return targetCF || { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
8539
+ return targetCF || { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
8509
8540
  }
8510
8541
  }
8511
8542
 
@@ -8598,7 +8629,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
8598
8629
  }
8599
8630
  return (targetRule || {
8600
8631
  ...originRule,
8601
- id: newId ? this.uuidGenerator.uuidv4() : originRule.id,
8632
+ id: newId ? this.uuidGenerator.smallUuid() : originRule.id,
8602
8633
  ranges: [],
8603
8634
  });
8604
8635
  }
@@ -8660,7 +8691,7 @@ class ImageClipboardHandler extends AbstractFigureClipboardHandler {
8660
8691
  };
8661
8692
  }
8662
8693
  getPasteTarget(sheetId, target, content, options) {
8663
- const newId = new UuidGenerator().uuidv4();
8694
+ const newId = new UuidGenerator().smallUuid();
8664
8695
  return { sheetId, zones: [], figureId: newId };
8665
8696
  }
8666
8697
  paste(target, clippedContent, options) {
@@ -15062,7 +15093,7 @@ const SORTN = {
15062
15093
  }
15063
15094
  }
15064
15095
  },
15065
- isExported: true,
15096
+ isExported: false,
15066
15097
  };
15067
15098
  // -----------------------------------------------------------------------------
15068
15099
  // UNIQUE
@@ -28516,17 +28547,15 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
28516
28547
  plugins: [],
28517
28548
  };
28518
28549
  }
28519
- function getChartLabelFormat(getters, range) {
28550
+ function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
28520
28551
  if (!range)
28521
28552
  return undefined;
28522
- const { sheetId, zone: { left, top, bottom }, } = range;
28523
- for (let row = top; row <= bottom; row++) {
28524
- const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
28525
- if (format) {
28526
- return format;
28527
- }
28553
+ const { sheetId, zone } = range;
28554
+ const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
28555
+ if (shouldRemoveFirstLabel) {
28556
+ formats.shift();
28528
28557
  }
28529
- return undefined;
28558
+ return formats.find((format) => format !== undefined);
28530
28559
  }
28531
28560
  function getChartLabelValues(getters, dataSets, labelRange) {
28532
28561
  let labels = { values: [], formattedValues: [] };
@@ -28814,9 +28843,7 @@ function createBarChartRuntime(chart, getters) {
28814
28843
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
28815
28844
  let labels = labelValues.formattedValues;
28816
28845
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
28817
- if (chart.dataSetsHaveTitle &&
28818
- dataSetsValues[0] &&
28819
- labels.length > dataSetsValues[0].data.length) {
28846
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
28820
28847
  labels.shift();
28821
28848
  }
28822
28849
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -29085,8 +29112,8 @@ function fixEmptyLabelsForDateCharts(labels, dataSetsValues) {
29085
29112
  }
29086
29113
  return { labels: newLabels, dataSetsValues: newDatasets };
29087
29114
  }
29088
- function canChartParseLabels(labelRange, getters) {
29089
- return canBeDateChart(labelRange, getters) || canBeLinearChart(labelRange, getters);
29115
+ function canChartParseLabels(chart, getters) {
29116
+ return canBeDateChart(chart, getters) || canBeLinearChart(chart, getters);
29090
29117
  }
29091
29118
  function getChartAxisType(chart, getters) {
29092
29119
  if (isDateChart(chart, getters) && isLuxonTimeAdapterInstalled()) {
@@ -29098,23 +29125,26 @@ function getChartAxisType(chart, getters) {
29098
29125
  return "category";
29099
29126
  }
29100
29127
  function isDateChart(chart, getters) {
29101
- return !chart.labelsAsText && canBeDateChart(chart.labelRange, getters);
29128
+ return !chart.labelsAsText && canBeDateChart(chart, getters);
29102
29129
  }
29103
29130
  function isLinearChart(chart, getters) {
29104
- return !chart.labelsAsText && canBeLinearChart(chart.labelRange, getters);
29131
+ return !chart.labelsAsText && canBeLinearChart(chart, getters);
29105
29132
  }
29106
- function canBeDateChart(labelRange, getters) {
29107
- if (!labelRange || !canBeLinearChart(labelRange, getters)) {
29133
+ function canBeDateChart(chart, getters) {
29134
+ if (!chart.labelRange || !canBeLinearChart(chart, getters)) {
29108
29135
  return false;
29109
29136
  }
29110
- const labelFormat = getChartLabelFormat(getters, labelRange);
29137
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle));
29111
29138
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
29112
29139
  }
29113
- function canBeLinearChart(labelRange, getters) {
29114
- if (!labelRange) {
29140
+ function canBeLinearChart(chart, getters) {
29141
+ if (!chart.labelRange) {
29115
29142
  return false;
29116
29143
  }
29117
- const labels = getters.getRangeValues(labelRange);
29144
+ const labels = getters.getRangeValues(chart.labelRange);
29145
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
29146
+ labels.shift();
29147
+ }
29118
29148
  if (labels.some((label) => isNaN(Number(label)) && label)) {
29119
29149
  return false;
29120
29150
  }
@@ -29198,9 +29228,8 @@ function createLineOrScatterChartRuntime(chart, getters) {
29198
29228
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
29199
29229
  let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
29200
29230
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
29201
- if (chart.dataSetsHaveTitle &&
29202
- dataSetsValues[0] &&
29203
- labels.length > dataSetsValues[0].data.length) {
29231
+ const removeFirstLabel = shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle);
29232
+ if (removeFirstLabel) {
29204
29233
  labels.shift();
29205
29234
  }
29206
29235
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -29290,12 +29319,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
29290
29319
  background: chart.background,
29291
29320
  callback: formatTickValue(options),
29292
29321
  };
29293
- if (chart.dataSetsHaveTitle &&
29294
- dataSetsValues[0] &&
29295
- labels.length > dataSetsValues[0].data.length) {
29296
- labels.shift();
29297
- }
29298
- const labelFormat = getChartLabelFormat(getters, chart.labelRange);
29322
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, removeFirstLabel);
29299
29323
  if (axisType === "time") {
29300
29324
  const axis = {
29301
29325
  type: "time",
@@ -29553,9 +29577,7 @@ function createComboChartRuntime(chart, getters) {
29553
29577
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
29554
29578
  let labels = labelValues.formattedValues;
29555
29579
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
29556
- if (chart.dataSetsHaveTitle &&
29557
- dataSetsValues[0] &&
29558
- labels.length > dataSetsValues[0].data.length) {
29580
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
29559
29581
  labels.shift();
29560
29582
  }
29561
29583
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -30246,9 +30268,7 @@ function createPieChartRuntime(chart, getters) {
30246
30268
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
30247
30269
  let labels = labelValues.formattedValues;
30248
30270
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
30249
- if (chart.dataSetsHaveTitle &&
30250
- dataSetsValues[0] &&
30251
- labels.length > dataSetsValues[0].data.length) {
30271
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
30252
30272
  labels.shift();
30253
30273
  }
30254
30274
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -30793,9 +30813,7 @@ function createWaterfallChartRuntime(chart, getters) {
30793
30813
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
30794
30814
  let labels = labelValues.formattedValues;
30795
30815
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
30796
- if (chart.dataSetsHaveTitle &&
30797
- dataSetsValues[0] &&
30798
- labels.length > dataSetsValues[0].data.length) {
30816
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
30799
30817
  labels.shift();
30800
30818
  }
30801
30819
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -32291,7 +32309,7 @@ const linkSheet = {
32291
32309
  const deleteSheet = {
32292
32310
  name: _t("Delete"),
32293
32311
  isVisible: (env) => {
32294
- return env.model.getters.getSheetIds().length > 1;
32312
+ return env.model.getters.getVisibleSheetIds().length > 1;
32295
32313
  },
32296
32314
  execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
32297
32315
  env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
@@ -32302,7 +32320,7 @@ const duplicateSheet = {
32302
32320
  name: _t("Duplicate"),
32303
32321
  execute: (env) => {
32304
32322
  const sheetIdFrom = env.model.getters.getActiveSheetId();
32305
- const sheetIdTo = env.model.uuidGenerator.uuidv4();
32323
+ const sheetIdTo = env.model.uuidGenerator.smallUuid();
32306
32324
  env.model.dispatch("DUPLICATE_SHEET", {
32307
32325
  sheetId: sheetIdFrom,
32308
32326
  sheetIdTo,
@@ -32929,20 +32947,21 @@ function getSmartChartDefinition(zone, getters) {
32929
32947
  }
32930
32948
  // Only display legend for several datasets.
32931
32949
  const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
32932
- const labelRange = labelRangeXc ? getters.getRangeFromSheetXC(sheetId, labelRangeXc) : undefined;
32933
- if (canChartParseLabels(labelRange, getters)) {
32934
- return {
32935
- title: {},
32936
- dataSets,
32937
- labelsAsText: false,
32938
- stacked: false,
32939
- aggregated: false,
32940
- cumulative: false,
32941
- labelRange: labelRangeXc,
32942
- type: "line",
32943
- dataSetsHaveTitle,
32944
- legendPosition: newLegendPos,
32945
- };
32950
+ const lineChartDefinition = {
32951
+ title: {},
32952
+ dataSets,
32953
+ labelsAsText: false,
32954
+ stacked: false,
32955
+ aggregated: false,
32956
+ cumulative: false,
32957
+ labelRange: labelRangeXc,
32958
+ type: "line",
32959
+ dataSetsHaveTitle,
32960
+ legendPosition: newLegendPos,
32961
+ };
32962
+ const chart = new LineChart(lineChartDefinition, sheetId, getters);
32963
+ if (canChartParseLabels(chart, getters)) {
32964
+ return lineChartDefinition;
32946
32965
  }
32947
32966
  const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
32948
32967
  if (singleColumn &&
@@ -33310,7 +33329,7 @@ const HIDE_ROWS_NAME = (env) => {
33310
33329
  //------------------------------------------------------------------------------
33311
33330
  const CREATE_CHART = (env) => {
33312
33331
  const getters = env.model.getters;
33313
- const id = env.model.uuidGenerator.uuidv4();
33332
+ const id = env.model.uuidGenerator.smallUuid();
33314
33333
  const sheetId = getters.getActiveSheetId();
33315
33334
  if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
33316
33335
  env.model.selection.selectTableAroundSelection();
@@ -33333,8 +33352,8 @@ const CREATE_CHART = (env) => {
33333
33352
  // Pivots
33334
33353
  //------------------------------------------------------------------------------
33335
33354
  const CREATE_PIVOT = (env) => {
33336
- const pivotId = env.model.uuidGenerator.uuidv4();
33337
- const newSheetId = env.model.uuidGenerator.uuidv4();
33355
+ const pivotId = env.model.uuidGenerator.smallUuid();
33356
+ const newSheetId = env.model.uuidGenerator.smallUuid();
33338
33357
  const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
33339
33358
  if (result.isSuccessful) {
33340
33359
  env.openSidePanel("PivotSidePanel", { pivotId });
@@ -33393,7 +33412,7 @@ async function requestImage(env) {
33393
33412
  const CREATE_IMAGE = async (env) => {
33394
33413
  if (env.imageProvider) {
33395
33414
  const sheetId = env.model.getters.getActiveSheetId();
33396
- const figureId = env.model.uuidGenerator.uuidv4();
33415
+ const figureId = env.model.uuidGenerator.smallUuid();
33397
33416
  const image = await requestImage(env);
33398
33417
  if (!image) {
33399
33418
  throw new Error("No image provider was given to the environment");
@@ -33946,7 +33965,7 @@ const insertCheckbox = {
33946
33965
  ranges,
33947
33966
  sheetId,
33948
33967
  rule: {
33949
- id: env.model.uuidGenerator.uuidv4(),
33968
+ id: env.model.uuidGenerator.smallUuid(),
33950
33969
  criterion: {
33951
33970
  type: "isBoolean",
33952
33971
  values: [],
@@ -33962,7 +33981,7 @@ const insertDropdown = {
33962
33981
  const zones = env.model.getters.getSelectedZones();
33963
33982
  const sheetId = env.model.getters.getActiveSheetId();
33964
33983
  const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
33965
- const ruleID = env.model.uuidGenerator.uuidv4();
33984
+ const ruleID = env.model.uuidGenerator.smallUuid();
33966
33985
  env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
33967
33986
  ranges,
33968
33987
  sheetId,
@@ -33993,7 +34012,7 @@ const insertSheet = {
33993
34012
  execute: (env) => {
33994
34013
  const activeSheetId = env.model.getters.getActiveSheetId();
33995
34014
  const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
33996
- const sheetId = env.model.uuidGenerator.uuidv4();
34015
+ const sheetId = env.model.uuidGenerator.smallUuid();
33997
34016
  env.model.dispatch("CREATE_SHEET", { sheetId, position });
33998
34017
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
33999
34018
  },
@@ -37988,7 +38007,7 @@ class LineConfigPanel extends GenericChartConfigPanel {
37988
38007
  get canTreatLabelsAsText() {
37989
38008
  const chart = this.env.model.getters.getChart(this.props.figureId);
37990
38009
  if (chart && chart instanceof LineChart) {
37991
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
38010
+ return canChartParseLabels(chart, this.env.model.getters);
37992
38011
  }
37993
38012
  return false;
37994
38013
  }
@@ -38057,7 +38076,7 @@ class ScatterConfigPanel extends GenericChartConfigPanel {
38057
38076
  get canTreatLabelsAsText() {
38058
38077
  const chart = this.env.model.getters.getChart(this.props.figureId);
38059
38078
  if (chart && chart instanceof ScatterChart) {
38060
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
38079
+ return canChartParseLabels(chart, this.env.model.getters);
38061
38080
  }
38062
38081
  return false;
38063
38082
  }
@@ -39872,7 +39891,7 @@ class ConditionalFormattingEditor extends owl.Component {
39872
39891
  state;
39873
39892
  setup() {
39874
39893
  const cf = this.props.editedCf || {
39875
- id: this.env.model.uuidGenerator.uuidv4(),
39894
+ id: this.env.model.uuidGenerator.smallUuid(),
39876
39895
  ranges: this.env.model.getters
39877
39896
  .getSelectedZones()
39878
39897
  .map((zone) => this.env.model.getters.zoneToXC(this.env.model.getters.getActiveSheetId(), zone)),
@@ -41468,7 +41487,7 @@ class DataValidationEditor extends owl.Component {
41468
41487
  .getSelectedZones()
41469
41488
  .map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
41470
41489
  return {
41471
- id: this.env.model.uuidGenerator.uuidv4(),
41490
+ id: this.env.model.uuidGenerator.smallUuid(),
41472
41491
  criterion: { type: "textContains", values: [""] },
41473
41492
  ranges,
41474
41493
  };
@@ -42987,8 +43006,8 @@ class PivotTitleSection extends owl.Component {
42987
43006
  return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
42988
43007
  }
42989
43008
  duplicatePivot() {
42990
- const newPivotId = this.env.model.uuidGenerator.uuidv4();
42991
- const newSheetId = this.env.model.uuidGenerator.uuidv4();
43009
+ const newPivotId = this.env.model.uuidGenerator.smallUuid();
43010
+ const newSheetId = this.env.model.uuidGenerator.smallUuid();
42992
43011
  const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
42993
43012
  pivotId: this.props.pivotId,
42994
43013
  newPivotId,
@@ -45553,7 +45572,7 @@ class TableStyleEditorPanel extends owl.Component {
45553
45572
  this.state.selectedTemplateName = templateName;
45554
45573
  }
45555
45574
  onConfirm() {
45556
- const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.uuidv4();
45575
+ const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
45557
45576
  this.env.model.dispatch("CREATE_TABLE_STYLE", {
45558
45577
  tableStyleId,
45559
45578
  tableStyleName: this.state.styleName,
@@ -54219,7 +54238,7 @@ class SheetPlugin extends CorePlugin {
54219
54238
  ? "Success" /* CommandResult.Success */
54220
54239
  : "InvalidColor" /* CommandResult.InvalidColor */;
54221
54240
  case "DELETE_SHEET":
54222
- return this.orderedSheetIds.length > 1
54241
+ return this.getVisibleSheetIds().length > 1
54223
54242
  ? "Success" /* CommandResult.Success */
54224
54243
  : "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
54225
54244
  case "ADD_COLUMNS_ROWS":
@@ -55085,7 +55104,7 @@ class TablePlugin extends CorePlugin {
55085
55104
  const union = this.getters.getRangesUnion(ranges);
55086
55105
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
55087
55106
  this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
55088
- const id = this.uuidGenerator.uuidv4();
55107
+ const id = this.uuidGenerator.smallUuid();
55089
55108
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
55090
55109
  const newTable = cmd.tableType === "dynamic"
55091
55110
  ? this.createDynamicTable(id, union, config)
@@ -55238,7 +55257,7 @@ class TablePlugin extends CorePlugin {
55238
55257
  filters = [];
55239
55258
  for (const i of range(zone.left, zone.right + 1)) {
55240
55259
  const filterZone = { ...zone, left: i, right: i };
55241
- const uid = this.uuidGenerator.uuidv4();
55260
+ const uid = this.uuidGenerator.smallUuid();
55242
55261
  filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
55243
55262
  }
55244
55263
  }
@@ -55303,7 +55322,7 @@ class TablePlugin extends CorePlugin {
55303
55322
  ? table.filters.find((f) => f.col === i)
55304
55323
  : undefined;
55305
55324
  const filterZone = { ...tableZone, left: i, right: i };
55306
- const filterId = oldFilter?.id || this.uuidGenerator.uuidv4();
55325
+ const filterId = oldFilter?.id || this.uuidGenerator.smallUuid();
55307
55326
  filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
55308
55327
  }
55309
55328
  }
@@ -55404,7 +55423,7 @@ class TablePlugin extends CorePlugin {
55404
55423
  if (filters.length < zoneToDimension(tableZone).numberOfCols) {
55405
55424
  for (let col = tableZone.left; col <= tableZone.right; col++) {
55406
55425
  if (!filters.find((filter) => filter.col === col)) {
55407
- const uid = this.uuidGenerator.uuidv4();
55426
+ const uid = this.uuidGenerator.smallUuid();
55408
55427
  const filterZone = { ...tableZone, left: col, right: col };
55409
55428
  filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
55410
55429
  }
@@ -61604,6 +61623,15 @@ class Session extends EventBus {
61604
61623
  this.waitingAck = true;
61605
61624
  this.sendPendingMessage();
61606
61625
  }
61626
+ dropPendingRevision(revisionId) {
61627
+ this.revisions.drop(revisionId);
61628
+ const revisionIds = this.pendingMessages
61629
+ .filter((message) => message.type === "REMOTE_REVISION")
61630
+ .map((message) => message.nextRevisionId);
61631
+ this.trigger("pending-revisions-dropped", { revisionIds });
61632
+ this.waitingAck = false;
61633
+ this.waitingUndoRedoAck = false;
61634
+ }
61607
61635
  /**
61608
61636
  * Send the next pending message
61609
61637
  */
@@ -61618,13 +61646,7 @@ class Session extends EventBus {
61618
61646
  * The command is empty, we have to drop all the next local revisions
61619
61647
  * to avoid issues with undo/redo
61620
61648
  */
61621
- this.revisions.drop(revision.id);
61622
- const revisionIds = this.pendingMessages
61623
- .filter((message) => message.type === "REMOTE_REVISION")
61624
- .map((message) => message.nextRevisionId);
61625
- this.trigger("pending-revisions-dropped", { revisionIds });
61626
- this.waitingAck = false;
61627
- this.waitingUndoRedoAck = false;
61649
+ this.dropPendingRevision(revision.id);
61628
61650
  this.pendingMessages = [];
61629
61651
  return;
61630
61652
  }
@@ -61650,7 +61672,6 @@ class Session extends EventBus {
61650
61672
  switch (message.type) {
61651
61673
  case "REMOTE_REVISION":
61652
61674
  case "REVISION_REDONE":
61653
- case "REVISION_UNDONE":
61654
61675
  case "SNAPSHOT_CREATED":
61655
61676
  this.waitingAck = false;
61656
61677
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
@@ -61659,6 +61680,27 @@ class Session extends EventBus {
61659
61680
  this.lastRevisionMessage = message;
61660
61681
  this.sendPendingMessage();
61661
61682
  break;
61683
+ case "REVISION_UNDONE": {
61684
+ this.waitingAck = false;
61685
+ this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
61686
+ const pendingRemoteRevisions = this.pendingMessages.filter((message) => message.type === "REMOTE_REVISION");
61687
+ const firstTransformedRevisionIndex = pendingRemoteRevisions.findIndex((message) => !deepEquals(message.commands, this.revisions.get(message.nextRevisionId).commands));
61688
+ if (firstTransformedRevisionIndex !== -1) {
61689
+ /**
61690
+ * Some revisions undergo transformations that may cause issues with
61691
+ * undo/redo if the transformation is destructive (we don't get back
61692
+ * the original command by transforming it with the inverse).
61693
+ * To prevent these problems, we must discard all subsequent local
61694
+ * revisions.
61695
+ */
61696
+ this.dropPendingRevision(this.pendingMessages[firstTransformedRevisionIndex].nextRevisionId);
61697
+ this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
61698
+ }
61699
+ this.serverRevisionId = message.nextRevisionId;
61700
+ this.processedRevisions.add(message.nextRevisionId);
61701
+ this.sendPendingMessage();
61702
+ break;
61703
+ }
61662
61704
  }
61663
61705
  }
61664
61706
  isAlreadyProcessed(message) {
@@ -63090,23 +63132,23 @@ const uuidGenerator = new UuidGenerator();
63090
63132
  function repeatCreateChartCommand(getters, cmd) {
63091
63133
  return {
63092
63134
  ...repeatSheetDependantCommand(getters, cmd),
63093
- id: uuidGenerator.uuidv4(),
63135
+ id: uuidGenerator.smallUuid(),
63094
63136
  };
63095
63137
  }
63096
63138
  function repeatCreateImageCommand(getters, cmd) {
63097
63139
  return {
63098
63140
  ...repeatSheetDependantCommand(getters, cmd),
63099
- figureId: uuidGenerator.uuidv4(),
63141
+ figureId: uuidGenerator.smallUuid(),
63100
63142
  };
63101
63143
  }
63102
63144
  function repeatCreateFigureCommand(getters, cmd) {
63103
63145
  const newCmd = repeatSheetDependantCommand(getters, cmd);
63104
- newCmd.figure.id = uuidGenerator.uuidv4();
63146
+ newCmd.figure.id = uuidGenerator.smallUuid();
63105
63147
  return newCmd;
63106
63148
  }
63107
63149
  function repeatCreateSheetCommand(getters, cmd) {
63108
63150
  const newCmd = deepCopy(cmd);
63109
- newCmd.sheetId = uuidGenerator.uuidv4();
63151
+ newCmd.sheetId = uuidGenerator.smallUuid();
63110
63152
  const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
63111
63153
  // Extract the prefix of the sheet name (everything before the number at the end of the name)
63112
63154
  const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
@@ -64569,23 +64611,7 @@ class GridSelectionPlugin extends UIPlugin {
64569
64611
  gridSelection: deepCopy(gridSelection),
64570
64612
  };
64571
64613
  }
64572
- if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
64573
- const currentSheetIds = this.getters.getVisibleSheetIds();
64574
- this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
64575
- if (this.activeSheet.id in this.sheetsData) {
64576
- const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
64577
- this.selectCell(anchor.cell.col, anchor.cell.row);
64578
- }
64579
- else {
64580
- this.selectCell(0, 0);
64581
- }
64582
- const { col, row } = this.gridSelection.anchor.cell;
64583
- this.moveClient({
64584
- sheetId: this.getters.getActiveSheetId(),
64585
- col,
64586
- row,
64587
- });
64588
- }
64614
+ this.fallbackToVisibleSheet();
64589
64615
  const sheetId = this.getters.getActiveSheetId();
64590
64616
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
64591
64617
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
@@ -64595,6 +64621,7 @@ class GridSelectionPlugin extends UIPlugin {
64595
64621
  }
64596
64622
  }
64597
64623
  finalize() {
64624
+ this.fallbackToVisibleSheet();
64598
64625
  /** Any change to the selection has to be reflected in the selection processor. */
64599
64626
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
64600
64627
  }
@@ -64898,6 +64925,25 @@ class GridSelectionPlugin extends UIPlugin {
64898
64925
  }
64899
64926
  return "Success" /* CommandResult.Success */;
64900
64927
  }
64928
+ fallbackToVisibleSheet() {
64929
+ if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
64930
+ const currentSheetIds = this.getters.getVisibleSheetIds();
64931
+ this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
64932
+ if (this.activeSheet.id in this.sheetsData) {
64933
+ const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
64934
+ this.selectCell(anchor.cell.col, anchor.cell.row);
64935
+ }
64936
+ else {
64937
+ this.selectCell(0, 0);
64938
+ }
64939
+ const { col, row } = this.gridSelection.anchor.cell;
64940
+ this.moveClient({
64941
+ sheetId: this.getters.getActiveSheetId(),
64942
+ col,
64943
+ row,
64944
+ });
64945
+ }
64946
+ }
64901
64947
  //-------------------------------------------
64902
64948
  // Helpers for extensions
64903
64949
  // ------------------------------------------
@@ -66900,7 +66946,7 @@ class BottomBar extends owl.Component {
66900
66946
  clickAddSheet(ev) {
66901
66947
  const activeSheetId = this.env.model.getters.getActiveSheetId();
66902
66948
  const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
66903
- const sheetId = this.env.model.uuidGenerator.uuidv4();
66949
+ const sheetId = this.env.model.uuidGenerator.smallUuid();
66904
66950
  const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
66905
66951
  this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
66906
66952
  this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
@@ -67988,7 +68034,7 @@ css /* scss */ `
67988
68034
  .o-font-size-editor {
67989
68035
  height: calc(100% - 4px);
67990
68036
  input.o-font-size {
67991
- outline-color: ${SELECTION_BORDER_COLOR};
68037
+ outline: none;
67992
68038
  height: 20px;
67993
68039
  width: 23px;
67994
68040
  }
@@ -69275,7 +69321,7 @@ class Tree {
69275
69321
  }
69276
69322
  /**
69277
69323
  * Drop the operation and all following operations in every
69278
- * branch
69324
+ * branches
69279
69325
  */
69280
69326
  drop(operationId) {
69281
69327
  for (const branch of this.branches) {
@@ -72652,7 +72698,7 @@ class Model extends EventBus {
72652
72698
  }
72653
72699
  setupConfig(config) {
72654
72700
  const client = config.client || {
72655
- id: this.uuidGenerator.uuidv4(),
72701
+ id: this.uuidGenerator.smallUuid(),
72656
72702
  name: _t("Anonymous").toString(),
72657
72703
  };
72658
72704
  const transportService = config.transportService || new LocalTransportService();
@@ -73182,6 +73228,6 @@ exports.tokenColors = tokenColors;
73182
73228
  exports.tokenize = tokenize;
73183
73229
 
73184
73230
 
73185
- __info__.version = "18.0.15";
73186
- __info__.date = "2025-02-10T08:59:22.993Z";
73187
- __info__.hash = "5b19f88";
73231
+ __info__.version = "18.0.16";
73232
+ __info__.date = "2025-02-14T08:44:19.475Z";
73233
+ __info__.hash = "39979ab";