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