@odoo/o-spreadsheet 18.1.17 → 18.1.19

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.1.17
6
- * @date 2025-04-25T08:08:46.599Z
7
- * @hash a63687f
5
+ * @version 18.1.19
6
+ * @date 2025-05-12T05:26:05.861Z
7
+ * @hash 44cc170
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -3761,6 +3761,7 @@
3761
3761
  CommandResult["ValueCellIsInvalidFormula"] = "ValueCellIsInvalidFormula";
3762
3762
  CommandResult["InvalidDefinition"] = "InvalidDefinition";
3763
3763
  CommandResult["InvalidColor"] = "InvalidColor";
3764
+ CommandResult["InvalidPivotDataSet"] = "InvalidPivotDataSet";
3764
3765
  })(exports.CommandResult || (exports.CommandResult = {}));
3765
3766
 
3766
3767
  const DEFAULT_LOCALES = [
@@ -6271,6 +6272,25 @@
6271
6272
  })
6272
6273
  .filter(isDefined);
6273
6274
  }
6275
+ function getNextSheetName(existingNames, baseName = "Sheet") {
6276
+ let i = 1;
6277
+ let name = `${baseName}${i}`;
6278
+ while (existingNames.includes(name)) {
6279
+ name = `${baseName}${i}`;
6280
+ i++;
6281
+ }
6282
+ return name;
6283
+ }
6284
+ function getDuplicateSheetName(nameToDuplicate, existingNames) {
6285
+ let i = 1;
6286
+ const baseName = _t("Copy of %s", nameToDuplicate);
6287
+ let name = baseName.toString();
6288
+ while (existingNames.includes(name)) {
6289
+ name = `${baseName} (${i})`;
6290
+ i++;
6291
+ }
6292
+ return name;
6293
+ }
6274
6294
 
6275
6295
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
6276
6296
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -7969,6 +7989,24 @@
7969
7989
  return `${normalizedValue}`;
7970
7990
  },
7971
7991
  };
7992
+ /**
7993
+ * normalizes month number + year
7994
+ */
7995
+ const monthAdapter = {
7996
+ normalizeFunctionValue(value) {
7997
+ const date = toNumber(value, DEFAULT_LOCALE);
7998
+ return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
7999
+ },
8000
+ toValueAndFormat(normalizedValue) {
8001
+ return {
8002
+ value: toNumber(normalizedValue, DEFAULT_LOCALE),
8003
+ format: "mmmm yyyy",
8004
+ };
8005
+ },
8006
+ toFunctionValue(normalizedValue) {
8007
+ return `"${normalizedValue}"`;
8008
+ },
8009
+ };
7972
8010
  /**
7973
8011
  * normalizes quarter number
7974
8012
  */
@@ -8099,6 +8137,7 @@
8099
8137
  .add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
8100
8138
  .add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
8101
8139
  .add("month_number", nullHandlerDecorator(monthNumberAdapter))
8140
+ .add("month", nullHandlerDecorator(monthAdapter))
8102
8141
  .add("quarter_number", nullHandlerDecorator(quarterNumberAdapter))
8103
8142
  .add("day_of_week", nullHandlerDecorator(dayOfWeekAdapter))
8104
8143
  .add("hour_number", nullHandlerDecorator(hourNumberAdapter))
@@ -8278,10 +8317,7 @@
8278
8317
  return normalizer(groupValueString, dimension.granularity);
8279
8318
  }
8280
8319
  function normalizeDateTime(value, granularity) {
8281
- if (!granularity) {
8282
- throw new Error("Missing granularity");
8283
- }
8284
- return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
8320
+ return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
8285
8321
  }
8286
8322
  function toFunctionPivotValue(value, dimension) {
8287
8323
  if (value === null) {
@@ -8293,10 +8329,7 @@
8293
8329
  return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
8294
8330
  }
8295
8331
  function toFunctionValueDateTime(value, granularity) {
8296
- if (!granularity) {
8297
- throw new Error("Missing granularity");
8298
- }
8299
- return pivotTimeAdapter(granularity).toFunctionValue(value);
8332
+ return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
8300
8333
  }
8301
8334
  const pivotNormalizationValueRegistry = new Registry();
8302
8335
  pivotNormalizationValueRegistry
@@ -9611,12 +9644,24 @@ stores.inject(MyMetaStore, storeInstance);
9611
9644
  }
9612
9645
 
9613
9646
  const chartJsExtensionRegistry = new Registry();
9614
- /** Return window.Chart, making sure all our extensions are loaded in ChartJS */
9615
- function getChartJSConstructor() {
9616
- if (window.Chart && !window.Chart?.registry.plugins.get("chartShowValuesPlugin")) {
9617
- window.Chart.register(...chartJsExtensionRegistry.getAll());
9647
+ function areChartJSExtensionsLoaded() {
9648
+ return !!window.Chart.registry.plugins.get("chartShowValuesPlugin");
9649
+ }
9650
+ function registerChartJSExtensions() {
9651
+ if (!window.Chart || areChartJSExtensionsLoaded()) {
9652
+ return;
9653
+ }
9654
+ for (const registryItem of chartJsExtensionRegistry.getAll()) {
9655
+ registryItem.register(window.Chart);
9656
+ }
9657
+ }
9658
+ function unregisterChartJsExtensions() {
9659
+ if (!window.Chart) {
9660
+ return;
9661
+ }
9662
+ for (const registryItem of chartJsExtensionRegistry.getAll()) {
9663
+ registryItem.unregister(window.Chart);
9618
9664
  }
9619
- return window.Chart;
9620
9665
  }
9621
9666
 
9622
9667
  const TREND_LINE_XAXIS_ID = "x1";
@@ -10008,7 +10053,7 @@ stores.inject(MyMetaStore, storeInstance);
10008
10053
  const yMin = chart.chartArea.top;
10009
10054
  const textsPositions = {};
10010
10055
  for (const dataset of chart._metasets) {
10011
- if (isTrendLineAxis(dataset.axisID) || dataset.hidden) {
10056
+ if (isTrendLineAxis(dataset.xAxisID) || dataset.hidden) {
10012
10057
  continue;
10013
10058
  }
10014
10059
  for (let i = 0; i < dataset._parsed.length; i++) {
@@ -10051,7 +10096,7 @@ stores.inject(MyMetaStore, storeInstance);
10051
10096
  const xMin = chart.chartArea.left;
10052
10097
  const textsPositions = {};
10053
10098
  for (const dataset of chart._metasets) {
10054
- if (isTrendLineAxis(dataset.axisID)) {
10099
+ if (isTrendLineAxis(dataset.xAxisID)) {
10055
10100
  return; // ignore trend lines
10056
10101
  }
10057
10102
  for (let i = 0; i < dataset._parsed.length; i++) {
@@ -10157,8 +10202,14 @@ stores.inject(MyMetaStore, storeInstance);
10157
10202
  return bars.find((bar, i) => i > startIndex && bar.height !== 0);
10158
10203
  }
10159
10204
 
10160
- chartJsExtensionRegistry.add("chartShowValuesPlugin", chartShowValuesPlugin);
10161
- chartJsExtensionRegistry.add("waterfallLinesPlugin", waterfallLinesPlugin);
10205
+ chartJsExtensionRegistry.add("chartShowValuesPlugin", {
10206
+ register: (Chart) => Chart.register(chartShowValuesPlugin),
10207
+ unregister: (Chart) => Chart.unregister(chartShowValuesPlugin),
10208
+ });
10209
+ chartJsExtensionRegistry.add("waterfallLinesPlugin", {
10210
+ register: (Chart) => Chart.register(waterfallLinesPlugin),
10211
+ unregister: (Chart) => Chart.unregister(waterfallLinesPlugin),
10212
+ });
10162
10213
  class ChartJsComponent extends owl.Component {
10163
10214
  static template = "o-spreadsheet-ChartJsComponent";
10164
10215
  static props = {
@@ -10167,6 +10218,7 @@ stores.inject(MyMetaStore, storeInstance);
10167
10218
  canvas = owl.useRef("graphContainer");
10168
10219
  chart;
10169
10220
  currentRuntime;
10221
+ currentDevicePixelRatio = window.devicePixelRatio;
10170
10222
  get background() {
10171
10223
  return this.chartRuntime.background;
10172
10224
  }
@@ -10200,13 +10252,16 @@ stores.inject(MyMetaStore, storeInstance);
10200
10252
  }
10201
10253
  this.currentRuntime = runtime;
10202
10254
  }
10255
+ else if (this.currentDevicePixelRatio !== window.devicePixelRatio) {
10256
+ this.currentDevicePixelRatio = window.devicePixelRatio;
10257
+ this.updateChartJs(deepCopy(this.currentRuntime.chartJsConfig));
10258
+ }
10203
10259
  });
10204
10260
  }
10205
10261
  createChart(chartData) {
10206
10262
  const canvas = this.canvas.el;
10207
10263
  const ctx = canvas.getContext("2d");
10208
- const Chart = getChartJSConstructor();
10209
- this.chart = new Chart(ctx, chartData);
10264
+ this.chart = new window.Chart(ctx, chartData);
10210
10265
  }
10211
10266
  updateChartJs(chartData) {
10212
10267
  if (chartData.data && chartData.data.datasets) {
@@ -10455,9 +10510,11 @@ stores.inject(MyMetaStore, storeInstance);
10455
10510
  };
10456
10511
  function drawScoreChart(structure, canvas) {
10457
10512
  const ctx = canvas.getContext("2d");
10458
- canvas.width = structure.canvas.width;
10459
- const availableWidth = canvas.width - CHART_PADDING$1 * 2;
10460
- canvas.height = structure.canvas.height;
10513
+ const dpr = window.devicePixelRatio || 1;
10514
+ canvas.width = dpr * structure.canvas.width;
10515
+ canvas.height = dpr * structure.canvas.height;
10516
+ ctx.scale(dpr, dpr);
10517
+ const availableWidth = structure.canvas.width - CHART_PADDING$1 * 2;
10461
10518
  ctx.fillStyle = structure.canvas.backgroundColor;
10462
10519
  ctx.fillRect(0, 0, structure.canvas.width, structure.canvas.height);
10463
10520
  if (structure.title) {
@@ -10820,7 +10877,7 @@ stores.inject(MyMetaStore, storeInstance);
10820
10877
  owl.useEffect(this.createChart.bind(this), () => {
10821
10878
  const canvas = this.canvas.el;
10822
10879
  const rect = canvas.getBoundingClientRect();
10823
- return [rect.width, rect.height, this.runtime, this.canvas.el];
10880
+ return [rect.width, rect.height, this.runtime, this.canvas.el, window.devicePixelRatio];
10824
10881
  });
10825
10882
  }
10826
10883
  createChart() {
@@ -18336,7 +18393,7 @@ stores.inject(MyMetaStore, storeInstance);
18336
18393
  return { value: "" };
18337
18394
  }
18338
18395
  if (result.value === null) {
18339
- result.value = "";
18396
+ return { ...result, value: "" };
18340
18397
  }
18341
18398
  return result;
18342
18399
  },
@@ -18357,7 +18414,7 @@ stores.inject(MyMetaStore, storeInstance);
18357
18414
  return { value: "" };
18358
18415
  }
18359
18416
  if (result.value === null) {
18360
- result.value = "";
18417
+ return { ...result, value: "" };
18361
18418
  }
18362
18419
  return result;
18363
18420
  },
@@ -18378,7 +18435,7 @@ stores.inject(MyMetaStore, storeInstance);
18378
18435
  return { value: "" };
18379
18436
  }
18380
18437
  if (result.value === null) {
18381
- result.value = "";
18438
+ return { ...result, value: "" };
18382
18439
  }
18383
18440
  return result;
18384
18441
  },
@@ -18404,7 +18461,7 @@ stores.inject(MyMetaStore, storeInstance);
18404
18461
  return { value: "" };
18405
18462
  }
18406
18463
  if (result.value === null) {
18407
- result.value = "";
18464
+ return { ...result, value: "" };
18408
18465
  }
18409
18466
  return result;
18410
18467
  }
@@ -18522,6 +18579,11 @@ stores.inject(MyMetaStore, storeInstance);
18522
18579
  if (range === undefined || range.invalidXc || range.invalidSheetName) {
18523
18580
  throw new InvalidReferenceError();
18524
18581
  }
18582
+ if (evalContext.__originCellPosition &&
18583
+ range.sheetId === evalContext.__originSheetId &&
18584
+ isZoneInside(positionToZone(evalContext.__originCellPosition), zone)) {
18585
+ throw new CircularDependencyError();
18586
+ }
18525
18587
  dependencies.push(range);
18526
18588
  }
18527
18589
  for (const measure of forMeasures) {
@@ -22409,9 +22471,11 @@ stores.inject(MyMetaStore, storeInstance);
22409
22471
  const GAUGE_TITLE_SECTION_HEIGHT = 25;
22410
22472
  function drawGaugeChart(canvas, runtime) {
22411
22473
  const canvasBoundingRect = canvas.getBoundingClientRect();
22412
- canvas.width = canvasBoundingRect.width;
22413
- canvas.height = canvasBoundingRect.height;
22474
+ const dpr = window.devicePixelRatio || 1;
22475
+ canvas.width = dpr * canvasBoundingRect.width;
22476
+ canvas.height = dpr * canvasBoundingRect.height;
22414
22477
  const ctx = canvas.getContext("2d");
22478
+ ctx.scale(dpr, dpr);
22415
22479
  const config = getGaugeRenderingConfig(canvasBoundingRect, runtime, ctx);
22416
22480
  drawBackground(ctx, config);
22417
22481
  drawGauge(ctx, config);
@@ -22746,7 +22810,7 @@ stores.inject(MyMetaStore, storeInstance);
22746
22810
  owl.useEffect(() => drawGaugeChart(this.canvas.el, this.runtime), () => {
22747
22811
  const canvas = this.canvas.el;
22748
22812
  const rect = canvas.getBoundingClientRect();
22749
- return [rect.width, rect.height, this.runtime, this.canvas.el];
22813
+ return [rect.width, rect.height, this.runtime, this.canvas.el, window.devicePixelRatio];
22750
22814
  });
22751
22815
  }
22752
22816
  }
@@ -22781,6 +22845,7 @@ stores.inject(MyMetaStore, storeInstance);
22781
22845
  },
22782
22846
  },
22783
22847
  animation: false,
22848
+ events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "mouseup"],
22784
22849
  };
22785
22850
  function truncateLabel(label) {
22786
22851
  if (!label) {
@@ -22806,8 +22871,7 @@ stores.inject(MyMetaStore, storeInstance);
22806
22871
  if ("chartJsConfig" in runtime) {
22807
22872
  const config = deepCopy(runtime.chartJsConfig);
22808
22873
  config.plugins = [backgroundColorChartJSPlugin];
22809
- const Chart = getChartJSConstructor();
22810
- const chart = new Chart(canvas, config);
22874
+ const chart = new window.Chart(canvas, config);
22811
22875
  const imgContent = chart.toBase64Image();
22812
22876
  chart.destroy();
22813
22877
  div.remove();
@@ -27939,6 +28003,7 @@ stores.inject(MyMetaStore, storeInstance);
27939
28003
  initialMessages = dropCommands(initialMessages, "SORT_CELLS");
27940
28004
  initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
27941
28005
  initialMessages = fixChartDefinitions(data, initialMessages);
28006
+ initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
27942
28007
  return initialMessages;
27943
28008
  }
27944
28009
  /**
@@ -28038,6 +28103,40 @@ stores.inject(MyMetaStore, storeInstance);
28038
28103
  }
28039
28104
  return messages;
28040
28105
  }
28106
+ function fixTranslatedDuplicateSheetName(data, initialMessages) {
28107
+ const sheetNames = {};
28108
+ for (const sheet of data.sheets || []) {
28109
+ sheetNames[sheet.id] = sheet.name;
28110
+ }
28111
+ const messages = [];
28112
+ for (const message of initialMessages) {
28113
+ if (message.type === "REMOTE_REVISION") {
28114
+ const commands = [];
28115
+ for (const cmd of message.commands) {
28116
+ switch (cmd.type) {
28117
+ case "DUPLICATE_SHEET":
28118
+ cmd.sheetNameTo =
28119
+ cmd.sheetNameTo ??
28120
+ getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
28121
+ break;
28122
+ case "CREATE_SHEET":
28123
+ case "RENAME_SHEET":
28124
+ sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
28125
+ break;
28126
+ }
28127
+ commands.push(cmd);
28128
+ }
28129
+ messages.push({
28130
+ ...message,
28131
+ commands,
28132
+ });
28133
+ }
28134
+ else {
28135
+ messages.push(message);
28136
+ }
28137
+ }
28138
+ return initialMessages;
28139
+ }
28041
28140
  // -----------------------------------------------------------------------------
28042
28141
  // Helpers
28043
28142
  // -----------------------------------------------------------------------------
@@ -28835,12 +28934,11 @@ stores.inject(MyMetaStore, storeInstance);
28835
28934
  }
28836
28935
  let missingTimeAdapterAlreadyWarned = false;
28837
28936
  function isLuxonTimeAdapterInstalled() {
28838
- const Chart = getChartJSConstructor();
28839
- if (!Chart) {
28937
+ if (!window.Chart) {
28840
28938
  return false;
28841
28939
  }
28842
28940
  // @ts-ignore
28843
- const adapter = new Chart._adapters._date({});
28941
+ const adapter = new window.Chart._adapters._date({});
28844
28942
  const isInstalled = adapter._id === "luxon";
28845
28943
  if (!isInstalled && !missingTimeAdapterAlreadyWarned) {
28846
28944
  missingTimeAdapterAlreadyWarned = true;
@@ -29478,6 +29576,9 @@ stores.inject(MyMetaStore, storeInstance);
29478
29576
  target.style.cursor = "default";
29479
29577
  },
29480
29578
  onClick: (event, legendItem, legend) => {
29579
+ if (event.type !== "click") {
29580
+ return;
29581
+ }
29481
29582
  const index = legendItem.datasetIndex;
29482
29583
  if (!legend.legendItems || index === undefined) {
29483
29584
  return;
@@ -29558,7 +29659,7 @@ stores.inject(MyMetaStore, storeInstance);
29558
29659
  };
29559
29660
  scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID] = {
29560
29661
  ...scales.x,
29561
- offset: false,
29662
+ offset: true,
29562
29663
  display: false,
29563
29664
  };
29564
29665
  }
@@ -30155,9 +30256,6 @@ stores.inject(MyMetaStore, storeInstance);
30155
30256
  };
30156
30257
  }
30157
30258
  getDefinitionForExcel() {
30158
- // Excel does not support aggregating labels
30159
- if (this.aggregated)
30160
- return undefined;
30161
30259
  const dataSets = this.dataSets
30162
30260
  .map((ds) => toExcelDataset(this.getters, ds))
30163
30261
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -30838,9 +30936,6 @@ stores.inject(MyMetaStore, storeInstance);
30838
30936
  return new LineChart(definition, this.sheetId, this.getters);
30839
30937
  }
30840
30938
  getDefinitionForExcel() {
30841
- // Excel does not support aggregating labels
30842
- if (this.aggregated)
30843
- return undefined;
30844
30939
  const dataSets = this.dataSets
30845
30940
  .map((ds) => toExcelDataset(this.getters, ds))
30846
30941
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -30977,9 +31072,6 @@ stores.inject(MyMetaStore, storeInstance);
30977
31072
  return new PieChart(definition, sheetId, this.getters);
30978
31073
  }
30979
31074
  getDefinitionForExcel() {
30980
- // Excel does not support aggregating labels
30981
- if (this.aggregated)
30982
- return undefined;
30983
31075
  const dataSets = this.dataSets
30984
31076
  .map((ds) => toExcelDataset(this.getters, ds))
30985
31077
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -33212,10 +33304,13 @@ stores.inject(MyMetaStore, storeInstance);
33212
33304
  name: _t("Duplicate"),
33213
33305
  execute: (env) => {
33214
33306
  const sheetIdFrom = env.model.getters.getActiveSheetId();
33307
+ const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
33215
33308
  const sheetIdTo = env.model.uuidGenerator.smallUuid();
33309
+ const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
33216
33310
  env.model.dispatch("DUPLICATE_SHEET", {
33217
33311
  sheetId: sheetIdFrom,
33218
33312
  sheetIdTo,
33313
+ sheetNameTo,
33219
33314
  });
33220
33315
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
33221
33316
  },
@@ -33455,18 +33550,28 @@ stores.inject(MyMetaStore, storeInstance);
33455
33550
  function useInterval(callback, delay) {
33456
33551
  let intervalId;
33457
33552
  const { setInterval, clearInterval } = window;
33553
+ const pause = () => {
33554
+ clearInterval(intervalId);
33555
+ intervalId = undefined;
33556
+ };
33557
+ const safeCallback = () => {
33558
+ try {
33559
+ callback();
33560
+ }
33561
+ catch (e) {
33562
+ pause();
33563
+ throw e;
33564
+ }
33565
+ };
33458
33566
  owl.useEffect(() => {
33459
- intervalId = setInterval(callback, delay);
33567
+ intervalId = setInterval(safeCallback, delay);
33460
33568
  return () => clearInterval(intervalId);
33461
33569
  }, () => [delay]);
33462
33570
  return {
33463
- pause: () => {
33464
- clearInterval(intervalId);
33465
- intervalId = undefined;
33466
- },
33571
+ pause,
33467
33572
  resume: () => {
33468
33573
  if (intervalId === undefined) {
33469
- intervalId = setInterval(callback, delay);
33574
+ intervalId = setInterval(safeCallback, delay);
33470
33575
  }
33471
33576
  },
33472
33577
  };
@@ -41025,6 +41130,13 @@ stores.inject(MyMetaStore, storeInstance);
41025
41130
  openAssistant() {
41026
41131
  this.assistant.forcedClosed = false;
41027
41132
  }
41133
+ onWheel(event) {
41134
+ // detect if scrollbar is available
41135
+ if (this.composerRef.el &&
41136
+ this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
41137
+ event.stopPropagation();
41138
+ }
41139
+ }
41028
41140
  // ---------------------------------------------------------------------------
41029
41141
  // Private
41030
41142
  // ---------------------------------------------------------------------------
@@ -45962,8 +46074,8 @@ stores.inject(MyMetaStore, storeInstance);
45962
46074
 
45963
46075
  const NULL_SYMBOL = Symbol("NULL");
45964
46076
  function createDate(dimension, value, locale) {
45965
- const granularity = dimension.granularity;
45966
- if (!granularity || !(granularity in MAP_VALUE_DIMENSION_DATE)) {
46077
+ const granularity = dimension.granularity || "month";
46078
+ if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
45967
46079
  throw new Error(`Unknown date granularity: ${granularity}`);
45968
46080
  }
45969
46081
  const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
@@ -45982,6 +46094,9 @@ stores.inject(MyMetaStore, storeInstance);
45982
46094
  case "month_number":
45983
46095
  number = date.getMonth() + 1;
45984
46096
  break;
46097
+ case "month":
46098
+ number = Math.floor(toNumber(value, locale));
46099
+ break;
45985
46100
  case "iso_week_number":
45986
46101
  number = date.getIsoWeek();
45987
46102
  break;
@@ -46075,6 +46190,10 @@ stores.inject(MyMetaStore, storeInstance);
46075
46190
  set: new Set(),
46076
46191
  values: {},
46077
46192
  },
46193
+ month: {
46194
+ set: new Set(),
46195
+ values: {},
46196
+ },
46078
46197
  iso_week_number: {
46079
46198
  set: new Set(),
46080
46199
  values: {},
@@ -46285,7 +46404,7 @@ stores.inject(MyMetaStore, storeInstance);
46285
46404
  const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
46286
46405
  const finalCell = cells[0]?.[dimension.nameWithGranularity];
46287
46406
  if (dimension.type === "datetime") {
46288
- const adapter = pivotTimeAdapter(dimension.granularity);
46407
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
46289
46408
  return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
46290
46409
  }
46291
46410
  if (!finalCell) {
@@ -46403,7 +46522,7 @@ stores.inject(MyMetaStore, storeInstance);
46403
46522
  if (nonEmptyCells.length === 0) {
46404
46523
  return "integer";
46405
46524
  }
46406
- if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
46525
+ if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
46407
46526
  return "datetime";
46408
46527
  }
46409
46528
  if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
@@ -46498,7 +46617,7 @@ stores.inject(MyMetaStore, storeInstance);
46498
46617
  for (const entry of dataEntries) {
46499
46618
  for (const dimension of dateDimensions) {
46500
46619
  const value = createDate(dimension, entry[dimension.fieldName]?.value || null, this.getters.getLocale());
46501
- const adapter = pivotTimeAdapter(dimension.granularity);
46620
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
46502
46621
  const { format, value: valueToFormat } = adapter.toValueAndFormat(value, locale);
46503
46622
  entry[dimension.nameWithGranularity] = {
46504
46623
  value,
@@ -46518,6 +46637,7 @@ stores.inject(MyMetaStore, storeInstance);
46518
46637
  "year",
46519
46638
  "quarter_number",
46520
46639
  "month_number",
46640
+ "month",
46521
46641
  "iso_week_number",
46522
46642
  "day_of_month",
46523
46643
  "day",
@@ -46765,7 +46885,7 @@ stores.inject(MyMetaStore, storeInstance);
46765
46885
  : this.datetimeGranularities);
46766
46886
  }
46767
46887
  for (const field of dateFields) {
46768
- granularitiesPerFields[field.fieldName].delete(field.granularity);
46888
+ granularitiesPerFields[field.fieldName].delete(field.granularity || "month");
46769
46889
  }
46770
46890
  return granularitiesPerFields;
46771
46891
  }
@@ -48940,6 +49060,8 @@ stores.inject(MyMetaStore, storeInstance);
48940
49060
  }
48941
49061
  get composerProps() {
48942
49062
  const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
49063
+ // Remove the wrapper border width
49064
+ const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
48943
49065
  return {
48944
49066
  rect: { ...this.rect },
48945
49067
  delimitation: {
@@ -48957,6 +49079,7 @@ stores.inject(MyMetaStore, storeInstance);
48957
49079
  }),
48958
49080
  onInputContextMenu: this.props.onInputContextMenu,
48959
49081
  composerStore: this.composerStore,
49082
+ inputStyle: `max-height: ${maxHeight}px;`,
48960
49083
  };
48961
49084
  }
48962
49085
  get containerStyle() {
@@ -50455,7 +50578,7 @@ stores.inject(MyMetaStore, storeInstance);
50455
50578
  position: absolute;
50456
50579
  top: 0;
50457
50580
  left: ${HEADER_WIDTH}px;
50458
- right: 0;
50581
+ right: ${SCROLLBAR_WIDTH}px;
50459
50582
  height: ${HEADER_HEIGHT}px;
50460
50583
  &.o-dragging {
50461
50584
  cursor: grabbing;
@@ -50621,9 +50744,8 @@ stores.inject(MyMetaStore, storeInstance);
50621
50744
  position: absolute;
50622
50745
  top: ${HEADER_HEIGHT}px;
50623
50746
  left: 0;
50624
- right: 0;
50747
+ bottom: ${SCROLLBAR_WIDTH}px;
50625
50748
  width: ${HEADER_WIDTH}px;
50626
- height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
50627
50749
  &.o-dragging {
50628
50750
  cursor: grabbing;
50629
50751
  }
@@ -54248,9 +54370,7 @@ stores.inject(MyMetaStore, storeInstance);
54248
54370
  : "Success" /* CommandResult.Success */;
54249
54371
  }
54250
54372
  checkChartExists(cmd) {
54251
- return this.getters.getFigureSheetId(cmd.id)
54252
- ? "Success" /* CommandResult.Success */
54253
- : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
54373
+ return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
54254
54374
  }
54255
54375
  }
54256
54376
 
@@ -56535,6 +56655,7 @@ stores.inject(MyMetaStore, storeInstance);
56535
56655
  "getCommandZones",
56536
56656
  "getUnboundedZone",
56537
56657
  "checkElementsIncludeAllNonFrozenHeaders",
56658
+ "getDuplicateSheetName",
56538
56659
  ];
56539
56660
  sheetIdsMapName = {};
56540
56661
  orderedSheetIds = [];
@@ -56559,7 +56680,11 @@ stores.inject(MyMetaStore, storeInstance);
56559
56680
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
56560
56681
  }
56561
56682
  case "DUPLICATE_SHEET": {
56562
- return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
56683
+ if (this.sheets[cmd.sheetIdTo])
56684
+ return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
56685
+ if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
56686
+ return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
56687
+ return "Success" /* CommandResult.Success */;
56563
56688
  }
56564
56689
  case "MOVE_SHEET":
56565
56690
  try {
@@ -56636,7 +56761,7 @@ stores.inject(MyMetaStore, storeInstance);
56636
56761
  this.showSheet(cmd.sheetId);
56637
56762
  break;
56638
56763
  case "DUPLICATE_SHEET":
56639
- this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
56764
+ this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
56640
56765
  break;
56641
56766
  case "DELETE_SHEET":
56642
56767
  this.deleteSheet(this.sheets[cmd.sheetId]);
@@ -56842,14 +56967,8 @@ stores.inject(MyMetaStore, storeInstance);
56842
56967
  return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
56843
56968
  }
56844
56969
  getNextSheetName(baseName = "Sheet") {
56845
- let i = 1;
56846
56970
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
56847
- let name = `${baseName}${i}`;
56848
- while (names.includes(name)) {
56849
- name = `${baseName}${i}`;
56850
- i++;
56851
- }
56852
- return name;
56971
+ return getNextSheetName(names, baseName);
56853
56972
  }
56854
56973
  getSheetSize(sheetId) {
56855
56974
  return {
@@ -57095,9 +57214,8 @@ stores.inject(MyMetaStore, storeInstance);
57095
57214
  showSheet(sheetId) {
57096
57215
  this.history.update("sheets", sheetId, "isVisible", true);
57097
57216
  }
57098
- duplicateSheet(fromId, toId) {
57217
+ duplicateSheet(fromId, toId, toName) {
57099
57218
  const sheet = this.getSheet(fromId);
57100
- const toName = this.getDuplicateSheetName(sheet.name);
57101
57219
  const newSheet = deepCopy(sheet);
57102
57220
  newSheet.id = toId;
57103
57221
  newSheet.name = toName;
@@ -57129,15 +57247,8 @@ stores.inject(MyMetaStore, storeInstance);
57129
57247
  this.history.update("sheetIdsMapName", sheetIdsMapName);
57130
57248
  }
57131
57249
  getDuplicateSheetName(sheetName) {
57132
- let i = 1;
57133
57250
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
57134
- const baseName = _t("Copy of %s", sheetName);
57135
- let name = baseName.toString();
57136
- while (names.includes(name)) {
57137
- name = `${baseName} (${i})`;
57138
- i++;
57139
- }
57140
- return name;
57251
+ return getDuplicateSheetName(sheetName, names);
57141
57252
  }
57142
57253
  deleteSheet(sheet) {
57143
57254
  const name = sheet.name;
@@ -58624,6 +58735,15 @@ stores.inject(MyMetaStore, storeInstance);
58624
58735
  }
58625
58736
  }
58626
58737
  class SpreadsheetPivotCorePlugin extends CorePlugin {
58738
+ allowDispatch(cmd) {
58739
+ switch (cmd.type) {
58740
+ case "ADD_PIVOT":
58741
+ case "UPDATE_PIVOT":
58742
+ const definition = cmd.pivot;
58743
+ return this.checkDataSetValidity(definition);
58744
+ }
58745
+ return "Success" /* CommandResult.Success */;
58746
+ }
58627
58747
  adaptRanges(applyChange) {
58628
58748
  for (const pivotId of this.getters.getPivotIds()) {
58629
58749
  const definition = this.getters.getPivotCoreDefinition(pivotId);
@@ -58642,6 +58762,16 @@ stores.inject(MyMetaStore, storeInstance);
58642
58762
  }
58643
58763
  }
58644
58764
  }
58765
+ checkDataSetValidity(definition) {
58766
+ if (definition.type === "SPREADSHEET" && definition.dataSet) {
58767
+ const { zone, sheetId } = definition.dataSet;
58768
+ if (!sheetId || !this.getters.tryGetSheet(sheetId) || !zone || !isZoneValid(zone)) {
58769
+ return "InvalidDataSet" /* CommandResult.InvalidDataSet */;
58770
+ }
58771
+ return this.getters.checkZonesExistInSheet(sheetId, [zone]);
58772
+ }
58773
+ return "Success" /* CommandResult.Success */;
58774
+ }
58645
58775
  }
58646
58776
 
58647
58777
  class TableStylePlugin extends CorePlugin {
@@ -59945,8 +60075,8 @@ stores.inject(MyMetaStore, storeInstance);
59945
60075
  const EMPTY_ARRAY = [];
59946
60076
 
59947
60077
  const MAX_ITERATION = 30;
59948
- const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
59949
- const EMPTY_CELL = createEvaluatedCell({ value: null });
60078
+ const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
60079
+ const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
59950
60080
  class Evaluator {
59951
60081
  context;
59952
60082
  getters;
@@ -61441,7 +61571,7 @@ stores.inject(MyMetaStore, storeInstance);
61441
61571
  tables = {};
61442
61572
  handle(cmd) {
61443
61573
  if (invalidateEvaluationCommands.has(cmd.type) ||
61444
- (cmd.type === "UPDATE_CELL" && "content" in cmd) ||
61574
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd)) ||
61445
61575
  cmd.type === "EVALUATE_CELLS") {
61446
61576
  this.tables = {};
61447
61577
  return;
@@ -65298,7 +65428,7 @@ stores.inject(MyMetaStore, storeInstance);
65298
65428
  tableStyles = {};
65299
65429
  handle(cmd) {
65300
65430
  if (invalidateEvaluationCommands.has(cmd.type) ||
65301
- (cmd.type === "UPDATE_CELL" && "content" in cmd) ||
65431
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd)) ||
65302
65432
  cmd.type === "EVALUATE_CELLS") {
65303
65433
  this.tableStyles = {};
65304
65434
  return;
@@ -67262,6 +67392,8 @@ stores.inject(MyMetaStore, storeInstance);
67262
67392
  });
67263
67393
  this.selectCell(col, row);
67264
67394
  }
67395
+ const { col, row } = this.gridSelection.anchor.cell;
67396
+ this.moveClient({ sheetId: this.activeSheet.id, col, row });
67265
67397
  }
67266
67398
  /**
67267
67399
  * Ensure selections are not outside sheet boundaries.
@@ -68001,8 +68133,11 @@ stores.inject(MyMetaStore, storeInstance);
68001
68133
  case "REMOVE_TABLE":
68002
68134
  case "UPDATE_TABLE":
68003
68135
  case "UPDATE_FILTER":
68004
- this.sheetsWithDirtyViewports.add(cmd.sheetId);
68005
- break;
68136
+ case "UNFREEZE_ROWS":
68137
+ case "UNFREEZE_COLUMNS":
68138
+ case "FREEZE_COLUMNS":
68139
+ case "FREEZE_ROWS":
68140
+ case "UNFREEZE_COLUMNS_ROWS":
68006
68141
  case "REMOVE_COLUMNS_ROWS":
68007
68142
  case "RESIZE_COLUMNS_ROWS":
68008
68143
  case "HIDE_COLUMNS_ROWS":
@@ -68015,11 +68150,9 @@ stores.inject(MyMetaStore, storeInstance);
68015
68150
  case "FOLD_HEADER_GROUPS_IN_ZONE":
68016
68151
  case "UNFOLD_HEADER_GROUPS_IN_ZONE":
68017
68152
  case "UNFOLD_ALL_HEADER_GROUPS":
68018
- case "FOLD_ALL_HEADER_GROUPS": {
68019
- const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.getActiveSheetId();
68020
- this.sheetsWithDirtyViewports.add(sheetId);
68153
+ case "FOLD_ALL_HEADER_GROUPS":
68154
+ this.sheetsWithDirtyViewports.add(cmd.sheetId);
68021
68155
  break;
68022
- }
68023
68156
  case "UPDATE_CELL":
68024
68157
  // update cell content or format can change hidden rows because of data filters
68025
68158
  if ("content" in cmd || "format" in cmd || cmd.style?.fontSize !== undefined) {
@@ -68035,13 +68168,6 @@ stores.inject(MyMetaStore, storeInstance);
68035
68168
  case "ACTIVATE_SHEET":
68036
68169
  this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
68037
68170
  break;
68038
- case "UNFREEZE_ROWS":
68039
- case "UNFREEZE_COLUMNS":
68040
- case "FREEZE_COLUMNS":
68041
- case "FREEZE_ROWS":
68042
- case "UNFREEZE_COLUMNS_ROWS":
68043
- this.resetViewports(this.getters.getActiveSheetId());
68044
- break;
68045
68171
  case "SCROLL_TO_CELL":
68046
68172
  this.refreshViewport(this.getters.getActiveSheetId(), { col: cmd.col, row: cmd.row });
68047
68173
  break;
@@ -69219,7 +69345,7 @@ stores.inject(MyMetaStore, storeInstance);
69219
69345
  }
69220
69346
  handle(cmd) {
69221
69347
  if (invalidateEvaluationCommands.has(cmd.type) ||
69222
- (cmd.type === "UPDATE_CELL" && "content" in cmd)) {
69348
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
69223
69349
  this.isDirty = true;
69224
69350
  }
69225
69351
  switch (cmd.type) {
@@ -71282,11 +71408,13 @@ stores.inject(MyMetaStore, storeInstance);
71282
71408
  this.checkViewportSize();
71283
71409
  stores.on("store-updated", this, render);
71284
71410
  resizeObserver.observe(this.spreadsheetRef.el);
71411
+ registerChartJSExtensions();
71285
71412
  });
71286
71413
  owl.onWillUnmount(() => {
71287
71414
  this.unbindModelEvents();
71288
71415
  stores.off("store-updated", this);
71289
71416
  resizeObserver.disconnect();
71417
+ unregisterChartJsExtensions();
71290
71418
  });
71291
71419
  owl.onPatched(() => {
71292
71420
  this.checkViewportSize();
@@ -75780,9 +75908,9 @@ stores.inject(MyMetaStore, storeInstance);
75780
75908
  exports.tokenize = tokenize;
75781
75909
 
75782
75910
 
75783
- __info__.version = "18.1.17";
75784
- __info__.date = "2025-04-25T08:08:46.599Z";
75785
- __info__.hash = "a63687f";
75911
+ __info__.version = "18.1.19";
75912
+ __info__.date = "2025-05-12T05:26:05.861Z";
75913
+ __info__.hash = "44cc170";
75786
75914
 
75787
75915
 
75788
75916
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);