@odoo/o-spreadsheet 18.0.25 → 18.0.27

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.0.25
6
- * @date 2025-04-25T08:08:43.377Z
7
- * @hash 24aac2c
5
+ * @version 18.0.27
6
+ * @date 2025-05-12T05:25:47.149Z
7
+ * @hash 9b36340
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -3592,6 +3592,7 @@
3592
3592
  CommandResult["ValueCellIsInvalidFormula"] = "ValueCellIsInvalidFormula";
3593
3593
  CommandResult["InvalidDefinition"] = "InvalidDefinition";
3594
3594
  CommandResult["InvalidColor"] = "InvalidColor";
3595
+ CommandResult["InvalidPivotDataSet"] = "InvalidPivotDataSet";
3595
3596
  })(exports.CommandResult || (exports.CommandResult = {}));
3596
3597
 
3597
3598
  const DEFAULT_LOCALES = [
@@ -6102,6 +6103,25 @@
6102
6103
  })
6103
6104
  .filter(isDefined);
6104
6105
  }
6106
+ function getNextSheetName(existingNames, baseName = "Sheet") {
6107
+ let i = 1;
6108
+ let name = `${baseName}${i}`;
6109
+ while (existingNames.includes(name)) {
6110
+ name = `${baseName}${i}`;
6111
+ i++;
6112
+ }
6113
+ return name;
6114
+ }
6115
+ function getDuplicateSheetName(nameToDuplicate, existingNames) {
6116
+ let i = 1;
6117
+ const baseName = _t("Copy of %s", nameToDuplicate);
6118
+ let name = baseName.toString();
6119
+ while (existingNames.includes(name)) {
6120
+ name = `${baseName} (${i})`;
6121
+ i++;
6122
+ }
6123
+ return name;
6124
+ }
6105
6125
 
6106
6126
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
6107
6127
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -7790,6 +7810,24 @@
7790
7810
  return `${normalizedValue}`;
7791
7811
  },
7792
7812
  };
7813
+ /**
7814
+ * normalizes month number + year
7815
+ */
7816
+ const monthAdapter = {
7817
+ normalizeFunctionValue(value) {
7818
+ const date = toNumber(value, DEFAULT_LOCALE);
7819
+ return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
7820
+ },
7821
+ toValueAndFormat(normalizedValue) {
7822
+ return {
7823
+ value: toNumber(normalizedValue, DEFAULT_LOCALE),
7824
+ format: "mmmm yyyy",
7825
+ };
7826
+ },
7827
+ toFunctionValue(normalizedValue) {
7828
+ return `"${normalizedValue}"`;
7829
+ },
7830
+ };
7793
7831
  /**
7794
7832
  * normalizes quarter number
7795
7833
  */
@@ -7920,6 +7958,7 @@
7920
7958
  .add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
7921
7959
  .add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
7922
7960
  .add("month_number", nullHandlerDecorator(monthNumberAdapter))
7961
+ .add("month", nullHandlerDecorator(monthAdapter))
7923
7962
  .add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
7924
7963
  .add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
7925
7964
  .add("hour_number", nullHandlerDecorator(hourNumberAdapter))
@@ -8100,10 +8139,7 @@
8100
8139
  return normalizer(groupValueString, dimension.granularity);
8101
8140
  }
8102
8141
  function normalizeDateTime(value, granularity) {
8103
- if (!granularity) {
8104
- throw new Error("Missing granularity");
8105
- }
8106
- return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
8142
+ return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
8107
8143
  }
8108
8144
  function toFunctionPivotValue(value, dimension) {
8109
8145
  if (value === null) {
@@ -8115,10 +8151,7 @@
8115
8151
  return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
8116
8152
  }
8117
8153
  function toFunctionValueDateTime(value, granularity) {
8118
- if (!granularity) {
8119
- throw new Error("Missing granularity");
8120
- }
8121
- return pivotTimeAdapter(granularity).toFunctionValue(value);
8154
+ return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
8122
8155
  }
8123
8156
  const pivotNormalizationValueRegistry = new Registry();
8124
8157
  pivotNormalizationValueRegistry
@@ -15251,6 +15284,7 @@ stores.inject(MyMetaStore, storeInstance);
15251
15284
  initialMessages = dropCommands(initialMessages, "SORT_CELLS");
15252
15285
  initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
15253
15286
  initialMessages = fixChartDefinitions(data, initialMessages);
15287
+ initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
15254
15288
  return initialMessages;
15255
15289
  }
15256
15290
  /**
@@ -15350,6 +15384,40 @@ stores.inject(MyMetaStore, storeInstance);
15350
15384
  }
15351
15385
  return messages;
15352
15386
  }
15387
+ function fixTranslatedDuplicateSheetName(data, initialMessages) {
15388
+ const sheetNames = {};
15389
+ for (const sheet of data.sheets || []) {
15390
+ sheetNames[sheet.id] = sheet.name;
15391
+ }
15392
+ const messages = [];
15393
+ for (const message of initialMessages) {
15394
+ if (message.type === "REMOTE_REVISION") {
15395
+ const commands = [];
15396
+ for (const cmd of message.commands) {
15397
+ switch (cmd.type) {
15398
+ case "DUPLICATE_SHEET":
15399
+ cmd.sheetNameTo =
15400
+ cmd.sheetNameTo ??
15401
+ getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
15402
+ break;
15403
+ case "CREATE_SHEET":
15404
+ case "RENAME_SHEET":
15405
+ sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
15406
+ break;
15407
+ }
15408
+ commands.push(cmd);
15409
+ }
15410
+ messages.push({
15411
+ ...message,
15412
+ commands,
15413
+ });
15414
+ }
15415
+ else {
15416
+ messages.push(message);
15417
+ }
15418
+ }
15419
+ return initialMessages;
15420
+ }
15353
15421
  // -----------------------------------------------------------------------------
15354
15422
  // Helpers
15355
15423
  // -----------------------------------------------------------------------------
@@ -16916,6 +16984,7 @@ stores.inject(MyMetaStore, storeInstance);
16916
16984
  canvas = owl.useRef("graphContainer");
16917
16985
  chart;
16918
16986
  currentRuntime;
16987
+ currentDevicePixelRatio = window.devicePixelRatio;
16919
16988
  get background() {
16920
16989
  return this.chartRuntime.background;
16921
16990
  }
@@ -16949,11 +17018,11 @@ stores.inject(MyMetaStore, storeInstance);
16949
17018
  }
16950
17019
  this.currentRuntime = runtime;
16951
17020
  }
17021
+ else if (this.currentDevicePixelRatio !== window.devicePixelRatio) {
17022
+ this.currentDevicePixelRatio = window.devicePixelRatio;
17023
+ this.updateChartJs(deepCopy(this.currentRuntime));
17024
+ }
16952
17025
  });
16953
- owl.useEffect(() => {
16954
- this.currentRuntime = this.chartRuntime;
16955
- this.updateChartJs(deepCopy(this.currentRuntime));
16956
- }, () => [window.devicePixelRatio]);
16957
17026
  }
16958
17027
  createChart(chartData) {
16959
17028
  const canvas = this.canvas.el;
@@ -24364,7 +24433,7 @@ stores.inject(MyMetaStore, storeInstance);
24364
24433
  return { value: "" };
24365
24434
  }
24366
24435
  if (result.value === null) {
24367
- result.value = "";
24436
+ return { ...result, value: "" };
24368
24437
  }
24369
24438
  return result;
24370
24439
  },
@@ -24385,7 +24454,7 @@ stores.inject(MyMetaStore, storeInstance);
24385
24454
  return { value: "" };
24386
24455
  }
24387
24456
  if (result.value === null) {
24388
- result.value = "";
24457
+ return { ...result, value: "" };
24389
24458
  }
24390
24459
  return result;
24391
24460
  },
@@ -24406,7 +24475,7 @@ stores.inject(MyMetaStore, storeInstance);
24406
24475
  return { value: "" };
24407
24476
  }
24408
24477
  if (result.value === null) {
24409
- result.value = "";
24478
+ return { ...result, value: "" };
24410
24479
  }
24411
24480
  return result;
24412
24481
  },
@@ -24432,7 +24501,7 @@ stores.inject(MyMetaStore, storeInstance);
24432
24501
  return { value: "" };
24433
24502
  }
24434
24503
  if (result.value === null) {
24435
- result.value = "";
24504
+ return { ...result, value: "" };
24436
24505
  }
24437
24506
  return result;
24438
24507
  }
@@ -24550,6 +24619,11 @@ stores.inject(MyMetaStore, storeInstance);
24550
24619
  if (range === undefined || range.invalidXc || range.invalidSheetName) {
24551
24620
  throw new InvalidReferenceError();
24552
24621
  }
24622
+ if (evalContext.__originCellPosition &&
24623
+ range.sheetId === evalContext.__originSheetId &&
24624
+ isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
24625
+ throw new CircularDependencyError();
24626
+ }
24553
24627
  dependencies.push(range);
24554
24628
  }
24555
24629
  for (const measure of forMeasures) {
@@ -27557,6 +27631,13 @@ stores.inject(MyMetaStore, storeInstance);
27557
27631
  openAssistant() {
27558
27632
  this.assistant.forcedClosed = false;
27559
27633
  }
27634
+ onWheel(event) {
27635
+ // detect if scrollbar is available
27636
+ if (this.composerRef.el &&
27637
+ this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
27638
+ event.stopPropagation();
27639
+ }
27640
+ }
27560
27641
  // ---------------------------------------------------------------------------
27561
27642
  // Private
27562
27643
  // ---------------------------------------------------------------------------
@@ -29058,9 +29139,6 @@ stores.inject(MyMetaStore, storeInstance);
29058
29139
  };
29059
29140
  }
29060
29141
  getDefinitionForExcel() {
29061
- // Excel does not support aggregating labels
29062
- if (this.aggregated)
29063
- return undefined;
29064
29142
  const dataSets = this.dataSets
29065
29143
  .map((ds) => toExcelDataset(this.getters, ds))
29066
29144
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -30301,9 +30379,6 @@ stores.inject(MyMetaStore, storeInstance);
30301
30379
  return new LineChart(definition, this.sheetId, this.getters);
30302
30380
  }
30303
30381
  getDefinitionForExcel() {
30304
- // Excel does not support aggregating labels
30305
- if (this.aggregated)
30306
- return undefined;
30307
30382
  const dataSets = this.dataSets
30308
30383
  .map((ds) => toExcelDataset(this.getters, ds))
30309
30384
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -30414,9 +30489,6 @@ stores.inject(MyMetaStore, storeInstance);
30414
30489
  return new PieChart(definition, sheetId, this.getters);
30415
30490
  }
30416
30491
  getDefinitionForExcel() {
30417
- // Excel does not support aggregating labels
30418
- if (this.aggregated)
30419
- return undefined;
30420
30492
  const dataSets = this.dataSets
30421
30493
  .map((ds) => toExcelDataset(this.getters, ds))
30422
30494
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -32565,10 +32637,13 @@ stores.inject(MyMetaStore, storeInstance);
32565
32637
  name: _t("Duplicate"),
32566
32638
  execute: (env) => {
32567
32639
  const sheetIdFrom = env.model.getters.getActiveSheetId();
32640
+ const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
32568
32641
  const sheetIdTo = env.model.uuidGenerator.smallUuid();
32642
+ const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
32569
32643
  env.model.dispatch("DUPLICATE_SHEET", {
32570
32644
  sheetId: sheetIdFrom,
32571
32645
  sheetIdTo,
32646
+ sheetNameTo,
32572
32647
  });
32573
32648
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
32574
32649
  },
@@ -32635,18 +32710,28 @@ stores.inject(MyMetaStore, storeInstance);
32635
32710
  function useInterval(callback, delay) {
32636
32711
  let intervalId;
32637
32712
  const { setInterval, clearInterval } = window;
32713
+ const pause = () => {
32714
+ clearInterval(intervalId);
32715
+ intervalId = undefined;
32716
+ };
32717
+ const safeCallback = () => {
32718
+ try {
32719
+ callback();
32720
+ }
32721
+ catch (e) {
32722
+ pause();
32723
+ throw e;
32724
+ }
32725
+ };
32638
32726
  owl.useEffect(() => {
32639
- intervalId = setInterval(callback, delay);
32727
+ intervalId = setInterval(safeCallback, delay);
32640
32728
  return () => clearInterval(intervalId);
32641
32729
  }, () => [delay]);
32642
32730
  return {
32643
- pause: () => {
32644
- clearInterval(intervalId);
32645
- intervalId = undefined;
32646
- },
32731
+ pause,
32647
32732
  resume: () => {
32648
32733
  if (intervalId === undefined) {
32649
- intervalId = setInterval(callback, delay);
32734
+ intervalId = setInterval(safeCallback, delay);
32650
32735
  }
32651
32736
  },
32652
32737
  };
@@ -43897,8 +43982,8 @@ stores.inject(MyMetaStore, storeInstance);
43897
43982
 
43898
43983
  const NULL_SYMBOL = Symbol("NULL");
43899
43984
  function createDate(dimension, value, locale) {
43900
- const granularity = dimension.granularity;
43901
- if (!granularity || !(granularity in MAP_VALUE_DIMENSION_DATE)) {
43985
+ const granularity = dimension.granularity || "month";
43986
+ if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
43902
43987
  throw new Error(`Unknown date granularity: ${granularity}`);
43903
43988
  }
43904
43989
  const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
@@ -43917,6 +44002,9 @@ stores.inject(MyMetaStore, storeInstance);
43917
44002
  case "month_number":
43918
44003
  number = date.getMonth() + 1;
43919
44004
  break;
44005
+ case "month":
44006
+ number = Math.floor(toNumber(value, locale));
44007
+ break;
43920
44008
  case "iso_week_number":
43921
44009
  number = date.getIsoWeek();
43922
44010
  break;
@@ -44010,6 +44098,10 @@ stores.inject(MyMetaStore, storeInstance);
44010
44098
  set: new Set(),
44011
44099
  values: {},
44012
44100
  },
44101
+ month: {
44102
+ set: new Set(),
44103
+ values: {},
44104
+ },
44013
44105
  iso_week_number: {
44014
44106
  set: new Set(),
44015
44107
  values: {},
@@ -44220,7 +44312,7 @@ stores.inject(MyMetaStore, storeInstance);
44220
44312
  const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
44221
44313
  const finalCell = cells[0]?.[dimension.nameWithGranularity];
44222
44314
  if (dimension.type === "datetime") {
44223
- const adapter = pivotTimeAdapter(dimension.granularity);
44315
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
44224
44316
  return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
44225
44317
  }
44226
44318
  if (!finalCell) {
@@ -44338,7 +44430,7 @@ stores.inject(MyMetaStore, storeInstance);
44338
44430
  if (nonEmptyCells.length === 0) {
44339
44431
  return "integer";
44340
44432
  }
44341
- if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
44433
+ if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
44342
44434
  return "datetime";
44343
44435
  }
44344
44436
  if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
@@ -44433,7 +44525,7 @@ stores.inject(MyMetaStore, storeInstance);
44433
44525
  for (const entry of dataEntries) {
44434
44526
  for (const dimension of dateDimensions) {
44435
44527
  const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
44436
- const adapter = pivotTimeAdapter(dimension.granularity);
44528
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
44437
44529
  const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
44438
44530
  entry[dimension.nameWithGranularity] = {
44439
44531
  value,
@@ -44453,6 +44545,7 @@ stores.inject(MyMetaStore, storeInstance);
44453
44545
  "year",
44454
44546
  "quarter_number",
44455
44547
  "month_number",
44548
+ "month",
44456
44549
  "iso_week_number",
44457
44550
  "day_of_month",
44458
44551
  "day",
@@ -44693,7 +44786,7 @@ stores.inject(MyMetaStore, storeInstance);
44693
44786
  : this.datetimeGranularities);
44694
44787
  }
44695
44788
  for (const field of dateFields) {
44696
- granularitiesPerFields[field.fieldName].delete(field.granularity);
44789
+ granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
44697
44790
  }
44698
44791
  return granularitiesPerFields;
44699
44792
  }
@@ -46851,6 +46944,8 @@ stores.inject(MyMetaStore, storeInstance);
46851
46944
  }
46852
46945
  get composerProps() {
46853
46946
  const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
46947
+ // Remove the wrapper border width
46948
+ const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
46854
46949
  return {
46855
46950
  rect: { ...this.rect },
46856
46951
  delimitation: {
@@ -46868,6 +46963,7 @@ stores.inject(MyMetaStore, storeInstance);
46868
46963
  }),
46869
46964
  onInputContextMenu: this.props.onInputContextMenu,
46870
46965
  composerStore: this.composerStore,
46966
+ inputStyle: `max-height: ${maxHeight}px;`,
46871
46967
  };
46872
46968
  }
46873
46969
  get containerStyle() {
@@ -48366,7 +48462,7 @@ stores.inject(MyMetaStore, storeInstance);
48366
48462
  position: absolute;
48367
48463
  top: 0;
48368
48464
  left: ${HEADER_WIDTH}px;
48369
- right: 0;
48465
+ right: ${SCROLLBAR_WIDTH}px;
48370
48466
  height: ${HEADER_HEIGHT}px;
48371
48467
  &.o-dragging {
48372
48468
  cursor: grabbing;
@@ -48532,9 +48628,8 @@ stores.inject(MyMetaStore, storeInstance);
48532
48628
  position: absolute;
48533
48629
  top: ${HEADER_HEIGHT}px;
48534
48630
  left: 0;
48535
- right: 0;
48631
+ bottom: ${SCROLLBAR_WIDTH}px;
48536
48632
  width: ${HEADER_WIDTH}px;
48537
- height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
48538
48633
  &.o-dragging {
48539
48634
  cursor: grabbing;
48540
48635
  }
@@ -52268,9 +52363,7 @@ stores.inject(MyMetaStore, storeInstance);
52268
52363
  : "Success" /* CommandResult.Success */;
52269
52364
  }
52270
52365
  checkChartExists(cmd) {
52271
- return this.getters.getFigureSheetId(cmd.id)
52272
- ? "Success" /* CommandResult.Success */
52273
- : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
52366
+ return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
52274
52367
  }
52275
52368
  }
52276
52369
 
@@ -54531,6 +54624,7 @@ stores.inject(MyMetaStore, storeInstance);
54531
54624
  "getCommandZones",
54532
54625
  "getUnboundedZone",
54533
54626
  "checkElementsIncludeAllNonFrozenHeaders",
54627
+ "getDuplicateSheetName",
54534
54628
  ];
54535
54629
  sheetIdsMapName = {};
54536
54630
  orderedSheetIds = [];
@@ -54555,7 +54649,11 @@ stores.inject(MyMetaStore, storeInstance);
54555
54649
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
54556
54650
  }
54557
54651
  case "DUPLICATE_SHEET": {
54558
- return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
54652
+ if (this.sheets[cmd.sheetIdTo])
54653
+ return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
54654
+ if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
54655
+ return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
54656
+ return "Success" /* CommandResult.Success */;
54559
54657
  }
54560
54658
  case "MOVE_SHEET":
54561
54659
  try {
@@ -54632,7 +54730,7 @@ stores.inject(MyMetaStore, storeInstance);
54632
54730
  this.showSheet(cmd.sheetId);
54633
54731
  break;
54634
54732
  case "DUPLICATE_SHEET":
54635
- this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
54733
+ this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
54636
54734
  break;
54637
54735
  case "DELETE_SHEET":
54638
54736
  this.deleteSheet(this.sheets[cmd.sheetId]);
@@ -54838,14 +54936,8 @@ stores.inject(MyMetaStore, storeInstance);
54838
54936
  return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
54839
54937
  }
54840
54938
  getNextSheetName(baseName = "Sheet") {
54841
- let i = 1;
54842
54939
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
54843
- let name = `${baseName}${i}`;
54844
- while (names.includes(name)) {
54845
- name = `${baseName}${i}`;
54846
- i++;
54847
- }
54848
- return name;
54940
+ return getNextSheetName(names, baseName);
54849
54941
  }
54850
54942
  getSheetSize(sheetId) {
54851
54943
  return {
@@ -55091,9 +55183,8 @@ stores.inject(MyMetaStore, storeInstance);
55091
55183
  showSheet(sheetId) {
55092
55184
  this.history.update("sheets", sheetId, "isVisible", true);
55093
55185
  }
55094
- duplicateSheet(fromId, toId) {
55186
+ duplicateSheet(fromId, toId, toName) {
55095
55187
  const sheet = this.getSheet(fromId);
55096
- const toName = this.getDuplicateSheetName(sheet.name);
55097
55188
  const newSheet = deepCopy(sheet);
55098
55189
  newSheet.id = toId;
55099
55190
  newSheet.name = toName;
@@ -55125,15 +55216,8 @@ stores.inject(MyMetaStore, storeInstance);
55125
55216
  this.history.update("sheetIdsMapName", sheetIdsMapName);
55126
55217
  }
55127
55218
  getDuplicateSheetName(sheetName) {
55128
- let i = 1;
55129
55219
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
55130
- const baseName = _t("Copy of %s", sheetName);
55131
- let name = baseName.toString();
55132
- while (names.includes(name)) {
55133
- name = `${baseName} (${i})`;
55134
- i++;
55135
- }
55136
- return name;
55220
+ return getDuplicateSheetName(sheetName, names);
55137
55221
  }
55138
55222
  deleteSheet(sheet) {
55139
55223
  const name = sheet.name;
@@ -56619,6 +56703,15 @@ stores.inject(MyMetaStore, storeInstance);
56619
56703
  }
56620
56704
  }
56621
56705
  class SpreadsheetPivotCorePlugin extends CorePlugin {
56706
+ allowDispatch(cmd) {
56707
+ switch (cmd.type) {
56708
+ case "ADD_PIVOT":
56709
+ case "UPDATE_PIVOT":
56710
+ const definition = cmd.pivot;
56711
+ return this.checkDataSetValidity(definition);
56712
+ }
56713
+ return "Success" /* CommandResult.Success */;
56714
+ }
56622
56715
  adaptRanges(applyChange) {
56623
56716
  for (const pivotId of this.getters.getPivotIds()) {
56624
56717
  const definition = this.getters.getPivotCoreDefinition(pivotId);
@@ -56637,6 +56730,16 @@ stores.inject(MyMetaStore, storeInstance);
56637
56730
  }
56638
56731
  }
56639
56732
  }
56733
+ checkDataSetValidity(definition) {
56734
+ if (definition.type === "SPREADSHEET" && definition.dataSet) {
56735
+ const { zone, sheetId } = definition.dataSet;
56736
+ if (!sheetId || !this.getters.tryGetSheet(sheetId) || !zone || !isZoneValid(zone)) {
56737
+ return "InvalidDataSet" /* CommandResult.InvalidDataSet */;
56738
+ }
56739
+ return this.getters.checkZonesExistInSheet(sheetId, [zone]);
56740
+ }
56741
+ return "Success" /* CommandResult.Success */;
56742
+ }
56640
56743
  }
56641
56744
 
56642
56745
  class TableStylePlugin extends CorePlugin {
@@ -57940,8 +58043,8 @@ stores.inject(MyMetaStore, storeInstance);
57940
58043
  const EMPTY_ARRAY = [];
57941
58044
 
57942
58045
  const MAX_ITERATION = 30;
57943
- const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
57944
- const EMPTY_CELL = createEvaluatedCell({ value: null });
58046
+ const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
58047
+ const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
57945
58048
  class Evaluator {
57946
58049
  context;
57947
58050
  getters;
@@ -59474,7 +59577,7 @@ stores.inject(MyMetaStore, storeInstance);
59474
59577
  tables = {};
59475
59578
  handle(cmd) {
59476
59579
  if (invalidateEvaluationCommands.has(cmd.type) ||
59477
- (cmd.type === "UPDATE_CELL" && "content" in cmd) ||
59580
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd)) ||
59478
59581
  cmd.type === "EVALUATE_CELLS") {
59479
59582
  this.tables = {};
59480
59583
  return;
@@ -63278,7 +63381,7 @@ stores.inject(MyMetaStore, storeInstance);
63278
63381
  tableStyles = {};
63279
63382
  handle(cmd) {
63280
63383
  if (invalidateEvaluationCommands.has(cmd.type) ||
63281
- (cmd.type === "UPDATE_CELL" && "content" in cmd) ||
63384
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd)) ||
63282
63385
  cmd.type === "EVALUATE_CELLS") {
63283
63386
  this.tableStyles = {};
63284
63387
  return;
@@ -65242,6 +65345,8 @@ stores.inject(MyMetaStore, storeInstance);
65242
65345
  });
65243
65346
  this.selectCell(col, row);
65244
65347
  }
65348
+ const { col, row } = this.gridSelection.anchor.cell;
65349
+ this.moveClient({ sheetId: this.activeSheet.id, col, row });
65245
65350
  }
65246
65351
  /**
65247
65352
  * Ensure selections are not outside sheet boundaries.
@@ -65974,8 +66079,11 @@ stores.inject(MyMetaStore, storeInstance);
65974
66079
  case "REMOVE_TABLE":
65975
66080
  case "UPDATE_TABLE":
65976
66081
  case "UPDATE_FILTER":
65977
- this.sheetsWithDirtyViewports.add(cmd.sheetId);
65978
- break;
66082
+ case "UNFREEZE_ROWS":
66083
+ case "UNFREEZE_COLUMNS":
66084
+ case "FREEZE_COLUMNS":
66085
+ case "FREEZE_ROWS":
66086
+ case "UNFREEZE_COLUMNS_ROWS":
65979
66087
  case "REMOVE_COLUMNS_ROWS":
65980
66088
  case "RESIZE_COLUMNS_ROWS":
65981
66089
  case "HIDE_COLUMNS_ROWS":
@@ -65988,11 +66096,9 @@ stores.inject(MyMetaStore, storeInstance);
65988
66096
  case "FOLD_HEADER_GROUPS_IN_ZONE":
65989
66097
  case "UNFOLD_HEADER_GROUPS_IN_ZONE":
65990
66098
  case "UNFOLD_ALL_HEADER_GROUPS":
65991
- case "FOLD_ALL_HEADER_GROUPS": {
65992
- const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.getActiveSheetId();
65993
- this.sheetsWithDirtyViewports.add(sheetId);
66099
+ case "FOLD_ALL_HEADER_GROUPS":
66100
+ this.sheetsWithDirtyViewports.add(cmd.sheetId);
65994
66101
  break;
65995
- }
65996
66102
  case "UPDATE_CELL":
65997
66103
  // update cell content or format can change hidden rows because of data filters
65998
66104
  if ("content" in cmd || "format" in cmd || cmd.style?.fontSize !== undefined) {
@@ -66008,13 +66114,6 @@ stores.inject(MyMetaStore, storeInstance);
66008
66114
  case "ACTIVATE_SHEET":
66009
66115
  this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
66010
66116
  break;
66011
- case "UNFREEZE_ROWS":
66012
- case "UNFREEZE_COLUMNS":
66013
- case "FREEZE_COLUMNS":
66014
- case "FREEZE_ROWS":
66015
- case "UNFREEZE_COLUMNS_ROWS":
66016
- this.resetViewports(this.getters.getActiveSheetId());
66017
- break;
66018
66117
  case "DELETE_SHEET":
66019
66118
  this.sheetsWithDirtyViewports.delete(cmd.sheetId);
66020
66119
  break;
@@ -67194,7 +67293,7 @@ stores.inject(MyMetaStore, storeInstance);
67194
67293
  }
67195
67294
  handle(cmd) {
67196
67295
  if (invalidateEvaluationCommands.has(cmd.type) ||
67197
- (cmd.type === "UPDATE_CELL" && "content" in cmd)) {
67296
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
67198
67297
  this.isDirty = true;
67199
67298
  }
67200
67299
  switch (cmd.type) {
@@ -73776,9 +73875,9 @@ stores.inject(MyMetaStore, storeInstance);
73776
73875
  exports.tokenize = tokenize;
73777
73876
 
73778
73877
 
73779
- __info__.version = "18.0.25";
73780
- __info__.date = "2025-04-25T08:08:43.377Z";
73781
- __info__.hash = "24aac2c";
73878
+ __info__.version = "18.0.27";
73879
+ __info__.date = "2025-05-12T05:25:47.149Z";
73880
+ __info__.hash = "9b36340";
73782
73881
 
73783
73882
 
73784
73883
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);