@odoo/o-spreadsheet 17.0.49 → 17.0.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.0.49
6
- * @date 2025-02-10T08:55:47.771Z
7
- * @hash 1049319
5
+ * @version 17.0.50
6
+ * @date 2025-02-14T08:37:34.289Z
7
+ * @hash cc1037d
8
8
  */
9
9
 
10
10
  'use strict';
@@ -1910,12 +1910,12 @@ function isTargetDependent(cmd) {
1910
1910
  function isRangeDependant(cmd) {
1911
1911
  return "ranges" in cmd;
1912
1912
  }
1913
- function isZoneDependent(cmd) {
1914
- return "zone" in cmd;
1915
- }
1916
1913
  function isPositionDependent(cmd) {
1917
1914
  return "col" in cmd && "row" in cmd && "sheetId" in cmd;
1918
1915
  }
1916
+ function isZoneDependent(cmd) {
1917
+ return "sheetId" in cmd && "zone" in cmd;
1918
+ }
1919
1919
  const invalidateEvaluationCommands = new Set([
1920
1920
  "RENAME_SHEET",
1921
1921
  "DELETE_SHEET",
@@ -1925,6 +1925,7 @@ const invalidateEvaluationCommands = new Set([
1925
1925
  "UNDO",
1926
1926
  "REDO",
1927
1927
  "ADD_MERGE",
1928
+ "DUPLICATE_SHEET",
1928
1929
  "UPDATE_LOCALE",
1929
1930
  ]);
1930
1931
  const invalidateDependenciesCommands = new Set([
@@ -1933,7 +1934,6 @@ const invalidateDependenciesCommands = new Set([
1933
1934
  ]);
1934
1935
  const invalidateCFEvaluationCommands = new Set([
1935
1936
  ...invalidateEvaluationCommands,
1936
- "DUPLICATE_SHEET",
1937
1937
  "EVALUATE_CELLS",
1938
1938
  "ADD_CONDITIONAL_FORMAT",
1939
1939
  "REMOVE_CONDITIONAL_FORMAT",
@@ -2093,6 +2093,7 @@ exports.CommandResult = void 0;
2093
2093
  CommandResult["InvalidRange"] = "InvalidRange";
2094
2094
  CommandResult["InvalidZones"] = "InvalidZones";
2095
2095
  CommandResult["InvalidSheetId"] = "InvalidSheetId";
2096
+ CommandResult["InvalidCellId"] = "InvalidCellId";
2096
2097
  CommandResult["InvalidFigureId"] = "InvalidFigureId";
2097
2098
  CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
2098
2099
  CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
@@ -3673,17 +3674,20 @@ function toZoneWithoutBoundaryChanges(xc) {
3673
3674
  */
3674
3675
  function toUnboundedZone(xc) {
3675
3676
  const zone = toZoneWithoutBoundaryChanges(xc);
3677
+ reorderZone(zone);
3678
+ return zone;
3679
+ }
3680
+ function reorderZone(zone) {
3676
3681
  if (zone.right !== undefined && zone.right < zone.left) {
3677
- const tmp = zone.left;
3682
+ const right = zone.left;
3678
3683
  zone.left = zone.right;
3679
- zone.right = tmp;
3684
+ zone.right = right;
3680
3685
  }
3681
3686
  if (zone.bottom !== undefined && zone.bottom < zone.top) {
3682
- const tmp = zone.top;
3687
+ const bottom = zone.top;
3683
3688
  zone.top = zone.bottom;
3684
- zone.bottom = tmp;
3689
+ zone.bottom = bottom;
3685
3690
  }
3686
- return zone;
3687
3691
  }
3688
3692
  /**
3689
3693
  * Convert from a cartesian reference to a Zone.
@@ -4716,6 +4720,37 @@ class UuidGenerator {
4716
4720
  setIsFastStrategy(isFast) {
4717
4721
  this.isFastIdStrategy = isFast;
4718
4722
  }
4723
+ /**
4724
+ * Generates a custom UUID using a simple 26^8 method (8-character alphanumeric string with lowercase letters)
4725
+ * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
4726
+ * it also has a smaller size, which is preferable to alleviate the overall data size.
4727
+ *
4728
+ * This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
4729
+ * as they will appear several times in the revisions and local history.
4730
+ *
4731
+ */
4732
+ smallUuid() {
4733
+ if (this.isFastIdStrategy) {
4734
+ this.fastIdStart++;
4735
+ return String(this.fastIdStart);
4736
+ //@ts-ignore
4737
+ }
4738
+ else if (window.crypto && window.crypto.getRandomValues) {
4739
+ //@ts-ignore
4740
+ return ([1e7] + -1e3).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
4741
+ }
4742
+ else {
4743
+ // mainly for jest and other browsers that do not have the crypto functionality
4744
+ return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
4745
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
4746
+ return v.toString(16);
4747
+ });
4748
+ }
4749
+ }
4750
+ /**
4751
+ * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
4752
+ * This method should be used when you need to avoid collisions at all costs, like the id of a revision.
4753
+ */
4719
4754
  uuidv4() {
4720
4755
  if (this.isFastIdStrategy) {
4721
4756
  this.fastIdStart++;
@@ -4729,7 +4764,7 @@ class UuidGenerator {
4729
4764
  else {
4730
4765
  // mainly for jest and other browsers that do not have the crypto functionality
4731
4766
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
4732
- var r = (Math.random() * 16) | 0, v = c === "x" ? r : (r & 0x3) | 0x8;
4767
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
4733
4768
  return v.toString(16);
4734
4769
  });
4735
4770
  }
@@ -7942,7 +7977,7 @@ const linkSheet = {
7942
7977
  const deleteSheet = {
7943
7978
  name: _t("Delete"),
7944
7979
  isVisible: (env) => {
7945
- return env.model.getters.getSheetIds().length > 1;
7980
+ return env.model.getters.getVisibleSheetIds().length > 1;
7946
7981
  },
7947
7982
  execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
7948
7983
  env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
@@ -7952,7 +7987,7 @@ const duplicateSheet = {
7952
7987
  name: _t("Duplicate"),
7953
7988
  execute: (env) => {
7954
7989
  const sheetIdFrom = env.model.getters.getActiveSheetId();
7955
- const sheetIdTo = env.model.uuidGenerator.uuidv4();
7990
+ const sheetIdTo = env.model.uuidGenerator.smallUuid();
7956
7991
  env.model.dispatch("DUPLICATE_SHEET", {
7957
7992
  sheetId: sheetIdFrom,
7958
7993
  sheetIdTo,
@@ -8502,17 +8537,15 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
8502
8537
  plugins: [],
8503
8538
  };
8504
8539
  }
8505
- function getChartLabelFormat(getters, range) {
8540
+ function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
8506
8541
  if (!range)
8507
8542
  return undefined;
8508
- const { sheetId, zone: { left, top, bottom }, } = range;
8509
- for (let row = top; row <= bottom; row++) {
8510
- const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
8511
- if (format) {
8512
- return format;
8513
- }
8543
+ const { sheetId, zone } = range;
8544
+ const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
8545
+ if (shouldRemoveFirstLabel) {
8546
+ formats.shift();
8514
8547
  }
8515
- return undefined;
8548
+ return formats.find((format) => format !== undefined);
8516
8549
  }
8517
8550
  function getChartLabelValues(getters, dataSets, labelRange) {
8518
8551
  let labels = { values: [], formattedValues: [] };
@@ -8793,9 +8826,7 @@ function createBarChartRuntime(chart, getters) {
8793
8826
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
8794
8827
  let labels = labelValues.formattedValues;
8795
8828
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
8796
- if (chart.dataSetsHaveTitle &&
8797
- dataSetsValues[0] &&
8798
- labels.length > dataSetsValues[0].data.length) {
8829
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
8799
8830
  labels.shift();
8800
8831
  }
8801
8832
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -9339,8 +9370,8 @@ function fixEmptyLabelsForDateCharts(labels, dataSetsValues) {
9339
9370
  }
9340
9371
  return { labels: newLabels, dataSetsValues: newDatasets };
9341
9372
  }
9342
- function canChartParseLabels(labelRange, getters) {
9343
- return canBeDateChart(labelRange, getters) || canBeLinearChart(labelRange, getters);
9373
+ function canChartParseLabels(chart, getters) {
9374
+ return canBeDateChart(chart, getters) || canBeLinearChart(chart, getters);
9344
9375
  }
9345
9376
  function getChartAxisType(chart, getters) {
9346
9377
  if (isDateChart(chart, getters) && isLuxonTimeAdapterInstalled()) {
@@ -9352,23 +9383,26 @@ function getChartAxisType(chart, getters) {
9352
9383
  return "category";
9353
9384
  }
9354
9385
  function isDateChart(chart, getters) {
9355
- return !chart.labelsAsText && canBeDateChart(chart.labelRange, getters);
9386
+ return !chart.labelsAsText && canBeDateChart(chart, getters);
9356
9387
  }
9357
9388
  function isLinearChart(chart, getters) {
9358
- return !chart.labelsAsText && canBeLinearChart(chart.labelRange, getters);
9389
+ return !chart.labelsAsText && canBeLinearChart(chart, getters);
9359
9390
  }
9360
- function canBeDateChart(labelRange, getters) {
9361
- if (!labelRange || !canBeLinearChart(labelRange, getters)) {
9391
+ function canBeDateChart(chart, getters) {
9392
+ if (!chart.labelRange || !canBeLinearChart(chart, getters)) {
9362
9393
  return false;
9363
9394
  }
9364
- const labelFormat = getChartLabelFormat(getters, labelRange);
9395
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle));
9365
9396
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
9366
9397
  }
9367
- function canBeLinearChart(labelRange, getters) {
9368
- if (!labelRange) {
9398
+ function canBeLinearChart(chart, getters) {
9399
+ if (!chart.labelRange) {
9369
9400
  return false;
9370
9401
  }
9371
- const labels = getters.getRangeValues(labelRange);
9402
+ const labels = getters.getRangeValues(chart.labelRange);
9403
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
9404
+ labels.shift();
9405
+ }
9372
9406
  if (labels.some((label) => isNaN(Number(label)) && label)) {
9373
9407
  return false;
9374
9408
  }
@@ -9442,9 +9476,8 @@ function createLineChartRuntime(chart, getters) {
9442
9476
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
9443
9477
  let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
9444
9478
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
9445
- if (chart.dataSetsHaveTitle &&
9446
- dataSetsValues[0] &&
9447
- labels.length > dataSetsValues[0].data.length) {
9479
+ const removeFirstLabel = shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle);
9480
+ if (removeFirstLabel) {
9448
9481
  labels.shift();
9449
9482
  }
9450
9483
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -9459,7 +9492,7 @@ function createLineChartRuntime(chart, getters) {
9459
9492
  const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
9460
9493
  const options = { format: dataSetFormat, locale, truncateLabels };
9461
9494
  const config = getLineConfiguration(chart, labels, options);
9462
- const labelFormat = getChartLabelFormat(getters, chart.labelRange);
9495
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, removeFirstLabel);
9463
9496
  if (axisType === "time") {
9464
9497
  const axis = {
9465
9498
  type: "time",
@@ -9681,9 +9714,7 @@ function createPieChartRuntime(chart, getters) {
9681
9714
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
9682
9715
  let labels = labelValues.formattedValues;
9683
9716
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
9684
- if (chart.dataSetsHaveTitle &&
9685
- dataSetsValues[0] &&
9686
- labels.length > dataSetsValues[0].data.length) {
9717
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
9687
9718
  labels.shift();
9688
9719
  }
9689
9720
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -10204,21 +10235,22 @@ function getSmartChartDefinition(zone, getters) {
10204
10235
  }
10205
10236
  // Only display legend for several datasets.
10206
10237
  const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
10207
- const labelRange = labelRangeXc ? getters.getRangeFromSheetXC(sheetId, labelRangeXc) : undefined;
10208
- if (canChartParseLabels(labelRange, getters)) {
10209
- return {
10210
- title,
10211
- dataSets,
10212
- labelsAsText: false,
10213
- stacked: false,
10214
- aggregated: false,
10215
- cumulative: false,
10216
- labelRange: labelRangeXc,
10217
- type: "line",
10218
- dataSetsHaveTitle,
10219
- verticalAxisPosition: "left",
10220
- legendPosition: newLegendPos,
10221
- };
10238
+ const lineChartDefinition = {
10239
+ title,
10240
+ dataSets,
10241
+ labelsAsText: false,
10242
+ stacked: false,
10243
+ aggregated: false,
10244
+ cumulative: false,
10245
+ labelRange: labelRangeXc,
10246
+ type: "line",
10247
+ dataSetsHaveTitle,
10248
+ verticalAxisPosition: "left",
10249
+ legendPosition: newLegendPos,
10250
+ };
10251
+ const chart = new LineChart(lineChartDefinition, sheetId, getters);
10252
+ if (canChartParseLabels(chart, getters)) {
10253
+ return lineChartDefinition;
10222
10254
  }
10223
10255
  return {
10224
10256
  title,
@@ -10818,7 +10850,7 @@ const HIDE_ROWS_NAME = (env) => {
10818
10850
  //------------------------------------------------------------------------------
10819
10851
  const CREATE_CHART = (env) => {
10820
10852
  const getters = env.model.getters;
10821
- const id = env.model.uuidGenerator.uuidv4();
10853
+ const id = env.model.uuidGenerator.smallUuid();
10822
10854
  const sheetId = getters.getActiveSheetId();
10823
10855
  if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
10824
10856
  env.model.selection.selectTableAroundSelection();
@@ -10852,7 +10884,7 @@ async function requestImage(env) {
10852
10884
  const CREATE_IMAGE = async (env) => {
10853
10885
  if (env.imageProvider) {
10854
10886
  const sheetId = env.model.getters.getActiveSheetId();
10855
- const figureId = env.model.uuidGenerator.uuidv4();
10887
+ const figureId = env.model.uuidGenerator.smallUuid();
10856
10888
  const image = await requestImage(env);
10857
10889
  if (!image) {
10858
10890
  throw new Error("No image provider was given to the environment");
@@ -12573,6 +12605,26 @@ const LN = {
12573
12605
  isExported: true,
12574
12606
  };
12575
12607
  // -----------------------------------------------------------------------------
12608
+ // LOG
12609
+ // -----------------------------------------------------------------------------
12610
+ const LOG = {
12611
+ description: _t("The logarithm of a number, for a given base."),
12612
+ args: [
12613
+ arg("value (number)", _t("The value for which to calculate the logarithm.")),
12614
+ arg("base (number, default=10)", _t("The base of the logarithm.")),
12615
+ ],
12616
+ returns: ["NUMBER"],
12617
+ compute: function (value, base = 10) {
12618
+ const _value = toNumber(value, this.locale);
12619
+ const _base = toNumber(base, this.locale);
12620
+ assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
12621
+ assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
12622
+ assert(() => _base !== 1, _t("The base must be different from 1."));
12623
+ return Math.log10(_value) / Math.log10(_base);
12624
+ },
12625
+ isExported: true,
12626
+ };
12627
+ // -----------------------------------------------------------------------------
12576
12628
  // MOD
12577
12629
  // -----------------------------------------------------------------------------
12578
12630
  const MOD = {
@@ -13093,6 +13145,7 @@ var math = /*#__PURE__*/Object.freeze({
13093
13145
  ISODD: ISODD,
13094
13146
  ISO_CEILING: ISO_CEILING,
13095
13147
  LN: LN,
13148
+ LOG: LOG,
13096
13149
  MOD: MOD,
13097
13150
  MUNIT: MUNIT,
13098
13151
  ODD: ODD,
@@ -15954,7 +16007,7 @@ const SORTN = {
15954
16007
  }
15955
16008
  }
15956
16009
  },
15957
- isExported: true,
16010
+ isExported: false,
15958
16011
  };
15959
16012
  // -----------------------------------------------------------------------------
15960
16013
  // UNIQUE
@@ -19855,7 +19908,7 @@ const insertSheet = {
19855
19908
  execute: (env) => {
19856
19909
  const activeSheetId = env.model.getters.getActiveSheetId();
19857
19910
  const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
19858
- const sheetId = env.model.uuidGenerator.uuidv4();
19911
+ const sheetId = env.model.uuidGenerator.smallUuid();
19859
19912
  env.model.dispatch("CREATE_SHEET", { sheetId, position });
19860
19913
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
19861
19914
  },
@@ -21531,7 +21584,7 @@ css /* scss */ `
21531
21584
  */
21532
21585
  class SelectionInput extends owl.Component {
21533
21586
  static template = "o-spreadsheet-SelectionInput";
21534
- id = uuidGenerator$1.uuidv4();
21587
+ id = uuidGenerator$1.smallUuid();
21535
21588
  previousRanges = this.props.ranges() || [];
21536
21589
  originSheet = this.env.model.getters.getActiveSheetId();
21537
21590
  state = owl.useState({
@@ -22581,7 +22634,7 @@ class LineConfigPanel extends LineBarPieConfigPanel {
22581
22634
  get canTreatLabelsAsText() {
22582
22635
  const chart = this.env.model.getters.getChart(this.props.figureId);
22583
22636
  if (chart && chart instanceof LineChart) {
22584
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
22637
+ return canChartParseLabels(chart, this.env.model.getters);
22585
22638
  }
22586
22639
  return false;
22587
22640
  }
@@ -23609,7 +23662,7 @@ class ConditionalFormattingEditor extends owl.Component {
23609
23662
  state;
23610
23663
  setup() {
23611
23664
  const cf = this.props.editedCf || {
23612
- id: this.env.model.uuidGenerator.uuidv4(),
23665
+ id: this.env.model.uuidGenerator.smallUuid(),
23613
23666
  ranges: this.env.model.getters
23614
23667
  .getSelectedZones()
23615
23668
  .map((zone) => this.env.model.getters.zoneToXC(this.env.model.getters.getActiveSheetId(), zone)),
@@ -25558,7 +25611,7 @@ class DataValidationEditor extends owl.Component {
25558
25611
  .getSelectedZones()
25559
25612
  .map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
25560
25613
  return {
25561
- id: this.env.model.uuidGenerator.uuidv4(),
25614
+ id: this.env.model.uuidGenerator.smallUuid(),
25562
25615
  criterion: { type: "textContains", values: [""] },
25563
25616
  ranges,
25564
25617
  };
@@ -34178,7 +34231,7 @@ function forceUnicityOfFigure(data) {
34178
34231
  for (const sheet of data.sheets || []) {
34179
34232
  for (const figure of sheet.figures || []) {
34180
34233
  if (figureIds.has(figure.id)) {
34181
- figure.id += uuidGenerator.uuidv4();
34234
+ figure.id += uuidGenerator.smallUuid();
34182
34235
  }
34183
34236
  figureIds.add(figure.id);
34184
34237
  }
@@ -35854,6 +35907,10 @@ class CellPlugin extends CorePlugin {
35854
35907
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
35855
35908
  case "CLEAR_CELL":
35856
35909
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
35910
+ case "UPDATE_CELL_POSITION":
35911
+ return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
35912
+ ? "Success" /* CommandResult.Success */
35913
+ : "InvalidCellId" /* CommandResult.InvalidCellId */;
35857
35914
  default:
35858
35915
  return "Success" /* CommandResult.Success */;
35859
35916
  }
@@ -35895,6 +35952,9 @@ class CellPlugin extends CorePlugin {
35895
35952
  case "CLEAR_CELLS":
35896
35953
  this.clearCells(cmd.sheetId, cmd.target);
35897
35954
  break;
35955
+ case "DELETE_SHEET": {
35956
+ this.history.update("cells", cmd.sheetId, undefined);
35957
+ }
35898
35958
  }
35899
35959
  }
35900
35960
  /**
@@ -36973,8 +37033,14 @@ class DataValidationPlugin extends CorePlugin {
36973
37033
  allowDispatch(cmd) {
36974
37034
  switch (cmd.type) {
36975
37035
  case "ADD_DATA_VALIDATION_RULE":
37036
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
37037
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
37038
+ }
36976
37039
  return this.checkValidations(cmd, this.chainValidations(this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
36977
37040
  case "REMOVE_DATA_VALIDATION_RULE":
37041
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
37042
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
37043
+ }
36978
37044
  if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
36979
37045
  return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
36980
37046
  }
@@ -37148,6 +37214,7 @@ class DataValidationPlugin extends CorePlugin {
37148
37214
  class FigurePlugin extends CorePlugin {
37149
37215
  static getters = ["getFigures", "getFigure", "getFigureSheetId"];
37150
37216
  figures = {};
37217
+ insertionOrders = []; // TODO use a list in master
37151
37218
  // ---------------------------------------------------------------------------
37152
37219
  // Command Handling
37153
37220
  // ---------------------------------------------------------------------------
@@ -37250,11 +37317,14 @@ class FigurePlugin extends CorePlugin {
37250
37317
  }
37251
37318
  addFigure(figure, sheetId) {
37252
37319
  this.history.update("figures", sheetId, figure.id, figure);
37320
+ this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
37253
37321
  }
37254
37322
  deleteSheet(sheetId) {
37323
+ this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
37255
37324
  this.history.update("figures", sheetId, undefined);
37256
37325
  }
37257
37326
  removeFigure(id, sheetId) {
37327
+ this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
37258
37328
  this.history.update("figures", sheetId, id, undefined);
37259
37329
  }
37260
37330
  checkFigureExists(sheetId, figureId) {
@@ -37273,7 +37343,14 @@ class FigurePlugin extends CorePlugin {
37273
37343
  // Getters
37274
37344
  // ---------------------------------------------------------------------------
37275
37345
  getFigures(sheetId) {
37276
- return Object.values(this.figures[sheetId] || {}).filter(isDefined$1);
37346
+ const figures = [];
37347
+ for (const figureId of this.insertionOrders) {
37348
+ const figure = this.figures[sheetId]?.[figureId];
37349
+ if (figure) {
37350
+ figures.push(figure);
37351
+ }
37352
+ }
37353
+ return figures;
37277
37354
  }
37278
37355
  getFigure(sheetId, figureId) {
37279
37356
  return this.figures[sheetId]?.[figureId];
@@ -37286,11 +37363,9 @@ class FigurePlugin extends CorePlugin {
37286
37363
  // ---------------------------------------------------------------------------
37287
37364
  import(data) {
37288
37365
  for (let sheet of data.sheets) {
37289
- const figures = {};
37290
- sheet.figures.forEach((figure) => {
37291
- figures[figure.id] = figure;
37292
- });
37293
- this.figures[sheet.id] = figures;
37366
+ for (const figure of sheet.figures) {
37367
+ this.addFigure(figure, sheet.id);
37368
+ }
37294
37369
  }
37295
37370
  }
37296
37371
  export(data) {
@@ -37314,10 +37389,10 @@ class FilterTable {
37314
37389
  this.filters = [];
37315
37390
  this.zone = zone;
37316
37391
  const uuid = new UuidGenerator();
37317
- this.id = uuid.uuidv4();
37392
+ this.id = uuid.smallUuid();
37318
37393
  for (const i of range(zone.left, zone.right + 1)) {
37319
37394
  const filterZone = { ...this.zone, left: i, right: i };
37320
- this.filters.push(new Filter(uuid.uuidv4(), filterZone));
37395
+ this.filters.push(new Filter(uuid.smallUuid(), filterZone));
37321
37396
  }
37322
37397
  }
37323
37398
  /** Get zone of the table without the headers */
@@ -37519,7 +37594,7 @@ class FiltersPlugin extends CorePlugin {
37519
37594
  if (filters.length < zoneToDimension(zone).numberOfCols) {
37520
37595
  for (let col = zone.left; col <= zone.right; col++) {
37521
37596
  if (!filters.find((filter) => filter.col === col)) {
37522
- filters.push(new Filter(this.uuidGenerator.uuidv4(), { ...zone, left: col, right: col }));
37597
+ filters.push(new Filter(this.uuidGenerator.smallUuid(), { ...zone, left: col, right: col }));
37523
37598
  }
37524
37599
  }
37525
37600
  filters.sort((f1, f2) => f1.col - f2.col);
@@ -39008,6 +39083,9 @@ class SheetPlugin extends CorePlugin {
39008
39083
  case "CREATE_SHEET": {
39009
39084
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
39010
39085
  }
39086
+ case "DUPLICATE_SHEET": {
39087
+ return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
39088
+ }
39011
39089
  case "MOVE_SHEET":
39012
39090
  try {
39013
39091
  const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
@@ -39020,7 +39098,7 @@ class SheetPlugin extends CorePlugin {
39020
39098
  case "RENAME_SHEET":
39021
39099
  return this.isRenameAllowed(cmd);
39022
39100
  case "DELETE_SHEET":
39023
- return this.orderedSheetIds.length > 1
39101
+ return this.getVisibleSheetIds().length > 1
39024
39102
  ? "Success" /* CommandResult.Success */
39025
39103
  : "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
39026
39104
  case "ADD_COLUMNS_ROWS":
@@ -39833,6 +39911,10 @@ class SheetPlugin extends CorePlugin {
39833
39911
  checkZonesAreInSheet(cmd) {
39834
39912
  if (!("sheetId" in cmd))
39835
39913
  return "Success" /* CommandResult.Success */;
39914
+ if ("ranges" in cmd &&
39915
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
39916
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
39917
+ }
39836
39918
  return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
39837
39919
  }
39838
39920
  }
@@ -39852,7 +39934,10 @@ class HeaderGroupingPlugin extends CorePlugin {
39852
39934
  allowDispatch(cmd) {
39853
39935
  switch (cmd.type) {
39854
39936
  case "GROUP_HEADERS": {
39855
- const { start, end } = cmd;
39937
+ const { start, end, sheetId } = cmd;
39938
+ if (!this.getters.tryGetSheet(sheetId)) {
39939
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
39940
+ }
39856
39941
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
39857
39942
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
39858
39943
  }
@@ -39865,7 +39950,10 @@ class HeaderGroupingPlugin extends CorePlugin {
39865
39950
  break;
39866
39951
  }
39867
39952
  case "UNGROUP_HEADERS": {
39868
- const { start, end } = cmd;
39953
+ const { start, end, sheetId } = cmd;
39954
+ if (!this.getters.tryGetSheet(sheetId)) {
39955
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
39956
+ }
39869
39957
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
39870
39958
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
39871
39959
  }
@@ -39876,6 +39964,9 @@ class HeaderGroupingPlugin extends CorePlugin {
39876
39964
  }
39877
39965
  case "UNFOLD_HEADER_GROUP":
39878
39966
  case "FOLD_HEADER_GROUP":
39967
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
39968
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
39969
+ }
39879
39970
  const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
39880
39971
  if (!group) {
39881
39972
  return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
@@ -44145,6 +44236,9 @@ function updateChartRangesTransformation(toTransform, executed) {
44145
44236
  };
44146
44237
  }
44147
44238
  function createSheetTransformation(toTransform, executed) {
44239
+ if (toTransform.sheetId === executed.sheetId) {
44240
+ toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
44241
+ }
44148
44242
  if (toTransform.name === executed.name) {
44149
44243
  return {
44150
44244
  ...toTransform,
@@ -44781,21 +44875,14 @@ class Session extends EventBus {
44781
44875
  if (!message)
44782
44876
  return;
44783
44877
  if (message.type === "REMOTE_REVISION") {
44784
- const revision = this.revisions.get(message.nextRevisionId);
44878
+ let revision = this.revisions.get(message.nextRevisionId);
44785
44879
  if (revision.commands.length === 0) {
44786
44880
  /**
44787
- * The command is empty, we have to drop all the next local revisions
44881
+ * The command is empty, we have to rebase all the next local revisions
44788
44882
  * to avoid issues with undo/redo
44789
44883
  */
44790
- this.revisions.drop(revision.id);
44791
- const revisionIds = this.pendingMessages
44792
- .filter((message) => message.type === "REMOTE_REVISION")
44793
- .map((message) => message.nextRevisionId);
44794
- this.trigger("pending-revisions-dropped", { revisionIds });
44795
- this.waitingAck = false;
44796
- this.waitingUndoRedoAck = false;
44797
- this.pendingMessages = [];
44798
- return;
44884
+ this.revisions.rebase(revision.id);
44885
+ revision = this.revisions.get(message.nextRevisionId);
44799
44886
  }
44800
44887
  message = {
44801
44888
  ...message,
@@ -44819,7 +44906,6 @@ class Session extends EventBus {
44819
44906
  switch (message.type) {
44820
44907
  case "REMOTE_REVISION":
44821
44908
  case "REVISION_REDONE":
44822
- case "REVISION_UNDONE":
44823
44909
  case "SNAPSHOT_CREATED":
44824
44910
  this.waitingAck = false;
44825
44911
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
@@ -44827,6 +44913,25 @@ class Session extends EventBus {
44827
44913
  this.processedRevisions.add(message.nextRevisionId);
44828
44914
  this.sendPendingMessage();
44829
44915
  break;
44916
+ case "REVISION_UNDONE": {
44917
+ this.waitingAck = false;
44918
+ this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
44919
+ const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
44920
+ if (firstPendingRevisionId !== -1) {
44921
+ /**
44922
+ * Some revisions undergo transformations that may cause issues with
44923
+ * undo/redo if the transformation is destructive (we don't get back
44924
+ * the original command by transforming it with the inverse).
44925
+ * To prevent these problems, we must rebase all subsequent local
44926
+ * revisions.
44927
+ */
44928
+ this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
44929
+ }
44930
+ this.serverRevisionId = message.nextRevisionId;
44931
+ this.processedRevisions.add(message.nextRevisionId);
44932
+ this.sendPendingMessage();
44933
+ break;
44934
+ }
44830
44935
  }
44831
44936
  }
44832
44937
  isAlreadyProcessed(message) {
@@ -45531,7 +45636,9 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
45531
45636
  const cfInTarget = this.getters
45532
45637
  .getConditionalFormats(targetSheetId)
45533
45638
  .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
45534
- return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
45639
+ return cfInTarget
45640
+ ? cfInTarget
45641
+ : { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
45535
45642
  }
45536
45643
  pasteDataValidation(origin, target) {
45537
45644
  const rule = this.getters.getValidationRuleForCell(origin);
@@ -45563,7 +45670,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
45563
45670
  originRule.isBlocking === rule.isBlocking);
45564
45671
  return ruleInTargetSheet
45565
45672
  ? ruleInTargetSheet
45566
- : { ...originRule, id: this.uuidGenerator.uuidv4(), ranges: [] };
45673
+ : { ...originRule, id: this.uuidGenerator.smallUuid(), ranges: [] };
45567
45674
  }
45568
45675
  /**
45569
45676
  * Add or remove XCs to a given data validation rule.
@@ -47755,6 +47862,10 @@ class SheetUIPlugin extends UIPlugin {
47755
47862
  */
47756
47863
  checkZonesAreInSheet(cmd) {
47757
47864
  const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
47865
+ if ("ranges" in cmd &&
47866
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
47867
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
47868
+ }
47758
47869
  const zones = this.getters.getCommandZones(cmd);
47759
47870
  if (!sheetId && zones.length > 0) {
47760
47871
  return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
@@ -47803,23 +47914,23 @@ const uuidGenerator = new UuidGenerator();
47803
47914
  function repeatCreateChartCommand(getters, cmd) {
47804
47915
  return {
47805
47916
  ...repeatSheetDependantCommand(getters, cmd),
47806
- id: uuidGenerator.uuidv4(),
47917
+ id: uuidGenerator.smallUuid(),
47807
47918
  };
47808
47919
  }
47809
47920
  function repeatCreateImageCommand(getters, cmd) {
47810
47921
  return {
47811
47922
  ...repeatSheetDependantCommand(getters, cmd),
47812
- figureId: uuidGenerator.uuidv4(),
47923
+ figureId: uuidGenerator.smallUuid(),
47813
47924
  };
47814
47925
  }
47815
47926
  function repeatCreateFigureCommand(getters, cmd) {
47816
47927
  const newCmd = repeatSheetDependantCommand(getters, cmd);
47817
- newCmd.figure.id = uuidGenerator.uuidv4();
47928
+ newCmd.figure.id = uuidGenerator.smallUuid();
47818
47929
  return newCmd;
47819
47930
  }
47820
47931
  function repeatCreateSheetCommand(getters, cmd) {
47821
47932
  const newCmd = deepCopy(cmd);
47822
- newCmd.sheetId = uuidGenerator.uuidv4();
47933
+ newCmd.sheetId = uuidGenerator.smallUuid();
47823
47934
  const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
47824
47935
  // Extract the prefix of the sheet name (everything before the number at the end of the name)
47825
47936
  const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
@@ -48014,7 +48125,6 @@ class HistoryPlugin extends UIPlugin {
48014
48125
  super(config);
48015
48126
  this.session = config.session;
48016
48127
  this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
48017
- this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
48018
48128
  this.session.on("snapshot", this, () => {
48019
48129
  this.undoStack = [];
48020
48130
  this.redoStack = [];
@@ -48084,10 +48194,6 @@ class HistoryPlugin extends UIPlugin {
48084
48194
  const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
48085
48195
  return canRepeatRevision(lastNonRedoRevision);
48086
48196
  }
48087
- drop(revisionIds) {
48088
- this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
48089
- this.redoStack = [];
48090
- }
48091
48197
  onNewLocalStateUpdate({ id }) {
48092
48198
  this.undoStack.push(id);
48093
48199
  this.redoStack = [];
@@ -48354,7 +48460,7 @@ class ClipboardFigureState {
48354
48460
  x: maxX < width ? 0 : Math.min(targetX, maxX - width),
48355
48461
  y: maxY < height ? 0 : Math.min(targetY, maxY - height),
48356
48462
  };
48357
- const newId = new UuidGenerator().uuidv4();
48463
+ const newId = new UuidGenerator().smallUuid();
48358
48464
  this.copiedFigureContent.paste(sheetId, newId, position, { height, width });
48359
48465
  if (this.operation === "CUT") {
48360
48466
  this.dispatch("DELETE_FIGURE", {
@@ -50057,23 +50163,7 @@ class GridSelectionPlugin extends UIPlugin {
50057
50163
  gridSelection: deepCopy(gridSelection),
50058
50164
  };
50059
50165
  }
50060
- if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
50061
- const currentSheetIds = this.getters.getVisibleSheetIds();
50062
- this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
50063
- if (this.activeSheet.id in this.sheetsData) {
50064
- const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
50065
- this.selectCell(anchor.cell.col, anchor.cell.row);
50066
- }
50067
- else {
50068
- this.selectCell(0, 0);
50069
- }
50070
- const { col, row } = this.gridSelection.anchor.cell;
50071
- this.moveClient({
50072
- sheetId: this.getters.getActiveSheetId(),
50073
- col,
50074
- row,
50075
- });
50076
- }
50166
+ this.fallbackToVisibleSheet();
50077
50167
  const sheetId = this.getters.getActiveSheetId();
50078
50168
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
50079
50169
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
@@ -50083,6 +50173,7 @@ class GridSelectionPlugin extends UIPlugin {
50083
50173
  }
50084
50174
  }
50085
50175
  finalize() {
50176
+ this.fallbackToVisibleSheet();
50086
50177
  /** Any change to the selection has to be reflected in the selection processor. */
50087
50178
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
50088
50179
  }
@@ -50434,6 +50525,25 @@ class GridSelectionPlugin extends UIPlugin {
50434
50525
  }
50435
50526
  return "Success" /* CommandResult.Success */;
50436
50527
  }
50528
+ fallbackToVisibleSheet() {
50529
+ if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
50530
+ const currentSheetIds = this.getters.getVisibleSheetIds();
50531
+ this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
50532
+ if (this.activeSheet.id in this.sheetsData) {
50533
+ const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
50534
+ this.selectCell(anchor.cell.col, anchor.cell.row);
50535
+ }
50536
+ else {
50537
+ this.selectCell(0, 0);
50538
+ }
50539
+ const { col, row } = this.gridSelection.anchor.cell;
50540
+ this.moveClient({
50541
+ sheetId: this.getters.getActiveSheetId(),
50542
+ col,
50543
+ row,
50544
+ });
50545
+ }
50546
+ }
50437
50547
  //-------------------------------------------
50438
50548
  // Helpers for extensions
50439
50549
  // ------------------------------------------
@@ -51581,7 +51691,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
51581
51691
  case "UNGROUP_HEADERS":
51582
51692
  case "GROUP_HEADERS":
51583
51693
  case "CREATE_SHEET":
51584
- this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
51694
+ if (this.getters.tryGetSheet(cmd.sheetId)) {
51695
+ this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
51696
+ }
51585
51697
  break;
51586
51698
  case "DUPLICATE_SHEET":
51587
51699
  this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
@@ -51589,12 +51701,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
51589
51701
  }
51590
51702
  }
51591
51703
  finalize() {
51592
- if (this.isDirty) {
51593
- for (const sheetId of this.getters.getSheetIds()) {
51704
+ for (const sheetId of this.getters.getSheetIds()) {
51705
+ // sheets can be created without this plugin being aware of it
51706
+ // in concurrent situations.
51707
+ if (this.isDirty || !this.headerPositions[sheetId]) {
51594
51708
  this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
51595
51709
  }
51596
- this.isDirty = false;
51597
51710
  }
51711
+ this.isDirty = false;
51598
51712
  }
51599
51713
  /**
51600
51714
  * Returns the size, start and end coordinates of a column on an unfolded sheet
@@ -52278,7 +52392,7 @@ class BottomBar extends owl.Component {
52278
52392
  clickAddSheet(ev) {
52279
52393
  const activeSheetId = this.env.model.getters.getActiveSheetId();
52280
52394
  const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
52281
- const sheetId = this.env.model.uuidGenerator.uuidv4();
52395
+ const sheetId = this.env.model.uuidGenerator.smallUuid();
52282
52396
  const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
52283
52397
  this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
52284
52398
  this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
@@ -53340,7 +53454,7 @@ css /* scss */ `
53340
53454
  .o-font-size-editor {
53341
53455
  height: calc(100% - 4px);
53342
53456
  input.o-font-size {
53343
- outline-color: ${SELECTION_BORDER_COLOR};
53457
+ outline: none;
53344
53458
  height: 20px;
53345
53459
  width: 23px;
53346
53460
  }
@@ -54515,7 +54629,7 @@ class Tree {
54515
54629
  }
54516
54630
  /**
54517
54631
  * Drop the operation and all following operations in every
54518
- * branch
54632
+ * branches
54519
54633
  */
54520
54634
  drop(operationId) {
54521
54635
  for (const branch of this.branches) {
@@ -54820,9 +54934,16 @@ class SelectiveHistory {
54820
54934
  this.fastForward();
54821
54935
  this.insert(redoId, this.buildEmpty(redoId), insertAfter);
54822
54936
  }
54823
- drop(operationId) {
54937
+ rebase(operationId) {
54938
+ const operation = this.get(operationId);
54939
+ const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
54824
54940
  this.revertBefore(operationId);
54941
+ const baseId = this.HEAD_OPERATION.id;
54825
54942
  this.tree.drop(operationId);
54943
+ this.insert(operationId, operation, baseId);
54944
+ for (const { operation } of execution) {
54945
+ this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
54946
+ }
54826
54947
  }
54827
54948
  getRevertedExecution() {
54828
54949
  const data = [];
@@ -57399,6 +57520,11 @@ class Model extends EventBus {
57399
57520
  dispatch: (command) => {
57400
57521
  const result = this.checkDispatchAllowed(command);
57401
57522
  if (!result.isSuccessful) {
57523
+ // core views plugins need to be invalidated
57524
+ this.dispatchToHandlers(this.coreHandlers, {
57525
+ type: "UNDO",
57526
+ commands: [command],
57527
+ });
57402
57528
  return;
57403
57529
  }
57404
57530
  this.isReplayingCommand = true;
@@ -57427,7 +57553,7 @@ class Model extends EventBus {
57427
57553
  }
57428
57554
  setupConfig(config) {
57429
57555
  const client = config.client || {
57430
- id: this.uuidGenerator.uuidv4(),
57556
+ id: this.uuidGenerator.smallUuid(),
57431
57557
  name: _t("Anonymous").toString(),
57432
57558
  };
57433
57559
  const transportService = config.transportService || new LocalTransportService();
@@ -57848,6 +57974,6 @@ exports.setTranslationMethod = setTranslationMethod;
57848
57974
  exports.tokenize = tokenize;
57849
57975
 
57850
57976
 
57851
- __info__.version = "17.0.49";
57852
- __info__.date = "2025-02-10T08:55:47.771Z";
57853
- __info__.hash = "1049319";
57977
+ __info__.version = "17.0.50";
57978
+ __info__.date = "2025-02-14T08:37:34.289Z";
57979
+ __info__.hash = "cc1037d";