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