@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
  'use strict';
@@ -6533,6 +6533,25 @@ function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
6533
6533
  })
6534
6534
  .filter(isDefined);
6535
6535
  }
6536
+ function getNextSheetName(existingNames, baseName = "Sheet") {
6537
+ let i = 1;
6538
+ let name = `${baseName}${i}`;
6539
+ while (existingNames.includes(name)) {
6540
+ name = `${baseName}${i}`;
6541
+ i++;
6542
+ }
6543
+ return name;
6544
+ }
6545
+ function getDuplicateSheetName(nameToDuplicate, existingNames) {
6546
+ let i = 1;
6547
+ const baseName = _t("Copy of %s", nameToDuplicate);
6548
+ let name = baseName.toString();
6549
+ while (existingNames.includes(name)) {
6550
+ name = `${baseName} (${i})`;
6551
+ i++;
6552
+ }
6553
+ return name;
6554
+ }
6536
6555
 
6537
6556
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
6538
6557
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -8275,6 +8294,24 @@ const monthNumberAdapter = {
8275
8294
  return `${normalizedValue}`;
8276
8295
  },
8277
8296
  };
8297
+ /**
8298
+ * normalizes month number + year
8299
+ */
8300
+ const monthAdapter = {
8301
+ normalizeFunctionValue(value) {
8302
+ const date = toNumber(value, DEFAULT_LOCALE);
8303
+ return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
8304
+ },
8305
+ toValueAndFormat(normalizedValue) {
8306
+ return {
8307
+ value: toNumber(normalizedValue, DEFAULT_LOCALE),
8308
+ format: "mmmm yyyy",
8309
+ };
8310
+ },
8311
+ toFunctionValue(normalizedValue) {
8312
+ return `"${normalizedValue}"`;
8313
+ },
8314
+ };
8278
8315
  /**
8279
8316
  * normalizes quarter number
8280
8317
  */
@@ -8410,6 +8447,7 @@ pivotTimeAdapterRegistry
8410
8447
  .add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
8411
8448
  .add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
8412
8449
  .add("month_number", nullHandlerDecorator(monthNumberAdapter))
8450
+ .add("month", nullHandlerDecorator(monthAdapter))
8413
8451
  .add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
8414
8452
  .add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
8415
8453
  .add("hour_number", nullHandlerDecorator(hourNumberAdapter))
@@ -8590,10 +8628,7 @@ function toNormalizedPivotValue(dimension, groupValue) {
8590
8628
  return normalizer(groupValueString, dimension.granularity);
8591
8629
  }
8592
8630
  function normalizeDateTime(value, granularity) {
8593
- if (!granularity) {
8594
- throw new Error("Missing granularity");
8595
- }
8596
- return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
8631
+ return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
8597
8632
  }
8598
8633
  function toFunctionPivotValue(value, dimension) {
8599
8634
  if (value === null) {
@@ -8605,10 +8640,7 @@ function toFunctionPivotValue(value, dimension) {
8605
8640
  return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
8606
8641
  }
8607
8642
  function toFunctionValueDateTime(value, granularity) {
8608
- if (!granularity) {
8609
- throw new Error("Missing granularity");
8610
- }
8611
- return pivotTimeAdapter(granularity).toFunctionValue(value);
8643
+ return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
8612
8644
  }
8613
8645
  const pivotNormalizationValueRegistry = new Registry();
8614
8646
  pivotNormalizationValueRegistry
@@ -10082,20 +10114,24 @@ function getElementMargins(el) {
10082
10114
  }
10083
10115
 
10084
10116
  const chartJsExtensionRegistry = new Registry();
10085
- /** Return window.Chart, making sure all our extensions are loaded in ChartJS */
10086
- function getChartJSConstructor() {
10087
- if (window.Chart && !window.Chart?.registry.plugins.get("chartShowValuesPlugin")) {
10088
- const extensions = chartJsExtensionRegistry.getAll();
10089
- for (const extension of extensions) {
10090
- if (typeof extension === "function") {
10091
- extension(window.Chart);
10092
- }
10093
- else {
10094
- window.Chart.register(extension);
10095
- }
10096
- }
10117
+ function areChartJSExtensionsLoaded() {
10118
+ return !!window.Chart.registry.plugins.get("chartShowValuesPlugin");
10119
+ }
10120
+ function registerChartJSExtensions() {
10121
+ if (!window.Chart || areChartJSExtensionsLoaded()) {
10122
+ return;
10123
+ }
10124
+ for (const registryItem of chartJsExtensionRegistry.getAll()) {
10125
+ registryItem.register(window.Chart);
10126
+ }
10127
+ }
10128
+ function unregisterChartJsExtensions() {
10129
+ if (!window.Chart) {
10130
+ return;
10131
+ }
10132
+ for (const registryItem of chartJsExtensionRegistry.getAll()) {
10133
+ registryItem.unregister(window.Chart);
10097
10134
  }
10098
- return window.Chart;
10099
10135
  }
10100
10136
 
10101
10137
  function getFunnelChartController() {
@@ -11461,13 +11497,35 @@ css /* scss */ `
11461
11497
  }
11462
11498
  }
11463
11499
  `;
11464
- chartJsExtensionRegistry.add("chartShowValuesPlugin", chartShowValuesPlugin);
11465
- chartJsExtensionRegistry.add("waterfallLinesPlugin", waterfallLinesPlugin);
11466
- chartJsExtensionRegistry.add("funnelController", (Chart) => Chart.register(getFunnelChartController()));
11467
- chartJsExtensionRegistry.add("funnelElement", (Chart) => Chart.register(getFunnelChartElement()));
11468
- chartJsExtensionRegistry.add("funnelTooltipPositioner", (Chart) => (Chart.Tooltip.positioners.funnelTooltipPositioner = funnelTooltipPositioner));
11469
- chartJsExtensionRegistry.add("sunburstLabelsPlugin", sunburstLabelsPlugin);
11470
- chartJsExtensionRegistry.add("sunburstHoverPlugin", sunburstHoverPlugin);
11500
+ chartJsExtensionRegistry.add("chartShowValuesPlugin", {
11501
+ register: (Chart) => Chart.register(chartShowValuesPlugin),
11502
+ unregister: (Chart) => Chart.unregister(chartShowValuesPlugin),
11503
+ });
11504
+ chartJsExtensionRegistry.add("waterfallLinesPlugin", {
11505
+ register: (Chart) => Chart.register(waterfallLinesPlugin),
11506
+ unregister: (Chart) => Chart.unregister(waterfallLinesPlugin),
11507
+ });
11508
+ chartJsExtensionRegistry.add("funnelController", {
11509
+ register: (Chart) => Chart.register(getFunnelChartController()),
11510
+ unregister: (Chart) => Chart.unregister(getFunnelChartController()),
11511
+ });
11512
+ chartJsExtensionRegistry.add("funnelElement", {
11513
+ register: (Chart) => Chart.register(getFunnelChartElement()),
11514
+ unregister: (Chart) => Chart.unregister(getFunnelChartElement()),
11515
+ });
11516
+ chartJsExtensionRegistry.add("funnelTooltipPositioner", {
11517
+ register: (Chart) => (Chart.Tooltip.positioners.funnelTooltipPositioner = funnelTooltipPositioner),
11518
+ // @ts-expect-error
11519
+ unregister: (Chart) => (Chart.Tooltip.positioners.funnelTooltipPositioner = undefined),
11520
+ });
11521
+ chartJsExtensionRegistry.add("sunburstLabelsPlugin", {
11522
+ register: (Chart) => Chart.register(sunburstLabelsPlugin),
11523
+ unregister: (Chart) => Chart.unregister(sunburstLabelsPlugin),
11524
+ });
11525
+ chartJsExtensionRegistry.add("sunburstHoverPlugin", {
11526
+ register: (Chart) => Chart.register(sunburstHoverPlugin),
11527
+ unregister: (Chart) => Chart.unregister(sunburstHoverPlugin),
11528
+ });
11471
11529
  class ChartJsComponent extends owl.Component {
11472
11530
  static template = "o-spreadsheet-ChartJsComponent";
11473
11531
  static props = {
@@ -11519,8 +11577,7 @@ class ChartJsComponent extends owl.Component {
11519
11577
  createChart(chartData) {
11520
11578
  const canvas = this.canvas.el;
11521
11579
  const ctx = canvas.getContext("2d");
11522
- const Chart = getChartJSConstructor();
11523
- this.chart = new Chart(ctx, chartData);
11580
+ this.chart = new window.Chart(ctx, chartData);
11524
11581
  }
11525
11582
  updateChartJs(chartData) {
11526
11583
  if (chartData.data && chartData.data.datasets) {
@@ -19825,7 +19882,7 @@ const IF = {
19825
19882
  return { value: "" };
19826
19883
  }
19827
19884
  if (result.value === null) {
19828
- result.value = "";
19885
+ return { ...result, value: "" };
19829
19886
  }
19830
19887
  return result;
19831
19888
  },
@@ -19846,7 +19903,7 @@ const IFERROR = {
19846
19903
  return { value: "" };
19847
19904
  }
19848
19905
  if (result.value === null) {
19849
- result.value = "";
19906
+ return { ...result, value: "" };
19850
19907
  }
19851
19908
  return result;
19852
19909
  },
@@ -19867,7 +19924,7 @@ const IFNA = {
19867
19924
  return { value: "" };
19868
19925
  }
19869
19926
  if (result.value === null) {
19870
- result.value = "";
19927
+ return { ...result, value: "" };
19871
19928
  }
19872
19929
  return result;
19873
19930
  },
@@ -19893,7 +19950,7 @@ const IFS = {
19893
19950
  return { value: "" };
19894
19951
  }
19895
19952
  if (result.value === null) {
19896
- result.value = "";
19953
+ return { ...result, value: "" };
19897
19954
  }
19898
19955
  return result;
19899
19956
  }
@@ -20040,6 +20097,11 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
20040
20097
  if (range === undefined || range.invalidXc || range.invalidSheetName) {
20041
20098
  throw new InvalidReferenceError();
20042
20099
  }
20100
+ if (evalContext.__originCellPosition &&
20101
+ range.sheetId === evalContext.__originSheetId &&
20102
+ isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
20103
+ throw new CircularDependencyError();
20104
+ }
20043
20105
  dependencies.push(range);
20044
20106
  }
20045
20107
  for (const measure of forMeasures) {
@@ -24399,6 +24461,7 @@ const CHART_COMMON_OPTIONS = {
24399
24461
  },
24400
24462
  },
24401
24463
  animation: false,
24464
+ events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "mouseup"],
24402
24465
  };
24403
24466
  function chartToImageUrl(runtime, figure, type) {
24404
24467
  // wrap the canvas in a div with a fixed size because chart.js would
@@ -24448,8 +24511,7 @@ async function chartToImageFile(runtime, figure, type) {
24448
24511
  if ("chartJsConfig" in runtime) {
24449
24512
  const config = deepCopy(runtime.chartJsConfig);
24450
24513
  config.plugins = [backgroundColorChartJSPlugin];
24451
- const Chart = getChartJSConstructor();
24452
- const chart = new Chart(canvas, config);
24514
+ const chart = new window.Chart(canvas, config);
24453
24515
  chartBlob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
24454
24516
  chart.destroy();
24455
24517
  }
@@ -25201,11 +25263,10 @@ function canBeLinearChart(definition, dataSets, labelRange, getters) {
25201
25263
  }
25202
25264
  let missingTimeAdapterAlreadyWarned = false;
25203
25265
  function isLuxonTimeAdapterInstalled() {
25204
- const Chart = getChartJSConstructor();
25205
- if (!Chart) {
25266
+ if (!window.Chart) {
25206
25267
  return false;
25207
25268
  }
25208
- const adapter = new Chart._adapters._date({});
25269
+ const adapter = new window.Chart._adapters._date({});
25209
25270
  // @ts-ignore
25210
25271
  const isInstalled = adapter._id === "luxon";
25211
25272
  if (!isInstalled && !missingTimeAdapterAlreadyWarned) {
@@ -25703,6 +25764,9 @@ const INTERACTIVE_LEGEND_CONFIG = {
25703
25764
  target.style.cursor = "default";
25704
25765
  },
25705
25766
  onClick: (event, legendItem, legend) => {
25767
+ if (event.type !== "click") {
25768
+ return;
25769
+ }
25706
25770
  const index = legendItem.datasetIndex;
25707
25771
  if (!legend.legendItems || index === undefined) {
25708
25772
  return;
@@ -34849,6 +34913,7 @@ function repairInitialMessages(data, initialMessages) {
34849
34913
  initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
34850
34914
  initialMessages = fixChartDefinitions(data, initialMessages);
34851
34915
  initialMessages = fixFigureOffset(data, initialMessages);
34916
+ initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
34852
34917
  return initialMessages;
34853
34918
  }
34854
34919
  /**
@@ -34981,6 +35046,42 @@ function fixFigureOffset(data, messages) {
34981
35046
  }
34982
35047
  return messages;
34983
35048
  }
35049
+ function fixTranslatedDuplicateSheetName(data, initialMessages) {
35050
+ const sheetNames = {};
35051
+ for (const sheet of data.sheets || []) {
35052
+ sheetNames[sheet.id] = sheet.name;
35053
+ }
35054
+ const messages = [];
35055
+ for (const message of initialMessages) {
35056
+ if (message.type === "REMOTE_REVISION") {
35057
+ const commands = [];
35058
+ for (const cmd of message.commands) {
35059
+ switch (cmd.type) {
35060
+ case "DUPLICATE_SHEET":
35061
+ cmd.sheetNameTo =
35062
+ cmd.sheetNameTo ??
35063
+ getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
35064
+ break;
35065
+ case "CREATE_SHEET":
35066
+ sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
35067
+ break;
35068
+ case "RENAME_SHEET":
35069
+ sheetNames[cmd.sheetId] = cmd.newName || getNextSheetName(Object.values(sheetNames));
35070
+ break;
35071
+ }
35072
+ commands.push(cmd);
35073
+ }
35074
+ messages.push({
35075
+ ...message,
35076
+ commands,
35077
+ });
35078
+ }
35079
+ else {
35080
+ messages.push(message);
35081
+ }
35082
+ }
35083
+ return initialMessages;
35084
+ }
34984
35085
  // -----------------------------------------------------------------------------
34985
35086
  // Helpers
34986
35087
  // -----------------------------------------------------------------------------
@@ -36039,10 +36140,13 @@ const duplicateSheet = {
36039
36140
  name: _t("Duplicate"),
36040
36141
  execute: (env) => {
36041
36142
  const sheetIdFrom = env.model.getters.getActiveSheetId();
36143
+ const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
36042
36144
  const sheetIdTo = env.model.uuidGenerator.smallUuid();
36145
+ const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
36043
36146
  env.model.dispatch("DUPLICATE_SHEET", {
36044
36147
  sheetId: sheetIdFrom,
36045
36148
  sheetIdTo,
36149
+ sheetNameTo,
36046
36150
  });
36047
36151
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
36048
36152
  },
@@ -40683,7 +40787,7 @@ class GenericChartConfigPanel extends owl.Component {
40683
40787
  const cancelledReasons = [
40684
40788
  ...(this.state.datasetDispatchResult?.reasons || []),
40685
40789
  ...(this.state.labelsDispatchResult?.reasons || []),
40686
- ];
40790
+ ].filter((reason) => reason !== "NoChanges" /* CommandResult.NoChanges */);
40687
40791
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
40688
40792
  }
40689
40793
  get isDatasetInvalid() {
@@ -43215,6 +43319,13 @@ class Composer extends owl.Component {
43215
43319
  openAssistant() {
43216
43320
  this.assistant.forcedClosed = false;
43217
43321
  }
43322
+ onWheel(event) {
43323
+ // detect if scrollbar is available
43324
+ if (this.composerRef.el &&
43325
+ this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
43326
+ event.stopPropagation();
43327
+ }
43328
+ }
43218
43329
  // ---------------------------------------------------------------------------
43219
43330
  // Private
43220
43331
  // ---------------------------------------------------------------------------
@@ -48939,8 +49050,8 @@ function compareDimensionValues(dimension, a, b) {
48939
49050
 
48940
49051
  const NULL_SYMBOL = Symbol("NULL");
48941
49052
  function createDate(dimension, value, locale) {
48942
- const granularity = dimension.granularity;
48943
- if (!granularity || !(granularity in MAP_VALUE_DIMENSION_DATE)) {
49053
+ const granularity = dimension.granularity || "month";
49054
+ if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
48944
49055
  throw new Error(`Unknown date granularity: ${granularity}`);
48945
49056
  }
48946
49057
  const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
@@ -48959,6 +49070,9 @@ function createDate(dimension, value, locale) {
48959
49070
  case "month_number":
48960
49071
  number = date.getMonth() + 1;
48961
49072
  break;
49073
+ case "month":
49074
+ number = Math.floor(toNumber(value, locale));
49075
+ break;
48962
49076
  case "iso_week_number":
48963
49077
  number = date.getIsoWeek();
48964
49078
  break;
@@ -49052,6 +49166,10 @@ const MAP_VALUE_DIMENSION_DATE = {
49052
49166
  set: new Set(),
49053
49167
  values: {},
49054
49168
  },
49169
+ month: {
49170
+ set: new Set(),
49171
+ values: {},
49172
+ },
49055
49173
  iso_week_number: {
49056
49174
  set: new Set(),
49057
49175
  values: {},
@@ -49262,7 +49380,7 @@ class SpreadsheetPivot {
49262
49380
  const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
49263
49381
  const finalCell = cells[0]?.[dimension.nameWithGranularity];
49264
49382
  if (dimension.type === "datetime") {
49265
- const adapter = pivotTimeAdapter(dimension.granularity);
49383
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
49266
49384
  return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
49267
49385
  }
49268
49386
  if (!finalCell) {
@@ -49380,7 +49498,7 @@ class SpreadsheetPivot {
49380
49498
  if (nonEmptyCells.length === 0) {
49381
49499
  return "integer";
49382
49500
  }
49383
- if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
49501
+ if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
49384
49502
  return "datetime";
49385
49503
  }
49386
49504
  if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
@@ -49473,7 +49591,7 @@ class SpreadsheetPivot {
49473
49591
  for (const entry of dataEntries) {
49474
49592
  for (const dimension of dateDimensions) {
49475
49593
  const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
49476
- const adapter = pivotTimeAdapter(dimension.granularity);
49594
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
49477
49595
  const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
49478
49596
  entry[dimension.nameWithGranularity] = {
49479
49597
  value,
@@ -49493,6 +49611,7 @@ const dateGranularities = [
49493
49611
  "year",
49494
49612
  "quarter_number",
49495
49613
  "month_number",
49614
+ "month",
49496
49615
  "iso_week_number",
49497
49616
  "day_of_month",
49498
49617
  "day",
@@ -49743,7 +49862,7 @@ class PivotSidePanelStore extends SpreadsheetStore {
49743
49862
  : this.datetimeGranularities);
49744
49863
  }
49745
49864
  for (const field of dateFields) {
49746
- granularitiesPerFields[field.fieldName].delete(field.granularity);
49865
+ granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
49747
49866
  }
49748
49867
  return granularitiesPerFields;
49749
49868
  }
@@ -52083,6 +52202,8 @@ class GridComposer extends owl.Component {
52083
52202
  }
52084
52203
  get composerProps() {
52085
52204
  const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
52205
+ // Remove the wrapper border width
52206
+ const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
52086
52207
  return {
52087
52208
  rect: { ...this.rect },
52088
52209
  delimitation: {
@@ -52100,6 +52221,7 @@ class GridComposer extends owl.Component {
52100
52221
  }),
52101
52222
  onInputContextMenu: this.props.onInputContextMenu,
52102
52223
  composerStore: this.composerStore,
52224
+ inputStyle: `max-height: ${maxHeight}px;`,
52103
52225
  };
52104
52226
  }
52105
52227
  get containerStyle() {
@@ -57421,7 +57543,7 @@ class ChartPlugin extends CorePlugin {
57421
57543
  case "CREATE_CHART":
57422
57544
  return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartDuplicate));
57423
57545
  case "UPDATE_CHART":
57424
- return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists));
57546
+ return this.checkValidations(cmd, this.chainValidations(this.validateChartDefinition, this.checkChartExists, this.checkChartChanged));
57425
57547
  default:
57426
57548
  return "Success" /* CommandResult.Success */;
57427
57549
  }
@@ -57575,10 +57697,15 @@ class ChartPlugin extends CorePlugin {
57575
57697
  : "Success" /* CommandResult.Success */;
57576
57698
  }
57577
57699
  checkChartExists(cmd) {
57578
- return this.getters.getFigureSheetId(cmd.figureId)
57700
+ return this.isChartDefined(cmd.figureId)
57579
57701
  ? "Success" /* CommandResult.Success */
57580
57702
  : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
57581
57703
  }
57704
+ checkChartChanged(cmd) {
57705
+ return deepEquals(this.getChartDefinition(cmd.figureId), cmd.definition)
57706
+ ? "NoChanges" /* CommandResult.NoChanges */
57707
+ : "Success" /* CommandResult.Success */;
57708
+ }
57582
57709
  }
57583
57710
 
57584
57711
  // -----------------------------------------------------------------------------
@@ -59836,6 +59963,7 @@ class SheetPlugin extends CorePlugin {
59836
59963
  "getCommandZones",
59837
59964
  "getUnboundedZone",
59838
59965
  "checkElementsIncludeAllNonFrozenHeaders",
59966
+ "getDuplicateSheetName",
59839
59967
  ];
59840
59968
  sheetIdsMapName = {};
59841
59969
  orderedSheetIds = [];
@@ -59860,7 +59988,11 @@ class SheetPlugin extends CorePlugin {
59860
59988
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
59861
59989
  }
59862
59990
  case "DUPLICATE_SHEET": {
59863
- return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
59991
+ if (this.sheets[cmd.sheetIdTo])
59992
+ return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
59993
+ if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
59994
+ return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
59995
+ return "Success" /* CommandResult.Success */;
59864
59996
  }
59865
59997
  case "MOVE_SHEET":
59866
59998
  try {
@@ -59937,7 +60069,7 @@ class SheetPlugin extends CorePlugin {
59937
60069
  this.showSheet(cmd.sheetId);
59938
60070
  break;
59939
60071
  case "DUPLICATE_SHEET":
59940
- this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
60072
+ this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
59941
60073
  break;
59942
60074
  case "DELETE_SHEET":
59943
60075
  this.deleteSheet(this.sheets[cmd.sheetId]);
@@ -60144,10 +60276,7 @@ class SheetPlugin extends CorePlugin {
60144
60276
  }
60145
60277
  getNextSheetName(baseName = "Sheet") {
60146
60278
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
60147
- return getUniqueText(baseName, names, {
60148
- compute: (name, i) => `${name}${i}`,
60149
- computeFirstOne: true,
60150
- });
60279
+ return getNextSheetName(names, baseName);
60151
60280
  }
60152
60281
  getSheetSize(sheetId) {
60153
60282
  return {
@@ -60394,9 +60523,8 @@ class SheetPlugin extends CorePlugin {
60394
60523
  showSheet(sheetId) {
60395
60524
  this.history.update("sheets", sheetId, "isVisible", true);
60396
60525
  }
60397
- duplicateSheet(fromId, toId) {
60526
+ duplicateSheet(fromId, toId, toName) {
60398
60527
  const sheet = this.getSheet(fromId);
60399
- const toName = this.getDuplicateSheetName(sheet.name);
60400
60528
  const newSheet = deepCopy(sheet);
60401
60529
  newSheet.id = toId;
60402
60530
  newSheet.name = toName;
@@ -60429,8 +60557,7 @@ class SheetPlugin extends CorePlugin {
60429
60557
  }
60430
60558
  getDuplicateSheetName(sheetName) {
60431
60559
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
60432
- const baseName = _t("Copy of %s", sheetName);
60433
- return getUniqueText(baseName.toString(), names);
60560
+ return getDuplicateSheetName(sheetName, names);
60434
60561
  }
60435
60562
  deleteSheet(sheet) {
60436
60563
  const name = sheet.name;
@@ -63234,8 +63361,8 @@ class SpreadingRelation {
63234
63361
  const EMPTY_ARRAY = [];
63235
63362
 
63236
63363
  const MAX_ITERATION = 30;
63237
- const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
63238
- const EMPTY_CELL = createEvaluatedCell({ value: null });
63364
+ const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
63365
+ const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
63239
63366
  class Evaluator {
63240
63367
  context;
63241
63368
  getters;
@@ -75338,11 +75465,13 @@ class Spreadsheet extends owl.Component {
75338
75465
  this.checkViewportSize();
75339
75466
  stores.on("store-updated", this, render);
75340
75467
  resizeObserver.observe(this.spreadsheetRef.el);
75468
+ registerChartJSExtensions();
75341
75469
  });
75342
75470
  owl.onWillUnmount(() => {
75343
75471
  this.unbindModelEvents();
75344
75472
  stores.off("store-updated", this);
75345
75473
  resizeObserver.disconnect();
75474
+ unregisterChartJsExtensions();
75346
75475
  });
75347
75476
  owl.onPatched(() => {
75348
75477
  this.checkViewportSize();
@@ -79881,6 +80010,6 @@ exports.tokenColors = tokenColors;
79881
80010
  exports.tokenize = tokenize;
79882
80011
 
79883
80012
 
79884
- __info__.version = "18.3.1";
79885
- __info__.date = "2025-05-02T12:33:27.384Z";
79886
- __info__.hash = "7b9574b";
80013
+ __info__.version = "18.3.2";
80014
+ __info__.date = "2025-05-12T05:25:42.099Z";
80015
+ __info__.hash = "57d5a67";
@@ -6,7 +6,6 @@ import * as _odoo_owl from '@odoo/owl';
6
6
  import { ComponentConstructor, Component } from '@odoo/owl';
7
7
  import * as chart_js_dist_types_utils from 'chart.js/dist/types/utils';
8
8
  import * as chart_js_dist_types_geometric from 'chart.js/dist/types/geometric';
9
- import * as chart_js_dist_types_basic from 'chart.js/dist/types/basic';
10
9
 
11
10
  interface FigureInfo {
12
11
  id: UID;
@@ -2742,6 +2741,7 @@ interface DeleteSheetCommand extends SheetDependentCommand, SheetEditingCommand
2742
2741
  interface DuplicateSheetCommand extends SheetDependentCommand {
2743
2742
  type: "DUPLICATE_SHEET";
2744
2743
  sheetIdTo: UID;
2744
+ sheetNameTo: string;
2745
2745
  }
2746
2746
  interface MoveSheetCommand extends SheetDependentCommand {
2747
2747
  type: "MOVE_SHEET";
@@ -4660,6 +4660,7 @@ declare class ChartPlugin extends CorePlugin<ChartState> implements ChartState {
4660
4660
  private addChart;
4661
4661
  private checkChartDuplicate;
4662
4662
  private checkChartExists;
4663
+ private checkChartChanged;
4663
4664
  }
4664
4665
 
4665
4666
  interface ConditionalFormatState {
@@ -5084,7 +5085,7 @@ interface SheetState {
5084
5085
  readonly cellPosition: Record<UID, CellPosition | undefined>;
5085
5086
  }
5086
5087
  declare class SheetPlugin extends CorePlugin<SheetState> implements SheetState {
5087
- 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"];
5088
+ 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"];
5088
5089
  readonly sheetIdsMapName: Record<string, UID | undefined>;
5089
5090
  readonly orderedSheetIds: UID[];
5090
5091
  readonly sheets: Record<UID, Sheet | undefined>;
@@ -5161,7 +5162,7 @@ declare class SheetPlugin extends CorePlugin<SheetState> implements SheetState {
5161
5162
  private hideSheet;
5162
5163
  private showSheet;
5163
5164
  private duplicateSheet;
5164
- private getDuplicateSheetName;
5165
+ getDuplicateSheetName(sheetName: string): string;
5165
5166
  private deleteSheet;
5166
5167
  /**
5167
5168
  * Delete column. This requires a lot of handling:
@@ -8513,6 +8514,7 @@ declare class Composer extends Component<CellComposerProps, SpreadsheetChildEnv>
8513
8514
  onContextMenu(ev: MouseEvent): void;
8514
8515
  closeAssistant(): void;
8515
8516
  openAssistant(): void;
8517
+ onWheel(event: WheelEvent): void;
8516
8518
  private processContent;
8517
8519
  /**
8518
8520
  * Get the HTML content corresponding to the current composer token, divided by lines.
@@ -11778,7 +11780,10 @@ declare const registries: {
11778
11780
  supportedPivotPositionalFormulaRegistry: Registry<boolean>;
11779
11781
  pivotToFunctionValueRegistry: Registry<(value: CellValue, granularity?: string) => string>;
11780
11782
  migrationStepRegistry: Registry<MigrationStep>;
11781
- chartJsExtensionRegistry: Registry<chart_js.Plugin<keyof chart_js.ChartTypeRegistry, chart_js_dist_types_basic.AnyObject> | ((chart: typeof window.Chart) => void)>;
11783
+ chartJsExtensionRegistry: Registry<{
11784
+ register: (chart: typeof window.Chart) => void;
11785
+ unregister: (chart: typeof window.Chart) => void;
11786
+ }>;
11782
11787
  };
11783
11788
  declare const helpers: {
11784
11789
  arg: typeof arg;