@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
  'use strict';
@@ -5192,6 +5192,25 @@ function moveHeaderIndexesOnHeaderDeletion(deletedHeaders, headers) {
5192
5192
  })
5193
5193
  .filter(isDefined);
5194
5194
  }
5195
+ function getNextSheetName(existingNames, baseName = "Sheet") {
5196
+ let i = 1;
5197
+ let name = `${baseName}${i}`;
5198
+ while (existingNames.includes(name)) {
5199
+ name = `${baseName}${i}`;
5200
+ i++;
5201
+ }
5202
+ return name;
5203
+ }
5204
+ function getDuplicateSheetName(nameToDuplicate, existingNames) {
5205
+ let i = 1;
5206
+ const baseName = _t("Copy of %s", nameToDuplicate);
5207
+ let name = baseName.toString();
5208
+ while (existingNames.includes(name)) {
5209
+ name = `${baseName} (${i})`;
5210
+ i++;
5211
+ }
5212
+ return name;
5213
+ }
5195
5214
 
5196
5215
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
5197
5216
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -6395,6 +6414,24 @@ const monthNumberAdapter = {
6395
6414
  return `${normalizedValue}`;
6396
6415
  },
6397
6416
  };
6417
+ /**
6418
+ * normalizes month number + year
6419
+ */
6420
+ const monthAdapter = {
6421
+ normalizeFunctionValue(value) {
6422
+ const date = toNumber(value, DEFAULT_LOCALE);
6423
+ return formatValue(date, { locale: DEFAULT_LOCALE, format: "mm/yyyy" });
6424
+ },
6425
+ toValueAndFormat(normalizedValue) {
6426
+ return {
6427
+ value: toNumber(normalizedValue, DEFAULT_LOCALE),
6428
+ format: "mmmm yyyy",
6429
+ };
6430
+ },
6431
+ toFunctionValue(normalizedValue) {
6432
+ return `"${normalizedValue}"`;
6433
+ },
6434
+ };
6398
6435
  /**
6399
6436
  * normalizes quarter number
6400
6437
  */
@@ -6462,6 +6499,7 @@ pivotTimeAdapterRegistry
6462
6499
  .add("day_of_month", nullHandlerDecorator(dayOfMonthAdapter))
6463
6500
  .add("iso_week_number", nullHandlerDecorator(isoWeekNumberAdapter))
6464
6501
  .add("month_number", nullHandlerDecorator(monthNumberAdapter))
6502
+ .add("month", nullHandlerDecorator(monthAdapter))
6465
6503
  .add("quarter_number", nullHandlerDecorator(quarterNumberAdapter));
6466
6504
 
6467
6505
  const AGGREGATOR_NAMES = {
@@ -6642,10 +6680,7 @@ function toNormalizedPivotValue(dimension, groupValue) {
6642
6680
  return normalizer(groupValueString, dimension.granularity);
6643
6681
  }
6644
6682
  function normalizeDateTime(value, granularity) {
6645
- if (!granularity) {
6646
- throw new Error("Missing granularity");
6647
- }
6648
- return pivotTimeAdapter(granularity).normalizeFunctionValue(value);
6683
+ return pivotTimeAdapter(granularity ?? "month").normalizeFunctionValue(value);
6649
6684
  }
6650
6685
  function toFunctionPivotValue(value, dimension) {
6651
6686
  if (value === null) {
@@ -6657,10 +6692,7 @@ function toFunctionPivotValue(value, dimension) {
6657
6692
  return pivotToFunctionValueRegistry.get(dimension.type)(value, dimension.granularity);
6658
6693
  }
6659
6694
  function toFunctionValueDateTime(value, granularity) {
6660
- if (!granularity) {
6661
- throw new Error("Missing granularity");
6662
- }
6663
- return pivotTimeAdapter(granularity).toFunctionValue(value);
6695
+ return pivotTimeAdapter(granularity ?? "month").toFunctionValue(value);
6664
6696
  }
6665
6697
  const pivotNormalizationValueRegistry = new Registry();
6666
6698
  pivotNormalizationValueRegistry
@@ -19384,7 +19416,7 @@ const IF = {
19384
19416
  return { value: "" };
19385
19417
  }
19386
19418
  if (result.value === null) {
19387
- result.value = "";
19419
+ return { ...result, value: "" };
19388
19420
  }
19389
19421
  return result;
19390
19422
  },
@@ -19405,7 +19437,7 @@ const IFERROR = {
19405
19437
  return { value: "" };
19406
19438
  }
19407
19439
  if (result.value === null) {
19408
- result.value = "";
19440
+ return { ...result, value: "" };
19409
19441
  }
19410
19442
  return result;
19411
19443
  },
@@ -19426,7 +19458,7 @@ const IFNA = {
19426
19458
  return { value: "" };
19427
19459
  }
19428
19460
  if (result.value === null) {
19429
- result.value = "";
19461
+ return { ...result, value: "" };
19430
19462
  }
19431
19463
  return result;
19432
19464
  },
@@ -19452,7 +19484,7 @@ const IFS = {
19452
19484
  return { value: "" };
19453
19485
  }
19454
19486
  if (result.value === null) {
19455
- result.value = "";
19487
+ return { ...result, value: "" };
19456
19488
  }
19457
19489
  return result;
19458
19490
  }
@@ -22623,10 +22655,13 @@ const duplicateSheet = {
22623
22655
  name: _t("Duplicate"),
22624
22656
  execute: (env) => {
22625
22657
  const sheetIdFrom = env.model.getters.getActiveSheetId();
22658
+ const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
22626
22659
  const sheetIdTo = env.model.uuidGenerator.smallUuid();
22660
+ const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
22627
22661
  env.model.dispatch("DUPLICATE_SHEET", {
22628
22662
  sheetId: sheetIdFrom,
22629
22663
  sheetIdTo,
22664
+ sheetNameTo,
22630
22665
  });
22631
22666
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
22632
22667
  },
@@ -24071,6 +24106,13 @@ class Composer extends owl.Component {
24071
24106
  this.props.onInputContextMenu?.(ev);
24072
24107
  }
24073
24108
  }
24109
+ onWheel(event) {
24110
+ // detect if scrollbar is available
24111
+ if (this.composerRef.el &&
24112
+ this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
24113
+ event.stopPropagation();
24114
+ }
24115
+ }
24074
24116
  // ---------------------------------------------------------------------------
24075
24117
  // Private
24076
24118
  // ---------------------------------------------------------------------------
@@ -29359,7 +29401,7 @@ const FIX_FORMULAS = {
29359
29401
  if (!pivot.isValid()) {
29360
29402
  return;
29361
29403
  }
29362
- env.model.dispatch("INSERT_PIVOT", {
29404
+ env.model.dispatch("SPLIT_PIVOT_FORMULA", {
29363
29405
  sheetId,
29364
29406
  col,
29365
29407
  row,
@@ -36993,8 +37035,8 @@ function compareDimensionValues(dimension, a, b) {
36993
37035
 
36994
37036
  const NULL_SYMBOL = Symbol("NULL");
36995
37037
  function createDate(dimension, value, locale) {
36996
- const granularity = dimension.granularity;
36997
- if (!granularity || !(granularity in MAP_VALUE_DIMENSION_DATE)) {
37038
+ const granularity = dimension.granularity || "month";
37039
+ if (!(granularity in MAP_VALUE_DIMENSION_DATE)) {
36998
37040
  throw new Error(`Unknown date granularity: ${granularity}`);
36999
37041
  }
37000
37042
  const keyInMap = typeof value === "number" || typeof value === "string" ? value : NULL_SYMBOL;
@@ -37013,6 +37055,9 @@ function createDate(dimension, value, locale) {
37013
37055
  case "month_number":
37014
37056
  number = date.getMonth() + 1;
37015
37057
  break;
37058
+ case "month":
37059
+ number = Math.floor(toNumber(value, locale));
37060
+ break;
37016
37061
  case "iso_week_number":
37017
37062
  number = date.getIsoWeek();
37018
37063
  break;
@@ -37071,6 +37116,10 @@ const MAP_VALUE_DIMENSION_DATE = {
37071
37116
  set: new Set(),
37072
37117
  values: {},
37073
37118
  },
37119
+ month: {
37120
+ set: new Set(),
37121
+ values: {},
37122
+ },
37074
37123
  iso_week_number: {
37075
37124
  set: new Set(),
37076
37125
  values: {},
@@ -37247,7 +37296,7 @@ class SpreadsheetPivot {
37247
37296
  const cells = this.filterDataEntriesFromDomain(this.dataEntries, domain);
37248
37297
  const finalCell = cells[0]?.[dimension.nameWithGranularity];
37249
37298
  if (dimension.type === "date") {
37250
- const adapter = pivotTimeAdapter(dimension.granularity);
37299
+ const adapter = pivotTimeAdapter((dimension.granularity || "month"));
37251
37300
  return adapter.toValueAndFormat(lastNode.value, this.getters.getLocale());
37252
37301
  }
37253
37302
  if (!finalCell) {
@@ -37332,7 +37381,7 @@ class SpreadsheetPivot {
37332
37381
  if (nonEmptyCells.length === 0) {
37333
37382
  return "integer";
37334
37383
  }
37335
- if (nonEmptyCells.every((cell) => cell.format && isDateTimeFormat(cell.format))) {
37384
+ if (nonEmptyCells.every((cell) => cell.type === CellValueType.number && cell.format && isDateTimeFormat(cell.format))) {
37336
37385
  return "date";
37337
37386
  }
37338
37387
  if (nonEmptyCells.every((cell) => cell.type === CellValueType.boolean)) {
@@ -37447,6 +37496,7 @@ pivotRegistry.add("SPREADSHEET", {
37447
37496
  "year",
37448
37497
  "quarter_number",
37449
37498
  "month_number",
37499
+ "month",
37450
37500
  "iso_week_number",
37451
37501
  "day_of_month",
37452
37502
  "day",
@@ -37656,7 +37706,7 @@ class PivotSidePanelStore extends SpreadsheetStore {
37656
37706
  granularitiesPerFields[field.name] = new Set(granularities);
37657
37707
  }
37658
37708
  for (const field of dateFields) {
37659
- granularitiesPerFields[field.name].delete(field.granularity);
37709
+ granularitiesPerFields[field.name].delete(field.granularity || "month");
37660
37710
  }
37661
37711
  return granularitiesPerFields;
37662
37712
  }
@@ -39543,12 +39593,15 @@ class GridComposer extends owl.Component {
39543
39593
  });
39544
39594
  }
39545
39595
  get composerProps() {
39596
+ // Remove the wrapper border width
39597
+ const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
39546
39598
  return {
39547
39599
  focus: this.composerFocusStore.gridComposerFocus,
39548
39600
  isDefaultFocus: true,
39549
39601
  onComposerContentFocused: () => this.composerFocusStore.focusGridComposerContent(),
39550
39602
  onComposerCellFocused: (content) => this.composerFocusStore.focusGridComposerCell(content),
39551
39603
  onInputContextMenu: this.props.onInputContextMenu,
39604
+ inputStyle: `max-height: ${maxHeight}px;`,
39552
39605
  };
39553
39606
  }
39554
39607
  get containerStyle() {
@@ -47305,6 +47358,7 @@ function repairInitialMessages(data, initialMessages) {
47305
47358
  initialMessages = dropCommands(initialMessages, "SORT_CELLS");
47306
47359
  initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
47307
47360
  initialMessages = fixChartDefinitions(data, initialMessages);
47361
+ initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
47308
47362
  return initialMessages;
47309
47363
  }
47310
47364
  /**
@@ -47424,6 +47478,40 @@ function fixOverlappingFilters(data) {
47424
47478
  }
47425
47479
  return data;
47426
47480
  }
47481
+ function fixTranslatedDuplicateSheetName(data, initialMessages) {
47482
+ const sheetNames = {};
47483
+ for (const sheet of data.sheets || []) {
47484
+ sheetNames[sheet.id] = sheet.name;
47485
+ }
47486
+ const messages = [];
47487
+ for (const message of initialMessages) {
47488
+ if (message.type === "REMOTE_REVISION") {
47489
+ const commands = [];
47490
+ for (const cmd of message.commands) {
47491
+ switch (cmd.type) {
47492
+ case "DUPLICATE_SHEET":
47493
+ cmd.sheetNameTo =
47494
+ cmd.sheetNameTo ??
47495
+ getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
47496
+ break;
47497
+ case "CREATE_SHEET":
47498
+ case "RENAME_SHEET":
47499
+ sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
47500
+ break;
47501
+ }
47502
+ commands.push(cmd);
47503
+ }
47504
+ messages.push({
47505
+ ...message,
47506
+ commands,
47507
+ });
47508
+ }
47509
+ else {
47510
+ messages.push(message);
47511
+ }
47512
+ }
47513
+ return initialMessages;
47514
+ }
47427
47515
  // -----------------------------------------------------------------------------
47428
47516
  // Helpers
47429
47517
  // -----------------------------------------------------------------------------
@@ -48959,9 +49047,7 @@ class ChartPlugin extends CorePlugin {
48959
49047
  : "Success" /* CommandResult.Success */;
48960
49048
  }
48961
49049
  checkChartExists(cmd) {
48962
- return this.getters.getFigureSheetId(cmd.id)
48963
- ? "Success" /* CommandResult.Success */
48964
- : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
49050
+ return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
48965
49051
  }
48966
49052
  }
48967
49053
 
@@ -51138,6 +51224,7 @@ class SheetPlugin extends CorePlugin {
51138
51224
  "getCommandZones",
51139
51225
  "getUnboundedZone",
51140
51226
  "checkElementsIncludeAllNonFrozenHeaders",
51227
+ "getDuplicateSheetName",
51141
51228
  ];
51142
51229
  sheetIdsMapName = {};
51143
51230
  orderedSheetIds = [];
@@ -51162,7 +51249,11 @@ class SheetPlugin extends CorePlugin {
51162
51249
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
51163
51250
  }
51164
51251
  case "DUPLICATE_SHEET": {
51165
- return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
51252
+ if (this.sheets[cmd.sheetIdTo])
51253
+ return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
51254
+ if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
51255
+ return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
51256
+ return "Success" /* CommandResult.Success */;
51166
51257
  }
51167
51258
  case "MOVE_SHEET":
51168
51259
  try {
@@ -51232,7 +51323,7 @@ class SheetPlugin extends CorePlugin {
51232
51323
  this.showSheet(cmd.sheetId);
51233
51324
  break;
51234
51325
  case "DUPLICATE_SHEET":
51235
- this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
51326
+ this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
51236
51327
  break;
51237
51328
  case "DELETE_SHEET":
51238
51329
  this.deleteSheet(this.sheets[cmd.sheetId]);
@@ -51432,14 +51523,8 @@ class SheetPlugin extends CorePlugin {
51432
51523
  return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
51433
51524
  }
51434
51525
  getNextSheetName(baseName = "Sheet") {
51435
- let i = 1;
51436
51526
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
51437
- let name = `${baseName}${i}`;
51438
- while (names.includes(name)) {
51439
- name = `${baseName}${i}`;
51440
- i++;
51441
- }
51442
- return name;
51527
+ return getNextSheetName(names, baseName);
51443
51528
  }
51444
51529
  getSheetSize(sheetId) {
51445
51530
  return {
@@ -51685,9 +51770,8 @@ class SheetPlugin extends CorePlugin {
51685
51770
  showSheet(sheetId) {
51686
51771
  this.history.update("sheets", sheetId, "isVisible", true);
51687
51772
  }
51688
- duplicateSheet(fromId, toId) {
51773
+ duplicateSheet(fromId, toId, toName) {
51689
51774
  const sheet = this.getSheet(fromId);
51690
- const toName = this.getDuplicateSheetName(sheet.name);
51691
51775
  const newSheet = deepCopy(sheet);
51692
51776
  newSheet.id = toId;
51693
51777
  newSheet.name = toName;
@@ -51719,15 +51803,8 @@ class SheetPlugin extends CorePlugin {
51719
51803
  this.history.update("sheetIdsMapName", sheetIdsMapName);
51720
51804
  }
51721
51805
  getDuplicateSheetName(sheetName) {
51722
- let i = 1;
51723
51806
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
51724
- const baseName = _t("Copy of %s", sheetName);
51725
- let name = baseName.toString();
51726
- while (names.includes(name)) {
51727
- name = `${baseName} (${i})`;
51728
- i++;
51729
- }
51730
- return name;
51807
+ return getDuplicateSheetName(sheetName, names);
51731
51808
  }
51732
51809
  deleteSheet(sheet) {
51733
51810
  const name = sheet.name;
@@ -54526,8 +54603,8 @@ class SpreadingRelation {
54526
54603
  const EMPTY_ARRAY = [];
54527
54604
 
54528
54605
  const MAX_ITERATION = 30;
54529
- const ERROR_CYCLE_CELL = createEvaluatedCell(new CircularDependencyError());
54530
- const EMPTY_CELL = createEvaluatedCell({ value: null });
54606
+ const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
54607
+ const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
54531
54608
  class Evaluator {
54532
54609
  context;
54533
54610
  getters;
@@ -58589,6 +58666,8 @@ class InsertPivotPlugin extends UIPlugin {
58589
58666
  case "INSERT_PIVOT_WITH_TABLE":
58590
58667
  this.insertPivotWithTable(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table, cmd.pivotMode);
58591
58668
  break;
58669
+ case "SPLIT_PIVOT_FORMULA":
58670
+ this.splitPivotFormula(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table);
58592
58671
  }
58593
58672
  }
58594
58673
  insertNewPivot(pivotId, sheetId) {
@@ -58736,6 +58815,36 @@ class InsertPivotPlugin extends UIPlugin {
58736
58815
  });
58737
58816
  }
58738
58817
  }
58818
+ splitPivotFormula(sheetId, col, row, pivotId, pivotTableData) {
58819
+ this.dispatch("INSERT_PIVOT", {
58820
+ sheetId,
58821
+ col,
58822
+ row,
58823
+ pivotId,
58824
+ table: pivotTableData,
58825
+ });
58826
+ const table = this.getters.getCoreTable({ sheetId, col, row });
58827
+ if (table?.type === "dynamic") {
58828
+ const zone = positionToZone({ col, row });
58829
+ const { cols, rows, measures, fieldsType } = pivotTableData;
58830
+ const pivotTable = new SpreadsheetPivotTable(cols, rows, measures, fieldsType || {});
58831
+ const colNumber = pivotTable.getNumberOfDataColumns() + 1;
58832
+ const rowNumber = pivotTable.columns.length + pivotTable.rows.length;
58833
+ const tableZone = {
58834
+ left: col,
58835
+ top: row,
58836
+ right: col + colNumber - 1,
58837
+ bottom: row + rowNumber - 1,
58838
+ };
58839
+ const rangeData = this.getters.getRangeDataFromZone(sheetId, tableZone);
58840
+ this.dispatch("UPDATE_TABLE", {
58841
+ sheetId,
58842
+ zone,
58843
+ newTableRange: rangeData,
58844
+ tableType: "static",
58845
+ });
58846
+ }
58847
+ }
58739
58848
  }
58740
58849
 
58741
58850
  class SortPlugin extends UIPlugin {
@@ -69406,6 +69515,6 @@ exports.tokenColors = tokenColors;
69406
69515
  exports.tokenize = tokenize;
69407
69516
 
69408
69517
 
69409
- __info__.version = "17.4.33";
69410
- __info__.date = "2025-05-02T12:30:31.263Z";
69411
- __info__.hash = "3ba00e6";
69518
+ __info__.version = "17.4.34";
69519
+ __info__.date = "2025-05-12T05:23:37.387Z";
69520
+ __info__.hash = "e3ac48a";