@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
  'use strict';
@@ -3593,6 +3593,7 @@ exports.CommandResult = void 0;
3593
3593
  CommandResult["ValueCellIsInvalidFormula"] = "ValueCellIsInvalidFormula";
3594
3594
  CommandResult["InvalidDefinition"] = "InvalidDefinition";
3595
3595
  CommandResult["InvalidColor"] = "InvalidColor";
3596
+ CommandResult["InvalidPivotDataSet"] = "InvalidPivotDataSet";
3596
3597
  })(exports.CommandResult || (exports.CommandResult = {}));
3597
3598
 
3598
3599
  const DEFAULT_LOCALES = [
@@ -6103,6 +6104,25 @@ function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
6103
6104
  })
6104
6105
  .filter(isDefined);
6105
6106
  }
6107
+ function getNextSheetName(existingNames, baseName = "Sheet") {
6108
+ let i = 1;
6109
+ let name = `${baseName}${i}`;
6110
+ while (existingNames.includes(name)) {
6111
+ name = `${baseName}${i}`;
6112
+ i++;
6113
+ }
6114
+ return name;
6115
+ }
6116
+ function getDuplicateSheetName(nameToDuplicate, existingNames) {
6117
+ let i = 1;
6118
+ const baseName = _t("Copy of %s", nameToDuplicate);
6119
+ let name = baseName.toString();
6120
+ while (existingNames.includes(name)) {
6121
+ name = `${baseName} (${i})`;
6122
+ i++;
6123
+ }
6124
+ return name;
6125
+ }
6106
6126
 
6107
6127
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
6108
6128
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -7791,6 +7811,24 @@ const monthNumberAdapter = {
7791
7811
  return `${normalizedValue}`;
7792
7812
  },
7793
7813
  };
7814
+ /**
7815
+ * normalizes month number + year
7816
+ */
7817
+ const monthAdapter = {
7818
+ normalizeFunctionValue(value) {
7819
+ const date = toNumber(value, DEFAULT_LOCALE);
7820
+ return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
7821
+ },
7822
+ toValueAndFormat(normalizedValue) {
7823
+ return {
7824
+ value: toNumber(normalizedValue, DEFAULT_LOCALE),
7825
+ format: "mmmm yyyy",
7826
+ };
7827
+ },
7828
+ toFunctionValue(normalizedValue) {
7829
+ return `"${normalizedValue}"`;
7830
+ },
7831
+ };
7794
7832
  /**
7795
7833
  * normalizes quarter number
7796
7834
  */
@@ -7921,6 +7959,7 @@ pivotTimeAdapterRegistry
7921
7959
  .add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
7922
7960
  .add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
7923
7961
  .add("month_number", nullHandlerDecorator(monthNumberAdapter))
7962
+ .add("month", nullHandlerDecorator(monthAdapter))
7924
7963
  .add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
7925
7964
  .add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
7926
7965
  .add("hour_number", nullHandlerDecorator(hourNumberAdapter))
@@ -8101,10 +8140,7 @@ function toNormalizedPivotValue(dimension, groupValue) {
8101
8140
  return normalizer(groupValueString, dimension.granularity);
8102
8141
  }
8103
8142
  function normalizeDateTime(value, granularity) {
8104
- if (!granularity) {
8105
- throw new Error("Missing granularity");
8106
- }
8107
- return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
8143
+ return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
8108
8144
  }
8109
8145
  function toFunctionPivotValue(value, dimension) {
8110
8146
  if (value === null) {
@@ -8116,10 +8152,7 @@ function toFunctionPivotValue(value, dimension) {
8116
8152
  return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
8117
8153
  }
8118
8154
  function toFunctionValueDateTime(value, granularity) {
8119
- if (!granularity) {
8120
- throw new Error("Missing granularity");
8121
- }
8122
- return pivotTimeAdapter(granularity).toFunctionValue(value);
8155
+ return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
8123
8156
  }
8124
8157
  const pivotNormalizationValueRegistry = new Registry();
8125
8158
  pivotNormalizationValueRegistry
@@ -15252,6 +15285,7 @@ function repairInitialMessages(data, initialMessages) {
15252
15285
  initialMessages = dropCommands(initialMessages, "SORT_CELLS");
15253
15286
  initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
15254
15287
  initialMessages = fixChartDefinitions(data, initialMessages);
15288
+ initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
15255
15289
  return initialMessages;
15256
15290
  }
15257
15291
  /**
@@ -15351,6 +15385,40 @@ function fixChartDefinitions(data, initialMessages) {
15351
15385
  }
15352
15386
  return messages;
15353
15387
  }
15388
+ function fixTranslatedDuplicateSheetName(data, initialMessages) {
15389
+ const sheetNames = {};
15390
+ for (const sheet of data.sheets || []) {
15391
+ sheetNames[sheet.id] = sheet.name;
15392
+ }
15393
+ const messages = [];
15394
+ for (const message of initialMessages) {
15395
+ if (message.type === "REMOTE_REVISION") {
15396
+ const commands = [];
15397
+ for (const cmd of message.commands) {
15398
+ switch (cmd.type) {
15399
+ case "DUPLICATE_SHEET":
15400
+ cmd.sheetNameTo =
15401
+ cmd.sheetNameTo ??
15402
+ getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
15403
+ break;
15404
+ case "CREATE_SHEET":
15405
+ case "RENAME_SHEET":
15406
+ sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
15407
+ break;
15408
+ }
15409
+ commands.push(cmd);
15410
+ }
15411
+ messages.push({
15412
+ ...message,
15413
+ commands,
15414
+ });
15415
+ }
15416
+ else {
15417
+ messages.push(message);
15418
+ }
15419
+ }
15420
+ return initialMessages;
15421
+ }
15354
15422
  // -----------------------------------------------------------------------------
15355
15423
  // Helpers
15356
15424
  // -----------------------------------------------------------------------------
@@ -16917,6 +16985,7 @@ class ChartJsComponent extends owl.Component {
16917
16985
  canvas = owl.useRef("graphContainer");
16918
16986
  chart;
16919
16987
  currentRuntime;
16988
+ currentDevicePixelRatio = window.devicePixelRatio;
16920
16989
  get background() {
16921
16990
  return this.chartRuntime.background;
16922
16991
  }
@@ -16950,11 +17019,11 @@ class ChartJsComponent extends owl.Component {
16950
17019
  }
16951
17020
  this.currentRuntime = runtime;
16952
17021
  }
17022
+ else if (this.currentDevicePixelRatio !== window.devicePixelRatio) {
17023
+ this.currentDevicePixelRatio = window.devicePixelRatio;
17024
+ this.updateChartJs(deepCopy(this.currentRuntime));
17025
+ }
16953
17026
  });
16954
- owl.useEffect(() => {
16955
- this.currentRuntime = this.chartRuntime;
16956
- this.updateChartJs(deepCopy(this.currentRuntime));
16957
- }, () => [window.devicePixelRatio]);
16958
17027
  }
16959
17028
  createChart(chartData) {
16960
17029
  const canvas = this.canvas.el;
@@ -24365,7 +24434,7 @@ const IF = {
24365
24434
  return { value: "" };
24366
24435
  }
24367
24436
  if (result.value === null) {
24368
- result.value = "";
24437
+ return { ...result, value: "" };
24369
24438
  }
24370
24439
  return result;
24371
24440
  },
@@ -24386,7 +24455,7 @@ const IFERROR = {
24386
24455
  return { value: "" };
24387
24456
  }
24388
24457
  if (result.value === null) {
24389
- result.value = "";
24458
+ return { ...result, value: "" };
24390
24459
  }
24391
24460
  return result;
24392
24461
  },
@@ -24407,7 +24476,7 @@ const IFNA = {
24407
24476
  return { value: "" };
24408
24477
  }
24409
24478
  if (result.value === null) {
24410
- result.value = "";
24479
+ return { ...result, value: "" };
24411
24480
  }
24412
24481
  return result;
24413
24482
  },
@@ -24433,7 +24502,7 @@ const IFS = {
24433
24502
  return { value: "" };
24434
24503
  }
24435
24504
  if (result.value === null) {
24436
- result.value = "";
24505
+ return { ...result, value: "" };
24437
24506
  }
24438
24507
  return result;
24439
24508
  }
@@ -24551,6 +24620,11 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
24551
24620
  if (range === undefined || range.invalidXc || range.invalidSheetName) {
24552
24621
  throw new InvalidReferenceError();
24553
24622
  }
24623
+ if (evalContext.__originCellPosition &&
24624
+ range.sheetId === evalContext.__originSheetId &&
24625
+ isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
24626
+ throw new CircularDependencyError();
24627
+ }
24554
24628
  dependencies.push(range);
24555
24629
  }
24556
24630
  for (const measure of forMeasures) {
@@ -27558,6 +27632,13 @@ class Composer extends owl.Component {
27558
27632
  openAssistant() {
27559
27633
  this.assistant.forcedClosed = false;
27560
27634
  }
27635
+ onWheel(event) {
27636
+ // detect if scrollbar is available
27637
+ if (this.composerRef.el &&
27638
+ this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
27639
+ event.stopPropagation();
27640
+ }
27641
+ }
27561
27642
  // ---------------------------------------------------------------------------
27562
27643
  // Private
27563
27644
  // ---------------------------------------------------------------------------
@@ -29059,9 +29140,6 @@ class BarChart extends AbstractChart {
29059
29140
  };
29060
29141
  }
29061
29142
  getDefinitionForExcel() {
29062
- // Excel does not support aggregating labels
29063
- if (this.aggregated)
29064
- return undefined;
29065
29143
  const dataSets = this.dataSets
29066
29144
  .map((ds) => toExcelDataset(this.getters, ds))
29067
29145
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -30302,9 +30380,6 @@ class LineChart extends AbstractChart {
30302
30380
  return new LineChart(definition, this.sheetId, this.getters);
30303
30381
  }
30304
30382
  getDefinitionForExcel() {
30305
- // Excel does not support aggregating labels
30306
- if (this.aggregated)
30307
- return undefined;
30308
30383
  const dataSets = this.dataSets
30309
30384
  .map((ds) => toExcelDataset(this.getters, ds))
30310
30385
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -30415,9 +30490,6 @@ class PieChart extends AbstractChart {
30415
30490
  return new PieChart(definition, sheetId, this.getters);
30416
30491
  }
30417
30492
  getDefinitionForExcel() {
30418
- // Excel does not support aggregating labels
30419
- if (this.aggregated)
30420
- return undefined;
30421
30493
  const dataSets = this.dataSets
30422
30494
  .map((ds) => toExcelDataset(this.getters, ds))
30423
30495
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -32566,10 +32638,13 @@ const duplicateSheet = {
32566
32638
  name: _t("Duplicate"),
32567
32639
  execute: (env) => {
32568
32640
  const sheetIdFrom = env.model.getters.getActiveSheetId();
32641
+ const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
32569
32642
  const sheetIdTo = env.model.uuidGenerator.smallUuid();
32643
+ const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
32570
32644
  env.model.dispatch("DUPLICATE_SHEET", {
32571
32645
  sheetId: sheetIdFrom,
32572
32646
  sheetIdTo,
32647
+ sheetNameTo,
32573
32648
  });
32574
32649
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
32575
32650
  },
@@ -32636,18 +32711,28 @@ linkMenuRegistry.add("sheet", {
32636
32711
  function useInterval(callback, delay) {
32637
32712
  let intervalId;
32638
32713
  const { setInterval, clearInterval } = window;
32714
+ const pause = () => {
32715
+ clearInterval(intervalId);
32716
+ intervalId = undefined;
32717
+ };
32718
+ const safeCallback = () => {
32719
+ try {
32720
+ callback();
32721
+ }
32722
+ catch (e) {
32723
+ pause();
32724
+ throw e;
32725
+ }
32726
+ };
32639
32727
  owl.useEffect(() => {
32640
- intervalId = setInterval(callback, delay);
32728
+ intervalId = setInterval(safeCallback, delay);
32641
32729
  return () => clearInterval(intervalId);
32642
32730
  }, () => [delay]);
32643
32731
  return {
32644
- pause: () => {
32645
- clearInterval(intervalId);
32646
- intervalId = undefined;
32647
- },
32732
+ pause,
32648
32733
  resume: () => {
32649
32734
  if (intervalId === undefined) {
32650
- intervalId = setInterval(callback, delay);
32735
+ intervalId = setInterval(safeCallback, delay);
32651
32736
  }
32652
32737
  },
32653
32738
  };
@@ -43898,8 +43983,8 @@ function compareDimensionValues(dimension, a, b) {
43898
43983
 
43899
43984
  const NULL_SYMBOL = Symbol("NULL");
43900
43985
  function createDate(dimension, value, locale) {
43901
- const granularity = dimension.granularity;
43902
- if (!granularity || !(granularity in MAP_VALUE_DIMENSION_DATE)) {
43986
+ const granularity = dimension.granularity || "month";
43987
+ if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
43903
43988
  throw new Error(`Unknown date granularity: ${granularity}`);
43904
43989
  }
43905
43990
  const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
@@ -43918,6 +44003,9 @@ function createDate(dimension, value, locale) {
43918
44003
  case "month_number":
43919
44004
  number = date.getMonth() + 1;
43920
44005
  break;
44006
+ case "month":
44007
+ number = Math.floor(toNumber(value, locale));
44008
+ break;
43921
44009
  case "iso_week_number":
43922
44010
  number = date.getIsoWeek();
43923
44011
  break;
@@ -44011,6 +44099,10 @@ const MAP_VALUE_DIMENSION_DATE = {
44011
44099
  set: new Set(),
44012
44100
  values: {},
44013
44101
  },
44102
+ month: {
44103
+ set: new Set(),
44104
+ values: {},
44105
+ },
44014
44106
  iso_week_number: {
44015
44107
  set: new Set(),
44016
44108
  values: {},
@@ -44221,7 +44313,7 @@ class SpreadsheetPivot {
44221
44313
  const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
44222
44314
  const finalCell = cells[0]?.[dimension.nameWithGranularity];
44223
44315
  if (dimension.type === "datetime") {
44224
- const adapter = pivotTimeAdapter(dimension.granularity);
44316
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
44225
44317
  return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
44226
44318
  }
44227
44319
  if (!finalCell) {
@@ -44339,7 +44431,7 @@ class SpreadsheetPivot {
44339
44431
  if (nonEmptyCells.length === 0) {
44340
44432
  return "integer";
44341
44433
  }
44342
- if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
44434
+ if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
44343
44435
  return "datetime";
44344
44436
  }
44345
44437
  if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
@@ -44434,7 +44526,7 @@ class SpreadsheetPivot {
44434
44526
  for (const entry of dataEntries) {
44435
44527
  for (const dimension of dateDimensions) {
44436
44528
  const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
44437
- const adapter = pivotTimeAdapter(dimension.granularity);
44529
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
44438
44530
  const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
44439
44531
  entry[dimension.nameWithGranularity] = {
44440
44532
  value,
@@ -44454,6 +44546,7 @@ const dateGranularities = [
44454
44546
  "year",
44455
44547
  "quarter_number",
44456
44548
  "month_number",
44549
+ "month",
44457
44550
  "iso_week_number",
44458
44551
  "day_of_month",
44459
44552
  "day",
@@ -44694,7 +44787,7 @@ class PivotSidePanelStore extends SpreadsheetStore {
44694
44787
  : this.datetimeGranularities);
44695
44788
  }
44696
44789
  for (const field of dateFields) {
44697
- granularitiesPerFields[field.fieldName].delete(field.granularity);
44790
+ granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
44698
44791
  }
44699
44792
  return granularitiesPerFields;
44700
44793
  }
@@ -46852,6 +46945,8 @@ class GridComposer extends owl.Component {
46852
46945
  }
46853
46946
  get composerProps() {
46854
46947
  const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
46948
+ // Remove the wrapper border width
46949
+ const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
46855
46950
  return {
46856
46951
  rect: { ...this.rect },
46857
46952
  delimitation: {
@@ -46869,6 +46964,7 @@ class GridComposer extends owl.Component {
46869
46964
  }),
46870
46965
  onInputContextMenu: this.props.onInputContextMenu,
46871
46966
  composerStore: this.composerStore,
46967
+ inputStyle: `max-height: ${maxHeight}px;`,
46872
46968
  };
46873
46969
  }
46874
46970
  get containerStyle() {
@@ -48367,7 +48463,7 @@ css /* scss */ `
48367
48463
  position: absolute;
48368
48464
  top: 0;
48369
48465
  left: ${HEADER_WIDTH}px;
48370
- right: 0;
48466
+ right: ${SCROLLBAR_WIDTH}px;
48371
48467
  height: ${HEADER_HEIGHT}px;
48372
48468
  &.o-dragging {
48373
48469
  cursor: grabbing;
@@ -48533,9 +48629,8 @@ css /* scss */ `
48533
48629
  position: absolute;
48534
48630
  top: ${HEADER_HEIGHT}px;
48535
48631
  left: 0;
48536
- right: 0;
48632
+ bottom: ${SCROLLBAR_WIDTH}px;
48537
48633
  width: ${HEADER_WIDTH}px;
48538
- height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
48539
48634
  &.o-dragging {
48540
48635
  cursor: grabbing;
48541
48636
  }
@@ -52269,9 +52364,7 @@ class ChartPlugin extends CorePlugin {
52269
52364
  : "Success" /* CommandResult.Success */;
52270
52365
  }
52271
52366
  checkChartExists(cmd) {
52272
- return this.getters.getFigureSheetId(cmd.id)
52273
- ? "Success" /* CommandResult.Success */
52274
- : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
52367
+ return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
52275
52368
  }
52276
52369
  }
52277
52370
 
@@ -54532,6 +54625,7 @@ class SheetPlugin extends CorePlugin {
54532
54625
  "getCommandZones",
54533
54626
  "getUnboundedZone",
54534
54627
  "checkElementsIncludeAllNonFrozenHeaders",
54628
+ "getDuplicateSheetName",
54535
54629
  ];
54536
54630
  sheetIdsMapName = {};
54537
54631
  orderedSheetIds = [];
@@ -54556,7 +54650,11 @@ class SheetPlugin extends CorePlugin {
54556
54650
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
54557
54651
  }
54558
54652
  case "DUPLICATE_SHEET": {
54559
- return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
54653
+ if (this.sheets[cmd.sheetIdTo])
54654
+ return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
54655
+ if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
54656
+ return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
54657
+ return "Success" /* CommandResult.Success */;
54560
54658
  }
54561
54659
  case "MOVE_SHEET":
54562
54660
  try {
@@ -54633,7 +54731,7 @@ class SheetPlugin extends CorePlugin {
54633
54731
  this.showSheet(cmd.sheetId);
54634
54732
  break;
54635
54733
  case "DUPLICATE_SHEET":
54636
- this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
54734
+ this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
54637
54735
  break;
54638
54736
  case "DELETE_SHEET":
54639
54737
  this.deleteSheet(this.sheets[cmd.sheetId]);
@@ -54839,14 +54937,8 @@ class SheetPlugin extends CorePlugin {
54839
54937
  return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
54840
54938
  }
54841
54939
  getNextSheetName(baseName = "Sheet") {
54842
- let i = 1;
54843
54940
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
54844
- let name = `${baseName}${i}`;
54845
- while (names.includes(name)) {
54846
- name = `${baseName}${i}`;
54847
- i++;
54848
- }
54849
- return name;
54941
+ return getNextSheetName(names, baseName);
54850
54942
  }
54851
54943
  getSheetSize(sheetId) {
54852
54944
  return {
@@ -55092,9 +55184,8 @@ class SheetPlugin extends CorePlugin {
55092
55184
  showSheet(sheetId) {
55093
55185
  this.history.update("sheets", sheetId, "isVisible", true);
55094
55186
  }
55095
- duplicateSheet(fromId, toId) {
55187
+ duplicateSheet(fromId, toId, toName) {
55096
55188
  const sheet = this.getSheet(fromId);
55097
- const toName = this.getDuplicateSheetName(sheet.name);
55098
55189
  const newSheet = deepCopy(sheet);
55099
55190
  newSheet.id = toId;
55100
55191
  newSheet.name = toName;
@@ -55126,15 +55217,8 @@ class SheetPlugin extends CorePlugin {
55126
55217
  this.history.update("sheetIdsMapName", sheetIdsMapName);
55127
55218
  }
55128
55219
  getDuplicateSheetName(sheetName) {
55129
- let i = 1;
55130
55220
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
55131
- const baseName = _t("Copy of %s", sheetName);
55132
- let name = baseName.toString();
55133
- while (names.includes(name)) {
55134
- name = `${baseName} (${i})`;
55135
- i++;
55136
- }
55137
- return name;
55221
+ return getDuplicateSheetName(sheetName, names);
55138
55222
  }
55139
55223
  deleteSheet(sheet) {
55140
55224
  const name = sheet.name;
@@ -56620,6 +56704,15 @@ function adaptPivotRange(range, applyChange) {
56620
56704
  }
56621
56705
  }
56622
56706
  class SpreadsheetPivotCorePlugin extends CorePlugin {
56707
+ allowDispatch(cmd) {
56708
+ switch (cmd.type) {
56709
+ case "ADD_PIVOT":
56710
+ case "UPDATE_PIVOT":
56711
+ const definition = cmd.pivot;
56712
+ return this.checkDataSetValidity(definition);
56713
+ }
56714
+ return "Success" /* CommandResult.Success */;
56715
+ }
56623
56716
  adaptRanges(applyChange) {
56624
56717
  for (const pivotId of this.getters.getPivotIds()) {
56625
56718
  const definition = this.getters.getPivotCoreDefinition(pivotId);
@@ -56638,6 +56731,16 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
56638
56731
  }
56639
56732
  }
56640
56733
  }
56734
+ checkDataSetValidity(definition) {
56735
+ if (definition.type === "SPREADSHEET" && definition.dataSet) {
56736
+ const { zone, sheetId } = definition.dataSet;
56737
+ if (!sheetId || !this.getters.tryGetSheet(sheetId) || !zone || !isZoneValid(zone)) {
56738
+ return "InvalidDataSet" /* CommandResult.InvalidDataSet */;
56739
+ }
56740
+ return this.getters.checkZonesExistInSheet(sheetId, [zone]);
56741
+ }
56742
+ return "Success" /* CommandResult.Success */;
56743
+ }
56641
56744
  }
56642
56745
 
56643
56746
  class TableStylePlugin extends CorePlugin {
@@ -57941,8 +58044,8 @@ class SpreadingRelation {
57941
58044
  const EMPTY_ARRAY = [];
57942
58045
 
57943
58046
  const MAX_ITERATION = 30;
57944
- const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
57945
- const EMPTY_CELL = createEvaluatedCell({ value: null });
58047
+ const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
58048
+ const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
57946
58049
  class Evaluator {
57947
58050
  context;
57948
58051
  getters;
@@ -59475,7 +59578,7 @@ class DynamicTablesPlugin extends UIPlugin {
59475
59578
  tables = {};
59476
59579
  handle(cmd) {
59477
59580
  if (invalidateEvaluationCommands.has(cmd.type) ||
59478
- (cmd.type === "UPDATE_CELL" && "content" in cmd) ||
59581
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd)) ||
59479
59582
  cmd.type === "EVALUATE_CELLS") {
59480
59583
  this.tables = {};
59481
59584
  return;
@@ -63279,7 +63382,7 @@ class TableComputedStylePlugin extends UIPlugin {
63279
63382
  tableStyles = {};
63280
63383
  handle(cmd) {
63281
63384
  if (invalidateEvaluationCommands.has(cmd.type) ||
63282
- (cmd.type === "UPDATE_CELL" && "content" in cmd) ||
63385
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd)) ||
63283
63386
  cmd.type === "EVALUATE_CELLS") {
63284
63387
  this.tableStyles = {};
63285
63388
  return;
@@ -65243,6 +65346,8 @@ class GridSelectionPlugin extends UIPlugin {
65243
65346
  });
65244
65347
  this.selectCell(col, row);
65245
65348
  }
65349
+ const { col, row } = this.gridSelection.anchor.cell;
65350
+ this.moveClient({ sheetId: this.activeSheet.id, col, row });
65246
65351
  }
65247
65352
  /**
65248
65353
  * Ensure selections are not outside sheet boundaries.
@@ -65975,8 +66080,11 @@ class SheetViewPlugin extends UIPlugin {
65975
66080
  case "REMOVE_TABLE":
65976
66081
  case "UPDATE_TABLE":
65977
66082
  case "UPDATE_FILTER":
65978
- this.sheetsWithDirtyViewports.add(cmd.sheetId);
65979
- break;
66083
+ case "UNFREEZE_ROWS":
66084
+ case "UNFREEZE_COLUMNS":
66085
+ case "FREEZE_COLUMNS":
66086
+ case "FREEZE_ROWS":
66087
+ case "UNFREEZE_COLUMNS_ROWS":
65980
66088
  case "REMOVE_COLUMNS_ROWS":
65981
66089
  case "RESIZE_COLUMNS_ROWS":
65982
66090
  case "HIDE_COLUMNS_ROWS":
@@ -65989,11 +66097,9 @@ class SheetViewPlugin extends UIPlugin {
65989
66097
  case "FOLD_HEADER_GROUPS_IN_ZONE":
65990
66098
  case "UNFOLD_HEADER_GROUPS_IN_ZONE":
65991
66099
  case "UNFOLD_ALL_HEADER_GROUPS":
65992
- case "FOLD_ALL_HEADER_GROUPS": {
65993
- const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.getActiveSheetId();
65994
- this.sheetsWithDirtyViewports.add(sheetId);
66100
+ case "FOLD_ALL_HEADER_GROUPS":
66101
+ this.sheetsWithDirtyViewports.add(cmd.sheetId);
65995
66102
  break;
65996
- }
65997
66103
  case "UPDATE_CELL":
65998
66104
  // update cell content or format can change hidden rows because of data filters
65999
66105
  if ("content" in cmd || "format" in cmd || cmd.style?.fontSize !== undefined) {
@@ -66009,13 +66115,6 @@ class SheetViewPlugin extends UIPlugin {
66009
66115
  case "ACTIVATE_SHEET":
66010
66116
  this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
66011
66117
  break;
66012
- case "UNFREEZE_ROWS":
66013
- case "UNFREEZE_COLUMNS":
66014
- case "FREEZE_COLUMNS":
66015
- case "FREEZE_ROWS":
66016
- case "UNFREEZE_COLUMNS_ROWS":
66017
- this.resetViewports(this.getters.getActiveSheetId());
66018
- break;
66019
66118
  case "DELETE_SHEET":
66020
66119
  this.sheetsWithDirtyViewports.delete(cmd.sheetId);
66021
66120
  break;
@@ -67195,7 +67294,7 @@ class AggregateStatisticsStore extends SpreadsheetStore {
67195
67294
  }
67196
67295
  handle(cmd) {
67197
67296
  if (invalidateEvaluationCommands.has(cmd.type) ||
67198
- (cmd.type === "UPDATE_CELL" && "content" in cmd)) {
67297
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
67199
67298
  this.isDirty = true;
67200
67299
  }
67201
67300
  switch (cmd.type) {
@@ -73777,6 +73876,6 @@ exports.tokenColors = tokenColors;
73777
73876
  exports.tokenize = tokenize;
73778
73877
 
73779
73878
 
73780
- __info__.version = "18.0.25";
73781
- __info__.date = "2025-04-25T08:08:43.377Z";
73782
- __info__.hash = "24aac2c";
73879
+ __info__.version = "18.0.27";
73880
+ __info__.date = "2025-05-12T05:25:47.149Z";
73881
+ __info__.hash = "9b36340";
@@ -2059,6 +2059,7 @@ interface DeleteSheetCommand extends SheetDependentCommand {
2059
2059
  interface DuplicateSheetCommand extends SheetDependentCommand {
2060
2060
  type: "DUPLICATE_SHEET";
2061
2061
  sheetIdTo: UID;
2062
+ sheetNameTo: string;
2062
2063
  }
2063
2064
  interface MoveSheetCommand extends SheetDependentCommand {
2064
2065
  type: "MOVE_SHEET";
@@ -2688,7 +2689,8 @@ declare const enum CommandResult {
2688
2689
  EmptyName = "EmptyName",
2689
2690
  ValueCellIsInvalidFormula = "ValueCellIsInvalidFormula",
2690
2691
  InvalidDefinition = "InvalidDefinition",
2691
- InvalidColor = "InvalidColor"
2692
+ InvalidColor = "InvalidColor",
2693
+ InvalidPivotDataSet = "InvalidPivotDataSet"
2692
2694
  }
2693
2695
  interface CommandHandler<T> {
2694
2696
  allowDispatch(command: T): CommandResult | CommandResult[];
@@ -4313,7 +4315,7 @@ interface SheetState {
4313
4315
  readonly cellPosition: Record<UID, CellPosition | undefined>;
4314
4316
  }
4315
4317
  declare class SheetPlugin extends CorePlugin<SheetState> implements SheetState {
4316
- static getters: readonly ["getSheetName", "tryGetSheetName", "getSheet", "tryGetSheet", "getSheetIdByName", "getSheetIds", "getVisibleSheetIds", "isSheetVisible", "doesHeaderExist", "doesHeadersExist", "getCell", "getCellPosition", "getColsZone", "getRowCells", "getRowsZone", "getNumberCols", "getNumberRows", "getNumberHeaders", "getGridLinesVisibility", "getNextSheetName", "getSheetSize", "getSheetZone", "getPaneDivisions", "checkZonesExistInSheet", "getCommandZones", "getUnboundedZone", "checkElementsIncludeAllNonFrozenHeaders"];
4318
+ static getters: readonly ["getSheetName", "tryGetSheetName", "getSheet", "tryGetSheet", "getSheetIdByName", "getSheetIds", "getVisibleSheetIds", "isSheetVisible", "doesHeaderExist", "doesHeadersExist", "getCell", "getCellPosition", "getColsZone", "getRowCells", "getRowsZone", "getNumberCols", "getNumberRows", "getNumberHeaders", "getGridLinesVisibility", "getNextSheetName", "getSheetSize", "getSheetZone", "getPaneDivisions", "checkZonesExistInSheet", "getCommandZones", "getUnboundedZone", "checkElementsIncludeAllNonFrozenHeaders", "getDuplicateSheetName"];
4317
4319
  readonly sheetIdsMapName: Record<string, UID | undefined>;
4318
4320
  readonly orderedSheetIds: UID[];
4319
4321
  readonly sheets: Record<UID, Sheet | undefined>;
@@ -4390,7 +4392,7 @@ declare class SheetPlugin extends CorePlugin<SheetState> implements SheetState {
4390
4392
  private hideSheet;
4391
4393
  private showSheet;
4392
4394
  private duplicateSheet;
4393
- private getDuplicateSheetName;
4395
+ getDuplicateSheetName(sheetName: string): string;
4394
4396
  private deleteSheet;
4395
4397
  /**
4396
4398
  * Delete column. This requires a lot of handling:
@@ -8166,6 +8168,7 @@ declare class Composer extends Component<CellComposerProps, SpreadsheetChildEnv>
8166
8168
  onContextMenu(ev: MouseEvent): void;
8167
8169
  closeAssistant(): void;
8168
8170
  openAssistant(): void;
8171
+ onWheel(event: WheelEvent): void;
8169
8172
  private processContent;
8170
8173
  /**
8171
8174
  * Get the HTML content corresponding to the current composer token, divided by lines.
@@ -8275,6 +8278,7 @@ declare class ChartJsComponent extends Component<Props$M, SpreadsheetChildEnv> {
8275
8278
  private canvas;
8276
8279
  private chart?;
8277
8280
  private currentRuntime;
8281
+ private currentDevicePixelRatio;
8278
8282
  get background(): string;
8279
8283
  get canvasStyle(): string;
8280
8284
  get chartRuntime(): ChartJSRuntime;