@odoo/o-spreadsheet 18.4.12 → 18.4.14
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.js +171 -125
- package/dist/o-spreadsheet.d.ts +5 -0
- package/dist/o-spreadsheet.esm.js +171 -125
- package/dist/o-spreadsheet.iife.js +171 -125
- package/dist/o-spreadsheet.iife.min.js +17 -24
- package/dist/o_spreadsheet.xml +25 -5
- 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.4.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.4.14
|
|
6
|
+
* @date 2025-10-16T06:39:40.249Z
|
|
7
|
+
* @hash bc55c40
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -904,9 +904,7 @@ function removeIndexesFromArray(array, indexes) {
|
|
|
904
904
|
return newArray;
|
|
905
905
|
}
|
|
906
906
|
function insertItemsAtIndex(array, items, index) {
|
|
907
|
-
|
|
908
|
-
newArray.splice(index, 0, ...items);
|
|
909
|
-
return newArray;
|
|
907
|
+
return array.slice(0, index).concat(items).concat(array.slice(index));
|
|
910
908
|
}
|
|
911
909
|
function replaceItemAtIndex(array, newItem, index) {
|
|
912
910
|
const newArray = [...array];
|
|
@@ -3194,7 +3192,17 @@ function toNumberMatrix(data, argName) {
|
|
|
3194
3192
|
return toMatrix(data).map((row) => {
|
|
3195
3193
|
return row.map((cell) => {
|
|
3196
3194
|
if (typeof cell.value !== "number") {
|
|
3197
|
-
|
|
3195
|
+
let message = "";
|
|
3196
|
+
if (typeof cell === "object") {
|
|
3197
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got an empty value.", argName);
|
|
3198
|
+
}
|
|
3199
|
+
else if (typeof cell === "string") {
|
|
3200
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a string.", argName);
|
|
3201
|
+
}
|
|
3202
|
+
else if (typeof cell === "boolean") {
|
|
3203
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a boolean.", argName);
|
|
3204
|
+
}
|
|
3205
|
+
throw new EvaluationError(message);
|
|
3198
3206
|
}
|
|
3199
3207
|
return cell.value;
|
|
3200
3208
|
});
|
|
@@ -4313,7 +4321,7 @@ function tokensToTextInternalFormat(tokens) {
|
|
|
4313
4321
|
* Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
|
|
4314
4322
|
*
|
|
4315
4323
|
* As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
|
|
4316
|
-
* preceded by a data token "h", then it's not a month but
|
|
4324
|
+
* preceded by a data token "h", then it's not a month but a minute.
|
|
4317
4325
|
*/
|
|
4318
4326
|
function convertTokensToMinutesInDateFormat(tokens) {
|
|
4319
4327
|
const dateParts = tokens.filter((token) => token.type === "DATE_PART");
|
|
@@ -4356,6 +4364,9 @@ function internalFormatPartToFormat(internalFormat) {
|
|
|
4356
4364
|
case "REPEATED_CHAR":
|
|
4357
4365
|
format += "*" + token.value;
|
|
4358
4366
|
break;
|
|
4367
|
+
case "DATE_PART":
|
|
4368
|
+
format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
|
|
4369
|
+
break;
|
|
4359
4370
|
default:
|
|
4360
4371
|
format += token.value;
|
|
4361
4372
|
}
|
|
@@ -9079,7 +9090,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
9079
9090
|
pasteCell(origin, target, clipboardOption) {
|
|
9080
9091
|
const { sheetId, col, row } = target;
|
|
9081
9092
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
9082
|
-
const originFormat = origin?.format
|
|
9093
|
+
const originFormat = origin?.format || origin.evaluatedCell.format;
|
|
9083
9094
|
if (clipboardOption?.pasteOption === "asValue") {
|
|
9084
9095
|
this.dispatch("UPDATE_CELL", {
|
|
9085
9096
|
...target,
|
|
@@ -13176,7 +13187,7 @@ const GROWTH = {
|
|
|
13176
13187
|
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13177
13188
|
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13178
13189
|
}
|
|
13179
|
-
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "
|
|
13190
|
+
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "known_data_y")), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b)));
|
|
13180
13191
|
},
|
|
13181
13192
|
};
|
|
13182
13193
|
// -----------------------------------------------------------------------------
|
|
@@ -13249,7 +13260,7 @@ const LINEST = {
|
|
|
13249
13260
|
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13250
13261
|
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13251
13262
|
}
|
|
13252
|
-
return fullLinearRegression(toNumberMatrix(dataX, "
|
|
13263
|
+
return fullLinearRegression(toNumberMatrix(dataX, "data_x"), toNumberMatrix(dataY, "data_y"), toBoolean(calculateB), toBoolean(verbose));
|
|
13253
13264
|
},
|
|
13254
13265
|
isExported: true,
|
|
13255
13266
|
};
|
|
@@ -13268,7 +13279,7 @@ const LOGEST = {
|
|
|
13268
13279
|
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13269
13280
|
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13270
13281
|
}
|
|
13271
|
-
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "
|
|
13282
|
+
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "data_x"), logM(toNumberMatrix(dataY, "data_y")), toBoolean(calculateB), toBoolean(verbose));
|
|
13272
13283
|
for (let i = 0; i < coeffs.length; i++) {
|
|
13273
13284
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
13274
13285
|
}
|
|
@@ -13882,7 +13893,7 @@ const TREND = {
|
|
|
13882
13893
|
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13883
13894
|
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13884
13895
|
}
|
|
13885
|
-
return predictLinearValues(toNumberMatrix(knownDataY, "
|
|
13896
|
+
return predictLinearValues(toNumberMatrix(knownDataY, "known_data_y"), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b));
|
|
13886
13897
|
},
|
|
13887
13898
|
};
|
|
13888
13899
|
// -----------------------------------------------------------------------------
|
|
@@ -21876,6 +21887,10 @@ const chartShowValuesPlugin = {
|
|
|
21876
21887
|
}
|
|
21877
21888
|
const ctx = chart.ctx;
|
|
21878
21889
|
ctx.save();
|
|
21890
|
+
const { left, top, height, width } = chart.chartArea;
|
|
21891
|
+
ctx.beginPath();
|
|
21892
|
+
ctx.rect(left, top, width, height);
|
|
21893
|
+
ctx.clip();
|
|
21879
21894
|
ctx.textAlign = "center";
|
|
21880
21895
|
ctx.textBaseline = "middle";
|
|
21881
21896
|
ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
|
|
@@ -22911,7 +22926,18 @@ class ChartJsComponent extends Component {
|
|
|
22911
22926
|
this.chart.update();
|
|
22912
22927
|
}
|
|
22913
22928
|
hasChartDataChanged() {
|
|
22914
|
-
return !deepEquals(this.currentRuntime
|
|
22929
|
+
return !deepEquals(this.getChartDataInRuntime(this.currentRuntime), this.getChartDataInRuntime(this.chartRuntime));
|
|
22930
|
+
}
|
|
22931
|
+
getChartDataInRuntime(runtime) {
|
|
22932
|
+
const data = runtime.chartJsConfig.data;
|
|
22933
|
+
return {
|
|
22934
|
+
labels: data.labels,
|
|
22935
|
+
dataset: data.datasets.map((dataset) => ({
|
|
22936
|
+
data: dataset.data,
|
|
22937
|
+
label: dataset.label,
|
|
22938
|
+
tree: dataset.tree,
|
|
22939
|
+
})),
|
|
22940
|
+
};
|
|
22915
22941
|
}
|
|
22916
22942
|
enableAnimationInChartData(chartData) {
|
|
22917
22943
|
return {
|
|
@@ -24533,6 +24559,7 @@ function getChartTimeOptions(labels, labelFormat, locale) {
|
|
|
24533
24559
|
parser: luxonFormat,
|
|
24534
24560
|
displayFormats,
|
|
24535
24561
|
unit: timeUnit ?? false,
|
|
24562
|
+
tooltipFormat: luxonFormat,
|
|
24536
24563
|
};
|
|
24537
24564
|
}
|
|
24538
24565
|
/**
|
|
@@ -25613,6 +25640,7 @@ function getLineChartScales(definition, args) {
|
|
|
25613
25640
|
};
|
|
25614
25641
|
Object.assign(scales.x, axis);
|
|
25615
25642
|
scales.x.ticks.maxTicksLimit = 15;
|
|
25643
|
+
delete scales?.x?.ticks?.callback;
|
|
25616
25644
|
}
|
|
25617
25645
|
else if (axisType === "linear") {
|
|
25618
25646
|
scales.x.type = "linear";
|
|
@@ -30661,7 +30689,7 @@ class ChartDashboardMenu extends Component {
|
|
|
30661
30689
|
}
|
|
30662
30690
|
openContextMenu(ev) {
|
|
30663
30691
|
this.menuState.isOpen = true;
|
|
30664
|
-
this.menuState.anchorRect =
|
|
30692
|
+
this.menuState.anchorRect = getBoundingRectAsPOJO(ev.currentTarget);
|
|
30665
30693
|
this.menuState.menuItems = getChartMenuActions(this.props.figureUI.id, () => { }, this.env);
|
|
30666
30694
|
}
|
|
30667
30695
|
get fullScreenMenuItem() {
|
|
@@ -37463,6 +37491,74 @@ function getPath2D(svgPath) {
|
|
|
37463
37491
|
return path2D;
|
|
37464
37492
|
}
|
|
37465
37493
|
|
|
37494
|
+
/**
|
|
37495
|
+
* Get the relative path between two files
|
|
37496
|
+
*
|
|
37497
|
+
* Eg.:
|
|
37498
|
+
* from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
|
|
37499
|
+
*/
|
|
37500
|
+
function getRelativePath(from, to) {
|
|
37501
|
+
const fromPathParts = from.split("/");
|
|
37502
|
+
const toPathParts = to.split("/");
|
|
37503
|
+
let relPath = "";
|
|
37504
|
+
let startIndex = 0;
|
|
37505
|
+
for (let i = 0; i < fromPathParts.length - 1; i++) {
|
|
37506
|
+
if (fromPathParts[i] === toPathParts[i]) {
|
|
37507
|
+
startIndex++;
|
|
37508
|
+
}
|
|
37509
|
+
else {
|
|
37510
|
+
relPath += "../";
|
|
37511
|
+
}
|
|
37512
|
+
}
|
|
37513
|
+
relPath += toPathParts.slice(startIndex).join("/");
|
|
37514
|
+
return relPath;
|
|
37515
|
+
}
|
|
37516
|
+
/**
|
|
37517
|
+
* Convert an array of element into an object where the objects keys were the elements position in the array.
|
|
37518
|
+
* Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
|
|
37519
|
+
*
|
|
37520
|
+
* eg. : ["a", "b"] => {0:"a", 1:"b"}
|
|
37521
|
+
*/
|
|
37522
|
+
function arrayToObject(array, indexOffset = 0) {
|
|
37523
|
+
const obj = {};
|
|
37524
|
+
for (let i = 0; i < array.length; i++) {
|
|
37525
|
+
if (array[i]) {
|
|
37526
|
+
obj[i + indexOffset] = array[i];
|
|
37527
|
+
}
|
|
37528
|
+
}
|
|
37529
|
+
return obj;
|
|
37530
|
+
}
|
|
37531
|
+
/**
|
|
37532
|
+
* In xlsx we can have string with unicode characters with the format _x00fa_.
|
|
37533
|
+
* Replace with characters understandable by JS
|
|
37534
|
+
*/
|
|
37535
|
+
function fixXlsxUnicode(str) {
|
|
37536
|
+
return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
|
|
37537
|
+
return String.fromCharCode(parseInt(code, 16));
|
|
37538
|
+
});
|
|
37539
|
+
}
|
|
37540
|
+
/** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
|
|
37541
|
+
function getSheetDataHeader(sheetData, dimension, index) {
|
|
37542
|
+
if (dimension === "COL") {
|
|
37543
|
+
if (!sheetData.cols[index]) {
|
|
37544
|
+
sheetData.cols[index] = {};
|
|
37545
|
+
}
|
|
37546
|
+
return sheetData.cols[index];
|
|
37547
|
+
}
|
|
37548
|
+
if (!sheetData.rows[index]) {
|
|
37549
|
+
sheetData.rows[index] = {};
|
|
37550
|
+
}
|
|
37551
|
+
return sheetData.rows[index];
|
|
37552
|
+
}
|
|
37553
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
37554
|
+
function prefixFormulaWithEqual(formula) {
|
|
37555
|
+
if (formula[0] === "=") {
|
|
37556
|
+
return formula;
|
|
37557
|
+
}
|
|
37558
|
+
const tokens = tokenize(formula);
|
|
37559
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
37560
|
+
}
|
|
37561
|
+
|
|
37466
37562
|
/**
|
|
37467
37563
|
* Map of the different types of conversions warnings and their name in error messages
|
|
37468
37564
|
*/
|
|
@@ -37985,66 +38081,6 @@ function hexaToInt(hex) {
|
|
|
37985
38081
|
*/
|
|
37986
38082
|
const DEFAULT_SYSTEM_COLOR = "FF000000";
|
|
37987
38083
|
|
|
37988
|
-
/**
|
|
37989
|
-
* Get the relative path between two files
|
|
37990
|
-
*
|
|
37991
|
-
* Eg.:
|
|
37992
|
-
* from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
|
|
37993
|
-
*/
|
|
37994
|
-
function getRelativePath(from, to) {
|
|
37995
|
-
const fromPathParts = from.split("/");
|
|
37996
|
-
const toPathParts = to.split("/");
|
|
37997
|
-
let relPath = "";
|
|
37998
|
-
let startIndex = 0;
|
|
37999
|
-
for (let i = 0; i < fromPathParts.length - 1; i++) {
|
|
38000
|
-
if (fromPathParts[i] === toPathParts[i]) {
|
|
38001
|
-
startIndex++;
|
|
38002
|
-
}
|
|
38003
|
-
else {
|
|
38004
|
-
relPath += "../";
|
|
38005
|
-
}
|
|
38006
|
-
}
|
|
38007
|
-
relPath += toPathParts.slice(startIndex).join("/");
|
|
38008
|
-
return relPath;
|
|
38009
|
-
}
|
|
38010
|
-
/**
|
|
38011
|
-
* Convert an array of element into an object where the objects keys were the elements position in the array.
|
|
38012
|
-
* Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
|
|
38013
|
-
*
|
|
38014
|
-
* eg. : ["a", "b"] => {0:"a", 1:"b"}
|
|
38015
|
-
*/
|
|
38016
|
-
function arrayToObject(array, indexOffset = 0) {
|
|
38017
|
-
const obj = {};
|
|
38018
|
-
for (let i = 0; i < array.length; i++) {
|
|
38019
|
-
if (array[i]) {
|
|
38020
|
-
obj[i + indexOffset] = array[i];
|
|
38021
|
-
}
|
|
38022
|
-
}
|
|
38023
|
-
return obj;
|
|
38024
|
-
}
|
|
38025
|
-
/**
|
|
38026
|
-
* In xlsx we can have string with unicode characters with the format _x00fa_.
|
|
38027
|
-
* Replace with characters understandable by JS
|
|
38028
|
-
*/
|
|
38029
|
-
function fixXlsxUnicode(str) {
|
|
38030
|
-
return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
|
|
38031
|
-
return String.fromCharCode(parseInt(code, 16));
|
|
38032
|
-
});
|
|
38033
|
-
}
|
|
38034
|
-
/** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
|
|
38035
|
-
function getSheetDataHeader(sheetData, dimension, index) {
|
|
38036
|
-
if (dimension === "COL") {
|
|
38037
|
-
if (!sheetData.cols[index]) {
|
|
38038
|
-
sheetData.cols[index] = {};
|
|
38039
|
-
}
|
|
38040
|
-
return sheetData.cols[index];
|
|
38041
|
-
}
|
|
38042
|
-
if (!sheetData.rows[index]) {
|
|
38043
|
-
sheetData.rows[index] = {};
|
|
38044
|
-
}
|
|
38045
|
-
return sheetData.rows[index];
|
|
38046
|
-
}
|
|
38047
|
-
|
|
38048
38084
|
const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
|
|
38049
38085
|
/**
|
|
38050
38086
|
* Convert excel format to o_spreadsheet format
|
|
@@ -38254,9 +38290,9 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
|
|
|
38254
38290
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
38255
38291
|
continue;
|
|
38256
38292
|
operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.operator];
|
|
38257
|
-
values.push(
|
|
38293
|
+
values.push(prefixFormulaWithEqual(rule.formula[0]));
|
|
38258
38294
|
if (rule.formula.length === 2) {
|
|
38259
|
-
values.push(
|
|
38295
|
+
values.push(prefixFormulaWithEqual(rule.formula[1]));
|
|
38260
38296
|
}
|
|
38261
38297
|
break;
|
|
38262
38298
|
}
|
|
@@ -38414,11 +38450,6 @@ function convertIcons(xlsxIconSet, index) {
|
|
|
38414
38450
|
? ICON_SETS[iconSet].neutral
|
|
38415
38451
|
: ICON_SETS[iconSet].good;
|
|
38416
38452
|
}
|
|
38417
|
-
/** Prefix the string by "=" if the string looks like a formula */
|
|
38418
|
-
function prefixFormula(formula) {
|
|
38419
|
-
const tokens = tokenize(formula);
|
|
38420
|
-
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
38421
|
-
}
|
|
38422
38453
|
// ---------------------------------------------------------------------------
|
|
38423
38454
|
// Warnings
|
|
38424
38455
|
// ---------------------------------------------------------------------------
|
|
@@ -38890,7 +38921,7 @@ function convertDataValidationRules(xlsxDataValidations, warningManager) {
|
|
|
38890
38921
|
dvRules.push(decimalRule);
|
|
38891
38922
|
break;
|
|
38892
38923
|
case "list":
|
|
38893
|
-
const listRule =
|
|
38924
|
+
const listRule = convertListRule(dvId++, dv);
|
|
38894
38925
|
dvRules.push(listRule);
|
|
38895
38926
|
break;
|
|
38896
38927
|
case "date":
|
|
@@ -38910,9 +38941,9 @@ function convertDataValidationRules(xlsxDataValidations, warningManager) {
|
|
|
38910
38941
|
return dvRules;
|
|
38911
38942
|
}
|
|
38912
38943
|
function convertDecimalRule(id, dv) {
|
|
38913
|
-
const values = [dv.formula1.toString()];
|
|
38944
|
+
const values = [prefixFormulaWithEqual(dv.formula1.toString())];
|
|
38914
38945
|
if (dv.formula2) {
|
|
38915
|
-
values.push(dv.formula2.toString());
|
|
38946
|
+
values.push(prefixFormulaWithEqual(dv.formula2.toString()));
|
|
38916
38947
|
}
|
|
38917
38948
|
return {
|
|
38918
38949
|
id: id.toString(),
|
|
@@ -38924,7 +38955,7 @@ function convertDecimalRule(id, dv) {
|
|
|
38924
38955
|
},
|
|
38925
38956
|
};
|
|
38926
38957
|
}
|
|
38927
|
-
function
|
|
38958
|
+
function convertListRule(id, dv) {
|
|
38928
38959
|
const formula1 = dv.formula1.toString();
|
|
38929
38960
|
const isRangeRule = rangeReference.test(formula1);
|
|
38930
38961
|
return {
|
|
@@ -38940,9 +38971,9 @@ function convertListrule(id, dv) {
|
|
|
38940
38971
|
}
|
|
38941
38972
|
function convertDateRule(id, dv) {
|
|
38942
38973
|
let criterion;
|
|
38943
|
-
const values = [dv.formula1.toString()];
|
|
38974
|
+
const values = [prefixFormulaWithEqual(dv.formula1.toString())];
|
|
38944
38975
|
if (dv.formula2) {
|
|
38945
|
-
values.push(dv.formula2.toString());
|
|
38976
|
+
values.push(prefixFormulaWithEqual(dv.formula2.toString()));
|
|
38946
38977
|
criterion = {
|
|
38947
38978
|
type: XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[dv.operator],
|
|
38948
38979
|
values: getDateCriterionFormattedValues(values, DEFAULT_LOCALE),
|
|
@@ -38969,7 +39000,7 @@ function convertCustomRule(id, dv) {
|
|
|
38969
39000
|
isBlocking: dv.errorStyle !== "warning",
|
|
38970
39001
|
criterion: {
|
|
38971
39002
|
type: "customFormula",
|
|
38972
|
-
values: [
|
|
39003
|
+
values: [prefixFormulaWithEqual(dv.formula1.toString())],
|
|
38973
39004
|
},
|
|
38974
39005
|
};
|
|
38975
39006
|
}
|
|
@@ -52860,12 +52891,13 @@ class DataValidationEditor extends Component {
|
|
|
52860
52891
|
onCloseSidePanel: { type: Function, optional: true },
|
|
52861
52892
|
};
|
|
52862
52893
|
state = useState({ rule: this.defaultDataValidationRule, errors: [] });
|
|
52894
|
+
editingSheetId;
|
|
52863
52895
|
setup() {
|
|
52896
|
+
this.editingSheetId = this.env.model.getters.getActiveSheetId();
|
|
52864
52897
|
if (this.props.rule) {
|
|
52865
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
52866
52898
|
this.state.rule = {
|
|
52867
52899
|
...this.props.rule,
|
|
52868
|
-
ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range,
|
|
52900
|
+
ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
|
|
52869
52901
|
};
|
|
52870
52902
|
this.state.rule.criterion.type = this.props.rule.criterion.type;
|
|
52871
52903
|
}
|
|
@@ -52899,7 +52931,6 @@ class DataValidationEditor extends Component {
|
|
|
52899
52931
|
const locale = this.env.model.getters.getLocale();
|
|
52900
52932
|
const criterion = rule.criterion;
|
|
52901
52933
|
const criterionEvaluator = criterionEvaluatorRegistry.get(criterion.type);
|
|
52902
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
52903
52934
|
const values = criterion.values
|
|
52904
52935
|
.slice(0, criterionEvaluator.numberOfValues(criterion))
|
|
52905
52936
|
.map((value) => value?.trim())
|
|
@@ -52907,8 +52938,8 @@ class DataValidationEditor extends Component {
|
|
|
52907
52938
|
.map((value) => canonicalizeContent(value, locale));
|
|
52908
52939
|
rule.criterion = { ...criterion, values };
|
|
52909
52940
|
return {
|
|
52910
|
-
sheetId,
|
|
52911
|
-
ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(
|
|
52941
|
+
sheetId: this.editingSheetId,
|
|
52942
|
+
ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(this.editingSheetId, xc)),
|
|
52912
52943
|
rule,
|
|
52913
52944
|
};
|
|
52914
52945
|
}
|
|
@@ -53435,6 +53466,7 @@ css /* scss */ `
|
|
|
53435
53466
|
.o-button {
|
|
53436
53467
|
height: 19px;
|
|
53437
53468
|
width: 19px;
|
|
53469
|
+
box-sizing: content-box;
|
|
53438
53470
|
.o-icon {
|
|
53439
53471
|
height: 14px;
|
|
53440
53472
|
width: 14px;
|
|
@@ -54244,7 +54276,7 @@ class PivotMeasureEditor extends Component {
|
|
|
54244
54276
|
return undefined;
|
|
54245
54277
|
}
|
|
54246
54278
|
get isCalculatedMeasureInvalid() {
|
|
54247
|
-
return
|
|
54279
|
+
return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
|
|
54248
54280
|
}
|
|
54249
54281
|
}
|
|
54250
54282
|
|
|
@@ -61256,11 +61288,11 @@ class HeaderSizePlugin extends CorePlugin {
|
|
|
61256
61288
|
break;
|
|
61257
61289
|
}
|
|
61258
61290
|
case "ADD_COLUMNS_ROWS": {
|
|
61259
|
-
const sizes =
|
|
61291
|
+
const sizes = this.sizes[cmd.sheetId][cmd.dimension];
|
|
61260
61292
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
61261
61293
|
const baseSize = sizes[cmd.base];
|
|
61262
|
-
sizes
|
|
61263
|
-
this.history.update("sizes", cmd.sheetId, cmd.dimension,
|
|
61294
|
+
const newSizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
|
|
61295
|
+
this.history.update("sizes", cmd.sheetId, cmd.dimension, newSizes);
|
|
61264
61296
|
break;
|
|
61265
61297
|
}
|
|
61266
61298
|
case "RESIZE_COLUMNS_ROWS":
|
|
@@ -61411,9 +61443,8 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
61411
61443
|
break;
|
|
61412
61444
|
}
|
|
61413
61445
|
case "ADD_COLUMNS_ROWS": {
|
|
61414
|
-
const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
|
|
61415
61446
|
const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
|
|
61416
|
-
hiddenHeaders.
|
|
61447
|
+
const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
|
|
61417
61448
|
this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
|
|
61418
61449
|
break;
|
|
61419
61450
|
}
|
|
@@ -65448,12 +65479,12 @@ class SpreadsheetRTree {
|
|
|
65448
65479
|
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
65449
65480
|
}
|
|
65450
65481
|
rtreeItemComparer(left, right) {
|
|
65451
|
-
return (left.
|
|
65452
|
-
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
65482
|
+
return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
65453
65483
|
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
65454
65484
|
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
65455
65485
|
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
65456
|
-
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom
|
|
65486
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
|
|
65487
|
+
deepEquals(left.data, right.data));
|
|
65457
65488
|
}
|
|
65458
65489
|
}
|
|
65459
65490
|
/**
|
|
@@ -65526,7 +65557,7 @@ class FormulaDependencyGraph {
|
|
|
65526
65557
|
* in the correct order they should be evaluated.
|
|
65527
65558
|
* This is called a topological ordering (excluding cycles)
|
|
65528
65559
|
*/
|
|
65529
|
-
getCellsDependingOn(ranges) {
|
|
65560
|
+
getCellsDependingOn(ranges, ignore) {
|
|
65530
65561
|
const visited = this.createEmptyPositionSet();
|
|
65531
65562
|
const queue = Array.from(ranges).reverse();
|
|
65532
65563
|
while (queue.length > 0) {
|
|
@@ -65541,7 +65572,7 @@ class FormulaDependencyGraph {
|
|
|
65541
65572
|
const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
|
|
65542
65573
|
const nextInQueue = {};
|
|
65543
65574
|
for (const position of impactedPositions) {
|
|
65544
|
-
if (!visited.has(position)) {
|
|
65575
|
+
if (!visited.has(position) && !ignore.has(position)) {
|
|
65545
65576
|
if (!nextInQueue[position.sheetId]) {
|
|
65546
65577
|
nextInQueue[position.sheetId] = [];
|
|
65547
65578
|
}
|
|
@@ -66098,7 +66129,7 @@ class Evaluator {
|
|
|
66098
66129
|
}
|
|
66099
66130
|
invalidatePositionsDependingOnSpread(sheetId, resultZone) {
|
|
66100
66131
|
// the result matrix is split in 2 zones to exclude the array formula position
|
|
66101
|
-
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
|
|
66132
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })), this.nextPositionsToUpdate);
|
|
66102
66133
|
invalidatedPositions.delete({ sheetId, col: resultZone.left, row: resultZone.top });
|
|
66103
66134
|
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
66104
66135
|
}
|
|
@@ -66216,7 +66247,7 @@ class Evaluator {
|
|
|
66216
66247
|
for (const sheetId in zonesBySheetIds) {
|
|
66217
66248
|
ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
|
|
66218
66249
|
}
|
|
66219
|
-
return this.formulaDependencies().getCellsDependingOn(ranges);
|
|
66250
|
+
return this.formulaDependencies().getCellsDependingOn(ranges, this.nextPositionsToUpdate);
|
|
66220
66251
|
}
|
|
66221
66252
|
}
|
|
66222
66253
|
function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
|
|
@@ -67689,7 +67720,8 @@ class DynamicTablesPlugin extends CoreViewPlugin {
|
|
|
67689
67720
|
const topLeft = { col: unionZone.left, row: unionZone.top, sheetId };
|
|
67690
67721
|
const parentSpreadingCell = this.getters.getArrayFormulaSpreadingOn(topLeft);
|
|
67691
67722
|
if (!parentSpreadingCell) {
|
|
67692
|
-
|
|
67723
|
+
const evaluatedCell = this.getters.getEvaluatedCell(topLeft);
|
|
67724
|
+
return (evaluatedCell.value === CellErrorType.SpilledBlocked && !evaluatedCell.errorOriginPosition);
|
|
67693
67725
|
}
|
|
67694
67726
|
else if (deepEquals(parentSpreadingCell, topLeft) && getZoneArea(unionZone) === 1) {
|
|
67695
67727
|
return true;
|
|
@@ -78590,6 +78622,7 @@ class RibbonMenu extends Component {
|
|
|
78590
78622
|
static components = { Menu };
|
|
78591
78623
|
rootItems = topbarMenuRegistry.getMenuItems();
|
|
78592
78624
|
menuRef = useRef("menu");
|
|
78625
|
+
containerRef = useRef("container");
|
|
78593
78626
|
state = useState({
|
|
78594
78627
|
menuItems: this.rootItems,
|
|
78595
78628
|
title: _t("Menu Bar"),
|
|
@@ -78597,6 +78630,7 @@ class RibbonMenu extends Component {
|
|
|
78597
78630
|
});
|
|
78598
78631
|
setup() {
|
|
78599
78632
|
useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
78633
|
+
onMounted(this.updateShadows);
|
|
78600
78634
|
}
|
|
78601
78635
|
onExternalClick(ev) {
|
|
78602
78636
|
if (!this.menuRef.el?.contains(ev.target)) {
|
|
@@ -78609,6 +78643,7 @@ class RibbonMenu extends Component {
|
|
|
78609
78643
|
this.state.parentState = { ...this.state };
|
|
78610
78644
|
this.state.menuItems = children;
|
|
78611
78645
|
this.state.title = menu.name(this.env);
|
|
78646
|
+
this.containerRef.el?.scrollTo({ top: 0 });
|
|
78612
78647
|
}
|
|
78613
78648
|
else {
|
|
78614
78649
|
this.state.menuItems = this.rootItems;
|
|
@@ -78630,6 +78665,19 @@ class RibbonMenu extends Component {
|
|
|
78630
78665
|
height: `${this.props.height}px`,
|
|
78631
78666
|
});
|
|
78632
78667
|
}
|
|
78668
|
+
updateShadows() {
|
|
78669
|
+
if (!this.containerRef.el) {
|
|
78670
|
+
return;
|
|
78671
|
+
}
|
|
78672
|
+
this.containerRef.el.classList.remove("scroll-top", "scroll-bottom");
|
|
78673
|
+
const maxScroll = this.containerRef.el.scrollHeight - this.containerRef.el.clientHeight || 0;
|
|
78674
|
+
if (this.containerRef.el.scrollTop < maxScroll - 1) {
|
|
78675
|
+
this.containerRef.el.classList.add("scroll-bottom");
|
|
78676
|
+
}
|
|
78677
|
+
if (this.containerRef.el.scrollTop > 0) {
|
|
78678
|
+
this.containerRef.el.classList.add("scroll-top");
|
|
78679
|
+
}
|
|
78680
|
+
}
|
|
78633
78681
|
onClickBack() {
|
|
78634
78682
|
if (!this.state.parentState) {
|
|
78635
78683
|
this.props.onClose();
|
|
@@ -78638,6 +78686,7 @@ class RibbonMenu extends Component {
|
|
|
78638
78686
|
this.state.menuItems = this.state.parentState.menuItems;
|
|
78639
78687
|
this.state.title = this.state.parentState.title;
|
|
78640
78688
|
this.state.parentState = this.state.parentState.parentState;
|
|
78689
|
+
this.containerRef.el?.scrollTo({ top: 0 });
|
|
78641
78690
|
}
|
|
78642
78691
|
get backTitle() {
|
|
78643
78692
|
return this.state.parentState ? _t("Go to previous menu") : _t("Close menu bar");
|
|
@@ -78693,6 +78742,11 @@ class SmallBottomBar extends Component {
|
|
|
78693
78742
|
? this.composerFocusStore.focusMode
|
|
78694
78743
|
: "inactive";
|
|
78695
78744
|
}
|
|
78745
|
+
get showFxIcon() {
|
|
78746
|
+
return (this.focus === "inactive" &&
|
|
78747
|
+
!this.composerStore.currentContent &&
|
|
78748
|
+
!this.composerStore.placeholder);
|
|
78749
|
+
}
|
|
78696
78750
|
get rect() {
|
|
78697
78751
|
return this.composerRef.el
|
|
78698
78752
|
? getBoundingRectAsPOJO(this.composerRef.el)
|
|
@@ -78717,6 +78771,7 @@ class SmallBottomBar extends Component {
|
|
|
78717
78771
|
"max-height": `130px`,
|
|
78718
78772
|
}),
|
|
78719
78773
|
showAssistant: !isIOS(), // Hide assistant on iOS as it breaks visually
|
|
78774
|
+
placeholder: this.composerStore.placeholder,
|
|
78720
78775
|
};
|
|
78721
78776
|
}
|
|
78722
78777
|
get symbols() {
|
|
@@ -78735,12 +78790,6 @@ class SmallBottomBar extends Component {
|
|
|
78735
78790
|
}
|
|
78736
78791
|
|
|
78737
78792
|
const COMPOSER_MAX_HEIGHT = 100;
|
|
78738
|
-
/* svg free of use from https://uxwing.com/formula-fx-icon/ */
|
|
78739
|
-
const FX_SVG = /*xml*/ `
|
|
78740
|
-
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
|
|
78741
|
-
<path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
|
|
78742
|
-
</svg>
|
|
78743
|
-
`;
|
|
78744
78793
|
css /* scss */ `
|
|
78745
78794
|
.o-topbar-composer-container {
|
|
78746
78795
|
height: ${DESKTOP_TOPBAR_TOOLBAR_HEIGHT}px;
|
|
@@ -78752,14 +78801,6 @@ css /* scss */ `
|
|
|
78752
78801
|
margin-bottom: -1px;
|
|
78753
78802
|
border: 1px solid;
|
|
78754
78803
|
font-family: ${DEFAULT_FONT};
|
|
78755
|
-
|
|
78756
|
-
/* In readonly we always show the fx icon if the composer is empty, not matter the focus */
|
|
78757
|
-
.o-composer:empty:not(:focus):not(.active)::before,
|
|
78758
|
-
&.o-topbar-composer-readonly .o-composer:empty::before {
|
|
78759
|
-
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
78760
|
-
position: relative;
|
|
78761
|
-
top: 20%;
|
|
78762
|
-
}
|
|
78763
78804
|
}
|
|
78764
78805
|
|
|
78765
78806
|
.user-select-text {
|
|
@@ -78792,6 +78833,11 @@ class TopBarComposer extends Component {
|
|
|
78792
78833
|
? this.composerFocusStore.focusMode
|
|
78793
78834
|
: "inactive";
|
|
78794
78835
|
}
|
|
78836
|
+
get showFxIcon() {
|
|
78837
|
+
return (this.focus === "inactive" &&
|
|
78838
|
+
!this.composerStore.currentContent &&
|
|
78839
|
+
!this.composerStore.placeholder);
|
|
78840
|
+
}
|
|
78795
78841
|
get composerStyle() {
|
|
78796
78842
|
const style = {
|
|
78797
78843
|
padding: "5px 0px 5px 8px",
|
|
@@ -84809,6 +84855,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
84809
84855
|
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, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
84810
84856
|
|
|
84811
84857
|
|
|
84812
|
-
__info__.version = "18.4.
|
|
84813
|
-
__info__.date = "2025-
|
|
84814
|
-
__info__.hash = "
|
|
84858
|
+
__info__.version = "18.4.14";
|
|
84859
|
+
__info__.date = "2025-10-16T06:39:40.249Z";
|
|
84860
|
+
__info__.hash = "bc55c40";
|