@odoo/o-spreadsheet 18.3.1 → 18.3.2

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.3.1
6
- * @date 2025-05-02T12:33:27.384Z
7
- * @hash 7b9574b
5
+ * @version 18.3.2
6
+ * @date 2025-05-12T05:25:42.099Z
7
+ * @hash 57d5a67
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -6532,6 +6532,25 @@
6532
6532
  })
6533
6533
  .filter(isDefined);
6534
6534
  }
6535
+ function getNextSheetName(existingNames, baseName = "Sheet") {
6536
+ let i = 1;
6537
+ let name = `${baseName}${i}`;
6538
+ while (existingNames.includes(name)) {
6539
+ name = `${baseName}${i}`;
6540
+ i++;
6541
+ }
6542
+ return name;
6543
+ }
6544
+ function getDuplicateSheetName(nameToDuplicate, existingNames) {
6545
+ let i = 1;
6546
+ const baseName = _t("Copy of %s", nameToDuplicate);
6547
+ let name = baseName.toString();
6548
+ while (existingNames.includes(name)) {
6549
+ name = `${baseName} (${i})`;
6550
+ i++;
6551
+ }
6552
+ return name;
6553
+ }
6535
6554
 
6536
6555
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
6537
6556
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -8274,6 +8293,24 @@
8274
8293
  return `${normalizedValue}`;
8275
8294
  },
8276
8295
  };
8296
+ /**
8297
+ * normalizes month number + year
8298
+ */
8299
+ const monthAdapter = {
8300
+ normalizeFunctionValue(value) {
8301
+ const date = toNumber(value, DEFAULT_LOCALE);
8302
+ return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
8303
+ },
8304
+ toValueAndFormat(normalizedValue) {
8305
+ return {
8306
+ value: toNumber(normalizedValue, DEFAULT_LOCALE),
8307
+ format: "mmmm yyyy",
8308
+ };
8309
+ },
8310
+ toFunctionValue(normalizedValue) {
8311
+ return `"${normalizedValue}"`;
8312
+ },
8313
+ };
8277
8314
  /**
8278
8315
  * normalizes quarter number
8279
8316
  */
@@ -8409,6 +8446,7 @@
8409
8446
  .add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
8410
8447
  .add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
8411
8448
  .add("month_number", nullHandlerDecorator(monthNumberAdapter))
8449
+ .add("month", nullHandlerDecorator(monthAdapter))
8412
8450
  .add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
8413
8451
  .add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
8414
8452
  .add("hour_number", nullHandlerDecorator(hourNumberAdapter))
@@ -8589,10 +8627,7 @@
8589
8627
  return normalizer(groupValueString, dimension.granularity);
8590
8628
  }
8591
8629
  function normalizeDateTime(value, granularity) {
8592
- if (!granularity) {
8593
- throw new Error("Missing granularity");
8594
- }
8595
- return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
8630
+ return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
8596
8631
  }
8597
8632
  function toFunctionPivotValue(value, dimension) {
8598
8633
  if (value === null) {
@@ -8604,10 +8639,7 @@
8604
8639
  return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
8605
8640
  }
8606
8641
  function toFunctionValueDateTime(value, granularity) {
8607
- if (!granularity) {
8608
- throw new Error("Missing granularity");
8609
- }
8610
- return pivotTimeAdapter(granularity).toFunctionValue(value);
8642
+ return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
8611
8643
  }
8612
8644
  const pivotNormalizationValueRegistry = new Registry();
8613
8645
  pivotNormalizationValueRegistry
@@ -10081,20 +10113,24 @@ stores.inject(MyMetaStore, storeInstance);
10081
10113
  }
10082
10114
 
10083
10115
  const chartJsExtensionRegistry = new Registry();
10084
- /** Return window.Chart, making sure all our extensions are loaded in ChartJS */
10085
- function getChartJSConstructor() {
10086
- if (window.Chart && !window.Chart?.registry.plugins.get("chartShowValuesPlugin")) {
10087
- const extensions = chartJsExtensionRegistry.getAll();
10088
- for (const extension of extensions) {
10089
- if (typeof extension === "function") {
10090
- extension(window.Chart);
10091
- }
10092
- else {
10093
- window.Chart.register(extension);
10094
- }
10095
- }
10116
+ function areChartJSExtensionsLoaded() {
10117
+ return !!window.Chart.registry.plugins.get("chartShowValuesPlugin");
10118
+ }
10119
+ function registerChartJSExtensions() {
10120
+ if (!window.Chart || areChartJSExtensionsLoaded()) {
10121
+ return;
10122
+ }
10123
+ for (const registryItem of chartJsExtensionRegistry.getAll()) {
10124
+ registryItem.register(window.Chart);
10125
+ }
10126
+ }
10127
+ function unregisterChartJsExtensions() {
10128
+ if (!window.Chart) {
10129
+ return;
10130
+ }
10131
+ for (const registryItem of chartJsExtensionRegistry.getAll()) {
10132
+ registryItem.unregister(window.Chart);
10096
10133
  }
10097
- return window.Chart;
10098
10134
  }
10099
10135
 
10100
10136
  function getFunnelChartController() {
@@ -11460,13 +11496,35 @@ stores.inject(MyMetaStore, storeInstance);
11460
11496
  }
11461
11497
  }
11462
11498
  `;
11463
- chartJsExtensionRegistry.add("chartShowValuesPlugin", chartShowValuesPlugin);
11464
- chartJsExtensionRegistry.add("waterfallLinesPlugin", waterfallLinesPlugin);
11465
- chartJsExtensionRegistry.add("funnelController", (Chart) => Chart.register(getFunnelChartController()));
11466
- chartJsExtensionRegistry.add("funnelElement", (Chart) => Chart.register(getFunnelChartElement()));
11467
- chartJsExtensionRegistry.add("funnelTooltipPositioner", (Chart) => (Chart.Tooltip.positioners.funnelTooltipPositioner = funnelTooltipPositioner));
11468
- chartJsExtensionRegistry.add("sunburstLabelsPlugin", sunburstLabelsPlugin);
11469
- chartJsExtensionRegistry.add("sunburstHoverPlugin", sunburstHoverPlugin);
11499
+ chartJsExtensionRegistry.add("chartShowValuesPlugin", {
11500
+ register: (Chart) => Chart.register(chartShowValuesPlugin),
11501
+ unregister: (Chart) => Chart.unregister(chartShowValuesPlugin),
11502
+ });
11503
+ chartJsExtensionRegistry.add("waterfallLinesPlugin", {
11504
+ register: (Chart) => Chart.register(waterfallLinesPlugin),
11505
+ unregister: (Chart) => Chart.unregister(waterfallLinesPlugin),
11506
+ });
11507
+ chartJsExtensionRegistry.add("funnelController", {
11508
+ register: (Chart) => Chart.register(getFunnelChartController()),
11509
+ unregister: (Chart) => Chart.unregister(getFunnelChartController()),
11510
+ });
11511
+ chartJsExtensionRegistry.add("funnelElement", {
11512
+ register: (Chart) => Chart.register(getFunnelChartElement()),
11513
+ unregister: (Chart) => Chart.unregister(getFunnelChartElement()),
11514
+ });
11515
+ chartJsExtensionRegistry.add("funnelTooltipPositioner", {
11516
+ register: (Chart) => (Chart.Tooltip.positioners.funnelTooltipPositioner = funnelTooltipPositioner),
11517
+ // @ts-expect-error
11518
+ unregister: (Chart) => (Chart.Tooltip.positioners.funnelTooltipPositioner = undefined),
11519
+ });
11520
+ chartJsExtensionRegistry.add("sunburstLabelsPlugin", {
11521
+ register: (Chart) => Chart.register(sunburstLabelsPlugin),
11522
+ unregister: (Chart) => Chart.unregister(sunburstLabelsPlugin),
11523
+ });
11524
+ chartJsExtensionRegistry.add("sunburstHoverPlugin", {
11525
+ register: (Chart) => Chart.register(sunburstHoverPlugin),
11526
+ unregister: (Chart) => Chart.unregister(sunburstHoverPlugin),
11527
+ });
11470
11528
  class ChartJsComponent extends owl.Component {
11471
11529
  static template = "o-spreadsheet-ChartJsComponent";
11472
11530
  static props = {
@@ -11518,8 +11576,7 @@ stores.inject(MyMetaStore, storeInstance);
11518
11576
  createChart(chartData) {
11519
11577
  const canvas = this.canvas.el;
11520
11578
  const ctx = canvas.getContext("2d");
11521
- const Chart = getChartJSConstructor();
11522
- this.chart = new Chart(ctx, chartData);
11579
+ this.chart = new window.Chart(ctx, chartData);
11523
11580
  }
11524
11581
  updateChartJs(chartData) {
11525
11582
  if (chartData.data && chartData.data.datasets) {
@@ -19824,7 +19881,7 @@ stores.inject(MyMetaStore, storeInstance);
19824
19881
  return { value: "" };
19825
19882
  }
19826
19883
  if (result.value === null) {
19827
- result.value = "";
19884
+ return { ...result, value: "" };
19828
19885
  }
19829
19886
  return result;
19830
19887
  },
@@ -19845,7 +19902,7 @@ stores.inject(MyMetaStore, storeInstance);
19845
19902
  return { value: "" };
19846
19903
  }
19847
19904
  if (result.value === null) {
19848
- result.value = "";
19905
+ return { ...result, value: "" };
19849
19906
  }
19850
19907
  return result;
19851
19908
  },
@@ -19866,7 +19923,7 @@ stores.inject(MyMetaStore, storeInstance);
19866
19923
  return { value: "" };
19867
19924
  }
19868
19925
  if (result.value === null) {
19869
- result.value = "";
19926
+ return { ...result, value: "" };
19870
19927
  }
19871
19928
  return result;
19872
19929
  },
@@ -19892,7 +19949,7 @@ stores.inject(MyMetaStore, storeInstance);
19892
19949
  return { value: "" };
19893
19950
  }
19894
19951
  if (result.value === null) {
19895
- result.value = "";
19952
+ return { ...result, value: "" };
19896
19953
  }
19897
19954
  return result;
19898
19955
  }
@@ -20039,6 +20096,11 @@ stores.inject(MyMetaStore, storeInstance);
20039
20096
  if (range === undefined || range.invalidXc || range.invalidSheetName) {
20040
20097
  throw new InvalidReferenceError();
20041
20098
  }
20099
+ if (evalContext.__originCellPosition &&
20100
+ range.sheetId === evalContext.__originSheetId &&
20101
+ isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
20102
+ throw new CircularDependencyError();
20103
+ }
20042
20104
  dependencies.push(range);
20043
20105
  }
20044
20106
  for (const measure of forMeasures) {
@@ -24398,6 +24460,7 @@ stores.inject(MyMetaStore, storeInstance);
24398
24460
  },
24399
24461
  },
24400
24462
  animation: false,
24463
+ events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "mouseup"],
24401
24464
  };
24402
24465
  function chartToImageUrl(runtime, figure, type) {
24403
24466
  // wrap the canvas in a div with a fixed size because chart.js would
@@ -24447,8 +24510,7 @@ stores.inject(MyMetaStore, storeInstance);
24447
24510
  if ("chartJsConfig" in runtime) {
24448
24511
  const config = deepCopy(runtime.chartJsConfig);
24449
24512
  config.plugins = [backgroundColorChartJSPlugin];
24450
- const Chart = getChartJSConstructor();
24451
- const chart = new Chart(canvas, config);
24513
+ const chart = new window.Chart(canvas, config);
24452
24514
  chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
24453
24515
  chart.destroy();
24454
24516
  }
@@ -25200,11 +25262,10 @@ stores.inject(MyMetaStore, storeInstance);
25200
25262
  }
25201
25263
  let missingTimeAdapterAlreadyWarned = false;
25202
25264
  function isLuxonTimeAdapterInstalled() {
25203
- const Chart = getChartJSConstructor();
25204
- if (!Chart) {
25265
+ if (!window.Chart) {
25205
25266
  return false;
25206
25267
  }
25207
- const adapter = new Chart._adapters._date({});
25268
+ const adapter = new window.Chart._adapters._date({});
25208
25269
  // @ts-ignore
25209
25270
  const isInstalled = adapter._id === "luxon";
25210
25271
  if (!isInstalled && !missingTimeAdapterAlreadyWarned) {
@@ -25702,6 +25763,9 @@ stores.inject(MyMetaStore, storeInstance);
25702
25763
  target.style.cursor = "default";
25703
25764
  },
25704
25765
  onClick: (event, legendItem, legend) => {
25766
+ if (event.type !== "click") {
25767
+ return;
25768
+ }
25705
25769
  const index = legendItem.datasetIndex;
25706
25770
  if (!legend.legendItems || index === undefined) {
25707
25771
  return;
@@ -34848,6 +34912,7 @@ stores.inject(MyMetaStore, storeInstance);
34848
34912
  initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
34849
34913
  initialMessages = fixChartDefinitions(data, initialMessages);
34850
34914
  initialMessages = fixFigureOffset(data, initialMessages);
34915
+ initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
34851
34916
  return initialMessages;
34852
34917
  }
34853
34918
  /**
@@ -34980,6 +35045,42 @@ stores.inject(MyMetaStore, storeInstance);
34980
35045
  }
34981
35046
  return messages;
34982
35047
  }
35048
+ function fixTranslatedDuplicateSheetName(data, initialMessages) {
35049
+ const sheetNames = {};
35050
+ for (const sheet of data.sheets || []) {
35051
+ sheetNames[sheet.id] = sheet.name;
35052
+ }
35053
+ const messages = [];
35054
+ for (const message of initialMessages) {
35055
+ if (message.type === "REMOTE_REVISION") {
35056
+ const commands = [];
35057
+ for (const cmd of message.commands) {
35058
+ switch (cmd.type) {
35059
+ case "DUPLICATE_SHEET":
35060
+ cmd.sheetNameTo =
35061
+ cmd.sheetNameTo ??
35062
+ getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
35063
+ break;
35064
+ case "CREATE_SHEET":
35065
+ sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
35066
+ break;
35067
+ case "RENAME_SHEET":
35068
+ sheetNames[cmd.sheetId] = cmd.newName || getNextSheetName(Object.values(sheetNames));
35069
+ break;
35070
+ }
35071
+ commands.push(cmd);
35072
+ }
35073
+ messages.push({
35074
+ ...message,
35075
+ commands,
35076
+ });
35077
+ }
35078
+ else {
35079
+ messages.push(message);
35080
+ }
35081
+ }
35082
+ return initialMessages;
35083
+ }
34983
35084
  // -----------------------------------------------------------------------------
34984
35085
  // Helpers
34985
35086
  // -----------------------------------------------------------------------------
@@ -36038,10 +36139,13 @@ stores.inject(MyMetaStore, storeInstance);
36038
36139
  name: _t("Duplicate"),
36039
36140
  execute: (env) => {
36040
36141
  const sheetIdFrom = env.model.getters.getActiveSheetId();
36142
+ const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
36041
36143
  const sheetIdTo = env.model.uuidGenerator.smallUuid();
36144
+ const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
36042
36145
  env.model.dispatch("DUPLICATE_SHEET", {
36043
36146
  sheetId: sheetIdFrom,
36044
36147
  sheetIdTo,
36148
+ sheetNameTo,
36045
36149
  });
36046
36150
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
36047
36151
  },
@@ -40682,7 +40786,7 @@ stores.inject(MyMetaStore, storeInstance);
40682
40786
  const cancelledReasons = [
40683
40787
  ...(this.state.datasetDispatchResult?.reasons || []),
40684
40788
  ...(this.state.labelsDispatchResult?.reasons || []),
40685
- ];
40789
+ ].filter((reason) => reason !== "NoChanges" /* CommandResult.NoChanges */);
40686
40790
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
40687
40791
  }
40688
40792
  get isDatasetInvalid() {
@@ -43214,6 +43318,13 @@ stores.inject(MyMetaStore, storeInstance);
43214
43318
  openAssistant() {
43215
43319
  this.assistant.forcedClosed = false;
43216
43320
  }
43321
+ onWheel(event) {
43322
+ // detect if scrollbar is available
43323
+ if (this.composerRef.el &&
43324
+ this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
43325
+ event.stopPropagation();
43326
+ }
43327
+ }
43217
43328
  // ---------------------------------------------------------------------------
43218
43329
  // Private
43219
43330
  // ---------------------------------------------------------------------------
@@ -48938,8 +49049,8 @@ stores.inject(MyMetaStore, storeInstance);
48938
49049
 
48939
49050
  const NULL_SYMBOL = Symbol("NULL");
48940
49051
  function createDate(dimension, value, locale) {
48941
- const granularity = dimension.granularity;
48942
- if (!granularity || !(granularity in MAP_VALUE_DIMENSION_DATE)) {
49052
+ const granularity = dimension.granularity || "month";
49053
+ if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
48943
49054
  throw new Error(`Unknown date granularity: ${granularity}`);
48944
49055
  }
48945
49056
  const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
@@ -48958,6 +49069,9 @@ stores.inject(MyMetaStore, storeInstance);
48958
49069
  case "month_number":
48959
49070
  number = date.getMonth() + 1;
48960
49071
  break;
49072
+ case "month":
49073
+ number = Math.floor(toNumber(value, locale));
49074
+ break;
48961
49075
  case "iso_week_number":
48962
49076
  number = date.getIsoWeek();
48963
49077
  break;
@@ -49051,6 +49165,10 @@ stores.inject(MyMetaStore, storeInstance);
49051
49165
  set: new Set(),
49052
49166
  values: {},
49053
49167
  },
49168
+ month: {
49169
+ set: new Set(),
49170
+ values: {},
49171
+ },
49054
49172
  iso_week_number: {
49055
49173
  set: new Set(),
49056
49174
  values: {},
@@ -49261,7 +49379,7 @@ stores.inject(MyMetaStore, storeInstance);
49261
49379
  const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
49262
49380
  const finalCell = cells[0]?.[dimension.nameWithGranularity];
49263
49381
  if (dimension.type === "datetime") {
49264
- const adapter = pivotTimeAdapter(dimension.granularity);
49382
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
49265
49383
  return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
49266
49384
  }
49267
49385
  if (!finalCell) {
@@ -49379,7 +49497,7 @@ stores.inject(MyMetaStore, storeInstance);
49379
49497
  if (nonEmptyCells.length === 0) {
49380
49498
  return "integer";
49381
49499
  }
49382
- if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
49500
+ if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
49383
49501
  return "datetime";
49384
49502
  }
49385
49503
  if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
@@ -49472,7 +49590,7 @@ stores.inject(MyMetaStore, storeInstance);
49472
49590
  for (const entry of dataEntries) {
49473
49591
  for (const dimension of dateDimensions) {
49474
49592
  const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
49475
- const adapter = pivotTimeAdapter(dimension.granularity);
49593
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
49476
49594
  const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
49477
49595
  entry[dimension.nameWithGranularity] = {
49478
49596
  value,
@@ -49492,6 +49610,7 @@ stores.inject(MyMetaStore, storeInstance);
49492
49610
  "year",
49493
49611
  "quarter_number",
49494
49612
  "month_number",
49613
+ "month",
49495
49614
  "iso_week_number",
49496
49615
  "day_of_month",
49497
49616
  "day",
@@ -49742,7 +49861,7 @@ stores.inject(MyMetaStore, storeInstance);
49742
49861
  : this.datetimeGranularities);
49743
49862
  }
49744
49863
  for (const field of dateFields) {
49745
- granularitiesPerFields[field.fieldName].delete(field.granularity);
49864
+ granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
49746
49865
  }
49747
49866
  return granularitiesPerFields;
49748
49867
  }
@@ -52082,6 +52201,8 @@ stores.inject(MyMetaStore, storeInstance);
52082
52201
  }
52083
52202
  get composerProps() {
52084
52203
  const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
52204
+ // Remove the wrapper border width
52205
+ const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
52085
52206
  return {
52086
52207
  rect: { ...this.rect },
52087
52208
  delimitation: {
@@ -52099,6 +52220,7 @@ stores.inject(MyMetaStore, storeInstance);
52099
52220
  }),
52100
52221
  onInputContextMenu: this.props.onInputContextMenu,
52101
52222
  composerStore: this.composerStore,
52223
+ inputStyle: `max-height: ${maxHeight}px;`,
52102
52224
  };
52103
52225
  }
52104
52226
  get containerStyle() {
@@ -57420,7 +57542,7 @@ stores.inject(MyMetaStore, storeInstance);
57420
57542
  case "CREATE_CHART":
57421
57543
  return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartDuplicate));
57422
57544
  case "UPDATE_CHART":
57423
- return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists));
57545
+ return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists, this.checkChartChanged));
57424
57546
  default:
57425
57547
  return "Success" /* CommandResult.Success */;
57426
57548
  }
@@ -57574,10 +57696,15 @@ stores.inject(MyMetaStore, storeInstance);
57574
57696
  : "Success" /* CommandResult.Success */;
57575
57697
  }
57576
57698
  checkChartExists(cmd) {
57577
- return this.getters.getFigureSheetId(cmd.figureId)
57699
+ return this.isChartDefined(cmd.figureId)
57578
57700
  ? "Success" /* CommandResult.Success */
57579
57701
  : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
57580
57702
  }
57703
+ checkChartChanged(cmd) {
57704
+ return deepEquals(this.getChartDefinition(cmd.figureId), cmd.definition)
57705
+ ? "NoChanges" /* CommandResult.NoChanges */
57706
+ : "Success" /* CommandResult.Success */;
57707
+ }
57581
57708
  }
57582
57709
 
57583
57710
  // -----------------------------------------------------------------------------
@@ -59835,6 +59962,7 @@ stores.inject(MyMetaStore, storeInstance);
59835
59962
  "getCommandZones",
59836
59963
  "getUnboundedZone",
59837
59964
  "checkElementsIncludeAllNonFrozenHeaders",
59965
+ "getDuplicateSheetName",
59838
59966
  ];
59839
59967
  sheetIdsMapName = {};
59840
59968
  orderedSheetIds = [];
@@ -59859,7 +59987,11 @@ stores.inject(MyMetaStore, storeInstance);
59859
59987
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
59860
59988
  }
59861
59989
  case "DUPLICATE_SHEET": {
59862
- return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
59990
+ if (this.sheets[cmd.sheetIdTo])
59991
+ return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
59992
+ if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
59993
+ return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
59994
+ return "Success" /* CommandResult.Success */;
59863
59995
  }
59864
59996
  case "MOVE_SHEET":
59865
59997
  try {
@@ -59936,7 +60068,7 @@ stores.inject(MyMetaStore, storeInstance);
59936
60068
  this.showSheet(cmd.sheetId);
59937
60069
  break;
59938
60070
  case "DUPLICATE_SHEET":
59939
- this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
60071
+ this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
59940
60072
  break;
59941
60073
  case "DELETE_SHEET":
59942
60074
  this.deleteSheet(this.sheets[cmd.sheetId]);
@@ -60143,10 +60275,7 @@ stores.inject(MyMetaStore, storeInstance);
60143
60275
  }
60144
60276
  getNextSheetName(baseName = "Sheet") {
60145
60277
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
60146
- return getUniqueText(baseName, names, {
60147
- compute: (name, i) => `${name}${i}`,
60148
- computeFirstOne: true,
60149
- });
60278
+ return getNextSheetName(names, baseName);
60150
60279
  }
60151
60280
  getSheetSize(sheetId) {
60152
60281
  return {
@@ -60393,9 +60522,8 @@ stores.inject(MyMetaStore, storeInstance);
60393
60522
  showSheet(sheetId) {
60394
60523
  this.history.update("sheets", sheetId, "isVisible", true);
60395
60524
  }
60396
- duplicateSheet(fromId, toId) {
60525
+ duplicateSheet(fromId, toId, toName) {
60397
60526
  const sheet = this.getSheet(fromId);
60398
- const toName = this.getDuplicateSheetName(sheet.name);
60399
60527
  const newSheet = deepCopy(sheet);
60400
60528
  newSheet.id = toId;
60401
60529
  newSheet.name = toName;
@@ -60428,8 +60556,7 @@ stores.inject(MyMetaStore, storeInstance);
60428
60556
  }
60429
60557
  getDuplicateSheetName(sheetName) {
60430
60558
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
60431
- const baseName = _t("Copy of %s", sheetName);
60432
- return getUniqueText(baseName.toString(), names);
60559
+ return getDuplicateSheetName(sheetName, names);
60433
60560
  }
60434
60561
  deleteSheet(sheet) {
60435
60562
  const name = sheet.name;
@@ -63233,8 +63360,8 @@ stores.inject(MyMetaStore, storeInstance);
63233
63360
  const EMPTY_ARRAY = [];
63234
63361
 
63235
63362
  const MAX_ITERATION = 30;
63236
- const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
63237
- const EMPTY_CELL = createEvaluatedCell({ value: null });
63363
+ const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
63364
+ const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
63238
63365
  class Evaluator {
63239
63366
  context;
63240
63367
  getters;
@@ -75337,11 +75464,13 @@ stores.inject(MyMetaStore, storeInstance);
75337
75464
  this.checkViewportSize();
75338
75465
  stores.on("store-updated", this, render);
75339
75466
  resizeObserver.observe(this.spreadsheetRef.el);
75467
+ registerChartJSExtensions();
75340
75468
  });
75341
75469
  owl.onWillUnmount(() => {
75342
75470
  this.unbindModelEvents();
75343
75471
  stores.off("store-updated", this);
75344
75472
  resizeObserver.disconnect();
75473
+ unregisterChartJsExtensions();
75345
75474
  });
75346
75475
  owl.onPatched(() => {
75347
75476
  this.checkViewportSize();
@@ -79880,9 +80009,9 @@ stores.inject(MyMetaStore, storeInstance);
79880
80009
  exports.tokenize = tokenize;
79881
80010
 
79882
80011
 
79883
- __info__.version = "18.3.1";
79884
- __info__.date = "2025-05-02T12:33:27.384Z";
79885
- __info__.hash = "7b9574b";
80012
+ __info__.version = "18.3.2";
80013
+ __info__.date = "2025-05-12T05:25:42.099Z";
80014
+ __info__.hash = "57d5a67";
79886
80015
 
79887
80016
 
79888
80017
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);