@odoo/o-spreadsheet 19.4.7 → 19.4.8
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.
- package/dist/o_spreadsheet.cjs +59 -40
- package/dist/o_spreadsheet.css +19 -3
- package/dist/o_spreadsheet.esm.js +59 -40
- package/dist/o_spreadsheet.iife.js +59 -40
- package/dist/o_spreadsheet.min.iife.js +261 -261
- package/dist/o_spreadsheet.xml +12 -11
- package/dist/types/components/figures/figure/figure.d.ts +1 -0
- package/dist/types/functions/helpers.d.ts +4 -0
- package/dist/types/functions/module_operators.d.ts +1 -1
- package/dist/types/functions/module_text.d.ts +11 -11
- package/dist/types/functions/module_web.d.ts +1 -1
- package/dist/types/registries/figures_registry.d.ts +1 -0
- package/package.json +1 -1
package/dist/o_spreadsheet.cjs
CHANGED
|
@@ -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.4.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.4.8
|
|
6
|
+
* @date 2026-08-19T09:25:13.754Z
|
|
7
|
+
* @hash 9dd828e
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
@@ -4026,6 +4026,18 @@ function toString(data) {
|
|
|
4026
4026
|
default: return "";
|
|
4027
4027
|
}
|
|
4028
4028
|
}
|
|
4029
|
+
/**
|
|
4030
|
+
* Only converts the decimal separator, ignore number format such as % or dates
|
|
4031
|
+
*/
|
|
4032
|
+
function toLocaleString(data, locale) {
|
|
4033
|
+
const value = toValue(data);
|
|
4034
|
+
switch (typeof value) {
|
|
4035
|
+
case "string": return value;
|
|
4036
|
+
case "number": return value.toString().replace(".", locale.decimalSeparator);
|
|
4037
|
+
case "boolean": return value ? "TRUE" : "FALSE";
|
|
4038
|
+
default: return "";
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4029
4041
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
4030
4042
|
const normalizeString = memoize(function normalizeString(str) {
|
|
4031
4043
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
@@ -15479,18 +15491,21 @@ const figureRegistry = new Registry();
|
|
|
15479
15491
|
figureRegistry.add("chart", {
|
|
15480
15492
|
Component: ChartFigure,
|
|
15481
15493
|
SidePanelComponent: "ChartPanel",
|
|
15482
|
-
menuBuilder: getChartMenuActions
|
|
15494
|
+
menuBuilder: getChartMenuActions,
|
|
15495
|
+
isThemeDependant: true
|
|
15483
15496
|
});
|
|
15484
15497
|
figureRegistry.add("image", {
|
|
15485
15498
|
Component: ImageFigure,
|
|
15486
15499
|
keepRatio: true,
|
|
15487
15500
|
minFigSize: 20,
|
|
15488
15501
|
borderWidth: 0,
|
|
15489
|
-
menuBuilder: getImageMenuActions
|
|
15502
|
+
menuBuilder: getImageMenuActions,
|
|
15503
|
+
isThemeDependant: false
|
|
15490
15504
|
});
|
|
15491
15505
|
figureRegistry.add("carousel", {
|
|
15492
15506
|
Component: CarouselFigure,
|
|
15493
|
-
menuBuilder: getCarouselMenuActions
|
|
15507
|
+
menuBuilder: getCarouselMenuActions,
|
|
15508
|
+
isThemeDependant: true
|
|
15494
15509
|
});
|
|
15495
15510
|
|
|
15496
15511
|
//#endregion
|
|
@@ -15519,6 +15534,9 @@ var FigureComponent = class extends Component {
|
|
|
15519
15534
|
get isSelected() {
|
|
15520
15535
|
return this.env.model.getters.getSelectedFigureIds().includes(this.props.figureUI.id);
|
|
15521
15536
|
}
|
|
15537
|
+
get isThemeDependant() {
|
|
15538
|
+
return figureRegistry.get(this.props.figureUI.tag).isThemeDependant;
|
|
15539
|
+
}
|
|
15522
15540
|
get figureRegistry() {
|
|
15523
15541
|
return figureRegistry;
|
|
15524
15542
|
}
|
|
@@ -78026,12 +78044,13 @@ var FilterMenu = class extends Component {
|
|
|
78026
78044
|
}
|
|
78027
78045
|
sortFilterZone(sortDirection) {
|
|
78028
78046
|
const filterPosition = this.props.filterPosition;
|
|
78029
|
-
const
|
|
78047
|
+
const table = this.table;
|
|
78048
|
+
const tableZone = table?.range.zone;
|
|
78030
78049
|
if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
|
|
78031
78050
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
78032
78051
|
const contentZone = {
|
|
78033
78052
|
...tableZone,
|
|
78034
|
-
top: tableZone.top +
|
|
78053
|
+
top: tableZone.top + table.config.numberOfHeaders
|
|
78035
78054
|
};
|
|
78036
78055
|
const sortAnchor = {
|
|
78037
78056
|
col: filterPosition.col,
|
|
@@ -80288,7 +80307,7 @@ const ARRAYTOTEXT = {
|
|
|
80288
80307
|
else if (_format === 0) {
|
|
80289
80308
|
const rowSeparator = this.locale.decimalSeparator === "," ? "/" : ",";
|
|
80290
80309
|
return transposeMatrix(_array).flatMap((row) => row.map((value) => {
|
|
80291
|
-
return isEvaluationError(value.value) ? value.value :
|
|
80310
|
+
return isEvaluationError(value.value) ? value.value : toLocaleString(value, this.locale);
|
|
80292
80311
|
})).join(rowSeparator);
|
|
80293
80312
|
} else return new EvaluationError(_t("Format must be 0 or 1"));
|
|
80294
80313
|
},
|
|
@@ -86054,7 +86073,7 @@ const CONCAT = {
|
|
|
86054
86073
|
description: _t("Concatenation of two values."),
|
|
86055
86074
|
args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
|
|
86056
86075
|
compute: function(value1, value2) {
|
|
86057
|
-
return
|
|
86076
|
+
return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
|
|
86058
86077
|
},
|
|
86059
86078
|
isExported: true
|
|
86060
86079
|
};
|
|
@@ -86937,7 +86956,7 @@ const CLEAN = {
|
|
|
86937
86956
|
description: _t("Remove non-printable characters from a piece of text."),
|
|
86938
86957
|
args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
|
|
86939
86958
|
compute: function(text) {
|
|
86940
|
-
const _text =
|
|
86959
|
+
const _text = toLocaleString(text, this.locale);
|
|
86941
86960
|
let cleanedStr = "";
|
|
86942
86961
|
for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
|
|
86943
86962
|
return cleanedStr;
|
|
@@ -86948,7 +86967,7 @@ const CONCATENATE = {
|
|
|
86948
86967
|
description: _t("Appends strings to one another."),
|
|
86949
86968
|
args: [arg("string (string, range<string>, repeating)", _t("String to append in sequence."))],
|
|
86950
86969
|
compute: function(...datas) {
|
|
86951
|
-
return reduceAny(datas, (acc, a) => acc +
|
|
86970
|
+
return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
|
|
86952
86971
|
},
|
|
86953
86972
|
isExported: true
|
|
86954
86973
|
};
|
|
@@ -86956,7 +86975,7 @@ const EXACT = {
|
|
|
86956
86975
|
description: _t("Tests whether two strings are identical."),
|
|
86957
86976
|
args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
|
|
86958
86977
|
compute: function(string1, string2) {
|
|
86959
|
-
return
|
|
86978
|
+
return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
|
|
86960
86979
|
},
|
|
86961
86980
|
isExported: true
|
|
86962
86981
|
};
|
|
@@ -86968,8 +86987,8 @@ const FIND = {
|
|
|
86968
86987
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
86969
86988
|
],
|
|
86970
86989
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
86971
|
-
const _searchFor =
|
|
86972
|
-
const _textToSearch =
|
|
86990
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
86991
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
86973
86992
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
86974
86993
|
if (_textToSearch === "") return new EvaluationError(_t("The text_to_search must be non-empty."));
|
|
86975
86994
|
if (_startingAt < 1) return new EvaluationError(_t("The starting_at (%s) must be greater than or equal to 1.", _startingAt));
|
|
@@ -87006,8 +87025,8 @@ const JOIN = {
|
|
|
87006
87025
|
description: _t("Concatenates elements of arrays with delimiter."),
|
|
87007
87026
|
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."))],
|
|
87008
87027
|
compute: function(delimiter, ...valuesOrArrays) {
|
|
87009
|
-
const _delimiter =
|
|
87010
|
-
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") +
|
|
87028
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
87029
|
+
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
|
|
87011
87030
|
}
|
|
87012
87031
|
};
|
|
87013
87032
|
const LEFT = {
|
|
@@ -87016,7 +87035,7 @@ const LEFT = {
|
|
|
87016
87035
|
compute: function(text, ...args) {
|
|
87017
87036
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
87018
87037
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
87019
|
-
return
|
|
87038
|
+
return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
|
|
87020
87039
|
},
|
|
87021
87040
|
isExported: true
|
|
87022
87041
|
};
|
|
@@ -87024,7 +87043,7 @@ const LEN = {
|
|
|
87024
87043
|
description: _t("Length of a string."),
|
|
87025
87044
|
args: [arg("text (string)", _t("The string whose length will be returned."))],
|
|
87026
87045
|
compute: function(text) {
|
|
87027
|
-
return
|
|
87046
|
+
return toLocaleString(text, this.locale).length;
|
|
87028
87047
|
},
|
|
87029
87048
|
isExported: true
|
|
87030
87049
|
};
|
|
@@ -87032,7 +87051,7 @@ const LOWER = {
|
|
|
87032
87051
|
description: _t("Converts a specified string to lowercase."),
|
|
87033
87052
|
args: [arg("text (string)", _t("The string to convert to lowercase."))],
|
|
87034
87053
|
compute: function(text) {
|
|
87035
|
-
return
|
|
87054
|
+
return toLocaleString(text, this.locale).toLowerCase();
|
|
87036
87055
|
},
|
|
87037
87056
|
isExported: true
|
|
87038
87057
|
};
|
|
@@ -87044,7 +87063,7 @@ const MID = {
|
|
|
87044
87063
|
arg("extract_length (number)", _t("The length of the segment to extract."))
|
|
87045
87064
|
],
|
|
87046
87065
|
compute: function(text, starting_at, extract_length) {
|
|
87047
|
-
const _text =
|
|
87066
|
+
const _text = toLocaleString(text, this.locale);
|
|
87048
87067
|
const _starting_at = toNumber(starting_at, this.locale);
|
|
87049
87068
|
const _extract_length = toNumber(extract_length, this.locale);
|
|
87050
87069
|
if (_starting_at < 1) return new EvaluationError(_t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
|
|
@@ -87057,7 +87076,7 @@ const PROPER = {
|
|
|
87057
87076
|
description: _t("Capitalizes each word in a specified string."),
|
|
87058
87077
|
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."))],
|
|
87059
87078
|
compute: function(text) {
|
|
87060
|
-
return
|
|
87079
|
+
return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
|
|
87061
87080
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
87062
87081
|
});
|
|
87063
87082
|
},
|
|
@@ -87207,8 +87226,8 @@ const REPLACE = {
|
|
|
87207
87226
|
if (_position < 1) return new EvaluationError(_t("The position (%s) must be greater than or equal to 1.", _position));
|
|
87208
87227
|
const _length = toNumber(length, this.locale);
|
|
87209
87228
|
if (_length < 0) return new EvaluationError(_t("The length (%s) must be positive or zero.", _length));
|
|
87210
|
-
const _text =
|
|
87211
|
-
const _newText =
|
|
87229
|
+
const _text = toLocaleString(text, this.locale);
|
|
87230
|
+
const _newText = toLocaleString(newText, this.locale);
|
|
87212
87231
|
return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
|
|
87213
87232
|
},
|
|
87214
87233
|
isExported: true
|
|
@@ -87219,7 +87238,7 @@ const RIGHT = {
|
|
|
87219
87238
|
compute: function(text, ...args) {
|
|
87220
87239
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
87221
87240
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or zero.", _numberOfCharacters));
|
|
87222
|
-
const _text =
|
|
87241
|
+
const _text = toLocaleString(text, this.locale);
|
|
87223
87242
|
const stringLength = _text.length;
|
|
87224
87243
|
return _text.substring(stringLength - _numberOfCharacters, stringLength);
|
|
87225
87244
|
},
|
|
@@ -87233,8 +87252,8 @@ const SEARCH = {
|
|
|
87233
87252
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
87234
87253
|
],
|
|
87235
87254
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
87236
|
-
const _searchFor =
|
|
87237
|
-
const _textToSearch =
|
|
87255
|
+
const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
|
|
87256
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
|
|
87238
87257
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
87239
87258
|
if (_textToSearch === "") return {
|
|
87240
87259
|
value: CellErrorType.GenericError,
|
|
@@ -87264,8 +87283,8 @@ const SPLIT = {
|
|
|
87264
87283
|
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."))
|
|
87265
87284
|
],
|
|
87266
87285
|
compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
|
|
87267
|
-
const _text =
|
|
87268
|
-
const _delimiter = escapeRegExp(
|
|
87286
|
+
const _text = toLocaleString(text, this.locale);
|
|
87287
|
+
const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
|
|
87269
87288
|
const _splitByEach = toBoolean(splitByEach);
|
|
87270
87289
|
const _removeEmptyText = toBoolean(removeEmptyText);
|
|
87271
87290
|
if (_delimiter.length <= 0) return new EvaluationError(_t("The delimiter (%s) must be not be empty.", _delimiter));
|
|
@@ -87287,10 +87306,10 @@ const SUBSTITUTE = {
|
|
|
87287
87306
|
compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
|
|
87288
87307
|
const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
|
|
87289
87308
|
if (_occurrenceNumber < 0) return new EvaluationError(_t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber));
|
|
87290
|
-
const _textToSearch =
|
|
87291
|
-
const _searchFor =
|
|
87309
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
87310
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
87292
87311
|
if (_searchFor === "") return _textToSearch;
|
|
87293
|
-
const _replaceWith =
|
|
87312
|
+
const _replaceWith = toLocaleString(replaceWith, this.locale);
|
|
87294
87313
|
const reg = new RegExp(escapeRegExp(_searchFor), "g");
|
|
87295
87314
|
if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
|
|
87296
87315
|
let n = 0;
|
|
@@ -87313,10 +87332,10 @@ const TEXTJOIN = {
|
|
|
87313
87332
|
arg("texts (string, range<string>, repeating)", _t("Text item to join."))
|
|
87314
87333
|
],
|
|
87315
87334
|
compute: function(delimiter, ignoreEmpty = { value: TEXTJOIN_DEFAULT_IGNORE_EMPTY }, ...textsOrArrays) {
|
|
87316
|
-
const _delimiter =
|
|
87335
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
87317
87336
|
const _ignoreEmpty = toBoolean(ignoreEmpty);
|
|
87318
87337
|
let n = 0;
|
|
87319
|
-
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty &&
|
|
87338
|
+
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
|
|
87320
87339
|
},
|
|
87321
87340
|
isExported: true
|
|
87322
87341
|
};
|
|
@@ -87369,7 +87388,7 @@ const TRIM = {
|
|
|
87369
87388
|
description: _t("Removes space characters."),
|
|
87370
87389
|
args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
|
|
87371
87390
|
compute: function(text) {
|
|
87372
|
-
return trimContent(
|
|
87391
|
+
return trimContent(toLocaleString(text, this.locale));
|
|
87373
87392
|
},
|
|
87374
87393
|
isExported: true
|
|
87375
87394
|
};
|
|
@@ -87377,7 +87396,7 @@ const UPPER = {
|
|
|
87377
87396
|
description: _t("Converts a specified string to uppercase."),
|
|
87378
87397
|
args: [arg("text (string)", _t("The string to convert to uppercase."))],
|
|
87379
87398
|
compute: function(text) {
|
|
87380
|
-
return
|
|
87399
|
+
return toLocaleString(text, this.locale).toUpperCase();
|
|
87381
87400
|
},
|
|
87382
87401
|
isExported: true
|
|
87383
87402
|
};
|
|
@@ -87474,7 +87493,7 @@ const HYPERLINK = {
|
|
|
87474
87493
|
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."))],
|
|
87475
87494
|
compute: function(url, linkLabel) {
|
|
87476
87495
|
const processedUrl = toString(url).trim();
|
|
87477
|
-
const processedLabel =
|
|
87496
|
+
const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
|
|
87478
87497
|
if (processedUrl === "") return processedLabel;
|
|
87479
87498
|
return markdownLink(processedLabel, processedUrl);
|
|
87480
87499
|
},
|
|
@@ -87923,6 +87942,6 @@ exports.stores = stores;
|
|
|
87923
87942
|
exports.tokenColors = tokenColors;
|
|
87924
87943
|
exports.tokenize = tokenize;
|
|
87925
87944
|
|
|
87926
|
-
__info__.version = "19.4.
|
|
87927
|
-
__info__.date = "2026-08-
|
|
87928
|
-
__info__.hash = "
|
|
87945
|
+
__info__.version = "19.4.8";
|
|
87946
|
+
__info__.date = "2026-08-19T09:25:13.754Z";
|
|
87947
|
+
__info__.hash = "9dd828e";
|
package/dist/o_spreadsheet.css
CHANGED
|
@@ -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.4.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.4.8
|
|
6
|
+
* @date 2026-08-19T09:25:15.535Z
|
|
7
|
+
* @hash 9dd828e
|
|
8
8
|
*/
|
|
9
9
|
:root {
|
|
10
10
|
--os-gray-100: light-dark(#f9fafb, #1b1d26);
|
|
@@ -2565,6 +2565,22 @@
|
|
|
2565
2565
|
}
|
|
2566
2566
|
}
|
|
2567
2567
|
|
|
2568
|
+
/* Originates from src/components/figures/figure_image/figure_image.css */
|
|
2569
|
+
.o-spreadsheet {
|
|
2570
|
+
.o-figure-menu-item {
|
|
2571
|
+
cursor: pointer;
|
|
2572
|
+
color: var(--os-gray-900) !important;
|
|
2573
|
+
height: 20px;
|
|
2574
|
+
width: 20px;
|
|
2575
|
+
&.active,
|
|
2576
|
+
&:hover,
|
|
2577
|
+
&:target {
|
|
2578
|
+
cursor: pointer;
|
|
2579
|
+
background-color: var(--os-background-gray-color-hover);
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
|
|
2568
2584
|
/* Originates from src/components/figures/figure_container/figure_container.css */
|
|
2569
2585
|
.o-spreadsheet {
|
|
2570
2586
|
.o-figure-snap-line {
|
|
@@ -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.4.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.4.8
|
|
6
|
+
* @date 2026-08-19T09:25:13.754Z
|
|
7
|
+
* @hash 9dd828e
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import * as owl from "@odoo/owl";
|
|
@@ -4025,6 +4025,18 @@ function toString(data) {
|
|
|
4025
4025
|
default: return "";
|
|
4026
4026
|
}
|
|
4027
4027
|
}
|
|
4028
|
+
/**
|
|
4029
|
+
* Only converts the decimal separator, ignore number format such as % or dates
|
|
4030
|
+
*/
|
|
4031
|
+
function toLocaleString(data, locale) {
|
|
4032
|
+
const value = toValue(data);
|
|
4033
|
+
switch (typeof value) {
|
|
4034
|
+
case "string": return value;
|
|
4035
|
+
case "number": return value.toString().replace(".", locale.decimalSeparator);
|
|
4036
|
+
case "boolean": return value ? "TRUE" : "FALSE";
|
|
4037
|
+
default: return "";
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4028
4040
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
4029
4041
|
const normalizeString = memoize(function normalizeString(str) {
|
|
4030
4042
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
@@ -15478,18 +15490,21 @@ const figureRegistry = new Registry();
|
|
|
15478
15490
|
figureRegistry.add("chart", {
|
|
15479
15491
|
Component: ChartFigure,
|
|
15480
15492
|
SidePanelComponent: "ChartPanel",
|
|
15481
|
-
menuBuilder: getChartMenuActions
|
|
15493
|
+
menuBuilder: getChartMenuActions,
|
|
15494
|
+
isThemeDependant: true
|
|
15482
15495
|
});
|
|
15483
15496
|
figureRegistry.add("image", {
|
|
15484
15497
|
Component: ImageFigure,
|
|
15485
15498
|
keepRatio: true,
|
|
15486
15499
|
minFigSize: 20,
|
|
15487
15500
|
borderWidth: 0,
|
|
15488
|
-
menuBuilder: getImageMenuActions
|
|
15501
|
+
menuBuilder: getImageMenuActions,
|
|
15502
|
+
isThemeDependant: false
|
|
15489
15503
|
});
|
|
15490
15504
|
figureRegistry.add("carousel", {
|
|
15491
15505
|
Component: CarouselFigure,
|
|
15492
|
-
menuBuilder: getCarouselMenuActions
|
|
15506
|
+
menuBuilder: getCarouselMenuActions,
|
|
15507
|
+
isThemeDependant: true
|
|
15493
15508
|
});
|
|
15494
15509
|
|
|
15495
15510
|
//#endregion
|
|
@@ -15518,6 +15533,9 @@ var FigureComponent = class extends Component {
|
|
|
15518
15533
|
get isSelected() {
|
|
15519
15534
|
return this.env.model.getters.getSelectedFigureIds().includes(this.props.figureUI.id);
|
|
15520
15535
|
}
|
|
15536
|
+
get isThemeDependant() {
|
|
15537
|
+
return figureRegistry.get(this.props.figureUI.tag).isThemeDependant;
|
|
15538
|
+
}
|
|
15521
15539
|
get figureRegistry() {
|
|
15522
15540
|
return figureRegistry;
|
|
15523
15541
|
}
|
|
@@ -77841,12 +77859,13 @@ var FilterMenu = class extends Component {
|
|
|
77841
77859
|
}
|
|
77842
77860
|
sortFilterZone(sortDirection) {
|
|
77843
77861
|
const filterPosition = this.props.filterPosition;
|
|
77844
|
-
const
|
|
77862
|
+
const table = this.table;
|
|
77863
|
+
const tableZone = table?.range.zone;
|
|
77845
77864
|
if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
|
|
77846
77865
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
77847
77866
|
const contentZone = {
|
|
77848
77867
|
...tableZone,
|
|
77849
|
-
top: tableZone.top +
|
|
77868
|
+
top: tableZone.top + table.config.numberOfHeaders
|
|
77850
77869
|
};
|
|
77851
77870
|
const sortAnchor = {
|
|
77852
77871
|
col: filterPosition.col,
|
|
@@ -80103,7 +80122,7 @@ const ARRAYTOTEXT = {
|
|
|
80103
80122
|
else if (_format === 0) {
|
|
80104
80123
|
const rowSeparator = this.locale.decimalSeparator === "," ? "/" : ",";
|
|
80105
80124
|
return transposeMatrix(_array).flatMap((row) => row.map((value) => {
|
|
80106
|
-
return isEvaluationError(value.value) ? value.value :
|
|
80125
|
+
return isEvaluationError(value.value) ? value.value : toLocaleString(value, this.locale);
|
|
80107
80126
|
})).join(rowSeparator);
|
|
80108
80127
|
} else return new EvaluationError(_t("Format must be 0 or 1"));
|
|
80109
80128
|
},
|
|
@@ -85869,7 +85888,7 @@ const CONCAT = {
|
|
|
85869
85888
|
description: _t("Concatenation of two values."),
|
|
85870
85889
|
args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
|
|
85871
85890
|
compute: function(value1, value2) {
|
|
85872
|
-
return
|
|
85891
|
+
return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
|
|
85873
85892
|
},
|
|
85874
85893
|
isExported: true
|
|
85875
85894
|
};
|
|
@@ -86752,7 +86771,7 @@ const CLEAN = {
|
|
|
86752
86771
|
description: _t("Remove non-printable characters from a piece of text."),
|
|
86753
86772
|
args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
|
|
86754
86773
|
compute: function(text) {
|
|
86755
|
-
const _text =
|
|
86774
|
+
const _text = toLocaleString(text, this.locale);
|
|
86756
86775
|
let cleanedStr = "";
|
|
86757
86776
|
for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
|
|
86758
86777
|
return cleanedStr;
|
|
@@ -86763,7 +86782,7 @@ const CONCATENATE = {
|
|
|
86763
86782
|
description: _t("Appends strings to one another."),
|
|
86764
86783
|
args: [arg("string (string, range<string>, repeating)", _t("String to append in sequence."))],
|
|
86765
86784
|
compute: function(...datas) {
|
|
86766
|
-
return reduceAny(datas, (acc, a) => acc +
|
|
86785
|
+
return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
|
|
86767
86786
|
},
|
|
86768
86787
|
isExported: true
|
|
86769
86788
|
};
|
|
@@ -86771,7 +86790,7 @@ const EXACT = {
|
|
|
86771
86790
|
description: _t("Tests whether two strings are identical."),
|
|
86772
86791
|
args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
|
|
86773
86792
|
compute: function(string1, string2) {
|
|
86774
|
-
return
|
|
86793
|
+
return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
|
|
86775
86794
|
},
|
|
86776
86795
|
isExported: true
|
|
86777
86796
|
};
|
|
@@ -86783,8 +86802,8 @@ const FIND = {
|
|
|
86783
86802
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
86784
86803
|
],
|
|
86785
86804
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
86786
|
-
const _searchFor =
|
|
86787
|
-
const _textToSearch =
|
|
86805
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
86806
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
86788
86807
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
86789
86808
|
if (_textToSearch === "") return new EvaluationError(_t("The text_to_search must be non-empty."));
|
|
86790
86809
|
if (_startingAt < 1) return new EvaluationError(_t("The starting_at (%s) must be greater than or equal to 1.", _startingAt));
|
|
@@ -86821,8 +86840,8 @@ const JOIN = {
|
|
|
86821
86840
|
description: _t("Concatenates elements of arrays with delimiter."),
|
|
86822
86841
|
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."))],
|
|
86823
86842
|
compute: function(delimiter, ...valuesOrArrays) {
|
|
86824
|
-
const _delimiter =
|
|
86825
|
-
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") +
|
|
86843
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
86844
|
+
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
|
|
86826
86845
|
}
|
|
86827
86846
|
};
|
|
86828
86847
|
const LEFT = {
|
|
@@ -86831,7 +86850,7 @@ const LEFT = {
|
|
|
86831
86850
|
compute: function(text, ...args) {
|
|
86832
86851
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
86833
86852
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
86834
|
-
return
|
|
86853
|
+
return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
|
|
86835
86854
|
},
|
|
86836
86855
|
isExported: true
|
|
86837
86856
|
};
|
|
@@ -86839,7 +86858,7 @@ const LEN = {
|
|
|
86839
86858
|
description: _t("Length of a string."),
|
|
86840
86859
|
args: [arg("text (string)", _t("The string whose length will be returned."))],
|
|
86841
86860
|
compute: function(text) {
|
|
86842
|
-
return
|
|
86861
|
+
return toLocaleString(text, this.locale).length;
|
|
86843
86862
|
},
|
|
86844
86863
|
isExported: true
|
|
86845
86864
|
};
|
|
@@ -86847,7 +86866,7 @@ const LOWER = {
|
|
|
86847
86866
|
description: _t("Converts a specified string to lowercase."),
|
|
86848
86867
|
args: [arg("text (string)", _t("The string to convert to lowercase."))],
|
|
86849
86868
|
compute: function(text) {
|
|
86850
|
-
return
|
|
86869
|
+
return toLocaleString(text, this.locale).toLowerCase();
|
|
86851
86870
|
},
|
|
86852
86871
|
isExported: true
|
|
86853
86872
|
};
|
|
@@ -86859,7 +86878,7 @@ const MID = {
|
|
|
86859
86878
|
arg("extract_length (number)", _t("The length of the segment to extract."))
|
|
86860
86879
|
],
|
|
86861
86880
|
compute: function(text, starting_at, extract_length) {
|
|
86862
|
-
const _text =
|
|
86881
|
+
const _text = toLocaleString(text, this.locale);
|
|
86863
86882
|
const _starting_at = toNumber(starting_at, this.locale);
|
|
86864
86883
|
const _extract_length = toNumber(extract_length, this.locale);
|
|
86865
86884
|
if (_starting_at < 1) return new EvaluationError(_t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
|
|
@@ -86872,7 +86891,7 @@ const PROPER = {
|
|
|
86872
86891
|
description: _t("Capitalizes each word in a specified string."),
|
|
86873
86892
|
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."))],
|
|
86874
86893
|
compute: function(text) {
|
|
86875
|
-
return
|
|
86894
|
+
return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
|
|
86876
86895
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
86877
86896
|
});
|
|
86878
86897
|
},
|
|
@@ -87022,8 +87041,8 @@ const REPLACE = {
|
|
|
87022
87041
|
if (_position < 1) return new EvaluationError(_t("The position (%s) must be greater than or equal to 1.", _position));
|
|
87023
87042
|
const _length = toNumber(length, this.locale);
|
|
87024
87043
|
if (_length < 0) return new EvaluationError(_t("The length (%s) must be positive or zero.", _length));
|
|
87025
|
-
const _text =
|
|
87026
|
-
const _newText =
|
|
87044
|
+
const _text = toLocaleString(text, this.locale);
|
|
87045
|
+
const _newText = toLocaleString(newText, this.locale);
|
|
87027
87046
|
return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
|
|
87028
87047
|
},
|
|
87029
87048
|
isExported: true
|
|
@@ -87034,7 +87053,7 @@ const RIGHT = {
|
|
|
87034
87053
|
compute: function(text, ...args) {
|
|
87035
87054
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
87036
87055
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or zero.", _numberOfCharacters));
|
|
87037
|
-
const _text =
|
|
87056
|
+
const _text = toLocaleString(text, this.locale);
|
|
87038
87057
|
const stringLength = _text.length;
|
|
87039
87058
|
return _text.substring(stringLength - _numberOfCharacters, stringLength);
|
|
87040
87059
|
},
|
|
@@ -87048,8 +87067,8 @@ const SEARCH = {
|
|
|
87048
87067
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
87049
87068
|
],
|
|
87050
87069
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
87051
|
-
const _searchFor =
|
|
87052
|
-
const _textToSearch =
|
|
87070
|
+
const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
|
|
87071
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
|
|
87053
87072
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
87054
87073
|
if (_textToSearch === "") return {
|
|
87055
87074
|
value: CellErrorType.GenericError,
|
|
@@ -87079,8 +87098,8 @@ const SPLIT = {
|
|
|
87079
87098
|
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."))
|
|
87080
87099
|
],
|
|
87081
87100
|
compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
|
|
87082
|
-
const _text =
|
|
87083
|
-
const _delimiter = escapeRegExp(
|
|
87101
|
+
const _text = toLocaleString(text, this.locale);
|
|
87102
|
+
const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
|
|
87084
87103
|
const _splitByEach = toBoolean(splitByEach);
|
|
87085
87104
|
const _removeEmptyText = toBoolean(removeEmptyText);
|
|
87086
87105
|
if (_delimiter.length <= 0) return new EvaluationError(_t("The delimiter (%s) must be not be empty.", _delimiter));
|
|
@@ -87102,10 +87121,10 @@ const SUBSTITUTE = {
|
|
|
87102
87121
|
compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
|
|
87103
87122
|
const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
|
|
87104
87123
|
if (_occurrenceNumber < 0) return new EvaluationError(_t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber));
|
|
87105
|
-
const _textToSearch =
|
|
87106
|
-
const _searchFor =
|
|
87124
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
87125
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
87107
87126
|
if (_searchFor === "") return _textToSearch;
|
|
87108
|
-
const _replaceWith =
|
|
87127
|
+
const _replaceWith = toLocaleString(replaceWith, this.locale);
|
|
87109
87128
|
const reg = new RegExp(escapeRegExp(_searchFor), "g");
|
|
87110
87129
|
if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
|
|
87111
87130
|
let n = 0;
|
|
@@ -87128,10 +87147,10 @@ const TEXTJOIN = {
|
|
|
87128
87147
|
arg("texts (string, range<string>, repeating)", _t("Text item to join."))
|
|
87129
87148
|
],
|
|
87130
87149
|
compute: function(delimiter, ignoreEmpty = { value: TEXTJOIN_DEFAULT_IGNORE_EMPTY }, ...textsOrArrays) {
|
|
87131
|
-
const _delimiter =
|
|
87150
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
87132
87151
|
const _ignoreEmpty = toBoolean(ignoreEmpty);
|
|
87133
87152
|
let n = 0;
|
|
87134
|
-
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty &&
|
|
87153
|
+
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
|
|
87135
87154
|
},
|
|
87136
87155
|
isExported: true
|
|
87137
87156
|
};
|
|
@@ -87184,7 +87203,7 @@ const TRIM = {
|
|
|
87184
87203
|
description: _t("Removes space characters."),
|
|
87185
87204
|
args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
|
|
87186
87205
|
compute: function(text) {
|
|
87187
|
-
return trimContent(
|
|
87206
|
+
return trimContent(toLocaleString(text, this.locale));
|
|
87188
87207
|
},
|
|
87189
87208
|
isExported: true
|
|
87190
87209
|
};
|
|
@@ -87192,7 +87211,7 @@ const UPPER = {
|
|
|
87192
87211
|
description: _t("Converts a specified string to uppercase."),
|
|
87193
87212
|
args: [arg("text (string)", _t("The string to convert to uppercase."))],
|
|
87194
87213
|
compute: function(text) {
|
|
87195
|
-
return
|
|
87214
|
+
return toLocaleString(text, this.locale).toUpperCase();
|
|
87196
87215
|
},
|
|
87197
87216
|
isExported: true
|
|
87198
87217
|
};
|
|
@@ -87289,7 +87308,7 @@ const HYPERLINK = {
|
|
|
87289
87308
|
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."))],
|
|
87290
87309
|
compute: function(url, linkLabel) {
|
|
87291
87310
|
const processedUrl = toString(url).trim();
|
|
87292
|
-
const processedLabel =
|
|
87311
|
+
const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
|
|
87293
87312
|
if (processedUrl === "") return processedLabel;
|
|
87294
87313
|
return markdownLink(processedLabel, processedUrl);
|
|
87295
87314
|
},
|
|
@@ -87644,6 +87663,6 @@ const chartHelpers = {
|
|
|
87644
87663
|
//#endregion
|
|
87645
87664
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, BadExpressionError, CHART_TYPES, CellErrorType, CellValueType, CircularDependencyError, ClientDisconnectedError, ClipboardMIMEType, CommandResult, CompiledFormula, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DEFAULT_LOCALE_DIGIT_GROUPING, DIRECTION, DispatchResult, DivisionByZeroError, EvaluationError, InvalidReferenceError, LocalTransportService, Model, NEXT_VALUE, NotAvailableError, NumberTooLargeError, OrderedLayers, PREVIOUS_VALUE, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, SplillBlockedError, Spreadsheet, SpreadsheetPivotTable, UIPlugin, UnknownFunctionError, __info__, addFunction, addRenderingLayer, astToFormula, availableConditionalFormatOperators, availableDataValidationOperators, availableFiltersOperators, borderPositions, borderStyles, canExecuteInReadonly, categories, chartHelpers, compatibility, components, composerFocusTypes, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, errorTypes, filterDateCriterionOperators, filterNumberCriterionOperators, filterTextCriterionOperators, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidSubtotalFormulasCommands, invalidateBordersCommands, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, isCoreCommand, isHeadersDependant, isMatrix, isPositionDependent, isRangeDependant, isSheetDependent, isTargetDependent, isZoneDependent, iterateAstNodes, links, load, lockedSheetAllowedCommands, parse, parseTokens, readonlyAllowedCommands, registries, schemeToColorScale, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
87646
87665
|
|
|
87647
|
-
__info__.version = "19.4.
|
|
87648
|
-
__info__.date = "2026-08-
|
|
87649
|
-
__info__.hash = "
|
|
87666
|
+
__info__.version = "19.4.8";
|
|
87667
|
+
__info__.date = "2026-08-19T09:25:13.754Z";
|
|
87668
|
+
__info__.hash = "9dd828e";
|