@odoo/o-spreadsheet 17.4.22 → 17.4.23

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 17.4.22
6
- * @date 2025-02-10T09:14:48.889Z
7
- * @hash 667f2b1
5
+ * @version 17.4.23
6
+ * @date 2025-02-14T08:37:12.219Z
7
+ * @hash 8339907
8
8
  */
9
9
 
10
10
  'use strict';
@@ -5500,6 +5500,37 @@ class UuidGenerator {
5500
5500
  setIsFastStrategy(isFast) {
5501
5501
  this.isFastIdStrategy = isFast;
5502
5502
  }
5503
+ /**
5504
+ * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
5505
+ * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
5506
+ * it also has a smaller size, which is preferable to alleviate the overall data size.
5507
+ *
5508
+ * This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
5509
+ * as they will appear several times in the revisions and local history.
5510
+ *
5511
+ */
5512
+ smallUuid() {
5513
+ if (this.isFastIdStrategy) {
5514
+ this.fastIdStart++;
5515
+ return String(this.fastIdStart);
5516
+ //@ts-ignore
5517
+ }
5518
+ else if (window.crypto && window.crypto.getRandomValues) {
5519
+ //@ts-ignore
5520
+ return ([1e7] + -1e3).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
5521
+ }
5522
+ else {
5523
+ // mainly for jest and other browsers that do not have the crypto functionality
5524
+ return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
5525
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
5526
+ return v.toString(16);
5527
+ });
5528
+ }
5529
+ }
5530
+ /**
5531
+ * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
5532
+ * This method should be used when you need to avoid collisions at all costs, like the id of a revision.
5533
+ */
5503
5534
  uuidv4() {
5504
5535
  if (this.isFastIdStrategy) {
5505
5536
  this.fastIdStart++;
@@ -5513,7 +5544,7 @@ class UuidGenerator {
5513
5544
  else {
5514
5545
  // mainly for jest and other browsers that do not have the crypto functionality
5515
5546
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
5516
- var r = (Math.random() * 16) | 0, v = c === "x" ? r : (r & 0x3) | 0x8;
5547
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
5517
5548
  return v.toString(16);
5518
5549
  });
5519
5550
  }
@@ -6900,7 +6931,7 @@ class ChartClipboardHandler extends AbstractFigureClipboardHandler {
6900
6931
  };
6901
6932
  }
6902
6933
  getPasteTarget(sheetId, target, content, options) {
6903
- const newId = new UuidGenerator().uuidv4();
6934
+ const newId = new UuidGenerator().smallUuid();
6904
6935
  return { zones: [], figureId: newId, sheetId };
6905
6936
  }
6906
6937
  paste(target, clippedContent, options) {
@@ -7042,7 +7073,9 @@ class ConditionalFormatClipboardHandler extends AbstractCellClipboardHandler {
7042
7073
  const cfInTarget = this.getters
7043
7074
  .getConditionalFormats(targetSheetId)
7044
7075
  .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
7045
- return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
7076
+ return cfInTarget
7077
+ ? cfInTarget
7078
+ : { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
7046
7079
  }
7047
7080
  }
7048
7081
 
@@ -7127,7 +7160,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
7127
7160
  originRule.isBlocking === rule.isBlocking);
7128
7161
  return ruleInTargetSheet
7129
7162
  ? ruleInTargetSheet
7130
- : { ...originRule, id: newId ? this.uuidGenerator.uuidv4() : originRule.id, ranges: [] };
7163
+ : { ...originRule, id: newId ? this.uuidGenerator.smallUuid() : originRule.id, ranges: [] };
7131
7164
  }
7132
7165
  /**
7133
7166
  * Add or remove XCs to a given data validation rule.
@@ -7168,7 +7201,7 @@ class ImageClipboardHandler extends AbstractFigureClipboardHandler {
7168
7201
  };
7169
7202
  }
7170
7203
  getPasteTarget(sheetId, target, content, options) {
7171
- const newId = new UuidGenerator().uuidv4();
7204
+ const newId = new UuidGenerator().smallUuid();
7172
7205
  return { sheetId, zones: [], figureId: newId };
7173
7206
  }
7174
7207
  paste(target, clippedContent, options) {
@@ -13037,6 +13070,25 @@ const LN = {
13037
13070
  isExported: true,
13038
13071
  };
13039
13072
  // -----------------------------------------------------------------------------
13073
+ // LOG
13074
+ // -----------------------------------------------------------------------------
13075
+ const LOG = {
13076
+ description: _t("The logarithm of a number, for a given base."),
13077
+ args: [
13078
+ arg("value (number)", _t("The value for which to calculate the logarithm.")),
13079
+ arg("base (number, default=10)", _t("The base of the logarithm.")),
13080
+ ],
13081
+ compute: function (value, base = { value: 10 }) {
13082
+ const _value = toNumber(value, this.locale);
13083
+ const _base = toNumber(base, this.locale);
13084
+ assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
13085
+ assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
13086
+ assert(() => _base !== 1, _t("The base must be different from 1."));
13087
+ return Math.log10(_value) / Math.log10(_base);
13088
+ },
13089
+ isExported: true,
13090
+ };
13091
+ // -----------------------------------------------------------------------------
13040
13092
  // MOD
13041
13093
  // -----------------------------------------------------------------------------
13042
13094
  function mod(dividend, divisor) {
@@ -13550,6 +13602,7 @@ var math = /*#__PURE__*/Object.freeze({
13550
13602
  ISODD: ISODD,
13551
13603
  ISO_CEILING: ISO_CEILING,
13552
13604
  LN: LN,
13605
+ LOG: LOG,
13553
13606
  MOD: MOD,
13554
13607
  MUNIT: MUNIT,
13555
13608
  ODD: ODD,
@@ -16258,7 +16311,7 @@ const SORTN = {
16258
16311
  }
16259
16312
  }
16260
16313
  },
16261
- isExported: true,
16314
+ isExported: false,
16262
16315
  };
16263
16316
  // -----------------------------------------------------------------------------
16264
16317
  // UNIQUE
@@ -23524,17 +23577,15 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
23524
23577
  plugins: [],
23525
23578
  };
23526
23579
  }
23527
- function getChartLabelFormat(getters, range) {
23580
+ function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
23528
23581
  if (!range)
23529
23582
  return undefined;
23530
- const { sheetId, zone: { left, top, bottom }, } = range;
23531
- for (let row = top; row <= bottom; row++) {
23532
- const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
23533
- if (format) {
23534
- return format;
23535
- }
23583
+ const { sheetId, zone } = range;
23584
+ const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
23585
+ if (shouldRemoveFirstLabel) {
23586
+ formats.shift();
23536
23587
  }
23537
- return undefined;
23588
+ return formats.find((format) => format !== undefined);
23538
23589
  }
23539
23590
  function getChartLabelValues(getters, dataSets, labelRange) {
23540
23591
  let labels = { values: [], formattedValues: [] };
@@ -23872,9 +23923,7 @@ function createBarChartRuntime(chart, getters) {
23872
23923
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
23873
23924
  let labels = labelValues.formattedValues;
23874
23925
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
23875
- if (chart.dataSetsHaveTitle &&
23876
- dataSetsValues[0] &&
23877
- labels.length > dataSetsValues[0].data.length) {
23926
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
23878
23927
  labels.shift();
23879
23928
  }
23880
23929
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -24051,8 +24100,8 @@ function fixEmptyLabelsForDateCharts(labels, dataSetsValues) {
24051
24100
  }
24052
24101
  return { labels: newLabels, dataSetsValues: newDatasets };
24053
24102
  }
24054
- function canChartParseLabels(labelRange, getters) {
24055
- return canBeDateChart(labelRange, getters) || canBeLinearChart(labelRange, getters);
24103
+ function canChartParseLabels(chart, getters) {
24104
+ return canBeDateChart(chart, getters) || canBeLinearChart(chart, getters);
24056
24105
  }
24057
24106
  function getChartAxisType(chart, getters) {
24058
24107
  if (isDateChart(chart, getters) && isLuxonTimeAdapterInstalled()) {
@@ -24064,23 +24113,26 @@ function getChartAxisType(chart, getters) {
24064
24113
  return "category";
24065
24114
  }
24066
24115
  function isDateChart(chart, getters) {
24067
- return !chart.labelsAsText && canBeDateChart(chart.labelRange, getters);
24116
+ return !chart.labelsAsText && canBeDateChart(chart, getters);
24068
24117
  }
24069
24118
  function isLinearChart(chart, getters) {
24070
- return !chart.labelsAsText && canBeLinearChart(chart.labelRange, getters);
24119
+ return !chart.labelsAsText && canBeLinearChart(chart, getters);
24071
24120
  }
24072
- function canBeDateChart(labelRange, getters) {
24073
- if (!labelRange || !canBeLinearChart(labelRange, getters)) {
24121
+ function canBeDateChart(chart, getters) {
24122
+ if (!chart.labelRange || !canBeLinearChart(chart, getters)) {
24074
24123
  return false;
24075
24124
  }
24076
- const labelFormat = getChartLabelFormat(getters, labelRange);
24125
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle));
24077
24126
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
24078
24127
  }
24079
- function canBeLinearChart(labelRange, getters) {
24080
- if (!labelRange) {
24128
+ function canBeLinearChart(chart, getters) {
24129
+ if (!chart.labelRange) {
24081
24130
  return false;
24082
24131
  }
24083
- const labels = getters.getRangeValues(labelRange);
24132
+ const labels = getters.getRangeValues(chart.labelRange);
24133
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
24134
+ labels.shift();
24135
+ }
24084
24136
  if (labels.some((label) => isNaN(Number(label)) && label)) {
24085
24137
  return false;
24086
24138
  }
@@ -24183,9 +24235,8 @@ function createLineOrScatterChartRuntime(chart, getters) {
24183
24235
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
24184
24236
  let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
24185
24237
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
24186
- if (chart.dataSetsHaveTitle &&
24187
- dataSetsValues[0] &&
24188
- labels.length > dataSetsValues[0].data.length) {
24238
+ const removeFirstLabel = shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle);
24239
+ if (removeFirstLabel) {
24189
24240
  labels.shift();
24190
24241
  }
24191
24242
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -24200,7 +24251,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
24200
24251
  const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
24201
24252
  const options = { format: dataSetFormat, locale, truncateLabels };
24202
24253
  const config = getLineOrScatterConfiguration(chart, labels, options);
24203
- const labelFormat = getChartLabelFormat(getters, chart.labelRange);
24254
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, removeFirstLabel);
24204
24255
  if (axisType === "time") {
24205
24256
  const axis = {
24206
24257
  type: "time",
@@ -24414,9 +24465,7 @@ function createComboChartRuntime(chart, getters) {
24414
24465
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
24415
24466
  let labels = labelValues.formattedValues;
24416
24467
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
24417
- if (chart.dataSetsHaveTitle &&
24418
- dataSetsValues[0] &&
24419
- labels.length > dataSetsValues[0].data.length) {
24468
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
24420
24469
  labels.shift();
24421
24470
  }
24422
24471
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -25069,9 +25118,7 @@ function createPieChartRuntime(chart, getters) {
25069
25118
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
25070
25119
  let labels = labelValues.formattedValues;
25071
25120
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
25072
- if (chart.dataSetsHaveTitle &&
25073
- dataSetsValues[0] &&
25074
- labels.length > dataSetsValues[0].data.length) {
25121
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
25075
25122
  labels.shift();
25076
25123
  }
25077
25124
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -25619,9 +25666,7 @@ function createWaterfallChartRuntime(chart, getters) {
25619
25666
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
25620
25667
  let labels = labelValues.formattedValues;
25621
25668
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
25622
- if (chart.dataSetsHaveTitle &&
25623
- dataSetsValues[0] &&
25624
- labels.length > dataSetsValues[0].data.length) {
25669
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
25625
25670
  labels.shift();
25626
25671
  }
25627
25672
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -27139,7 +27184,7 @@ const linkSheet = {
27139
27184
  const deleteSheet = {
27140
27185
  name: _t("Delete"),
27141
27186
  isVisible: (env) => {
27142
- return env.model.getters.getSheetIds().length > 1;
27187
+ return env.model.getters.getVisibleSheetIds().length > 1;
27143
27188
  },
27144
27189
  execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
27145
27190
  env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
@@ -27149,7 +27194,7 @@ const duplicateSheet = {
27149
27194
  name: _t("Duplicate"),
27150
27195
  execute: (env) => {
27151
27196
  const sheetIdFrom = env.model.getters.getActiveSheetId();
27152
- const sheetIdTo = env.model.uuidGenerator.uuidv4();
27197
+ const sheetIdTo = env.model.uuidGenerator.smallUuid();
27153
27198
  env.model.dispatch("DUPLICATE_SHEET", {
27154
27199
  sheetId: sheetIdFrom,
27155
27200
  sheetIdTo,
@@ -27764,20 +27809,21 @@ function getSmartChartDefinition(zone, getters) {
27764
27809
  }
27765
27810
  // Only display legend for several datasets.
27766
27811
  const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
27767
- const labelRange = labelRangeXc ? getters.getRangeFromSheetXC(sheetId, labelRangeXc) : undefined;
27768
- if (canChartParseLabels(labelRange, getters)) {
27769
- return {
27770
- title: {},
27771
- dataSets,
27772
- labelsAsText: false,
27773
- stacked: false,
27774
- aggregated: false,
27775
- cumulative: false,
27776
- labelRange: labelRangeXc,
27777
- type: "line",
27778
- dataSetsHaveTitle,
27779
- legendPosition: newLegendPos,
27780
- };
27812
+ const lineChartDefinition = {
27813
+ title: {},
27814
+ dataSets,
27815
+ labelsAsText: false,
27816
+ stacked: false,
27817
+ aggregated: false,
27818
+ cumulative: false,
27819
+ labelRange: labelRangeXc,
27820
+ type: "line",
27821
+ dataSetsHaveTitle,
27822
+ legendPosition: newLegendPos,
27823
+ };
27824
+ const chart = new LineChart(lineChartDefinition, sheetId, getters);
27825
+ if (canChartParseLabels(chart, getters)) {
27826
+ return lineChartDefinition;
27781
27827
  }
27782
27828
  const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
27783
27829
  if (singleColumn &&
@@ -28471,7 +28517,7 @@ const HIDE_ROWS_NAME = (env) => {
28471
28517
  //------------------------------------------------------------------------------
28472
28518
  const CREATE_CHART = (env) => {
28473
28519
  const getters = env.model.getters;
28474
- const id = env.model.uuidGenerator.uuidv4();
28520
+ const id = env.model.uuidGenerator.smallUuid();
28475
28521
  const sheetId = getters.getActiveSheetId();
28476
28522
  if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
28477
28523
  env.model.selection.selectTableAroundSelection();
@@ -28494,8 +28540,8 @@ const CREATE_CHART = (env) => {
28494
28540
  // Pivots
28495
28541
  //------------------------------------------------------------------------------
28496
28542
  const CREATE_PIVOT = (env) => {
28497
- const pivotId = env.model.uuidGenerator.uuidv4();
28498
- const newSheetId = env.model.uuidGenerator.uuidv4();
28543
+ const pivotId = env.model.uuidGenerator.smallUuid();
28544
+ const newSheetId = env.model.uuidGenerator.smallUuid();
28499
28545
  const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
28500
28546
  if (result.isSuccessful) {
28501
28547
  env.openSidePanel("PivotSidePanel", { pivotId });
@@ -28554,7 +28600,7 @@ async function requestImage(env) {
28554
28600
  const CREATE_IMAGE = async (env) => {
28555
28601
  if (env.imageProvider) {
28556
28602
  const sheetId = env.model.getters.getActiveSheetId();
28557
- const figureId = env.model.uuidGenerator.uuidv4();
28603
+ const figureId = env.model.uuidGenerator.smallUuid();
28558
28604
  const image = await requestImage(env);
28559
28605
  if (!image) {
28560
28606
  throw new Error("No image provider was given to the environment");
@@ -29107,7 +29153,7 @@ const insertCheckbox = {
29107
29153
  ranges,
29108
29154
  sheetId,
29109
29155
  rule: {
29110
- id: env.model.uuidGenerator.uuidv4(),
29156
+ id: env.model.uuidGenerator.smallUuid(),
29111
29157
  criterion: {
29112
29158
  type: "isBoolean",
29113
29159
  values: [],
@@ -29123,7 +29169,7 @@ const insertDropdown = {
29123
29169
  const zones = env.model.getters.getSelectedZones();
29124
29170
  const sheetId = env.model.getters.getActiveSheetId();
29125
29171
  const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
29126
- const ruleID = env.model.uuidGenerator.uuidv4();
29172
+ const ruleID = env.model.uuidGenerator.smallUuid();
29127
29173
  env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
29128
29174
  ranges,
29129
29175
  sheetId,
@@ -29154,7 +29200,7 @@ const insertSheet = {
29154
29200
  execute: (env) => {
29155
29201
  const activeSheetId = env.model.getters.getActiveSheetId();
29156
29202
  const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
29157
- const sheetId = env.model.uuidGenerator.uuidv4();
29203
+ const sheetId = env.model.uuidGenerator.smallUuid();
29158
29204
  env.model.dispatch("CREATE_SHEET", { sheetId, position });
29159
29205
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
29160
29206
  },
@@ -32853,7 +32899,7 @@ class LineConfigPanel extends GenericChartConfigPanel {
32853
32899
  get canTreatLabelsAsText() {
32854
32900
  const chart = this.env.model.getters.getChart(this.props.figureId);
32855
32901
  if (chart && chart instanceof LineChart) {
32856
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
32902
+ return canChartParseLabels(chart, this.env.model.getters);
32857
32903
  }
32858
32904
  return false;
32859
32905
  }
@@ -32925,7 +32971,7 @@ class ScatterConfigPanel extends GenericChartConfigPanel {
32925
32971
  get canTreatLabelsAsText() {
32926
32972
  const chart = this.env.model.getters.getChart(this.props.figureId);
32927
32973
  if (chart && chart instanceof ScatterChart) {
32928
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
32974
+ return canChartParseLabels(chart, this.env.model.getters);
32929
32975
  }
32930
32976
  return false;
32931
32977
  }
@@ -34224,7 +34270,7 @@ class ConditionalFormattingEditor extends owl.Component {
34224
34270
  state;
34225
34271
  setup() {
34226
34272
  const cf = this.props.editedCf || {
34227
- id: this.env.model.uuidGenerator.uuidv4(),
34273
+ id: this.env.model.uuidGenerator.smallUuid(),
34228
34274
  ranges: this.env.model.getters
34229
34275
  .getSelectedZones()
34230
34276
  .map((zone) => this.env.model.getters.zoneToXC(this.env.model.getters.getActiveSheetId(), zone)),
@@ -35196,7 +35242,7 @@ class DataValidationEditor extends owl.Component {
35196
35242
  .getSelectedZones()
35197
35243
  .map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
35198
35244
  return {
35199
- id: this.env.model.uuidGenerator.uuidv4(),
35245
+ id: this.env.model.uuidGenerator.smallUuid(),
35200
35246
  criterion: { type: "textContains", values: [""] },
35201
35247
  ranges,
35202
35248
  };
@@ -36315,8 +36361,8 @@ class PivotTitleSection extends owl.Component {
36315
36361
  return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
36316
36362
  }
36317
36363
  duplicatePivot() {
36318
- const newPivotId = this.env.model.uuidGenerator.uuidv4();
36319
- const newSheetId = this.env.model.uuidGenerator.uuidv4();
36364
+ const newPivotId = this.env.model.uuidGenerator.smallUuid();
36365
+ const newSheetId = this.env.model.uuidGenerator.smallUuid();
36320
36366
  const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
36321
36367
  pivotId: this.props.pivotId,
36322
36368
  newPivotId,
@@ -38645,7 +38691,7 @@ class TableStyleEditorPanel extends owl.Component {
38645
38691
  this.state.selectedTemplateName = templateName;
38646
38692
  }
38647
38693
  onConfirm() {
38648
- const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.uuidv4();
38694
+ const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
38649
38695
  this.env.model.dispatch("CREATE_TABLE_STYLE", {
38650
38696
  tableStyleId,
38651
38697
  tableStyleName: this.state.styleName,
@@ -50926,7 +50972,7 @@ class SheetPlugin extends CorePlugin {
50926
50972
  case "RENAME_SHEET":
50927
50973
  return this.isRenameAllowed(cmd);
50928
50974
  case "DELETE_SHEET":
50929
- return this.orderedSheetIds.length > 1
50975
+ return this.getVisibleSheetIds().length > 1
50930
50976
  ? "Success" /* CommandResult.Success */
50931
50977
  : "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
50932
50978
  case "ADD_COLUMNS_ROWS":
@@ -51783,7 +51829,7 @@ class TablePlugin extends CorePlugin {
51783
51829
  const union = this.getters.getRangesUnion(ranges);
51784
51830
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
51785
51831
  this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
51786
- const id = this.uuidGenerator.uuidv4();
51832
+ const id = this.uuidGenerator.smallUuid();
51787
51833
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
51788
51834
  const newTable = cmd.tableType === "dynamic"
51789
51835
  ? this.createDynamicTable(id, union, config)
@@ -51936,7 +51982,7 @@ class TablePlugin extends CorePlugin {
51936
51982
  filters = [];
51937
51983
  for (const i of range(zone.left, zone.right + 1)) {
51938
51984
  const filterZone = { ...zone, left: i, right: i };
51939
- const uid = this.uuidGenerator.uuidv4();
51985
+ const uid = this.uuidGenerator.smallUuid();
51940
51986
  filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
51941
51987
  }
51942
51988
  }
@@ -52001,7 +52047,7 @@ class TablePlugin extends CorePlugin {
52001
52047
  ? table.filters.find((f) => f.col === i)
52002
52048
  : undefined;
52003
52049
  const filterZone = { ...tableZone, left: i, right: i };
52004
- const filterId = oldFilter?.id || this.uuidGenerator.uuidv4();
52050
+ const filterId = oldFilter?.id || this.uuidGenerator.smallUuid();
52005
52051
  filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
52006
52052
  }
52007
52053
  }
@@ -52102,7 +52148,7 @@ class TablePlugin extends CorePlugin {
52102
52148
  if (filters.length < zoneToDimension(tableZone).numberOfCols) {
52103
52149
  for (let col = tableZone.left; col <= tableZone.right; col++) {
52104
52150
  if (!filters.find((filter) => filter.col === col)) {
52105
- const uid = this.uuidGenerator.uuidv4();
52151
+ const uid = this.uuidGenerator.smallUuid();
52106
52152
  const filterZone = { ...tableZone, left: col, right: col };
52107
52153
  filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
52108
52154
  }
@@ -59051,23 +59097,23 @@ const uuidGenerator = new UuidGenerator();
59051
59097
  function repeatCreateChartCommand(getters, cmd) {
59052
59098
  return {
59053
59099
  ...repeatSheetDependantCommand(getters, cmd),
59054
- id: uuidGenerator.uuidv4(),
59100
+ id: uuidGenerator.smallUuid(),
59055
59101
  };
59056
59102
  }
59057
59103
  function repeatCreateImageCommand(getters, cmd) {
59058
59104
  return {
59059
59105
  ...repeatSheetDependantCommand(getters, cmd),
59060
- figureId: uuidGenerator.uuidv4(),
59106
+ figureId: uuidGenerator.smallUuid(),
59061
59107
  };
59062
59108
  }
59063
59109
  function repeatCreateFigureCommand(getters, cmd) {
59064
59110
  const newCmd = repeatSheetDependantCommand(getters, cmd);
59065
- newCmd.figure.id = uuidGenerator.uuidv4();
59111
+ newCmd.figure.id = uuidGenerator.smallUuid();
59066
59112
  return newCmd;
59067
59113
  }
59068
59114
  function repeatCreateSheetCommand(getters, cmd) {
59069
59115
  const newCmd = deepCopy(cmd);
59070
- newCmd.sheetId = uuidGenerator.uuidv4();
59116
+ newCmd.sheetId = uuidGenerator.smallUuid();
59071
59117
  const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
59072
59118
  // Extract the prefix of the sheet name (everything before the number at the end of the name)
59073
59119
  const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
@@ -60537,23 +60583,7 @@ class GridSelectionPlugin extends UIPlugin {
60537
60583
  gridSelection: deepCopy(gridSelection),
60538
60584
  };
60539
60585
  }
60540
- if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
60541
- const currentSheetIds = this.getters.getVisibleSheetIds();
60542
- this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
60543
- if (this.activeSheet.id in this.sheetsData) {
60544
- const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
60545
- this.selectCell(anchor.cell.col, anchor.cell.row);
60546
- }
60547
- else {
60548
- this.selectCell(0, 0);
60549
- }
60550
- const { col, row } = this.gridSelection.anchor.cell;
60551
- this.moveClient({
60552
- sheetId: this.getters.getActiveSheetId(),
60553
- col,
60554
- row,
60555
- });
60556
- }
60586
+ this.fallbackToVisibleSheet();
60557
60587
  const sheetId = this.getters.getActiveSheetId();
60558
60588
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
60559
60589
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
@@ -60563,6 +60593,7 @@ class GridSelectionPlugin extends UIPlugin {
60563
60593
  }
60564
60594
  }
60565
60595
  finalize() {
60596
+ this.fallbackToVisibleSheet();
60566
60597
  /** Any change to the selection has to be reflected in the selection processor. */
60567
60598
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
60568
60599
  }
@@ -60866,6 +60897,25 @@ class GridSelectionPlugin extends UIPlugin {
60866
60897
  }
60867
60898
  return "Success" /* CommandResult.Success */;
60868
60899
  }
60900
+ fallbackToVisibleSheet() {
60901
+ if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
60902
+ const currentSheetIds = this.getters.getVisibleSheetIds();
60903
+ this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
60904
+ if (this.activeSheet.id in this.sheetsData) {
60905
+ const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
60906
+ this.selectCell(anchor.cell.col, anchor.cell.row);
60907
+ }
60908
+ else {
60909
+ this.selectCell(0, 0);
60910
+ }
60911
+ const { col, row } = this.gridSelection.anchor.cell;
60912
+ this.moveClient({
60913
+ sheetId: this.getters.getActiveSheetId(),
60914
+ col,
60915
+ row,
60916
+ });
60917
+ }
60918
+ }
60869
60919
  //-------------------------------------------
60870
60920
  // Helpers for extensions
60871
60921
  // ------------------------------------------
@@ -62845,7 +62895,7 @@ class BottomBar extends owl.Component {
62845
62895
  clickAddSheet(ev) {
62846
62896
  const activeSheetId = this.env.model.getters.getActiveSheetId();
62847
62897
  const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
62848
- const sheetId = this.env.model.uuidGenerator.uuidv4();
62898
+ const sheetId = this.env.model.uuidGenerator.smallUuid();
62849
62899
  const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
62850
62900
  this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
62851
62901
  this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
@@ -68403,7 +68453,7 @@ class Model extends EventBus {
68403
68453
  }
68404
68454
  setupConfig(config) {
68405
68455
  const client = config.client || {
68406
- id: this.uuidGenerator.uuidv4(),
68456
+ id: this.uuidGenerator.smallUuid(),
68407
68457
  name: _t("Anonymous").toString(),
68408
68458
  };
68409
68459
  const transportService = config.transportService || new LocalTransportService();
@@ -68922,6 +68972,6 @@ exports.tokenColors = tokenColors;
68922
68972
  exports.tokenize = tokenize;
68923
68973
 
68924
68974
 
68925
- __info__.version = "17.4.22";
68926
- __info__.date = "2025-02-10T09:14:48.889Z";
68927
- __info__.hash = "667f2b1";
68975
+ __info__.version = "17.4.23";
68976
+ __info__.date = "2025-02-14T08:37:12.219Z";
68977
+ __info__.hash = "8339907";
@@ -4884,6 +4884,7 @@ declare class GridSelectionPlugin extends UIPlugin {
4884
4884
  private onAddElements;
4885
4885
  private onMoveElements;
4886
4886
  private isMoveElementAllowed;
4887
+ private fallbackToVisibleSheet;
4887
4888
  /**
4888
4889
  * Clip the selection if it spans outside the sheet
4889
4890
  */
@@ -5642,6 +5643,20 @@ declare class UuidGenerator {
5642
5643
  private isFastIdStrategy;
5643
5644
  private fastIdStart;
5644
5645
  setIsFastStrategy(isFast: boolean): void;
5646
+ /**
5647
+ * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
5648
+ * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
5649
+ * it also has a smaller size, which is preferable to alleviate the overall data size.
5650
+ *
5651
+ * This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
5652
+ * as they will appear several times in the revisions and local history.
5653
+ *
5654
+ */
5655
+ smallUuid(): string;
5656
+ /**
5657
+ * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
5658
+ * This method should be used when you need to avoid collisions at all costs, like the id of a revision.
5659
+ */
5645
5660
  uuidv4(): string;
5646
5661
  }
5647
5662