@odoo/o-spreadsheet 17.4.33 → 17.4.34

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 17.4.33
6
- * @date 2025-05-02T12:30:31.263Z
7
- * @hash 3ba00e6
5
+ * @version 17.4.34
6
+ * @date 2025-05-12T05:23:37.387Z
7
+ * @hash e3ac48a
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -5190,6 +5190,25 @@ function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
5190
5190
  })
5191
5191
  .filter(isDefined);
5192
5192
  }
5193
+ function getNextSheetName(existingNames, baseName = "Sheet") {
5194
+ let i = 1;
5195
+ let name = `${baseName}${i}`;
5196
+ while (existingNames.includes(name)) {
5197
+ name = `${baseName}${i}`;
5198
+ i++;
5199
+ }
5200
+ return name;
5201
+ }
5202
+ function getDuplicateSheetName(nameToDuplicate, existingNames) {
5203
+ let i = 1;
5204
+ const baseName = _t("Copy of %s", nameToDuplicate);
5205
+ let name = baseName.toString();
5206
+ while (existingNames.includes(name)) {
5207
+ name = `${baseName} (${i})`;
5208
+ i++;
5209
+ }
5210
+ return name;
5211
+ }
5193
5212
 
5194
5213
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
5195
5214
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -6393,6 +6412,24 @@ const monthNumberAdapter = {
6393
6412
  return `${normalizedValue}`;
6394
6413
  },
6395
6414
  };
6415
+ /**
6416
+ * normalizes month number + year
6417
+ */
6418
+ const monthAdapter = {
6419
+ normalizeFunctionValue(value) {
6420
+ const date = toNumber(value, DEFAULT_LOCALE);
6421
+ return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
6422
+ },
6423
+ toValueAndFormat(normalizedValue) {
6424
+ return {
6425
+ value: toNumber(normalizedValue, DEFAULT_LOCALE),
6426
+ format: "mmmm yyyy",
6427
+ };
6428
+ },
6429
+ toFunctionValue(normalizedValue) {
6430
+ return `"${normalizedValue}"`;
6431
+ },
6432
+ };
6396
6433
  /**
6397
6434
  * normalizes quarter number
6398
6435
  */
@@ -6460,6 +6497,7 @@ pivotTimeAdapterRegistry
6460
6497
  .add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
6461
6498
  .add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
6462
6499
  .add("month_number", nullHandlerDecorator(monthNumberAdapter))
6500
+ .add("month", nullHandlerDecorator(monthAdapter))
6463
6501
  .add("quarter_number", nullHandlerDecorator(quarterNumberAdapter));
6464
6502
 
6465
6503
  const AGGREGATOR_NAMES = {
@@ -6640,10 +6678,7 @@ function toNormalizedPivotValue(dimension, groupValue) {
6640
6678
  return normalizer(groupValueString, dimension.granularity);
6641
6679
  }
6642
6680
  function normalizeDateTime(value, granularity) {
6643
- if (!granularity) {
6644
- throw new Error("Missing granularity");
6645
- }
6646
- return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
6681
+ return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
6647
6682
  }
6648
6683
  function toFunctionPivotValue(value, dimension) {
6649
6684
  if (value === null) {
@@ -6655,10 +6690,7 @@ function toFunctionPivotValue(value, dimension) {
6655
6690
  return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
6656
6691
  }
6657
6692
  function toFunctionValueDateTime(value, granularity) {
6658
- if (!granularity) {
6659
- throw new Error("Missing granularity");
6660
- }
6661
- return pivotTimeAdapter(granularity).toFunctionValue(value);
6693
+ return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
6662
6694
  }
6663
6695
  const pivotNormalizationValueRegistry = new Registry();
6664
6696
  pivotNormalizationValueRegistry
@@ -19382,7 +19414,7 @@ const IF = {
19382
19414
  return { value: "" };
19383
19415
  }
19384
19416
  if (result.value === null) {
19385
- result.value = "";
19417
+ return { ...result, value: "" };
19386
19418
  }
19387
19419
  return result;
19388
19420
  },
@@ -19403,7 +19435,7 @@ const IFERROR = {
19403
19435
  return { value: "" };
19404
19436
  }
19405
19437
  if (result.value === null) {
19406
- result.value = "";
19438
+ return { ...result, value: "" };
19407
19439
  }
19408
19440
  return result;
19409
19441
  },
@@ -19424,7 +19456,7 @@ const IFNA = {
19424
19456
  return { value: "" };
19425
19457
  }
19426
19458
  if (result.value === null) {
19427
- result.value = "";
19459
+ return { ...result, value: "" };
19428
19460
  }
19429
19461
  return result;
19430
19462
  },
@@ -19450,7 +19482,7 @@ const IFS = {
19450
19482
  return { value: "" };
19451
19483
  }
19452
19484
  if (result.value === null) {
19453
- result.value = "";
19485
+ return { ...result, value: "" };
19454
19486
  }
19455
19487
  return result;
19456
19488
  }
@@ -22621,10 +22653,13 @@ const duplicateSheet = {
22621
22653
  name: _t("Duplicate"),
22622
22654
  execute: (env) => {
22623
22655
  const sheetIdFrom = env.model.getters.getActiveSheetId();
22656
+ const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
22624
22657
  const sheetIdTo = env.model.uuidGenerator.smallUuid();
22658
+ const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
22625
22659
  env.model.dispatch("DUPLICATE_SHEET", {
22626
22660
  sheetId: sheetIdFrom,
22627
22661
  sheetIdTo,
22662
+ sheetNameTo,
22628
22663
  });
22629
22664
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
22630
22665
  },
@@ -24069,6 +24104,13 @@ class Composer extends Component {
24069
24104
  this.props.onInputContextMenu?.(ev);
24070
24105
  }
24071
24106
  }
24107
+ onWheel(event) {
24108
+ // detect if scrollbar is available
24109
+ if (this.composerRef.el &&
24110
+ this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
24111
+ event.stopPropagation();
24112
+ }
24113
+ }
24072
24114
  // ---------------------------------------------------------------------------
24073
24115
  // Private
24074
24116
  // ---------------------------------------------------------------------------
@@ -29357,7 +29399,7 @@ const FIX_FORMULAS = {
29357
29399
  if (!pivot.isValid()) {
29358
29400
  return;
29359
29401
  }
29360
- env.model.dispatch("INSERT_PIVOT", {
29402
+ env.model.dispatch("SPLIT_PIVOT_FORMULA", {
29361
29403
  sheetId,
29362
29404
  col,
29363
29405
  row,
@@ -36991,8 +37033,8 @@ function compareDimensionValues(dimension, a, b) {
36991
37033
 
36992
37034
  const NULL_SYMBOL = Symbol("NULL");
36993
37035
  function createDate(dimension, value, locale) {
36994
- const granularity = dimension.granularity;
36995
- if (!granularity || !(granularity in MAP_VALUE_DIMENSION_DATE)) {
37036
+ const granularity = dimension.granularity || "month";
37037
+ if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
36996
37038
  throw new Error(`Unknown date granularity: ${granularity}`);
36997
37039
  }
36998
37040
  const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
@@ -37011,6 +37053,9 @@ function createDate(dimension, value, locale) {
37011
37053
  case "month_number":
37012
37054
  number = date.getMonth() + 1;
37013
37055
  break;
37056
+ case "month":
37057
+ number = Math.floor(toNumber(value, locale));
37058
+ break;
37014
37059
  case "iso_week_number":
37015
37060
  number = date.getIsoWeek();
37016
37061
  break;
@@ -37069,6 +37114,10 @@ const MAP_VALUE_DIMENSION_DATE = {
37069
37114
  set: new Set(),
37070
37115
  values: {},
37071
37116
  },
37117
+ month: {
37118
+ set: new Set(),
37119
+ values: {},
37120
+ },
37072
37121
  iso_week_number: {
37073
37122
  set: new Set(),
37074
37123
  values: {},
@@ -37245,7 +37294,7 @@ class SpreadsheetPivot {
37245
37294
  const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
37246
37295
  const finalCell = cells[0]?.[dimension.nameWithGranularity];
37247
37296
  if (dimension.type === "date") {
37248
- const adapter = pivotTimeAdapter(dimension.granularity);
37297
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
37249
37298
  return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
37250
37299
  }
37251
37300
  if (!finalCell) {
@@ -37330,7 +37379,7 @@ class SpreadsheetPivot {
37330
37379
  if (nonEmptyCells.length === 0) {
37331
37380
  return "integer";
37332
37381
  }
37333
- if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
37382
+ if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
37334
37383
  return "date";
37335
37384
  }
37336
37385
  if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
@@ -37445,6 +37494,7 @@ pivotRegistry.add("SPREADSHEET", {
37445
37494
  "year",
37446
37495
  "quarter_number",
37447
37496
  "month_number",
37497
+ "month",
37448
37498
  "iso_week_number",
37449
37499
  "day_of_month",
37450
37500
  "day",
@@ -37654,7 +37704,7 @@ class PivotSidePanelStore extends SpreadsheetStore {
37654
37704
  granularitiesPerFields[field.name] = new Set(granularities);
37655
37705
  }
37656
37706
  for (const field of dateFields) {
37657
- granularitiesPerFields[field.name].delete(field.granularity);
37707
+ granularitiesPerFields[field.name].delete(field.granularity || "month");
37658
37708
  }
37659
37709
  return granularitiesPerFields;
37660
37710
  }
@@ -39541,12 +39591,15 @@ class GridComposer extends Component {
39541
39591
  });
39542
39592
  }
39543
39593
  get composerProps() {
39594
+ // Remove the wrapper border width
39595
+ const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
39544
39596
  return {
39545
39597
  focus: this.composerFocusStore.gridComposerFocus,
39546
39598
  isDefaultFocus: true,
39547
39599
  onComposerContentFocused: () => this.composerFocusStore.focusGridComposerContent(),
39548
39600
  onComposerCellFocused: (content) => this.composerFocusStore.focusGridComposerCell(content),
39549
39601
  onInputContextMenu: this.props.onInputContextMenu,
39602
+ inputStyle: `max-height: ${maxHeight}px;`,
39550
39603
  };
39551
39604
  }
39552
39605
  get containerStyle() {
@@ -47303,6 +47356,7 @@ function repairInitialMessages(data, initialMessages) {
47303
47356
  initialMessages = dropCommands(initialMessages, "SORT_CELLS");
47304
47357
  initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
47305
47358
  initialMessages = fixChartDefinitions(data, initialMessages);
47359
+ initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
47306
47360
  return initialMessages;
47307
47361
  }
47308
47362
  /**
@@ -47422,6 +47476,40 @@ function fixOverlappingFilters(data) {
47422
47476
  }
47423
47477
  return data;
47424
47478
  }
47479
+ function fixTranslatedDuplicateSheetName(data, initialMessages) {
47480
+ const sheetNames = {};
47481
+ for (const sheet of data.sheets || []) {
47482
+ sheetNames[sheet.id] = sheet.name;
47483
+ }
47484
+ const messages = [];
47485
+ for (const message of initialMessages) {
47486
+ if (message.type === "REMOTE_REVISION") {
47487
+ const commands = [];
47488
+ for (const cmd of message.commands) {
47489
+ switch (cmd.type) {
47490
+ case "DUPLICATE_SHEET":
47491
+ cmd.sheetNameTo =
47492
+ cmd.sheetNameTo ??
47493
+ getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
47494
+ break;
47495
+ case "CREATE_SHEET":
47496
+ case "RENAME_SHEET":
47497
+ sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
47498
+ break;
47499
+ }
47500
+ commands.push(cmd);
47501
+ }
47502
+ messages.push({
47503
+ ...message,
47504
+ commands,
47505
+ });
47506
+ }
47507
+ else {
47508
+ messages.push(message);
47509
+ }
47510
+ }
47511
+ return initialMessages;
47512
+ }
47425
47513
  // -----------------------------------------------------------------------------
47426
47514
  // Helpers
47427
47515
  // -----------------------------------------------------------------------------
@@ -48957,9 +49045,7 @@ class ChartPlugin extends CorePlugin {
48957
49045
  : "Success" /* CommandResult.Success */;
48958
49046
  }
48959
49047
  checkChartExists(cmd) {
48960
- return this.getters.getFigureSheetId(cmd.id)
48961
- ? "Success" /* CommandResult.Success */
48962
- : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
49048
+ return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
48963
49049
  }
48964
49050
  }
48965
49051
 
@@ -51136,6 +51222,7 @@ class SheetPlugin extends CorePlugin {
51136
51222
  "getCommandZones",
51137
51223
  "getUnboundedZone",
51138
51224
  "checkElementsIncludeAllNonFrozenHeaders",
51225
+ "getDuplicateSheetName",
51139
51226
  ];
51140
51227
  sheetIdsMapName = {};
51141
51228
  orderedSheetIds = [];
@@ -51160,7 +51247,11 @@ class SheetPlugin extends CorePlugin {
51160
51247
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
51161
51248
  }
51162
51249
  case "DUPLICATE_SHEET": {
51163
- return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
51250
+ if (this.sheets[cmd.sheetIdTo])
51251
+ return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
51252
+ if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
51253
+ return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
51254
+ return "Success" /* CommandResult.Success */;
51164
51255
  }
51165
51256
  case "MOVE_SHEET":
51166
51257
  try {
@@ -51230,7 +51321,7 @@ class SheetPlugin extends CorePlugin {
51230
51321
  this.showSheet(cmd.sheetId);
51231
51322
  break;
51232
51323
  case "DUPLICATE_SHEET":
51233
- this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
51324
+ this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
51234
51325
  break;
51235
51326
  case "DELETE_SHEET":
51236
51327
  this.deleteSheet(this.sheets[cmd.sheetId]);
@@ -51430,14 +51521,8 @@ class SheetPlugin extends CorePlugin {
51430
51521
  return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
51431
51522
  }
51432
51523
  getNextSheetName(baseName = "Sheet") {
51433
- let i = 1;
51434
51524
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
51435
- let name = `${baseName}${i}`;
51436
- while (names.includes(name)) {
51437
- name = `${baseName}${i}`;
51438
- i++;
51439
- }
51440
- return name;
51525
+ return getNextSheetName(names, baseName);
51441
51526
  }
51442
51527
  getSheetSize(sheetId) {
51443
51528
  return {
@@ -51683,9 +51768,8 @@ class SheetPlugin extends CorePlugin {
51683
51768
  showSheet(sheetId) {
51684
51769
  this.history.update("sheets", sheetId, "isVisible", true);
51685
51770
  }
51686
- duplicateSheet(fromId, toId) {
51771
+ duplicateSheet(fromId, toId, toName) {
51687
51772
  const sheet = this.getSheet(fromId);
51688
- const toName = this.getDuplicateSheetName(sheet.name);
51689
51773
  const newSheet = deepCopy(sheet);
51690
51774
  newSheet.id = toId;
51691
51775
  newSheet.name = toName;
@@ -51717,15 +51801,8 @@ class SheetPlugin extends CorePlugin {
51717
51801
  this.history.update("sheetIdsMapName", sheetIdsMapName);
51718
51802
  }
51719
51803
  getDuplicateSheetName(sheetName) {
51720
- let i = 1;
51721
51804
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
51722
- const baseName = _t("Copy of %s", sheetName);
51723
- let name = baseName.toString();
51724
- while (names.includes(name)) {
51725
- name = `${baseName} (${i})`;
51726
- i++;
51727
- }
51728
- return name;
51805
+ return getDuplicateSheetName(sheetName, names);
51729
51806
  }
51730
51807
  deleteSheet(sheet) {
51731
51808
  const name = sheet.name;
@@ -54524,8 +54601,8 @@ class SpreadingRelation {
54524
54601
  const EMPTY_ARRAY = [];
54525
54602
 
54526
54603
  const MAX_ITERATION = 30;
54527
- const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
54528
- const EMPTY_CELL = createEvaluatedCell({ value: null });
54604
+ const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
54605
+ const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
54529
54606
  class Evaluator {
54530
54607
  context;
54531
54608
  getters;
@@ -58587,6 +58664,8 @@ class InsertPivotPlugin extends UIPlugin {
58587
58664
  case "INSERT_PIVOT_WITH_TABLE":
58588
58665
  this.insertPivotWithTable(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table, cmd.pivotMode);
58589
58666
  break;
58667
+ case "SPLIT_PIVOT_FORMULA":
58668
+ this.splitPivotFormula(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table);
58590
58669
  }
58591
58670
  }
58592
58671
  insertNewPivot(pivotId, sheetId) {
@@ -58734,6 +58813,36 @@ class InsertPivotPlugin extends UIPlugin {
58734
58813
  });
58735
58814
  }
58736
58815
  }
58816
+ splitPivotFormula(sheetId, col, row, pivotId, pivotTableData) {
58817
+ this.dispatch("INSERT_PIVOT", {
58818
+ sheetId,
58819
+ col,
58820
+ row,
58821
+ pivotId,
58822
+ table: pivotTableData,
58823
+ });
58824
+ const table = this.getters.getCoreTable({ sheetId, col, row });
58825
+ if (table?.type === "dynamic") {
58826
+ const zone = positionToZone({ col, row });
58827
+ const { cols, rows, measures, fieldsType } = pivotTableData;
58828
+ const pivotTable = new SpreadsheetPivotTable(cols, rows, measures, fieldsType || {});
58829
+ const colNumber = pivotTable.getNumberOfDataColumns() + 1;
58830
+ const rowNumber = pivotTable.columns.length + pivotTable.rows.length;
58831
+ const tableZone = {
58832
+ left: col,
58833
+ top: row,
58834
+ right: col + colNumber - 1,
58835
+ bottom: row + rowNumber - 1,
58836
+ };
58837
+ const rangeData = this.getters.getRangeDataFromZone(sheetId, tableZone);
58838
+ this.dispatch("UPDATE_TABLE", {
58839
+ sheetId,
58840
+ zone,
58841
+ newTableRange: rangeData,
58842
+ tableType: "static",
58843
+ });
58844
+ }
58845
+ }
58737
58846
  }
58738
58847
 
58739
58848
  class SortPlugin extends UIPlugin {
@@ -69361,6 +69470,6 @@ const constants = {
69361
69470
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
69362
69471
 
69363
69472
 
69364
- __info__.version = "17.4.33";
69365
- __info__.date = "2025-05-02T12:30:31.263Z";
69366
- __info__.hash = "3ba00e6";
69473
+ __info__.version = "17.4.34";
69474
+ __info__.date = "2025-05-12T05:23:37.387Z";
69475
+ __info__.hash = "e3ac48a";