@odoo/o-spreadsheet 18.2.0-alpha.7 → 18.2.0

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.2.0-alpha.7
6
- * @date 2025-02-10T09:01:19.353Z
7
- * @hash 0432f17
5
+ * @version 18.2.0
6
+ * @date 2025-02-18T08:27:07.101Z
7
+ * @hash d708714
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -2230,17 +2230,7 @@
2230
2230
  */
2231
2231
  function toUnboundedZone(xc) {
2232
2232
  const zone = toZoneWithoutBoundaryChanges(xc);
2233
- if (zone.right !== undefined && zone.right < zone.left) {
2234
- const tmp = zone.left;
2235
- zone.left = zone.right;
2236
- zone.right = tmp;
2237
- }
2238
- if (zone.bottom !== undefined && zone.bottom < zone.top) {
2239
- const tmp = zone.top;
2240
- zone.top = zone.bottom;
2241
- zone.bottom = tmp;
2242
- }
2243
- return zone;
2233
+ return reorderZone(zone);
2244
2234
  }
2245
2235
  /**
2246
2236
  * Convert from a cartesian reference to a Zone.
@@ -2514,11 +2504,11 @@
2514
2504
  return positions;
2515
2505
  }
2516
2506
  function reorderZone(zone) {
2517
- if (zone.left > zone.right) {
2518
- zone = { left: zone.right, right: zone.left, top: zone.top, bottom: zone.bottom };
2507
+ if (zone.right !== undefined && zone.left > zone.right) {
2508
+ zone = { ...zone, left: zone.right, right: zone.left };
2519
2509
  }
2520
- if (zone.top > zone.bottom) {
2521
- zone = { left: zone.left, right: zone.right, top: zone.bottom, bottom: zone.top };
2510
+ if (zone.bottom !== undefined && zone.top > zone.bottom) {
2511
+ zone = { ...zone, top: zone.bottom, bottom: zone.top };
2522
2512
  }
2523
2513
  return zone;
2524
2514
  }
@@ -3423,12 +3413,12 @@
3423
3413
  function isRangeDependant(cmd) {
3424
3414
  return "ranges" in cmd;
3425
3415
  }
3426
- function isZoneDependent(cmd) {
3427
- return "zone" in cmd;
3428
- }
3429
3416
  function isPositionDependent(cmd) {
3430
3417
  return "col" in cmd && "row" in cmd && "sheetId" in cmd;
3431
3418
  }
3419
+ function isZoneDependent(cmd) {
3420
+ return "sheetId" in cmd && "zone" in cmd;
3421
+ }
3432
3422
  const invalidateEvaluationCommands = new Set([
3433
3423
  "RENAME_SHEET",
3434
3424
  "DELETE_SHEET",
@@ -3440,6 +3430,7 @@
3440
3430
  "REDO",
3441
3431
  "ADD_MERGE",
3442
3432
  "REMOVE_MERGE",
3433
+ "DUPLICATE_SHEET",
3443
3434
  "UPDATE_LOCALE",
3444
3435
  "ADD_PIVOT",
3445
3436
  "UPDATE_PIVOT",
@@ -3469,7 +3460,6 @@
3469
3460
  ]);
3470
3461
  const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
3471
3462
  const invalidateCFEvaluationCommands = new Set([
3472
- "DUPLICATE_SHEET",
3473
3463
  "EVALUATE_CELLS",
3474
3464
  "ADD_CONDITIONAL_FORMAT",
3475
3465
  "REMOVE_CONDITIONAL_FORMAT",
@@ -3639,6 +3629,7 @@
3639
3629
  CommandResult["InvalidRange"] = "InvalidRange";
3640
3630
  CommandResult["InvalidZones"] = "InvalidZones";
3641
3631
  CommandResult["InvalidSheetId"] = "InvalidSheetId";
3632
+ CommandResult["InvalidCellId"] = "InvalidCellId";
3642
3633
  CommandResult["InvalidFigureId"] = "InvalidFigureId";
3643
3634
  CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
3644
3635
  CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
@@ -6489,6 +6480,33 @@
6489
6480
  * https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
6490
6481
  * */
6491
6482
  class UuidGenerator {
6483
+ /**
6484
+ * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
6485
+ * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
6486
+ * it also has a smaller size, which is preferable to alleviate the overall data size.
6487
+ *
6488
+ * This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
6489
+ * as they will appear several times in the revisions and local history.
6490
+ *
6491
+ */
6492
+ smallUuid() {
6493
+ //@ts-ignore
6494
+ if (window.crypto && window.crypto.getRandomValues) {
6495
+ //@ts-ignore
6496
+ return ([1e7] + -1e3).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
6497
+ }
6498
+ else {
6499
+ // mainly for jest and other browsers that do not have the crypto functionality
6500
+ return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
6501
+ const r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
6502
+ return v.toString(16);
6503
+ });
6504
+ }
6505
+ }
6506
+ /**
6507
+ * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
6508
+ * This method should be used when you need to avoid collisions at all costs, like the id of a revision.
6509
+ */
6492
6510
  uuidv4() {
6493
6511
  //@ts-ignore
6494
6512
  if (window.crypto && window.crypto.getRandomValues) {
@@ -8524,7 +8542,7 @@
8524
8542
  };
8525
8543
  }
8526
8544
  getPasteTarget(sheetId, target, content, options) {
8527
- const newId = new UuidGenerator().uuidv4();
8545
+ const newId = new UuidGenerator().smallUuid();
8528
8546
  return { zones: [], figureId: newId, sheetId };
8529
8547
  }
8530
8548
  paste(target, clippedContent, options) {
@@ -8690,7 +8708,7 @@
8690
8708
  if (!targetCF && queuedCfs) {
8691
8709
  targetCF = queuedCfs.find((queued) => queued.cf.stopIfTrue === originCF.stopIfTrue && deepEquals(queued.cf.rule, originCF.rule))?.cf;
8692
8710
  }
8693
- return targetCF || { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
8711
+ return targetCF || { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
8694
8712
  }
8695
8713
  }
8696
8714
 
@@ -8783,7 +8801,7 @@
8783
8801
  }
8784
8802
  return (targetRule || {
8785
8803
  ...originRule,
8786
- id: newId ? this.uuidGenerator.uuidv4() : originRule.id,
8804
+ id: newId ? this.uuidGenerator.smallUuid() : originRule.id,
8787
8805
  ranges: [],
8788
8806
  });
8789
8807
  }
@@ -8845,7 +8863,7 @@
8845
8863
  };
8846
8864
  }
8847
8865
  getPasteTarget(sheetId, target, content, options) {
8848
- const newId = new UuidGenerator().uuidv4();
8866
+ const newId = new UuidGenerator().smallUuid();
8849
8867
  return { sheetId, zones: [], figureId: newId };
8850
8868
  }
8851
8869
  paste(target, clippedContent, options) {
@@ -10180,9 +10198,6 @@ stores.inject(MyMetaStore, storeInstance);
10180
10198
  font-size: 12px;
10181
10199
  background-color: #fff;
10182
10200
  z-index: ${ComponentsImportance.FigureTooltip};
10183
- table td span {
10184
- box-sizing: border-box;
10185
- }
10186
10201
  }
10187
10202
  }
10188
10203
  `;
@@ -12213,6 +12228,25 @@ stores.inject(MyMetaStore, storeInstance);
12213
12228
  isExported: true,
12214
12229
  };
12215
12230
  // -----------------------------------------------------------------------------
12231
+ // LOG
12232
+ // -----------------------------------------------------------------------------
12233
+ const LOG = {
12234
+ description: _t("The logarithm of a number, for a given base."),
12235
+ args: [
12236
+ arg("value (number)", _t("The value for which to calculate the logarithm.")),
12237
+ arg("base (number, default=10)", _t("The base of the logarithm.")),
12238
+ ],
12239
+ compute: function (value, base = { value: 10 }) {
12240
+ const _value = toNumber(value, this.locale);
12241
+ const _base = toNumber(base, this.locale);
12242
+ assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
12243
+ assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
12244
+ assert(() => _base !== 1, _t("The base must be different from 1."));
12245
+ return Math.log10(_value) / Math.log10(_base);
12246
+ },
12247
+ isExported: true,
12248
+ };
12249
+ // -----------------------------------------------------------------------------
12216
12250
  // MOD
12217
12251
  // -----------------------------------------------------------------------------
12218
12252
  function mod(dividend, divisor) {
@@ -12752,6 +12786,7 @@ stores.inject(MyMetaStore, storeInstance);
12752
12786
  ISODD: ISODD,
12753
12787
  ISO_CEILING: ISO_CEILING,
12754
12788
  LN: LN,
12789
+ LOG: LOG,
12755
12790
  MOD: MOD,
12756
12791
  MUNIT: MUNIT,
12757
12792
  ODD: ODD,
@@ -15286,7 +15321,7 @@ stores.inject(MyMetaStore, storeInstance);
15286
15321
  }
15287
15322
  }
15288
15323
  },
15289
- isExported: true,
15324
+ isExported: false,
15290
15325
  };
15291
15326
  // -----------------------------------------------------------------------------
15292
15327
  // UNIQUE
@@ -22874,6 +22909,10 @@ stores.inject(MyMetaStore, storeInstance);
22874
22909
  const DRAWING_NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
22875
22910
  const CONTENT_TYPES = {
22876
22911
  workbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
22912
+ macroEnabledWorkbook: "application/vnd.ms-excel.sheet.macroEnabled.main+xml",
22913
+ templateWorkbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml",
22914
+ macroEnabledTemplateWorkbook: "application/vnd.ms-excel.template.macroEnabled.main+xml",
22915
+ excelAddInWorkbook: "application/vnd.ms-excel.addin.macroEnabled.main+xml",
22877
22916
  sheet: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
22878
22917
  sharedStrings: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
22879
22918
  styles: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
@@ -26945,7 +26984,11 @@ stores.inject(MyMetaStore, storeInstance);
26945
26984
  buildXlsxFileStructure() {
26946
26985
  const xlsxFileStructure = {
26947
26986
  sheets: getXLSXFilesOfType(CONTENT_TYPES.sheet, this.xmls),
26948
- workbook: getXLSXFilesOfType(CONTENT_TYPES.workbook, this.xmls)[0],
26987
+ workbook: getXLSXFilesOfType(CONTENT_TYPES.workbook, this.xmls)[0] ||
26988
+ getXLSXFilesOfType(CONTENT_TYPES.macroEnabledWorkbook, this.xmls)[0] ||
26989
+ getXLSXFilesOfType(CONTENT_TYPES.templateWorkbook, this.xmls)[0] ||
26990
+ getXLSXFilesOfType(CONTENT_TYPES.macroEnabledTemplateWorkbook, this.xmls)[0] ||
26991
+ getXLSXFilesOfType(CONTENT_TYPES.excelAddInWorkbook, this.xmls)[0],
26949
26992
  styles: getXLSXFilesOfType(CONTENT_TYPES.styles, this.xmls)[0],
26950
26993
  sharedStrings: getXLSXFilesOfType(CONTENT_TYPES.sharedStrings, this.xmls)[0],
26951
26994
  theme: getXLSXFilesOfType(CONTENT_TYPES.themes, this.xmls)[0],
@@ -27643,7 +27686,7 @@ stores.inject(MyMetaStore, storeInstance);
27643
27686
  for (const sheet of data.sheets || []) {
27644
27687
  for (const figure of sheet.figures || []) {
27645
27688
  if (figureIds.has(figure.id)) {
27646
- figure.id += uuidGenerator.uuidv4();
27689
+ figure.id += uuidGenerator.smallUuid();
27647
27690
  }
27648
27691
  figureIds.add(figure.id);
27649
27692
  }
@@ -28227,9 +28270,7 @@ stores.inject(MyMetaStore, storeInstance);
28227
28270
  const labelValues = getChartLabelValues(getters, dataSets, labelRange);
28228
28271
  let labels = labelValues.formattedValues;
28229
28272
  let dataSetsValues = getChartDatasetValues(getters, dataSets);
28230
- if (definition.dataSetsHaveTitle &&
28231
- dataSetsValues[0] &&
28232
- labels.length > dataSetsValues[0].data.length) {
28273
+ if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
28233
28274
  labels.shift();
28234
28275
  }
28235
28276
  ({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
@@ -28278,13 +28319,12 @@ stores.inject(MyMetaStore, storeInstance);
28278
28319
  };
28279
28320
  }
28280
28321
  function getLineChartData(definition, dataSets, labelRange, getters) {
28281
- const axisType = getChartAxisType(definition, labelRange, getters);
28322
+ const axisType = getChartAxisType(definition, dataSets, labelRange, getters);
28282
28323
  const labelValues = getChartLabelValues(getters, dataSets, labelRange);
28283
28324
  let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
28284
28325
  let dataSetsValues = getChartDatasetValues(getters, dataSets);
28285
- if (definition.dataSetsHaveTitle &&
28286
- dataSetsValues[0] &&
28287
- labels.length > dataSetsValues[0].data.length) {
28326
+ const removeFirstLabel = shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false);
28327
+ if (removeFirstLabel) {
28288
28328
  labels.shift();
28289
28329
  }
28290
28330
  ({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
@@ -28296,7 +28336,7 @@ stores.inject(MyMetaStore, storeInstance);
28296
28336
  }
28297
28337
  const leftAxisFormat = getChartDatasetFormat(getters, dataSets, "left");
28298
28338
  const rightAxisFormat = getChartDatasetFormat(getters, dataSets, "right");
28299
- const labelsFormat = getChartLabelFormat(getters, labelRange);
28339
+ const labelsFormat = getChartLabelFormat(getters, labelRange, removeFirstLabel);
28300
28340
  const axisFormats = { y: leftAxisFormat, y1: rightAxisFormat, x: labelsFormat };
28301
28341
  const trendDataSetsValues = [];
28302
28342
  for (const index in dataSetsValues) {
@@ -28332,9 +28372,7 @@ stores.inject(MyMetaStore, storeInstance);
28332
28372
  const labelValues = getChartLabelValues(getters, dataSets, labelRange);
28333
28373
  let labels = labelValues.formattedValues;
28334
28374
  let dataSetsValues = getChartDatasetValues(getters, dataSets);
28335
- if (definition.dataSetsHaveTitle &&
28336
- dataSetsValues[0] &&
28337
- labels.length > dataSetsValues[0].data.length) {
28375
+ if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
28338
28376
  labels.shift();
28339
28377
  }
28340
28378
  ({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
@@ -28354,9 +28392,7 @@ stores.inject(MyMetaStore, storeInstance);
28354
28392
  const labelValues = getChartLabelValues(getters, dataSets, labelRange);
28355
28393
  let labels = labelValues.formattedValues;
28356
28394
  let dataSetsValues = getChartDatasetValues(getters, dataSets);
28357
- if (definition.dataSetsHaveTitle &&
28358
- dataSetsValues[0] &&
28359
- labels.length > dataSetsValues[0].data.length) {
28395
+ if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
28360
28396
  labels.shift();
28361
28397
  }
28362
28398
  ({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
@@ -28376,7 +28412,7 @@ stores.inject(MyMetaStore, storeInstance);
28376
28412
  function getGeoChartData(definition, dataSets, labelRange, getters) {
28377
28413
  const labelValues = getChartLabelValues(getters, dataSets, labelRange);
28378
28414
  let labels = labelValues.formattedValues;
28379
- if (definition.dataSetsHaveTitle) {
28415
+ if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
28380
28416
  labels.shift();
28381
28417
  }
28382
28418
  let dataSetsValues = getChartDatasetValues(getters, dataSets);
@@ -28537,36 +28573,41 @@ stores.inject(MyMetaStore, storeInstance);
28537
28573
  }
28538
28574
  return { normalizedLabels, normalizedNewLabels };
28539
28575
  }
28540
- function getChartAxisType(chart, labelRange, getters) {
28541
- if (isDateChart(chart, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
28576
+ function getChartAxisType(definition, dataSets, labelRange, getters) {
28577
+ if (isDateChart(definition, dataSets, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
28542
28578
  return "time";
28543
28579
  }
28544
- if (isLinearChart(chart, labelRange, getters)) {
28580
+ if (isLinearChart(definition, dataSets, labelRange, getters)) {
28545
28581
  return "linear";
28546
28582
  }
28547
28583
  return "category";
28548
28584
  }
28549
- function isDateChart(definition, labelRange, getters) {
28550
- return !definition.labelsAsText && canBeDateChart(labelRange, getters);
28585
+ function isDateChart(definition, dataSets, labelRange, getters) {
28586
+ return !definition.labelsAsText && canBeDateChart(definition, dataSets, labelRange, getters);
28551
28587
  }
28552
- function isLinearChart(definition, labelRange, getters) {
28553
- return !definition.labelsAsText && canBeLinearChart(labelRange, getters);
28588
+ function isLinearChart(definition, dataSets, labelRange, getters) {
28589
+ return !definition.labelsAsText && canBeLinearChart(definition, dataSets, labelRange, getters);
28554
28590
  }
28555
- function canChartParseLabels(labelRange, getters) {
28556
- return canBeDateChart(labelRange, getters) || canBeLinearChart(labelRange, getters);
28591
+ function canChartParseLabels(definition, dataSets, labelRange, getters) {
28592
+ return (canBeDateChart(definition, dataSets, labelRange, getters) ||
28593
+ canBeLinearChart(definition, dataSets, labelRange, getters));
28557
28594
  }
28558
- function canBeDateChart(labelRange, getters) {
28559
- if (!labelRange || !canBeLinearChart(labelRange, getters)) {
28595
+ function canBeDateChart(definition, dataSets, labelRange, getters) {
28596
+ if (!labelRange || !canBeLinearChart(definition, dataSets, labelRange, getters)) {
28560
28597
  return false;
28561
28598
  }
28562
- const labelFormat = getChartLabelFormat(getters, labelRange);
28599
+ const removeFirstLabel = shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false);
28600
+ const labelFormat = getChartLabelFormat(getters, labelRange, removeFirstLabel);
28563
28601
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
28564
28602
  }
28565
- function canBeLinearChart(labelRange, getters) {
28603
+ function canBeLinearChart(definition, dataSets, labelRange, getters) {
28566
28604
  if (!labelRange) {
28567
28605
  return false;
28568
28606
  }
28569
28607
  const labels = getters.getRangeValues(labelRange);
28608
+ if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
28609
+ labels.shift();
28610
+ }
28570
28611
  if (labels.some((label) => isNaN(Number(label)) && label)) {
28571
28612
  return false;
28572
28613
  }
@@ -28675,17 +28716,15 @@ stores.inject(MyMetaStore, storeInstance);
28675
28716
  })),
28676
28717
  };
28677
28718
  }
28678
- function getChartLabelFormat(getters, range) {
28719
+ function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
28679
28720
  if (!range)
28680
28721
  return undefined;
28681
- const { sheetId, zone: { left, top, bottom }, } = range;
28682
- for (let row = top; row <= bottom; row++) {
28683
- const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
28684
- if (format) {
28685
- return format;
28686
- }
28722
+ const { sheetId, zone } = range;
28723
+ const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
28724
+ if (shouldRemoveFirstLabel) {
28725
+ formats.shift();
28687
28726
  }
28688
- return undefined;
28727
+ return formats.find((format) => format !== undefined);
28689
28728
  }
28690
28729
  function getChartLabelValues(getters, dataSets, labelRange) {
28691
28730
  let labels = { values: [], formattedValues: [] };
@@ -28903,7 +28942,7 @@ stores.inject(MyMetaStore, storeInstance);
28903
28942
  const dataset = {
28904
28943
  label,
28905
28944
  data,
28906
- borderColor: BACKGROUND_CHART_COLOR,
28945
+ borderColor: definition.background || "#FFFFFF",
28907
28946
  backgroundColor,
28908
28947
  hoverOffset: 30,
28909
28948
  };
@@ -32592,7 +32631,6 @@ stores.inject(MyMetaStore, storeInstance);
32592
32631
  border-left: 3px solid red;
32593
32632
  padding: 10px;
32594
32633
  width: ${ERROR_TOOLTIP_WIDTH}px;
32595
- box-sizing: border-box !important;
32596
32634
  overflow-wrap: break-word;
32597
32635
 
32598
32636
  .o-error-tooltip-message {
@@ -32675,7 +32713,6 @@ stores.inject(MyMetaStore, storeInstance);
32675
32713
  width: ${CHECKBOX_WIDTH}px;
32676
32714
  height: ${CHECKBOX_WIDTH}px;
32677
32715
  vertical-align: top;
32678
- box-sizing: border-box;
32679
32716
  outline: none;
32680
32717
  border: 1px solid ${GRAY_300};
32681
32718
  cursor: pointer;
@@ -32748,14 +32785,12 @@ stores.inject(MyMetaStore, storeInstance);
32748
32785
  const FILTER_MENU_HEIGHT = 295;
32749
32786
  const CSS = css /* scss */ `
32750
32787
  .o-filter-menu {
32751
- box-sizing: border-box;
32752
32788
  padding: 8px 16px;
32753
32789
  height: ${FILTER_MENU_HEIGHT}px;
32754
32790
  line-height: 1;
32755
32791
 
32756
32792
  .o-filter-menu-item {
32757
32793
  display: flex;
32758
- box-sizing: border-box;
32759
32794
  cursor: pointer;
32760
32795
  user-select: none;
32761
32796
 
@@ -32985,7 +33020,6 @@ stores.inject(MyMetaStore, storeInstance);
32985
33020
  justify-content: space-between;
32986
33021
  height: ${LINK_TOOLTIP_HEIGHT}px;
32987
33022
  width: ${LINK_TOOLTIP_WIDTH}px;
32988
- box-sizing: border-box !important;
32989
33023
 
32990
33024
  img {
32991
33025
  margin-right: 3px;
@@ -33102,7 +33136,7 @@ stores.inject(MyMetaStore, storeInstance);
33102
33136
  const deleteSheet = {
33103
33137
  name: _t("Delete"),
33104
33138
  isVisible: (env) => {
33105
- return env.model.getters.getSheetIds().length > 1;
33139
+ return env.model.getters.getVisibleSheetIds().length > 1;
33106
33140
  },
33107
33141
  execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
33108
33142
  env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
@@ -33113,7 +33147,7 @@ stores.inject(MyMetaStore, storeInstance);
33113
33147
  name: _t("Duplicate"),
33114
33148
  execute: (env) => {
33115
33149
  const sheetIdFrom = env.model.getters.getActiveSheetId();
33116
- const sheetIdTo = env.model.uuidGenerator.uuidv4();
33150
+ const sheetIdTo = env.model.uuidGenerator.smallUuid();
33117
33151
  env.model.dispatch("DUPLICATE_SHEET", {
33118
33152
  sheetId: sheetIdFrom,
33119
33153
  sheetIdTo,
@@ -33402,11 +33436,9 @@ stores.inject(MyMetaStore, storeInstance);
33402
33436
  background-color: white;
33403
33437
  padding: ${MENU_VERTICAL_PADDING}px 0px;
33404
33438
  width: ${MENU_WIDTH}px;
33405
- box-sizing: border-box !important;
33406
33439
  user-select: none;
33407
33440
 
33408
33441
  .o-menu-item {
33409
- box-sizing: border-box;
33410
33442
  height: ${MENU_ITEM_HEIGHT}px;
33411
33443
  padding: ${MENU_ITEM_PADDING_VERTICAL}px ${MENU_ITEM_PADDING_HORIZONTAL}px;
33412
33444
  cursor: pointer;
@@ -33658,7 +33690,7 @@ stores.inject(MyMetaStore, storeInstance);
33658
33690
  const MENU_OFFSET_X = 320;
33659
33691
  const MENU_OFFSET_Y = 100;
33660
33692
  const PADDING = 12;
33661
- const LINK_EDITOR_WIDTH = 340;
33693
+ const LINK_EDITOR_WIDTH = 340 + 2 * PADDING;
33662
33694
  css /* scss */ `
33663
33695
  .o-link-editor {
33664
33696
  font-size: 13px;
@@ -33682,7 +33714,6 @@ stores.inject(MyMetaStore, storeInstance);
33682
33714
  text-align: right;
33683
33715
  }
33684
33716
  input.o-input {
33685
- box-sizing: border-box;
33686
33717
  width: 100%;
33687
33718
  padding: 0 23px 4px 0;
33688
33719
  }
@@ -33910,20 +33941,21 @@ stores.inject(MyMetaStore, storeInstance);
33910
33941
  }
33911
33942
  // Only display legend for several datasets.
33912
33943
  const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
33913
- const labelRange = labelRangeXc ? getters.getRangeFromSheetXC(sheetId, labelRangeXc) : undefined;
33914
- if (canChartParseLabels(labelRange, getters)) {
33915
- return {
33916
- title: {},
33917
- dataSets,
33918
- labelsAsText: false,
33919
- stacked: false,
33920
- aggregated: false,
33921
- cumulative: false,
33922
- labelRange: labelRangeXc,
33923
- type: "line",
33924
- dataSetsHaveTitle,
33925
- legendPosition: newLegendPos,
33926
- };
33944
+ const lineChartDefinition = {
33945
+ title: {},
33946
+ dataSets,
33947
+ labelsAsText: false,
33948
+ stacked: false,
33949
+ aggregated: false,
33950
+ cumulative: false,
33951
+ labelRange: labelRangeXc,
33952
+ type: "line",
33953
+ dataSetsHaveTitle,
33954
+ legendPosition: newLegendPos,
33955
+ };
33956
+ const chart = new LineChart(lineChartDefinition, sheetId, getters);
33957
+ if (canChartParseLabels(lineChartDefinition, chart.dataSets, chart.labelRange, getters)) {
33958
+ return lineChartDefinition;
33927
33959
  }
33928
33960
  const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
33929
33961
  if (singleColumn &&
@@ -34337,7 +34369,7 @@ stores.inject(MyMetaStore, storeInstance);
34337
34369
  //------------------------------------------------------------------------------
34338
34370
  const CREATE_CHART = (env) => {
34339
34371
  const getters = env.model.getters;
34340
- const id = env.model.uuidGenerator.uuidv4();
34372
+ const id = env.model.uuidGenerator.smallUuid();
34341
34373
  const sheetId = getters.getActiveSheetId();
34342
34374
  if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
34343
34375
  env.model.selection.selectTableAroundSelection();
@@ -34360,8 +34392,8 @@ stores.inject(MyMetaStore, storeInstance);
34360
34392
  // Pivots
34361
34393
  //------------------------------------------------------------------------------
34362
34394
  const CREATE_PIVOT = (env) => {
34363
- const pivotId = env.model.uuidGenerator.uuidv4();
34364
- const newSheetId = env.model.uuidGenerator.uuidv4();
34395
+ const pivotId = env.model.uuidGenerator.smallUuid();
34396
+ const newSheetId = env.model.uuidGenerator.smallUuid();
34365
34397
  const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
34366
34398
  if (result.isSuccessful) {
34367
34399
  env.openSidePanel("PivotSidePanel", { pivotId });
@@ -34420,7 +34452,7 @@ stores.inject(MyMetaStore, storeInstance);
34420
34452
  const CREATE_IMAGE = async (env) => {
34421
34453
  if (env.imageProvider) {
34422
34454
  const sheetId = env.model.getters.getActiveSheetId();
34423
- const figureId = env.model.uuidGenerator.uuidv4();
34455
+ const figureId = env.model.uuidGenerator.smallUuid();
34424
34456
  const image = await requestImage(env);
34425
34457
  if (!image) {
34426
34458
  throw new Error("No image provider was given to the environment");
@@ -34973,7 +35005,7 @@ stores.inject(MyMetaStore, storeInstance);
34973
35005
  ranges,
34974
35006
  sheetId,
34975
35007
  rule: {
34976
- id: env.model.uuidGenerator.uuidv4(),
35008
+ id: env.model.uuidGenerator.smallUuid(),
34977
35009
  criterion: {
34978
35010
  type: "isBoolean",
34979
35011
  values: [],
@@ -34989,7 +35021,7 @@ stores.inject(MyMetaStore, storeInstance);
34989
35021
  const zones = env.model.getters.getSelectedZones();
34990
35022
  const sheetId = env.model.getters.getActiveSheetId();
34991
35023
  const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
34992
- const ruleID = env.model.uuidGenerator.uuidv4();
35024
+ const ruleID = env.model.uuidGenerator.smallUuid();
34993
35025
  env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
34994
35026
  ranges,
34995
35027
  sheetId,
@@ -35020,7 +35052,7 @@ stores.inject(MyMetaStore, storeInstance);
35020
35052
  execute: (env) => {
35021
35053
  const activeSheetId = env.model.getters.getActiveSheetId();
35022
35054
  const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
35023
- const sheetId = env.model.uuidGenerator.uuidv4();
35055
+ const sheetId = env.model.uuidGenerator.smallUuid();
35024
35056
  env.model.dispatch("CREATE_SHEET", { sheetId, position });
35025
35057
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
35026
35058
  },
@@ -37998,7 +38030,6 @@ stores.inject(MyMetaStore, storeInstance);
37998
38030
  }
37999
38031
  }
38000
38032
  .o-button {
38001
- height: 28px;
38002
38033
  flex-grow: 0;
38003
38034
  }
38004
38035
 
@@ -38555,8 +38586,8 @@ stores.inject(MyMetaStore, storeInstance);
38555
38586
  }
38556
38587
  }
38557
38588
  .o-color-picker-line-item {
38558
- width: ${ITEM_EDGE_LENGTH}px;
38559
- height: ${ITEM_EDGE_LENGTH}px;
38589
+ width: ${ITEM_EDGE_LENGTH + 2 * ITEM_BORDER_WIDTH}px;
38590
+ height: ${ITEM_EDGE_LENGTH + 2 * ITEM_BORDER_WIDTH}px;
38560
38591
  margin: 0px;
38561
38592
  border-radius: 50px;
38562
38593
  border: ${ITEM_BORDER_WIDTH}px solid #666666;
@@ -38579,7 +38610,6 @@ stores.inject(MyMetaStore, storeInstance);
38579
38610
  font-size: 14px;
38580
38611
  background: white;
38581
38612
  border-radius: 4px;
38582
- box-sizing: border-box;
38583
38613
  &:hover:enabled {
38584
38614
  background-color: rgba(0, 0, 0, 0.08);
38585
38615
  }
@@ -38606,7 +38636,6 @@ stores.inject(MyMetaStore, storeInstance);
38606
38636
  .o-gradient {
38607
38637
  margin-bottom: ${MAGNIFIER_EDGE / 2}px;
38608
38638
  border: ${ITEM_BORDER_WIDTH}px solid #c0c0c0;
38609
- box-sizing: border-box;
38610
38639
  width: ${INNER_GRADIENT_WIDTH + 2 * ITEM_BORDER_WIDTH}px;
38611
38640
  height: ${INNER_GRADIENT_HEIGHT + 2 * ITEM_BORDER_WIDTH}px;
38612
38641
  position: relative;
@@ -38615,7 +38644,6 @@ stores.inject(MyMetaStore, storeInstance);
38615
38644
  .magnifier {
38616
38645
  height: ${MAGNIFIER_EDGE}px;
38617
38646
  width: ${MAGNIFIER_EDGE}px;
38618
- box-sizing: border-box;
38619
38647
  border-radius: 50%;
38620
38648
  border: 2px solid #fff;
38621
38649
  box-shadow: 0px 0px 3px #c0c0c0;
@@ -38630,7 +38658,6 @@ stores.inject(MyMetaStore, storeInstance);
38630
38658
  }
38631
38659
  .o-hue-picker {
38632
38660
  border: ${ITEM_BORDER_WIDTH}px solid #c0c0c0;
38633
- box-sizing: border-box;
38634
38661
  width: 100%;
38635
38662
  height: 12px;
38636
38663
  border-radius: 4px;
@@ -38657,7 +38684,6 @@ stores.inject(MyMetaStore, storeInstance);
38657
38684
  padding: 2px 0px;
38658
38685
  display: flex;
38659
38686
  input {
38660
- box-sizing: border-box;
38661
38687
  width: 50%;
38662
38688
  border-radius: 4px;
38663
38689
  padding: 4px 23px 4px 10px;
@@ -38856,7 +38882,7 @@ stores.inject(MyMetaStore, storeInstance);
38856
38882
  .o-color-picker-button {
38857
38883
  > span {
38858
38884
  border-bottom: 4px solid;
38859
- height: 16px;
38885
+ height: 20px;
38860
38886
  margin-top: 2px;
38861
38887
  display: block;
38862
38888
  }
@@ -38904,7 +38930,7 @@ stores.inject(MyMetaStore, storeInstance);
38904
38930
  .o-font-size-editor {
38905
38931
  height: calc(100% - 4px);
38906
38932
  input.o-font-size {
38907
- outline-color: ${SELECTION_BORDER_COLOR};
38933
+ outline: none;
38908
38934
  height: 20px;
38909
38935
  width: 23px;
38910
38936
  }
@@ -39185,8 +39211,8 @@ stores.inject(MyMetaStore, storeInstance);
39185
39211
  `;
39186
39212
  css /* scss */ `
39187
39213
  .o-round-color-picker-button {
39188
- width: 18px;
39189
- height: 18px;
39214
+ width: 20px;
39215
+ height: 20px;
39190
39216
  cursor: pointer;
39191
39217
  border: 1px solid ${GRAY_300};
39192
39218
  background-position: 1px 1px;
@@ -39333,7 +39359,6 @@ stores.inject(MyMetaStore, storeInstance);
39333
39359
  width: 14px;
39334
39360
  height: 14px;
39335
39361
  border: 1px solid ${GRAY_300};
39336
- box-sizing: border-box;
39337
39362
  outline: none;
39338
39363
  border-radius: 8px;
39339
39364
 
@@ -40049,8 +40074,6 @@ stores.inject(MyMetaStore, storeInstance);
40049
40074
  word-break: break-all;
40050
40075
  padding-right: 2px;
40051
40076
 
40052
- box-sizing: border-box;
40053
-
40054
40077
  caret-color: black;
40055
40078
  padding-left: 3px;
40056
40079
  padding-right: 3px;
@@ -40706,7 +40729,6 @@ stores.inject(MyMetaStore, storeInstance);
40706
40729
  .o-spreadsheet {
40707
40730
  .o-standalone-composer {
40708
40731
  min-height: 24px;
40709
- box-sizing: border-box;
40710
40732
 
40711
40733
  border-bottom: 1px solid;
40712
40734
  border-color: ${GRAY_300};
@@ -40808,7 +40830,6 @@ stores.inject(MyMetaStore, storeInstance);
40808
40830
  }
40809
40831
 
40810
40832
  td {
40811
- box-sizing: border-box;
40812
40833
  height: 30px;
40813
40834
  padding: 6px 0;
40814
40835
  }
@@ -40831,7 +40852,6 @@ stores.inject(MyMetaStore, storeInstance);
40831
40852
  select {
40832
40853
  width: 100%;
40833
40854
  height: 100%;
40834
- box-sizing: border-box;
40835
40855
  }
40836
40856
  }
40837
40857
  `;
@@ -41061,7 +41081,7 @@ stores.inject(MyMetaStore, storeInstance);
41061
41081
  get canTreatLabelsAsText() {
41062
41082
  const chart = this.env.model.getters.getChart(this.props.figureId);
41063
41083
  if (chart && chart instanceof LineChart) {
41064
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
41084
+ return canChartParseLabels(chart.getDefinition(), chart.dataSets, chart.labelRange, this.env.model.getters);
41065
41085
  }
41066
41086
  return false;
41067
41087
  }
@@ -41138,7 +41158,7 @@ stores.inject(MyMetaStore, storeInstance);
41138
41158
  get canTreatLabelsAsText() {
41139
41159
  const chart = this.env.model.getters.getChart(this.props.figureId);
41140
41160
  if (chart && chart instanceof ScatterChart) {
41141
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
41161
+ return canChartParseLabels(chart.getDefinition(), chart.dataSets, chart.labelRange, this.env.model.getters);
41142
41162
  }
41143
41163
  return false;
41144
41164
  }
@@ -41391,7 +41411,6 @@ stores.inject(MyMetaStore, storeInstance);
41391
41411
  }
41392
41412
 
41393
41413
  .o-popover .o-chart-select-popover {
41394
- box-sizing: border-box;
41395
41414
  background: #fff;
41396
41415
  .o-chart-type-item {
41397
41416
  cursor: pointer;
@@ -41691,7 +41710,7 @@ stores.inject(MyMetaStore, storeInstance);
41691
41710
  }
41692
41711
 
41693
41712
  border-bottom: 1px solid ${GRAY_300};
41694
- height: 60px;
41713
+ height: 80px;
41695
41714
  padding: 10px;
41696
41715
  position: relative;
41697
41716
  cursor: pointer;
@@ -42425,7 +42444,7 @@ stores.inject(MyMetaStore, storeInstance);
42425
42444
  this.originalEditedCf = undefined;
42426
42445
  }
42427
42446
  addConditionalFormat() {
42428
- const cfId = this.env.model.uuidGenerator.uuidv4();
42447
+ const cfId = this.env.model.uuidGenerator.smallUuid();
42429
42448
  this.env.model.dispatch("ADD_CONDITIONAL_FORMAT", {
42430
42449
  sheetId: this.activeSheetId,
42431
42450
  ranges: this.env.model.getters
@@ -43695,7 +43714,7 @@ stores.inject(MyMetaStore, storeInstance);
43695
43714
  .getSelectedZones()
43696
43715
  .map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
43697
43716
  return {
43698
- id: this.env.model.uuidGenerator.uuidv4(),
43717
+ id: this.env.model.uuidGenerator.smallUuid(),
43699
43718
  criterion: { type: "textContains", values: [""] },
43700
43719
  ranges,
43701
43720
  };
@@ -43712,7 +43731,6 @@ stores.inject(MyMetaStore, storeInstance);
43712
43731
  .o-sidePanel {
43713
43732
  .o-dv-preview {
43714
43733
  height: 70px;
43715
- box-sizing: border-box;
43716
43734
  cursor: pointer;
43717
43735
  border-bottom: 1px solid ${FIGURE_BORDER_COLOR};
43718
43736
 
@@ -44328,7 +44346,7 @@ stores.inject(MyMetaStore, storeInstance);
44328
44346
  css /* scss */ `
44329
44347
  .o-more-formats-panel {
44330
44348
  .format-preview {
44331
- height: 48px;
44349
+ height: 49px;
44332
44350
  background-color: white;
44333
44351
  cursor: pointer;
44334
44352
 
@@ -44500,7 +44518,6 @@ stores.inject(MyMetaStore, storeInstance);
44500
44518
  .o-sidePanel {
44501
44519
  .o-pivot-measure-display-field,
44502
44520
  .o-pivot-measure-display-value {
44503
- box-sizing: border-box;
44504
44521
  border: solid 1px ${GRAY_300};
44505
44522
  border-radius: 3px;
44506
44523
  }
@@ -44543,7 +44560,7 @@ stores.inject(MyMetaStore, storeInstance);
44543
44560
 
44544
44561
  css /* scss */ `
44545
44562
  .pivot-defer-update {
44546
- min-height: 35px;
44563
+ min-height: 40px;
44547
44564
  }
44548
44565
  `;
44549
44566
  class PivotDeferUpdate extends owl.Component {
@@ -44689,7 +44706,6 @@ stores.inject(MyMetaStore, storeInstance);
44689
44706
  css /* scss */ `
44690
44707
  .o-spreadsheet {
44691
44708
  .os-input {
44692
- box-sizing: border-box;
44693
44709
  border-width: 0 0 1px 0;
44694
44710
  border-color: transparent;
44695
44711
  outline: none;
@@ -45313,8 +45329,8 @@ stores.inject(MyMetaStore, storeInstance);
45313
45329
  return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
45314
45330
  }
45315
45331
  duplicatePivot() {
45316
- const newPivotId = this.env.model.uuidGenerator.uuidv4();
45317
- const newSheetId = this.env.model.uuidGenerator.uuidv4();
45332
+ const newPivotId = this.env.model.uuidGenerator.smallUuid();
45333
+ const newSheetId = this.env.model.uuidGenerator.smallUuid();
45318
45334
  const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
45319
45335
  pivotId: this.props.pivotId,
45320
45336
  newPivotId,
@@ -47658,7 +47674,6 @@ stores.inject(MyMetaStore, storeInstance);
47658
47674
 
47659
47675
  css /* scss */ `
47660
47676
  .o-table-style-picker {
47661
- box-sizing: border-box;
47662
47677
  border: 1px solid ${GRAY_300};
47663
47678
  border-radius: 3px;
47664
47679
 
@@ -47937,7 +47952,7 @@ stores.inject(MyMetaStore, storeInstance);
47937
47952
  this.state.selectedTemplateName = templateName;
47938
47953
  }
47939
47954
  onConfirm() {
47940
- const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.uuidv4();
47955
+ const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
47941
47956
  this.env.model.dispatch("CREATE_TABLE_STYLE", {
47942
47957
  tableStyleId,
47943
47958
  tableStyleName: this.state.styleName,
@@ -48110,7 +48125,6 @@ stores.inject(MyMetaStore, storeInstance);
48110
48125
  const ACTIVE_BORDER_WIDTH = 2;
48111
48126
  css /*SCSS*/ `
48112
48127
  div.o-figure {
48113
- box-sizing: border-box;
48114
48128
  position: absolute;
48115
48129
  width: 100%;
48116
48130
  height: 100%;
@@ -48122,7 +48136,6 @@ stores.inject(MyMetaStore, storeInstance);
48122
48136
  }
48123
48137
 
48124
48138
  div.o-figure-border {
48125
- box-sizing: border-box;
48126
48139
  z-index: 1;
48127
48140
  }
48128
48141
 
@@ -48496,7 +48509,6 @@ stores.inject(MyMetaStore, storeInstance);
48496
48509
  height: ${AUTOFILL_EDGE_LENGTH}px;
48497
48510
  width: ${AUTOFILL_EDGE_LENGTH}px;
48498
48511
  border: 1px solid white;
48499
- box-sizing: border-box !important;
48500
48512
  background-color: #1a73e8;
48501
48513
  }
48502
48514
 
@@ -48873,7 +48885,6 @@ stores.inject(MyMetaStore, storeInstance);
48873
48885
  css /* scss */ `
48874
48886
  div.o-grid-composer {
48875
48887
  z-index: ${ComponentsImportance.GridComposer};
48876
- box-sizing: border-box;
48877
48888
  position: absolute;
48878
48889
  border: ${COMPOSER_BORDER_WIDTH}px solid ${SELECTION_BORDER_COLOR};
48879
48890
  font-family: ${DEFAULT_FONT};
@@ -49122,8 +49133,6 @@ stores.inject(MyMetaStore, storeInstance);
49122
49133
  const MARGIN = (GRID_ICON_EDGE_LENGTH - CHECKBOX_WIDTH) / 2;
49123
49134
  css /* scss */ `
49124
49135
  .o-dv-checkbox {
49125
- box-sizing: border-box !important;
49126
- accent-color: #808080;
49127
49136
  margin: ${MARGIN}px;
49128
49137
  /* required to prevent the checkbox position to be sensible to the font-size (affects Firefox) */
49129
49138
  position: absolute;
@@ -49883,7 +49892,6 @@ stores.inject(MyMetaStore, storeInstance);
49883
49892
  css /* scss */ `
49884
49893
  .o-grid-add-rows {
49885
49894
  input.o-input {
49886
- box-sizing: border-box;
49887
49895
  width: 60px;
49888
49896
  height: 30px;
49889
49897
  }
@@ -51811,6 +51819,7 @@ stores.inject(MyMetaStore, storeInstance);
51811
51819
  background-color: ${BACKGROUND_GRAY_COLOR};
51812
51820
 
51813
51821
  &.corner {
51822
+ box-sizing: content-box;
51814
51823
  right: 0px;
51815
51824
  bottom: 0px;
51816
51825
  height: ${SCROLLBAR_WIDTH}px;
@@ -52046,8 +52055,8 @@ stores.inject(MyMetaStore, storeInstance);
52046
52055
  const COLOR = "#777";
52047
52056
  css /* scss */ `
52048
52057
  .o-table-resizer {
52049
- width: ${SIZE}px;
52050
- height: ${SIZE}px;
52058
+ width: ${SIZE * 2}px;
52059
+ height: ${SIZE * 2}px;
52051
52060
  border-bottom: ${SIZE}px solid ${COLOR};
52052
52061
  border-right: ${SIZE}px solid ${COLOR};
52053
52062
  cursor: nwse-resize;
@@ -53467,6 +53476,10 @@ stores.inject(MyMetaStore, storeInstance);
53467
53476
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
53468
53477
  case "CLEAR_CELL":
53469
53478
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
53479
+ case "UPDATE_CELL_POSITION":
53480
+ return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
53481
+ ? "Success" /* CommandResult.Success */
53482
+ : "InvalidCellId" /* CommandResult.InvalidCellId */;
53470
53483
  default:
53471
53484
  return "Success" /* CommandResult.Success */;
53472
53485
  }
@@ -53511,6 +53524,9 @@ stores.inject(MyMetaStore, storeInstance);
53511
53524
  case "DELETE_CONTENT":
53512
53525
  this.clearZones(cmd.sheetId, cmd.target);
53513
53526
  break;
53527
+ case "DELETE_SHEET": {
53528
+ this.history.update("cells", cmd.sheetId, undefined);
53529
+ }
53514
53530
  }
53515
53531
  }
53516
53532
  clearZones(sheetId, zones) {
@@ -54301,6 +54317,9 @@ stores.inject(MyMetaStore, storeInstance);
54301
54317
  allowDispatch(cmd) {
54302
54318
  switch (cmd.type) {
54303
54319
  case "ADD_CONDITIONAL_FORMAT":
54320
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
54321
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54322
+ }
54304
54323
  return this.checkValidations(cmd, this.checkCFRule, this.checkEmptyRange, this.checkCFHasChanged);
54305
54324
  case "CHANGE_CONDITIONAL_FORMAT_PRIORITY":
54306
54325
  return this.checkValidPriorityChange(cmd.cfId, cmd.delta, cmd.sheetId);
@@ -54717,8 +54736,17 @@ stores.inject(MyMetaStore, storeInstance);
54717
54736
  allowDispatch(cmd) {
54718
54737
  switch (cmd.type) {
54719
54738
  case "ADD_DATA_VALIDATION_RULE":
54739
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
54740
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54741
+ }
54742
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
54743
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54744
+ }
54720
54745
  return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkValidRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
54721
54746
  case "REMOVE_DATA_VALIDATION_RULE":
54747
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
54748
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54749
+ }
54722
54750
  if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
54723
54751
  return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
54724
54752
  }
@@ -54945,6 +54973,7 @@ stores.inject(MyMetaStore, storeInstance);
54945
54973
  class FigurePlugin extends CorePlugin {
54946
54974
  static getters = ["getFigures", "getFigure", "getFigureSheetId"];
54947
54975
  figures = {};
54976
+ insertionOrders = []; // TODO use a list in master
54948
54977
  // ---------------------------------------------------------------------------
54949
54978
  // Command Handling
54950
54979
  // ---------------------------------------------------------------------------
@@ -55047,11 +55076,14 @@ stores.inject(MyMetaStore, storeInstance);
55047
55076
  }
55048
55077
  addFigure(figure, sheetId) {
55049
55078
  this.history.update("figures", sheetId, figure.id, figure);
55079
+ this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
55050
55080
  }
55051
55081
  deleteSheet(sheetId) {
55082
+ this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
55052
55083
  this.history.update("figures", sheetId, undefined);
55053
55084
  }
55054
55085
  removeFigure(id, sheetId) {
55086
+ this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
55055
55087
  this.history.update("figures", sheetId, id, undefined);
55056
55088
  }
55057
55089
  checkFigureExists(sheetId, figureId) {
@@ -55070,7 +55102,14 @@ stores.inject(MyMetaStore, storeInstance);
55070
55102
  // Getters
55071
55103
  // ---------------------------------------------------------------------------
55072
55104
  getFigures(sheetId) {
55073
- return Object.values(this.figures[sheetId] || {}).filter(isDefined);
55105
+ const figures = [];
55106
+ for (const figureId of this.insertionOrders) {
55107
+ const figure = this.figures[sheetId]?.[figureId];
55108
+ if (figure) {
55109
+ figures.push(figure);
55110
+ }
55111
+ }
55112
+ return figures;
55074
55113
  }
55075
55114
  getFigure(sheetId, figureId) {
55076
55115
  return this.figures[sheetId]?.[figureId];
@@ -55083,11 +55122,9 @@ stores.inject(MyMetaStore, storeInstance);
55083
55122
  // ---------------------------------------------------------------------------
55084
55123
  import(data) {
55085
55124
  for (let sheet of data.sheets) {
55086
- const figures = {};
55087
- sheet.figures.forEach((figure) => {
55088
- figures[figure.id] = figure;
55089
- });
55090
- this.figures[sheet.id] = figures;
55125
+ for (const figure of sheet.figures) {
55126
+ this.addFigure(figure, sheet.id);
55127
+ }
55091
55128
  }
55092
55129
  }
55093
55130
  export(data) {
@@ -56547,6 +56584,9 @@ stores.inject(MyMetaStore, storeInstance);
56547
56584
  case "CREATE_SHEET": {
56548
56585
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
56549
56586
  }
56587
+ case "DUPLICATE_SHEET": {
56588
+ return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
56589
+ }
56550
56590
  case "MOVE_SHEET":
56551
56591
  try {
56552
56592
  const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
@@ -56563,7 +56603,7 @@ stores.inject(MyMetaStore, storeInstance);
56563
56603
  ? "Success" /* CommandResult.Success */
56564
56604
  : "InvalidColor" /* CommandResult.InvalidColor */;
56565
56605
  case "DELETE_SHEET":
56566
- return this.orderedSheetIds.length > 1
56606
+ return this.getVisibleSheetIds().length > 1
56567
56607
  ? "Success" /* CommandResult.Success */
56568
56608
  : "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
56569
56609
  case "ADD_COLUMNS_ROWS":
@@ -57349,14 +57389,18 @@ stores.inject(MyMetaStore, storeInstance);
57349
57389
  checkZonesAreInSheet(cmd) {
57350
57390
  if (!("sheetId" in cmd))
57351
57391
  return "Success" /* CommandResult.Success */;
57392
+ if ("ranges" in cmd &&
57393
+ cmd.ranges.some((rangeData) => rangeData._sheetId !== "" && !this.getters.tryGetSheet(rangeData._sheetId))) {
57394
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57395
+ }
57352
57396
  return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
57353
57397
  }
57354
57398
  }
57355
57399
 
57356
- let nextTableId = 1;
57357
57400
  class TablePlugin extends CorePlugin {
57358
57401
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
57359
57402
  tables = {};
57403
+ nextTableId = 1;
57360
57404
  adaptRanges(applyChange, sheetId) {
57361
57405
  const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
57362
57406
  for (const sheetId of sheetIds) {
@@ -57368,6 +57412,9 @@ stores.inject(MyMetaStore, storeInstance);
57368
57412
  allowDispatch(cmd) {
57369
57413
  switch (cmd.type) {
57370
57414
  case "CREATE_TABLE":
57415
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
57416
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57417
+ }
57371
57418
  const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
57372
57419
  if (!areZonesContinuous(zones)) {
57373
57420
  return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
@@ -57421,7 +57468,7 @@ stores.inject(MyMetaStore, storeInstance);
57421
57468
  const union = this.getters.getRangesUnion(ranges);
57422
57469
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
57423
57470
  this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
57424
- const id = `${nextTableId++}`;
57471
+ const id = this.consumeNextId();
57425
57472
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
57426
57473
  const newTable = cmd.tableType === "dynamic"
57427
57474
  ? this.createDynamicTable(id, union, config)
@@ -57574,7 +57621,7 @@ stores.inject(MyMetaStore, storeInstance);
57574
57621
  filters = [];
57575
57622
  for (const i of range(zone.left, zone.right + 1)) {
57576
57623
  const filterZone = { ...zone, left: i, right: i };
57577
- const uid = `${nextTableId++}`;
57624
+ const uid = this.consumeNextId();
57578
57625
  filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
57579
57626
  }
57580
57627
  }
@@ -57639,7 +57686,7 @@ stores.inject(MyMetaStore, storeInstance);
57639
57686
  ? table.filters.find((f) => f.col === i)
57640
57687
  : undefined;
57641
57688
  const filterZone = { ...tableZone, left: i, right: i };
57642
- const filterId = oldFilter?.id || `${nextTableId++}`;
57689
+ const filterId = oldFilter?.id || this.consumeNextId();
57643
57690
  filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
57644
57691
  }
57645
57692
  }
@@ -57740,7 +57787,7 @@ stores.inject(MyMetaStore, storeInstance);
57740
57787
  if (filters.length < zoneToDimension(tableZone).numberOfCols) {
57741
57788
  for (let col = tableZone.left; col <= tableZone.right; col++) {
57742
57789
  if (!filters.find((filter) => filter.col === col)) {
57743
- const uid = `${nextTableId++}`;
57790
+ const uid = this.consumeNextId();
57744
57791
  const filterZone = { ...tableZone, left: col, right: col };
57745
57792
  filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
57746
57793
  }
@@ -57750,13 +57797,18 @@ stores.inject(MyMetaStore, storeInstance);
57750
57797
  const newTable = this.createStaticTable(table.id, table.type, newTableRange, table.config, filters);
57751
57798
  this.history.update("tables", sheetId, table.id, newTable);
57752
57799
  }
57800
+ consumeNextId() {
57801
+ const id = `${this.nextTableId}`;
57802
+ this.history.update("nextTableId", this.nextTableId + 1);
57803
+ return id;
57804
+ }
57753
57805
  // ---------------------------------------------------------------------------
57754
57806
  // Import/Export
57755
57807
  // ---------------------------------------------------------------------------
57756
57808
  import(data) {
57757
57809
  for (const sheet of data.sheets) {
57758
57810
  for (const tableData of sheet.tables || []) {
57759
- const uuid = `${nextTableId++}`;
57811
+ const uuid = this.consumeNextId();
57760
57812
  const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
57761
57813
  const range = this.getters.getRangeFromSheetXC(sheet.id, tableData.range);
57762
57814
  const tableType = tableData.type || "static";
@@ -57804,7 +57856,10 @@ stores.inject(MyMetaStore, storeInstance);
57804
57856
  allowDispatch(cmd) {
57805
57857
  switch (cmd.type) {
57806
57858
  case "GROUP_HEADERS": {
57807
- const { start, end } = cmd;
57859
+ const { start, end, sheetId } = cmd;
57860
+ if (!this.getters.tryGetSheet(sheetId)) {
57861
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57862
+ }
57808
57863
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
57809
57864
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
57810
57865
  }
@@ -57817,7 +57872,10 @@ stores.inject(MyMetaStore, storeInstance);
57817
57872
  break;
57818
57873
  }
57819
57874
  case "UNGROUP_HEADERS": {
57820
- const { start, end } = cmd;
57875
+ const { start, end, sheetId } = cmd;
57876
+ if (!this.getters.tryGetSheet(sheetId)) {
57877
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57878
+ }
57821
57879
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
57822
57880
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
57823
57881
  }
@@ -57828,6 +57886,9 @@ stores.inject(MyMetaStore, storeInstance);
57828
57886
  }
57829
57887
  case "UNFOLD_HEADER_GROUP":
57830
57888
  case "FOLD_HEADER_GROUP":
57889
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
57890
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57891
+ }
57831
57892
  const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
57832
57893
  if (!group) {
57833
57894
  return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
@@ -58228,6 +58289,9 @@ stores.inject(MyMetaStore, storeInstance);
58228
58289
  return this.checkDuplicatedMeasureIds(cmd.pivot);
58229
58290
  }
58230
58291
  case "UPDATE_PIVOT": {
58292
+ if (!(cmd.pivotId in this.pivots)) {
58293
+ return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
58294
+ }
58231
58295
  if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
58232
58296
  return "NoChanges" /* CommandResult.NoChanges */;
58233
58297
  }
@@ -58244,6 +58308,8 @@ stores.inject(MyMetaStore, storeInstance);
58244
58308
  return "EmptyName" /* CommandResult.EmptyName */;
58245
58309
  }
58246
58310
  break;
58311
+ case "REMOVE_PIVOT":
58312
+ case "DUPLICATE_PIVOT":
58247
58313
  case "INSERT_PIVOT": {
58248
58314
  if (!(cmd.pivotId in this.pivots)) {
58249
58315
  return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
@@ -58293,7 +58359,7 @@ stores.inject(MyMetaStore, storeInstance);
58293
58359
  break;
58294
58360
  }
58295
58361
  case "UPDATE_PIVOT": {
58296
- this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
58362
+ this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
58297
58363
  this.compileCalculatedMeasures(cmd.pivot.measures);
58298
58364
  break;
58299
58365
  }
@@ -58364,7 +58430,7 @@ stores.inject(MyMetaStore, storeInstance);
58364
58430
  // Private
58365
58431
  // -------------------------------------------------------------------------
58366
58432
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
58367
- this.history.update("pivots", pivotId, { definition: pivot, formulaId });
58433
+ this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
58368
58434
  this.compileCalculatedMeasures(pivot.measures);
58369
58435
  this.history.update("formulaIds", formulaId, pivotId);
58370
58436
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
@@ -63282,6 +63348,9 @@ stores.inject(MyMetaStore, storeInstance);
63282
63348
  };
63283
63349
  }
63284
63350
  function createSheetTransformation(toTransform, executed) {
63351
+ if (toTransform.sheetId === executed.sheetId) {
63352
+ toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
63353
+ }
63285
63354
  if (toTransform.name === executed.name) {
63286
63355
  return {
63287
63356
  ...toTransform,
@@ -63933,21 +64002,14 @@ stores.inject(MyMetaStore, storeInstance);
63933
64002
  if (!message)
63934
64003
  return;
63935
64004
  if (message.type === "REMOTE_REVISION") {
63936
- const revision = this.revisions.get(message.nextRevisionId);
64005
+ let revision = this.revisions.get(message.nextRevisionId);
63937
64006
  if (revision.commands.length === 0) {
63938
64007
  /**
63939
- * The command is empty, we have to drop all the next local revisions
64008
+ * The command is empty, we have to rebase all the next local revisions
63940
64009
  * to avoid issues with undo/redo
63941
64010
  */
63942
- this.revisions.drop(revision.id);
63943
- const revisionIds = this.pendingMessages
63944
- .filter((message) => message.type === "REMOTE_REVISION")
63945
- .map((message) => message.nextRevisionId);
63946
- this.trigger("pending-revisions-dropped", { revisionIds });
63947
- this.waitingAck = false;
63948
- this.waitingUndoRedoAck = false;
63949
- this.pendingMessages = [];
63950
- return;
64011
+ this.revisions.rebase(revision.id);
64012
+ revision = this.revisions.get(message.nextRevisionId);
63951
64013
  }
63952
64014
  message = {
63953
64015
  ...message,
@@ -63972,7 +64034,6 @@ stores.inject(MyMetaStore, storeInstance);
63972
64034
  switch (message.type) {
63973
64035
  case "REMOTE_REVISION":
63974
64036
  case "REVISION_REDONE":
63975
- case "REVISION_UNDONE":
63976
64037
  case "SNAPSHOT_CREATED":
63977
64038
  this.waitingAck = false;
63978
64039
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
@@ -63981,6 +64042,25 @@ stores.inject(MyMetaStore, storeInstance);
63981
64042
  this.lastRevisionMessage = message;
63982
64043
  this.sendPendingMessage();
63983
64044
  break;
64045
+ case "REVISION_UNDONE": {
64046
+ this.waitingAck = false;
64047
+ this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
64048
+ const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
64049
+ if (firstPendingRevisionId !== -1) {
64050
+ /**
64051
+ * Some revisions undergo transformations that may cause issues with
64052
+ * undo/redo if the transformation is destructive (we don't get back
64053
+ * the original command by transforming it with the inverse).
64054
+ * To prevent these problems, we must rebase all subsequent local
64055
+ * revisions.
64056
+ */
64057
+ this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
64058
+ }
64059
+ this.serverRevisionId = message.nextRevisionId;
64060
+ this.processedRevisions.add(message.nextRevisionId);
64061
+ this.sendPendingMessage();
64062
+ break;
64063
+ }
63984
64064
  }
63985
64065
  }
63986
64066
  isAlreadyProcessed(message) {
@@ -65096,6 +65176,10 @@ stores.inject(MyMetaStore, storeInstance);
65096
65176
  */
65097
65177
  checkZonesAreInSheet(cmd) {
65098
65178
  const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
65179
+ if ("ranges" in cmd &&
65180
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
65181
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
65182
+ }
65099
65183
  const zones = this.getters.getCommandZones(cmd);
65100
65184
  if (!sheetId && zones.length > 0) {
65101
65185
  return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
@@ -65445,23 +65529,23 @@ stores.inject(MyMetaStore, storeInstance);
65445
65529
  function repeatCreateChartCommand(getters, cmd) {
65446
65530
  return {
65447
65531
  ...repeatSheetDependantCommand(getters, cmd),
65448
- id: uuidGenerator.uuidv4(),
65532
+ id: uuidGenerator.smallUuid(),
65449
65533
  };
65450
65534
  }
65451
65535
  function repeatCreateImageCommand(getters, cmd) {
65452
65536
  return {
65453
65537
  ...repeatSheetDependantCommand(getters, cmd),
65454
- figureId: uuidGenerator.uuidv4(),
65538
+ figureId: uuidGenerator.smallUuid(),
65455
65539
  };
65456
65540
  }
65457
65541
  function repeatCreateFigureCommand(getters, cmd) {
65458
65542
  const newCmd = repeatSheetDependantCommand(getters, cmd);
65459
- newCmd.figure.id = uuidGenerator.uuidv4();
65543
+ newCmd.figure.id = uuidGenerator.smallUuid();
65460
65544
  return newCmd;
65461
65545
  }
65462
65546
  function repeatCreateSheetCommand(getters, cmd) {
65463
65547
  const newCmd = deepCopy(cmd);
65464
- newCmd.sheetId = uuidGenerator.uuidv4();
65548
+ newCmd.sheetId = uuidGenerator.smallUuid();
65465
65549
  const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
65466
65550
  // Extract the prefix of the sheet name (everything before the number at the end of the name)
65467
65551
  const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
@@ -65650,7 +65734,6 @@ stores.inject(MyMetaStore, storeInstance);
65650
65734
  super(config);
65651
65735
  this.session = config.session;
65652
65736
  this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
65653
- this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
65654
65737
  this.session.on("snapshot", this, () => {
65655
65738
  this.undoStack = [];
65656
65739
  this.redoStack = [];
@@ -65720,10 +65803,6 @@ stores.inject(MyMetaStore, storeInstance);
65720
65803
  const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
65721
65804
  return canRepeatRevision(lastNonRedoRevision);
65722
65805
  }
65723
- drop(revisionIds) {
65724
- this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
65725
- this.redoStack = [];
65726
- }
65727
65806
  onNewLocalStateUpdate({ id }) {
65728
65807
  this.undoStack.push(id);
65729
65808
  this.redoStack = [];
@@ -66921,23 +67000,7 @@ stores.inject(MyMetaStore, storeInstance);
66921
67000
  gridSelection: deepCopy(gridSelection),
66922
67001
  };
66923
67002
  }
66924
- if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
66925
- const currentSheetIds = this.getters.getVisibleSheetIds();
66926
- this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
66927
- if (this.activeSheet.id in this.sheetsData) {
66928
- const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
66929
- this.selectCell(anchor.cell.col, anchor.cell.row);
66930
- }
66931
- else {
66932
- this.selectCell(0, 0);
66933
- }
66934
- const { col, row } = this.gridSelection.anchor.cell;
66935
- this.moveClient({
66936
- sheetId: this.getters.getActiveSheetId(),
66937
- col,
66938
- row,
66939
- });
66940
- }
67003
+ this.fallbackToVisibleSheet();
66941
67004
  const sheetId = this.getters.getActiveSheetId();
66942
67005
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
66943
67006
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
@@ -66947,6 +67010,7 @@ stores.inject(MyMetaStore, storeInstance);
66947
67010
  }
66948
67011
  }
66949
67012
  finalize() {
67013
+ this.fallbackToVisibleSheet();
66950
67014
  /** Any change to the selection has to be reflected in the selection processor. */
66951
67015
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
66952
67016
  }
@@ -67257,6 +67321,25 @@ stores.inject(MyMetaStore, storeInstance);
67257
67321
  }
67258
67322
  return "Success" /* CommandResult.Success */;
67259
67323
  }
67324
+ fallbackToVisibleSheet() {
67325
+ if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
67326
+ const currentSheetIds = this.getters.getVisibleSheetIds();
67327
+ this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
67328
+ if (this.activeSheet.id in this.sheetsData) {
67329
+ const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
67330
+ this.selectCell(anchor.cell.col, anchor.cell.row);
67331
+ }
67332
+ else {
67333
+ this.selectCell(0, 0);
67334
+ }
67335
+ const { col, row } = this.gridSelection.anchor.cell;
67336
+ this.moveClient({
67337
+ sheetId: this.getters.getActiveSheetId(),
67338
+ col,
67339
+ row,
67340
+ });
67341
+ }
67342
+ }
67260
67343
  //-------------------------------------------
67261
67344
  // Helpers for extensions
67262
67345
  // ------------------------------------------
@@ -68394,7 +68477,9 @@ stores.inject(MyMetaStore, storeInstance);
68394
68477
  case "UNGROUP_HEADERS":
68395
68478
  case "GROUP_HEADERS":
68396
68479
  case "CREATE_SHEET":
68397
- this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
68480
+ if (this.getters.tryGetSheet(cmd.sheetId)) {
68481
+ this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
68482
+ }
68398
68483
  break;
68399
68484
  case "DUPLICATE_SHEET":
68400
68485
  this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
@@ -68402,12 +68487,14 @@ stores.inject(MyMetaStore, storeInstance);
68402
68487
  }
68403
68488
  }
68404
68489
  finalize() {
68405
- if (this.isDirty) {
68406
- for (const sheetId of this.getters.getSheetIds()) {
68490
+ for (const sheetId of this.getters.getSheetIds()) {
68491
+ // sheets can be created without this plugin being aware of it
68492
+ // in concurrent situations.
68493
+ if (this.isDirty || !this.headerPositions[sheetId]) {
68407
68494
  this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
68408
68495
  }
68409
- this.isDirty = false;
68410
68496
  }
68497
+ this.isDirty = false;
68411
68498
  }
68412
68499
  /**
68413
68500
  * Returns the size, start and end coordinates of a column on an unfolded sheet
@@ -69231,7 +69318,7 @@ stores.inject(MyMetaStore, storeInstance);
69231
69318
  clickAddSheet(ev) {
69232
69319
  const activeSheetId = this.env.model.getters.getActiveSheetId();
69233
69320
  const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
69234
- const sheetId = this.env.model.uuidGenerator.uuidv4();
69321
+ const sheetId = this.env.model.uuidGenerator.smallUuid();
69235
69322
  const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
69236
69323
  this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
69237
69324
  this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
@@ -69547,8 +69634,8 @@ stores.inject(MyMetaStore, storeInstance);
69547
69634
  z-index: ${ComponentsImportance.HeaderGroupingButton};
69548
69635
  .o-group-fold-button {
69549
69636
  cursor: pointer;
69550
- width: 13px;
69551
- height: 13px;
69637
+ width: 15px;
69638
+ height: 15px;
69552
69639
  border: 1px solid ${HEADER_GROUPING_BORDER_COLOR};
69553
69640
  .o-icon {
69554
69641
  width: 7px;
@@ -69560,9 +69647,6 @@ stores.inject(MyMetaStore, storeInstance);
69560
69647
  }
69561
69648
  }
69562
69649
  }
69563
- .o-group-border {
69564
- box-sizing: border-box;
69565
- }
69566
69650
  }
69567
69651
  `;
69568
69652
  class AbstractHeaderGroup extends owl.Component {
@@ -69957,7 +70041,7 @@ stores.inject(MyMetaStore, storeInstance);
69957
70041
  margin: 2px 1px;
69958
70042
  padding: 0px 1px;
69959
70043
  border-radius: 2px;
69960
- min-width: 20px;
70044
+ min-width: 22px;
69961
70045
  }
69962
70046
  .o-disabled {
69963
70047
  opacity: 0.6;
@@ -70056,8 +70140,8 @@ stores.inject(MyMetaStore, storeInstance);
70056
70140
  margin: 1px;
70057
70141
  .o-line-item {
70058
70142
  padding: 4px;
70059
- width: 18px;
70060
- height: 18px;
70143
+ width: 26px;
70144
+ height: 26px;
70061
70145
  &.active {
70062
70146
  background-color: ${BUTTON_ACTIVE_BG};
70063
70147
  }
@@ -70251,6 +70335,10 @@ stores.inject(MyMetaStore, storeInstance);
70251
70335
  </svg>
70252
70336
  `;
70253
70337
  css /* scss */ `
70338
+ .o-topbar-composer-container {
70339
+ height: ${TOPBAR_TOOLBAR_HEIGHT}px;
70340
+ }
70341
+
70254
70342
  .o-topbar-composer {
70255
70343
  height: fit-content;
70256
70344
  margin-top: -1px;
@@ -70738,7 +70826,6 @@ stores.inject(MyMetaStore, storeInstance);
70738
70826
  *,
70739
70827
  *:before,
70740
70828
  *:after {
70741
- box-sizing: content-box;
70742
70829
  /* rtl not supported ATM */
70743
70830
  direction: ltr;
70744
70831
  }
@@ -70797,7 +70884,6 @@ stores.inject(MyMetaStore, storeInstance);
70797
70884
  .o-input {
70798
70885
  min-width: 0px;
70799
70886
  padding: 1px 0;
70800
- box-sizing: border-box;
70801
70887
  width: 100%;
70802
70888
  outline: none;
70803
70889
  border-color: ${GRAY_300};
@@ -70868,18 +70954,9 @@ stores.inject(MyMetaStore, storeInstance);
70868
70954
  }
70869
70955
 
70870
70956
  > canvas {
70957
+ box-sizing: content-box;
70871
70958
  border-bottom: 1px solid #e2e3e3;
70872
70959
  }
70873
- .o-scrollbar {
70874
- &.corner {
70875
- right: 0px;
70876
- bottom: 0px;
70877
- height: ${SCROLLBAR_WIDTH}px;
70878
- width: ${SCROLLBAR_WIDTH}px;
70879
- border-top: 1px solid #e2e3e3;
70880
- border-left: 1px solid #e2e3e3;
70881
- }
70882
- }
70883
70960
 
70884
70961
  .o-grid-overlay {
70885
70962
  position: absolute;
@@ -70892,7 +70969,7 @@ stores.inject(MyMetaStore, storeInstance);
70892
70969
  border-radius: 4px;
70893
70970
  font-weight: 500;
70894
70971
  font-size: 14px;
70895
- height: 30px;
70972
+ height: 32px;
70896
70973
  line-height: 16px;
70897
70974
  flex-grow: 1;
70898
70975
  background-color: ${BUTTON_BG};
@@ -71520,7 +71597,7 @@ stores.inject(MyMetaStore, storeInstance);
71520
71597
  }
71521
71598
  /**
71522
71599
  * Drop the operation and all following operations in every
71523
- * branch
71600
+ * branches
71524
71601
  */
71525
71602
  drop(operationId) {
71526
71603
  for (const branch of this.branches) {
@@ -71825,9 +71902,16 @@ stores.inject(MyMetaStore, storeInstance);
71825
71902
  this.fastForward();
71826
71903
  this.insert(redoId, this.buildEmpty(redoId), insertAfter);
71827
71904
  }
71828
- drop(operationId) {
71905
+ rebase(operationId) {
71906
+ const operation = this.get(operationId);
71907
+ const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
71829
71908
  this.revertBefore(operationId);
71909
+ const baseId = this.HEAD_OPERATION.id;
71830
71910
  this.tree.drop(operationId);
71911
+ this.insert(operationId, operation, baseId);
71912
+ for (const { operation } of execution) {
71913
+ this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
71914
+ }
71831
71915
  }
71832
71916
  /**
71833
71917
  * Revert the state as it was *before* the given operation was executed.
@@ -74955,6 +75039,11 @@ stores.inject(MyMetaStore, storeInstance);
74955
75039
  dispatch: (command) => {
74956
75040
  const result = this.checkDispatchAllowed(command);
74957
75041
  if (!result.isSuccessful) {
75042
+ // core views plugins need to be invalidated
75043
+ this.dispatchToHandlers(this.coreHandlers, {
75044
+ type: "UNDO",
75045
+ commands: [command],
75046
+ });
74958
75047
  return;
74959
75048
  }
74960
75049
  this.isReplayingCommand = true;
@@ -74982,7 +75071,7 @@ stores.inject(MyMetaStore, storeInstance);
74982
75071
  }
74983
75072
  setupConfig(config) {
74984
75073
  const client = config.client || {
74985
- id: this.uuidGenerator.uuidv4(),
75074
+ id: this.uuidGenerator.smallUuid(),
74986
75075
  name: _t("Anonymous").toString(),
74987
75076
  };
74988
75077
  const transportService = config.transportService || new LocalTransportService();
@@ -75521,9 +75610,9 @@ stores.inject(MyMetaStore, storeInstance);
75521
75610
  exports.tokenize = tokenize;
75522
75611
 
75523
75612
 
75524
- __info__.version = "18.2.0-alpha.7";
75525
- __info__.date = "2025-02-10T09:01:19.353Z";
75526
- __info__.hash = "0432f17";
75613
+ __info__.version = "18.2.0";
75614
+ __info__.date = "2025-02-18T08:27:07.101Z";
75615
+ __info__.hash = "d708714";
75527
75616
 
75528
75617
 
75529
75618
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);