@odoo/o-spreadsheet 19.0.46 → 19.0.48
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.css +3 -3
- package/dist/o_spreadsheet.esm.js +61 -36
- package/dist/o_spreadsheet.iife.js +61 -36
- package/dist/o_spreadsheet.iife.min.js +332 -321
- package/dist/o_spreadsheet.xml +8 -4
- package/package.json +1 -1
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.0.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.48
|
|
6
|
+
* @date 2026-08-29T09:14:14.219Z
|
|
7
|
+
* @hash 0a6c168
|
|
8
8
|
*/
|
|
9
9
|
/* Originates from src/components/top_bar/top_bar.scss */
|
|
10
10
|
@media (max-width: 1200px) {
|
|
@@ -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.0.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.48
|
|
6
|
+
* @date 2026-08-29T09:14:12.472Z
|
|
7
|
+
* @hash 0a6c168
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { App, Component, blockDom, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, xml } from "@odoo/owl";
|
|
@@ -2919,6 +2919,18 @@ function toString(data) {
|
|
|
2919
2919
|
default: return "";
|
|
2920
2920
|
}
|
|
2921
2921
|
}
|
|
2922
|
+
/**
|
|
2923
|
+
* Only converts the decimal separator, ignore number format such as % or dates
|
|
2924
|
+
*/
|
|
2925
|
+
function toLocaleString(data, locale) {
|
|
2926
|
+
const value = toValue(data);
|
|
2927
|
+
switch (typeof value) {
|
|
2928
|
+
case "string": return value;
|
|
2929
|
+
case "number": return value.toString().replace(".", locale.decimalSeparator);
|
|
2930
|
+
case "boolean": return value ? "TRUE" : "FALSE";
|
|
2931
|
+
default: return "";
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2922
2934
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
2923
2935
|
const normalizeString = memoize(function normalizeString(str) {
|
|
2924
2936
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
@@ -17164,7 +17176,7 @@ const CONCAT = {
|
|
|
17164
17176
|
description: _t("Concatenation of two values."),
|
|
17165
17177
|
args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
|
|
17166
17178
|
compute: function(value1, value2) {
|
|
17167
|
-
return
|
|
17179
|
+
return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
|
|
17168
17180
|
},
|
|
17169
17181
|
isExported: true
|
|
17170
17182
|
};
|
|
@@ -17996,7 +18008,7 @@ const CLEAN = {
|
|
|
17996
18008
|
description: _t("Remove non-printable characters from a piece of text."),
|
|
17997
18009
|
args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
|
|
17998
18010
|
compute: function(text) {
|
|
17999
|
-
const _text =
|
|
18011
|
+
const _text = toLocaleString(text, this.locale);
|
|
18000
18012
|
let cleanedStr = "";
|
|
18001
18013
|
for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
|
|
18002
18014
|
return cleanedStr;
|
|
@@ -18007,7 +18019,7 @@ const CONCATENATE = {
|
|
|
18007
18019
|
description: _t("Appends strings to one another."),
|
|
18008
18020
|
args: [arg("string1 (string, range<string>)", _t("The initial string.")), arg("string2 (string, range<string>, repeating)", _t("More strings to append in sequence."))],
|
|
18009
18021
|
compute: function(...datas) {
|
|
18010
|
-
return reduceAny(datas, (acc, a) => acc +
|
|
18022
|
+
return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
|
|
18011
18023
|
},
|
|
18012
18024
|
isExported: true
|
|
18013
18025
|
};
|
|
@@ -18015,7 +18027,7 @@ const EXACT = {
|
|
|
18015
18027
|
description: _t("Tests whether two strings are identical."),
|
|
18016
18028
|
args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
|
|
18017
18029
|
compute: function(string1, string2) {
|
|
18018
|
-
return
|
|
18030
|
+
return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
|
|
18019
18031
|
},
|
|
18020
18032
|
isExported: true
|
|
18021
18033
|
};
|
|
@@ -18027,8 +18039,8 @@ const FIND = {
|
|
|
18027
18039
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
18028
18040
|
],
|
|
18029
18041
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
18030
|
-
const _searchFor =
|
|
18031
|
-
const _textToSearch =
|
|
18042
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
18043
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
18032
18044
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
18033
18045
|
if (_textToSearch === "") return new EvaluationError(_t("The text_to_search must be non-empty."));
|
|
18034
18046
|
if (_startingAt < 1) return new EvaluationError(_t("The starting_at (%s) must be greater than or equal to 1.", _startingAt));
|
|
@@ -18046,8 +18058,8 @@ const JOIN = {
|
|
|
18046
18058
|
arg("value_or_array2 (string, range<string>, repeating)", _t("More values to be appended using delimiter."))
|
|
18047
18059
|
],
|
|
18048
18060
|
compute: function(delimiter, ...valuesOrArrays) {
|
|
18049
|
-
const _delimiter =
|
|
18050
|
-
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") +
|
|
18061
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
18062
|
+
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
|
|
18051
18063
|
}
|
|
18052
18064
|
};
|
|
18053
18065
|
const LEFT = {
|
|
@@ -18056,7 +18068,7 @@ const LEFT = {
|
|
|
18056
18068
|
compute: function(text, ...args) {
|
|
18057
18069
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
18058
18070
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
18059
|
-
return
|
|
18071
|
+
return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
|
|
18060
18072
|
},
|
|
18061
18073
|
isExported: true
|
|
18062
18074
|
};
|
|
@@ -18064,7 +18076,7 @@ const LEN = {
|
|
|
18064
18076
|
description: _t("Length of a string."),
|
|
18065
18077
|
args: [arg("text (string)", _t("The string whose length will be returned."))],
|
|
18066
18078
|
compute: function(text) {
|
|
18067
|
-
return
|
|
18079
|
+
return toLocaleString(text, this.locale).length;
|
|
18068
18080
|
},
|
|
18069
18081
|
isExported: true
|
|
18070
18082
|
};
|
|
@@ -18072,7 +18084,7 @@ const LOWER = {
|
|
|
18072
18084
|
description: _t("Converts a specified string to lowercase."),
|
|
18073
18085
|
args: [arg("text (string)", _t("The string to convert to lowercase."))],
|
|
18074
18086
|
compute: function(text) {
|
|
18075
|
-
return
|
|
18087
|
+
return toLocaleString(text, this.locale).toLowerCase();
|
|
18076
18088
|
},
|
|
18077
18089
|
isExported: true
|
|
18078
18090
|
};
|
|
@@ -18084,7 +18096,7 @@ const MID = {
|
|
|
18084
18096
|
arg("extract_length (number)", _t("The length of the segment to extract."))
|
|
18085
18097
|
],
|
|
18086
18098
|
compute: function(text, starting_at, extract_length) {
|
|
18087
|
-
const _text =
|
|
18099
|
+
const _text = toLocaleString(text, this.locale);
|
|
18088
18100
|
const _starting_at = toNumber(starting_at, this.locale);
|
|
18089
18101
|
const _extract_length = toNumber(extract_length, this.locale);
|
|
18090
18102
|
if (_starting_at < 1) return new EvaluationError(_t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
|
|
@@ -18097,7 +18109,7 @@ const PROPER = {
|
|
|
18097
18109
|
description: _t("Capitalizes each word in a specified string."),
|
|
18098
18110
|
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."))],
|
|
18099
18111
|
compute: function(text) {
|
|
18100
|
-
return
|
|
18112
|
+
return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
|
|
18101
18113
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
18102
18114
|
});
|
|
18103
18115
|
},
|
|
@@ -18172,9 +18184,9 @@ const REPLACE = {
|
|
|
18172
18184
|
compute: function(text, position, length, newText) {
|
|
18173
18185
|
const _position = toNumber(position, this.locale);
|
|
18174
18186
|
if (_position < 1) return new EvaluationError(_t("The position (%s) must be greater than or equal to 1.", _position));
|
|
18175
|
-
const _text =
|
|
18187
|
+
const _text = toLocaleString(text, this.locale);
|
|
18176
18188
|
const _length = toNumber(length, this.locale);
|
|
18177
|
-
const _newText =
|
|
18189
|
+
const _newText = toLocaleString(newText, this.locale);
|
|
18178
18190
|
return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
|
|
18179
18191
|
},
|
|
18180
18192
|
isExported: true
|
|
@@ -18185,7 +18197,7 @@ const RIGHT = {
|
|
|
18185
18197
|
compute: function(text, ...args) {
|
|
18186
18198
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
18187
18199
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
18188
|
-
const _text =
|
|
18200
|
+
const _text = toLocaleString(text, this.locale);
|
|
18189
18201
|
const stringLength = _text.length;
|
|
18190
18202
|
return _text.substring(stringLength - _numberOfCharacters, stringLength);
|
|
18191
18203
|
},
|
|
@@ -18199,8 +18211,8 @@ const SEARCH = {
|
|
|
18199
18211
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
18200
18212
|
],
|
|
18201
18213
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
18202
|
-
const _searchFor =
|
|
18203
|
-
const _textToSearch =
|
|
18214
|
+
const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
|
|
18215
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
|
|
18204
18216
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
18205
18217
|
if (_textToSearch === "") return {
|
|
18206
18218
|
value: CellErrorType.GenericError,
|
|
@@ -18230,8 +18242,8 @@ const SPLIT = {
|
|
|
18230
18242
|
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."))
|
|
18231
18243
|
],
|
|
18232
18244
|
compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
|
|
18233
|
-
const _text =
|
|
18234
|
-
const _delimiter = escapeRegExp(
|
|
18245
|
+
const _text = toLocaleString(text, this.locale);
|
|
18246
|
+
const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
|
|
18235
18247
|
const _splitByEach = toBoolean(splitByEach);
|
|
18236
18248
|
const _removeEmptyText = toBoolean(removeEmptyText);
|
|
18237
18249
|
if (_delimiter.length <= 0) return new EvaluationError(_t("The delimiter (%s) must be not be empty.", _delimiter));
|
|
@@ -18253,10 +18265,10 @@ const SUBSTITUTE = {
|
|
|
18253
18265
|
compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
|
|
18254
18266
|
const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
|
|
18255
18267
|
if (_occurrenceNumber < 0) return new EvaluationError(_t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber));
|
|
18256
|
-
const _textToSearch =
|
|
18257
|
-
const _searchFor =
|
|
18268
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
18269
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
18258
18270
|
if (_searchFor === "") return _textToSearch;
|
|
18259
|
-
const _replaceWith =
|
|
18271
|
+
const _replaceWith = toLocaleString(replaceWith, this.locale);
|
|
18260
18272
|
const reg = new RegExp(escapeRegExp(_searchFor), "g");
|
|
18261
18273
|
if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
|
|
18262
18274
|
let n = 0;
|
|
@@ -18280,10 +18292,10 @@ const TEXTJOIN = {
|
|
|
18280
18292
|
arg("text2 (string, range<string>, repeating)", _t("Additional text item(s)."))
|
|
18281
18293
|
],
|
|
18282
18294
|
compute: function(delimiter, ignoreEmpty = { value: TEXTJOIN_DEFAULT_IGNORE_EMPTY }, ...textsOrArrays) {
|
|
18283
|
-
const _delimiter =
|
|
18295
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
18284
18296
|
const _ignoreEmpty = toBoolean(ignoreEmpty);
|
|
18285
18297
|
let n = 0;
|
|
18286
|
-
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty &&
|
|
18298
|
+
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
|
|
18287
18299
|
},
|
|
18288
18300
|
isExported: true
|
|
18289
18301
|
};
|
|
@@ -18336,7 +18348,7 @@ const TRIM = {
|
|
|
18336
18348
|
description: _t("Removes space characters."),
|
|
18337
18349
|
args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
|
|
18338
18350
|
compute: function(text) {
|
|
18339
|
-
return trimContent(
|
|
18351
|
+
return trimContent(toLocaleString(text, this.locale));
|
|
18340
18352
|
},
|
|
18341
18353
|
isExported: true
|
|
18342
18354
|
};
|
|
@@ -18344,7 +18356,7 @@ const UPPER = {
|
|
|
18344
18356
|
description: _t("Converts a specified string to uppercase."),
|
|
18345
18357
|
args: [arg("text (string)", _t("The string to convert to uppercase."))],
|
|
18346
18358
|
compute: function(text) {
|
|
18347
|
-
return
|
|
18359
|
+
return toLocaleString(text, this.locale).toUpperCase();
|
|
18348
18360
|
},
|
|
18349
18361
|
isExported: true
|
|
18350
18362
|
};
|
|
@@ -18441,7 +18453,7 @@ const HYPERLINK = {
|
|
|
18441
18453
|
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."))],
|
|
18442
18454
|
compute: function(url, linkLabel) {
|
|
18443
18455
|
const processedUrl = toString(url).trim();
|
|
18444
|
-
const processedLabel =
|
|
18456
|
+
const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
|
|
18445
18457
|
if (processedUrl === "") return processedLabel;
|
|
18446
18458
|
return markdownLink(processedLabel, processedUrl);
|
|
18447
18459
|
},
|
|
@@ -19705,6 +19717,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
19705
19717
|
hidden,
|
|
19706
19718
|
borderColor,
|
|
19707
19719
|
backgroundColor: borderColor,
|
|
19720
|
+
pointBackgroundColor: borderColor,
|
|
19708
19721
|
pointRadius: definition.hideDataMarkers ? 0 : 3
|
|
19709
19722
|
};
|
|
19710
19723
|
if (fill) {
|
|
@@ -33189,12 +33202,13 @@ var FilterMenu = class extends Component {
|
|
|
33189
33202
|
}
|
|
33190
33203
|
sortFilterZone(sortDirection) {
|
|
33191
33204
|
const filterPosition = this.props.filterPosition;
|
|
33192
|
-
const
|
|
33205
|
+
const table = this.table;
|
|
33206
|
+
const tableZone = table?.range.zone;
|
|
33193
33207
|
if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
|
|
33194
33208
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
33195
33209
|
const contentZone = {
|
|
33196
33210
|
...tableZone,
|
|
33197
|
-
top: tableZone.top +
|
|
33211
|
+
top: tableZone.top + table.config.numberOfHeaders
|
|
33198
33212
|
};
|
|
33199
33213
|
const sortAnchor = {
|
|
33200
33214
|
col: filterPosition.col,
|
|
@@ -47297,6 +47311,7 @@ css`
|
|
|
47297
47311
|
.o-spreadsheet {
|
|
47298
47312
|
.os-input {
|
|
47299
47313
|
border-width: 0 0 1px 0;
|
|
47314
|
+
border-style: solid;
|
|
47300
47315
|
border-color: transparent;
|
|
47301
47316
|
outline: none;
|
|
47302
47317
|
text-overflow: ellipsis;
|
|
@@ -48649,6 +48664,12 @@ css`
|
|
|
48649
48664
|
background-color: ${ACTION_COLOR};
|
|
48650
48665
|
border-color: ${ACTION_COLOR};
|
|
48651
48666
|
}
|
|
48667
|
+
|
|
48668
|
+
&:focus {
|
|
48669
|
+
outline: none;
|
|
48670
|
+
box-shadow: 0 0 0 0.25rem rgba(113, 75, 103, 0.25);
|
|
48671
|
+
border-color: ${ACTION_COLOR};
|
|
48672
|
+
}
|
|
48652
48673
|
}
|
|
48653
48674
|
}
|
|
48654
48675
|
`;
|
|
@@ -72900,6 +72921,9 @@ css`
|
|
|
72900
72921
|
position: absolute;
|
|
72901
72922
|
cursor: pointer;
|
|
72902
72923
|
}
|
|
72924
|
+
.o-grid.o-dashboard-grid {
|
|
72925
|
+
background: #ffffff;
|
|
72926
|
+
}
|
|
72903
72927
|
`;
|
|
72904
72928
|
var SpreadsheetDashboard = class extends Component {
|
|
72905
72929
|
static template = "o-spreadsheet-SpreadsheetDashboard";
|
|
@@ -74833,6 +74857,7 @@ css`
|
|
|
74833
74857
|
width: 100%;
|
|
74834
74858
|
outline: none;
|
|
74835
74859
|
border-color: ${GRAY_300};
|
|
74860
|
+
border-style: solid;
|
|
74836
74861
|
color: ${GRAY_900};
|
|
74837
74862
|
|
|
74838
74863
|
&::placeholder {
|
|
@@ -79439,6 +79464,6 @@ const chartHelpers = {
|
|
|
79439
79464
|
//#endregion
|
|
79440
79465
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
79441
79466
|
|
|
79442
|
-
__info__.version = "19.0.
|
|
79443
|
-
__info__.date = "2026-08-
|
|
79444
|
-
__info__.hash = "
|
|
79467
|
+
__info__.version = "19.0.48";
|
|
79468
|
+
__info__.date = "2026-08-29T09:14:12.472Z";
|
|
79469
|
+
__info__.hash = "0a6c168";
|
|
@@ -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.0.
|
|
6
|
-
* @date 2026-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.48
|
|
6
|
+
* @date 2026-08-29T09:14:12.472Z
|
|
7
|
+
* @hash 0a6c168
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function(exports, _odoo_owl) {
|
|
@@ -2921,6 +2921,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2921
2921
|
default: return "";
|
|
2922
2922
|
}
|
|
2923
2923
|
}
|
|
2924
|
+
/**
|
|
2925
|
+
* Only converts the decimal separator, ignore number format such as % or dates
|
|
2926
|
+
*/
|
|
2927
|
+
function toLocaleString(data, locale) {
|
|
2928
|
+
const value = toValue(data);
|
|
2929
|
+
switch (typeof value) {
|
|
2930
|
+
case "string": return value;
|
|
2931
|
+
case "number": return value.toString().replace(".", locale.decimalSeparator);
|
|
2932
|
+
case "boolean": return value ? "TRUE" : "FALSE";
|
|
2933
|
+
default: return "";
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2924
2936
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
2925
2937
|
const normalizeString = memoize(function normalizeString(str) {
|
|
2926
2938
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
@@ -17166,7 +17178,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
17166
17178
|
description: _t("Concatenation of two values."),
|
|
17167
17179
|
args: [arg("value1 (string)", _t("The value to which value2 will be appended.")), arg("value2 (string)", _t("The value to append to value1."))],
|
|
17168
17180
|
compute: function(value1, value2) {
|
|
17169
|
-
return
|
|
17181
|
+
return toLocaleString(value1, this.locale) + toLocaleString(value2, this.locale);
|
|
17170
17182
|
},
|
|
17171
17183
|
isExported: true
|
|
17172
17184
|
};
|
|
@@ -17998,7 +18010,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
17998
18010
|
description: _t("Remove non-printable characters from a piece of text."),
|
|
17999
18011
|
args: [arg("text (string)", _t("The text whose non-printable characters are to be removed."))],
|
|
18000
18012
|
compute: function(text) {
|
|
18001
|
-
const _text =
|
|
18013
|
+
const _text = toLocaleString(text, this.locale);
|
|
18002
18014
|
let cleanedStr = "";
|
|
18003
18015
|
for (const char of _text) if (char && char.charCodeAt(0) > 31) cleanedStr += char;
|
|
18004
18016
|
return cleanedStr;
|
|
@@ -18009,7 +18021,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18009
18021
|
description: _t("Appends strings to one another."),
|
|
18010
18022
|
args: [arg("string1 (string, range<string>)", _t("The initial string.")), arg("string2 (string, range<string>, repeating)", _t("More strings to append in sequence."))],
|
|
18011
18023
|
compute: function(...datas) {
|
|
18012
|
-
return reduceAny(datas, (acc, a) => acc +
|
|
18024
|
+
return reduceAny(datas, (acc, a) => acc + toLocaleString(a, this.locale), "");
|
|
18013
18025
|
},
|
|
18014
18026
|
isExported: true
|
|
18015
18027
|
};
|
|
@@ -18017,7 +18029,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18017
18029
|
description: _t("Tests whether two strings are identical."),
|
|
18018
18030
|
args: [arg("string1 (string)", _t("The first string to compare.")), arg("string2 (string)", _t("The second string to compare."))],
|
|
18019
18031
|
compute: function(string1, string2) {
|
|
18020
|
-
return
|
|
18032
|
+
return toLocaleString(string1, this.locale) === toLocaleString(string2, this.locale);
|
|
18021
18033
|
},
|
|
18022
18034
|
isExported: true
|
|
18023
18035
|
};
|
|
@@ -18029,8 +18041,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18029
18041
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
18030
18042
|
],
|
|
18031
18043
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
18032
|
-
const _searchFor =
|
|
18033
|
-
const _textToSearch =
|
|
18044
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
18045
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
18034
18046
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
18035
18047
|
if (_textToSearch === "") return new EvaluationError(_t("The text_to_search must be non-empty."));
|
|
18036
18048
|
if (_startingAt < 1) return new EvaluationError(_t("The starting_at (%s) must be greater than or equal to 1.", _startingAt));
|
|
@@ -18048,8 +18060,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18048
18060
|
arg("value_or_array2 (string, range<string>, repeating)", _t("More values to be appended using delimiter."))
|
|
18049
18061
|
],
|
|
18050
18062
|
compute: function(delimiter, ...valuesOrArrays) {
|
|
18051
|
-
const _delimiter =
|
|
18052
|
-
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") +
|
|
18063
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
18064
|
+
return reduceAny(valuesOrArrays, (acc, a) => (acc ? acc + _delimiter : "") + toLocaleString(a, this.locale), "");
|
|
18053
18065
|
}
|
|
18054
18066
|
};
|
|
18055
18067
|
const LEFT = {
|
|
@@ -18058,7 +18070,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18058
18070
|
compute: function(text, ...args) {
|
|
18059
18071
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
18060
18072
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
18061
|
-
return
|
|
18073
|
+
return toLocaleString(text, this.locale).substring(0, _numberOfCharacters);
|
|
18062
18074
|
},
|
|
18063
18075
|
isExported: true
|
|
18064
18076
|
};
|
|
@@ -18066,7 +18078,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18066
18078
|
description: _t("Length of a string."),
|
|
18067
18079
|
args: [arg("text (string)", _t("The string whose length will be returned."))],
|
|
18068
18080
|
compute: function(text) {
|
|
18069
|
-
return
|
|
18081
|
+
return toLocaleString(text, this.locale).length;
|
|
18070
18082
|
},
|
|
18071
18083
|
isExported: true
|
|
18072
18084
|
};
|
|
@@ -18074,7 +18086,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18074
18086
|
description: _t("Converts a specified string to lowercase."),
|
|
18075
18087
|
args: [arg("text (string)", _t("The string to convert to lowercase."))],
|
|
18076
18088
|
compute: function(text) {
|
|
18077
|
-
return
|
|
18089
|
+
return toLocaleString(text, this.locale).toLowerCase();
|
|
18078
18090
|
},
|
|
18079
18091
|
isExported: true
|
|
18080
18092
|
};
|
|
@@ -18086,7 +18098,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18086
18098
|
arg("extract_length (number)", _t("The length of the segment to extract."))
|
|
18087
18099
|
],
|
|
18088
18100
|
compute: function(text, starting_at, extract_length) {
|
|
18089
|
-
const _text =
|
|
18101
|
+
const _text = toLocaleString(text, this.locale);
|
|
18090
18102
|
const _starting_at = toNumber(starting_at, this.locale);
|
|
18091
18103
|
const _extract_length = toNumber(extract_length, this.locale);
|
|
18092
18104
|
if (_starting_at < 1) return new EvaluationError(_t("The starting_at argument (%s) must be positive greater than one.", _starting_at.toString()));
|
|
@@ -18099,7 +18111,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18099
18111
|
description: _t("Capitalizes each word in a specified string."),
|
|
18100
18112
|
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."))],
|
|
18101
18113
|
compute: function(text) {
|
|
18102
|
-
return
|
|
18114
|
+
return toLocaleString(text, this.locale).replace(wordRegex, (word) => {
|
|
18103
18115
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
18104
18116
|
});
|
|
18105
18117
|
},
|
|
@@ -18174,9 +18186,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18174
18186
|
compute: function(text, position, length, newText) {
|
|
18175
18187
|
const _position = toNumber(position, this.locale);
|
|
18176
18188
|
if (_position < 1) return new EvaluationError(_t("The position (%s) must be greater than or equal to 1.", _position));
|
|
18177
|
-
const _text =
|
|
18189
|
+
const _text = toLocaleString(text, this.locale);
|
|
18178
18190
|
const _length = toNumber(length, this.locale);
|
|
18179
|
-
const _newText =
|
|
18191
|
+
const _newText = toLocaleString(newText, this.locale);
|
|
18180
18192
|
return _text.substring(0, _position - 1) + _newText + _text.substring(_position - 1 + _length);
|
|
18181
18193
|
},
|
|
18182
18194
|
isExported: true
|
|
@@ -18187,7 +18199,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18187
18199
|
compute: function(text, ...args) {
|
|
18188
18200
|
const _numberOfCharacters = args.length ? toNumber(args[0], this.locale) : 1;
|
|
18189
18201
|
if (_numberOfCharacters < 0) return new EvaluationError(_t("The number_of_characters (%s) must be positive or null.", _numberOfCharacters));
|
|
18190
|
-
const _text =
|
|
18202
|
+
const _text = toLocaleString(text, this.locale);
|
|
18191
18203
|
const stringLength = _text.length;
|
|
18192
18204
|
return _text.substring(stringLength - _numberOfCharacters, stringLength);
|
|
18193
18205
|
},
|
|
@@ -18201,8 +18213,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18201
18213
|
arg(`starting_at (number, default=${DEFAULT_STARTING_AT})`, _t("The character within text_to_search at which to start the search."))
|
|
18202
18214
|
],
|
|
18203
18215
|
compute: function(searchFor, textToSearch, startingAt = { value: DEFAULT_STARTING_AT }) {
|
|
18204
|
-
const _searchFor =
|
|
18205
|
-
const _textToSearch =
|
|
18216
|
+
const _searchFor = toLocaleString(searchFor, this.locale).toLowerCase();
|
|
18217
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale).toLowerCase();
|
|
18206
18218
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
18207
18219
|
if (_textToSearch === "") return {
|
|
18208
18220
|
value: CellErrorType.GenericError,
|
|
@@ -18232,8 +18244,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18232
18244
|
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."))
|
|
18233
18245
|
],
|
|
18234
18246
|
compute: function(text, delimiter, splitByEach = { value: SPLIT_DEFAULT_SPLIT_BY_EACH }, removeEmptyText = { value: SPLIT_DEFAULT_REMOVE_EMPTY_TEXT }) {
|
|
18235
|
-
const _text =
|
|
18236
|
-
const _delimiter = escapeRegExp(
|
|
18247
|
+
const _text = toLocaleString(text, this.locale);
|
|
18248
|
+
const _delimiter = escapeRegExp(toLocaleString(delimiter, this.locale));
|
|
18237
18249
|
const _splitByEach = toBoolean(splitByEach);
|
|
18238
18250
|
const _removeEmptyText = toBoolean(removeEmptyText);
|
|
18239
18251
|
if (_delimiter.length <= 0) return new EvaluationError(_t("The delimiter (%s) must be not be empty.", _delimiter));
|
|
@@ -18255,10 +18267,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18255
18267
|
compute: function(textToSearch, searchFor, replaceWith, occurrenceNumber) {
|
|
18256
18268
|
const _occurrenceNumber = toNumber(occurrenceNumber, this.locale);
|
|
18257
18269
|
if (_occurrenceNumber < 0) return new EvaluationError(_t("The occurrenceNumber (%s) must be positive or null.", _occurrenceNumber));
|
|
18258
|
-
const _textToSearch =
|
|
18259
|
-
const _searchFor =
|
|
18270
|
+
const _textToSearch = toLocaleString(textToSearch, this.locale);
|
|
18271
|
+
const _searchFor = toLocaleString(searchFor, this.locale);
|
|
18260
18272
|
if (_searchFor === "") return _textToSearch;
|
|
18261
|
-
const _replaceWith =
|
|
18273
|
+
const _replaceWith = toLocaleString(replaceWith, this.locale);
|
|
18262
18274
|
const reg = new RegExp(escapeRegExp(_searchFor), "g");
|
|
18263
18275
|
if (_occurrenceNumber === 0) return _textToSearch.replace(reg, _replaceWith);
|
|
18264
18276
|
let n = 0;
|
|
@@ -18282,10 +18294,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18282
18294
|
arg("text2 (string, range<string>, repeating)", _t("Additional text item(s)."))
|
|
18283
18295
|
],
|
|
18284
18296
|
compute: function(delimiter, ignoreEmpty = { value: TEXTJOIN_DEFAULT_IGNORE_EMPTY }, ...textsOrArrays) {
|
|
18285
|
-
const _delimiter =
|
|
18297
|
+
const _delimiter = toLocaleString(delimiter, this.locale);
|
|
18286
18298
|
const _ignoreEmpty = toBoolean(ignoreEmpty);
|
|
18287
18299
|
let n = 0;
|
|
18288
|
-
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty &&
|
|
18300
|
+
return reduceAny(textsOrArrays, (acc, a) => !(_ignoreEmpty && toLocaleString(a, this.locale) === "") ? (n++ ? acc + _delimiter : "") + toLocaleString(a, this.locale) : acc, "");
|
|
18289
18301
|
},
|
|
18290
18302
|
isExported: true
|
|
18291
18303
|
};
|
|
@@ -18338,7 +18350,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18338
18350
|
description: _t("Removes space characters."),
|
|
18339
18351
|
args: [arg("text (string)", _t("The text or reference to a cell containing text to be trimmed."))],
|
|
18340
18352
|
compute: function(text) {
|
|
18341
|
-
return trimContent(
|
|
18353
|
+
return trimContent(toLocaleString(text, this.locale));
|
|
18342
18354
|
},
|
|
18343
18355
|
isExported: true
|
|
18344
18356
|
};
|
|
@@ -18346,7 +18358,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18346
18358
|
description: _t("Converts a specified string to uppercase."),
|
|
18347
18359
|
args: [arg("text (string)", _t("The string to convert to uppercase."))],
|
|
18348
18360
|
compute: function(text) {
|
|
18349
|
-
return
|
|
18361
|
+
return toLocaleString(text, this.locale).toUpperCase();
|
|
18350
18362
|
},
|
|
18351
18363
|
isExported: true
|
|
18352
18364
|
};
|
|
@@ -18443,7 +18455,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18443
18455
|
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."))],
|
|
18444
18456
|
compute: function(url, linkLabel) {
|
|
18445
18457
|
const processedUrl = toString(url).trim();
|
|
18446
|
-
const processedLabel =
|
|
18458
|
+
const processedLabel = toLocaleString(linkLabel, this.locale) || processedUrl;
|
|
18447
18459
|
if (processedUrl === "") return processedLabel;
|
|
18448
18460
|
return markdownLink(processedLabel, processedUrl);
|
|
18449
18461
|
},
|
|
@@ -19707,6 +19719,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
19707
19719
|
hidden,
|
|
19708
19720
|
borderColor,
|
|
19709
19721
|
backgroundColor: borderColor,
|
|
19722
|
+
pointBackgroundColor: borderColor,
|
|
19710
19723
|
pointRadius: definition.hideDataMarkers ? 0 : 3
|
|
19711
19724
|
};
|
|
19712
19725
|
if (fill) {
|
|
@@ -33191,12 +33204,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33191
33204
|
}
|
|
33192
33205
|
sortFilterZone(sortDirection) {
|
|
33193
33206
|
const filterPosition = this.props.filterPosition;
|
|
33194
|
-
const
|
|
33207
|
+
const table = this.table;
|
|
33208
|
+
const tableZone = table?.range.zone;
|
|
33195
33209
|
if (!filterPosition || !tableZone || tableZone.top === tableZone.bottom) return;
|
|
33196
33210
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
33197
33211
|
const contentZone = {
|
|
33198
33212
|
...tableZone,
|
|
33199
|
-
top: tableZone.top +
|
|
33213
|
+
top: tableZone.top + table.config.numberOfHeaders
|
|
33200
33214
|
};
|
|
33201
33215
|
const sortAnchor = {
|
|
33202
33216
|
col: filterPosition.col,
|
|
@@ -47299,6 +47313,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47299
47313
|
.o-spreadsheet {
|
|
47300
47314
|
.os-input {
|
|
47301
47315
|
border-width: 0 0 1px 0;
|
|
47316
|
+
border-style: solid;
|
|
47302
47317
|
border-color: transparent;
|
|
47303
47318
|
outline: none;
|
|
47304
47319
|
text-overflow: ellipsis;
|
|
@@ -48651,6 +48666,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
48651
48666
|
background-color: ${ACTION_COLOR};
|
|
48652
48667
|
border-color: ${ACTION_COLOR};
|
|
48653
48668
|
}
|
|
48669
|
+
|
|
48670
|
+
&:focus {
|
|
48671
|
+
outline: none;
|
|
48672
|
+
box-shadow: 0 0 0 0.25rem rgba(113, 75, 103, 0.25);
|
|
48673
|
+
border-color: ${ACTION_COLOR};
|
|
48674
|
+
}
|
|
48654
48675
|
}
|
|
48655
48676
|
}
|
|
48656
48677
|
`;
|
|
@@ -72902,6 +72923,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
72902
72923
|
position: absolute;
|
|
72903
72924
|
cursor: pointer;
|
|
72904
72925
|
}
|
|
72926
|
+
.o-grid.o-dashboard-grid {
|
|
72927
|
+
background: #ffffff;
|
|
72928
|
+
}
|
|
72905
72929
|
`;
|
|
72906
72930
|
var SpreadsheetDashboard = class extends _odoo_owl.Component {
|
|
72907
72931
|
static template = "o-spreadsheet-SpreadsheetDashboard";
|
|
@@ -74835,6 +74859,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74835
74859
|
width: 100%;
|
|
74836
74860
|
outline: none;
|
|
74837
74861
|
border-color: ${GRAY_300};
|
|
74862
|
+
border-style: solid;
|
|
74838
74863
|
color: ${GRAY_900};
|
|
74839
74864
|
|
|
74840
74865
|
&::placeholder {
|
|
@@ -79492,8 +79517,8 @@ exports.stores = stores;
|
|
|
79492
79517
|
exports.tokenColors = tokenColors;
|
|
79493
79518
|
exports.tokenize = tokenize;
|
|
79494
79519
|
|
|
79495
|
-
__info__.version = "19.0.
|
|
79496
|
-
__info__.date = "2026-08-
|
|
79497
|
-
__info__.hash = "
|
|
79520
|
+
__info__.version = "19.0.48";
|
|
79521
|
+
__info__.date = "2026-08-29T09:14:12.472Z";
|
|
79522
|
+
__info__.hash = "0a6c168";
|
|
79498
79523
|
|
|
79499
79524
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|