@odoo/o-spreadsheet 18.4.2 → 18.4.4

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.4.2
6
- * @date 2025-07-11T11:11:12.642Z
7
- * @hash 29b6458
5
+ * @version 18.4.4
6
+ * @date 2025-07-30T11:20:08.639Z
7
+ * @hash b14de14
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -8625,12 +8625,12 @@
8625
8625
  avg: _t("Average"),
8626
8626
  sum: _t("Sum"),
8627
8627
  };
8628
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8628
+ const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8629
8629
  const AGGREGATORS_BY_FIELD_TYPE = {
8630
- integer: NUMBER_CHAR_AGGREGATORS,
8631
- char: NUMBER_CHAR_AGGREGATORS,
8630
+ integer: DEFAULT_AGGREGATORS,
8631
+ char: DEFAULT_AGGREGATORS,
8632
+ datetime: DEFAULT_AGGREGATORS,
8632
8633
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8633
- datetime: ["max", "min", "count_distinct", "count"],
8634
8634
  };
8635
8635
  const AGGREGATORS = {};
8636
8636
  for (const type in AGGREGATORS_BY_FIELD_TYPE) {
@@ -19034,13 +19034,19 @@ stores.inject(MyMetaStore, storeInstance);
19034
19034
  if (isEvaluationError(cellReference?.value)) {
19035
19035
  return cellReference;
19036
19036
  }
19037
- const column = cellReference === undefined
19038
- ? this.__originCellPosition?.col
19039
- : toZone(cellReference.value).left;
19040
- if (column === undefined) {
19041
- return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
19037
+ if (cellReference === undefined) {
19038
+ if (this.__originCellPosition?.col === undefined) {
19039
+ return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
19040
+ }
19041
+ return this.__originCellPosition.col + 1;
19042
+ }
19043
+ const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
19044
+ if (zone.left === zone.right) {
19045
+ return zone.left + 1;
19042
19046
  }
19043
- return column + 1;
19047
+ return generateMatrix(zone.right - zone.left + 1, 1, (col, row) => ({
19048
+ value: zone.left + col + 1,
19049
+ }));
19044
19050
  },
19045
19051
  isExported: true,
19046
19052
  };
@@ -19271,13 +19277,19 @@ stores.inject(MyMetaStore, storeInstance);
19271
19277
  if (isEvaluationError(cellReference?.value)) {
19272
19278
  return cellReference;
19273
19279
  }
19274
- const row = cellReference === undefined
19275
- ? this.__originCellPosition?.row
19276
- : toZone(cellReference.value).top;
19277
- if (row === undefined) {
19278
- return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
19280
+ if (cellReference === undefined) {
19281
+ if (this.__originCellPosition?.row === undefined) {
19282
+ return new EvaluationError(_t("In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter."));
19283
+ }
19284
+ return this.__originCellPosition.row + 1;
19279
19285
  }
19280
- return row + 1;
19286
+ const zone = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), cellReference.value).zone;
19287
+ if (zone.top === zone.bottom) {
19288
+ return zone.top + 1;
19289
+ }
19290
+ return generateMatrix(1, zone.bottom - zone.top + 1, (col, row) => ({
19291
+ value: zone.top + row + 1,
19292
+ }));
19281
19293
  },
19282
19294
  isExported: true,
19283
19295
  };
@@ -31696,7 +31708,7 @@ stores.inject(MyMetaStore, storeInstance);
31696
31708
  }
31697
31709
  const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
31698
31710
  return criterionValues
31699
- .map((value) => value.toLowerCase())
31711
+ .map((value) => value.value.toLowerCase())
31700
31712
  .includes(value.toString().toLowerCase());
31701
31713
  },
31702
31714
  getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
@@ -32607,6 +32619,9 @@ stores.inject(MyMetaStore, storeInstance);
32607
32619
  get isAutoCompleteDisplayed() {
32608
32620
  return !!this.autoComplete.provider;
32609
32621
  }
32622
+ get canBeToggled() {
32623
+ return this.autoComplete.provider?.canBeToggled ?? true;
32624
+ }
32610
32625
  cycleReferences() {
32611
32626
  const locale = this.getters.getLocale();
32612
32627
  const updated = cycleFixedReference(this.composerSelection, this._currentContent, locale);
@@ -33136,6 +33151,7 @@ stores.inject(MyMetaStore, storeInstance);
33136
33151
  proposals,
33137
33152
  selectProposal: provider.selectProposal,
33138
33153
  autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
33154
+ canBeToggled: provider.canBeToggled,
33139
33155
  };
33140
33156
  }
33141
33157
  if (exactMatch && this._currentContent !== this.initialContent) {
@@ -33158,6 +33174,7 @@ stores.inject(MyMetaStore, storeInstance);
33158
33174
  proposals,
33159
33175
  selectProposal: provider.selectProposal,
33160
33176
  autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
33177
+ canBeToggled: provider.canBeToggled,
33161
33178
  };
33162
33179
  }
33163
33180
  }
@@ -33728,9 +33745,13 @@ stores.inject(MyMetaStore, storeInstance);
33728
33745
  }
33729
33746
  }
33730
33747
  closeAssistant() {
33748
+ if (!this.props.composerStore.canBeToggled)
33749
+ return;
33731
33750
  this.assistant.forcedClosed = true;
33732
33751
  }
33733
33752
  openAssistant() {
33753
+ if (!this.props.composerStore.canBeToggled)
33754
+ return;
33734
33755
  this.assistant.forcedClosed = false;
33735
33756
  }
33736
33757
  onWheel(event) {
@@ -33920,7 +33941,7 @@ stores.inject(MyMetaStore, storeInstance);
33920
33941
  return [...new Set(argsToFocus)];
33921
33942
  }
33922
33943
  autoComplete(value) {
33923
- if (!value || this.assistant.forcedClosed) {
33944
+ if (!value || (this.assistant.forcedClosed && this.props.composerStore.canBeToggled)) {
33924
33945
  return;
33925
33946
  }
33926
33947
  this.props.composerStore.insertAutoCompleteValue(value);
@@ -52022,7 +52043,8 @@ stores.inject(MyMetaStore, storeInstance);
52022
52043
  static props = {
52023
52044
  editedCf: Object,
52024
52045
  onCancel: Function,
52025
- onSave: Function,
52046
+ onExit: Function,
52047
+ isNewCf: Boolean,
52026
52048
  };
52027
52049
  static components = {
52028
52050
  SelectionInput,
@@ -52047,6 +52069,7 @@ stores.inject(MyMetaStore, storeInstance);
52047
52069
  currentCFType: this.props.editedCf.rule.type,
52048
52070
  ranges: this.props.editedCf.ranges,
52049
52071
  rules: this.getDefaultRules(),
52072
+ hasEditedCf: this.props.isNewCf,
52050
52073
  });
52051
52074
  switch (this.props.editedCf.rule.type) {
52052
52075
  case "CellIsRule":
@@ -52098,6 +52121,9 @@ stores.inject(MyMetaStore, storeInstance);
52098
52121
  ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
52099
52122
  sheetId,
52100
52123
  });
52124
+ if (result.isSuccessful) {
52125
+ this.state.hasEditedCf = true;
52126
+ }
52101
52127
  const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
52102
52128
  if (!newCf.suppressErrors) {
52103
52129
  this.state.errors = reasons;
@@ -52119,7 +52145,15 @@ stores.inject(MyMetaStore, storeInstance);
52119
52145
  onSave() {
52120
52146
  const result = this.updateConditionalFormat({});
52121
52147
  if (result.length === 0) {
52122
- this.props.onSave();
52148
+ this.props.onExit();
52149
+ }
52150
+ }
52151
+ onCancel() {
52152
+ if (this.state.hasEditedCf) {
52153
+ this.props.onCancel();
52154
+ }
52155
+ else {
52156
+ this.props.onExit();
52123
52157
  }
52124
52158
  }
52125
52159
  getDefaultRules() {
@@ -55681,9 +55715,15 @@ stores.inject(MyMetaStore, storeInstance);
55681
55715
  return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
55682
55716
  }
55683
55717
  filterDataEntriesFromDomainNode(dataEntries, domain) {
55684
- const { field, value } = domain;
55718
+ const { field, value, type } = domain;
55685
55719
  const { nameWithGranularity } = this.getDimension(field);
55686
- return dataEntries.filter((entry) => entry[nameWithGranularity]?.value === value);
55720
+ return dataEntries.filter((entry) => {
55721
+ const cellValue = entry[nameWithGranularity]?.value;
55722
+ if (type === "char") {
55723
+ return String(cellValue) === String(value);
55724
+ }
55725
+ return cellValue === value;
55726
+ });
55687
55727
  }
55688
55728
  getDimension(nameWithGranularity) {
55689
55729
  return this.definition.getDimension(nameWithGranularity);
@@ -67008,8 +67048,16 @@ stores.inject(MyMetaStore, storeInstance);
67008
67048
  }
67009
67049
  getDataValidationRangeValues(sheetId, criterion) {
67010
67050
  const range = this.getters.getRangeFromSheetXC(sheetId, String(criterion.values[0]));
67011
- const criterionValues = this.getters.getRangeValues(range);
67012
- return criterionValues.map((value) => value?.toString()).filter(isDefined);
67051
+ const values = [];
67052
+ const labelsSet = new Set();
67053
+ for (const p of positions(range.zone)) {
67054
+ const cell = this.getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
67055
+ if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
67056
+ labelsSet.add(cell.formattedValue);
67057
+ values.push({ label: cell.formattedValue, value: cell.value?.toString() || "" });
67058
+ }
67059
+ }
67060
+ return values;
67013
67061
  }
67014
67062
  isCellValidCheckbox(cellPosition) {
67015
67063
  if (!this.getters.isMainCellPosition(cellPosition)) {
@@ -67552,6 +67600,23 @@ stores.inject(MyMetaStore, storeInstance);
67552
67600
  static getters = ["getRowSize", "getHeaderSize", "getMaxAnchorOffset"];
67553
67601
  tallestCellInRow = {};
67554
67602
  ctx = document.createElement("canvas").getContext("2d");
67603
+ beforeHandle(cmd) {
67604
+ switch (cmd.type) {
67605
+ // Ensure rows are updated before "UPDATE_CELL" is dispatched from cell plugin.
67606
+ // "UPDATE_CELL" uses the Sheet core plugin to access row data.
67607
+ // If "ADD_COLUMNS_ROWS" has not been processed yet by header_sizes_ui,
67608
+ // size updates may apply to incorrect (pre-insert) rows.
67609
+ case "ADD_COLUMNS_ROWS":
67610
+ if (cmd.dimension === "COL") {
67611
+ return;
67612
+ }
67613
+ const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
67614
+ const newCells = Array(cmd.quantity).fill(undefined);
67615
+ const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
67616
+ this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
67617
+ break;
67618
+ }
67619
+ }
67555
67620
  handle(cmd) {
67556
67621
  switch (cmd.type) {
67557
67622
  case "START":
@@ -67581,16 +67646,6 @@ stores.inject(MyMetaStore, storeInstance);
67581
67646
  this.history.update("tallestCellInRow", cmd.sheetId, tallestCells);
67582
67647
  break;
67583
67648
  }
67584
- case "ADD_COLUMNS_ROWS": {
67585
- if (cmd.dimension === "COL") {
67586
- return;
67587
- }
67588
- const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
67589
- const newCells = Array(cmd.quantity).fill(undefined);
67590
- const newTallestCells = insertItemsAtIndex(this.tallestCellInRow[cmd.sheetId], newCells, addIndex);
67591
- this.history.update("tallestCellInRow", cmd.sheetId, newTallestCells);
67592
- break;
67593
- }
67594
67649
  case "RESIZE_COLUMNS_ROWS":
67595
67650
  {
67596
67651
  const sheetId = cmd.sheetId;
@@ -74132,6 +74187,14 @@ stores.inject(MyMetaStore, storeInstance);
74132
74187
  const isBasedBefore = cmd.base < start;
74133
74188
  const deltaCol = isBasedBefore && isCol ? thickness : 0;
74134
74189
  const deltaRow = isBasedBefore && !isCol ? thickness : 0;
74190
+ const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
74191
+ const originalSize = Object.fromEntries(toRemove.map((element) => {
74192
+ const size = isCol
74193
+ ? this.getters.getColSize(cmd.sheetId, element)
74194
+ : this.getters.getUserRowSize(cmd.sheetId, element);
74195
+ const isDefaultCol = isCol && size === DEFAULT_CELL_WIDTH;
74196
+ return [element, isDefaultCol ? undefined : size];
74197
+ }));
74135
74198
  const target = [
74136
74199
  {
74137
74200
  left: isCol ? start + deltaCol : 0,
@@ -74162,13 +74225,12 @@ stores.inject(MyMetaStore, storeInstance);
74162
74225
  const col = selection.left;
74163
74226
  const row = selection.top;
74164
74227
  this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
74165
- const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
74166
74228
  let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
74167
74229
  const resizingGroups = {};
74168
74230
  for (const element of toRemove) {
74169
- const size = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
74231
+ const size = originalSize[element];
74170
74232
  const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex);
74171
- if (size !== currentSize) {
74233
+ if (size && size !== currentSize) {
74172
74234
  resizingGroups[size] ??= [];
74173
74235
  resizingGroups[size].push(currentIndex);
74174
74236
  currentIndex += 1;
@@ -75594,6 +75656,7 @@ stores.inject(MyMetaStore, storeInstance);
75594
75656
 
75595
75657
  autoCompleteProviders.add("dataValidation", {
75596
75658
  displayAllOnInitialContent: true,
75659
+ canBeToggled: false,
75597
75660
  getProposals(tokenAtCursor, content) {
75598
75661
  if (isFormula(content)) {
75599
75662
  return [];
@@ -75609,25 +75672,30 @@ stores.inject(MyMetaStore, storeInstance);
75609
75672
  }
75610
75673
  const sheetId = this.composer.currentEditedCell.sheetId;
75611
75674
  const values = rule.criterion.type === "isValueInRange"
75612
- ? Array.from(new Set(this.getters.getDataValidationRangeValues(sheetId, rule.criterion)))
75613
- : rule.criterion.values;
75675
+ ? this.getters.getDataValidationRangeValues(sheetId, rule.criterion)
75676
+ : rule.criterion.values.map((value) => ({ label: value, value }));
75614
75677
  const isChip = rule.criterion.displayStyle === "chip";
75615
75678
  if (!isChip) {
75616
- return values.map((value) => ({ text: value }));
75679
+ return values.map((value) => ({
75680
+ text: value.value,
75681
+ fuzzySearchKey: value.label,
75682
+ htmlContent: [{ value: value.label }],
75683
+ }));
75617
75684
  }
75618
75685
  const colors = rule.criterion.colors;
75619
75686
  return values.map((value) => {
75620
- const color = colors?.[value];
75687
+ const color = colors?.[value.value];
75621
75688
  return {
75622
- text: value,
75689
+ text: value.value,
75623
75690
  htmlContent: [
75624
75691
  {
75625
- value,
75692
+ value: value.label,
75626
75693
  color: color ? chipTextColor(color) : undefined,
75627
75694
  backgroundColor: color || GRAY_200,
75628
75695
  classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"],
75629
75696
  },
75630
75697
  ],
75698
+ fuzzySearchKey: value.label,
75631
75699
  };
75632
75700
  });
75633
75701
  },
@@ -77159,14 +77227,12 @@ stores.inject(MyMetaStore, storeInstance);
77159
77227
  this.editionState = "initializing";
77160
77228
  }
77161
77229
  stopEdition() {
77162
- const input = this.sheetNameRef.el;
77163
- if (!this.state.isEditing || !input)
77230
+ if (!this.state.isEditing || !this.sheetNameRef.el)
77164
77231
  return;
77165
77232
  this.state.isEditing = false;
77166
77233
  this.editionState = "initializing";
77167
- input.blur();
77234
+ this.sheetNameRef.el.blur();
77168
77235
  const inputValue = this.getInputContent() || "";
77169
- input.innerText = inputValue;
77170
77236
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
77171
77237
  }
77172
77238
  cancelEdition() {
@@ -84605,9 +84671,9 @@ stores.inject(MyMetaStore, storeInstance);
84605
84671
  exports.tokenize = tokenize;
84606
84672
 
84607
84673
 
84608
- __info__.version = "18.4.2";
84609
- __info__.date = "2025-07-11T11:11:12.642Z";
84610
- __info__.hash = "29b6458";
84674
+ __info__.version = "18.4.4";
84675
+ __info__.date = "2025-07-30T11:20:08.639Z";
84676
+ __info__.hash = "b14de14";
84611
84677
 
84612
84678
 
84613
84679
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);