@odoo/o-spreadsheet 18.1.7 → 18.1.9
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 +499 -284
- package/dist/o-spreadsheet.d.ts +51 -46
- package/dist/o-spreadsheet.esm.js +499 -284
- package/dist/o-spreadsheet.iife.js +499 -284
- package/dist/o-spreadsheet.iife.min.js +358 -354
- 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.1.
|
|
6
|
-
* @date 2025-02-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.9
|
|
6
|
+
* @date 2025-02-25T05:59:45.472Z
|
|
7
|
+
* @hash 6789c1c
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -2219,17 +2219,7 @@
|
|
|
2219
2219
|
*/
|
|
2220
2220
|
function toUnboundedZone(xc) {
|
|
2221
2221
|
const zone = toZoneWithoutBoundaryChanges(xc);
|
|
2222
|
-
|
|
2223
|
-
const tmp = zone.left;
|
|
2224
|
-
zone.left = zone.right;
|
|
2225
|
-
zone.right = tmp;
|
|
2226
|
-
}
|
|
2227
|
-
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2228
|
-
const tmp = zone.top;
|
|
2229
|
-
zone.top = zone.bottom;
|
|
2230
|
-
zone.bottom = tmp;
|
|
2231
|
-
}
|
|
2232
|
-
return zone;
|
|
2222
|
+
return reorderZone(zone);
|
|
2233
2223
|
}
|
|
2234
2224
|
/**
|
|
2235
2225
|
* Convert from a cartesian reference to a Zone.
|
|
@@ -2503,11 +2493,11 @@
|
|
|
2503
2493
|
return positions;
|
|
2504
2494
|
}
|
|
2505
2495
|
function reorderZone(zone) {
|
|
2506
|
-
if (zone.left > zone.right) {
|
|
2507
|
-
zone = { left: zone.right, right: zone.left
|
|
2496
|
+
if (zone.right !== undefined && zone.left > zone.right) {
|
|
2497
|
+
zone = { ...zone, left: zone.right, right: zone.left };
|
|
2508
2498
|
}
|
|
2509
|
-
if (zone.top > zone.bottom) {
|
|
2510
|
-
zone = {
|
|
2499
|
+
if (zone.bottom !== undefined && zone.top > zone.bottom) {
|
|
2500
|
+
zone = { ...zone, top: zone.bottom, bottom: zone.top };
|
|
2511
2501
|
}
|
|
2512
2502
|
return zone;
|
|
2513
2503
|
}
|
|
@@ -3412,12 +3402,12 @@
|
|
|
3412
3402
|
function isRangeDependant(cmd) {
|
|
3413
3403
|
return "ranges" in cmd;
|
|
3414
3404
|
}
|
|
3415
|
-
function isZoneDependent(cmd) {
|
|
3416
|
-
return "zone" in cmd;
|
|
3417
|
-
}
|
|
3418
3405
|
function isPositionDependent(cmd) {
|
|
3419
3406
|
return "col" in cmd && "row" in cmd && "sheetId" in cmd;
|
|
3420
3407
|
}
|
|
3408
|
+
function isZoneDependent(cmd) {
|
|
3409
|
+
return "sheetId" in cmd && "zone" in cmd;
|
|
3410
|
+
}
|
|
3421
3411
|
const invalidateEvaluationCommands = new Set([
|
|
3422
3412
|
"RENAME_SHEET",
|
|
3423
3413
|
"DELETE_SHEET",
|
|
@@ -3429,6 +3419,7 @@
|
|
|
3429
3419
|
"REDO",
|
|
3430
3420
|
"ADD_MERGE",
|
|
3431
3421
|
"REMOVE_MERGE",
|
|
3422
|
+
"DUPLICATE_SHEET",
|
|
3432
3423
|
"UPDATE_LOCALE",
|
|
3433
3424
|
"ADD_PIVOT",
|
|
3434
3425
|
"UPDATE_PIVOT",
|
|
@@ -3458,7 +3449,6 @@
|
|
|
3458
3449
|
]);
|
|
3459
3450
|
const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
|
|
3460
3451
|
const invalidateCFEvaluationCommands = new Set([
|
|
3461
|
-
"DUPLICATE_SHEET",
|
|
3462
3452
|
"EVALUATE_CELLS",
|
|
3463
3453
|
"ADD_CONDITIONAL_FORMAT",
|
|
3464
3454
|
"REMOVE_CONDITIONAL_FORMAT",
|
|
@@ -3628,6 +3618,7 @@
|
|
|
3628
3618
|
CommandResult["InvalidRange"] = "InvalidRange";
|
|
3629
3619
|
CommandResult["InvalidZones"] = "InvalidZones";
|
|
3630
3620
|
CommandResult["InvalidSheetId"] = "InvalidSheetId";
|
|
3621
|
+
CommandResult["InvalidCellId"] = "InvalidCellId";
|
|
3631
3622
|
CommandResult["InvalidFigureId"] = "InvalidFigureId";
|
|
3632
3623
|
CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
|
|
3633
3624
|
CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
|
|
@@ -4459,7 +4450,7 @@
|
|
|
4459
4450
|
* @param reverseSearch if true, search in the array starting from the end.
|
|
4460
4451
|
|
|
4461
4452
|
*/
|
|
4462
|
-
function linearSearch(data, target, mode, numberOfValues, getValueInData, reverseSearch = false) {
|
|
4453
|
+
function linearSearch(data, target, mode, numberOfValues, getValueInData, lookupCaches, reverseSearch = false) {
|
|
4463
4454
|
if (target === undefined || target.value === null) {
|
|
4464
4455
|
return -1;
|
|
4465
4456
|
}
|
|
@@ -4468,17 +4459,48 @@
|
|
|
4468
4459
|
}
|
|
4469
4460
|
const _target = normalizeValue(target.value);
|
|
4470
4461
|
const getValue = reverseSearch
|
|
4471
|
-
? (data, i) => getValueInData(data, numberOfValues - i - 1)
|
|
4472
|
-
: getValueInData;
|
|
4462
|
+
? (data, i) => normalizeValue(getValueInData(data, numberOfValues - i - 1))
|
|
4463
|
+
: (data, i) => normalizeValue(getValueInData(data, i));
|
|
4464
|
+
// first check if the target is in the cache
|
|
4465
|
+
const isNotWildcardTarget = mode !== "wildcard" ||
|
|
4466
|
+
typeof _target !== "string" ||
|
|
4467
|
+
!(_target.includes("*") || _target.includes("?"));
|
|
4468
|
+
if (lookupCaches && isNotWildcardTarget) {
|
|
4469
|
+
const searchMode = reverseSearch ? "reverseSearch" : "forwardSearch";
|
|
4470
|
+
let cache = lookupCaches[searchMode].get(data);
|
|
4471
|
+
if (cache === undefined) {
|
|
4472
|
+
// build the cache for all the values
|
|
4473
|
+
cache = new Map();
|
|
4474
|
+
for (let i = 0; i < numberOfValues; i++) {
|
|
4475
|
+
const value = getValue(data, i) ?? null;
|
|
4476
|
+
if (!cache.has(value)) {
|
|
4477
|
+
cache.set(value, i);
|
|
4478
|
+
}
|
|
4479
|
+
}
|
|
4480
|
+
lookupCaches[searchMode].set(data, cache);
|
|
4481
|
+
}
|
|
4482
|
+
if (cache.has(_target)) {
|
|
4483
|
+
const resultIndex = cache.get(_target);
|
|
4484
|
+
return reverseSearch ? numberOfValues - resultIndex - 1 : resultIndex;
|
|
4485
|
+
}
|
|
4486
|
+
if (mode === "strict") {
|
|
4487
|
+
return -1;
|
|
4488
|
+
}
|
|
4489
|
+
}
|
|
4490
|
+
// else perform the linear search
|
|
4491
|
+
const resultIndex = _linearSearch(data, _target, mode, numberOfValues, getValue);
|
|
4492
|
+
return reverseSearch && resultIndex !== -1 ? numberOfValues - resultIndex - 1 : resultIndex;
|
|
4493
|
+
}
|
|
4494
|
+
function _linearSearch(data, _target, mode, numberOfValues, getNormalizeValue) {
|
|
4473
4495
|
let indexMatchTarget = (i) => {
|
|
4474
|
-
return
|
|
4496
|
+
return getNormalizeValue(data, i) === _target;
|
|
4475
4497
|
};
|
|
4476
4498
|
if (mode === "wildcard" &&
|
|
4477
4499
|
typeof _target === "string" &&
|
|
4478
4500
|
(_target.includes("*") || _target.includes("?"))) {
|
|
4479
4501
|
const regExp = wildcardToRegExp(_target);
|
|
4480
4502
|
indexMatchTarget = (i) => {
|
|
4481
|
-
const value =
|
|
4503
|
+
const value = getNormalizeValue(data, i);
|
|
4482
4504
|
if (typeof value === "string") {
|
|
4483
4505
|
return regExp.test(value);
|
|
4484
4506
|
}
|
|
@@ -4489,7 +4511,7 @@
|
|
|
4489
4511
|
let closestMatchIndex = -1;
|
|
4490
4512
|
if (mode === "nextSmaller") {
|
|
4491
4513
|
indexMatchTarget = (i) => {
|
|
4492
|
-
const value =
|
|
4514
|
+
const value = getNormalizeValue(data, i);
|
|
4493
4515
|
if ((!closestMatch && compareCellValues(_target, value) >= 0) ||
|
|
4494
4516
|
(compareCellValues(_target, value) >= 0 && compareCellValues(value, closestMatch) > 0)) {
|
|
4495
4517
|
closestMatch = value;
|
|
@@ -4500,7 +4522,7 @@
|
|
|
4500
4522
|
}
|
|
4501
4523
|
if (mode === "nextGreater") {
|
|
4502
4524
|
indexMatchTarget = (i) => {
|
|
4503
|
-
const value =
|
|
4525
|
+
const value = getNormalizeValue(data, i);
|
|
4504
4526
|
if ((!closestMatch && compareCellValues(_target, value) <= 0) ||
|
|
4505
4527
|
(compareCellValues(_target, value) <= 0 && compareCellValues(value, closestMatch) < 0)) {
|
|
4506
4528
|
closestMatch = value;
|
|
@@ -4511,12 +4533,10 @@
|
|
|
4511
4533
|
}
|
|
4512
4534
|
for (let i = 0; i < numberOfValues; i++) {
|
|
4513
4535
|
if (indexMatchTarget(i)) {
|
|
4514
|
-
return
|
|
4536
|
+
return i;
|
|
4515
4537
|
}
|
|
4516
4538
|
}
|
|
4517
|
-
return
|
|
4518
|
-
? numberOfValues - closestMatchIndex - 1
|
|
4519
|
-
: closestMatchIndex;
|
|
4539
|
+
return closestMatchIndex;
|
|
4520
4540
|
}
|
|
4521
4541
|
/**
|
|
4522
4542
|
* Normalize a value.
|
|
@@ -6480,11 +6500,40 @@
|
|
|
6480
6500
|
* https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
|
|
6481
6501
|
* */
|
|
6482
6502
|
class UuidGenerator {
|
|
6503
|
+
/**
|
|
6504
|
+
* Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
|
|
6505
|
+
* This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
|
|
6506
|
+
* it also has a smaller size, which is preferable to alleviate the overall data size.
|
|
6507
|
+
*
|
|
6508
|
+
* This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
|
|
6509
|
+
* as they will appear several times in the revisions and local history.
|
|
6510
|
+
*
|
|
6511
|
+
*/
|
|
6512
|
+
smallUuid() {
|
|
6513
|
+
if (window.crypto) {
|
|
6514
|
+
return "10000000-1000".replace(/[01]/g, (c) => {
|
|
6515
|
+
const n = Number(c);
|
|
6516
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6517
|
+
});
|
|
6518
|
+
}
|
|
6519
|
+
else {
|
|
6520
|
+
// mainly for jest and other browsers that do not have the crypto functionality
|
|
6521
|
+
return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
|
|
6522
|
+
const r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
6523
|
+
return v.toString(16);
|
|
6524
|
+
});
|
|
6525
|
+
}
|
|
6526
|
+
}
|
|
6527
|
+
/**
|
|
6528
|
+
* Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
|
|
6529
|
+
* This method should be used when you need to avoid collisions at all costs, like the id of a revision.
|
|
6530
|
+
*/
|
|
6483
6531
|
uuidv4() {
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6532
|
+
if (window.crypto) {
|
|
6533
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
|
|
6534
|
+
const n = Number(c);
|
|
6535
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6536
|
+
});
|
|
6488
6537
|
}
|
|
6489
6538
|
else {
|
|
6490
6539
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -8514,7 +8563,7 @@
|
|
|
8514
8563
|
};
|
|
8515
8564
|
}
|
|
8516
8565
|
getPasteTarget(sheetId, target, content, options) {
|
|
8517
|
-
const newId = new UuidGenerator().
|
|
8566
|
+
const newId = new UuidGenerator().smallUuid();
|
|
8518
8567
|
return { zones: [], figureId: newId, sheetId };
|
|
8519
8568
|
}
|
|
8520
8569
|
paste(target, clippedContent, options) {
|
|
@@ -8680,7 +8729,7 @@
|
|
|
8680
8729
|
if (!targetCF && queuedCfs) {
|
|
8681
8730
|
targetCF = queuedCfs.find((queued) => queued.cf.stopIfTrue === originCF.stopIfTrue && deepEquals(queued.cf.rule, originCF.rule))?.cf;
|
|
8682
8731
|
}
|
|
8683
|
-
return targetCF || { ...originCF, id: this.uuidGenerator.
|
|
8732
|
+
return targetCF || { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
|
|
8684
8733
|
}
|
|
8685
8734
|
}
|
|
8686
8735
|
|
|
@@ -8773,7 +8822,7 @@
|
|
|
8773
8822
|
}
|
|
8774
8823
|
return (targetRule || {
|
|
8775
8824
|
...originRule,
|
|
8776
|
-
id: newId ? this.uuidGenerator.
|
|
8825
|
+
id: newId ? this.uuidGenerator.smallUuid() : originRule.id,
|
|
8777
8826
|
ranges: [],
|
|
8778
8827
|
});
|
|
8779
8828
|
}
|
|
@@ -8835,7 +8884,7 @@
|
|
|
8835
8884
|
};
|
|
8836
8885
|
}
|
|
8837
8886
|
getPasteTarget(sheetId, target, content, options) {
|
|
8838
|
-
const newId = new UuidGenerator().
|
|
8887
|
+
const newId = new UuidGenerator().smallUuid();
|
|
8839
8888
|
return { sheetId, zones: [], figureId: newId };
|
|
8840
8889
|
}
|
|
8841
8890
|
paste(target, clippedContent, options) {
|
|
@@ -12037,6 +12086,25 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
12037
12086
|
isExported: true,
|
|
12038
12087
|
};
|
|
12039
12088
|
// -----------------------------------------------------------------------------
|
|
12089
|
+
// LOG
|
|
12090
|
+
// -----------------------------------------------------------------------------
|
|
12091
|
+
const LOG = {
|
|
12092
|
+
description: _t("The logarithm of a number, for a given base."),
|
|
12093
|
+
args: [
|
|
12094
|
+
arg("value (number)", _t("The value for which to calculate the logarithm.")),
|
|
12095
|
+
arg("base (number, default=10)", _t("The base of the logarithm.")),
|
|
12096
|
+
],
|
|
12097
|
+
compute: function (value, base = { value: 10 }) {
|
|
12098
|
+
const _value = toNumber(value, this.locale);
|
|
12099
|
+
const _base = toNumber(base, this.locale);
|
|
12100
|
+
assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
|
|
12101
|
+
assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
|
|
12102
|
+
assert(() => _base !== 1, _t("The base must be different from 1."));
|
|
12103
|
+
return Math.log10(_value) / Math.log10(_base);
|
|
12104
|
+
},
|
|
12105
|
+
isExported: true,
|
|
12106
|
+
};
|
|
12107
|
+
// -----------------------------------------------------------------------------
|
|
12040
12108
|
// MOD
|
|
12041
12109
|
// -----------------------------------------------------------------------------
|
|
12042
12110
|
function mod(dividend, divisor) {
|
|
@@ -12576,6 +12644,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
12576
12644
|
ISODD: ISODD,
|
|
12577
12645
|
ISO_CEILING: ISO_CEILING,
|
|
12578
12646
|
LN: LN,
|
|
12647
|
+
LOG: LOG,
|
|
12579
12648
|
MOD: MOD,
|
|
12580
12649
|
MUNIT: MUNIT,
|
|
12581
12650
|
ODD: ODD,
|
|
@@ -15110,7 +15179,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
15110
15179
|
}
|
|
15111
15180
|
}
|
|
15112
15181
|
},
|
|
15113
|
-
isExported:
|
|
15182
|
+
isExported: false,
|
|
15114
15183
|
};
|
|
15115
15184
|
// -----------------------------------------------------------------------------
|
|
15116
15185
|
// UNIQUE
|
|
@@ -18474,7 +18543,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18474
18543
|
const _isSorted = toBoolean(isSorted.value);
|
|
18475
18544
|
const colIndex = _isSorted
|
|
18476
18545
|
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18477
|
-
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18546
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange, this.lookupCaches);
|
|
18478
18547
|
const col = _range[colIndex];
|
|
18479
18548
|
if (col === undefined) {
|
|
18480
18549
|
return valueNotAvailable(searchKey);
|
|
@@ -18629,7 +18698,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18629
18698
|
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18630
18699
|
break;
|
|
18631
18700
|
case 0:
|
|
18632
|
-
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18701
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement, this.lookupCaches);
|
|
18633
18702
|
break;
|
|
18634
18703
|
case -1:
|
|
18635
18704
|
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
@@ -18697,7 +18766,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18697
18766
|
const _isSorted = toBoolean(isSorted.value);
|
|
18698
18767
|
const rowIndex = _isSorted
|
|
18699
18768
|
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18700
|
-
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18769
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange, this.lookupCaches);
|
|
18701
18770
|
const value = _range[_index - 1][rowIndex];
|
|
18702
18771
|
if (value === undefined) {
|
|
18703
18772
|
return valueNotAvailable(searchKey);
|
|
@@ -18753,7 +18822,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18753
18822
|
const reverseSearch = _searchMode === -1;
|
|
18754
18823
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18755
18824
|
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18756
|
-
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18825
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, this.lookupCaches, reverseSearch);
|
|
18757
18826
|
if (index !== -1) {
|
|
18758
18827
|
return lookupDirection === "col"
|
|
18759
18828
|
? _returnRange.map((col) => [col[index]])
|
|
@@ -27623,7 +27692,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27623
27692
|
for (const sheet of data.sheets || []) {
|
|
27624
27693
|
for (const figure of sheet.figures || []) {
|
|
27625
27694
|
if (figureIds.has(figure.id)) {
|
|
27626
|
-
figure.id += uuidGenerator.
|
|
27695
|
+
figure.id += uuidGenerator.smallUuid();
|
|
27627
27696
|
}
|
|
27628
27697
|
figureIds.add(figure.id);
|
|
27629
27698
|
}
|
|
@@ -28208,9 +28277,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28208
28277
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28209
28278
|
let labels = labelValues.formattedValues;
|
|
28210
28279
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
28211
|
-
if (definition.dataSetsHaveTitle
|
|
28212
|
-
dataSetsValues[0] &&
|
|
28213
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28280
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28214
28281
|
labels.shift();
|
|
28215
28282
|
}
|
|
28216
28283
|
({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
|
|
@@ -28243,7 +28310,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28243
28310
|
}
|
|
28244
28311
|
function getPyramidChartData(definition, dataSets, labelRange, getters) {
|
|
28245
28312
|
const barChartData = getBarChartData(definition, dataSets, labelRange, getters);
|
|
28246
|
-
const barDataset = barChartData.dataSetsValues;
|
|
28313
|
+
const barDataset = barChartData.dataSetsValues.filter((ds) => !ds.hidden);
|
|
28247
28314
|
const pyramidDatasetValues = [];
|
|
28248
28315
|
if (barDataset[0]) {
|
|
28249
28316
|
const pyramidData = barDataset[0].data.map((value) => (value > 0 ? value : 0));
|
|
@@ -28259,13 +28326,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28259
28326
|
};
|
|
28260
28327
|
}
|
|
28261
28328
|
function getLineChartData(definition, dataSets, labelRange, getters) {
|
|
28262
|
-
const axisType = getChartAxisType(definition, labelRange, getters);
|
|
28329
|
+
const axisType = getChartAxisType(definition, dataSets, labelRange, getters);
|
|
28263
28330
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28264
28331
|
let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
|
|
28265
28332
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
28266
|
-
|
|
28267
|
-
|
|
28268
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28333
|
+
const removeFirstLabel = shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false);
|
|
28334
|
+
if (removeFirstLabel) {
|
|
28269
28335
|
labels.shift();
|
|
28270
28336
|
}
|
|
28271
28337
|
({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
|
|
@@ -28277,7 +28343,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28277
28343
|
}
|
|
28278
28344
|
const leftAxisFormat = getChartDatasetFormat(getters, dataSets, "left");
|
|
28279
28345
|
const rightAxisFormat = getChartDatasetFormat(getters, dataSets, "right");
|
|
28280
|
-
const labelsFormat = getChartLabelFormat(getters, labelRange);
|
|
28346
|
+
const labelsFormat = getChartLabelFormat(getters, labelRange, removeFirstLabel);
|
|
28281
28347
|
const axisFormats = { y: leftAxisFormat, y1: rightAxisFormat, x: labelsFormat };
|
|
28282
28348
|
const trendDataSetsValues = [];
|
|
28283
28349
|
for (const index in dataSetsValues) {
|
|
@@ -28313,9 +28379,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28313
28379
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28314
28380
|
let labels = labelValues.formattedValues;
|
|
28315
28381
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
28316
|
-
if (definition.dataSetsHaveTitle
|
|
28317
|
-
dataSetsValues[0] &&
|
|
28318
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28382
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28319
28383
|
labels.shift();
|
|
28320
28384
|
}
|
|
28321
28385
|
({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
|
|
@@ -28335,9 +28399,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28335
28399
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28336
28400
|
let labels = labelValues.formattedValues;
|
|
28337
28401
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
28338
|
-
if (definition.dataSetsHaveTitle
|
|
28339
|
-
dataSetsValues[0] &&
|
|
28340
|
-
labels.length > dataSetsValues[0].data.length) {
|
|
28402
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28341
28403
|
labels.shift();
|
|
28342
28404
|
}
|
|
28343
28405
|
({ labels, dataSetsValues } = filterInvalidDataPoints(labels, dataSetsValues));
|
|
@@ -28357,7 +28419,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28357
28419
|
function getGeoChartData(definition, dataSets, labelRange, getters) {
|
|
28358
28420
|
const labelValues = getChartLabelValues(getters, dataSets, labelRange);
|
|
28359
28421
|
let labels = labelValues.formattedValues;
|
|
28360
|
-
if (definition.dataSetsHaveTitle) {
|
|
28422
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28361
28423
|
labels.shift();
|
|
28362
28424
|
}
|
|
28363
28425
|
let dataSetsValues = getChartDatasetValues(getters, dataSets);
|
|
@@ -28518,36 +28580,41 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28518
28580
|
}
|
|
28519
28581
|
return { normalizedLabels, normalizedNewLabels };
|
|
28520
28582
|
}
|
|
28521
|
-
function getChartAxisType(
|
|
28522
|
-
if (isDateChart(
|
|
28583
|
+
function getChartAxisType(definition, dataSets, labelRange, getters) {
|
|
28584
|
+
if (isDateChart(definition, dataSets, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
|
|
28523
28585
|
return "time";
|
|
28524
28586
|
}
|
|
28525
|
-
if (isLinearChart(
|
|
28587
|
+
if (isLinearChart(definition, dataSets, labelRange, getters)) {
|
|
28526
28588
|
return "linear";
|
|
28527
28589
|
}
|
|
28528
28590
|
return "category";
|
|
28529
28591
|
}
|
|
28530
|
-
function isDateChart(definition, labelRange, getters) {
|
|
28531
|
-
return !definition.labelsAsText && canBeDateChart(labelRange, getters);
|
|
28592
|
+
function isDateChart(definition, dataSets, labelRange, getters) {
|
|
28593
|
+
return !definition.labelsAsText && canBeDateChart(definition, dataSets, labelRange, getters);
|
|
28532
28594
|
}
|
|
28533
|
-
function isLinearChart(definition, labelRange, getters) {
|
|
28534
|
-
return !definition.labelsAsText && canBeLinearChart(labelRange, getters);
|
|
28595
|
+
function isLinearChart(definition, dataSets, labelRange, getters) {
|
|
28596
|
+
return !definition.labelsAsText && canBeLinearChart(definition, dataSets, labelRange, getters);
|
|
28535
28597
|
}
|
|
28536
|
-
function canChartParseLabels(labelRange, getters) {
|
|
28537
|
-
return canBeDateChart(
|
|
28598
|
+
function canChartParseLabels(definition, dataSets, labelRange, getters) {
|
|
28599
|
+
return (canBeDateChart(definition, dataSets, labelRange, getters) ||
|
|
28600
|
+
canBeLinearChart(definition, dataSets, labelRange, getters));
|
|
28538
28601
|
}
|
|
28539
|
-
function canBeDateChart(labelRange, getters) {
|
|
28540
|
-
if (!labelRange || !canBeLinearChart(labelRange, getters)) {
|
|
28602
|
+
function canBeDateChart(definition, dataSets, labelRange, getters) {
|
|
28603
|
+
if (!labelRange || !canBeLinearChart(definition, dataSets, labelRange, getters)) {
|
|
28541
28604
|
return false;
|
|
28542
28605
|
}
|
|
28543
|
-
const
|
|
28606
|
+
const removeFirstLabel = shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false);
|
|
28607
|
+
const labelFormat = getChartLabelFormat(getters, labelRange, removeFirstLabel);
|
|
28544
28608
|
return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
|
|
28545
28609
|
}
|
|
28546
|
-
function canBeLinearChart(labelRange, getters) {
|
|
28610
|
+
function canBeLinearChart(definition, dataSets, labelRange, getters) {
|
|
28547
28611
|
if (!labelRange) {
|
|
28548
28612
|
return false;
|
|
28549
28613
|
}
|
|
28550
28614
|
const labels = getters.getRangeValues(labelRange);
|
|
28615
|
+
if (shouldRemoveFirstLabel(labelRange, dataSets[0], definition.dataSetsHaveTitle || false)) {
|
|
28616
|
+
labels.shift();
|
|
28617
|
+
}
|
|
28551
28618
|
if (labels.some((label) => isNaN(Number(label)) && label)) {
|
|
28552
28619
|
return false;
|
|
28553
28620
|
}
|
|
@@ -28656,17 +28723,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28656
28723
|
})),
|
|
28657
28724
|
};
|
|
28658
28725
|
}
|
|
28659
|
-
function getChartLabelFormat(getters, range) {
|
|
28726
|
+
function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
|
|
28660
28727
|
if (!range)
|
|
28661
28728
|
return undefined;
|
|
28662
|
-
const { sheetId, zone
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
return format;
|
|
28667
|
-
}
|
|
28729
|
+
const { sheetId, zone } = range;
|
|
28730
|
+
const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
|
|
28731
|
+
if (shouldRemoveFirstLabel) {
|
|
28732
|
+
formats.shift();
|
|
28668
28733
|
}
|
|
28669
|
-
return undefined;
|
|
28734
|
+
return formats.find((format) => format !== undefined);
|
|
28670
28735
|
}
|
|
28671
28736
|
function getChartLabelValues(getters, dataSets, labelRange) {
|
|
28672
28737
|
let labels = { values: [], formattedValues: [] };
|
|
@@ -28722,10 +28787,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28722
28787
|
function getChartDatasetValues(getters, dataSets) {
|
|
28723
28788
|
const datasetValues = [];
|
|
28724
28789
|
for (const [dsIndex, ds] of Object.entries(dataSets)) {
|
|
28725
|
-
if (getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left)) {
|
|
28726
|
-
continue;
|
|
28727
|
-
}
|
|
28728
28790
|
let label;
|
|
28791
|
+
let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
|
|
28729
28792
|
if (ds.labelCell) {
|
|
28730
28793
|
const labelRange = ds.labelCell;
|
|
28731
28794
|
const cell = labelRange
|
|
@@ -28752,9 +28815,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28752
28815
|
data.fill(1);
|
|
28753
28816
|
}
|
|
28754
28817
|
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
|
|
28755
|
-
|
|
28818
|
+
hidden = true;
|
|
28756
28819
|
}
|
|
28757
|
-
datasetValues.push({ data, label });
|
|
28820
|
+
datasetValues.push({ data, label, hidden });
|
|
28758
28821
|
}
|
|
28759
28822
|
return datasetValues;
|
|
28760
28823
|
}
|
|
@@ -28765,12 +28828,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28765
28828
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28766
28829
|
const trendDatasets = [];
|
|
28767
28830
|
for (const index in dataSetsValues) {
|
|
28768
|
-
let { label, data } = dataSetsValues[index];
|
|
28831
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28769
28832
|
label = definition.dataSets?.[index].label || label;
|
|
28770
28833
|
const backgroundColor = colors.next();
|
|
28771
28834
|
const dataset = {
|
|
28772
28835
|
label,
|
|
28773
28836
|
data,
|
|
28837
|
+
hidden,
|
|
28774
28838
|
borderColor: definition.background || BACKGROUND_CHART_COLOR,
|
|
28775
28839
|
borderWidth: definition.stacked ? 1 : 0,
|
|
28776
28840
|
backgroundColor,
|
|
@@ -28803,6 +28867,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28803
28867
|
const labelsWithSubTotals = [];
|
|
28804
28868
|
let lastValue = 0;
|
|
28805
28869
|
for (const dataSetsValue of dataSetsValues) {
|
|
28870
|
+
if (dataSetsValue.hidden) {
|
|
28871
|
+
continue;
|
|
28872
|
+
}
|
|
28806
28873
|
for (let i = 0; i < dataSetsValue.data.length; i++) {
|
|
28807
28874
|
const data = dataSetsValue.data[i];
|
|
28808
28875
|
labelsWithSubTotals.push(labels[i]);
|
|
@@ -28838,7 +28905,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28838
28905
|
const trendDatasets = [];
|
|
28839
28906
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28840
28907
|
for (let index = 0; index < dataSetsValues.length; index++) {
|
|
28841
|
-
let { label, data } = dataSetsValues[index];
|
|
28908
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28842
28909
|
label = definition.dataSets?.[index].label || label;
|
|
28843
28910
|
const color = colors.next();
|
|
28844
28911
|
if (axisType && ["linear", "time"].includes(axisType)) {
|
|
@@ -28848,6 +28915,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28848
28915
|
const dataset = {
|
|
28849
28916
|
label,
|
|
28850
28917
|
data,
|
|
28918
|
+
hidden,
|
|
28851
28919
|
tension: 0, // 0 -> render straight lines, which is much faster
|
|
28852
28920
|
borderColor: color,
|
|
28853
28921
|
backgroundColor: areaChart ? setColorAlpha(color, LINE_FILL_TRANSPARENCY) : color,
|
|
@@ -28880,11 +28948,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28880
28948
|
const dataSets = [];
|
|
28881
28949
|
const dataSetsLength = Math.max(0, ...dataSetsValues.map((ds) => ds?.data?.length ?? 0));
|
|
28882
28950
|
const backgroundColor = getPieColors(new ColorGenerator(dataSetsLength), dataSetsValues);
|
|
28883
|
-
for (const { label, data } of dataSetsValues) {
|
|
28951
|
+
for (const { label, data, hidden } of dataSetsValues) {
|
|
28952
|
+
if (hidden)
|
|
28953
|
+
continue;
|
|
28884
28954
|
const dataset = {
|
|
28885
28955
|
label,
|
|
28886
28956
|
data,
|
|
28887
|
-
borderColor:
|
|
28957
|
+
borderColor: definition.background || "#FFFFFF",
|
|
28888
28958
|
backgroundColor,
|
|
28889
28959
|
hoverOffset: 30,
|
|
28890
28960
|
};
|
|
@@ -28898,7 +28968,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28898
28968
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28899
28969
|
const trendDatasets = [];
|
|
28900
28970
|
for (let index = 0; index < dataSetsValues.length; index++) {
|
|
28901
|
-
let { label, data } = dataSetsValues[index];
|
|
28971
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28902
28972
|
label = definition.dataSets?.[index].label || label;
|
|
28903
28973
|
const design = definition.dataSets?.[index];
|
|
28904
28974
|
const color = colors.next();
|
|
@@ -28906,6 +28976,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28906
28976
|
const dataset = {
|
|
28907
28977
|
label: label,
|
|
28908
28978
|
data,
|
|
28979
|
+
hidden,
|
|
28909
28980
|
borderColor: color,
|
|
28910
28981
|
backgroundColor: color,
|
|
28911
28982
|
yAxisID: definition.dataSets?.[index].yAxisId || "y",
|
|
@@ -28930,7 +29001,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28930
29001
|
const fill = definition.fillArea ?? false;
|
|
28931
29002
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28932
29003
|
for (let i = 0; i < dataSetsValues.length; i++) {
|
|
28933
|
-
let { label, data } = dataSetsValues[i];
|
|
29004
|
+
let { label, data, hidden } = dataSetsValues[i];
|
|
28934
29005
|
if (definition.dataSets?.[i]?.label) {
|
|
28935
29006
|
label = definition.dataSets[i].label;
|
|
28936
29007
|
}
|
|
@@ -28938,6 +29009,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28938
29009
|
const dataset = {
|
|
28939
29010
|
label,
|
|
28940
29011
|
data,
|
|
29012
|
+
hidden,
|
|
28941
29013
|
borderColor,
|
|
28942
29014
|
backgroundColor: borderColor,
|
|
28943
29015
|
};
|
|
@@ -29083,6 +29155,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29083
29155
|
hidden: false,
|
|
29084
29156
|
lineWidth: 2,
|
|
29085
29157
|
})),
|
|
29158
|
+
filter: (legendItem, data) => {
|
|
29159
|
+
return "datasetIndex" in legendItem
|
|
29160
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29161
|
+
: true;
|
|
29162
|
+
},
|
|
29086
29163
|
},
|
|
29087
29164
|
};
|
|
29088
29165
|
}
|
|
@@ -29144,6 +29221,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29144
29221
|
}
|
|
29145
29222
|
return legendValues;
|
|
29146
29223
|
},
|
|
29224
|
+
filter: (legendItem, data) => {
|
|
29225
|
+
return "datasetIndex" in legendItem
|
|
29226
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29227
|
+
: true;
|
|
29228
|
+
},
|
|
29147
29229
|
},
|
|
29148
29230
|
onClick: () => { }, // Disables click interaction with the waterfall chart legend items
|
|
29149
29231
|
};
|
|
@@ -29227,6 +29309,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
29227
29309
|
...legendLabelConfig,
|
|
29228
29310
|
};
|
|
29229
29311
|
}),
|
|
29312
|
+
filter: (legendItem, data) => {
|
|
29313
|
+
return "datasetIndex" in legendItem
|
|
29314
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29315
|
+
: true;
|
|
29316
|
+
},
|
|
29230
29317
|
},
|
|
29231
29318
|
};
|
|
29232
29319
|
}
|
|
@@ -32899,7 +32986,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32899
32986
|
const deleteSheet = {
|
|
32900
32987
|
name: _t("Delete"),
|
|
32901
32988
|
isVisible: (env) => {
|
|
32902
|
-
return env.model.getters.
|
|
32989
|
+
return env.model.getters.getVisibleSheetIds().length > 1;
|
|
32903
32990
|
},
|
|
32904
32991
|
execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
|
|
32905
32992
|
env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
|
|
@@ -32910,7 +32997,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32910
32997
|
name: _t("Duplicate"),
|
|
32911
32998
|
execute: (env) => {
|
|
32912
32999
|
const sheetIdFrom = env.model.getters.getActiveSheetId();
|
|
32913
|
-
const sheetIdTo = env.model.uuidGenerator.
|
|
33000
|
+
const sheetIdTo = env.model.uuidGenerator.smallUuid();
|
|
32914
33001
|
env.model.dispatch("DUPLICATE_SHEET", {
|
|
32915
33002
|
sheetId: sheetIdFrom,
|
|
32916
33003
|
sheetIdTo,
|
|
@@ -33016,6 +33103,100 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33016
33103
|
function getOpenedMenus() {
|
|
33017
33104
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
33018
33105
|
}
|
|
33106
|
+
function getCurrentSelection(el) {
|
|
33107
|
+
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = getStartAndEndSelection(el);
|
|
33108
|
+
let startSizeBefore = findSelectionIndex(el, startElement, startSelectionOffset);
|
|
33109
|
+
let endSizeBefore = findSelectionIndex(el, endElement, endSelectionOffset);
|
|
33110
|
+
return {
|
|
33111
|
+
start: startSizeBefore,
|
|
33112
|
+
end: endSizeBefore,
|
|
33113
|
+
};
|
|
33114
|
+
}
|
|
33115
|
+
function getStartAndEndSelection(el) {
|
|
33116
|
+
const selection = document.getSelection();
|
|
33117
|
+
return {
|
|
33118
|
+
startElement: selection.anchorNode || el,
|
|
33119
|
+
startSelectionOffset: selection.anchorOffset,
|
|
33120
|
+
endElement: selection.focusNode || el,
|
|
33121
|
+
endSelectionOffset: selection.focusOffset,
|
|
33122
|
+
};
|
|
33123
|
+
}
|
|
33124
|
+
/**
|
|
33125
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
33126
|
+
* The selected node is either a Text node or an Element node.
|
|
33127
|
+
*
|
|
33128
|
+
* case 1 -Text node:
|
|
33129
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
33130
|
+
* content length of all previous nodes.
|
|
33131
|
+
*
|
|
33132
|
+
* case 2 - Element node:
|
|
33133
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
33134
|
+
* all the nodes prior to the selected node as well as the content of the child node before the offset.
|
|
33135
|
+
*
|
|
33136
|
+
* See the MDN documentation for more details.
|
|
33137
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
33138
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
33139
|
+
*
|
|
33140
|
+
*/
|
|
33141
|
+
function findSelectionIndex(el, nodeToFind, nodeOffset) {
|
|
33142
|
+
let usedCharacters = 0;
|
|
33143
|
+
let it = iterateChildren(el);
|
|
33144
|
+
let current = it.next();
|
|
33145
|
+
let isFirstParagraph = true;
|
|
33146
|
+
while (!current.done && current.value !== nodeToFind) {
|
|
33147
|
+
if (!current.value.hasChildNodes()) {
|
|
33148
|
+
if (current.value.textContent) {
|
|
33149
|
+
usedCharacters += current.value.textContent.length;
|
|
33150
|
+
}
|
|
33151
|
+
}
|
|
33152
|
+
// One new paragraph = one new line character, except for the first paragraph
|
|
33153
|
+
if (current.value.nodeName === "P" ||
|
|
33154
|
+
(current.value.nodeName === "DIV" && current.value !== el) // On paste, the HTML may contain <div> instead of <p>
|
|
33155
|
+
) {
|
|
33156
|
+
if (isFirstParagraph) {
|
|
33157
|
+
isFirstParagraph = false;
|
|
33158
|
+
}
|
|
33159
|
+
else {
|
|
33160
|
+
usedCharacters++;
|
|
33161
|
+
}
|
|
33162
|
+
}
|
|
33163
|
+
current = it.next();
|
|
33164
|
+
}
|
|
33165
|
+
if (current.value !== nodeToFind) {
|
|
33166
|
+
/** This situation can happen if the code is called while the selection is not currently on the element.
|
|
33167
|
+
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
33168
|
+
*
|
|
33169
|
+
* A known occurrence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
33170
|
+
*/
|
|
33171
|
+
return 0;
|
|
33172
|
+
}
|
|
33173
|
+
else {
|
|
33174
|
+
if (!current.value.hasChildNodes()) {
|
|
33175
|
+
usedCharacters += nodeOffset;
|
|
33176
|
+
}
|
|
33177
|
+
else {
|
|
33178
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
33179
|
+
usedCharacters += children.reduce((acc, child, index) => {
|
|
33180
|
+
if (child.textContent !== null) {
|
|
33181
|
+
// need to account for paragraph nodes that implicitly add a new line
|
|
33182
|
+
// except for the last paragraph
|
|
33183
|
+
let chars = child.textContent.length;
|
|
33184
|
+
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
33185
|
+
chars++;
|
|
33186
|
+
}
|
|
33187
|
+
return acc + chars;
|
|
33188
|
+
}
|
|
33189
|
+
else {
|
|
33190
|
+
return acc;
|
|
33191
|
+
}
|
|
33192
|
+
}, 0);
|
|
33193
|
+
}
|
|
33194
|
+
}
|
|
33195
|
+
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
33196
|
+
usedCharacters++;
|
|
33197
|
+
}
|
|
33198
|
+
return usedCharacters;
|
|
33199
|
+
}
|
|
33019
33200
|
const letterRegex = /^[a-zA-Z]$/;
|
|
33020
33201
|
/**
|
|
33021
33202
|
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
@@ -33613,20 +33794,21 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33613
33794
|
}
|
|
33614
33795
|
// Only display legend for several datasets.
|
|
33615
33796
|
const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
|
|
33616
|
-
const
|
|
33617
|
-
|
|
33618
|
-
|
|
33619
|
-
|
|
33620
|
-
|
|
33621
|
-
|
|
33622
|
-
|
|
33623
|
-
|
|
33624
|
-
|
|
33625
|
-
|
|
33626
|
-
|
|
33627
|
-
|
|
33628
|
-
|
|
33629
|
-
|
|
33797
|
+
const lineChartDefinition = {
|
|
33798
|
+
title: {},
|
|
33799
|
+
dataSets,
|
|
33800
|
+
labelsAsText: false,
|
|
33801
|
+
stacked: false,
|
|
33802
|
+
aggregated: false,
|
|
33803
|
+
cumulative: false,
|
|
33804
|
+
labelRange: labelRangeXc,
|
|
33805
|
+
type: "line",
|
|
33806
|
+
dataSetsHaveTitle,
|
|
33807
|
+
legendPosition: newLegendPos,
|
|
33808
|
+
};
|
|
33809
|
+
const chart = new LineChart(lineChartDefinition, sheetId, getters);
|
|
33810
|
+
if (canChartParseLabels(lineChartDefinition, chart.dataSets, chart.labelRange, getters)) {
|
|
33811
|
+
return lineChartDefinition;
|
|
33630
33812
|
}
|
|
33631
33813
|
const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
|
|
33632
33814
|
if (singleColumn &&
|
|
@@ -34040,7 +34222,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34040
34222
|
//------------------------------------------------------------------------------
|
|
34041
34223
|
const CREATE_CHART = (env) => {
|
|
34042
34224
|
const getters = env.model.getters;
|
|
34043
|
-
const id = env.model.uuidGenerator.
|
|
34225
|
+
const id = env.model.uuidGenerator.smallUuid();
|
|
34044
34226
|
const sheetId = getters.getActiveSheetId();
|
|
34045
34227
|
if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
|
|
34046
34228
|
env.model.selection.selectTableAroundSelection();
|
|
@@ -34063,8 +34245,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34063
34245
|
// Pivots
|
|
34064
34246
|
//------------------------------------------------------------------------------
|
|
34065
34247
|
const CREATE_PIVOT = (env) => {
|
|
34066
|
-
const pivotId = env.model.uuidGenerator.
|
|
34067
|
-
const newSheetId = env.model.uuidGenerator.
|
|
34248
|
+
const pivotId = env.model.uuidGenerator.smallUuid();
|
|
34249
|
+
const newSheetId = env.model.uuidGenerator.smallUuid();
|
|
34068
34250
|
const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
|
|
34069
34251
|
if (result.isSuccessful) {
|
|
34070
34252
|
env.openSidePanel("PivotSidePanel", { pivotId });
|
|
@@ -34123,7 +34305,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34123
34305
|
const CREATE_IMAGE = async (env) => {
|
|
34124
34306
|
if (env.imageProvider) {
|
|
34125
34307
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
34126
|
-
const figureId = env.model.uuidGenerator.
|
|
34308
|
+
const figureId = env.model.uuidGenerator.smallUuid();
|
|
34127
34309
|
const image = await requestImage(env);
|
|
34128
34310
|
if (!image) {
|
|
34129
34311
|
throw new Error("No image provider was given to the environment");
|
|
@@ -34676,7 +34858,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34676
34858
|
ranges,
|
|
34677
34859
|
sheetId,
|
|
34678
34860
|
rule: {
|
|
34679
|
-
id: env.model.uuidGenerator.
|
|
34861
|
+
id: env.model.uuidGenerator.smallUuid(),
|
|
34680
34862
|
criterion: {
|
|
34681
34863
|
type: "isBoolean",
|
|
34682
34864
|
values: [],
|
|
@@ -34692,7 +34874,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34692
34874
|
const zones = env.model.getters.getSelectedZones();
|
|
34693
34875
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
34694
34876
|
const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
|
|
34695
|
-
const ruleID = env.model.uuidGenerator.
|
|
34877
|
+
const ruleID = env.model.uuidGenerator.smallUuid();
|
|
34696
34878
|
env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
|
|
34697
34879
|
ranges,
|
|
34698
34880
|
sheetId,
|
|
@@ -34723,7 +34905,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34723
34905
|
execute: (env) => {
|
|
34724
34906
|
const activeSheetId = env.model.getters.getActiveSheetId();
|
|
34725
34907
|
const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
|
|
34726
|
-
const sheetId = env.model.uuidGenerator.
|
|
34908
|
+
const sheetId = env.model.uuidGenerator.smallUuid();
|
|
34727
34909
|
env.model.dispatch("CREATE_SHEET", { sheetId, position });
|
|
34728
34910
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
|
|
34729
34911
|
},
|
|
@@ -38250,7 +38432,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
38250
38432
|
.o-font-size-editor {
|
|
38251
38433
|
height: calc(100% - 4px);
|
|
38252
38434
|
input.o-font-size {
|
|
38253
|
-
outline
|
|
38435
|
+
outline: none;
|
|
38254
38436
|
height: 20px;
|
|
38255
38437
|
width: 23px;
|
|
38256
38438
|
}
|
|
@@ -39212,7 +39394,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39212
39394
|
get canTreatLabelsAsText() {
|
|
39213
39395
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
39214
39396
|
if (chart && chart instanceof LineChart) {
|
|
39215
|
-
return canChartParseLabels(chart.labelRange, this.env.model.getters);
|
|
39397
|
+
return canChartParseLabels(chart.getDefinition(), chart.dataSets, chart.labelRange, this.env.model.getters);
|
|
39216
39398
|
}
|
|
39217
39399
|
return false;
|
|
39218
39400
|
}
|
|
@@ -39289,7 +39471,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39289
39471
|
get canTreatLabelsAsText() {
|
|
39290
39472
|
const chart = this.env.model.getters.getChart(this.props.figureId);
|
|
39291
39473
|
if (chart && chart instanceof ScatterChart) {
|
|
39292
|
-
return canChartParseLabels(chart.labelRange, this.env.model.getters);
|
|
39474
|
+
return canChartParseLabels(chart.getDefinition(), chart.dataSets, chart.labelRange, this.env.model.getters);
|
|
39293
39475
|
}
|
|
39294
39476
|
return false;
|
|
39295
39477
|
}
|
|
@@ -39863,6 +40045,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39863
40045
|
if (currentStart === start && currentEnd === end) {
|
|
39864
40046
|
return;
|
|
39865
40047
|
}
|
|
40048
|
+
if (selection.rangeCount === 0) {
|
|
40049
|
+
const range = document.createRange();
|
|
40050
|
+
selection.addRange(range);
|
|
40051
|
+
}
|
|
39866
40052
|
const currentRange = selection.getRangeAt(0);
|
|
39867
40053
|
let range;
|
|
39868
40054
|
if (this.el.contains(currentRange.startContainer)) {
|
|
@@ -39890,8 +40076,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39890
40076
|
}
|
|
39891
40077
|
let startNode = this.findChildAtCharacterIndex(start);
|
|
39892
40078
|
let endNode = this.findChildAtCharacterIndex(end);
|
|
39893
|
-
|
|
39894
|
-
|
|
40079
|
+
// setEnd (setStart) will result in a collapsed range if the end point is before the start point
|
|
40080
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Range/setEnd
|
|
40081
|
+
if (start <= end) {
|
|
40082
|
+
range.setStart(startNode.node, startNode.offset);
|
|
40083
|
+
range.setEnd(endNode.node, endNode.offset);
|
|
40084
|
+
}
|
|
40085
|
+
else {
|
|
40086
|
+
range.setStart(endNode.node, endNode.offset);
|
|
40087
|
+
range.setEnd(startNode.node, startNode.offset);
|
|
40088
|
+
}
|
|
39895
40089
|
}
|
|
39896
40090
|
}
|
|
39897
40091
|
/**
|
|
@@ -40025,7 +40219,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40025
40219
|
if (!focusedNode || !this.el.contains(focusedNode))
|
|
40026
40220
|
return;
|
|
40027
40221
|
const element = focusedNode instanceof HTMLElement ? focusedNode : focusedNode.parentElement;
|
|
40028
|
-
element?.scrollIntoView({ block: "nearest" });
|
|
40222
|
+
element?.scrollIntoView?.({ block: "nearest" });
|
|
40029
40223
|
}
|
|
40030
40224
|
/**
|
|
40031
40225
|
* remove the current selection of the user
|
|
@@ -40045,100 +40239,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40045
40239
|
* finds the indexes of the current selection.
|
|
40046
40240
|
* */
|
|
40047
40241
|
getCurrentSelection() {
|
|
40048
|
-
|
|
40049
|
-
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
40050
|
-
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
40051
|
-
return {
|
|
40052
|
-
start: startSizeBefore,
|
|
40053
|
-
end: endSizeBefore,
|
|
40054
|
-
};
|
|
40055
|
-
}
|
|
40056
|
-
/**
|
|
40057
|
-
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
40058
|
-
* The selected node is either a Text node or an Element node.
|
|
40059
|
-
*
|
|
40060
|
-
* case 1 -Text node:
|
|
40061
|
-
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
40062
|
-
* content length of all previous nodes.
|
|
40063
|
-
*
|
|
40064
|
-
* case 2 - Element node:
|
|
40065
|
-
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
40066
|
-
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
40067
|
-
*
|
|
40068
|
-
* See the MDN documentation for more details.
|
|
40069
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
40070
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
40071
|
-
*
|
|
40072
|
-
*/
|
|
40073
|
-
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
40074
|
-
let usedCharacters = 0;
|
|
40075
|
-
let it = iterateChildren(this.el);
|
|
40076
|
-
let current = it.next();
|
|
40077
|
-
let isFirstParagraph = true;
|
|
40078
|
-
while (!current.done && current.value !== nodeToFind) {
|
|
40079
|
-
if (!current.value.hasChildNodes()) {
|
|
40080
|
-
if (current.value.textContent) {
|
|
40081
|
-
usedCharacters += current.value.textContent.length;
|
|
40082
|
-
}
|
|
40083
|
-
}
|
|
40084
|
-
// One new paragraph = one new line character, except for the first paragraph
|
|
40085
|
-
if (current.value.nodeName === "P" ||
|
|
40086
|
-
(current.value.nodeName === "DIV" && current.value !== this.el) // On paste, the HTML may contain <div> instead of <p>
|
|
40087
|
-
) {
|
|
40088
|
-
if (isFirstParagraph) {
|
|
40089
|
-
isFirstParagraph = false;
|
|
40090
|
-
}
|
|
40091
|
-
else {
|
|
40092
|
-
usedCharacters++;
|
|
40093
|
-
}
|
|
40094
|
-
}
|
|
40095
|
-
current = it.next();
|
|
40096
|
-
}
|
|
40097
|
-
if (current.value !== nodeToFind) {
|
|
40098
|
-
/** This situation can happen if the code is called while the selection is not currently on the ContentEditableHelper.
|
|
40099
|
-
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
40100
|
-
*
|
|
40101
|
-
* A known occurence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
40102
|
-
*
|
|
40103
|
-
* FIXME: find a way to test eventhough the selection API is not available in jsDOM.
|
|
40104
|
-
*/
|
|
40105
|
-
return 0;
|
|
40106
|
-
}
|
|
40107
|
-
else {
|
|
40108
|
-
if (!current.value.hasChildNodes()) {
|
|
40109
|
-
usedCharacters += nodeOffset;
|
|
40110
|
-
}
|
|
40111
|
-
else {
|
|
40112
|
-
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
40113
|
-
usedCharacters += children.reduce((acc, child, index) => {
|
|
40114
|
-
if (child.textContent !== null) {
|
|
40115
|
-
// need to account for paragraph nodes that implicitely add a new line
|
|
40116
|
-
// except for the last paragraph
|
|
40117
|
-
let chars = child.textContent.length;
|
|
40118
|
-
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
40119
|
-
chars++;
|
|
40120
|
-
}
|
|
40121
|
-
return acc + chars;
|
|
40122
|
-
}
|
|
40123
|
-
else {
|
|
40124
|
-
return acc;
|
|
40125
|
-
}
|
|
40126
|
-
}, 0);
|
|
40127
|
-
}
|
|
40128
|
-
}
|
|
40129
|
-
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
40130
|
-
usedCharacters++;
|
|
40131
|
-
}
|
|
40132
|
-
return usedCharacters;
|
|
40133
|
-
}
|
|
40134
|
-
getStartAndEndSelection() {
|
|
40135
|
-
const selection = document.getSelection();
|
|
40136
|
-
return {
|
|
40137
|
-
startElement: selection.anchorNode || this.el,
|
|
40138
|
-
startSelectionOffset: selection.anchorOffset,
|
|
40139
|
-
endElement: selection.focusNode || this.el,
|
|
40140
|
-
endSelectionOffset: selection.focusOffset,
|
|
40141
|
-
};
|
|
40242
|
+
return getCurrentSelection(this.el);
|
|
40142
40243
|
}
|
|
40143
40244
|
getText() {
|
|
40144
40245
|
let text = "";
|
|
@@ -42067,7 +42168,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
42067
42168
|
this.originalEditedCf = undefined;
|
|
42068
42169
|
}
|
|
42069
42170
|
addConditionalFormat() {
|
|
42070
|
-
const cfId = this.env.model.uuidGenerator.
|
|
42171
|
+
const cfId = this.env.model.uuidGenerator.smallUuid();
|
|
42071
42172
|
this.env.model.dispatch("ADD_CONDITIONAL_FORMAT", {
|
|
42072
42173
|
sheetId: this.activeSheetId,
|
|
42073
42174
|
ranges: this.env.model.getters
|
|
@@ -43337,7 +43438,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
43337
43438
|
.getSelectedZones()
|
|
43338
43439
|
.map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
|
|
43339
43440
|
return {
|
|
43340
|
-
id: this.env.model.uuidGenerator.
|
|
43441
|
+
id: this.env.model.uuidGenerator.smallUuid(),
|
|
43341
43442
|
criterion: { type: "textContains", values: [""] },
|
|
43342
43443
|
ranges,
|
|
43343
43444
|
};
|
|
@@ -44955,8 +45056,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
44955
45056
|
return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
|
|
44956
45057
|
}
|
|
44957
45058
|
duplicatePivot() {
|
|
44958
|
-
const newPivotId = this.env.model.uuidGenerator.
|
|
44959
|
-
const newSheetId = this.env.model.uuidGenerator.
|
|
45059
|
+
const newPivotId = this.env.model.uuidGenerator.smallUuid();
|
|
45060
|
+
const newSheetId = this.env.model.uuidGenerator.smallUuid();
|
|
44960
45061
|
const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
|
|
44961
45062
|
pivotId: this.props.pivotId,
|
|
44962
45063
|
newPivotId,
|
|
@@ -47581,7 +47682,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
47581
47682
|
this.state.selectedTemplateName = templateName;
|
|
47582
47683
|
}
|
|
47583
47684
|
onConfirm() {
|
|
47584
|
-
const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.
|
|
47685
|
+
const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
|
|
47585
47686
|
this.env.model.dispatch("CREATE_TABLE_STYLE", {
|
|
47586
47687
|
tableStyleId,
|
|
47587
47688
|
tableStyleName: this.state.styleName,
|
|
@@ -53093,6 +53194,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53093
53194
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
53094
53195
|
case "CLEAR_CELL":
|
|
53095
53196
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
53197
|
+
case "UPDATE_CELL_POSITION":
|
|
53198
|
+
return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
|
|
53199
|
+
? "Success" /* CommandResult.Success */
|
|
53200
|
+
: "InvalidCellId" /* CommandResult.InvalidCellId */;
|
|
53096
53201
|
default:
|
|
53097
53202
|
return "Success" /* CommandResult.Success */;
|
|
53098
53203
|
}
|
|
@@ -53137,6 +53242,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53137
53242
|
case "DELETE_CONTENT":
|
|
53138
53243
|
this.clearZones(cmd.sheetId, cmd.target);
|
|
53139
53244
|
break;
|
|
53245
|
+
case "DELETE_SHEET": {
|
|
53246
|
+
this.history.update("cells", cmd.sheetId, undefined);
|
|
53247
|
+
}
|
|
53140
53248
|
}
|
|
53141
53249
|
}
|
|
53142
53250
|
clearZones(sheetId, zones) {
|
|
@@ -53927,6 +54035,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53927
54035
|
allowDispatch(cmd) {
|
|
53928
54036
|
switch (cmd.type) {
|
|
53929
54037
|
case "ADD_CONDITIONAL_FORMAT":
|
|
54038
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
54039
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54040
|
+
}
|
|
53930
54041
|
return this.checkValidations(cmd, this.checkCFRule, this.checkEmptyRange, this.checkCFHasChanged);
|
|
53931
54042
|
case "CHANGE_CONDITIONAL_FORMAT_PRIORITY":
|
|
53932
54043
|
return this.checkValidPriorityChange(cmd.cfId, cmd.delta, cmd.sheetId);
|
|
@@ -54343,8 +54454,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54343
54454
|
allowDispatch(cmd) {
|
|
54344
54455
|
switch (cmd.type) {
|
|
54345
54456
|
case "ADD_DATA_VALIDATION_RULE":
|
|
54457
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
54458
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54459
|
+
}
|
|
54460
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
54461
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54462
|
+
}
|
|
54346
54463
|
return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkValidRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
|
|
54347
54464
|
case "REMOVE_DATA_VALIDATION_RULE":
|
|
54465
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
54466
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54467
|
+
}
|
|
54348
54468
|
if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
|
|
54349
54469
|
return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
|
|
54350
54470
|
}
|
|
@@ -54571,6 +54691,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54571
54691
|
class FigurePlugin extends CorePlugin {
|
|
54572
54692
|
static getters = ["getFigures", "getFigure", "getFigureSheetId"];
|
|
54573
54693
|
figures = {};
|
|
54694
|
+
insertionOrders = []; // TODO use a list in master
|
|
54574
54695
|
// ---------------------------------------------------------------------------
|
|
54575
54696
|
// Command Handling
|
|
54576
54697
|
// ---------------------------------------------------------------------------
|
|
@@ -54673,11 +54794,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54673
54794
|
}
|
|
54674
54795
|
addFigure(figure, sheetId) {
|
|
54675
54796
|
this.history.update("figures", sheetId, figure.id, figure);
|
|
54797
|
+
this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
|
|
54676
54798
|
}
|
|
54677
54799
|
deleteSheet(sheetId) {
|
|
54800
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
|
|
54678
54801
|
this.history.update("figures", sheetId, undefined);
|
|
54679
54802
|
}
|
|
54680
54803
|
removeFigure(id, sheetId) {
|
|
54804
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
|
|
54681
54805
|
this.history.update("figures", sheetId, id, undefined);
|
|
54682
54806
|
}
|
|
54683
54807
|
checkFigureExists(sheetId, figureId) {
|
|
@@ -54696,7 +54820,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54696
54820
|
// Getters
|
|
54697
54821
|
// ---------------------------------------------------------------------------
|
|
54698
54822
|
getFigures(sheetId) {
|
|
54699
|
-
|
|
54823
|
+
const figures = [];
|
|
54824
|
+
for (const figureId of this.insertionOrders) {
|
|
54825
|
+
const figure = this.figures[sheetId]?.[figureId];
|
|
54826
|
+
if (figure) {
|
|
54827
|
+
figures.push(figure);
|
|
54828
|
+
}
|
|
54829
|
+
}
|
|
54830
|
+
return figures;
|
|
54700
54831
|
}
|
|
54701
54832
|
getFigure(sheetId, figureId) {
|
|
54702
54833
|
return this.figures[sheetId]?.[figureId];
|
|
@@ -54709,11 +54840,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
54709
54840
|
// ---------------------------------------------------------------------------
|
|
54710
54841
|
import(data) {
|
|
54711
54842
|
for (let sheet of data.sheets) {
|
|
54712
|
-
const figures
|
|
54713
|
-
|
|
54714
|
-
|
|
54715
|
-
});
|
|
54716
|
-
this.figures[sheet.id] = figures;
|
|
54843
|
+
for (const figure of sheet.figures) {
|
|
54844
|
+
this.addFigure(figure, sheet.id);
|
|
54845
|
+
}
|
|
54717
54846
|
}
|
|
54718
54847
|
}
|
|
54719
54848
|
export(data) {
|
|
@@ -56139,6 +56268,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56139
56268
|
case "CREATE_SHEET": {
|
|
56140
56269
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
56141
56270
|
}
|
|
56271
|
+
case "DUPLICATE_SHEET": {
|
|
56272
|
+
return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
|
|
56273
|
+
}
|
|
56142
56274
|
case "MOVE_SHEET":
|
|
56143
56275
|
try {
|
|
56144
56276
|
const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
|
|
@@ -56155,7 +56287,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56155
56287
|
? "Success" /* CommandResult.Success */
|
|
56156
56288
|
: "InvalidColor" /* CommandResult.InvalidColor */;
|
|
56157
56289
|
case "DELETE_SHEET":
|
|
56158
|
-
return this.
|
|
56290
|
+
return this.getVisibleSheetIds().length > 1
|
|
56159
56291
|
? "Success" /* CommandResult.Success */
|
|
56160
56292
|
: "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
|
|
56161
56293
|
case "ADD_COLUMNS_ROWS":
|
|
@@ -56950,6 +57082,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56950
57082
|
checkZonesAreInSheet(cmd) {
|
|
56951
57083
|
if (!("sheetId" in cmd))
|
|
56952
57084
|
return "Success" /* CommandResult.Success */;
|
|
57085
|
+
if ("ranges" in cmd &&
|
|
57086
|
+
cmd.ranges.some((rangeData) => rangeData._sheetId !== "" && !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
57087
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57088
|
+
}
|
|
56953
57089
|
return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
|
|
56954
57090
|
}
|
|
56955
57091
|
}
|
|
@@ -56958,6 +57094,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56958
57094
|
class TablePlugin extends CorePlugin {
|
|
56959
57095
|
static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
|
|
56960
57096
|
tables = {};
|
|
57097
|
+
insertionOrders = {};
|
|
56961
57098
|
adaptRanges(applyChange, sheetId) {
|
|
56962
57099
|
const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
|
|
56963
57100
|
for (const sheetId of sheetIds) {
|
|
@@ -56969,6 +57106,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56969
57106
|
allowDispatch(cmd) {
|
|
56970
57107
|
switch (cmd.type) {
|
|
56971
57108
|
case "CREATE_TABLE":
|
|
57109
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
|
|
57110
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57111
|
+
}
|
|
56972
57112
|
const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
|
|
56973
57113
|
if (!areZonesContinuous(zones)) {
|
|
56974
57114
|
return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
|
|
@@ -56999,11 +57139,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
56999
57139
|
switch (cmd.type) {
|
|
57000
57140
|
case "CREATE_SHEET":
|
|
57001
57141
|
this.history.update("tables", cmd.sheetId, {});
|
|
57142
|
+
this.history.update("insertionOrders", cmd.sheetId, []);
|
|
57002
57143
|
break;
|
|
57003
57144
|
case "DELETE_SHEET": {
|
|
57004
57145
|
const tables = { ...this.tables };
|
|
57005
57146
|
delete tables[cmd.sheetId];
|
|
57006
57147
|
this.history.update("tables", tables);
|
|
57148
|
+
this.history.update("insertionOrders", cmd.sheetId, undefined);
|
|
57007
57149
|
break;
|
|
57008
57150
|
}
|
|
57009
57151
|
case "DUPLICATE_SHEET": {
|
|
@@ -57015,6 +57157,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57015
57157
|
: this.copyStaticTableForSheet(cmd.sheetIdTo, table);
|
|
57016
57158
|
}
|
|
57017
57159
|
this.history.update("tables", cmd.sheetIdTo, newTables);
|
|
57160
|
+
this.history.update("insertionOrders", cmd.sheetIdTo, [
|
|
57161
|
+
...(this.insertionOrders[cmd.sheetId] ?? []),
|
|
57162
|
+
]);
|
|
57018
57163
|
break;
|
|
57019
57164
|
}
|
|
57020
57165
|
case "CREATE_TABLE": {
|
|
@@ -57028,6 +57173,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57028
57173
|
? this.createDynamicTable(id, union, config)
|
|
57029
57174
|
: this.createStaticTable(id, cmd.tableType, union, config);
|
|
57030
57175
|
this.history.update("tables", cmd.sheetId, newTable.id, newTable);
|
|
57176
|
+
this.history.update("insertionOrders", cmd.sheetId, [
|
|
57177
|
+
...(this.insertionOrders[cmd.sheetId] ?? []),
|
|
57178
|
+
newTable.id,
|
|
57179
|
+
]);
|
|
57031
57180
|
break;
|
|
57032
57181
|
}
|
|
57033
57182
|
case "REMOVE_TABLE": {
|
|
@@ -57038,6 +57187,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57038
57187
|
}
|
|
57039
57188
|
}
|
|
57040
57189
|
this.history.update("tables", cmd.sheetId, tables);
|
|
57190
|
+
this.history.update("insertionOrders", cmd.sheetId, this.insertionOrders[cmd.sheetId]?.filter((id) => id in tables));
|
|
57041
57191
|
break;
|
|
57042
57192
|
}
|
|
57043
57193
|
case "UPDATE_TABLE": {
|
|
@@ -57073,7 +57223,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57073
57223
|
}
|
|
57074
57224
|
}
|
|
57075
57225
|
getCoreTables(sheetId) {
|
|
57076
|
-
|
|
57226
|
+
const tables = [];
|
|
57227
|
+
for (const tableId of this.insertionOrders[sheetId] || []) {
|
|
57228
|
+
const table = this.tables[sheetId][tableId];
|
|
57229
|
+
if (table) {
|
|
57230
|
+
tables.push(table);
|
|
57231
|
+
}
|
|
57232
|
+
}
|
|
57233
|
+
return tables;
|
|
57077
57234
|
}
|
|
57078
57235
|
getCoreTable({ sheetId, col, row }) {
|
|
57079
57236
|
return this.getCoreTables(sheetId).find((table) => isInside(col, row, table.range.zone));
|
|
@@ -57356,6 +57513,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57356
57513
|
// ---------------------------------------------------------------------------
|
|
57357
57514
|
import(data) {
|
|
57358
57515
|
for (const sheet of data.sheets) {
|
|
57516
|
+
const tableIds = [];
|
|
57359
57517
|
for (const tableData of sheet.tables || []) {
|
|
57360
57518
|
const uuid = `${nextTableId++}`;
|
|
57361
57519
|
const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
|
|
@@ -57365,7 +57523,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57365
57523
|
? this.createDynamicTable(uuid, range, tableConfig)
|
|
57366
57524
|
: this.createStaticTable(uuid, tableType, range, tableConfig);
|
|
57367
57525
|
this.history.update("tables", sheet.id, table.id, table);
|
|
57526
|
+
tableIds.push(table.id);
|
|
57368
57527
|
}
|
|
57528
|
+
this.history.update("insertionOrders", sheet.id, tableIds);
|
|
57369
57529
|
}
|
|
57370
57530
|
}
|
|
57371
57531
|
export(data) {
|
|
@@ -57405,7 +57565,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57405
57565
|
allowDispatch(cmd) {
|
|
57406
57566
|
switch (cmd.type) {
|
|
57407
57567
|
case "GROUP_HEADERS": {
|
|
57408
|
-
const { start, end } = cmd;
|
|
57568
|
+
const { start, end, sheetId } = cmd;
|
|
57569
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
57570
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57571
|
+
}
|
|
57409
57572
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
57410
57573
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
57411
57574
|
}
|
|
@@ -57418,7 +57581,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57418
57581
|
break;
|
|
57419
57582
|
}
|
|
57420
57583
|
case "UNGROUP_HEADERS": {
|
|
57421
|
-
const { start, end } = cmd;
|
|
57584
|
+
const { start, end, sheetId } = cmd;
|
|
57585
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
57586
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57587
|
+
}
|
|
57422
57588
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
57423
57589
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
57424
57590
|
}
|
|
@@ -57429,6 +57595,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57429
57595
|
}
|
|
57430
57596
|
case "UNFOLD_HEADER_GROUP":
|
|
57431
57597
|
case "FOLD_HEADER_GROUP":
|
|
57598
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
57599
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57600
|
+
}
|
|
57432
57601
|
const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
|
|
57433
57602
|
if (!group) {
|
|
57434
57603
|
return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
|
|
@@ -57829,6 +57998,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57829
57998
|
return this.checkDuplicatedMeasureIds(cmd.pivot);
|
|
57830
57999
|
}
|
|
57831
58000
|
case "UPDATE_PIVOT": {
|
|
58001
|
+
if (!(cmd.pivotId in this.pivots)) {
|
|
58002
|
+
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
58003
|
+
}
|
|
57832
58004
|
if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
|
|
57833
58005
|
return "NoChanges" /* CommandResult.NoChanges */;
|
|
57834
58006
|
}
|
|
@@ -57845,6 +58017,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57845
58017
|
return "EmptyName" /* CommandResult.EmptyName */;
|
|
57846
58018
|
}
|
|
57847
58019
|
break;
|
|
58020
|
+
case "REMOVE_PIVOT":
|
|
58021
|
+
case "DUPLICATE_PIVOT":
|
|
57848
58022
|
case "INSERT_PIVOT": {
|
|
57849
58023
|
if (!(cmd.pivotId in this.pivots)) {
|
|
57850
58024
|
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
@@ -57894,7 +58068,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57894
58068
|
break;
|
|
57895
58069
|
}
|
|
57896
58070
|
case "UPDATE_PIVOT": {
|
|
57897
|
-
this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
|
|
58071
|
+
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
57898
58072
|
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
57899
58073
|
break;
|
|
57900
58074
|
}
|
|
@@ -57965,7 +58139,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57965
58139
|
// Private
|
|
57966
58140
|
// -------------------------------------------------------------------------
|
|
57967
58141
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
57968
|
-
this.history.update("pivots", pivotId, { definition: pivot, formulaId });
|
|
58142
|
+
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
57969
58143
|
this.compileCalculatedMeasures(pivot.measures);
|
|
57970
58144
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
57971
58145
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
@@ -59551,6 +59725,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59551
59725
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
59552
59726
|
this.compilationParams.evalContext.updateDependencies = this.updateDependencies.bind(this);
|
|
59553
59727
|
this.compilationParams.evalContext.addDependencies = this.addDependencies.bind(this);
|
|
59728
|
+
this.compilationParams.evalContext.lookupCaches = {
|
|
59729
|
+
forwardSearch: new Map(),
|
|
59730
|
+
reverseSearch: new Map(),
|
|
59731
|
+
};
|
|
59554
59732
|
}
|
|
59555
59733
|
createEmptyPositionSet() {
|
|
59556
59734
|
const sheetSizes = {};
|
|
@@ -62871,6 +63049,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
62871
63049
|
};
|
|
62872
63050
|
}
|
|
62873
63051
|
function createSheetTransformation(toTransform, executed) {
|
|
63052
|
+
if (toTransform.sheetId === executed.sheetId) {
|
|
63053
|
+
toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
|
|
63054
|
+
}
|
|
62874
63055
|
if (toTransform.name === executed.name) {
|
|
62875
63056
|
return {
|
|
62876
63057
|
...toTransform,
|
|
@@ -63522,21 +63703,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
63522
63703
|
if (!message)
|
|
63523
63704
|
return;
|
|
63524
63705
|
if (message.type === "REMOTE_REVISION") {
|
|
63525
|
-
|
|
63706
|
+
let revision = this.revisions.get(message.nextRevisionId);
|
|
63526
63707
|
if (revision.commands.length === 0) {
|
|
63527
63708
|
/**
|
|
63528
|
-
* The command is empty, we have to
|
|
63709
|
+
* The command is empty, we have to rebase all the next local revisions
|
|
63529
63710
|
* to avoid issues with undo/redo
|
|
63530
63711
|
*/
|
|
63531
|
-
this.revisions.
|
|
63532
|
-
|
|
63533
|
-
.filter((message) => message.type === "REMOTE_REVISION")
|
|
63534
|
-
.map((message) => message.nextRevisionId);
|
|
63535
|
-
this.trigger("pending-revisions-dropped", { revisionIds });
|
|
63536
|
-
this.waitingAck = false;
|
|
63537
|
-
this.waitingUndoRedoAck = false;
|
|
63538
|
-
this.pendingMessages = [];
|
|
63539
|
-
return;
|
|
63712
|
+
this.revisions.rebase(revision.id);
|
|
63713
|
+
revision = this.revisions.get(message.nextRevisionId);
|
|
63540
63714
|
}
|
|
63541
63715
|
message = {
|
|
63542
63716
|
...message,
|
|
@@ -63561,7 +63735,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
63561
63735
|
switch (message.type) {
|
|
63562
63736
|
case "REMOTE_REVISION":
|
|
63563
63737
|
case "REVISION_REDONE":
|
|
63564
|
-
case "REVISION_UNDONE":
|
|
63565
63738
|
case "SNAPSHOT_CREATED":
|
|
63566
63739
|
this.waitingAck = false;
|
|
63567
63740
|
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
@@ -63570,6 +63743,25 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
63570
63743
|
this.lastRevisionMessage = message;
|
|
63571
63744
|
this.sendPendingMessage();
|
|
63572
63745
|
break;
|
|
63746
|
+
case "REVISION_UNDONE": {
|
|
63747
|
+
this.waitingAck = false;
|
|
63748
|
+
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
63749
|
+
const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
|
|
63750
|
+
if (firstPendingRevisionId !== -1) {
|
|
63751
|
+
/**
|
|
63752
|
+
* Some revisions undergo transformations that may cause issues with
|
|
63753
|
+
* undo/redo if the transformation is destructive (we don't get back
|
|
63754
|
+
* the original command by transforming it with the inverse).
|
|
63755
|
+
* To prevent these problems, we must rebase all subsequent local
|
|
63756
|
+
* revisions.
|
|
63757
|
+
*/
|
|
63758
|
+
this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
|
|
63759
|
+
}
|
|
63760
|
+
this.serverRevisionId = message.nextRevisionId;
|
|
63761
|
+
this.processedRevisions.add(message.nextRevisionId);
|
|
63762
|
+
this.sendPendingMessage();
|
|
63763
|
+
break;
|
|
63764
|
+
}
|
|
63573
63765
|
}
|
|
63574
63766
|
}
|
|
63575
63767
|
isAlreadyProcessed(message) {
|
|
@@ -64691,6 +64883,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
64691
64883
|
*/
|
|
64692
64884
|
checkZonesAreInSheet(cmd) {
|
|
64693
64885
|
const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
|
|
64886
|
+
if ("ranges" in cmd &&
|
|
64887
|
+
cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
64888
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
64889
|
+
}
|
|
64694
64890
|
const zones = this.getters.getCommandZones(cmd);
|
|
64695
64891
|
if (!sheetId && zones.length > 0) {
|
|
64696
64892
|
return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
|
|
@@ -65040,23 +65236,23 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65040
65236
|
function repeatCreateChartCommand(getters, cmd) {
|
|
65041
65237
|
return {
|
|
65042
65238
|
...repeatSheetDependantCommand(getters, cmd),
|
|
65043
|
-
id: uuidGenerator.
|
|
65239
|
+
id: uuidGenerator.smallUuid(),
|
|
65044
65240
|
};
|
|
65045
65241
|
}
|
|
65046
65242
|
function repeatCreateImageCommand(getters, cmd) {
|
|
65047
65243
|
return {
|
|
65048
65244
|
...repeatSheetDependantCommand(getters, cmd),
|
|
65049
|
-
figureId: uuidGenerator.
|
|
65245
|
+
figureId: uuidGenerator.smallUuid(),
|
|
65050
65246
|
};
|
|
65051
65247
|
}
|
|
65052
65248
|
function repeatCreateFigureCommand(getters, cmd) {
|
|
65053
65249
|
const newCmd = repeatSheetDependantCommand(getters, cmd);
|
|
65054
|
-
newCmd.figure.id = uuidGenerator.
|
|
65250
|
+
newCmd.figure.id = uuidGenerator.smallUuid();
|
|
65055
65251
|
return newCmd;
|
|
65056
65252
|
}
|
|
65057
65253
|
function repeatCreateSheetCommand(getters, cmd) {
|
|
65058
65254
|
const newCmd = deepCopy(cmd);
|
|
65059
|
-
newCmd.sheetId = uuidGenerator.
|
|
65255
|
+
newCmd.sheetId = uuidGenerator.smallUuid();
|
|
65060
65256
|
const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
|
|
65061
65257
|
// Extract the prefix of the sheet name (everything before the number at the end of the name)
|
|
65062
65258
|
const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
|
|
@@ -65245,7 +65441,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65245
65441
|
super(config);
|
|
65246
65442
|
this.session = config.session;
|
|
65247
65443
|
this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
|
|
65248
|
-
this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
|
|
65249
65444
|
this.session.on("snapshot", this, () => {
|
|
65250
65445
|
this.undoStack = [];
|
|
65251
65446
|
this.redoStack = [];
|
|
@@ -65315,10 +65510,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
65315
65510
|
const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
|
|
65316
65511
|
return canRepeatRevision(lastNonRedoRevision);
|
|
65317
65512
|
}
|
|
65318
|
-
drop(revisionIds) {
|
|
65319
|
-
this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
|
|
65320
|
-
this.redoStack = [];
|
|
65321
|
-
}
|
|
65322
65513
|
onNewLocalStateUpdate({ id }) {
|
|
65323
65514
|
this.undoStack.push(id);
|
|
65324
65515
|
this.redoStack = [];
|
|
@@ -66519,23 +66710,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66519
66710
|
gridSelection: deepCopy(gridSelection),
|
|
66520
66711
|
};
|
|
66521
66712
|
}
|
|
66522
|
-
|
|
66523
|
-
const currentSheetIds = this.getters.getVisibleSheetIds();
|
|
66524
|
-
this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
|
|
66525
|
-
if (this.activeSheet.id in this.sheetsData) {
|
|
66526
|
-
const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
|
|
66527
|
-
this.selectCell(anchor.cell.col, anchor.cell.row);
|
|
66528
|
-
}
|
|
66529
|
-
else {
|
|
66530
|
-
this.selectCell(0, 0);
|
|
66531
|
-
}
|
|
66532
|
-
const { col, row } = this.gridSelection.anchor.cell;
|
|
66533
|
-
this.moveClient({
|
|
66534
|
-
sheetId: this.getters.getActiveSheetId(),
|
|
66535
|
-
col,
|
|
66536
|
-
row,
|
|
66537
|
-
});
|
|
66538
|
-
}
|
|
66713
|
+
this.fallbackToVisibleSheet();
|
|
66539
66714
|
const sheetId = this.getters.getActiveSheetId();
|
|
66540
66715
|
this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
|
|
66541
66716
|
this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
|
|
@@ -66545,6 +66720,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66545
66720
|
}
|
|
66546
66721
|
}
|
|
66547
66722
|
finalize() {
|
|
66723
|
+
this.fallbackToVisibleSheet();
|
|
66548
66724
|
/** Any change to the selection has to be reflected in the selection processor. */
|
|
66549
66725
|
this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
|
|
66550
66726
|
}
|
|
@@ -66855,6 +67031,25 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66855
67031
|
}
|
|
66856
67032
|
return "Success" /* CommandResult.Success */;
|
|
66857
67033
|
}
|
|
67034
|
+
fallbackToVisibleSheet() {
|
|
67035
|
+
if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
|
|
67036
|
+
const currentSheetIds = this.getters.getVisibleSheetIds();
|
|
67037
|
+
this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
|
|
67038
|
+
if (this.activeSheet.id in this.sheetsData) {
|
|
67039
|
+
const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
|
|
67040
|
+
this.selectCell(anchor.cell.col, anchor.cell.row);
|
|
67041
|
+
}
|
|
67042
|
+
else {
|
|
67043
|
+
this.selectCell(0, 0);
|
|
67044
|
+
}
|
|
67045
|
+
const { col, row } = this.gridSelection.anchor.cell;
|
|
67046
|
+
this.moveClient({
|
|
67047
|
+
sheetId: this.getters.getActiveSheetId(),
|
|
67048
|
+
col,
|
|
67049
|
+
row,
|
|
67050
|
+
});
|
|
67051
|
+
}
|
|
67052
|
+
}
|
|
66858
67053
|
//-------------------------------------------
|
|
66859
67054
|
// Helpers for extensions
|
|
66860
67055
|
// ------------------------------------------
|
|
@@ -68018,7 +68213,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68018
68213
|
case "UNGROUP_HEADERS":
|
|
68019
68214
|
case "GROUP_HEADERS":
|
|
68020
68215
|
case "CREATE_SHEET":
|
|
68021
|
-
this.
|
|
68216
|
+
if (this.getters.tryGetSheet(cmd.sheetId)) {
|
|
68217
|
+
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
68218
|
+
}
|
|
68022
68219
|
break;
|
|
68023
68220
|
case "DUPLICATE_SHEET":
|
|
68024
68221
|
this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
|
|
@@ -68026,12 +68223,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68026
68223
|
}
|
|
68027
68224
|
}
|
|
68028
68225
|
finalize() {
|
|
68029
|
-
|
|
68030
|
-
|
|
68226
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
68227
|
+
// sheets can be created without this plugin being aware of it
|
|
68228
|
+
// in concurrent situations.
|
|
68229
|
+
if (this.isDirty || !this.headerPositions[sheetId]) {
|
|
68031
68230
|
this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
|
|
68032
68231
|
}
|
|
68033
|
-
this.isDirty = false;
|
|
68034
68232
|
}
|
|
68233
|
+
this.isDirty = false;
|
|
68035
68234
|
}
|
|
68036
68235
|
/**
|
|
68037
68236
|
* Returns the size, start and end coordinates of a column on an unfolded sheet
|
|
@@ -68855,7 +69054,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68855
69054
|
clickAddSheet(ev) {
|
|
68856
69055
|
const activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
68857
69056
|
const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
|
|
68858
|
-
const sheetId = this.env.model.uuidGenerator.
|
|
69057
|
+
const sheetId = this.env.model.uuidGenerator.smallUuid();
|
|
68859
69058
|
const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
|
|
68860
69059
|
this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
|
|
68861
69060
|
this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
|
|
@@ -69870,6 +70069,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69870
70069
|
</svg>
|
|
69871
70070
|
`;
|
|
69872
70071
|
css /* scss */ `
|
|
70072
|
+
.o-topbar-composer-container {
|
|
70073
|
+
height: ${TOPBAR_TOOLBAR_HEIGHT}px;
|
|
70074
|
+
}
|
|
70075
|
+
|
|
69873
70076
|
.o-topbar-composer {
|
|
69874
70077
|
height: fit-content;
|
|
69875
70078
|
margin-top: -1px;
|
|
@@ -71143,7 +71346,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
71143
71346
|
}
|
|
71144
71347
|
/**
|
|
71145
71348
|
* Drop the operation and all following operations in every
|
|
71146
|
-
*
|
|
71349
|
+
* branches
|
|
71147
71350
|
*/
|
|
71148
71351
|
drop(operationId) {
|
|
71149
71352
|
for (const branch of this.branches) {
|
|
@@ -71448,9 +71651,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
71448
71651
|
this.fastForward();
|
|
71449
71652
|
this.insert(redoId, this.buildEmpty(redoId), insertAfter);
|
|
71450
71653
|
}
|
|
71451
|
-
|
|
71654
|
+
rebase(operationId) {
|
|
71655
|
+
const operation = this.get(operationId);
|
|
71656
|
+
const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
|
|
71452
71657
|
this.revertBefore(operationId);
|
|
71658
|
+
const baseId = this.HEAD_OPERATION.id;
|
|
71453
71659
|
this.tree.drop(operationId);
|
|
71660
|
+
this.insert(operationId, operation, baseId);
|
|
71661
|
+
for (const { operation } of execution) {
|
|
71662
|
+
this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
|
|
71663
|
+
}
|
|
71454
71664
|
}
|
|
71455
71665
|
/**
|
|
71456
71666
|
* Revert the state as it was *before* the given operation was executed.
|
|
@@ -74561,6 +74771,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74561
74771
|
dispatch: (command) => {
|
|
74562
74772
|
const result = this.checkDispatchAllowed(command);
|
|
74563
74773
|
if (!result.isSuccessful) {
|
|
74774
|
+
// core views plugins need to be invalidated
|
|
74775
|
+
this.dispatchToHandlers(this.coreHandlers, {
|
|
74776
|
+
type: "UNDO",
|
|
74777
|
+
commands: [command],
|
|
74778
|
+
});
|
|
74564
74779
|
return;
|
|
74565
74780
|
}
|
|
74566
74781
|
this.isReplayingCommand = true;
|
|
@@ -74588,7 +74803,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
74588
74803
|
}
|
|
74589
74804
|
setupConfig(config) {
|
|
74590
74805
|
const client = config.client || {
|
|
74591
|
-
id: this.uuidGenerator.
|
|
74806
|
+
id: this.uuidGenerator.smallUuid(),
|
|
74592
74807
|
name: _t("Anonymous").toString(),
|
|
74593
74808
|
};
|
|
74594
74809
|
const transportService = config.transportService || new LocalTransportService();
|
|
@@ -75111,9 +75326,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
75111
75326
|
exports.tokenize = tokenize;
|
|
75112
75327
|
|
|
75113
75328
|
|
|
75114
|
-
__info__.version = "18.1.
|
|
75115
|
-
__info__.date = "2025-02-
|
|
75116
|
-
__info__.hash = "
|
|
75329
|
+
__info__.version = "18.1.9";
|
|
75330
|
+
__info__.date = "2025-02-25T05:59:45.472Z";
|
|
75331
|
+
__info__.hash = "6789c1c";
|
|
75117
75332
|
|
|
75118
75333
|
|
|
75119
75334
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|