@odoo/o-spreadsheet 18.2.0-alpha.8 → 18.2.1
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 +265 -135
- package/dist/o-spreadsheet.d.ts +35 -26
- package/dist/o-spreadsheet.esm.js +265 -135
- package/dist/o-spreadsheet.iife.js +265 -135
- package/dist/o-spreadsheet.iife.min.js +291 -287
- package/dist/o_spreadsheet.xml +17 -14
- package/package.json +4 -2
|
@@ -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.2.
|
|
6
|
-
* @date 2025-02-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.1
|
|
6
|
+
* @date 2025-02-25T06:03:13.262Z
|
|
7
|
+
* @hash 3b4b5c9
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -2231,17 +2231,7 @@ function toZoneWithoutBoundaryChanges(xc) {
|
|
|
2231
2231
|
*/
|
|
2232
2232
|
function toUnboundedZone(xc) {
|
|
2233
2233
|
const zone = toZoneWithoutBoundaryChanges(xc);
|
|
2234
|
-
|
|
2235
|
-
const tmp = zone.left;
|
|
2236
|
-
zone.left = zone.right;
|
|
2237
|
-
zone.right = tmp;
|
|
2238
|
-
}
|
|
2239
|
-
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2240
|
-
const tmp = zone.top;
|
|
2241
|
-
zone.top = zone.bottom;
|
|
2242
|
-
zone.bottom = tmp;
|
|
2243
|
-
}
|
|
2244
|
-
return zone;
|
|
2234
|
+
return reorderZone(zone);
|
|
2245
2235
|
}
|
|
2246
2236
|
/**
|
|
2247
2237
|
* Convert from a cartesian reference to a Zone.
|
|
@@ -2515,11 +2505,11 @@ function positions(zone) {
|
|
|
2515
2505
|
return positions;
|
|
2516
2506
|
}
|
|
2517
2507
|
function reorderZone(zone) {
|
|
2518
|
-
if (zone.left > zone.right) {
|
|
2519
|
-
zone = { left: zone.right, right: zone.left
|
|
2508
|
+
if (zone.right !== undefined && zone.left > zone.right) {
|
|
2509
|
+
zone = { ...zone, left: zone.right, right: zone.left };
|
|
2520
2510
|
}
|
|
2521
|
-
if (zone.top > zone.bottom) {
|
|
2522
|
-
zone = {
|
|
2511
|
+
if (zone.bottom !== undefined && zone.top > zone.bottom) {
|
|
2512
|
+
zone = { ...zone, top: zone.bottom, bottom: zone.top };
|
|
2523
2513
|
}
|
|
2524
2514
|
return zone;
|
|
2525
2515
|
}
|
|
@@ -3424,12 +3414,12 @@ function isTargetDependent(cmd) {
|
|
|
3424
3414
|
function isRangeDependant(cmd) {
|
|
3425
3415
|
return "ranges" in cmd;
|
|
3426
3416
|
}
|
|
3427
|
-
function isZoneDependent(cmd) {
|
|
3428
|
-
return "zone" in cmd;
|
|
3429
|
-
}
|
|
3430
3417
|
function isPositionDependent(cmd) {
|
|
3431
3418
|
return "col" in cmd && "row" in cmd && "sheetId" in cmd;
|
|
3432
3419
|
}
|
|
3420
|
+
function isZoneDependent(cmd) {
|
|
3421
|
+
return "sheetId" in cmd && "zone" in cmd;
|
|
3422
|
+
}
|
|
3433
3423
|
const invalidateEvaluationCommands = new Set([
|
|
3434
3424
|
"RENAME_SHEET",
|
|
3435
3425
|
"DELETE_SHEET",
|
|
@@ -3441,6 +3431,7 @@ const invalidateEvaluationCommands = new Set([
|
|
|
3441
3431
|
"REDO",
|
|
3442
3432
|
"ADD_MERGE",
|
|
3443
3433
|
"REMOVE_MERGE",
|
|
3434
|
+
"DUPLICATE_SHEET",
|
|
3444
3435
|
"UPDATE_LOCALE",
|
|
3445
3436
|
"ADD_PIVOT",
|
|
3446
3437
|
"UPDATE_PIVOT",
|
|
@@ -3470,7 +3461,6 @@ const invalidateChartEvaluationCommands = new Set([
|
|
|
3470
3461
|
]);
|
|
3471
3462
|
const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
|
|
3472
3463
|
const invalidateCFEvaluationCommands = new Set([
|
|
3473
|
-
"DUPLICATE_SHEET",
|
|
3474
3464
|
"EVALUATE_CELLS",
|
|
3475
3465
|
"ADD_CONDITIONAL_FORMAT",
|
|
3476
3466
|
"REMOVE_CONDITIONAL_FORMAT",
|
|
@@ -3640,6 +3630,7 @@ exports.CommandResult = void 0;
|
|
|
3640
3630
|
CommandResult["InvalidRange"] = "InvalidRange";
|
|
3641
3631
|
CommandResult["InvalidZones"] = "InvalidZones";
|
|
3642
3632
|
CommandResult["InvalidSheetId"] = "InvalidSheetId";
|
|
3633
|
+
CommandResult["InvalidCellId"] = "InvalidCellId";
|
|
3643
3634
|
CommandResult["InvalidFigureId"] = "InvalidFigureId";
|
|
3644
3635
|
CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
|
|
3645
3636
|
CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
|
|
@@ -4469,7 +4460,7 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
|
|
|
4469
4460
|
* @param reverseSearch if true, search in the array starting from the end.
|
|
4470
4461
|
|
|
4471
4462
|
*/
|
|
4472
|
-
function linearSearch(data, target, mode, numberOfValues, getValueInData, reverseSearch = false) {
|
|
4463
|
+
function linearSearch(data, target, mode, numberOfValues, getValueInData, lookupCaches, reverseSearch = false) {
|
|
4473
4464
|
if (target === undefined || target.value === null) {
|
|
4474
4465
|
return -1;
|
|
4475
4466
|
}
|
|
@@ -4478,17 +4469,48 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4478
4469
|
}
|
|
4479
4470
|
const _target = normalizeValue(target.value);
|
|
4480
4471
|
const getValue = reverseSearch
|
|
4481
|
-
? (data, i) => getValueInData(data, numberOfValues - i - 1)
|
|
4482
|
-
: getValueInData;
|
|
4472
|
+
? (data, i) => normalizeValue(getValueInData(data, numberOfValues - i - 1))
|
|
4473
|
+
: (data, i) => normalizeValue(getValueInData(data, i));
|
|
4474
|
+
// first check if the target is in the cache
|
|
4475
|
+
const isNotWildcardTarget = mode !== "wildcard" ||
|
|
4476
|
+
typeof _target !== "string" ||
|
|
4477
|
+
!(_target.includes("*") || _target.includes("?"));
|
|
4478
|
+
if (lookupCaches && isNotWildcardTarget) {
|
|
4479
|
+
const searchMode = reverseSearch ? "reverseSearch" : "forwardSearch";
|
|
4480
|
+
let cache = lookupCaches[searchMode].get(data);
|
|
4481
|
+
if (cache === undefined) {
|
|
4482
|
+
// build the cache for all the values
|
|
4483
|
+
cache = new Map();
|
|
4484
|
+
for (let i = 0; i < numberOfValues; i++) {
|
|
4485
|
+
const value = getValue(data, i) ?? null;
|
|
4486
|
+
if (!cache.has(value)) {
|
|
4487
|
+
cache.set(value, i);
|
|
4488
|
+
}
|
|
4489
|
+
}
|
|
4490
|
+
lookupCaches[searchMode].set(data, cache);
|
|
4491
|
+
}
|
|
4492
|
+
if (cache.has(_target)) {
|
|
4493
|
+
const resultIndex = cache.get(_target);
|
|
4494
|
+
return reverseSearch ? numberOfValues - resultIndex - 1 : resultIndex;
|
|
4495
|
+
}
|
|
4496
|
+
if (mode === "strict") {
|
|
4497
|
+
return -1;
|
|
4498
|
+
}
|
|
4499
|
+
}
|
|
4500
|
+
// else perform the linear search
|
|
4501
|
+
const resultIndex = _linearSearch(data, _target, mode, numberOfValues, getValue);
|
|
4502
|
+
return reverseSearch && resultIndex !== -1 ? numberOfValues - resultIndex - 1 : resultIndex;
|
|
4503
|
+
}
|
|
4504
|
+
function _linearSearch(data, _target, mode, numberOfValues, getNormalizeValue) {
|
|
4483
4505
|
let indexMatchTarget = (i) => {
|
|
4484
|
-
return
|
|
4506
|
+
return getNormalizeValue(data, i) === _target;
|
|
4485
4507
|
};
|
|
4486
4508
|
if (mode === "wildcard" &&
|
|
4487
4509
|
typeof _target === "string" &&
|
|
4488
4510
|
(_target.includes("*") || _target.includes("?"))) {
|
|
4489
4511
|
const regExp = wildcardToRegExp(_target);
|
|
4490
4512
|
indexMatchTarget = (i) => {
|
|
4491
|
-
const value =
|
|
4513
|
+
const value = getNormalizeValue(data, i);
|
|
4492
4514
|
if (typeof value === "string") {
|
|
4493
4515
|
return regExp.test(value);
|
|
4494
4516
|
}
|
|
@@ -4499,7 +4521,7 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4499
4521
|
let closestMatchIndex = -1;
|
|
4500
4522
|
if (mode === "nextSmaller") {
|
|
4501
4523
|
indexMatchTarget = (i) => {
|
|
4502
|
-
const value =
|
|
4524
|
+
const value = getNormalizeValue(data, i);
|
|
4503
4525
|
if ((!closestMatch && compareCellValues(_target, value) >= 0) ||
|
|
4504
4526
|
(compareCellValues(_target, value) >= 0 && compareCellValues(value, closestMatch) > 0)) {
|
|
4505
4527
|
closestMatch = value;
|
|
@@ -4510,7 +4532,7 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4510
4532
|
}
|
|
4511
4533
|
if (mode === "nextGreater") {
|
|
4512
4534
|
indexMatchTarget = (i) => {
|
|
4513
|
-
const value =
|
|
4535
|
+
const value = getNormalizeValue(data, i);
|
|
4514
4536
|
if ((!closestMatch && compareCellValues(_target, value) <= 0) ||
|
|
4515
4537
|
(compareCellValues(_target, value) <= 0 && compareCellValues(value, closestMatch) < 0)) {
|
|
4516
4538
|
closestMatch = value;
|
|
@@ -4521,12 +4543,10 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4521
4543
|
}
|
|
4522
4544
|
for (let i = 0; i < numberOfValues; i++) {
|
|
4523
4545
|
if (indexMatchTarget(i)) {
|
|
4524
|
-
return
|
|
4546
|
+
return i;
|
|
4525
4547
|
}
|
|
4526
4548
|
}
|
|
4527
|
-
return
|
|
4528
|
-
? numberOfValues - closestMatchIndex - 1
|
|
4529
|
-
: closestMatchIndex;
|
|
4549
|
+
return closestMatchIndex;
|
|
4530
4550
|
}
|
|
4531
4551
|
/**
|
|
4532
4552
|
* Normalize a value.
|
|
@@ -6500,10 +6520,11 @@ class UuidGenerator {
|
|
|
6500
6520
|
*
|
|
6501
6521
|
*/
|
|
6502
6522
|
smallUuid() {
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6523
|
+
if (window.crypto) {
|
|
6524
|
+
return "10000000-1000".replace(/[01]/g, (c) => {
|
|
6525
|
+
const n = Number(c);
|
|
6526
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6527
|
+
});
|
|
6507
6528
|
}
|
|
6508
6529
|
else {
|
|
6509
6530
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -6518,10 +6539,11 @@ class UuidGenerator {
|
|
|
6518
6539
|
* This method should be used when you need to avoid collisions at all costs, like the id of a revision.
|
|
6519
6540
|
*/
|
|
6520
6541
|
uuidv4() {
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6542
|
+
if (window.crypto) {
|
|
6543
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
|
|
6544
|
+
const n = Number(c);
|
|
6545
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6546
|
+
});
|
|
6525
6547
|
}
|
|
6526
6548
|
else {
|
|
6527
6549
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -12238,6 +12260,25 @@ const LN = {
|
|
|
12238
12260
|
isExported: true,
|
|
12239
12261
|
};
|
|
12240
12262
|
// -----------------------------------------------------------------------------
|
|
12263
|
+
// LOG
|
|
12264
|
+
// -----------------------------------------------------------------------------
|
|
12265
|
+
const LOG = {
|
|
12266
|
+
description: _t("The logarithm of a number, for a given base."),
|
|
12267
|
+
args: [
|
|
12268
|
+
arg("value (number)", _t("The value for which to calculate the logarithm.")),
|
|
12269
|
+
arg("base (number, default=10)", _t("The base of the logarithm.")),
|
|
12270
|
+
],
|
|
12271
|
+
compute: function (value, base = { value: 10 }) {
|
|
12272
|
+
const _value = toNumber(value, this.locale);
|
|
12273
|
+
const _base = toNumber(base, this.locale);
|
|
12274
|
+
assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
|
|
12275
|
+
assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
|
|
12276
|
+
assert(() => _base !== 1, _t("The base must be different from 1."));
|
|
12277
|
+
return Math.log10(_value) / Math.log10(_base);
|
|
12278
|
+
},
|
|
12279
|
+
isExported: true,
|
|
12280
|
+
};
|
|
12281
|
+
// -----------------------------------------------------------------------------
|
|
12241
12282
|
// MOD
|
|
12242
12283
|
// -----------------------------------------------------------------------------
|
|
12243
12284
|
function mod(dividend, divisor) {
|
|
@@ -12777,6 +12818,7 @@ var math = /*#__PURE__*/Object.freeze({
|
|
|
12777
12818
|
ISODD: ISODD,
|
|
12778
12819
|
ISO_CEILING: ISO_CEILING,
|
|
12779
12820
|
LN: LN,
|
|
12821
|
+
LOG: LOG,
|
|
12780
12822
|
MOD: MOD,
|
|
12781
12823
|
MUNIT: MUNIT,
|
|
12782
12824
|
ODD: ODD,
|
|
@@ -18675,7 +18717,7 @@ const HLOOKUP = {
|
|
|
18675
18717
|
const _isSorted = toBoolean(isSorted.value);
|
|
18676
18718
|
const colIndex = _isSorted
|
|
18677
18719
|
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18678
|
-
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18720
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange, this.lookupCaches);
|
|
18679
18721
|
const col = _range[colIndex];
|
|
18680
18722
|
if (col === undefined) {
|
|
18681
18723
|
return valueNotAvailable(searchKey);
|
|
@@ -18830,7 +18872,7 @@ const MATCH = {
|
|
|
18830
18872
|
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18831
18873
|
break;
|
|
18832
18874
|
case 0:
|
|
18833
|
-
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18875
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement, this.lookupCaches);
|
|
18834
18876
|
break;
|
|
18835
18877
|
case -1:
|
|
18836
18878
|
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
@@ -18898,7 +18940,7 @@ const VLOOKUP = {
|
|
|
18898
18940
|
const _isSorted = toBoolean(isSorted.value);
|
|
18899
18941
|
const rowIndex = _isSorted
|
|
18900
18942
|
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18901
|
-
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18943
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange, this.lookupCaches);
|
|
18902
18944
|
const value = _range[_index - 1][rowIndex];
|
|
18903
18945
|
if (value === undefined) {
|
|
18904
18946
|
return valueNotAvailable(searchKey);
|
|
@@ -18954,7 +18996,7 @@ const XLOOKUP = {
|
|
|
18954
18996
|
const reverseSearch = _searchMode === -1;
|
|
18955
18997
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18956
18998
|
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18957
|
-
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18999
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, this.lookupCaches, reverseSearch);
|
|
18958
19000
|
if (index !== -1) {
|
|
18959
19001
|
return lookupDirection === "col"
|
|
18960
19002
|
? _returnRange.map((col) => [col[index]])
|
|
@@ -28293,7 +28335,7 @@ function getBarChartData(definition, dataSets, labelRange, getters) {
|
|
|
28293
28335
|
}
|
|
28294
28336
|
function getPyramidChartData(definition, dataSets, labelRange, getters) {
|
|
28295
28337
|
const barChartData = getBarChartData(definition, dataSets, labelRange, getters);
|
|
28296
|
-
const barDataset = barChartData.dataSetsValues;
|
|
28338
|
+
const barDataset = barChartData.dataSetsValues.filter((ds) => !ds.hidden);
|
|
28297
28339
|
const pyramidDatasetValues = [];
|
|
28298
28340
|
if (barDataset[0]) {
|
|
28299
28341
|
const pyramidData = barDataset[0].data.map((value) => (value > 0 ? value : 0));
|
|
@@ -28770,10 +28812,8 @@ function getChartDatasetFormat(getters, allDataSets, axis) {
|
|
|
28770
28812
|
function getChartDatasetValues(getters, dataSets) {
|
|
28771
28813
|
const datasetValues = [];
|
|
28772
28814
|
for (const [dsIndex, ds] of Object.entries(dataSets)) {
|
|
28773
|
-
if (getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left)) {
|
|
28774
|
-
continue;
|
|
28775
|
-
}
|
|
28776
28815
|
let label;
|
|
28816
|
+
let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
|
|
28777
28817
|
if (ds.labelCell) {
|
|
28778
28818
|
const labelRange = ds.labelCell;
|
|
28779
28819
|
const cell = labelRange
|
|
@@ -28800,9 +28840,9 @@ function getChartDatasetValues(getters, dataSets) {
|
|
|
28800
28840
|
data.fill(1);
|
|
28801
28841
|
}
|
|
28802
28842
|
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
|
|
28803
|
-
|
|
28843
|
+
hidden = true;
|
|
28804
28844
|
}
|
|
28805
|
-
datasetValues.push({ data, label });
|
|
28845
|
+
datasetValues.push({ data, label, hidden });
|
|
28806
28846
|
}
|
|
28807
28847
|
return datasetValues;
|
|
28808
28848
|
}
|
|
@@ -28813,12 +28853,13 @@ function getBarChartDatasets(definition, args) {
|
|
|
28813
28853
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28814
28854
|
const trendDatasets = [];
|
|
28815
28855
|
for (const index in dataSetsValues) {
|
|
28816
|
-
let { label, data } = dataSetsValues[index];
|
|
28856
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28817
28857
|
label = definition.dataSets?.[index].label || label;
|
|
28818
28858
|
const backgroundColor = colors.next();
|
|
28819
28859
|
const dataset = {
|
|
28820
28860
|
label,
|
|
28821
28861
|
data,
|
|
28862
|
+
hidden,
|
|
28822
28863
|
borderColor: definition.background || BACKGROUND_CHART_COLOR,
|
|
28823
28864
|
borderWidth: definition.stacked ? 1 : 0,
|
|
28824
28865
|
backgroundColor,
|
|
@@ -28851,6 +28892,9 @@ function getWaterfallDatasetAndLabels(definition, args) {
|
|
|
28851
28892
|
const labelsWithSubTotals = [];
|
|
28852
28893
|
let lastValue = 0;
|
|
28853
28894
|
for (const dataSetsValue of dataSetsValues) {
|
|
28895
|
+
if (dataSetsValue.hidden) {
|
|
28896
|
+
continue;
|
|
28897
|
+
}
|
|
28854
28898
|
for (let i = 0; i < dataSetsValue.data.length; i++) {
|
|
28855
28899
|
const data = dataSetsValue.data[i];
|
|
28856
28900
|
labelsWithSubTotals.push(labels[i]);
|
|
@@ -28886,7 +28930,7 @@ function getLineChartDatasets(definition, args) {
|
|
|
28886
28930
|
const trendDatasets = [];
|
|
28887
28931
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28888
28932
|
for (let index = 0; index < dataSetsValues.length; index++) {
|
|
28889
|
-
let { label, data } = dataSetsValues[index];
|
|
28933
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28890
28934
|
label = definition.dataSets?.[index].label || label;
|
|
28891
28935
|
const color = colors.next();
|
|
28892
28936
|
if (axisType && ["linear", "time"].includes(axisType)) {
|
|
@@ -28896,6 +28940,7 @@ function getLineChartDatasets(definition, args) {
|
|
|
28896
28940
|
const dataset = {
|
|
28897
28941
|
label,
|
|
28898
28942
|
data,
|
|
28943
|
+
hidden,
|
|
28899
28944
|
tension: 0, // 0 -> render straight lines, which is much faster
|
|
28900
28945
|
borderColor: color,
|
|
28901
28946
|
backgroundColor: areaChart ? setColorAlpha(color, LINE_FILL_TRANSPARENCY) : color,
|
|
@@ -28928,11 +28973,13 @@ function getPieChartDatasets(definition, args) {
|
|
|
28928
28973
|
const dataSets = [];
|
|
28929
28974
|
const dataSetsLength = Math.max(0, ...dataSetsValues.map((ds) => ds?.data?.length ?? 0));
|
|
28930
28975
|
const backgroundColor = getPieColors(new ColorGenerator(dataSetsLength), dataSetsValues);
|
|
28931
|
-
for (const { label, data } of dataSetsValues) {
|
|
28976
|
+
for (const { label, data, hidden } of dataSetsValues) {
|
|
28977
|
+
if (hidden)
|
|
28978
|
+
continue;
|
|
28932
28979
|
const dataset = {
|
|
28933
28980
|
label,
|
|
28934
28981
|
data,
|
|
28935
|
-
borderColor:
|
|
28982
|
+
borderColor: definition.background || "#FFFFFF",
|
|
28936
28983
|
backgroundColor,
|
|
28937
28984
|
hoverOffset: 30,
|
|
28938
28985
|
};
|
|
@@ -28946,7 +28993,7 @@ function getComboChartDatasets(definition, args) {
|
|
|
28946
28993
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28947
28994
|
const trendDatasets = [];
|
|
28948
28995
|
for (let index = 0; index < dataSetsValues.length; index++) {
|
|
28949
|
-
let { label, data } = dataSetsValues[index];
|
|
28996
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28950
28997
|
label = definition.dataSets?.[index].label || label;
|
|
28951
28998
|
const design = definition.dataSets?.[index];
|
|
28952
28999
|
const color = colors.next();
|
|
@@ -28954,6 +29001,7 @@ function getComboChartDatasets(definition, args) {
|
|
|
28954
29001
|
const dataset = {
|
|
28955
29002
|
label: label,
|
|
28956
29003
|
data,
|
|
29004
|
+
hidden,
|
|
28957
29005
|
borderColor: color,
|
|
28958
29006
|
backgroundColor: color,
|
|
28959
29007
|
yAxisID: definition.dataSets?.[index].yAxisId || "y",
|
|
@@ -28978,7 +29026,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
28978
29026
|
const fill = definition.fillArea ?? false;
|
|
28979
29027
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28980
29028
|
for (let i = 0; i < dataSetsValues.length; i++) {
|
|
28981
|
-
let { label, data } = dataSetsValues[i];
|
|
29029
|
+
let { label, data, hidden } = dataSetsValues[i];
|
|
28982
29030
|
if (definition.dataSets?.[i]?.label) {
|
|
28983
29031
|
label = definition.dataSets[i].label;
|
|
28984
29032
|
}
|
|
@@ -28986,6 +29034,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
28986
29034
|
const dataset = {
|
|
28987
29035
|
label,
|
|
28988
29036
|
data,
|
|
29037
|
+
hidden,
|
|
28989
29038
|
borderColor,
|
|
28990
29039
|
backgroundColor: borderColor,
|
|
28991
29040
|
};
|
|
@@ -29131,6 +29180,11 @@ function getPieChartLegend(definition, args) {
|
|
|
29131
29180
|
hidden: false,
|
|
29132
29181
|
lineWidth: 2,
|
|
29133
29182
|
})),
|
|
29183
|
+
filter: (legendItem, data) => {
|
|
29184
|
+
return "datasetIndex" in legendItem
|
|
29185
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29186
|
+
: true;
|
|
29187
|
+
},
|
|
29134
29188
|
},
|
|
29135
29189
|
};
|
|
29136
29190
|
}
|
|
@@ -29192,6 +29246,11 @@ function getWaterfallChartLegend(definition, args) {
|
|
|
29192
29246
|
}
|
|
29193
29247
|
return legendValues;
|
|
29194
29248
|
},
|
|
29249
|
+
filter: (legendItem, data) => {
|
|
29250
|
+
return "datasetIndex" in legendItem
|
|
29251
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29252
|
+
: true;
|
|
29253
|
+
},
|
|
29195
29254
|
},
|
|
29196
29255
|
onClick: () => { }, // Disables click interaction with the waterfall chart legend items
|
|
29197
29256
|
};
|
|
@@ -29275,6 +29334,11 @@ function getCustomLegendLabels(fontColor, legendLabelConfig) {
|
|
|
29275
29334
|
...legendLabelConfig,
|
|
29276
29335
|
};
|
|
29277
29336
|
}),
|
|
29337
|
+
filter: (legendItem, data) => {
|
|
29338
|
+
return "datasetIndex" in legendItem
|
|
29339
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29340
|
+
: true;
|
|
29341
|
+
},
|
|
29278
29342
|
},
|
|
29279
29343
|
};
|
|
29280
29344
|
}
|
|
@@ -29608,7 +29672,7 @@ const templates = /* xml */ `
|
|
|
29608
29672
|
<div
|
|
29609
29673
|
class="o-chart-custom-tooltip border rounded px-2 py-1 pe-none mw-100 position-absolute text-nowrap shadow opacity-100">
|
|
29610
29674
|
<table class="overflow-hidden m-0">
|
|
29611
|
-
<thead>
|
|
29675
|
+
<thead t-if="title">
|
|
29612
29676
|
<tr>
|
|
29613
29677
|
<th class="o-tooltip-title align-baseline border-0 text-truncate" t-esc="title" t-attf-style="max-width: {{ labelsMaxWidth }}"/>
|
|
29614
29678
|
</tr>
|
|
@@ -29669,8 +29733,8 @@ function getBarChartTooltip(definition, args) {
|
|
|
29669
29733
|
? undefined
|
|
29670
29734
|
: "";
|
|
29671
29735
|
},
|
|
29736
|
+
beforeLabel: (tooltipItem) => tooltipItem.dataset?.label || tooltipItem.label,
|
|
29672
29737
|
label: function (tooltipItem) {
|
|
29673
|
-
const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
|
|
29674
29738
|
const horizontalChart = definition.horizontal;
|
|
29675
29739
|
let yLabel = horizontalChart ? tooltipItem.parsed.x : tooltipItem.parsed.y;
|
|
29676
29740
|
if (yLabel === undefined || yLabel === null) {
|
|
@@ -29678,7 +29742,7 @@ function getBarChartTooltip(definition, args) {
|
|
|
29678
29742
|
}
|
|
29679
29743
|
const axisId = horizontalChart ? tooltipItem.dataset.xAxisID : tooltipItem.dataset.yAxisID;
|
|
29680
29744
|
const yLabelStr = formatChartDatasetValue(args.axisFormats, args.locale)(yLabel, axisId);
|
|
29681
|
-
return
|
|
29745
|
+
return yLabelStr;
|
|
29682
29746
|
},
|
|
29683
29747
|
},
|
|
29684
29748
|
};
|
|
@@ -29703,21 +29767,18 @@ function getLineChartTooltip(definition, args) {
|
|
|
29703
29767
|
const formattedX = formatValue(label, { locale, format: labelFormat });
|
|
29704
29768
|
const axisId = tooltipItem.dataset.yAxisID || "y";
|
|
29705
29769
|
const formattedY = formatValue(dataSetPoint, { locale, format: axisFormats?.[axisId] });
|
|
29706
|
-
|
|
29707
|
-
return formattedX
|
|
29708
|
-
? `${dataSetTitle}: (${formattedX}, ${formattedY})`
|
|
29709
|
-
: `${dataSetTitle}: ${formattedY}`;
|
|
29770
|
+
return formattedX ? `(${formattedX}, ${formattedY})` : `${formattedY}`;
|
|
29710
29771
|
};
|
|
29711
29772
|
}
|
|
29712
29773
|
else {
|
|
29713
29774
|
tooltip.callbacks.label = function (tooltipItem) {
|
|
29714
|
-
const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
|
|
29715
29775
|
const yLabel = tooltipItem.parsed.y;
|
|
29716
29776
|
const axisId = tooltipItem.dataset.yAxisID;
|
|
29717
29777
|
const yLabelStr = formatChartDatasetValue(axisFormats, locale)(yLabel, axisId);
|
|
29718
|
-
return
|
|
29778
|
+
return yLabelStr;
|
|
29719
29779
|
};
|
|
29720
29780
|
}
|
|
29781
|
+
tooltip.callbacks.beforeLabel = (tooltipItem) => tooltipItem.dataset?.label || tooltipItem.label;
|
|
29721
29782
|
tooltip.callbacks.title = function (tooltipItems) {
|
|
29722
29783
|
const displayTooltipTitle = axisType !== "linear" &&
|
|
29723
29784
|
tooltipItems.some((item) => item.dataset.xAxisID !== TREND_LINE_XAXIS_ID);
|
|
@@ -29735,17 +29796,15 @@ function getPieChartTooltip(definition, args) {
|
|
|
29735
29796
|
title: function (tooltipItems) {
|
|
29736
29797
|
return tooltipItems[0].dataset.label;
|
|
29737
29798
|
},
|
|
29799
|
+
beforeLabel: (tooltipItem) => tooltipItem.label || tooltipItem.dataset.label,
|
|
29738
29800
|
label: function (tooltipItem) {
|
|
29739
29801
|
const data = tooltipItem.dataset.data;
|
|
29740
29802
|
const dataIndex = tooltipItem.dataIndex;
|
|
29741
29803
|
const percentage = calculatePercentage(data, dataIndex);
|
|
29742
|
-
const xLabel = tooltipItem.label || tooltipItem.dataset.label;
|
|
29743
29804
|
const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
|
|
29744
29805
|
const toolTipFormat = !format && yLabel >= 1000 ? "#,##" : format;
|
|
29745
29806
|
const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
|
|
29746
|
-
return
|
|
29747
|
-
? `${xLabel}: ${yLabelStr} (${percentage}%)`
|
|
29748
|
-
: `${yLabelStr} (${percentage}%)`;
|
|
29807
|
+
return `${yLabelStr} (${percentage}%)`;
|
|
29749
29808
|
},
|
|
29750
29809
|
},
|
|
29751
29810
|
};
|
|
@@ -29758,16 +29817,17 @@ function getWaterfallChartTooltip(definition, args) {
|
|
|
29758
29817
|
enabled: false,
|
|
29759
29818
|
external: customTooltipHandler,
|
|
29760
29819
|
callbacks: {
|
|
29761
|
-
|
|
29762
|
-
const [lastValue, currentValue] = tooltipItem.raw;
|
|
29763
|
-
const yLabel = currentValue - lastValue;
|
|
29820
|
+
beforeLabel: function (tooltipItem) {
|
|
29764
29821
|
const dataSeriesIndex = labels.length
|
|
29765
29822
|
? Math.floor(tooltipItem.dataIndex / labels.length)
|
|
29766
29823
|
: 0;
|
|
29767
|
-
|
|
29824
|
+
return dataSeriesLabels[dataSeriesIndex];
|
|
29825
|
+
},
|
|
29826
|
+
label: function (tooltipItem) {
|
|
29827
|
+
const [lastValue, currentValue] = tooltipItem.raw;
|
|
29828
|
+
const yLabel = currentValue - lastValue;
|
|
29768
29829
|
const toolTipFormat = !format && Math.abs(yLabel) > 1000 ? "#,##" : format;
|
|
29769
|
-
|
|
29770
|
-
return dataSeriesLabel ? `${dataSeriesLabel}: ${yLabelStr}` : yLabelStr;
|
|
29830
|
+
return formatValue(yLabel, { format: toolTipFormat, locale });
|
|
29771
29831
|
},
|
|
29772
29832
|
},
|
|
29773
29833
|
};
|
|
@@ -29791,11 +29851,10 @@ function getRadarChartTooltip(definition, args) {
|
|
|
29791
29851
|
enabled: false,
|
|
29792
29852
|
external: customTooltipHandler,
|
|
29793
29853
|
callbacks: {
|
|
29854
|
+
beforeLabel: (tooltipItem) => tooltipItem.dataset?.label || tooltipItem.label,
|
|
29794
29855
|
label: function (tooltipItem) {
|
|
29795
|
-
const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
|
|
29796
29856
|
const yLabel = tooltipItem.parsed.r;
|
|
29797
|
-
|
|
29798
|
-
return xLabel ? `${xLabel}: ${formattedY}` : formattedY;
|
|
29857
|
+
return formatValue(yLabel, { format: axisFormats?.r, locale });
|
|
29799
29858
|
},
|
|
29800
29859
|
},
|
|
29801
29860
|
};
|
|
@@ -29810,13 +29869,12 @@ function getGeoChartTooltip(definition, args) {
|
|
|
29810
29869
|
return tooltipItem.raw.value !== undefined;
|
|
29811
29870
|
},
|
|
29812
29871
|
callbacks: {
|
|
29872
|
+
beforeLabel: (tooltipItem) => tooltipItem.raw.feature.properties.name,
|
|
29813
29873
|
label: function (tooltipItem) {
|
|
29814
29874
|
const rawItem = tooltipItem.raw;
|
|
29815
|
-
const xLabel = rawItem.feature.properties.name;
|
|
29816
29875
|
const yLabel = rawItem.value;
|
|
29817
29876
|
const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
|
|
29818
|
-
|
|
29819
|
-
return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
|
|
29877
|
+
return formatValue(yLabel, { format: toolTipFormat, locale });
|
|
29820
29878
|
},
|
|
29821
29879
|
},
|
|
29822
29880
|
};
|
|
@@ -29836,7 +29894,8 @@ function customTooltipHandler({ chart, tooltip }) {
|
|
|
29836
29894
|
return;
|
|
29837
29895
|
}
|
|
29838
29896
|
const tooltipItems = tooltip.body.map((body, index) => {
|
|
29839
|
-
let
|
|
29897
|
+
let label = body.before[0];
|
|
29898
|
+
let value = body.lines[0];
|
|
29840
29899
|
if (!value) {
|
|
29841
29900
|
value = label;
|
|
29842
29901
|
label = "";
|
|
@@ -38920,7 +38979,7 @@ css /* scss */ `
|
|
|
38920
38979
|
.o-font-size-editor {
|
|
38921
38980
|
height: calc(100% - 4px);
|
|
38922
38981
|
input.o-font-size {
|
|
38923
|
-
outline
|
|
38982
|
+
outline: none;
|
|
38924
38983
|
height: 20px;
|
|
38925
38984
|
width: 23px;
|
|
38926
38985
|
}
|
|
@@ -51628,8 +51687,8 @@ class Border extends owl.Component {
|
|
|
51628
51687
|
css /* scss */ `
|
|
51629
51688
|
.o-corner {
|
|
51630
51689
|
position: absolute;
|
|
51631
|
-
height:
|
|
51632
|
-
width:
|
|
51690
|
+
height: 8px;
|
|
51691
|
+
width: 8px;
|
|
51633
51692
|
border: 1px solid white;
|
|
51634
51693
|
}
|
|
51635
51694
|
.o-corner-nw,
|
|
@@ -53466,6 +53525,10 @@ class CellPlugin extends CorePlugin {
|
|
|
53466
53525
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
53467
53526
|
case "CLEAR_CELL":
|
|
53468
53527
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
53528
|
+
case "UPDATE_CELL_POSITION":
|
|
53529
|
+
return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
|
|
53530
|
+
? "Success" /* CommandResult.Success */
|
|
53531
|
+
: "InvalidCellId" /* CommandResult.InvalidCellId */;
|
|
53469
53532
|
default:
|
|
53470
53533
|
return "Success" /* CommandResult.Success */;
|
|
53471
53534
|
}
|
|
@@ -53510,6 +53573,9 @@ class CellPlugin extends CorePlugin {
|
|
|
53510
53573
|
case "DELETE_CONTENT":
|
|
53511
53574
|
this.clearZones(cmd.sheetId, cmd.target);
|
|
53512
53575
|
break;
|
|
53576
|
+
case "DELETE_SHEET": {
|
|
53577
|
+
this.history.update("cells", cmd.sheetId, undefined);
|
|
53578
|
+
}
|
|
53513
53579
|
}
|
|
53514
53580
|
}
|
|
53515
53581
|
clearZones(sheetId, zones) {
|
|
@@ -54300,6 +54366,9 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
54300
54366
|
allowDispatch(cmd) {
|
|
54301
54367
|
switch (cmd.type) {
|
|
54302
54368
|
case "ADD_CONDITIONAL_FORMAT":
|
|
54369
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
54370
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54371
|
+
}
|
|
54303
54372
|
return this.checkValidations(cmd, this.checkCFRule, this.checkEmptyRange, this.checkCFHasChanged);
|
|
54304
54373
|
case "CHANGE_CONDITIONAL_FORMAT_PRIORITY":
|
|
54305
54374
|
return this.checkValidPriorityChange(cmd.cfId, cmd.delta, cmd.sheetId);
|
|
@@ -54716,8 +54785,17 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
54716
54785
|
allowDispatch(cmd) {
|
|
54717
54786
|
switch (cmd.type) {
|
|
54718
54787
|
case "ADD_DATA_VALIDATION_RULE":
|
|
54788
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
54789
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54790
|
+
}
|
|
54791
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
54792
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54793
|
+
}
|
|
54719
54794
|
return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkValidRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
|
|
54720
54795
|
case "REMOVE_DATA_VALIDATION_RULE":
|
|
54796
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
54797
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54798
|
+
}
|
|
54721
54799
|
if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
|
|
54722
54800
|
return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
|
|
54723
54801
|
}
|
|
@@ -54944,6 +55022,7 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
54944
55022
|
class FigurePlugin extends CorePlugin {
|
|
54945
55023
|
static getters = ["getFigures", "getFigure", "getFigureSheetId"];
|
|
54946
55024
|
figures = {};
|
|
55025
|
+
insertionOrders = []; // TODO use a list in master
|
|
54947
55026
|
// ---------------------------------------------------------------------------
|
|
54948
55027
|
// Command Handling
|
|
54949
55028
|
// ---------------------------------------------------------------------------
|
|
@@ -55046,11 +55125,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
55046
55125
|
}
|
|
55047
55126
|
addFigure(figure, sheetId) {
|
|
55048
55127
|
this.history.update("figures", sheetId, figure.id, figure);
|
|
55128
|
+
this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
|
|
55049
55129
|
}
|
|
55050
55130
|
deleteSheet(sheetId) {
|
|
55131
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
|
|
55051
55132
|
this.history.update("figures", sheetId, undefined);
|
|
55052
55133
|
}
|
|
55053
55134
|
removeFigure(id, sheetId) {
|
|
55135
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
|
|
55054
55136
|
this.history.update("figures", sheetId, id, undefined);
|
|
55055
55137
|
}
|
|
55056
55138
|
checkFigureExists(sheetId, figureId) {
|
|
@@ -55069,7 +55151,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
55069
55151
|
// Getters
|
|
55070
55152
|
// ---------------------------------------------------------------------------
|
|
55071
55153
|
getFigures(sheetId) {
|
|
55072
|
-
|
|
55154
|
+
const figures = [];
|
|
55155
|
+
for (const figureId of this.insertionOrders) {
|
|
55156
|
+
const figure = this.figures[sheetId]?.[figureId];
|
|
55157
|
+
if (figure) {
|
|
55158
|
+
figures.push(figure);
|
|
55159
|
+
}
|
|
55160
|
+
}
|
|
55161
|
+
return figures;
|
|
55073
55162
|
}
|
|
55074
55163
|
getFigure(sheetId, figureId) {
|
|
55075
55164
|
return this.figures[sheetId]?.[figureId];
|
|
@@ -55082,11 +55171,9 @@ class FigurePlugin extends CorePlugin {
|
|
|
55082
55171
|
// ---------------------------------------------------------------------------
|
|
55083
55172
|
import(data) {
|
|
55084
55173
|
for (let sheet of data.sheets) {
|
|
55085
|
-
const figures
|
|
55086
|
-
|
|
55087
|
-
|
|
55088
|
-
});
|
|
55089
|
-
this.figures[sheet.id] = figures;
|
|
55174
|
+
for (const figure of sheet.figures) {
|
|
55175
|
+
this.addFigure(figure, sheet.id);
|
|
55176
|
+
}
|
|
55090
55177
|
}
|
|
55091
55178
|
}
|
|
55092
55179
|
export(data) {
|
|
@@ -56546,6 +56633,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
56546
56633
|
case "CREATE_SHEET": {
|
|
56547
56634
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
56548
56635
|
}
|
|
56636
|
+
case "DUPLICATE_SHEET": {
|
|
56637
|
+
return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
|
|
56638
|
+
}
|
|
56549
56639
|
case "MOVE_SHEET":
|
|
56550
56640
|
try {
|
|
56551
56641
|
const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
|
|
@@ -57348,14 +57438,18 @@ class SheetPlugin extends CorePlugin {
|
|
|
57348
57438
|
checkZonesAreInSheet(cmd) {
|
|
57349
57439
|
if (!("sheetId" in cmd))
|
|
57350
57440
|
return "Success" /* CommandResult.Success */;
|
|
57441
|
+
if ("ranges" in cmd &&
|
|
57442
|
+
cmd.ranges.some((rangeData) => rangeData._sheetId !== "" && !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
57443
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57444
|
+
}
|
|
57351
57445
|
return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
|
|
57352
57446
|
}
|
|
57353
57447
|
}
|
|
57354
57448
|
|
|
57355
|
-
let nextTableId = 1;
|
|
57356
57449
|
class TablePlugin extends CorePlugin {
|
|
57357
57450
|
static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
|
|
57358
57451
|
tables = {};
|
|
57452
|
+
nextTableId = 1;
|
|
57359
57453
|
adaptRanges(applyChange, sheetId) {
|
|
57360
57454
|
const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
|
|
57361
57455
|
for (const sheetId of sheetIds) {
|
|
@@ -57367,6 +57461,9 @@ class TablePlugin extends CorePlugin {
|
|
|
57367
57461
|
allowDispatch(cmd) {
|
|
57368
57462
|
switch (cmd.type) {
|
|
57369
57463
|
case "CREATE_TABLE":
|
|
57464
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
|
|
57465
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57466
|
+
}
|
|
57370
57467
|
const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
|
|
57371
57468
|
if (!areZonesContinuous(zones)) {
|
|
57372
57469
|
return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
|
|
@@ -57420,7 +57517,7 @@ class TablePlugin extends CorePlugin {
|
|
|
57420
57517
|
const union = this.getters.getRangesUnion(ranges);
|
|
57421
57518
|
const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
|
|
57422
57519
|
this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
|
|
57423
|
-
const id =
|
|
57520
|
+
const id = this.consumeNextId();
|
|
57424
57521
|
const config = cmd.config || DEFAULT_TABLE_CONFIG;
|
|
57425
57522
|
const newTable = cmd.tableType === "dynamic"
|
|
57426
57523
|
? this.createDynamicTable(id, union, config)
|
|
@@ -57573,7 +57670,7 @@ class TablePlugin extends CorePlugin {
|
|
|
57573
57670
|
filters = [];
|
|
57574
57671
|
for (const i of range(zone.left, zone.right + 1)) {
|
|
57575
57672
|
const filterZone = { ...zone, left: i, right: i };
|
|
57576
|
-
const uid =
|
|
57673
|
+
const uid = this.consumeNextId();
|
|
57577
57674
|
filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
|
|
57578
57675
|
}
|
|
57579
57676
|
}
|
|
@@ -57638,7 +57735,7 @@ class TablePlugin extends CorePlugin {
|
|
|
57638
57735
|
? table.filters.find((f) => f.col === i)
|
|
57639
57736
|
: undefined;
|
|
57640
57737
|
const filterZone = { ...tableZone, left: i, right: i };
|
|
57641
|
-
const filterId = oldFilter?.id ||
|
|
57738
|
+
const filterId = oldFilter?.id || this.consumeNextId();
|
|
57642
57739
|
filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
|
|
57643
57740
|
}
|
|
57644
57741
|
}
|
|
@@ -57739,7 +57836,7 @@ class TablePlugin extends CorePlugin {
|
|
|
57739
57836
|
if (filters.length < zoneToDimension(tableZone).numberOfCols) {
|
|
57740
57837
|
for (let col = tableZone.left; col <= tableZone.right; col++) {
|
|
57741
57838
|
if (!filters.find((filter) => filter.col === col)) {
|
|
57742
|
-
const uid =
|
|
57839
|
+
const uid = this.consumeNextId();
|
|
57743
57840
|
const filterZone = { ...tableZone, left: col, right: col };
|
|
57744
57841
|
filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
|
|
57745
57842
|
}
|
|
@@ -57749,13 +57846,18 @@ class TablePlugin extends CorePlugin {
|
|
|
57749
57846
|
const newTable = this.createStaticTable(table.id, table.type, newTableRange, table.config, filters);
|
|
57750
57847
|
this.history.update("tables", sheetId, table.id, newTable);
|
|
57751
57848
|
}
|
|
57849
|
+
consumeNextId() {
|
|
57850
|
+
const id = `${this.nextTableId}`;
|
|
57851
|
+
this.history.update("nextTableId", this.nextTableId + 1);
|
|
57852
|
+
return id;
|
|
57853
|
+
}
|
|
57752
57854
|
// ---------------------------------------------------------------------------
|
|
57753
57855
|
// Import/Export
|
|
57754
57856
|
// ---------------------------------------------------------------------------
|
|
57755
57857
|
import(data) {
|
|
57756
57858
|
for (const sheet of data.sheets) {
|
|
57757
57859
|
for (const tableData of sheet.tables || []) {
|
|
57758
|
-
const uuid =
|
|
57860
|
+
const uuid = this.consumeNextId();
|
|
57759
57861
|
const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
|
|
57760
57862
|
const range = this.getters.getRangeFromSheetXC(sheet.id, tableData.range);
|
|
57761
57863
|
const tableType = tableData.type || "static";
|
|
@@ -57803,7 +57905,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57803
57905
|
allowDispatch(cmd) {
|
|
57804
57906
|
switch (cmd.type) {
|
|
57805
57907
|
case "GROUP_HEADERS": {
|
|
57806
|
-
const { start, end } = cmd;
|
|
57908
|
+
const { start, end, sheetId } = cmd;
|
|
57909
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
57910
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57911
|
+
}
|
|
57807
57912
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
57808
57913
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
57809
57914
|
}
|
|
@@ -57816,7 +57921,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57816
57921
|
break;
|
|
57817
57922
|
}
|
|
57818
57923
|
case "UNGROUP_HEADERS": {
|
|
57819
|
-
const { start, end } = cmd;
|
|
57924
|
+
const { start, end, sheetId } = cmd;
|
|
57925
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
57926
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57927
|
+
}
|
|
57820
57928
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
57821
57929
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
57822
57930
|
}
|
|
@@ -57827,6 +57935,9 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57827
57935
|
}
|
|
57828
57936
|
case "UNFOLD_HEADER_GROUP":
|
|
57829
57937
|
case "FOLD_HEADER_GROUP":
|
|
57938
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
57939
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57940
|
+
}
|
|
57830
57941
|
const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
|
|
57831
57942
|
if (!group) {
|
|
57832
57943
|
return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
|
|
@@ -58227,6 +58338,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
58227
58338
|
return this.checkDuplicatedMeasureIds(cmd.pivot);
|
|
58228
58339
|
}
|
|
58229
58340
|
case "UPDATE_PIVOT": {
|
|
58341
|
+
if (!(cmd.pivotId in this.pivots)) {
|
|
58342
|
+
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
58343
|
+
}
|
|
58230
58344
|
if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
|
|
58231
58345
|
return "NoChanges" /* CommandResult.NoChanges */;
|
|
58232
58346
|
}
|
|
@@ -58243,6 +58357,8 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
58243
58357
|
return "EmptyName" /* CommandResult.EmptyName */;
|
|
58244
58358
|
}
|
|
58245
58359
|
break;
|
|
58360
|
+
case "REMOVE_PIVOT":
|
|
58361
|
+
case "DUPLICATE_PIVOT":
|
|
58246
58362
|
case "INSERT_PIVOT": {
|
|
58247
58363
|
if (!(cmd.pivotId in this.pivots)) {
|
|
58248
58364
|
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
@@ -58292,7 +58408,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
58292
58408
|
break;
|
|
58293
58409
|
}
|
|
58294
58410
|
case "UPDATE_PIVOT": {
|
|
58295
|
-
this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
|
|
58411
|
+
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
58296
58412
|
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
58297
58413
|
break;
|
|
58298
58414
|
}
|
|
@@ -58363,7 +58479,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
58363
58479
|
// Private
|
|
58364
58480
|
// -------------------------------------------------------------------------
|
|
58365
58481
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
58366
|
-
this.history.update("pivots", pivotId, { definition: pivot, formulaId });
|
|
58482
|
+
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
58367
58483
|
this.compileCalculatedMeasures(pivot.measures);
|
|
58368
58484
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
58369
58485
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
@@ -59933,6 +60049,10 @@ class Evaluator {
|
|
|
59933
60049
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
59934
60050
|
this.compilationParams.evalContext.updateDependencies = this.updateDependencies.bind(this);
|
|
59935
60051
|
this.compilationParams.evalContext.addDependencies = this.addDependencies.bind(this);
|
|
60052
|
+
this.compilationParams.evalContext.lookupCaches = {
|
|
60053
|
+
forwardSearch: new Map(),
|
|
60054
|
+
reverseSearch: new Map(),
|
|
60055
|
+
};
|
|
59936
60056
|
}
|
|
59937
60057
|
createEmptyPositionSet() {
|
|
59938
60058
|
const sheetSizes = {};
|
|
@@ -63281,6 +63401,9 @@ function updateChartRangesTransformation(toTransform, executed) {
|
|
|
63281
63401
|
};
|
|
63282
63402
|
}
|
|
63283
63403
|
function createSheetTransformation(toTransform, executed) {
|
|
63404
|
+
if (toTransform.sheetId === executed.sheetId) {
|
|
63405
|
+
toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
|
|
63406
|
+
}
|
|
63284
63407
|
if (toTransform.name === executed.name) {
|
|
63285
63408
|
return {
|
|
63286
63409
|
...toTransform,
|
|
@@ -63924,15 +64047,6 @@ class Session extends EventBus {
|
|
|
63924
64047
|
}
|
|
63925
64048
|
this.sendPendingMessage();
|
|
63926
64049
|
}
|
|
63927
|
-
dropPendingRevision(revisionId) {
|
|
63928
|
-
this.revisions.drop(revisionId);
|
|
63929
|
-
const revisionIds = this.pendingMessages
|
|
63930
|
-
.filter((message) => message.type === "REMOTE_REVISION")
|
|
63931
|
-
.map((message) => message.nextRevisionId);
|
|
63932
|
-
this.trigger("pending-revisions-dropped", { revisionIds });
|
|
63933
|
-
this.waitingAck = false;
|
|
63934
|
-
this.waitingUndoRedoAck = false;
|
|
63935
|
-
}
|
|
63936
64050
|
/**
|
|
63937
64051
|
* Send the next pending message
|
|
63938
64052
|
*/
|
|
@@ -63941,15 +64055,14 @@ class Session extends EventBus {
|
|
|
63941
64055
|
if (!message)
|
|
63942
64056
|
return;
|
|
63943
64057
|
if (message.type === "REMOTE_REVISION") {
|
|
63944
|
-
|
|
64058
|
+
let revision = this.revisions.get(message.nextRevisionId);
|
|
63945
64059
|
if (revision.commands.length === 0) {
|
|
63946
64060
|
/**
|
|
63947
|
-
* The command is empty, we have to
|
|
64061
|
+
* The command is empty, we have to rebase all the next local revisions
|
|
63948
64062
|
* to avoid issues with undo/redo
|
|
63949
64063
|
*/
|
|
63950
|
-
this.
|
|
63951
|
-
|
|
63952
|
-
return;
|
|
64064
|
+
this.revisions.rebase(revision.id);
|
|
64065
|
+
revision = this.revisions.get(message.nextRevisionId);
|
|
63953
64066
|
}
|
|
63954
64067
|
message = {
|
|
63955
64068
|
...message,
|
|
@@ -63985,18 +64098,16 @@ class Session extends EventBus {
|
|
|
63985
64098
|
case "REVISION_UNDONE": {
|
|
63986
64099
|
this.waitingAck = false;
|
|
63987
64100
|
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
63988
|
-
const
|
|
63989
|
-
|
|
63990
|
-
if (firstTransformedRevisionIndex !== -1) {
|
|
64101
|
+
const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
|
|
64102
|
+
if (firstPendingRevisionId !== -1) {
|
|
63991
64103
|
/**
|
|
63992
64104
|
* Some revisions undergo transformations that may cause issues with
|
|
63993
64105
|
* undo/redo if the transformation is destructive (we don't get back
|
|
63994
64106
|
* the original command by transforming it with the inverse).
|
|
63995
|
-
* To prevent these problems, we must
|
|
64107
|
+
* To prevent these problems, we must rebase all subsequent local
|
|
63996
64108
|
* revisions.
|
|
63997
64109
|
*/
|
|
63998
|
-
this.
|
|
63999
|
-
this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
|
|
64110
|
+
this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
|
|
64000
64111
|
}
|
|
64001
64112
|
this.serverRevisionId = message.nextRevisionId;
|
|
64002
64113
|
this.processedRevisions.add(message.nextRevisionId);
|
|
@@ -65118,6 +65229,10 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
65118
65229
|
*/
|
|
65119
65230
|
checkZonesAreInSheet(cmd) {
|
|
65120
65231
|
const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
|
|
65232
|
+
if ("ranges" in cmd &&
|
|
65233
|
+
cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
65234
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
65235
|
+
}
|
|
65121
65236
|
const zones = this.getters.getCommandZones(cmd);
|
|
65122
65237
|
if (!sheetId && zones.length > 0) {
|
|
65123
65238
|
return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
|
|
@@ -65672,7 +65787,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
65672
65787
|
super(config);
|
|
65673
65788
|
this.session = config.session;
|
|
65674
65789
|
this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
|
|
65675
|
-
this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
|
|
65676
65790
|
this.session.on("snapshot", this, () => {
|
|
65677
65791
|
this.undoStack = [];
|
|
65678
65792
|
this.redoStack = [];
|
|
@@ -65742,10 +65856,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
65742
65856
|
const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
|
|
65743
65857
|
return canRepeatRevision(lastNonRedoRevision);
|
|
65744
65858
|
}
|
|
65745
|
-
drop(revisionIds) {
|
|
65746
|
-
this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
|
|
65747
|
-
this.redoStack = [];
|
|
65748
|
-
}
|
|
65749
65859
|
onNewLocalStateUpdate({ id }) {
|
|
65750
65860
|
this.undoStack.push(id);
|
|
65751
65861
|
this.redoStack = [];
|
|
@@ -68420,7 +68530,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
68420
68530
|
case "UNGROUP_HEADERS":
|
|
68421
68531
|
case "GROUP_HEADERS":
|
|
68422
68532
|
case "CREATE_SHEET":
|
|
68423
|
-
this.
|
|
68533
|
+
if (this.getters.tryGetSheet(cmd.sheetId)) {
|
|
68534
|
+
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
68535
|
+
}
|
|
68424
68536
|
break;
|
|
68425
68537
|
case "DUPLICATE_SHEET":
|
|
68426
68538
|
this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
|
|
@@ -68428,12 +68540,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
68428
68540
|
}
|
|
68429
68541
|
}
|
|
68430
68542
|
finalize() {
|
|
68431
|
-
|
|
68432
|
-
|
|
68543
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
68544
|
+
// sheets can be created without this plugin being aware of it
|
|
68545
|
+
// in concurrent situations.
|
|
68546
|
+
if (this.isDirty || !this.headerPositions[sheetId]) {
|
|
68433
68547
|
this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
|
|
68434
68548
|
}
|
|
68435
|
-
this.isDirty = false;
|
|
68436
68549
|
}
|
|
68550
|
+
this.isDirty = false;
|
|
68437
68551
|
}
|
|
68438
68552
|
/**
|
|
68439
68553
|
* Returns the size, start and end coordinates of a column on an unfolded sheet
|
|
@@ -70274,6 +70388,10 @@ const FX_SVG = /*xml*/ `
|
|
|
70274
70388
|
</svg>
|
|
70275
70389
|
`;
|
|
70276
70390
|
css /* scss */ `
|
|
70391
|
+
.o-topbar-composer-container {
|
|
70392
|
+
height: ${TOPBAR_TOOLBAR_HEIGHT}px;
|
|
70393
|
+
}
|
|
70394
|
+
|
|
70277
70395
|
.o-topbar-composer {
|
|
70278
70396
|
height: fit-content;
|
|
70279
70397
|
margin-top: -1px;
|
|
@@ -71837,9 +71955,16 @@ class SelectiveHistory {
|
|
|
71837
71955
|
this.fastForward();
|
|
71838
71956
|
this.insert(redoId, this.buildEmpty(redoId), insertAfter);
|
|
71839
71957
|
}
|
|
71840
|
-
|
|
71958
|
+
rebase(operationId) {
|
|
71959
|
+
const operation = this.get(operationId);
|
|
71960
|
+
const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
|
|
71841
71961
|
this.revertBefore(operationId);
|
|
71962
|
+
const baseId = this.HEAD_OPERATION.id;
|
|
71842
71963
|
this.tree.drop(operationId);
|
|
71964
|
+
this.insert(operationId, operation, baseId);
|
|
71965
|
+
for (const { operation } of execution) {
|
|
71966
|
+
this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
|
|
71967
|
+
}
|
|
71843
71968
|
}
|
|
71844
71969
|
/**
|
|
71845
71970
|
* Revert the state as it was *before* the given operation was executed.
|
|
@@ -74967,6 +75092,11 @@ class Model extends EventBus {
|
|
|
74967
75092
|
dispatch: (command) => {
|
|
74968
75093
|
const result = this.checkDispatchAllowed(command);
|
|
74969
75094
|
if (!result.isSuccessful) {
|
|
75095
|
+
// core views plugins need to be invalidated
|
|
75096
|
+
this.dispatchToHandlers(this.coreHandlers, {
|
|
75097
|
+
type: "UNDO",
|
|
75098
|
+
commands: [command],
|
|
75099
|
+
});
|
|
74970
75100
|
return;
|
|
74971
75101
|
}
|
|
74972
75102
|
this.isReplayingCommand = true;
|
|
@@ -75533,6 +75663,6 @@ exports.tokenColors = tokenColors;
|
|
|
75533
75663
|
exports.tokenize = tokenize;
|
|
75534
75664
|
|
|
75535
75665
|
|
|
75536
|
-
__info__.version = "18.2.
|
|
75537
|
-
__info__.date = "2025-02-
|
|
75538
|
-
__info__.hash = "
|
|
75666
|
+
__info__.version = "18.2.1";
|
|
75667
|
+
__info__.date = "2025-02-25T06:03:13.262Z";
|
|
75668
|
+
__info__.hash = "3b4b5c9";
|