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