@odoo/o-spreadsheet 19.3.16 → 19.3.17

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 19.3.16
6
- * @date 2026-08-12T09:15:31.627Z
7
- * @hash 464be42
5
+ * @version 19.3.17
6
+ * @date 2026-08-21T15:31:50.940Z
7
+ * @hash cf8c614
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -4071,6 +4071,18 @@ stores.inject(MyMetaStore, storeInstance);
4071
4071
  default: return "";
4072
4072
  }
4073
4073
  }
4074
+ /**
4075
+ * Only converts the decimal separator, ignore number format such as % or dates
4076
+ */
4077
+ function toLocaleString(data, locale) {
4078
+ const value = toValue(data);
4079
+ switch (typeof value) {
4080
+ case "string": return value;
4081
+ case "number": return value.toString().replace(".", locale.decimalSeparator);
4082
+ case "boolean": return value ? "TRUE" : "FALSE";
4083
+ default: return "";
4084
+ }
4085
+ }
4074
4086
  /** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
4075
4087
  const normalizeString = memoize(function normalizeString(str) {
4076
4088
  return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
@@ -29089,12 +29101,13 @@ stores.inject(MyMetaStore, storeInstance);
29089
29101
  }
29090
29102
  sortFilterZone(sortDirection) {
29091
29103
  const filterPosition = this.props.filterPosition;
29092
- const tableZone = this.table?.range.zone;
29104
+ const table = this.table;
29105
+ const tableZone = table?.range.zone;
29093
29106
  if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
29094
29107
  const sheetId = this.env.model.getters.getActiveSheetId();
29095
29108
  const contentZone = {
29096
29109
  ...tableZone,
29097
- top: tableZone.top + 1
29110
+ top: tableZone.top + table.config.numberOfHeaders
29098
29111
  };
29099
29112
  const sortAnchor = {
29100
29113
  col: filterPosition.col,
@@ -77216,7 +77229,7 @@ stores.inject(MyMetaStore, storeInstance);
77216
77229
  else if (_format === 0) {
77217
77230
  const rowSeparator = this.locale.decimalSeparator === "," ? "/" : ",";
77218
77231
  return transposeMatrix(_array).flatMap((row) => row.map((value) => {
77219
- return isEvaluationError(value.value) ? value.value : toString(value);
77232
+ return isEvaluationError(value.value) ? value.value : toLocaleString(value, this.locale);
77220
77233
  })).join(rowSeparator);
77221
77234
  } else return new EvaluationError(_t("Format must be 0 or 1"));
77222
77235
  },
@@ -82977,7 +82990,7 @@ stores.inject(MyMetaStore, storeInstance);
82977
82990
  description: _t("Concatenation of two values."),
82978
82991
  args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
82979
82992
  compute: function(value1, value2) {
82980
- return toString(value1) + toString(value2);
82993
+ return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
82981
82994
  },
82982
82995
  isExported: true
82983
82996
  };
@@ -83842,7 +83855,7 @@ stores.inject(MyMetaStore, storeInstance);
83842
83855
  description: _t("Remove non-printable characters from a piece of text."),
83843
83856
  args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
83844
83857
  compute: function(text) {
83845
- const _text = toString(text);
83858
+ const _text = toLocaleString(text, this.locale);
83846
83859
  let cleanedStr = "";
83847
83860
  for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
83848
83861
  return cleanedStr;
@@ -83853,7 +83866,7 @@ stores.inject(MyMetaStore, storeInstance);
83853
83866
  description: _t("Appends strings to one another."),
83854
83867
  args: [arg("string (string, range<string>, repeating)", _t("String to append in sequence."))],
83855
83868
  compute: function(...datas) {
83856
- return reduceAny(datas, (acc, a) => acc + toString(a), "");
83869
+ return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
83857
83870
  },
83858
83871
  isExported: true
83859
83872
  };
@@ -83861,7 +83874,7 @@ stores.inject(MyMetaStore, storeInstance);
83861
83874
  description: _t("Tests whether two strings are identical."),
83862
83875
  args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
83863
83876
  compute: function(string1, string2) {
83864
- return toString(string1) === toString(string2);
83877
+ return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
83865
83878
  },
83866
83879
  isExported: true
83867
83880
  };
@@ -83873,8 +83886,8 @@ stores.inject(MyMetaStore, storeInstance);
83873
83886
  arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
83874
83887
  ],
83875
83888
  compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
83876
- const _searchFor = toString(searchFor);
83877
- const _textToSearch = toString(textToSearch);
83889
+ const _searchFor = toLocaleString(searchFor, this.locale);
83890
+ const _textToSearch = toLocaleString(textToSearch, this.locale);
83878
83891
  const _startingAt = toNumber(startingAt, this.locale);
83879
83892
  if (_textToSearch === "") return new EvaluationError(_t("The text_to_search must be non-empty."));
83880
83893
  if (_startingAt < 1) return new EvaluationError(_t("The starting_at (%s) must be greater than or equal to 1.", _startingAt));
@@ -83911,8 +83924,8 @@ stores.inject(MyMetaStore, storeInstance);
83911
83924
  description: _t("Concatenates elements of arrays with delimiter."),
83912
83925
  args: [arg("delimiter (string)", _t("The character or string to place between each concatenated value.")), arg("value_or_array (string, range<string>, repeating)", _t("Value to be appended using delimiter."))],
83913
83926
  compute: function(delimiter, ...valuesOrArrays) {
83914
- const _delimiter = toString(delimiter);
83915
- return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toString(a), "");
83927
+ const _delimiter = toLocaleString(delimiter, this.locale);
83928
+ return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
83916
83929
  }
83917
83930
  };
83918
83931
  const LEFT = {
@@ -83921,7 +83934,7 @@ stores.inject(MyMetaStore, storeInstance);
83921
83934
  compute: function(text, ...args) {
83922
83935
  const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
83923
83936
  if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
83924
- return toString(text).substring(0, _numberOfCharacters);
83937
+ return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
83925
83938
  },
83926
83939
  isExported: true
83927
83940
  };
@@ -83929,7 +83942,7 @@ stores.inject(MyMetaStore, storeInstance);
83929
83942
  description: _t("Length of a string."),
83930
83943
  args: [arg("text (string)", _t("The string whose length will be returned."))],
83931
83944
  compute: function(text) {
83932
- return toString(text).length;
83945
+ return toLocaleString(text, this.locale).length;
83933
83946
  },
83934
83947
  isExported: true
83935
83948
  };
@@ -83937,7 +83950,7 @@ stores.inject(MyMetaStore, storeInstance);
83937
83950
  description: _t("Converts a specified string to lowercase."),
83938
83951
  args: [arg("text (string)", _t("The string to convert to lowercase."))],
83939
83952
  compute: function(text) {
83940
- return toString(text).toLowerCase();
83953
+ return toLocaleString(text, this.locale).toLowerCase();
83941
83954
  },
83942
83955
  isExported: true
83943
83956
  };
@@ -83949,7 +83962,7 @@ stores.inject(MyMetaStore, storeInstance);
83949
83962
  arg("extract_length (number)", _t("The length of the segment to extract."))
83950
83963
  ],
83951
83964
  compute: function(text, starting_at, extract_length) {
83952
- const _text = toString(text);
83965
+ const _text = toLocaleString(text, this.locale);
83953
83966
  const _starting_at = toNumber(starting_at, this.locale);
83954
83967
  const _extract_length = toNumber(extract_length, this.locale);
83955
83968
  if (_starting_at < 1) return new EvaluationError(_t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
@@ -83962,7 +83975,7 @@ stores.inject(MyMetaStore, storeInstance);
83962
83975
  description: _t("Capitalizes each word in a specified string."),
83963
83976
  args: [arg("text_to_capitalize (string)", _t("The text which will be returned with the first letter of each word in uppercase and all other letters in lowercase."))],
83964
83977
  compute: function(text) {
83965
- return toString(text).replace(wordRegex, (word) => {
83978
+ return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
83966
83979
  return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
83967
83980
  });
83968
83981
  },
@@ -84110,9 +84123,9 @@ stores.inject(MyMetaStore, storeInstance);
84110
84123
  compute: function(text, position, length, newText) {
84111
84124
  const _position = toNumber(position, this.locale);
84112
84125
  if (_position < 1) return new EvaluationError(_t("The position (%s) must be greater than or equal to 1.", _position));
84113
- const _text = toString(text);
84126
+ const _text = toLocaleString(text, this.locale);
84114
84127
  const _length = toNumber(length, this.locale);
84115
- const _newText = toString(newText);
84128
+ const _newText = toLocaleString(newText, this.locale);
84116
84129
  return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
84117
84130
  },
84118
84131
  isExported: true
@@ -84123,7 +84136,7 @@ stores.inject(MyMetaStore, storeInstance);
84123
84136
  compute: function(text, ...args) {
84124
84137
  const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
84125
84138
  if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
84126
- const _text = toString(text);
84139
+ const _text = toLocaleString(text, this.locale);
84127
84140
  const stringLength = _text.length;
84128
84141
  return _text.substring(stringLength - _numberOfCharacters, stringLength);
84129
84142
  },
@@ -84137,8 +84150,8 @@ stores.inject(MyMetaStore, storeInstance);
84137
84150
  arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
84138
84151
  ],
84139
84152
  compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
84140
- const _searchFor = toString(searchFor).toLowerCase();
84141
- const _textToSearch = toString(textToSearch).toLowerCase();
84153
+ const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
84154
+ const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
84142
84155
  const _startingAt = toNumber(startingAt, this.locale);
84143
84156
  if (_textToSearch === "") return {
84144
84157
  value: CellErrorType.GenericError,
@@ -84168,8 +84181,8 @@ stores.inject(MyMetaStore, storeInstance);
84168
84181
  arg(`remove_empty_text (boolean, default=${SPLIT_DEFAULT_REMOVE_EMPTY_TEXT})`, _t("Whether or not to remove empty text messages from the split results. The default behavior is to treat consecutive delimiters as one (if TRUE). If FALSE, empty cells values are added between consecutive delimiters."))
84169
84182
  ],
84170
84183
  compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
84171
- const _text = toString(text);
84172
- const _delimiter = escapeRegExp(toString(delimiter));
84184
+ const _text = toLocaleString(text, this.locale);
84185
+ const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
84173
84186
  const _splitByEach = toBoolean(splitByEach);
84174
84187
  const _removeEmptyText = toBoolean(removeEmptyText);
84175
84188
  if (_delimiter.length <= 0) return new EvaluationError(_t("The delimiter (%s) must be not be empty.", _delimiter));
@@ -84191,10 +84204,10 @@ stores.inject(MyMetaStore, storeInstance);
84191
84204
  compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
84192
84205
  const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
84193
84206
  if (_occurrenceNumber < 0) return new EvaluationError(_t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber));
84194
- const _textToSearch = toString(textToSearch);
84195
- const _searchFor = toString(searchFor);
84207
+ const _textToSearch = toLocaleString(textToSearch, this.locale);
84208
+ const _searchFor = toLocaleString(searchFor, this.locale);
84196
84209
  if (_searchFor === "") return _textToSearch;
84197
- const _replaceWith = toString(replaceWith);
84210
+ const _replaceWith = toLocaleString(replaceWith, this.locale);
84198
84211
  const reg = new RegExp(escapeRegExp(_searchFor), "g");
84199
84212
  if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
84200
84213
  let n = 0;
@@ -84217,10 +84230,10 @@ stores.inject(MyMetaStore, storeInstance);
84217
84230
  arg("texts (string, range<string>, repeating)", _t("Text item to join."))
84218
84231
  ],
84219
84232
  compute: function(delimiter, ignoreEmpty = { value: TEXTJOIN_DEFAULT_IGNORE_EMPTY }, ...textsOrArrays) {
84220
- const _delimiter = toString(delimiter);
84233
+ const _delimiter = toLocaleString(delimiter, this.locale);
84221
84234
  const _ignoreEmpty = toBoolean(ignoreEmpty);
84222
84235
  let n = 0;
84223
- return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toString(a) === "") ? (n++ ? acc + _delimiter : "") + toString(a) : acc, "");
84236
+ return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
84224
84237
  },
84225
84238
  isExported: true
84226
84239
  };
@@ -84273,7 +84286,7 @@ stores.inject(MyMetaStore, storeInstance);
84273
84286
  description: _t("Removes space characters."),
84274
84287
  args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
84275
84288
  compute: function(text) {
84276
- return trimContent(toString(text));
84289
+ return trimContent(toLocaleString(text, this.locale));
84277
84290
  },
84278
84291
  isExported: true
84279
84292
  };
@@ -84281,7 +84294,7 @@ stores.inject(MyMetaStore, storeInstance);
84281
84294
  description: _t("Converts a specified string to uppercase."),
84282
84295
  args: [arg("text (string)", _t("The string to convert to uppercase."))],
84283
84296
  compute: function(text) {
84284
- return toString(text).toUpperCase();
84297
+ return toLocaleString(text, this.locale).toUpperCase();
84285
84298
  },
84286
84299
  isExported: true
84287
84300
  };
@@ -84378,7 +84391,7 @@ stores.inject(MyMetaStore, storeInstance);
84378
84391
  args: [arg("url (string)", _t("The full URL of the link enclosed in quotation marks.")), arg("link_label (string, optional)", _t("The text to display in the cell, enclosed in quotation marks."))],
84379
84392
  compute: function(url, linkLabel) {
84380
84393
  const processedUrl = toString(url).trim();
84381
- const processedLabel = toString(linkLabel) || processedUrl;
84394
+ const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
84382
84395
  if (processedUrl === "") return processedLabel;
84383
84396
  return markdownLink(processedLabel, processedUrl);
84384
84397
  },
@@ -84775,8 +84788,8 @@ exports.stores = stores;
84775
84788
  exports.tokenColors = tokenColors;
84776
84789
  exports.tokenize = tokenize;
84777
84790
 
84778
- __info__.version = "19.3.16";
84779
- __info__.date = "2026-08-12T09:15:31.627Z";
84780
- __info__.hash = "464be42";
84791
+ __info__.version = "19.3.17";
84792
+ __info__.date = "2026-08-21T15:31:50.940Z";
84793
+ __info__.hash = "cf8c614";
84781
84794
 
84782
84795
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);