@odoo/o-spreadsheet 18.2.21 → 18.2.23

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.2.21
6
- * @date 2025-07-11T11:11:48.661Z
7
- * @hash 1c32303
5
+ * @version 18.2.23
6
+ * @date 2025-07-30T11:19:55.262Z
7
+ * @hash 4419b30
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -8366,12 +8366,12 @@
8366
8366
  avg: _t("Average"),
8367
8367
  sum: _t("Sum"),
8368
8368
  };
8369
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8369
+ const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8370
8370
  const AGGREGATORS_BY_FIELD_TYPE = {
8371
- integer: NUMBER_CHAR_AGGREGATORS,
8372
- char: NUMBER_CHAR_AGGREGATORS,
8371
+ integer: DEFAULT_AGGREGATORS,
8372
+ char: DEFAULT_AGGREGATORS,
8373
+ datetime: DEFAULT_AGGREGATORS,
8373
8374
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8374
- datetime: ["max", "min", "count_distinct", "count"],
8375
8375
  };
8376
8376
  const AGGREGATORS = {};
8377
8377
  for (const type in AGGREGATORS_BY_FIELD_TYPE) {
@@ -11308,6 +11308,7 @@ stores.inject(MyMetaStore, storeInstance);
11308
11308
 
11309
11309
  autoCompleteProviders.add("dataValidation", {
11310
11310
  displayAllOnInitialContent: true,
11311
+ canBeToggled: false,
11311
11312
  getProposals(tokenAtCursor, content) {
11312
11313
  if (content.startsWith("=")) {
11313
11314
  return [];
@@ -11315,31 +11316,40 @@ stores.inject(MyMetaStore, storeInstance);
11315
11316
  if (!this.composer.currentEditedCell) {
11316
11317
  return [];
11317
11318
  }
11318
- const position = this.composer.currentEditedCell;
11319
- const rule = this.getters.getValidationRuleForCell(position);
11320
- if (!rule ||
11321
- (rule.criterion.type !== "isValueInList" && rule.criterion.type !== "isValueInRange")) {
11322
- return [];
11323
- }
11324
- let values;
11325
- if (rule.criterion.type === "isValueInList") {
11326
- values = rule.criterion.values;
11327
- }
11328
- else {
11329
- const range = this.getters.getRangeFromSheetXC(position.sheetId, rule.criterion.values[0]);
11330
- values = Array.from(new Set(this.getters
11331
- .getRangeValues(range)
11332
- .filter(isNotNull)
11333
- .map((value) => value.toString())
11334
- .filter((val) => val !== "")));
11335
- }
11336
- return values.map((value) => ({ text: value }));
11319
+ return getProposedValues(this.getters, this.composer.currentEditedCell).map((value) => ({
11320
+ text: value.value?.toString() || "",
11321
+ htmlContent: [{ value: value.label }],
11322
+ fuzzySearchKey: value.label,
11323
+ }));
11337
11324
  },
11338
11325
  selectProposal(tokenAtCursor, value) {
11339
11326
  this.composer.setCurrentContent(value);
11340
11327
  this.composer.stopEdition();
11341
11328
  },
11342
11329
  });
11330
+ function getProposedValues(getters, position) {
11331
+ const rule = getters.getValidationRuleForCell(position);
11332
+ if (!rule ||
11333
+ (rule.criterion.type !== "isValueInList" && rule.criterion.type !== "isValueInRange")) {
11334
+ return [];
11335
+ }
11336
+ let values = [];
11337
+ if (rule.criterion.type === "isValueInList") {
11338
+ values = rule.criterion.values.map((value) => ({ label: value, value }));
11339
+ }
11340
+ else {
11341
+ const labelsSet = new Set();
11342
+ const range = getters.getRangeFromSheetXC(position.sheetId, rule.criterion.values[0]);
11343
+ for (const p of positions(range.zone)) {
11344
+ const cell = getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
11345
+ if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
11346
+ labelsSet.add(cell.formattedValue);
11347
+ values.push({ label: cell.formattedValue, value: cell.value });
11348
+ }
11349
+ }
11350
+ }
11351
+ return values;
11352
+ }
11343
11353
 
11344
11354
  function getHtmlContentFromPattern(pattern, value, highlightColor, className) {
11345
11355
  const pendingHtmlContent = [];
@@ -19110,11 +19120,17 @@ stores.inject(MyMetaStore, storeInstance);
19110
19120
  if (isEvaluationError(cellReference?.value)) {
19111
19121
  return cellReference;
19112
19122
  }
19113
- const column = cellReference === undefined
19114
- ? this.__originCellPosition?.col
19115
- : toZone(cellReference.value).left;
19116
- assert(() => column !== undefined, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
19117
- return column + 1;
19123
+ if (cellReference === undefined) {
19124
+ assert(() => this.__originCellPosition?.col !== undefined, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
19125
+ return this.__originCellPosition.col + 1;
19126
+ }
19127
+ const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
19128
+ if (zone.left === zone.right) {
19129
+ return zone.left + 1;
19130
+ }
19131
+ return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
19132
+ value: zone.left + col + 1,
19133
+ }));
19118
19134
  },
19119
19135
  isExported: true,
19120
19136
  };
@@ -19333,11 +19349,17 @@ stores.inject(MyMetaStore, storeInstance);
19333
19349
  if (isEvaluationError(cellReference?.value)) {
19334
19350
  return cellReference;
19335
19351
  }
19336
- const row = cellReference === undefined
19337
- ? this.__originCellPosition?.row
19338
- : toZone(cellReference.value).top;
19339
- assert(() => row !== undefined, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
19340
- return row + 1;
19352
+ if (cellReference === undefined) {
19353
+ assert(() => this.__originCellPosition?.row !== undefined, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
19354
+ return this.__originCellPosition.row + 1;
19355
+ }
19356
+ const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
19357
+ if (zone.top === zone.bottom) {
19358
+ return zone.top + 1;
19359
+ }
19360
+ return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
19361
+ value: zone.top + row + 1,
19362
+ }));
19341
19363
  },
19342
19364
  isExported: true,
19343
19365
  };
@@ -21613,6 +21635,7 @@ stores.inject(MyMetaStore, storeInstance);
21613
21635
  proposals,
21614
21636
  selectProposal: provider.selectProposal,
21615
21637
  autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
21638
+ canBeToggled: provider.canBeToggled,
21616
21639
  };
21617
21640
  }
21618
21641
  if (exactMatch && this._currentContent !== this.initialContent) {
@@ -21635,6 +21658,7 @@ stores.inject(MyMetaStore, storeInstance);
21635
21658
  proposals,
21636
21659
  selectProposal: provider.selectProposal,
21637
21660
  autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
21661
+ canBeToggled: provider.canBeToggled,
21638
21662
  };
21639
21663
  }
21640
21664
  }
@@ -41306,9 +41330,13 @@ stores.inject(MyMetaStore, storeInstance);
41306
41330
  }
41307
41331
  }
41308
41332
  closeAssistant() {
41333
+ if (!this.canBeToggled)
41334
+ return;
41309
41335
  this.assistant.forcedClosed = true;
41310
41336
  }
41311
41337
  openAssistant() {
41338
+ if (!this.canBeToggled)
41339
+ return;
41312
41340
  this.assistant.forcedClosed = false;
41313
41341
  }
41314
41342
  onWheel(event) {
@@ -41318,6 +41346,9 @@ stores.inject(MyMetaStore, storeInstance);
41318
41346
  event.stopPropagation();
41319
41347
  }
41320
41348
  }
41349
+ get canBeToggled() {
41350
+ return this.autoCompleteState.provider?.canBeToggled ?? true;
41351
+ }
41321
41352
  // ---------------------------------------------------------------------------
41322
41353
  // Private
41323
41354
  // ---------------------------------------------------------------------------
@@ -41453,7 +41484,7 @@ stores.inject(MyMetaStore, storeInstance);
41453
41484
  }
41454
41485
  }
41455
41486
  autoComplete(value) {
41456
- if (!value || this.assistant.forcedClosed) {
41487
+ if (!value || (this.assistant.forcedClosed && this.canBeToggled)) {
41457
41488
  return;
41458
41489
  }
41459
41490
  this.autoCompleteState.provider?.selectProposal(value);
@@ -42789,7 +42820,8 @@ stores.inject(MyMetaStore, storeInstance);
42789
42820
  static props = {
42790
42821
  editedCf: Object,
42791
42822
  onCancel: Function,
42792
- onSave: Function,
42823
+ onExit: Function,
42824
+ isNewCf: Boolean,
42793
42825
  };
42794
42826
  static components = {
42795
42827
  SelectionInput,
@@ -42808,6 +42840,7 @@ stores.inject(MyMetaStore, storeInstance);
42808
42840
  getTextDecoration = getTextDecoration;
42809
42841
  colorNumberString = colorNumberString;
42810
42842
  state;
42843
+ hasEditedCf = this.props.isNewCf;
42811
42844
  setup() {
42812
42845
  this.state = owl.useState({
42813
42846
  errors: [],
@@ -42865,6 +42898,9 @@ stores.inject(MyMetaStore, storeInstance);
42865
42898
  ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
42866
42899
  sheetId,
42867
42900
  });
42901
+ if (result.isSuccessful) {
42902
+ this.hasEditedCf = true;
42903
+ }
42868
42904
  const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
42869
42905
  if (!newCf.suppressErrors) {
42870
42906
  this.state.errors = reasons;
@@ -42886,7 +42922,15 @@ stores.inject(MyMetaStore, storeInstance);
42886
42922
  onSave() {
42887
42923
  const result = this.updateConditionalFormat({});
42888
42924
  if (result.length === 0) {
42889
- this.props.onSave();
42925
+ this.props.onExit();
42926
+ }
42927
+ }
42928
+ onCancel() {
42929
+ if (this.hasEditedCf) {
42930
+ this.props.onCancel();
42931
+ }
42932
+ else {
42933
+ this.props.onExit();
42890
42934
  }
42891
42935
  }
42892
42936
  getDefaultRules() {
@@ -47237,9 +47281,15 @@ stores.inject(MyMetaStore, storeInstance);
47237
47281
  return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
47238
47282
  }
47239
47283
  filterDataEntriesFromDomainNode(dataEntries, domain) {
47240
- const { field, value } = domain;
47284
+ const { field, value, type } = domain;
47241
47285
  const { nameWithGranularity } = this.getDimension(field);
47242
- return dataEntries.filter((entry) => entry[nameWithGranularity]?.value === value);
47286
+ return dataEntries.filter((entry) => {
47287
+ const cellValue = entry[nameWithGranularity]?.value;
47288
+ if (type === "char") {
47289
+ return String(cellValue) === String(value);
47290
+ }
47291
+ return cellValue === value;
47292
+ });
47243
47293
  }
47244
47294
  getDimension(nameWithGranularity) {
47245
47295
  return this.definition.getDimension(nameWithGranularity);
@@ -49735,6 +49785,11 @@ stores.inject(MyMetaStore, storeInstance);
49735
49785
  rect = this.defaultRect;
49736
49786
  isEditing = false;
49737
49787
  isCellReferenceVisible = false;
49788
+ currentEditedCell = {
49789
+ col: 0,
49790
+ row: 0,
49791
+ sheetId: this.env.model.getters.getActiveSheetId(),
49792
+ };
49738
49793
  composerStore;
49739
49794
  composerFocusStore;
49740
49795
  composerInterface;
@@ -49764,7 +49819,7 @@ stores.inject(MyMetaStore, storeInstance);
49764
49819
  return this.isCellReferenceVisible;
49765
49820
  }
49766
49821
  get cellReference() {
49767
- const { col, row, sheetId } = this.composerStore.currentEditedCell;
49822
+ const { col, row, sheetId } = this.currentEditedCell;
49768
49823
  const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
49769
49824
  return getFullReference(prefixSheet ? this.env.model.getters.getSheetName(sheetId) : undefined, toXC(col, row));
49770
49825
  }
@@ -49856,12 +49911,17 @@ stores.inject(MyMetaStore, storeInstance);
49856
49911
  if (!isEditing && this.composerFocusStore.activeComposer !== this.composerInterface) {
49857
49912
  this.composerFocusStore.focusComposer(this.composerInterface, { focusMode: "inactive" });
49858
49913
  }
49914
+ let shouldRecomputeRect = isEditing && !deepEquals(this.currentEditedCell, this.composerStore.currentEditedCell);
49859
49915
  if (this.isEditing !== isEditing) {
49860
49916
  this.isEditing = isEditing;
49861
49917
  if (!isEditing) {
49862
49918
  this.rect = this.defaultRect;
49863
49919
  return;
49864
49920
  }
49921
+ this.currentEditedCell = this.composerStore.currentEditedCell;
49922
+ shouldRecomputeRect = true;
49923
+ }
49924
+ if (shouldRecomputeRect) {
49865
49925
  const position = this.env.model.getters.getActivePosition();
49866
49926
  const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
49867
49927
  this.rect = this.env.model.getters.getVisibleRect(zone);
@@ -62970,6 +63030,23 @@ stores.inject(MyMetaStore, storeInstance);
62970
63030
  static getters = ["getRowSize", "getHeaderSize"];
62971
63031
  tallestCellInRow = {};
62972
63032
  ctx = document.createElement("canvas").getContext("2d");
63033
+ beforeHandle(cmd) {
63034
+ switch (cmd.type) {
63035
+ // Ensure rows are updated before "UPDATE_CELL" is dispatched from cell plugin.
63036
+ // "UPDATE_CELL" uses the Sheet core plugin to access row data.
63037
+ // If "ADD_COLUMNS_ROWS" has not been processed yet by header_sizes_ui,
63038
+ // size updates may apply to incorrect (pre-insert) rows.
63039
+ case "ADD_COLUMNS_ROWS":
63040
+ if (cmd.dimension === "COL") {
63041
+ return;
63042
+ }
63043
+ const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
63044
+ const newCells = Array(cmd.quantity).fill(undefined);
63045
+ const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
63046
+ this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
63047
+ break;
63048
+ }
63049
+ }
62973
63050
  handle(cmd) {
62974
63051
  switch (cmd.type) {
62975
63052
  case "START":
@@ -62999,16 +63076,6 @@ stores.inject(MyMetaStore, storeInstance);
62999
63076
  this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
63000
63077
  break;
63001
63078
  }
63002
- case "ADD_COLUMNS_ROWS": {
63003
- if (cmd.dimension === "COL") {
63004
- return;
63005
- }
63006
- const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
63007
- const newCells = Array(cmd.quantity).fill(undefined);
63008
- const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
63009
- this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
63010
- break;
63011
- }
63012
63079
  case "RESIZE_COLUMNS_ROWS":
63013
63080
  {
63014
63081
  const sheetId = cmd.sheetId;
@@ -68761,6 +68828,14 @@ stores.inject(MyMetaStore, storeInstance);
68761
68828
  const isBasedBefore = cmd.base < start;
68762
68829
  const deltaCol = isBasedBefore && isCol ? thickness : 0;
68763
68830
  const deltaRow = isBasedBefore && !isCol ? thickness : 0;
68831
+ const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
68832
+ const originalSize = Object.fromEntries(toRemove.map((element) => {
68833
+ const size = isCol
68834
+ ? this.getters.getColSize(cmd.sheetId, element)
68835
+ : this.getters.getUserRowSize(cmd.sheetId, element);
68836
+ const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
68837
+ return [element, isDefaultCol ? undefined : size];
68838
+ }));
68764
68839
  const target = [
68765
68840
  {
68766
68841
  left: isCol ? start + deltaCol : 0,
@@ -68791,13 +68866,12 @@ stores.inject(MyMetaStore, storeInstance);
68791
68866
  const col = selection.left;
68792
68867
  const row = selection.top;
68793
68868
  this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
68794
- const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
68795
68869
  let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
68796
68870
  const resizingGroups = {};
68797
68871
  for (const element of toRemove) {
68798
- const size = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
68872
+ const size = originalSize[element];
68799
68873
  const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
68800
- if (size != currentSize) {
68874
+ if (size && size != currentSize) {
68801
68875
  resizingGroups[size] ??= [];
68802
68876
  resizingGroups[size].push(currentIndex);
68803
68877
  currentIndex += 1;
@@ -70482,14 +70556,12 @@ stores.inject(MyMetaStore, storeInstance);
70482
70556
  this.editionState = "initializing";
70483
70557
  }
70484
70558
  stopEdition() {
70485
- const input = this.sheetNameRef.el;
70486
- if (!this.state.isEditing || !input)
70559
+ if (!this.state.isEditing || !this.sheetNameRef.el)
70487
70560
  return;
70488
70561
  this.state.isEditing = false;
70489
70562
  this.editionState = "initializing";
70490
- input.blur();
70563
+ this.sheetNameRef.el.blur();
70491
70564
  const inputValue = this.getInputContent() || "";
70492
- input.innerText = inputValue;
70493
70565
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
70494
70566
  }
70495
70567
  cancelEdition() {
@@ -77186,9 +77258,9 @@ stores.inject(MyMetaStore, storeInstance);
77186
77258
  exports.tokenize = tokenize;
77187
77259
 
77188
77260
 
77189
- __info__.version = "18.2.21";
77190
- __info__.date = "2025-07-11T11:11:48.661Z";
77191
- __info__.hash = "1c32303";
77261
+ __info__.version = "18.2.23";
77262
+ __info__.date = "2025-07-30T11:19:55.262Z";
77263
+ __info__.hash = "4419b30";
77192
77264
 
77193
77265
 
77194
77266
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);