@odoo/o-spreadsheet 18.0.78 → 18.0.80
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.esm.js +61 -37
- package/dist/o-spreadsheet.iife.js +61 -37
- package/dist/o-spreadsheet.iife.min.js +296 -285
- package/dist/o_spreadsheet.xml +8 -4
- 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/package.json +1 -1
|
@@ -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.0.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.80
|
|
6
|
+
* @date 2026-08-29T09:13:05.057Z
|
|
7
|
+
* @hash af324f5
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Component, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, xml } from "@odoo/owl";
|
|
@@ -3272,6 +3272,18 @@ function toString(data) {
|
|
|
3272
3272
|
default: return "";
|
|
3273
3273
|
}
|
|
3274
3274
|
}
|
|
3275
|
+
/**
|
|
3276
|
+
* Only converts the decimal separator, ignore number format such as % or dates
|
|
3277
|
+
*/
|
|
3278
|
+
function toLocaleString(data, locale) {
|
|
3279
|
+
const value = toValue(data);
|
|
3280
|
+
switch (typeof value) {
|
|
3281
|
+
case "string": return value;
|
|
3282
|
+
case "number": return value.toString().replace(".", locale.decimalSeparator);
|
|
3283
|
+
case "boolean": return value ? "TRUE" : "FALSE";
|
|
3284
|
+
default: return "";
|
|
3285
|
+
}
|
|
3286
|
+
}
|
|
3275
3287
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
3276
3288
|
const normalizeString = memoize(function normalizeString(str) {
|
|
3277
3289
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
@@ -21713,7 +21725,7 @@ const CONCAT = {
|
|
|
21713
21725
|
description: _t("Concatenation of two values."),
|
|
21714
21726
|
args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
|
|
21715
21727
|
compute: function(value1, value2) {
|
|
21716
|
-
return
|
|
21728
|
+
return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
|
|
21717
21729
|
},
|
|
21718
21730
|
isExported: true
|
|
21719
21731
|
};
|
|
@@ -22515,7 +22527,7 @@ const CLEAN = {
|
|
|
22515
22527
|
description: _t("Remove non-printable characters from a piece of text."),
|
|
22516
22528
|
args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
|
|
22517
22529
|
compute: function(text) {
|
|
22518
|
-
const _text =
|
|
22530
|
+
const _text = toLocaleString(text, this.locale);
|
|
22519
22531
|
let cleanedStr = "";
|
|
22520
22532
|
for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
|
|
22521
22533
|
return cleanedStr;
|
|
@@ -22526,7 +22538,7 @@ const CONCATENATE = {
|
|
|
22526
22538
|
description: _t("Appends strings to one another."),
|
|
22527
22539
|
args: [arg("string1 (string, range<string>)", _t("The initial string.")), arg("string2 (string, range<string>, repeating)", _t("More strings to append in sequence."))],
|
|
22528
22540
|
compute: function(...datas) {
|
|
22529
|
-
return reduceAny(datas, (acc, a) => acc +
|
|
22541
|
+
return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
|
|
22530
22542
|
},
|
|
22531
22543
|
isExported: true
|
|
22532
22544
|
};
|
|
@@ -22534,7 +22546,7 @@ const EXACT = {
|
|
|
22534
22546
|
description: _t("Tests whether two strings are identical."),
|
|
22535
22547
|
args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
|
|
22536
22548
|
compute: function(string1, string2) {
|
|
22537
|
-
return
|
|
22549
|
+
return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
|
|
22538
22550
|
},
|
|
22539
22551
|
isExported: true
|
|
22540
22552
|
};
|
|
@@ -22546,13 +22558,13 @@ const FIND = {
|
|
|
22546
22558
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
22547
22559
|
],
|
|
22548
22560
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
22549
|
-
const _searchFor =
|
|
22550
|
-
const _textToSearch =
|
|
22561
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
22562
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
22551
22563
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
22552
22564
|
assert(() => _textToSearch !== "", _t("The text_to_search must be non-empty."));
|
|
22553
22565
|
assert(() => _startingAt >= 1, _t("The starting_at (%s) must be greater than or equal to 1.", _startingAt.toString()));
|
|
22554
22566
|
const result = _textToSearch.indexOf(_searchFor, _startingAt - 1);
|
|
22555
|
-
assert(() => result >= 0, _t("In [[FUNCTION_NAME]] evaluation, cannot find '%s' within '%s'.", _searchFor
|
|
22567
|
+
assert(() => result >= 0, _t("In [[FUNCTION_NAME]] evaluation, cannot find '%s' within '%s'.", _searchFor, _textToSearch));
|
|
22556
22568
|
return result + 1;
|
|
22557
22569
|
},
|
|
22558
22570
|
isExported: true
|
|
@@ -22565,8 +22577,8 @@ const JOIN = {
|
|
|
22565
22577
|
arg("value_or_array2 (string, range<string>, repeating)", _t("More values to be appended using delimiter."))
|
|
22566
22578
|
],
|
|
22567
22579
|
compute: function(delimiter, ...valuesOrArrays) {
|
|
22568
|
-
const _delimiter =
|
|
22569
|
-
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") +
|
|
22580
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
22581
|
+
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
|
|
22570
22582
|
}
|
|
22571
22583
|
};
|
|
22572
22584
|
const LEFT = {
|
|
@@ -22575,7 +22587,7 @@ const LEFT = {
|
|
|
22575
22587
|
compute: function(text, ...args) {
|
|
22576
22588
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
22577
22589
|
assert(() => _numberOfCharacters >= 0, _t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters.toString()));
|
|
22578
|
-
return
|
|
22590
|
+
return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
|
|
22579
22591
|
},
|
|
22580
22592
|
isExported: true
|
|
22581
22593
|
};
|
|
@@ -22583,7 +22595,7 @@ const LEN = {
|
|
|
22583
22595
|
description: _t("Length of a string."),
|
|
22584
22596
|
args: [arg("text (string)", _t("The string whose length will be returned."))],
|
|
22585
22597
|
compute: function(text) {
|
|
22586
|
-
return
|
|
22598
|
+
return toLocaleString(text, this.locale).length;
|
|
22587
22599
|
},
|
|
22588
22600
|
isExported: true
|
|
22589
22601
|
};
|
|
@@ -22591,7 +22603,7 @@ const LOWER = {
|
|
|
22591
22603
|
description: _t("Converts a specified string to lowercase."),
|
|
22592
22604
|
args: [arg("text (string)", _t("The string to convert to lowercase."))],
|
|
22593
22605
|
compute: function(text) {
|
|
22594
|
-
return
|
|
22606
|
+
return toLocaleString(text, this.locale).toLowerCase();
|
|
22595
22607
|
},
|
|
22596
22608
|
isExported: true
|
|
22597
22609
|
};
|
|
@@ -22603,7 +22615,7 @@ const MID = {
|
|
|
22603
22615
|
arg("extract_length (number)", _t("The length of the segment to extract."))
|
|
22604
22616
|
],
|
|
22605
22617
|
compute: function(text, starting_at, extract_length) {
|
|
22606
|
-
const _text =
|
|
22618
|
+
const _text = toLocaleString(text, this.locale);
|
|
22607
22619
|
const _starting_at = toNumber(starting_at, this.locale);
|
|
22608
22620
|
const _extract_length = toNumber(extract_length, this.locale);
|
|
22609
22621
|
assert(() => _starting_at >= 1, _t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
|
|
@@ -22616,7 +22628,7 @@ const PROPER = {
|
|
|
22616
22628
|
description: _t("Capitalizes each word in a specified string."),
|
|
22617
22629
|
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."))],
|
|
22618
22630
|
compute: function(text) {
|
|
22619
|
-
return
|
|
22631
|
+
return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
|
|
22620
22632
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
22621
22633
|
});
|
|
22622
22634
|
},
|
|
@@ -22633,9 +22645,9 @@ const REPLACE = {
|
|
|
22633
22645
|
compute: function(text, position, length, newText) {
|
|
22634
22646
|
const _position = toNumber(position, this.locale);
|
|
22635
22647
|
assert(() => _position >= 1, _t("The position (%s) must be greater than or equal to 1.", _position.toString()));
|
|
22636
|
-
const _text =
|
|
22648
|
+
const _text = toLocaleString(text, this.locale);
|
|
22637
22649
|
const _length = toNumber(length, this.locale);
|
|
22638
|
-
const _newText =
|
|
22650
|
+
const _newText = toLocaleString(newText, this.locale);
|
|
22639
22651
|
return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
|
|
22640
22652
|
},
|
|
22641
22653
|
isExported: true
|
|
@@ -22646,7 +22658,7 @@ const RIGHT = {
|
|
|
22646
22658
|
compute: function(text, ...args) {
|
|
22647
22659
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
22648
22660
|
assert(() => _numberOfCharacters >= 0, _t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters.toString()));
|
|
22649
|
-
const _text =
|
|
22661
|
+
const _text = toLocaleString(text, this.locale);
|
|
22650
22662
|
const stringLength = _text.length;
|
|
22651
22663
|
return _text.substring(stringLength - _numberOfCharacters, stringLength);
|
|
22652
22664
|
},
|
|
@@ -22660,8 +22672,8 @@ const SEARCH = {
|
|
|
22660
22672
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
22661
22673
|
],
|
|
22662
22674
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
22663
|
-
const _searchFor =
|
|
22664
|
-
const _textToSearch =
|
|
22675
|
+
const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
|
|
22676
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
|
|
22665
22677
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
22666
22678
|
if (_textToSearch === "") return {
|
|
22667
22679
|
value: CellErrorType.GenericError,
|
|
@@ -22691,8 +22703,8 @@ const SPLIT = {
|
|
|
22691
22703
|
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."))
|
|
22692
22704
|
],
|
|
22693
22705
|
compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
|
|
22694
|
-
const _text =
|
|
22695
|
-
const _delimiter = escapeRegExp(
|
|
22706
|
+
const _text = toLocaleString(text, this.locale);
|
|
22707
|
+
const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
|
|
22696
22708
|
const _splitByEach = toBoolean(splitByEach);
|
|
22697
22709
|
const _removeEmptyText = toBoolean(removeEmptyText);
|
|
22698
22710
|
assert(() => _delimiter.length > 0, _t("The _delimiter (%s) must be not be empty.", _delimiter));
|
|
@@ -22714,10 +22726,10 @@ const SUBSTITUTE = {
|
|
|
22714
22726
|
compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
|
|
22715
22727
|
const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
|
|
22716
22728
|
assert(() => _occurrenceNumber >= 0, _t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber.toString()));
|
|
22717
|
-
const _textToSearch =
|
|
22718
|
-
const _searchFor =
|
|
22729
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
22730
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
22719
22731
|
if (_searchFor === "") return _textToSearch;
|
|
22720
|
-
const _replaceWith =
|
|
22732
|
+
const _replaceWith = toLocaleString(replaceWith, this.locale);
|
|
22721
22733
|
const reg = new RegExp(escapeRegExp(_searchFor), "g");
|
|
22722
22734
|
if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
|
|
22723
22735
|
let n = 0;
|
|
@@ -22734,10 +22746,10 @@ const TEXTJOIN = {
|
|
|
22734
22746
|
arg("text2 (string, range<string>, repeating)", _t("Additional text item(s)."))
|
|
22735
22747
|
],
|
|
22736
22748
|
compute: function(delimiter, ignoreEmpty, ...textsOrArrays) {
|
|
22737
|
-
const _delimiter =
|
|
22749
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
22738
22750
|
const _ignoreEmpty = toBoolean(ignoreEmpty);
|
|
22739
22751
|
let n = 0;
|
|
22740
|
-
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty &&
|
|
22752
|
+
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
|
|
22741
22753
|
},
|
|
22742
22754
|
isExported: true
|
|
22743
22755
|
};
|
|
@@ -22745,7 +22757,7 @@ const TRIM = {
|
|
|
22745
22757
|
description: _t("Removes space characters."),
|
|
22746
22758
|
args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
|
|
22747
22759
|
compute: function(text) {
|
|
22748
|
-
return trimContent(
|
|
22760
|
+
return trimContent(toLocaleString(text, this.locale));
|
|
22749
22761
|
},
|
|
22750
22762
|
isExported: true
|
|
22751
22763
|
};
|
|
@@ -22753,7 +22765,7 @@ const UPPER = {
|
|
|
22753
22765
|
description: _t("Converts a specified string to uppercase."),
|
|
22754
22766
|
args: [arg("text (string)", _t("The string to convert to uppercase."))],
|
|
22755
22767
|
compute: function(text) {
|
|
22756
|
-
return
|
|
22768
|
+
return toLocaleString(text, this.locale).toUpperCase();
|
|
22757
22769
|
},
|
|
22758
22770
|
isExported: true
|
|
22759
22771
|
};
|
|
@@ -22785,7 +22797,7 @@ const HYPERLINK = {
|
|
|
22785
22797
|
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."))],
|
|
22786
22798
|
compute: function(url, linkLabel) {
|
|
22787
22799
|
const processedUrl = toString(url).trim();
|
|
22788
|
-
const processedLabel =
|
|
22800
|
+
const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
|
|
22789
22801
|
if (processedUrl === "") return processedLabel;
|
|
22790
22802
|
return markdownLink(processedLabel, processedUrl);
|
|
22791
22803
|
},
|
|
@@ -27971,12 +27983,13 @@ var FilterMenu = class extends Component {
|
|
|
27971
27983
|
}
|
|
27972
27984
|
sortFilterZone(sortDirection) {
|
|
27973
27985
|
const filterPosition = this.props.filterPosition;
|
|
27974
|
-
const
|
|
27986
|
+
const table = this.table;
|
|
27987
|
+
const tableZone = table?.range.zone;
|
|
27975
27988
|
if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
|
|
27976
27989
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
27977
27990
|
const contentZone = {
|
|
27978
27991
|
...tableZone,
|
|
27979
|
-
top: tableZone.top +
|
|
27992
|
+
top: tableZone.top + table.config.numberOfHeaders
|
|
27980
27993
|
};
|
|
27981
27994
|
this.env.model.dispatch("SORT_CELLS", {
|
|
27982
27995
|
sheetId,
|
|
@@ -32559,6 +32572,12 @@ css`
|
|
|
32559
32572
|
background-color: ${ACTION_COLOR};
|
|
32560
32573
|
border-color: ${ACTION_COLOR};
|
|
32561
32574
|
}
|
|
32575
|
+
|
|
32576
|
+
&:focus {
|
|
32577
|
+
outline: none;
|
|
32578
|
+
box-shadow: 0 0 0 0.25rem rgba(113, 75, 103, 0.25);
|
|
32579
|
+
border-color: ${ACTION_COLOR};
|
|
32580
|
+
}
|
|
32562
32581
|
}
|
|
32563
32582
|
}
|
|
32564
32583
|
`;
|
|
@@ -38090,6 +38109,7 @@ css`
|
|
|
38090
38109
|
.os-input {
|
|
38091
38110
|
box-sizing: border-box;
|
|
38092
38111
|
border-width: 0 0 1px 0;
|
|
38112
|
+
border-style: solid;
|
|
38093
38113
|
border-color: transparent;
|
|
38094
38114
|
outline: none;
|
|
38095
38115
|
text-overflow: ellipsis;
|
|
@@ -60651,6 +60671,9 @@ css`
|
|
|
60651
60671
|
position: absolute;
|
|
60652
60672
|
cursor: pointer;
|
|
60653
60673
|
}
|
|
60674
|
+
.o-grid.o-dashboard-grid {
|
|
60675
|
+
background: #ffffff;
|
|
60676
|
+
}
|
|
60654
60677
|
`;
|
|
60655
60678
|
var SpreadsheetDashboard = class extends Component {
|
|
60656
60679
|
static template = "o-spreadsheet-SpreadsheetDashboard";
|
|
@@ -62063,6 +62086,7 @@ css`
|
|
|
62063
62086
|
width: 100%;
|
|
62064
62087
|
outline: none;
|
|
62065
62088
|
border-color: ${GRAY_300};
|
|
62089
|
+
border-style: solid;
|
|
62066
62090
|
color: ${GRAY_900};
|
|
62067
62091
|
|
|
62068
62092
|
&::placeholder {
|
|
@@ -66388,6 +66412,6 @@ const constants = {
|
|
|
66388
66412
|
//#endregion
|
|
66389
66413
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
66390
66414
|
|
|
66391
|
-
__info__.version = "18.0.
|
|
66392
|
-
__info__.date = "2026-08-
|
|
66393
|
-
__info__.hash = "
|
|
66415
|
+
__info__.version = "18.0.80";
|
|
66416
|
+
__info__.date = "2026-08-29T09:13:05.057Z";
|
|
66417
|
+
__info__.hash = "af324f5";
|
|
@@ -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.0.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.80
|
|
6
|
+
* @date 2026-08-29T09:13:05.057Z
|
|
7
|
+
* @hash af324f5
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function(exports, _odoo_owl) {
|
|
@@ -3274,6 +3274,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3274
3274
|
default: return "";
|
|
3275
3275
|
}
|
|
3276
3276
|
}
|
|
3277
|
+
/**
|
|
3278
|
+
* Only converts the decimal separator, ignore number format such as % or dates
|
|
3279
|
+
*/
|
|
3280
|
+
function toLocaleString(data, locale) {
|
|
3281
|
+
const value = toValue(data);
|
|
3282
|
+
switch (typeof value) {
|
|
3283
|
+
case "string": return value;
|
|
3284
|
+
case "number": return value.toString().replace(".", locale.decimalSeparator);
|
|
3285
|
+
case "boolean": return value ? "TRUE" : "FALSE";
|
|
3286
|
+
default: return "";
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3277
3289
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
3278
3290
|
const normalizeString = memoize(function normalizeString(str) {
|
|
3279
3291
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
@@ -21715,7 +21727,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
21715
21727
|
description: _t("Concatenation of two values."),
|
|
21716
21728
|
args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
|
|
21717
21729
|
compute: function(value1, value2) {
|
|
21718
|
-
return
|
|
21730
|
+
return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
|
|
21719
21731
|
},
|
|
21720
21732
|
isExported: true
|
|
21721
21733
|
};
|
|
@@ -22517,7 +22529,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22517
22529
|
description: _t("Remove non-printable characters from a piece of text."),
|
|
22518
22530
|
args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
|
|
22519
22531
|
compute: function(text) {
|
|
22520
|
-
const _text =
|
|
22532
|
+
const _text = toLocaleString(text, this.locale);
|
|
22521
22533
|
let cleanedStr = "";
|
|
22522
22534
|
for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
|
|
22523
22535
|
return cleanedStr;
|
|
@@ -22528,7 +22540,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22528
22540
|
description: _t("Appends strings to one another."),
|
|
22529
22541
|
args: [arg("string1 (string, range<string>)", _t("The initial string.")), arg("string2 (string, range<string>, repeating)", _t("More strings to append in sequence."))],
|
|
22530
22542
|
compute: function(...datas) {
|
|
22531
|
-
return reduceAny(datas, (acc, a) => acc +
|
|
22543
|
+
return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
|
|
22532
22544
|
},
|
|
22533
22545
|
isExported: true
|
|
22534
22546
|
};
|
|
@@ -22536,7 +22548,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22536
22548
|
description: _t("Tests whether two strings are identical."),
|
|
22537
22549
|
args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
|
|
22538
22550
|
compute: function(string1, string2) {
|
|
22539
|
-
return
|
|
22551
|
+
return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
|
|
22540
22552
|
},
|
|
22541
22553
|
isExported: true
|
|
22542
22554
|
};
|
|
@@ -22548,13 +22560,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22548
22560
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
22549
22561
|
],
|
|
22550
22562
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
22551
|
-
const _searchFor =
|
|
22552
|
-
const _textToSearch =
|
|
22563
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
22564
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
22553
22565
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
22554
22566
|
assert(() => _textToSearch !== "", _t("The text_to_search must be non-empty."));
|
|
22555
22567
|
assert(() => _startingAt >= 1, _t("The starting_at (%s) must be greater than or equal to 1.", _startingAt.toString()));
|
|
22556
22568
|
const result = _textToSearch.indexOf(_searchFor, _startingAt - 1);
|
|
22557
|
-
assert(() => result >= 0, _t("In [[FUNCTION_NAME]] evaluation, cannot find '%s' within '%s'.", _searchFor
|
|
22569
|
+
assert(() => result >= 0, _t("In [[FUNCTION_NAME]] evaluation, cannot find '%s' within '%s'.", _searchFor, _textToSearch));
|
|
22558
22570
|
return result + 1;
|
|
22559
22571
|
},
|
|
22560
22572
|
isExported: true
|
|
@@ -22567,8 +22579,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22567
22579
|
arg("value_or_array2 (string, range<string>, repeating)", _t("More values to be appended using delimiter."))
|
|
22568
22580
|
],
|
|
22569
22581
|
compute: function(delimiter, ...valuesOrArrays) {
|
|
22570
|
-
const _delimiter =
|
|
22571
|
-
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") +
|
|
22582
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
22583
|
+
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
|
|
22572
22584
|
}
|
|
22573
22585
|
};
|
|
22574
22586
|
const LEFT = {
|
|
@@ -22577,7 +22589,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22577
22589
|
compute: function(text, ...args) {
|
|
22578
22590
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
22579
22591
|
assert(() => _numberOfCharacters >= 0, _t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters.toString()));
|
|
22580
|
-
return
|
|
22592
|
+
return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
|
|
22581
22593
|
},
|
|
22582
22594
|
isExported: true
|
|
22583
22595
|
};
|
|
@@ -22585,7 +22597,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22585
22597
|
description: _t("Length of a string."),
|
|
22586
22598
|
args: [arg("text (string)", _t("The string whose length will be returned."))],
|
|
22587
22599
|
compute: function(text) {
|
|
22588
|
-
return
|
|
22600
|
+
return toLocaleString(text, this.locale).length;
|
|
22589
22601
|
},
|
|
22590
22602
|
isExported: true
|
|
22591
22603
|
};
|
|
@@ -22593,7 +22605,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22593
22605
|
description: _t("Converts a specified string to lowercase."),
|
|
22594
22606
|
args: [arg("text (string)", _t("The string to convert to lowercase."))],
|
|
22595
22607
|
compute: function(text) {
|
|
22596
|
-
return
|
|
22608
|
+
return toLocaleString(text, this.locale).toLowerCase();
|
|
22597
22609
|
},
|
|
22598
22610
|
isExported: true
|
|
22599
22611
|
};
|
|
@@ -22605,7 +22617,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22605
22617
|
arg("extract_length (number)", _t("The length of the segment to extract."))
|
|
22606
22618
|
],
|
|
22607
22619
|
compute: function(text, starting_at, extract_length) {
|
|
22608
|
-
const _text =
|
|
22620
|
+
const _text = toLocaleString(text, this.locale);
|
|
22609
22621
|
const _starting_at = toNumber(starting_at, this.locale);
|
|
22610
22622
|
const _extract_length = toNumber(extract_length, this.locale);
|
|
22611
22623
|
assert(() => _starting_at >= 1, _t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
|
|
@@ -22618,7 +22630,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22618
22630
|
description: _t("Capitalizes each word in a specified string."),
|
|
22619
22631
|
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."))],
|
|
22620
22632
|
compute: function(text) {
|
|
22621
|
-
return
|
|
22633
|
+
return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
|
|
22622
22634
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
22623
22635
|
});
|
|
22624
22636
|
},
|
|
@@ -22635,9 +22647,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22635
22647
|
compute: function(text, position, length, newText) {
|
|
22636
22648
|
const _position = toNumber(position, this.locale);
|
|
22637
22649
|
assert(() => _position >= 1, _t("The position (%s) must be greater than or equal to 1.", _position.toString()));
|
|
22638
|
-
const _text =
|
|
22650
|
+
const _text = toLocaleString(text, this.locale);
|
|
22639
22651
|
const _length = toNumber(length, this.locale);
|
|
22640
|
-
const _newText =
|
|
22652
|
+
const _newText = toLocaleString(newText, this.locale);
|
|
22641
22653
|
return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
|
|
22642
22654
|
},
|
|
22643
22655
|
isExported: true
|
|
@@ -22648,7 +22660,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22648
22660
|
compute: function(text, ...args) {
|
|
22649
22661
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
22650
22662
|
assert(() => _numberOfCharacters >= 0, _t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters.toString()));
|
|
22651
|
-
const _text =
|
|
22663
|
+
const _text = toLocaleString(text, this.locale);
|
|
22652
22664
|
const stringLength = _text.length;
|
|
22653
22665
|
return _text.substring(stringLength - _numberOfCharacters, stringLength);
|
|
22654
22666
|
},
|
|
@@ -22662,8 +22674,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22662
22674
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
22663
22675
|
],
|
|
22664
22676
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
22665
|
-
const _searchFor =
|
|
22666
|
-
const _textToSearch =
|
|
22677
|
+
const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
|
|
22678
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
|
|
22667
22679
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
22668
22680
|
if (_textToSearch === "") return {
|
|
22669
22681
|
value: CellErrorType.GenericError,
|
|
@@ -22693,8 +22705,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22693
22705
|
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."))
|
|
22694
22706
|
],
|
|
22695
22707
|
compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
|
|
22696
|
-
const _text =
|
|
22697
|
-
const _delimiter = escapeRegExp(
|
|
22708
|
+
const _text = toLocaleString(text, this.locale);
|
|
22709
|
+
const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
|
|
22698
22710
|
const _splitByEach = toBoolean(splitByEach);
|
|
22699
22711
|
const _removeEmptyText = toBoolean(removeEmptyText);
|
|
22700
22712
|
assert(() => _delimiter.length > 0, _t("The _delimiter (%s) must be not be empty.", _delimiter));
|
|
@@ -22716,10 +22728,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22716
22728
|
compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
|
|
22717
22729
|
const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
|
|
22718
22730
|
assert(() => _occurrenceNumber >= 0, _t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber.toString()));
|
|
22719
|
-
const _textToSearch =
|
|
22720
|
-
const _searchFor =
|
|
22731
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
22732
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
22721
22733
|
if (_searchFor === "") return _textToSearch;
|
|
22722
|
-
const _replaceWith =
|
|
22734
|
+
const _replaceWith = toLocaleString(replaceWith, this.locale);
|
|
22723
22735
|
const reg = new RegExp(escapeRegExp(_searchFor), "g");
|
|
22724
22736
|
if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
|
|
22725
22737
|
let n = 0;
|
|
@@ -22736,10 +22748,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22736
22748
|
arg("text2 (string, range<string>, repeating)", _t("Additional text item(s)."))
|
|
22737
22749
|
],
|
|
22738
22750
|
compute: function(delimiter, ignoreEmpty, ...textsOrArrays) {
|
|
22739
|
-
const _delimiter =
|
|
22751
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
22740
22752
|
const _ignoreEmpty = toBoolean(ignoreEmpty);
|
|
22741
22753
|
let n = 0;
|
|
22742
|
-
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty &&
|
|
22754
|
+
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
|
|
22743
22755
|
},
|
|
22744
22756
|
isExported: true
|
|
22745
22757
|
};
|
|
@@ -22747,7 +22759,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22747
22759
|
description: _t("Removes space characters."),
|
|
22748
22760
|
args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
|
|
22749
22761
|
compute: function(text) {
|
|
22750
|
-
return trimContent(
|
|
22762
|
+
return trimContent(toLocaleString(text, this.locale));
|
|
22751
22763
|
},
|
|
22752
22764
|
isExported: true
|
|
22753
22765
|
};
|
|
@@ -22755,7 +22767,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22755
22767
|
description: _t("Converts a specified string to uppercase."),
|
|
22756
22768
|
args: [arg("text (string)", _t("The string to convert to uppercase."))],
|
|
22757
22769
|
compute: function(text) {
|
|
22758
|
-
return
|
|
22770
|
+
return toLocaleString(text, this.locale).toUpperCase();
|
|
22759
22771
|
},
|
|
22760
22772
|
isExported: true
|
|
22761
22773
|
};
|
|
@@ -22787,7 +22799,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22787
22799
|
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."))],
|
|
22788
22800
|
compute: function(url, linkLabel) {
|
|
22789
22801
|
const processedUrl = toString(url).trim();
|
|
22790
|
-
const processedLabel =
|
|
22802
|
+
const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
|
|
22791
22803
|
if (processedUrl === "") return processedLabel;
|
|
22792
22804
|
return markdownLink(processedLabel, processedUrl);
|
|
22793
22805
|
},
|
|
@@ -27973,12 +27985,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27973
27985
|
}
|
|
27974
27986
|
sortFilterZone(sortDirection) {
|
|
27975
27987
|
const filterPosition = this.props.filterPosition;
|
|
27976
|
-
const
|
|
27988
|
+
const table = this.table;
|
|
27989
|
+
const tableZone = table?.range.zone;
|
|
27977
27990
|
if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
|
|
27978
27991
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
27979
27992
|
const contentZone = {
|
|
27980
27993
|
...tableZone,
|
|
27981
|
-
top: tableZone.top +
|
|
27994
|
+
top: tableZone.top + table.config.numberOfHeaders
|
|
27982
27995
|
};
|
|
27983
27996
|
this.env.model.dispatch("SORT_CELLS", {
|
|
27984
27997
|
sheetId,
|
|
@@ -32561,6 +32574,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32561
32574
|
background-color: ${ACTION_COLOR};
|
|
32562
32575
|
border-color: ${ACTION_COLOR};
|
|
32563
32576
|
}
|
|
32577
|
+
|
|
32578
|
+
&:focus {
|
|
32579
|
+
outline: none;
|
|
32580
|
+
box-shadow: 0 0 0 0.25rem rgba(113, 75, 103, 0.25);
|
|
32581
|
+
border-color: ${ACTION_COLOR};
|
|
32582
|
+
}
|
|
32564
32583
|
}
|
|
32565
32584
|
}
|
|
32566
32585
|
`;
|
|
@@ -38092,6 +38111,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
38092
38111
|
.os-input {
|
|
38093
38112
|
box-sizing: border-box;
|
|
38094
38113
|
border-width: 0 0 1px 0;
|
|
38114
|
+
border-style: solid;
|
|
38095
38115
|
border-color: transparent;
|
|
38096
38116
|
outline: none;
|
|
38097
38117
|
text-overflow: ellipsis;
|
|
@@ -60653,6 +60673,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
60653
60673
|
position: absolute;
|
|
60654
60674
|
cursor: pointer;
|
|
60655
60675
|
}
|
|
60676
|
+
.o-grid.o-dashboard-grid {
|
|
60677
|
+
background: #ffffff;
|
|
60678
|
+
}
|
|
60656
60679
|
`;
|
|
60657
60680
|
var SpreadsheetDashboard = class extends _odoo_owl.Component {
|
|
60658
60681
|
static template = "o-spreadsheet-SpreadsheetDashboard";
|
|
@@ -62065,6 +62088,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62065
62088
|
width: 100%;
|
|
62066
62089
|
outline: none;
|
|
62067
62090
|
border-color: ${GRAY_300};
|
|
62091
|
+
border-style: solid;
|
|
62068
62092
|
color: ${GRAY_900};
|
|
62069
62093
|
|
|
62070
62094
|
&::placeholder {
|
|
@@ -66434,8 +66458,8 @@ exports.stores = stores;
|
|
|
66434
66458
|
exports.tokenColors = tokenColors;
|
|
66435
66459
|
exports.tokenize = tokenize;
|
|
66436
66460
|
|
|
66437
|
-
__info__.version = "18.0.
|
|
66438
|
-
__info__.date = "2026-08-
|
|
66439
|
-
__info__.hash = "
|
|
66461
|
+
__info__.version = "18.0.80";
|
|
66462
|
+
__info__.date = "2026-08-29T09:13:05.057Z";
|
|
66463
|
+
__info__.hash = "af324f5";
|
|
66440
66464
|
|
|
66441
66465
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|