@odoo/o-spreadsheet 17.4.21 → 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.21
6
- * @date 2025-02-05T06:46:54.366Z
7
- * @hash 0c55e18
5
+ * @version 17.4.23
6
+ * @date 2025-02-14T08:37:12.219Z
7
+ * @hash 8339907
8
8
  */
9
9
 
10
10
  'use strict';
@@ -748,9 +748,16 @@ function deepEqualsArray(arr1, arr2) {
748
748
  }
749
749
  return true;
750
750
  }
751
- /** Check if the given array contains all the values of the other array. */
751
+ /**
752
+ * Check if the given array contains all the values of the other array.
753
+ * It makes the assumption that both array do not contain duplicates.
754
+ */
752
755
  function includesAll(arr, values) {
753
- return values.every((value) => arr.includes(value));
756
+ if (arr.length < values.length) {
757
+ return false;
758
+ }
759
+ const set = new Set(arr);
760
+ return values.every((value) => set.has(value));
754
761
  }
755
762
  /**
756
763
  * Return an object with all the keys in the object that have a falsy value removed.
@@ -5493,6 +5500,37 @@ class UuidGenerator {
5493
5500
  setIsFastStrategy(isFast) {
5494
5501
  this.isFastIdStrategy = isFast;
5495
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
+ */
5496
5534
  uuidv4() {
5497
5535
  if (this.isFastIdStrategy) {
5498
5536
  this.fastIdStart++;
@@ -5506,7 +5544,7 @@ class UuidGenerator {
5506
5544
  else {
5507
5545
  // mainly for jest and other browsers that do not have the crypto functionality
5508
5546
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
5509
- 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;
5510
5548
  return v.toString(16);
5511
5549
  });
5512
5550
  }
@@ -6893,7 +6931,7 @@ class ChartClipboardHandler extends AbstractFigureClipboardHandler {
6893
6931
  };
6894
6932
  }
6895
6933
  getPasteTarget(sheetId, target, content, options) {
6896
- const newId = new UuidGenerator().uuidv4();
6934
+ const newId = new UuidGenerator().smallUuid();
6897
6935
  return { zones: [], figureId: newId, sheetId };
6898
6936
  }
6899
6937
  paste(target, clippedContent, options) {
@@ -7035,7 +7073,9 @@ class ConditionalFormatClipboardHandler extends AbstractCellClipboardHandler {
7035
7073
  const cfInTarget = this.getters
7036
7074
  .getConditionalFormats(targetSheetId)
7037
7075
  .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
7038
- return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
7076
+ return cfInTarget
7077
+ ? cfInTarget
7078
+ : { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
7039
7079
  }
7040
7080
  }
7041
7081
 
@@ -7120,7 +7160,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
7120
7160
  originRule.isBlocking === rule.isBlocking);
7121
7161
  return ruleInTargetSheet
7122
7162
  ? ruleInTargetSheet
7123
- : { ...originRule, id: newId ? this.uuidGenerator.uuidv4() : originRule.id, ranges: [] };
7163
+ : { ...originRule, id: newId ? this.uuidGenerator.smallUuid() : originRule.id, ranges: [] };
7124
7164
  }
7125
7165
  /**
7126
7166
  * Add or remove XCs to a given data validation rule.
@@ -7161,7 +7201,7 @@ class ImageClipboardHandler extends AbstractFigureClipboardHandler {
7161
7201
  };
7162
7202
  }
7163
7203
  getPasteTarget(sheetId, target, content, options) {
7164
- const newId = new UuidGenerator().uuidv4();
7204
+ const newId = new UuidGenerator().smallUuid();
7165
7205
  return { sheetId, zones: [], figureId: newId };
7166
7206
  }
7167
7207
  paste(target, clippedContent, options) {
@@ -13030,6 +13070,25 @@ const LN = {
13030
13070
  isExported: true,
13031
13071
  };
13032
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
+ // -----------------------------------------------------------------------------
13033
13092
  // MOD
13034
13093
  // -----------------------------------------------------------------------------
13035
13094
  function mod(dividend, divisor) {
@@ -13543,6 +13602,7 @@ var math = /*#__PURE__*/Object.freeze({
13543
13602
  ISODD: ISODD,
13544
13603
  ISO_CEILING: ISO_CEILING,
13545
13604
  LN: LN,
13605
+ LOG: LOG,
13546
13606
  MOD: MOD,
13547
13607
  MUNIT: MUNIT,
13548
13608
  ODD: ODD,
@@ -16251,7 +16311,7 @@ const SORTN = {
16251
16311
  }
16252
16312
  }
16253
16313
  },
16254
- isExported: true,
16314
+ isExported: false,
16255
16315
  };
16256
16316
  // -----------------------------------------------------------------------------
16257
16317
  // UNIQUE
@@ -23517,17 +23577,15 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
23517
23577
  plugins: [],
23518
23578
  };
23519
23579
  }
23520
- function getChartLabelFormat(getters, range) {
23580
+ function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
23521
23581
  if (!range)
23522
23582
  return undefined;
23523
- const { sheetId, zone: { left, top, bottom }, } = range;
23524
- for (let row = top; row <= bottom; row++) {
23525
- const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
23526
- if (format) {
23527
- return format;
23528
- }
23583
+ const { sheetId, zone } = range;
23584
+ const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
23585
+ if (shouldRemoveFirstLabel) {
23586
+ formats.shift();
23529
23587
  }
23530
- return undefined;
23588
+ return formats.find((format) => format !== undefined);
23531
23589
  }
23532
23590
  function getChartLabelValues(getters, dataSets, labelRange) {
23533
23591
  let labels = { values: [], formattedValues: [] };
@@ -23865,9 +23923,7 @@ function createBarChartRuntime(chart, getters) {
23865
23923
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
23866
23924
  let labels = labelValues.formattedValues;
23867
23925
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
23868
- if (chart.dataSetsHaveTitle &&
23869
- dataSetsValues[0] &&
23870
- labels.length > dataSetsValues[0].data.length) {
23926
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
23871
23927
  labels.shift();
23872
23928
  }
23873
23929
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -24044,8 +24100,8 @@ function fixEmptyLabelsForDateCharts(labels, dataSetsValues) {
24044
24100
  }
24045
24101
  return { labels: newLabels, dataSetsValues: newDatasets };
24046
24102
  }
24047
- function canChartParseLabels(labelRange, getters) {
24048
- return canBeDateChart(labelRange, getters) || canBeLinearChart(labelRange, getters);
24103
+ function canChartParseLabels(chart, getters) {
24104
+ return canBeDateChart(chart, getters) || canBeLinearChart(chart, getters);
24049
24105
  }
24050
24106
  function getChartAxisType(chart, getters) {
24051
24107
  if (isDateChart(chart, getters) && isLuxonTimeAdapterInstalled()) {
@@ -24057,23 +24113,26 @@ function getChartAxisType(chart, getters) {
24057
24113
  return "category";
24058
24114
  }
24059
24115
  function isDateChart(chart, getters) {
24060
- return !chart.labelsAsText && canBeDateChart(chart.labelRange, getters);
24116
+ return !chart.labelsAsText && canBeDateChart(chart, getters);
24061
24117
  }
24062
24118
  function isLinearChart(chart, getters) {
24063
- return !chart.labelsAsText && canBeLinearChart(chart.labelRange, getters);
24119
+ return !chart.labelsAsText && canBeLinearChart(chart, getters);
24064
24120
  }
24065
- function canBeDateChart(labelRange, getters) {
24066
- if (!labelRange || !canBeLinearChart(labelRange, getters)) {
24121
+ function canBeDateChart(chart, getters) {
24122
+ if (!chart.labelRange || !canBeLinearChart(chart, getters)) {
24067
24123
  return false;
24068
24124
  }
24069
- const labelFormat = getChartLabelFormat(getters, labelRange);
24125
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle));
24070
24126
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
24071
24127
  }
24072
- function canBeLinearChart(labelRange, getters) {
24073
- if (!labelRange) {
24128
+ function canBeLinearChart(chart, getters) {
24129
+ if (!chart.labelRange) {
24074
24130
  return false;
24075
24131
  }
24076
- 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
+ }
24077
24136
  if (labels.some((label) => isNaN(Number(label)) && label)) {
24078
24137
  return false;
24079
24138
  }
@@ -24176,9 +24235,8 @@ function createLineOrScatterChartRuntime(chart, getters) {
24176
24235
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
24177
24236
  let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
24178
24237
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
24179
- if (chart.dataSetsHaveTitle &&
24180
- dataSetsValues[0] &&
24181
- labels.length > dataSetsValues[0].data.length) {
24238
+ const removeFirstLabel = shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle);
24239
+ if (removeFirstLabel) {
24182
24240
  labels.shift();
24183
24241
  }
24184
24242
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -24193,7 +24251,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
24193
24251
  const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
24194
24252
  const options = { format: dataSetFormat, locale, truncateLabels };
24195
24253
  const config = getLineOrScatterConfiguration(chart, labels, options);
24196
- const labelFormat = getChartLabelFormat(getters, chart.labelRange);
24254
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, removeFirstLabel);
24197
24255
  if (axisType === "time") {
24198
24256
  const axis = {
24199
24257
  type: "time",
@@ -24407,9 +24465,7 @@ function createComboChartRuntime(chart, getters) {
24407
24465
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
24408
24466
  let labels = labelValues.formattedValues;
24409
24467
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
24410
- if (chart.dataSetsHaveTitle &&
24411
- dataSetsValues[0] &&
24412
- labels.length > dataSetsValues[0].data.length) {
24468
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
24413
24469
  labels.shift();
24414
24470
  }
24415
24471
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -25062,9 +25118,7 @@ function createPieChartRuntime(chart, getters) {
25062
25118
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
25063
25119
  let labels = labelValues.formattedValues;
25064
25120
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
25065
- if (chart.dataSetsHaveTitle &&
25066
- dataSetsValues[0] &&
25067
- labels.length > dataSetsValues[0].data.length) {
25121
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
25068
25122
  labels.shift();
25069
25123
  }
25070
25124
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -25612,9 +25666,7 @@ function createWaterfallChartRuntime(chart, getters) {
25612
25666
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
25613
25667
  let labels = labelValues.formattedValues;
25614
25668
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
25615
- if (chart.dataSetsHaveTitle &&
25616
- dataSetsValues[0] &&
25617
- labels.length > dataSetsValues[0].data.length) {
25669
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
25618
25670
  labels.shift();
25619
25671
  }
25620
25672
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -27132,7 +27184,7 @@ const linkSheet = {
27132
27184
  const deleteSheet = {
27133
27185
  name: _t("Delete"),
27134
27186
  isVisible: (env) => {
27135
- return env.model.getters.getSheetIds().length > 1;
27187
+ return env.model.getters.getVisibleSheetIds().length > 1;
27136
27188
  },
27137
27189
  execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
27138
27190
  env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
@@ -27142,7 +27194,7 @@ const duplicateSheet = {
27142
27194
  name: _t("Duplicate"),
27143
27195
  execute: (env) => {
27144
27196
  const sheetIdFrom = env.model.getters.getActiveSheetId();
27145
- const sheetIdTo = env.model.uuidGenerator.uuidv4();
27197
+ const sheetIdTo = env.model.uuidGenerator.smallUuid();
27146
27198
  env.model.dispatch("DUPLICATE_SHEET", {
27147
27199
  sheetId: sheetIdFrom,
27148
27200
  sheetIdTo,
@@ -27757,20 +27809,21 @@ function getSmartChartDefinition(zone, getters) {
27757
27809
  }
27758
27810
  // Only display legend for several datasets.
27759
27811
  const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
27760
- const labelRange = labelRangeXc ? getters.getRangeFromSheetXC(sheetId, labelRangeXc) : undefined;
27761
- if (canChartParseLabels(labelRange, getters)) {
27762
- return {
27763
- title: {},
27764
- dataSets,
27765
- labelsAsText: false,
27766
- stacked: false,
27767
- aggregated: false,
27768
- cumulative: false,
27769
- labelRange: labelRangeXc,
27770
- type: "line",
27771
- dataSetsHaveTitle,
27772
- legendPosition: newLegendPos,
27773
- };
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;
27774
27827
  }
27775
27828
  const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
27776
27829
  if (singleColumn &&
@@ -28464,7 +28517,7 @@ const HIDE_ROWS_NAME = (env) => {
28464
28517
  //------------------------------------------------------------------------------
28465
28518
  const CREATE_CHART = (env) => {
28466
28519
  const getters = env.model.getters;
28467
- const id = env.model.uuidGenerator.uuidv4();
28520
+ const id = env.model.uuidGenerator.smallUuid();
28468
28521
  const sheetId = getters.getActiveSheetId();
28469
28522
  if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
28470
28523
  env.model.selection.selectTableAroundSelection();
@@ -28487,8 +28540,8 @@ const CREATE_CHART = (env) => {
28487
28540
  // Pivots
28488
28541
  //------------------------------------------------------------------------------
28489
28542
  const CREATE_PIVOT = (env) => {
28490
- const pivotId = env.model.uuidGenerator.uuidv4();
28491
- const newSheetId = env.model.uuidGenerator.uuidv4();
28543
+ const pivotId = env.model.uuidGenerator.smallUuid();
28544
+ const newSheetId = env.model.uuidGenerator.smallUuid();
28492
28545
  const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
28493
28546
  if (result.isSuccessful) {
28494
28547
  env.openSidePanel("PivotSidePanel", { pivotId });
@@ -28547,7 +28600,7 @@ async function requestImage(env) {
28547
28600
  const CREATE_IMAGE = async (env) => {
28548
28601
  if (env.imageProvider) {
28549
28602
  const sheetId = env.model.getters.getActiveSheetId();
28550
- const figureId = env.model.uuidGenerator.uuidv4();
28603
+ const figureId = env.model.uuidGenerator.smallUuid();
28551
28604
  const image = await requestImage(env);
28552
28605
  if (!image) {
28553
28606
  throw new Error("No image provider was given to the environment");
@@ -29100,7 +29153,7 @@ const insertCheckbox = {
29100
29153
  ranges,
29101
29154
  sheetId,
29102
29155
  rule: {
29103
- id: env.model.uuidGenerator.uuidv4(),
29156
+ id: env.model.uuidGenerator.smallUuid(),
29104
29157
  criterion: {
29105
29158
  type: "isBoolean",
29106
29159
  values: [],
@@ -29116,7 +29169,7 @@ const insertDropdown = {
29116
29169
  const zones = env.model.getters.getSelectedZones();
29117
29170
  const sheetId = env.model.getters.getActiveSheetId();
29118
29171
  const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
29119
- const ruleID = env.model.uuidGenerator.uuidv4();
29172
+ const ruleID = env.model.uuidGenerator.smallUuid();
29120
29173
  env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
29121
29174
  ranges,
29122
29175
  sheetId,
@@ -29147,7 +29200,7 @@ const insertSheet = {
29147
29200
  execute: (env) => {
29148
29201
  const activeSheetId = env.model.getters.getActiveSheetId();
29149
29202
  const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
29150
- const sheetId = env.model.uuidGenerator.uuidv4();
29203
+ const sheetId = env.model.uuidGenerator.smallUuid();
29151
29204
  env.model.dispatch("CREATE_SHEET", { sheetId, position });
29152
29205
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
29153
29206
  },
@@ -32846,7 +32899,7 @@ class LineConfigPanel extends GenericChartConfigPanel {
32846
32899
  get canTreatLabelsAsText() {
32847
32900
  const chart = this.env.model.getters.getChart(this.props.figureId);
32848
32901
  if (chart && chart instanceof LineChart) {
32849
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
32902
+ return canChartParseLabels(chart, this.env.model.getters);
32850
32903
  }
32851
32904
  return false;
32852
32905
  }
@@ -32918,7 +32971,7 @@ class ScatterConfigPanel extends GenericChartConfigPanel {
32918
32971
  get canTreatLabelsAsText() {
32919
32972
  const chart = this.env.model.getters.getChart(this.props.figureId);
32920
32973
  if (chart && chart instanceof ScatterChart) {
32921
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
32974
+ return canChartParseLabels(chart, this.env.model.getters);
32922
32975
  }
32923
32976
  return false;
32924
32977
  }
@@ -33547,8 +33600,8 @@ function useDragAndDropListItems() {
33547
33600
  document.body.style.cursor = "move";
33548
33601
  state.draggedItemId = args.draggedItemId;
33549
33602
  const container = direction === "horizontal"
33550
- ? new HorizontalContainer(args.containerEl)
33551
- : new VerticalContainer(args.containerEl);
33603
+ ? new HorizontalContainer(args.scrollableContainerEl)
33604
+ : new VerticalContainer(args.scrollableContainerEl);
33552
33605
  dndHelper = new DOMDndHelper({
33553
33606
  ...args,
33554
33607
  container,
@@ -33559,8 +33612,8 @@ function useDragAndDropListItems() {
33559
33612
  const stopListening = startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
33560
33613
  cleanupFns.push(stopListening);
33561
33614
  const onScroll = dndHelper.onScroll.bind(dndHelper);
33562
- args.containerEl.addEventListener("scroll", onScroll);
33563
- cleanupFns.push(() => args.containerEl.removeEventListener("scroll", onScroll));
33615
+ args.scrollableContainerEl.addEventListener("scroll", onScroll);
33616
+ cleanupFns.push(() => args.scrollableContainerEl.removeEventListener("scroll", onScroll));
33564
33617
  cleanupFns.push(dndHelper.destroy.bind(dndHelper));
33565
33618
  };
33566
33619
  owl.onWillUnmount(() => {
@@ -34008,7 +34061,7 @@ class ConditionalFormatPreviewList extends owl.Component {
34008
34061
  draggedItemId: cf.id,
34009
34062
  initialMousePosition: event.clientY,
34010
34063
  items: items,
34011
- containerEl: this.cfListRef.el,
34064
+ scrollableContainerEl: this.cfListRef.el,
34012
34065
  onDragEnd: (cfId, finalIndex) => this.onDragEnd(cfId, finalIndex),
34013
34066
  });
34014
34067
  }
@@ -34217,7 +34270,7 @@ class ConditionalFormattingEditor extends owl.Component {
34217
34270
  state;
34218
34271
  setup() {
34219
34272
  const cf = this.props.editedCf || {
34220
- id: this.env.model.uuidGenerator.uuidv4(),
34273
+ id: this.env.model.uuidGenerator.smallUuid(),
34221
34274
  ranges: this.env.model.getters
34222
34275
  .getSelectedZones()
34223
34276
  .map((zone) => this.env.model.getters.zoneToXC(this.env.model.getters.getActiveSheetId(), zone)),
@@ -35189,7 +35242,7 @@ class DataValidationEditor extends owl.Component {
35189
35242
  .getSelectedZones()
35190
35243
  .map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
35191
35244
  return {
35192
- id: this.env.model.uuidGenerator.uuidv4(),
35245
+ id: this.env.model.uuidGenerator.smallUuid(),
35193
35246
  criterion: { type: "textContains", values: [""] },
35194
35247
  ranges,
35195
35248
  };
@@ -36020,6 +36073,7 @@ class PivotLayoutConfigurator extends owl.Component {
36020
36073
  unusedMeasureFields: Array,
36021
36074
  unusedDateTimeGranularities: Object,
36022
36075
  allGranularities: Array,
36076
+ getScrollableContainerEl: { type: Function, optional: true },
36023
36077
  };
36024
36078
  dimensionsRef = owl.useRef("pivot-dimensions");
36025
36079
  dragAndDrop = useDragAndDropListItems();
@@ -36048,7 +36102,7 @@ class PivotLayoutConfigurator extends owl.Component {
36048
36102
  draggedItemId: dimension.nameWithGranularity,
36049
36103
  initialMousePosition: event.clientY,
36050
36104
  items: draggableItems,
36051
- containerEl: this.dimensionsRef.el,
36105
+ scrollableContainerEl: this.props.getScrollableContainerEl?.() || this.dimensionsRef.el,
36052
36106
  onDragEnd: (dimensionName, finalIndex) => {
36053
36107
  const originalIndex = draggableIds.findIndex((id) => id === dimensionName);
36054
36108
  if (originalIndex === finalIndex) {
@@ -36088,7 +36142,7 @@ class PivotLayoutConfigurator extends owl.Component {
36088
36142
  draggedItemId: measure.name,
36089
36143
  initialMousePosition: event.clientY,
36090
36144
  items: draggableItems,
36091
- containerEl: this.dimensionsRef.el,
36145
+ scrollableContainerEl: this.props.getScrollableContainerEl?.() || this.dimensionsRef.el,
36092
36146
  onDragEnd: (measureName, finalIndex) => {
36093
36147
  const originalIndex = draggableIds.findIndex((id) => id === measureName);
36094
36148
  if (originalIndex === finalIndex) {
@@ -36307,8 +36361,8 @@ class PivotTitleSection extends owl.Component {
36307
36361
  return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
36308
36362
  }
36309
36363
  duplicatePivot() {
36310
- const newPivotId = this.env.model.uuidGenerator.uuidv4();
36311
- const newSheetId = this.env.model.uuidGenerator.uuidv4();
36364
+ const newPivotId = this.env.model.uuidGenerator.smallUuid();
36365
+ const newSheetId = this.env.model.uuidGenerator.smallUuid();
36312
36366
  const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
36313
36367
  pivotId: this.props.pivotId,
36314
36368
  newPivotId,
@@ -37527,6 +37581,7 @@ class PivotSpreadsheetSidePanel extends owl.Component {
37527
37581
  };
37528
37582
  store;
37529
37583
  state;
37584
+ pivotSidePanelRef = owl.useRef("pivotSidePanel");
37530
37585
  setup() {
37531
37586
  this.store = useLocalStore(PivotSidePanelStore, this.props.pivotId);
37532
37587
  this.state = owl.useState({
@@ -37555,6 +37610,9 @@ class PivotSpreadsheetSidePanel extends owl.Component {
37555
37610
  get definition() {
37556
37611
  return this.store.definition;
37557
37612
  }
37613
+ getScrollableContainerEl() {
37614
+ return this.pivotSidePanelRef.el;
37615
+ }
37558
37616
  onSelectionChanged(ranges) {
37559
37617
  this.state.rangeHasChanged = true;
37560
37618
  this.state.range = ranges[0];
@@ -38633,7 +38691,7 @@ class TableStyleEditorPanel extends owl.Component {
38633
38691
  this.state.selectedTemplateName = templateName;
38634
38692
  }
38635
38693
  onConfirm() {
38636
- const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.uuidv4();
38694
+ const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
38637
38695
  this.env.model.dispatch("CREATE_TABLE_STYLE", {
38638
38696
  tableStyleId,
38639
38697
  tableStyleName: this.state.styleName,
@@ -50914,7 +50972,7 @@ class SheetPlugin extends CorePlugin {
50914
50972
  case "RENAME_SHEET":
50915
50973
  return this.isRenameAllowed(cmd);
50916
50974
  case "DELETE_SHEET":
50917
- return this.orderedSheetIds.length > 1
50975
+ return this.getVisibleSheetIds().length > 1
50918
50976
  ? "Success" /* CommandResult.Success */
50919
50977
  : "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
50920
50978
  case "ADD_COLUMNS_ROWS":
@@ -51771,7 +51829,7 @@ class TablePlugin extends CorePlugin {
51771
51829
  const union = this.getters.getRangesUnion(ranges);
51772
51830
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
51773
51831
  this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
51774
- const id = this.uuidGenerator.uuidv4();
51832
+ const id = this.uuidGenerator.smallUuid();
51775
51833
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
51776
51834
  const newTable = cmd.tableType === "dynamic"
51777
51835
  ? this.createDynamicTable(id, union, config)
@@ -51924,7 +51982,7 @@ class TablePlugin extends CorePlugin {
51924
51982
  filters = [];
51925
51983
  for (const i of range(zone.left, zone.right + 1)) {
51926
51984
  const filterZone = { ...zone, left: i, right: i };
51927
- const uid = this.uuidGenerator.uuidv4();
51985
+ const uid = this.uuidGenerator.smallUuid();
51928
51986
  filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
51929
51987
  }
51930
51988
  }
@@ -51989,7 +52047,7 @@ class TablePlugin extends CorePlugin {
51989
52047
  ? table.filters.find((f) => f.col === i)
51990
52048
  : undefined;
51991
52049
  const filterZone = { ...tableZone, left: i, right: i };
51992
- const filterId = oldFilter?.id || this.uuidGenerator.uuidv4();
52050
+ const filterId = oldFilter?.id || this.uuidGenerator.smallUuid();
51993
52051
  filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
51994
52052
  }
51995
52053
  }
@@ -52090,7 +52148,7 @@ class TablePlugin extends CorePlugin {
52090
52148
  if (filters.length < zoneToDimension(tableZone).numberOfCols) {
52091
52149
  for (let col = tableZone.left; col <= tableZone.right; col++) {
52092
52150
  if (!filters.find((filter) => filter.col === col)) {
52093
- const uid = this.uuidGenerator.uuidv4();
52151
+ const uid = this.uuidGenerator.smallUuid();
52094
52152
  const filterZone = { ...tableZone, left: col, right: col };
52095
52153
  filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
52096
52154
  }
@@ -59039,23 +59097,23 @@ const uuidGenerator = new UuidGenerator();
59039
59097
  function repeatCreateChartCommand(getters, cmd) {
59040
59098
  return {
59041
59099
  ...repeatSheetDependantCommand(getters, cmd),
59042
- id: uuidGenerator.uuidv4(),
59100
+ id: uuidGenerator.smallUuid(),
59043
59101
  };
59044
59102
  }
59045
59103
  function repeatCreateImageCommand(getters, cmd) {
59046
59104
  return {
59047
59105
  ...repeatSheetDependantCommand(getters, cmd),
59048
- figureId: uuidGenerator.uuidv4(),
59106
+ figureId: uuidGenerator.smallUuid(),
59049
59107
  };
59050
59108
  }
59051
59109
  function repeatCreateFigureCommand(getters, cmd) {
59052
59110
  const newCmd = repeatSheetDependantCommand(getters, cmd);
59053
- newCmd.figure.id = uuidGenerator.uuidv4();
59111
+ newCmd.figure.id = uuidGenerator.smallUuid();
59054
59112
  return newCmd;
59055
59113
  }
59056
59114
  function repeatCreateSheetCommand(getters, cmd) {
59057
59115
  const newCmd = deepCopy(cmd);
59058
- newCmd.sheetId = uuidGenerator.uuidv4();
59116
+ newCmd.sheetId = uuidGenerator.smallUuid();
59059
59117
  const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
59060
59118
  // Extract the prefix of the sheet name (everything before the number at the end of the name)
59061
59119
  const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
@@ -60525,23 +60583,7 @@ class GridSelectionPlugin extends UIPlugin {
60525
60583
  gridSelection: deepCopy(gridSelection),
60526
60584
  };
60527
60585
  }
60528
- if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
60529
- const currentSheetIds = this.getters.getVisibleSheetIds();
60530
- this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
60531
- if (this.activeSheet.id in this.sheetsData) {
60532
- const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
60533
- this.selectCell(anchor.cell.col, anchor.cell.row);
60534
- }
60535
- else {
60536
- this.selectCell(0, 0);
60537
- }
60538
- const { col, row } = this.gridSelection.anchor.cell;
60539
- this.moveClient({
60540
- sheetId: this.getters.getActiveSheetId(),
60541
- col,
60542
- row,
60543
- });
60544
- }
60586
+ this.fallbackToVisibleSheet();
60545
60587
  const sheetId = this.getters.getActiveSheetId();
60546
60588
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
60547
60589
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
@@ -60551,6 +60593,7 @@ class GridSelectionPlugin extends UIPlugin {
60551
60593
  }
60552
60594
  }
60553
60595
  finalize() {
60596
+ this.fallbackToVisibleSheet();
60554
60597
  /** Any change to the selection has to be reflected in the selection processor. */
60555
60598
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
60556
60599
  }
@@ -60854,6 +60897,25 @@ class GridSelectionPlugin extends UIPlugin {
60854
60897
  }
60855
60898
  return "Success" /* CommandResult.Success */;
60856
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
+ }
60857
60919
  //-------------------------------------------
60858
60920
  // Helpers for extensions
60859
60921
  // ------------------------------------------
@@ -62833,7 +62895,7 @@ class BottomBar extends owl.Component {
62833
62895
  clickAddSheet(ev) {
62834
62896
  const activeSheetId = this.env.model.getters.getActiveSheetId();
62835
62897
  const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
62836
- const sheetId = this.env.model.uuidGenerator.uuidv4();
62898
+ const sheetId = this.env.model.uuidGenerator.smallUuid();
62837
62899
  const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
62838
62900
  this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
62839
62901
  this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
@@ -62948,7 +63010,7 @@ class BottomBar extends owl.Component {
62948
63010
  draggedItemId: sheetId,
62949
63011
  initialMousePosition: event.clientX,
62950
63012
  items: sheets,
62951
- containerEl: this.sheetListRef.el,
63013
+ scrollableContainerEl: this.sheetListRef.el,
62952
63014
  onDragEnd: (sheetId, finalIndex) => this.onDragEnd(sheetId, finalIndex),
62953
63015
  });
62954
63016
  }
@@ -68391,7 +68453,7 @@ class Model extends EventBus {
68391
68453
  }
68392
68454
  setupConfig(config) {
68393
68455
  const client = config.client || {
68394
- id: this.uuidGenerator.uuidv4(),
68456
+ id: this.uuidGenerator.smallUuid(),
68395
68457
  name: _t("Anonymous").toString(),
68396
68458
  };
68397
68459
  const transportService = config.transportService || new LocalTransportService();
@@ -68910,6 +68972,6 @@ exports.tokenColors = tokenColors;
68910
68972
  exports.tokenize = tokenize;
68911
68973
 
68912
68974
 
68913
- __info__.version = "17.4.21";
68914
- __info__.date = "2025-02-05T06:46:54.366Z";
68915
- __info__.hash = "0c55e18";
68975
+ __info__.version = "17.4.23";
68976
+ __info__.date = "2025-02-14T08:37:12.219Z";
68977
+ __info__.hash = "8339907";